Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1497 lines
39 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1999 Microsoft Corporation
  4. //
  5. // File: keypack.c
  6. //
  7. // Contents: Keypack encoding/decoding library
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "precomp.h"
  13. #include <stddef.h>
  14. #include "md5.h"
  15. #include "rc4.h"
  16. #ifdef IGNORE_EXPIRATION
  17. #define LICENSE_EXPIRATION_IGNORE L"SOFTWARE\\Microsoft\\TermServLicensing\\IgnoreLicenseExpiration"
  18. #endif
  19. typedef struct _Enveloped_Data
  20. {
  21. DWORD cbEncryptedKey;
  22. PBYTE pbEncryptedKey;
  23. DWORD cbEncryptedData;
  24. PBYTE pbEncryptedData;
  25. } Enveloped_Data, * PEnveloped_Data;
  26. ///////////////////////////////////////////////////////////////////////////////
  27. //
  28. // Internal functions
  29. //
  30. DWORD WINAPI
  31. VerifyAndGetLicenseKeyPack(
  32. HCRYPTPROV hCryptProv,
  33. PLicense_KeyPack pLicenseKeyPack,
  34. DWORD cbSignerCert,
  35. PBYTE pbSignerCert,
  36. DWORD cbRootCertificate,
  37. PBYTE pbRootCertificate,
  38. DWORD cbSignedBlob,
  39. PBYTE pbSignedBlob
  40. );
  41. DWORD WINAPI
  42. GetCertificate(
  43. DWORD cbCertificateBlob,
  44. PBYTE pbCertificateBlob,
  45. HCRYPTPROV hCryptProv,
  46. PCCERT_CONTEXT * ppCertContext,
  47. HCERTSTORE * phCertStore
  48. );
  49. DWORD WINAPI
  50. VerifyCertificateChain(
  51. HCERTSTORE hCertStore,
  52. PCCERT_CONTEXT pCertContext,
  53. DWORD cbRootCertificate,
  54. PBYTE pbRootCertificate
  55. );
  56. DWORD WINAPI
  57. GetCertVerificationResult(
  58. DWORD dwFlags
  59. );
  60. DWORD WINAPI
  61. UnpackEnvelopedData(
  62. IN OUT PEnveloped_Data pEnvelopedData,
  63. IN DWORD cbPackedData,
  64. IN PBYTE pbPackedData
  65. );
  66. DWORD WINAPI
  67. GetEnvelopedData(
  68. IN DWORD dwEncyptType,
  69. IN HCRYPTPROV hCryptProv,
  70. IN PEnveloped_Data pEnvelopedData,
  71. OUT PDWORD pcbData,
  72. OUT PBYTE *ppbData
  73. );
  74. /////////////////////////////////////////////////////////
  75. DWORD WINAPI
  76. LicensePackEncryptDecryptData(
  77. IN PBYTE pbParm,
  78. IN DWORD cbParm,
  79. IN OUT PBYTE pbData,
  80. IN DWORD cbData
  81. )
  82. /*++
  83. Abstract:
  84. Internal routine to encrypt/decrypt a blob of data
  85. Parameter:
  86. pbParm : binary blob to generate encrypt/decrypt key.
  87. cbParm : size of binary blob.
  88. pbData : data to be encrypt/decrypt.
  89. cbData : size of data to be encrypt/decrypt.
  90. Returns:
  91. ERROR_SUCCESS or error code.
  92. Remark:
  93. --*/
  94. {
  95. DWORD dwRetCode = ERROR_SUCCESS;
  96. MD5_CTX md5Ctx;
  97. RC4_KEYSTRUCT rc4KS;
  98. BYTE key[16];
  99. int i;
  100. if(NULL == pbParm || 0 == cbParm)
  101. {
  102. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  103. return dwRetCode;
  104. }
  105. MD5Init(&md5Ctx);
  106. MD5Update(
  107. &md5Ctx,
  108. pbParm,
  109. cbParm
  110. );
  111. MD5Final(&md5Ctx);
  112. memset(key, 0, sizeof(key));
  113. for(i=0; i < 5; i++)
  114. {
  115. key[i] = md5Ctx.digest[i];
  116. }
  117. //
  118. // Call RC4 to encrypt/decrypt data
  119. //
  120. rc4_key(
  121. &rc4KS,
  122. sizeof(key),
  123. key
  124. );
  125. rc4(
  126. &rc4KS,
  127. cbData,
  128. pbData
  129. );
  130. return dwRetCode;
  131. }
  132. static BYTE rgbPubKeyWithExponentOfOne[] =
  133. {
  134. 0x06, 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00,
  135. 0x52, 0x53, 0x41, 0x31, 0x00, 0x02, 0x00, 0x00,
  136. 0x01, 0x00, 0x00, 0x00,
  137. 0xab, 0xef, 0xfa, 0xc6, 0x7d, 0xe8, 0xde, 0xfb,
  138. 0x68, 0x38, 0x09, 0x92, 0xd9, 0x42, 0x7e, 0x6b,
  139. 0x89, 0x9e, 0x21, 0xd7, 0x52, 0x1c, 0x99, 0x3c,
  140. 0x17, 0x48, 0x4e, 0x3a, 0x44, 0x02, 0xf2, 0xfa,
  141. 0x74, 0x57, 0xda, 0xe4, 0xd3, 0xc0, 0x35, 0x67,
  142. 0xfa, 0x6e, 0xdf, 0x78, 0x4c, 0x75, 0x35, 0x1c,
  143. 0xa0, 0x74, 0x49, 0xe3, 0x20, 0x13, 0x71, 0x35,
  144. 0x65, 0xdf, 0x12, 0x20, 0xf5, 0xf5, 0xf5, 0xc1
  145. };
  146. //---------------------------------------------------------------
  147. BOOL WINAPI
  148. GetPlaintextKey(
  149. IN HCRYPTPROV hProv,
  150. IN HCRYPTKEY hSymKey,
  151. OUT BYTE *pbPlainKey // this must be a 16 byte buffer
  152. )
  153. /*++
  154. part of Jeff Spelman's code
  155. --*/
  156. {
  157. HCRYPTKEY hPubKey = 0;
  158. BYTE rgbSimpleBlob[128];
  159. DWORD cbSimpleBlob;
  160. BYTE *pb;
  161. DWORD i;
  162. BOOL fRet = FALSE;
  163. memset(rgbSimpleBlob, 0, sizeof(rgbSimpleBlob));
  164. if (!CryptImportKey(hProv,
  165. rgbPubKeyWithExponentOfOne,
  166. sizeof(rgbPubKeyWithExponentOfOne),
  167. 0,
  168. 0,
  169. &hPubKey))
  170. {
  171. goto Ret;
  172. }
  173. cbSimpleBlob = sizeof(rgbSimpleBlob);
  174. if (!CryptExportKey(hSymKey,
  175. hPubKey,
  176. SIMPLEBLOB,
  177. 0,
  178. rgbSimpleBlob,
  179. &cbSimpleBlob))
  180. {
  181. goto Ret;
  182. }
  183. memset(pbPlainKey, 0, 16);
  184. pb = rgbSimpleBlob + sizeof(BLOBHEADER) + sizeof(ALG_ID);
  185. // byte reverse the key
  186. for (i = 0; i < 5; i++)
  187. {
  188. pbPlainKey[i] = pb[5 - (i + 1)];
  189. }
  190. fRet = TRUE;
  191. Ret:
  192. if (hPubKey)
  193. {
  194. CryptDestroyKey(hPubKey);
  195. }
  196. return fRet;
  197. }
  198. //--------------------------------------------------------------------
  199. DWORD WINAPI
  200. KeyPackDecryptData(
  201. IN DWORD dwEncryptType,
  202. IN HCRYPTPROV hCryptProv,
  203. IN BYTE* pbEncryptKey,
  204. IN DWORD cbEncryptKey,
  205. IN BYTE* pbEncryptData,
  206. IN DWORD cbEncryptData,
  207. OUT PBYTE* ppbDecryptData,
  208. OUT PDWORD pcbDecryptData
  209. )
  210. /*++
  211. Abstract:
  212. Decrypt a blob of data
  213. Parameters:
  214. bForceCrypto : TRUE if always use Crypto. API, FALSE otherwise.
  215. hCryptProv :
  216. pbEncryptKey :
  217. cbEncryptKey :
  218. pbEncryptData :
  219. cbEncryptData :
  220. ppbDecryptData :
  221. pcbDecryptData :
  222. Returns:
  223. ERROR_SUCCESS or error code.
  224. Remark:
  225. --*/
  226. {
  227. HCRYPTKEY hSymKey = 0;
  228. DWORD dwErrCode = ERROR_SUCCESS;
  229. BYTE rgbPlainKey[16];
  230. RC4_KEYSTRUCT KeyStruct;
  231. BOOL bFrenchLocale;
  232. bFrenchLocale = (MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH) == GetSystemDefaultLangID());
  233. if( (HCRYPTPROV)NULL == hCryptProv || NULL == pbEncryptKey || 0 == cbEncryptKey ||
  234. NULL == pbEncryptData || 0 == cbEncryptData )
  235. {
  236. SetLastError(dwErrCode = ERROR_INVALID_PARAMETER);
  237. return dwErrCode;
  238. }
  239. if( NULL == ppbDecryptData || NULL == pcbDecryptData )
  240. {
  241. SetLastError(dwErrCode = ERROR_INVALID_PARAMETER);
  242. return dwErrCode;
  243. }
  244. *pcbDecryptData = 0;
  245. *ppbDecryptData = NULL;
  246. if(!CryptImportKey(
  247. hCryptProv,
  248. pbEncryptKey,
  249. cbEncryptKey,
  250. 0,
  251. CRYPT_EXPORTABLE,
  252. &hSymKey
  253. ))
  254. {
  255. dwErrCode = GetLastError();
  256. goto cleanup;
  257. }
  258. *pcbDecryptData = cbEncryptData;
  259. *ppbDecryptData = (PBYTE) LocalAlloc(LPTR, cbEncryptData);
  260. if(NULL == *ppbDecryptData)
  261. {
  262. dwErrCode = GetLastError();
  263. goto cleanup;
  264. }
  265. memcpy(
  266. *ppbDecryptData,
  267. pbEncryptData,
  268. *pcbDecryptData
  269. );
  270. if(bFrenchLocale && LICENSE_KEYPACK_ENCRYPT_CRYPTO == dwEncryptType)
  271. {
  272. if(!GetPlaintextKey(
  273. hCryptProv,
  274. hSymKey,
  275. rgbPlainKey))
  276. {
  277. dwErrCode = GetLastError();
  278. goto cleanup;
  279. }
  280. //
  281. // RC4 - input buffer size = output buffer size
  282. //
  283. rc4_key(&KeyStruct, sizeof(rgbPlainKey), rgbPlainKey);
  284. rc4(&KeyStruct, *pcbDecryptData, *ppbDecryptData);
  285. dwErrCode = ERROR_SUCCESS;
  286. }
  287. else
  288. {
  289. if(!CryptDecrypt(hSymKey, 0, TRUE, 0, *ppbDecryptData, pcbDecryptData))
  290. {
  291. dwErrCode = GetLastError();
  292. if(NTE_BAD_LEN == dwErrCode)
  293. {
  294. PBYTE pbNew;
  295. //
  296. // output buffer is too small, re-allocate
  297. //
  298. pbNew = (PBYTE) LocalReAlloc(
  299. *ppbDecryptData,
  300. *pcbDecryptData,
  301. LMEM_ZEROINIT
  302. );
  303. if(NULL == pbNew)
  304. {
  305. dwErrCode = GetLastError();
  306. goto cleanup;
  307. }
  308. *ppbDecryptData = pbNew;
  309. }
  310. memcpy(
  311. *ppbDecryptData,
  312. pbEncryptData,
  313. cbEncryptData
  314. );
  315. if(!CryptDecrypt(hSymKey, 0, TRUE, 0, *ppbDecryptData, pcbDecryptData))
  316. {
  317. dwErrCode = GetLastError();
  318. }
  319. }
  320. }
  321. cleanup:
  322. if (hSymKey)
  323. {
  324. CryptDestroyKey(hSymKey);
  325. }
  326. if(dwErrCode != ERROR_SUCCESS)
  327. {
  328. if(*ppbDecryptData != NULL)
  329. {
  330. LocalFree(*ppbDecryptData);
  331. }
  332. *ppbDecryptData = NULL;
  333. *pcbDecryptData = 0;
  334. }
  335. return dwErrCode;
  336. }
  337. ///////////////////////////////////////////////////////////////////////////////
  338. //
  339. // decode the encrypted license key pack blob with the license server's private
  340. // key.
  341. //
  342. // hCryptProv is opened with the key container that contains the key exchange
  343. // private key.
  344. //
  345. ///////////////////////////////////////////////////////////////////////////////
  346. DWORD WINAPI
  347. DecodeLicenseKeyPackEx(
  348. OUT PLicense_KeyPack pLicenseKeyPack,
  349. IN PLicensePackDecodeParm pDecodeParm,
  350. IN DWORD cbKeyPackBlob,
  351. IN PBYTE pbKeyPackBlob
  352. )
  353. /*++
  354. Abstract:
  355. Decode the encrypted license key pack blob.
  356. Parameters:
  357. pLicenseKeyPack : Decoded license key pack.
  358. hCryptProv :
  359. --*/
  360. {
  361. DWORD dwRetCode = ERROR_SUCCESS;
  362. DWORD cbSignedBlob, cbSignature;
  363. PBYTE pbSignedBlob = NULL, pcbSignature = NULL;
  364. Enveloped_Data EnvelopedData;
  365. PEncodedLicenseKeyPack pEncodedLicensePack;
  366. if( NULL == pLicenseKeyPack || NULL == pDecodeParm ||
  367. NULL == pbKeyPackBlob || 0 == cbKeyPackBlob )
  368. {
  369. return ERROR_INVALID_PARAMETER;
  370. }
  371. if( (HCRYPTPROV)NULL == pDecodeParm->hCryptProv )
  372. {
  373. return ERROR_INVALID_PARAMETER;
  374. }
  375. pEncodedLicensePack = (PEncodedLicenseKeyPack)pbKeyPackBlob;
  376. if(pEncodedLicensePack->dwSignature != LICENSEPACKENCODE_SIGNATURE)
  377. {
  378. //
  379. // EncodedLicenseKeyPack() puts size of encryption key as first DWORD
  380. //
  381. dwRetCode = DecodeLicenseKeyPack(
  382. pLicenseKeyPack,
  383. pDecodeParm->hCryptProv,
  384. pDecodeParm->cbClearingHouseCert,
  385. pDecodeParm->pbClearingHouseCert,
  386. pDecodeParm->cbRootCertificate,
  387. pDecodeParm->pbRootCertificate,
  388. cbKeyPackBlob,
  389. pbKeyPackBlob
  390. );
  391. return dwRetCode;
  392. }
  393. if(pEncodedLicensePack->dwStructVersion > LICENSEPACKENCODE_CURRENTVERSION)
  394. {
  395. return ERROR_INVALID_DATA;
  396. }
  397. if( pEncodedLicensePack->dwEncodeType > LICENSE_KEYPACK_ENCRYPT_MAX )
  398. {
  399. return ERROR_INVALID_DATA;
  400. }
  401. if( cbKeyPackBlob != offsetof(EncodedLicenseKeyPack, pbData) + pEncodedLicensePack->cbData )
  402. {
  403. return ERROR_INVALID_DATA;
  404. }
  405. //
  406. // check input parameters
  407. //
  408. if( 0 == pDecodeParm->cbClearingHouseCert ||
  409. NULL == pDecodeParm->pbClearingHouseCert ||
  410. 0 == pDecodeParm->cbRootCertificate ||
  411. NULL == pDecodeParm->pbRootCertificate )
  412. {
  413. return ERROR_INVALID_PARAMETER;
  414. }
  415. //
  416. // Get the enveloped data
  417. //
  418. memset(
  419. &EnvelopedData,
  420. 0,
  421. sizeof( Enveloped_Data )
  422. );
  423. dwRetCode = UnpackEnvelopedData(
  424. &EnvelopedData,
  425. pEncodedLicensePack->cbData,
  426. &(pEncodedLicensePack->pbData[0])
  427. );
  428. if( ERROR_SUCCESS != dwRetCode )
  429. {
  430. goto done;
  431. }
  432. switch( pEncodedLicensePack->dwEncodeType )
  433. {
  434. case LICENSE_KEYPACK_ENCRYPT_CRYPTO:
  435. case LICENSE_KEYPACK_ENCRYPT_ALWAYSCRYPTO:
  436. //
  437. // unpack the enveloped data to get the signed keypack blob
  438. //
  439. dwRetCode = GetEnvelopedData(
  440. pEncodedLicensePack->dwEncodeType,
  441. pDecodeParm->hCryptProv,
  442. &EnvelopedData,
  443. &cbSignedBlob,
  444. &pbSignedBlob
  445. );
  446. break;
  447. default:
  448. // impossible to come here
  449. dwRetCode = ERROR_INVALID_DATA;
  450. }
  451. if( ERROR_SUCCESS != dwRetCode )
  452. {
  453. goto done;
  454. }
  455. //
  456. // Get the license keypack from the signed blob. We also provide the
  457. // clearing house certificate to verify the authenticity of the keypack.
  458. //
  459. dwRetCode = VerifyAndGetLicenseKeyPack(
  460. pDecodeParm->hCryptProv,
  461. pLicenseKeyPack,
  462. pDecodeParm->cbClearingHouseCert,
  463. pDecodeParm->pbClearingHouseCert,
  464. pDecodeParm->cbRootCertificate,
  465. pDecodeParm->pbRootCertificate,
  466. cbSignedBlob,
  467. pbSignedBlob
  468. );
  469. done:
  470. if( EnvelopedData.pbEncryptedKey )
  471. {
  472. LocalFree( EnvelopedData.pbEncryptedKey );
  473. }
  474. if( EnvelopedData.pbEncryptedData )
  475. {
  476. LocalFree( EnvelopedData.pbEncryptedData );
  477. }
  478. if( pbSignedBlob )
  479. {
  480. LocalFree( pbSignedBlob );
  481. }
  482. return( dwRetCode );
  483. }
  484. ///////////////////////////////////////////////////////////////////////////////
  485. DWORD WINAPI
  486. GetEnvelopedData(
  487. IN DWORD dwEncryptType,
  488. IN HCRYPTPROV hCryptProv,
  489. IN PEnveloped_Data pEnvelopedData,
  490. OUT PDWORD pcbData,
  491. OUT PBYTE *ppbData
  492. )
  493. /*++
  494. --*/
  495. {
  496. HCRYPTKEY hPrivateKey = 0;
  497. DWORD dwRetCode = ERROR_SUCCESS;
  498. if( (HCRYPTPROV)NULL == hCryptProv || pEnvelopedData == NULL ||
  499. ppbData == NULL || pcbData == NULL )
  500. {
  501. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  502. return dwRetCode;
  503. }
  504. //
  505. // Make sure we have a exchange key to decrypt session key.
  506. //
  507. if( !CryptGetUserKey( hCryptProv, AT_KEYEXCHANGE, &hPrivateKey ) )
  508. {
  509. dwRetCode = GetLastError();
  510. goto done;
  511. }
  512. //
  513. // decrypt the data, KeyPackDecryptData() handle
  514. // memory freeing in case of error.
  515. //
  516. dwRetCode = KeyPackDecryptData(
  517. dwEncryptType,
  518. hCryptProv,
  519. pEnvelopedData->pbEncryptedKey,
  520. pEnvelopedData->cbEncryptedKey,
  521. pEnvelopedData->pbEncryptedData,
  522. pEnvelopedData->cbEncryptedData,
  523. ppbData,
  524. pcbData
  525. );
  526. done:
  527. if( hPrivateKey )
  528. {
  529. CryptDestroyKey( hPrivateKey );
  530. }
  531. return( dwRetCode );
  532. }
  533. ///////////////////////////////////////////////////////////////////////////////
  534. DWORD WINAPI
  535. UnpackEnvelopedData(
  536. IN OUT PEnveloped_Data pEnvelopedData,
  537. IN DWORD cbPackedData,
  538. IN PBYTE pbPackedData
  539. )
  540. /*++
  541. Abstract:
  542. Unpack an encrypted license pack blob.
  543. Parameters:
  544. pEnvelopedData :
  545. cbPackedData :
  546. pbPackedData :
  547. Returns:
  548. --*/
  549. {
  550. PBYTE pbCopyPos = pbPackedData;
  551. DWORD cbDataToUnpack = cbPackedData;
  552. //
  553. // ensure that the data is of minimum length
  554. //
  555. if( ( ( sizeof( DWORD ) * 2 ) > cbPackedData ) ||
  556. ( NULL == pbPackedData ) ||
  557. ( NULL == pEnvelopedData ) )
  558. {
  559. return( ERROR_INVALID_PARAMETER );
  560. }
  561. //
  562. // read a DWORD to get the encrypted key length
  563. //
  564. memcpy( &pEnvelopedData->cbEncryptedKey, pbCopyPos, sizeof( DWORD ) );
  565. pbCopyPos += sizeof( DWORD );
  566. cbDataToUnpack -= sizeof( DWORD );
  567. if( cbDataToUnpack < pEnvelopedData->cbEncryptedKey )
  568. {
  569. return( ERROR_INVALID_DATA );
  570. }
  571. //
  572. // Allocate memory to unpack the encrypted key
  573. //
  574. if(pEnvelopedData->cbEncryptedKey > 0)
  575. {
  576. pEnvelopedData->pbEncryptedKey = LocalAlloc( GPTR, pEnvelopedData->cbEncryptedKey );
  577. if( NULL == pEnvelopedData->pbEncryptedKey )
  578. {
  579. return( GetLastError() );
  580. }
  581. memcpy( pEnvelopedData->pbEncryptedKey, pbCopyPos, pEnvelopedData->cbEncryptedKey );
  582. }
  583. pbCopyPos += pEnvelopedData->cbEncryptedKey;
  584. cbDataToUnpack -= pEnvelopedData->cbEncryptedKey;
  585. //
  586. // expecting to read a DWORD for the encrypted data length
  587. //
  588. if( sizeof( DWORD ) > cbDataToUnpack )
  589. {
  590. return( ERROR_INVALID_DATA );
  591. }
  592. memcpy( &pEnvelopedData->cbEncryptedData, pbCopyPos, sizeof( DWORD ) );
  593. pbCopyPos += sizeof( DWORD );
  594. cbDataToUnpack -= sizeof( DWORD );
  595. if( cbDataToUnpack < pEnvelopedData->cbEncryptedData )
  596. {
  597. return( ERROR_INVALID_DATA );
  598. }
  599. //
  600. // allocate memory for the encrypted data
  601. //
  602. pEnvelopedData->pbEncryptedData = LocalAlloc( GPTR, pEnvelopedData->cbEncryptedData );
  603. if( NULL == pEnvelopedData->pbEncryptedData )
  604. {
  605. return( GetLastError() );
  606. }
  607. memcpy( pEnvelopedData->pbEncryptedData, pbCopyPos, pEnvelopedData->cbEncryptedData );
  608. return( ERROR_SUCCESS );
  609. }
  610. ///////////////////////////////////////////////////////////////////////////////
  611. //
  612. // decode the encrypted license key pack blob with the license server's private
  613. // key.
  614. //
  615. // hCryptProv is opened with the key container that contains the key exchange
  616. // private key.
  617. //
  618. ///////////////////////////////////////////////////////////////////////////////
  619. DWORD WINAPI
  620. DecodeLicenseKeyPack(
  621. PLicense_KeyPack pLicenseKeyPack,
  622. HCRYPTPROV hCryptProv,
  623. DWORD cbClearingHouseCert,
  624. PBYTE pbClearingHouseCert,
  625. DWORD cbRootCertificate,
  626. PBYTE pbRootCertificate,
  627. DWORD cbKeyPackBlob,
  628. PBYTE pbKeyPackBlob )
  629. {
  630. DWORD dwRetCode = ERROR_SUCCESS;
  631. DWORD cbSignedBlob, cbSignature;
  632. PBYTE pbSignedBlob = NULL, pcbSignature = NULL;
  633. Enveloped_Data EnvelopedData;
  634. if( 0 == hCryptProv )
  635. {
  636. return( ERROR_INVALID_PARAMETER );
  637. }
  638. //
  639. // Get the enveloped data
  640. //
  641. memset( &EnvelopedData, 0, sizeof( Enveloped_Data ) );
  642. dwRetCode = UnpackEnvelopedData( &EnvelopedData, cbKeyPackBlob, pbKeyPackBlob );
  643. if( ERROR_SUCCESS != dwRetCode )
  644. {
  645. goto done;
  646. }
  647. //
  648. // unpack the enveloped data to get the signed keypack blob
  649. //
  650. dwRetCode = GetEnvelopedData(
  651. LICENSE_KEYPACK_ENCRYPT_CRYPTO,
  652. hCryptProv,
  653. &EnvelopedData,
  654. &cbSignedBlob,
  655. &pbSignedBlob
  656. );
  657. if( ERROR_SUCCESS != dwRetCode )
  658. {
  659. goto done;
  660. }
  661. //
  662. // Get the license keypack from the signed blob. We also provide the
  663. // clearing house certificate to verify the authenticity of the keypack.
  664. //
  665. dwRetCode = VerifyAndGetLicenseKeyPack( hCryptProv, pLicenseKeyPack,
  666. cbClearingHouseCert, pbClearingHouseCert,
  667. cbRootCertificate, pbRootCertificate,
  668. cbSignedBlob, pbSignedBlob );
  669. done:
  670. if( EnvelopedData.pbEncryptedKey )
  671. {
  672. LocalFree( EnvelopedData.pbEncryptedKey );
  673. }
  674. if( EnvelopedData.pbEncryptedData )
  675. {
  676. LocalFree( EnvelopedData.pbEncryptedData );
  677. }
  678. if( pbSignedBlob )
  679. {
  680. LocalFree( pbSignedBlob );
  681. }
  682. return( dwRetCode );
  683. }
  684. ///////////////////////////////////////////////////////////////////////////////
  685. DWORD WINAPI
  686. VerifyAndGetLicenseKeyPack(
  687. HCRYPTPROV hCryptProv,
  688. PLicense_KeyPack pLicenseKeyPack,
  689. DWORD cbSignerCert,
  690. PBYTE pbSignerCert,
  691. DWORD cbRootCertificate,
  692. PBYTE pbRootCertificate,
  693. DWORD cbSignedBlob,
  694. PBYTE pbSignedBlob )
  695. {
  696. DWORD dwRetCode = ERROR_SUCCESS;
  697. PCCERT_CONTEXT pCertContext = 0;
  698. HCERTSTORE hCertStore = 0;
  699. HCRYPTHASH hCryptHash = 0;
  700. HCRYPTKEY hPubKey = 0;
  701. PBYTE pbCopyPos = pbSignedBlob, pbSignedHash;
  702. PKeyPack_Description pKpDesc;
  703. DWORD i, cbSignedHash, cbRequired = 0;
  704. SetLastError(ERROR_SUCCESS);
  705. //
  706. // make sure that the signed key blob is of the minimum size
  707. //
  708. cbRequired = ( 10 * sizeof( DWORD ) ) + ( 3 * sizeof( FILETIME ) ) +
  709. sizeof( GUID ) ;
  710. if( cbSignedBlob < cbRequired )
  711. {
  712. return( ERROR_INVALID_PARAMETER );
  713. }
  714. //
  715. // get a certificate context for the signer's certificate
  716. //
  717. dwRetCode = GetCertificate( cbSignerCert,
  718. pbSignerCert,
  719. hCryptProv,
  720. &pCertContext,
  721. &hCertStore );
  722. if( ERROR_SUCCESS != dwRetCode )
  723. {
  724. SetLastError(dwRetCode);
  725. goto ErrorReturn;
  726. }
  727. //
  728. // Verify the signer's certificate and the certificate chain that issued the
  729. // certificate.
  730. //
  731. dwRetCode = VerifyCertificateChain( hCertStore, pCertContext,
  732. cbRootCertificate, pbRootCertificate );
  733. if( ERROR_SUCCESS != dwRetCode )
  734. {
  735. SetLastError(dwRetCode);
  736. goto ErrorReturn;
  737. }
  738. //
  739. // unpack the signed blob
  740. //
  741. memcpy( &pLicenseKeyPack->dwVersion, pbCopyPos, sizeof( DWORD ) );
  742. pbCopyPos += sizeof( DWORD );
  743. memcpy( &pLicenseKeyPack->dwKeypackType, pbCopyPos, sizeof( DWORD ) );
  744. pbCopyPos += sizeof( DWORD );
  745. memcpy( &pLicenseKeyPack->dwDistChannel, pbCopyPos, sizeof( DWORD ) );
  746. pbCopyPos += sizeof( DWORD );
  747. memcpy( &pLicenseKeyPack->KeypackSerialNum, pbCopyPos, sizeof( GUID ) );
  748. pbCopyPos += sizeof( GUID );
  749. memcpy( &pLicenseKeyPack->IssueDate, pbCopyPos, sizeof( FILETIME ) );
  750. pbCopyPos += sizeof( FILETIME );
  751. memcpy( &pLicenseKeyPack->ActiveDate, pbCopyPos, sizeof( FILETIME ) );
  752. pbCopyPos += sizeof( FILETIME );
  753. memcpy( &pLicenseKeyPack->ExpireDate, pbCopyPos, sizeof( FILETIME ) );
  754. pbCopyPos += sizeof( FILETIME );
  755. memcpy( &pLicenseKeyPack->dwBeginSerialNum, pbCopyPos, sizeof( DWORD ) );
  756. pbCopyPos += sizeof( DWORD );
  757. memcpy( &pLicenseKeyPack->dwQuantity, pbCopyPos, sizeof( DWORD ) );
  758. pbCopyPos += sizeof( DWORD );
  759. memcpy( &pLicenseKeyPack->cbProductId, pbCopyPos, sizeof( DWORD ) );
  760. pbCopyPos += sizeof( DWORD );
  761. if( pLicenseKeyPack->cbProductId )
  762. {
  763. cbRequired += pLicenseKeyPack->cbProductId;
  764. if( cbSignedBlob < cbRequired )
  765. {
  766. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  767. goto ErrorReturn;
  768. }
  769. pLicenseKeyPack->pbProductId = LocalAlloc( GPTR, pLicenseKeyPack->cbProductId );
  770. if( NULL == pLicenseKeyPack->pbProductId )
  771. {
  772. goto ErrorReturn;
  773. }
  774. memcpy( pLicenseKeyPack->pbProductId, pbCopyPos, pLicenseKeyPack->cbProductId );
  775. pbCopyPos += pLicenseKeyPack->cbProductId;
  776. }
  777. memcpy( &pLicenseKeyPack->dwProductVersion, pbCopyPos, sizeof( DWORD ) );
  778. pbCopyPos += sizeof( DWORD );
  779. memcpy( &pLicenseKeyPack->dwPlatformId, pbCopyPos, sizeof( DWORD ) );
  780. pbCopyPos += sizeof( DWORD );
  781. memcpy( &pLicenseKeyPack->dwLicenseType, pbCopyPos, sizeof( DWORD ) );
  782. pbCopyPos += sizeof( DWORD );
  783. memcpy( &pLicenseKeyPack->dwDescriptionCount, pbCopyPos, sizeof( DWORD ) );
  784. pbCopyPos += sizeof( DWORD );
  785. if( pLicenseKeyPack->dwDescriptionCount )
  786. {
  787. //
  788. // allocate memory for the keypack descriptions structure
  789. //
  790. pLicenseKeyPack->pDescription = LocalAlloc( GPTR, ( sizeof( KeyPack_Description ) *
  791. pLicenseKeyPack->dwDescriptionCount ) );
  792. if( NULL == pLicenseKeyPack->pDescription )
  793. {
  794. goto ErrorReturn;
  795. }
  796. for( i = 0, pKpDesc = pLicenseKeyPack->pDescription;
  797. i < pLicenseKeyPack->dwDescriptionCount;
  798. i++, pKpDesc++ )
  799. {
  800. cbRequired += ( sizeof( LCID ) + 2* (sizeof( DWORD ) ));
  801. if( cbSignedBlob < cbRequired)
  802. {
  803. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  804. goto ErrorReturn;
  805. }
  806. memcpy( &pKpDesc->Locale, pbCopyPos, sizeof( LCID ) );
  807. pbCopyPos += sizeof( LCID );
  808. memcpy( &pKpDesc->cbProductName, pbCopyPos, sizeof( DWORD ) );
  809. pbCopyPos += sizeof( DWORD );
  810. if( pKpDesc->cbProductName )
  811. {
  812. //
  813. // allocate memory for product name
  814. //
  815. cbRequired += (pKpDesc->cbProductName);
  816. if( cbSignedBlob < cbRequired)
  817. {
  818. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  819. goto ErrorReturn;
  820. }
  821. pKpDesc->pbProductName = LocalAlloc( GPTR, pKpDesc->cbProductName );
  822. if( NULL == pKpDesc->pbProductName )
  823. {
  824. goto ErrorReturn;
  825. }
  826. //
  827. // copy the product name
  828. //
  829. memcpy( pKpDesc->pbProductName, pbCopyPos, pKpDesc->cbProductName );
  830. pbCopyPos += pKpDesc->cbProductName;
  831. }
  832. memcpy( &pKpDesc->cbDescription, pbCopyPos, sizeof( DWORD ) );
  833. pbCopyPos += sizeof( DWORD );
  834. if( pKpDesc->cbDescription )
  835. {
  836. //
  837. // allocate memory for the keypack description
  838. //
  839. cbRequired += (pKpDesc->cbDescription);
  840. if( cbSignedBlob < cbRequired)
  841. {
  842. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  843. goto ErrorReturn;
  844. }
  845. pKpDesc->pDescription = LocalAlloc( GPTR, pKpDesc->cbDescription );
  846. if( NULL == pKpDesc->pDescription )
  847. {
  848. goto ErrorReturn;
  849. }
  850. //
  851. // copy the key pack description
  852. //
  853. memcpy( pKpDesc->pDescription, pbCopyPos, pKpDesc->cbDescription );
  854. pbCopyPos += pKpDesc->cbDescription;
  855. }
  856. }
  857. }
  858. cbRequired += ( 3 * sizeof( DWORD ));
  859. if( cbSignedBlob < cbRequired)
  860. {
  861. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  862. goto ErrorReturn;
  863. }
  864. memcpy( &pLicenseKeyPack->cbManufacturer, pbCopyPos, sizeof( DWORD ) );
  865. pbCopyPos += sizeof( DWORD );
  866. if( pLicenseKeyPack->cbManufacturer )
  867. {
  868. cbRequired += (pLicenseKeyPack->cbManufacturer);
  869. if( cbSignedBlob < cbRequired)
  870. {
  871. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  872. goto ErrorReturn;
  873. }
  874. pLicenseKeyPack->pbManufacturer = LocalAlloc( GPTR, pLicenseKeyPack->cbManufacturer );
  875. if( NULL == pLicenseKeyPack->pbManufacturer )
  876. {
  877. goto ErrorReturn;
  878. }
  879. memcpy( pLicenseKeyPack->pbManufacturer, pbCopyPos, pLicenseKeyPack->cbManufacturer );
  880. pbCopyPos += pLicenseKeyPack->cbManufacturer;
  881. }
  882. memcpy( &pLicenseKeyPack->cbManufacturerData, pbCopyPos, sizeof( DWORD ) );
  883. pbCopyPos += sizeof( DWORD );
  884. if( pLicenseKeyPack->cbManufacturerData )
  885. {
  886. cbRequired += (pLicenseKeyPack->cbManufacturerData);
  887. if( cbSignedBlob < cbRequired)
  888. {
  889. SetLastError(dwRetCode = ERROR_INVALID_PARAMETER);
  890. goto ErrorReturn;
  891. }
  892. pLicenseKeyPack->pbManufacturerData = LocalAlloc( GPTR, pLicenseKeyPack->cbManufacturerData );
  893. if( NULL == pLicenseKeyPack->pbManufacturerData )
  894. {
  895. goto ErrorReturn;
  896. }
  897. memcpy( pLicenseKeyPack->pbManufacturerData, pbCopyPos, pLicenseKeyPack->cbManufacturerData );
  898. pbCopyPos += pLicenseKeyPack->cbManufacturerData;
  899. }
  900. //
  901. // get the size and the pointer of the signed hash.
  902. //
  903. memcpy( &cbSignedHash, pbCopyPos, sizeof( DWORD ) );
  904. pbSignedHash = pbCopyPos + sizeof( DWORD );
  905. //
  906. // compute the hash
  907. //
  908. if( !CryptCreateHash( hCryptProv, CALG_MD5, 0, 0, &hCryptHash ) )
  909. {
  910. goto ErrorReturn;
  911. }
  912. if( !CryptHashData( hCryptHash, pbSignedBlob, (DWORD)(pbCopyPos - pbSignedBlob), 0 ) )
  913. {
  914. goto ErrorReturn;
  915. }
  916. //
  917. // import the public key
  918. //
  919. if( !CryptImportPublicKeyInfoEx( hCryptProv, X509_ASN_ENCODING,
  920. &pCertContext->pCertInfo->SubjectPublicKeyInfo,
  921. CALG_RSA_SIGN, 0, NULL, &hPubKey ) )
  922. {
  923. goto ErrorReturn;
  924. }
  925. //
  926. // use the public key to verify the signed hash
  927. //
  928. if( !CryptVerifySignature( hCryptHash, pbSignedHash, cbSignedHash, hPubKey,
  929. NULL, 0) )
  930. {
  931. goto ErrorReturn;
  932. }
  933. ErrorReturn:
  934. dwRetCode = GetLastError();
  935. if( hCryptHash )
  936. {
  937. CryptDestroyHash( hCryptHash );
  938. }
  939. if( hPubKey )
  940. {
  941. CryptDestroyKey( hPubKey );
  942. }
  943. if( pCertContext )
  944. {
  945. CertFreeCertificateContext( pCertContext );
  946. }
  947. if( hCertStore )
  948. {
  949. CertCloseStore( hCertStore, CERT_CLOSE_STORE_FORCE_FLAG );
  950. }
  951. return( dwRetCode );
  952. }
  953. ///////////////////////////////////////////////////////////////////////////////
  954. //
  955. // GetCertificate
  956. //
  957. // Get the first certificate from the certificate blob. The certificate blob
  958. // is in fact a certificate store that may contain a chain of certificates.
  959. // This function also return handles to the crypto provider and the certificate
  960. // store.
  961. //
  962. ///////////////////////////////////////////////////////////////////////////////
  963. DWORD WINAPI
  964. GetCertificate(
  965. DWORD cbCertificateBlob,
  966. PBYTE pbCertificateBlob,
  967. HCRYPTPROV hCryptProv,
  968. PCCERT_CONTEXT * ppCertContext,
  969. HCERTSTORE * phCertStore )
  970. {
  971. CRYPT_DATA_BLOB CertBlob;
  972. DWORD dwRetCode = ERROR_SUCCESS;
  973. //
  974. // Open the PKCS7 certificate store
  975. //
  976. CertBlob.cbData = cbCertificateBlob;
  977. CertBlob.pbData = pbCertificateBlob;
  978. *phCertStore = CertOpenStore( sz_CERT_STORE_PROV_PKCS7,
  979. PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
  980. hCryptProv,
  981. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  982. &CertBlob );
  983. if( NULL == ( *phCertStore ) )
  984. {
  985. return( GetLastError() );
  986. }
  987. //
  988. // get the first certificate from the store
  989. //
  990. *ppCertContext = CertEnumCertificatesInStore( *phCertStore, NULL );
  991. if( NULL == ( *ppCertContext ) )
  992. {
  993. return( GetLastError() );
  994. }
  995. return( dwRetCode );
  996. }
  997. ///////////////////////////////////////////////////////////////////////////////
  998. //
  999. // VerifyCertificateChain
  1000. //
  1001. // Verify the certificate represented by the cert context against the
  1002. // issuers in the certificate store. The caller may provide a root
  1003. // certificate so that all issuers are eventually verified against this
  1004. // root certificate. If no root certificate is provided, then the last
  1005. // issuer in the chain must be a self-signing issuer.
  1006. //
  1007. ///////////////////////////////////////////////////////////////////////////////
  1008. DWORD WINAPI
  1009. VerifyCertificateChain(
  1010. HCERTSTORE hCertStore,
  1011. PCCERT_CONTEXT pCertContext,
  1012. DWORD cbRootCertificate,
  1013. PBYTE pbRootCertificate )
  1014. {
  1015. DWORD dwRetCode = ERROR_SUCCESS, dwFlags;
  1016. PCCERT_CONTEXT pRootCertCtx = NULL;
  1017. PCCERT_CONTEXT pIssuerCertCtx = NULL;
  1018. PCCERT_CONTEXT pCurrentContext = NULL;
  1019. #ifdef IGNORE_EXPIRATION
  1020. LONG lRet;
  1021. HKEY hKey = NULL;
  1022. #endif
  1023. if( ( 0 != cbRootCertificate ) && ( NULL != pbRootCertificate ) )
  1024. {
  1025. //
  1026. // Get a certificate context for the root certificate
  1027. //
  1028. pRootCertCtx = CertCreateCertificateContext( X509_ASN_ENCODING,
  1029. pbRootCertificate,
  1030. cbRootCertificate );
  1031. if( NULL == pRootCertCtx )
  1032. {
  1033. dwRetCode = GetLastError();
  1034. goto done;
  1035. }
  1036. }
  1037. //
  1038. // Verify the certificate chain. The time, signature and validity of
  1039. // the subject certificate is verified. Only the signatures are verified
  1040. // for the certificates in the issuer chain.
  1041. //
  1042. #ifdef IGNORE_EXPIRATION
  1043. //Verify if registry key exists and ignore time check
  1044. lRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1045. LICENSE_EXPIRATION_IGNORE ,
  1046. 0,
  1047. KEY_READ ,
  1048. &hKey );
  1049. if( ERROR_SUCCESS == lRet )
  1050. {
  1051. dwFlags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG;
  1052. }
  1053. else
  1054. {
  1055. #endif
  1056. dwFlags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG |
  1057. CERT_STORE_TIME_VALIDITY_FLAG;
  1058. #ifdef IGNORE_EXPIRATION
  1059. }
  1060. if(hKey)
  1061. {
  1062. RegCloseKey(hKey);
  1063. }
  1064. #endif
  1065. pCurrentContext = CertDuplicateCertificateContext( pCertContext );
  1066. if (NULL == pCurrentContext)
  1067. {
  1068. dwRetCode = ERROR_INVALID_PARAMETER;
  1069. goto done;
  1070. }
  1071. do
  1072. {
  1073. pIssuerCertCtx = NULL;
  1074. pIssuerCertCtx = CertGetIssuerCertificateFromStore( hCertStore,
  1075. pCurrentContext,
  1076. pIssuerCertCtx,
  1077. &dwFlags );
  1078. if( pIssuerCertCtx )
  1079. {
  1080. //
  1081. // Found the issuer, verify that the checks went OK
  1082. //
  1083. dwRetCode = GetCertVerificationResult( dwFlags );
  1084. if( ERROR_SUCCESS != dwRetCode )
  1085. {
  1086. break;
  1087. }
  1088. //
  1089. // only verify the signature for subsequent issuer certificates
  1090. //
  1091. dwFlags = CERT_STORE_SIGNATURE_FLAG;
  1092. //
  1093. // free the current certificate context and make the current issuer certificate
  1094. // the subject certificate for the next iteration.
  1095. //
  1096. CertFreeCertificateContext( pCurrentContext );
  1097. pCurrentContext = pIssuerCertCtx;
  1098. }
  1099. } while( pIssuerCertCtx );
  1100. if( ERROR_SUCCESS != dwRetCode )
  1101. {
  1102. //
  1103. // encountered some error while verifying the certificate
  1104. //
  1105. goto done;
  1106. }
  1107. //
  1108. // we got here because we have walked through the chain of issuers in the
  1109. // store. The last issuer in the chain may or may not be a self signing root.
  1110. //
  1111. if( pRootCertCtx )
  1112. {
  1113. //
  1114. // The caller has specified a root certificate that must be used. Verify the
  1115. // last issuer against this root certificate regardless of whether it is a
  1116. // self signing root.
  1117. //
  1118. dwFlags = CERT_STORE_REVOCATION_FLAG | CERT_STORE_SIGNATURE_FLAG |
  1119. CERT_STORE_TIME_VALIDITY_FLAG;
  1120. if( ( NULL == pCurrentContext ) ||
  1121. ( !CertVerifySubjectCertificateContext( pCurrentContext, pRootCertCtx, &dwFlags ) ) )
  1122. {
  1123. dwRetCode = GetLastError();
  1124. goto done;
  1125. }
  1126. //
  1127. // get the certificate verification result
  1128. //
  1129. dwRetCode = GetCertVerificationResult( dwFlags );
  1130. }
  1131. else
  1132. {
  1133. //
  1134. // if the caller did not specify a CA root certificate, make sure that the root
  1135. // issuer of the certificate is a self-signed root. Otherwise, return an error
  1136. //
  1137. if( CRYPT_E_SELF_SIGNED != GetLastError() )
  1138. {
  1139. dwRetCode = GetLastError();
  1140. }
  1141. }
  1142. done:
  1143. if( pRootCertCtx )
  1144. {
  1145. CertFreeCertificateContext( pRootCertCtx );
  1146. }
  1147. if( pCurrentContext )
  1148. {
  1149. CertFreeCertificateContext( pCurrentContext );
  1150. }
  1151. if( pIssuerCertCtx )
  1152. {
  1153. CertFreeCertificateContext( pIssuerCertCtx );
  1154. }
  1155. return( dwRetCode );
  1156. }
  1157. ///////////////////////////////////////////////////////////////////////////////
  1158. DWORD WINAPI
  1159. GetCertVerificationResult(
  1160. DWORD dwFlags )
  1161. {
  1162. if( dwFlags & CERT_STORE_SIGNATURE_FLAG )
  1163. {
  1164. //
  1165. // The certificate signature did not verify
  1166. //
  1167. return( (DWORD )NTE_BAD_SIGNATURE );
  1168. }
  1169. if( dwFlags & CERT_STORE_TIME_VALIDITY_FLAG )
  1170. {
  1171. //
  1172. // The certificate has expired
  1173. //
  1174. return( ( DWORD )CERT_E_EXPIRED );
  1175. }
  1176. //
  1177. // check if the cert has been revoked
  1178. //
  1179. if( dwFlags & CERT_STORE_REVOCATION_FLAG )
  1180. {
  1181. if( !( dwFlags & CERT_STORE_NO_CRL_FLAG ) )
  1182. {
  1183. //
  1184. // The certificate has been revoked
  1185. //
  1186. return( ( DWORD )CERT_E_REVOKED );
  1187. }
  1188. }
  1189. return( ERROR_SUCCESS );
  1190. }