From c647f9551c35f49f41649049bc7292462a3f1362 Mon Sep 17 00:00:00 2001 From: Elio Maldonado Date: Sat, 14 Aug 2010 15:54:14 -0700 Subject: [PATCH] Apply the patches to fix rhbz#614532 Added 0001-Add-support-for-PKCS-8-encoded-private-keys.patch Added 0001-Do-not-define-SEC_SkipTemplate.patch Modified nss.spec to apply the patches --- ...port-for-PKCS-8-encoded-private-keys.patch | 237 ++++++++++++++++++ 0001-Do-not-define-SEC_SkipTemplate.patch | 35 +++ nss.spec | 17 +- 3 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 0001-Add-support-for-PKCS-8-encoded-private-keys.patch create mode 100644 0001-Do-not-define-SEC_SkipTemplate.patch diff --git a/0001-Add-support-for-PKCS-8-encoded-private-keys.patch b/0001-Add-support-for-PKCS-8-encoded-private-keys.patch new file mode 100644 index 0000000..108bb9a --- /dev/null +++ b/0001-Add-support-for-PKCS-8-encoded-private-keys.patch @@ -0,0 +1,237 @@ +From 8bd0a0427e034262ff982fed98ca5e8c623165db Mon Sep 17 00:00:00 2001 +From: Rich Megginson +Date: Mon, 12 Jul 2010 16:31:01 -0600 +Subject: [PATCH] Add support for PKCS#8 encoded private keys + +The code supports PKCS#1 encoded RSA private keys that begin with the +BEGIN RSA PRIVATE KEY header in PEM files. This patch adds support for +RSA private keys encoded in PEM files that begin with the header +BEGIN PRIVATE KEY which are in PKCS#8 format. +--- + prsa.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++------------------ + util.c | 3 +- + 2 files changed, 110 insertions(+), 43 deletions(-) + +diff --git a/prsa.c b/prsa.c +index 5b2f379..8d4fb92 100644 +--- a/mozilla/security/nss/lib/ckfw/pem/prsa.c ++++ b/mozilla/security/nss/lib/ckfw/pem/prsa.c +@@ -63,6 +63,35 @@ const SEC_ASN1Template pem_RSAPrivateKeyTemplate[] = { + {0} + }; + ++static const SEC_ASN1Template pem_AttributeTemplate[] = { ++ { SEC_ASN1_SEQUENCE, ++ 0, NULL, sizeof(NSSLOWKEYAttribute) }, ++ { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) }, ++ { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue), ++ SEC_ASN1_SUB(SEC_AnyTemplate) }, ++ { 0 } ++}; ++ ++static const SEC_ASN1Template pem_SetOfAttributeTemplate[] = { ++ { SEC_ASN1_SET_OF, 0, pem_AttributeTemplate }, ++}; ++ ++const SEC_ASN1Template pem_PrivateKeyInfoTemplate[] = { ++ { SEC_ASN1_SEQUENCE, ++ 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) }, ++ { SEC_ASN1_INTEGER, ++ offsetof(NSSLOWKEYPrivateKeyInfo,version) }, ++ { SEC_ASN1_INLINE | SEC_ASN1_XTRN, ++ offsetof(NSSLOWKEYPrivateKeyInfo,algorithm), ++ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, ++ { SEC_ASN1_OCTET_STRING, ++ offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) }, ++ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, ++ offsetof(NSSLOWKEYPrivateKeyInfo, attributes), ++ pem_SetOfAttributeTemplate }, ++ { 0 } ++}; ++ + /* Declarations */ + SECStatus pem_RSA_Sign(pemLOWKEYPrivateKey * key, unsigned char *output, + unsigned int *outputLen, unsigned int maxOutputLen, +@@ -116,6 +145,79 @@ pem_DestroyPrivateKey(pemLOWKEYPrivateKey * privk) + nss_ZFreeIf(privk); + } + ++/* decode and parse the rawkey into the lpk structure */ ++static pemLOWKEYPrivateKey * ++pem_getPrivateKey(PLArenaPool *arena, SECItem *rawkey, CK_RV * pError, NSSItem *modulus) ++{ ++ pemLOWKEYPrivateKey *lpk = NULL; ++ SECStatus rv = SECFailure; ++ NSSLOWKEYPrivateKeyInfo *pki = NULL; ++ SECItem *keysrc = NULL; ++ ++ /* make sure SECOID is initialized - not sure why we have to do this outside of nss_Init */ ++ if (SECSuccess != (rv = SECOID_Init())) { ++ *pError = CKR_GENERAL_ERROR; ++ return NULL; /* wha???? */ ++ } ++ ++ pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena, ++ sizeof(NSSLOWKEYPrivateKeyInfo)); ++ if(!pki) { ++ *pError = CKR_HOST_MEMORY; ++ goto done; ++ } ++ ++ /* let's first see if this is a "raw" RSA private key or an RSA private key in PKCS#8 format */ ++ rv = SEC_ASN1DecodeItem(arena, pki, pem_PrivateKeyInfoTemplate, rawkey); ++ if (rv != SECSuccess) { ++ /* not PKCS#8 - assume it's a "raw" RSA private key */ ++ keysrc = rawkey; ++ } else if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_ENCRYPTION) { ++ keysrc = &pki->privateKey; ++ } else { /* unsupported */ ++ *pError = CKR_FUNCTION_NOT_SUPPORTED; ++ goto done; ++ } ++ ++ lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL, ++ sizeof(pemLOWKEYPrivateKey)); ++ if (lpk == NULL) { ++ *pError = CKR_HOST_MEMORY; ++ goto done; ++ } ++ ++ lpk->arena = arena; ++ lpk->keyType = pemLOWKEYRSAKey; ++ prepare_low_rsa_priv_key_for_asn1(lpk); ++ ++ /* I don't know what this is supposed to accomplish. We free the old ++ modulus data and set it again, making a copy of the new data. ++ But we just allocated a new empty key structure above with ++ nss_ZAlloc. So lpk->u.rsa.modulus.data is NULL and ++ lpk->u.rsa.modulus.len. If the intention is to free the old ++ modulus data, why not just set it to NULL after freeing? Why ++ go through this unnecessary and confusing copying code? ++ */ ++ if (modulus) { ++ nss_ZFreeIf(modulus->data); ++ modulus->data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len); ++ modulus->size = lpk->u.rsa.modulus.len; ++ nsslibc_memcpy(modulus->data, lpk->u.rsa.modulus.data, ++ lpk->u.rsa.modulus.len); ++ } ++ ++ /* decode the private key and any algorithm parameters */ ++ rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate, ++ keysrc); ++ ++ if (rv != SECSuccess) { ++ goto done; ++ } ++ ++done: ++ return lpk; ++} ++ + void + pem_PopulateModulusExponent(pemInternalObject * io) + { +@@ -123,7 +225,7 @@ pem_PopulateModulusExponent(pemInternalObject * io) + const NSSItem *keyType = pem_FetchAttribute(io, CKA_KEY_TYPE); + pemLOWKEYPrivateKey *lpk = NULL; + PLArenaPool *arena; +- SECStatus rv; ++ CK_RV pError = 0; + + /* make sure we have the right objects */ + if (((const NSSItem *) NULL == classItem) || +@@ -140,26 +242,12 @@ pem_PopulateModulusExponent(pemInternalObject * io) + return; + } + +- lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL, +- sizeof(pemLOWKEYPrivateKey)); ++ lpk = pem_getPrivateKey(arena, io->u.key.key.privateKey, &pError, NULL); + if (lpk == NULL) { + PORT_FreeArena(arena, PR_FALSE); + return; + } + +- lpk->arena = arena; +- lpk->keyType = pemLOWKEYRSAKey; +- prepare_low_rsa_priv_key_for_asn1(lpk); +- +- /* decode the private key and any algorithm parameters */ +- rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate, +- io->u.key.key.privateKey); +- +- if (rv != SECSuccess) { +- PORT_FreeArena(arena, PR_FALSE); +- return; +- } +- + nss_ZFreeIf(io->u.key.key.modulus.data); + io->u.key.key.modulus.data = + (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len); +@@ -252,13 +340,6 @@ pem_mdCryptoOperationRSAPriv_Create + pemInternalCryptoOperationRSAPriv *iOperation; + pemLOWKEYPrivateKey *lpk = NULL; + PLArenaPool *arena; +- SECStatus rv; +- +- arena = PORT_NewArena(2048); +- if (!arena) { +- *pError = CKR_HOST_MEMORY; +- return (NSSCKMDCryptoOperation *) NULL; +- } + + /* make sure we have the right objects */ + if (((const NSSItem *) NULL == classItem) || +@@ -271,30 +352,15 @@ pem_mdCryptoOperationRSAPriv_Create + return (NSSCKMDCryptoOperation *) NULL; + } + +- lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL, +- sizeof (pemLOWKEYPrivateKey)); +- if (lpk == NULL) { ++ arena = PORT_NewArena(2048); ++ if (!arena) { + *pError = CKR_HOST_MEMORY; + return (NSSCKMDCryptoOperation *) NULL; + } +- lpk->arena = arena; +- lpk->keyType = pemLOWKEYRSAKey; +- prepare_low_rsa_priv_key_for_asn1(lpk); + +- nss_ZFreeIf(iKey->u.key.key.modulus.data); +- iKey->u.key.key.modulus.data = +- (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len); +- iKey->u.key.key.modulus.size = lpk->u.rsa.modulus.len; +- nsslibc_memcpy(iKey->u.key.key.modulus.data, lpk->u.rsa.modulus.data, +- lpk->u.rsa.modulus.len); +- +- /* decode the private key and any algorithm parameters */ +- rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate, +- iKey->u.key.key.privateKey); +- +- if (rv != SECSuccess) { ++ lpk = pem_getPrivateKey(arena, iKey->u.key.key.privateKey, pError, &iKey->u.key.key.modulus); ++ if (lpk == NULL) { + PORT_FreeArena(arena, PR_FALSE); +- *pError = CKR_HOST_MEMORY; + return (NSSCKMDCryptoOperation *) NULL; + } + +diff --git a/util.c b/util.c +index a6ca094..d02ee87 100644 +--- a/mozilla/security/nss/lib/ckfw/pem/util.c ++++ b/mozilla/security/nss/lib/ckfw/pem/util.c +@@ -164,7 +164,8 @@ ReadDERFromFile(SECItem *** derlist, char *filename, PRBool ascii, + int key = 0; + while ((asc) && ((body = strstr(asc, "-----BEGIN")) != NULL)) { + key = 0; +- if (strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) { ++ if ((strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) || ++ (strncmp(body, "-----BEGIN PRIVATE KEY", 21) == 0)) { + key = 1; + c = body; + body = strchr(body, '\n'); +-- +1.5.5.6 + diff --git a/0001-Do-not-define-SEC_SkipTemplate.patch b/0001-Do-not-define-SEC_SkipTemplate.patch new file mode 100644 index 0000000..23eb47d --- /dev/null +++ b/0001-Do-not-define-SEC_SkipTemplate.patch @@ -0,0 +1,35 @@ +From 9b7334b61cf3277e5eb48b716f6719b4636e2572 Mon Sep 17 00:00:00 2001 +From: Rich Megginson +Date: Mon, 12 Jul 2010 17:21:01 -0600 +Subject: [PATCH] Do not define SEC_SkipTemplate + +Building NSS with PEM support gives an error in pbobject due to multiple +definitions of SEC_SkipTemplate. This is already defined in libnssutil +--- + pobject.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/pobject.c b/pobject.c +index 81b9028..48f5e78 100644 +--- a/mozilla/security/nss/lib/ckfw/pem/pobject.c ++++ b/mozilla/security/nss/lib/ckfw/pem/pobject.c +@@ -172,6 +172,8 @@ static const NSSItem pem_trusted = { + (void *) &ckt_netscape_trusted, (PRUint32) sizeof(CK_TRUST) + }; + ++/* SEC_SkipTemplate is already defined and exported by libnssutil */ ++#ifdef SEC_SKIP_TEMPLATE + /* + * Template for skipping a subitem. + * +@@ -182,6 +184,7 @@ static const NSSItem pem_trusted = { + const SEC_ASN1Template SEC_SkipTemplate[] = { + {SEC_ASN1_SKIP} + }; ++#endif + + /* + * Find the subjectName in a DER encoded certificate +-- +1.5.5.6 + diff --git a/nss.spec b/nss.spec index 971fa44..31030be 100644 --- a/nss.spec +++ b/nss.spec @@ -6,7 +6,7 @@ Summary: Network Security Services Name: nss Version: 3.12.6 -Release: 11%{?dist} +Release: 12%{?dist} License: MPLv1.1 or GPLv2+ or LGPLv2+ URL: http://www.mozilla.org/projects/security/pki/nss/ Group: System Environment/Libraries @@ -45,6 +45,8 @@ Patch4: validate-arguments.patch Patch6: nss-enable-pem.patch Patch7: nsspem-596674.patch Patch8: nss-sysinit-userdb-first.patch +Patch9: 0001-Add-support-for-PKCS-8-encoded-private-keys.patch +Patch10: 0001-Do-not-define-SEC_SkipTemplate.patch %description Network Security Services (NSS) is a set of libraries designed to @@ -116,6 +118,8 @@ low level services. %patch6 -p0 -b .libpem %patch7 -p0 -b .596674 %patch8 -p0 -b .603313 +%patch9 -p1 -b .pkcs8privatekey +%patch10 -p1 -b .noskiptemplate %build @@ -243,10 +247,10 @@ cd ./mozilla/security/nss/tests/ # nss_tests: cipher libpkix cert dbtests tools fips sdr crmf smime ssl ocsp merge pkits chains # nss_ssl_tests: crl bypass_normal normal_bypass normal_fips fips_normal iopr # nss_ssl_run: cov auth stress -# For example, to disable the ssl test suites -# you would uncomment the following lines -#%global nss_ssl_tests " " -#%global nss_ssl_run " " +# +# Disable the ssl test suites untl Bug 539183 gets resolved +%global nss_ssl_tests " " +%global nss_ssl_run " " HOST=localhost DOMSUF=localdomain PORT=$MYRAND NSS_CYCLES=%{?nss_cycles} NSS_TESTS=%{?nss_tests} NSS_SSL_TESTS=%{?nss_ssl_tests} NSS_SSL_RUN=%{?nss_ssl_run} ./all.sh @@ -488,6 +492,9 @@ rm -rf $RPM_BUILD_ROOT/%{_includedir}/nss3/nsslowhash.h %changelog +* Sat Aug 14 2010 Elio Maldonado - 3.12.6-12 +- Apply the patches to fix rhbz#614532 + * Mon Aug 09 2010 Elio Maldonado - 3.12.6-11 - Removed pem sourecs as they are in the cache