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();
	}
}
Example #3
0
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;
}