зеркало из 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.
|
* 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_
|
#ifndef _CMS_H_
|
||||||
|
@ -868,9 +868,35 @@ extern NSSCMSRecipientInfo *
|
||||||
NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
|
NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
|
||||||
CERTCertificate *cert);
|
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
|
extern void
|
||||||
NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri);
|
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
|
extern int
|
||||||
NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri);
|
NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri);
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
/*
|
/*
|
||||||
* CMS recipientInfo methods.
|
* 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"
|
#include "cmslocal.h"
|
||||||
|
@ -61,10 +61,11 @@ nss_cmsrecipientinfo_usessubjectkeyid(NSSCMSRecipientInfo *ri)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static SECOidData fakeContent = { 0 };
|
||||||
NSSCMSRecipientInfo *
|
NSSCMSRecipientInfo *
|
||||||
nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
|
nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
|
||||||
CERTCertificate *cert, SECKEYPublicKey *pubKey,
|
CERTCertificate *cert, SECKEYPublicKey *pubKey,
|
||||||
SECItem *subjKeyID)
|
SECItem *subjKeyID, void* pwfn_arg, SECItem* DERinput)
|
||||||
{
|
{
|
||||||
NSSCMSRecipientInfo *ri;
|
NSSCMSRecipientInfo *ri;
|
||||||
void *mark;
|
void *mark;
|
||||||
|
@ -77,6 +78,16 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
|
||||||
PLArenaPool *poolp;
|
PLArenaPool *poolp;
|
||||||
CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL;
|
CERTSubjectPublicKeyInfo *spki, *freeSpki = NULL;
|
||||||
NSSCMSRecipientIdentifier *rid;
|
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;
|
poolp = cmsg->poolp;
|
||||||
|
|
||||||
|
@ -87,14 +98,43 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
|
||||||
goto loser;
|
goto loser;
|
||||||
|
|
||||||
ri->cmsg = cmsg;
|
ri->cmsg = cmsg;
|
||||||
if (type == NSSCMSRecipientID_IssuerSN) {
|
|
||||||
ri->cert = CERT_DupCertificate(cert);
|
if (DERinput) {
|
||||||
if (ri->cert == NULL)
|
/* decode everything from DER */
|
||||||
goto loser;
|
SECItem newinput;
|
||||||
spki = &(cert->subjectPublicKeyInfo);
|
SECStatus rv = SECITEM_CopyItem(poolp, &newinput, DERinput);
|
||||||
} else {
|
if (SECSuccess != rv)
|
||||||
PORT_Assert(pubKey);
|
goto loser;
|
||||||
spki = freeSpki = SECKEY_CreateSubjectPublicKeyInfo(pubKey);
|
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));
|
certalgtag = SECOID_GetAlgorithmTag(&(spki->algorithm));
|
||||||
|
@ -238,15 +278,20 @@ nss_cmsrecipientinfo_create(NSSCMSMessage *cmsg, NSSCMSRecipientIDSelector type,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
PORT_ArenaUnmark (poolp, mark);
|
PORT_ArenaUnmark (poolp, mark);
|
||||||
if (freeSpki)
|
if (freeSpki)
|
||||||
SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
|
SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
|
||||||
return ri;
|
return ri;
|
||||||
|
|
||||||
loser:
|
loser:
|
||||||
if (freeSpki)
|
if (freeSpki) {
|
||||||
SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
|
SECKEY_DestroySubjectPublicKeyInfo(freeSpki);
|
||||||
|
}
|
||||||
PORT_ArenaRelease (poolp, mark);
|
PORT_ArenaRelease (poolp, mark);
|
||||||
|
if (cmsg->contentInfo.contentTypeTag == &fakeContent) {
|
||||||
|
NSS_CMSMessage_Destroy(cmsg);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,16 +306,31 @@ NSSCMSRecipientInfo *
|
||||||
NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert)
|
NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert)
|
||||||
{
|
{
|
||||||
return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_IssuerSN, 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 *
|
NSSCMSRecipientInfo *
|
||||||
NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
|
NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
|
||||||
SECItem *subjKeyID,
|
SECItem *subjKeyID,
|
||||||
SECKEYPublicKey *pubKey)
|
SECKEYPublicKey *pubKey)
|
||||||
{
|
{
|
||||||
return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID,
|
return nss_cmsrecipientinfo_create(cmsg, NSSCMSRecipientID_SubjectKeyID,
|
||||||
NULL, pubKey, subjKeyID);
|
NULL, pubKey, subjKeyID, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
NSSCMSRecipientInfo *
|
NSSCMSRecipientInfo *
|
||||||
|
@ -306,6 +366,9 @@ done:
|
||||||
void
|
void
|
||||||
NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri)
|
NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri)
|
||||||
{
|
{
|
||||||
|
if (!ri) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* version was allocated on the pool, so no need to destroy it */
|
/* version was allocated on the pool, so no need to destroy it */
|
||||||
/* issuerAndSN 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)
|
if (ri->cert != NULL)
|
||||||
|
@ -317,8 +380,10 @@ NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri)
|
||||||
if (extra->pubKey)
|
if (extra->pubKey)
|
||||||
SECKEY_DestroyPublicKey(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. */
|
/* we're done. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,3 +641,78 @@ NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
|
||||||
loser:
|
loser:
|
||||||
return NULL;
|
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.
|
* 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_
|
#ifndef _CMST_H_
|
||||||
|
@ -283,7 +283,8 @@ struct NSSCMSOriginatorInfoStr {
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NSSCMSRecipientID_IssuerSN = 0,
|
NSSCMSRecipientID_IssuerSN = 0,
|
||||||
NSSCMSRecipientID_SubjectKeyID = 1
|
NSSCMSRecipientID_SubjectKeyID = 1,
|
||||||
|
NSSCMSRecipientID_BrandNew = 2
|
||||||
} NSSCMSRecipientIDSelector;
|
} NSSCMSRecipientIDSelector;
|
||||||
|
|
||||||
struct NSSCMSRecipientIdentifierStr {
|
struct NSSCMSRecipientIdentifierStr {
|
||||||
|
|
|
@ -230,3 +230,11 @@ NSS_CMSRecipientInfo_UnwrapBulkKey;
|
||||||
;+ local:
|
;+ local:
|
||||||
;+ *;
|
;+ *;
|
||||||
;+};
|
;+};
|
||||||
|
;+NSS_3.8 { # NSS 3.8 release
|
||||||
|
;+ global:
|
||||||
|
NSS_CMSRecipientInfo_CreateNew;
|
||||||
|
NSS_CMSRecipientInfo_CreateFromDER;
|
||||||
|
NSS_CMSRecipientInfo_GetCertAndKey;
|
||||||
|
;+ local:
|
||||||
|
;+ *;
|
||||||
|
;+};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче