]> git.ipfire.org Git - people/arne_f/ipfire-3.x.git/blob - pkgs/nss/patches/0001-Add-support-for-PKCS-8-encoded-private-keys.patch
108bb9ab47cbfbc50e4534c5f8e08a02a17bcc65
[people/arne_f/ipfire-3.x.git] / pkgs / nss / patches / 0001-Add-support-for-PKCS-8-encoded-private-keys.patch
1 From 8bd0a0427e034262ff982fed98ca5e8c623165db Mon Sep 17 00:00:00 2001
2 From: Rich Megginson <rmeggins@redhat.com>
3 Date: Mon, 12 Jul 2010 16:31:01 -0600
4 Subject: [PATCH] Add support for PKCS#8 encoded private keys
5
6 The code supports PKCS#1 encoded RSA private keys that begin with the
7 BEGIN RSA PRIVATE KEY header in PEM files. This patch adds support for
8 RSA private keys encoded in PEM files that begin with the header
9 BEGIN 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
15 diff --git a/prsa.c b/prsa.c
16 index 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
221 diff --git a/util.c b/util.c
222 index 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 --
236 1.5.5.6
237