зеркало из https://github.com/mozilla/gecko-dev.git
bug 19590
RFE:Add ability to encode/decode NSSCMSRecipientInfo structures r=javi,wtc
This commit is contained in:
Родитель
0cd6fbdd62
Коммит
ed4ffe44f6
|
@ -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:
|
||||
;+ *;
|
||||
;+};
|
||||
|
|
Загрузка…
Ссылка в новой задаче