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 all_ok = 0, 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;
244 int error_code = SSL_ERROR_NOT_SUPPORTED;
245 char *uni_pass = make_uni_pass(password, &uni_pass_len);
246 static const uint8_t pkcs_data[] = /* pkc7 data */
247 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 };
248 static const uint8_t pkcs_encrypted[] = /* pkc7 encrypted */
249 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06 };
250 static const uint8_t pkcs8_key_bag[] = /* 1.2.840.113549.1.12.10.1.2 */
251 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02 };
253 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
255 #ifdef CONFIG_SSL_FULL_MODE
256 printf("Error: Invalid p12 ASN.1 file\n");
261 if (asn1_get_int(buf, &offset, &version) < 0 || *version != 3)
263 error_code = SSL_ERROR_INVALID_VERSION;
267 /* remove all the boring pcks7 bits */
268 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
269 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
270 len != sizeof(pkcs_data) ||
271 memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
276 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
277 asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0)
280 /* work out the MAC start/end points (done on AuthSafes) */
281 auth_safes_start = offset;
282 auth_safes_end = offset;
283 if (asn1_skip_obj(buf, &auth_safes_end, ASN1_SEQUENCE) < 0)
286 auth_safes_len = auth_safes_end - auth_safes_start;
287 auth_safes = malloc(auth_safes_len);
289 memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len);
291 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
292 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
293 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
294 (len != sizeof(pkcs_encrypted) ||
295 memcmp(&buf[offset], pkcs_encrypted, sizeof(pkcs_encrypted))))
300 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
301 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
302 asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 ||
303 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
304 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
305 len != sizeof(pkcs_data) ||
306 memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
311 /* work out the salt for the certificate */
312 if (get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
313 (len = asn1_next_obj(buf, &offset, ASN1_IMPLICIT_TAG)) < 0)
316 /* decrypt the certificate */
318 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
319 len, PKCS12_KEY_ID)) < 0)
324 /* load the certificate */
326 all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE);
328 /* keep going until all certs are loaded */
329 while (key_offset < all_certs)
331 int cert_offset = key_offset;
333 if (asn1_skip_obj(cert, &cert_offset, ASN1_SEQUENCE) < 0 ||
334 asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
335 asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
336 asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
337 asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 ||
338 asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 ||
339 asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 ||
340 (len = asn1_next_obj(cert, &key_offset, ASN1_OCTET_STRING)) < 0)
343 if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0)
346 key_offset = cert_offset;
349 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
350 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
351 len != sizeof(pkcs_data) ||
352 memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data)))
357 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
358 asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0 ||
359 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
360 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
361 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 ||
362 (len != sizeof(pkcs8_key_bag)) ||
363 memcmp(&buf[offset], pkcs8_key_bag, sizeof(pkcs8_key_bag)))
368 /* work out the salt for the private key */
369 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
370 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
371 get_pbe_params(buf, &offset, &salt, &iterations) < 0 ||
372 (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
375 /* decrypt the private key */
377 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
378 len, PKCS12_KEY_ID)) < 0)
383 /* load the private key */
384 if ((ret = p8_add_key(ssl_ctx, cert)) < 0)
387 /* miss out on friendly name, local key id etc */
388 if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0)
391 /* work out the MAC */
392 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
393 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
394 asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 ||
395 (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 ||
399 orig_mac = &buf[offset];
403 if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8)
408 /* work out what the mac should be */
409 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations,
410 key, SHA1_SIZE, PKCS12_MAC_ID)) < 0)
413 hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac);
415 if (memcmp(mac, orig_mac, SHA1_SIZE))
417 error_code = SSL_ERROR_INVALID_HMAC;
427 return all_ok ? SSL_OK : error_code;
431 * Retrieve the salt/iteration details from a PBE block.
433 static int get_pbe_params(uint8_t *buf, int *offset,
434 const uint8_t **salt, int *iterations)
436 static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4 */
437 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 };
440 uint8_t *iter = NULL;
441 int error_code = SSL_ERROR_NOT_SUPPORTED;
443 /* Get the PBE type */
444 if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
445 (len = asn1_next_obj(buf, offset, ASN1_OID)) < 0)
448 /* we expect pbeWithSHAAnd128BitRC4 (1.2.840.113549.1.12.1.1)
449 which is the only algorithm we support */
450 if (len != sizeof(pbeSH1RC4) ||
451 memcmp(&buf[*offset], pbeSH1RC4, sizeof(pbeSH1RC4)))
453 #ifdef CONFIG_SSL_FULL_MODE
454 printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n");
461 if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
462 (len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 ||
466 *salt = &buf[*offset];
469 if ((len = asn1_get_int(buf, offset, &iter)) < 0)
473 for (i = 0; i < len; i++)
476 (*iterations) += iter[i];
480 error_code = SSL_OK; /* got here - we are ok */