|
Packit |
40b132 |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
40b132 |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
40b132 |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* CMS envelopedData methods.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
#include "cmslocal.h"
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
#include "cert.h"
|
|
Packit |
40b132 |
#include "key.h"
|
|
Packit |
40b132 |
#include "secasn1.h"
|
|
Packit |
40b132 |
#include "secitem.h"
|
|
Packit |
40b132 |
#include "secoid.h"
|
|
Packit |
40b132 |
#include "pk11func.h"
|
|
Packit |
40b132 |
#include "secerr.h"
|
|
Packit |
40b132 |
#include "secpkcs5.h"
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Create - create an enveloped data message
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
NSSCMSEnvelopedData *
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
void *mark;
|
|
Packit |
40b132 |
NSSCMSEnvelopedData *envd;
|
|
Packit |
40b132 |
PLArenaPool *poolp;
|
|
Packit |
40b132 |
SECStatus rv;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
poolp = cmsg->poolp;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
mark = PORT_ArenaMark(poolp);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
envd = (NSSCMSEnvelopedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSEnvelopedData));
|
|
Packit |
40b132 |
if (envd == NULL)
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
envd->cmsg = cmsg;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* version is set in NSS_CMSEnvelopedData_Encode_BeforeStart() */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, &(envd->contentInfo), algorithm, NULL, keysize);
|
|
Packit |
40b132 |
if (rv != SECSuccess)
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PORT_ArenaUnmark(poolp, mark);
|
|
Packit |
40b132 |
return envd;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
loser:
|
|
Packit |
40b132 |
PORT_ArenaRelease(poolp, mark);
|
|
Packit |
40b132 |
return NULL;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Destroy - destroy an enveloped data message
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
void
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Destroy(NSSCMSEnvelopedData *edp)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
NSSCMSRecipientInfo **recipientinfos;
|
|
Packit |
40b132 |
NSSCMSRecipientInfo *ri;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (edp == NULL)
|
|
Packit |
40b132 |
return;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
recipientinfos = edp->recipientInfos;
|
|
Packit |
40b132 |
if (recipientinfos == NULL)
|
|
Packit |
40b132 |
return;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
while ((ri = *recipientinfos++) != NULL)
|
|
Packit |
40b132 |
NSS_CMSRecipientInfo_Destroy(ri);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
NSS_CMSContentInfo_Destroy(&(edp->contentInfo));
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_GetContentInfo - return pointer to this envelopedData's contentinfo
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
NSSCMSContentInfo *
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_GetContentInfo(NSSCMSEnvelopedData *envd)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
return &(envd->contentInfo);
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_AddRecipient - add a recipientinfo to the enveloped data msg
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* rip must be created on the same pool as edp - this is not enforced, though.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
SECStatus
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_AddRecipient(NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo *rip)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
void *mark;
|
|
Packit |
40b132 |
SECStatus rv;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* XXX compare pools, if not same, copy rip into edp's pool */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PR_ASSERT(edp != NULL);
|
|
Packit |
40b132 |
PR_ASSERT(rip != NULL);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
mark = PORT_ArenaMark(edp->cmsg->poolp);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rv = NSS_CMSArray_Add(edp->cmsg->poolp, (void ***)&(edp->recipientInfos), (void *)rip);
|
|
Packit |
40b132 |
if (rv != SECSuccess) {
|
|
Packit |
40b132 |
PORT_ArenaRelease(edp->cmsg->poolp, mark);
|
|
Packit |
40b132 |
return SECFailure;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PORT_ArenaUnmark (edp->cmsg->poolp, mark);
|
|
Packit |
40b132 |
return SECSuccess;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Encode_BeforeStart - prepare this envelopedData for encoding
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* at this point, we need
|
|
Packit |
40b132 |
* - recipientinfos set up with recipient's certificates
|
|
Packit |
40b132 |
* - a content encryption algorithm (if none, 3DES will be used)
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* this function will generate a random content encryption key (aka bulk key),
|
|
Packit |
40b132 |
* initialize the recipientinfos with certificate identification and wrap the bulk key
|
|
Packit |
40b132 |
* using the proper algorithm for every certificiate.
|
|
Packit |
40b132 |
* it will finally set the bulk algorithm and key so that the encode step can find it.
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
SECStatus
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
int version;
|
|
Packit |
40b132 |
NSSCMSRecipientInfo **recipientinfos;
|
|
Packit |
40b132 |
NSSCMSContentInfo *cinfo;
|
|
Packit |
40b132 |
PK11SymKey *bulkkey = NULL;
|
|
Packit |
40b132 |
SECOidTag bulkalgtag;
|
|
Packit |
40b132 |
CK_MECHANISM_TYPE type;
|
|
Packit |
40b132 |
PK11SlotInfo *slot;
|
|
Packit |
40b132 |
SECStatus rv;
|
|
Packit |
40b132 |
SECItem *dummy;
|
|
Packit |
40b132 |
PLArenaPool *poolp;
|
|
Packit |
40b132 |
extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
|
|
Packit |
40b132 |
void *mark = NULL;
|
|
Packit |
40b132 |
int i;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
poolp = envd->cmsg->poolp;
|
|
Packit |
40b132 |
cinfo = &(envd->contentInfo);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
recipientinfos = envd->recipientInfos;
|
|
Packit |
40b132 |
if (recipientinfos == NULL) {
|
|
Packit |
40b132 |
PORT_SetError(SEC_ERROR_BAD_DATA);
|
|
Packit |
40b132 |
#if 0
|
|
Packit |
40b132 |
PORT_SetErrorString("Cannot find recipientinfos to encode.");
|
|
Packit |
40b132 |
#endif
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
version = NSS_CMS_ENVELOPED_DATA_VERSION_REG;
|
|
Packit |
40b132 |
if (envd->originatorInfo != NULL || envd->unprotectedAttr != NULL) {
|
|
Packit |
40b132 |
version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV;
|
|
Packit |
40b132 |
} else {
|
|
Packit |
40b132 |
for (i = 0; recipientinfos[i] != NULL; i++) {
|
|
Packit |
40b132 |
if (NSS_CMSRecipientInfo_GetVersion(recipientinfos[i]) != 0) {
|
|
Packit |
40b132 |
version = NSS_CMS_ENVELOPED_DATA_VERSION_ADV;
|
|
Packit |
40b132 |
break;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
dummy = SEC_ASN1EncodeInteger(poolp, &(envd->version), version);
|
|
Packit |
40b132 |
if (dummy == NULL)
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* now we need to have a proper content encryption algorithm
|
|
Packit |
40b132 |
* on the SMIME level, we would figure one out by looking at SMIME capabilities
|
|
Packit |
40b132 |
* we cannot do that on our level, so if none is set already, we'll just go
|
|
Packit |
40b132 |
* with one of the mandatory algorithms (3DES) */
|
|
Packit |
40b132 |
if ((bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo)) == SEC_OID_UNKNOWN) {
|
|
Packit |
40b132 |
rv = NSS_CMSContentInfo_SetContentEncAlg(poolp, cinfo, SEC_OID_DES_EDE3_CBC, NULL, 168);
|
|
Packit |
40b132 |
if (rv != SECSuccess)
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
bulkalgtag = SEC_OID_DES_EDE3_CBC;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* generate a random bulk key suitable for content encryption alg */
|
|
Packit |
40b132 |
type = PK11_AlgtagToMechanism(bulkalgtag);
|
|
Packit |
40b132 |
slot = PK11_GetBestSlot(type, envd->cmsg->pwfn_arg);
|
|
Packit |
40b132 |
if (slot == NULL)
|
|
Packit |
40b132 |
goto loser; /* error has been set by PK11_GetBestSlot */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* this is expensive... */
|
|
Packit |
40b132 |
bulkkey = PK11_KeyGen(slot, type, NULL, NSS_CMSContentInfo_GetBulkKeySize(cinfo) / 8, envd->cmsg->pwfn_arg);
|
|
Packit |
40b132 |
PK11_FreeSlot(slot);
|
|
Packit |
40b132 |
if (bulkkey == NULL)
|
|
Packit |
40b132 |
goto loser; /* error has been set by PK11_KeyGen */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
mark = PORT_ArenaMark(poolp);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* Encrypt the bulk key with the public key of each recipient. */
|
|
Packit |
40b132 |
for (i = 0; recipientinfos[i] != NULL; i++) {
|
|
Packit |
40b132 |
rv = NSS_CMSRecipientInfo_WrapBulkKey(recipientinfos[i], bulkkey, bulkalgtag);
|
|
Packit |
40b132 |
if (rv != SECSuccess)
|
|
Packit |
40b132 |
goto loser; /* error has been set by NSS_CMSRecipientInfo_EncryptBulkKey */
|
|
Packit |
40b132 |
/* could be: alg not supported etc. */
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* the recipientinfos are all finished. now sort them by DER for SET OF encoding */
|
|
Packit |
40b132 |
rv = NSS_CMSArray_SortByDER((void **)envd->recipientInfos, NSSCMSRecipientInfoTemplate, NULL);
|
|
Packit |
40b132 |
if (rv != SECSuccess)
|
|
Packit |
40b132 |
goto loser; /* error has been set by NSS_CMSArray_SortByDER */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* store the bulk key in the contentInfo so that the encoder can find it */
|
|
Packit |
40b132 |
NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PORT_ArenaUnmark(poolp, mark);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
PK11_FreeSymKey(bulkkey);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
return SECSuccess;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
loser:
|
|
Packit |
40b132 |
if (mark != NULL)
|
|
Packit |
40b132 |
PORT_ArenaRelease (poolp, mark);
|
|
Packit |
40b132 |
if (bulkkey)
|
|
Packit |
40b132 |
PK11_FreeSymKey(bulkkey);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
return SECFailure;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Encode_BeforeData - set up encryption
|
|
Packit |
40b132 |
*
|
|
Packit |
40b132 |
* it is essential that this is called before the contentEncAlg is encoded, because
|
|
Packit |
40b132 |
* setting up the encryption may generate IVs and thus change it!
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
SECStatus
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
NSSCMSContentInfo *cinfo;
|
|
Packit |
40b132 |
PK11SymKey *bulkkey;
|
|
Packit |
40b132 |
SECAlgorithmID *algid;
|
|
Packit |
40b132 |
SECStatus rv;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cinfo = &(envd->contentInfo);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* find bulkkey and algorithm - must have been set by NSS_CMSEnvelopedData_Encode_BeforeStart */
|
|
Packit |
40b132 |
bulkkey = NSS_CMSContentInfo_GetBulkKey(cinfo);
|
|
Packit |
40b132 |
if (bulkkey == NULL)
|
|
Packit |
40b132 |
return SECFailure;
|
|
Packit |
40b132 |
algid = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
|
|
Packit |
40b132 |
if (algid == NULL)
|
|
Packit |
40b132 |
return SECFailure;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rv = NSS_CMSContentInfo_Private_Init(cinfo);
|
|
Packit |
40b132 |
if (rv != SECSuccess) {
|
|
Packit |
40b132 |
return SECFailure;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
/* this may modify algid (with IVs generated in a token).
|
|
Packit |
40b132 |
* it is essential that algid is a pointer to the contentEncAlg data, not a
|
|
Packit |
40b132 |
* pointer to a copy! */
|
|
Packit |
40b132 |
cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartEncrypt(envd->cmsg->poolp, bulkkey, algid);
|
|
Packit |
40b132 |
PK11_FreeSymKey(bulkkey);
|
|
Packit |
40b132 |
if (cinfo->privateInfo->ciphcx == NULL)
|
|
Packit |
40b132 |
return SECFailure;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
return SECSuccess;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Encode_AfterData - finalize this envelopedData for encoding
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
SECStatus
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
if (envd->contentInfo.privateInfo && envd->contentInfo.privateInfo->ciphcx) {
|
|
Packit |
40b132 |
NSS_CMSCipherContext_Destroy(envd->contentInfo.privateInfo->ciphcx);
|
|
Packit |
40b132 |
envd->contentInfo.privateInfo->ciphcx = NULL;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* nothing else to do after data */
|
|
Packit |
40b132 |
return SECSuccess;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
|
|
Packit |
40b132 |
* derive bulk key & set up our contentinfo
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
SECStatus
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
NSSCMSRecipientInfo *ri;
|
|
Packit |
40b132 |
PK11SymKey *bulkkey = NULL;
|
|
Packit |
40b132 |
SECOidTag bulkalgtag;
|
|
Packit |
40b132 |
SECAlgorithmID *bulkalg;
|
|
Packit |
40b132 |
SECStatus rv = SECFailure;
|
|
Packit |
40b132 |
NSSCMSContentInfo *cinfo;
|
|
Packit |
40b132 |
NSSCMSRecipient **recipient_list = NULL;
|
|
Packit |
40b132 |
NSSCMSRecipient *recipient;
|
|
Packit |
40b132 |
int rlIndex;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
if (NSS_CMSArray_Count((void **)envd->recipientInfos) == 0) {
|
|
Packit |
40b132 |
PORT_SetError(SEC_ERROR_BAD_DATA);
|
|
Packit |
40b132 |
#if 0
|
|
Packit |
40b132 |
PORT_SetErrorString("No recipient data in envelope.");
|
|
Packit |
40b132 |
#endif
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* look if one of OUR cert's issuerSN is on the list of recipients, and if so, */
|
|
Packit |
40b132 |
/* get the cert and private key for it right away */
|
|
Packit |
40b132 |
recipient_list = nss_cms_recipient_list_create(envd->recipientInfos);
|
|
Packit |
40b132 |
if (recipient_list == NULL)
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* what about multiple recipientInfos that match?
|
|
Packit |
40b132 |
* especially if, for some reason, we could not produce a bulk key with the first match?!
|
|
Packit |
40b132 |
* we could loop & feed partial recipient_list to PK11_FindCertAndKeyByRecipientList...
|
|
Packit |
40b132 |
* maybe later... */
|
|
Packit |
40b132 |
rlIndex = PK11_FindCertAndKeyByRecipientListNew(recipient_list, envd->cmsg->pwfn_arg);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/* if that fails, then we're not an intended recipient and cannot decrypt */
|
|
Packit |
40b132 |
if (rlIndex < 0) {
|
|
Packit |
40b132 |
PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT);
|
|
Packit |
40b132 |
#if 0
|
|
Packit |
40b132 |
PORT_SetErrorString("Cannot decrypt data because proper key cannot be found.");
|
|
Packit |
40b132 |
#endif
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
recipient = recipient_list[rlIndex];
|
|
Packit |
40b132 |
if (!recipient->cert || !recipient->privkey) {
|
|
Packit |
40b132 |
/* XXX should set an error code ?!? */
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
/* get a pointer to "our" recipientinfo */
|
|
Packit |
40b132 |
ri = envd->recipientInfos[recipient->riIndex];
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
cinfo = &(envd->contentInfo);
|
|
Packit |
40b132 |
bulkalgtag = NSS_CMSContentInfo_GetContentEncAlgTag(cinfo);
|
|
Packit |
40b132 |
if (bulkalgtag == SEC_OID_UNKNOWN) {
|
|
Packit |
40b132 |
PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
|
|
Packit |
40b132 |
} else
|
|
Packit |
40b132 |
bulkkey =
|
|
Packit |
40b132 |
NSS_CMSRecipientInfo_UnwrapBulkKey(ri,recipient->subIndex,
|
|
Packit |
40b132 |
recipient->cert,
|
|
Packit |
40b132 |
recipient->privkey,
|
|
Packit |
40b132 |
bulkalgtag);
|
|
Packit |
40b132 |
if (bulkkey == NULL) {
|
|
Packit |
40b132 |
/* no success finding a bulk key */
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
NSS_CMSContentInfo_SetBulkKey(cinfo, bulkkey);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
bulkalg = NSS_CMSContentInfo_GetContentEncAlg(cinfo);
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rv = NSS_CMSContentInfo_Private_Init(cinfo);
|
|
Packit |
40b132 |
if (rv != SECSuccess) {
|
|
Packit |
40b132 |
goto loser;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
rv = SECFailure;
|
|
Packit |
40b132 |
cinfo->privateInfo->ciphcx = NSS_CMSCipherContext_StartDecrypt(bulkkey, bulkalg);
|
|
Packit |
40b132 |
if (cinfo->privateInfo->ciphcx == NULL)
|
|
Packit |
40b132 |
goto loser; /* error has been set by NSS_CMSCipherContext_StartDecrypt */
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
rv = SECSuccess;
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
loser:
|
|
Packit |
40b132 |
if (bulkkey)
|
|
Packit |
40b132 |
PK11_FreeSymKey(bulkkey);
|
|
Packit |
40b132 |
if (recipient_list != NULL)
|
|
Packit |
40b132 |
nss_cms_recipient_list_destroy(recipient_list);
|
|
Packit |
40b132 |
return rv;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Decode_AfterData - finish decrypting this envelopedData's content
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
SECStatus
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
if (envd && envd->contentInfo.privateInfo && envd->contentInfo.privateInfo->ciphcx) {
|
|
Packit |
40b132 |
NSS_CMSCipherContext_Destroy(envd->contentInfo.privateInfo->ciphcx);
|
|
Packit |
40b132 |
envd->contentInfo.privateInfo->ciphcx = NULL;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
return SECSuccess;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|
|
Packit |
40b132 |
/*
|
|
Packit |
40b132 |
* NSS_CMSEnvelopedData_Decode_AfterEnd - finish decoding this envelopedData
|
|
Packit |
40b132 |
*/
|
|
Packit |
40b132 |
SECStatus
|
|
Packit |
40b132 |
NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd)
|
|
Packit |
40b132 |
{
|
|
Packit |
40b132 |
/* apply final touches */
|
|
Packit |
40b132 |
return SECSuccess;
|
|
Packit |
40b132 |
}
|
|
Packit |
40b132 |
|