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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>