/* * 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_CMSEncryptedData_Encode_BeforeData - set up encryption */ SECStatus NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd) { NSSCMSContentInfo *cinfo; PK11SymKey *bulkkey; SECAlgorithmID *algid; cinfo = &(encd->contentInfo); /* find bulkkey and algorithm - must have been set by NSS_CMSEncryptedData_Encode_BeforeStart */ bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo); if (bulkkey == NULL) return SECFailure; algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo); if (algid == NULL) return SECFailure; /* this may modify algid (with IVs generated in a token). * it is therefore essential that algid is a pointer to the "real" contentEncAlg, * not just to a copy */ cinfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(encd->cmsg->poolp, bulkkey, algid); PK11_FreeSymKey(bulkkey); if (cinfo->ciphcx == NULL) return SECFailure; return SECSuccess; }
/* * NSS_CMSEncryptedData_Encode_BeforeStart - do all the necessary things to a EncryptedData * before encoding begins. * * In particular: * - set the correct version value. * - get the encryption key */ SECStatus NSS_CMSEncryptedData_Encode_BeforeStart(NSSCMSEncryptedData *encd) { int version; PK11SymKey *bulkkey = NULL; SECItem *dummy; NSSCMSContentInfo *cinfo = &(encd->contentInfo); if (NSS_CMSArray_IsEmpty((void **)encd->unprotectedAttr)) version = NSS_CMS_ENCRYPTED_DATA_VERSION; else version = NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR; dummy = SEC_ASN1EncodeInteger (encd->cmsg->poolp, &(encd->version), version); if (dummy == NULL) return SECFailure; /* now get content encryption key (bulk key) by using our cmsg callback */ if (encd->cmsg->decrypt_key_cb) bulkkey = (*encd->cmsg->decrypt_key_cb)(encd->cmsg->decrypt_key_cb_arg, NSS_CMSContentInfo_GetContentEncAlg(cinfo)); if (bulkkey == NULL) return SECFailure; /* store the bulk key in the contentInfo so that the encoder can find it */ NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey); PK11_FreeSymKey (bulkkey); return SECSuccess; }
/* * NSS_CMSEnvelopedData_Encode_BeforeData - set up encryption * * it is essential that this is called before the contentEncAlg is encoded, because * setting up the encryption may generate IVs and thus change it! */ SECStatus NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd) { NSSCMSContentInfo *cinfo; PK11SymKey *bulkkey; SECAlgorithmID *algid; SECStatus rv; cinfo = &(envd->contentInfo); /* find bulkkey and algorithm - must have been set by NSS_CMSEnvelopedData_Encode_BeforeStart */ bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo); if (bulkkey == NULL) return SECFailure; algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo); if (algid == NULL) return SECFailure; rv = NSS_CMSContentInfo_Private_Init(cinfo); if (rv != SECSuccess) { return SECFailure; } /* this may modify algid (with IVs generated in a token). * it is essential that algid is a pointer to the contentEncAlg data, not a * pointer to a copy! */ cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid); PK11_FreeSymKey(bulkkey); if (cinfo->privateInfo->ciphcx == NULL) return SECFailure; return SECSuccess; }
/* * 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; }