summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchrisk%netscape.com <devnull@localhost>2000-06-20 16:28:59 +0000
committerchrisk%netscape.com <devnull@localhost>2000-06-20 16:28:59 +0000
commit865a0f38c06532bb671c67d352459c6dcc07aef9 (patch)
tree505d72345b57fee8d6003e386539ea4e3c8c86e0
parentb070f39457684d8fd2f9dde93907f85be561b450 (diff)
downloadnss-hg-865a0f38c06532bb671c67d352459c6dcc07aef9.tar.gz
Add code for generation of SMIMEProfile and SMIMEKeyEncryptionPreference
-rw-r--r--security/nss/cmd/smimetools/cmsutil.c27
-rw-r--r--security/nss/lib/smime/cms.h17
-rw-r--r--security/nss/lib/smime/cmsasn1.c2
-rw-r--r--security/nss/lib/smime/cmsattr.c3
-rw-r--r--security/nss/lib/smime/cmssiginfo.c97
-rw-r--r--security/nss/lib/smime/smime.h15
-rw-r--r--security/nss/lib/smime/smimeutil.c136
-rw-r--r--security/nss/lib/util/secoid.c10
-rw-r--r--security/nss/lib/util/secoidt.h3
9 files changed, 279 insertions, 31 deletions
diff --git a/security/nss/cmd/smimetools/cmsutil.c b/security/nss/cmd/smimetools/cmsutil.c
index 4ccfad691..f78076677 100644
--- a/security/nss/cmd/smimetools/cmsutil.c
+++ b/security/nss/cmd/smimetools/cmsutil.c
@@ -356,7 +356,7 @@ sign(FILE *out, FILE *infile, char *progName, struct optionsStr options, struct
char ibuf[4096];
PK11PasswordFunc pwcb;
void *pwcb_arg;
- CERTCertificate *cert;
+ CERTCertificate *cert, *ekpcert;
if (signOptions.nickname == NULL) {
fprintf(stderr, "ERROR: please indicate the nickname of a certificate to sign with.\n");
@@ -431,8 +431,31 @@ sign(FILE *out, FILE *infile, char *progName, struct optionsStr options, struct
}
}
if (signOptions.encryptionKeyPreferenceNick) {
- /* TBD */
/* get the cert, add it to the message */
+ if ((ekpcert = CERT_FindCertByNickname(options.certHandle, signOptions.encryptionKeyPreferenceNick)) == NULL) {
+ SECU_PrintError(progName, "the corresponding cert for key \"%s\" does not exist",
+ signOptions.encryptionKeyPreferenceNick);
+ NSS_CMSMessage_Destroy(cmsg);
+ return SECFailure;
+ }
+ if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, ekpcert, options.certHandle) != SECSuccess) {
+ fprintf(stderr, "ERROR: cannot add SMIMEEncKeyPrefs attribute.\n");
+ NSS_CMSMessage_Destroy(cmsg);
+ return SECFailure;
+ }
+ if (NSS_CMSSignedData_AddCertificate(sigd, ekpcert) != SECSuccess) {
+ fprintf(stderr, "ERROR: cannot add encryption certificate.\n");
+ NSS_CMSMessage_Destroy(cmsg);
+ return SECFailure;
+ }
+ } else {
+ /* check signing cert for fitness as encryption cert */
+ /* if yes, add signing cert as EncryptionKeyPreference */
+ if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, cert, options.certHandle) != SECSuccess) {
+ fprintf(stderr, "ERROR: cannot add default SMIMEEncKeyPrefs attribute.\n");
+ NSS_CMSMessage_Destroy(cmsg);
+ return SECFailure;
+ }
}
if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess) {
diff --git a/security/nss/lib/smime/cms.h b/security/nss/lib/smime/cms.h
index 2793f682a..cb9a9001a 100644
--- a/security/nss/lib/smime/cms.h
+++ b/security/nss/lib/smime/cms.h
@@ -716,16 +716,17 @@ NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t);
extern SECStatus
NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo);
+/*
+ * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed messages for email (S/MIME).
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb);
+
/*
* NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
- *
- * 1. digest the DER-encoded signature value of the original signerinfo
- * 2. create new signerinfo with correct version, sid, digestAlg
- * 3. add message-digest authAttr, but NO content-type
- * 4. sign the authAttrs
- * 5. add the whole thing to original signerInfo's unAuthAttrs
- *
- * XXXX give back the new signerinfo?
*/
extern SECStatus
NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
diff --git a/security/nss/lib/smime/cmsasn1.c b/security/nss/lib/smime/cmsasn1.c
index afd82d407..d649c4192 100644
--- a/security/nss/lib/smime/cmsasn1.c
+++ b/security/nss/lib/smime/cmsasn1.c
@@ -305,7 +305,7 @@ static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = {
{ 0 }
};
-static const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = {
+const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) },
{ SEC_ASN1_OCTET_STRING,
diff --git a/security/nss/lib/smime/cmsattr.c b/security/nss/lib/smime/cmsattr.c
index e0433fd18..34016bd55 100644
--- a/security/nss/lib/smime/cmsattr.c
+++ b/security/nss/lib/smime/cmsattr.c
@@ -234,6 +234,9 @@ cms_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding)
theTemplate = SEC_AnyTemplate;
} else {
switch (oiddata->offset) {
+ SEC_OID_PKCS9_SMIME_CAPABILITIES:
+ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE:
+ /* these guys need to stay DER-encoded */
default:
/* same goes for OIDs that are not handled here */
encoded = PR_TRUE;
diff --git a/security/nss/lib/smime/cmssiginfo.c b/security/nss/lib/smime/cmssiginfo.c
index 56b23ceb1..76e5d8d66 100644
--- a/security/nss/lib/smime/cmssiginfo.c
+++ b/security/nss/lib/smime/cmssiginfo.c
@@ -49,6 +49,8 @@
#include "secerr.h"
#include "cryptohi.h"
+#include "smime.h"
+
/* =============================================================================
* SIGNERINFO
*/
@@ -674,7 +676,7 @@ NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo)
goto loser;
/* create new signing time attribute */
- if (NSS_SMIMEUtil_GetSMIMECapabilities(poolp, smimecaps,
+ if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps,
PK11_FortezzaHasKEA(signerinfo->cert)) != SECSuccess)
goto loser;
@@ -693,13 +695,59 @@ loser:
}
/*
+ * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed messages for email (S/MIME).
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
+{
+ NSSCMSAttribute *attr;
+ SECItem *smimeekp = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ /* verify this cert for encryption */
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
+ return SECFailure;
+ }
+
+ poolp = signerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
+ if (smimeekp == NULL)
+ goto loser;
+
+ /* create new signing time attribute */
+ if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
* NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
*
* 1. digest the DER-encoded signature value of the original signerinfo
* 2. create new signerinfo with correct version, sid, digestAlg
* 3. add message-digest authAttr, but NO content-type
* 4. sign the authAttrs
- * 5. add the whole thing to original signerInfo's unAuthAttrs
+ * 5. DER-encode the new signerInfo
+ * 6. add the whole thing to original signerInfo's unAuthAttrs
+ * as a SEC_OID_PKCS9_COUNTER_SIGNATURE attribute
*
* XXXX give back the new signerinfo?
*/
@@ -718,22 +766,51 @@ NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
SECStatus
NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo)
{
- CERTCertificate *cert;
+ CERTCertificate *cert = NULL;
SECItem *profile = NULL;
NSSCMSAttribute *attr;
- SECItem *utc_stime;
+ SECItem *utc_stime = NULL;
+ SECItem *ekp;
+ CERTCertDBHandle *certdb;
int save_error;
SECStatus rv;
- /* XXX sanity check - see if verification status is ok */
- /* XXX 0 = unverified */
+ certdb = CERT_GetDefaultCertDB();
+
+ /* sanity check - see if verification status is ok (unverified does not count...) */
+ if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature)
+ return SECFailure;
+
+ /* find preferred encryption cert */
+ if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr) &&
+ (attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL)
+ { /* we have a SMIME_ENCRYPTION_KEY_PREFERENCE attribute! */
+ ekp = NSS_CMSAttribute_GetValue(attr);
+ if (ekp == NULL)
+ return SECFailure;
+
+ /* we assume that all certs coming with the message have been imported to the */
+ /* temporary database */
+ cert = NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(certdb, ekp);
+ if (cert == NULL)
+ return SECFailure;
+ }
- /* XXX find preferred encyption cert */
+ if (cert == NULL) {
+ /* no preferred cert found?
+ * find the cert the signerinfo is signed with instead */
+ cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb);
+ if (cert == NULL || cert->emailAddr == NULL)
+ return SECFailure;
+ }
- /* find the cert the signerinfo is signed with */
- cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL);
- if (cert == NULL || cert->emailAddr == NULL)
+ /* verify this cert for encryption (has been verified for signing so far) */
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
return SECFailure;
+ }
+
+ /* XXX store encryption cert permanently? */
/*
* Remember the current error set because we do not care about
diff --git a/security/nss/lib/smime/smime.h b/security/nss/lib/smime/smime.h
index eb381461c..1832634f7 100644
--- a/security/nss/lib/smime/smime.h
+++ b/security/nss/lib/smime/smime.h
@@ -118,12 +118,23 @@ extern PRBool NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey
extern PRBool NSS_SMIMEUtil_EncryptionPossible(void);
/*
- * NSS_SMIMEUtil_GetSMIMECapabilities - get S/MIME capabilities for this instance of NSS
+ * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities attr value
*
* scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
* S/MIME capabilities attribute value.
*/
-extern SECStatus NSS_SMIMEUtil_GetSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers);
+extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers);
+
+/*
+ * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
+ */
+extern SECStatus NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert);
+
+/*
+ * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference - find cert marked by EncryptionKeyPreference
+ * attribute
+ */
+extern CERTCertificate *NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp);
/*
* NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients
diff --git a/security/nss/lib/smime/smimeutil.c b/security/nss/lib/smime/smimeutil.c
index 6f81f6fad..7d98b6a09 100644
--- a/security/nss/lib/smime/smimeutil.c
+++ b/security/nss/lib/smime/smimeutil.c
@@ -46,6 +46,7 @@
#include "cert.h"
#include "key.h"
#include "secerr.h"
+#include "cms.h"
/* various integer's ASN.1 encoding */
static unsigned char asn1_int40[] = { SEC_ASN1_INTEGER, 0x01, 0x28 };
@@ -68,7 +69,7 @@ typedef struct {
long cipher; /* optimization */
} NSSSMIMECapability;
-static const SEC_ASN1Template smime_capability_template[] = {
+static const SEC_ASN1Template NSSSMIMECapabilityTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(NSSSMIMECapability) },
{ SEC_ASN1_OBJECT_ID,
@@ -78,8 +79,48 @@ static const SEC_ASN1Template smime_capability_template[] = {
{ 0, }
};
-static const SEC_ASN1Template smime_capabilities_template[] = {
- { SEC_ASN1_SEQUENCE_OF, 0, smime_capability_template }
+static const SEC_ASN1Template NSSSMIMECapabilitiesTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF, 0, NSSSMIMECapabilityTemplate }
+};
+
+/*
+ * NSSSMIMEEncryptionKeyPreference - if we find one of these, it needs to prompt us
+ * to store this and only this certificate permanently for the sender email address.
+ */
+typedef enum {
+ NSSSMIMEEncryptionKeyPref_IssuerSN,
+ NSSSMIMEEncryptionKeyPref_RKeyID,
+ NSSSMIMEEncryptionKeyPref_SubjectKeyID
+} NSSSMIMEEncryptionKeyPrefSelector;
+
+typedef struct {
+ NSSSMIMEEncryptionKeyPrefSelector selector;
+ union {
+ CERTIssuerAndSN *issuerAndSN;
+ NSSCMSRecipientKeyIdentifier *recipientKeyID;
+ SECItem *subjectKeyID;
+ } id;
+} NSSSMIMEEncryptionKeyPreference;
+
+extern const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[];
+
+static const SEC_ASN1Template smime_encryptionkeypref_template[] = {
+ { SEC_ASN1_CHOICE,
+ offsetof(NSSSMIMEEncryptionKeyPreference,selector), NULL,
+ sizeof(NSSSMIMEEncryptionKeyPreference) },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(NSSSMIMEEncryptionKeyPreference,id.issuerAndSN),
+ CERT_IssuerAndSNTemplate,
+ NSSSMIMEEncryptionKeyPref_IssuerSN },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(NSSSMIMEEncryptionKeyPreference,id.recipientKeyID),
+ NSSCMSRecipientKeyIdentifierTemplate,
+ NSSSMIMEEncryptionKeyPref_IssuerSN },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 2,
+ offsetof(NSSSMIMEEncryptionKeyPreference,id.subjectKeyID),
+ SEC_OctetStringTemplate,
+ NSSSMIMEEncryptionKeyPref_SubjectKeyID },
+ { 0, }
};
/* smime_cipher_map - map of SMIME symmetric "ciphers" to algtag & parameters */
@@ -369,10 +410,10 @@ smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
profile = CERT_FindSMimeProfile(rcerts[rcount]);
if (profile != NULL && profile->data != NULL && profile->len > 0) {
- /* we have a profile */
+ /* we have a profile (still DER-encoded) */
caps = NULL;
/* decode it */
- if (SEC_ASN1DecodeItem(poolp, &caps, smime_capabilities_template, profile) == SECSuccess &&
+ if (SEC_ASN1DecodeItem(poolp, &caps, NSSSMIMECapabilitiesTemplate, profile) == SECSuccess &&
caps != NULL)
{
/* walk the SMIME capabilities for this recipient */
@@ -514,7 +555,7 @@ NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulk
}
/*
- * NSS_SMIMEUtil_GetSMIMECapabilities - get S/MIME capabilities for this instance of NSS
+ * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities for this instance of NSS
*
* scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
* S/MIME capabilities attribute value.
@@ -527,7 +568,7 @@ NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulk
* "includeFortezzaCiphers" - PR_TRUE if fortezza ciphers should be included
*/
SECStatus
-NSS_SMIMEUtil_GetSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers)
+NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool includeFortezzaCiphers)
{
NSSSMIMECapability *cap;
NSSSMIMECapability **smime_capabilities;
@@ -582,7 +623,7 @@ NSS_SMIMEUtil_GetSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool inc
/* XXX add key encipherment algorithms */
smime_capabilities[capIndex] = NULL; /* last one - now encode */
- dummy = SEC_ASN1EncodeItem(poolp, dest, &smime_capabilities, smime_capabilities_template);
+ dummy = SEC_ASN1EncodeItem(poolp, dest, &smime_capabilities, NSSSMIMECapabilitiesTemplate);
/* now that we have the proper encoded SMIMECapabilities (or not),
* free the work data */
@@ -592,3 +633,82 @@ NSS_SMIMEUtil_GetSMIMECapabilities(PLArenaPool *poolp, SECItem *dest, PRBool inc
return (dummy == NULL) ? SECFailure : SECSuccess;
}
+
+/*
+ * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
+ *
+ * "poolp" - arena pool to create the attr value on
+ * "dest" - SECItem to put the data in
+ * "cert" - certificate that should be marked as preferred encryption key
+ * cert is expected to have been verified for EmailRecipient usage.
+ */
+SECStatus
+NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert)
+{
+ NSSSMIMEEncryptionKeyPreference ekp;
+ SECItem *dummy = NULL;
+ PLArenaPool *tmppoolp;
+
+ if (cert == NULL)
+ goto loser;
+
+ tmppoolp = PORT_NewArena(1024);
+ if (tmppoolp == NULL)
+ goto loser;
+
+ /* XXX hardcoded IssuerSN choice for now */
+ ekp.selector = NSSSMIMEEncryptionKeyPref_IssuerSN;
+ ekp.id.issuerAndSN = CERT_GetCertIssuerAndSN(tmppoolp, cert);
+ if (ekp.id.issuerAndSN == NULL)
+ goto loser;
+
+ dummy = SEC_ASN1EncodeItem(poolp, dest, &ekp, smime_encryptionkeypref_template);
+
+loser:
+ if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference -
+ * find cert marked by EncryptionKeyPreference attribute
+ *
+ * "certdb" - handle for the cert database to look in
+ * "DERekp" - DER-encoded value of S/MIME Encryption Key Preference attribute
+ *
+ * if certificate is supposed to be found among the message's included certificates,
+ * they are assumed to have been imported already.
+ */
+CERTCertificate *
+NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp)
+{
+ PLArenaPool *tmppoolp = NULL;
+ CERTCertificate *cert = NULL;
+ NSSSMIMEEncryptionKeyPreference ekp;
+
+ tmppoolp = PORT_NewArena(1024);
+ if (tmppoolp == NULL)
+ return NULL;
+
+ /* decode DERekp */
+ if (SEC_ASN1DecodeItem(tmppoolp, &ekp, smime_encryptionkeypref_template, DERekp) != SECSuccess)
+ goto loser;
+
+ /* find cert */
+ switch (ekp.selector) {
+ case NSSSMIMEEncryptionKeyPref_IssuerSN:
+ cert = CERT_FindCertByIssuerAndSN(certdb, ekp.id.issuerAndSN);
+ break;
+ case NSSSMIMEEncryptionKeyPref_RKeyID:
+ case NSSSMIMEEncryptionKeyPref_SubjectKeyID:
+ /* XXX not supported yet - we need to be able to look up certs by SubjectKeyID */
+ break;
+ default:
+ PORT_Assert(0);
+ }
+loser:
+ if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
+
+ return cert;
+}
diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c
index 737a24ffd..3e6ec55df 100644
--- a/security/nss/lib/util/secoid.c
+++ b/security/nss/lib/util/secoid.c
@@ -127,6 +127,7 @@
#define PKCS9_CERT_TYPES PKCS9, 0x16
#define PKCS9_CRL_TYPES PKCS9, 0x17
#define PKCS9_SMIME_IDS PKCS9, 0x10
+#define PKCS9_SMIME_ATTRS PKCS9_SMIME_IDS, 2
#define PKCS9_SMIME_ALGS PKCS9_SMIME_IDS, 3
#define PKCS12_VERSION1 PKCS12, 0x0a
#define PKCS12_V1_BAG_IDS PKCS12_VERSION1, 1
@@ -391,6 +392,9 @@ static unsigned char cmsESDH[] = { PKCS9_SMIME_ALGS, 5 };
static unsigned char cms3DESwrap[] = { PKCS9_SMIME_ALGS, 6 };
static unsigned char cmsRC2wrap[] = { PKCS9_SMIME_ALGS, 7 };
+/* RFC2633 SMIME message attributes */
+static unsigned char smimeEncryptionKeyPreference[] = { PKCS9_SMIME_ATTRS, 11 };
+
/*
* NOTE: the order of these entries must mach the SECOidTag enum in secoidt.h!
*/
@@ -1205,6 +1209,12 @@ static SECOidData oids[] = {
SEC_OID_CMS_RC2_KEY_WRAP,
"CMS RC2 Key Wrap", CKM_INVALID_MECHANISM /* XXX */,
INVALID_CERT_EXTENSION },
+ { { siDEROID, smimeEncryptionKeyPreference,
+ sizeof(smimeEncryptionKeyPreference) },
+ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE,
+ "S/MIME Encryption Key Preference", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION },
+
};
/*
diff --git a/security/nss/lib/util/secoidt.h b/security/nss/lib/util/secoidt.h
index f3a1b7c59..66d3424a0 100644
--- a/security/nss/lib/util/secoidt.h
+++ b/security/nss/lib/util/secoidt.h
@@ -281,6 +281,9 @@ typedef enum {
SEC_OID_CMS_3DES_KEY_WRAP,
SEC_OID_CMS_RC2_KEY_WRAP,
+ /* SMIME attributes */
+ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE,
+
SEC_OID_TOTAL
} SECOidTag;