RFE:Add ability to encode/decode NSSCMSRecipientInfo structures

r=javi,wtc
This commit is contained in:
relyea%netscape.com 2003-02-28 23:32:29 +00:00
Родитель 0cd6fbdd62
Коммит ed4ffe44f6
4 изменённых файлов: 192 добавлений и 17 удалений

Просмотреть файл

@ -34,7 +34,7 @@
/*
* Interfaces of the CMS implementation.
*
* $Id: cms.h,v 1.15 2002/12/17 01:39:45 wtc%netscape.com Exp $
* $Id: cms.h,v 1.16 2003/02/28 23:32:29 relyea%netscape.com Exp $
*/
#ifndef _CMS_H_
@ -868,9 +868,35 @@ extern NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
CERTCertificate *cert);
/*
* NSS_CMSRecipientInfo_CreateNew - create a blank recipientinfo for
* applications which want to encode their own CMS structures and
* key exchange types.
*/
extern NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg);
/*
* NSS_CMSRecipientInfo_CreateFromDER - create a recipientinfo from partially
* decoded DER data for applications which want to encode their own CMS
* structures and key exchange types.
*/
extern NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg);
extern void
NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri);
/*
* NSS_CMSRecipientInfo_GetCertAndKey - retrieve the cert and key from the
* recipientInfo struct. If retcert or retkey are NULL, the cert or
* key (respectively) would not be returned). This function is a no-op if both
* retcert and retkey are NULL. Caller inherits ownership of the cert and key
* he requested (and is responsible to free them).
*/
SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
CERTCertificate** retcert, SECKEYPrivateKey** retkey);
extern int
NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri);

Просмотреть файл

@ -34,7 +34,7 @@
/*
* CMS recipientInfo methods.
*
* $Id: cmsrecinfo.c,v 1.10 2003/01/17 02:49:07 wtc%netscape.com Exp $
* $Id: cmsrecinfo.c,v 1.11 2003/02/28 23:32:29 relyea%netscape.com Exp $
*/
#include "cmslocal.h"
@ -61,10 +61,11 @@ nss_cmsrecipientinfo_usessubjectkeyid(NSSCMSRecipientInfo *ri)
}
static SECOidData fakeContent = { 0 };
NSSCMSRecipientInfo *
nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
CERTCertificate *cert, SECKEYPublicKey *pubKey,
SECItem *subjKeyID)
SECItem *subjKeyID, void* pwfn_arg, SECItem* DERinput)
{
NSSCMSRecipientInfo *ri;
void *mark;
@ -77,6 +78,16 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
PLArenaPool *poolp;
CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL;
NSSCMSRecipientIdentifier *rid;
extern const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
if (!cmsg) {
/* a CMSMessage wasn't supplied, create a fake one to hold the pwfunc
* and a private arena pool */
cmsg = NSS_CMSMessage_Create(NULL);
cmsg->pwfn_arg = pwfn_arg;
/* mark it as a special cms message */
cmsg->contentInfo.contentTypeTag = &fakeContent;
}
poolp = cmsg->poolp;
@ -87,14 +98,43 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
goto loser;
ri->cmsg = cmsg;
if (type == NSSCMSRecipientID_IssuerSN) {
ri->cert = CERT_DupCertificate(cert);
if (ri->cert == NULL)
goto loser;
spki = &(cert->subjectPublicKeyInfo);
} else {
PORT_Assert(pubKey);
spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
if (DERinput) {
/* decode everything from DER */
SECItem newinput;
SECStatus rv = SECITEM_CopyItem(poolp, &newinput, DERinput);
if (SECSuccess != rv)
goto loser;
rv = SEC_QuickDERDecodeItem(poolp, ri, NSSCMSRecipientInfoTemplate, &newinput);
if (SECSuccess != rv)
goto loser;
}
switch (type) {
case NSSCMSRecipientID_IssuerSN:
{
ri->cert = CERT_DupCertificate(cert);
if (NULL == ri->cert)
goto loser;
spki = &(cert->subjectPublicKeyInfo);
break;
}
case NSSCMSRecipientID_SubjectKeyID:
{
PORT_Assert(pubKey);
spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
break;
}
case NSSCMSRecipientID_BrandNew:
goto done;
break;
default:
/* unkown type */
goto loser;
break;
}
certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm));
@ -238,15 +278,20 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
}
done:
PORT_ArenaUnmark (poolp, mark);
if (freeSpki)
SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
return ri;
loser:
if (freeSpki)
if (freeSpki) {
SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
}
PORT_ArenaRelease (poolp, mark);
if (cmsg->contentInfo.contentTypeTag == &fakeContent) {
NSS_CMSMessage_Destroy(cmsg);
}
return NULL;
}
@ -261,16 +306,31 @@ NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert)
{
return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_IssuerSN, cert,
NULL, NULL);
NULL, NULL, NULL, NULL);
}
NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg)
{
return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
NULL, NULL, pwfn_arg, NULL);
}
NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg)
{
return nss_cmsrecipientinfo_create(NULL, NSSCMSRecipientID_BrandNew, NULL,
NULL, NULL, pwfn_arg, input);
}
NSSCMSRecipientInfo *
NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
SECItem *subjKeyID,
SECKEYPublicKey *pubKey)
{
return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID,
NULL, pubKey, subjKeyID);
NULL, pubKey, subjKeyID, NULL, NULL);
}
NSSCMSRecipientInfo *
@ -306,6 +366,9 @@ done:
void
NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri)
{
if (!ri) {
return;
}
/* version was allocated on the pool, so no need to destroy it */
/* issuerAndSN was allocated on the pool, so no need to destroy it */
if (ri->cert != NULL)
@ -317,8 +380,10 @@ NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri)
if (extra->pubKey)
SECKEY_DestroyPublicKey(extra->pubKey);
}
if (ri->cmsg->contentInfo.contentTypeTag == &fakeContent) {
NSS_CMSMessage_Destroy(ri->cmsg);
}
/* recipientInfo structure itself was allocated on the pool, so no need to destroy it */
/* we're done. */
}
@ -576,3 +641,78 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
loser:
return NULL;
}
SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
CERTCertificate** retcert,
SECKEYPrivateKey** retkey)
{
CERTCertificate* cert = NULL;
NSSCMSRecipient** recipients = NULL;
NSSCMSRecipientInfo* recipientInfos[2];
SECStatus rv = SECSuccess;
SECKEYPrivateKey* key = NULL;
if (!ri)
return SECFailure;
if (!retcert && !retkey) {
/* nothing requested, nothing found, success */
return SECSuccess;
}
if (retcert) {
*retcert = NULL;
}
if (retkey) {
*retkey = NULL;
}
if (ri->cert) {
cert = CERT_DupCertificate(ri->cert);
if (!cert) {
rv = SECFailure;
}
}
if (SECSuccess == rv && !cert) {
/* we don't have the cert, we have to look for it */
/* first build an NSS_CMSRecipient */
recipientInfos[0] = ri;
recipientInfos[1] = NULL;
recipients = nss_cms_recipient_list_create(recipientInfos);
if (recipients) {
/* now look for the cert and key */
if (0 == PK11_FindCertAndKeyByRecipientListNew(recipients,
ri->cmsg->pwfn_arg)) {
cert = CERT_DupCertificate(recipients[0]->cert);
key = SECKEY_CopyPrivateKey(recipients[0]->privkey);
} else {
rv = SECFailure;
}
nss_cms_recipient_list_destroy(recipients);
}
else {
rv = SECFailure;
}
} else if (SECSuccess == rv && cert && retkey) {
/* we have the cert, we just need the key now */
key = PK11_FindPrivateKeyFromCert(cert->slot, cert, ri->cmsg->pwfn_arg);
}
if (retcert) {
*retcert = cert;
} else {
if (cert) {
CERT_DestroyCertificate(cert);
}
}
if (retkey) {
*retkey = key;
} else {
if (key) {
SECKEY_DestroyPrivateKey(key);
}
}
return rv;
}

Просмотреть файл

@ -34,7 +34,7 @@
/*
* Header for CMS types.
*
* $Id: cmst.h,v 1.7 2002/12/24 02:25:36 wtc%netscape.com Exp $
* $Id: cmst.h,v 1.8 2003/02/28 23:32:29 relyea%netscape.com Exp $
*/
#ifndef _CMST_H_
@ -283,7 +283,8 @@ struct NSSCMSOriginatorInfoStr {
*/
typedef enum {
NSSCMSRecipientID_IssuerSN = 0,
NSSCMSRecipientID_SubjectKeyID = 1
NSSCMSRecipientID_SubjectKeyID = 1,
NSSCMSRecipientID_BrandNew = 2
} NSSCMSRecipientIDSelector;
struct NSSCMSRecipientIdentifierStr {

Просмотреть файл

@ -230,3 +230,11 @@ NSS_CMSRecipientInfo_UnwrapBulkKey;
;+ local:
;+ *;
;+};
;+NSS_3.8 { # NSS 3.8 release
;+ global:
NSS_CMSRecipientInfo_CreateNew;
NSS_CMSRecipientInfo_CreateFromDER;
NSS_CMSRecipientInfo_GetCertAndKey;
;+ local:
;+ *;
;+};