2 * Copyright (c) 2007, Cameron Rich
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * * Neither the name of the axTLS project nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 * Process PKCS#8/PKCS#12 keys.
34 * The decoding of a PKCS#12 key is fairly specific - this code was tested on a
37 * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
38 * -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128
39 * -name "p12_withoutCA" -out axTLS.withoutCA.p12 -password pass:abcd
41 * or with a certificate chain:
43 * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem
44 * -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe
45 * PBE-SHA1-RC4-128 -name "p12_withCA" -out axTLS.withCA.p12 -password pass:abcd
47 * Note that the PBE has to be specified with PBE-SHA1-RC4-128. The
48 * private/public keys/certs have to use RSA encryption. Both the integrity
49 * and privacy passwords are the same.
51 * The PKCS#8 files were generated with something like:
54 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1
55 * PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8
58 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER
59 * -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8
68 /* all commented out if not used */
69 #ifdef CONFIG_SSL_USE_PKCS12
72 #define PKCS12_KEY_ID 1
73 #define PKCS12_IV_ID 2
74 #define PKCS12_MAC_ID 3
76 static char *make_uni_pass(const char *password
, int *uni_pass_len
);
77 static int p8_decrypt(const char *uni_pass
, int uni_pass_len
,
78 const uint8_t *salt
, int iter
,
79 uint8_t *priv_key
, int priv_key_len
, int id
);
80 static int p8_add_key(SSL_CTX
*ssl_ctx
, uint8_t *priv_key
);
81 static int get_pbe_params(uint8_t *buf
, int *offset
,
82 const uint8_t **salt
, int *iterations
);
85 * Take a raw pkcs8 block and then decrypt it and turn it into a normal key.
87 int pkcs8_decode(SSL_CTX
*ssl_ctx
, SSLObjLoader
*ssl_obj
, const char *password
)
89 uint8_t *buf
= ssl_obj
->buf
;
93 uint8_t *version
= NULL
;
97 char *uni_pass
= make_uni_pass(password
, &uni_pass_len
);
99 if (asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0)
101 #ifdef CONFIG_SSL_FULL_MODE
102 printf("Error: Invalid p8 ASN.1 file\n");
107 /* unencrypted key? */
108 if (asn1_get_int(buf
, &offset
, &version
) > 0 && *version
== 0)
110 ret
= p8_add_key(ssl_ctx
, buf
);
114 if (get_pbe_params(buf
, &offset
, &salt
, &iterations
) < 0)
117 if ((len
= asn1_next_obj(buf
, &offset
, ASN1_OCTET_STRING
)) < 0)
120 priv_key
= &buf
[offset
];
122 p8_decrypt(uni_pass
, uni_pass_len
, salt
,
123 iterations
, priv_key
, len
, PKCS12_KEY_ID
);
124 ret
= p8_add_key(ssl_ctx
, priv_key
);
133 * Take the unencrypted pkcs8 and turn it into a private key
135 static int p8_add_key(SSL_CTX
*ssl_ctx
, uint8_t *priv_key
)
137 uint8_t *buf
= priv_key
;
139 int ret
= SSL_NOT_OK
;
141 /* Skip the preamble and go straight to the private key.
142 We only support rsaEncryption (1.2.840.113549.1.1.1) */
143 if (asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
144 asn1_skip_obj(buf
, &offset
, ASN1_INTEGER
) < 0 ||
145 asn1_skip_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
146 (len
= asn1_next_obj(buf
, &offset
, ASN1_OCTET_STRING
)) < 0)
149 ret
= asn1_get_private_key(&buf
[offset
], len
, &ssl_ctx
->rsa_ctx
);
156 * Create the unicode password
158 static char *make_uni_pass(const char *password
, int *uni_pass_len
)
163 if (password
== NULL
)
168 uni_pass
= (char *)malloc((strlen(password
)+1)*2);
170 /* modify the password into a unicode version */
171 for (i
= 0; i
< (int)strlen(password
); i
++)
173 uni_pass
[pass_len
++] = 0;
174 uni_pass
[pass_len
++] = password
[i
];
177 uni_pass
[pass_len
++] = 0; /* null terminate */
178 uni_pass
[pass_len
++] = 0;
179 *uni_pass_len
= pass_len
;
184 * Decrypt a pkcs8 block.
186 static int p8_decrypt(const char *uni_pass
, int uni_pass_len
,
187 const uint8_t *salt
, int iter
,
188 uint8_t *priv_key
, int priv_key_len
, int id
)
190 uint8_t p
[BLOCK_SIZE
*2];
191 uint8_t d
[BLOCK_SIZE
];
192 uint8_t Ai
[SHA1_SIZE
];
197 for (i
= 0; i
< BLOCK_SIZE
; i
++)
199 p
[i
] = salt
[i
% SALT_SIZE
];
200 p
[BLOCK_SIZE
+i
] = uni_pass
[i
% uni_pass_len
];
204 /* get the key - no IV since we are using RC4 */
206 SHA1_Update(&sha_ctx
, d
, sizeof(d
));
207 SHA1_Update(&sha_ctx
, p
, sizeof(p
));
208 SHA1_Final(Ai
, &sha_ctx
);
210 for (i
= 1; i
< iter
; i
++)
213 SHA1_Update(&sha_ctx
, Ai
, SHA1_SIZE
);
214 SHA1_Final(Ai
, &sha_ctx
);
217 /* do the decryption */
218 if (id
== PKCS12_KEY_ID
)
220 RC4_setup(&rc4_ctx
, Ai
, 16);
221 RC4_crypt(&rc4_ctx
, priv_key
, priv_key
, priv_key_len
);
224 memcpy(priv_key
, Ai
, SHA1_SIZE
);
230 * Take a raw pkcs12 block and the decrypt it and turn it into a certificate(s)
233 int pkcs12_decode(SSL_CTX
*ssl_ctx
, SSLObjLoader
*ssl_obj
, const char *password
)
235 uint8_t *buf
= ssl_obj
->buf
;
236 int len
, iterations
, auth_safes_start
,
237 auth_safes_end
, auth_safes_len
, key_offset
, offset
= 0;
239 uint8_t *version
= NULL
, *auth_safes
= NULL
, *cert
, *orig_mac
;
240 uint8_t key
[SHA1_SIZE
];
241 uint8_t mac
[SHA1_SIZE
];
243 int uni_pass_len
, ret
= SSL_OK
;
244 char *uni_pass
= make_uni_pass(password
, &uni_pass_len
);
245 static const uint8_t pkcs_data
[] = /* pkc7 data */
246 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 };
247 static const uint8_t pkcs_encrypted
[] = /* pkc7 encrypted */
248 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06 };
249 static const uint8_t pkcs8_key_bag
[] = /* 1.2.840.113549.1.12.10.1.2 */
250 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02 };
252 if (asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0)
254 #ifdef CONFIG_SSL_FULL_MODE
255 printf("Error: Invalid p12 ASN.1 file\n");
260 if (asn1_get_int(buf
, &offset
, &version
) < 0 || *version
!= 3)
262 ret
= SSL_ERROR_INVALID_VERSION
;
266 /* remove all the boring pcks7 bits */
267 if (asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
268 (len
= asn1_next_obj(buf
, &offset
, ASN1_OID
)) < 0 ||
269 len
!= sizeof(pkcs_data
) ||
270 memcmp(&buf
[offset
], pkcs_data
, sizeof(pkcs_data
)))
275 if (asn1_next_obj(buf
, &offset
, ASN1_EXPLICIT_TAG
) < 0 ||
276 asn1_next_obj(buf
, &offset
, ASN1_OCTET_STRING
) < 0)
279 /* work out the MAC start/end points (done on AuthSafes) */
280 auth_safes_start
= offset
;
281 auth_safes_end
= offset
;
282 if (asn1_skip_obj(buf
, &auth_safes_end
, ASN1_SEQUENCE
) < 0)
285 auth_safes_len
= auth_safes_end
- auth_safes_start
;
286 auth_safes
= malloc(auth_safes_len
);
288 memcpy(auth_safes
, &buf
[auth_safes_start
], auth_safes_len
);
290 if (asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
291 asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
292 (len
= asn1_next_obj(buf
, &offset
, ASN1_OID
)) < 0 ||
293 (len
!= sizeof(pkcs_encrypted
) ||
294 memcmp(&buf
[offset
], pkcs_encrypted
, sizeof(pkcs_encrypted
))))
299 if (asn1_next_obj(buf
, &offset
, ASN1_EXPLICIT_TAG
) < 0 ||
300 asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
301 asn1_skip_obj(buf
, &offset
, ASN1_INTEGER
) < 0 ||
302 asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
303 (len
= asn1_next_obj(buf
, &offset
, ASN1_OID
)) < 0 ||
304 len
!= sizeof(pkcs_data
) ||
305 memcmp(&buf
[offset
], pkcs_data
, sizeof(pkcs_data
)))
310 /* work out the salt for the certificate */
311 if (get_pbe_params(buf
, &offset
, &salt
, &iterations
) < 0 ||
312 (len
= asn1_next_obj(buf
, &offset
, ASN1_IMPLICIT_TAG
)) < 0)
315 /* decrypt the certificate */
317 if ((ret
= p8_decrypt(uni_pass
, uni_pass_len
, salt
, iterations
, cert
,
318 len
, PKCS12_KEY_ID
)) < 0)
323 /* load the certificate */
325 all_certs
= asn1_next_obj(cert
, &key_offset
, ASN1_SEQUENCE
);
327 /* keep going until all certs are loaded */
328 while (key_offset
< all_certs
)
330 int cert_offset
= key_offset
;
332 if (asn1_skip_obj(cert
, &cert_offset
, ASN1_SEQUENCE
) < 0 ||
333 asn1_next_obj(cert
, &key_offset
, ASN1_SEQUENCE
) < 0 ||
334 asn1_skip_obj(cert
, &key_offset
, ASN1_OID
) < 0 ||
335 asn1_next_obj(cert
, &key_offset
, ASN1_EXPLICIT_TAG
) < 0 ||
336 asn1_next_obj(cert
, &key_offset
, ASN1_SEQUENCE
) < 0 ||
337 asn1_skip_obj(cert
, &key_offset
, ASN1_OID
) < 0 ||
338 asn1_next_obj(cert
, &key_offset
, ASN1_EXPLICIT_TAG
) < 0 ||
339 (len
= asn1_next_obj(cert
, &key_offset
, ASN1_OCTET_STRING
)) < 0)
342 if ((ret
= add_cert(ssl_ctx
, &cert
[key_offset
], len
)) < 0)
345 key_offset
= cert_offset
;
348 if (asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
349 (len
= asn1_next_obj(buf
, &offset
, ASN1_OID
)) < 0 ||
350 len
!= sizeof(pkcs_data
) ||
351 memcmp(&buf
[offset
], pkcs_data
, sizeof(pkcs_data
)))
356 if (asn1_next_obj(buf
, &offset
, ASN1_EXPLICIT_TAG
) < 0 ||
357 asn1_next_obj(buf
, &offset
, ASN1_OCTET_STRING
) < 0 ||
358 asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
359 asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
360 (len
= asn1_next_obj(buf
, &offset
, ASN1_OID
)) < 0 ||
361 (len
!= sizeof(pkcs8_key_bag
)) ||
362 memcmp(&buf
[offset
], pkcs8_key_bag
, sizeof(pkcs8_key_bag
)))
367 /* work out the salt for the private key */
368 if (asn1_next_obj(buf
, &offset
, ASN1_EXPLICIT_TAG
) < 0 ||
369 asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
370 get_pbe_params(buf
, &offset
, &salt
, &iterations
) < 0 ||
371 (len
= asn1_next_obj(buf
, &offset
, ASN1_OCTET_STRING
)) < 0)
374 /* decrypt the private key */
376 if ((ret
= p8_decrypt(uni_pass
, uni_pass_len
, salt
, iterations
, cert
,
377 len
, PKCS12_KEY_ID
)) < 0)
382 /* load the private key */
383 if ((ret
= p8_add_key(ssl_ctx
, cert
)) < 0)
386 /* miss out on friendly name, local key id etc */
387 if (asn1_skip_obj(buf
, &offset
, ASN1_SET
) < 0)
390 /* work out the MAC */
391 if (asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
392 asn1_next_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
393 asn1_skip_obj(buf
, &offset
, ASN1_SEQUENCE
) < 0 ||
394 (len
= asn1_next_obj(buf
, &offset
, ASN1_OCTET_STRING
)) < 0 ||
398 orig_mac
= &buf
[offset
];
402 if ((len
= asn1_next_obj(buf
, &offset
, ASN1_OCTET_STRING
)) < 0 || len
!= 8)
407 /* work out what the mac should be */
408 if ((ret
= p8_decrypt(uni_pass
, uni_pass_len
, salt
, iterations
,
409 key
, SHA1_SIZE
, PKCS12_MAC_ID
)) < 0)
412 hmac_sha1(auth_safes
, auth_safes_len
, key
, SHA1_SIZE
, mac
);
414 if (memcmp(mac
, orig_mac
, SHA1_SIZE
))
416 ret
= SSL_ERROR_INVALID_HMAC
;
428 * Retrieve the salt/iteration details from a PBE block.
430 static int get_pbe_params(uint8_t *buf
, int *offset
,
431 const uint8_t **salt
, int *iterations
)
433 static const uint8_t pbeSH1RC4
[] = /* pbeWithSHAAnd128BitRC4 */
434 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 };
437 uint8_t *iter
= NULL
;
438 int error_code
= SSL_ERROR_NOT_SUPPORTED
;
440 /* Get the PBE type */
441 if (asn1_next_obj(buf
, offset
, ASN1_SEQUENCE
) < 0 ||
442 (len
= asn1_next_obj(buf
, offset
, ASN1_OID
)) < 0)
445 /* we expect pbeWithSHAAnd128BitRC4 (1.2.840.113549.1.12.1.1)
446 which is the only algorithm we support */
447 if (len
!= sizeof(pbeSH1RC4
) ||
448 memcmp(&buf
[*offset
], pbeSH1RC4
, sizeof(pbeSH1RC4
)))
450 #ifdef CONFIG_SSL_FULL_MODE
451 printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n");
458 if (asn1_next_obj(buf
, offset
, ASN1_SEQUENCE
) < 0 ||
459 (len
= asn1_next_obj(buf
, offset
, ASN1_OCTET_STRING
)) < 0 ||
463 *salt
= &buf
[*offset
];
466 if ((len
= asn1_get_int(buf
, offset
, &iter
)) < 0)
470 for (i
= 0; i
< len
; i
++)
473 (*iterations
) += iter
[i
];
477 error_code
= SSL_OK
; /* got here - we are ok */