comparison deps/Platinum/ThirdParty/Neptune/ThirdParty/axTLS/ssl/p12.c @ 0:3425707ddbf6

Initial import (hopefully this mercurial stuff works...)
author fraserofthenight
date Mon, 06 Jul 2009 08:06:28 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3425707ddbf6
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
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 all_ok = 0, 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;
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 };
252
253 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0)
254 {
255 #ifdef CONFIG_SSL_FULL_MODE
256 printf("Error: Invalid p12 ASN.1 file\n");
257 #endif
258 goto error;
259 }
260
261 if (asn1_get_int(buf, &offset, &version) < 0 || *version != 3)
262 {
263 error_code = SSL_ERROR_INVALID_VERSION;
264 goto error;
265 }
266
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)))
272 goto error;
273
274 offset += len;
275
276 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 ||
277 asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0)
278 goto error;
279
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)
284 goto error;
285
286 auth_safes_len = auth_safes_end - auth_safes_start;
287 auth_safes = malloc(auth_safes_len);
288
289 memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len);
290
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))))
296 goto error;
297
298 offset += len;
299
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)))
307 goto error;
308
309 offset += len;
310
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)
314 goto error;
315
316 /* decrypt the certificate */
317 cert = &buf[offset];
318 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
319 len, PKCS12_KEY_ID)) < 0)
320 goto error;
321
322 offset += len;
323
324 /* load the certificate */
325 key_offset = 0;
326 all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE);
327
328 /* keep going until all certs are loaded */
329 while (key_offset < all_certs)
330 {
331 int cert_offset = key_offset;
332
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)
341 goto error;
342
343 if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0)
344 goto error;
345
346 key_offset = cert_offset;
347 }
348
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)))
353 goto error;
354
355 offset += len;
356
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)))
364 goto error;
365
366 offset += len;
367
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)
373 goto error;
374
375 /* decrypt the private key */
376 cert = &buf[offset];
377 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert,
378 len, PKCS12_KEY_ID)) < 0)
379 goto error;
380
381 offset += len;
382
383 /* load the private key */
384 if ((ret = p8_add_key(ssl_ctx, cert)) < 0)
385 goto error;
386
387 /* miss out on friendly name, local key id etc */
388 if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0)
389 goto error;
390
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 ||
396 len != SHA1_SIZE)
397 goto error;
398
399 orig_mac = &buf[offset];
400 offset += len;
401
402 /* get the salt */
403 if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8)
404 goto error;
405
406 salt = &buf[offset];
407
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)
411 goto error;
412
413 hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac);
414
415 if (memcmp(mac, orig_mac, SHA1_SIZE))
416 {
417 error_code = SSL_ERROR_INVALID_HMAC;
418 goto error;
419 }
420
421 all_ok = 1;
422
423 error:
424 free(version);
425 free(uni_pass);
426 free(auth_safes);
427 return all_ok ? SSL_OK : error_code;
428 }
429
430 /*
431 * Retrieve the salt/iteration details from a PBE block.
432 */
433 static int get_pbe_params(uint8_t *buf, int *offset,
434 const uint8_t **salt, int *iterations)
435 {
436 static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4 */
437 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 };
438
439 int i, len;
440 uint8_t *iter = NULL;
441 int error_code = SSL_ERROR_NOT_SUPPORTED;
442
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)
446 goto error;
447
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)))
452 {
453 #ifdef CONFIG_SSL_FULL_MODE
454 printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n");
455 #endif
456 goto error;
457 }
458
459 *offset += len;
460
461 if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 ||
462 (len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 ||
463 len != 8)
464 goto error;
465
466 *salt = &buf[*offset];
467 *offset += len;
468
469 if ((len = asn1_get_int(buf, offset, &iter)) < 0)
470 goto error;
471
472 *iterations = 0;
473 for (i = 0; i < len; i++)
474 {
475 (*iterations) <<= 8;
476 (*iterations) += iter[i];
477 }
478
479 free(iter);
480 error_code = SSL_OK; /* got here - we are ok */
481
482 error:
483 return error_code;
484 }
485
486 #endif