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.

4016 lines
117 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows NT Security
  4. // Copyright (C) Microsoft Corporation, 1997 - 1998
  5. //
  6. // File: txenrol.cpp
  7. //
  8. // Contents: XEnroll C++ Tests
  9. //
  10. // History: 03-Nov-97 keithv Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #include <windows.h>
  14. #include <assert.h>
  15. #include "wincrypt.h"
  16. #include "xenroll.h"
  17. #include "unicode.h"
  18. #define SECURITY_WIN32
  19. #include <security.h>
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. #include <string.h>
  23. #include <memory.h>
  24. #include <time.h>
  25. #include <malloc.h>
  26. #define NO_OSS_DEBUG
  27. #include <dbgdef.h>
  28. //globals
  29. char *g_pszDNName = NULL;
  30. char *g_pszCAXchgFileName = NULL;
  31. char *g_pszCMCFileName = NULL;
  32. char *g_pszCMCResponseFileName = NULL;
  33. char *g_pszKeyContainer = NULL;
  34. DWORD g_cStress = 1;
  35. DWORD g_dwTestID = MAXDWORD;
  36. BOOL g_fPause = FALSE;
  37. BOOL g_fVerb = FALSE;
  38. char *g_pszPKCS7FileName = NULL;
  39. char *g_pszPFXFileName = NULL;
  40. char *g_pszPFXPassword = NULL;
  41. #define TXEnrollLocalScope(ScopeName) struct ScopeName##TheLocalScope { public
  42. #define TXEnrollEndLocalScope } local
  43. #define HASHFROMCERT(a, b) CryptHashCertificate(NULL, 0, X509_ASN_ENCODING, (a)->pbCertEncoded, (a)->cbCertEncoded, (b)->pbData, &(b)->cbData)
  44. #define PRINT_ERROR(Error) \
  45. Error##: \
  46. printf("failed => %s, Error = %08x\n", #Error, GetLastError()); \
  47. goto ERROR_RETURN_LABEL;
  48. #define PRINT_ERROR2(Error, hr) \
  49. Error##: \
  50. printf("failed => %s, Error = 0x%08x\n", #Error, (hr)); \
  51. goto ERROR_RETURN_LABEL;
  52. #define PRINT_ERROR_IF(Error, hr, condition) \
  53. Error##: \
  54. { \
  55. if (condition) { \
  56. printf("failed => %s, Error = 0x%08x\n", #Error, (hr)); \
  57. } \
  58. goto ERROR_RETURN_LABEL; \
  59. }
  60. static BOOL B64EncodeBlob(PCRYPT_DATA_BLOB pBlob, PCRYPT_DATA_BLOB pBlobB64) {
  61. DWORD cchBlob = 0;
  62. DWORD err = ERROR_SUCCESS;
  63. assert(pBlobB64 != NULL && pBlob != NULL);
  64. memset(pBlobB64, 0, sizeof(CRYPT_DATA_BLOB));
  65. // base64 encode the cert
  66. if (CryptBinaryToStringW(
  67. pBlob->pbData,
  68. pBlob->cbData,
  69. CRYPT_STRING_BASE64,
  70. NULL,
  71. &cchBlob))
  72. {
  73. pBlobB64->pbData = (PBYTE) malloc(cchBlob * sizeof(WCHAR));
  74. if(pBlobB64->pbData == NULL)
  75. err = ERROR_NOT_ENOUGH_MEMORY;
  76. }
  77. else
  78. {
  79. err = GetLastError();
  80. assert(ERROR_SUCCESS != err);
  81. }
  82. if(err == ERROR_SUCCESS) {
  83. if (!CryptBinaryToStringW(
  84. pBlob->pbData,
  85. pBlob->cbData,
  86. CRYPT_STRING_BASE64,
  87. (LPWSTR) pBlobB64->pbData,
  88. &cchBlob))
  89. {
  90. err = GetLastError();
  91. assert(ERROR_SUCCESS != err);
  92. }
  93. }
  94. if(err != ERROR_SUCCESS) {
  95. SetLastError(err);
  96. memset(pBlobB64, 0, sizeof(CRYPT_DATA_BLOB));
  97. return(FALSE);
  98. }
  99. pBlobB64->cbData = cchBlob * sizeof(WCHAR);
  100. return(TRUE);
  101. }
  102. static BOOL BSTREncodeBlob(PCRYPT_DATA_BLOB pBlob, BSTR * pbstr) {
  103. CRYPT_DATA_BLOB blob64;
  104. BOOL fRet = TRUE;
  105. assert(pbstr != NULL);
  106. memset(&blob64, 0, sizeof(CRYPT_DATA_BLOB));
  107. if( !B64EncodeBlob(pBlob, &blob64) )
  108. return(FALSE);
  109. if( NULL == (*pbstr = SysAllocStringByteLen((LPCSTR) blob64.pbData, blob64.cbData)) )
  110. fRet = FALSE;
  111. if(blob64.pbData != NULL)
  112. free(blob64.pbData);
  113. return(fRet);
  114. }
  115. static HRESULT GetCertificateContextPropertySimple(IN PCCERT_CONTEXT pCertContext,
  116. IN DWORD dwPropID,
  117. OUT PCRYPT_DATA_BLOB dataBlob)
  118. {
  119. BOOL fDone = FALSE;
  120. dataBlob->pbData = NULL;
  121. dataBlob->cbData = 0x150;
  122. do {
  123. if (dataBlob->pbData != NULL) { LocalFree(dataBlob->pbData); }
  124. dataBlob->pbData = (LPBYTE)LocalAlloc(LPTR, dataBlob->cbData);
  125. if (dataBlob->pbData == NULL) { return E_OUTOFMEMORY; }
  126. if (!CertGetCertificateContextProperty
  127. (pCertContext,
  128. dwPropID,
  129. (LPVOID)dataBlob->pbData,
  130. &(dataBlob->cbData)))
  131. {
  132. if (GetLastError() != ERROR_MORE_DATA)
  133. return HRESULT_FROM_WIN32(GetLastError());
  134. }
  135. else
  136. {
  137. fDone = TRUE;
  138. }
  139. } while (!fDone);
  140. return S_OK;
  141. }
  142. static HRESULT ResyncIEnrollRequestStore(IN OUT IEnroll4 **ppIEnroll4)
  143. {
  144. CRYPT_DATA_BLOB hashBlob;
  145. HRESULT hr;
  146. ZeroMemory(&hashBlob, sizeof(hashBlob));
  147. // Get the thumbprint of the created request.
  148. if (S_OK != (hr = (*ppIEnroll4)->get_ThumbPrintWStr(&hashBlob)))
  149. goto get_ThumbPrintWStrError;
  150. hashBlob.pbData = (LPBYTE)LocalAlloc(LPTR, hashBlob.cbData);
  151. if (NULL == hashBlob.pbData)
  152. goto MemoryError;
  153. if (S_OK != (hr = (*ppIEnroll4)->get_ThumbPrintWStr(&hashBlob)))
  154. goto get_ThumbPrintWStrError;
  155. (*ppIEnroll4)->Release();
  156. if (NULL == (*ppIEnroll4 = PIEnroll4GetNoCOM()))
  157. goto PIEnroll4GetNoCOMError;
  158. if (S_OK != (hr = (*ppIEnroll4)->put_ThumbPrintWStr(hashBlob)))
  159. goto put_ThumbPrintWStrError;
  160. hr = S_OK;
  161. ErrorReturn:
  162. return hr;
  163. TRACE_ERROR(get_ThumbPrintWStrError);
  164. SET_HRESULT(MemoryError, E_OUTOFMEMORY);
  165. SET_HRESULT(PIEnroll4GetNoCOMError, HRESULT_FROM_WIN32(GetLastError()));
  166. TRACE_ERROR(put_ThumbPrintWStrError);
  167. }
  168. static HRESULT FindPendingRequest(IN IEnroll4 *pIEnroll4,
  169. IN PCCERT_CONTEXT pCertContext,
  170. IN HRESULT hrExpected,
  171. OUT LONG *plIndex)
  172. {
  173. CRYPT_DATA_BLOB hashBlob;
  174. CRYPT_DATA_BLOB hashBlobExpected;
  175. HRESULT hr;
  176. LONG lIndex;
  177. ZeroMemory(&hashBlob, sizeof(hashBlob));
  178. ZeroMemory(&hashBlobExpected, sizeof(hashBlobExpected));
  179. if (NULL == pIEnroll4 || NULL == pCertContext || NULL == plIndex)
  180. goto InvalidArgError;
  181. if (S_OK != (hr = GetCertificateContextPropertySimple
  182. (pCertContext,
  183. CERT_HASH_PROP_ID,
  184. &hashBlobExpected)))
  185. goto GetCertificateContextPropertySimpleError;
  186. // Initialize the enumeration.
  187. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(XEPR_ENUM_FIRST, 0, NULL)))
  188. goto enumPendingRequestWStrError1;
  189. for (lIndex = 0; TRUE; lIndex++)
  190. {
  191. hashBlob.pbData = NULL;
  192. hashBlob.cbData = 0;
  193. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr
  194. (lIndex,
  195. XEPR_HASH,
  196. (LPVOID)&hashBlob)))
  197. goto enumPendingRequestWStrError2;
  198. hashBlob.pbData = (LPBYTE)LocalAlloc(LPTR, hashBlob.cbData);
  199. if (NULL == hashBlob.pbData)
  200. goto MemoryError;
  201. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr
  202. (lIndex,
  203. XEPR_HASH,
  204. (LPVOID)&hashBlob)))
  205. goto enumPendingRequestWStrError3;
  206. // We've found the request we want.
  207. if ((hashBlobExpected.cbData == hashBlob.cbData) &&
  208. (0 == memcmp(hashBlobExpected.pbData, hashBlob.pbData, hashBlob.cbData)))
  209. break;
  210. }
  211. // Success: assign the OUT param.
  212. *plIndex = lIndex;
  213. hr = S_OK;
  214. CommonReturn:
  215. if (NULL != hashBlob.pbData) { LocalFree(hashBlob.pbData); }
  216. return hr;
  217. ErrorReturn:
  218. goto CommonReturn;
  219. PRINT_ERROR_IF(enumPendingRequestWStrError1, hr, (hrExpected != hr));
  220. PRINT_ERROR_IF(enumPendingRequestWStrError2, hr, (hrExpected != hr));
  221. PRINT_ERROR_IF(enumPendingRequestWStrError3, hr, (hrExpected != hr));
  222. PRINT_ERROR_IF(GetCertificateContextPropertySimpleError, hr, (hrExpected != hr));
  223. PRINT_ERROR2(InvalidArgError, hr = E_INVALIDARG);
  224. PRINT_ERROR2(MemoryError, hr = E_OUTOFMEMORY);
  225. }
  226. static PCCERT_CONTEXT GetCertOutOfStore(PCRYPT_DATA_BLOB pBlobRequest, DWORD dwStoreFlags, LPWSTR pwszStoreName)
  227. {
  228. HCERTSTORE hStoreRequest = NULL;
  229. PCERT_REQUEST_INFO pReqInfo = NULL;
  230. PCCERT_CONTEXT pCertContextRequest = NULL;
  231. if( !CryptQueryObject(CERT_QUERY_OBJECT_BLOB,
  232. pBlobRequest,
  233. CERT_QUERY_CONTENT_FLAG_PKCS10,
  234. CERT_QUERY_FORMAT_FLAG_ALL,
  235. CRYPT_DECODE_ALLOC_FLAG,
  236. NULL,
  237. NULL,
  238. NULL,
  239. NULL,
  240. NULL,
  241. (const void **) &pReqInfo) )
  242. goto ErrorCryptQueryObject;
  243. if( NULL == (hStoreRequest = CertOpenStore(
  244. CERT_STORE_PROV_SYSTEM,
  245. X509_ASN_ENCODING,
  246. NULL,
  247. dwStoreFlags | CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG,
  248. pwszStoreName)) )
  249. goto ErrorOpenRequestStore;
  250. // Now get this out of the request store
  251. if( NULL == (pCertContextRequest = CertFindCertificateInStore(
  252. hStoreRequest,
  253. CRYPT_ASN_ENCODING,
  254. 0,
  255. CERT_FIND_PUBLIC_KEY,
  256. (void *) &pReqInfo->SubjectPublicKeyInfo,
  257. NULL)) )
  258. goto ErrorCertGetRequestCert;
  259. CommonReturn:
  260. if(hStoreRequest != NULL)
  261. CertCloseStore(hStoreRequest, 0);
  262. if(pReqInfo != NULL)
  263. LocalFree(pReqInfo);
  264. return(pCertContextRequest);
  265. ErrorReturn:
  266. if(pCertContextRequest != NULL)
  267. CertFreeCertificateContext(pCertContextRequest);
  268. pCertContextRequest = NULL;
  269. goto CommonReturn;
  270. PRINT_ERROR(ErrorCryptQueryObject);
  271. PRINT_ERROR(ErrorOpenRequestStore);
  272. PRINT_ERROR(ErrorCertGetRequestCert);
  273. }
  274. static PCCERT_CONTEXT GetCertOutOfRequestStoreMachine(PCRYPT_DATA_BLOB pBlobRequest) {
  275. return GetCertOutOfStore
  276. (pBlobRequest,
  277. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  278. L"REQUEST");
  279. }
  280. static PCCERT_CONTEXT GetCertOutOfRequestStore(PCRYPT_DATA_BLOB pBlobRequest) {
  281. return GetCertOutOfStore
  282. (pBlobRequest,
  283. CERT_SYSTEM_STORE_CURRENT_USER,
  284. L"REQUEST");
  285. }
  286. // This version assumes the PKCS 10 is within a PKCS 7
  287. static PCCERT_CONTEXT GetCertOutOfRequestStore2(
  288. PCRYPT_DATA_BLOB pBlob7)
  289. {
  290. CRYPT_DATA_BLOB Blob10;
  291. CRYPT_VERIFY_MESSAGE_PARA VerifyPara;
  292. PCCERT_CONTEXT pCert;
  293. Blob10.pbData = NULL;
  294. Blob10.cbData = 0;
  295. memset(&VerifyPara, 0, sizeof(VerifyPara));
  296. VerifyPara.cbSize = sizeof(VerifyPara);
  297. VerifyPara.dwMsgAndCertEncodingType =
  298. PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
  299. if (!CryptVerifyMessageSignature(
  300. &VerifyPara,
  301. 0, // dwSignerIndex
  302. pBlob7->pbData,
  303. pBlob7->cbData,
  304. Blob10.pbData,
  305. &Blob10.cbData,
  306. NULL // ppSignerCert
  307. ) || 0 == Blob10.cbData)
  308. goto ErrorCryptVerifyMessageSignature;
  309. if (NULL == (Blob10.pbData = (PBYTE) _alloca(Blob10.cbData)))
  310. goto ErrorOutOfMemory;
  311. if (!CryptVerifyMessageSignature(
  312. &VerifyPara,
  313. 0, // dwSignerIndex
  314. pBlob7->pbData,
  315. pBlob7->cbData,
  316. Blob10.pbData,
  317. &Blob10.cbData,
  318. NULL // ppSignerCert
  319. ))
  320. goto ErrorCryptVerifyMessageSignature;
  321. pCert = GetCertOutOfRequestStore(&Blob10);
  322. CommonReturn:
  323. return pCert;
  324. ErrorReturn:
  325. pCert = NULL;
  326. goto CommonReturn;
  327. PRINT_ERROR(ErrorCryptVerifyMessageSignature);
  328. PRINT_ERROR(ErrorOutOfMemory);
  329. }
  330. static PCRYPT_DATA_BLOB MakePKCS7ResponseEx(
  331. PCRYPT_DATA_BLOB pBlobRequest,
  332. PCRYPT_HASH_BLOB pHash,
  333. BOOL fUser)
  334. {
  335. HCERTSTORE hStorePKCS7 = NULL;
  336. PCCERT_CONTEXT pCertContextRequest = NULL;
  337. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  338. PCRYPT_KEY_PROV_INFO pKeyProvInfo = NULL;
  339. DWORD cbKeyProvInfo = 0;
  340. HCRYPTPROV hProv = NULL;
  341. PCCERT_CONTEXT pCertContextNew = NULL;
  342. CRYPT_DATA_BLOB blobPKCS7;
  343. if (fUser)
  344. {
  345. pCertContextRequest = GetCertOutOfRequestStore(pBlobRequest);
  346. }
  347. else
  348. {
  349. pCertContextRequest = GetCertOutOfRequestStoreMachine(pBlobRequest);
  350. }
  351. if( NULL == pCertContextRequest)
  352. goto ErrorGetCertOutOfRequestStore;
  353. // get the prov info off of the cert
  354. if(
  355. !CertGetCertificateContextProperty(
  356. pCertContextRequest,
  357. CERT_KEY_PROV_INFO_PROP_ID,
  358. NULL,
  359. &cbKeyProvInfo
  360. ) ||
  361. (NULL == (pKeyProvInfo = (PCRYPT_KEY_PROV_INFO) _alloca(cbKeyProvInfo))) ||
  362. !CertGetCertificateContextProperty(
  363. pCertContextRequest,
  364. CERT_KEY_PROV_INFO_PROP_ID,
  365. pKeyProvInfo,
  366. &cbKeyProvInfo
  367. ) )
  368. goto ErrorCertGetCertificateContextProperty;
  369. // get and hProv off of this certificate
  370. if( !CryptAcquireCertificatePrivateKey(
  371. pCertContextRequest,
  372. 0,
  373. NULL,
  374. &hProv,
  375. NULL,
  376. NULL
  377. ) )
  378. goto ErrorCryptAcquireCertificatePrivateKey;
  379. // build a self-signed cert with this key
  380. if( NULL == (pCertContextNew = CertCreateSelfSignCertificate(
  381. hProv,
  382. &pCertContextRequest->pCertInfo->Subject,
  383. 0,
  384. pKeyProvInfo,
  385. &pCertContextRequest->pCertInfo->SignatureAlgorithm,
  386. NULL,
  387. NULL,
  388. NULL
  389. )) )
  390. goto ErrorCertCreateSelfSignCertificate;
  391. // make a pkcs7
  392. if( NULL == (hStorePKCS7 = CertOpenStore(
  393. CERT_STORE_PROV_MEMORY,
  394. X509_ASN_ENCODING,
  395. NULL,
  396. 0,
  397. NULL)) )
  398. goto ErrorOpenPKCS7Store;
  399. if( !CertAddCertificateContextToStore(
  400. hStorePKCS7,
  401. pCertContextNew,
  402. CERT_STORE_ADD_USE_EXISTING,
  403. NULL) )
  404. goto ErrorCertAddToPKCS7Store;
  405. assert(pHash != NULL);
  406. if( !HASHFROMCERT(pCertContextNew, pHash))
  407. goto ErrorHASHFROMCERT;
  408. memset(&blobPKCS7, 0, sizeof(blobPKCS7));
  409. if(!CertSaveStore(
  410. hStorePKCS7,
  411. PKCS_7_ASN_ENCODING | CRYPT_ASN_ENCODING,
  412. CERT_STORE_SAVE_AS_PKCS7,
  413. CERT_STORE_SAVE_TO_MEMORY,
  414. &blobPKCS7,
  415. 0) )
  416. goto ErrorCreatePKCS7;
  417. pBlobPKCS7 = (PCRYPT_DATA_BLOB) malloc(sizeof(CRYPT_DATA_BLOB) + blobPKCS7.cbData);
  418. if(NULL == pBlobPKCS7) {
  419. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  420. goto OutOfMemory;
  421. }
  422. *pBlobPKCS7 = blobPKCS7;
  423. pBlobPKCS7->pbData = ((PBYTE) pBlobPKCS7) + sizeof(CRYPT_DATA_BLOB);
  424. if( !CertSaveStore(
  425. hStorePKCS7,
  426. PKCS_7_ASN_ENCODING | CRYPT_ASN_ENCODING,
  427. CERT_STORE_SAVE_AS_PKCS7,
  428. CERT_STORE_SAVE_TO_MEMORY,
  429. pBlobPKCS7,
  430. 0))
  431. goto ErrorCreatePKCS7;
  432. CommonReturn:
  433. if(hStorePKCS7 != NULL)
  434. CertCloseStore(hStorePKCS7, 0);
  435. if(pCertContextRequest != NULL)
  436. CertFreeCertificateContext(pCertContextRequest);
  437. if(pCertContextNew != NULL)
  438. CertFreeCertificateContext(pCertContextNew);
  439. if(hProv != NULL)
  440. CryptReleaseContext(hProv, 0);
  441. return(pBlobPKCS7);
  442. ErrorReturn:
  443. if(pBlobPKCS7 != NULL)
  444. free(pBlobPKCS7);
  445. pBlobPKCS7 = NULL;
  446. goto CommonReturn;
  447. PRINT_ERROR(ErrorCertCreateSelfSignCertificate);
  448. PRINT_ERROR(ErrorCertGetCertificateContextProperty);
  449. PRINT_ERROR(ErrorCryptAcquireCertificatePrivateKey);
  450. PRINT_ERROR(ErrorGetCertOutOfRequestStore);
  451. PRINT_ERROR(ErrorOpenPKCS7Store);
  452. PRINT_ERROR(ErrorCertAddToPKCS7Store);
  453. PRINT_ERROR(ErrorCreatePKCS7);
  454. PRINT_ERROR(OutOfMemory);
  455. PRINT_ERROR(ErrorHASHFROMCERT);
  456. }
  457. static PCRYPT_DATA_BLOB MakePKCS7ResponseMachine(
  458. PCRYPT_DATA_BLOB pBlobRequest,
  459. PCRYPT_HASH_BLOB pHash)
  460. {
  461. return MakePKCS7ResponseEx(pBlobRequest, pHash, FALSE);
  462. }
  463. static PCRYPT_DATA_BLOB MakePKCS7Response(
  464. PCRYPT_DATA_BLOB pBlobRequest,
  465. PCRYPT_HASH_BLOB pHash)
  466. {
  467. return MakePKCS7ResponseEx(pBlobRequest, pHash, TRUE);
  468. }
  469. static PCRYPT_DATA_BLOB GetPKCS10FromPKCS7(PCRYPT_DATA_BLOB pPKCS7) {
  470. CRYPT_VERIFY_MESSAGE_PARA MsgPara;
  471. PCCERT_CONTEXT pCert = NULL;
  472. CRYPT_DATA_BLOB blob;
  473. PCRYPT_DATA_BLOB pBlob = NULL;
  474. assert(pPKCS7 != NULL);
  475. memset(&blob, 0, sizeof(CRYPT_DATA_BLOB));
  476. memset(&MsgPara, 0, sizeof(CRYPT_VERIFY_MESSAGE_PARA));
  477. MsgPara.cbSize = sizeof(CRYPT_VERIFY_MESSAGE_PARA);
  478. MsgPara.dwMsgAndCertEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
  479. if( !CryptVerifyMessageSignature(
  480. &MsgPara,
  481. 0,
  482. pPKCS7->pbData,
  483. pPKCS7->cbData,
  484. NULL,
  485. &blob.cbData,
  486. NULL
  487. ) )
  488. goto ErrorCryptVerifyMessageSignature;
  489. if( (pBlob = (PCRYPT_DATA_BLOB) malloc(blob.cbData + sizeof(CRYPT_DATA_BLOB))) == NULL ) {
  490. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  491. goto OutOfMemory;
  492. }
  493. pBlob->pbData = ((BYTE *) pBlob) + sizeof(CRYPT_DATA_BLOB);
  494. pBlob->cbData = blob.cbData;
  495. if( !CryptVerifyMessageSignature(
  496. &MsgPara,
  497. 0,
  498. pPKCS7->pbData,
  499. pPKCS7->cbData,
  500. pBlob->pbData,
  501. &blob.cbData,
  502. &pCert
  503. ) )
  504. goto ErrorCryptVerifyMessageSignature;
  505. CommonReturn:
  506. if(pCert != NULL)
  507. CertFreeCertificateContext(pCert);
  508. return(pBlob);
  509. ErrorReturn:
  510. if(pBlob != NULL)
  511. free(pBlob);
  512. pBlob = NULL;
  513. goto CommonReturn;
  514. PRINT_ERROR(ErrorCryptVerifyMessageSignature);
  515. PRINT_ERROR(OutOfMemory);
  516. }
  517. void DeleteCertPrivateKey(PCCERT_CONTEXT pCert) {
  518. PCRYPT_KEY_PROV_INFO pKeyProvInfo = NULL;
  519. DWORD cbKeyProvInfo = 0;
  520. HCRYPTPROV hProv;
  521. BYTE rgbKeyIdHash[20];
  522. CRYPT_HASH_BLOB KeyIdentifier;
  523. // get the prov info off of the cert
  524. if(
  525. !CertGetCertificateContextProperty(
  526. pCert,
  527. CERT_KEY_PROV_INFO_PROP_ID,
  528. NULL,
  529. &cbKeyProvInfo
  530. ) ||
  531. (NULL == (pKeyProvInfo = (PCRYPT_KEY_PROV_INFO) _alloca(cbKeyProvInfo))) ||
  532. !CertGetCertificateContextProperty(
  533. pCert,
  534. CERT_KEY_PROV_INFO_PROP_ID,
  535. pKeyProvInfo,
  536. &cbKeyProvInfo
  537. ) )
  538. goto ErrorCertGetCertificateContextProperty;
  539. // Note: for CRYPT_DELETEKEYSET, the returned hProv is undefined and
  540. // must not be released.
  541. if( !CryptAcquireContextU(&hProv,
  542. pKeyProvInfo->pwszContainerName,
  543. pKeyProvInfo->pwszProvName,
  544. pKeyProvInfo->dwProvType,
  545. (pKeyProvInfo->dwFlags & ~CERT_SET_KEY_CONTEXT_PROP_ID) |
  546. CRYPT_DELETEKEYSET) )
  547. goto ErrorCryptDeleteKeySet;
  548. // Also delete the private key identifier
  549. KeyIdentifier.pbData = rgbKeyIdHash;
  550. KeyIdentifier.cbData = sizeof(rgbKeyIdHash);
  551. if (!CertGetCertificateContextProperty(
  552. pCert,
  553. CERT_KEY_IDENTIFIER_PROP_ID,
  554. KeyIdentifier.pbData,
  555. &KeyIdentifier.cbData
  556. ))
  557. goto ErrorCertGetCertificateKeyIdentifierProperty;
  558. if (!CryptSetKeyIdentifierProperty(
  559. &KeyIdentifier,
  560. 0, // dwPropId
  561. CRYPT_KEYID_DELETE_FLAG |
  562. pKeyProvInfo->dwFlags & CRYPT_KEYID_MACHINE_FLAG,
  563. NULL, // pwszComputerName
  564. NULL, // pvReserved
  565. NULL // pvData
  566. )) {
  567. DWORD dwErr = GetLastError();
  568. if (ERROR_FILE_NOT_FOUND != dwErr)
  569. goto ErrorDeleteKeyIdentifier;
  570. }
  571. CommonReturn:
  572. return;
  573. ErrorReturn:
  574. goto CommonReturn;
  575. PRINT_ERROR(ErrorCertGetCertificateContextProperty)
  576. PRINT_ERROR(ErrorCryptDeleteKeySet)
  577. PRINT_ERROR(ErrorCertGetCertificateKeyIdentifierProperty)
  578. PRINT_ERROR(ErrorDeleteKeyIdentifier)
  579. }
  580. BOOL RemoveCertFromStore(PCRYPT_HASH_BLOB pHash, LPCWSTR wszStore, DWORD dwStoreFlags) {
  581. BOOL fRet = TRUE;
  582. HCERTSTORE hStore = NULL;
  583. DWORD err = GetLastError();
  584. PCCERT_CONTEXT pCert = NULL;
  585. // open the my store
  586. if( NULL == (hStore = CertOpenStore(
  587. CERT_STORE_PROV_SYSTEM,
  588. X509_ASN_ENCODING,
  589. NULL,
  590. dwStoreFlags,
  591. wszStore)) )
  592. goto ErrorOpenStore;
  593. // find the cert by hash
  594. if( NULL == (pCert = CertFindCertificateInStore(
  595. hStore,
  596. X509_ASN_ENCODING,
  597. 0,
  598. CERT_FIND_HASH,
  599. pHash,
  600. NULL ) ))
  601. goto ErrorCertFindCertificateInStore;
  602. // delete the cert's private key
  603. DeleteCertPrivateKey(pCert);
  604. //delete the cert
  605. if( !CertDeleteCertificateFromStore(pCert) ) {
  606. pCert = NULL;
  607. goto ErrorCertDeleteCertificateFromStore;
  608. }
  609. pCert = NULL;
  610. CommonReturn:
  611. if(pCert != NULL)
  612. CertFreeCertificateContext(pCert);
  613. if(hStore != NULL)
  614. CertCloseStore(hStore, 0);
  615. SetLastError(err);
  616. return(fRet);
  617. ErrorReturn:
  618. fRet = FALSE;
  619. err = GetLastError();
  620. goto CommonReturn;
  621. PRINT_ERROR(ErrorOpenStore);
  622. PRINT_ERROR(ErrorCertFindCertificateInStore);
  623. PRINT_ERROR(ErrorCertDeleteCertificateFromStore);
  624. }
  625. // Define a struct which will hold the data we need to test with.
  626. typedef struct _PENDING_INFO {
  627. DWORD dwRequestID;
  628. LPWSTR pwszCADNS;
  629. LPWSTR pwszCAName;
  630. LPWSTR pwszFriendlyName;
  631. DWORD dwStoreFlags;
  632. LPWSTR pwszStoreName;
  633. HRESULT hrExpectedResult;
  634. } PENDING_INFO;
  635. class TXEnrollPendingAPITester {
  636. public:
  637. BOOL TestMethod_enumPendingRequestWStr(IEnroll4 *pIEnroll4,
  638. CRYPT_DATA_BLOB pkcs10Request,
  639. PENDING_INFO *pPendingInfo);
  640. BOOL TestMethod_removePendingRequestWStr(IEnroll4 *pIEnroll4);
  641. BOOL TestMethod_setPendingInfoWStr(IEnroll4 *pIEnroll4,
  642. CRYPT_DATA_BLOB pkcs10Request,
  643. PENDING_INFO *pPendingInfo);
  644. BOOL TestProperty_ThumbPrintWStr(IEnroll4 *pIEnroll4);
  645. };
  646. BOOL TXEnrollPendingAPITester::TestMethod_removePendingRequestWStr(IEnroll4 *pIEnroll4)
  647. {
  648. BOOL fResult;
  649. CRYPT_DATA_BLOB hashBlob;
  650. CRYPT_DATA_BLOB pkcs10Blob;
  651. HRESULT hr;
  652. LONG lIndex;
  653. LONG lRequestID = 0;
  654. PCCERT_CONTEXT pCertContext = NULL;
  655. WCHAR pwszCADNS[] = L"duncanb1.ntdev.microsoft.com";
  656. WCHAR pwszCAName[] = L"Test RPR";
  657. WCHAR pwszFriendlyName[]= L"\0";
  658. WCHAR wszDNName[] = L"CN=Xenroll TestMethod_removePendingRequestWStr Test";
  659. ZeroMemory(&hashBlob, sizeof(hashBlob));
  660. ZeroMemory(&pkcs10Blob, sizeof(pkcs10Blob));
  661. //
  662. // Case 0) Removal of a request in the REQUEST (normal case).
  663. //
  664. if (S_OK != (hr = pIEnroll4->resetExtensions()))
  665. goto resetExtensionsError;
  666. if (S_OK != (hr = pIEnroll4->resetAttributes()))
  667. goto resetAttributesError;
  668. // Small key size so the test runs faster.
  669. if (S_OK != (hr = pIEnroll4->put_GenKeyFlags(384 << 16)))
  670. goto put_GenKeyFlagsError;
  671. // Create a request to test on.
  672. if (S_OK != (hr = pIEnroll4->createRequestWStr
  673. (XECR_PKCS10_V2_0,
  674. wszDNName,
  675. NULL,
  676. &pkcs10Blob)))
  677. goto createRequestWStrError;
  678. // Set pending info on the request, so it can be accessed via the pending API:
  679. if (S_OK != (hr = pIEnroll4->setPendingRequestInfoWStr
  680. (lRequestID,
  681. pwszCADNS,
  682. pwszCAName,
  683. pwszFriendlyName)))
  684. goto setPendingRequestInfoWStrError;
  685. if (S_OK != (hr = ResyncIEnrollRequestStore(&pIEnroll4)))
  686. goto ResyncIEnrollRequestStoreError;
  687. pCertContext = GetCertOutOfRequestStore(&pkcs10Blob);
  688. if (NULL == pCertContext)
  689. goto GetCertOutOfRequestStoreError;
  690. // Verify that the request is in the REQUEST store:
  691. if (S_OK != (hr = FindPendingRequest
  692. (pIEnroll4,
  693. pCertContext,
  694. S_OK,
  695. &lIndex)))
  696. goto RequestNotAddedToStoreError;
  697. // Get the thumbprint of the created request.
  698. if (S_OK != (hr = pIEnroll4->get_ThumbPrintWStr(&hashBlob)))
  699. goto get_ThumbPrintWStrError;
  700. hashBlob.pbData = (LPBYTE)LocalAlloc(LPTR, hashBlob.cbData);
  701. if (NULL == hashBlob.pbData)
  702. goto MemoryError;
  703. if (S_OK != (hr = pIEnroll4->get_ThumbPrintWStr(&hashBlob)))
  704. goto get_ThumbPrintWStrError;
  705. // Remove the request from the request store:
  706. if (S_OK != (hr = pIEnroll4->removePendingRequestWStr(hashBlob)))
  707. goto removePendingRequestWStrError;
  708. // Verify that it is actually gone:
  709. if (HRESULT_FROM_WIN32(CRYPT_E_NOT_FOUND) != (hr = FindPendingRequest
  710. (pIEnroll4,
  711. pCertContext,
  712. HRESULT_FROM_WIN32(CRYPT_E_NOT_FOUND),
  713. &lIndex)))
  714. {
  715. if (!FAILED(hr))
  716. hr = E_FAIL;
  717. goto PendingRequestNotRemovedError;
  718. }
  719. // No need to delete the request, the pending API has already done this.
  720. pkcs10Blob.pbData = NULL;
  721. //
  722. // Case 1) invalid arg:
  723. //
  724. {
  725. CRYPT_DATA_BLOB invalidBlob;
  726. ZeroMemory(&invalidBlob, sizeof(invalidBlob));
  727. if (E_INVALIDARG != (hr = pIEnroll4->removePendingRequestWStr(invalidBlob)))
  728. goto removePendingRequestWStrError;
  729. }
  730. //
  731. // Case 2) cert not found:
  732. //
  733. if (HRESULT_FROM_WIN32(CRYPT_E_NOT_FOUND) != (hr = pIEnroll4->removePendingRequestWStr
  734. (hashBlob)))
  735. {
  736. if (!FAILED(hr))
  737. hr = E_FAIL;
  738. goto removePendingRequestWStrError;
  739. }
  740. fResult = TRUE;
  741. CommonReturn:
  742. if (NULL != pkcs10Blob.pbData)
  743. {
  744. pCertContext = GetCertOutOfRequestStore(&pkcs10Blob);
  745. if (NULL != pCertContext)
  746. {
  747. CertDeleteCertificateFromStore(pCertContext);
  748. }
  749. LocalFree(pkcs10Blob.pbData);
  750. }
  751. if (NULL != hashBlob.pbData) { LocalFree(hashBlob.pbData); }
  752. return fResult;
  753. ErrorReturn:
  754. SetLastError(hr);
  755. fResult = FALSE;
  756. goto CommonReturn;
  757. PRINT_ERROR2(createRequestWStrError, hr);
  758. PRINT_ERROR2(get_ThumbPrintWStrError, hr);
  759. PRINT_ERROR2(GetCertOutOfRequestStoreError, hr = GetLastError());
  760. PRINT_ERROR2(MemoryError, hr = E_OUTOFMEMORY);
  761. PRINT_ERROR2(PendingRequestNotRemovedError, hr);
  762. PRINT_ERROR2(put_GenKeyFlagsError, hr);
  763. PRINT_ERROR2(RequestNotAddedToStoreError, hr);
  764. PRINT_ERROR2(removePendingRequestWStrError, hr);
  765. PRINT_ERROR2(resetExtensionsError, hr);
  766. PRINT_ERROR2(resetAttributesError, hr);
  767. PRINT_ERROR2(ResyncIEnrollRequestStoreError, hr);
  768. PRINT_ERROR2(setPendingRequestInfoWStrError, hr);
  769. }
  770. BOOL TXEnrollPendingAPITester::TestProperty_ThumbPrintWStr(IEnroll4 *pIEnroll4)
  771. {
  772. DWORD const dw_NUM_CASES = 3;
  773. BOOL fResult;
  774. CRYPT_DATA_BLOB hashBlobs [dw_NUM_CASES];
  775. CRYPT_DATA_BLOB hashBlobsExpected [dw_NUM_CASES];
  776. CRYPT_DATA_BLOB pkcs10Blobs [dw_NUM_CASES];
  777. DWORD dwCase;
  778. DWORD dwRequestIDExpected;
  779. HRESULT hr = S_OK;
  780. LONG lIndex;
  781. PCCERT_CONTEXT pCertContexts [dw_NUM_CASES];
  782. WCHAR wszDNName[] = L"CN=Xenroll TestProperty_ThumbPrintWStr Test";
  783. PENDING_INFO pendingInfo =
  784. { 100, L"duncanb.ntdev.microsoft.com", L"ThumbPrint Test", L"TT Test", 0, NULL, S_OK };
  785. ZeroMemory(&hashBlobs[0], sizeof(hashBlobs));
  786. ZeroMemory(&hashBlobsExpected[0], sizeof(hashBlobsExpected));
  787. ZeroMemory(&pkcs10Blobs[0], sizeof(pkcs10Blobs));
  788. ZeroMemory(&pCertContexts[0], sizeof(pCertContexts));
  789. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  790. //
  791. // Declare locally-scoped helper functions:
  792. //
  793. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  794. TXEnrollLocalScope(TestProperty_ThumbPrintWStrHelper):
  795. HRESULT GetThumbPrintAndCertContext(IN IEnroll4 *pIEnroll4,
  796. IN CRYPT_DATA_BLOB pkcs10Request,
  797. OUT PCRYPT_DATA_BLOB pThumbPrintBlob,
  798. OUT PCCERT_CONTEXT *ppCertContext)
  799. {
  800. HRESULT hr;
  801. pThumbPrintBlob->pbData = NULL;
  802. *ppCertContext = NULL;
  803. *ppCertContext = GetCertOutOfRequestStore(&pkcs10Request);
  804. if (NULL == *ppCertContext)
  805. goto GetCertOutOfRequestStoreError;
  806. // Use get_ThumbPrintWStr to get the hash of the request.
  807. if (S_OK != (hr = pIEnroll4->get_ThumbPrintWStr(pThumbPrintBlob)))
  808. goto get_ThumbPrintWStrError;
  809. pThumbPrintBlob->pbData = (LPBYTE)LocalAlloc(LPTR, pThumbPrintBlob->cbData);
  810. if (NULL == pThumbPrintBlob->pbData)
  811. goto MemoryError;
  812. if (S_OK != (hr = pIEnroll4->get_ThumbPrintWStr(pThumbPrintBlob)))
  813. goto get_ThumbPrintWStrError;
  814. hr = S_OK;
  815. CommonReturn:
  816. return hr;
  817. ErrorReturn:
  818. if (NULL != pThumbPrintBlob->pbData) { LocalFree(pThumbPrintBlob->pbData); }
  819. if (NULL != *ppCertContext) { CertDeleteCertificateFromStore(*ppCertContext); }
  820. pThumbPrintBlob->pbData = NULL;
  821. *ppCertContext = NULL;
  822. goto CommonReturn;
  823. PRINT_ERROR2(get_ThumbPrintWStrError, hr);
  824. PRINT_ERROR2(GetCertOutOfRequestStoreError, hr = GetLastError());
  825. PRINT_ERROR2(MemoryError, hr = E_OUTOFMEMORY);
  826. }
  827. TXEnrollEndLocalScope;
  828. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  829. //
  830. // Case 0: Check that thumbprint returned is the hash of the last created cert.
  831. //
  832. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  833. dwCase = 0;
  834. if (S_OK != (hr = pIEnroll4->resetExtensions()))
  835. goto resetExtensionsError;
  836. if (S_OK != (hr = pIEnroll4->resetAttributes()))
  837. goto resetAttributesError;
  838. // Small key size so the test runs faster.
  839. if (S_OK != (hr = pIEnroll4->put_GenKeyFlags(384 << 16)))
  840. goto put_GenKeyFlagsError;
  841. // Create a request to test on.
  842. if (S_OK != (hr = pIEnroll4->createRequestWStr
  843. (XECR_PKCS10_V2_0,
  844. wszDNName,
  845. NULL,
  846. &pkcs10Blobs[dwCase])))
  847. goto createRequestWStrError;
  848. // Make sure xenroll syncs up its request store!
  849. if (S_OK != (hr = ResyncIEnrollRequestStore(&pIEnroll4)))
  850. goto ResyncIEnrollRequestStoreError;
  851. // Get a PCCERT_CONTEXT and thumbprint from the request:
  852. if (S_OK != (hr = local.GetThumbPrintAndCertContext
  853. (pIEnroll4,
  854. pkcs10Blobs[dwCase],
  855. &hashBlobs[dwCase],
  856. &pCertContexts[dwCase])))
  857. goto GetThumbPrintAndCertContextError;
  858. // Manually get the HASH of the request.
  859. if (S_OK != (hr = GetCertificateContextPropertySimple
  860. (pCertContexts[dwCase],
  861. CERT_HASH_PROP_ID,
  862. &hashBlobsExpected[dwCase])))
  863. goto GetCertificateContextPropertySimpleError;
  864. if (!
  865. ((hashBlobs[dwCase].cbData == hashBlobsExpected[dwCase].cbData) &&
  866. (0 == memcmp(hashBlobs[dwCase].pbData, hashBlobsExpected[dwCase].pbData, hashBlobs[dwCase].cbData))))
  867. goto get_ThumbPrintWStrError;
  868. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  869. //
  870. // Case 1: Make sure that put_ThumbPrintWStr is used as the target of setPendingInfoWStr().
  871. //
  872. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  873. dwCase++;
  874. // Flush the first request from the pending cache.
  875. //
  876. if (S_OK != (hr = pIEnroll4->createRequestWStr
  877. (XECR_PKCS10_V2_0,
  878. wszDNName,
  879. NULL,
  880. &pkcs10Blobs[dwCase])))
  881. goto createRequestWStrError;
  882. // Make sure xenroll syncs up its request store!
  883. if (S_OK != (hr = ResyncIEnrollRequestStore(&pIEnroll4)))
  884. goto ResyncIEnrollRequestStoreError;
  885. // Get a PCCERT_CONTEXT and thumbprint from the request:
  886. if (S_OK != (hr = local.GetThumbPrintAndCertContext
  887. (pIEnroll4,
  888. pkcs10Blobs[dwCase],
  889. &hashBlobs[dwCase],
  890. &pCertContexts[dwCase])))
  891. goto GetThumbPrintAndCertContextError;
  892. // Manually specify the previous request through put_ThumbPrint:
  893. if (S_OK != (hr = pIEnroll4->put_ThumbPrintWStr(hashBlobs[dwCase-1])))
  894. goto put_ThumbPrintWStrError;
  895. if (S_OK != (hr = pIEnroll4->setPendingRequestInfoWStr
  896. (pendingInfo.dwRequestID,
  897. pendingInfo.pwszCADNS,
  898. pendingInfo.pwszCAName,
  899. pendingInfo.pwszFriendlyName)))
  900. goto setPendingRequestInfoWStrError;
  901. if (S_OK != (hr = FindPendingRequest(pIEnroll4, pCertContexts[dwCase-1], S_OK, &lIndex)))
  902. goto FindPendingRequestError;
  903. // Success -- if put_ThumbPrintWstr was not working correctly, it would not be possible
  904. // to find pending info associated with the previous cert context.
  905. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  906. //
  907. // Case 2: Make sure that put_ThumbPrintWStr is used as the target of get_ThumbPrintWStr
  908. //
  909. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  910. dwCase++;
  911. // Flush the previous request from the pending cache.
  912. //
  913. if (S_OK != (hr = pIEnroll4->createRequestWStr
  914. (XECR_PKCS10_V2_0,
  915. wszDNName,
  916. NULL,
  917. &pkcs10Blobs[dwCase])))
  918. goto createRequestWStrError;
  919. // Make sure xenroll syncs up its request store!
  920. if (S_OK != (hr = ResyncIEnrollRequestStore(&pIEnroll4)))
  921. goto ResyncIEnrollRequestStoreError;
  922. pCertContexts[dwCase] = GetCertOutOfRequestStore(&pkcs10Blobs[dwCase]);
  923. if (NULL == pCertContexts[dwCase])
  924. goto GetCertOutOfRequestStoreError;
  925. // Manually specify a request through put_ThumbPrint:
  926. //
  927. if (S_OK != (hr = pIEnroll4->put_ThumbPrintWStr(hashBlobs[dwCase-1])))
  928. goto put_ThumbPrintWStrError;
  929. // Extract the request through get_ThumbPrintWStr:
  930. //
  931. if (S_OK != (hr = pIEnroll4->get_ThumbPrintWStr(&hashBlobs[dwCase])))
  932. goto put_ThumbPrintWStrError;
  933. hashBlobs[dwCase].pbData = (LPBYTE)LocalAlloc(LPTR, hashBlobs[dwCase].cbData);
  934. if (NULL == hashBlobs[dwCase].pbData)
  935. goto MemoryError;
  936. if (S_OK != (hr = pIEnroll4->get_ThumbPrintWStr(&hashBlobs[dwCase])))
  937. goto put_ThumbPrintWStrError;
  938. if (!
  939. ((hashBlobs[dwCase].cbData == hashBlobs[dwCase-1].cbData) &&
  940. (0 == memcmp(hashBlobs[dwCase].pbData, hashBlobs[dwCase-1].pbData, hashBlobs[dwCase].cbData))))
  941. goto get_ThumbPrintWStrError;
  942. fResult = TRUE;
  943. CommonReturn:
  944. if (NULL != pIEnroll4) { pIEnroll4->Release(); }
  945. for (dwCase = 0; dwCase < dw_NUM_CASES; dwCase++)
  946. {
  947. if (NULL != pkcs10Blobs[dwCase].pbData) { LocalFree(pkcs10Blobs[dwCase].pbData); }
  948. if (NULL != hashBlobs[dwCase].pbData) { LocalFree(hashBlobs[dwCase].pbData); }
  949. if (NULL != hashBlobsExpected[dwCase].pbData) { LocalFree(hashBlobsExpected[dwCase].pbData); }
  950. if (NULL != pCertContexts[dwCase]) { CertDeleteCertificateFromStore(pCertContexts[dwCase]); }
  951. }
  952. return fResult;
  953. ErrorReturn:
  954. fResult = FALSE;
  955. SetLastError(hr);
  956. goto CommonReturn;
  957. PRINT_ERROR2(createRequestWStrError, hr);
  958. PRINT_ERROR2(FindPendingRequestError, hr);
  959. PRINT_ERROR2(get_ThumbPrintWStrError, hr);
  960. PRINT_ERROR(GetCertOutOfRequestStoreError);
  961. PRINT_ERROR2(GetCertificateContextPropertySimpleError, hr);
  962. PRINT_ERROR2(GetThumbPrintAndCertContextError, hr);
  963. PRINT_ERROR2(MemoryError, E_OUTOFMEMORY);
  964. PRINT_ERROR2(put_GenKeyFlagsError, hr);
  965. PRINT_ERROR2(put_ThumbPrintWStrError, hr);
  966. PRINT_ERROR2(resetAttributesError, hr);
  967. PRINT_ERROR2(resetExtensionsError, hr);
  968. PRINT_ERROR2(ResyncIEnrollRequestStoreError, hr);
  969. PRINT_ERROR2(setPendingRequestInfoWStrError, hr);
  970. }
  971. BOOL TXEnrollPendingAPITester::TestMethod_enumPendingRequestWStr(IEnroll4 *pIEnroll4,
  972. CRYPT_DATA_BLOB pkcs10Blob,
  973. PENDING_INFO *pPendingInfo)
  974. {
  975. BOOL fResult;
  976. CRYPT_DATA_BLOB caDNSBlob;
  977. CRYPT_DATA_BLOB caNameBlob;
  978. CRYPT_DATA_BLOB friendlyNameBlob;
  979. CRYPT_DATA_BLOB hashBlob;
  980. CRYPT_DATA_BLOB hashBlobExpected;
  981. CRYPT_DATA_BLOB v1TemplateNameBlob;
  982. DWORD dwRequestID;
  983. FILETIME ftDate;
  984. FILETIME ftDateExpected;
  985. HRESULT hr = S_OK;
  986. LONG lIndex;
  987. PCCERT_CONTEXT pCertContext = NULL;
  988. // Init:
  989. ZeroMemory(&caDNSBlob, sizeof(CRYPT_DATA_BLOB));
  990. ZeroMemory(&caNameBlob, sizeof(CRYPT_DATA_BLOB));
  991. ZeroMemory(&friendlyNameBlob, sizeof(CRYPT_DATA_BLOB));
  992. ZeroMemory(&hashBlob, sizeof(CRYPT_DATA_BLOB));
  993. ZeroMemory(&hashBlobExpected, sizeof(CRYPT_DATA_BLOB));
  994. ZeroMemory(&v1TemplateNameBlob, sizeof(CRYPT_DATA_BLOB));
  995. if (NULL == pIEnroll4 || NULL == pPendingInfo)
  996. goto InvalidArgError;
  997. pCertContext = GetCertOutOfStore(&pkcs10Blob, pPendingInfo->dwStoreFlags, pPendingInfo->pwszStoreName);
  998. if (NULL == pCertContext)
  999. goto GetCertOutOfStoreError;
  1000. if (S_OK != (hr = GetCertificateContextPropertySimple
  1001. (pCertContext,
  1002. CERT_HASH_PROP_ID,
  1003. &hashBlobExpected)))
  1004. goto GetCertificateContextPropertySimpleError;
  1005. // Initialize the enumeration.
  1006. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(XEPR_ENUM_FIRST, 0, NULL)))
  1007. goto enumPendingRequestWStrError;
  1008. for (lIndex = 0; TRUE; lIndex++) // Find the index of the pending request in the request store:
  1009. {
  1010. hashBlob.pbData = NULL;
  1011. hashBlob.cbData = 0;
  1012. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr
  1013. (lIndex,
  1014. XEPR_HASH,
  1015. (LPVOID)&hashBlob)))
  1016. goto enumPendingRequestWStrError;
  1017. hashBlob.pbData = (LPBYTE)LocalAlloc(LPTR, hashBlob.cbData);
  1018. if (NULL == hashBlob.pbData)
  1019. goto MemoryError;
  1020. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr
  1021. (lIndex,
  1022. XEPR_HASH,
  1023. (LPVOID)&hashBlob)))
  1024. goto enumPendingRequestWStrError;
  1025. // We've found the request we want.
  1026. if ((hashBlobExpected.cbData == hashBlob.cbData) &&
  1027. (0 == memcmp(hashBlobExpected.pbData, hashBlob.pbData, hashBlob.cbData)))
  1028. break;
  1029. }
  1030. // Test XEPR_REQUESTID property:
  1031. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_REQUESTID, (LPVOID)&dwRequestID)))
  1032. goto enumPendingRequestWStrError;
  1033. if (dwRequestID != pPendingInfo->dwRequestID)
  1034. goto pendingInfoDoesntMatchError;
  1035. // Test XEPR_CANAME property:
  1036. caNameBlob.pbData = NULL;
  1037. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_CANAME, (LPVOID)&caNameBlob)))
  1038. goto enumPendingRequestWStrError;
  1039. caNameBlob.pbData = (LPBYTE)LocalAlloc(LPTR, caNameBlob.cbData);
  1040. if (NULL == caNameBlob.pbData)
  1041. goto MemoryError;
  1042. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_CANAME, (LPVOID)&caNameBlob)))
  1043. goto enumPendingRequestWStrError;
  1044. if (0 != wcscmp((LPWSTR)caNameBlob.pbData, pPendingInfo->pwszCAName))
  1045. goto enumPendingRequestWStrError;
  1046. // Test XEPR_CADNS property:
  1047. caDNSBlob.pbData = NULL;
  1048. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_CADNS, (LPVOID)&caDNSBlob)))
  1049. goto enumPendingRequestWStrError;
  1050. caDNSBlob.pbData = (LPBYTE)LocalAlloc(LPTR, caDNSBlob.cbData);
  1051. if (NULL == caDNSBlob.pbData)
  1052. goto MemoryError;
  1053. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_CADNS, (LPVOID)&caDNSBlob)))
  1054. goto enumPendingRequestWStrError;
  1055. if (0 != wcscmp((LPWSTR)caDNSBlob.pbData, pPendingInfo->pwszCADNS))
  1056. goto enumPendingRequestWStrError;
  1057. // Test XEPR_CAFRIENDLYNAME property:
  1058. // Note: it is legal to pass NULL when setting the friendly name property. In this case,
  1059. // the friendly name property is set to the empty string.
  1060. if (NULL == pPendingInfo->pwszFriendlyName) { pPendingInfo->pwszFriendlyName = L""; }
  1061. friendlyNameBlob.pbData = NULL;
  1062. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_CAFRIENDLYNAME, (LPVOID)&friendlyNameBlob)))
  1063. goto enumPendingRequestWStrError;
  1064. friendlyNameBlob.pbData = (LPBYTE)LocalAlloc(LPTR, friendlyNameBlob.cbData);
  1065. if (NULL == friendlyNameBlob.pbData)
  1066. goto MemoryError;
  1067. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_CAFRIENDLYNAME, (LPVOID)&friendlyNameBlob)))
  1068. goto enumPendingRequestWStrError;
  1069. if (0 != wcscmp((LPWSTR)friendlyNameBlob.pbData, pPendingInfo->pwszFriendlyName))
  1070. goto enumPendingRequestWStrError;
  1071. // Test XEPR_V1TEMPLATENAME property:
  1072. #if 0
  1073. v1TemplateNameBlob.pbData = NULL;
  1074. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_V1TEMPLATENAME, (LPVOID)&v1TemplateNameBlob)))
  1075. goto enumPendingRequestWStrError;
  1076. v1TemplateNameBlob.pbData = (LPBYTE)LocalAlloc(LPTR, v1TemplateNameBlob.cbData);
  1077. if (NULL == v1TemplateNameBlob.pbData)
  1078. goto ErrorReturn;
  1079. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_V1TEMPLATENAME, (LPVOID)&v1TemplateNameBlob)))
  1080. goto enumPendingRequestWStrError;
  1081. if (0 != wcscmp(pwszV1TemplateNameExpected, (LPWSTR)v1TemplateNameBlob.pbData))
  1082. goto enumPendingRequestWStrError;
  1083. #endif
  1084. // Test XEPR_DATE property:
  1085. if (S_OK != (hr = pIEnroll4->enumPendingRequestWStr(lIndex, XEPR_DATE, (LPVOID)&ftDate)))
  1086. goto enumPendingRequestWStrError;
  1087. ftDateExpected = pCertContext->pCertInfo->NotAfter;
  1088. if (0 != memcmp((LPVOID)&ftDateExpected, (LPVOID)&ftDate, sizeof(FILETIME)))
  1089. goto enumPendingRequestWStrError;
  1090. // Test XEPR_V2TEMPLATEOID property:
  1091. // XEPR_V2TEMPLATEOID property not yet impl.
  1092. // Test XEPR_VERSION property:
  1093. // XEPR_VERSION property not yet impl.
  1094. fResult = TRUE;
  1095. CommonReturn:
  1096. if (NULL != caDNSBlob.pbData) { LocalFree(caDNSBlob.pbData); }
  1097. if (NULL != caNameBlob.pbData) { LocalFree(caNameBlob.pbData); }
  1098. if (NULL != friendlyNameBlob.pbData) { LocalFree(friendlyNameBlob.pbData); }
  1099. if (NULL != hashBlob.pbData) { LocalFree(hashBlob.pbData); }
  1100. if (NULL != v1TemplateNameBlob.pbData) { LocalFree(v1TemplateNameBlob.pbData); }
  1101. if (NULL != pCertContext) { CertFreeCertificateContext(pCertContext); }
  1102. return fResult;
  1103. ErrorReturn:
  1104. fResult = FALSE;
  1105. SetLastError(hr);
  1106. goto CommonReturn;
  1107. PRINT_ERROR2(enumPendingRequestWStrError, hr);
  1108. PRINT_ERROR2(GetCertificateContextPropertySimpleError, hr);
  1109. PRINT_ERROR2(GetCertOutOfStoreError, hr = GetLastError());
  1110. PRINT_ERROR2(InvalidArgError, hr = E_INVALIDARG);
  1111. PRINT_ERROR2(MemoryError, hr = E_OUTOFMEMORY);
  1112. PRINT_ERROR2(pendingInfoDoesntMatchError, hr = E_FAIL);
  1113. }
  1114. BOOL TXEnrollPendingAPITester::TestMethod_setPendingInfoWStr(IEnroll4 *pIEnroll4,
  1115. CRYPT_DATA_BLOB pkcs10Blob,
  1116. PENDING_INFO *pPendingInfo)
  1117. {
  1118. BOOL fResult;
  1119. CRYPT_DATA_BLOB dataBlob;
  1120. DWORD dwSize;
  1121. LPBYTE pbPendingInfo;
  1122. HRESULT hr = S_OK;
  1123. PCCERT_CONTEXT pCertContext = NULL;
  1124. WCHAR wszDNNName[] = L"CN=Xenroll setPendingInfoWStr Test 1";
  1125. ZeroMemory(&dataBlob, sizeof(dataBlob));
  1126. if (NULL == pIEnroll4 || NULL == pPendingInfo)
  1127. goto InvalidArgError;
  1128. hr = pIEnroll4->setPendingRequestInfoWStr
  1129. (pPendingInfo->dwRequestID,
  1130. pPendingInfo->pwszCADNS,
  1131. pPendingInfo->pwszCAName,
  1132. pPendingInfo->pwszFriendlyName);
  1133. if (hr != pPendingInfo->hrExpectedResult)
  1134. goto setPendingRequestInfoWStrError;
  1135. if (hr != S_OK)
  1136. {
  1137. // This test was supposed to fail.
  1138. fResult = TRUE;
  1139. goto CommonReturn;
  1140. }
  1141. pCertContext = GetCertOutOfStore(&pkcs10Blob, pPendingInfo->dwStoreFlags, pPendingInfo->pwszStoreName);
  1142. if (NULL == pCertContext)
  1143. goto GetCertOutOfStoreError;
  1144. if (!CertGetCertificateContextProperty
  1145. (pCertContext,
  1146. CERT_ENROLLMENT_PROP_ID,
  1147. NULL,
  1148. &(dataBlob.cbData)))
  1149. goto CertGetCertificateContextPropertyError;
  1150. dataBlob.pbData = (LPBYTE)LocalAlloc(LPTR, dataBlob.cbData);
  1151. if (NULL == dataBlob.pbData)
  1152. goto MemoryError;
  1153. if (!CertGetCertificateContextProperty
  1154. (pCertContext,
  1155. CERT_ENROLLMENT_PROP_ID,
  1156. dataBlob.pbData,
  1157. &(dataBlob.cbData)))
  1158. goto CertGetCertificateContextPropertyError;
  1159. // Is request ID set correctly?
  1160. pbPendingInfo = dataBlob.pbData;
  1161. if (0 != memcmp(pbPendingInfo, &pPendingInfo->dwRequestID, sizeof(DWORD)))
  1162. goto setPendingRequestInfoWStrError;
  1163. pbPendingInfo += sizeof(DWORD);
  1164. // Is CADNS set correctly?
  1165. dwSize = wcslen(pPendingInfo->pwszCADNS) + 1;
  1166. if (0 != memcmp(pbPendingInfo, &dwSize, sizeof(DWORD)))
  1167. goto setPendingRequestInfoWStrError;
  1168. pbPendingInfo += sizeof(DWORD);
  1169. if (0 != memcmp(pbPendingInfo, pPendingInfo->pwszCADNS, sizeof(WCHAR) * dwSize))
  1170. goto setPendingRequestInfoWStrError;
  1171. pbPendingInfo += sizeof(WCHAR) * dwSize;
  1172. // Is CAName set correctly?
  1173. dwSize = wcslen(pPendingInfo->pwszCAName) + 1;
  1174. if (0 != memcmp(pbPendingInfo, &dwSize, sizeof(DWORD)))
  1175. goto setPendingRequestInfoWStrError;
  1176. pbPendingInfo += sizeof(DWORD);
  1177. if (0 != memcmp(pbPendingInfo, pPendingInfo->pwszCAName, sizeof(WCHAR) * dwSize))
  1178. goto setPendingRequestInfoWStrError;
  1179. pbPendingInfo += sizeof(WCHAR) * dwSize;
  1180. // Is friendly name set correctly?
  1181. // Note: it is legal to pass NULL when setting the friendly name property. In this case,
  1182. // the friendly name property is set to the empty string.
  1183. if (NULL == pPendingInfo->pwszFriendlyName) { pPendingInfo->pwszFriendlyName = L""; }
  1184. dwSize = wcslen(pPendingInfo->pwszFriendlyName) + 1;
  1185. if (0 != memcmp(pbPendingInfo, &dwSize, sizeof(DWORD)))
  1186. goto setPendingRequestInfoWStrError;
  1187. pbPendingInfo += sizeof(DWORD);
  1188. if (0 != memcmp(pbPendingInfo, pPendingInfo->pwszFriendlyName, sizeof(WCHAR) * dwSize))
  1189. goto setPendingRequestInfoWStrError;
  1190. pbPendingInfo += sizeof(WCHAR) * dwSize;
  1191. // Success!
  1192. fResult = TRUE;
  1193. CommonReturn:
  1194. if (NULL != dataBlob.pbData) { LocalFree(dataBlob.pbData); }
  1195. if (NULL != pCertContext) { CertFreeCertificateContext(pCertContext); }
  1196. return fResult;
  1197. ErrorReturn:
  1198. fResult = FALSE;
  1199. SetLastError(hr);
  1200. goto CommonReturn;
  1201. PRINT_ERROR2(CertGetCertificateContextPropertyError, hr = GetLastError());
  1202. PRINT_ERROR2(GetCertOutOfStoreError, hr = GetLastError());
  1203. PRINT_ERROR2(InvalidArgError, hr = E_INVALIDARG);
  1204. PRINT_ERROR2(MemoryError, hr = E_OUTOFMEMORY);
  1205. PRINT_ERROR2(setPendingRequestInfoWStrError, hr);
  1206. }
  1207. static BOOL WriteBlobToFile(LPCWSTR wszFile, DWORD dwFlags, PCRYPT_DATA_BLOB pBlob) {
  1208. HANDLE hFile = NULL;
  1209. BOOL fRet = TRUE;
  1210. DWORD cb = 0;
  1211. // open the File
  1212. if( fRet = ((hFile = CreateFileW(
  1213. wszFile,
  1214. GENERIC_WRITE,
  1215. FILE_SHARE_READ,
  1216. NULL,
  1217. CREATE_ALWAYS,
  1218. FILE_ATTRIBUTE_NORMAL,
  1219. NULL)) != NULL && hFile != INVALID_HANDLE_VALUE) ) {
  1220. // write out the data
  1221. fRet = WriteFile(
  1222. hFile,
  1223. pBlob->pbData,
  1224. pBlob->cbData,
  1225. &cb,
  1226. NULL);
  1227. CloseHandle(hFile);
  1228. }
  1229. return(fRet);
  1230. }
  1231. // Basic operation, create keys, gen request, accept cert.
  1232. BOOL Test1() {
  1233. IEnroll * pIEnroll = NULL;
  1234. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1235. CRYPT_DATA_BLOB blobPKCS10;
  1236. BYTE arSha1Hash[20];
  1237. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1238. BOOL fRet = TRUE;
  1239. DWORD Err = GetLastError();
  1240. HRESULT hr = S_OK;
  1241. LPWSTR szwHashAlg = NULL;
  1242. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1243. // TEST 1 Normal usage
  1244. pIEnroll = PIEnrollGetNoCOM();
  1245. if(S_OK != pIEnroll->get_HashAlgorithmWStr(&szwHashAlg) ||
  1246. wcscmp(szwHashAlg, L"1.3.14.3.2.26") ) {
  1247. SetLastError(NTE_BAD_HASH);
  1248. goto ErrorNoHashAlg;
  1249. }
  1250. if(S_OK != pIEnroll->put_HashAlgorithmWStr(L"MD2") ) {
  1251. SetLastError(NTE_BAD_HASH);
  1252. goto ErrorNoHashAlg;
  1253. }
  1254. if(S_OK != pIEnroll->get_HashAlgorithmWStr(&szwHashAlg) ||
  1255. wcscmp(szwHashAlg, L"1.2.840.113549.2.2") ) {
  1256. SetLastError(NTE_BAD_HASH);
  1257. goto ErrorNoHashAlg;
  1258. }
  1259. // enroll for a new cert
  1260. if( S_OK != (hr = pIEnroll->createPKCS10WStr(L"CN=XEnroll Test", L"1.2.3.4, 1.2.6.7", &blobPKCS10)) ) {
  1261. SetLastError(hr);
  1262. goto ErrorCreatePkCS10;
  1263. }
  1264. if( NULL == (pBlobPKCS7 = MakePKCS7Response(&blobPKCS10, &hash)) )
  1265. goto ErrorMakePKCS7Response;
  1266. // accept the new cert
  1267. if( S_OK != (hr = pIEnroll->acceptPKCS7Blob(pBlobPKCS7)) ) {
  1268. SetLastError(hr);
  1269. goto ErrorAcceptPKCS7;
  1270. }
  1271. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_CURRENT_USER) )
  1272. goto ErrorRemoveCertFromStore;
  1273. CommonReturn:
  1274. if(pBlobPKCS7 != NULL)
  1275. free(pBlobPKCS7);
  1276. if(pIEnroll != NULL)
  1277. pIEnroll->Release();
  1278. if(blobPKCS10.pbData != NULL)
  1279. LocalFree(blobPKCS10.pbData);
  1280. SetLastError(Err);
  1281. return(fRet);
  1282. ErrorReturn:
  1283. Err = GetLastError();
  1284. fRet = FALSE;
  1285. goto CommonReturn;
  1286. PRINT_ERROR(ErrorNoHashAlg);
  1287. PRINT_ERROR(ErrorCreatePkCS10);
  1288. PRINT_ERROR(ErrorAcceptPKCS7);
  1289. PRINT_ERROR(ErrorMakePKCS7Response);
  1290. PRINT_ERROR(ErrorRemoveCertFromStore);
  1291. }
  1292. // Test basic operation but with no EKU or no DN name
  1293. BOOL Test2() {
  1294. IEnroll * pIEnroll = NULL;
  1295. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1296. CRYPT_DATA_BLOB blobPKCS10;
  1297. BYTE arSha1Hash[20];
  1298. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1299. BOOL fRet = TRUE;
  1300. DWORD Err = GetLastError();
  1301. HRESULT hr = S_OK;
  1302. // TEST 1 Normal usage
  1303. pIEnroll = PIEnrollGetNoCOM();
  1304. // enroll for a new cert
  1305. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1306. if( S_OK != (hr = pIEnroll->createPKCS10WStr(NULL, NULL, &blobPKCS10)) ) {
  1307. SetLastError(hr);
  1308. goto ErrorCreatePkCS10;
  1309. }
  1310. if( NULL == (pBlobPKCS7 = MakePKCS7Response(&blobPKCS10, &hash)) )
  1311. goto ErrorMakePKCS7Response;
  1312. // accept the new cert
  1313. if( S_OK != (hr = pIEnroll->acceptPKCS7Blob(pBlobPKCS7)) ) {
  1314. SetLastError(hr);
  1315. goto ErrorAcceptPKCS7;
  1316. }
  1317. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_CURRENT_USER) )
  1318. goto ErrorRemoveCertFromStore;
  1319. CommonReturn:
  1320. if(pBlobPKCS7 != NULL)
  1321. free(pBlobPKCS7);
  1322. if(pIEnroll != NULL)
  1323. pIEnroll->Release();
  1324. if(blobPKCS10.pbData != NULL)
  1325. LocalFree(blobPKCS10.pbData);
  1326. SetLastError(Err);
  1327. return(fRet);
  1328. ErrorReturn:
  1329. Err = GetLastError();
  1330. fRet = FALSE;
  1331. goto CommonReturn;
  1332. PRINT_ERROR(ErrorCreatePkCS10);
  1333. PRINT_ERROR(ErrorAcceptPKCS7);
  1334. PRINT_ERROR(ErrorMakePKCS7Response);
  1335. PRINT_ERROR(ErrorRemoveCertFromStore);
  1336. }
  1337. // Test Renewal, Create original cert, create renewal request, create renewed cert
  1338. BOOL Test3() {
  1339. IEnroll * pIEnroll = NULL;
  1340. IEnroll * pIEnroll2 = NULL;
  1341. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1342. PCRYPT_DATA_BLOB pBlobPKCS72 = NULL;
  1343. PCRYPT_DATA_BLOB pBlobPKCS102 = NULL;
  1344. PCCERT_CONTEXT pCert1 = NULL;
  1345. CRYPT_DATA_BLOB blobPKCS10;
  1346. CRYPT_DATA_BLOB blobPKCS102;
  1347. BYTE arSha1Hash[20];
  1348. BYTE arSha1Hash2[20];
  1349. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1350. CRYPT_HASH_BLOB hash2 = {sizeof(arSha1Hash2), arSha1Hash2};
  1351. BOOL fRet = TRUE;
  1352. DWORD Err = GetLastError();
  1353. HRESULT hr = S_OK;
  1354. // TEST 1 Normal usage
  1355. pIEnroll = PIEnrollGetNoCOM();
  1356. // enroll for a new cert
  1357. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1358. if( S_OK != (hr = pIEnroll->createPKCS10WStr(NULL, NULL, &blobPKCS10)) ) {
  1359. SetLastError(hr);
  1360. goto ErrorCreatePkCS10;
  1361. }
  1362. if( NULL == (pBlobPKCS7 = MakePKCS7Response(&blobPKCS10, &hash)) )
  1363. goto ErrorMakePKCS7Response;
  1364. // accept the new cert
  1365. if( S_OK != (hr = pIEnroll->acceptPKCS7Blob(pBlobPKCS7)) ) {
  1366. SetLastError(hr);
  1367. goto ErrorAcceptPKCS7;
  1368. }
  1369. // get the cert just created
  1370. if( NULL == (pCert1 = pIEnroll->getCertContextFromPKCS7(pBlobPKCS7)) ) {
  1371. goto ErrorGetCertContextFromPKCS7;
  1372. }
  1373. pIEnroll2 = PIEnrollGetNoCOM();
  1374. // enroll for a new cert, Really I will get a 7 back with a 10 in it.
  1375. if( S_OK != (hr = pIEnroll2->put_RenewalCertificate(pCert1)) ) {
  1376. SetLastError(hr);
  1377. goto ErrorPut_RenewalCertificate;
  1378. }
  1379. memset(&blobPKCS102, 0, sizeof(blobPKCS102));
  1380. if( S_OK != (hr = pIEnroll2->createPKCS10WStr(NULL, NULL, &blobPKCS102)) ) {
  1381. SetLastError(hr);
  1382. goto ErrorCreatePkCS10;
  1383. }
  1384. // get the pkcs10 from the pkcs7
  1385. if( NULL == (pBlobPKCS102 = GetPKCS10FromPKCS7(&blobPKCS102)) )
  1386. goto ErrorGetPKCS10FromPKCS7;
  1387. // make the response
  1388. if( NULL == (pBlobPKCS72 = MakePKCS7Response(pBlobPKCS102, &hash2)) )
  1389. goto ErrorMakePKCS7Response;
  1390. // accept the new cert
  1391. if( S_OK != (hr = pIEnroll2->acceptPKCS7Blob(pBlobPKCS72)) ) {
  1392. SetLastError(hr);
  1393. goto ErrorAcceptPKCS7;
  1394. }
  1395. if( !RemoveCertFromStore(&hash2, L"MY", CERT_SYSTEM_STORE_CURRENT_USER) )
  1396. goto ErrorRemoveCertFromStore;
  1397. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_CURRENT_USER) )
  1398. goto ErrorRemoveCertFromStore;
  1399. CommonReturn:
  1400. if(pCert1 != NULL)
  1401. CertFreeCertificateContext(pCert1);
  1402. if(pBlobPKCS7 != NULL)
  1403. free(pBlobPKCS7);
  1404. if(pBlobPKCS72 != NULL)
  1405. free(pBlobPKCS72);
  1406. if(pBlobPKCS102 != NULL)
  1407. free(pBlobPKCS102);
  1408. if(pIEnroll != NULL)
  1409. pIEnroll->Release();
  1410. if(pIEnroll2 != NULL)
  1411. pIEnroll2->Release();
  1412. if(blobPKCS10.pbData != NULL)
  1413. LocalFree(blobPKCS10.pbData);
  1414. if(blobPKCS102.pbData != NULL)
  1415. LocalFree(blobPKCS102.pbData);
  1416. SetLastError(Err);
  1417. return(fRet);
  1418. ErrorReturn:
  1419. Err = GetLastError();
  1420. fRet = FALSE;
  1421. goto CommonReturn;
  1422. PRINT_ERROR(ErrorCreatePkCS10);
  1423. PRINT_ERROR(ErrorAcceptPKCS7);
  1424. PRINT_ERROR(ErrorMakePKCS7Response);
  1425. PRINT_ERROR(ErrorRemoveCertFromStore);
  1426. PRINT_ERROR(ErrorGetCertContextFromPKCS7);
  1427. PRINT_ERROR(ErrorGetPKCS10FromPKCS7);
  1428. PRINT_ERROR(ErrorPut_RenewalCertificate);
  1429. }
  1430. // Basic operation, create keys, gen request, accept cert, but put the certs in HKLM
  1431. BOOL Test4() {
  1432. IEnroll * pIEnroll = NULL;
  1433. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1434. CRYPT_DATA_BLOB blobPKCS10;
  1435. BYTE arSha1Hash[20];
  1436. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1437. BOOL fRet = TRUE;
  1438. DWORD Err = GetLastError();
  1439. HRESULT hr = S_OK;
  1440. // TEST 1 Normal usage
  1441. if( NULL == (pIEnroll = PIEnrollGetNoCOM()))
  1442. goto ErrorPIEnrollGetNoCOM;
  1443. // say I want the result in HKLM
  1444. pIEnroll->put_MyStoreFlags(CERT_SYSTEM_STORE_LOCAL_MACHINE);
  1445. // enroll for a new cert
  1446. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1447. if( S_OK != (hr = pIEnroll->createPKCS10WStr(L"CN=XEnroll Test", L"1.2.3.4", &blobPKCS10)) ) {
  1448. SetLastError(hr);
  1449. goto ErrorCreatePkCS10;
  1450. }
  1451. pIEnroll->Release();
  1452. if( NULL == (pIEnroll = PIEnrollGetNoCOM()))
  1453. goto ErrorPIEnrollGetNoCOM;
  1454. if( NULL == (pBlobPKCS7 = MakePKCS7ResponseMachine(&blobPKCS10, &hash)) )
  1455. goto ErrorMakePKCS7Response;
  1456. //this is new xenroll instance, set to machine store
  1457. pIEnroll->put_MyStoreFlags(CERT_SYSTEM_STORE_LOCAL_MACHINE);
  1458. // accept the new cert
  1459. if( S_OK != (hr = pIEnroll->acceptPKCS7Blob(pBlobPKCS7)) ) {
  1460. SetLastError(hr);
  1461. goto ErrorAcceptPKCS7;
  1462. }
  1463. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_LOCAL_MACHINE) )
  1464. goto ErrorRemoveCertFromStore;
  1465. CommonReturn:
  1466. if(pBlobPKCS7 != NULL)
  1467. free(pBlobPKCS7);
  1468. if(pIEnroll != NULL)
  1469. pIEnroll->Release();
  1470. if(blobPKCS10.pbData != NULL)
  1471. LocalFree(blobPKCS10.pbData);
  1472. SetLastError(Err);
  1473. return(fRet);
  1474. ErrorReturn:
  1475. Err = GetLastError();
  1476. fRet = FALSE;
  1477. goto CommonReturn;
  1478. PRINT_ERROR(ErrorPIEnrollGetNoCOM);
  1479. PRINT_ERROR(ErrorCreatePkCS10);
  1480. PRINT_ERROR(ErrorAcceptPKCS7);
  1481. PRINT_ERROR(ErrorMakePKCS7Response);
  1482. PRINT_ERROR(ErrorRemoveCertFromStore);
  1483. }
  1484. BOOL Test5() {
  1485. #define DNNAME L"CN=Test"
  1486. DWORD Err = GetLastError();
  1487. BOOL fRet = TRUE;
  1488. HCRYPTPROV hProv = NULL;
  1489. HCRYPTKEY hKey = NULL;
  1490. PCCERT_CONTEXT pCertContext = NULL;
  1491. DWORD dwFlagsT = 0;
  1492. CERT_NAME_BLOB nameBlob;
  1493. CRYPT_KEY_PROV_INFO keyProvInfo;
  1494. GUID guidContainerName;
  1495. SYSTEMTIME startTime;
  1496. SYSTEMTIME endTime;
  1497. memset(&keyProvInfo, 0, sizeof(CRYPT_KEY_PROV_INFO));
  1498. memset(&nameBlob, 0, sizeof(CERT_NAME_BLOB));
  1499. memset(&guidContainerName, 0, sizeof(GUID));
  1500. // get a container based on a guid
  1501. UuidCreate(&guidContainerName);
  1502. UuidToStringW(&guidContainerName, &keyProvInfo.pwszContainerName);
  1503. keyProvInfo.pwszProvName = L"";
  1504. keyProvInfo.dwProvType = PROV_RSA_FULL;
  1505. keyProvInfo.dwFlags = 0;
  1506. keyProvInfo.cProvParam = 0;
  1507. keyProvInfo.rgProvParam = NULL;
  1508. keyProvInfo.dwKeySpec = AT_SIGNATURE;
  1509. if( !CryptAcquireContextW(&hProv,
  1510. keyProvInfo.pwszContainerName,
  1511. keyProvInfo.pwszProvName,
  1512. keyProvInfo.dwProvType,
  1513. CRYPT_NEWKEYSET) ) {
  1514. hProv = NULL;
  1515. goto ErrorCryptAcquireContext;
  1516. }
  1517. // we better not have a key here, so gen it
  1518. if(!CryptGenKey( hProv,
  1519. keyProvInfo.dwKeySpec,
  1520. 0,
  1521. &hKey) )
  1522. goto ErrorCryptGenKey;
  1523. // get the Subject DN only if one is specified
  1524. if( !CertStrToNameW(
  1525. CRYPT_ASN_ENCODING,
  1526. DNNAME,
  1527. 0,
  1528. NULL,
  1529. NULL,
  1530. &nameBlob.cbData,
  1531. NULL) ||
  1532. (nameBlob.pbData = (BYTE *) _alloca(nameBlob.cbData)) == NULL ||
  1533. !CertStrToNameW(
  1534. CRYPT_ASN_ENCODING,
  1535. DNNAME,
  1536. 0,
  1537. NULL,
  1538. nameBlob.pbData,
  1539. &nameBlob.cbData,
  1540. NULL) ) {
  1541. goto ErrorCertStrToNameW;
  1542. }
  1543. // check that predefine dates work
  1544. memset(&startTime, 0, sizeof(startTime));
  1545. startTime.wYear = 1998;
  1546. startTime.wMonth = 6;
  1547. startTime.wDay = 20;
  1548. startTime.wHour = 12;
  1549. memset(&endTime, 0, sizeof(endTime));
  1550. endTime.wYear = 1998;
  1551. endTime.wMonth = 7;
  1552. endTime.wDay = 10;
  1553. endTime.wHour = 4;
  1554. if ( NULL == (pCertContext = CertCreateSelfSignCertificate(
  1555. hProv,
  1556. &nameBlob,
  1557. 0,
  1558. NULL,
  1559. NULL,
  1560. &startTime,
  1561. &endTime,
  1562. NULL
  1563. ) ) )
  1564. goto ErrorCertCreateSelfSignCertificate;
  1565. dwFlagsT = CERT_STORE_SIGNATURE_FLAG | CERT_STORE_TIME_VALIDITY_FLAG;
  1566. if( !CertVerifySubjectCertificateContext(
  1567. pCertContext,
  1568. pCertContext,
  1569. &dwFlagsT
  1570. ) )
  1571. goto ErrorCertVerifySubjectCertificateContext;
  1572. // check the time to see if it is correct
  1573. if( pCertContext->pCertInfo->NotBefore.dwLowDateTime != 0xF34E2000 ||
  1574. pCertContext->pCertInfo->NotBefore.dwHighDateTime != 0x1BD9C42 ||
  1575. pCertContext->pCertInfo->NotAfter.dwLowDateTime != 0x356DE000 ||
  1576. pCertContext->pCertInfo->NotAfter.dwHighDateTime != 0x1BDABB7 ) {
  1577. SetLastError(ERROR_INVALID_TIME);
  1578. goto ErrorDateTime;
  1579. }
  1580. CommonReturn:
  1581. if (hProv != NULL) {
  1582. HCRYPTPROV hDeleteProv;
  1583. CryptAcquireContextW(&hDeleteProv,
  1584. keyProvInfo.pwszContainerName,
  1585. keyProvInfo.pwszProvName,
  1586. keyProvInfo.dwProvType,
  1587. CRYPT_DELETEKEYSET);
  1588. }
  1589. if(pCertContext !=NULL)
  1590. CertFreeCertificateContext(pCertContext);
  1591. if(hKey != NULL)
  1592. CryptDestroyKey(hKey);
  1593. if(keyProvInfo.pwszContainerName != NULL)
  1594. RpcStringFreeW(&keyProvInfo.pwszContainerName);
  1595. if(hProv != NULL)
  1596. CryptReleaseContext(hProv, 0);
  1597. SetLastError(Err);
  1598. return(fRet);
  1599. ErrorReturn:
  1600. Err = GetLastError();
  1601. fRet = FALSE;
  1602. goto CommonReturn;
  1603. PRINT_ERROR(ErrorCryptAcquireContext);
  1604. PRINT_ERROR(ErrorCertStrToNameW);
  1605. PRINT_ERROR(ErrorCryptGenKey);
  1606. PRINT_ERROR(ErrorCertVerifySubjectCertificateContext);
  1607. PRINT_ERROR(ErrorCertCreateSelfSignCertificate);
  1608. PRINT_ERROR(ErrorDateTime);
  1609. }
  1610. // Basic operation, create keys, gen request, accept cert.
  1611. BOOL Test6() {
  1612. ICEnroll * pEnroll = NULL;
  1613. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1614. BSTR bstrRequest = NULL;
  1615. CRYPT_DATA_BLOB blobPKCS10;
  1616. BYTE arSha1Hash[20];
  1617. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1618. BOOL fRet = TRUE;
  1619. DWORD Err = GetLastError();
  1620. HRESULT hr = S_OK;
  1621. BSTR bstrResponse = NULL;
  1622. if( S_OK != CoInitialize(NULL) )
  1623. goto ErrorCoInitializeEx;
  1624. // TEST 1 Normal usage
  1625. if( S_OK != (hr = CoCreateInstance(CLSID_CEnroll, NULL, CLSCTX_INPROC_SERVER, IID_ICEnroll, (void **) &pEnroll)) ) {
  1626. SetLastError(hr);
  1627. goto ErrorCoCreateInstance;
  1628. }
  1629. // enroll for a new cert
  1630. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1631. if( S_OK != (hr = pEnroll->createPKCS10(L"CN=XEnroll Test", L"1.2.3.4, 1.2.6.7", &bstrRequest)) ) {
  1632. SetLastError(hr);
  1633. goto ErrorCreatePkCS10;
  1634. }
  1635. blobPKCS10.cbData = SysStringByteLen(bstrRequest);
  1636. blobPKCS10.pbData = (PBYTE) bstrRequest;
  1637. if( NULL == (pBlobPKCS7 = MakePKCS7Response(&blobPKCS10, &hash)) )
  1638. goto ErrorMakePKCS7Response;
  1639. if( NULL == (bstrResponse = SysAllocStringByteLen((LPCSTR) pBlobPKCS7->pbData, pBlobPKCS7->cbData)) )
  1640. goto ErrorSysAllocStringByteLen;
  1641. // accept the new cert
  1642. if( S_OK != (hr = pEnroll->acceptPKCS7(bstrResponse)) ) {
  1643. SetLastError(hr);
  1644. goto ErrorAcceptPKCS7;
  1645. }
  1646. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_CURRENT_USER) )
  1647. goto ErrorRemoveCertFromStore;
  1648. CommonReturn:
  1649. if(pBlobPKCS7 != NULL)
  1650. free(pBlobPKCS7);
  1651. if(pEnroll != NULL)
  1652. pEnroll->Release();
  1653. if(bstrResponse != NULL)
  1654. SysFreeString(bstrResponse);
  1655. CoUninitialize();
  1656. SetLastError(Err);
  1657. return(fRet);
  1658. ErrorReturn:
  1659. Err = GetLastError();
  1660. fRet = FALSE;
  1661. goto CommonReturn;
  1662. PRINT_ERROR(ErrorCoInitializeEx);
  1663. PRINT_ERROR(ErrorCoCreateInstance);
  1664. PRINT_ERROR(ErrorSysAllocStringByteLen);
  1665. PRINT_ERROR(ErrorCreatePkCS10);
  1666. PRINT_ERROR(ErrorAcceptPKCS7);
  1667. PRINT_ERROR(ErrorMakePKCS7Response);
  1668. PRINT_ERROR(ErrorRemoveCertFromStore);
  1669. }
  1670. // Basic operation, create keys, gen request, accept cert, but put the certs in HKLM
  1671. BOOL Test7() {
  1672. IEnroll * pIEnroll = NULL;
  1673. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1674. CRYPT_DATA_BLOB blobPKCS10;
  1675. BYTE arSha1Hash[20];
  1676. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1677. BOOL fRet = TRUE;
  1678. DWORD Err = GetLastError();
  1679. HRESULT hr = S_OK;
  1680. // TEST 1 Normal usage
  1681. if( NULL == (pIEnroll = PIEnrollGetNoCOM()))
  1682. goto ErrorPIEnrollGetNoCOM;
  1683. // say I want the result in HKLM
  1684. pIEnroll->put_RequestStoreFlags(CERT_SYSTEM_STORE_LOCAL_MACHINE);
  1685. // enroll for a new cert
  1686. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1687. if( S_OK != (hr = pIEnroll->createPKCS10WStr(L"CN=XEnroll Test", L"1.2.3.4", &blobPKCS10)) ) {
  1688. SetLastError(hr);
  1689. goto ErrorCreatePkCS10;
  1690. }
  1691. pIEnroll->Release();
  1692. if( NULL == (pIEnroll = PIEnrollGetNoCOM()))
  1693. goto ErrorPIEnrollGetNoCOM;
  1694. if( NULL == (pBlobPKCS7 = MakePKCS7ResponseMachine(&blobPKCS10, &hash)) )
  1695. goto ErrorMakePKCS7Response;
  1696. // say I want the result in HKLM
  1697. pIEnroll->put_MyStoreFlags(CERT_SYSTEM_STORE_LOCAL_MACHINE);
  1698. // accept the new cert
  1699. if( S_OK != (hr = pIEnroll->acceptPKCS7Blob(pBlobPKCS7)) ) {
  1700. SetLastError(hr);
  1701. goto ErrorAcceptPKCS7;
  1702. }
  1703. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_LOCAL_MACHINE) )
  1704. goto ErrorRemoveCertFromStore;
  1705. CommonReturn:
  1706. if(pBlobPKCS7 != NULL)
  1707. free(pBlobPKCS7);
  1708. if(pIEnroll != NULL)
  1709. pIEnroll->Release();
  1710. if(blobPKCS10.pbData != NULL)
  1711. LocalFree(blobPKCS10.pbData);
  1712. SetLastError(Err);
  1713. return(fRet);
  1714. ErrorReturn:
  1715. Err = GetLastError();
  1716. fRet = FALSE;
  1717. goto CommonReturn;
  1718. PRINT_ERROR(ErrorPIEnrollGetNoCOM);
  1719. PRINT_ERROR(ErrorCreatePkCS10);
  1720. PRINT_ERROR(ErrorAcceptPKCS7);
  1721. PRINT_ERROR(ErrorMakePKCS7Response);
  1722. PRINT_ERROR(ErrorRemoveCertFromStore);
  1723. }
  1724. // Test some alg enum stuff
  1725. BOOL Test8() {
  1726. IEnroll2 * pIEnroll = NULL;
  1727. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1728. CRYPT_DATA_BLOB blobPKCS10;
  1729. BYTE arSha1Hash[20];
  1730. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1731. BOOL fRet = TRUE;
  1732. DWORD Err = GetLastError();
  1733. HRESULT hr = S_OK;
  1734. LONG lFlags = 0;
  1735. DWORD i = 0;
  1736. LPWSTR wsz = NULL;
  1737. // TEST 1 Normal usage
  1738. if( NULL == (pIEnroll = PIEnroll2GetNoCOM()))
  1739. goto ErrorPIEnrollGetNoCOM;
  1740. // enum the default algids
  1741. while( (S_OK == (hr = pIEnroll->EnumAlgs(i++, ALG_CLASS_HASH, &lFlags))) ) {
  1742. if( (S_OK == (hr = pIEnroll->GetAlgNameWStr(lFlags, &wsz))) ) {
  1743. LocalFree(wsz);
  1744. }
  1745. else {
  1746. goto ErrorGetAlgName;
  1747. }
  1748. }
  1749. if( i == 1 ) {
  1750. SetLastError(hr);
  1751. goto ErrorEnumAlgs;
  1752. }
  1753. if(S_OK != (hr = pIEnroll->GetSupportedKeySpec(&lFlags))) {
  1754. SetLastError(hr);
  1755. goto ErrorGetSupportedKeySpec;
  1756. }
  1757. if(S_OK != (hr = pIEnroll->GetKeyLen(FALSE, FALSE, &lFlags))) {
  1758. SetLastError(hr);
  1759. goto ErrorGetKeyLen;
  1760. }
  1761. if(S_OK != (hr = pIEnroll->GetKeyLen(FALSE, TRUE, &lFlags))) {
  1762. SetLastError(hr);
  1763. goto ErrorGetKeyLen;
  1764. }
  1765. if(S_OK != (hr = pIEnroll->GetKeyLen(TRUE, FALSE, &lFlags))) {
  1766. SetLastError(hr);
  1767. goto ErrorGetKeyLen;
  1768. }
  1769. if(S_OK != (hr = pIEnroll->GetKeyLen(TRUE, TRUE, &lFlags))) {
  1770. SetLastError(hr);
  1771. goto ErrorGetKeyLen;
  1772. }
  1773. // get the keyspec data
  1774. // enroll for a new cert
  1775. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1776. if( S_OK != (hr = pIEnroll->createPKCS10WStr(L"CN=XEnroll Test", L"1.2.3.4", &blobPKCS10)) ) {
  1777. SetLastError(hr);
  1778. goto ErrorCreatePkCS10;
  1779. }
  1780. pIEnroll->Reset();
  1781. if( NULL == (pBlobPKCS7 = MakePKCS7Response(&blobPKCS10, &hash)) )
  1782. goto ErrorMakePKCS7Response;
  1783. // accept the new cert
  1784. if( S_OK != (hr = pIEnroll->acceptPKCS7Blob(pBlobPKCS7)) ) {
  1785. SetLastError(hr);
  1786. goto ErrorAcceptPKCS7;
  1787. }
  1788. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_CURRENT_USER) )
  1789. goto ErrorRemoveCertFromStore;
  1790. CommonReturn:
  1791. if(pBlobPKCS7 != NULL)
  1792. free(pBlobPKCS7);
  1793. if(pIEnroll != NULL)
  1794. pIEnroll->Release();
  1795. if(blobPKCS10.pbData != NULL)
  1796. LocalFree(blobPKCS10.pbData);
  1797. SetLastError(Err);
  1798. return(fRet);
  1799. ErrorReturn:
  1800. Err = GetLastError();
  1801. fRet = FALSE;
  1802. goto CommonReturn;
  1803. PRINT_ERROR(ErrorPIEnrollGetNoCOM);
  1804. PRINT_ERROR(ErrorCreatePkCS10);
  1805. PRINT_ERROR(ErrorAcceptPKCS7);
  1806. PRINT_ERROR(ErrorMakePKCS7Response);
  1807. PRINT_ERROR(ErrorRemoveCertFromStore);
  1808. PRINT_ERROR(ErrorEnumAlgs);
  1809. PRINT_ERROR(ErrorGetKeyLen);
  1810. PRINT_ERROR(ErrorGetSupportedKeySpec);
  1811. PRINT_ERROR(ErrorGetAlgName);
  1812. }
  1813. // Test some alg enum stuff
  1814. BOOL Test9() {
  1815. IEnroll2 * pIEnroll = NULL;
  1816. PCCERT_CONTEXT pCertContext = NULL;
  1817. CRYPT_DATA_BLOB blobPKCS10;
  1818. BOOL fRet = TRUE;
  1819. DWORD Err = GetLastError();
  1820. HRESULT hr = S_OK;
  1821. DWORD i = 0;
  1822. // TEST 1 Normal usage
  1823. if( NULL == (pIEnroll = PIEnroll2GetNoCOM()))
  1824. goto ErrorPIEnrollGetNoCOM;
  1825. for(i=0; i<100; i++) {
  1826. // get the keyspec data
  1827. // enroll for a new cert
  1828. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1829. if( S_OK != (hr = pIEnroll->createPKCS10WStr(L"CN=XEnroll Test", L"1.2.3.4", &blobPKCS10)) ) {
  1830. SetLastError(hr);
  1831. goto ErrorCreatePkCS10;
  1832. }
  1833. pIEnroll->Reset();
  1834. // clean up after ourself
  1835. if(NULL != (pCertContext = GetCertOutOfRequestStore(&blobPKCS10)) ) {
  1836. // delete the cert's private key
  1837. DeleteCertPrivateKey(pCertContext);
  1838. CertDeleteCertificateFromStore(pCertContext);
  1839. pCertContext = NULL;
  1840. }
  1841. if(blobPKCS10.pbData != NULL)
  1842. LocalFree(blobPKCS10.pbData);
  1843. }
  1844. CommonReturn:
  1845. if(pIEnroll != NULL)
  1846. pIEnroll->Release();
  1847. SetLastError(Err);
  1848. return(fRet);
  1849. ErrorReturn:
  1850. Err = GetLastError();
  1851. fRet = FALSE;
  1852. goto CommonReturn;
  1853. PRINT_ERROR(ErrorPIEnrollGetNoCOM);
  1854. PRINT_ERROR(ErrorCreatePkCS10);
  1855. }
  1856. // test to see if we can build PVK and SPC files
  1857. BOOL TestUI1() {
  1858. IEnroll * pIEnroll = NULL;
  1859. PCRYPT_DATA_BLOB pBlobPKCS7 = NULL;
  1860. CRYPT_DATA_BLOB blobPKCS10;
  1861. BYTE arSha1Hash[20];
  1862. CRYPT_HASH_BLOB hash = {sizeof(arSha1Hash), arSha1Hash};
  1863. BOOL fRet = TRUE;
  1864. DWORD Err = GetLastError();
  1865. HRESULT hr = S_OK;
  1866. // TEST 1 Normal usage
  1867. pIEnroll = PIEnrollGetNoCOM();
  1868. if( S_OK != pIEnroll->put_PVKFileNameWStr(L"c:\\temp\\foo.pvk") )
  1869. goto ErrorPVKFileNameWStr;
  1870. // enroll for a new cert
  1871. memset(&blobPKCS10, 0, sizeof(blobPKCS10));
  1872. if( S_OK != (hr = pIEnroll->createPKCS10WStr(NULL, NULL, &blobPKCS10)) ) {
  1873. SetLastError(hr);
  1874. goto ErrorCreatePkCS10;
  1875. }
  1876. if( NULL == (pBlobPKCS7 = MakePKCS7Response(&blobPKCS10, &hash)) )
  1877. goto ErrorMakePKCS7Response;
  1878. // accept the new cert
  1879. if( S_OK != (hr = pIEnroll->acceptPKCS7Blob(pBlobPKCS7)) ) {
  1880. SetLastError(hr);
  1881. goto ErrorAcceptPKCS7;
  1882. }
  1883. if( !RemoveCertFromStore(&hash, L"MY", CERT_SYSTEM_STORE_CURRENT_USER) )
  1884. goto ErrorRemoveCertFromStore;
  1885. CommonReturn:
  1886. if(pBlobPKCS7 != NULL)
  1887. free(pBlobPKCS7);
  1888. if(pIEnroll != NULL)
  1889. pIEnroll->Release();
  1890. if(blobPKCS10.pbData != NULL)
  1891. LocalFree(blobPKCS10.pbData);
  1892. SetLastError(Err);
  1893. return(fRet);
  1894. ErrorReturn:
  1895. Err = GetLastError();
  1896. fRet = FALSE;
  1897. goto CommonReturn;
  1898. PRINT_ERROR(ErrorCreatePkCS10);
  1899. PRINT_ERROR(ErrorAcceptPKCS7);
  1900. PRINT_ERROR(ErrorMakePKCS7Response);
  1901. PRINT_ERROR(ErrorRemoveCertFromStore);
  1902. PRINT_ERROR(ErrorPVKFileNameWStr);
  1903. }
  1904. // Test Renewal, Create original cert, create renewal request, create renewed cert
  1905. BOOL Test10() {
  1906. BOOL fRet = TRUE;
  1907. DWORD Err = GetLastError();
  1908. HRESULT hr = S_OK;
  1909. // GetUserNameExW is NOT a 2 pass call, so I have to guess at the MAX
  1910. #define MAXUSERNAME 256
  1911. WCHAR wszUserName[MAXUSERNAME];
  1912. DWORD cchUserName = MAXUSERNAME;
  1913. IEnroll * pIEnrollRenew = NULL;
  1914. IEnroll * pIEnrollRA1 = NULL;
  1915. IEnroll * pIEnrollRA2 = NULL;
  1916. CRYPT_DATA_BLOB blobRenewRequest;
  1917. CRYPT_DATA_BLOB blobRA1Reqest;
  1918. CRYPT_DATA_BLOB blobRA2Reqest;
  1919. CRYPT_DATA_BLOB blobT;
  1920. CERT_NAME_BLOB blobNameRA1;
  1921. CERT_NAME_BLOB blobNameRA2;
  1922. CERT_NAME_BLOB blobNameOld;
  1923. PCCERT_CONTEXT pCertRA1 = NULL;
  1924. PCCERT_CONTEXT pCertRA2 = NULL;
  1925. PCCERT_CONTEXT pCertOld = NULL;
  1926. CERT_EXTENSION rgExtension[] = {
  1927. {szOID_ENHANCED_KEY_USAGE, FALSE, {0, NULL}}
  1928. };
  1929. CERT_EXTENSIONS Extensions = {sizeof(rgExtension)/sizeof(CERT_EXTENSION), rgExtension};
  1930. LPSTR rgszOIDUsages[] = {szOID_ENROLLMENT_AGENT};
  1931. CERT_ENHKEY_USAGE eku = {1 ,rgszOIDUsages};
  1932. memset(&blobRenewRequest, 0, sizeof(blobRenewRequest));
  1933. memset(&blobRA1Reqest, 0, sizeof(blobRA1Reqest));
  1934. memset(&blobRA2Reqest, 0, sizeof(blobRA2Reqest));
  1935. memset(&blobNameRA1, 0, sizeof(blobNameRA1));
  1936. memset(&blobNameRA2, 0, sizeof(blobNameRA2));
  1937. memset(&blobNameOld, 0, sizeof(blobNameOld));
  1938. // encode the enhanced key usage
  1939. if( !CryptEncodeObjectEx(
  1940. CRYPT_ASN_ENCODING,
  1941. X509_ENHANCED_KEY_USAGE,
  1942. &eku,
  1943. CRYPT_ENCODE_ALLOC_FLAG,
  1944. NULL,
  1945. &rgExtension[0].Value.pbData,
  1946. &rgExtension[0].Value.cbData
  1947. ) )
  1948. goto ErrorCryptEncodeObjectEx;
  1949. // get the Subject DN only if one is specified
  1950. if( !CertStrToNameW(
  1951. CRYPT_ASN_ENCODING,
  1952. L"CN=Test RA1",
  1953. 0,
  1954. NULL,
  1955. NULL,
  1956. &blobNameRA1.cbData,
  1957. NULL) ||
  1958. (blobNameRA1.pbData = (BYTE *) _alloca(blobNameRA1.cbData)) == NULL ||
  1959. !CertStrToNameW(
  1960. CRYPT_ASN_ENCODING,
  1961. L"CN=Test RA1",
  1962. 0,
  1963. NULL,
  1964. blobNameRA1.pbData,
  1965. &blobNameRA1.cbData,
  1966. NULL) ) {
  1967. goto ErrorCertStrToNameW;
  1968. }
  1969. // get a Cert for the 1st RA
  1970. if( NULL == (pCertRA1 = CertCreateSelfSignCertificate(
  1971. NULL,
  1972. &blobNameRA1,
  1973. 0,
  1974. NULL,
  1975. NULL,
  1976. NULL,
  1977. NULL,
  1978. &Extensions
  1979. ) ) )
  1980. goto ErrorCertCreateSelfSignCertificate;
  1981. blobT.cbData = pCertRA1->cbCertEncoded;
  1982. blobT.pbData = pCertRA1->pbCertEncoded;
  1983. WriteBlobToFile(L"RA1.cer", 0, &blobT);
  1984. // get the Subject DN only if one is specified
  1985. if( !CertStrToNameW(
  1986. CRYPT_ASN_ENCODING,
  1987. L"CN=Test RA2",
  1988. 0,
  1989. NULL,
  1990. NULL,
  1991. &blobNameRA2.cbData,
  1992. NULL) ||
  1993. (blobNameRA2.pbData = (BYTE *) _alloca(blobNameRA2.cbData)) == NULL ||
  1994. !CertStrToNameW(
  1995. CRYPT_ASN_ENCODING,
  1996. L"CN=Test RA2",
  1997. 0,
  1998. NULL,
  1999. blobNameRA2.pbData,
  2000. &blobNameRA2.cbData,
  2001. NULL) ) {
  2002. goto ErrorCertStrToNameW;
  2003. }
  2004. // get a Cert for the 2'nd RA
  2005. if( NULL == (pCertRA2 = CertCreateSelfSignCertificate(
  2006. NULL,
  2007. &blobNameRA2,
  2008. 0,
  2009. NULL,
  2010. NULL,
  2011. NULL,
  2012. NULL,
  2013. &Extensions
  2014. ) ) )
  2015. goto ErrorCertCreateSelfSignCertificate;
  2016. blobT.cbData = pCertRA2->cbCertEncoded;
  2017. blobT.pbData = pCertRA2->pbCertEncoded;
  2018. WriteBlobToFile(L"RA2.cer", 0, &blobT);
  2019. // get the Subject DN only if one is specified
  2020. if( !CertStrToNameW(
  2021. CRYPT_ASN_ENCODING,
  2022. L"CN=Test Cert Old",
  2023. 0,
  2024. NULL,
  2025. NULL,
  2026. &blobNameOld.cbData,
  2027. NULL) ||
  2028. (blobNameOld.pbData = (BYTE *) _alloca(blobNameOld.cbData)) == NULL ||
  2029. !CertStrToNameW(
  2030. CRYPT_ASN_ENCODING,
  2031. L"CN=Test Cert Old",
  2032. 0,
  2033. NULL,
  2034. blobNameOld.pbData,
  2035. &blobNameOld.cbData,
  2036. NULL) ) {
  2037. goto ErrorCertStrToNameW;
  2038. }
  2039. // get a Cert for the Original cert
  2040. if( NULL == (pCertOld = CertCreateSelfSignCertificate(
  2041. NULL,
  2042. &blobNameOld,
  2043. 0,
  2044. NULL,
  2045. NULL,
  2046. NULL,
  2047. NULL,
  2048. NULL
  2049. ) ) )
  2050. goto ErrorCertCreateSelfSignCertificate;
  2051. blobT.cbData = pCertOld->cbCertEncoded;
  2052. blobT.pbData = pCertOld->pbCertEncoded;
  2053. WriteBlobToFile(L"Original.cer", 0, &blobT);
  2054. // Make an RA cert
  2055. if(NULL == (pIEnrollRenew = PIEnrollGetNoCOM()) )
  2056. goto ErrorPIEnrollGetNoCOM;
  2057. // enroll for a new cert.
  2058. if( S_OK != (hr = pIEnrollRenew->put_RenewalCertificate(pCertOld)) ) {
  2059. SetLastError(hr);
  2060. goto ErrorPut_RenewalCertificate;
  2061. }
  2062. // put in a certtype for laughs
  2063. if( S_OK != (hr = pIEnrollRenew->AddCertTypeToRequestWStr(L"MY CERT TYPE")) ) {
  2064. SetLastError(hr);
  2065. goto ErrorAddCertTypeToRequest;
  2066. }
  2067. // get the renewal PKCS7 (in the 10 blob)
  2068. if( S_OK != (hr = pIEnrollRenew->createPKCS10WStr(L"CN=XEnroll Test Renew", L"1.3.6.1.5.5.7.3.8", &blobRenewRequest)) ) {
  2069. SetLastError(hr);
  2070. goto ErrorCreatePkCS10;
  2071. }
  2072. WriteBlobToFile(L"Renewal.p7s", 0, &blobRenewRequest);
  2073. // Make an RA cert
  2074. if(NULL == (pIEnrollRA1 = PIEnrollGetNoCOM()) )
  2075. goto ErrorPIEnrollGetNoCOM;
  2076. if(S_OK != pIEnrollRA1->AddNameValuePairToSignatureWStr(L"CreateUserCertificate", L"stimpy.ntdev.microsoft.com"))
  2077. goto ErrorAddNameValuePairToSignatureWStr;
  2078. if( !GetUserNameExW(NameSamCompatible, wszUserName, &cchUserName) )
  2079. goto ErrorGetUserName;
  2080. if(S_OK != pIEnrollRA1->AddNameValuePairToSignatureWStr(L"UserName", wszUserName))
  2081. goto ErrorAddNameValuePairToSignatureWStr;
  2082. // get the 1st RA Request
  2083. if( S_OK != (hr = pIEnrollRA1->CreatePKCS7RequestFromRequest(
  2084. &blobRenewRequest,
  2085. pCertRA1,
  2086. &blobRA1Reqest) ) )
  2087. goto ErrorCreatePKCS7RequestFromRequest;
  2088. WriteBlobToFile(L"RA1.p7s", 0, &blobRA1Reqest);
  2089. // Make an RA cert
  2090. if(NULL == (pIEnrollRA2 = PIEnrollGetNoCOM()) )
  2091. goto ErrorPIEnrollGetNoCOM;
  2092. if(S_OK != pIEnrollRA2->AddNameValuePairToSignatureWStr(L"ChangeUserCertificate", L"stimpy.redmond.microsoft.com"))
  2093. goto ErrorAddNameValuePairToSignatureWStr;
  2094. // get the 2nd RA Request
  2095. if( S_OK != (hr = pIEnrollRA2->CreatePKCS7RequestFromRequest(
  2096. &blobRA1Reqest,
  2097. pCertRA2,
  2098. &blobRA2Reqest) ) )
  2099. goto ErrorCreatePKCS7RequestFromRequest;
  2100. // put this out to a file for Vic
  2101. WriteBlobToFile(L"RA2.p7s", 0, &blobRA2Reqest);
  2102. CommonReturn:
  2103. if(rgExtension[0].Value.pbData != NULL)
  2104. LocalFree(rgExtension[0].Value.pbData);
  2105. if(blobRenewRequest.pbData != NULL) {
  2106. // clean up after ourself
  2107. PCCERT_CONTEXT pCertRequest;
  2108. if(NULL != (pCertRequest = GetCertOutOfRequestStore2(
  2109. &blobRenewRequest)) ) {
  2110. // delete the cert's private key
  2111. DeleteCertPrivateKey(pCertRequest);
  2112. CertDeleteCertificateFromStore(pCertRequest);
  2113. }
  2114. LocalFree(blobRenewRequest.pbData);
  2115. }
  2116. if(pIEnrollRenew != NULL)
  2117. pIEnrollRenew->freeRequestInfoBlob(blobRenewRequest);
  2118. if(pCertRA1 != NULL) {
  2119. DeleteCertPrivateKey(pCertRA1);
  2120. CertFreeCertificateContext(pCertRA1);
  2121. }
  2122. if(pCertRA2 != NULL) {
  2123. DeleteCertPrivateKey(pCertRA2);
  2124. CertFreeCertificateContext(pCertRA2);
  2125. }
  2126. if(pCertOld != NULL) {
  2127. DeleteCertPrivateKey(pCertOld);
  2128. CertFreeCertificateContext(pCertOld);
  2129. }
  2130. if(blobRA1Reqest.pbData != NULL)
  2131. LocalFree(blobRA1Reqest.pbData);
  2132. if(blobRA2Reqest.pbData != NULL)
  2133. LocalFree(blobRA2Reqest.pbData);
  2134. if(pIEnrollRenew != NULL)
  2135. pIEnrollRenew->Release();
  2136. if(pIEnrollRA1 != NULL)
  2137. pIEnrollRA1->Release();
  2138. if(pIEnrollRA2 != NULL)
  2139. pIEnrollRA2->Release();
  2140. SetLastError(Err);
  2141. return(fRet);
  2142. ErrorReturn:
  2143. Err = GetLastError();
  2144. fRet = FALSE;
  2145. goto CommonReturn;
  2146. PRINT_ERROR(ErrorGetUserName);
  2147. PRINT_ERROR(ErrorAddNameValuePairToSignatureWStr);
  2148. PRINT_ERROR(ErrorPIEnrollGetNoCOM);
  2149. PRINT_ERROR(ErrorCertStrToNameW);
  2150. PRINT_ERROR(ErrorCertCreateSelfSignCertificate);
  2151. PRINT_ERROR(ErrorCreatePKCS7RequestFromRequest);
  2152. PRINT_ERROR(ErrorCreatePkCS10);
  2153. PRINT_ERROR(ErrorPut_RenewalCertificate);
  2154. PRINT_ERROR(ErrorCryptEncodeObjectEx);
  2155. PRINT_ERROR(ErrorAddCertTypeToRequest);
  2156. }
  2157. HRESULT
  2158. myMultiByteToWideChar(
  2159. IN char *psz,
  2160. OUT WCHAR **ppwsz)
  2161. {
  2162. HRESULT hr;
  2163. int cch = 0;
  2164. WCHAR *pwsz = NULL;
  2165. assert (NULL != psz);
  2166. while (TRUE)
  2167. {
  2168. cch = MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, cch);
  2169. assert((cch - 1) == (int)strlen(psz));
  2170. if (NULL != pwsz)
  2171. {
  2172. break; //done
  2173. }
  2174. pwsz = (WCHAR*)LocalAlloc(LMEM_FIXED, cch * sizeof(WCHAR));
  2175. if (NULL == pwsz)
  2176. {
  2177. hr = E_OUTOFMEMORY;
  2178. goto LocalAllocError;
  2179. }
  2180. }
  2181. *ppwsz = pwsz;
  2182. pwsz = NULL;
  2183. hr = S_OK;
  2184. ErrorReturn:
  2185. if (NULL != pwsz)
  2186. {
  2187. LocalFree(pwsz);
  2188. }
  2189. return hr;
  2190. PRINT_ERROR(LocalAllocError)
  2191. }
  2192. // test Enroll4 interface
  2193. BOOL Test11()
  2194. {
  2195. BOOL fRet = FALSE;
  2196. HRESULT hr;
  2197. IEnroll4 *pIEnroll4 = NULL;
  2198. HANDLE hCAFile = NULL;
  2199. CHAR *pchCACert = NULL;
  2200. BYTE *pbCACert = NULL;
  2201. DWORD cchCACert;
  2202. DWORD cbCACert;
  2203. DWORD cbRead;
  2204. PCCERT_CONTEXT pCACert = NULL;
  2205. WCHAR *pwszDNName = NULL;
  2206. WCHAR *pwszCMCFileName = NULL;
  2207. WCHAR *pwszKeyContainer = NULL;
  2208. CRYPT_DATA_BLOB blobCMC;
  2209. WCHAR wszMyDNName[] = L"CN=Xenroll CMC Test";
  2210. LONG lKeySize;
  2211. ZeroMemory(&blobCMC, sizeof(blobCMC));
  2212. pIEnroll4 = PIEnroll4GetNoCOM();
  2213. if(NULL == pIEnroll4)
  2214. {
  2215. goto PIEnroll4GetNoCOMError;
  2216. }
  2217. if (NULL != g_pszKeyContainer)
  2218. {
  2219. hr = myMultiByteToWideChar(g_pszKeyContainer, &pwszKeyContainer);
  2220. if (S_OK != hr)
  2221. {
  2222. goto myMultiByteToWideCharError;
  2223. }
  2224. }
  2225. if (NULL != pwszKeyContainer)
  2226. {
  2227. hr = pIEnroll4->put_ContainerNameWStr(pwszKeyContainer);
  2228. if (S_OK != hr)
  2229. {
  2230. goto put_ContainerNameWStrError;
  2231. }
  2232. }
  2233. hr = pIEnroll4->resetExtensions();
  2234. if (S_OK != hr)
  2235. {
  2236. goto resetExtensionsError;
  2237. }
  2238. hr = pIEnroll4->resetAttributes();
  2239. if (S_OK != hr)
  2240. {
  2241. goto resetAttributesError;
  2242. }
  2243. //add some extensions
  2244. //add some attributes
  2245. hr = pIEnroll4->addNameValuePairToRequestWStr(
  2246. 0,
  2247. L"NameValue name",
  2248. L"NameValue value");
  2249. if (S_OK != hr)
  2250. {
  2251. goto addNameValuePairToRequestWStrError;
  2252. }
  2253. if (NULL != g_pszCAXchgFileName)
  2254. {
  2255. //get a ca cert
  2256. hCAFile = CreateFileA(
  2257. g_pszCAXchgFileName,
  2258. GENERIC_READ,
  2259. FILE_SHARE_READ,
  2260. NULL,
  2261. OPEN_EXISTING,
  2262. 0,
  2263. NULL);
  2264. if (NULL != hCAFile)
  2265. {
  2266. cchCACert = GetFileSize(hCAFile, NULL);
  2267. assert(0 < cchCACert);
  2268. pchCACert = (CHAR*)LocalAlloc(LMEM_FIXED, cchCACert);
  2269. if (NULL == pchCACert)
  2270. {
  2271. goto LocalAllocError;
  2272. }
  2273. if (!ReadFile(hCAFile, pchCACert, cchCACert, &cbRead, NULL))
  2274. {
  2275. goto ReadFileError;
  2276. }
  2277. assert(cbRead <= cchCACert);
  2278. pbCACert = NULL;
  2279. while (TRUE)
  2280. {
  2281. if (!CryptStringToBinaryA(
  2282. pchCACert,
  2283. cchCACert,
  2284. CRYPT_STRING_ANY,
  2285. pbCACert,
  2286. &cbCACert,
  2287. NULL,
  2288. NULL))
  2289. {
  2290. goto CryptStringToBinaryAError;
  2291. }
  2292. if (NULL != pbCACert)
  2293. {
  2294. break;
  2295. }
  2296. pbCACert = (BYTE*)LocalAlloc(LMEM_FIXED, cbCACert);
  2297. if (NULL == pbCACert)
  2298. {
  2299. goto LocalAllocError;
  2300. }
  2301. }
  2302. pCACert = CertCreateCertificateContext(
  2303. X509_ASN_ENCODING,
  2304. pbCACert,
  2305. cbCACert);
  2306. if (NULL == pCACert)
  2307. {
  2308. goto CertCreateCertificateContextError;
  2309. }
  2310. hr = pIEnroll4->SetPrivateKeyArchiveCertificate(
  2311. pCACert);
  2312. if (S_OK != hr)
  2313. {
  2314. goto SetPrivateKeyArchiveCertificateError;
  2315. }
  2316. }
  2317. #if 0
  2318. hr = pIEnroll4->put_GenKeyFlags(CRYPT_EXPORTABLE);
  2319. if (S_OK != hr)
  2320. {
  2321. goto put_GenKeyFlagsError;
  2322. }
  2323. #endif
  2324. }
  2325. pwszDNName = wszMyDNName;
  2326. if (NULL != g_pszDNName)
  2327. {
  2328. hr = myMultiByteToWideChar(g_pszDNName, &pwszDNName);
  2329. if (S_OK != hr)
  2330. {
  2331. goto myMultiByteToWideCharError;
  2332. }
  2333. }
  2334. if (NULL != g_pszCMCFileName)
  2335. {
  2336. hr = myMultiByteToWideChar(g_pszCMCFileName, &pwszCMCFileName);
  2337. if (S_OK != hr)
  2338. {
  2339. goto myMultiByteToWideCharError;
  2340. }
  2341. }
  2342. // enroll for a new cert
  2343. if (NULL != pwszCMCFileName)
  2344. {
  2345. hr = pIEnroll4->createFileRequestWStr(
  2346. XECR_CMC,
  2347. pwszDNName,
  2348. NULL,
  2349. pwszCMCFileName);
  2350. }
  2351. else
  2352. {
  2353. hr = pIEnroll4->createRequestWStr(
  2354. XECR_CMC,
  2355. pwszDNName,
  2356. NULL,
  2357. &blobCMC);
  2358. }
  2359. if (S_OK != hr)
  2360. {
  2361. goto createRequestWStrError;
  2362. }
  2363. fRet = TRUE;
  2364. ErrorReturn:
  2365. if (NULL != pwszKeyContainer)
  2366. {
  2367. LocalFree(pwszKeyContainer);
  2368. }
  2369. if (NULL != pchCACert)
  2370. {
  2371. LocalFree(pchCACert);
  2372. }
  2373. if (NULL != pbCACert)
  2374. {
  2375. LocalFree(pbCACert);
  2376. }
  2377. if (NULL != pwszCMCFileName)
  2378. {
  2379. LocalFree(pwszCMCFileName);
  2380. }
  2381. if (NULL != pwszDNName && pwszDNName != wszMyDNName)
  2382. {
  2383. LocalFree(pwszDNName);
  2384. }
  2385. if(NULL != pIEnroll4)
  2386. {
  2387. pIEnroll4->Release();
  2388. }
  2389. if (NULL != hCAFile)
  2390. {
  2391. CloseHandle(hCAFile);
  2392. }
  2393. if (NULL != pCACert)
  2394. {
  2395. CertFreeCertificateContext(pCACert);
  2396. }
  2397. if (NULL != blobCMC.pbData)
  2398. {
  2399. LocalFree(blobCMC.pbData);
  2400. }
  2401. return fRet;
  2402. PRINT_ERROR(CryptStringToBinaryAError)
  2403. #if 0
  2404. PRINT_ERROR2(put_GenKeyFlagsError, hr)
  2405. #endif
  2406. PRINT_ERROR2(SetPrivateKeyArchiveCertificateError, hr)
  2407. PRINT_ERROR(CertCreateCertificateContextError)
  2408. PRINT_ERROR(ReadFileError)
  2409. PRINT_ERROR2(createRequestWStrError, hr)
  2410. PRINT_ERROR2(addNameValuePairToRequestWStrError, hr)
  2411. PRINT_ERROR2(resetExtensionsError, hr)
  2412. PRINT_ERROR2(resetAttributesError, hr)
  2413. PRINT_ERROR(PIEnroll4GetNoCOMError)
  2414. PRINT_ERROR2(put_ContainerNameWStrError, hr)
  2415. PRINT_ERROR2(LocalAllocError, E_OUTOFMEMORY)
  2416. PRINT_ERROR2(myMultiByteToWideCharError, hr)
  2417. }
  2418. // test Enroll4 interface, accept CMC response
  2419. BOOL Test12()
  2420. {
  2421. HRESULT hr;
  2422. BOOL fRet = FALSE;
  2423. IEnroll4 *pIEnroll4 = NULL;
  2424. int cch;
  2425. WCHAR *pwszResponseFile = NULL;
  2426. if (NULL == g_pszCMCResponseFileName)
  2427. {
  2428. //skip the test
  2429. printf("Test12 is skipped\n");
  2430. fRet = TRUE;
  2431. goto ErrorReturn;
  2432. }
  2433. pIEnroll4 = PIEnroll4GetNoCOM();
  2434. if(NULL == pIEnroll4)
  2435. {
  2436. goto PIEnroll4GetNoCOMError;
  2437. }
  2438. hr = myMultiByteToWideChar(g_pszCMCResponseFileName, &pwszResponseFile);
  2439. if (S_OK != hr)
  2440. {
  2441. goto myMultiByteToWideCharError;
  2442. }
  2443. hr = pIEnroll4->acceptFileResponseWStr(pwszResponseFile);
  2444. if (S_OK != hr)
  2445. {
  2446. goto acceptFileResponseWStrError;
  2447. }
  2448. fRet = TRUE;
  2449. ErrorReturn:
  2450. if (NULL != pwszResponseFile)
  2451. {
  2452. LocalFree(pwszResponseFile);
  2453. }
  2454. if(NULL != pIEnroll4)
  2455. {
  2456. pIEnroll4->Release();
  2457. }
  2458. return fRet;
  2459. PRINT_ERROR(PIEnroll4GetNoCOMError)
  2460. PRINT_ERROR(acceptFileResponseWStrError)
  2461. PRINT_ERROR(myMultiByteToWideCharError)
  2462. }
  2463. // Test pending API
  2464. BOOL Test13()
  2465. {
  2466. BOOL fRet;
  2467. CRYPT_DATA_BLOB pkcs10Blob;
  2468. DWORD dwIndex;
  2469. DWORD dwNumTests;
  2470. HRESULT hr;
  2471. IEnroll4 *pIEnroll4 = NULL;
  2472. PCCERT_CONTEXT pCertContext = NULL;
  2473. TXEnrollPendingAPITester *pTester = NULL;
  2474. WCHAR wszDNName[] = L"CN=Xenroll PendingAPI Test";
  2475. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2476. //
  2477. // TEST CASES
  2478. //
  2479. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2480. PENDING_INFO rgPendingTests[] = {
  2481. // 0) Normal inputs
  2482. {
  2483. 100,
  2484. L"duncanb1.ntdev.microsoft.com",
  2485. L"setPendingInfoWStr Test 1",
  2486. L"SPI Test 1",
  2487. 0,
  2488. NULL,
  2489. S_OK
  2490. },
  2491. // 1) Negative Req ID
  2492. {
  2493. -1,
  2494. L"duncanb1.ntdev.microsoft.com",
  2495. L"setPendingInfoWStr Test 1",
  2496. L"SPI Test 1",
  2497. 0,
  2498. NULL,
  2499. E_INVALIDARG
  2500. },
  2501. // 2) NULL CA location.
  2502. {
  2503. 100,
  2504. NULL,
  2505. L"setPendingInfoWStr Test 1",
  2506. L"SPI Test 1",
  2507. 0,
  2508. NULL,
  2509. E_INVALIDARG
  2510. },
  2511. // 3) NULL CA name.
  2512. {
  2513. 100,
  2514. L"duncanb1.ntdev.microsoft.com",
  2515. NULL,
  2516. L"SPI Test 1",
  2517. 0,
  2518. NULL,
  2519. E_INVALIDARG
  2520. },
  2521. // 4) NULL friendly name.
  2522. {
  2523. 100,
  2524. L"duncanb1.ntdev.microsoft.com",
  2525. L"setPendingInfoWStr Test 1",
  2526. NULL,
  2527. 0,
  2528. NULL,
  2529. S_OK
  2530. },
  2531. // 5) Specify USER store flags.
  2532. {
  2533. 100,
  2534. L"duncanb1.ntdev.microsoft.com",
  2535. L"setPendingInfoWStr Test 1",
  2536. L"SPI Test 1",
  2537. CERT_SYSTEM_STORE_CURRENT_USER,
  2538. NULL,
  2539. S_OK
  2540. },
  2541. // 6) Specify LM store flags.
  2542. {
  2543. 100,
  2544. L"duncanb1.ntdev.microsoft.com",
  2545. L"setPendingInfoWStr Test 1",
  2546. L"SPI Test 1",
  2547. CERT_SYSTEM_STORE_LOCAL_MACHINE,
  2548. NULL,
  2549. S_OK
  2550. },
  2551. // 7) Long names:
  2552. {
  2553. 100,
  2554. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.com"
  2555. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comcom"
  2556. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comcom"
  2557. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comcom"
  2558. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comcom"
  2559. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comcom"
  2560. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comcom"
  2561. L"duncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.comduncanb1.ntdev.microsoft.com",
  2562. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1"
  2563. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1"
  2564. L"setPendingInfoWStr Test 1Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1"
  2565. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1Test 1setPendingInfoWStr Test 1"
  2566. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1Test 1"
  2567. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1"
  2568. L"setPendingInfoWStr Test 1Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1"
  2569. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1Test 1setPendingInfoWStr Test 1"
  2570. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1Test 1"
  2571. L"setPendingInfoWStr Test 1setPendingInfoWStr Test 1setPendingInfoWStr Test 1"
  2572. L"setPendingInfoWStr Test 1",
  2573. L"SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2574. L"SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2575. L"Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2576. L"SPITest 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2577. L"SPITest 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2578. L"SPITest 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2579. L"SPITest 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2580. L"SPITest 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2581. L"SPITest 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1"
  2582. L"SPITest 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI Test 1SPI",
  2583. 0,
  2584. NULL,
  2585. S_OK
  2586. }
  2587. };
  2588. ZeroMemory(&pkcs10Blob, sizeof(pkcs10Blob));
  2589. pIEnroll4 = PIEnroll4GetNoCOM();
  2590. if(NULL == pIEnroll4)
  2591. goto PIEnroll4GetNoCOMError;
  2592. pTester = new TXEnrollPendingAPITester;
  2593. if (NULL == pTester)
  2594. goto MemoryError;
  2595. // Test the ThumbPrintWStr property.
  2596. if (!pTester->TestProperty_ThumbPrintWStr(pIEnroll4))
  2597. goto TestProperty_ThumbPrintWStrError;
  2598. pIEnroll4 = PIEnroll4GetNoCOM();
  2599. if(NULL == pIEnroll4)
  2600. goto PIEnroll4GetNoCOMError;
  2601. // Test the removePendingRequestWStr method.
  2602. if (!pTester->TestMethod_removePendingRequestWStr(pIEnroll4))
  2603. goto TestMethod_removePendingRequestWStrError;
  2604. // Test all enumPending / setPendingInfo cases:
  2605. dwNumTests = sizeof(rgPendingTests) / sizeof(PENDING_INFO);
  2606. for (dwIndex = 0; dwIndex < dwNumTests; dwIndex++)
  2607. {
  2608. pIEnroll4 = PIEnroll4GetNoCOM();
  2609. if(NULL == pIEnroll4)
  2610. goto PIEnroll4GetNoCOMError;
  2611. if (S_OK != (hr = pIEnroll4->resetExtensions()))
  2612. goto resetExtensionsError;
  2613. if (S_OK != (hr = pIEnroll4->resetAttributes()))
  2614. goto resetAttributesError;
  2615. // Small key size so the test runs faster.
  2616. if (S_OK != (hr = pIEnroll4->put_GenKeyFlags(384 << 16)))
  2617. goto put_GenKeyFlagsError;
  2618. // Default to CURRENT_USER.
  2619. if (0 == rgPendingTests[dwIndex].dwStoreFlags)
  2620. rgPendingTests[dwIndex].dwStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER;
  2621. // Default to REQUEST store.
  2622. if (NULL == rgPendingTests[dwIndex].pwszStoreName)
  2623. rgPendingTests[dwIndex].pwszStoreName = L"REQUEST";
  2624. if (S_OK != (hr = pIEnroll4->put_RequestStoreFlags(rgPendingTests[dwIndex].dwStoreFlags)))
  2625. goto put_RequestStoreFlagsError;
  2626. if (S_OK != (hr = pIEnroll4->put_RequestStoreNameWStr(rgPendingTests[dwIndex].pwszStoreName)))
  2627. goto put_RequestStoreNameWStrError;
  2628. // Create a request to test on.
  2629. if (S_OK != (hr = pIEnroll4->createRequestWStr
  2630. (XECR_PKCS10_V2_0,
  2631. wszDNName,
  2632. NULL,
  2633. &pkcs10Blob)))
  2634. goto createRequestWStrError;
  2635. if (!pTester->TestMethod_setPendingInfoWStr(pIEnroll4, pkcs10Blob, &rgPendingTests[dwIndex]))
  2636. goto TestMethod_setPendingInfoWStrError;
  2637. // only continue if we are not testing a failure case.
  2638. // Eventually this should be extended to test the failure cases for enumPendingRequestWStr.
  2639. if (S_OK == rgPendingTests[dwIndex].hrExpectedResult)
  2640. {
  2641. if (!pTester->TestMethod_enumPendingRequestWStr(pIEnroll4, pkcs10Blob, &rgPendingTests[dwIndex]))
  2642. goto TestMethod_enumPendingRequestWStrError;
  2643. }
  2644. pCertContext = GetCertOutOfStore(&pkcs10Blob, rgPendingTests[dwIndex].dwStoreFlags, rgPendingTests[dwIndex].pwszStoreName);
  2645. if (NULL == pCertContext)
  2646. goto GetCertOutOfStoreError;
  2647. CertDeleteCertificateFromStore(pCertContext);
  2648. LocalFree(pkcs10Blob.pbData);
  2649. ZeroMemory(&pkcs10Blob, sizeof(pkcs10Blob));
  2650. pCertContext = NULL;
  2651. pIEnroll4->Release();
  2652. }
  2653. fRet = TRUE;
  2654. CommonReturn:
  2655. if (NULL != pkcs10Blob.pbData)
  2656. {
  2657. pCertContext = GetCertOutOfStore(&pkcs10Blob, rgPendingTests[dwIndex].dwStoreFlags, rgPendingTests[dwIndex].pwszStoreName);
  2658. if (NULL != pCertContext) { CertDeleteCertificateFromStore(pCertContext); }
  2659. LocalFree(pkcs10Blob.pbData);
  2660. }
  2661. return fRet;
  2662. ErrorReturn:
  2663. fRet = FALSE;
  2664. SetLastError(hr);
  2665. goto CommonReturn;
  2666. PRINT_ERROR2(createRequestWStrError, hr);
  2667. PRINT_ERROR2(GetCertOutOfStoreError, hr = GetLastError());
  2668. PRINT_ERROR2(MemoryError, hr = E_OUTOFMEMORY);
  2669. PRINT_ERROR2(PIEnroll4GetNoCOMError, hr = GetLastError());
  2670. PRINT_ERROR2(put_GenKeyFlagsError, hr);
  2671. PRINT_ERROR2(put_RequestStoreFlagsError, hr);
  2672. PRINT_ERROR2(put_RequestStoreNameWStrError, hr);
  2673. PRINT_ERROR2(resetAttributesError, hr);
  2674. PRINT_ERROR2(resetExtensionsError, hr);
  2675. PRINT_ERROR2(TestMethod_enumPendingRequestWStrError, hr = GetLastError());
  2676. PRINT_ERROR2(TestMethod_removePendingRequestWStrError, hr = GetLastError());
  2677. PRINT_ERROR2(TestMethod_setPendingInfoWStrError, hr = GetLastError());
  2678. PRINT_ERROR2(TestProperty_ThumbPrintWStrError, hr = GetLastError());
  2679. }
  2680. // test Enroll4 misc. methods
  2681. BOOL Test14()
  2682. {
  2683. BOOL fRet = FALSE;
  2684. HRESULT hr;
  2685. ICEnroll4 *pICEnroll = NULL;
  2686. ICEnroll4 *pICEnroll2 = NULL;
  2687. ICEnroll4 *pICEnroll3 = NULL;
  2688. ICEnroll4 *pICEnroll4 = NULL;
  2689. IEnroll4 *pIEnroll = NULL;
  2690. IEnroll4 *pIEnroll2 = NULL;
  2691. IEnroll4 *pIEnroll4 = NULL;
  2692. LONG lKeySize;
  2693. BOOL fCoInit = FALSE;
  2694. hr = CoInitialize(NULL);
  2695. if (S_OK != hr && S_FALSE != hr)
  2696. {
  2697. goto CoInitializeError;
  2698. }
  2699. fCoInit = TRUE;
  2700. hr = CoCreateInstance(
  2701. CLSID_CEnroll,
  2702. NULL,
  2703. CLSCTX_INPROC_SERVER,
  2704. IID_ICEnroll,
  2705. (void **) &pICEnroll);
  2706. if( S_OK != hr || NULL == pICEnroll)
  2707. {
  2708. goto CoCreateInstanceError;
  2709. }
  2710. if (g_fVerb)
  2711. {
  2712. printf("CoCreateInstance(ICEnroll) test passed\n");
  2713. }
  2714. hr = CoCreateInstance(
  2715. CLSID_CEnroll,
  2716. NULL,
  2717. CLSCTX_INPROC_SERVER,
  2718. IID_ICEnroll2,
  2719. (void **) &pICEnroll2);
  2720. if( S_OK != hr || NULL == pICEnroll2)
  2721. {
  2722. goto CoCreateInstanceError;
  2723. }
  2724. if (g_fVerb)
  2725. {
  2726. printf("CoCreateInstance(ICEnroll2) test passed\n");
  2727. }
  2728. hr = CoCreateInstance(
  2729. CLSID_CEnroll,
  2730. NULL,
  2731. CLSCTX_INPROC_SERVER,
  2732. IID_ICEnroll3,
  2733. (void **) &pICEnroll3);
  2734. if( S_OK != hr || NULL == pICEnroll3)
  2735. {
  2736. goto CoCreateInstanceError;
  2737. }
  2738. if (g_fVerb)
  2739. {
  2740. printf("CoCreateInstance(ICEnroll3) test passed\n");
  2741. }
  2742. hr = CoCreateInstance(
  2743. CLSID_CEnroll,
  2744. NULL,
  2745. CLSCTX_INPROC_SERVER,
  2746. IID_ICEnroll4,
  2747. (void **) &pICEnroll4);
  2748. if( S_OK != hr || NULL == pICEnroll4)
  2749. {
  2750. goto CoCreateInstanceError;
  2751. }
  2752. if (g_fVerb)
  2753. {
  2754. printf("CoCreateInstance(ICEnroll4) test passed\n");
  2755. }
  2756. hr = CoCreateInstance(
  2757. CLSID_CEnroll,
  2758. NULL,
  2759. CLSCTX_INPROC_SERVER,
  2760. IID_IEnroll,
  2761. (void **) &pIEnroll);
  2762. if( S_OK != hr || NULL == pIEnroll)
  2763. {
  2764. goto CoCreateInstanceError;
  2765. }
  2766. if (g_fVerb)
  2767. {
  2768. printf("CoCreateInstance(IEnroll) test passed\n");
  2769. }
  2770. hr = CoCreateInstance(
  2771. CLSID_CEnroll,
  2772. NULL,
  2773. CLSCTX_INPROC_SERVER,
  2774. IID_IEnroll4,
  2775. (void **) &pIEnroll2);
  2776. if( S_OK != hr || NULL == pIEnroll2)
  2777. {
  2778. goto CoCreateInstanceError;
  2779. }
  2780. if (g_fVerb)
  2781. {
  2782. printf("CoCreateInstance(IEnroll2) test passed\n");
  2783. }
  2784. hr = CoCreateInstance(
  2785. CLSID_CEnroll,
  2786. NULL,
  2787. CLSCTX_INPROC_SERVER,
  2788. IID_IEnroll4,
  2789. (void **) &pIEnroll4);
  2790. if( S_OK != hr || NULL == pIEnroll4)
  2791. {
  2792. goto CoCreateInstanceError;
  2793. }
  2794. if (g_fVerb)
  2795. {
  2796. printf("CoCreateInstance(IEnroll4) test passed\n");
  2797. }
  2798. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_MIN, XEKL_KEYSPEC_KEYX, &lKeySize);
  2799. if (S_OK != hr)
  2800. {
  2801. goto GetKeyLenExError;
  2802. }
  2803. if (g_fVerb)
  2804. {
  2805. printf("Minimun exchange key size is %d\n", lKeySize);
  2806. }
  2807. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_MAX, XEKL_KEYSPEC_KEYX, &lKeySize);
  2808. if (S_OK != hr)
  2809. {
  2810. goto GetKeyLenExError;
  2811. }
  2812. if (g_fVerb)
  2813. {
  2814. printf("Maximun exchange key size is %d\n", lKeySize);
  2815. }
  2816. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_DEFAULT, XEKL_KEYSPEC_KEYX, &lKeySize);
  2817. if (S_OK != hr)
  2818. {
  2819. goto GetKeyLenExError;
  2820. }
  2821. if (g_fVerb)
  2822. {
  2823. printf("Default exchange key size is %d\n", lKeySize);
  2824. }
  2825. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_INC, XEKL_KEYSPEC_KEYX, &lKeySize);
  2826. if (S_OK != hr)
  2827. {
  2828. goto GetKeyLenExError;
  2829. }
  2830. if (g_fVerb)
  2831. {
  2832. printf("Exchange key increment size is %d\n", lKeySize);
  2833. }
  2834. //signature key
  2835. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_MIN, XEKL_KEYSPEC_SIG, &lKeySize);
  2836. if (S_OK != hr)
  2837. {
  2838. goto GetKeyLenExError;
  2839. }
  2840. if (g_fVerb)
  2841. {
  2842. printf("Minimun signature key size is %d\n", lKeySize);
  2843. }
  2844. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_MAX, XEKL_KEYSPEC_SIG, &lKeySize);
  2845. if (S_OK != hr)
  2846. {
  2847. goto GetKeyLenExError;
  2848. }
  2849. if (g_fVerb)
  2850. {
  2851. printf("Maximun signature key size is %d\n", lKeySize);
  2852. }
  2853. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_DEFAULT, XEKL_KEYSPEC_SIG, &lKeySize);
  2854. if (S_OK != hr)
  2855. {
  2856. goto GetKeyLenExError;
  2857. }
  2858. if (g_fVerb)
  2859. {
  2860. printf("Default signature key size is %d\n", lKeySize);
  2861. }
  2862. hr = pIEnroll4->GetKeyLenEx(XEKL_KEYSIZE_INC, XEKL_KEYSPEC_SIG, &lKeySize);
  2863. if (S_OK != hr)
  2864. {
  2865. goto GetKeyLenExError;
  2866. }
  2867. if (g_fVerb)
  2868. {
  2869. printf("Signature key increment size is %d\n", lKeySize);
  2870. }
  2871. fRet = TRUE;
  2872. ErrorReturn:
  2873. if(NULL != pICEnroll)
  2874. {
  2875. pICEnroll->Release();
  2876. }
  2877. if(NULL != pICEnroll2)
  2878. {
  2879. pICEnroll2->Release();
  2880. }
  2881. if(NULL != pICEnroll3)
  2882. {
  2883. pICEnroll3->Release();
  2884. }
  2885. if(NULL != pICEnroll4)
  2886. {
  2887. pICEnroll4->Release();
  2888. }
  2889. if(NULL != pIEnroll)
  2890. {
  2891. pIEnroll->Release();
  2892. }
  2893. if(NULL != pIEnroll2)
  2894. {
  2895. pIEnroll2->Release();
  2896. }
  2897. if(NULL != pIEnroll4)
  2898. {
  2899. pIEnroll4->Release();
  2900. }
  2901. if (fCoInit)
  2902. {
  2903. CoUninitialize();
  2904. }
  2905. return fRet;
  2906. PRINT_ERROR2(CoCreateInstanceError, hr)
  2907. PRINT_ERROR2(CoInitializeError, hr)
  2908. PRINT_ERROR2(GetKeyLenExError, hr)
  2909. }
  2910. // test acceptPKCS7 and PFX
  2911. BOOL Test15()
  2912. {
  2913. BOOL fRet = FALSE;
  2914. HRESULT hr;
  2915. IEnroll4 *pIEnroll4 = NULL;
  2916. BOOL fCoInit = FALSE;
  2917. WCHAR *pwszPKCS7FileName = NULL;
  2918. WCHAR *pwszPFXFileName = NULL;
  2919. WCHAR *pwszPFXPassword = NULL;
  2920. WCHAR wszEmptyPassword[] = L"";
  2921. if (MAXDWORD == g_dwTestID &&
  2922. NULL == g_pszPKCS7FileName)
  2923. {
  2924. printf("Test15 is skipped.\n");
  2925. goto done;
  2926. }
  2927. if (NULL == g_pszPKCS7FileName)
  2928. {
  2929. printf("You must provide a PKCS7 file\n");
  2930. goto MissedPKCS7FileError;
  2931. }
  2932. hr = CoInitialize(NULL);
  2933. if (S_OK != hr && S_FALSE != hr)
  2934. {
  2935. goto CoInitializeError;
  2936. }
  2937. fCoInit = TRUE;
  2938. hr = CoCreateInstance(
  2939. CLSID_CEnroll,
  2940. NULL,
  2941. CLSCTX_INPROC_SERVER,
  2942. IID_IEnroll4,
  2943. (void **) &pIEnroll4);
  2944. if( S_OK != hr || NULL == pIEnroll4)
  2945. {
  2946. goto CoCreateInstanceError;
  2947. }
  2948. hr = myMultiByteToWideChar(g_pszPKCS7FileName, &pwszPKCS7FileName);
  2949. if (S_OK != hr)
  2950. {
  2951. goto myMultiByteToWideCharError;
  2952. }
  2953. hr = pIEnroll4->acceptFilePKCS7WStr(pwszPKCS7FileName);
  2954. if (S_OK != hr)
  2955. {
  2956. goto acceptFilePKCS7WStrError;
  2957. }
  2958. if (NULL != g_pszPFXFileName)
  2959. {
  2960. if (NULL == g_pszPFXPassword)
  2961. {
  2962. pwszPFXPassword = wszEmptyPassword;
  2963. if (g_fVerb)
  2964. {
  2965. printf("Empty PFX password is used.\n");
  2966. }
  2967. }
  2968. hr = myMultiByteToWideChar(g_pszPFXFileName, &pwszPFXFileName);
  2969. if (S_OK != hr)
  2970. {
  2971. goto myMultiByteToWideCharError;
  2972. }
  2973. if (NULL != g_pszPFXPassword)
  2974. {
  2975. hr = myMultiByteToWideChar(g_pszPFXPassword, &pwszPFXPassword);
  2976. if (S_OK != hr)
  2977. {
  2978. goto myMultiByteToWideCharError;
  2979. }
  2980. }
  2981. //create pfx file
  2982. hr = pIEnroll4->createFilePFXWStr(pwszPFXPassword, pwszPFXFileName);
  2983. if (S_OK != hr)
  2984. {
  2985. goto createFilePFXWStrError;
  2986. }
  2987. }
  2988. done:
  2989. fRet = TRUE;
  2990. ErrorReturn:
  2991. if(NULL != pIEnroll4)
  2992. {
  2993. pIEnroll4->Release();
  2994. }
  2995. if (fCoInit)
  2996. {
  2997. CoUninitialize();
  2998. }
  2999. if (NULL != pwszPKCS7FileName)
  3000. {
  3001. LocalFree(pwszPKCS7FileName);
  3002. }
  3003. if (NULL != pwszPFXFileName)
  3004. {
  3005. LocalFree(pwszPFXFileName);
  3006. }
  3007. if (NULL != pwszPFXPassword && pwszPFXPassword != wszEmptyPassword)
  3008. {
  3009. LocalFree(pwszPFXPassword);
  3010. }
  3011. return fRet;
  3012. PRINT_ERROR2(CoCreateInstanceError, hr)
  3013. PRINT_ERROR2(myMultiByteToWideCharError, hr)
  3014. PRINT_ERROR2(acceptFilePKCS7WStrError, hr)
  3015. PRINT_ERROR2(createFilePFXWStrError, hr)
  3016. PRINT_ERROR2(CoInitializeError, hr)
  3017. PRINT_ERROR2(MissedPKCS7FileError, E_INVALIDARG)
  3018. }
  3019. //+---------------------------------------------------------------------------
  3020. //
  3021. // Function: Usage
  3022. //
  3023. // Synopsis: prints the usage statement
  3024. //
  3025. //----------------------------------------------------------------------------
  3026. static void Usage(DWORD cTest)
  3027. {
  3028. printf("Usage: txenrol [options]\n");
  3029. printf(" options:\n");
  3030. printf(" -h this help\n");
  3031. printf(" -k [KeyContainerName]\n");
  3032. printf(" -n [DNName]\n");
  3033. printf(" -x [CAExchangeCertFileName]\n");
  3034. printf(" -o [CMCRequestFileName]\n");
  3035. printf(" -s [#] stress test count\n");
  3036. printf(" -t [TestID] run single test. There are %d tests.\n", cTest);
  3037. printf(" -r [CMCResponseFile]\n");
  3038. printf(" -a [PKCS7FileName]\n");
  3039. printf(" -f [PFXFileName], -a is required\n");
  3040. printf(" -w [PFXPassword], -a is required. If no -p, empty password is used.\n");
  3041. printf(" -p pause before each test\n");
  3042. printf(" -v verbose\n");
  3043. printf("\n");
  3044. printf(" Test1: basic operation, gen keys, gen request, accept cert.\n");
  3045. printf(" Test2: basic operation but with no EKU or no DN name.\n");
  3046. printf(" Test3: test renewal cert.\n");
  3047. printf(" Test4: basic operation but put the certs in HKLM\n");
  3048. printf(" Test5: test self signed certificate creation\n");
  3049. printf(" Test6: basic operation with attributes\n");
  3050. printf(" Test7: basic operation but put the certs in HKLM\n");
  3051. printf(" Test8: test some alg enum stuff\n");
  3052. printf(" Test9: test some alg enum stuff\n");
  3053. printf(" Test10: test renewal\n");
  3054. printf(" Test11: test CMC request generation\n");
  3055. printf(" Test12: test CMC response. skipped except -r is passed\n");
  3056. printf(" Test13: test pending API\n");
  3057. printf(" Test14: test Enroll4 misc. methods\n");
  3058. printf(" Test15: test acceptPKCS7 and PFX\n");
  3059. }
  3060. BOOL
  3061. ParseOptions(int argc, char *argv[])
  3062. {
  3063. int i;
  3064. for (i = 1; i < argc; ++i)
  3065. {
  3066. if ('-' == argv[i][0])
  3067. {
  3068. switch (argv[i][1])
  3069. {
  3070. case 'n':
  3071. case 'N':
  3072. ++i;
  3073. if (i < argc)
  3074. {
  3075. g_pszDNName = argv[i];
  3076. }
  3077. else
  3078. {
  3079. printf("missed DNName\n");
  3080. return FALSE;
  3081. }
  3082. break;
  3083. case 'x':
  3084. case 'X':
  3085. ++i;
  3086. if (i < argc)
  3087. {
  3088. g_pszCAXchgFileName = argv[i];
  3089. }
  3090. else
  3091. {
  3092. printf("missed CAExchangeFileName\n");
  3093. return FALSE;
  3094. }
  3095. break;
  3096. case 'o':
  3097. case 'O':
  3098. ++i;
  3099. if (i < argc)
  3100. {
  3101. g_pszCMCFileName = argv[i];
  3102. }
  3103. else
  3104. {
  3105. printf("missed CMCRequestFileName\n");
  3106. return FALSE;
  3107. }
  3108. break;
  3109. case 'w':
  3110. case 'W':
  3111. ++i;
  3112. if (i < argc)
  3113. {
  3114. g_pszPFXPassword = argv[i];
  3115. }
  3116. else
  3117. {
  3118. printf("missed PFXPassword\n");
  3119. return FALSE;
  3120. }
  3121. break;
  3122. case 'f':
  3123. case 'F':
  3124. ++i;
  3125. if (i < argc)
  3126. {
  3127. g_pszPFXFileName = argv[i];
  3128. }
  3129. else
  3130. {
  3131. printf("missed PFXFileName\n");
  3132. return FALSE;
  3133. }
  3134. break;
  3135. case 'a':
  3136. case 'A':
  3137. ++i;
  3138. if (i < argc)
  3139. {
  3140. g_pszPKCS7FileName = argv[i];
  3141. }
  3142. else
  3143. {
  3144. printf("missed PKCS7FileName\n");
  3145. return FALSE;
  3146. }
  3147. break;
  3148. case 'r':
  3149. case 'R':
  3150. ++i;
  3151. if (i < argc)
  3152. {
  3153. g_pszCMCResponseFileName = argv[i];
  3154. }
  3155. else
  3156. {
  3157. printf("missed CMCResponseFileName\n");
  3158. return FALSE;
  3159. }
  3160. break;
  3161. case 'k':
  3162. case 'K':
  3163. ++i;
  3164. if (i < argc)
  3165. {
  3166. g_pszKeyContainer = argv[i];
  3167. }
  3168. else
  3169. {
  3170. printf("missed KeyContainerName\n");
  3171. return FALSE;
  3172. }
  3173. break;
  3174. case 's':
  3175. case 'S':
  3176. ++i;
  3177. if (i < argc)
  3178. {
  3179. g_cStress = atoi(argv[i]);
  3180. }
  3181. break;
  3182. case 't':
  3183. case 'T':
  3184. ++i;
  3185. if (i < argc)
  3186. {
  3187. g_dwTestID = atoi(argv[i]);
  3188. }
  3189. break;
  3190. case 'p':
  3191. case 'P':
  3192. g_fPause = TRUE;
  3193. break;
  3194. case 'v':
  3195. case 'V':
  3196. g_fVerb = TRUE;
  3197. break;
  3198. case 'h':
  3199. case 'H':
  3200. return FALSE;
  3201. default:
  3202. printf("Unrecognized options -%c\n", argv[i][1]);
  3203. return FALSE;
  3204. break;
  3205. }
  3206. }
  3207. else
  3208. {
  3209. printf("Unrecognized options %s\n", argv[i]);
  3210. return FALSE;
  3211. }
  3212. }
  3213. return TRUE;
  3214. }
  3215. //+---------------------------------------------------------------------------
  3216. //
  3217. // Function: main
  3218. //
  3219. // Synopsis: main program entry point
  3220. //
  3221. //----------------------------------------------------------------------------
  3222. typedef BOOL (* PFNTest)(void);
  3223. PFNTest arPfnTest[] = {Test1, Test2, Test3, Test4, Test5, Test6, Test7, Test8, Test9, Test10, Test11, Test12, Test13, Test14, Test15};
  3224. #define COUNT_TEST sizeof(arPfnTest)/sizeof(arPfnTest[0])
  3225. int _cdecl main(int argc, char * argv[])
  3226. {
  3227. int ErrReturn = 0;
  3228. DWORD i;
  3229. DWORD n;
  3230. DWORD NBRTests = sizeof(arPfnTest) / sizeof(PFNTest);
  3231. BOOL fPassed = TRUE;
  3232. if (1 > argc)
  3233. {
  3234. Usage(COUNT_TEST);
  3235. return( 1 );
  3236. }
  3237. //parse options
  3238. if (!ParseOptions(argc, argv))
  3239. {
  3240. Usage(COUNT_TEST);
  3241. return (1);
  3242. }
  3243. for (DWORD n = 0; n < g_cStress; ++n)
  3244. {
  3245. if (g_fPause)
  3246. {
  3247. char wszgets[3];
  3248. if (MAXDWORD == g_dwTestID)
  3249. {
  3250. printf("press enter key to start the tests ...");
  3251. }
  3252. else
  3253. {
  3254. printf("press enter key to run Test%d ...", g_dwTestID);
  3255. }
  3256. gets(wszgets);
  3257. }
  3258. if (MAXDWORD != g_dwTestID &&
  3259. COUNT_TEST >= g_dwTestID)
  3260. {
  3261. //only do one test
  3262. if (!arPfnTest[g_dwTestID - 1]())
  3263. {
  3264. printf("Test%d failed.\n", g_dwTestID);
  3265. fPassed = FALSE;
  3266. }
  3267. else
  3268. {
  3269. printf("Test%d finished.\n", g_dwTestID);
  3270. }
  3271. }
  3272. else
  3273. {
  3274. for(i=0; i<NBRTests; i++)
  3275. {
  3276. if( !arPfnTest[i]() )
  3277. {
  3278. printf("Test%d failed.\n", i+1);
  3279. fPassed = FALSE;
  3280. }
  3281. else
  3282. {
  3283. printf("Test%d finished.\n", i+1);
  3284. }
  3285. }
  3286. }
  3287. if (1 < g_cStress)
  3288. {
  3289. printf("test round %d finished\n", n+1);
  3290. }
  3291. }
  3292. if (fPassed)
  3293. {
  3294. printf("All XEnroll tests passed.\n");
  3295. }
  3296. else
  3297. {
  3298. printf("One or more XEnroll tests didn't pass.\n");
  3299. }
  3300. return(ErrReturn);
  3301. }