/* * NSS_CMSEncryptedData_Decode_BeforeData - find bulk key & set up decryption */ SECStatus NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd) { PK11SymKey *bulkkey = NULL; NSSCMSContentInfo *cinfo; SECAlgorithmID *bulkalg; SECStatus rv = SECFailure; cinfo = &(encd->contentInfo); bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo); if (encd->cmsg->decrypt_key_cb == NULL) /* no callback? no key../ */ goto loser; bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg, bulkalg); if (bulkkey == NULL) /* no success finding a bulk key */ goto loser; NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); cinfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); if (cinfo->ciphcx == NULL) goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */ /* we are done with (this) bulkkey now. */ PK11_FreeSymKey(bulkkey); rv = SECSuccess; loser: return rv; }
/* * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo, * derive bulk key & set up our contentinfo */ SECStatus NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd) { NSSCMSRecipientInfo *ri; PK11SymKey *bulkkey = NULL; SECOidTag bulkalgtag; SECAlgorithmID *bulkalg; SECStatus rv = SECFailure; NSSCMSContentInfo *cinfo; NSSCMSRecipient **recipient_list = NULL; NSSCMSRecipient *recipient; int rlIndex; if (NSS_CMSArray_Count((void **)envd->recipientInfos) == 0) { PORT_SetError(SEC_ERROR_BAD_DATA); #if 0 PORT_SetErrorString("No recipient data in envelope."); #endif goto loser; } /* look if one of OUR cert's issuerSN is on the list of recipients, and if so, */ /* get the cert and private key for it right away */ recipient_list = nss_cms_recipient_list_create(envd->recipientInfos); if (recipient_list == NULL) goto loser; /* what about multiple recipientInfos that match? * especially if, for some reason, we could not produce a bulk key with the first match?! * we could loop & feed partial recipient_list to PK11_FindCertAndKeyByRecipientList... * maybe later... */ rlIndex = PK11_FindCertAndKeyByRecipientListNew(recipient_list, envd->cmsg->pwfn_arg); /* if that fails, then we're not an intended recipient and cannot decrypt */ if (rlIndex < 0) { PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT); #if 0 PORT_SetErrorString("Cannot decrypt data because proper key cannot be found."); #endif goto loser; } recipient = recipient_list[rlIndex]; if (!recipient->cert || !recipient->privkey) { /* XXX should set an error code ?!? */ goto loser; } /* get a pointer to "our" recipientinfo */ ri = envd->recipientInfos[recipient->riIndex]; cinfo = &(envd->contentInfo); bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo); if (bulkalgtag == SEC_OID_UNKNOWN) { PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); } else bulkkey = NSS_CMSRecipientInfo_UnwrapBulkKey(ri,recipient->subIndex, recipient->cert, recipient->privkey, bulkalgtag); if (bulkkey == NULL) { /* no success finding a bulk key */ goto loser; } NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo); rv = NSS_CMSContentInfo_Private_Init(cinfo); if (rv != SECSuccess) { goto loser; } rv = SECFailure; cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg); if (cinfo->privateInfo->ciphcx == NULL) goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */ rv = SECSuccess; loser: if (bulkkey) PK11_FreeSymKey(bulkkey); if (recipient_list != NULL) nss_cms_recipient_list_destroy(recipient_list); return rv; }