Example #1
0
/*
 * ShroudedKeyBag parser w/decrypt
 */
static int shroudedKeyBagParse(pkcs12_context * context, const NSS_P12_SafeBag *safeBag)
{
	p12DecodeLog("Found shrouded key bag");

	const NSS_P12_ShroudedKeyBag *keyBag = safeBag->bagValue.shroudedKeyBag;
    SecAsn1Item ptext = {0, NULL};
    require_noerr_quiet(p12Decrypt(context, &keyBag->algorithm, 
        &keyBag->encryptedData, &ptext), out);

    /* Decode PKCS#8 formatted private key */
    NSS_PrivateKeyInfo pki;
    memset(&pki, 0, sizeof(pki));
	require_noerr(decode_item(context, &ptext, kSecAsn1PrivateKeyInfoTemplate,
			&pki), out);
    DERItem algorithm = { pki.algorithm.algorithm.Data, pki.algorithm.algorithm.Length };
    require(DEROidCompare(&oidRsa, &algorithm), out);

    CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, pki.privateKey.Data, pki.privateKey.Length);

    require_noerr(emit_item(context, safeBag->bagAttrs, CFSTR("key"), keyData), out);
    CFRelease(keyData);
    
    return 0;
out:
    return -1;
}
Example #2
0
/*
 * Parse a ContentInfo in the context of (i.e., as an element of)
 * an AuthenticatedSafe.
 */
static int authSafeElementParse(pkcs12_context * context, const NSS_P7_DecodedContentInfo *info)
{
	p12DecodeLog("authSafeElementParse");
	switch(info->type) {
		case CT_Data:
			/* unencrypted SafeContents */
			require_noerr(safeContentsParse(context, info->content.data), out);
			break;
			
		case CT_EncryptedData:
		{
			/* 
			 * Decrypt contents to get a SafeContents and
			 * then parse that.
			 */
			SecAsn1Item ptext = {0, NULL};
            NSS_P7_EncryptedData *edata = info->content.encryptData;
            require_noerr_quiet(p12Decrypt(context, &edata->contentInfo.encrAlg, 
                &edata->contentInfo.encrContent, &ptext), out);
			require_noerr(safeContentsParse(context, &ptext), out);
			break;
		}	
		default:
            break;
	}
    return 0;
out:
    return -1;
}
/*
 * Decrypt the contents of a NSS_P7_EncryptedData
 */
void P12Coder::encryptedDataDecrypt(
	const NSS_P7_EncryptedData &edata,
	SecNssCoder &localCdr,
	NSS_P12_PBE_Params *pbep,	// preparsed
	CSSM_DATA &ptext)			// result goes here in localCdr space
{
	p12DecodeLog("encryptedDataDecrypt");

	/* see if we can grok the encr alg */
	CSSM_ALGORITHMS		keyAlg;			// e.g., CSSM_ALGID_DES
	CSSM_ALGORITHMS		encrAlg;		// e.g., CSSM_ALGID_3DES_3KEY_EDE
	CSSM_ALGORITHMS		pbeHashAlg;		// SHA1 or MD5
	uint32				keySizeInBits;
	uint32				blockSizeInBytes;	// for IV, optional
	CSSM_PADDING		padding;		// CSSM_PADDING_PKCS7, etc.
	CSSM_ENCRYPT_MODE	mode;			// CSSM_ALGMODE_CBCPadIV8, etc.
	PKCS_Which			pkcs;
	
	bool found = pkcsOidToParams(&edata.contentInfo.encrAlg.algorithm,
		keyAlg, encrAlg, pbeHashAlg, keySizeInBits, blockSizeInBytes,
		padding, mode, pkcs);
	if(!found || (pkcs != PW_PKCS12)) {
		p12ErrorLog("EncryptedData encrAlg not understood\n");
		CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
	}
		
	uint32 iterCount;
	if(!p12DataToInt(pbep->iterations, iterCount)) {
		p12ErrorLog("encryptedDataDecrypt: badly formed iterCount\n");
		P12_THROW_DECODE;
	}
	const CSSM_DATA *pwd = getEncrPassPhrase();
	const CSSM_KEY *passKey = getEncrPassKey();
	if((pwd == NULL) && (passKey == NULL)) {
		p12ErrorLog("no passphrase set\n");
		CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_PASSPHRASE);
	}
	
	/* go */
	CSSM_RETURN crtn = p12Decrypt(mCspHand,
		edata.contentInfo.encrContent,
		keyAlg, encrAlg, pbeHashAlg,
		keySizeInBits, blockSizeInBytes,
		padding, mode,
		iterCount, pbep->salt,
		pwd,
		passKey, 
		localCdr, 
		ptext);
	if(crtn) {
		CssmError::throwMe(crtn);
	}
}