]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/net/https/axTLS/ssl/p12.c
Merge commit 'fdc38ef3f92af7adeeb4de49550d8838c8a39b5c'
[tmk_keyboard.git] / tmk_core / tool / mbed / mbed-sdk / libraries / net / https / axTLS / ssl / p12.c
1 /*
2 * Copyright (c) 2007, Cameron Rich
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
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.
17 *
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.
29 */
30
31 /**
32 * Process PKCS#8/PKCS#12 keys.
33 *
34 * The decoding of a PKCS#12 key is fairly specific - this code was tested on a
35 * key generated with:
36 *
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
40 *
41 * or with a certificate chain:
42 *
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
46 *
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.
50 *
51 * The PKCS#8 files were generated with something like:
52 *
53 * PEM format:
54 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1
55 * PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8
56 *
57 * DER format:
58 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER
59 * -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8
60 */
61
62 #include <stdlib.h>
63 #include <string.h>
64 #include <stdio.h>
65 #include "os_port.h"
66 #include "ssl.h"
67
68 /* all commented out if not used */
69 #ifdef CONFIG_SSL_USE_PKCS12
70
71 #define BLOCK_SIZE 64
72 #define PKCS12_KEY_ID 1
73 #define PKCS12_IV_ID 2
74 #define PKCS12_MAC_ID 3
75
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);
83
84 /*
85 * Take a raw pkcs8 block and then decrypt it and turn it into a normal key.
86 */
87 int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
88 {
89 uint8_t *buf = ssl_obj->buf;
90 int len, offset = 0;
91 int iterations;
92 int ret = SSL_NOT_OK;
93 uint8_t *version = NULL;
94 const uint8_t *salt;
95 uint8_t *priv_key;
96 int uni_pass_len;
97 char *uni_pass = make_uni_pass(password, &uni_pass_len);
98
99 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
100 {
101 #ifdef CONFIG_SSL_FULL_MODE
102 printf("Error: Invalid p8 ASN.1 file\n");
103 #endif
104 goto error;
105 }
106
107 /* unencrypted key? */
108 if (asn1_get_int(buf, &offset, &version) > 0 && *version == 0)
109 {
110 ret = p8_add_key(ssl_ctx, buf);
111 goto error;
112 }
113
114 if (get_pbe_params(buf, &offset, &salt, &iterations) < 0)
115 goto error;
116
117 if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0)
118 goto error;
119
120 priv_key = &buf[offset];
121
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);
125
126 error:
127 free(version);
128 free(uni_pass);
129 return ret;
130 }
131
132 /*
133 * Take the unencrypted pkcs8 and turn it into a private key
134 */
135 static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key)
136 {
137 uint8_t *buf = priv_key;
138 int len, offset = 0;
139 int ret = SSL_NOT_OK;
140
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)
147 goto error;
148
149 ret = asn1_get_private_key(&buf[offset], len, &ssl_ctx->rsa_ctx);
150
151 error:
152 return ret;
153 }
154
155 /*
156 * Create the unicode password
157 */
158 static char *make_uni_pass(const char *password, int *uni_pass_len)
159 {
160 int pass_len = 0, i;
161 char *uni_pass;
162
163 if (password == NULL)
164 {
165 password = "";
166 }
167
168 uni_pass = (char *)malloc((strlen(password)+1)*2);
169
170 /* modify the password into a unicode version */
171 for (i = 0; i < (int)strlen(password); i++)
172 {
173 uni_pass[pass_len++] = 0;
174 uni_pass[pass_len++] = password[i];
175 }
176
177 uni_pass[pass_len++] = 0; /* null terminate */
178 uni_pass[pass_len++] = 0;
179 *uni_pass_len = pass_len;
180 return uni_pass;
181 }
182
183 /*
184 * Decrypt a pkcs8 block.
185 */
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)
189 {
190 uint8_t p[BLOCK_SIZE*2];
191 uint8_t d[BLOCK_SIZE];
192 uint8_t Ai[SHA1_SIZE];
193 SHA1_CTX sha_ctx;
194 RC4_CTX rc4_ctx;
195 int i;
196
197 for (i = 0; i < BLOCK_SIZE; i++)
198 {
199 p[i] = salt[i % SALT_SIZE];
200 p[BLOCK_SIZE+i] = uni_pass[i % uni_pass_len];
201 d[i] = id;
202 }
203
204 /* get the key - no IV since we are using RC4 */
205 SHA1_Init(&sha_ctx);
206 SHA1_Update(&sha_ctx, d, sizeof(d));
207 SHA1_Update(&sha_ctx, p, sizeof(p));
208 SHA1_Final(Ai, &sha_ctx);
209
210 for (i = 1; i < iter; i++)
211 {
212 SHA1_Init(&sha_ctx);
213 SHA1_Update(&sha_ctx, Ai, SHA1_SIZE);
214 SHA1_Final(Ai, &sha_ctx);
215 }
216
217 /* do the decryption */
218 if (id == PKCS12_KEY_ID)
219 {
220 RC4_setup(&rc4_ctx, Ai, 16);
221 RC4_crypt(&rc4_ctx, priv_key, priv_key, priv_key_len);
222 }
223 else /* MAC */
224 memcpy(priv_key, Ai, SHA1_SIZE);
225
226 return 0;
227 }
228
229 /*
230 * Take a raw pkcs12 block and the decrypt it and turn it into a certificate(s)
231 * and keys.
232 */
233 int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password)
234 {
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;
238 int all_certs = 0;
239 uint8_t *version = NULL, *auth_safes = NULL, *cert, *orig_mac;
240 uint8_t key[SHA1_SIZE];
241 uint8_t mac[SHA1_SIZE];
242 const uint8_t *salt;
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 };
251
252 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
253 {
254 #ifdef CONFIG_SSL_FULL_MODE
255 printf("Error: Invalid p12 ASN.1 file\n");
256 #endif
257 goto error;
258 }
259
260 if (asn1_get_int(buf, &offset, &version) < 0 || *version != 3)
261 {
262 ret = SSL_ERROR_INVALID_VERSION;
263 goto error;
264 }
265
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)))
271 goto error;
272
273 offset += len;
274
275 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
276 asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0)
277 goto error;
278
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)
283 goto error;
284
285 auth_safes_len = auth_safes_end - auth_safes_start;
286 auth_safes = malloc(auth_safes_len);
287
288 memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len);
289
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))))
295 goto error;
296
297 offset += len;
298
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)))
306 goto error;
307
308 offset += len;
309
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)
313 goto error;
314
315 /* decrypt the certificate */
316 cert = &buf[offset];
317 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
318 len, PKCS12_KEY_ID)) < 0)
319 goto error;
320
321 offset += len;
322
323 /* load the certificate */
324 key_offset = 0;
325 all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE);
326
327 /* keep going until all certs are loaded */
328 while (key_offset < all_certs)
329 {
330 int cert_offset = key_offset;
331
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)
340 goto error;
341
342 if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0)
343 goto error;
344
345 key_offset = cert_offset;
346 }
347
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)))
352 goto error;
353
354 offset += len;
355
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)))
363 goto error;
364
365 offset += len;
366
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)
372 goto error;
373
374 /* decrypt the private key */
375 cert = &buf[offset];
376 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
377 len, PKCS12_KEY_ID)) < 0)
378 goto error;
379
380 offset += len;
381
382 /* load the private key */
383 if ((ret = p8_add_key(ssl_ctx, cert)) < 0)
384 goto error;
385
386 /* miss out on friendly name, local key id etc */
387 if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0)
388 goto error;
389
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 ||
395 len != SHA1_SIZE)
396 goto error;
397
398 orig_mac = &buf[offset];
399 offset += len;
400
401 /* get the salt */
402 if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8)
403 goto error;
404
405 salt = &buf[offset];
406
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)
410 goto error;
411
412 hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac);
413
414 if (memcmp(mac, orig_mac, SHA1_SIZE))
415 {
416 ret = SSL_ERROR_INVALID_HMAC;
417 goto error;
418 }
419
420 error:
421 free(version);
422 free(uni_pass);
423 free(auth_safes);
424 return ret;
425 }
426
427 /*
428 * Retrieve the salt/iteration details from a PBE block.
429 */
430 static int get_pbe_params(uint8_t *buf, int *offset,
431 const uint8_t **salt, int *iterations)
432 {
433 static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4 */
434 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 };
435
436 int i, len;
437 uint8_t *iter = NULL;
438 int error_code = SSL_ERROR_NOT_SUPPORTED;
439
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)
443 goto error;
444
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)))
449 {
450 #ifdef CONFIG_SSL_FULL_MODE
451 printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n");
452 #endif
453 goto error;
454 }
455
456 *offset += len;
457
458 if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
459 (len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 ||
460 len != 8)
461 goto error;
462
463 *salt = &buf[*offset];
464 *offset += len;
465
466 if ((len = asn1_get_int(buf, offset, &iter)) < 0)
467 goto error;
468
469 *iterations = 0;
470 for (i = 0; i < len; i++)
471 {
472 (*iterations) <<= 8;
473 (*iterations) += iter[i];
474 }
475
476 free(iter);
477 error_code = SSL_OK; /* got here - we are ok */
478
479 error:
480 return error_code;
481 }
482
483 #endif
Imprint / Impressum