Home | History | Annotate | Download | only in x509v3
      1 /* v3_conf.c */
      2 /*
      3  * Written by Dr Stephen N Henson (steve (at) openssl.org) for the OpenSSL project
      4  * 1999.
      5  */
      6 /* ====================================================================
      7  * Copyright (c) 1999-2002 The OpenSSL Project.  All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  *
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  *
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in
     18  *    the documentation and/or other materials provided with the
     19  *    distribution.
     20  *
     21  * 3. All advertising materials mentioning features or use of this
     22  *    software must display the following acknowledgment:
     23  *    "This product includes software developed by the OpenSSL Project
     24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
     25  *
     26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
     27  *    endorse or promote products derived from this software without
     28  *    prior written permission. For written permission, please contact
     29  *    licensing (at) OpenSSL.org.
     30  *
     31  * 5. Products derived from this software may not be called "OpenSSL"
     32  *    nor may "OpenSSL" appear in their names without prior written
     33  *    permission of the OpenSSL Project.
     34  *
     35  * 6. Redistributions of any form whatsoever must retain the following
     36  *    acknowledgment:
     37  *    "This product includes software developed by the OpenSSL Project
     38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
     39  *
     40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
     41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
     44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     51  * OF THE POSSIBILITY OF SUCH DAMAGE.
     52  * ====================================================================
     53  *
     54  * This product includes cryptographic software written by Eric Young
     55  * (eay (at) cryptsoft.com).  This product includes software written by Tim
     56  * Hudson (tjh (at) cryptsoft.com). */
     57 
     58 /* extension creation utilities */
     59 
     60 #include <ctype.h>
     61 #include <stdio.h>
     62 #include <string.h>
     63 
     64 #include <openssl/conf.h>
     65 #include <openssl/err.h>
     66 #include <openssl/mem.h>
     67 #include <openssl/obj.h>
     68 #include <openssl/x509.h>
     69 #include <openssl/x509v3.h>
     70 
     71 #include "../internal.h"
     72 
     73 static int v3_check_critical(char **value);
     74 static int v3_check_generic(char **value);
     75 static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
     76                                     int crit, char *value);
     77 static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
     78                                             int crit, int type,
     79                                             X509V3_CTX *ctx);
     80 static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
     81                                   int ext_nid, int crit, void *ext_struc);
     82 static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
     83                                    long *ext_len);
     84 /* CONF *conf:  Config file    */
     85 /* char *name:  Name    */
     86 /* char *value:  Value    */
     87 X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
     88                                  char *value)
     89 {
     90     int crit;
     91     int ext_type;
     92     X509_EXTENSION *ret;
     93     crit = v3_check_critical(&value);
     94     if ((ext_type = v3_check_generic(&value)))
     95         return v3_generic_extension(name, value, crit, ext_type, ctx);
     96     ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
     97     if (!ret) {
     98         OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
     99         ERR_add_error_data(4, "name=", name, ", value=", value);
    100     }
    101     return ret;
    102 }
    103 
    104 /* CONF *conf:  Config file    */
    105 /* char *value:  Value    */
    106 X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid,
    107                                      char *value)
    108 {
    109     int crit;
    110     int ext_type;
    111     crit = v3_check_critical(&value);
    112     if ((ext_type = v3_check_generic(&value)))
    113         return v3_generic_extension(OBJ_nid2sn(ext_nid),
    114                                     value, crit, ext_type, ctx);
    115     return do_ext_nconf(conf, ctx, ext_nid, crit, value);
    116 }
    117 
    118 /* CONF *conf:  Config file    */
    119 /* char *value:  Value    */
    120 static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
    121                                     int crit, char *value)
    122 {
    123     const X509V3_EXT_METHOD *method;
    124     X509_EXTENSION *ext;
    125     STACK_OF(CONF_VALUE) *nval;
    126     void *ext_struc;
    127     if (ext_nid == NID_undef) {
    128         OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
    129         return NULL;
    130     }
    131     if (!(method = X509V3_EXT_get_nid(ext_nid))) {
    132         OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
    133         return NULL;
    134     }
    135     /* Now get internal extension representation based on type */
    136     if (method->v2i) {
    137         if (*value == '@')
    138             nval = NCONF_get_section(conf, value + 1);
    139         else
    140             nval = X509V3_parse_list(value);
    141         if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) {
    142             OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
    143             ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
    144                                value);
    145             if (*value != '@')
    146                 sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
    147             return NULL;
    148         }
    149         ext_struc = method->v2i(method, ctx, nval);
    150         if (*value != '@')
    151             sk_CONF_VALUE_pop_free(nval, X509V3_conf_free);
    152         if (!ext_struc)
    153             return NULL;
    154     } else if (method->s2i) {
    155         if (!(ext_struc = method->s2i(method, ctx, value)))
    156             return NULL;
    157     } else if (method->r2i) {
    158         if (!ctx->db || !ctx->db_meth) {
    159             OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE);
    160             return NULL;
    161         }
    162         if (!(ext_struc = method->r2i(method, ctx, value)))
    163             return NULL;
    164     } else {
    165         OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
    166         ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
    167         return NULL;
    168     }
    169 
    170     ext = do_ext_i2d(method, ext_nid, crit, ext_struc);
    171     if (method->it)
    172         ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it));
    173     else
    174         method->ext_free(ext_struc);
    175     return ext;
    176 
    177 }
    178 
    179 static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method,
    180                                   int ext_nid, int crit, void *ext_struc)
    181 {
    182     unsigned char *ext_der;
    183     int ext_len;
    184     ASN1_OCTET_STRING *ext_oct;
    185     X509_EXTENSION *ext;
    186     /* Convert internal representation to DER */
    187     if (method->it) {
    188         ext_der = NULL;
    189         ext_len =
    190             ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it));
    191         if (ext_len < 0)
    192             goto merr;
    193     } else {
    194         unsigned char *p;
    195         ext_len = method->i2d(ext_struc, NULL);
    196         if (!(ext_der = OPENSSL_malloc(ext_len)))
    197             goto merr;
    198         p = ext_der;
    199         method->i2d(ext_struc, &p);
    200     }
    201     if (!(ext_oct = M_ASN1_OCTET_STRING_new()))
    202         goto merr;
    203     ext_oct->data = ext_der;
    204     ext_oct->length = ext_len;
    205 
    206     ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct);
    207     if (!ext)
    208         goto merr;
    209     M_ASN1_OCTET_STRING_free(ext_oct);
    210 
    211     return ext;
    212 
    213  merr:
    214     OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    215     return NULL;
    216 
    217 }
    218 
    219 /* Given an internal structure, nid and critical flag create an extension */
    220 
    221 X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
    222 {
    223     const X509V3_EXT_METHOD *method;
    224     if (!(method = X509V3_EXT_get_nid(ext_nid))) {
    225         OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
    226         return NULL;
    227     }
    228     return do_ext_i2d(method, ext_nid, crit, ext_struc);
    229 }
    230 
    231 /* Check the extension string for critical flag */
    232 static int v3_check_critical(char **value)
    233 {
    234     char *p = *value;
    235     if ((strlen(p) < 9) || strncmp(p, "critical,", 9))
    236         return 0;
    237     p += 9;
    238     while (isspace((unsigned char)*p))
    239         p++;
    240     *value = p;
    241     return 1;
    242 }
    243 
    244 /* Check extension string for generic extension and return the type */
    245 static int v3_check_generic(char **value)
    246 {
    247     int gen_type = 0;
    248     char *p = *value;
    249     if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) {
    250         p += 4;
    251         gen_type = 1;
    252     } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) {
    253         p += 5;
    254         gen_type = 2;
    255     } else
    256         return 0;
    257 
    258     while (isspace((unsigned char)*p))
    259         p++;
    260     *value = p;
    261     return gen_type;
    262 }
    263 
    264 /* Create a generic extension: for now just handle DER type */
    265 static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
    266                                             int crit, int gen_type,
    267                                             X509V3_CTX *ctx)
    268 {
    269     unsigned char *ext_der = NULL;
    270     long ext_len = 0;
    271     ASN1_OBJECT *obj = NULL;
    272     ASN1_OCTET_STRING *oct = NULL;
    273     X509_EXTENSION *extension = NULL;
    274     if (!(obj = OBJ_txt2obj(ext, 0))) {
    275         OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
    276         ERR_add_error_data(2, "name=", ext);
    277         goto err;
    278     }
    279 
    280     if (gen_type == 1)
    281         ext_der = string_to_hex(value, &ext_len);
    282     else if (gen_type == 2)
    283         ext_der = generic_asn1(value, ctx, &ext_len);
    284 
    285     if (ext_der == NULL) {
    286         OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
    287         ERR_add_error_data(2, "value=", value);
    288         goto err;
    289     }
    290 
    291     if (!(oct = M_ASN1_OCTET_STRING_new())) {
    292         OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
    293         goto err;
    294     }
    295 
    296     oct->data = ext_der;
    297     oct->length = ext_len;
    298     ext_der = NULL;
    299 
    300     extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);
    301 
    302  err:
    303     ASN1_OBJECT_free(obj);
    304     M_ASN1_OCTET_STRING_free(oct);
    305     if (ext_der)
    306         OPENSSL_free(ext_der);
    307     return extension;
    308 
    309 }
    310 
    311 static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx,
    312                                    long *ext_len)
    313 {
    314     ASN1_TYPE *typ;
    315     unsigned char *ext_der = NULL;
    316     typ = ASN1_generate_v3(value, ctx);
    317     if (typ == NULL)
    318         return NULL;
    319     *ext_len = i2d_ASN1_TYPE(typ, &ext_der);
    320     ASN1_TYPE_free(typ);
    321     return ext_der;
    322 }
    323 
    324 /*
    325  * This is the main function: add a bunch of extensions based on a config
    326  * file section to an extension STACK.
    327  */
    328 
    329 int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section,
    330                             STACK_OF(X509_EXTENSION) **sk)
    331 {
    332     X509_EXTENSION *ext;
    333     STACK_OF(CONF_VALUE) *nval;
    334     CONF_VALUE *val;
    335     size_t i;
    336     if (!(nval = NCONF_get_section(conf, section)))
    337         return 0;
    338     for (i = 0; i < sk_CONF_VALUE_num(nval); i++) {
    339         val = sk_CONF_VALUE_value(nval, i);
    340         if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value)))
    341             return 0;
    342         if (sk)
    343             X509v3_add_ext(sk, ext, -1);
    344         X509_EXTENSION_free(ext);
    345     }
    346     return 1;
    347 }
    348 
    349 /*
    350  * Convenience functions to add extensions to a certificate, CRL and request
    351  */
    352 
    353 int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
    354                          X509 *cert)
    355 {
    356     STACK_OF(X509_EXTENSION) **sk = NULL;
    357     if (cert)
    358         sk = &cert->cert_info->extensions;
    359     return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
    360 }
    361 
    362 /* Same as above but for a CRL */
    363 
    364 int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
    365                              X509_CRL *crl)
    366 {
    367     STACK_OF(X509_EXTENSION) **sk = NULL;
    368     if (crl)
    369         sk = &crl->crl->extensions;
    370     return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
    371 }
    372 
    373 /* Add extensions to certificate request */
    374 
    375 int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section,
    376                              X509_REQ *req)
    377 {
    378     STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL;
    379     int i;
    380     if (req)
    381         sk = &extlist;
    382     i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk);
    383     if (!i || !sk)
    384         return i;
    385     i = X509_REQ_add_extensions(req, extlist);
    386     sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
    387     return i;
    388 }
    389 
    390 /* Config database functions */
    391 
    392 char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
    393 {
    394     if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) {
    395         OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
    396         return NULL;
    397     }
    398     if (ctx->db_meth->get_string)
    399         return ctx->db_meth->get_string(ctx->db, name, section);
    400     return NULL;
    401 }
    402 
    403 STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section)
    404 {
    405     if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) {
    406         OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
    407         return NULL;
    408     }
    409     if (ctx->db_meth->get_section)
    410         return ctx->db_meth->get_section(ctx->db, section);
    411     return NULL;
    412 }
    413 
    414 void X509V3_string_free(X509V3_CTX *ctx, char *str)
    415 {
    416     if (!str)
    417         return;
    418     if (ctx->db_meth->free_string)
    419         ctx->db_meth->free_string(ctx->db, str);
    420 }
    421 
    422 void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section)
    423 {
    424     if (!section)
    425         return;
    426     if (ctx->db_meth->free_section)
    427         ctx->db_meth->free_section(ctx->db, section);
    428 }
    429 
    430 static char *nconf_get_string(void *db, char *section, char *value)
    431 {
    432     /* TODO(fork): this should return a const value. */
    433     return (char *)NCONF_get_string(db, section, value);
    434 }
    435 
    436 static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section)
    437 {
    438     return NCONF_get_section(db, section);
    439 }
    440 
    441 static const X509V3_CONF_METHOD nconf_method = {
    442     nconf_get_string,
    443     nconf_get_section,
    444     NULL,
    445     NULL
    446 };
    447 
    448 void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf)
    449 {
    450     ctx->db_meth = &nconf_method;
    451     ctx->db = conf;
    452 }
    453 
    454 void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req,
    455                     X509_CRL *crl, int flags)
    456 {
    457     ctx->issuer_cert = issuer;
    458     ctx->subject_cert = subj;
    459     ctx->crl = crl;
    460     ctx->subject_req = req;
    461     ctx->flags = flags;
    462 }
    463