Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The following example shows typical Diffie-Hellman/Schannel client-side code for creating a master key.
//--------------------------------------------------------------------
// Define and initialize local variables.
HCRYPTPROV hProv = <protocol engine's key container>;
HCRYPTKEY hClientDHKey; // handle to the client's DH key
HCRYPTKEY hMasterKey;
ALG_ID Algid;
PBYTE pbServerPub = <pointer to Server Public Key>;
DWORD cbServerPub = <size of Server Public Key>;
BYTE rgbServerBlob[<max BLOB size>];
DWORD cbServerBlob;
PBYTE pbG = <pointer to generator G from Server>;
DWORD cbG = <size of generator G from Server>;
PBYTE pbP = <pointer to prime P from Server>;
DWORD cbP = <size of prime P from Server>;
CRYPT_DATA_BLOB Data;
BYTE rgbClientPubBlob[size of the client public key BLOB];
DWORD cbClientPubBlob;
//--------------------------------------------------------------------
// Generate and set the parameters on the client DH key
// Schannel specifies the key size and [regen flag when generating
// a client DH key.
CryptGenKey(
hProv,
CALG_DH_EPHEM,
((cbP * 8) << 16)|CRYPT_PREGEN,
&hClientDHKey);
Data.pbData = pbP;
Data.cbData = cbP;
CryptSetKeyParam(
hClientDHKey,
KP_P,
(BYTE*)&Data,
0);
Data.pbData = pbG;
Data.cbData = cbG;
CryptSetKeyParam(
hClientDHKey,
KP_G,
(BYTE*)&Data,
0);
//--------------------------------------------------------------------
// Create the client private DH key
CryptSetKeyParam(
hClientDHKey,
KP_X,
NULL,
0);
//--------------------------------------------------------------------
// Build PUBLICKEYBLOB around the server's public key
{
BLOBHEADER *pBlobHeader = (BLOBHEADER *)rgbServerBlob;
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 = dwServerPub * 8;
ReverseMemCopy(pData, pbServerPub, cbServerPub);
cbServerBlob = sizeof(BLOBHEADER) + sizeof(DHPUBKEY) +
cbServerPub;
}
//--------------------------------------------------------------------
// Import the server's public key and get an agreed key
CryptImportKey(
hProv,
rgbServerBlob,
cbServerBlob,
hClientDHKey,
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);
//--------------------------------------------------------------------
// Export the client Diffie-Hellman public key.
cbClientPubBlob = sizeof(rgbClientPubBlob);
CryptExportKey(
hClientDHKey,
0,
PUBLICKEYBLOB,
0,
rgbClientPubBlob,
& cbClientPubBlob);
CryptDestroyKey(hClientDHKey);