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.

1785 lines
51 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Copyright (c) 1997-1999 Microsoft Corporation
  4. //
  5. // File: gencert.cpp
  6. //
  7. // Contents:
  8. //
  9. // History:
  10. //
  11. //---------------------------------------------------------------------------
  12. #include "pch.cpp"
  13. #include "misc.h"
  14. #include "utils.h"
  15. #include "gencert.h"
  16. #include "globals.h"
  17. #ifndef UNICODE
  18. const DWORD dwCertRdnValueType = CERT_RDN_PRINTABLE_STRING;
  19. #else
  20. const DWORD dwCertRdnValueType = CERT_RDN_UNICODE_STRING;
  21. #endif
  22. #ifndef CertStrToName
  23. //
  24. // Function prototype not found in wincrypt.h or anywhere but
  25. // is in crypt32.lib
  26. //
  27. #ifdef __cplusplus
  28. extern "C" {
  29. #endif
  30. BOOL WINAPI
  31. CertStrToNameA(
  32. DWORD dwCertEncodingType, // in
  33. LPCSTR pszX500, // in
  34. DWORD dwStrType, // in
  35. void* pvReserved, // in, optional
  36. BYTE* pbEncoded, // out
  37. DWORD* pcbEncoded, // in/out
  38. LPCSTR* ppszError // out, optional
  39. );
  40. CertStrToNameW(
  41. DWORD dwCertEncodingType, // in
  42. LPCWSTR pszX500, // in
  43. DWORD dwStrType, // in
  44. void* pvReserved, // in, optional
  45. BYTE* pbEncoded, // out
  46. DWORD* pcbEncoded, // in/out
  47. LPCWSTR* ppszError // out, optional
  48. );
  49. #ifdef UNICODE
  50. #define CertStrToName CertStrToNameW
  51. #else
  52. #define CertStrToName CertStrToNameA
  53. #endif
  54. #ifdef __cplusplus
  55. }
  56. #endif
  57. #endif
  58. /*******************************************************************************************
  59. Function:
  60. LSEncryptBase64EncodeHWID()
  61. Description:
  62. Encrypt using license server private key then base64 encode the hardware ID
  63. Arguments:
  64. IN PHWID - pointer to HWID to be encrypt/encoded
  65. OUT DWORD* cbBase64EncodeHwid - size of pointer to encrypted/encoded string
  66. OUT PBYTE* szBase64EncodeHwid - Pointer to encrypted/encoded string.
  67. Returns:
  68. TRUE if successful, FALSE otherwise, call GetLastError() for detail.
  69. *******************************************************************************************/
  70. BOOL
  71. TLSEncryptBase64EncodeHWID(
  72. PHWID pHwid,
  73. DWORD* cbBase64EncodeHwid,
  74. PBYTE* szBase64EncodeHwid
  75. )
  76. {
  77. DWORD status=ERROR_SUCCESS;
  78. //
  79. // Encrypt HWID
  80. //
  81. BYTE tmp_pbEncryptedHwid[sizeof(HWID)*2+2];
  82. DWORD tmp_cbEncryptedHwid=sizeof(tmp_pbEncryptedHwid);
  83. do {
  84. memset(tmp_pbEncryptedHwid, 0, sizeof(tmp_pbEncryptedHwid));
  85. if((status=LicenseEncryptHwid(
  86. pHwid,
  87. &tmp_cbEncryptedHwid,
  88. tmp_pbEncryptedHwid,
  89. g_cbSecretKey,
  90. g_pbSecretKey) != LICENSE_STATUS_OK))
  91. {
  92. break;
  93. }
  94. //
  95. // BASE64 Encode Encrypted HWID - printable char. string
  96. //
  97. if((status=LSBase64Encode(
  98. tmp_pbEncryptedHwid,
  99. tmp_cbEncryptedHwid,
  100. NULL,
  101. cbBase64EncodeHwid)) != ERROR_SUCCESS)
  102. {
  103. break;
  104. }
  105. *szBase64EncodeHwid=(PBYTE)AllocateMemory(*cbBase64EncodeHwid*(sizeof(TCHAR)+1));
  106. if(*szBase64EncodeHwid == NULL)
  107. {
  108. SetLastError(status = ERROR_OUTOFMEMORY);
  109. break;
  110. }
  111. // base64 encoding
  112. status=LSBase64Encode(
  113. tmp_pbEncryptedHwid,
  114. tmp_cbEncryptedHwid,
  115. (TCHAR *)*szBase64EncodeHwid,
  116. cbBase64EncodeHwid);
  117. } while(FALSE);
  118. return status == ERROR_SUCCESS;
  119. }
  120. /*******************************************************************************************/
  121. DWORD
  122. TLSAddCertAuthorityInfoAccess(
  123. LPTSTR szIssuerDnsName,
  124. PCERT_EXTENSION pExtension
  125. )
  126. /*
  127. */
  128. {
  129. LSCERT_AUTHORITY_INFO_ACCESS certInfoAccess;
  130. LSCERT_ACCESS_DESCRIPTION certAcccessDesc;
  131. certAcccessDesc.pszAccessMethod=szOID_X509_ACCESS_PKIX_OCSP;
  132. certAcccessDesc.AccessLocation.dwAltNameChoice = LSCERT_ALT_NAME_DNS_NAME;
  133. certAcccessDesc.AccessLocation.pwszDNSName = szIssuerDnsName;
  134. certInfoAccess.cAccDescr = 1;
  135. certInfoAccess.rgAccDescr = &certAcccessDesc;
  136. pExtension->pszObjId = szOID_X509_AUTHORITY_ACCESS_INFO;
  137. pExtension->fCritical = TRUE;
  138. return TLSCryptEncodeObject(
  139. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  140. szOID_X509_AUTHORITY_ACCESS_INFO,
  141. &certInfoAccess,
  142. &pExtension->Value.pbData,
  143. &pExtension->Value.cbData
  144. );
  145. }
  146. ///////////////////////////////////////////////////////////////////////////////
  147. DWORD
  148. TLSAddCertAuthorityKeyIdExtension(
  149. LPTSTR szIssuer,
  150. ULARGE_INTEGER* CertSerialNumber,
  151. PCERT_EXTENSION pExtension
  152. )
  153. /*
  154. */
  155. {
  156. //
  157. // Use CERT_AUTHORITY_KEY_ID2_INFO
  158. // some structure not defined in SP3's wincrypt.h
  159. //
  160. LSCERT_ALT_NAME_ENTRY certAltNameEntry;
  161. LSCERT_AUTHORITY_KEY_ID2_INFO authKeyId2Info;
  162. memset(&authKeyId2Info, 0, sizeof(authKeyId2Info));
  163. authKeyId2Info.AuthorityCertSerialNumber.cbData = sizeof(ULARGE_INTEGER);
  164. authKeyId2Info.AuthorityCertSerialNumber.pbData = (PBYTE)CertSerialNumber;
  165. memset(&certAltNameEntry, 0, sizeof(certAltNameEntry));
  166. certAltNameEntry.dwAltNameChoice=CERT_ALT_NAME_DIRECTORY_NAME; //LSCERT_ALT_NAME_RFC822_NAME;
  167. certAltNameEntry.DirectoryName.cbData = (_tcslen(szIssuer) + 1) * sizeof(TCHAR);
  168. certAltNameEntry.DirectoryName.pbData = (PBYTE)szIssuer;
  169. authKeyId2Info.AuthorityCertIssuer.cAltEntry=1;
  170. authKeyId2Info.AuthorityCertIssuer.rgAltEntry=&certAltNameEntry;
  171. pExtension->pszObjId = szOID_X509_AUTHORITY_KEY_ID2;
  172. pExtension->fCritical = TRUE;
  173. return TLSCryptEncodeObject(
  174. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  175. szOID_X509_AUTHORITY_KEY_ID2,
  176. &authKeyId2Info,
  177. &pExtension->Value.pbData,
  178. &pExtension->Value.cbData
  179. );
  180. }
  181. ///////////////////////////////////////////////////////////////////////////////
  182. DWORD
  183. TLSExportPublicKey(
  184. IN HCRYPTPROV hCryptProv,
  185. IN DWORD dwKeyType,
  186. IN OUT PDWORD pcbByte,
  187. IN OUT PCERT_PUBLIC_KEY_INFO *ppbByte
  188. )
  189. /*
  190. */
  191. {
  192. BOOL bRetCode=TRUE;
  193. *pcbByte=0;
  194. *ppbByte=NULL;
  195. bRetCode = CryptExportPublicKeyInfo(
  196. hCryptProv,
  197. dwKeyType,
  198. X509_ASN_ENCODING,
  199. NULL,
  200. pcbByte);
  201. if(bRetCode == FALSE)
  202. goto cleanup;
  203. if((*ppbByte=(PCERT_PUBLIC_KEY_INFO)AllocateMemory(*pcbByte)) == NULL)
  204. {
  205. bRetCode = FALSE;
  206. goto cleanup;
  207. }
  208. bRetCode = CryptExportPublicKeyInfo(
  209. hCryptProv,
  210. dwKeyType,
  211. X509_ASN_ENCODING,
  212. *ppbByte,
  213. pcbByte);
  214. if(bRetCode == FALSE)
  215. {
  216. FreeMemory(*ppbByte);
  217. *pcbByte = 0;
  218. }
  219. cleanup:
  220. return (bRetCode) ? ERROR_SUCCESS : GetLastError();
  221. }
  222. ///////////////////////////////////////////////////////////////////////////////
  223. DWORD
  224. TLSCryptEncodeObject(
  225. IN DWORD dwEncodingType,
  226. IN LPCSTR lpszStructType,
  227. IN const void * pvStructInfo,
  228. OUT PBYTE* ppbEncoded,
  229. OUT DWORD* pcbEncoded
  230. )
  231. /*
  232. Description:
  233. Allocate memory and encode object, wrapper for CryptEncodeObject()
  234. */
  235. {
  236. DWORD dwStatus = ERROR_SUCCESS;
  237. if(!CryptEncodeObject(dwEncodingType, lpszStructType, pvStructInfo, NULL, pcbEncoded) ||
  238. (*ppbEncoded=(PBYTE)AllocateMemory(*pcbEncoded)) == NULL ||
  239. !CryptEncodeObject(dwEncodingType, lpszStructType, pvStructInfo, *ppbEncoded, pcbEncoded))
  240. {
  241. dwStatus=GetLastError();
  242. }
  243. return dwStatus;
  244. }
  245. //////////////////////////////////////////////////////////////////////
  246. DWORD
  247. TLSCryptSignAndEncodeCertificate(
  248. IN HCRYPTPROV hCryptProv,
  249. IN DWORD dwKeySpec,
  250. IN PCERT_INFO pCertInfo,
  251. IN PCRYPT_ALGORITHM_IDENTIFIER pSignatureAlgorithm,
  252. IN OUT PBYTE* ppbEncodedCert,
  253. IN OUT PDWORD pcbEncodedCert
  254. )
  255. /*
  256. */
  257. {
  258. BOOL bRetCode;
  259. bRetCode = CryptSignAndEncodeCertificate(
  260. hCryptProv,
  261. dwKeySpec,
  262. X509_ASN_ENCODING,
  263. X509_CERT_TO_BE_SIGNED,
  264. pCertInfo,
  265. pSignatureAlgorithm,
  266. NULL,
  267. NULL,
  268. pcbEncodedCert);
  269. if(bRetCode == FALSE && GetLastError() != ERROR_MORE_DATA)
  270. goto cleanup;
  271. *ppbEncodedCert=(PBYTE)AllocateMemory(*pcbEncodedCert);
  272. if(*ppbEncodedCert == FALSE)
  273. goto cleanup;
  274. bRetCode = CryptSignAndEncodeCertificate(
  275. hCryptProv,
  276. AT_SIGNATURE,
  277. X509_ASN_ENCODING,
  278. X509_CERT_TO_BE_SIGNED,
  279. pCertInfo,
  280. pSignatureAlgorithm,
  281. NULL,
  282. *ppbEncodedCert,
  283. pcbEncodedCert);
  284. if(bRetCode == FALSE)
  285. {
  286. FreeMemory(*ppbEncodedCert);
  287. *pcbEncodedCert = 0;
  288. }
  289. cleanup:
  290. return (bRetCode) ? ERROR_SUCCESS : GetLastError();
  291. }
  292. ////////////////////////////////////////////////////////////////////////
  293. #define MAX_NUM_CERT_BLOBS 200 // actually, we can't go over 10.
  294. DWORD
  295. TLSVerifyProprietyChainedCertificate(
  296. HCRYPTPROV hCryptProv,
  297. PBYTE pbCert,
  298. DWORD cbCert
  299. )
  300. /*++
  301. --*/
  302. {
  303. DWORD dwStatus=ERROR_SUCCESS, cbRequired = 0;
  304. PCert_Chain pCertChain = (PCert_Chain)pbCert;
  305. UNALIGNED Cert_Blob *pCertificate = NULL;
  306. PCCERT_CONTEXT pIssuerCert = NULL;
  307. PCCERT_CONTEXT pSubjectCert = NULL;
  308. DWORD dwVerifyFlag = CERT_DATE_DONT_VALIDATE;
  309. int i;
  310. cbRequired = 2 * sizeof(DWORD);
  311. if( pCertChain == NULL || ( cbCert < cbRequired ) ||
  312. MAX_CERT_CHAIN_VERSION < GET_CERTIFICATE_VERSION(pCertChain->dwVersion) ||
  313. pCertChain->dwNumCertBlobs > MAX_NUM_CERT_BLOBS ||
  314. pCertChain->dwNumCertBlobs <= 1 ) // must have at least two certificates
  315. {
  316. SetLastError(dwStatus = TLS_E_INVALID_DATA);
  317. return dwStatus;
  318. }
  319. //
  320. // Verify input data before actually allocate memory
  321. //
  322. pCertificate = (PCert_Blob)&(pCertChain->CertBlob[0]);
  323. for(i=0; i < pCertChain->dwNumCertBlobs; i++)
  324. {
  325. cbRequired += (sizeof (DWORD)+ sizeof(BYTE)) ;
  326. if(cbCert < cbRequired )
  327. {
  328. SetLastError(dwStatus = TLS_E_INVALID_DATA);
  329. return dwStatus;
  330. }
  331. if (((PBYTE)pCertificate > (cbCert + pbCert - sizeof(Cert_Blob))) ||
  332. (pCertificate->cbCert == 0) ||
  333. (pCertificate->cbCert > (DWORD)((pbCert + cbCert) - pCertificate->abCert)))
  334. {
  335. return (LICENSE_STATUS_INVALID_INPUT);
  336. }
  337. pCertificate = (PCert_Blob)(pCertificate->abCert + pCertificate->cbCert);
  338. }
  339. //
  340. // First certificate is root certificate
  341. //
  342. pCertificate = (PCert_Blob)&(pCertChain->CertBlob[0]);
  343. pIssuerCert = CertCreateCertificateContext(
  344. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  345. &(pCertificate->abCert[0]),
  346. pCertificate->cbCert
  347. );
  348. if(pIssuerCert == NULL)
  349. {
  350. dwStatus = GetLastError(); // just for debugging.
  351. goto cleanup;
  352. }
  353. dwStatus = ERROR_SUCCESS;
  354. pSubjectCert = CertDuplicateCertificateContext(pIssuerCert);
  355. for(i=0; i < pCertChain->dwNumCertBlobs; i++)
  356. {
  357. if(pSubjectCert == NULL)
  358. {
  359. dwStatus = GetLastError();
  360. break;
  361. }
  362. //
  363. // verify subject's certificate
  364. dwVerifyFlag = CERT_STORE_SIGNATURE_FLAG;
  365. if(CertVerifySubjectCertificateContext(
  366. pSubjectCert,
  367. pIssuerCert,
  368. &dwVerifyFlag
  369. ) == FALSE)
  370. {
  371. dwStatus = GetLastError();
  372. break;
  373. }
  374. if(dwVerifyFlag != 0)
  375. {
  376. // signature verification failed.
  377. dwStatus = TLS_E_INVALID_DATA;
  378. break;
  379. }
  380. if(CertFreeCertificateContext(pIssuerCert) == FALSE)
  381. {
  382. dwStatus = GetLastError();
  383. break;
  384. }
  385. pIssuerCert = pSubjectCert;
  386. pCertificate = (PCert_Blob)(pCertificate->abCert + pCertificate->cbCert);
  387. pSubjectCert = CertCreateCertificateContext(
  388. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  389. &(pCertificate->abCert[0]),
  390. pCertificate->cbCert
  391. );
  392. }
  393. cleanup:
  394. if(pSubjectCert != NULL)
  395. {
  396. CertFreeCertificateContext(pSubjectCert);
  397. }
  398. if(pIssuerCert != NULL)
  399. {
  400. CertFreeCertificateContext(pIssuerCert);
  401. }
  402. return dwStatus;
  403. }
  404. ////////////////////////////////////////////////////////////////////////
  405. BOOL IsHydraClientCertficate( PCERT_INFO pCertInfo )
  406. {
  407. CERT_EXTENSION UNALIGNED * pCertExtension=pCertInfo->rgExtension;
  408. DWORD dwVersion = TERMSERV_CERT_VERSION_UNKNOWN;
  409. DWORD UNALIGNED * pdwVersion;
  410. for(DWORD i=0; i < pCertInfo->cExtension; i++, pCertExtension++)
  411. {
  412. if(strcmp(pCertExtension->pszObjId, szOID_PKIX_HYDRA_CERT_VERSION) == 0)
  413. {
  414. pdwVersion = (DWORD UNALIGNED *) pCertExtension->Value.pbData;
  415. if(pCertExtension->Value.cbData == sizeof(DWORD) &&
  416. *pdwVersion <= TERMSERV_CERT_VERSION_CURRENT)
  417. {
  418. dwVersion = *pdwVersion;
  419. break;
  420. }
  421. }
  422. }
  423. return (dwVersion == TERMSERV_CERT_VERSION_UNKNOWN) ? FALSE : TRUE;
  424. }
  425. ////////////////////////////////////////////////////////////////////////
  426. DWORD
  427. ChainProprietyCert(
  428. HCRYPTPROV hCryptProv,
  429. HCERTSTORE hCertStore,
  430. PCCERT_CONTEXT pCertContext,
  431. PCert_Chain pCertChain,
  432. DWORD* dwCertOffset,
  433. DWORD dwBufSize)
  434. {
  435. DWORD dwStatus = ERROR_SUCCESS;
  436. DWORD dwFlags;
  437. PCCERT_CONTEXT pCertIssuer=NULL;
  438. pCertIssuer=NULL;
  439. dwFlags = CERT_STORE_SIGNATURE_FLAG;
  440. //
  441. // Get the issuer's certificate from store
  442. //
  443. pCertIssuer = CertGetIssuerCertificateFromStore(
  444. hCertStore,
  445. pCertContext,
  446. pCertIssuer,
  447. &dwFlags
  448. );
  449. if(pCertIssuer != NULL)
  450. {
  451. if(dwFlags & CERT_STORE_SIGNATURE_FLAG)
  452. {
  453. // invalid signature
  454. dwStatus = TLS_E_INVALID_DATA;
  455. }
  456. else
  457. {
  458. //
  459. // Recursively find the issuer of the issuer's certificate
  460. //
  461. dwStatus = ChainProprietyCert(
  462. hCryptProv,
  463. hCertStore,
  464. pCertIssuer,
  465. pCertChain,
  466. dwCertOffset,
  467. dwBufSize
  468. );
  469. }
  470. }
  471. else
  472. {
  473. dwStatus = GetLastError();
  474. if(dwStatus != CRYPT_E_SELF_SIGNED)
  475. {
  476. goto cleanup;
  477. }
  478. //
  479. // Verify issuer's certificate
  480. //
  481. if(CryptVerifyCertificateSignature(
  482. hCryptProv,
  483. X509_ASN_ENCODING,
  484. pCertContext->pbCertEncoded,
  485. pCertContext->cbCertEncoded,
  486. &pCertContext->pCertInfo->SubjectPublicKeyInfo))
  487. {
  488. dwStatus=ERROR_SUCCESS;
  489. }
  490. }
  491. if(dwStatus == ERROR_SUCCESS)
  492. {
  493. //
  494. // Push certificate into propriety certificate chain
  495. //
  496. if((*dwCertOffset + pCertContext->cbCertEncoded) >= dwBufSize)
  497. {
  498. dwStatus = ERROR_MORE_DATA;
  499. goto cleanup;
  500. }
  501. (pCertChain->dwNumCertBlobs)++;
  502. UNALIGNED Cert_Blob *pCertBlob = (PCert_Blob)((PBYTE)&(pCertChain->CertBlob) + *dwCertOffset);
  503. pCertBlob->cbCert = pCertContext->cbCertEncoded;
  504. memcpy( &(pCertBlob->abCert),
  505. pCertContext->pbCertEncoded,
  506. pCertContext->cbCertEncoded);
  507. *dwCertOffset += (sizeof(pCertBlob->cbCert) + pCertContext->cbCertEncoded);
  508. }
  509. cleanup:
  510. if(pCertIssuer != NULL)
  511. {
  512. CertFreeCertificateContext(pCertIssuer);
  513. }
  514. return dwStatus;
  515. }
  516. ////////////////////////////////////////////////////////////////////////
  517. DWORD
  518. TLSChainProprietyCertificate(
  519. HCRYPTPROV hCryptProv,
  520. BOOL bTemp,
  521. PBYTE pbLicense,
  522. DWORD cbLicense,
  523. PBYTE* pbChained,
  524. DWORD* cbChained
  525. )
  526. {
  527. HCERTSTORE hCertStore=NULL;
  528. DWORD dwStatus=ERROR_SUCCESS;
  529. CRYPT_DATA_BLOB Serialized;
  530. PCCERT_CONTEXT pCertContext=NULL;
  531. PCCERT_CONTEXT pPrevCertContext=NULL;
  532. PCERT_INFO pCertInfo;
  533. BOOL bFound=FALSE;
  534. Serialized.pbData = pbLicense;
  535. Serialized.cbData = cbLicense;
  536. DWORD dwCertOffset = 0;
  537. PCert_Chain pCertChain;
  538. DWORD numCerts=0;
  539. DWORD cbSize=0;
  540. if(hCryptProv == NULL)
  541. {
  542. SetLastError(dwStatus = ERROR_INVALID_PARAMETER);
  543. goto cleanup;
  544. }
  545. hCertStore=CertOpenStore(
  546. sz_CERT_STORE_PROV_PKCS7,
  547. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  548. hCryptProv,
  549. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  550. &Serialized
  551. );
  552. if(!hCertStore)
  553. {
  554. dwStatus=GetLastError();
  555. goto cleanup;
  556. }
  557. //
  558. // Get number of certificate and estimated size first - save memory
  559. //
  560. do {
  561. pCertContext = CertEnumCertificatesInStore(
  562. hCertStore,
  563. pPrevCertContext
  564. );
  565. if(pCertContext == NULL)
  566. {
  567. dwStatus = GetLastError();
  568. if(dwStatus != CRYPT_E_NOT_FOUND)
  569. goto cleanup;
  570. dwStatus = ERROR_SUCCESS;
  571. break;
  572. }
  573. numCerts++;
  574. cbSize += pCertContext->cbCertEncoded;
  575. pPrevCertContext = pCertContext;
  576. } while(TRUE);
  577. *cbChained = cbSize + numCerts * sizeof(Cert_Blob) + sizeof(Cert_Chain);
  578. //
  579. // Allocate memory for our propriety certificate chain
  580. //
  581. pCertChain=(PCert_Chain)LocalAlloc(LPTR, *cbChained);
  582. if(pCertChain == NULL)
  583. {
  584. dwStatus = GetLastError();
  585. goto cleanup;
  586. }
  587. pCertChain->dwVersion = CERT_CHAIN_VERSION_2 | ((bTemp) ? 0x80000000 : 0);
  588. //
  589. // Enumerate license in certificate to find actual client license.
  590. //
  591. pPrevCertContext = NULL;
  592. do {
  593. pCertContext=CertEnumCertificatesInStore(hCertStore, pPrevCertContext);
  594. if(pCertContext == NULL)
  595. {
  596. // end certificate in store or error
  597. if((dwStatus=GetLastError()) != CRYPT_E_NOT_FOUND)
  598. goto cleanup;
  599. dwStatus = ERROR_SUCCESS;
  600. break;
  601. }
  602. pPrevCertContext = pCertContext;
  603. if(IsHydraClientCertficate(pCertContext->pCertInfo))
  604. {
  605. bFound = TRUE;
  606. }
  607. } while(bFound == FALSE);
  608. if(bFound == FALSE)
  609. {
  610. dwStatus = ERROR_INVALID_PARAMETER;
  611. goto cleanup;
  612. }
  613. //
  614. // Recusively chain certificate in backward.
  615. //
  616. dwStatus = ChainProprietyCert(
  617. hCryptProv,
  618. hCertStore,
  619. pCertContext,
  620. pCertChain,
  621. &dwCertOffset,
  622. *cbChained);
  623. *pbChained = (PBYTE)pCertChain;
  624. cleanup:
  625. if(hCertStore)
  626. CertCloseStore(hCertStore, CERT_CLOSE_STORE_FORCE_FLAG);
  627. return dwStatus;
  628. }
  629. ///////////////////////////////////////////////////////////////////////////////
  630. DWORD
  631. TLSCertSetCertRdnStr(
  632. IN OUT CERT_NAME_BLOB* pCertNameBlob,
  633. IN LPTSTR szRdn
  634. )
  635. /*
  636. Abstract:
  637. Add RDN into certificate
  638. Parameter:
  639. pCertNameBlob -
  640. szRdn - RDN to be added, see CertStrToName() for help
  641. Returns:
  642. ERROR_INVALID_PARAMETER
  643. Memory allocation failed.
  644. Error returns from CertStrToName()
  645. */
  646. {
  647. if(pCertNameBlob == NULL)
  648. return ERROR_INVALID_PARAMETER;
  649. BOOL bRetCode=TRUE;
  650. bRetCode = CertStrToName(
  651. X509_ASN_ENCODING,
  652. szRdn,
  653. CERT_X500_NAME_STR | CERT_SIMPLE_NAME_STR,
  654. NULL,
  655. pCertNameBlob->pbData,
  656. &pCertNameBlob->cbData,
  657. NULL
  658. );
  659. if(bRetCode != TRUE)
  660. goto cleanup;
  661. pCertNameBlob->pbData = (PBYTE)AllocateMemory(pCertNameBlob->cbData);
  662. if(pCertNameBlob->pbData == NULL)
  663. goto cleanup;
  664. bRetCode = CertStrToName(
  665. X509_ASN_ENCODING,
  666. szRdn,
  667. CERT_X500_NAME_STR | CERT_SIMPLE_NAME_STR,
  668. NULL,
  669. pCertNameBlob->pbData,
  670. &pCertNameBlob->cbData,
  671. NULL
  672. );
  673. cleanup:
  674. return (bRetCode) ? ERROR_SUCCESS : GetLastError();
  675. }
  676. ///////////////////////////////////////////////////////////////////////////////
  677. DWORD
  678. TLSCertSetCertRdnName(
  679. IN OUT CERT_NAME_BLOB* pCertNameBlob,
  680. IN CERT_NAME_INFO* pRdn
  681. )
  682. /*
  683. Abstract:
  684. Add RDN into certificate
  685. Parameters:
  686. pCertNameBlob -
  687. pRdn -
  688. Returns
  689. ERROR_INVALID_PARAMETER
  690. Error code from CryptEncodeObject()
  691. Memory allocation fail.
  692. */
  693. {
  694. if(pCertNameBlob == NULL || pRdn == NULL)
  695. return ERROR_INVALID_PARAMETER;
  696. //
  697. // CertStrToName() not defined in SP3 build environment
  698. //
  699. return TLSCryptEncodeObject(
  700. CRYPT_ASN_ENCODING,
  701. X509_NAME,
  702. pRdn,
  703. &pCertNameBlob->pbData,
  704. &pCertNameBlob->cbData
  705. );
  706. }
  707. //////////////////////////////////////////////////////////////////////////
  708. DWORD
  709. TLSSetCertRdn(
  710. PCERT_NAME_BLOB pCertNameBlob,
  711. PTLSClientCertRDN pLsCertRdn
  712. )
  713. /*
  714. */
  715. {
  716. DWORD dwStatus=ERROR_SUCCESS;
  717. switch(pLsCertRdn->type)
  718. {
  719. case LSCERT_RDN_STRING_TYPE:
  720. dwStatus = TLSCertSetCertRdnStr(
  721. pCertNameBlob,
  722. pLsCertRdn->szRdn
  723. );
  724. break;
  725. case LSCERT_RDN_NAME_INFO_TYPE:
  726. dwStatus = TLSCertSetCertRdnName(
  727. pCertNameBlob,
  728. pLsCertRdn->pCertNameInfo
  729. );
  730. break;
  731. case LSCERT_RDN_NAME_BLOB_TYPE:
  732. *pCertNameBlob = *pLsCertRdn->pNameBlob;
  733. break;
  734. case LSCERT_CLIENT_INFO_TYPE:
  735. {
  736. PBYTE szBase64EncodeHwid=NULL;
  737. DWORD cbBase64EncodeHwid=0;
  738. if(!TLSEncryptBase64EncodeHWID(
  739. pLsCertRdn->ClientInfo.pClientID,
  740. &cbBase64EncodeHwid,
  741. &szBase64EncodeHwid))
  742. {
  743. TLSLogEvent(
  744. EVENTLOG_ERROR_TYPE,
  745. TLS_E_GENERATECLIENTELICENSE,
  746. dwStatus=TLS_E_ENCRYPTHWID,
  747. GetLastError()
  748. );
  749. break;
  750. }
  751. CERT_RDN_ATTR rgNameAttr[] = {
  752. {
  753. OID_SUBJECT_CLIENT_COMPUTERNAME,
  754. dwCertRdnValueType,
  755. _tcslen(pLsCertRdn->ClientInfo.szMachineName) * sizeof(TCHAR),
  756. (UCHAR *)pLsCertRdn->ClientInfo.szMachineName
  757. },
  758. {
  759. OID_SUBJECT_CLIENT_USERNAME,
  760. dwCertRdnValueType,
  761. _tcslen(pLsCertRdn->ClientInfo.szUserName) * sizeof(TCHAR),
  762. (UCHAR *)pLsCertRdn->ClientInfo.szUserName
  763. },
  764. {
  765. OID_SUBJECT_CLIENT_HWID,
  766. dwCertRdnValueType,
  767. cbBase64EncodeHwid*sizeof(TCHAR),
  768. (UCHAR *)szBase64EncodeHwid
  769. }
  770. };
  771. CERT_RDN rgRDN[] = {
  772. sizeof(rgNameAttr)/sizeof(rgNameAttr[0]),
  773. &rgNameAttr[0]
  774. };
  775. CERT_NAME_INFO Name = {1, rgRDN};
  776. dwStatus = TLSCertSetCertRdnName(
  777. pCertNameBlob,
  778. &Name
  779. );
  780. FreeMemory(szBase64EncodeHwid);
  781. }
  782. break;
  783. default:
  784. dwStatus = ERROR_INVALID_PARAMETER;
  785. }
  786. return dwStatus;
  787. }
  788. //////////////////////////////////////////////////////////////////////////
  789. DWORD
  790. TLSGenerateCertificate(
  791. HCRYPTPROV hCryptProv,
  792. DWORD dwKeySpec,
  793. ULARGE_INTEGER* pCertSerialNumber,
  794. PTLSClientCertRDN pCertIssuer,
  795. PTLSClientCertRDN pCertSubject,
  796. FILETIME* ftNotBefore,
  797. FILETIME* ftNotAfter,
  798. PCERT_PUBLIC_KEY_INFO pSubjectPublicKey,
  799. DWORD dwNumExtensions,
  800. PCERT_EXTENSION pCertExtensions,
  801. PDWORD pcbEncodedCert,
  802. PBYTE* ppbEncodedCert
  803. )
  804. /*
  805. */
  806. {
  807. DWORD dwStatus=ERROR_SUCCESS;
  808. CRYPT_ALGORITHM_IDENTIFIER SignatureAlgorithm={ szOID_OIWSEC_sha1RSASign, 0, 0 };
  809. CERT_INFO CertInfo;
  810. PCERT_PUBLIC_KEY_INFO pbPublicKeyInfo=NULL;
  811. DWORD cbPublicKeyInfo=0;
  812. memset(&CertInfo, 0, sizeof(CERT_INFO));
  813. CertInfo.dwVersion = CERT_V3;
  814. CertInfo.SerialNumber.cbData = sizeof(*pCertSerialNumber);
  815. CertInfo.SerialNumber.pbData = (PBYTE)pCertSerialNumber;
  816. CertInfo.SignatureAlgorithm = SignatureAlgorithm;
  817. dwStatus = TLSSetCertRdn(
  818. &CertInfo.Issuer,
  819. pCertIssuer
  820. );
  821. if(dwStatus != ERROR_SUCCESS)
  822. {
  823. TLSLogEvent(
  824. EVENTLOG_ERROR_TYPE,
  825. TLS_E_GENERATECLIENTELICENSE,
  826. TLS_E_SETCERTISSUER,
  827. dwStatus
  828. );
  829. goto cleanup;
  830. }
  831. CertInfo.NotBefore = *ftNotBefore;
  832. CertInfo.NotAfter = *ftNotAfter;
  833. dwStatus = TLSSetCertRdn(
  834. &CertInfo.Subject,
  835. pCertSubject
  836. );
  837. if(dwStatus != ERROR_SUCCESS)
  838. {
  839. TLSLogEvent(
  840. EVENTLOG_ERROR_TYPE,
  841. TLS_E_GENERATECLIENTELICENSE,
  842. TLS_E_SETCERTSUBJECT,
  843. dwStatus
  844. );
  845. goto cleanup;
  846. }
  847. if(pSubjectPublicKey)
  848. {
  849. CertInfo.SubjectPublicKeyInfo = *pSubjectPublicKey;
  850. }
  851. else
  852. {
  853. dwStatus = TLSExportPublicKey(
  854. hCryptProv,
  855. dwKeySpec,
  856. &cbPublicKeyInfo,
  857. &pbPublicKeyInfo
  858. );
  859. if(dwStatus != ERROR_SUCCESS)
  860. {
  861. TLSLogEvent(
  862. EVENTLOG_ERROR_TYPE,
  863. TLS_E_GENERATECLIENTELICENSE,
  864. TLS_E_EXPORT_KEY,
  865. dwStatus
  866. );
  867. goto cleanup;
  868. }
  869. CertInfo.SubjectPublicKeyInfo = *pbPublicKeyInfo;
  870. }
  871. CertInfo.cExtension = dwNumExtensions;
  872. CertInfo.rgExtension = pCertExtensions;
  873. dwStatus = TLSCryptSignAndEncodeCertificate(
  874. hCryptProv,
  875. dwKeySpec,
  876. &CertInfo,
  877. &SignatureAlgorithm,
  878. ppbEncodedCert,
  879. pcbEncodedCert
  880. );
  881. if(dwStatus != ERROR_SUCCESS)
  882. {
  883. TLSLogEvent(
  884. EVENTLOG_ERROR_TYPE,
  885. TLS_E_GENERATECLIENTELICENSE,
  886. TLS_E_SIGNENCODECERT,
  887. dwStatus
  888. );
  889. }
  890. cleanup:
  891. if(pbPublicKeyInfo)
  892. {
  893. FreeMemory(pbPublicKeyInfo);
  894. }
  895. if(pCertIssuer->type != LSCERT_RDN_NAME_BLOB_TYPE)
  896. {
  897. FreeMemory(CertInfo.Issuer.pbData);
  898. }
  899. if(pCertSubject->type != LSCERT_RDN_NAME_BLOB_TYPE)
  900. {
  901. FreeMemory(CertInfo.Subject.pbData);
  902. }
  903. return dwStatus;
  904. }
  905. //////////////////////////////////////////////////////////////////////
  906. DWORD
  907. TLSCreateSelfSignCertificate(
  908. IN HCRYPTPROV hCryptProv,
  909. IN DWORD dwKeySpec,
  910. IN PBYTE pbSPK,
  911. IN DWORD cbSPK,
  912. IN DWORD dwNumExtensions,
  913. IN PCERT_EXTENSION pCertExtension,
  914. OUT PDWORD cbEncoded,
  915. OUT PBYTE* pbEncoded
  916. )
  917. /*
  918. */
  919. {
  920. DWORD dwStatus=ERROR_SUCCESS;
  921. DWORD index;
  922. #define MAX_EXTENSIONS_IN_SELFSIGN 40
  923. SYSTEMTIME sysTime;
  924. FILETIME ftTime;
  925. CERT_EXTENSION rgExtension[MAX_EXTENSIONS_IN_SELFSIGN];
  926. int iExtCount=0, iExtNotFreeCount=0;
  927. FILETIME ftNotBefore;
  928. FILETIME ftNotAfter;
  929. ULARGE_INTEGER ulSerialNumber;
  930. TLSClientCertRDN certRdn;
  931. CERT_BASIC_CONSTRAINTS2_INFO basicConstraint;
  932. // modify here is we want to set to different issuer name
  933. LPTSTR szIssuerName;
  934. szIssuerName = g_szComputerName;
  935. //static LPTSTR pszEnforce=L"Enforce";
  936. CERT_RDN_ATTR rgNameAttr[] = {
  937. {
  938. szOID_COMMON_NAME,
  939. dwCertRdnValueType,
  940. _tcslen(szIssuerName) * sizeof(TCHAR),
  941. (UCHAR *)szIssuerName
  942. },
  943. //#if ENFORCE_LICENSING
  944. // {
  945. // szOID_BUSINESS_CATEGORY,
  946. // dwCertRdnValueType,
  947. // _tcslen(pszEnforce) * sizeof(TCHAR),
  948. // (UCHAR *)pszEnforce
  949. // },
  950. //#endif
  951. {
  952. szOID_LOCALITY_NAME,
  953. dwCertRdnValueType,
  954. _tcslen(g_pszScope) * sizeof(TCHAR),
  955. (UCHAR *)g_pszScope
  956. }
  957. };
  958. CERT_RDN rgRDN[] = { sizeof(rgNameAttr)/sizeof(rgNameAttr[0]), &rgNameAttr[0] };
  959. CERT_NAME_INFO Name = {1, rgRDN};
  960. certRdn.type = LSCERT_RDN_NAME_INFO_TYPE;
  961. certRdn.pCertNameInfo = &Name;
  962. memset(rgExtension, 0, sizeof(rgExtension));
  963. //
  964. // Set validity of self sign certificate
  965. //
  966. //
  967. // If system time is not in sync, this will cause server
  968. // can't request cert. from license server
  969. //
  970. memset(&sysTime, 0, sizeof(sysTime));
  971. GetSystemTime(&sysTime);
  972. sysTime.wYear = 1970;
  973. if(TLSSystemTimeToFileTime(&sysTime, &ftNotBefore) == FALSE)
  974. {
  975. dwStatus = GetLastError();
  976. goto cleanup;
  977. }
  978. //
  979. // draft-ietf-pkix-ipki-part1-06.txt section 4.1.2.5.1
  980. // where year is greater or equal to 50, the year shall be interpreted as 19YY; and
  981. // where year is less than 50, the year shall be interpreted as 20YY
  982. //
  983. sysTime.wYear = PERMANENT_CERT_EXPIRE_DATE;
  984. if(TLSSystemTimeToFileTime(&sysTime, &ftNotAfter) == FALSE)
  985. {
  986. dwStatus = GetLastError();
  987. goto cleanup;
  988. }
  989. ulSerialNumber.LowPart = ftNotBefore.dwLowDateTime;
  990. ulSerialNumber.HighPart = ftNotBefore.dwHighDateTime;
  991. //
  992. // Add basic constrains extension to indicate this is a CA certificate
  993. //
  994. rgExtension[iExtCount].pszObjId = szOID_BASIC_CONSTRAINTS2;
  995. rgExtension[iExtCount].fCritical = FALSE;
  996. basicConstraint.fCA = TRUE; // act as CA
  997. basicConstraint.fPathLenConstraint = TRUE;
  998. basicConstraint.dwPathLenConstraint = 0; // can only issue certificates
  999. // to end-entities and not to further CAs
  1000. dwStatus=TLSCryptEncodeObject(
  1001. X509_ASN_ENCODING,
  1002. szOID_BASIC_CONSTRAINTS2,
  1003. &basicConstraint,
  1004. &(rgExtension[iExtCount].Value.pbData),
  1005. &(rgExtension[iExtCount].Value.cbData)
  1006. );
  1007. if(dwStatus != ERROR_SUCCESS)
  1008. {
  1009. TLSLogEvent(
  1010. EVENTLOG_ERROR_TYPE,
  1011. TLS_E_GENERATECLIENTELICENSE,
  1012. TLS_E_SIGNENCODECERT,
  1013. dwStatus
  1014. );
  1015. goto cleanup;
  1016. }
  1017. iExtCount++;
  1018. //
  1019. // From here - extension memory should not be free
  1020. //
  1021. if(pbSPK != NULL && cbSPK != 0)
  1022. {
  1023. rgExtension[iExtCount].pszObjId = szOID_PKIS_TLSERVER_SPK_OID;
  1024. rgExtension[iExtCount].fCritical = FALSE;
  1025. rgExtension[iExtCount].Value.pbData = pbSPK;
  1026. rgExtension[iExtCount].Value.cbData = cbSPK;
  1027. iExtNotFreeCount++;
  1028. iExtCount++;
  1029. }
  1030. for(index = 0;
  1031. index < dwNumExtensions;
  1032. index ++, iExtCount++, iExtNotFreeCount++ )
  1033. {
  1034. if (iExtCount >= MAX_EXTENSIONS_IN_SELFSIGN)
  1035. {
  1036. iExtCount--;
  1037. dwStatus = ERROR_INVALID_PARAMETER;
  1038. goto cleanup;
  1039. }
  1040. rgExtension[iExtCount] = pCertExtension[index];
  1041. }
  1042. dwStatus = TLSGenerateCertificate(
  1043. hCryptProv,
  1044. dwKeySpec,
  1045. &ulSerialNumber,
  1046. &certRdn,
  1047. &certRdn,
  1048. &ftNotBefore,
  1049. &ftNotAfter,
  1050. NULL,
  1051. iExtCount,
  1052. rgExtension,
  1053. cbEncoded,
  1054. pbEncoded
  1055. );
  1056. cleanup:
  1057. //
  1058. // Don't free memory for SPK and extensions...
  1059. //
  1060. for(int i=0; i < iExtCount - iExtNotFreeCount; i++)
  1061. {
  1062. FreeMemory(rgExtension[i].Value.pbData);
  1063. }
  1064. return (dwStatus != ERROR_SUCCESS) ? TLS_E_CREATE_SELFSIGN_CERT : ERROR_SUCCESS;
  1065. }
  1066. ////////////////////////////////////////////////////////////////////////////
  1067. DWORD
  1068. TLSGenerateSingleCertificate(
  1069. IN HCRYPTPROV hCryptProv,
  1070. IN PCERT_NAME_BLOB pIssuerRdn,
  1071. IN PTLSClientCertRDN pSubjectRdn,
  1072. IN PCERT_PUBLIC_KEY_INFO pSubjectPublicKeyInfo,
  1073. IN PTLSDBLICENSEDPRODUCT pLicProduct,
  1074. OUT PBYTE* ppbEncodedCert,
  1075. IN PDWORD pcbEncodedCert
  1076. )
  1077. /*
  1078. */
  1079. {
  1080. DWORD dwStatus = ERROR_SUCCESS;
  1081. #define MAX_CLIENT_EXTENSION 10
  1082. CERT_EXTENSION CertExtension[MAX_CLIENT_EXTENSION];
  1083. DWORD dwNumExtensions=0;
  1084. DWORD currentCertVersion=TERMSERV_CERT_VERSION_CURRENT;
  1085. TLSClientCertRDN IssuerRdn;
  1086. #if ENFORCE_LICENSING
  1087. //
  1088. // Use certificate that CH gets for us
  1089. //
  1090. IssuerRdn.type = LSCERT_RDN_NAME_BLOB_TYPE;
  1091. //IssuerRdn.pNameBlob = &g_LicenseCertContext->pCertInfo->Subject;
  1092. IssuerRdn.pNameBlob = pIssuerRdn;
  1093. #else
  1094. LPTSTR szIssuerName;
  1095. // modify here if we want to set to different issuer name
  1096. szIssuerName = g_szComputerName;
  1097. CERT_RDN_ATTR rgNameAttr[] = {
  1098. {
  1099. OID_ISSUER_LICENSE_SERVER_NAME,
  1100. dwCertRdnValueType,
  1101. _tcslen(szIssuerName) * sizeof(TCHAR),
  1102. (UCHAR *)szIssuerName
  1103. },
  1104. {
  1105. OID_ISSUER_LICENSE_SERVER_SCOPE,
  1106. dwCertRdnValueType,
  1107. _tcslen(g_pszScope) * sizeof(TCHAR),
  1108. (UCHAR *)g_pszScope
  1109. }
  1110. };
  1111. CERT_RDN rgRDN[] = {
  1112. sizeof(rgNameAttr)/sizeof(rgNameAttr[0]),
  1113. &rgNameAttr[0]
  1114. };
  1115. CERT_NAME_INFO Name = {1, rgRDN};
  1116. IssuerRdn.type = LSCERT_RDN_NAME_INFO_TYPE;
  1117. IssuerRdn.pCertNameInfo = &Name;
  1118. #endif
  1119. //------------------------------------------------------------------------------------------
  1120. // add extension to certificate
  1121. // WARNING : End of routine free memory allocated for extension's pbData, skip those
  1122. // that can't be free, for example, version stamp extension. all these is just
  1123. // to keep memory fragmentaion low
  1124. //------------------------------------------------------------------------------------------
  1125. //
  1126. // DO NOT FREE pbData on first two extensions
  1127. //
  1128. // Hydra Certificate version stamp - DO NOT FREE
  1129. memset(CertExtension, 0, sizeof(CertExtension));
  1130. dwNumExtensions = 0;
  1131. //
  1132. // Add License Server Info
  1133. //
  1134. CertExtension[dwNumExtensions].pszObjId = szOID_PKIX_HYDRA_CERT_VERSION;
  1135. CertExtension[dwNumExtensions].fCritical = TRUE;
  1136. CertExtension[dwNumExtensions].Value.cbData = sizeof(DWORD);
  1137. CertExtension[dwNumExtensions].Value.pbData = (PBYTE)&currentCertVersion;
  1138. dwNumExtensions++;
  1139. // manufacturer's name, no encoding - DO NOT FREE
  1140. CertExtension[dwNumExtensions].pszObjId = szOID_PKIX_MANUFACTURER;
  1141. CertExtension[dwNumExtensions].fCritical = TRUE;
  1142. CertExtension[dwNumExtensions].Value.cbData = (_tcslen(pLicProduct->szCompanyName)+1) * sizeof(TCHAR);
  1143. CertExtension[dwNumExtensions].Value.pbData = (PBYTE)pLicProduct->szCompanyName;
  1144. dwNumExtensions++;
  1145. //
  1146. // MS Licensed Product Info, no encoding
  1147. //
  1148. LICENSED_VERSION_INFO LicensedInfo;
  1149. memset(&LicensedInfo, 0, sizeof(LicensedInfo));
  1150. LicensedInfo.wMajorVersion = HIWORD(pLicProduct->dwProductVersion);
  1151. LicensedInfo.wMinorVersion = LOWORD(pLicProduct->dwProductVersion);
  1152. LicensedInfo.dwFlags = (pLicProduct->bTemp) ? LICENSED_VERSION_TEMPORARY : 0;
  1153. DWORD dwLSVersionMajor;
  1154. DWORD dwLSVersionMinor;
  1155. dwLSVersionMajor = GET_SERVER_MAJOR_VERSION(TLS_CURRENT_VERSION);
  1156. dwLSVersionMinor = GET_SERVER_MINOR_VERSION(TLS_CURRENT_VERSION);
  1157. LicensedInfo.dwFlags |= ((dwLSVersionMajor << 4 | dwLSVersionMinor) << 16);
  1158. if(TLSIsBetaNTServer() == FALSE)
  1159. {
  1160. LicensedInfo.dwFlags |= LICENSED_VERSION_RTM;
  1161. }
  1162. #if ENFORCE_LICENSING
  1163. LicensedInfo.dwFlags |= LICENSE_ISSUER_ENFORCE_TYPE;
  1164. #endif
  1165. CertExtension[dwNumExtensions].pszObjId = szOID_PKIX_LICENSED_PRODUCT_INFO;
  1166. CertExtension[dwNumExtensions].fCritical = TRUE;
  1167. dwStatus=LSLicensedProductInfoToExtension(
  1168. 1,
  1169. pLicProduct->dwPlatformID,
  1170. pLicProduct->dwLanguageID,
  1171. (PBYTE)pLicProduct->szRequestProductId,
  1172. (_tcslen(pLicProduct->szRequestProductId) + 1) * sizeof(TCHAR),
  1173. (PBYTE)pLicProduct->szLicensedProductId,
  1174. (_tcslen(pLicProduct->szLicensedProductId) + 1) * sizeof(TCHAR),
  1175. &LicensedInfo,
  1176. 1,
  1177. &(CertExtension[dwNumExtensions].Value.pbData),
  1178. &(CertExtension[dwNumExtensions].Value.cbData)
  1179. );
  1180. if(dwStatus != ERROR_SUCCESS)
  1181. goto cleanup;
  1182. dwNumExtensions++;
  1183. //
  1184. // Add license server info into extension
  1185. //
  1186. CertExtension[dwNumExtensions].pszObjId = szOID_PKIX_MS_LICENSE_SERVER_INFO;
  1187. CertExtension[dwNumExtensions].fCritical = TRUE;
  1188. dwStatus=LSMsLicenseServerInfoToExtension(
  1189. g_szComputerName,
  1190. (LPTSTR)g_pszServerPid,
  1191. g_pszScope,
  1192. &(CertExtension[dwNumExtensions].Value.pbData),
  1193. &(CertExtension[dwNumExtensions].Value.cbData)
  1194. );
  1195. if(dwStatus != ERROR_SUCCESS)
  1196. goto cleanup;
  1197. dwNumExtensions++;
  1198. //
  1199. // Add policy module specific extension
  1200. if( pLicProduct->pbPolicyData != NULL && pLicProduct->cbPolicyData != 0 )
  1201. {
  1202. CertExtension[dwNumExtensions].pszObjId = szOID_PKIS_PRODUCT_SPECIFIC_OID;
  1203. CertExtension[dwNumExtensions].fCritical = TRUE;
  1204. CertExtension[dwNumExtensions].Value.pbData = pLicProduct->pbPolicyData;
  1205. CertExtension[dwNumExtensions].Value.cbData = pLicProduct->cbPolicyData;
  1206. dwNumExtensions++;
  1207. }
  1208. //
  1209. // Add CertAuthorityKeyId2Info for certificate chain
  1210. dwStatus=TLSAddCertAuthorityKeyIdExtension(
  1211. g_szComputerName,
  1212. &pLicProduct->ulSerialNumber,
  1213. CertExtension + dwNumExtensions
  1214. );
  1215. if(dwStatus != ERROR_SUCCESS)
  1216. goto cleanup;
  1217. dwNumExtensions++;
  1218. // Add Access info
  1219. dwStatus = TLSGenerateCertificate(
  1220. hCryptProv,
  1221. AT_SIGNATURE,
  1222. &pLicProduct->ulSerialNumber,
  1223. &IssuerRdn,
  1224. pSubjectRdn,
  1225. &pLicProduct->NotBefore,
  1226. &pLicProduct->NotAfter,
  1227. pLicProduct->pSubjectPublicKeyInfo,
  1228. dwNumExtensions,
  1229. CertExtension,
  1230. pcbEncodedCert,
  1231. ppbEncodedCert
  1232. );
  1233. cleanup:
  1234. // Extensions. DO NOT FREE first two extensions
  1235. for(int i=2; i < dwNumExtensions; i++)
  1236. {
  1237. FreeMemory(CertExtension[i].Value.pbData);
  1238. }
  1239. return (dwStatus != ERROR_SUCCESS) ? TLS_E_CREATE_CERT : ERROR_SUCCESS;
  1240. }
  1241. ////////////////////////////////////////////////////////////
  1242. DWORD
  1243. TLSGenerateClientCertificate(
  1244. IN HCRYPTPROV hCryptProv,
  1245. IN DWORD dwNumLicensedProduct,
  1246. IN PTLSDBLICENSEDPRODUCT pLicProduct,
  1247. IN WORD wLicenseChainDetail,
  1248. OUT PBYTE* ppbEncodedCert,
  1249. OUT PDWORD pcbEncodedCert
  1250. )
  1251. /*++
  1252. ++*/
  1253. {
  1254. DWORD dwStatus = ERROR_SUCCESS;
  1255. HCERTSTORE hStore = NULL;
  1256. PCCERT_CONTEXT pCertContext = NULL;
  1257. PBYTE pbCert=NULL;
  1258. DWORD cbCert=NULL;
  1259. DWORD index;
  1260. TLSClientCertRDN clientCertRdn;
  1261. PCERT_NAME_BLOB pIssuerNameBlob = NULL;
  1262. //
  1263. // Create a in-memory store
  1264. //
  1265. hStore=CertOpenStore(
  1266. CERT_STORE_PROV_MEMORY,
  1267. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1268. hCryptProv,
  1269. CERT_STORE_NO_CRYPT_RELEASE_FLAG,
  1270. NULL
  1271. );
  1272. if(!hStore)
  1273. {
  1274. TLSLogEvent(
  1275. EVENTLOG_ERROR_TYPE,
  1276. TLS_E_GENERATECLIENTELICENSE,
  1277. TLS_E_OPEN_CERT_STORE,
  1278. dwStatus=GetLastError()
  1279. );
  1280. goto cleanup;
  1281. }
  1282. #ifndef ENFORCE_LICENSING
  1283. pIssuerNameBlob = &g_SelfSignCertContext->pCertInfo->Subject;
  1284. #else
  1285. if( g_SelfSignCertContext == NULL )
  1286. {
  1287. TLSASSERT(FALSE);
  1288. dwStatus = TLS_E_INTERNAL;
  1289. goto cleanup;
  1290. }
  1291. if(g_bHasHydraCert && g_hCaStore && wLicenseChainDetail == LICENSE_DETAIL_DETAIL)
  1292. {
  1293. pIssuerNameBlob = &g_LicenseCertContext->pCertInfo->Subject;
  1294. }
  1295. else
  1296. {
  1297. pIssuerNameBlob = &g_SelfSignCertContext->pCertInfo->Subject;
  1298. }
  1299. #endif
  1300. //
  1301. // Generate client certificate and add to certstore
  1302. //
  1303. for(index = 0; index < dwNumLicensedProduct; index++)
  1304. {
  1305. if(pCertContext != NULL)
  1306. {
  1307. //
  1308. // Need to keep one pCertContext for later use
  1309. //
  1310. CertFreeCertificateContext(pCertContext);
  1311. pCertContext = NULL;
  1312. }
  1313. clientCertRdn.type = LSCERT_CLIENT_INFO_TYPE;
  1314. clientCertRdn.ClientInfo.szUserName = pLicProduct[index].szUserName;
  1315. clientCertRdn.ClientInfo.szMachineName = pLicProduct[index].szMachineName;
  1316. clientCertRdn.ClientInfo.pClientID = &pLicProduct[index].ClientHwid;
  1317. dwStatus = TLSGenerateSingleCertificate(
  1318. hCryptProv,
  1319. pIssuerNameBlob,
  1320. &clientCertRdn,
  1321. pLicProduct[index].pSubjectPublicKeyInfo,
  1322. pLicProduct+index,
  1323. &pbCert,
  1324. &cbCert
  1325. );
  1326. if(dwStatus != ERROR_SUCCESS)
  1327. {
  1328. break;
  1329. }
  1330. //
  1331. // Add certificate to store
  1332. //
  1333. pCertContext = CertCreateCertificateContext(
  1334. X509_ASN_ENCODING,
  1335. pbCert,
  1336. cbCert
  1337. );
  1338. if(pCertContext == NULL)
  1339. {
  1340. TLSLogEvent(
  1341. EVENTLOG_ERROR_TYPE,
  1342. TLS_E_GENERATECLIENTELICENSE,
  1343. TLS_E_CREATE_CERTCONTEXT,
  1344. dwStatus=GetLastError()
  1345. );
  1346. break;
  1347. }
  1348. //
  1349. // always start from empty so CERT_STORE_ADD_ALWAYS
  1350. //
  1351. if(!CertAddCertificateContextToStore(hStore, pCertContext, CERT_STORE_ADD_ALWAYS, NULL))
  1352. {
  1353. TLSLogEvent(
  1354. EVENTLOG_ERROR_TYPE,
  1355. TLS_E_GENERATECLIENTELICENSE,
  1356. TLS_E_ADD_CERT_TO_STORE,
  1357. dwStatus=GetLastError()
  1358. );
  1359. break;
  1360. }
  1361. FreeMemory(pbCert);
  1362. pbCert = NULL;
  1363. }
  1364. if(dwStatus == ERROR_SUCCESS)
  1365. {
  1366. #ifndef ENFORCE_LICENSING
  1367. //
  1368. // Add license server's certificate
  1369. if(!CertAddCertificateContextToStore(hStore, g_LicenseCertContext, CERT_STORE_ADD_ALWAYS, NULL))
  1370. {
  1371. TLSLogEvent(
  1372. EVENTLOG_ERROR_TYPE,
  1373. TLS_E_GENERATECLIENTELICENSE,
  1374. TLS_E_ADD_CERT_TO_STORE,
  1375. dwStatus=GetLastError()
  1376. );
  1377. goto cleanup;
  1378. }
  1379. #else
  1380. //
  1381. // we don't support LICENSE_DETAIL_MODERATE at this time, treat it as LICENSE_DETAIL_SIMPLE
  1382. //
  1383. if(g_bHasHydraCert && g_hCaStore && wLicenseChainDetail == LICENSE_DETAIL_DETAIL)
  1384. {
  1385. //
  1386. // Chain issuer certificate with client certificate
  1387. //
  1388. if(!TLSChainIssuerCertificate(hCryptProv, g_hCaStore, hStore, pCertContext))
  1389. {
  1390. TLSLogEvent(
  1391. EVENTLOG_ERROR_TYPE,
  1392. TLS_E_GENERATECLIENTELICENSE,
  1393. TLS_E_ADD_CERT_TO_STORE,
  1394. dwStatus=GetLastError()
  1395. );
  1396. goto cleanup;
  1397. }
  1398. }
  1399. else
  1400. {
  1401. //
  1402. // Add license server's certificate
  1403. if(!CertAddCertificateContextToStore(hStore, g_SelfSignCertContext, CERT_STORE_ADD_ALWAYS, NULL))
  1404. {
  1405. TLSLogEvent(
  1406. EVENTLOG_ERROR_TYPE,
  1407. TLS_E_GENERATECLIENTELICENSE,
  1408. TLS_E_ADD_CERT_TO_STORE,
  1409. dwStatus=GetLastError()
  1410. );
  1411. goto cleanup;
  1412. }
  1413. }
  1414. #endif
  1415. CRYPT_DATA_BLOB saveBlob;
  1416. memset(&saveBlob, 0, sizeof(saveBlob));
  1417. // save certificate into memory
  1418. if(!CertSaveStore(hStore,
  1419. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1420. LICENSE_BLOB_SAVEAS_TYPE,
  1421. CERT_STORE_SAVE_TO_MEMORY,
  1422. &saveBlob,
  1423. 0) && (dwStatus=GetLastError()) != ERROR_MORE_DATA)
  1424. {
  1425. TLSLogEvent(
  1426. EVENTLOG_ERROR_TYPE,
  1427. TLS_E_GENERATECLIENTELICENSE,
  1428. TLS_E_SAVE_STORE,
  1429. dwStatus=GetLastError()
  1430. );
  1431. goto cleanup;
  1432. }
  1433. if(!(saveBlob.pbData = (PBYTE)AllocateMemory(saveBlob.cbData)))
  1434. {
  1435. dwStatus=TLS_E_ALLOCATE_MEMORY;
  1436. goto cleanup;
  1437. }
  1438. // save certificate into memory
  1439. if(!CertSaveStore(hStore,
  1440. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  1441. LICENSE_BLOB_SAVEAS_TYPE,
  1442. CERT_STORE_SAVE_TO_MEMORY,
  1443. &saveBlob,
  1444. 0))
  1445. {
  1446. TLSLogEvent(
  1447. EVENTLOG_ERROR_TYPE,
  1448. TLS_E_GENERATECLIENTELICENSE,
  1449. TLS_E_SAVE_STORE,
  1450. dwStatus=GetLastError()
  1451. );
  1452. goto cleanup;
  1453. }
  1454. *ppbEncodedCert = saveBlob.pbData;
  1455. *pcbEncodedCert = saveBlob.cbData;
  1456. }
  1457. cleanup:
  1458. FreeMemory(pbCert);
  1459. if(pCertContext)
  1460. {
  1461. CertFreeCertificateContext(pCertContext);
  1462. }
  1463. if(hStore)
  1464. {
  1465. CertCloseStore(hStore, CERT_CLOSE_STORE_FORCE_FLAG);
  1466. }
  1467. return dwStatus;
  1468. }