Home | History | Annotate | Line # | Download | only in x509
      1 /*
      2  * Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include <stdio.h>
     11 #include "internal/cryptlib.h"
     12 #include <openssl/conf.h>
     13 #include <openssl/asn1.h>
     14 #include <openssl/asn1t.h>
     15 #include <openssl/x509v3.h>
     16 #include "ext_dat.h"
     17 
     18 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
     19                                                            *method,
     20     AUTHORITY_INFO_ACCESS
     21         *ainfo,
     22     STACK_OF(CONF_VALUE)
     23         *ret);
     24 static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
     25                                                             *method,
     26     X509V3_CTX *ctx,
     27     STACK_OF(CONF_VALUE)
     28         *nval);
     29 
     30 const X509V3_EXT_METHOD ossl_v3_info = { NID_info_access, X509V3_EXT_MULTILINE,
     31     ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
     32     0, 0, 0, 0,
     33     0, 0,
     34     (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
     35     (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
     36     0, 0,
     37     NULL };
     38 
     39 const X509V3_EXT_METHOD ossl_v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE,
     40     ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
     41     0, 0, 0, 0,
     42     0, 0,
     43     (X509V3_EXT_I2V)i2v_AUTHORITY_INFO_ACCESS,
     44     (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
     45     0, 0,
     46     NULL };
     47 
     48 ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
     49     ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
     50     ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME)
     51 } ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
     52 
     53 IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION)
     54 
     55 ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
     56 ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
     57 
     58 IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
     59 
     60 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
     61     X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo,
     62     STACK_OF(CONF_VALUE) *ret)
     63 {
     64     ACCESS_DESCRIPTION *desc;
     65     int i, nlen;
     66     char objtmp[80], *ntmp;
     67     CONF_VALUE *vtmp;
     68     STACK_OF(CONF_VALUE) *tret = ret;
     69 
     70     for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
     71         STACK_OF(CONF_VALUE) *tmp;
     72 
     73         desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
     74         tmp = i2v_GENERAL_NAME(method, desc->location, tret);
     75         if (tmp == NULL) {
     76             ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
     77             goto err;
     78         }
     79         tret = tmp;
     80         vtmp = sk_CONF_VALUE_value(tret, i);
     81         i2t_ASN1_OBJECT(objtmp, sizeof(objtmp), desc->method);
     82         nlen = strlen(objtmp) + 3 + strlen(vtmp->name) + 1;
     83         ntmp = OPENSSL_malloc(nlen);
     84         if (ntmp == NULL)
     85             goto err;
     86         BIO_snprintf(ntmp, nlen, "%s - %s", objtmp, vtmp->name);
     87         OPENSSL_free(vtmp->name);
     88         vtmp->name = ntmp;
     89     }
     90     if (ret == NULL && tret == NULL)
     91         return sk_CONF_VALUE_new_null();
     92 
     93     return tret;
     94 err:
     95     if (ret == NULL && tret != NULL)
     96         sk_CONF_VALUE_pop_free(tret, X509V3_conf_free);
     97     return NULL;
     98 }
     99 
    100 static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
    101                                                             *method,
    102     X509V3_CTX *ctx,
    103     STACK_OF(CONF_VALUE)
    104         *nval)
    105 {
    106     AUTHORITY_INFO_ACCESS *ainfo = NULL;
    107     CONF_VALUE *cnf, ctmp;
    108     ACCESS_DESCRIPTION *acc;
    109     int i;
    110     const int num = sk_CONF_VALUE_num(nval);
    111     char *objtmp, *ptmp;
    112 
    113     if ((ainfo = sk_ACCESS_DESCRIPTION_new_reserve(NULL, num)) == NULL) {
    114         ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB);
    115         return NULL;
    116     }
    117     for (i = 0; i < num; i++) {
    118         cnf = sk_CONF_VALUE_value(nval, i);
    119         if ((acc = ACCESS_DESCRIPTION_new()) == NULL) {
    120             ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB);
    121             goto err;
    122         }
    123         sk_ACCESS_DESCRIPTION_push(ainfo, acc); /* Cannot fail due to reserve */
    124         ptmp = strchr(cnf->name, ';');
    125         if (ptmp == NULL) {
    126             ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX);
    127             goto err;
    128         }
    129         ctmp.name = ptmp + 1;
    130         ctmp.value = cnf->value;
    131         if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
    132             goto err;
    133         if ((objtmp = OPENSSL_strndup(cnf->name, ptmp - cnf->name)) == NULL)
    134             goto err;
    135         acc->method = OBJ_txt2obj(objtmp, 0);
    136         if (!acc->method) {
    137             ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_OBJECT,
    138                 "value=%s", objtmp);
    139             OPENSSL_free(objtmp);
    140             goto err;
    141         }
    142         OPENSSL_free(objtmp);
    143     }
    144     return ainfo;
    145 err:
    146     sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
    147     return NULL;
    148 }
    149 
    150 int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a)
    151 {
    152     i2a_ASN1_OBJECT(bp, a->method);
    153     return 2;
    154 }
    155