The Server Side

The protocol engine's server-side code is typically:

HCRYPTPROV hProv         = <server's key container>;
PBYTE      pbKeyExchange = <pointer to RSA envelope>;
DWORD      dwKeyExchange = <size of RSA envelope>;
HCRYPTKEY  hPublicKey;
HCRYPTKEY  hMasterKey;
ALG_ID     Algid;
DWORD      dwFlags;
BYTE       rgbBlob[<max blob size>];
DWORD      cbBlob;

// Select the master key type.
switch(<protocol being used>)
{
    case <PCT 1.0>:
        Algid = CALG_PCT1_MASTER;
        dwFlags = 0;
        break;

    case <SSL 2.0>:
        Algid = CALG_SSL2_MASTER;
        if(<we support SSL3>)
            dwFlags = CRYPT_SSL2_FALLBACK;
        else
            dwFlags = 0;
        break;

    case <SSL 3.0>:
        Algid = CALG_SSL3_MASTER;
        dwFlags = 0;
        break;

    case <TLS 1.0>:
        Algid = CALG_TLS1_MASTER;
        dwFlags = 0;
        break;
}

// Build SIMPLEBLOB around the RSA envelope.
{
     BLOBHEADER *pBlobHeader = (BLOBHEADER *)rgbBlob;
     ALG_ID     *pAlgid      = (ALG_ID *)(pBlobHeader + 1);
     BYTE       *pData       = (BYTE *)(pAlgid + 1);

     pBlobHeader->bType    = SIMPLEBLOB;
     pBlobHeader->bVersion = CUR_BLOB_VERSION;
     pBlobHeader->reserved = 0;
     pBlobHeader->aiKeyAlg = Algid;

     *pAlgid = CALG_RSA_KEYX;

     ReverseMemCopy(pData, pbKeyExchange, cbKeyExchange);
}

// Decrypt the master key.
CryptGetUserKey(hProv, AT_KEYEXCHANGE, &hPublicKey);
CryptImportKey(hProv, rgbBlob, cbBlob, hPublicKey, 
               dwFlags, &hMasterKey);
CryptDestroyKey(hPublicKey);