From 7b6200261348d478ed289ce5689e8f8d8a70b050 Mon Sep 17 00:00:00 2001 From: "jpierre%netscape.com" Date: Fri, 20 Sep 2002 04:41:47 +0000 Subject: [PATCH] Fix for 145785 - Need to create signer infos using Subject Key ID. r=relyea git-svn-id: svn://10.0.0.236/trunk@130120 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/security/nss/lib/nss/nss.def | 1 + mozilla/security/nss/lib/smime/cms.h | 4 +- mozilla/security/nss/lib/smime/cmssiginfo.c | 82 +++++++++++++++++---- mozilla/security/nss/lib/smime/cmst.h | 4 +- mozilla/security/nss/lib/smime/smime.def | 6 ++ 5 files changed, 82 insertions(+), 15 deletions(-) diff --git a/mozilla/security/nss/lib/nss/nss.def b/mozilla/security/nss/lib/nss/nss.def index 3be8f298b57..fdb159e62e7 100644 --- a/mozilla/security/nss/lib/nss/nss.def +++ b/mozilla/security/nss/lib/nss/nss.def @@ -704,6 +704,7 @@ PK11_ImportDERCert; PK11_PubUnwrapSymKeyWithFlags; PK11_SaveContextAlloc; SEC_QuickDERDecodeItem; +SECKEY_CopyPublicKey; ;+ local: ;+ *; ;+}; diff --git a/mozilla/security/nss/lib/smime/cms.h b/mozilla/security/nss/lib/smime/cms.h index fa2cc272ada..6dd5c3c6c47 100644 --- a/mozilla/security/nss/lib/smime/cms.h +++ b/mozilla/security/nss/lib/smime/cms.h @@ -34,7 +34,7 @@ /* * Interfaces of the CMS implementation. * - * $Id: cms.h,v 1.12 2002-08-27 13:14:38 kaie%netscape.com Exp $ + * $Id: cms.h,v 1.13 2002-09-20 04:41:45 jpierre%netscape.com Exp $ */ #ifndef _CMS_H_ @@ -598,6 +598,8 @@ NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PR extern NSSCMSSignerInfo * NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag); +extern NSSCMSSignerInfo * +NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag); /* * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure diff --git a/mozilla/security/nss/lib/smime/cmssiginfo.c b/mozilla/security/nss/lib/smime/cmssiginfo.c index 0d38e992831..2630706ec29 100644 --- a/mozilla/security/nss/lib/smime/cmssiginfo.c +++ b/mozilla/security/nss/lib/smime/cmssiginfo.c @@ -34,7 +34,7 @@ /* * CMS signerInfo methods. * - * $Id: cmssiginfo.c,v 1.11 2002-08-27 13:14:39 kaie%netscape.com Exp $ + * $Id: cmssiginfo.c,v 1.12 2002-09-20 04:41:47 jpierre%netscape.com Exp $ */ #include "cmslocal.h" @@ -55,9 +55,23 @@ /* ============================================================================= * SIGNERINFO */ +NSSCMSSignerInfo * +nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type, CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag); + +NSSCMSSignerInfo * +NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag) +{ + return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_SubjectKeyID, NULL, subjKeyID, pubKey, signingKey, digestalgtag); +} NSSCMSSignerInfo * NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag) +{ + return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_IssuerSN, cert, NULL, NULL, NULL, digestalgtag); +} + +NSSCMSSignerInfo * +nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type, CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag) { void *mark; NSSCMSSignerInfo *signerinfo; @@ -74,14 +88,36 @@ NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag d return NULL; } - if ((signerinfo->cert = CERT_DupCertificate(cert)) == NULL) - goto loser; signerinfo->cmsg = cmsg; - signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_IssuerSN; /* hardcoded for now */ - if ((signerinfo->signerIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL) - goto loser; + switch(type) { + case NSSCMSSignerID_IssuerSN: + signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_IssuerSN; + if ((signerinfo->cert = CERT_DupCertificate(cert)) == NULL) + goto loser; + if ((signerinfo->signerIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL) + goto loser; + break; + case NSSCMSSignerID_SubjectKeyID: + signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_SubjectKeyID; + PORT_Assert(subjKeyID); + if (!subjKeyID) + goto loser; + + signerinfo->signerIdentifier.id.subjectKeyID = PORT_ArenaNew(poolp, SECItem); + SECITEM_CopyItem(poolp, signerinfo->signerIdentifier.id.subjectKeyID, + subjKeyID); + signerinfo->signingKey = SECKEY_CopyPrivateKey(signingKey); + if (!signerinfo->signingKey) + goto loser; + signerinfo->pubKey = SECKEY_CopyPublicKey(pubKey); + if (!signerinfo->pubKey) + goto loser; + break; + default: + goto loser; + } /* set version right now */ version = NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN; @@ -129,23 +165,44 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *c SECOidTag signalgtag; SECItem signature = { 0 }; SECStatus rv; - PLArenaPool *poolp, *tmppoolp; + PLArenaPool *poolp, *tmppoolp; + SECAlgorithmID *algID, freeAlgID; + CERTSubjectPublicKeyInfo *spki; PORT_Assert (digest != NULL); poolp = signerinfo->cmsg->poolp; - cert = signerinfo->cert; - - if ((privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg)) == NULL) - goto loser; + switch (signerinfo->signerIdentifier.identifierType) { + case NSSCMSSignerID_IssuerSN: + cert = signerinfo->cert; + if ((privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg)) == NULL) + goto loser; + algID = &cert->subjectPublicKeyInfo.algorithm; + break; + case NSSCMSSignerID_SubjectKeyID: + privkey = signerinfo->signingKey; + signerinfo->signingKey = NULL; + spki = SECKEY_CreateSubjectPublicKeyInfo(signerinfo->pubKey); + SECKEY_DestroyPublicKey(signerinfo->pubKey); + signerinfo->pubKey = NULL; + SECOID_CopyAlgorithmID(NULL, &freeAlgID, &spki->algorithm); + SECKEY_DestroySubjectPublicKeyInfo(spki); + algID = &freeAlgID; + break; + default: + goto loser; + } digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo); /* * XXX I think there should be a cert-level interface for this, * so that I do not have to know about subjectPublicKeyInfo... */ - signalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); + signalgtag = SECOID_GetAlgorithmTag(algID); + if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) { + SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE); + } /* Fortezza MISSI have weird signature formats. Map them to standard DSA formats */ signalgtag = PK11_FortezzaMapSig(signalgtag); @@ -196,7 +253,6 @@ NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *c } else { rv = SGN_Digest(privkey, digestalgtag, &signature, digest); } - SECKEY_DestroyPrivateKey(privkey); privkey = NULL; diff --git a/mozilla/security/nss/lib/smime/cmst.h b/mozilla/security/nss/lib/smime/cmst.h index bfa60e49962..d6b453784d8 100644 --- a/mozilla/security/nss/lib/smime/cmst.h +++ b/mozilla/security/nss/lib/smime/cmst.h @@ -34,7 +34,7 @@ /* * Header for CMS types. * - * $Id: cmst.h,v 1.4 2001-12-07 01:36:13 relyea%netscape.com Exp $ + * $Id: cmst.h,v 1.5 2002-09-20 04:41:47 jpierre%netscape.com Exp $ */ #ifndef _CMST_H_ @@ -243,6 +243,8 @@ struct NSSCMSSignerInfoStr { CERTCertificateList * certList; PRTime signingTime; NSSCMSVerificationStatus verificationStatus; + SECKEYPrivateKey * signingKey; /* Used if we're using subjKeyID*/ + SECKEYPublicKey * pubKey; }; #define NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */ #define NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */ diff --git a/mozilla/security/nss/lib/smime/smime.def b/mozilla/security/nss/lib/smime/smime.def index 6b8d11b88ea..4b893557e9b 100644 --- a/mozilla/security/nss/lib/smime/smime.def +++ b/mozilla/security/nss/lib/smime/smime.def @@ -211,6 +211,12 @@ NSS_CMSMessage_IsEncrypted; ;+}; ;+NSS_3.6 { # NSS 3.6 release ;+ global: +NSS_CMSSignerInfo_CreateWithSubjKeyID; +;+ local: +;+ *; +;+}; +;+NSS_3.6 { # NSS 3.6 release +;+ global: NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs; ;+ local: ;+ *;