]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blame - nss/patches/0001-Add-support-for-PKCS-8-encoded-private-keys.patch
Move all packages to root.
[people/amarx/ipfire-3.x.git] / nss / patches / 0001-Add-support-for-PKCS-8-encoded-private-keys.patch
CommitLineData
137c9981
MT
1From 8bd0a0427e034262ff982fed98ca5e8c623165db Mon Sep 17 00:00:00 2001
2From: Rich Megginson <rmeggins@redhat.com>
3Date: Mon, 12 Jul 2010 16:31:01 -0600
4Subject: [PATCH] Add support for PKCS#8 encoded private keys
5
6The code supports PKCS#1 encoded RSA private keys that begin with the
7BEGIN RSA PRIVATE KEY header in PEM files. This patch adds support for
8RSA private keys encoded in PEM files that begin with the header
9BEGIN PRIVATE KEY which are in PKCS#8 format.
10---
11 prsa.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++------------------
12 util.c | 3 +-
13 2 files changed, 110 insertions(+), 43 deletions(-)
14
15diff --git a/prsa.c b/prsa.c
16index 5b2f379..8d4fb92 100644
17--- a/mozilla/security/nss/lib/ckfw/pem/prsa.c
18+++ b/mozilla/security/nss/lib/ckfw/pem/prsa.c
19@@ -63,6 +63,35 @@ const SEC_ASN1Template pem_RSAPrivateKeyTemplate[] = {
20 {0}
21 };
22
23+static const SEC_ASN1Template pem_AttributeTemplate[] = {
24+ { SEC_ASN1_SEQUENCE,
25+ 0, NULL, sizeof(NSSLOWKEYAttribute) },
26+ { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
27+ { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue),
28+ SEC_ASN1_SUB(SEC_AnyTemplate) },
29+ { 0 }
30+};
31+
32+static const SEC_ASN1Template pem_SetOfAttributeTemplate[] = {
33+ { SEC_ASN1_SET_OF, 0, pem_AttributeTemplate },
34+};
35+
36+const SEC_ASN1Template pem_PrivateKeyInfoTemplate[] = {
37+ { SEC_ASN1_SEQUENCE,
38+ 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
39+ { SEC_ASN1_INTEGER,
40+ offsetof(NSSLOWKEYPrivateKeyInfo,version) },
41+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
42+ offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
43+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
44+ { SEC_ASN1_OCTET_STRING,
45+ offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
46+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
47+ offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
48+ pem_SetOfAttributeTemplate },
49+ { 0 }
50+};
51+
52 /* Declarations */
53 SECStatus pem_RSA_Sign(pemLOWKEYPrivateKey * key, unsigned char *output,
54 unsigned int *outputLen, unsigned int maxOutputLen,
55@@ -116,6 +145,79 @@ pem_DestroyPrivateKey(pemLOWKEYPrivateKey * privk)
56 nss_ZFreeIf(privk);
57 }
58
59+/* decode and parse the rawkey into the lpk structure */
60+static pemLOWKEYPrivateKey *
61+pem_getPrivateKey(PLArenaPool *arena, SECItem *rawkey, CK_RV * pError, NSSItem *modulus)
62+{
63+ pemLOWKEYPrivateKey *lpk = NULL;
64+ SECStatus rv = SECFailure;
65+ NSSLOWKEYPrivateKeyInfo *pki = NULL;
66+ SECItem *keysrc = NULL;
67+
68+ /* make sure SECOID is initialized - not sure why we have to do this outside of nss_Init */
69+ if (SECSuccess != (rv = SECOID_Init())) {
70+ *pError = CKR_GENERAL_ERROR;
71+ return NULL; /* wha???? */
72+ }
73+
74+ pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
75+ sizeof(NSSLOWKEYPrivateKeyInfo));
76+ if(!pki) {
77+ *pError = CKR_HOST_MEMORY;
78+ goto done;
79+ }
80+
81+ /* let's first see if this is a "raw" RSA private key or an RSA private key in PKCS#8 format */
82+ rv = SEC_ASN1DecodeItem(arena, pki, pem_PrivateKeyInfoTemplate, rawkey);
83+ if (rv != SECSuccess) {
84+ /* not PKCS#8 - assume it's a "raw" RSA private key */
85+ keysrc = rawkey;
86+ } else if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_ENCRYPTION) {
87+ keysrc = &pki->privateKey;
88+ } else { /* unsupported */
89+ *pError = CKR_FUNCTION_NOT_SUPPORTED;
90+ goto done;
91+ }
92+
93+ lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL,
94+ sizeof(pemLOWKEYPrivateKey));
95+ if (lpk == NULL) {
96+ *pError = CKR_HOST_MEMORY;
97+ goto done;
98+ }
99+
100+ lpk->arena = arena;
101+ lpk->keyType = pemLOWKEYRSAKey;
102+ prepare_low_rsa_priv_key_for_asn1(lpk);
103+
104+ /* I don't know what this is supposed to accomplish. We free the old
105+ modulus data and set it again, making a copy of the new data.
106+ But we just allocated a new empty key structure above with
107+ nss_ZAlloc. So lpk->u.rsa.modulus.data is NULL and
108+ lpk->u.rsa.modulus.len. If the intention is to free the old
109+ modulus data, why not just set it to NULL after freeing? Why
110+ go through this unnecessary and confusing copying code?
111+ */
112+ if (modulus) {
113+ nss_ZFreeIf(modulus->data);
114+ modulus->data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
115+ modulus->size = lpk->u.rsa.modulus.len;
116+ nsslibc_memcpy(modulus->data, lpk->u.rsa.modulus.data,
117+ lpk->u.rsa.modulus.len);
118+ }
119+
120+ /* decode the private key and any algorithm parameters */
121+ rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
122+ keysrc);
123+
124+ if (rv != SECSuccess) {
125+ goto done;
126+ }
127+
128+done:
129+ return lpk;
130+}
131+
132 void
133 pem_PopulateModulusExponent(pemInternalObject * io)
134 {
135@@ -123,7 +225,7 @@ pem_PopulateModulusExponent(pemInternalObject * io)
136 const NSSItem *keyType = pem_FetchAttribute(io, CKA_KEY_TYPE);
137 pemLOWKEYPrivateKey *lpk = NULL;
138 PLArenaPool *arena;
139- SECStatus rv;
140+ CK_RV pError = 0;
141
142 /* make sure we have the right objects */
143 if (((const NSSItem *) NULL == classItem) ||
144@@ -140,26 +242,12 @@ pem_PopulateModulusExponent(pemInternalObject * io)
145 return;
146 }
147
148- lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL,
149- sizeof(pemLOWKEYPrivateKey));
150+ lpk = pem_getPrivateKey(arena, io->u.key.key.privateKey, &pError, NULL);
151 if (lpk == NULL) {
152 PORT_FreeArena(arena, PR_FALSE);
153 return;
154 }
155
156- lpk->arena = arena;
157- lpk->keyType = pemLOWKEYRSAKey;
158- prepare_low_rsa_priv_key_for_asn1(lpk);
159-
160- /* decode the private key and any algorithm parameters */
161- rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
162- io->u.key.key.privateKey);
163-
164- if (rv != SECSuccess) {
165- PORT_FreeArena(arena, PR_FALSE);
166- return;
167- }
168-
169 nss_ZFreeIf(io->u.key.key.modulus.data);
170 io->u.key.key.modulus.data =
171 (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
172@@ -252,13 +340,6 @@ pem_mdCryptoOperationRSAPriv_Create
173 pemInternalCryptoOperationRSAPriv *iOperation;
174 pemLOWKEYPrivateKey *lpk = NULL;
175 PLArenaPool *arena;
176- SECStatus rv;
177-
178- arena = PORT_NewArena(2048);
179- if (!arena) {
180- *pError = CKR_HOST_MEMORY;
181- return (NSSCKMDCryptoOperation *) NULL;
182- }
183
184 /* make sure we have the right objects */
185 if (((const NSSItem *) NULL == classItem) ||
186@@ -271,30 +352,15 @@ pem_mdCryptoOperationRSAPriv_Create
187 return (NSSCKMDCryptoOperation *) NULL;
188 }
189
190- lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL,
191- sizeof (pemLOWKEYPrivateKey));
192- if (lpk == NULL) {
193+ arena = PORT_NewArena(2048);
194+ if (!arena) {
195 *pError = CKR_HOST_MEMORY;
196 return (NSSCKMDCryptoOperation *) NULL;
197 }
198- lpk->arena = arena;
199- lpk->keyType = pemLOWKEYRSAKey;
200- prepare_low_rsa_priv_key_for_asn1(lpk);
201
202- nss_ZFreeIf(iKey->u.key.key.modulus.data);
203- iKey->u.key.key.modulus.data =
204- (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
205- iKey->u.key.key.modulus.size = lpk->u.rsa.modulus.len;
206- nsslibc_memcpy(iKey->u.key.key.modulus.data, lpk->u.rsa.modulus.data,
207- lpk->u.rsa.modulus.len);
208-
209- /* decode the private key and any algorithm parameters */
210- rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
211- iKey->u.key.key.privateKey);
212-
213- if (rv != SECSuccess) {
214+ lpk = pem_getPrivateKey(arena, iKey->u.key.key.privateKey, pError, &iKey->u.key.key.modulus);
215+ if (lpk == NULL) {
216 PORT_FreeArena(arena, PR_FALSE);
217- *pError = CKR_HOST_MEMORY;
218 return (NSSCKMDCryptoOperation *) NULL;
219 }
220
221diff --git a/util.c b/util.c
222index a6ca094..d02ee87 100644
223--- a/mozilla/security/nss/lib/ckfw/pem/util.c
224+++ b/mozilla/security/nss/lib/ckfw/pem/util.c
225@@ -164,7 +164,8 @@ ReadDERFromFile(SECItem *** derlist, char *filename, PRBool ascii,
226 int key = 0;
227 while ((asc) && ((body = strstr(asc, "-----BEGIN")) != NULL)) {
228 key = 0;
229- if (strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) {
230+ if ((strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) ||
231+ (strncmp(body, "-----BEGIN PRIVATE KEY", 21) == 0)) {
232 key = 1;
233 c = body;
234 body = strchr(body, '\n');
235--
2361.5.5.6
237