/* top-level PKCS12 PFX decoder */ void P12Coder::decode( CFDataRef cdpfx) { SecNssCoder localCdr; NSS_P12_DecodedPFX pfx; p12DecodeLog("decode"); memset(&pfx, 0, sizeof(pfx)); const CSSM_DATA rawBlob = {int_cast<CFIndex, CSSM_SIZE>(CFDataGetLength(cdpfx)), (uint8 *)CFDataGetBytePtr(cdpfx)}; if(localCdr.decodeItem(rawBlob, NSS_P12_DecodedPFXTemplate, &pfx)) { p12ErrorLog("Error on top-level decode of NSS_P12_DecodedPFX\n"); P12_THROW_DECODE; } NSS_P7_DecodedContentInfo &dci = pfx.authSafe; if(dci.type != CT_Data) { /* no other types supported yet */ p12ErrorLog("bad top-level contentType\n"); P12_THROW_DECODE; } mIntegrityMode = kSecPkcs12ModePassword; if(pfx.macData == NULL) { /* not present is an error in kSecPkcs12ModePassword */ p12ErrorLog("no MAC in PFX\n"); P12_THROW_DECODE; } macParse(*pfx.macData, localCdr); const CSSM_DATA *macPhrase = getMacPassPhrase(); const CSSM_KEY *macPassKey = getMacPassKey(); if((macPhrase == NULL) && (macPassKey == NULL)) { p12ErrorLog("no passphrase set\n"); CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_PASSPHRASE); } CSSM_RETURN crtn = p12VerifyMac(pfx, mCspHand, macPhrase, macPassKey, localCdr); if(crtn) { p12LogCssmError("p12VerifyMac", crtn); CssmError::throwMe(errSecPkcs12VerifyFailure); } authSafeParse(*dci.content.data, localCdr); /* * On success, if we have a keychain, store certs and CRLs there */ if(mKeychain != NULL) { storeDecodeResults(); } }
p12_error p12decode(pkcs12_context * context, CFDataRef cdpfx) { int err = p12_decodeErr; NSS_P12_DecodedPFX pfx; memset(&pfx, 0, sizeof(pfx)); SecAsn1Item raw_blob = { CFDataGetLength(cdpfx), (void*)CFDataGetBytePtr(cdpfx) }; require_noerr_quiet(decode_item(context, &raw_blob, NSS_P12_DecodedPFXTemplate, &pfx), out); NSS_P7_DecodedContentInfo *dci = &pfx.authSafe; /* only support CT_Data at top level (password based integrity mode) */ require(dci->type == CT_Data, out); require(pfx.macData, out); require_noerr_action_quiet(p12VerifyMac(context, &pfx), out, err = p12_passwordErr); require_noerr_quiet(authSafeParse(context, dci->content.data), out); return errSecSuccess; out: return err; }