Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
asn1.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 * Some primitive asn methods for extraction ASN.1 data. 00033 */ 00034 00035 #include <stdio.h> 00036 #include <stdlib.h> 00037 #include <string.h> 00038 #include <time.h> 00039 #include "os_port.h" 00040 #include "crypto.h " 00041 #include "crypto_misc.h " 00042 #include "config.h" 00043 00044 #define SIG_OID_PREFIX_SIZE 8 00045 #define SIG_IIS6_OID_SIZE 5 00046 #define SIG_SUBJECT_ALT_NAME_SIZE 3 00047 00048 /* Must be an RSA algorithm with either SHA1 or MD5 for verifying to work */ 00049 static const uint8_t sig_oid_prefix[SIG_OID_PREFIX_SIZE] = 00050 { 00051 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01 00052 }; 00053 00054 static const uint8_t sig_sha1WithRSAEncrypt[SIG_IIS6_OID_SIZE] = 00055 { 00056 0x2b, 0x0e, 0x03, 0x02, 0x1d 00057 }; 00058 00059 static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] = 00060 { 00061 0x55, 0x1d, 0x11 00062 }; 00063 00064 /* CN, O, OU */ 00065 static const uint8_t g_dn_types[] = { 3, 10, 11 }; 00066 00067 int get_asn1_length(const uint8_t *buf, int *offset) 00068 { 00069 int len, i; 00070 00071 if (!(buf[*offset] & 0x80)) /* short form */ 00072 { 00073 len = buf[(*offset)++]; 00074 } 00075 else /* long form */ 00076 { 00077 int length_bytes = buf[(*offset)++]&0x7f; 00078 len = 0; 00079 for (i = 0; i < length_bytes; i++) 00080 { 00081 len <<= 8; 00082 len += buf[(*offset)++]; 00083 } 00084 } 00085 00086 return len; 00087 } 00088 00089 /** 00090 * Skip the ASN1.1 object type and its length. Get ready to read the object's 00091 * data. 00092 */ 00093 int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type) 00094 { 00095 if (buf[*offset] != obj_type) 00096 return X509_NOT_OK; 00097 (*offset)++; 00098 return get_asn1_length(buf, offset); 00099 } 00100 00101 /** 00102 * Skip over an ASN.1 object type completely. Get ready to read the next 00103 * object. 00104 */ 00105 int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type) 00106 { 00107 int len; 00108 00109 if (buf[*offset] != obj_type) 00110 return X509_NOT_OK; 00111 (*offset)++; 00112 len = get_asn1_length(buf, offset); 00113 *offset += len; 00114 return 0; 00115 } 00116 00117 /** 00118 * Read an integer value for ASN.1 data 00119 * Note: This function allocates memory which must be freed by the user. 00120 */ 00121 int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object) 00122 { 00123 int len; 00124 00125 if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0) 00126 goto end_int_array; 00127 00128 if (len > 1 && buf[*offset] == 0x00) /* ignore the negative byte */ 00129 { 00130 len--; 00131 (*offset)++; 00132 } 00133 00134 *object = (uint8_t *)malloc(len); 00135 memcpy(*object, &buf[*offset], len); 00136 *offset += len; 00137 00138 end_int_array: 00139 return len; 00140 } 00141 00142 /** 00143 * Get all the RSA private key specifics from an ASN.1 encoded file 00144 */ 00145 int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx) 00146 { 00147 int offset = 7; 00148 uint8_t *modulus = NULL, *priv_exp = NULL, *pub_exp = NULL; 00149 int mod_len, priv_len, pub_len; 00150 #ifdef CONFIG_BIGINT_CRT 00151 uint8_t *p = NULL, *q = NULL, *dP = NULL, *dQ = NULL, *qInv = NULL; 00152 int p_len, q_len, dP_len, dQ_len, qInv_len; 00153 #endif 00154 00155 /* not in der format */ 00156 if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */ 00157 { 00158 #ifdef CONFIG_SSL_FULL_MODE 00159 printf("Error: This is not a valid ASN.1 file\n"); 00160 #endif 00161 return X509_INVALID_PRIV_KEY; 00162 } 00163 00164 /* Use the private key to mix up the RNG if possible. */ 00165 RNG_custom_init(buf, len); 00166 00167 mod_len = asn1_get_int(buf, &offset, &modulus); 00168 pub_len = asn1_get_int(buf, &offset, &pub_exp); 00169 priv_len = asn1_get_int(buf, &offset, &priv_exp); 00170 00171 if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0) 00172 return X509_INVALID_PRIV_KEY; 00173 00174 #ifdef CONFIG_BIGINT_CRT 00175 p_len = asn1_get_int(buf, &offset, &p); 00176 q_len = asn1_get_int(buf, &offset, &q); 00177 dP_len = asn1_get_int(buf, &offset, &dP); 00178 dQ_len = asn1_get_int(buf, &offset, &dQ); 00179 qInv_len = asn1_get_int(buf, &offset, &qInv); 00180 00181 if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0) 00182 return X509_INVALID_PRIV_KEY; 00183 00184 RSA_priv_key_new(rsa_ctx, 00185 modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len, 00186 p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len); 00187 00188 free(p); 00189 free(q); 00190 free(dP); 00191 free(dQ); 00192 free(qInv); 00193 #else 00194 RSA_priv_key_new(rsa_ctx, 00195 modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len); 00196 #endif 00197 00198 free(modulus); 00199 free(priv_exp); 00200 free(pub_exp); 00201 return X509_OK; 00202 } 00203 00204 /** 00205 * Get the time of a certificate. Ignore hours/minutes/seconds. 00206 */ 00207 static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t) 00208 { 00209 int ret = X509_NOT_OK, len, t_offset; 00210 struct tm tm; 00211 00212 if (buf[(*offset)++] != ASN1_UTC_TIME) 00213 goto end_utc_time; 00214 00215 len = get_asn1_length(buf, offset); 00216 t_offset = *offset; 00217 00218 memset(&tm, 0, sizeof(struct tm)); 00219 tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0'); 00220 00221 if (tm.tm_year <= 50) /* 1951-2050 thing */ 00222 { 00223 tm.tm_year += 100; 00224 } 00225 00226 tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1; 00227 tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0'); 00228 *t = mktime(&tm); 00229 *offset += len; 00230 ret = X509_OK; 00231 00232 end_utc_time: 00233 return ret; 00234 } 00235 00236 /** 00237 * Get the version type of a certificate (which we don't actually care about) 00238 */ 00239 int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) 00240 { 00241 int ret = X509_NOT_OK; 00242 00243 (*offset) += 2; /* get past explicit tag */ 00244 if (asn1_skip_obj(cert, offset, ASN1_INTEGER)) 00245 goto end_version; 00246 00247 ret = X509_OK; 00248 end_version: 00249 return ret; 00250 } 00251 00252 /** 00253 * Retrieve the notbefore and notafter certificate times. 00254 */ 00255 int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) 00256 { 00257 return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || 00258 asn1_get_utc_time(cert, offset, &x509_ctx->not_before) || 00259 asn1_get_utc_time(cert, offset, &x509_ctx->not_after)); 00260 } 00261 00262 /** 00263 * Get the components of a distinguished name 00264 */ 00265 static int asn1_get_oid_x520(const uint8_t *buf, int *offset) 00266 { 00267 int dn_type = 0; 00268 int len; 00269 00270 if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0) 00271 goto end_oid; 00272 00273 /* expect a sequence of 2.5.4.[x] where x is a one of distinguished name 00274 components we are interested in. */ 00275 if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04) 00276 dn_type = buf[(*offset)++]; 00277 else 00278 { 00279 *offset += len; /* skip over it */ 00280 } 00281 00282 end_oid: 00283 return dn_type; 00284 } 00285 00286 /** 00287 * Obtain an ASN.1 printable string type. 00288 */ 00289 static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str) 00290 { 00291 int len = X509_NOT_OK; 00292 int asn1_type = buf[*offset]; 00293 00294 /* some certs have this awful crud in them for some reason */ 00295 if (asn1_type != ASN1_PRINTABLE_STR && 00296 asn1_type != ASN1_PRINTABLE_STR2 && 00297 asn1_type != ASN1_TELETEX_STR && 00298 asn1_type != ASN1_IA5_STR && 00299 asn1_type != ASN1_UNICODE_STR) 00300 goto end_pnt_str; 00301 00302 (*offset)++; 00303 len = get_asn1_length(buf, offset); 00304 00305 if (asn1_type == ASN1_UNICODE_STR) 00306 { 00307 int i; 00308 *str = (char *)malloc(len/2+1); /* allow for null */ 00309 00310 for (i = 0; i < len; i += 2) 00311 (*str)[i/2] = buf[*offset + i + 1]; 00312 00313 (*str)[len/2] = 0; /* null terminate */ 00314 } 00315 else 00316 { 00317 *str = (char *)malloc(len+1); /* allow for null */ 00318 memcpy(*str, &buf[*offset], len); 00319 (*str)[len] = 0; /* null terminate */ 00320 } 00321 00322 *offset += len; 00323 00324 end_pnt_str: 00325 return len; 00326 } 00327 00328 /** 00329 * Get the subject name (or the issuer) of a certificate. 00330 */ 00331 int asn1_name(const uint8_t *cert, int *offset, char *dn[]) 00332 { 00333 int ret = X509_NOT_OK; 00334 int dn_type; 00335 char *tmp; 00336 00337 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0) 00338 goto end_name; 00339 00340 while (asn1_next_obj(cert, offset, ASN1_SET) >= 0) 00341 { 00342 int i, found = 0; 00343 00344 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || 00345 (dn_type = asn1_get_oid_x520(cert, offset)) < 0) 00346 goto end_name; 00347 00348 tmp = NULL; 00349 00350 if (asn1_get_printable_str(cert, offset, &tmp) < 0) 00351 { 00352 free(tmp); 00353 goto end_name; 00354 } 00355 00356 /* find the distinguished named type */ 00357 for (i = 0; i < X509_NUM_DN_TYPES; i++) 00358 { 00359 if (dn_type == g_dn_types[i]) 00360 { 00361 if (dn[i] == NULL) 00362 { 00363 dn[i] = tmp; 00364 found = 1; 00365 break; 00366 } 00367 } 00368 } 00369 00370 if (found == 0) /* not found so get rid of it */ 00371 { 00372 free(tmp); 00373 } 00374 } 00375 00376 ret = X509_OK; 00377 end_name: 00378 return ret; 00379 } 00380 00381 /** 00382 * Read the modulus and public exponent of a certificate. 00383 */ 00384 int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) 00385 { 00386 int ret = X509_NOT_OK, mod_len, pub_len; 00387 uint8_t *modulus = NULL, *pub_exp = NULL; 00388 00389 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || 00390 asn1_skip_obj(cert, offset, ASN1_SEQUENCE) || 00391 asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0) 00392 goto end_pub_key; 00393 00394 (*offset)++; /* ignore the padding bit field */ 00395 00396 if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0) 00397 goto end_pub_key; 00398 00399 mod_len = asn1_get_int(cert, offset, &modulus); 00400 pub_len = asn1_get_int(cert, offset, &pub_exp); 00401 00402 RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len); 00403 00404 free(modulus); 00405 free(pub_exp); 00406 ret = X509_OK; 00407 00408 end_pub_key: 00409 return ret; 00410 } 00411 00412 #ifdef CONFIG_SSL_CERT_VERIFICATION 00413 /** 00414 * Read the signature of the certificate. 00415 */ 00416 int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) 00417 { 00418 int ret = X509_NOT_OK; 00419 00420 if (cert[(*offset)++] != ASN1_BIT_STRING) 00421 goto end_sig; 00422 00423 x509_ctx->sig_len = get_asn1_length(cert, offset)-1; 00424 (*offset)++; /* ignore bit string padding bits */ 00425 x509_ctx->signature = (uint8_t *)malloc(x509_ctx->sig_len); 00426 memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len); 00427 *offset += x509_ctx->sig_len; 00428 ret = X509_OK; 00429 00430 end_sig: 00431 return ret; 00432 } 00433 00434 /* 00435 * Compare 2 distinguished name components for equality 00436 * @return 0 if a match 00437 */ 00438 static int asn1_compare_dn_comp(const char *dn1, const char *dn2) 00439 { 00440 int ret; 00441 00442 if (dn1 == NULL && dn2 == NULL) 00443 ret = 0; 00444 else 00445 ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 1; 00446 00447 return ret; 00448 } 00449 00450 /** 00451 * Clean up all of the CA certificates. 00452 */ 00453 void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx) 00454 { 00455 int i = 0; 00456 00457 if (ca_cert_ctx == NULL) 00458 return; 00459 00460 while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) 00461 { 00462 x509_free(ca_cert_ctx->cert[i]); 00463 ca_cert_ctx->cert[i++] = NULL; 00464 } 00465 00466 free(ca_cert_ctx); 00467 } 00468 00469 /* 00470 * Compare 2 distinguished names for equality 00471 * @return 0 if a match 00472 */ 00473 int asn1_compare_dn(char * const dn1[], char * const dn2[]) 00474 { 00475 int i; 00476 00477 for (i = 0; i < X509_NUM_DN_TYPES; i++) 00478 { 00479 if (asn1_compare_dn_comp(dn1[i], dn2[i])) 00480 return 1; 00481 } 00482 00483 return 0; /* all good */ 00484 } 00485 00486 int asn1_find_oid(const uint8_t* cert, int* offset, 00487 const uint8_t* oid, int oid_length) 00488 { 00489 int seqlen; 00490 if ((seqlen = asn1_next_obj(cert, offset, ASN1_SEQUENCE))> 0) 00491 { 00492 int end = *offset + seqlen; 00493 00494 while (*offset < end) 00495 { 00496 int type = cert[(*offset)++]; 00497 int length = get_asn1_length(cert, offset); 00498 int noffset = *offset + length; 00499 00500 if (type == ASN1_SEQUENCE) 00501 { 00502 type = cert[(*offset)++]; 00503 length = get_asn1_length(cert, offset); 00504 00505 if (type == ASN1_OID && length == oid_length && 00506 memcmp(cert + *offset, oid, oid_length) == 0) 00507 { 00508 *offset += oid_length; 00509 return 1; 00510 } 00511 } 00512 00513 *offset = noffset; 00514 } 00515 } 00516 00517 return 0; 00518 } 00519 00520 int asn1_find_subjectaltname(const uint8_t* cert, int offset) 00521 { 00522 if (asn1_find_oid(cert, &offset, sig_subject_alt_name, 00523 SIG_SUBJECT_ALT_NAME_SIZE)) 00524 { 00525 return offset; 00526 } 00527 00528 return 0; 00529 } 00530 00531 #endif /* CONFIG_SSL_CERT_VERIFICATION */ 00532 00533 /** 00534 * Read the signature type of the certificate. We only support RSA-MD5 and 00535 * RSA-SHA1 signature types. 00536 */ 00537 int asn1_signature_type(const uint8_t *cert, 00538 int *offset, X509_CTX *x509_ctx) 00539 { 00540 int ret = X509_NOT_OK, len; 00541 00542 if (cert[(*offset)++] != ASN1_OID) 00543 goto end_check_sig; 00544 00545 len = get_asn1_length(cert, offset); 00546 00547 if (len == 5 && memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], 00548 SIG_IIS6_OID_SIZE) == 0) 00549 { 00550 x509_ctx->sig_type = SIG_TYPE_SHA1; 00551 } 00552 else 00553 { 00554 if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE)) 00555 goto end_check_sig; /* unrecognised cert type */ 00556 00557 x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE]; 00558 } 00559 00560 *offset += len; 00561 asn1_skip_obj(cert, offset, ASN1_NULL); /* if it's there */ 00562 ret = X509_OK; 00563 00564 end_check_sig: 00565 return ret; 00566 } 00567
Generated on Tue Jul 12 2022 18:48:00 by
1.7.2