static int p12Parse( const CSSM_DATA &rawBlob, P12ParseInfo &pinfo, unsigned depth) // print indent depth { NSS_P12_DecodedPFX pfx; memset(&pfx, 0, sizeof(pfx)); if(pinfo.mCoder.decodeItem(rawBlob, NSS_P12_DecodedPFXTemplate, &pfx)) { printf("***Error on top-level decode of NSS_P12_DecodedPFX\n"); return 1; } doIndent(depth); printf("version = %u\n", (unsigned)dataToInt(pfx.version)); NSS_P7_DecodedContentInfo &dci = pfx.authSafe; doIndent(depth); printf("contentType = %s\n", oidStr(dci.contentType, pinfo.mParser)); doIndent(depth); printf("type = %s\n", p7ContentInfoTypeStr(dci.type)); int rtn = 0; if(nssCompareCssmData(&dci.contentType, &CSSMOID_PKCS7_Data)) { doIndent(depth); printf("AuthenticatedSafe Length %u {\n", (unsigned)dci.content.data->Length); rtn = authSafeParse(*dci.content.data, pinfo, depth+3); doIndent(depth); printf("}\n"); } else { printf("Not parsing any other content type today.\n"); } if(pfx.macData) { doIndent(depth); printf("Mac Data {\n"); p12MacParse(*pfx.macData, pinfo, depth+3); doIndent(depth); printf("}\n"); if(pinfo.mPwd.Data == NULL) { doIndent(depth); printf("=== MAC not verified (no passphrase)===\n"); } else { CSSM_RETURN crtn = p12VerifyMac_app(pfx, pinfo.mCspHand, pinfo.mPwd, pinfo.mCoder); doIndent(depth); if(crtn) { cssmPerror("p12VerifyMac", crtn); doIndent(depth); printf("***MAC verify failure.\n"); } else { printf("MAC verifies OK.\n"); } } } return 0; }
/* 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; }