Source code of Windows XP (NT5)
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.

3451 lines
76 KiB

  1. /*++
  2. File name:
  3. csp.c
  4. Description:
  5. Contains routines to support cryptographic routines for termserv
  6. Copyright:
  7. Microsoft Confidential
  8. Copyright (c) Microsoft Corporation 1991-1998
  9. All rights reserved
  10. History:
  11. Frederick Chong( FredCh ) 07/29/98 Added functions to install
  12. X509 certificate.
  13. --*/
  14. #include <nt.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <ntlsa.h>
  18. #include <windows.h>
  19. #include <winbase.h>
  20. #include <winerror.h>
  21. #include <tchar.h>
  22. #include <stdio.h>
  23. #include "license.h"
  24. #include "cryptkey.h"
  25. #include "rng.h"
  26. #include "lscsp.h"
  27. #include "tlsapip.h"
  28. #include "certutil.h"
  29. #include "hydrakey.h"
  30. #include <md5.h>
  31. #include <sha.h>
  32. #include <rsa.h>
  33. #include <secdbg.h>
  34. #include "global.h"
  35. #ifdef OS_WIN16
  36. #include <string.h>
  37. #endif // OS_WIN16
  38. #include "licecert.h"
  39. #define LS_DISCOVERY_TIMEOUT (1*1000)
  40. //-----------------------------------------------------------------------------
  41. //
  42. // Internal Functions
  43. //
  44. //-----------------------------------------------------------------------------
  45. NTSTATUS
  46. OpenPolicy(
  47. LPWSTR ServerName,
  48. DWORD DesiredAccess,
  49. PLSA_HANDLE PolicyHandle );
  50. void
  51. InitLsaString(
  52. PLSA_UNICODE_STRING LsaString,
  53. LPWSTR String );
  54. LICENSE_STATUS
  55. GenerateRsaKeyPair(
  56. LPBYTE * ppbPublicKey,
  57. LPDWORD pcbPublicKey,
  58. LPBYTE * ppbPrivateKey,
  59. LPDWORD pcbPrivateKey,
  60. DWORD dwKeyLen );
  61. LICENSE_STATUS
  62. Bsafe2CapiPubKey(
  63. PCERT_PUBLIC_KEY_INFO pCapiPubKeyInfo,
  64. LPBYTE pbBsafePubKey,
  65. DWORD cbBsafePubKey );
  66. VOID
  67. FreeCapiPubKey(
  68. PCERT_PUBLIC_KEY_INFO pCapiPubKeyInfo );
  69. LICENSE_STATUS
  70. RequestCertificate(
  71. TLS_HANDLE hServer,
  72. PCERT_PUBLIC_KEY_INFO pPubKeyInfo,
  73. LPBYTE * ppbCertificate,
  74. LPDWORD pcbCertificate,
  75. HWID * pHwid );
  76. LICENSE_STATUS
  77. GetSubjectRdn(
  78. LPTSTR * ppSubjectRdn );
  79. LICENSE_STATUS
  80. GenerateMachineHWID(
  81. PHWID pHwid );
  82. LICENSE_STATUS
  83. ReloadCSPCertificateAndData();
  84. LICENSE_STATUS
  85. CreateProprietaryKeyAndCert(
  86. PBYTE *ppbPrivateKey,
  87. DWORD *pcbPrivateKey,
  88. PBYTE *ppbServerCert,
  89. DWORD *pcbServerCert);
  90. BOOL IsSystemService();
  91. /*++
  92. Function:
  93. LsCsp_ValidateServerCert
  94. Routine Description:
  95. This function validate the server public key.
  96. Arguments:
  97. pSserverCert - pointer to a server certificate.
  98. Return Value:
  99. TRUE - if the server public key is valid.
  100. FALSE - otherwise.
  101. --*/
  102. BOOL
  103. LsCsp_ValidateServerCert(
  104. PHydra_Server_Cert pServerCert
  105. )
  106. {
  107. BOOL bResult = TRUE;
  108. DWORD dwLen;
  109. LPBYTE pbSignature;
  110. MD5_CTX HashState;
  111. BYTE SignHash[0x48];
  112. DWORD buff[64];
  113. LPBYTE pbScan;
  114. //
  115. // pack the certificate data into a byte blob excluding the signature info.
  116. //
  117. dwLen =
  118. 3 * sizeof(DWORD) +
  119. 2 * sizeof(WORD) +
  120. pServerCert->PublicKeyData.wBlobLen;
  121. //
  122. // allocated space for the binary blob.
  123. //
  124. if (dwLen < sizeof(buff)) {
  125. pbSignature = (PBYTE)buff;
  126. } else {
  127. pbSignature = LocalAlloc( LPTR, (UINT)dwLen );
  128. if( pbSignature == NULL ) {
  129. #if DBG
  130. DbgPrint("LSCSP: LsCsp_ValidateServerCert buffer alloc failed.\n");
  131. #endif
  132. bResult = FALSE;
  133. goto vsc_done;
  134. }
  135. }
  136. pbScan = pbSignature;
  137. memcpy( pbScan, &pServerCert->dwVersion, sizeof(DWORD));
  138. pbScan += sizeof(DWORD);
  139. memcpy( pbScan, &pServerCert->dwSigAlgID, sizeof(DWORD));
  140. pbScan += sizeof(DWORD);
  141. memcpy( pbScan, &pServerCert->dwKeyAlgID, sizeof(DWORD));
  142. pbScan += sizeof(DWORD);
  143. memcpy( pbScan, &pServerCert->PublicKeyData.wBlobType, sizeof(WORD));
  144. pbScan += sizeof(WORD);
  145. memcpy( pbScan, &pServerCert->PublicKeyData.wBlobLen, sizeof(WORD));
  146. pbScan += sizeof(WORD);
  147. memcpy(
  148. pbScan,
  149. pServerCert->PublicKeyData.pBlob,
  150. pServerCert->PublicKeyData.wBlobLen);
  151. //
  152. // generate the hash on the data.
  153. //
  154. MD5Init( &HashState );
  155. MD5Update( &HashState, pbSignature, dwLen );
  156. MD5Final( &HashState );
  157. //
  158. // free the signature blob, we don't need it anymore.
  159. //
  160. if (pbSignature != (LPBYTE)buff) {
  161. LocalFree( pbSignature );
  162. }
  163. //
  164. // decrypt the signature.
  165. //
  166. memset(SignHash, 0x00, 0x48);
  167. BSafeEncPublic( csp_pRootPublicKey, pServerCert->SignatureBlob.pBlob, SignHash);
  168. //
  169. // compare the hash value.
  170. //
  171. if( memcmp( SignHash, HashState.digest, 16 )) {
  172. bResult = FALSE;
  173. } else {
  174. bResult = TRUE;
  175. }
  176. vsc_done:
  177. return( bResult );
  178. }
  179. /*++
  180. Function:
  181. LsCsp_UnpackServerCert
  182. Routine Description:
  183. This function unpacks the blob of server certicate to server certificate
  184. structure.
  185. Arguments:
  186. pbCert - pointer to the server public key blob.
  187. dwCertLen - length of the above server public key.
  188. pServerCert - pointer to a server certificate structure.
  189. Return Value:
  190. TRUE - if successfully unpacked.
  191. FALSE - otherwise.
  192. --*/
  193. BOOL
  194. LsCsp_UnpackServerCert(
  195. LPBYTE pbCert,
  196. DWORD dwCertLen,
  197. PHydra_Server_Cert pServerCert
  198. )
  199. {
  200. LPBYTE pbScan;
  201. BOOL bResult = TRUE;
  202. ASSERT(pbCert != NULL);
  203. ASSERT(dwCertLen < (3 * sizeof(DWORD) + 4 * sizeof(WORD)));
  204. ASSERT(pServerCert != NULL);
  205. pbScan = pbCert;
  206. //
  207. // Assign dwVersion
  208. //
  209. pServerCert->dwVersion = *(DWORD UNALIGNED FAR *)pbScan;
  210. pbScan += sizeof(DWORD);
  211. ASSERT(pServerCert->dwVersion == 0x01);
  212. //
  213. // Assign dwSigAlgID
  214. //
  215. pServerCert->dwSigAlgID = *(DWORD UNALIGNED FAR *)pbScan;
  216. pbScan += sizeof(DWORD);
  217. //
  218. // Assign dwSignID
  219. //
  220. pServerCert->dwKeyAlgID = *(DWORD UNALIGNED FAR *)pbScan;
  221. pbScan += sizeof(DWORD);
  222. //
  223. // Assign PublicKeyData
  224. //
  225. pServerCert->PublicKeyData.wBlobType = *(WORD UNALIGNED FAR *)pbScan;
  226. pbScan += sizeof(WORD);
  227. if( pServerCert->PublicKeyData.wBlobType != BB_RSA_KEY_BLOB ) {
  228. #if DBG
  229. DbgPrint("LSCSP: LsCsp_UnpackServerCert PublicKey not BB_RSA_KEY_BLOB\n");
  230. #endif
  231. bResult = FALSE;
  232. goto usc_done;
  233. }
  234. pServerCert->PublicKeyData.wBlobLen = *(WORD UNALIGNED FAR *)pbScan;
  235. pbScan += sizeof(WORD);
  236. if( pServerCert->PublicKeyData.wBlobLen > 0 ) {
  237. pServerCert->PublicKeyData.pBlob = pbScan;
  238. pbScan += pServerCert->PublicKeyData.wBlobLen;
  239. }
  240. else {
  241. pServerCert->PublicKeyData.pBlob = NULL;
  242. }
  243. //
  244. // Assign SignatureBlob
  245. //
  246. pServerCert->SignatureBlob.wBlobType = *(WORD UNALIGNED *)pbScan;
  247. pbScan += sizeof(WORD);
  248. if( pServerCert->SignatureBlob.wBlobType != BB_RSA_SIGNATURE_BLOB ) {
  249. #if DBG
  250. DbgPrint("LSCSP: LsCsp_UnpackServerCert Signature Blob not BB_RSA_SIGNATURE_BLOB\n");
  251. #endif
  252. bResult = FALSE;
  253. goto usc_done;
  254. }
  255. pServerCert->SignatureBlob.wBlobLen = *(WORD UNALIGNED FAR *)pbScan;
  256. pbScan += sizeof(WORD);
  257. if( pServerCert->SignatureBlob.wBlobLen > 0 ) {
  258. pServerCert->SignatureBlob.pBlob = pbScan;
  259. pbScan += pServerCert->SignatureBlob.wBlobLen;
  260. }
  261. else {
  262. pServerCert->SignatureBlob.pBlob = NULL;
  263. }
  264. usc_done:
  265. return( bResult );
  266. }
  267. /*++
  268. Function:
  269. LsCsp_DecryptEnvelopedData
  270. Routine Description:
  271. Decrypt the client random that is encrypted by the server public key.
  272. Arguments:
  273. dwCertType - The type of certificate that is used in the encryption.
  274. pbEnvelopedData - pointer to a buffer where the encrypted random key is
  275. passed in.
  276. cbEnvelopedDataLen - length of the random key passed in/out.
  277. pbData - pointer to a buffer where the decrypted data returned.
  278. pcbDataLen - pointer a DWORD location where the length of the above
  279. buffer is passed in and the length of the decrypted data is returned.
  280. Return Value:
  281. TRUE - if the key is decrypted successfully.
  282. FALSE - otherwise.
  283. --*/
  284. BOOL
  285. LsCsp_DecryptEnvelopedData(
  286. CERT_TYPE CertType,
  287. LPBYTE pbEnvelopedData,
  288. DWORD cbEnvelopedDataLen,
  289. LPBYTE pbData,
  290. LPDWORD pcbDataLen
  291. )
  292. {
  293. LPBSAFE_PRV_KEY pSrvPrivateKey = NULL;
  294. BOOL bResult = TRUE;
  295. ACQUIRE_EXCLUSIVE_ACCESS(csp_hMutex);
  296. //
  297. // determine the correct private key to use for the decryption operation
  298. //
  299. if( CERT_TYPE_PROPRIETORY == CertType )
  300. {
  301. pSrvPrivateKey = (LPBSAFE_PRV_KEY)csp_abServerPrivateKey;
  302. }
  303. else if( CERT_TYPE_X509 == CertType )
  304. {
  305. if( csp_abX509CertPrivateKey == NULL )
  306. {
  307. if( ReloadCSPCertificateAndData() != LICENSE_STATUS_OK )
  308. {
  309. ASSERT( FALSE );
  310. }
  311. }
  312. pSrvPrivateKey = (LPBSAFE_PRV_KEY)csp_abX509CertPrivateKey;
  313. }
  314. else
  315. {
  316. bResult = FALSE;
  317. goto ded_done;
  318. }
  319. if( NULL == pSrvPrivateKey )
  320. {
  321. bResult = FALSE;
  322. goto ded_done;
  323. }
  324. //
  325. // check to see the output buffer length pointer is valid.
  326. //
  327. if( pcbDataLen == NULL ) {
  328. bResult = FALSE;
  329. goto ded_done;
  330. }
  331. //
  332. // check to see the output buffer is valid and its length is sufficient.
  333. //
  334. if( (pbData == NULL) || (*pcbDataLen < pSrvPrivateKey->keylen) ) {
  335. *pcbDataLen = pSrvPrivateKey->keylen;
  336. bResult = FALSE;
  337. goto ded_done;
  338. }
  339. //
  340. // encrypted data length should be equal to server private key length.
  341. //
  342. if( cbEnvelopedDataLen != pSrvPrivateKey->keylen ) {
  343. *pcbDataLen = 0;
  344. bResult = FALSE;
  345. goto ded_done;
  346. }
  347. ASSERT( pbData != NULL );
  348. //
  349. // init the output buffer.
  350. //
  351. memset( pbData, 0x0, (UINT)pSrvPrivateKey->keylen );
  352. if( !BSafeDecPrivate(
  353. pSrvPrivateKey,
  354. pbEnvelopedData,
  355. pbData) ) {
  356. *pcbDataLen = 0;
  357. bResult = FALSE;
  358. goto ded_done;
  359. }
  360. //
  361. // successfully decrypted the client random.
  362. // set the encrypted data length before returning.
  363. //
  364. *pcbDataLen = pSrvPrivateKey->keylen;
  365. ded_done:
  366. RELEASE_EXCLUSIVE_ACCESS( csp_hMutex );
  367. return( bResult );
  368. }
  369. BOOL
  370. LsCsp_EncryptEnvelopedData(
  371. LPBYTE pbData,
  372. DWORD cbDataLen,
  373. LPBYTE pbEnvelopedData,
  374. LPDWORD pcbEnvelopedDataLen
  375. )
  376. {
  377. return FALSE;
  378. }
  379. /*++
  380. Function:
  381. LsCsp_DumpBinaryData
  382. Description:
  383. Display the binary data in the given buffer at the debugger output screen
  384. Arguments:
  385. pBuffer - Buffer containing the binary data to be displayed.
  386. uLen - Length of th binary data
  387. Return:
  388. Nothing.
  389. --*/
  390. #if DBG
  391. #ifdef DUMP
  392. VOID LsCsp_DumpBinaryData( PBYTE pBuffer, ULONG uLen )
  393. {
  394. UNALIGNED CHAR *p = (UNALIGNED CHAR *)pBuffer;
  395. CHAR c;
  396. DWORD dw;
  397. UINT i = 0;
  398. DbgPrint("{\n ");
  399. while( i < uLen ) {
  400. c = *p;
  401. dw = (DWORD)(c);
  402. DbgPrint( "0x%02X, ", dw & 0xFF );
  403. i++;
  404. p++;
  405. if ((i % 8) == 0)
  406. DbgPrint( "\n " );
  407. }
  408. DbgPrint( "\n}\n" );
  409. }
  410. #endif
  411. #endif
  412. /*++
  413. Function:
  414. LsCsp_GetBinaryData
  415. Description:
  416. Retrieve binary data from the registry
  417. Arguments:
  418. hKey - Handle to the registry key
  419. szValue - The registry value to read
  420. ppBuffer - Return pointer to the binary data
  421. pdwBufferLen - The length of the binary data.
  422. Return:
  423. A LICENSE_STATUS return code.
  424. --*/
  425. LICENSE_STATUS
  426. LsCsp_GetBinaryData(
  427. HKEY hKey,
  428. LPTSTR szValue,
  429. LPBYTE * ppBuffer,
  430. LPDWORD pdwBufferLen )
  431. {
  432. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  433. DWORD dwType;
  434. DWORD cbBuffer;
  435. LPBYTE lpBuffer;
  436. ASSERT( ppBuffer != NULL );
  437. ASSERT( pdwBufferLen != NULL );
  438. ASSERT( szValue != NULL );
  439. ASSERT( hKey != NULL );
  440. *ppBuffer = NULL;
  441. cbBuffer = 0;
  442. if ( RegQueryValueEx(
  443. hKey,
  444. szValue,
  445. 0,
  446. &dwType,
  447. (LPBYTE)NULL,
  448. &cbBuffer) != ERROR_SUCCESS ||
  449. dwType != REG_BINARY ||
  450. cbBuffer == 0 )
  451. {
  452. Status = LICENSE_STATUS_NO_CERTIFICATE;
  453. goto gbd_done;
  454. }
  455. lpBuffer = (LPBYTE)LocalAlloc( LPTR, cbBuffer );
  456. if (lpBuffer == NULL) {
  457. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  458. goto gbd_done;
  459. }
  460. if ( RegQueryValueEx(
  461. hKey,
  462. szValue,
  463. 0,
  464. &dwType,
  465. (LPBYTE)lpBuffer,
  466. &cbBuffer) != ERROR_SUCCESS ||
  467. dwType != REG_BINARY)
  468. {
  469. LocalFree( lpBuffer );
  470. Status = LICENSE_STATUS_NO_CERTIFICATE;
  471. goto gbd_done;
  472. }
  473. *ppBuffer = lpBuffer;
  474. *pdwBufferLen = cbBuffer;
  475. gbd_done:
  476. return( Status );
  477. }
  478. /*++
  479. Function:
  480. LsCsp_Initialize
  481. Description:
  482. Initialize this library.
  483. Arguments:
  484. Nothing.
  485. Return:
  486. A LICENSE_STATUS return code.
  487. --*/
  488. LICENSE_STATUS
  489. LsCsp_Initialize( void )
  490. {
  491. DWORD Status = LICENSE_STATUS_OK;
  492. DWORD dwResult, dwDisp;
  493. if( InterlockedIncrement( &csp_InitCount ) > 1 )
  494. {
  495. //
  496. // already initialized
  497. //
  498. return( LICENSE_STATUS_OK );
  499. }
  500. //
  501. // Create a global mutex for sync.
  502. //
  503. csp_hMutex = CreateMutex(
  504. NULL,
  505. FALSE,
  506. NULL
  507. );
  508. if(NULL == csp_hMutex)
  509. {
  510. #if DBG
  511. DbgPrint("LSCSP: CreateMutex() failed with error code %d\n", GetLastError());
  512. #endif
  513. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  514. goto ErrorExit;
  515. }
  516. //
  517. // initialize the Hydra Server Root Public key.
  518. //
  519. csp_pRootPublicKey = (LPBSAFE_PUB_KEY)csp_abPublicKeyModulus;
  520. csp_pRootPublicKey->magic = RSA1;
  521. csp_pRootPublicKey->keylen = 0x48;
  522. csp_pRootPublicKey->bitlen = 0x0200;
  523. csp_pRootPublicKey->datalen = 0x3f;
  524. csp_pRootPublicKey->pubexp = 0xc0887b5b;
  525. #if DBG
  526. #ifdef DUMP
  527. DbgPrint("Data0\n");
  528. LsCsp_DumpBinaryData( (LPBYTE)csp_pRootPublicKey, 92 );
  529. #endif
  530. #endif
  531. //
  532. // Initialize the proprietory certificate with the built in certificate
  533. //
  534. if( !LsCsp_UseBuiltInCert() )
  535. {
  536. Status = LICENSE_STATUS_NO_CERTIFICATE;
  537. goto ErrorExit;
  538. }
  539. //
  540. // Unpack and Validate the certificate
  541. //
  542. try {
  543. if (!LsCsp_UnpackServerCert(
  544. csp_abServerCertificate,
  545. csp_dwServerCertificateLen,
  546. &csp_hscData )) {
  547. Status = LICENSE_STATUS_INVALID_CERTIFICATE;
  548. goto ErrorExit;
  549. }
  550. if (!LsCsp_ValidateServerCert( &csp_hscData )) {
  551. Status = LICENSE_STATUS_INVALID_CERTIFICATE;
  552. }
  553. } except( EXCEPTION_EXECUTE_HANDLER ) {
  554. #if DBG
  555. DbgPrint("LSCSP: LsCsp_Initialize bad cert data!\n");
  556. #endif
  557. Status = LICENSE_STATUS_INVALID_CERTIFICATE;
  558. }
  559. Status = ReloadCSPCertificateAndData();
  560. if (LICENSE_STATUS_NO_CERTIFICATE == Status)
  561. {
  562. //
  563. // No X509 certificate. Not a failure, as the discovery
  564. // thread will soon install it.
  565. //
  566. Status = LICENSE_STATUS_OK;
  567. }
  568. else if(LICENSE_STATUS_OUT_OF_MEMORY == Status)
  569. {
  570. //
  571. // out of memory at initialization time,
  572. // this is critical error
  573. //
  574. goto ErrorExit;
  575. }
  576. //
  577. // Let initalization go thru if it can retrieve
  578. // private key from LSA, this is OK since we will try to install
  579. // certificate again in LsCsp_InstallX509Certificate()
  580. //
  581. Status = LICENSE_STATUS_OK;
  582. goto i_done;
  583. ErrorExit:
  584. LsCsp_Exit();
  585. i_done:
  586. return( Status );
  587. }
  588. /*++
  589. Function:
  590. LsCsp_Exit
  591. Description:
  592. Free all resources used by this library.
  593. Arguments:
  594. Nothing.
  595. Return:
  596. A LICENSE_STATUS return code.
  597. --*/
  598. VOID LsCsp_Exit( void )
  599. {
  600. if( InterlockedDecrement( &csp_InitCount ) > 0 )
  601. {
  602. //
  603. // someone is still using it.
  604. //
  605. return;
  606. }
  607. if ( csp_abServerPrivateKey)
  608. {
  609. LocalFree( csp_abServerPrivateKey );
  610. }
  611. csp_abServerPrivateKey = NULL;
  612. if ( csp_abServerCertificate )
  613. {
  614. LocalFree( csp_abServerCertificate );
  615. }
  616. csp_abServerCertificate = NULL;
  617. if( csp_abServerX509Cert )
  618. {
  619. LocalFree( csp_abServerX509Cert );
  620. }
  621. csp_abServerX509Cert = NULL;
  622. if( csp_abX509CertPrivateKey )
  623. {
  624. LocalFree( csp_abX509CertPrivateKey );
  625. }
  626. csp_abX509CertPrivateKey = NULL;
  627. if( csp_abX509CertID )
  628. {
  629. LocalFree( csp_abX509CertID );
  630. }
  631. csp_abX509CertID = NULL;
  632. if( csp_hMutex )
  633. {
  634. CloseHandle( csp_hMutex );
  635. }
  636. csp_hMutex = NULL;
  637. return;
  638. }
  639. /*++
  640. Function:
  641. LsCsp_GetServerData
  642. Routine Description:
  643. This function makes and return the microsoft terminal server certificate
  644. blob of data.
  645. Arguments:
  646. dwInfoDesired - What type of information to return.
  647. pBlob - pointer to a location where the certificate blob data
  648. pointer is returned.
  649. pdwServerCertLen - pointer to a location where the length of the above data
  650. is returned.
  651. Return Value:
  652. Windows Error Code.
  653. --*/
  654. LICENSE_STATUS
  655. LsCsp_GetServerData(
  656. LSCSPINFO Info,
  657. LPBYTE pBlob,
  658. LPDWORD pdwBlobLen
  659. )
  660. {
  661. LICENSE_STATUS Status = LICENSE_STATUS_OK;
  662. DWORD dwDataLen;
  663. LPBYTE pbData;
  664. ASSERT( pdwBlobLen != NULL );
  665. if ((Info == LsCspInfo_PrivateKey) || (Info == LsCspInfo_X509CertPrivateKey))
  666. {
  667. if (!IsSystemService())
  668. {
  669. return LICENSE_STATUS_NO_PRIVATE_KEY;
  670. }
  671. }
  672. ACQUIRE_EXCLUSIVE_ACCESS(csp_hMutex);
  673. switch (Info) {
  674. case LsCspInfo_Certificate:
  675. if( NULL == csp_abServerCertificate )
  676. {
  677. Status = LICENSE_STATUS_NO_CERTIFICATE;
  678. goto gsd_done;
  679. }
  680. pbData = csp_abServerCertificate;
  681. dwDataLen = csp_dwServerCertificateLen;
  682. break;
  683. case LsCspInfo_X509Certificate:
  684. //
  685. // We may not have an X509 certificate if the hydra server has not
  686. // requested one from the license server
  687. //
  688. if( NULL == csp_abServerX509Cert )
  689. {
  690. Status = LICENSE_STATUS_NO_CERTIFICATE;
  691. goto gsd_done;
  692. }
  693. pbData = csp_abServerX509Cert;
  694. dwDataLen = csp_dwServerX509CertLen;
  695. break;
  696. case LsCspInfo_X509CertID:
  697. //
  698. // we will not have a certificate ID if the X509 certificate is not present
  699. //
  700. if( NULL == csp_abX509CertID )
  701. {
  702. Status = LICENSE_STATUS_NO_CERTIFICATE;
  703. goto gsd_done;
  704. }
  705. pbData = csp_abX509CertID;
  706. dwDataLen = csp_dwX509CertIDLen;
  707. break;
  708. case LsCspInfo_PublicKey:
  709. pbData = csp_hscData.PublicKeyData.pBlob;
  710. dwDataLen = csp_hscData.PublicKeyData.wBlobLen;
  711. break;
  712. case LsCspInfo_PrivateKey:
  713. if( NULL == csp_abServerPrivateKey )
  714. {
  715. Status = LICENSE_STATUS_NO_PRIVATE_KEY;
  716. goto gsd_done;
  717. }
  718. pbData = csp_abServerPrivateKey;
  719. dwDataLen = csp_dwServerPrivateKeyLen;
  720. break;
  721. case LsCspInfo_X509CertPrivateKey:
  722. //
  723. // The X509 certificate private key may not have been created.
  724. //
  725. if( NULL == csp_abX509CertPrivateKey )
  726. {
  727. Status = LICENSE_STATUS_NO_PRIVATE_KEY;
  728. goto gsd_done;
  729. }
  730. pbData = csp_abX509CertPrivateKey;
  731. dwDataLen = csp_dwX509CertPrivateKeyLen;
  732. break;
  733. default:
  734. Status = LICENSE_STATUS_INVALID_INPUT;
  735. goto gsd_done;
  736. }
  737. if (pBlob != NULL) {
  738. if (*pdwBlobLen < dwDataLen) {
  739. *pdwBlobLen = dwDataLen;
  740. Status = LICENSE_STATUS_INSUFFICIENT_BUFFER;
  741. } else {
  742. memcpy(pBlob, pbData, dwDataLen);
  743. *pdwBlobLen = dwDataLen;
  744. }
  745. } else {
  746. *pdwBlobLen = dwDataLen;
  747. }
  748. gsd_done:
  749. RELEASE_EXCLUSIVE_ACCESS( csp_hMutex );
  750. return( Status );
  751. }
  752. /*++
  753. Function:
  754. LsCsp_ReadProprietaryDataFromStorage
  755. Description:
  756. Read proprietary public/private info from registry/LSA secret
  757. Arguments:
  758. None.
  759. Return:
  760. LICENSE_STATUS
  761. --*/
  762. LICENSE_STATUS
  763. LsCsp_ReadProprietaryDataFromStorage(PBYTE *ppbCert,
  764. DWORD *pcbCert,
  765. PBYTE *ppbPrivateKey,
  766. DWORD *pcbPrivateKey)
  767. {
  768. LICENSE_STATUS Status;
  769. HKEY hKey = NULL;
  770. DWORD dwDisp;
  771. *ppbCert = *ppbPrivateKey = NULL;
  772. *pcbCert = *pcbPrivateKey = 0;
  773. //
  774. // Open the Registry
  775. //
  776. if( RegCreateKeyEx(
  777. HKEY_LOCAL_MACHINE,
  778. TEXT( HYDRA_CERT_REG_KEY ),
  779. 0,
  780. NULL,
  781. REG_OPTION_NON_VOLATILE,
  782. KEY_READ,
  783. NULL,
  784. &hKey,
  785. &dwDisp ) != ERROR_SUCCESS )
  786. {
  787. Status = LICENSE_STATUS_NO_CERTIFICATE;
  788. goto done;
  789. }
  790. if ( RegQueryValueEx(
  791. hKey,
  792. TEXT( HYDRA_CERTIFICATE_VALUE ),
  793. NULL, // lpReserved
  794. NULL, // lpType
  795. NULL, // lpData
  796. pcbCert) != ERROR_SUCCESS )
  797. {
  798. Status = LICENSE_STATUS_NO_CERTIFICATE;
  799. goto done;
  800. }
  801. Status = LsCsp_RetrieveSecret(PRIVATE_KEY_NAME,
  802. NULL, // pbKey
  803. pcbPrivateKey);
  804. if (LICENSE_STATUS_OK != Status)
  805. {
  806. goto done;
  807. }
  808. *ppbCert = ( LPBYTE )LocalAlloc(LPTR,*pcbCert);
  809. if (NULL == *ppbCert)
  810. {
  811. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  812. goto done;
  813. }
  814. *ppbPrivateKey = ( LPBYTE )LocalAlloc(LPTR,*pcbPrivateKey);
  815. if (NULL == *ppbPrivateKey)
  816. {
  817. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  818. goto done;
  819. }
  820. if ( RegQueryValueEx(
  821. hKey,
  822. TEXT( HYDRA_CERTIFICATE_VALUE ),
  823. NULL, // lpReserved
  824. NULL, // lpType
  825. *ppbCert,
  826. pcbCert) != ERROR_SUCCESS )
  827. {
  828. Status = LICENSE_STATUS_NO_CERTIFICATE;
  829. goto done;
  830. }
  831. Status = LsCsp_RetrieveSecret(PRIVATE_KEY_NAME,
  832. *ppbPrivateKey,
  833. pcbPrivateKey);
  834. done:
  835. if (NULL != hKey)
  836. RegCloseKey(hKey);
  837. if (Status != LICENSE_STATUS_OK)
  838. {
  839. if (NULL != *ppbCert)
  840. {
  841. LocalFree(*ppbCert);
  842. *ppbCert = NULL;
  843. *pcbCert = 0;
  844. }
  845. if (NULL != *ppbPrivateKey)
  846. {
  847. LocalFree(*ppbPrivateKey);
  848. *ppbPrivateKey = NULL;
  849. *pcbPrivateKey = 0;
  850. }
  851. }
  852. return Status;
  853. }
  854. /*++
  855. Function:
  856. LsCsp_UseBuiltInCert
  857. Description:
  858. Initialize the global variables with hardcoded certificate.
  859. Arguments:
  860. None.
  861. Return:
  862. TRUE if the initialization is successful.
  863. --*/
  864. BOOL
  865. LsCsp_UseBuiltInCert( void )
  866. {
  867. LICENSE_STATUS Status;
  868. ACQUIRE_EXCLUSIVE_ACCESS(csp_hMutex);
  869. //
  870. // Step 1, cleanup and initialization that happened
  871. //
  872. if (csp_abServerPrivateKey)
  873. {
  874. LocalFree( csp_abServerPrivateKey );
  875. csp_abServerPrivateKey = NULL;
  876. }
  877. if (csp_abServerCertificate)
  878. {
  879. LocalFree( csp_abServerCertificate );
  880. csp_abServerCertificate = NULL;
  881. }
  882. //
  883. // Step 2, check for stored key and certificate
  884. //
  885. Status = LsCsp_ReadProprietaryDataFromStorage(&csp_abServerCertificate, &csp_dwServerCertificateLen,&csp_abServerPrivateKey, &csp_dwServerPrivateKeyLen);
  886. if (LICENSE_STATUS_OK != Status)
  887. {
  888. PBYTE pbPrivateKey, pbCertificate;
  889. DWORD cbPrivateKey, cbCertificate;
  890. //
  891. // Step 3, if no stored info found, generate new info and store it
  892. //
  893. Status = CreateProprietaryKeyAndCert(&pbPrivateKey,&cbPrivateKey,&pbCertificate,&cbCertificate);
  894. if (LICENSE_STATUS_OK == Status)
  895. {
  896. LsCsp_SetServerData(LsCspInfo_PrivateKey,pbPrivateKey,cbPrivateKey);
  897. LsCsp_SetServerData(LsCspInfo_Certificate,pbCertificate,cbCertificate);
  898. }
  899. }
  900. RELEASE_EXCLUSIVE_ACCESS( csp_hMutex );
  901. return( Status == LICENSE_STATUS_OK );
  902. }
  903. /*++
  904. Function:
  905. LsCsp_InstallX509Certificate
  906. Routine Description:
  907. This function generates a private/public key pair and then finds a
  908. license server to issue an X509 certificate for the public key.
  909. It then stores the private key and certificate.
  910. Arguments:
  911. None.
  912. Return Value:
  913. LSCSP return code.
  914. --*/
  915. LICENSE_STATUS
  916. LsCsp_InstallX509Certificate(LPVOID lpParam)
  917. {
  918. DWORD
  919. cbPubKey,
  920. cbPrivKey,
  921. cbCertificate;
  922. LICENSE_STATUS
  923. Status;
  924. LPBYTE
  925. pbPubKey = NULL,
  926. pbPrivKey = NULL,
  927. pbCertificate = NULL;
  928. CERT_PUBLIC_KEY_INFO
  929. CapiPubKeyInfo;
  930. HWID
  931. Hwid;
  932. TLS_HANDLE
  933. hServer;
  934. //
  935. // before we go through the trouble of generating private and public
  936. // keys, check if the license server is available.
  937. //
  938. hServer = TLSConnectToAnyLsServer(LS_DISCOVERY_TIMEOUT);
  939. if (NULL == hServer)
  940. {
  941. return( LICENSE_STATUS_NO_LICENSE_SERVER );
  942. }
  943. memset(&CapiPubKeyInfo, 0, sizeof(CapiPubKeyInfo));
  944. //
  945. // acquire exclusive access
  946. //
  947. ACQUIRE_EXCLUSIVE_ACCESS(csp_hMutex);
  948. //
  949. // Try to reload the certificate again, some other thread might have
  950. // install the certificate already.
  951. //
  952. Status = ReloadCSPCertificateAndData();
  953. if( LICENSE_STATUS_OK == Status )
  954. {
  955. goto done;
  956. }
  957. //
  958. // Generate a private/public key pair
  959. //
  960. Status = GenerateRsaKeyPair(
  961. &pbPubKey,
  962. &cbPubKey,
  963. &pbPrivKey,
  964. &cbPrivKey,
  965. RSA_KEY_LEN );
  966. if( LICENSE_STATUS_OK != Status )
  967. {
  968. #if DBG
  969. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: cannot generate RSA keypair\n" );
  970. #endif
  971. goto done;
  972. }
  973. //
  974. // convert the Bsafe public key into a CAPI public key
  975. //
  976. Status = Bsafe2CapiPubKey( &CapiPubKeyInfo, pbPubKey, cbPubKey );
  977. if( LICENSE_STATUS_OK != Status )
  978. {
  979. #if DBG
  980. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: cannot convert Bsafe Key to CAPI key\n" );
  981. #endif
  982. goto done;
  983. }
  984. //
  985. // generate a new hardware ID
  986. //
  987. Status = GenerateMachineHWID( &Hwid );
  988. if( LICENSE_STATUS_OK != Status )
  989. {
  990. #if DBG
  991. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: cannot generate certificate ID\n" );
  992. #endif
  993. goto done;
  994. }
  995. //
  996. // sends the certificate request to the license server
  997. //
  998. Status = RequestCertificate( hServer, &CapiPubKeyInfo, &pbCertificate, &cbCertificate, &Hwid );
  999. TLSDisconnectFromServer( hServer );
  1000. hServer = NULL;
  1001. if( LICENSE_STATUS_OK != Status )
  1002. {
  1003. #if DBG
  1004. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: error requesting terminal server certificate: %x\n", Status );
  1005. #endif
  1006. goto done;
  1007. }
  1008. //
  1009. // store the certificate identifier
  1010. //
  1011. Status = LsCsp_SetServerData(
  1012. LsCspInfo_X509CertID,
  1013. ( LPBYTE )&Hwid,
  1014. sizeof( Hwid ) );
  1015. if( LICENSE_STATUS_OK != Status )
  1016. {
  1017. #if DBG
  1018. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: cannot store terminal server certificate ID : %d\n", Status );
  1019. #endif
  1020. goto done;
  1021. }
  1022. //
  1023. // Stores the certificate and resets the global variable pointing
  1024. // to the X509 certificate.
  1025. //
  1026. Status = LsCsp_SetServerData(
  1027. LsCspInfo_X509Certificate,
  1028. pbCertificate,
  1029. cbCertificate );
  1030. if( LICENSE_STATUS_OK != Status )
  1031. {
  1032. #if DBG
  1033. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: cannot store terminal server certificate : %d\n", Status );
  1034. #endif
  1035. goto done;
  1036. }
  1037. //
  1038. // Stores the private key and resets the global variable pointing to the
  1039. // private key.
  1040. //
  1041. Status = LsCsp_SetServerData(
  1042. LsCspInfo_X509CertPrivateKey,
  1043. pbPrivKey,
  1044. cbPrivKey );
  1045. if( LICENSE_STATUS_OK != Status )
  1046. {
  1047. #if DBG
  1048. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: cannot store terminal server private key %d\n", Status );
  1049. #endif
  1050. goto done;
  1051. }
  1052. //
  1053. // Store the public key so we can verify at startup time
  1054. //
  1055. Status = LsCsp_StoreSecret(
  1056. X509_CERT_PUBLIC_KEY_NAME,
  1057. pbPubKey,
  1058. cbPubKey
  1059. );
  1060. if( LICENSE_STATUS_OK != Status )
  1061. {
  1062. #if DBG
  1063. DbgPrint( "LSCSP: LsCsp_InstallX509Certificate: cannot store terminal server public key : %d\n", Status );
  1064. #endif
  1065. }
  1066. done:
  1067. if (NULL != hServer)
  1068. {
  1069. TLSDisconnectFromServer( hServer );
  1070. hServer = NULL;
  1071. }
  1072. //
  1073. // release exclusive access
  1074. //
  1075. RELEASE_EXCLUSIVE_ACCESS( csp_hMutex );
  1076. if( pbCertificate )
  1077. {
  1078. LocalFree(pbCertificate);
  1079. }
  1080. if( pbPrivKey )
  1081. {
  1082. LocalFree( pbPrivKey );
  1083. }
  1084. if( pbPubKey )
  1085. {
  1086. LocalFree( pbPubKey );
  1087. }
  1088. FreeCapiPubKey( &CapiPubKeyInfo );
  1089. return( Status );
  1090. }
  1091. /*++
  1092. Function:
  1093. RequestCertificate
  1094. Routine Description:
  1095. Request a certificate from the license server
  1096. Arguments:
  1097. hServer - handle to license server
  1098. pPubKeyInfo - The public key info to be included in the certificate
  1099. ppbCertificate - The new certificate
  1100. pcbCertificate - size of the certificate
  1101. pHwid - The hardware ID that is used to identify the certificate
  1102. Return:
  1103. LICENSE_STATUS return code
  1104. --*/
  1105. LICENSE_STATUS
  1106. RequestCertificate(
  1107. TLS_HANDLE hServer,
  1108. PCERT_PUBLIC_KEY_INFO pPubKeyInfo,
  1109. LPBYTE * ppbCertificate,
  1110. LPDWORD pcbCertificate,
  1111. HWID * pHwid )
  1112. {
  1113. LSHydraCertRequest
  1114. CertRequest;
  1115. LICENSE_STATUS
  1116. Status;
  1117. DWORD
  1118. dwRpcCode,
  1119. dwResult,
  1120. cbChallengeData;
  1121. LPBYTE
  1122. pbChallengeData = NULL;
  1123. if( ( NULL == ppbCertificate ) ||
  1124. ( NULL == hServer ) ||
  1125. ( NULL == pPubKeyInfo ) ||
  1126. ( NULL == pcbCertificate ) )
  1127. {
  1128. return( LICENSE_STATUS_INVALID_INPUT );
  1129. }
  1130. *ppbCertificate = NULL;
  1131. *pcbCertificate = 0;
  1132. memset( &CertRequest, 0, sizeof( CertRequest ) );
  1133. CertRequest.dwHydraVersion = 0x00050000;
  1134. LsCsp_EncryptHwid( pHwid, NULL, &CertRequest.cbEncryptedHwid );
  1135. CertRequest.pbEncryptedHwid = LocalAlloc( LPTR, CertRequest.cbEncryptedHwid );
  1136. if( NULL == CertRequest.pbEncryptedHwid )
  1137. {
  1138. return LICENSE_STATUS_OUT_OF_MEMORY;
  1139. }
  1140. Status = LsCsp_EncryptHwid(
  1141. pHwid,
  1142. CertRequest.pbEncryptedHwid,
  1143. &CertRequest.cbEncryptedHwid );
  1144. if( LICENSE_STATUS_OK != Status )
  1145. {
  1146. goto done;
  1147. }
  1148. //
  1149. // get the subject RDN
  1150. //
  1151. Status = GetSubjectRdn( &CertRequest.szSubjectRdn );
  1152. if( LICENSE_STATUS_OK != Status )
  1153. {
  1154. goto done;
  1155. }
  1156. CertRequest.SubjectPublicKeyInfo = pPubKeyInfo;
  1157. //
  1158. // request an X509 certificate from the license server
  1159. //
  1160. dwRpcCode = TLSRequestTermServCert(hServer,
  1161. &CertRequest,
  1162. &cbChallengeData,
  1163. &pbChallengeData,
  1164. &dwResult );
  1165. if( ( RPC_S_OK != dwRpcCode ) || ( LSERVER_S_SUCCESS != dwResult ) )
  1166. {
  1167. Status = LICENSE_STATUS_CERTIFICATE_REQUEST_ERROR;
  1168. goto done;
  1169. }
  1170. dwRpcCode = TLSRetrieveTermServCert(
  1171. hServer,
  1172. cbChallengeData,
  1173. pbChallengeData,
  1174. pcbCertificate,
  1175. ppbCertificate,
  1176. &dwResult );
  1177. if( ( RPC_S_OK != dwRpcCode ) || ( LSERVER_ERROR_BASE <= dwResult ) )
  1178. {
  1179. Status = LICENSE_STATUS_CERTIFICATE_REQUEST_ERROR;
  1180. }
  1181. done:
  1182. if( CertRequest.pbEncryptedHwid )
  1183. {
  1184. LocalFree( CertRequest.pbEncryptedHwid );
  1185. }
  1186. if( CertRequest.szSubjectRdn )
  1187. {
  1188. LocalFree( CertRequest.szSubjectRdn );
  1189. }
  1190. if( pbChallengeData )
  1191. {
  1192. LocalFree( pbChallengeData );
  1193. }
  1194. return( Status );
  1195. }
  1196. /*++
  1197. Function:
  1198. GetSubjectRdn
  1199. Routine Description:
  1200. Construct the subject RDN for a certificate request
  1201. Argument:
  1202. ppSubjectRdn - Return pointer to the subject RDN
  1203. Return:
  1204. LICENSE_STATUS_OK if successful or a LICENSE_STATUS error code.
  1205. --*/
  1206. LICENSE_STATUS
  1207. GetSubjectRdn(
  1208. LPTSTR * ppSubjectRdn )
  1209. {
  1210. TCHAR
  1211. ComputerName[ MAX_COMPUTERNAME_LENGTH + 1 ];
  1212. DWORD
  1213. RdnLen = 0,
  1214. ComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1;
  1215. //
  1216. // use the computer name uas the common name
  1217. //
  1218. GetComputerName( ComputerName, &ComputerNameLen );
  1219. RdnLen += wcslen( TEXT( RDN_COMMON_NAME ) );
  1220. RdnLen += ComputerNameLen + 1;
  1221. RdnLen = RdnLen * sizeof( TCHAR );
  1222. *ppSubjectRdn = LocalAlloc( LPTR, RdnLen );
  1223. if( NULL == *ppSubjectRdn )
  1224. {
  1225. return( LICENSE_STATUS_OUT_OF_MEMORY );
  1226. }
  1227. wsprintf( *ppSubjectRdn, L"%s%s", TEXT( RDN_COMMON_NAME ), ComputerName );
  1228. return( LICENSE_STATUS_OK );
  1229. }
  1230. /*++
  1231. Function:
  1232. GenerateMachineHWID
  1233. Routine Description:
  1234. Generate a hardware ID for this machine
  1235. Arguments:
  1236. pHwid - Return value of the HWID
  1237. Return:
  1238. LICENSE_STATUS_OK if successful or a LICENSE_STATUS error code
  1239. --*/
  1240. LICENSE_STATUS
  1241. GenerateMachineHWID(
  1242. PHWID pHwid )
  1243. {
  1244. OSVERSIONINFO
  1245. osvInfo;
  1246. DWORD
  1247. cbCertId;
  1248. LPBYTE
  1249. pbCertId = NULL;
  1250. if( NULL == pHwid )
  1251. {
  1252. return( LICENSE_STATUS_INVALID_INPUT );
  1253. }
  1254. //
  1255. // Create the HWID
  1256. //
  1257. memset( &osvInfo, 0, sizeof( OSVERSIONINFO ) );
  1258. osvInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  1259. GetVersionEx( &osvInfo );
  1260. pHwid->dwPlatformID = osvInfo.dwPlatformId;
  1261. GenerateRandomBits( ( LPBYTE )&( pHwid->Data1 ), sizeof( DWORD ) );
  1262. GenerateRandomBits( ( LPBYTE )&( pHwid->Data2 ), sizeof( DWORD ) );
  1263. GenerateRandomBits( ( LPBYTE )&( pHwid->Data3 ), sizeof( DWORD ) );
  1264. GenerateRandomBits( ( LPBYTE )&( pHwid->Data4 ), sizeof( DWORD ) );
  1265. return( LICENSE_STATUS_OK );
  1266. }
  1267. /*++
  1268. Function:
  1269. LsCsp_EncryptHwid
  1270. Routine Description:
  1271. Encrypt the given hardward ID using the secret key shared by terminal
  1272. and license servers.
  1273. Arguments:
  1274. pHwid - The Hardware ID
  1275. pbEncryptedHwid - The encrypted HWID
  1276. pcbEncryptedHwid - Length of the encrypted HWID
  1277. Return:
  1278. LICENSE_STATUS_OK if successful or a LICENSE_STATUS error code otherwise.
  1279. --*/
  1280. LICENSE_STATUS
  1281. LsCsp_EncryptHwid(
  1282. PHWID pHwid,
  1283. LPBYTE pbEncryptedHwid,
  1284. LPDWORD pcbEncryptedHwid )
  1285. {
  1286. LICENSE_STATUS
  1287. Status;
  1288. LPBYTE
  1289. pbSecretKey = NULL;
  1290. DWORD
  1291. cbSecretKey = 0;
  1292. if( NULL == pcbEncryptedHwid )
  1293. {
  1294. return( LICENSE_STATUS_INVALID_INPUT );
  1295. }
  1296. if( ( NULL == pbEncryptedHwid ) ||
  1297. ( sizeof( HWID ) > *pcbEncryptedHwid ) )
  1298. {
  1299. *pcbEncryptedHwid = sizeof( HWID );
  1300. return( LICENSE_STATUS_INSUFFICIENT_BUFFER );
  1301. }
  1302. LicenseGetSecretKey( &cbSecretKey, NULL );
  1303. pbSecretKey = LocalAlloc( LPTR, cbSecretKey );
  1304. if( NULL == pbSecretKey )
  1305. {
  1306. return( LICENSE_STATUS_OUT_OF_MEMORY );
  1307. }
  1308. //
  1309. // Get the secret key used for encrypting the HWID
  1310. //
  1311. Status = LicenseGetSecretKey( &cbSecretKey, pbSecretKey );
  1312. if( LICENSE_STATUS_OK != Status )
  1313. {
  1314. goto done;
  1315. }
  1316. Status = LicenseEncryptHwid(
  1317. pHwid,
  1318. pcbEncryptedHwid,
  1319. pbEncryptedHwid,
  1320. cbSecretKey,
  1321. pbSecretKey );
  1322. done:
  1323. if( pbSecretKey )
  1324. {
  1325. LocalFree( pbSecretKey );
  1326. }
  1327. return( Status );
  1328. }
  1329. /*++
  1330. Function:
  1331. LsCsp_DecryptHwid
  1332. Routine Description:
  1333. Decrypt the given hardware ID
  1334. Arguments:
  1335. pHwid - The decrypted hardware ID
  1336. pbEncryptedHwid - The encrypted hardware ID
  1337. cbEncryptedHwid - Length of the encrypted hardware ID
  1338. Return:
  1339. LICENSE_STATUS_OK if successful or a LICENSE_STATUS error code.
  1340. --*/
  1341. LICENSE_STATUS
  1342. LsCsp_DecryptHwid(
  1343. PHWID pHwid,
  1344. LPBYTE pbEncryptedHwid,
  1345. LPDWORD pcbEncryptedHwid )
  1346. {
  1347. return( LICENSE_STATUS_OK );
  1348. }
  1349. /*++
  1350. Function:
  1351. LsCsp_StoreSecret
  1352. Description:
  1353. Use LSA to store a secret private key.
  1354. Arguments:
  1355. ptszKeyName - Name used to identify the secret private key.
  1356. pbKey - Points to the secret private key.
  1357. cbKey - Length of the private key.
  1358. Return:
  1359. A LICENSE_STATUS return code.
  1360. --*/
  1361. LICENSE_STATUS
  1362. LsCsp_StoreSecret(
  1363. PTCHAR ptszKeyName,
  1364. BYTE * pbKey,
  1365. DWORD cbKey )
  1366. {
  1367. LSA_HANDLE
  1368. PolicyHandle;
  1369. UNICODE_STRING
  1370. SecretKeyName;
  1371. UNICODE_STRING
  1372. SecretData;
  1373. DWORD
  1374. Status;
  1375. if( ( NULL == ptszKeyName ) || ( 0xffff < cbKey) )
  1376. {
  1377. return( LICENSE_STATUS_INVALID_INPUT );
  1378. }
  1379. //
  1380. // setup the UNICODE_STRINGs for the call.
  1381. //
  1382. InitLsaString( &SecretKeyName, ptszKeyName );
  1383. SecretData.Buffer = ( LPWSTR )pbKey;
  1384. SecretData.Length = ( USHORT )cbKey;
  1385. SecretData.MaximumLength = ( USHORT )cbKey;
  1386. Status = OpenPolicy( NULL, POLICY_CREATE_SECRET, &PolicyHandle );
  1387. if( ERROR_SUCCESS != Status )
  1388. {
  1389. return ( LICENSE_STATUS_CANNOT_OPEN_SECRET_STORE );
  1390. }
  1391. Status = LsaStorePrivateData(
  1392. PolicyHandle,
  1393. &SecretKeyName,
  1394. &SecretData
  1395. );
  1396. LsaClose( PolicyHandle );
  1397. Status = LsaNtStatusToWinError( Status );
  1398. if( ERROR_SUCCESS != Status )
  1399. {
  1400. return( LICENSE_STATUS_CANNOT_STORE_SECRET );
  1401. }
  1402. return( LICENSE_STATUS_OK );
  1403. }
  1404. /*++
  1405. Function:
  1406. LsCsp_RetrieveSecret
  1407. Description:
  1408. Retrieve the secret private key that is stored by LSA.
  1409. Arguments:
  1410. ptszKeyName - The name used to identify the secret private key.
  1411. ppbKey - Return value of the private key
  1412. pcbKey - Length of the private key.
  1413. Return:
  1414. A LICENSE_STATUS return code.
  1415. --*/
  1416. LICENSE_STATUS
  1417. LsCsp_RetrieveSecret(
  1418. PTCHAR ptszKeyName,
  1419. PBYTE pbKey,
  1420. DWORD * pcbKey )
  1421. {
  1422. LSA_HANDLE
  1423. PolicyHandle;
  1424. UNICODE_STRING
  1425. SecretKeyName;
  1426. UNICODE_STRING *
  1427. pSecretData = NULL;
  1428. DWORD
  1429. Status;
  1430. LICENSE_STATUS
  1431. LicenseStatus = LICENSE_STATUS_OK;
  1432. if( ( NULL == ptszKeyName ) || ( NULL == pcbKey ) )
  1433. {
  1434. return( ERROR_INVALID_PARAMETER );
  1435. }
  1436. //
  1437. // setup the UNICODE_STRINGs for the call.
  1438. //
  1439. InitLsaString( &SecretKeyName, ptszKeyName );
  1440. Status = OpenPolicy( NULL, POLICY_GET_PRIVATE_INFORMATION, &PolicyHandle );
  1441. if( ERROR_SUCCESS != Status )
  1442. {
  1443. #if DBG
  1444. DbgPrint( "LSCSP: cannot open LSA policy handle: %x\n", Status );
  1445. #endif
  1446. return( LICENSE_STATUS_CANNOT_OPEN_SECRET_STORE );
  1447. }
  1448. Status = LsaNtStatusToWinError( LsaRetrievePrivateData(
  1449. PolicyHandle,
  1450. &SecretKeyName,
  1451. &pSecretData ) );
  1452. LsaClose( PolicyHandle );
  1453. if (( ERROR_SUCCESS != Status ) || (NULL == pSecretData) || (pSecretData->Length == 0))
  1454. {
  1455. #if DBG
  1456. DbgPrint( "LSCSP: cannot retrieve LSA data: %x\n", Status );
  1457. #endif
  1458. return( LICENSE_STATUS_CANNOT_RETRIEVE_SECRET );
  1459. }
  1460. if( NULL == pbKey )
  1461. {
  1462. *pcbKey = pSecretData->Length;
  1463. }
  1464. else
  1465. {
  1466. if( pSecretData->Length > *pcbKey )
  1467. {
  1468. LicenseStatus = LICENSE_STATUS_INSUFFICIENT_BUFFER;
  1469. }
  1470. else
  1471. {
  1472. CopyMemory( pbKey, pSecretData->Buffer, pSecretData->Length );
  1473. }
  1474. *pcbKey = pSecretData->Length;
  1475. }
  1476. ZeroMemory( pSecretData->Buffer, pSecretData->Length );
  1477. LsaFreeMemory( pSecretData );
  1478. return( LicenseStatus );
  1479. }
  1480. /*++
  1481. Function:
  1482. OpenPolicy
  1483. Description:
  1484. Obtain an LSA policy handle used to perform subsequent LSA operations.
  1485. Arguments:
  1486. ServerName - The server which the handle should be obtained from.
  1487. DesiredAccess - The access given to the handle
  1488. PolicyHandle - The policy handle
  1489. Return:
  1490. A Win32 return code.
  1491. --*/
  1492. NTSTATUS
  1493. OpenPolicy(
  1494. LPWSTR ServerName,
  1495. DWORD DesiredAccess,
  1496. PLSA_HANDLE PolicyHandle )
  1497. {
  1498. LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  1499. LSA_UNICODE_STRING ServerString;
  1500. PLSA_UNICODE_STRING Server;
  1501. //
  1502. // Always initialize the object attributes to all zeroes.
  1503. //
  1504. ZeroMemory( &ObjectAttributes, sizeof( ObjectAttributes ) );
  1505. if( NULL != ServerName )
  1506. {
  1507. //
  1508. // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
  1509. //
  1510. InitLsaString(&ServerString, ServerName);
  1511. Server = &ServerString;
  1512. }
  1513. else
  1514. {
  1515. Server = NULL;
  1516. }
  1517. //
  1518. // Attempt to open the policy.
  1519. //
  1520. return( LsaNtStatusToWinError( LsaOpenPolicy(
  1521. Server,
  1522. &ObjectAttributes,
  1523. DesiredAccess,
  1524. PolicyHandle ) ) );
  1525. }
  1526. /*++
  1527. Function:
  1528. InitLsaString
  1529. Description:
  1530. Initialize a UNICODE string to LSA UNICODE string format.
  1531. Arguments:
  1532. LsaString - the LSA UNICODE string.
  1533. String - UNICODE string
  1534. Return:
  1535. Nothing.
  1536. --*/
  1537. void
  1538. InitLsaString(
  1539. PLSA_UNICODE_STRING LsaString,
  1540. LPWSTR String )
  1541. {
  1542. DWORD StringLength;
  1543. if( NULL == String )
  1544. {
  1545. LsaString->Buffer = NULL;
  1546. LsaString->Length = 0;
  1547. LsaString->MaximumLength = 0;
  1548. return;
  1549. }
  1550. StringLength = lstrlenW( String );
  1551. LsaString->Buffer = String;
  1552. LsaString->Length = ( USHORT ) StringLength * sizeof( WCHAR );
  1553. LsaString->MaximumLength=( USHORT )( StringLength + 1 ) * sizeof( WCHAR );
  1554. }
  1555. /*++
  1556. Function:
  1557. LsCsp_SetServerData
  1558. Description:
  1559. Saves the specified data.
  1560. Arguments:
  1561. Info - The data type of the data to be saved.
  1562. pBlob - Points to the data to be saved.
  1563. dwBlobLen - Length of the data to be saved.
  1564. Return:
  1565. A LICENSE_STATUS return code.
  1566. --*/
  1567. LICENSE_STATUS
  1568. LsCsp_SetServerData(
  1569. LSCSPINFO Info,
  1570. LPBYTE pBlob,
  1571. DWORD dwBlobLen )
  1572. {
  1573. LICENSE_STATUS
  1574. Status = LICENSE_STATUS_OK;
  1575. DWORD
  1576. dwResult,
  1577. dwDisp,
  1578. * pdwCspDataLen;
  1579. LPTSTR
  1580. lpRegValue;
  1581. PWCHAR
  1582. pwszKeyName;
  1583. LPBYTE *
  1584. ppCspData;
  1585. HKEY
  1586. hKey = NULL;
  1587. ASSERT( dwBlobLen != 0 );
  1588. ASSERT( pBlob != NULL );
  1589. ACQUIRE_EXCLUSIVE_ACCESS(csp_hMutex);
  1590. switch (Info) {
  1591. case LsCspInfo_Certificate:
  1592. //
  1593. // set proprietory certificate data
  1594. //
  1595. lpRegValue = TEXT( HYDRA_CERTIFICATE_VALUE );
  1596. ppCspData = &csp_abServerCertificate;
  1597. pdwCspDataLen = &csp_dwServerCertificateLen;
  1598. break;
  1599. case LsCspInfo_X509Certificate:
  1600. //
  1601. // set X509 certificate data
  1602. //
  1603. lpRegValue = TEXT( HYDRA_X509_CERTIFICATE );
  1604. ppCspData = &csp_abServerX509Cert;
  1605. pdwCspDataLen = &csp_dwServerX509CertLen;
  1606. break;
  1607. case LsCspInfo_PrivateKey:
  1608. //
  1609. // set the private key that corresponds to the proprietory certificate
  1610. //
  1611. pwszKeyName = PRIVATE_KEY_NAME;
  1612. ppCspData = &csp_abServerPrivateKey;
  1613. pdwCspDataLen = &csp_dwServerPrivateKeyLen;
  1614. break;
  1615. case LsCspInfo_X509CertPrivateKey:
  1616. //
  1617. // set private key that corresponds to the X509 certificate
  1618. //
  1619. pwszKeyName = X509_CERT_PRIVATE_KEY_NAME;
  1620. ppCspData = &csp_abX509CertPrivateKey;
  1621. pdwCspDataLen = &csp_dwX509CertPrivateKeyLen;
  1622. break;
  1623. case LsCspInfo_X509CertID:
  1624. //
  1625. // Set the X509 certificate ID
  1626. //
  1627. lpRegValue = TEXT( HYDRA_X509_CERT_ID );
  1628. ppCspData = &csp_abX509CertID;
  1629. pdwCspDataLen = &csp_dwX509CertIDLen;
  1630. break;
  1631. default:
  1632. Status = LICENSE_STATUS_INVALID_INPUT;
  1633. goto i_done;
  1634. }
  1635. if( ( LsCspInfo_X509CertPrivateKey == Info ) ||
  1636. ( LsCspInfo_PrivateKey == Info ) )
  1637. {
  1638. //
  1639. // store secret key information
  1640. //
  1641. dwResult = LsCsp_StoreSecret( pwszKeyName, pBlob, dwBlobLen );
  1642. if( ERROR_SUCCESS != dwResult )
  1643. {
  1644. Status = LICENSE_STATUS_WRITE_STORE_ERROR;
  1645. goto i_done;
  1646. }
  1647. }
  1648. else
  1649. {
  1650. //
  1651. // Open the Registry
  1652. //
  1653. if( RegCreateKeyEx(
  1654. HKEY_LOCAL_MACHINE,
  1655. TEXT( HYDRA_CERT_REG_KEY ),
  1656. 0,
  1657. NULL,
  1658. REG_OPTION_NON_VOLATILE,
  1659. KEY_WRITE,
  1660. NULL,
  1661. &hKey,
  1662. &dwDisp ) != ERROR_SUCCESS )
  1663. {
  1664. Status = LICENSE_STATUS_WRITE_STORE_ERROR;
  1665. goto i_done;
  1666. }
  1667. //
  1668. // Sets the value in the registry
  1669. //
  1670. if( ERROR_SUCCESS != RegSetValueEx(
  1671. hKey,
  1672. lpRegValue,
  1673. 0,
  1674. REG_BINARY,
  1675. pBlob,
  1676. dwBlobLen ) )
  1677. {
  1678. Status = LICENSE_STATUS_WRITE_STORE_ERROR;
  1679. goto i_done;
  1680. }
  1681. }
  1682. //
  1683. // reset the global data with the new data that we have just set
  1684. //
  1685. if ( *ppCspData )
  1686. {
  1687. LocalFree( *ppCspData );
  1688. }
  1689. *ppCspData = ( LPBYTE )LocalAlloc( LPTR, dwBlobLen );
  1690. if( NULL == *ppCspData )
  1691. {
  1692. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  1693. goto i_done;
  1694. }
  1695. memcpy( *ppCspData, pBlob, dwBlobLen );
  1696. *pdwCspDataLen = dwBlobLen;
  1697. i_done:
  1698. RELEASE_EXCLUSIVE_ACCESS( csp_hMutex );
  1699. if( hKey )
  1700. {
  1701. RegCloseKey( hKey );
  1702. }
  1703. return( Status );
  1704. }
  1705. /*++
  1706. Function:
  1707. LsCsp_NukeServerData
  1708. Description:
  1709. Permanently deletes the specified server data.
  1710. Arguments:
  1711. Info - The type of data to nuke.
  1712. Returns:
  1713. A LICENSE_STATUS return code.
  1714. --*/
  1715. LICENSE_STATUS
  1716. LsCsp_NukeServerData(
  1717. LSCSPINFO Info )
  1718. {
  1719. LICENSE_STATUS
  1720. Status = LICENSE_STATUS_OK;
  1721. LPTSTR
  1722. lpRegValue;
  1723. PWCHAR
  1724. pwszKeyName;
  1725. HKEY
  1726. hKey = NULL;
  1727. LPBYTE *
  1728. ppCspData;
  1729. DWORD *
  1730. pdwCspDataLen;
  1731. DWORD
  1732. dwResult;
  1733. ACQUIRE_EXCLUSIVE_ACCESS(csp_hMutex);
  1734. switch (Info) {
  1735. case LsCspInfo_X509Certificate:
  1736. //
  1737. // delete X509 certificate data
  1738. //
  1739. lpRegValue = TEXT( HYDRA_X509_CERTIFICATE );
  1740. ppCspData = &csp_abServerX509Cert;
  1741. pdwCspDataLen = &csp_dwServerX509CertLen;
  1742. break;
  1743. case LsCspInfo_X509CertPrivateKey:
  1744. //
  1745. // delete the private key that corresponds to the X509 certificate
  1746. //
  1747. pwszKeyName = X509_CERT_PRIVATE_KEY_NAME;
  1748. ppCspData = &csp_abX509CertPrivateKey;
  1749. pdwCspDataLen = &csp_dwX509CertPrivateKeyLen;
  1750. break;
  1751. case LsCspInfo_X509CertID:
  1752. //
  1753. // delete the X509 certificate ID
  1754. //
  1755. lpRegValue = TEXT( HYDRA_X509_CERT_ID );
  1756. ppCspData = &csp_abX509CertID;
  1757. pdwCspDataLen = &csp_dwX509CertIDLen;
  1758. break;
  1759. default:
  1760. Status = LICENSE_STATUS_INVALID_INPUT;
  1761. goto i_done;
  1762. }
  1763. if( (LsCspInfo_X509CertPrivateKey == Info ) ||
  1764. ( LsCspInfo_PrivateKey == Info ) )
  1765. {
  1766. //
  1767. // delete secret info stored by LSA
  1768. //
  1769. dwResult = LsCsp_StoreSecret( pwszKeyName, NULL, 0 );
  1770. if( ERROR_SUCCESS != dwResult )
  1771. {
  1772. Status = LICENSE_STATUS_WRITE_STORE_ERROR;
  1773. goto i_done;
  1774. }
  1775. }
  1776. else
  1777. {
  1778. //
  1779. // Delete the data kept in the registry
  1780. //
  1781. if( RegOpenKeyEx(
  1782. HKEY_LOCAL_MACHINE,
  1783. TEXT( HYDRA_CERT_REG_KEY ),
  1784. 0,
  1785. KEY_WRITE,
  1786. &hKey ) != ERROR_SUCCESS )
  1787. {
  1788. Status = LICENSE_STATUS_WRITE_STORE_ERROR;
  1789. goto i_done;
  1790. }
  1791. //
  1792. // Delete the value in the registry
  1793. //
  1794. if( ERROR_SUCCESS != RegDeleteValue( hKey, lpRegValue ) )
  1795. {
  1796. Status = LICENSE_STATUS_WRITE_STORE_ERROR;
  1797. goto i_done;
  1798. }
  1799. }
  1800. if ( *ppCspData )
  1801. {
  1802. //
  1803. // free the memory allocated for the global variable.
  1804. //
  1805. LocalFree( *ppCspData );
  1806. *ppCspData = NULL;
  1807. *pdwCspDataLen = 0;
  1808. }
  1809. i_done:
  1810. RELEASE_EXCLUSIVE_ACCESS( csp_hMutex );
  1811. if( hKey )
  1812. {
  1813. RegCloseKey( hKey );
  1814. }
  1815. return( Status );
  1816. }
  1817. /*++
  1818. Function:
  1819. GenerateKeyPair
  1820. Routine Description:
  1821. This function generates a private/public key pair.
  1822. Arguments:
  1823. ppbPublicKey - Return pointer to public Key
  1824. pcbPublicKey - Size of public key
  1825. ppbPrivateKey - Return pointer to private key
  1826. pcbPrivateKey - size of private key
  1827. dwKeyLen - Desired key length
  1828. Return Value:
  1829. LICENSE_STATUS return code.
  1830. --*/
  1831. LICENSE_STATUS
  1832. GenerateRsaKeyPair(
  1833. LPBYTE * ppbPublicKey,
  1834. LPDWORD pcbPublicKey,
  1835. LPBYTE * ppbPrivateKey,
  1836. LPDWORD pcbPrivateKey,
  1837. DWORD dwKeyLen )
  1838. {
  1839. DWORD
  1840. dwBits = dwKeyLen;
  1841. LICENSE_STATUS
  1842. Status = LICENSE_STATUS_OK;
  1843. *ppbPublicKey = NULL;
  1844. *ppbPrivateKey = NULL;
  1845. //
  1846. // find out the size of the private and public key sizes and allocate
  1847. // memory for them.
  1848. //
  1849. dwBits = BSafeComputeKeySizes( pcbPublicKey, pcbPrivateKey, &dwBits );
  1850. *ppbPrivateKey = ( LPBYTE )LocalAlloc( LPTR, *pcbPrivateKey );
  1851. if( NULL == *ppbPrivateKey )
  1852. {
  1853. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  1854. goto ErrorExit;
  1855. }
  1856. *ppbPublicKey = ( LPBYTE )LocalAlloc( LPTR, *pcbPublicKey );
  1857. if( NULL == *ppbPublicKey )
  1858. {
  1859. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  1860. goto ErrorExit;
  1861. }
  1862. //
  1863. // generate the private/public key pair
  1864. //
  1865. if( !BSafeMakeKeyPair( ( LPBSAFE_PUB_KEY )*ppbPublicKey,
  1866. ( LPBSAFE_PRV_KEY )*ppbPrivateKey,
  1867. dwKeyLen) )
  1868. {
  1869. Status = LICENSE_STATUS_CANNOT_MAKE_KEY_PAIR;
  1870. goto ErrorExit;
  1871. }
  1872. return( Status );
  1873. ErrorExit:
  1874. if( *ppbPublicKey )
  1875. {
  1876. LocalFree( *ppbPublicKey );
  1877. *pcbPublicKey = 0;
  1878. *ppbPublicKey = NULL;
  1879. }
  1880. if( *ppbPrivateKey )
  1881. {
  1882. LocalFree( *ppbPrivateKey );
  1883. *pcbPrivateKey = 0;
  1884. *ppbPrivateKey = NULL;
  1885. }
  1886. return( Status );
  1887. }
  1888. /*++
  1889. Function:
  1890. Bsafe2CapiPubKey
  1891. Routine Description:
  1892. Converts a Bsafe public key to a CAPI public key info structure
  1893. Arguments:
  1894. pCapiPubKeyInfo - Pointer to the CAPI public key info structure
  1895. pbBsafePubKey - Pointer to the Bsafe public key
  1896. cbBsafePubKey - size of the Bsafe public key
  1897. Returns:
  1898. LICENSE_STATUS return code.
  1899. --*/
  1900. LICENSE_STATUS
  1901. Bsafe2CapiPubKey(
  1902. PCERT_PUBLIC_KEY_INFO pCapiPubKeyInfo,
  1903. LPBYTE pbBsafeKey,
  1904. DWORD cbBsafeKey )
  1905. {
  1906. PUBLICKEYSTRUC *
  1907. pCapiPublicKey;
  1908. RSAPUBKEY *
  1909. pRsaPublicKey;
  1910. LPBSAFE_PUB_KEY
  1911. pBsafePubKey = ( LPBSAFE_PUB_KEY )pbBsafeKey;
  1912. LPBYTE
  1913. pbKeyMem = NULL,
  1914. pbEncodedPubKey = NULL;
  1915. DWORD
  1916. cbKeyMem,
  1917. dwError,
  1918. cbEncodedPubKey = 0;
  1919. LICENSE_STATUS
  1920. Status;
  1921. if( ( NULL == pbBsafeKey ) || ( 0 == cbBsafeKey ) )
  1922. {
  1923. return( LICENSE_STATUS_INVALID_INPUT );
  1924. }
  1925. cbKeyMem = sizeof( PUBLICKEYSTRUC ) + sizeof( RSAPUBKEY ) + pBsafePubKey->keylen;
  1926. pbKeyMem = ( LPBYTE )LocalAlloc( LPTR, cbKeyMem );
  1927. if( NULL == pbKeyMem )
  1928. {
  1929. return( LICENSE_STATUS_OUT_OF_MEMORY );
  1930. }
  1931. //
  1932. // convert the Bsafe public key to a crypto API public key structure.
  1933. // Note: make this a key exchange public key
  1934. //
  1935. pCapiPublicKey = ( PUBLICKEYSTRUC * )pbKeyMem;
  1936. pCapiPublicKey->bType = PUBLICKEYBLOB;
  1937. pCapiPublicKey->bVersion = CAPI_MAX_VERSION;
  1938. pCapiPublicKey->reserved = 0;
  1939. pCapiPublicKey->aiKeyAlg = CALG_RSA_KEYX;
  1940. pRsaPublicKey = ( RSAPUBKEY * )( pbKeyMem + sizeof( PUBLICKEYSTRUC ) );
  1941. pRsaPublicKey->magic = RSA1;
  1942. pRsaPublicKey->bitlen = pBsafePubKey->bitlen;
  1943. pRsaPublicKey->pubexp = pBsafePubKey->pubexp;
  1944. memcpy( pbKeyMem + sizeof( PUBLICKEYSTRUC ) + sizeof( RSAPUBKEY ),
  1945. pbBsafeKey + sizeof( BSAFE_PUB_KEY ),
  1946. pBsafePubKey->keylen );
  1947. //
  1948. // encode the public key structure
  1949. //
  1950. __try
  1951. {
  1952. if( CryptEncodeObject( X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB , pbKeyMem,
  1953. NULL, &cbEncodedPubKey ) )
  1954. {
  1955. pbEncodedPubKey = ( LPBYTE )LocalAlloc( LPTR, cbEncodedPubKey );
  1956. if( NULL == pbEncodedPubKey )
  1957. {
  1958. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  1959. goto done;
  1960. }
  1961. memset( pbEncodedPubKey, 0, cbEncodedPubKey );
  1962. if( !CryptEncodeObject( X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB , pbKeyMem,
  1963. pbEncodedPubKey, &cbEncodedPubKey ) )
  1964. {
  1965. Status = LICENSE_STATUS_ASN_ERROR;
  1966. goto done;
  1967. }
  1968. }
  1969. }
  1970. __except( EXCEPTION_EXECUTE_HANDLER )
  1971. {
  1972. DWORD dwExceptionCode = GetExceptionCode();
  1973. #if DBG
  1974. DbgPrint( "LICECSP: cannot encode server key pair: 0x%x\n", dwExceptionCode );
  1975. #endif
  1976. Status = LICENSE_STATUS_ASN_ERROR;
  1977. goto done;
  1978. }
  1979. //
  1980. // now we can initialize the CAPI public key info structure
  1981. //
  1982. memset( pCapiPubKeyInfo, 0, sizeof( CERT_PUBLIC_KEY_INFO ) );
  1983. pCapiPubKeyInfo->Algorithm.pszObjId = szOID_RSA_MD5RSA;
  1984. pCapiPubKeyInfo->Algorithm.Parameters.cbData = 0;
  1985. pCapiPubKeyInfo->Algorithm.Parameters.pbData = NULL;
  1986. pCapiPubKeyInfo->PublicKey.cbData = cbEncodedPubKey;
  1987. pCapiPubKeyInfo->PublicKey.pbData = pbEncodedPubKey;
  1988. Status = LICENSE_STATUS_OK;
  1989. done:
  1990. if( pbKeyMem )
  1991. {
  1992. LocalFree( pbKeyMem );
  1993. }
  1994. return( Status );
  1995. }
  1996. /*++
  1997. Function:
  1998. FreeCapiPubKey
  1999. Routine Description:
  2000. Free the memory in a capi pub key structure
  2001. Arguments:
  2002. pCapiPubKeyInfo - Pointer to the CAPI public key info structure
  2003. Returns:
  2004. Windows return code.
  2005. --*/
  2006. VOID
  2007. FreeCapiPubKey(
  2008. PCERT_PUBLIC_KEY_INFO pCapiPubKeyInfo )
  2009. {
  2010. if( pCapiPubKeyInfo->Algorithm.Parameters.pbData )
  2011. {
  2012. LocalFree( pCapiPubKeyInfo->Algorithm.Parameters.pbData );
  2013. pCapiPubKeyInfo->Algorithm.Parameters.pbData = NULL;
  2014. }
  2015. if( pCapiPubKeyInfo->PublicKey.pbData )
  2016. {
  2017. LocalFree( pCapiPubKeyInfo->PublicKey.pbData );
  2018. pCapiPubKeyInfo->PublicKey.pbData = NULL;
  2019. }
  2020. return;
  2021. }
  2022. //////////////////////////////////////////////////////////////////
  2023. DWORD
  2024. VerifyTermServCertificate(
  2025. DWORD cbCertLen,
  2026. PBYTE pbCert,
  2027. DWORD cbPrivateKeyLen,
  2028. PBYTE pbPrivateKey
  2029. )
  2030. /*++
  2031. Function :
  2032. VerifyTermServCertificate
  2033. Routine Description:
  2034. Verify TermSrv's X509 Certificate issued License Server, caller
  2035. must protect this call with critical section or mutex.
  2036. Arguments:
  2037. cbCertLen : size of TermSrv certificate.
  2038. pbCertLen : Pointer to TermSrv certificate to be verify.
  2039. cbPrivateKeyLen : Size of TermSrv private key.
  2040. pbPrivateKey : pointer to TermSrv private key.
  2041. Returns:
  2042. TRUE/FALSE
  2043. --*/
  2044. {
  2045. LICENSE_STATUS dwStatus = LICENSE_STATUS_OK;
  2046. PBYTE pbPublicKeyInLsa = NULL;
  2047. DWORD cbPublicKeyInLsa = 0;
  2048. PBYTE pbPublicKeyInCert = NULL;
  2049. DWORD cbPublicKeyInCert = 0;
  2050. DWORD pfDates;
  2051. CERT_PUBLIC_KEY_INFO CapiPubKeyInfoLsa;
  2052. CERT_PUBLIC_KEY_INFO CapiPubKeyInfoCert;
  2053. if(0 == cbCertLen || NULL == pbCert || 0 == cbPrivateKeyLen || NULL == pbPrivateKey)
  2054. {
  2055. ASSERT( 0 != cbCertLen && NULL != pbCert && 0 != cbPrivateKeyLen && NULL != pbPrivateKey );
  2056. return LICENSE_STATUS_INVALID_INPUT;
  2057. }
  2058. //
  2059. // try except here is to prevent memory leak
  2060. //
  2061. __try {
  2062. memset(&CapiPubKeyInfoLsa, 0, sizeof(CapiPubKeyInfoLsa));
  2063. memset(&CapiPubKeyInfoCert, 0, sizeof(CapiPubKeyInfoCert));
  2064. //
  2065. // Load the public key from LSA
  2066. //
  2067. dwStatus = LsCsp_RetrieveSecret(
  2068. X509_CERT_PUBLIC_KEY_NAME,
  2069. NULL,
  2070. &cbPublicKeyInLsa
  2071. );
  2072. if( LICENSE_STATUS_OK != dwStatus || 0 == cbPublicKeyInLsa )
  2073. {
  2074. #if DBG
  2075. DbgPrint( "LSCSP: VerifyTermServCertificate() No public key...\n" );
  2076. #endif
  2077. dwStatus = LICENSE_STATUS_CANNOT_RETRIEVE_SECRET;
  2078. goto cleanup;
  2079. }
  2080. // allocate memory
  2081. pbPublicKeyInLsa = (PBYTE)LocalAlloc(LPTR, cbPublicKeyInLsa);
  2082. if(NULL == pbPublicKeyInLsa)
  2083. {
  2084. dwStatus = LICENSE_STATUS_OUT_OF_MEMORY;
  2085. goto cleanup;
  2086. }
  2087. dwStatus = LsCsp_RetrieveSecret(
  2088. X509_CERT_PUBLIC_KEY_NAME,
  2089. pbPublicKeyInLsa,
  2090. &cbPublicKeyInLsa
  2091. );
  2092. if( LICENSE_STATUS_OK != dwStatus || 0 == cbPublicKeyInLsa )
  2093. {
  2094. dwStatus = LICENSE_STATUS_CANNOT_RETRIEVE_SECRET;
  2095. goto cleanup;
  2096. }
  2097. //
  2098. // Verify certificate and compare public key
  2099. //
  2100. //
  2101. // Try to avoid calling VerifyCertChain() twice.
  2102. //
  2103. cbPublicKeyInCert = 1024;
  2104. pbPublicKeyInCert = (PBYTE)LocalAlloc(LPTR, cbPublicKeyInCert);
  2105. if(NULL == pbPublicKeyInCert)
  2106. {
  2107. dwStatus = LICENSE_STATUS_OUT_OF_MEMORY;
  2108. goto cleanup;
  2109. }
  2110. pfDates = CERT_DATE_DONT_VALIDATE;
  2111. dwStatus = VerifyCertChain(
  2112. pbCert,
  2113. cbCertLen,
  2114. pbPublicKeyInCert,
  2115. &cbPublicKeyInCert,
  2116. &pfDates
  2117. );
  2118. if(LICENSE_STATUS_OK != dwStatus && LICENSE_STATUS_INSUFFICIENT_BUFFER != dwStatus)
  2119. {
  2120. #if DBG
  2121. DbgPrint( "LSCSP: VerifyCertChain() failed with error code %d\n", dwStatus );
  2122. #endif
  2123. goto cleanup;
  2124. }
  2125. if( dwStatus == LICENSE_STATUS_INSUFFICIENT_BUFFER )
  2126. {
  2127. if( NULL != pbPublicKeyInCert )
  2128. {
  2129. LocalFree(pbPublicKeyInCert);
  2130. }
  2131. pbPublicKeyInCert = (PBYTE)LocalAlloc(LPTR, cbPublicKeyInCert);
  2132. if(NULL == pbPublicKeyInCert)
  2133. {
  2134. dwStatus = LICENSE_STATUS_OUT_OF_MEMORY;
  2135. goto cleanup;
  2136. }
  2137. pfDates = CERT_DATE_DONT_VALIDATE;
  2138. dwStatus = VerifyCertChain(
  2139. pbCert,
  2140. cbCertLen,
  2141. pbPublicKeyInCert,
  2142. &cbPublicKeyInCert,
  2143. &pfDates
  2144. );
  2145. if(LICENSE_STATUS_OK != dwStatus)
  2146. {
  2147. goto cleanup;
  2148. }
  2149. }
  2150. dwStatus = Bsafe2CapiPubKey(
  2151. &CapiPubKeyInfoCert,
  2152. pbPublicKeyInCert,
  2153. cbPublicKeyInCert
  2154. );
  2155. if(LICENSE_STATUS_OK != dwStatus)
  2156. {
  2157. #if DBG
  2158. DbgPrint(
  2159. "LSCSP: Bsafe2CapiPubKey() on public key in certificate failed with %d\n",
  2160. dwStatus
  2161. );
  2162. #endif
  2163. goto cleanup;
  2164. }
  2165. dwStatus = Bsafe2CapiPubKey(
  2166. &CapiPubKeyInfoLsa,
  2167. pbPublicKeyInLsa,
  2168. cbPublicKeyInLsa
  2169. );
  2170. if(LICENSE_STATUS_OK != dwStatus)
  2171. {
  2172. #if DBG
  2173. DbgPrint(
  2174. "LSCSP: Bsafe2CapiPubKey() on public key in LSA failed with %d\n",
  2175. dwStatus
  2176. );
  2177. #endif
  2178. goto cleanup;
  2179. }
  2180. //
  2181. // compare public key
  2182. //
  2183. if( CapiPubKeyInfoCert.PublicKey.cbData != CapiPubKeyInfoLsa.PublicKey.cbData )
  2184. {
  2185. #if DBG
  2186. DbgPrint(
  2187. "LSCSP: public key length mismatched %d %d\n",
  2188. CapiPubKeyInfoCert.PublicKey.cbData,
  2189. CapiPubKeyInfoLsa.PublicKey.cbData
  2190. );
  2191. #endif
  2192. dwStatus = LICENSE_STATUS_INVALID_CERTIFICATE;
  2193. }
  2194. else if( memcmp(
  2195. CapiPubKeyInfoCert.PublicKey.pbData,
  2196. CapiPubKeyInfoLsa.PublicKey.pbData,
  2197. CapiPubKeyInfoLsa.PublicKey.cbData
  2198. ) != 0 )
  2199. {
  2200. #if DBG
  2201. DbgPrint( "LSCSP: public mismatched\n" );
  2202. #endif
  2203. dwStatus = LICENSE_STATUS_INVALID_CERTIFICATE;
  2204. }
  2205. }
  2206. __except( EXCEPTION_EXECUTE_HANDLER ) {
  2207. dwStatus = LICENSE_STATUS_INVALID_INPUT;
  2208. }
  2209. cleanup:
  2210. FreeCapiPubKey( &CapiPubKeyInfoCert );
  2211. FreeCapiPubKey( &CapiPubKeyInfoLsa );
  2212. if( NULL != pbPublicKeyInLsa )
  2213. {
  2214. LocalFree( pbPublicKeyInLsa );
  2215. }
  2216. if( NULL != pbPublicKeyInCert )
  2217. {
  2218. LocalFree( pbPublicKeyInCert );
  2219. }
  2220. return dwStatus;
  2221. }
  2222. //////////////////////////////////////////////////////////////////
  2223. LICENSE_STATUS
  2224. ReloadCSPCertificateAndData()
  2225. {
  2226. BOOL bSuccess;
  2227. DWORD Status = LICENSE_STATUS_OK;
  2228. LPBYTE i_csp_abServerX509Cert = NULL;
  2229. DWORD i_csp_dwServerX509CertLen = 0;
  2230. DWORD i_csp_dwX509CertPrivateKeyLen = 0;
  2231. LPBYTE i_csp_abX509CertPrivateKey = NULL;
  2232. LPBYTE i_csp_abX509CertID = NULL;
  2233. DWORD i_csp_dwX509CertIDLen = 0;
  2234. HKEY hKey = NULL;
  2235. DWORD dwResult, dwDisp;
  2236. //
  2237. // Acquire exclusive access
  2238. //
  2239. ACQUIRE_EXCLUSIVE_ACCESS( csp_hMutex );
  2240. //
  2241. // Prevent re-loading of same certificate/private key
  2242. //
  2243. if( NULL == csp_abServerX509Cert || 0 == csp_dwServerX509CertLen ||
  2244. NULL == csp_abX509CertPrivateKey || 0 == csp_dwX509CertPrivateKeyLen ||
  2245. NULL == csp_abX509CertID || 0 == csp_dwX509CertIDLen )
  2246. {
  2247. //
  2248. // Open the Registry
  2249. //
  2250. if( RegCreateKeyEx(
  2251. HKEY_LOCAL_MACHINE,
  2252. TEXT( HYDRA_CERT_REG_KEY ),
  2253. 0,
  2254. NULL,
  2255. REG_OPTION_NON_VOLATILE,
  2256. KEY_READ | KEY_WRITE,
  2257. NULL,
  2258. &hKey,
  2259. &dwDisp ) != ERROR_SUCCESS )
  2260. {
  2261. Status = LICENSE_STATUS_NO_CERTIFICATE;
  2262. }
  2263. else
  2264. {
  2265. __try {
  2266. //
  2267. // Get the X509 certificate from the registry.
  2268. //
  2269. Status = LsCsp_GetBinaryData(
  2270. hKey,
  2271. TEXT( HYDRA_X509_CERTIFICATE ),
  2272. &i_csp_abServerX509Cert,
  2273. &i_csp_dwServerX509CertLen
  2274. );
  2275. if( LICENSE_STATUS_OK == Status && 0 != i_csp_dwServerX509CertLen )
  2276. {
  2277. //
  2278. // Get the corresponding private key from the store.
  2279. // It is not OK if we have the X509 certificate but not the
  2280. // private key that goes with it.
  2281. //
  2282. Status = LsCsp_RetrieveSecret(
  2283. X509_CERT_PRIVATE_KEY_NAME,
  2284. NULL,
  2285. &i_csp_dwX509CertPrivateKeyLen
  2286. );
  2287. if( LICENSE_STATUS_OK == Status )
  2288. {
  2289. i_csp_abX509CertPrivateKey = LocalAlloc( LPTR, i_csp_dwX509CertPrivateKeyLen );
  2290. if( NULL != i_csp_abX509CertPrivateKey )
  2291. {
  2292. Status = LsCsp_RetrieveSecret(
  2293. X509_CERT_PRIVATE_KEY_NAME,
  2294. i_csp_abX509CertPrivateKey,
  2295. &i_csp_dwX509CertPrivateKeyLen
  2296. );
  2297. if(LICENSE_STATUS_OK == Status)
  2298. {
  2299. //
  2300. // Get the certificate ID for the X509 certificate
  2301. //
  2302. Status = LsCsp_GetBinaryData(
  2303. hKey,
  2304. TEXT( HYDRA_X509_CERT_ID ),
  2305. &i_csp_abX509CertID,
  2306. &i_csp_dwX509CertIDLen
  2307. );
  2308. }
  2309. }
  2310. else // memory allocate
  2311. {
  2312. Status = LICENSE_STATUS_OUT_OF_MEMORY;
  2313. }
  2314. }
  2315. }
  2316. else
  2317. {
  2318. Status = LICENSE_STATUS_NO_CERTIFICATE;
  2319. }
  2320. }
  2321. __except( EXCEPTION_EXECUTE_HANDLER ) {
  2322. Status = LICENSE_STATUS_INVALID_INPUT;
  2323. }
  2324. }
  2325. //
  2326. // verify our certificate
  2327. //
  2328. if(LICENSE_STATUS_OK == Status)
  2329. {
  2330. Status = VerifyTermServCertificate(
  2331. i_csp_dwServerX509CertLen,
  2332. i_csp_abServerX509Cert,
  2333. i_csp_dwX509CertPrivateKeyLen,
  2334. i_csp_abX509CertPrivateKey
  2335. );
  2336. if( LICENSE_STATUS_OK != Status )
  2337. {
  2338. //
  2339. // Deleting the X509 certificate is enough.
  2340. //
  2341. RegDeleteValue( hKey, TEXT( HYDRA_X509_CERTIFICATE ) );
  2342. }
  2343. }
  2344. if(LICENSE_STATUS_OK != Status)
  2345. {
  2346. if( NULL != i_csp_abServerX509Cert )
  2347. {
  2348. LocalFree( i_csp_abServerX509Cert );
  2349. }
  2350. if( NULL != i_csp_abX509CertPrivateKey )
  2351. {
  2352. LocalFree( i_csp_abX509CertPrivateKey );
  2353. }
  2354. if( NULL != i_csp_abX509CertID )
  2355. {
  2356. LocalFree( i_csp_abX509CertID );
  2357. }
  2358. }
  2359. else
  2360. {
  2361. csp_abServerX509Cert = i_csp_abServerX509Cert;
  2362. csp_dwServerX509CertLen = i_csp_dwServerX509CertLen;
  2363. csp_dwX509CertPrivateKeyLen = i_csp_dwX509CertPrivateKeyLen;
  2364. csp_abX509CertPrivateKey = i_csp_abX509CertPrivateKey;
  2365. csp_abX509CertID = i_csp_abX509CertID;
  2366. csp_dwX509CertIDLen = i_csp_dwX509CertIDLen;
  2367. }
  2368. }
  2369. RELEASE_EXCLUSIVE_ACCESS( csp_hMutex );
  2370. if (hKey)
  2371. {
  2372. RegCloseKey(hKey);
  2373. }
  2374. return Status;
  2375. }
  2376. LICENSE_STATUS
  2377. CreateProprietaryKeyAndCert(
  2378. PBYTE *ppbPrivateKey,
  2379. DWORD *pcbPrivateKey,
  2380. PBYTE *ppbServerCert,
  2381. DWORD *pcbServerCert
  2382. )
  2383. {
  2384. #define MD5RSA 0x01;
  2385. #define RSAKEY 0x01;
  2386. LPBSAFE_PRV_KEY PRV;
  2387. Hydra_Server_Cert Cert;
  2388. DWORD KeyLen = 512;
  2389. DWORD bits, j;
  2390. DWORD dwPubSize, dwPrivSize;
  2391. BYTE *kPublic;
  2392. BYTE *kPrivate;
  2393. MD5_CTX HashState;
  2394. PBYTE pbData, pbTemp = NULL;
  2395. DWORD dwTemp = 0;
  2396. BYTE pbHash[0x48];
  2397. BYTE Output[0x48];
  2398. unsigned char prvmodulus[] =
  2399. {
  2400. 0x00, 0x00, 0x00, 0x00,
  2401. 0x00, 0x00, 0x00, 0x00,
  2402. 0x00, 0x00, 0x00, 0x00,
  2403. 0x00, 0x00, 0x00, 0x00,
  2404. 0x00, 0x00, 0x00, 0x00,
  2405. 0x3d, 0x3a, 0x5e, 0xbd,
  2406. 0x72, 0x43, 0x3e, 0xc9, 0x4d, 0xbb, 0xc1, 0x1e,
  2407. 0x4a, 0xba, 0x5f, 0xcb, 0x3e, 0x88, 0x20, 0x87,
  2408. 0xef, 0xf5, 0xc1, 0xe2, 0xd7, 0xb7, 0x6b, 0x9a,
  2409. 0xf2, 0x52, 0x45, 0x95, 0xce, 0x63, 0x65, 0x6b,
  2410. 0x58, 0x3a, 0xfe, 0xef, 0x7c, 0xe7, 0xbf, 0xfe,
  2411. 0x3d, 0xf6, 0x5c, 0x7d, 0x6c, 0x5e, 0x06, 0x09,
  2412. 0x1a, 0xf5, 0x61, 0xbb, 0x20, 0x93, 0x09, 0x5f,
  2413. 0x05, 0x6d, 0xea, 0x87, 0x00, 0x00, 0x00, 0x00,
  2414. 0x00, 0x00, 0x00, 0x00, 0x3f, 0xbd, 0x29, 0x20,
  2415. 0x57, 0xd2, 0x3b, 0xf1, 0x07, 0xfa, 0xdf, 0xc1,
  2416. 0x16, 0x31, 0xe4, 0x95, 0xea, 0xc1, 0x2a, 0x46,
  2417. 0x2b, 0xad, 0x88, 0x57, 0x55, 0xf0, 0x57, 0x58,
  2418. 0xc6, 0x6f, 0x95, 0xeb, 0x00, 0x00, 0x00, 0x00,
  2419. 0x83, 0xdd, 0x9d, 0xd0, 0x03, 0xb1, 0x5a, 0x9b,
  2420. 0x9e, 0xb4, 0x63, 0x02, 0x43, 0x3e, 0xdf, 0xb0,
  2421. 0x52, 0x83, 0x5f, 0x6a, 0x03, 0xe7, 0xd6, 0x78,
  2422. 0x45, 0x83, 0x6a, 0x5b, 0xc4, 0xcb, 0xb1, 0x93,
  2423. 0x00, 0x00, 0x00, 0x00, 0x65, 0x9d, 0x43, 0xe8,
  2424. 0x48, 0x17, 0xcd, 0x29, 0x7e, 0xb9, 0x26, 0x5c,
  2425. 0x79, 0x66, 0x58, 0x61, 0x72, 0x86, 0x6a, 0xa3,
  2426. 0x63, 0xad, 0x63, 0xb8, 0xe1, 0x80, 0x4c, 0x0f,
  2427. 0x36, 0x7d, 0xd9, 0xa6, 0x00, 0x00, 0x00, 0x00,
  2428. 0x75, 0x3f, 0xef, 0x5a, 0x01, 0x5f, 0xf6, 0x0e,
  2429. 0xd7, 0xcd, 0x59, 0x1c, 0xc6, 0xec, 0xde, 0xf3,
  2430. 0x5a, 0x03, 0x09, 0xff, 0xf5, 0x23, 0xcc, 0x90,
  2431. 0x27, 0x1d, 0xaa, 0x29, 0x60, 0xde, 0x05, 0x6e,
  2432. 0x00, 0x00, 0x00, 0x00, 0xc0, 0x17, 0x0e, 0x57,
  2433. 0xf8, 0x9e, 0xd9, 0x5c, 0xf5, 0xb9, 0x3a, 0xfc,
  2434. 0x0e, 0xe2, 0x33, 0x27, 0x59, 0x1d, 0xd0, 0x97,
  2435. 0x4a, 0xb1, 0xb1, 0x1f, 0xc3, 0x37, 0xd1, 0xd6,
  2436. 0xe6, 0x9b, 0x35, 0xab, 0x00, 0x00, 0x00, 0x00,
  2437. 0x87, 0xa7, 0x19, 0x32, 0xda, 0x11, 0x87, 0x55,
  2438. 0x58, 0x00, 0x16, 0x16, 0x25, 0x65, 0x68, 0xf8,
  2439. 0x24, 0x3e, 0xe6, 0xfa, 0xe9, 0x67, 0x49, 0x94,
  2440. 0xcf, 0x92, 0xcc, 0x33, 0x99, 0xe8, 0x08, 0x60,
  2441. 0x17, 0x9a, 0x12, 0x9f, 0x24, 0xdd, 0xb1, 0x24,
  2442. 0x99, 0xc7, 0x3a, 0xb8, 0x0a, 0x7b, 0x0d, 0xdd,
  2443. 0x35, 0x07, 0x79, 0x17, 0x0b, 0x51, 0x9b, 0xb3,
  2444. 0xc7, 0x10, 0x01, 0x13, 0xe7, 0x3f, 0xf3, 0x5f,
  2445. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2446. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2447. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2448. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2449. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  2450. 0x00, 0x00, 0x00, 0x00
  2451. };
  2452. PRV = (LPBSAFE_PRV_KEY)prvmodulus;
  2453. PRV->magic = RSA2;
  2454. PRV->keylen = 0x48;
  2455. PRV->bitlen = 0x0200;
  2456. PRV->datalen = 0x3f;
  2457. PRV->pubexp = 0xc0887b5b;
  2458. Cert.dwVersion = 0x01;
  2459. Cert.dwSigAlgID = MD5RSA;
  2460. Cert.dwKeyAlgID = RSAKEY;
  2461. bits = KeyLen;
  2462. if (!BSafeComputeKeySizes(&dwPubSize, &dwPrivSize, &bits))
  2463. {
  2464. return LICENSE_STATUS_INVALID_INPUT;
  2465. }
  2466. if ((kPrivate = (BYTE *)LocalAlloc(LPTR,dwPrivSize)) == NULL)
  2467. {
  2468. return LICENSE_STATUS_OUT_OF_MEMORY;
  2469. }
  2470. if ((kPublic = (BYTE *)LocalAlloc(LPTR,dwPubSize)) == NULL)
  2471. {
  2472. LocalFree(kPrivate);
  2473. return LICENSE_STATUS_OUT_OF_MEMORY;
  2474. }
  2475. if (!BSafeMakeKeyPair((LPBSAFE_PUB_KEY)kPublic,
  2476. (LPBSAFE_PRV_KEY)kPrivate,
  2477. KeyLen))
  2478. {
  2479. LocalFree(kPrivate);
  2480. LocalFree(kPublic);
  2481. return LICENSE_STATUS_OUT_OF_MEMORY;
  2482. }
  2483. // make proprietary format cert
  2484. Cert.PublicKeyData.wBlobType = BB_RSA_KEY_BLOB;
  2485. Cert.PublicKeyData.wBlobLen = (WORD)dwPubSize;
  2486. if( NULL == (Cert.PublicKeyData.pBlob = (PBYTE)LocalAlloc(LPTR,dwPubSize) ) )
  2487. {
  2488. LocalFree(kPrivate);
  2489. LocalFree(kPublic);
  2490. return LICENSE_STATUS_OUT_OF_MEMORY;
  2491. }
  2492. memcpy(Cert.PublicKeyData.pBlob, kPublic, dwPubSize);
  2493. dwTemp = 3*sizeof(DWORD) + 2*sizeof(WORD) + dwPubSize;
  2494. if( NULL == (pbData = (PBYTE)LocalAlloc(LPTR,dwTemp)) )
  2495. {
  2496. LocalFree(kPrivate);
  2497. LocalFree(kPublic);
  2498. LocalFree(Cert.PublicKeyData.pBlob);
  2499. return LICENSE_STATUS_OUT_OF_MEMORY;
  2500. }
  2501. pbTemp = pbData;
  2502. memcpy(pbTemp, &Cert.dwVersion, sizeof(DWORD));
  2503. pbTemp += sizeof(DWORD);
  2504. memcpy(pbTemp, &Cert.dwSigAlgID, sizeof(DWORD));
  2505. pbTemp += sizeof(DWORD);
  2506. memcpy(pbTemp, &Cert.dwKeyAlgID, sizeof(DWORD));
  2507. pbTemp += sizeof(DWORD);
  2508. memcpy(pbTemp, &Cert.PublicKeyData.wBlobType, sizeof(WORD));
  2509. pbTemp += sizeof(WORD);
  2510. memcpy(pbTemp, &Cert.PublicKeyData.wBlobLen, sizeof(WORD));
  2511. pbTemp += sizeof(WORD);
  2512. memcpy(pbTemp, Cert.PublicKeyData.pBlob, Cert.PublicKeyData.wBlobLen);
  2513. pbTemp += Cert.PublicKeyData.wBlobLen;
  2514. // sign the cert
  2515. MD5Init(&HashState);
  2516. MD5Update(&HashState, pbData, dwTemp);
  2517. MD5Final(&HashState);
  2518. LocalFree(pbData);
  2519. memset(pbHash, 0x00, 0x48);
  2520. memset(pbHash, 0xff, 0x40);
  2521. pbHash[0x40-1] = 0;
  2522. pbHash[0x40-2] = 1;
  2523. pbHash[16] = 0;
  2524. memcpy(pbHash, HashState.digest, 16);
  2525. BSafeDecPrivate(PRV, pbHash, Output);
  2526. Cert.SignatureBlob.wBlobType = BB_RSA_SIGNATURE_BLOB;
  2527. Cert.SignatureBlob.wBlobLen = 0x48;
  2528. if( NULL == (Cert.SignatureBlob.pBlob = (PBYTE)LocalAlloc(LPTR,Cert.SignatureBlob.wBlobLen)) )
  2529. {
  2530. LocalFree(kPrivate);
  2531. LocalFree(kPublic);
  2532. LocalFree(Cert.PublicKeyData.pBlob);
  2533. return LICENSE_STATUS_OUT_OF_MEMORY;
  2534. }
  2535. memcpy(Cert.SignatureBlob.pBlob, Output, Cert.SignatureBlob.wBlobLen);
  2536. // Pack the Hydra_Server_Cert
  2537. dwTemp = 3*sizeof(DWORD) + 4*sizeof(WORD) + dwPubSize + 0x48;
  2538. if( NULL == (pbData = (PBYTE)LocalAlloc(LPTR,dwTemp)) )
  2539. {
  2540. LocalFree(kPrivate);
  2541. LocalFree(kPublic);
  2542. LocalFree(Cert.PublicKeyData.pBlob);
  2543. return LICENSE_STATUS_OUT_OF_MEMORY;
  2544. }
  2545. pbTemp = pbData;
  2546. memcpy(pbTemp, &Cert.dwVersion, sizeof(DWORD));
  2547. pbTemp += sizeof(DWORD);
  2548. memcpy(pbTemp, &Cert.dwSigAlgID, sizeof(DWORD));
  2549. pbTemp += sizeof(DWORD);
  2550. memcpy(pbTemp, &Cert.dwKeyAlgID, sizeof(DWORD));
  2551. pbTemp += sizeof(DWORD);
  2552. memcpy(pbTemp, &Cert.PublicKeyData.wBlobType, sizeof(WORD));
  2553. pbTemp += sizeof(WORD);
  2554. memcpy(pbTemp, &Cert.PublicKeyData.wBlobLen, sizeof(WORD));
  2555. pbTemp += sizeof(WORD);
  2556. memcpy(pbTemp, Cert.PublicKeyData.pBlob, Cert.PublicKeyData.wBlobLen);
  2557. pbTemp += Cert.PublicKeyData.wBlobLen;
  2558. memcpy(pbTemp, &Cert.SignatureBlob.wBlobType, sizeof(WORD));
  2559. pbTemp += sizeof(WORD);
  2560. memcpy(pbTemp, &Cert.SignatureBlob.wBlobLen, sizeof(WORD));
  2561. pbTemp += sizeof(WORD);
  2562. memcpy(pbTemp, Cert.SignatureBlob.pBlob, Cert.SignatureBlob.wBlobLen);
  2563. *ppbPrivateKey = kPrivate;
  2564. *pcbPrivateKey = dwPrivSize;
  2565. *ppbServerCert = pbData;
  2566. *pcbServerCert = dwTemp;
  2567. LocalFree(kPublic);
  2568. return LICENSE_STATUS_OK;
  2569. }
  2570. //***************************************************************************
  2571. //
  2572. // IsSystemService
  2573. //
  2574. // returns TRUE if we are running as local system
  2575. //
  2576. //***************************************************************************
  2577. BOOL IsSystemService()
  2578. {
  2579. BOOL bOK = FALSE;
  2580. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2581. // Construct the local system SID
  2582. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  2583. SID LocalSystemSid = { SID_REVISION,
  2584. 1,
  2585. SECURITY_NT_AUTHORITY,
  2586. SECURITY_LOCAL_SYSTEM_RID };
  2587. if ( !CheckTokenMembership ( NULL, &LocalSystemSid, &bOK ) )
  2588. {
  2589. bOK = FALSE;
  2590. }
  2591. return bOK;
  2592. }