Preliminary main mbed library for nexpaq development
libraries/net/https/axTLS/ssl/asn1.c@1:d96dbedaebdb, 2016-11-04 (annotated)
- Committer:
- nexpaq
- Date:
- Fri Nov 04 20:54:50 2016 +0000
- Revision:
- 1:d96dbedaebdb
- Parent:
- 0:6c56fb4bc5f0
Removed extra directories for other platforms
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nexpaq | 0:6c56fb4bc5f0 | 1 | /* |
nexpaq | 0:6c56fb4bc5f0 | 2 | * Copyright (c) 2007, Cameron Rich |
nexpaq | 0:6c56fb4bc5f0 | 3 | * |
nexpaq | 0:6c56fb4bc5f0 | 4 | * All rights reserved. |
nexpaq | 0:6c56fb4bc5f0 | 5 | * |
nexpaq | 0:6c56fb4bc5f0 | 6 | * Redistribution and use in source and binary forms, with or without |
nexpaq | 0:6c56fb4bc5f0 | 7 | * modification, are permitted provided that the following conditions are met: |
nexpaq | 0:6c56fb4bc5f0 | 8 | * |
nexpaq | 0:6c56fb4bc5f0 | 9 | * * Redistributions of source code must retain the above copyright notice, |
nexpaq | 0:6c56fb4bc5f0 | 10 | * this list of conditions and the following disclaimer. |
nexpaq | 0:6c56fb4bc5f0 | 11 | * * Redistributions in binary form must reproduce the above copyright notice, |
nexpaq | 0:6c56fb4bc5f0 | 12 | * this list of conditions and the following disclaimer in the documentation |
nexpaq | 0:6c56fb4bc5f0 | 13 | * and/or other materials provided with the distribution. |
nexpaq | 0:6c56fb4bc5f0 | 14 | * * Neither the name of the axTLS project nor the names of its contributors |
nexpaq | 0:6c56fb4bc5f0 | 15 | * may be used to endorse or promote products derived from this software |
nexpaq | 0:6c56fb4bc5f0 | 16 | * without specific prior written permission. |
nexpaq | 0:6c56fb4bc5f0 | 17 | * |
nexpaq | 0:6c56fb4bc5f0 | 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
nexpaq | 0:6c56fb4bc5f0 | 19 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
nexpaq | 0:6c56fb4bc5f0 | 20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
nexpaq | 0:6c56fb4bc5f0 | 21 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
nexpaq | 0:6c56fb4bc5f0 | 22 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
nexpaq | 0:6c56fb4bc5f0 | 23 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
nexpaq | 0:6c56fb4bc5f0 | 24 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
nexpaq | 0:6c56fb4bc5f0 | 25 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
nexpaq | 0:6c56fb4bc5f0 | 26 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
nexpaq | 0:6c56fb4bc5f0 | 27 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
nexpaq | 0:6c56fb4bc5f0 | 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
nexpaq | 0:6c56fb4bc5f0 | 29 | */ |
nexpaq | 0:6c56fb4bc5f0 | 30 | |
nexpaq | 0:6c56fb4bc5f0 | 31 | /** |
nexpaq | 0:6c56fb4bc5f0 | 32 | * Some primitive asn methods for extraction ASN.1 data. |
nexpaq | 0:6c56fb4bc5f0 | 33 | */ |
nexpaq | 0:6c56fb4bc5f0 | 34 | |
nexpaq | 0:6c56fb4bc5f0 | 35 | #include <stdio.h> |
nexpaq | 0:6c56fb4bc5f0 | 36 | #include <stdlib.h> |
nexpaq | 0:6c56fb4bc5f0 | 37 | #include <string.h> |
nexpaq | 0:6c56fb4bc5f0 | 38 | #include <time.h> |
nexpaq | 0:6c56fb4bc5f0 | 39 | #include "os_port.h" |
nexpaq | 0:6c56fb4bc5f0 | 40 | #include "crypto.h" |
nexpaq | 0:6c56fb4bc5f0 | 41 | #include "crypto_misc.h" |
nexpaq | 0:6c56fb4bc5f0 | 42 | #include "config.h" |
nexpaq | 0:6c56fb4bc5f0 | 43 | |
nexpaq | 0:6c56fb4bc5f0 | 44 | #define SIG_OID_PREFIX_SIZE 8 |
nexpaq | 0:6c56fb4bc5f0 | 45 | #define SIG_IIS6_OID_SIZE 5 |
nexpaq | 0:6c56fb4bc5f0 | 46 | #define SIG_SUBJECT_ALT_NAME_SIZE 3 |
nexpaq | 0:6c56fb4bc5f0 | 47 | |
nexpaq | 0:6c56fb4bc5f0 | 48 | /* Must be an RSA algorithm with either SHA1 or MD5 for verifying to work */ |
nexpaq | 0:6c56fb4bc5f0 | 49 | static const uint8_t sig_oid_prefix[SIG_OID_PREFIX_SIZE] = |
nexpaq | 0:6c56fb4bc5f0 | 50 | { |
nexpaq | 0:6c56fb4bc5f0 | 51 | 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01 |
nexpaq | 0:6c56fb4bc5f0 | 52 | }; |
nexpaq | 0:6c56fb4bc5f0 | 53 | |
nexpaq | 0:6c56fb4bc5f0 | 54 | static const uint8_t sig_sha1WithRSAEncrypt[SIG_IIS6_OID_SIZE] = |
nexpaq | 0:6c56fb4bc5f0 | 55 | { |
nexpaq | 0:6c56fb4bc5f0 | 56 | 0x2b, 0x0e, 0x03, 0x02, 0x1d |
nexpaq | 0:6c56fb4bc5f0 | 57 | }; |
nexpaq | 0:6c56fb4bc5f0 | 58 | |
nexpaq | 0:6c56fb4bc5f0 | 59 | static const uint8_t sig_subject_alt_name[SIG_SUBJECT_ALT_NAME_SIZE] = |
nexpaq | 0:6c56fb4bc5f0 | 60 | { |
nexpaq | 0:6c56fb4bc5f0 | 61 | 0x55, 0x1d, 0x11 |
nexpaq | 0:6c56fb4bc5f0 | 62 | }; |
nexpaq | 0:6c56fb4bc5f0 | 63 | |
nexpaq | 0:6c56fb4bc5f0 | 64 | /* CN, O, OU */ |
nexpaq | 0:6c56fb4bc5f0 | 65 | static const uint8_t g_dn_types[] = { 3, 10, 11 }; |
nexpaq | 0:6c56fb4bc5f0 | 66 | |
nexpaq | 0:6c56fb4bc5f0 | 67 | int get_asn1_length(const uint8_t *buf, int *offset) |
nexpaq | 0:6c56fb4bc5f0 | 68 | { |
nexpaq | 0:6c56fb4bc5f0 | 69 | int len, i; |
nexpaq | 0:6c56fb4bc5f0 | 70 | |
nexpaq | 0:6c56fb4bc5f0 | 71 | if (!(buf[*offset] & 0x80)) /* short form */ |
nexpaq | 0:6c56fb4bc5f0 | 72 | { |
nexpaq | 0:6c56fb4bc5f0 | 73 | len = buf[(*offset)++]; |
nexpaq | 0:6c56fb4bc5f0 | 74 | } |
nexpaq | 0:6c56fb4bc5f0 | 75 | else /* long form */ |
nexpaq | 0:6c56fb4bc5f0 | 76 | { |
nexpaq | 0:6c56fb4bc5f0 | 77 | int length_bytes = buf[(*offset)++]&0x7f; |
nexpaq | 0:6c56fb4bc5f0 | 78 | len = 0; |
nexpaq | 0:6c56fb4bc5f0 | 79 | for (i = 0; i < length_bytes; i++) |
nexpaq | 0:6c56fb4bc5f0 | 80 | { |
nexpaq | 0:6c56fb4bc5f0 | 81 | len <<= 8; |
nexpaq | 0:6c56fb4bc5f0 | 82 | len += buf[(*offset)++]; |
nexpaq | 0:6c56fb4bc5f0 | 83 | } |
nexpaq | 0:6c56fb4bc5f0 | 84 | } |
nexpaq | 0:6c56fb4bc5f0 | 85 | |
nexpaq | 0:6c56fb4bc5f0 | 86 | return len; |
nexpaq | 0:6c56fb4bc5f0 | 87 | } |
nexpaq | 0:6c56fb4bc5f0 | 88 | |
nexpaq | 0:6c56fb4bc5f0 | 89 | /** |
nexpaq | 0:6c56fb4bc5f0 | 90 | * Skip the ASN1.1 object type and its length. Get ready to read the object's |
nexpaq | 0:6c56fb4bc5f0 | 91 | * data. |
nexpaq | 0:6c56fb4bc5f0 | 92 | */ |
nexpaq | 0:6c56fb4bc5f0 | 93 | int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type) |
nexpaq | 0:6c56fb4bc5f0 | 94 | { |
nexpaq | 0:6c56fb4bc5f0 | 95 | if (buf[*offset] != obj_type) |
nexpaq | 0:6c56fb4bc5f0 | 96 | return X509_NOT_OK; |
nexpaq | 0:6c56fb4bc5f0 | 97 | (*offset)++; |
nexpaq | 0:6c56fb4bc5f0 | 98 | int tmp = get_asn1_length(buf, offset); |
nexpaq | 0:6c56fb4bc5f0 | 99 | return tmp; |
nexpaq | 0:6c56fb4bc5f0 | 100 | } |
nexpaq | 0:6c56fb4bc5f0 | 101 | |
nexpaq | 0:6c56fb4bc5f0 | 102 | /** |
nexpaq | 0:6c56fb4bc5f0 | 103 | * Skip over an ASN.1 object type completely. Get ready to read the next |
nexpaq | 0:6c56fb4bc5f0 | 104 | * object. |
nexpaq | 0:6c56fb4bc5f0 | 105 | */ |
nexpaq | 0:6c56fb4bc5f0 | 106 | int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type) |
nexpaq | 0:6c56fb4bc5f0 | 107 | { |
nexpaq | 0:6c56fb4bc5f0 | 108 | int len; |
nexpaq | 0:6c56fb4bc5f0 | 109 | if (buf[*offset] != obj_type) |
nexpaq | 0:6c56fb4bc5f0 | 110 | return X509_NOT_OK; |
nexpaq | 0:6c56fb4bc5f0 | 111 | (*offset)++; |
nexpaq | 0:6c56fb4bc5f0 | 112 | len = get_asn1_length(buf, offset); |
nexpaq | 0:6c56fb4bc5f0 | 113 | *offset += len; |
nexpaq | 0:6c56fb4bc5f0 | 114 | return 0; |
nexpaq | 0:6c56fb4bc5f0 | 115 | } |
nexpaq | 0:6c56fb4bc5f0 | 116 | |
nexpaq | 0:6c56fb4bc5f0 | 117 | /** |
nexpaq | 0:6c56fb4bc5f0 | 118 | * Read an integer value for ASN.1 data |
nexpaq | 0:6c56fb4bc5f0 | 119 | * Note: This function allocates memory which must be freed by the user. |
nexpaq | 0:6c56fb4bc5f0 | 120 | */ |
nexpaq | 0:6c56fb4bc5f0 | 121 | int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object) |
nexpaq | 0:6c56fb4bc5f0 | 122 | { |
nexpaq | 0:6c56fb4bc5f0 | 123 | int len; |
nexpaq | 0:6c56fb4bc5f0 | 124 | |
nexpaq | 0:6c56fb4bc5f0 | 125 | if ((len = asn1_next_obj(buf, offset, ASN1_INTEGER)) < 0) |
nexpaq | 0:6c56fb4bc5f0 | 126 | goto end_int_array; |
nexpaq | 0:6c56fb4bc5f0 | 127 | |
nexpaq | 0:6c56fb4bc5f0 | 128 | if (len > 1 && buf[*offset] == 0x00) /* ignore the negative byte */ |
nexpaq | 0:6c56fb4bc5f0 | 129 | { |
nexpaq | 0:6c56fb4bc5f0 | 130 | len--; |
nexpaq | 0:6c56fb4bc5f0 | 131 | (*offset)++; |
nexpaq | 0:6c56fb4bc5f0 | 132 | } |
nexpaq | 0:6c56fb4bc5f0 | 133 | |
nexpaq | 0:6c56fb4bc5f0 | 134 | *object = (uint8_t *)malloc(len); |
nexpaq | 0:6c56fb4bc5f0 | 135 | memcpy(*object, &buf[*offset], len); |
nexpaq | 0:6c56fb4bc5f0 | 136 | *offset += len; |
nexpaq | 0:6c56fb4bc5f0 | 137 | |
nexpaq | 0:6c56fb4bc5f0 | 138 | end_int_array: |
nexpaq | 0:6c56fb4bc5f0 | 139 | return len; |
nexpaq | 0:6c56fb4bc5f0 | 140 | } |
nexpaq | 0:6c56fb4bc5f0 | 141 | |
nexpaq | 0:6c56fb4bc5f0 | 142 | /** |
nexpaq | 0:6c56fb4bc5f0 | 143 | * Get all the RSA private key specifics from an ASN.1 encoded file |
nexpaq | 0:6c56fb4bc5f0 | 144 | */ |
nexpaq | 0:6c56fb4bc5f0 | 145 | int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx) |
nexpaq | 0:6c56fb4bc5f0 | 146 | { |
nexpaq | 0:6c56fb4bc5f0 | 147 | int offset = 7; |
nexpaq | 0:6c56fb4bc5f0 | 148 | uint8_t *modulus = NULL, *priv_exp = NULL, *pub_exp = NULL; |
nexpaq | 0:6c56fb4bc5f0 | 149 | int mod_len, priv_len, pub_len; |
nexpaq | 0:6c56fb4bc5f0 | 150 | #ifdef CONFIG_BIGINT_CRT |
nexpaq | 0:6c56fb4bc5f0 | 151 | uint8_t *p = NULL, *q = NULL, *dP = NULL, *dQ = NULL, *qInv = NULL; |
nexpaq | 0:6c56fb4bc5f0 | 152 | int p_len, q_len, dP_len, dQ_len, qInv_len; |
nexpaq | 0:6c56fb4bc5f0 | 153 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 154 | |
nexpaq | 0:6c56fb4bc5f0 | 155 | /* not in der format */ |
nexpaq | 0:6c56fb4bc5f0 | 156 | if (buf[0] != ASN1_SEQUENCE) /* basic sanity check */ |
nexpaq | 0:6c56fb4bc5f0 | 157 | { |
nexpaq | 0:6c56fb4bc5f0 | 158 | #ifdef CONFIG_SSL_FULL_MODE |
nexpaq | 0:6c56fb4bc5f0 | 159 | printf("Error: This is not a valid ASN.1 file\n"); |
nexpaq | 0:6c56fb4bc5f0 | 160 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 161 | return X509_INVALID_PRIV_KEY; |
nexpaq | 0:6c56fb4bc5f0 | 162 | } |
nexpaq | 0:6c56fb4bc5f0 | 163 | |
nexpaq | 0:6c56fb4bc5f0 | 164 | /* Use the private key to mix up the RNG if possible. */ |
nexpaq | 0:6c56fb4bc5f0 | 165 | RNG_custom_init(buf, len); |
nexpaq | 0:6c56fb4bc5f0 | 166 | |
nexpaq | 0:6c56fb4bc5f0 | 167 | mod_len = asn1_get_int(buf, &offset, &modulus); |
nexpaq | 0:6c56fb4bc5f0 | 168 | pub_len = asn1_get_int(buf, &offset, &pub_exp); |
nexpaq | 0:6c56fb4bc5f0 | 169 | priv_len = asn1_get_int(buf, &offset, &priv_exp); |
nexpaq | 0:6c56fb4bc5f0 | 170 | |
nexpaq | 0:6c56fb4bc5f0 | 171 | if (mod_len <= 0 || pub_len <= 0 || priv_len <= 0) |
nexpaq | 0:6c56fb4bc5f0 | 172 | return X509_INVALID_PRIV_KEY; |
nexpaq | 0:6c56fb4bc5f0 | 173 | |
nexpaq | 0:6c56fb4bc5f0 | 174 | #ifdef CONFIG_BIGINT_CRT |
nexpaq | 0:6c56fb4bc5f0 | 175 | p_len = asn1_get_int(buf, &offset, &p); |
nexpaq | 0:6c56fb4bc5f0 | 176 | q_len = asn1_get_int(buf, &offset, &q); |
nexpaq | 0:6c56fb4bc5f0 | 177 | dP_len = asn1_get_int(buf, &offset, &dP); |
nexpaq | 0:6c56fb4bc5f0 | 178 | dQ_len = asn1_get_int(buf, &offset, &dQ); |
nexpaq | 0:6c56fb4bc5f0 | 179 | qInv_len = asn1_get_int(buf, &offset, &qInv); |
nexpaq | 0:6c56fb4bc5f0 | 180 | |
nexpaq | 0:6c56fb4bc5f0 | 181 | if (p_len <= 0 || q_len <= 0 || dP_len <= 0 || dQ_len <= 0 || qInv_len <= 0) |
nexpaq | 0:6c56fb4bc5f0 | 182 | return X509_INVALID_PRIV_KEY; |
nexpaq | 0:6c56fb4bc5f0 | 183 | |
nexpaq | 0:6c56fb4bc5f0 | 184 | RSA_priv_key_new(rsa_ctx, |
nexpaq | 0:6c56fb4bc5f0 | 185 | modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len, |
nexpaq | 0:6c56fb4bc5f0 | 186 | p, p_len, q, p_len, dP, dP_len, dQ, dQ_len, qInv, qInv_len); |
nexpaq | 0:6c56fb4bc5f0 | 187 | |
nexpaq | 0:6c56fb4bc5f0 | 188 | free(p); |
nexpaq | 0:6c56fb4bc5f0 | 189 | free(q); |
nexpaq | 0:6c56fb4bc5f0 | 190 | free(dP); |
nexpaq | 0:6c56fb4bc5f0 | 191 | free(dQ); |
nexpaq | 0:6c56fb4bc5f0 | 192 | free(qInv); |
nexpaq | 0:6c56fb4bc5f0 | 193 | #else |
nexpaq | 0:6c56fb4bc5f0 | 194 | RSA_priv_key_new(rsa_ctx, |
nexpaq | 0:6c56fb4bc5f0 | 195 | modulus, mod_len, pub_exp, pub_len, priv_exp, priv_len); |
nexpaq | 0:6c56fb4bc5f0 | 196 | #endif |
nexpaq | 0:6c56fb4bc5f0 | 197 | |
nexpaq | 0:6c56fb4bc5f0 | 198 | free(modulus); |
nexpaq | 0:6c56fb4bc5f0 | 199 | free(priv_exp); |
nexpaq | 0:6c56fb4bc5f0 | 200 | free(pub_exp); |
nexpaq | 0:6c56fb4bc5f0 | 201 | return X509_OK; |
nexpaq | 0:6c56fb4bc5f0 | 202 | } |
nexpaq | 0:6c56fb4bc5f0 | 203 | |
nexpaq | 0:6c56fb4bc5f0 | 204 | /** |
nexpaq | 0:6c56fb4bc5f0 | 205 | * Get the time of a certificate. Ignore hours/minutes/seconds. |
nexpaq | 0:6c56fb4bc5f0 | 206 | */ |
nexpaq | 0:6c56fb4bc5f0 | 207 | static int asn1_get_utc_time(const uint8_t *buf, int *offset, time_t *t) |
nexpaq | 0:6c56fb4bc5f0 | 208 | { |
nexpaq | 0:6c56fb4bc5f0 | 209 | int ret = X509_NOT_OK, len, t_offset; |
nexpaq | 0:6c56fb4bc5f0 | 210 | struct tm tm; |
nexpaq | 0:6c56fb4bc5f0 | 211 | |
nexpaq | 0:6c56fb4bc5f0 | 212 | if (buf[(*offset)++] != ASN1_UTC_TIME) |
nexpaq | 0:6c56fb4bc5f0 | 213 | goto end_utc_time; |
nexpaq | 0:6c56fb4bc5f0 | 214 | |
nexpaq | 0:6c56fb4bc5f0 | 215 | len = get_asn1_length(buf, offset); |
nexpaq | 0:6c56fb4bc5f0 | 216 | t_offset = *offset; |
nexpaq | 0:6c56fb4bc5f0 | 217 | |
nexpaq | 0:6c56fb4bc5f0 | 218 | memset(&tm, 0, sizeof(struct tm)); |
nexpaq | 0:6c56fb4bc5f0 | 219 | tm.tm_year = (buf[t_offset] - '0')*10 + (buf[t_offset+1] - '0'); |
nexpaq | 0:6c56fb4bc5f0 | 220 | |
nexpaq | 0:6c56fb4bc5f0 | 221 | if (tm.tm_year <= 50) /* 1951-2050 thing */ |
nexpaq | 0:6c56fb4bc5f0 | 222 | { |
nexpaq | 0:6c56fb4bc5f0 | 223 | tm.tm_year += 100; |
nexpaq | 0:6c56fb4bc5f0 | 224 | } |
nexpaq | 0:6c56fb4bc5f0 | 225 | |
nexpaq | 0:6c56fb4bc5f0 | 226 | tm.tm_mon = (buf[t_offset+2] - '0')*10 + (buf[t_offset+3] - '0') - 1; |
nexpaq | 0:6c56fb4bc5f0 | 227 | tm.tm_mday = (buf[t_offset+4] - '0')*10 + (buf[t_offset+5] - '0'); |
nexpaq | 0:6c56fb4bc5f0 | 228 | *t = mktime(&tm); |
nexpaq | 0:6c56fb4bc5f0 | 229 | *offset += len; |
nexpaq | 0:6c56fb4bc5f0 | 230 | ret = X509_OK; |
nexpaq | 0:6c56fb4bc5f0 | 231 | |
nexpaq | 0:6c56fb4bc5f0 | 232 | end_utc_time: |
nexpaq | 0:6c56fb4bc5f0 | 233 | return ret; |
nexpaq | 0:6c56fb4bc5f0 | 234 | } |
nexpaq | 0:6c56fb4bc5f0 | 235 | |
nexpaq | 0:6c56fb4bc5f0 | 236 | /** |
nexpaq | 0:6c56fb4bc5f0 | 237 | * Get the version type of a certificate (which we don't actually care about) |
nexpaq | 0:6c56fb4bc5f0 | 238 | */ |
nexpaq | 0:6c56fb4bc5f0 | 239 | int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) |
nexpaq | 0:6c56fb4bc5f0 | 240 | { |
nexpaq | 0:6c56fb4bc5f0 | 241 | int ret = X509_NOT_OK; |
nexpaq | 0:6c56fb4bc5f0 | 242 | |
nexpaq | 0:6c56fb4bc5f0 | 243 | (*offset) += 2; /* get past explicit tag */ |
nexpaq | 0:6c56fb4bc5f0 | 244 | if (asn1_skip_obj(cert, offset, ASN1_INTEGER)) |
nexpaq | 0:6c56fb4bc5f0 | 245 | goto end_version; |
nexpaq | 0:6c56fb4bc5f0 | 246 | |
nexpaq | 0:6c56fb4bc5f0 | 247 | ret = X509_OK; |
nexpaq | 0:6c56fb4bc5f0 | 248 | end_version: |
nexpaq | 0:6c56fb4bc5f0 | 249 | return ret; |
nexpaq | 0:6c56fb4bc5f0 | 250 | } |
nexpaq | 0:6c56fb4bc5f0 | 251 | |
nexpaq | 0:6c56fb4bc5f0 | 252 | /** |
nexpaq | 0:6c56fb4bc5f0 | 253 | * Retrieve the notbefore and notafter certificate times. |
nexpaq | 0:6c56fb4bc5f0 | 254 | */ |
nexpaq | 0:6c56fb4bc5f0 | 255 | int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) |
nexpaq | 0:6c56fb4bc5f0 | 256 | { |
nexpaq | 0:6c56fb4bc5f0 | 257 | return (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || |
nexpaq | 0:6c56fb4bc5f0 | 258 | asn1_get_utc_time(cert, offset, &x509_ctx->not_before) || |
nexpaq | 0:6c56fb4bc5f0 | 259 | asn1_get_utc_time(cert, offset, &x509_ctx->not_after)); |
nexpaq | 0:6c56fb4bc5f0 | 260 | } |
nexpaq | 0:6c56fb4bc5f0 | 261 | |
nexpaq | 0:6c56fb4bc5f0 | 262 | /** |
nexpaq | 0:6c56fb4bc5f0 | 263 | * Get the components of a distinguished name |
nexpaq | 0:6c56fb4bc5f0 | 264 | */ |
nexpaq | 0:6c56fb4bc5f0 | 265 | static int asn1_get_oid_x520(const uint8_t *buf, int *offset) |
nexpaq | 0:6c56fb4bc5f0 | 266 | { |
nexpaq | 0:6c56fb4bc5f0 | 267 | int dn_type = 0; |
nexpaq | 0:6c56fb4bc5f0 | 268 | int len; |
nexpaq | 0:6c56fb4bc5f0 | 269 | |
nexpaq | 0:6c56fb4bc5f0 | 270 | if ((len = asn1_next_obj(buf, offset, ASN1_OID)) < 0) |
nexpaq | 0:6c56fb4bc5f0 | 271 | goto end_oid; |
nexpaq | 0:6c56fb4bc5f0 | 272 | |
nexpaq | 0:6c56fb4bc5f0 | 273 | /* expect a sequence of 2.5.4.[x] where x is a one of distinguished name |
nexpaq | 0:6c56fb4bc5f0 | 274 | components we are interested in. */ |
nexpaq | 0:6c56fb4bc5f0 | 275 | if (len == 3 && buf[(*offset)++] == 0x55 && buf[(*offset)++] == 0x04) |
nexpaq | 0:6c56fb4bc5f0 | 276 | dn_type = buf[(*offset)++]; |
nexpaq | 0:6c56fb4bc5f0 | 277 | else |
nexpaq | 0:6c56fb4bc5f0 | 278 | { |
nexpaq | 0:6c56fb4bc5f0 | 279 | *offset += len; /* skip over it */ |
nexpaq | 0:6c56fb4bc5f0 | 280 | } |
nexpaq | 0:6c56fb4bc5f0 | 281 | |
nexpaq | 0:6c56fb4bc5f0 | 282 | end_oid: |
nexpaq | 0:6c56fb4bc5f0 | 283 | return dn_type; |
nexpaq | 0:6c56fb4bc5f0 | 284 | } |
nexpaq | 0:6c56fb4bc5f0 | 285 | |
nexpaq | 0:6c56fb4bc5f0 | 286 | /** |
nexpaq | 0:6c56fb4bc5f0 | 287 | * Obtain an ASN.1 printable string type. |
nexpaq | 0:6c56fb4bc5f0 | 288 | */ |
nexpaq | 0:6c56fb4bc5f0 | 289 | static int asn1_get_printable_str(const uint8_t *buf, int *offset, char **str) |
nexpaq | 0:6c56fb4bc5f0 | 290 | { |
nexpaq | 0:6c56fb4bc5f0 | 291 | int len = X509_NOT_OK; |
nexpaq | 0:6c56fb4bc5f0 | 292 | int asn1_type = buf[*offset]; |
nexpaq | 0:6c56fb4bc5f0 | 293 | |
nexpaq | 0:6c56fb4bc5f0 | 294 | /* some certs have this awful crud in them for some reason */ |
nexpaq | 0:6c56fb4bc5f0 | 295 | if (asn1_type != ASN1_PRINTABLE_STR && |
nexpaq | 0:6c56fb4bc5f0 | 296 | asn1_type != ASN1_PRINTABLE_STR2 && |
nexpaq | 0:6c56fb4bc5f0 | 297 | asn1_type != ASN1_TELETEX_STR && |
nexpaq | 0:6c56fb4bc5f0 | 298 | asn1_type != ASN1_IA5_STR && |
nexpaq | 0:6c56fb4bc5f0 | 299 | asn1_type != ASN1_UNICODE_STR) |
nexpaq | 0:6c56fb4bc5f0 | 300 | goto end_pnt_str; |
nexpaq | 0:6c56fb4bc5f0 | 301 | |
nexpaq | 0:6c56fb4bc5f0 | 302 | (*offset)++; |
nexpaq | 0:6c56fb4bc5f0 | 303 | len = get_asn1_length(buf, offset); |
nexpaq | 0:6c56fb4bc5f0 | 304 | |
nexpaq | 0:6c56fb4bc5f0 | 305 | if (asn1_type == ASN1_UNICODE_STR) |
nexpaq | 0:6c56fb4bc5f0 | 306 | { |
nexpaq | 0:6c56fb4bc5f0 | 307 | int i; |
nexpaq | 0:6c56fb4bc5f0 | 308 | *str = (char *)malloc(len/2+1); /* allow for null */ |
nexpaq | 0:6c56fb4bc5f0 | 309 | |
nexpaq | 0:6c56fb4bc5f0 | 310 | for (i = 0; i < len; i += 2) |
nexpaq | 0:6c56fb4bc5f0 | 311 | (*str)[i/2] = buf[*offset + i + 1]; |
nexpaq | 0:6c56fb4bc5f0 | 312 | |
nexpaq | 0:6c56fb4bc5f0 | 313 | (*str)[len/2] = 0; /* null terminate */ |
nexpaq | 0:6c56fb4bc5f0 | 314 | } |
nexpaq | 0:6c56fb4bc5f0 | 315 | else |
nexpaq | 0:6c56fb4bc5f0 | 316 | { |
nexpaq | 0:6c56fb4bc5f0 | 317 | *str = (char *)malloc(len+1); /* allow for null */ |
nexpaq | 0:6c56fb4bc5f0 | 318 | memcpy(*str, &buf[*offset], len); |
nexpaq | 0:6c56fb4bc5f0 | 319 | (*str)[len] = 0; /* null terminate */ |
nexpaq | 0:6c56fb4bc5f0 | 320 | } |
nexpaq | 0:6c56fb4bc5f0 | 321 | |
nexpaq | 0:6c56fb4bc5f0 | 322 | *offset += len; |
nexpaq | 0:6c56fb4bc5f0 | 323 | |
nexpaq | 0:6c56fb4bc5f0 | 324 | end_pnt_str: |
nexpaq | 0:6c56fb4bc5f0 | 325 | return len; |
nexpaq | 0:6c56fb4bc5f0 | 326 | } |
nexpaq | 0:6c56fb4bc5f0 | 327 | |
nexpaq | 0:6c56fb4bc5f0 | 328 | /** |
nexpaq | 0:6c56fb4bc5f0 | 329 | * Get the subject name (or the issuer) of a certificate. |
nexpaq | 0:6c56fb4bc5f0 | 330 | */ |
nexpaq | 0:6c56fb4bc5f0 | 331 | int asn1_name(const uint8_t *cert, int *offset, char *dn[]) |
nexpaq | 0:6c56fb4bc5f0 | 332 | { |
nexpaq | 0:6c56fb4bc5f0 | 333 | int ret = X509_NOT_OK; |
nexpaq | 0:6c56fb4bc5f0 | 334 | int dn_type; |
nexpaq | 0:6c56fb4bc5f0 | 335 | char *tmp; |
nexpaq | 0:6c56fb4bc5f0 | 336 | |
nexpaq | 0:6c56fb4bc5f0 | 337 | if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0) |
nexpaq | 0:6c56fb4bc5f0 | 338 | goto end_name; |
nexpaq | 0:6c56fb4bc5f0 | 339 | |
nexpaq | 0:6c56fb4bc5f0 | 340 | while (asn1_next_obj(cert, offset, ASN1_SET) >= 0) |
nexpaq | 0:6c56fb4bc5f0 | 341 | { |
nexpaq | 0:6c56fb4bc5f0 | 342 | int i, found = 0; |
nexpaq | 0:6c56fb4bc5f0 | 343 | |
nexpaq | 0:6c56fb4bc5f0 | 344 | if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || |
nexpaq | 0:6c56fb4bc5f0 | 345 | (dn_type = asn1_get_oid_x520(cert, offset)) < 0) |
nexpaq | 0:6c56fb4bc5f0 | 346 | goto end_name; |
nexpaq | 0:6c56fb4bc5f0 | 347 | |
nexpaq | 0:6c56fb4bc5f0 | 348 | tmp = NULL; |
nexpaq | 0:6c56fb4bc5f0 | 349 | |
nexpaq | 0:6c56fb4bc5f0 | 350 | if (asn1_get_printable_str(cert, offset, &tmp) < 0) |
nexpaq | 0:6c56fb4bc5f0 | 351 | { |
nexpaq | 0:6c56fb4bc5f0 | 352 | free(tmp); |
nexpaq | 0:6c56fb4bc5f0 | 353 | goto end_name; |
nexpaq | 0:6c56fb4bc5f0 | 354 | } |
nexpaq | 0:6c56fb4bc5f0 | 355 | |
nexpaq | 0:6c56fb4bc5f0 | 356 | /* find the distinguished named type */ |
nexpaq | 0:6c56fb4bc5f0 | 357 | for (i = 0; i < X509_NUM_DN_TYPES; i++) |
nexpaq | 0:6c56fb4bc5f0 | 358 | { |
nexpaq | 0:6c56fb4bc5f0 | 359 | if (dn_type == g_dn_types[i]) |
nexpaq | 0:6c56fb4bc5f0 | 360 | { |
nexpaq | 0:6c56fb4bc5f0 | 361 | if (dn[i] == NULL) |
nexpaq | 0:6c56fb4bc5f0 | 362 | { |
nexpaq | 0:6c56fb4bc5f0 | 363 | dn[i] = tmp; |
nexpaq | 0:6c56fb4bc5f0 | 364 | found = 1; |
nexpaq | 0:6c56fb4bc5f0 | 365 | break; |
nexpaq | 0:6c56fb4bc5f0 | 366 | } |
nexpaq | 0:6c56fb4bc5f0 | 367 | } |
nexpaq | 0:6c56fb4bc5f0 | 368 | } |
nexpaq | 0:6c56fb4bc5f0 | 369 | |
nexpaq | 0:6c56fb4bc5f0 | 370 | if (found == 0) /* not found so get rid of it */ |
nexpaq | 0:6c56fb4bc5f0 | 371 | { |
nexpaq | 0:6c56fb4bc5f0 | 372 | free(tmp); |
nexpaq | 0:6c56fb4bc5f0 | 373 | } |
nexpaq | 0:6c56fb4bc5f0 | 374 | } |
nexpaq | 0:6c56fb4bc5f0 | 375 | |
nexpaq | 0:6c56fb4bc5f0 | 376 | ret = X509_OK; |
nexpaq | 0:6c56fb4bc5f0 | 377 | end_name: |
nexpaq | 0:6c56fb4bc5f0 | 378 | return ret; |
nexpaq | 0:6c56fb4bc5f0 | 379 | } |
nexpaq | 0:6c56fb4bc5f0 | 380 | |
nexpaq | 0:6c56fb4bc5f0 | 381 | /** |
nexpaq | 0:6c56fb4bc5f0 | 382 | * Read the modulus and public exponent of a certificate. |
nexpaq | 0:6c56fb4bc5f0 | 383 | */ |
nexpaq | 0:6c56fb4bc5f0 | 384 | int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) |
nexpaq | 0:6c56fb4bc5f0 | 385 | { |
nexpaq | 0:6c56fb4bc5f0 | 386 | int ret = X509_NOT_OK, mod_len, pub_len; |
nexpaq | 0:6c56fb4bc5f0 | 387 | uint8_t *modulus = NULL, *pub_exp = NULL; |
nexpaq | 0:6c56fb4bc5f0 | 388 | |
nexpaq | 0:6c56fb4bc5f0 | 389 | if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0 || |
nexpaq | 0:6c56fb4bc5f0 | 390 | asn1_skip_obj(cert, offset, ASN1_SEQUENCE) || |
nexpaq | 0:6c56fb4bc5f0 | 391 | asn1_next_obj(cert, offset, ASN1_BIT_STRING) < 0) |
nexpaq | 0:6c56fb4bc5f0 | 392 | goto end_pub_key; |
nexpaq | 0:6c56fb4bc5f0 | 393 | |
nexpaq | 0:6c56fb4bc5f0 | 394 | (*offset)++; /* ignore the padding bit field */ |
nexpaq | 0:6c56fb4bc5f0 | 395 | |
nexpaq | 0:6c56fb4bc5f0 | 396 | if (asn1_next_obj(cert, offset, ASN1_SEQUENCE) < 0) |
nexpaq | 0:6c56fb4bc5f0 | 397 | goto end_pub_key; |
nexpaq | 0:6c56fb4bc5f0 | 398 | |
nexpaq | 0:6c56fb4bc5f0 | 399 | mod_len = asn1_get_int(cert, offset, &modulus); |
nexpaq | 0:6c56fb4bc5f0 | 400 | pub_len = asn1_get_int(cert, offset, &pub_exp); |
nexpaq | 0:6c56fb4bc5f0 | 401 | RSA_pub_key_new(&x509_ctx->rsa_ctx, modulus, mod_len, pub_exp, pub_len); |
nexpaq | 0:6c56fb4bc5f0 | 402 | free(modulus); |
nexpaq | 0:6c56fb4bc5f0 | 403 | free(pub_exp); |
nexpaq | 0:6c56fb4bc5f0 | 404 | ret = X509_OK; |
nexpaq | 0:6c56fb4bc5f0 | 405 | |
nexpaq | 0:6c56fb4bc5f0 | 406 | end_pub_key: |
nexpaq | 0:6c56fb4bc5f0 | 407 | return ret; |
nexpaq | 0:6c56fb4bc5f0 | 408 | } |
nexpaq | 0:6c56fb4bc5f0 | 409 | |
nexpaq | 0:6c56fb4bc5f0 | 410 | #ifdef CONFIG_SSL_CERT_VERIFICATION |
nexpaq | 0:6c56fb4bc5f0 | 411 | /** |
nexpaq | 0:6c56fb4bc5f0 | 412 | * Read the signature of the certificate. |
nexpaq | 0:6c56fb4bc5f0 | 413 | */ |
nexpaq | 0:6c56fb4bc5f0 | 414 | int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx) |
nexpaq | 0:6c56fb4bc5f0 | 415 | { |
nexpaq | 0:6c56fb4bc5f0 | 416 | int ret = X509_NOT_OK; |
nexpaq | 0:6c56fb4bc5f0 | 417 | |
nexpaq | 0:6c56fb4bc5f0 | 418 | if (cert[(*offset)++] != ASN1_BIT_STRING) |
nexpaq | 0:6c56fb4bc5f0 | 419 | goto end_sig; |
nexpaq | 0:6c56fb4bc5f0 | 420 | |
nexpaq | 0:6c56fb4bc5f0 | 421 | x509_ctx->sig_len = get_asn1_length(cert, offset)-1; |
nexpaq | 0:6c56fb4bc5f0 | 422 | (*offset)++; /* ignore bit string padding bits */ |
nexpaq | 0:6c56fb4bc5f0 | 423 | x509_ctx->signature = (uint8_t *)malloc(x509_ctx->sig_len); |
nexpaq | 0:6c56fb4bc5f0 | 424 | memcpy(x509_ctx->signature, &cert[*offset], x509_ctx->sig_len); |
nexpaq | 0:6c56fb4bc5f0 | 425 | *offset += x509_ctx->sig_len; |
nexpaq | 0:6c56fb4bc5f0 | 426 | ret = X509_OK; |
nexpaq | 0:6c56fb4bc5f0 | 427 | |
nexpaq | 0:6c56fb4bc5f0 | 428 | end_sig: |
nexpaq | 0:6c56fb4bc5f0 | 429 | return ret; |
nexpaq | 0:6c56fb4bc5f0 | 430 | } |
nexpaq | 0:6c56fb4bc5f0 | 431 | |
nexpaq | 0:6c56fb4bc5f0 | 432 | /* |
nexpaq | 0:6c56fb4bc5f0 | 433 | * Compare 2 distinguished name components for equality |
nexpaq | 0:6c56fb4bc5f0 | 434 | * @return 0 if a match |
nexpaq | 0:6c56fb4bc5f0 | 435 | */ |
nexpaq | 0:6c56fb4bc5f0 | 436 | static int asn1_compare_dn_comp(const char *dn1, const char *dn2) |
nexpaq | 0:6c56fb4bc5f0 | 437 | { |
nexpaq | 0:6c56fb4bc5f0 | 438 | int ret; |
nexpaq | 0:6c56fb4bc5f0 | 439 | |
nexpaq | 0:6c56fb4bc5f0 | 440 | if (dn1 == NULL && dn2 == NULL) |
nexpaq | 0:6c56fb4bc5f0 | 441 | ret = 0; |
nexpaq | 0:6c56fb4bc5f0 | 442 | else |
nexpaq | 0:6c56fb4bc5f0 | 443 | ret = (dn1 && dn2) ? strcmp(dn1, dn2) : 1; |
nexpaq | 0:6c56fb4bc5f0 | 444 | |
nexpaq | 0:6c56fb4bc5f0 | 445 | return ret; |
nexpaq | 0:6c56fb4bc5f0 | 446 | } |
nexpaq | 0:6c56fb4bc5f0 | 447 | |
nexpaq | 0:6c56fb4bc5f0 | 448 | /** |
nexpaq | 0:6c56fb4bc5f0 | 449 | * Clean up all of the CA certificates. |
nexpaq | 0:6c56fb4bc5f0 | 450 | */ |
nexpaq | 0:6c56fb4bc5f0 | 451 | void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx) |
nexpaq | 0:6c56fb4bc5f0 | 452 | { |
nexpaq | 0:6c56fb4bc5f0 | 453 | int i = 0; |
nexpaq | 0:6c56fb4bc5f0 | 454 | |
nexpaq | 0:6c56fb4bc5f0 | 455 | if (ca_cert_ctx == NULL) |
nexpaq | 0:6c56fb4bc5f0 | 456 | return; |
nexpaq | 0:6c56fb4bc5f0 | 457 | |
nexpaq | 0:6c56fb4bc5f0 | 458 | while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i]) |
nexpaq | 0:6c56fb4bc5f0 | 459 | { |
nexpaq | 0:6c56fb4bc5f0 | 460 | x509_free(ca_cert_ctx->cert[i]); |
nexpaq | 0:6c56fb4bc5f0 | 461 | ca_cert_ctx->cert[i++] = NULL; |
nexpaq | 0:6c56fb4bc5f0 | 462 | } |
nexpaq | 0:6c56fb4bc5f0 | 463 | |
nexpaq | 0:6c56fb4bc5f0 | 464 | free(ca_cert_ctx); |
nexpaq | 0:6c56fb4bc5f0 | 465 | } |
nexpaq | 0:6c56fb4bc5f0 | 466 | |
nexpaq | 0:6c56fb4bc5f0 | 467 | /* |
nexpaq | 0:6c56fb4bc5f0 | 468 | * Compare 2 distinguished names for equality |
nexpaq | 0:6c56fb4bc5f0 | 469 | * @return 0 if a match |
nexpaq | 0:6c56fb4bc5f0 | 470 | */ |
nexpaq | 0:6c56fb4bc5f0 | 471 | int asn1_compare_dn(char * const dn1[], char * const dn2[]) |
nexpaq | 0:6c56fb4bc5f0 | 472 | { |
nexpaq | 0:6c56fb4bc5f0 | 473 | int i; |
nexpaq | 0:6c56fb4bc5f0 | 474 | |
nexpaq | 0:6c56fb4bc5f0 | 475 | for (i = 0; i < X509_NUM_DN_TYPES; i++) |
nexpaq | 0:6c56fb4bc5f0 | 476 | { |
nexpaq | 0:6c56fb4bc5f0 | 477 | if (asn1_compare_dn_comp(dn1[i], dn2[i])) |
nexpaq | 0:6c56fb4bc5f0 | 478 | return 1; |
nexpaq | 0:6c56fb4bc5f0 | 479 | } |
nexpaq | 0:6c56fb4bc5f0 | 480 | |
nexpaq | 0:6c56fb4bc5f0 | 481 | return 0; /* all good */ |
nexpaq | 0:6c56fb4bc5f0 | 482 | } |
nexpaq | 0:6c56fb4bc5f0 | 483 | |
nexpaq | 0:6c56fb4bc5f0 | 484 | int asn1_find_oid(const uint8_t* cert, int* offset, |
nexpaq | 0:6c56fb4bc5f0 | 485 | const uint8_t* oid, int oid_length) |
nexpaq | 0:6c56fb4bc5f0 | 486 | { |
nexpaq | 0:6c56fb4bc5f0 | 487 | int seqlen; |
nexpaq | 0:6c56fb4bc5f0 | 488 | if ((seqlen = asn1_next_obj(cert, offset, ASN1_SEQUENCE))> 0) |
nexpaq | 0:6c56fb4bc5f0 | 489 | { |
nexpaq | 0:6c56fb4bc5f0 | 490 | int end = *offset + seqlen; |
nexpaq | 0:6c56fb4bc5f0 | 491 | |
nexpaq | 0:6c56fb4bc5f0 | 492 | while (*offset < end) |
nexpaq | 0:6c56fb4bc5f0 | 493 | { |
nexpaq | 0:6c56fb4bc5f0 | 494 | int type = cert[(*offset)++]; |
nexpaq | 0:6c56fb4bc5f0 | 495 | int length = get_asn1_length(cert, offset); |
nexpaq | 0:6c56fb4bc5f0 | 496 | int noffset = *offset + length; |
nexpaq | 0:6c56fb4bc5f0 | 497 | |
nexpaq | 0:6c56fb4bc5f0 | 498 | if (type == ASN1_SEQUENCE) |
nexpaq | 0:6c56fb4bc5f0 | 499 | { |
nexpaq | 0:6c56fb4bc5f0 | 500 | type = cert[(*offset)++]; |
nexpaq | 0:6c56fb4bc5f0 | 501 | length = get_asn1_length(cert, offset); |
nexpaq | 0:6c56fb4bc5f0 | 502 | |
nexpaq | 0:6c56fb4bc5f0 | 503 | if (type == ASN1_OID && length == oid_length && |
nexpaq | 0:6c56fb4bc5f0 | 504 | memcmp(cert + *offset, oid, oid_length) == 0) |
nexpaq | 0:6c56fb4bc5f0 | 505 | { |
nexpaq | 0:6c56fb4bc5f0 | 506 | *offset += oid_length; |
nexpaq | 0:6c56fb4bc5f0 | 507 | return 1; |
nexpaq | 0:6c56fb4bc5f0 | 508 | } |
nexpaq | 0:6c56fb4bc5f0 | 509 | } |
nexpaq | 0:6c56fb4bc5f0 | 510 | |
nexpaq | 0:6c56fb4bc5f0 | 511 | *offset = noffset; |
nexpaq | 0:6c56fb4bc5f0 | 512 | } |
nexpaq | 0:6c56fb4bc5f0 | 513 | } |
nexpaq | 0:6c56fb4bc5f0 | 514 | |
nexpaq | 0:6c56fb4bc5f0 | 515 | return 0; |
nexpaq | 0:6c56fb4bc5f0 | 516 | } |
nexpaq | 0:6c56fb4bc5f0 | 517 | |
nexpaq | 0:6c56fb4bc5f0 | 518 | int asn1_find_subjectaltname(const uint8_t* cert, int offset) |
nexpaq | 0:6c56fb4bc5f0 | 519 | { |
nexpaq | 0:6c56fb4bc5f0 | 520 | if (asn1_find_oid(cert, &offset, sig_subject_alt_name, |
nexpaq | 0:6c56fb4bc5f0 | 521 | SIG_SUBJECT_ALT_NAME_SIZE)) |
nexpaq | 0:6c56fb4bc5f0 | 522 | { |
nexpaq | 0:6c56fb4bc5f0 | 523 | return offset; |
nexpaq | 0:6c56fb4bc5f0 | 524 | } |
nexpaq | 0:6c56fb4bc5f0 | 525 | |
nexpaq | 0:6c56fb4bc5f0 | 526 | return 0; |
nexpaq | 0:6c56fb4bc5f0 | 527 | } |
nexpaq | 0:6c56fb4bc5f0 | 528 | |
nexpaq | 0:6c56fb4bc5f0 | 529 | #endif /* CONFIG_SSL_CERT_VERIFICATION */ |
nexpaq | 0:6c56fb4bc5f0 | 530 | |
nexpaq | 0:6c56fb4bc5f0 | 531 | /** |
nexpaq | 0:6c56fb4bc5f0 | 532 | * Read the signature type of the certificate. We only support RSA-MD5 and |
nexpaq | 0:6c56fb4bc5f0 | 533 | * RSA-SHA1 signature types. |
nexpaq | 0:6c56fb4bc5f0 | 534 | */ |
nexpaq | 0:6c56fb4bc5f0 | 535 | int asn1_signature_type(const uint8_t *cert, |
nexpaq | 0:6c56fb4bc5f0 | 536 | int *offset, X509_CTX *x509_ctx) |
nexpaq | 0:6c56fb4bc5f0 | 537 | { |
nexpaq | 0:6c56fb4bc5f0 | 538 | int ret = X509_NOT_OK, len; |
nexpaq | 0:6c56fb4bc5f0 | 539 | |
nexpaq | 0:6c56fb4bc5f0 | 540 | if (cert[(*offset)++] != ASN1_OID) |
nexpaq | 0:6c56fb4bc5f0 | 541 | goto end_check_sig; |
nexpaq | 0:6c56fb4bc5f0 | 542 | |
nexpaq | 0:6c56fb4bc5f0 | 543 | len = get_asn1_length(cert, offset); |
nexpaq | 0:6c56fb4bc5f0 | 544 | |
nexpaq | 0:6c56fb4bc5f0 | 545 | if (len == 5 && memcmp(sig_sha1WithRSAEncrypt, &cert[*offset], |
nexpaq | 0:6c56fb4bc5f0 | 546 | SIG_IIS6_OID_SIZE) == 0) |
nexpaq | 0:6c56fb4bc5f0 | 547 | { |
nexpaq | 0:6c56fb4bc5f0 | 548 | x509_ctx->sig_type = SIG_TYPE_SHA1; |
nexpaq | 0:6c56fb4bc5f0 | 549 | } |
nexpaq | 0:6c56fb4bc5f0 | 550 | else |
nexpaq | 0:6c56fb4bc5f0 | 551 | { |
nexpaq | 0:6c56fb4bc5f0 | 552 | if (memcmp(sig_oid_prefix, &cert[*offset], SIG_OID_PREFIX_SIZE)) |
nexpaq | 0:6c56fb4bc5f0 | 553 | goto end_check_sig; /* unrecognised cert type */ |
nexpaq | 0:6c56fb4bc5f0 | 554 | |
nexpaq | 0:6c56fb4bc5f0 | 555 | x509_ctx->sig_type = cert[*offset + SIG_OID_PREFIX_SIZE]; |
nexpaq | 0:6c56fb4bc5f0 | 556 | } |
nexpaq | 0:6c56fb4bc5f0 | 557 | |
nexpaq | 0:6c56fb4bc5f0 | 558 | *offset += len; |
nexpaq | 0:6c56fb4bc5f0 | 559 | asn1_skip_obj(cert, offset, ASN1_NULL); /* if it's there */ |
nexpaq | 0:6c56fb4bc5f0 | 560 | ret = X509_OK; |
nexpaq | 0:6c56fb4bc5f0 | 561 | |
nexpaq | 0:6c56fb4bc5f0 | 562 | end_check_sig: |
nexpaq | 0:6c56fb4bc5f0 | 563 | return ret; |
nexpaq | 0:6c56fb4bc5f0 | 564 | } |
nexpaq | 0:6c56fb4bc5f0 | 565 |