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.

1960 lines
59 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1996 - 1999
  6. //
  7. // File: pfx.cpp
  8. //
  9. // Contents: PFX: Personal Information Exchange.
  10. //
  11. // Functions:
  12. //
  13. // History: 02-Aug-96 kevinr created
  14. // 01-May-97 mattt modified for pstore provider usage
  15. // 07-Jul-97 mattt modified for crypt32 inclusion
  16. //
  17. //--------------------------------------------------------------------------
  18. #include "global.hxx"
  19. #define _PFX_SOURCE_
  20. extern "C" {
  21. #include "pfxpkcs.h" // ASN1-generated
  22. }
  23. #include "pfxhelp.h"
  24. #include "pfxcmn.h"
  25. #include "crypttls.h"
  26. #include "pfxcrypt.h"
  27. #include <sha.h>
  28. #include "dbgdef.h"
  29. #define CURRENT_PFX_VERSION 0x3
  30. // fwd
  31. BOOL FPFXDumpSafeCntsToHPFX(SafeContents* pSafeCnts, HPFX hpfx);
  32. static HCRYPTASN1MODULE hPFXAsn1Module;
  33. BOOL InitPFX()
  34. {
  35. #ifdef OSS_CRYPT_ASN1
  36. if (0 == (hPFXAsn1Module = I_CryptInstallAsn1Module(pfxpkcs, 0, NULL)) )
  37. return FALSE;
  38. #else
  39. PFXPKCS_Module_Startup();
  40. if (0 == (hPFXAsn1Module = I_CryptInstallAsn1Module(
  41. PFXPKCS_Module, 0, NULL))) {
  42. PFXPKCS_Module_Cleanup();
  43. return FALSE;
  44. }
  45. #endif // OSS_CRYPT_ASN1
  46. return TRUE;
  47. }
  48. BOOL TerminatePFX()
  49. {
  50. I_CryptUninstallAsn1Module(hPFXAsn1Module);
  51. #ifndef OSS_CRYPT_ASN1
  52. PFXPKCS_Module_Cleanup();
  53. #endif // OSS_CRYPT_ASN1
  54. return TRUE;
  55. }
  56. static inline ASN1encoding_t GetEncoder(void)
  57. {
  58. return I_CryptGetAsn1Encoder(hPFXAsn1Module);
  59. }
  60. static inline ASN1decoding_t GetDecoder(void)
  61. {
  62. return I_CryptGetAsn1Decoder(hPFXAsn1Module);
  63. }
  64. //+-------------------------------------------------------------------------
  65. // Function: IPFX_Asn1ToObjectID
  66. //
  67. // Synopsis: Convert a dotted string oid to an ASN1 ObjectID
  68. //
  69. // Returns: FALSE iff failed
  70. //--------------------------------------------------------------------------
  71. BOOL
  72. IPFX_Asn1ToObjectID(
  73. IN OID oid,
  74. OUT ObjectID *pooid
  75. )
  76. {
  77. BOOL fRet;
  78. pooid->count = 16;
  79. if (!PkiAsn1ToObjectIdentifier(
  80. oid,
  81. &pooid->count,
  82. pooid->value))
  83. goto PkiAsn1ToObjectIdentifierError;
  84. fRet = TRUE;
  85. CommonReturn:
  86. return fRet;
  87. ErrorReturn:
  88. SetLastError(CRYPT_E_OID_FORMAT);
  89. fRet = FALSE;
  90. goto CommonReturn;
  91. TRACE_ERROR(PkiAsn1ToObjectIdentifierError)
  92. }
  93. //+-------------------------------------------------------------------------
  94. // Function: IPFX_Asn1FromObjectID
  95. //
  96. // Synopsis: Convert an ASN1 ObjectID to a dotted string oid
  97. //
  98. // Returns: FALSE iff failed
  99. //--------------------------------------------------------------------------
  100. BOOL
  101. IPFX_Asn1FromObjectID(
  102. IN ObjectID *pooid,
  103. OUT OID *poid
  104. )
  105. {
  106. BOOL fRet;
  107. OID oid = NULL;
  108. DWORD cb;
  109. if (!PkiAsn1FromObjectIdentifier(
  110. pooid->count,
  111. pooid->value,
  112. NULL,
  113. &cb))
  114. goto PkiAsn1FromObjectIdentifierSizeError;
  115. if (NULL == (oid = (OID)SSAlloc( cb)))
  116. goto OidAllocError;
  117. if (!PkiAsn1FromObjectIdentifier(
  118. pooid->count,
  119. pooid->value,
  120. oid,
  121. &cb))
  122. goto PkiAsn1FromObjectIdentifierError;
  123. fRet = TRUE;
  124. CommonReturn:
  125. *poid = oid;
  126. return fRet;
  127. ErrorReturn:
  128. SSFree(oid);
  129. fRet = FALSE;
  130. goto CommonReturn;
  131. TRACE_ERROR(OidAllocError)
  132. SET_ERROR(PkiAsn1FromObjectIdentifierSizeError ,CRYPT_E_OID_FORMAT)
  133. SET_ERROR(PkiAsn1FromObjectIdentifierError ,CRYPT_E_OID_FORMAT)
  134. }
  135. //+-------------------------------------------------------------------------
  136. // Function: IPFX_EqualObjectIDs
  137. //
  138. // Compare 2 OSS object id's.
  139. //
  140. // Returns: FALSE iff !equal
  141. //--------------------------------------------------------------------------
  142. BOOL
  143. WINAPI
  144. IPFX_EqualObjectIDs(
  145. IN ObjectID *poid1,
  146. IN ObjectID *poid2)
  147. {
  148. BOOL fRet;
  149. DWORD i;
  150. PDWORD pdw1;
  151. PDWORD pdw2;
  152. if (poid1->count != poid2->count)
  153. goto Unequal;
  154. for (i=poid1->count, pdw1=poid1->value, pdw2=poid2->value;
  155. (i>0) && (*pdw1==*pdw2);
  156. i--, pdw1++, pdw2++)
  157. ;
  158. if (i>0)
  159. goto Unequal;
  160. fRet = TRUE; // equal
  161. CommonReturn:
  162. return fRet;
  163. Unequal:
  164. fRet = FALSE; // !equal
  165. goto CommonReturn;
  166. }
  167. //+-------------------------------------------------------------------------
  168. // Function: PfxExportCreate
  169. //
  170. // Synopsis: Prepare the PFX for export
  171. //
  172. // Returns: NULL iff failed
  173. //--------------------------------------------------------------------------
  174. HPFX
  175. PFXAPI
  176. PfxExportCreate (
  177. LPCWSTR szPassword
  178. )
  179. {
  180. PPFX_INFO ppfx = NULL;
  181. PCCERT_CONTEXT pcctx = NULL;
  182. // Create the HPFX
  183. if (NULL == (ppfx = (PPFX_INFO)SSAlloc(sizeof(PFX_INFO))))
  184. goto PfxInfoAllocError;
  185. ZeroMemory(ppfx, sizeof(PFX_INFO));
  186. if (szPassword)
  187. {
  188. if (NULL == (ppfx->szPassword = (LPWSTR)SSAlloc(WSZ_BYTECOUNT(szPassword)) ))
  189. goto PfxInfoAllocError;
  190. CopyMemory(ppfx->szPassword, szPassword, WSZ_BYTECOUNT(szPassword));
  191. }
  192. else
  193. {
  194. ppfx->szPassword = NULL;
  195. }
  196. CommonReturn:
  197. // free pcctx
  198. return (HPFX)ppfx;
  199. ErrorReturn:
  200. PfxCloseHandle((HPFX)ppfx);
  201. ppfx = NULL;
  202. goto CommonReturn;
  203. TRACE_ERROR(PfxInfoAllocError)
  204. }
  205. BOOL ASNFreeSafeBag(SafeBag* pBag)
  206. {
  207. DWORD iAttr, iAnys;
  208. if (pBag->safeBagAttribs.value)
  209. {
  210. if (pBag->safeBagContent.value)
  211. {
  212. SSFree(pBag->safeBagContent.value);
  213. pBag->safeBagContent.value = NULL;
  214. }
  215. for (iAttr=0; iAttr<pBag->safeBagAttribs.count; iAttr++)
  216. {
  217. for (iAnys=0; iAnys<pBag->safeBagAttribs.value[iAttr].attributeValue.count; iAnys++)
  218. {
  219. if (pBag->safeBagAttribs.value[iAttr].attributeValue.value[iAnys].value)
  220. SSFree(pBag->safeBagAttribs.value[iAttr].attributeValue.value[iAnys].value);
  221. pBag->safeBagAttribs.value[iAttr].attributeValue.value[iAnys].value = NULL;
  222. }
  223. SSFree(pBag->safeBagAttribs.value[iAttr].attributeValue.value);
  224. }
  225. SSFree(pBag->safeBagAttribs.value);
  226. pBag->safeBagAttribs.value = NULL;
  227. pBag->safeBagAttribs.count = 0;
  228. }
  229. SSFree(pBag);
  230. return TRUE;
  231. }
  232. //+-------------------------------------------------------------------------
  233. // Function: PfxCloseHandle
  234. //
  235. // Synopsis: Free all resources associated with the hpfx
  236. //
  237. // Returns: error code
  238. //--------------------------------------------------------------------------
  239. BOOL
  240. PFXAPI
  241. PfxCloseHandle (
  242. IN HPFX hpfx)
  243. {
  244. BOOL fRet = FALSE;
  245. PPFX_INFO pPfx = (PPFX_INFO)hpfx;
  246. DWORD i;
  247. if (pPfx)
  248. {
  249. if (pPfx->szPassword)
  250. SSFree(pPfx->szPassword);
  251. // keys struct
  252. for (i=0; i<pPfx->cKeys; i++)
  253. {
  254. ASNFreeSafeBag((SafeBag*)pPfx->rgKeys[i]);
  255. pPfx->rgKeys[i] = NULL;
  256. }
  257. SSFree(pPfx->rgKeys);
  258. pPfx->rgKeys = NULL;
  259. pPfx->cKeys = 0;
  260. // shrouded keys
  261. for (i=0; i<pPfx->cShroudedKeys; i++)
  262. {
  263. ASNFreeSafeBag((SafeBag*)pPfx->rgShroudedKeys[i]);
  264. pPfx->rgShroudedKeys[i] = NULL;
  265. }
  266. SSFree(pPfx->rgShroudedKeys);
  267. pPfx->rgShroudedKeys = NULL;
  268. pPfx->cShroudedKeys = 0;
  269. // certcrl struct
  270. for (i=0; i<pPfx->cCertcrls; i++)
  271. {
  272. ASNFreeSafeBag((SafeBag*)pPfx->rgCertcrls[i]);
  273. pPfx->rgCertcrls[i] = NULL;
  274. }
  275. SSFree(pPfx->rgCertcrls);
  276. pPfx->rgCertcrls = NULL;
  277. pPfx->cCertcrls = 0;
  278. // secrets struct
  279. for (i=0; i<pPfx->cSecrets; i++)
  280. {
  281. ASNFreeSafeBag((SafeBag*)pPfx->rgSecrets[i]);
  282. pPfx->rgSecrets[i] = NULL;
  283. }
  284. SSFree(pPfx->rgSecrets);
  285. pPfx->rgSecrets = NULL;
  286. pPfx->cSecrets = 0;
  287. SSFree(pPfx);
  288. }
  289. fRet = TRUE;
  290. //Ret:
  291. return fRet;
  292. }
  293. BOOL
  294. MakeEncodedCertBag(
  295. BYTE *pbEncodedCert,
  296. DWORD cbEncodedCert,
  297. BYTE *pbEncodedCertBag,
  298. DWORD *pcbEncodedCertBag
  299. )
  300. {
  301. BOOL fRet = TRUE;
  302. DWORD dwErr;
  303. OctetStringType encodedCert;
  304. DWORD cbCertAsOctetString = 0;
  305. BYTE *pbCertAsOctetString = NULL;
  306. DWORD dwBytesNeeded = 0;
  307. CertBag certBag;
  308. BYTE *pbEncoded = NULL;
  309. DWORD cbEncoded = 0;
  310. ASN1encoding_t pEnc = GetEncoder();
  311. // wrap the encoded cert in an OCTET_STRING
  312. encodedCert.length = cbEncodedCert;
  313. encodedCert.value = pbEncodedCert;
  314. if (0 != PkiAsn1Encode(
  315. pEnc,
  316. &encodedCert,
  317. OctetStringType_PDU,
  318. &pbCertAsOctetString,
  319. &cbCertAsOctetString))
  320. goto SetPFXEncodeError;
  321. // setup and encode the CertBag
  322. // convert the X509Cert oid from a string to an ASN1 ObjectIdentifier
  323. if (!IPFX_Asn1ToObjectID(szOID_PKCS_12_x509Cert, &certBag.certType)) {
  324. goto ErrorReturn;
  325. }
  326. certBag.value.length = cbCertAsOctetString;
  327. certBag.value.value = pbCertAsOctetString;
  328. if (0 != PkiAsn1Encode(
  329. pEnc,
  330. &certBag,
  331. CertBag_PDU,
  332. &pbEncoded,
  333. &cbEncoded))
  334. goto SetPFXEncodeError;
  335. // check to see if the caller has enough space for the data
  336. if ((0 != *pcbEncodedCertBag) && (*pcbEncodedCertBag < cbEncoded)) {
  337. goto ErrorReturn;
  338. }
  339. else if (0 != *pcbEncodedCertBag) {
  340. memcpy(pbEncodedCertBag, pbEncoded, cbEncoded);
  341. }
  342. goto CommonReturn;
  343. SetPFXEncodeError:
  344. SetLastError(CRYPT_E_BAD_ENCODE);
  345. ErrorReturn:
  346. fRet = FALSE;
  347. CommonReturn:
  348. // save last error from TLS madness
  349. dwErr = GetLastError();
  350. *pcbEncodedCertBag = cbEncoded;
  351. PkiAsn1FreeEncoded(pEnc, pbCertAsOctetString);
  352. PkiAsn1FreeEncoded(pEnc, pbEncoded);
  353. // save last error from TLS madness
  354. SetLastError(dwErr);
  355. return fRet;
  356. }
  357. BOOL
  358. GetEncodedCertFromEncodedCertBag(
  359. BYTE *pbEncodedCertBag,
  360. DWORD cbEncodedCertBag,
  361. BYTE *pbEncodedCert,
  362. DWORD *pcbEncodedCert)
  363. {
  364. BOOL fRet = TRUE;
  365. DWORD dwErr;
  366. CertBag *pCertBag = NULL;
  367. OID oid = NULL;
  368. OctetStringType *pEncodedCert = NULL;
  369. ASN1decoding_t pDec = GetDecoder();
  370. // decode the cert bag
  371. if (0 != PkiAsn1Decode(
  372. pDec,
  373. (void **)&pCertBag,
  374. CertBag_PDU,
  375. pbEncodedCertBag,
  376. cbEncodedCertBag))
  377. goto SetPFXDecodeError;
  378. // make sure this is a X509 cert since that is all we support
  379. if (!IPFX_Asn1FromObjectID(&pCertBag->certType, &oid))
  380. goto ErrorReturn;
  381. // only support SHA1
  382. if (0 != strcmp( oid, szOID_PKCS_12_x509Cert))
  383. goto SetPFXDecodeError;
  384. // strip off the octet string wrapper of the encoded cert
  385. if (0 != PkiAsn1Decode(
  386. pDec,
  387. (void **)&pEncodedCert,
  388. OctetStringType_PDU,
  389. (BYTE *) pCertBag->value.value,
  390. pCertBag->value.length))
  391. goto SetPFXDecodeError;
  392. // check to see if the caller has enough space for the data
  393. if ((0 != *pcbEncodedCert) && (*pcbEncodedCert < (DWORD) pEncodedCert->length)) {
  394. goto ErrorReturn;
  395. }
  396. else if (0 != *pcbEncodedCert) {
  397. memcpy(pbEncodedCert, pEncodedCert->value, pEncodedCert->length);
  398. }
  399. goto CommonReturn;
  400. SetPFXDecodeError:
  401. SetLastError(CRYPT_E_BAD_ENCODE);
  402. ErrorReturn:
  403. fRet = FALSE;
  404. CommonReturn:
  405. // save last error from TLS madness
  406. dwErr = GetLastError();
  407. if (pEncodedCert)
  408. *pcbEncodedCert = pEncodedCert->length;
  409. PkiAsn1FreeDecoded(pDec, pCertBag, CertBag_PDU);
  410. PkiAsn1FreeDecoded(pDec, pEncodedCert, OctetStringType_PDU);
  411. if (oid)
  412. SSFree(oid);
  413. // save last error from TLS madness
  414. SetLastError(dwErr);
  415. return fRet;
  416. }
  417. BOOL
  418. GetSaltAndIterationCount(
  419. BYTE *pbParameters,
  420. DWORD cbParameters,
  421. BYTE **ppbSalt,
  422. DWORD *pcbSalt,
  423. int *piIterationCount
  424. )
  425. {
  426. BOOL fRet = TRUE;
  427. DWORD dwErr;
  428. PBEParameter *pPBEParameter = NULL;
  429. ASN1decoding_t pDec = GetDecoder();
  430. if (0 != PkiAsn1Decode(
  431. pDec,
  432. (void **)&pPBEParameter,
  433. PBEParameter_PDU,
  434. pbParameters,
  435. cbParameters))
  436. goto SetPFXDecodeError;
  437. if (NULL == (*ppbSalt = (BYTE *) SSAlloc(pPBEParameter->salt.length)))
  438. goto ErrorReturn;
  439. memcpy(*ppbSalt, pPBEParameter->salt.value, pPBEParameter->salt.length);
  440. *pcbSalt = pPBEParameter->salt.length;
  441. *piIterationCount = pPBEParameter->iterationCount;
  442. goto Ret;
  443. SetPFXDecodeError:
  444. SetLastError(CRYPT_E_BAD_ENCODE);
  445. fRet = FALSE;
  446. goto Ret;
  447. ErrorReturn:
  448. fRet = FALSE;
  449. Ret:
  450. // save last error from TLS madness
  451. dwErr = GetLastError();
  452. PkiAsn1FreeDecoded(pDec, pPBEParameter, PBEParameter_PDU);
  453. // save last error from TLS madness
  454. SetLastError(dwErr);
  455. return fRet;
  456. }
  457. BOOL
  458. SetSaltAndIterationCount(
  459. BYTE **ppbParameters,
  460. DWORD *pcbParameters,
  461. BYTE *pbSalt,
  462. DWORD cbSalt,
  463. int iIterationCount
  464. )
  465. {
  466. BOOL fRet = TRUE;
  467. DWORD dwErr;
  468. PBEParameter sPBEParameter;
  469. sPBEParameter.salt.length = cbSalt;
  470. sPBEParameter.salt.value = pbSalt;
  471. sPBEParameter.iterationCount = iIterationCount;
  472. BYTE *pbEncoded = NULL;
  473. DWORD cbEncoded;
  474. ASN1encoding_t pEnc = GetEncoder();
  475. if (0 != PkiAsn1Encode(
  476. pEnc,
  477. &sPBEParameter,
  478. PBEParameter_PDU,
  479. &pbEncoded,
  480. &cbEncoded))
  481. goto SetPFXDecodeError;
  482. if (NULL == (*ppbParameters = (BYTE *) SSAlloc(cbEncoded)))
  483. goto ErrorReturn;
  484. memcpy(*ppbParameters, pbEncoded, cbEncoded);
  485. *pcbParameters = cbEncoded;
  486. goto Ret;
  487. SetPFXDecodeError:
  488. SetLastError(CRYPT_E_BAD_ENCODE);
  489. fRet = FALSE;
  490. goto Ret;
  491. ErrorReturn:
  492. fRet = FALSE;
  493. Ret:
  494. // save last error from TLS madness
  495. dwErr = GetLastError();
  496. PkiAsn1FreeEncoded(pEnc, pbEncoded);
  497. // save last error from TLS madness
  498. SetLastError(dwErr);
  499. return fRet;
  500. }
  501. ///////////////////////////////////////////////////////////////////////////////////
  502. ///////////////////////////////////////////////////////////////////////////////////
  503. ///////////////////////////////////////////////////////////////////////////////////
  504. ///////////////////////////////////////////////////////////////////////////////////
  505. ///////////////////////////////////////////////////////////////////////////////////
  506. ///////////////////////////////////////////////////////////////////////////////////
  507. // wrap up data from pfx_info.safeContents area
  508. BOOL
  509. PFXAPI
  510. PfxExportBlob
  511. (
  512. HPFX hpfx,
  513. PBYTE pbOut,
  514. DWORD* pcbOut,
  515. DWORD dwFlags
  516. )
  517. {
  518. BOOL fRet = FALSE;
  519. BOOL fSizeOnly = (pbOut==NULL);
  520. DWORD dwErr;
  521. PPFX_INFO ppfx = (PPFX_INFO)hpfx;
  522. BYTE rgbSafeMac[A_SHA_DIGEST_LEN];
  523. BYTE rgbMacSalt[A_SHA_DIGEST_LEN];
  524. OID oid = NULL;
  525. EncryptedData EncrData; MAKEZERO(EncrData);
  526. OctetStringType OctetStr; MAKEZERO(OctetStr);
  527. AuthenticatedSafes AuthSafes; MAKEZERO(AuthSafes);
  528. PBEParameter PbeParam; MAKEZERO(PbeParam);
  529. ContentInfo rgCntInfo[2]; memset(&(rgCntInfo[0]), 0, sizeof(rgCntInfo));
  530. SafeContents SafeCnts; MAKEZERO(SafeCnts);
  531. PFX sPfx; MAKEZERO(sPfx);
  532. BYTE *pbEncoded = NULL;
  533. DWORD cbEncoded;
  534. ASN1encoding_t pEnc = GetEncoder();
  535. PBYTE pbEncrData = NULL;
  536. DWORD cbEncrData;
  537. DWORD i;
  538. // multi bags with differing security levels
  539. int iLevel, iBagSecurityLevels = 0;
  540. BOOL fNoSecurity, fLowSecurity, fHighSecurity;
  541. DWORD dwEncrAlg;
  542. HCRYPTPROV hVerifyProv = NULL;
  543. if (!CryptAcquireContext(&hVerifyProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
  544. goto ErrorOut;
  545. // Encode all SafeBags
  546. fNoSecurity = (ppfx->cShroudedKeys != 0); // no encr on these items
  547. fLowSecurity = ((ppfx->cSecrets + ppfx->cCertcrls) != 0); // low level crypto on these items
  548. fHighSecurity = (ppfx->cKeys != 0); // high level crypto on these items
  549. iBagSecurityLevels = (fNoSecurity ? 1:0) + (fLowSecurity ? 1:0) + (fHighSecurity ? 1:0);
  550. assert(iBagSecurityLevels <= (sizeof(rgCntInfo)/sizeof(rgCntInfo[0])) );
  551. for (iLevel=0; iLevel<iBagSecurityLevels; iLevel++)
  552. {
  553. // clean up these each time through loop
  554. if (SafeCnts.value)
  555. {
  556. SSFree(SafeCnts.value);
  557. MAKEZERO(SafeCnts);
  558. }
  559. if (PbeParam.salt.value)
  560. {
  561. SSFree(PbeParam.salt.value);
  562. MAKEZERO(PbeParam);
  563. }
  564. if (EncrData.encryptedContentInfo.contentEncryptionAlg.parameters.value)
  565. {
  566. PkiAsn1FreeEncoded( pEnc, EncrData.encryptedContentInfo.contentEncryptionAlg.parameters.value);
  567. MAKEZERO(EncrData);
  568. }
  569. if (pbEncrData)
  570. {
  571. SSFree(pbEncrData);
  572. pbEncrData = NULL;
  573. }
  574. if (fNoSecurity)
  575. {
  576. // no security: bag already shrouded
  577. SafeCnts.count = ppfx->cShroudedKeys;
  578. if (NULL == (SafeCnts.value = (SafeBag*) SSAlloc(SafeCnts.count * sizeof(SafeBag)) ))
  579. goto SetPfxAllocError;
  580. ZeroMemory(SafeCnts.value, SafeCnts.count * sizeof(SafeBag));
  581. for (i=0; i<(ppfx->cShroudedKeys); i++)
  582. CopyMemory(&SafeCnts.value[i], ppfx->rgShroudedKeys[i], sizeof(SafeBag));
  583. // bag already shrouded!
  584. dwEncrAlg = 0;
  585. // done with no security setup
  586. fNoSecurity = FALSE;
  587. }
  588. else if (fLowSecurity)
  589. {
  590. DWORD dw = 0;
  591. // do low security (keys/secrets)
  592. SafeCnts.count = ppfx->cSecrets +
  593. ppfx->cCertcrls;
  594. if (NULL == (SafeCnts.value = (SafeBag*) SSAlloc(SafeCnts.count * sizeof(SafeBag)) ))
  595. goto SetPfxAllocError;
  596. ZeroMemory(SafeCnts.value, SafeCnts.count * sizeof(SafeBag));
  597. for (i=0; i<(ppfx->cSecrets); i++, dw++)
  598. CopyMemory(SafeCnts.value, ppfx->rgSecrets[i], sizeof(SafeBag));
  599. for (i=0; i<(ppfx->cCertcrls); i++, dw++)
  600. CopyMemory(&SafeCnts.value[dw], ppfx->rgCertcrls[i], sizeof(SafeBag));
  601. // encr alg present, type
  602. EncrData.encryptedContentInfo.contentEncryptionAlg.bit_mask |= parameters_present;
  603. if (!IPFX_Asn1ToObjectID(szOID_PKCS_12_pbeWithSHA1And40BitRC2, &EncrData.encryptedContentInfo.contentEncryptionAlg.algorithm))
  604. goto ErrorOut;
  605. dwEncrAlg = RC2_40;
  606. // done with low security setup
  607. fLowSecurity = FALSE;
  608. }
  609. else if (fHighSecurity)
  610. {
  611. // high security: need strength for unencr keys
  612. SafeCnts.count = ppfx->cKeys;
  613. if (NULL == (SafeCnts.value = (SafeBag*) SSAlloc(SafeCnts.count * sizeof(SafeBag)) ))
  614. goto SetPfxAllocError;
  615. ZeroMemory(SafeCnts.value, SafeCnts.count * sizeof(SafeBag));
  616. for (i=0; i<(ppfx->cKeys); i++)
  617. CopyMemory(&SafeCnts.value[i], ppfx->rgKeys[i], sizeof(SafeBag));
  618. // encr alg present, type
  619. EncrData.encryptedContentInfo.contentEncryptionAlg.bit_mask |= parameters_present;
  620. if (!IPFX_Asn1ToObjectID(szOID_PKCS_12_pbeWithSHA1And3KeyTripleDES, &EncrData.encryptedContentInfo.contentEncryptionAlg.algorithm))
  621. goto ErrorOut;
  622. // bag already shrouded!
  623. dwEncrAlg = TripleDES;
  624. // done with high security setup
  625. fHighSecurity = FALSE;
  626. }
  627. else
  628. break; // no more bags
  629. // encode safecontents
  630. if (0 != PkiAsn1Encode(
  631. pEnc,
  632. &SafeCnts,
  633. SafeContents_PDU,
  634. &pbEncoded,
  635. &cbEncoded))
  636. goto SetPFXEncodeError;
  637. if (dwEncrAlg == 0)
  638. {
  639. // no encryption?
  640. OctetStr.length = cbEncoded;
  641. OctetStr.value = pbEncoded;
  642. // jam octet string into contentInfo
  643. if (0 != PkiAsn1Encode(
  644. pEnc,
  645. &OctetStr,
  646. OctetStringType_PDU,
  647. &pbEncoded,
  648. &cbEncoded))
  649. goto SetPFXEncodeError;
  650. if (OctetStr.value)
  651. {
  652. PkiAsn1FreeEncoded(pEnc, OctetStr.value);
  653. OctetStr.value = NULL;
  654. }
  655. // set up content info struct
  656. if (!IPFX_Asn1ToObjectID(
  657. szOID_RSA_data,
  658. &rgCntInfo[iLevel].contentType))
  659. goto ErrorOut;
  660. rgCntInfo[iLevel].content.length = cbEncoded;
  661. rgCntInfo[iLevel].content.value = pbEncoded;
  662. rgCntInfo[iLevel].bit_mask = content_present;
  663. }
  664. else
  665. {
  666. cbEncrData = cbEncoded;
  667. if (NULL == (pbEncrData = (PBYTE)SSAlloc(cbEncoded)) )
  668. goto SetPfxAllocError;
  669. CopyMemory(pbEncrData, pbEncoded, cbEncrData);
  670. PkiAsn1FreeEncoded(pEnc, pbEncoded);
  671. // PBE Param
  672. PbeParam.iterationCount = PKCS12_ENCR_PWD_ITERATIONS;
  673. if (NULL == (PbeParam.salt.value = (BYTE *) SSAlloc(PBE_SALT_LENGTH) ))
  674. goto SetPfxAllocError;
  675. PbeParam.salt.length = PBE_SALT_LENGTH;
  676. if (!CryptGenRandom(hVerifyProv, PBE_SALT_LENGTH, PbeParam.salt.value))
  677. goto ErrorOut;
  678. if (0 != PkiAsn1Encode(
  679. pEnc,
  680. &PbeParam,
  681. PBEParameter_PDU,
  682. &pbEncoded,
  683. &cbEncoded))
  684. goto SetPFXEncodeError;
  685. EncrData.encryptedContentInfo.contentEncryptionAlg.parameters.length = cbEncoded;
  686. EncrData.encryptedContentInfo.contentEncryptionAlg.parameters.value = pbEncoded;
  687. // ENCRYPT safeContents into encryptedData
  688. // using szPassword (in place)
  689. if (!PFXPasswordEncryptData(
  690. dwEncrAlg,
  691. ppfx->szPassword, // pwd itself
  692. (fSizeOnly) ? 1 : PbeParam.iterationCount, // don't do iterations if only returning size
  693. PbeParam.salt.value, // pkcs5 salt
  694. PbeParam.salt.length,
  695. &pbEncrData,
  696. &cbEncrData))
  697. goto SetPFXEncryptError;
  698. // encode content to encryptedContentInfo
  699. EncrData.encryptedContentInfo.bit_mask |= encryptedContent_present;
  700. if (!IPFX_Asn1ToObjectID(szOID_RSA_data, &EncrData.encryptedContentInfo.contentType))
  701. goto ErrorOut;
  702. EncrData.encryptedContentInfo.encryptedContent.length = cbEncrData;
  703. EncrData.encryptedContentInfo.encryptedContent.value = pbEncrData;
  704. if (0 != PkiAsn1Encode(
  705. pEnc,
  706. &EncrData,
  707. EncryptedData_PDU,
  708. &pbEncoded,
  709. &cbEncoded))
  710. goto SetPFXEncodeError;
  711. // jam octet string into contentInfo
  712. // set up content info struct
  713. if (!IPFX_Asn1ToObjectID(
  714. szOID_RSA_encryptedData,
  715. &rgCntInfo[iLevel].contentType))
  716. goto ErrorOut;
  717. rgCntInfo[iLevel].content.length = cbEncoded;
  718. rgCntInfo[iLevel].content.value = pbEncoded;
  719. rgCntInfo[iLevel].bit_mask = content_present;
  720. }
  721. }
  722. AuthSafes.count = iBagSecurityLevels;
  723. AuthSafes.value = rgCntInfo;
  724. // set up authenticated safe struct
  725. if (0 != PkiAsn1Encode(
  726. pEnc,
  727. &AuthSafes,
  728. AuthenticatedSafes_PDU,
  729. &pbEncoded,
  730. &cbEncoded))
  731. goto SetPFXEncodeError;
  732. {
  733. sPfx.macData.bit_mask = macIterationCount_present;
  734. sPfx.macData.safeMac.digest.length = sizeof(rgbSafeMac);
  735. sPfx.macData.safeMac.digest.value = rgbSafeMac;
  736. // COMPATIBILITY MODE: export with macIterationCount == 1
  737. if (dwFlags & PKCS12_ENHANCED_STRENGTH_ENCODING)
  738. sPfx.macData.macIterationCount = PKCS12_MAC_PWD_ITERATIONS;
  739. else
  740. sPfx.macData.macIterationCount = 1;
  741. if (!IPFX_Asn1ToObjectID( szOID_OIWSEC_sha1, &sPfx.macData.safeMac.digestAlgorithm.algorithm))
  742. goto ErrorOut;
  743. sPfx.macData.macSalt.length = sizeof(rgbMacSalt);
  744. sPfx.macData.macSalt.value = rgbMacSalt;
  745. if (!CryptGenRandom(hVerifyProv, sPfx.macData.macSalt.length, sPfx.macData.macSalt.value))
  746. goto ErrorOut;
  747. // create MAC
  748. if (!FGenerateMAC(
  749. ppfx->szPassword,
  750. sPfx.macData.macSalt.value, // pb salt
  751. sPfx.macData.macSalt.length, // cb salt
  752. (fSizeOnly) ? 1 : sPfx.macData.macIterationCount, // don't do iterations if only returning size
  753. pbEncoded, // pb data
  754. cbEncoded, // cb data
  755. sPfx.macData.safeMac.digest.value))
  756. goto SetPFXPasswordError;
  757. }
  758. sPfx.bit_mask |= macData_present;
  759. // stream to octet string
  760. OctetStr.length = cbEncoded;
  761. OctetStr.value = pbEncoded;
  762. if (0 != PkiAsn1Encode(
  763. pEnc,
  764. &OctetStr,
  765. OctetStringType_PDU,
  766. &pbEncoded,
  767. &cbEncoded))
  768. goto SetPFXEncodeError;
  769. // take encoded authsafes octet string, encode in PFX pdu
  770. if (!IPFX_Asn1ToObjectID(
  771. szOID_RSA_data,
  772. &sPfx.authSafes.contentType))
  773. goto ErrorOut;
  774. sPfx.authSafes.content.length = cbEncoded;
  775. sPfx.authSafes.content.value = pbEncoded;
  776. sPfx.authSafes.bit_mask = content_present;
  777. sPfx.version = CURRENT_PFX_VERSION;
  778. if (0 != PkiAsn1Encode(
  779. pEnc,
  780. &sPfx,
  781. PFX_PDU,
  782. &pbEncoded,
  783. &cbEncoded))
  784. goto SetPFXEncodeError;
  785. fRet = TRUE;
  786. goto Ret;
  787. SetPFXEncodeError:
  788. SetLastError(CRYPT_E_BAD_ENCODE);
  789. goto Ret;
  790. SetPFXPasswordError:
  791. SetLastError(ERROR_INVALID_PASSWORD);
  792. goto Ret;
  793. SetPFXEncryptError:
  794. SetLastError(NTE_FAIL);
  795. goto Ret;
  796. SetPfxAllocError:
  797. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  798. goto Ret;
  799. ErrorOut: // error already set; just return failure
  800. Ret:
  801. // save last error from TLS madness
  802. dwErr = GetLastError();
  803. if (hVerifyProv)
  804. CryptReleaseContext(hVerifyProv, 0);
  805. if (EncrData.encryptedContentInfo.contentEncryptionAlg.parameters.value)
  806. PkiAsn1FreeEncoded( pEnc, EncrData.encryptedContentInfo.contentEncryptionAlg.parameters.value);
  807. for(iLevel=0; iLevel<iBagSecurityLevels; iLevel++)
  808. {
  809. if (rgCntInfo[iLevel].content.value)
  810. PkiAsn1FreeEncoded( pEnc, rgCntInfo[iLevel].content.value);
  811. }
  812. PkiAsn1FreeEncoded(pEnc, OctetStr.value);
  813. PkiAsn1FreeEncoded(pEnc, sPfx.authSafes.content.value);
  814. if (pbEncrData)
  815. SSFree(pbEncrData);
  816. if (SafeCnts.value)
  817. SSFree(SafeCnts.value);
  818. if (PbeParam.salt.value)
  819. SSFree(PbeParam.salt.value);
  820. if (fRet)
  821. {
  822. if (pbOut == NULL)
  823. {
  824. // report size only
  825. *pcbOut = cbEncoded;
  826. }
  827. else if (*pcbOut < cbEncoded)
  828. {
  829. // report that we need a bigger buffer
  830. *pcbOut = cbEncoded;
  831. fRet = FALSE;
  832. }
  833. else
  834. {
  835. // give full results
  836. CopyMemory( pbOut, pbEncoded, cbEncoded);
  837. *pcbOut = cbEncoded;
  838. }
  839. }
  840. else
  841. *pcbOut = 0;
  842. PkiAsn1FreeEncoded(pEnc, pbEncoded);
  843. // save last error from TLS madness
  844. SetLastError(dwErr);
  845. return fRet;
  846. }
  847. HPFX
  848. PFXAPI
  849. PfxImportBlob
  850. (
  851. LPCWSTR szPassword,
  852. PBYTE pbIn,
  853. DWORD cbIn,
  854. DWORD dwFlags
  855. )
  856. {
  857. PPFX_INFO ppfx = NULL;
  858. BOOL fRet = FALSE;
  859. DWORD dwErr;
  860. int iEncrType;
  861. OID oid = NULL;
  862. DWORD iAuthSafes; // # of safes in a pfx bag
  863. PFX *psPfx = NULL;
  864. OctetStringType *pOctetString = NULL;
  865. AuthenticatedSafes *pAuthSafes = NULL;
  866. PBEParameter *pPBEParameter = NULL;
  867. EncryptedData *pEncrData = NULL;
  868. SafeContents *pSafeCnts = NULL;
  869. OctetStringType *pNonEncryptedOctetString = NULL;
  870. DWORD cbDecrData;
  871. PBYTE pbDecrData = NULL;
  872. BYTE *pbEncoded = NULL;
  873. DWORD cbEncoded;
  874. ASN1decoding_t pDec = GetDecoder();
  875. // alloc return struct
  876. if (NULL == (ppfx = (PFX_INFO*)SSAlloc(sizeof(PFX_INFO)) ))
  877. goto SetPfxAllocError;
  878. ZeroMemory(ppfx, sizeof(PFX_INFO));
  879. // Crack the PFX blob
  880. if (0 != PkiAsn1Decode(
  881. pDec,
  882. (void **)&psPfx,
  883. PFX_PDU,
  884. pbIn,
  885. cbIn))
  886. goto SetPFXDecodeError;
  887. // check version of the PFX bag
  888. if (psPfx->version != CURRENT_PFX_VERSION)
  889. goto SetPFXDecodeError;
  890. // info blurted into psPfx(PFX) - ensure content present
  891. if (0 == (psPfx->authSafes.bit_mask & content_present))
  892. goto SetPFXDecodeError;
  893. // could be data/signeddata
  894. // UNDONE: only support szOID_RSA_data
  895. if (!IPFX_Asn1FromObjectID( &psPfx->authSafes.contentType, &oid))
  896. goto ErrorOut;
  897. if (0 != strcmp( oid, szOID_RSA_data))
  898. goto SetPFXDecodeError;
  899. SSFree(oid);
  900. // DSIE: Bug 144526.
  901. oid = NULL;
  902. // content is data: decode
  903. if (0 != PkiAsn1Decode(
  904. pDec,
  905. (void **)&pOctetString,
  906. OctetStringType_PDU,
  907. (BYTE *) psPfx->authSafes.content.value,
  908. psPfx->authSafes.content.length))
  909. goto SetPFXDecodeError;
  910. if (0 != (psPfx->bit_mask & macData_present))
  911. {
  912. BYTE rgbMAC[A_SHA_DIGEST_LEN];
  913. if (!IPFX_Asn1FromObjectID( &psPfx->macData.safeMac.digestAlgorithm.algorithm, &oid))
  914. goto ErrorOut;
  915. // only support SHA1
  916. if (0 != strcmp( oid, szOID_OIWSEC_sha1))
  917. goto SetPFXDecodeError;
  918. SSFree(oid);
  919. // DSIE: Bug 144526.
  920. oid = NULL;
  921. if (psPfx->macData.safeMac.digest.length != A_SHA_DIGEST_LEN)
  922. goto SetPFXIntegrityError;
  923. // check MAC
  924. // if there is no iterationCount then 1 is the default
  925. if (!(psPfx->macData.bit_mask & macIterationCount_present))
  926. {
  927. if (!FGenerateMAC(
  928. szPassword,
  929. psPfx->macData.macSalt.value, // pb salt
  930. psPfx->macData.macSalt.length, // cb salt
  931. 1,
  932. pOctetString->value, // pb data
  933. pOctetString->length, // cb data
  934. rgbMAC))
  935. goto SetPFXIntegrityError;
  936. }
  937. else
  938. {
  939. if (!FGenerateMAC(
  940. szPassword,
  941. psPfx->macData.macSalt.value, // pb salt
  942. psPfx->macData.macSalt.length, // cb salt
  943. (DWORD)psPfx->macData.macIterationCount,
  944. pOctetString->value, // pb data
  945. pOctetString->length, // cb data
  946. rgbMAC))
  947. goto SetPFXIntegrityError;
  948. }
  949. if (0 != memcmp(rgbMAC, psPfx->macData.safeMac.digest.value, A_SHA_DIGEST_LEN))
  950. goto SetPFXIntegrityError;
  951. }
  952. // now we have octet string: this is an encoded authSafe
  953. if (0 != PkiAsn1Decode(
  954. pDec,
  955. (void **)&pAuthSafes,
  956. AuthenticatedSafes_PDU,
  957. pOctetString->value,
  958. pOctetString->length))
  959. goto SetPFXDecodeError;
  960. // handle multiple safes
  961. for (iAuthSafes = 0; iAuthSafes < pAuthSafes->count; iAuthSafes++)
  962. {
  963. // could be encryptedData/envelopedData
  964. // check to see if the content is szOID_RSA_encryptedData or szOID_RSA_data
  965. if (!IPFX_Asn1FromObjectID( &pAuthSafes->value[iAuthSafes].contentType, &oid))
  966. goto ErrorOut;
  967. if (0 == strcmp( oid, szOID_RSA_encryptedData))
  968. {
  969. SSFree(oid);
  970. // DSIE: Bug 144526.
  971. oid = NULL;
  972. // decode content to encryptedData
  973. if (0 != PkiAsn1Decode(
  974. pDec,
  975. (void **)&pEncrData,
  976. EncryptedData_PDU,
  977. (BYTE *) pAuthSafes->value[iAuthSafes].content.value,
  978. pAuthSafes->value[iAuthSafes].content.length))
  979. goto SetPFXDecodeError;
  980. // chk version
  981. if (pEncrData->version != 0)
  982. goto SetPFXDecodeError;
  983. // chk content present, type
  984. if (0 == (pEncrData->encryptedContentInfo.bit_mask & encryptedContent_present))
  985. goto SetPFXDecodeError;
  986. if (!IPFX_Asn1FromObjectID(&pEncrData->encryptedContentInfo.contentType, &oid))
  987. goto ErrorOut;
  988. if (0 != strcmp( oid, szOID_RSA_data))
  989. goto SetPFXDecodeError;
  990. SSFree(oid);
  991. // DSIE: Bug 144526.
  992. oid = NULL;
  993. // chk encr alg present, type
  994. if (0 == (pEncrData->encryptedContentInfo.contentEncryptionAlg.bit_mask & parameters_present))
  995. goto SetPFXDecodeError;
  996. if (!IPFX_Asn1FromObjectID(&pEncrData->encryptedContentInfo.contentEncryptionAlg.algorithm, &oid))
  997. goto ErrorOut;
  998. if (0 != PkiAsn1Decode(
  999. pDec,
  1000. (void **)&pPBEParameter,
  1001. PBEParameter_PDU,
  1002. (BYTE *) pEncrData->encryptedContentInfo.contentEncryptionAlg.parameters.value,
  1003. pEncrData->encryptedContentInfo.contentEncryptionAlg.parameters.length))
  1004. goto SetPFXDecodeError;
  1005. if (0 == strcmp( oid, szOID_PKCS_12_pbeWithSHA1And40BitRC2))
  1006. {
  1007. iEncrType = RC2_40;
  1008. }
  1009. else if (0 == strcmp( oid, szOID_PKCS_12_pbeWithSHA1And40BitRC4))
  1010. {
  1011. iEncrType = RC4_40;
  1012. }
  1013. else if (0 == strcmp( oid, szOID_PKCS_12_pbeWithSHA1And128BitRC2))
  1014. {
  1015. iEncrType = RC2_128;
  1016. }
  1017. else if (0 == strcmp( oid, szOID_PKCS_12_pbeWithSHA1And128BitRC4))
  1018. {
  1019. iEncrType = RC4_128;
  1020. }
  1021. else if (0 == strcmp( oid, szOID_PKCS_12_pbeWithSHA1And3KeyTripleDES))
  1022. {
  1023. // FIX - we need to differentiate between 2 and 3 key triple des
  1024. iEncrType = TripleDES;
  1025. }
  1026. else
  1027. goto SetPFXAlgIDError;
  1028. SSFree(oid);
  1029. // DSIE: Bug 144526.
  1030. oid = NULL;
  1031. // DECRYPT encryptedData using szPassword (in place)
  1032. cbDecrData = pEncrData->encryptedContentInfo.encryptedContent.length;
  1033. if (NULL == (pbDecrData = (PBYTE)SSAlloc(pEncrData->encryptedContentInfo.encryptedContent.length)) )
  1034. goto SetPfxAllocError;
  1035. CopyMemory(pbDecrData, pEncrData->encryptedContentInfo.encryptedContent.value, cbDecrData);
  1036. if (!PFXPasswordDecryptData(
  1037. iEncrType, // encr type
  1038. szPassword,
  1039. pPBEParameter->iterationCount,
  1040. pPBEParameter->salt.value, // pkcs5 salt
  1041. pPBEParameter->salt.length,
  1042. &pbDecrData,
  1043. (PDWORD)&cbDecrData))
  1044. goto SetPFXDecryptError;
  1045. // set up to decode the SafeContents
  1046. cbEncoded = cbDecrData;
  1047. pbEncoded = pbDecrData;
  1048. }
  1049. else if (0 == strcmp( oid, szOID_RSA_data))
  1050. {
  1051. SSFree(oid);
  1052. // DSIE: Bug 144526.
  1053. oid = NULL;
  1054. // strip off the octet string wrapper
  1055. if (0 != PkiAsn1Decode(
  1056. pDec,
  1057. (void **)&pNonEncryptedOctetString,
  1058. OctetStringType_PDU,
  1059. (BYTE *) pAuthSafes->value[iAuthSafes].content.value,
  1060. pAuthSafes->value[iAuthSafes].content.length))
  1061. goto SetPFXDecodeError;
  1062. // the safe isn't encrypted, so just setup to decode the data as SafeContents
  1063. cbEncoded = pNonEncryptedOctetString->length;
  1064. pbEncoded = pNonEncryptedOctetString->value;
  1065. }
  1066. else
  1067. {
  1068. SSFree(oid);
  1069. // DSIE: Bug 144526.
  1070. oid = NULL;
  1071. goto SetPFXDecodeError;
  1072. }
  1073. // decode the SafeContents, it is either the plaintext encryptedData or the original data
  1074. if (0 != PkiAsn1Decode(
  1075. pDec,
  1076. (void **)&pSafeCnts,
  1077. SafeContents_PDU,
  1078. pbEncoded,
  1079. cbEncoded))
  1080. goto SetPFXDecodeError;
  1081. // tear pSafeCnts apart, mash into ppfx
  1082. if (!FPFXDumpSafeCntsToHPFX(pSafeCnts, ppfx))
  1083. goto SetPFXDecodeError;
  1084. // loop cleanup
  1085. if (pEncrData) {
  1086. PkiAsn1FreeDecoded(pDec, pEncrData, EncryptedData_PDU);
  1087. pEncrData = NULL;
  1088. }
  1089. if (pPBEParameter) {
  1090. PkiAsn1FreeDecoded(pDec, pPBEParameter, PBEParameter_PDU);
  1091. pPBEParameter = NULL;
  1092. }
  1093. if (pNonEncryptedOctetString) {
  1094. PkiAsn1FreeDecoded(pDec, pNonEncryptedOctetString,
  1095. OctetStringType_PDU);
  1096. pNonEncryptedOctetString = NULL;
  1097. }
  1098. PkiAsn1FreeDecoded(pDec, pSafeCnts, SafeContents_PDU);
  1099. pSafeCnts = NULL;
  1100. if (pbDecrData)
  1101. {
  1102. SSFree(pbDecrData);
  1103. pbDecrData = NULL;
  1104. }
  1105. }
  1106. fRet = TRUE;
  1107. goto Ret;
  1108. SetPFXAlgIDError:
  1109. SetLastError(NTE_BAD_ALGID);
  1110. goto Ret;
  1111. SetPFXIntegrityError:
  1112. SetLastError(ERROR_INVALID_PASSWORD);
  1113. goto Ret;
  1114. SetPFXDecodeError:
  1115. SetLastError(CRYPT_E_BAD_ENCODE);
  1116. goto Ret;
  1117. SetPFXDecryptError:
  1118. SetLastError(NTE_FAIL);
  1119. goto Ret;
  1120. SetPfxAllocError:
  1121. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1122. goto Ret;
  1123. ErrorOut:
  1124. Ret:
  1125. // save any error conditions
  1126. dwErr = GetLastError();
  1127. PkiAsn1FreeDecoded(pDec, psPfx, PFX_PDU);
  1128. PkiAsn1FreeDecoded(pDec, pOctetString, OctetStringType_PDU);
  1129. PkiAsn1FreeDecoded(pDec, pAuthSafes, AuthenticatedSafes_PDU);
  1130. PkiAsn1FreeDecoded(pDec, pEncrData, EncryptedData_PDU);
  1131. PkiAsn1FreeDecoded(pDec, pPBEParameter, PBEParameter_PDU);
  1132. PkiAsn1FreeDecoded(pDec, pSafeCnts, SafeContents_PDU);
  1133. // DSIE: Bug 144526.
  1134. if (oid)
  1135. SSFree(oid);
  1136. if (pbDecrData)
  1137. SSFree(pbDecrData);
  1138. if (!fRet)
  1139. {
  1140. if (ppfx)
  1141. SSFree(ppfx);
  1142. ppfx = NULL;
  1143. }
  1144. // restore error conditions AFTER GetDecoder() calls, since TLS will clobber
  1145. SetLastError(dwErr);
  1146. return (HPFX)ppfx;
  1147. }
  1148. BOOL FPFXDumpSafeCntsToHPFX(SafeContents* pSafeCnts, HPFX hpfx)
  1149. {
  1150. PPFX_INFO ppfx = (PPFX_INFO)hpfx;
  1151. // sort and dump bags into correct areas
  1152. ObjectID oKeyBag, oCertBag, oShroudedKeyBag;
  1153. DWORD dw, iAttr, iAnys;
  1154. ZeroMemory(&oKeyBag, sizeof(ObjectID));
  1155. ZeroMemory(&oCertBag, sizeof(ObjectID));
  1156. ZeroMemory(&oShroudedKeyBag, sizeof(ObjectID));
  1157. if (!IPFX_Asn1ToObjectID( &szOID_PKCS_12_KEY_BAG, &oKeyBag))
  1158. return FALSE;
  1159. if (!IPFX_Asn1ToObjectID( &szOID_PKCS_12_CERT_BAG, &oCertBag))
  1160. return FALSE;
  1161. if (!IPFX_Asn1ToObjectID( &szOID_PKCS_12_SHROUDEDKEY_BAG, &oShroudedKeyBag))
  1162. return FALSE;
  1163. for (dw=0; dw<pSafeCnts->count; dw++)
  1164. {
  1165. SafeBag* pBag;
  1166. VOID *pv = NULL;
  1167. // new begin
  1168. // assign value to keys
  1169. if (NULL == (pBag = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1170. goto SetPfxAllocError;
  1171. CopyMemory(pBag, &pSafeCnts->value[dw], sizeof (SafeBag));
  1172. // obj id is static
  1173. // alloc content
  1174. if (NULL == (pBag->safeBagContent.value = (PBYTE)SSAlloc(pBag->safeBagContent.length) ))
  1175. goto SetPfxAllocError;
  1176. CopyMemory(pBag->safeBagContent.value, pSafeCnts->value[dw].safeBagContent.value, pBag->safeBagContent.length);
  1177. // alloc attributes
  1178. if (pBag->bit_mask & safeBagAttribs_present)
  1179. {
  1180. if (NULL == (pBag->safeBagAttribs.value = (Attribute*)SSAlloc(sizeof(Attribute) * pSafeCnts->value[dw].safeBagAttribs.count) ))
  1181. goto SetPfxAllocError;
  1182. for (iAttr=0; iAttr < pSafeCnts->value[dw].safeBagAttribs.count; iAttr++)
  1183. {
  1184. // copy static section of attribute
  1185. CopyMemory(&pBag->safeBagAttribs.value[iAttr], &pSafeCnts->value[dw].safeBagAttribs.value[iAttr], sizeof(Attribute));
  1186. // Alloc Attribute Anys
  1187. if (pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.count != 0)
  1188. {
  1189. if (NULL == (pBag->safeBagAttribs.value[iAttr].attributeValue.value = (Any*)SSAlloc(pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.count * sizeof(Any)) ))
  1190. goto SetPfxAllocError;
  1191. CopyMemory(pBag->safeBagAttribs.value[iAttr].attributeValue.value, pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.value, sizeof(Any));
  1192. for (iAnys=0; iAnys<pBag->safeBagAttribs.value[iAttr].attributeValue.count; iAnys++)
  1193. {
  1194. if (NULL == (pBag->safeBagAttribs.value[iAttr].attributeValue.value[iAnys].value = (PBYTE)SSAlloc(pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.value[iAnys].length) ))
  1195. goto SetPfxAllocError;
  1196. CopyMemory(pBag->safeBagAttribs.value[iAttr].attributeValue.value[iAnys].value, pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.value[iAnys].value, pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.value[iAnys].length);
  1197. }
  1198. }
  1199. else
  1200. {
  1201. pBag->safeBagAttribs.value[iAttr].attributeValue.value = NULL;
  1202. }
  1203. }
  1204. }
  1205. // new end
  1206. if (IPFX_EqualObjectIDs(&pSafeCnts->value[dw].safeBagType, &oKeyBag) )
  1207. {
  1208. // inc size
  1209. ppfx->cKeys++;
  1210. if (ppfx->rgKeys)
  1211. {
  1212. pv = ppfx->rgKeys;
  1213. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1214. ppfx->rgKeys = (void**)SSReAlloc(ppfx->rgKeys, ppfx->cKeys * sizeof(SafeBag*));
  1215. }
  1216. else
  1217. ppfx->rgKeys = (void**)SSAlloc(ppfx->cKeys * sizeof(SafeBag*));
  1218. if (ppfx->rgKeys == NULL)
  1219. {
  1220. if (pv != NULL)
  1221. {
  1222. SSFree(pv);
  1223. }
  1224. goto SetPfxAllocError;
  1225. }
  1226. // assign to keys
  1227. ppfx->rgKeys[ppfx->cKeys-1] = pBag;
  1228. }
  1229. else if (IPFX_EqualObjectIDs(&pSafeCnts->value[dw].safeBagType,
  1230. &oShroudedKeyBag) )
  1231. {
  1232. // inc size
  1233. ppfx->cShroudedKeys++;
  1234. if (ppfx->rgShroudedKeys)
  1235. {
  1236. pv = ppfx->rgShroudedKeys;
  1237. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1238. ppfx->rgShroudedKeys = (void**)SSReAlloc(ppfx->rgShroudedKeys, ppfx->cShroudedKeys * sizeof(SafeBag*));
  1239. }
  1240. else
  1241. ppfx->rgShroudedKeys = (void**)SSAlloc(ppfx->cShroudedKeys * sizeof(SafeBag*));
  1242. if (ppfx->rgShroudedKeys == NULL)
  1243. {
  1244. if (pv != NULL)
  1245. {
  1246. SSFree(pv);
  1247. }
  1248. goto SetPfxAllocError;
  1249. }
  1250. // assign to keys
  1251. ppfx->rgShroudedKeys[ppfx->cShroudedKeys-1] = pBag;
  1252. }
  1253. else if (IPFX_EqualObjectIDs(&pSafeCnts->value[dw].safeBagType,
  1254. &oCertBag) )
  1255. {
  1256. // inc size
  1257. ppfx->cCertcrls++;
  1258. if (ppfx->rgCertcrls)
  1259. {
  1260. pv = ppfx->rgCertcrls;
  1261. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1262. ppfx->rgCertcrls = (void**)SSReAlloc(ppfx->rgCertcrls, ppfx->cCertcrls * sizeof(SafeBag*));
  1263. }
  1264. else
  1265. ppfx->rgCertcrls = (void**)SSAlloc(ppfx->cCertcrls * sizeof(SafeBag*));
  1266. if (ppfx->rgCertcrls == NULL)
  1267. {
  1268. if (pv != NULL)
  1269. {
  1270. SSFree(pv);
  1271. }
  1272. goto SetPfxAllocError;
  1273. }
  1274. // assign to certs/crls
  1275. ppfx->rgCertcrls[ppfx->cCertcrls-1] = pBag;
  1276. }
  1277. else
  1278. {
  1279. // inc size
  1280. ppfx->cSecrets++;
  1281. if (ppfx->rgSecrets)
  1282. {
  1283. pv = ppfx->rgSecrets;
  1284. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1285. ppfx->rgSecrets = (void**)SSReAlloc(ppfx->rgSecrets, ppfx->cSecrets * sizeof(SafeBag*));
  1286. }
  1287. else
  1288. ppfx->rgSecrets = (void**)SSAlloc(ppfx->cSecrets * sizeof(SafeBag*));
  1289. if (ppfx->rgSecrets == NULL)
  1290. {
  1291. if (pv != NULL)
  1292. {
  1293. SSFree(pv);
  1294. }
  1295. goto SetPfxAllocError;
  1296. }
  1297. // assign to safebag
  1298. ppfx->rgSecrets[ppfx->cSecrets-1] = pBag;
  1299. }
  1300. }
  1301. return TRUE;
  1302. SetPfxAllocError:
  1303. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1304. return FALSE;
  1305. }
  1306. BOOL CopyASNtoCryptSafeBag(
  1307. SAFE_BAG* pCryptBag,
  1308. SafeBag* pAsnBag)
  1309. {
  1310. DWORD iAttrs, iAttr;
  1311. // ensure target is zeroed
  1312. ZeroMemory(pCryptBag, sizeof(SAFE_BAG));
  1313. if (!IPFX_Asn1FromObjectID( &pAsnBag->safeBagType, &pCryptBag->pszBagTypeOID))
  1314. return FALSE;
  1315. // copy bag contents
  1316. pCryptBag->BagContents.cbData = pAsnBag->safeBagContent.length;
  1317. if (NULL == (pCryptBag->BagContents.pbData = (PBYTE)SSAlloc(pCryptBag->BagContents.cbData) ))
  1318. goto SetPfxAllocError;
  1319. CopyMemory(pCryptBag->BagContents.pbData, pAsnBag->safeBagContent.value, pCryptBag->BagContents.cbData);
  1320. pCryptBag->Attributes.cAttr = pAsnBag->safeBagAttribs.count;
  1321. if (NULL == (pCryptBag->Attributes.rgAttr = (CRYPT_ATTRIBUTE*)SSAlloc(pCryptBag->Attributes.cAttr * sizeof(CRYPT_ATTRIBUTE)) ))
  1322. goto SetPfxAllocError;
  1323. // sizeof attribute data
  1324. for (iAttrs=0; iAttrs<pAsnBag->safeBagAttribs.count; iAttrs++)
  1325. {
  1326. // pAsnBag->safeBagAttribs.value === attribute struct
  1327. if (!IPFX_Asn1FromObjectID( &pAsnBag->safeBagAttribs.value[iAttrs].attributeType, &pCryptBag->Attributes.rgAttr[iAttrs].pszObjId))
  1328. continue;
  1329. pCryptBag->Attributes.rgAttr[iAttrs].cValue = pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count;
  1330. if (NULL == (pCryptBag->Attributes.rgAttr[iAttrs].rgValue = (CRYPT_ATTR_BLOB*)SSAlloc(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count * sizeof(CRYPT_ATTR_BLOB)) ))
  1331. goto SetPfxAllocError;
  1332. for (iAttr=0; iAttr<pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count; iAttr++)
  1333. {
  1334. // alloc and copy: for every attribute in attrs
  1335. pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData = pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length;
  1336. if (NULL == (pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].pbData = (PBYTE)SSAlloc(pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData) ))
  1337. goto SetPfxAllocError;
  1338. CopyMemory(pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].pbData, pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].value, pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData);
  1339. }
  1340. }
  1341. return TRUE;
  1342. SetPfxAllocError:
  1343. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1344. return FALSE;
  1345. }
  1346. BOOL CopyCrypttoASNSafeBag(
  1347. SAFE_BAG* pCryptBag,
  1348. SafeBag* pAsnBag)
  1349. {
  1350. DWORD iAttrs, iAttr;
  1351. // ensure target is zeroed
  1352. ZeroMemory(pAsnBag, sizeof(SafeBag));
  1353. if (!IPFX_Asn1ToObjectID( pCryptBag->pszBagTypeOID, &pAsnBag->safeBagType))
  1354. return FALSE;
  1355. pAsnBag->safeBagContent.length = pCryptBag->BagContents.cbData;
  1356. if (NULL == (pAsnBag->safeBagContent.value = (PBYTE)SSAlloc(pAsnBag->safeBagContent.length) ))
  1357. goto SetPfxAllocError;
  1358. CopyMemory(pAsnBag->safeBagContent.value, pCryptBag->BagContents.pbData, pAsnBag->safeBagContent.length);
  1359. pAsnBag->safeBagAttribs.count = pCryptBag->Attributes.cAttr;
  1360. if (NULL == (pAsnBag->safeBagAttribs.value = (Attribute*) SSAlloc(pAsnBag->safeBagAttribs.count * sizeof(Attribute)) ))
  1361. goto SetPfxAllocError;
  1362. //
  1363. // always set the present bit for backwards compatibility
  1364. //
  1365. pAsnBag->bit_mask = safeBagAttribs_present;
  1366. for (iAttrs=0; iAttrs<pCryptBag->Attributes.cAttr; iAttrs++)
  1367. {
  1368. //pAsnBag->bit_mask = safeBagAttribs_present;
  1369. if (!IPFX_Asn1ToObjectID( pCryptBag->Attributes.rgAttr[iAttrs].pszObjId, &pAsnBag->safeBagAttribs.value[iAttrs].attributeType))
  1370. continue;
  1371. pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count = pCryptBag->Attributes.rgAttr[iAttrs].cValue;
  1372. if (NULL == (pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value = (Any*)SSAlloc(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count * sizeof(Any)) ))
  1373. goto SetPfxAllocError;
  1374. for (iAttr=0; iAttr<pCryptBag->Attributes.rgAttr[iAttrs].cValue; iAttr++)
  1375. {
  1376. // for every attribute in attrs
  1377. pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length = pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData;
  1378. if (NULL == (pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].value = (PBYTE)SSAlloc(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length) ))
  1379. goto SetPfxAllocError;
  1380. CopyMemory(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].value, pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].pbData, pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length);
  1381. }
  1382. }
  1383. return TRUE;
  1384. SetPfxAllocError:
  1385. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1386. return FALSE;
  1387. }
  1388. // new entry points for loading up the HPFX
  1389. BOOL PfxGetKeysAndCerts(
  1390. HPFX hPfx,
  1391. SAFE_CONTENTS* pContents
  1392. )
  1393. {
  1394. PFX_INFO* pPfx = (PFX_INFO*)hPfx;
  1395. SafeBag* pAsnBag;
  1396. SAFE_BAG* pCryptBag;
  1397. DWORD iTotal, iBag;
  1398. DWORD cSafeBags;
  1399. pContents->cSafeBags = 0;
  1400. cSafeBags = pPfx->cKeys + pPfx->cCertcrls + pPfx->cShroudedKeys;
  1401. if (NULL == (pContents->pSafeBags = (SAFE_BAG*)SSAlloc(cSafeBags * sizeof(SAFE_BAG)) )) // make an array of safe bag *s
  1402. goto SetPfxAllocError;
  1403. pContents->cSafeBags = cSafeBags;
  1404. for (iBag=0, iTotal=0; iBag<pPfx->cKeys; iBag++, iTotal++)
  1405. {
  1406. pCryptBag = &pContents->pSafeBags[iTotal];
  1407. pAsnBag = (SafeBag*)pPfx->rgKeys[iBag];
  1408. if (!CopyASNtoCryptSafeBag(pCryptBag, pAsnBag))
  1409. continue;
  1410. }
  1411. iTotal = iBag;
  1412. for (iBag=0; iBag<pPfx->cShroudedKeys; iBag++, iTotal++)
  1413. {
  1414. pCryptBag = &pContents->pSafeBags[iTotal];
  1415. pAsnBag = (SafeBag*)pPfx->rgShroudedKeys[iBag];
  1416. if (!CopyASNtoCryptSafeBag(pCryptBag, pAsnBag))
  1417. continue;
  1418. }
  1419. for (iBag=0; iBag<pPfx->cCertcrls; iBag++, iTotal++)
  1420. {
  1421. pCryptBag = &pContents->pSafeBags[iTotal];
  1422. pAsnBag = (SafeBag*)pPfx->rgCertcrls[iBag];
  1423. if (!CopyASNtoCryptSafeBag(pCryptBag, pAsnBag))
  1424. continue;
  1425. }
  1426. return TRUE;
  1427. SetPfxAllocError:
  1428. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1429. return FALSE;
  1430. }
  1431. BOOL PfxAddSafeBags(
  1432. HPFX hPfx,
  1433. SAFE_BAG* pSafeBags,
  1434. DWORD cSafeBags
  1435. )
  1436. {
  1437. PFX_INFO* pPfx = (PFX_INFO*)hPfx;
  1438. DWORD i;
  1439. for (i=0; i<cSafeBags; i++)
  1440. {
  1441. VOID *pv = NULL;
  1442. if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_KEY_BAG))
  1443. {
  1444. pPfx->cKeys++;
  1445. if (pPfx->rgKeys)
  1446. {
  1447. pv = pPfx->rgKeys;
  1448. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1449. pPfx->rgKeys = (void**)SSReAlloc(pPfx->rgKeys, pPfx->cKeys*sizeof(SafeBag*));
  1450. }
  1451. else
  1452. pPfx->rgKeys = (void**)SSAlloc(pPfx->cKeys*sizeof(SafeBag*));
  1453. if (pPfx->rgKeys == NULL)
  1454. {
  1455. if (pv != NULL)
  1456. {
  1457. SSFree(pv);
  1458. }
  1459. goto SetPfxAllocError;
  1460. }
  1461. if (NULL == (pPfx->rgKeys[pPfx->cKeys-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1462. goto SetPfxAllocError;
  1463. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgKeys[pPfx->cKeys-1]))
  1464. continue;
  1465. }
  1466. else if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_SHROUDEDKEY_BAG))
  1467. {
  1468. pPfx->cShroudedKeys++;
  1469. if (pPfx->rgShroudedKeys)
  1470. {
  1471. pv = pPfx->rgShroudedKeys;
  1472. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1473. pPfx->rgShroudedKeys = (void**)SSReAlloc(pPfx->rgShroudedKeys, pPfx->cShroudedKeys*sizeof(SafeBag*));
  1474. }
  1475. else
  1476. pPfx->rgShroudedKeys = (void**)SSAlloc(pPfx->cShroudedKeys*sizeof(SafeBag*));
  1477. if (pPfx->rgShroudedKeys == NULL)
  1478. {
  1479. if (pv != NULL)
  1480. {
  1481. SSFree(pv);
  1482. }
  1483. goto SetPfxAllocError;
  1484. }
  1485. if (NULL == (pPfx->rgShroudedKeys[pPfx->cShroudedKeys-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1486. goto SetPfxAllocError;
  1487. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgShroudedKeys[pPfx->cShroudedKeys-1]))
  1488. continue;
  1489. }
  1490. else if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_CERT_BAG))
  1491. {
  1492. pPfx->cCertcrls++;
  1493. if (pPfx->rgCertcrls)
  1494. {
  1495. pv = pPfx->rgCertcrls;
  1496. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1497. pPfx->rgCertcrls = (void**)SSReAlloc(pPfx->rgCertcrls, pPfx->cCertcrls*sizeof(SafeBag*));
  1498. }
  1499. else
  1500. pPfx->rgCertcrls = (void**)SSAlloc(pPfx->cCertcrls*sizeof(SafeBag*));
  1501. if (pPfx->rgCertcrls == NULL)
  1502. {
  1503. if (pv != NULL)
  1504. {
  1505. SSFree(pv);
  1506. }
  1507. goto SetPfxAllocError;
  1508. }
  1509. if (NULL == (pPfx->rgCertcrls[pPfx->cCertcrls-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1510. goto SetPfxAllocError;
  1511. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgCertcrls[pPfx->cCertcrls-1]))
  1512. continue;
  1513. }
  1514. else if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_SECRET_BAG))
  1515. {
  1516. pPfx->cSecrets++;
  1517. if (pPfx->rgSecrets)
  1518. {
  1519. pv = pPfx->rgSecrets;
  1520. #pragma prefast(suppress:308, "the pointer was saved above (PREfast bug 506)")
  1521. pPfx->rgSecrets = (void**)SSReAlloc(pPfx->rgSecrets, pPfx->cSecrets*sizeof(SafeBag*));
  1522. }
  1523. else
  1524. pPfx->rgSecrets = (void**)SSAlloc(pPfx->cSecrets*sizeof(SafeBag*));
  1525. if (pPfx->rgSecrets == NULL)
  1526. {
  1527. if (pv != NULL)
  1528. {
  1529. SSFree(pv);
  1530. }
  1531. goto SetPfxAllocError;
  1532. }
  1533. if (NULL == (pPfx->rgSecrets[pPfx->cSecrets-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1534. goto SetPfxAllocError;
  1535. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgSecrets[pPfx->cSecrets-1]))
  1536. continue;
  1537. }
  1538. else
  1539. {
  1540. #if DBG
  1541. OutputDebugString(pSafeBags[i].pszBagTypeOID);
  1542. #endif
  1543. continue;
  1544. }
  1545. }
  1546. return TRUE;
  1547. SetPfxAllocError:
  1548. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1549. return FALSE;
  1550. }
  1551. BOOL
  1552. PFXAPI
  1553. IsRealPFXBlob(CRYPT_DATA_BLOB* pPFX)
  1554. {
  1555. PFX *psPfx = NULL;
  1556. ASN1decoding_t pDec = GetDecoder();
  1557. // Crack the PFX blob
  1558. if (0 == PkiAsn1Decode(
  1559. pDec,
  1560. (void **)&psPfx,
  1561. PFX_PDU,
  1562. pPFX->pbData,
  1563. pPFX->cbData
  1564. ))
  1565. {
  1566. PkiAsn1FreeDecoded(pDec, psPfx, PFX_PDU);
  1567. return TRUE;
  1568. }
  1569. return FALSE;
  1570. }