This is a fork of the mbed port of axTLS
Dependents: TLS_axTLS-Example HTTPSClientExample
p12.c
00001 /* 00002 * Copyright (c) 2007, Cameron Rich 00003 * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * 00009 * * Redistributions of source code must retain the above copyright notice, 00010 * this list of conditions and the following disclaimer. 00011 * * Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * * Neither the name of the axTLS project nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00021 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 00022 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00023 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00024 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00025 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00026 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00027 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00029 */ 00030 00031 /** 00032 * Process PKCS#8/PKCS#12 keys. 00033 * 00034 * The decoding of a PKCS#12 key is fairly specific - this code was tested on a 00035 * key generated with: 00036 * 00037 * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem 00038 * -keypbe PBE-SHA1-RC4-128 -certpbe PBE-SHA1-RC4-128 00039 * -name "p12_withoutCA" -out axTLS.withoutCA.p12 -password pass:abcd 00040 * 00041 * or with a certificate chain: 00042 * 00043 * openssl pkcs12 -export -in axTLS.x509_1024.pem -inkey axTLS.key_1024.pem 00044 * -certfile axTLS.ca_x509.pem -keypbe PBE-SHA1-RC4-128 -certpbe 00045 * PBE-SHA1-RC4-128 -name "p12_withCA" -out axTLS.withCA.p12 -password pass:abcd 00046 * 00047 * Note that the PBE has to be specified with PBE-SHA1-RC4-128. The 00048 * private/public keys/certs have to use RSA encryption. Both the integrity 00049 * and privacy passwords are the same. 00050 * 00051 * The PKCS#8 files were generated with something like: 00052 * 00053 * PEM format: 00054 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -v1 00055 * PBE-SHA1-RC4-128 -out axTLS.encrypted_pem.p8 00056 * 00057 * DER format: 00058 * openssl pkcs8 -in axTLS.key_512.pem -passout pass:abcd -topk8 -outform DER 00059 * -v1 PBE-SHA1-RC4-128 -out axTLS.encrypted.p8 00060 */ 00061 00062 #include <stdlib.h> 00063 #include <string.h> 00064 #include <stdio.h> 00065 #include "os_port.h" 00066 #include "ssl.h" 00067 00068 /* all commented out if not used */ 00069 #ifdef CONFIG_SSL_USE_PKCS12 00070 00071 #define BLOCK_SIZE 64 00072 #define PKCS12_KEY_ID 1 00073 #define PKCS12_IV_ID 2 00074 #define PKCS12_MAC_ID 3 00075 00076 static char *make_uni_pass(const char *password, int *uni_pass_len); 00077 static int p8_decrypt(const char *uni_pass, int uni_pass_len, 00078 const uint8_t *salt, int iter, 00079 uint8_t *priv_key, int priv_key_len, int id); 00080 static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key); 00081 static int get_pbe_params(uint8_t *buf, int *offset, 00082 const uint8_t **salt, int *iterations); 00083 00084 /* 00085 * Take a raw pkcs8 block and then decrypt it and turn it into a normal key. 00086 */ 00087 int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password) 00088 { 00089 uint8_t *buf = ssl_obj->buf; 00090 int len, offset = 0; 00091 int iterations; 00092 int ret = SSL_NOT_OK; 00093 uint8_t *version = NULL; 00094 const uint8_t *salt; 00095 uint8_t *priv_key; 00096 int uni_pass_len; 00097 char *uni_pass = make_uni_pass(password, &uni_pass_len); 00098 00099 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0) 00100 { 00101 #ifdef CONFIG_SSL_FULL_MODE 00102 printf("Error: Invalid p8 ASN.1 file\n"); 00103 #endif 00104 goto error; 00105 } 00106 00107 /* unencrypted key? */ 00108 if (asn1_get_int(buf, &offset, &version) > 0 && *version == 0) 00109 { 00110 ret = p8_add_key(ssl_ctx, buf); 00111 goto error; 00112 } 00113 00114 if (get_pbe_params(buf, &offset, &salt, &iterations) < 0) 00115 goto error; 00116 00117 if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0) 00118 goto error; 00119 00120 priv_key = &buf[offset]; 00121 00122 p8_decrypt(uni_pass, uni_pass_len, salt, 00123 iterations, priv_key, len, PKCS12_KEY_ID); 00124 ret = p8_add_key(ssl_ctx, priv_key); 00125 00126 error: 00127 free(version); 00128 free(uni_pass); 00129 return ret; 00130 } 00131 00132 /* 00133 * Take the unencrypted pkcs8 and turn it into a private key 00134 */ 00135 static int p8_add_key(SSL_CTX *ssl_ctx, uint8_t *priv_key) 00136 { 00137 uint8_t *buf = priv_key; 00138 int len, offset = 0; 00139 int ret = SSL_NOT_OK; 00140 00141 /* Skip the preamble and go straight to the private key. 00142 We only support rsaEncryption (1.2.840.113549.1.1.1) */ 00143 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00144 asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 || 00145 asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00146 (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0) 00147 goto error; 00148 00149 ret = asn1_get_private_key(&buf[offset], len, &ssl_ctx->rsa_ctx); 00150 00151 error: 00152 return ret; 00153 } 00154 00155 /* 00156 * Create the unicode password 00157 */ 00158 static char *make_uni_pass(const char *password, int *uni_pass_len) 00159 { 00160 int pass_len = 0, i; 00161 char *uni_pass; 00162 00163 if (password == NULL) 00164 { 00165 password = ""; 00166 } 00167 00168 uni_pass = (char *)malloc((strlen(password)+1)*2); 00169 00170 /* modify the password into a unicode version */ 00171 for (i = 0; i < (int)strlen(password); i++) 00172 { 00173 uni_pass[pass_len++] = 0; 00174 uni_pass[pass_len++] = password[i]; 00175 } 00176 00177 uni_pass[pass_len++] = 0; /* null terminate */ 00178 uni_pass[pass_len++] = 0; 00179 *uni_pass_len = pass_len; 00180 return uni_pass; 00181 } 00182 00183 /* 00184 * Decrypt a pkcs8 block. 00185 */ 00186 static int p8_decrypt(const char *uni_pass, int uni_pass_len, 00187 const uint8_t *salt, int iter, 00188 uint8_t *priv_key, int priv_key_len, int id) 00189 { 00190 uint8_t p[BLOCK_SIZE*2]; 00191 uint8_t d[BLOCK_SIZE]; 00192 uint8_t Ai[SHA1_SIZE]; 00193 SHA1_CTX sha_ctx; 00194 RC4_CTX rc4_ctx; 00195 int i; 00196 00197 for (i = 0; i < BLOCK_SIZE; i++) 00198 { 00199 p[i] = salt[i % SALT_SIZE]; 00200 p[BLOCK_SIZE+i] = uni_pass[i % uni_pass_len]; 00201 d[i] = id; 00202 } 00203 00204 /* get the key - no IV since we are using RC4 */ 00205 SHA1_Init(&sha_ctx); 00206 SHA1_Update(&sha_ctx, d, sizeof(d)); 00207 SHA1_Update(&sha_ctx, p, sizeof(p)); 00208 SHA1_Final(Ai, &sha_ctx); 00209 00210 for (i = 1; i < iter; i++) 00211 { 00212 SHA1_Init(&sha_ctx); 00213 SHA1_Update(&sha_ctx, Ai, SHA1_SIZE); 00214 SHA1_Final(Ai, &sha_ctx); 00215 } 00216 00217 /* do the decryption */ 00218 if (id == PKCS12_KEY_ID) 00219 { 00220 RC4_setup(&rc4_ctx, Ai, 16); 00221 RC4_crypt(&rc4_ctx, priv_key, priv_key, priv_key_len); 00222 } 00223 else /* MAC */ 00224 memcpy(priv_key, Ai, SHA1_SIZE); 00225 00226 return 0; 00227 } 00228 00229 /* 00230 * Take a raw pkcs12 block and the decrypt it and turn it into a certificate(s) 00231 * and keys. 00232 */ 00233 int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password) 00234 { 00235 uint8_t *buf = ssl_obj->buf; 00236 int len, iterations, auth_safes_start, 00237 auth_safes_end, auth_safes_len, key_offset, offset = 0; 00238 int all_certs = 0; 00239 uint8_t *version = NULL, *auth_safes = NULL, *cert, *orig_mac; 00240 uint8_t key[SHA1_SIZE]; 00241 uint8_t mac[SHA1_SIZE]; 00242 const uint8_t *salt; 00243 int uni_pass_len, ret = SSL_OK; 00244 char *uni_pass = make_uni_pass(password, &uni_pass_len); 00245 static const uint8_t pkcs_data[] = /* pkc7 data */ 00246 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01 }; 00247 static const uint8_t pkcs_encrypted[] = /* pkc7 encrypted */ 00248 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06 }; 00249 static const uint8_t pkcs8_key_bag[] = /* 1.2.840.113549.1.12.10.1.2 */ 00250 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02 }; 00251 00252 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0) 00253 { 00254 #ifdef CONFIG_SSL_FULL_MODE 00255 printf("Error: Invalid p12 ASN.1 file\n"); 00256 #endif 00257 goto error; 00258 } 00259 00260 if (asn1_get_int(buf, &offset, &version) < 0 || *version != 3) 00261 { 00262 ret = SSL_ERROR_INVALID_VERSION; 00263 goto error; 00264 } 00265 00266 /* remove all the boring pcks7 bits */ 00267 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00268 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || 00269 len != sizeof(pkcs_data) || 00270 memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data))) 00271 goto error; 00272 00273 offset += len; 00274 00275 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || 00276 asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0) 00277 goto error; 00278 00279 /* work out the MAC start/end points (done on AuthSafes) */ 00280 auth_safes_start = offset; 00281 auth_safes_end = offset; 00282 if (asn1_skip_obj(buf, &auth_safes_end, ASN1_SEQUENCE) < 0) 00283 goto error; 00284 00285 auth_safes_len = auth_safes_end - auth_safes_start; 00286 auth_safes = malloc(auth_safes_len); 00287 00288 memcpy(auth_safes, &buf[auth_safes_start], auth_safes_len); 00289 00290 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00291 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00292 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || 00293 (len != sizeof(pkcs_encrypted) || 00294 memcmp(&buf[offset], pkcs_encrypted, sizeof(pkcs_encrypted)))) 00295 goto error; 00296 00297 offset += len; 00298 00299 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || 00300 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00301 asn1_skip_obj(buf, &offset, ASN1_INTEGER) < 0 || 00302 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00303 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || 00304 len != sizeof(pkcs_data) || 00305 memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data))) 00306 goto error; 00307 00308 offset += len; 00309 00310 /* work out the salt for the certificate */ 00311 if (get_pbe_params(buf, &offset, &salt, &iterations) < 0 || 00312 (len = asn1_next_obj(buf, &offset, ASN1_IMPLICIT_TAG)) < 0) 00313 goto error; 00314 00315 /* decrypt the certificate */ 00316 cert = &buf[offset]; 00317 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert, 00318 len, PKCS12_KEY_ID)) < 0) 00319 goto error; 00320 00321 offset += len; 00322 00323 /* load the certificate */ 00324 key_offset = 0; 00325 all_certs = asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE); 00326 00327 /* keep going until all certs are loaded */ 00328 while (key_offset < all_certs) 00329 { 00330 int cert_offset = key_offset; 00331 00332 if (asn1_skip_obj(cert, &cert_offset, ASN1_SEQUENCE) < 0 || 00333 asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 || 00334 asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 || 00335 asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 || 00336 asn1_next_obj(cert, &key_offset, ASN1_SEQUENCE) < 0 || 00337 asn1_skip_obj(cert, &key_offset, ASN1_OID) < 0 || 00338 asn1_next_obj(cert, &key_offset, ASN1_EXPLICIT_TAG) < 0 || 00339 (len = asn1_next_obj(cert, &key_offset, ASN1_OCTET_STRING)) < 0) 00340 goto error; 00341 00342 if ((ret = add_cert(ssl_ctx, &cert[key_offset], len)) < 0) 00343 goto error; 00344 00345 key_offset = cert_offset; 00346 } 00347 00348 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00349 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || 00350 len != sizeof(pkcs_data) || 00351 memcmp(&buf[offset], pkcs_data, sizeof(pkcs_data))) 00352 goto error; 00353 00354 offset += len; 00355 00356 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || 00357 asn1_next_obj(buf, &offset, ASN1_OCTET_STRING) < 0 || 00358 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00359 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00360 (len = asn1_next_obj(buf, &offset, ASN1_OID)) < 0 || 00361 (len != sizeof(pkcs8_key_bag)) || 00362 memcmp(&buf[offset], pkcs8_key_bag, sizeof(pkcs8_key_bag))) 00363 goto error; 00364 00365 offset += len; 00366 00367 /* work out the salt for the private key */ 00368 if (asn1_next_obj(buf, &offset, ASN1_EXPLICIT_TAG) < 0 || 00369 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00370 get_pbe_params(buf, &offset, &salt, &iterations) < 0 || 00371 (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0) 00372 goto error; 00373 00374 /* decrypt the private key */ 00375 cert = &buf[offset]; 00376 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, cert, 00377 len, PKCS12_KEY_ID)) < 0) 00378 goto error; 00379 00380 offset += len; 00381 00382 /* load the private key */ 00383 if ((ret = p8_add_key(ssl_ctx, cert)) < 0) 00384 goto error; 00385 00386 /* miss out on friendly name, local key id etc */ 00387 if (asn1_skip_obj(buf, &offset, ASN1_SET) < 0) 00388 goto error; 00389 00390 /* work out the MAC */ 00391 if (asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00392 asn1_next_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00393 asn1_skip_obj(buf, &offset, ASN1_SEQUENCE) < 0 || 00394 (len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || 00395 len != SHA1_SIZE) 00396 goto error; 00397 00398 orig_mac = &buf[offset]; 00399 offset += len; 00400 00401 /* get the salt */ 00402 if ((len = asn1_next_obj(buf, &offset, ASN1_OCTET_STRING)) < 0 || len != 8) 00403 goto error; 00404 00405 salt = &buf[offset]; 00406 00407 /* work out what the mac should be */ 00408 if ((ret = p8_decrypt(uni_pass, uni_pass_len, salt, iterations, 00409 key, SHA1_SIZE, PKCS12_MAC_ID)) < 0) 00410 goto error; 00411 00412 hmac_sha1(auth_safes, auth_safes_len, key, SHA1_SIZE, mac); 00413 00414 if (memcmp(mac, orig_mac, SHA1_SIZE)) 00415 { 00416 ret = SSL_ERROR_INVALID_HMAC; 00417 goto error; 00418 } 00419 00420 error: 00421 free(version); 00422 free(uni_pass); 00423 free(auth_safes); 00424 return ret; 00425 } 00426 00427 /* 00428 * Retrieve the salt/iteration details from a PBE block. 00429 */ 00430 static int get_pbe_params(uint8_t *buf, int *offset, 00431 const uint8_t **salt, int *iterations) 00432 { 00433 static const uint8_t pbeSH1RC4[] = /* pbeWithSHAAnd128BitRC4 */ 00434 { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01 }; 00435 00436 int i, len; 00437 uint8_t *iter = NULL; 00438 int error_code = SSL_ERROR_NOT_SUPPORTED; 00439 00440 /* Get the PBE type */ 00441 if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 || 00442 (len = asn1_next_obj(buf, offset, ASN1_OID)) < 0) 00443 goto error; 00444 00445 /* we expect pbeWithSHAAnd128BitRC4 (1.2.840.113549.1.12.1.1) 00446 which is the only algorithm we support */ 00447 if (len != sizeof(pbeSH1RC4) || 00448 memcmp(&buf[*offset], pbeSH1RC4, sizeof(pbeSH1RC4))) 00449 { 00450 #ifdef CONFIG_SSL_FULL_MODE 00451 printf("Error: pkcs8/pkcs12 must use \"PBE-SHA1-RC4-128\"\n"); 00452 #endif 00453 goto error; 00454 } 00455 00456 *offset += len; 00457 00458 if (asn1_next_obj(buf, offset, ASN1_SEQUENCE) < 0 || 00459 (len = asn1_next_obj(buf, offset, ASN1_OCTET_STRING)) < 0 || 00460 len != 8) 00461 goto error; 00462 00463 *salt = &buf[*offset]; 00464 *offset += len; 00465 00466 if ((len = asn1_get_int(buf, offset, &iter)) < 0) 00467 goto error; 00468 00469 *iterations = 0; 00470 for (i = 0; i < len; i++) 00471 { 00472 (*iterations) <<= 8; 00473 (*iterations) += iter[i]; 00474 } 00475 00476 free(iter); 00477 error_code = SSL_OK; /* got here - we are ok */ 00478 00479 error: 00480 return error_code; 00481 } 00482 00483 #endif 00484 00485
Generated on Wed Jul 13 2022 19:30:07 by 1.7.2