Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1869 lines
53 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 "shacomm.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]; MAKEZERO(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. // new begin
  1167. // assign value to keys
  1168. if (NULL == (pBag = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1169. goto SetPfxAllocError;
  1170. CopyMemory(pBag, &pSafeCnts->value[dw], sizeof (SafeBag));
  1171. // obj id is static
  1172. // alloc content
  1173. if (NULL == (pBag->safeBagContent.value = (PBYTE)SSAlloc(pBag->safeBagContent.length) ))
  1174. goto SetPfxAllocError;
  1175. CopyMemory(pBag->safeBagContent.value, pSafeCnts->value[dw].safeBagContent.value, pBag->safeBagContent.length);
  1176. // alloc attributes
  1177. if (pBag->bit_mask & safeBagAttribs_present)
  1178. {
  1179. if (NULL == (pBag->safeBagAttribs.value = (Attribute*)SSAlloc(sizeof(Attribute) * pSafeCnts->value[dw].safeBagAttribs.count) ))
  1180. goto SetPfxAllocError;
  1181. for (iAttr=0; iAttr < pSafeCnts->value[dw].safeBagAttribs.count; iAttr++)
  1182. {
  1183. // copy static section of attribute
  1184. CopyMemory(&pBag->safeBagAttribs.value[iAttr], &pSafeCnts->value[dw].safeBagAttribs.value[iAttr], sizeof(Attribute));
  1185. // Alloc Attribute Anys
  1186. if (pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.count != 0)
  1187. {
  1188. if (NULL == (pBag->safeBagAttribs.value[iAttr].attributeValue.value = (Any*)SSAlloc(pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.count * sizeof(Any)) ))
  1189. goto SetPfxAllocError;
  1190. CopyMemory(pBag->safeBagAttribs.value[iAttr].attributeValue.value, pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.value, sizeof(Any));
  1191. for (iAnys=0; iAnys<pBag->safeBagAttribs.value[iAttr].attributeValue.count; iAnys++)
  1192. {
  1193. if (NULL == (pBag->safeBagAttribs.value[iAttr].attributeValue.value[iAnys].value = (PBYTE)SSAlloc(pSafeCnts->value[dw].safeBagAttribs.value[iAttr].attributeValue.value[iAnys].length) ))
  1194. goto SetPfxAllocError;
  1195. 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);
  1196. }
  1197. }
  1198. else
  1199. {
  1200. pBag->safeBagAttribs.value[iAttr].attributeValue.value = NULL;
  1201. }
  1202. }
  1203. }
  1204. // new end
  1205. if (IPFX_EqualObjectIDs(&pSafeCnts->value[dw].safeBagType, &oKeyBag) )
  1206. {
  1207. // inc size
  1208. ppfx->cKeys++;
  1209. if (ppfx->rgKeys)
  1210. ppfx->rgKeys = (void**)SSReAlloc(ppfx->rgKeys, ppfx->cKeys * sizeof(SafeBag*));
  1211. else
  1212. ppfx->rgKeys = (void**)SSAlloc(ppfx->cKeys * sizeof(SafeBag*));
  1213. if (ppfx->rgKeys == NULL)
  1214. goto SetPfxAllocError;
  1215. // assign to keys
  1216. ppfx->rgKeys[ppfx->cKeys-1] = pBag;
  1217. }
  1218. else if (IPFX_EqualObjectIDs(&pSafeCnts->value[dw].safeBagType,
  1219. &oShroudedKeyBag) )
  1220. {
  1221. // inc size
  1222. ppfx->cShroudedKeys++;
  1223. if (ppfx->rgShroudedKeys)
  1224. ppfx->rgShroudedKeys = (void**)SSReAlloc(ppfx->rgShroudedKeys, ppfx->cShroudedKeys * sizeof(SafeBag*));
  1225. else
  1226. ppfx->rgShroudedKeys = (void**)SSAlloc(ppfx->cShroudedKeys * sizeof(SafeBag*));
  1227. if (ppfx->rgShroudedKeys == NULL)
  1228. goto SetPfxAllocError;
  1229. // assign to keys
  1230. ppfx->rgShroudedKeys[ppfx->cShroudedKeys-1] = pBag;
  1231. }
  1232. else if (IPFX_EqualObjectIDs(&pSafeCnts->value[dw].safeBagType,
  1233. &oCertBag) )
  1234. {
  1235. // inc size
  1236. ppfx->cCertcrls++;
  1237. if (ppfx->rgCertcrls)
  1238. ppfx->rgCertcrls = (void**)SSReAlloc(ppfx->rgCertcrls, ppfx->cCertcrls * sizeof(SafeBag*));
  1239. else
  1240. ppfx->rgCertcrls = (void**)SSAlloc(ppfx->cCertcrls * sizeof(SafeBag*));
  1241. if (ppfx->rgCertcrls == NULL)
  1242. goto SetPfxAllocError;
  1243. // assign to certs/crls
  1244. ppfx->rgCertcrls[ppfx->cCertcrls-1] = pBag;
  1245. }
  1246. else
  1247. {
  1248. // inc size
  1249. ppfx->cSecrets++;
  1250. if (ppfx->rgSecrets)
  1251. ppfx->rgSecrets = (void**)SSReAlloc(ppfx->rgSecrets, ppfx->cSecrets * sizeof(SafeBag*));
  1252. else
  1253. ppfx->rgSecrets = (void**)SSAlloc(ppfx->cSecrets * sizeof(SafeBag*));
  1254. if (ppfx->rgSecrets == NULL)
  1255. goto SetPfxAllocError;
  1256. // assign to safebag
  1257. ppfx->rgSecrets[ppfx->cSecrets-1] = pBag;
  1258. }
  1259. }
  1260. return TRUE;
  1261. SetPfxAllocError:
  1262. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1263. return FALSE;
  1264. }
  1265. BOOL CopyASNtoCryptSafeBag(
  1266. SAFE_BAG* pCryptBag,
  1267. SafeBag* pAsnBag)
  1268. {
  1269. DWORD iAttrs, iAttr;
  1270. // ensure target is zeroed
  1271. ZeroMemory(pCryptBag, sizeof(SAFE_BAG));
  1272. if (!IPFX_Asn1FromObjectID( &pAsnBag->safeBagType, &pCryptBag->pszBagTypeOID))
  1273. return FALSE;
  1274. // copy bag contents
  1275. pCryptBag->BagContents.cbData = pAsnBag->safeBagContent.length;
  1276. if (NULL == (pCryptBag->BagContents.pbData = (PBYTE)SSAlloc(pCryptBag->BagContents.cbData) ))
  1277. goto SetPfxAllocError;
  1278. CopyMemory(pCryptBag->BagContents.pbData, pAsnBag->safeBagContent.value, pCryptBag->BagContents.cbData);
  1279. pCryptBag->Attributes.cAttr = pAsnBag->safeBagAttribs.count;
  1280. if (NULL == (pCryptBag->Attributes.rgAttr = (CRYPT_ATTRIBUTE*)SSAlloc(pCryptBag->Attributes.cAttr * sizeof(CRYPT_ATTRIBUTE)) ))
  1281. goto SetPfxAllocError;
  1282. // sizeof attribute data
  1283. for (iAttrs=0; iAttrs<pAsnBag->safeBagAttribs.count; iAttrs++)
  1284. {
  1285. // pAsnBag->safeBagAttribs.value === attribute struct
  1286. if (!IPFX_Asn1FromObjectID( &pAsnBag->safeBagAttribs.value[iAttrs].attributeType, &pCryptBag->Attributes.rgAttr[iAttrs].pszObjId))
  1287. continue;
  1288. pCryptBag->Attributes.rgAttr[iAttrs].cValue = pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count;
  1289. if (NULL == (pCryptBag->Attributes.rgAttr[iAttrs].rgValue = (CRYPT_ATTR_BLOB*)SSAlloc(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count * sizeof(CRYPT_ATTR_BLOB)) ))
  1290. goto SetPfxAllocError;
  1291. for (iAttr=0; iAttr<pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count; iAttr++)
  1292. {
  1293. // alloc and copy: for every attribute in attrs
  1294. pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData = pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length;
  1295. if (NULL == (pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].pbData = (PBYTE)SSAlloc(pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData) ))
  1296. goto SetPfxAllocError;
  1297. CopyMemory(pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].pbData, pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].value, pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData);
  1298. }
  1299. }
  1300. return TRUE;
  1301. SetPfxAllocError:
  1302. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1303. return FALSE;
  1304. }
  1305. BOOL CopyCrypttoASNSafeBag(
  1306. SAFE_BAG* pCryptBag,
  1307. SafeBag* pAsnBag)
  1308. {
  1309. DWORD iAttrs, iAttr;
  1310. // ensure target is zeroed
  1311. ZeroMemory(pAsnBag, sizeof(SafeBag));
  1312. if (!IPFX_Asn1ToObjectID( pCryptBag->pszBagTypeOID, &pAsnBag->safeBagType))
  1313. return FALSE;
  1314. pAsnBag->safeBagContent.length = pCryptBag->BagContents.cbData;
  1315. if (NULL == (pAsnBag->safeBagContent.value = (PBYTE)SSAlloc(pAsnBag->safeBagContent.length) ))
  1316. goto SetPfxAllocError;
  1317. CopyMemory(pAsnBag->safeBagContent.value, pCryptBag->BagContents.pbData, pAsnBag->safeBagContent.length);
  1318. pAsnBag->safeBagAttribs.count = pCryptBag->Attributes.cAttr;
  1319. if (NULL == (pAsnBag->safeBagAttribs.value = (Attribute*) SSAlloc(pAsnBag->safeBagAttribs.count * sizeof(Attribute)) ))
  1320. goto SetPfxAllocError;
  1321. //
  1322. // always set the present bit for backwards compatibility
  1323. //
  1324. pAsnBag->bit_mask = safeBagAttribs_present;
  1325. for (iAttrs=0; iAttrs<pCryptBag->Attributes.cAttr; iAttrs++)
  1326. {
  1327. //pAsnBag->bit_mask = safeBagAttribs_present;
  1328. if (!IPFX_Asn1ToObjectID( pCryptBag->Attributes.rgAttr[iAttrs].pszObjId, &pAsnBag->safeBagAttribs.value[iAttrs].attributeType))
  1329. continue;
  1330. pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count = pCryptBag->Attributes.rgAttr[iAttrs].cValue;
  1331. if (NULL == (pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value = (Any*)SSAlloc(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.count * sizeof(Any)) ))
  1332. goto SetPfxAllocError;
  1333. for (iAttr=0; iAttr<pCryptBag->Attributes.rgAttr[iAttrs].cValue; iAttr++)
  1334. {
  1335. // for every attribute in attrs
  1336. pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length = pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].cbData;
  1337. if (NULL == (pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].value = (PBYTE)SSAlloc(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length) ))
  1338. goto SetPfxAllocError;
  1339. CopyMemory(pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].value, pCryptBag->Attributes.rgAttr[iAttrs].rgValue[iAttr].pbData, pAsnBag->safeBagAttribs.value[iAttrs].attributeValue.value[iAttr].length);
  1340. }
  1341. }
  1342. return TRUE;
  1343. SetPfxAllocError:
  1344. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1345. return FALSE;
  1346. }
  1347. // new entry points for loading up the HPFX
  1348. BOOL PfxGetKeysAndCerts(
  1349. HPFX hPfx,
  1350. SAFE_CONTENTS* pContents
  1351. )
  1352. {
  1353. PFX_INFO* pPfx = (PFX_INFO*)hPfx;
  1354. SafeBag* pAsnBag;
  1355. SAFE_BAG* pCryptBag;
  1356. DWORD iTotal, iBag;
  1357. DWORD cSafeBags;
  1358. pContents->cSafeBags = 0;
  1359. cSafeBags = pPfx->cKeys + pPfx->cCertcrls + pPfx->cShroudedKeys;
  1360. if (NULL == (pContents->pSafeBags = (SAFE_BAG*)SSAlloc(cSafeBags * sizeof(SAFE_BAG)) )) // make an array of safe bag *s
  1361. goto SetPfxAllocError;
  1362. pContents->cSafeBags = cSafeBags;
  1363. for (iBag=0, iTotal=0; iBag<pPfx->cKeys; iBag++, iTotal++)
  1364. {
  1365. pCryptBag = &pContents->pSafeBags[iTotal];
  1366. pAsnBag = (SafeBag*)pPfx->rgKeys[iBag];
  1367. if (!CopyASNtoCryptSafeBag(pCryptBag, pAsnBag))
  1368. continue;
  1369. }
  1370. iTotal = iBag;
  1371. for (iBag=0; iBag<pPfx->cShroudedKeys; iBag++, iTotal++)
  1372. {
  1373. pCryptBag = &pContents->pSafeBags[iTotal];
  1374. pAsnBag = (SafeBag*)pPfx->rgShroudedKeys[iBag];
  1375. if (!CopyASNtoCryptSafeBag(pCryptBag, pAsnBag))
  1376. continue;
  1377. }
  1378. for (iBag=0; iBag<pPfx->cCertcrls; iBag++, iTotal++)
  1379. {
  1380. pCryptBag = &pContents->pSafeBags[iTotal];
  1381. pAsnBag = (SafeBag*)pPfx->rgCertcrls[iBag];
  1382. if (!CopyASNtoCryptSafeBag(pCryptBag, pAsnBag))
  1383. continue;
  1384. }
  1385. return TRUE;
  1386. SetPfxAllocError:
  1387. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1388. return FALSE;
  1389. }
  1390. BOOL PfxAddSafeBags(
  1391. HPFX hPfx,
  1392. SAFE_BAG* pSafeBags,
  1393. DWORD cSafeBags
  1394. )
  1395. {
  1396. PFX_INFO* pPfx = (PFX_INFO*)hPfx;
  1397. DWORD i;
  1398. for (i=0; i<cSafeBags; i++)
  1399. {
  1400. if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_KEY_BAG))
  1401. {
  1402. pPfx->cKeys++;
  1403. if (pPfx->rgKeys)
  1404. pPfx->rgKeys = (void**)SSReAlloc(pPfx->rgKeys, pPfx->cKeys*sizeof(SafeBag*));
  1405. else
  1406. pPfx->rgKeys = (void**)SSAlloc(pPfx->cKeys*sizeof(SafeBag*));
  1407. if (pPfx->rgKeys == NULL)
  1408. goto SetPfxAllocError;
  1409. if (NULL == (pPfx->rgKeys[pPfx->cKeys-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1410. goto SetPfxAllocError;
  1411. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgKeys[pPfx->cKeys-1]))
  1412. continue;
  1413. }
  1414. else if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_SHROUDEDKEY_BAG))
  1415. {
  1416. pPfx->cShroudedKeys++;
  1417. if (pPfx->rgShroudedKeys)
  1418. pPfx->rgShroudedKeys = (void**)SSReAlloc(pPfx->rgShroudedKeys, pPfx->cShroudedKeys*sizeof(SafeBag*));
  1419. else
  1420. pPfx->rgShroudedKeys = (void**)SSAlloc(pPfx->cShroudedKeys*sizeof(SafeBag*));
  1421. if (pPfx->rgShroudedKeys == NULL)
  1422. goto SetPfxAllocError;
  1423. if (NULL == (pPfx->rgShroudedKeys[pPfx->cShroudedKeys-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1424. goto SetPfxAllocError;
  1425. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgShroudedKeys[pPfx->cShroudedKeys-1]))
  1426. continue;
  1427. }
  1428. else if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_CERT_BAG))
  1429. {
  1430. pPfx->cCertcrls++;
  1431. if (pPfx->rgCertcrls)
  1432. pPfx->rgCertcrls = (void**)SSReAlloc(pPfx->rgCertcrls, pPfx->cCertcrls*sizeof(SafeBag*));
  1433. else
  1434. pPfx->rgCertcrls = (void**)SSAlloc(pPfx->cCertcrls*sizeof(SafeBag*));
  1435. if (pPfx->rgCertcrls == NULL)
  1436. goto SetPfxAllocError;
  1437. if (NULL == (pPfx->rgCertcrls[pPfx->cCertcrls-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1438. goto SetPfxAllocError;
  1439. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgCertcrls[pPfx->cCertcrls-1]))
  1440. continue;
  1441. }
  1442. else if (0 == strcmp(pSafeBags[i].pszBagTypeOID, szOID_PKCS_12_SECRET_BAG))
  1443. {
  1444. pPfx->cSecrets++;
  1445. if (pPfx->rgSecrets)
  1446. pPfx->rgSecrets = (void**)SSReAlloc(pPfx->rgSecrets, pPfx->cSecrets*sizeof(SafeBag*));
  1447. else
  1448. pPfx->rgSecrets = (void**)SSAlloc(pPfx->cSecrets*sizeof(SafeBag*));
  1449. if (pPfx->rgSecrets == NULL)
  1450. goto SetPfxAllocError;
  1451. if (NULL == (pPfx->rgSecrets[pPfx->cSecrets-1] = (SafeBag*)SSAlloc(sizeof(SafeBag)) ))
  1452. goto SetPfxAllocError;
  1453. if (!CopyCrypttoASNSafeBag(&pSafeBags[i], (SafeBag*)pPfx->rgSecrets[pPfx->cSecrets-1]))
  1454. continue;
  1455. }
  1456. else
  1457. {
  1458. #if DBG
  1459. OutputDebugString(pSafeBags[i].pszBagTypeOID);
  1460. #endif
  1461. continue;
  1462. }
  1463. }
  1464. return TRUE;
  1465. SetPfxAllocError:
  1466. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1467. return FALSE;
  1468. }
  1469. BOOL
  1470. PFXAPI
  1471. IsRealPFXBlob(CRYPT_DATA_BLOB* pPFX)
  1472. {
  1473. PFX *psPfx = NULL;
  1474. ASN1decoding_t pDec = GetDecoder();
  1475. // Crack the PFX blob
  1476. if (0 == PkiAsn1Decode(
  1477. pDec,
  1478. (void **)&psPfx,
  1479. PFX_PDU,
  1480. pPFX->pbData,
  1481. pPFX->cbData
  1482. ))
  1483. {
  1484. PkiAsn1FreeDecoded(pDec, psPfx, PFX_PDU);
  1485. return TRUE;
  1486. }
  1487. return FALSE;
  1488. }