The protocol engine's server-side code is typically:
HCRYPTPROV hProv = <protocol engine's key container>;
HCRYPTKEY hServerDHKey; // handle to the client's DH key
HCRYPTKEY hMasterKey;
ALG_ID Algid;
PBYTE pbClientPub = <pointer to Client Public Key>;
DWORD cbServerPub = <size of Client Public Key>;
BYTE rgbClientBlob[<max blob size>];
DWORD cbClientBlob = <size of the Client Key blob>;
CRYPT_DATA_BLOB Data;
// Build PUBLICKEYBLOB around the client's public key
{
BLOBHEADER *pBlobHeader = (BLOBHEADER *)rgbClientBlob;
DHPUBKEY *pDHPubKey = (DHPUBKEY *)(pBlobHeader + 1);
BYTE *pData = (BYTE *)(pDHPubKey + 1);
pBlobHeader->bType = PUBLICKEYBLOB;
pBlobHeader->bVersion = CUR_BLOB_VERSION;
pBlobHeader->reserved = 0;
pBlobHeader->aiKeyAlg = CALG_DH_EPHEM;
pDHPubKey->magic = 0x31484400;
pDHPubKey->bitlen = dwClientPub * 8;
ReverseMemCopy(pData, pbClientPub, cbClientPub);
cbClientBlob = sizeof(BLOBHEADER) + sizeof(DHPUBKEY) +
cbClientPub;
}
// import the client's public key and get an agreed key
CryptImportKey(hProv, rgbClientBlob, cbClientBlob, hServerDHKey, 0,
&hMasterKey);
// Select the master key type.
switch(<protocol being used>)
{
case <SSL 3.0>:
Algid = CALG_SSL3_MASTER;
break;
case <TLS 1.0>:
Algid = CALG_TLS1_MASTER;
break;
}
// Convert the agreed key to the appropriate master key
CryptSetKeyParam(hMasterKey, KP_ALGID, (BYTE*)&Algid, 0);