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.

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