ssl.c

来自「微软的http服务器实例代码」· C语言 代码 · 共 596 行 · 第 1/2 页

C
596
字号
/*++
 Copyright (c) 2002 - 2002 Microsoft Corporation.  All Rights Reserved.

 THIS CODE AND INFORMATION IS PROVIDED "AS-IS" WITHOUT WARRANTY OF
 ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 PARTICULAR PURPOSE.

 THIS CODE IS NOT SUPPORTED BY MICROSOFT. 

--*/

#include "precomp.h"
#pragma hdrstop

//
// Macros
//
#define MAX_HASH 20

#define CONVERT_WCHAR(ch, n)                                            \
    if(iswdigit((ch)))                                                  \
    {                                                                   \
        (n) = (UCHAR)((ch) - L'0');                                     \
    }                                                                   \
    else if(iswxdigit((ch)))                                            \
    {                                                                   \
        (n) = (UCHAR) ((ch) + 10 - (iswlower((ch))?L'a':L'A'));         \
    }                                                                   \
    else                                                                \
    {                                                                   \
        NlsPutMsg(HTTPCFG_INVALID_HASH, pHash);                         \
        return ERROR_INVALID_PARAMETER;                                 \
    }

//
// Private functions.
//

/***************************************************************************++

Routine Description:
    Prints a record in the SSL store.

Arguments:
    pOutput - A pointer to HTTP_SERVICE_CONFIG_SSL_SET

Return Value:
    None.

--***************************************************************************/
void
PrintSslRecord(
    IN PUCHAR pOutput
    )
{
    DWORD                        i;
    UNICODE_STRING               GuidString;
    WCHAR                        IpAddr[INET6_ADDRSTRLEN];
    DWORD                        dwIpAddrLen = INET6_ADDRSTRLEN;
    DWORD                        dwSockAddrLength;
    PUCHAR                       pStr;
    PSOCKADDR_IN                 pSockAddrIn;
    PHTTP_SERVICE_CONFIG_SSL_SET pSsl;
    DWORD                        Status;

    pSsl = (PHTTP_SERVICE_CONFIG_SSL_SET) pOutput;


    // Convert address to string.
    //

    pSockAddrIn = (PSOCKADDR_IN)  pSsl->KeyDesc.pIpPort;
    if(pSockAddrIn->sin_family == AF_INET)
    {
        dwSockAddrLength = sizeof(SOCKADDR_IN);
    }
    else if(pSockAddrIn->sin_family == AF_INET6)
    {
        dwSockAddrLength = sizeof(SOCKADDR_IN6);
    }
    else
    {
        // Status = ERROR_REGISTRY_CORRUPT;
        return;
    }

    Status = WSAAddressToString(pSsl->KeyDesc.pIpPort,
                       dwSockAddrLength,
                       NULL,
                       IpAddr,
                       &dwIpAddrLen
                       );

    if(NO_ERROR != Status)
    {
        return;
    }

    // Print the Key.
    NlsPutMsg(HTTPCFG_SSL_IP,   IpAddr);

    NlsPutMsg(HTTPCFG_SSL_HASH);

    
    pStr = (PUCHAR) pSsl->ParamDesc.pSslHash;
    for(i=0; i<pSsl->ParamDesc.SslHashLength; i++)
    {
        NlsPutMsg(HTTPCFG_CHAR,  pStr[i]);
    }

    NlsPutMsg(HTTPCFG_NEWLINE);

    Status = RtlStringFromGUID(&pSsl->ParamDesc.AppId, &GuidString);

    if(NO_ERROR != Status)
    {
        return;
    }

    NlsPutMsg(HTTPCFG_SSL_GUID, GuidString.Buffer);

    RtlFreeUnicodeString(&GuidString);

    NlsPutMsg(HTTPCFG_SSL_CERTSTORENAME, 
              pSsl->ParamDesc.pSslCertStoreName
              );

    NlsPutMsg(
              HTTPCFG_SSL_CERTCHECKMODE,   
              pSsl->ParamDesc.DefaultCertCheckMode
              );

    NlsPutMsg(
              HTTPCFG_SSL_REVOCATIONFRESHNESSTIME,   
              pSsl->ParamDesc.DefaultRevocationFreshnessTime
              );

    NlsPutMsg(
              HTTPCFG_SSL_REVOCATIONURLRETRIEVAL_TIMEOUT,   
              pSsl->ParamDesc.DefaultRevocationUrlRetrievalTimeout
              );

    NlsPutMsg(
              HTTPCFG_SSL_SSLCTLIDENTIFIER,   
              pSsl->ParamDesc.pDefaultSslCtlIdentifier
              );

    NlsPutMsg(
              HTTPCFG_SSL_SSLCTLSTORENAME,   
              pSsl->ParamDesc.pDefaultSslCtlStoreName
              );

    NlsPutMsg(
              HTTPCFG_SSL_FLAGS,   
              pSsl->ParamDesc.DefaultFlags
              );

    NlsPutMsg(
              HTTPCFG_RECORD_SEPARATOR   
              );
}

/***************************************************************************++

Routine Description:
    Sets a SSL entry.

Arguments:
    pIP            - The IP address.
    pGuid          - The GUID
    pHash          - Hash of the certificate.
    CertCheckMode  - CertCheckMode (Bit Field).
    Freshness      - DefaultRevocationFreshnessTime (seconds) 
    Timeout        - DefaultRevocationUrlRetrievalTimeout
    Flags          - DefaultFlags.
    pCtlIdentifier - List of issuers that we want to trust.
    pCtlStoreName  - Store name under LOCAL_MACHINE where pCtlIdentifier
                     can be found.
    pCertStoreName - Store name under LOCAL_MACHINE where certificate
                     can be found.
Return Value:
    Success/Failure.

--***************************************************************************/
int
DoSslSet(
    IN  PWCHAR pIp, 
    IN  PWCHAR pGuid, 
    IN  PWCHAR pHash, 
    IN  DWORD  CertCheckMode,
    IN  DWORD  Freshness,
    IN  DWORD  Timeout,
    IN  DWORD  Flags,
    IN  PWCHAR pCtlIdentifier,
    IN  PWCHAR pCtlStoreName,
    IN  PWCHAR pCertStoreName
    )
{
    HTTP_SERVICE_CONFIG_SSL_SET SetParam;
    UNICODE_STRING              GuidString;
    DWORD                       Status;
    SOCKADDR_STORAGE            TempSockAddr;
    USHORT                      HashLength;
    UCHAR                       BinaryHash[MAX_HASH];
    DWORD                       i, j;
    UCHAR                       n1, n2;

    ZeroMemory(&SetParam, sizeof(SetParam));

    SetParam.KeyDesc.pIpPort = (LPSOCKADDR)&TempSockAddr;

    //
    // Convert the string based IP into a SOCKADDR
    //
    if((Status = GetAddress(pIp, 
                            SetParam.KeyDesc.pIpPort,
                            sizeof(TempSockAddr)
                            )) != NO_ERROR)
    {
        NlsPutMsg(HTTPCFG_INVALID_IP, pIp);
        return Status;
    }

    //
    // Convert the string to a GUID.
    //
    if(pGuid)
    {
        GuidString.Length        = (USHORT)wcslen(pGuid) * sizeof(WCHAR);
        GuidString.MaximumLength = (USHORT)GuidString.Length+1;
        GuidString.Buffer        = pGuid;
        Status = RtlGUIDFromString(&GuidString, &SetParam.ParamDesc.AppId);

        if(Status != NO_ERROR)
        {
            NlsPutMsg(HTTPCFG_INVALID_GUID, pGuid);
            return Status;
        }
    }

    if(pHash)
    {
        HashLength = (USHORT) wcslen(pHash);

        for(i=0, j=0; i<MAX_HASH && HashLength >= 2; )
        {
            CONVERT_WCHAR(pHash[j], n1);
            CONVERT_WCHAR(pHash[j+1], n2);

            BinaryHash[i] = ((n1<<4) & 0xF0) | (n2 & 0x0F);

            // We've consumed 2 WCHARs
            HashLength -= 2;
            j += 2;

            // and used up one byte in BinaryHash
            i ++; 
        }

        if(HashLength != 0 || i != MAX_HASH)
        {
            NlsPutMsg(HTTPCFG_INVALID_HASH, pHash);
            return ERROR_INVALID_PARAMETER;
        }

        SetParam.ParamDesc.SslHashLength = i;
        SetParam.ParamDesc.pSslHash      = BinaryHash;
    }

    SetParam.ParamDesc.pSslCertStoreName                    = pCertStoreName;
    SetParam.ParamDesc.pDefaultSslCtlIdentifier             = pCtlIdentifier;
    SetParam.ParamDesc.pDefaultSslCtlStoreName              = pCtlStoreName;
    SetParam.ParamDesc.DefaultCertCheckMode                 = CertCheckMode;
    SetParam.ParamDesc.DefaultRevocationFreshnessTime       = Freshness;
    SetParam.ParamDesc.DefaultRevocationUrlRetrievalTimeout = Timeout;
    SetParam.ParamDesc.DefaultFlags                         = Flags;

    Status = HttpSetServiceConfiguration(
                NULL,
                HttpServiceConfigSSLCertInfo,
                &SetParam,
                sizeof(SetParam),
                NULL
                );

    NlsPutMsg(HTTPCFG_SETSERVICE_STATUS, Status);

    return Status;
}

/***************************************************************************++

Routine Description:
    Queries for a SSL entry.

Arguments:
    pIp - The IP address (if NULL, then enumerate the store).

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?