Annotation of embedaddon/axTLS/ssl/p12.c, revision 1.1.1.1
1.1 misho 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
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>