xref: /freebsd/crypto/openssl/crypto/x509/v3_info.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
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, AUTHORITY_INFO_ACCESS
20                                                        *ainfo, STACK_OF(CONF_VALUE)
21                                                        *ret);
22 static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
23                                                         *method,
24                                                         X509V3_CTX *ctx,
25                                                         STACK_OF(CONF_VALUE)
26                                                         *nval);
27 
28 const X509V3_EXT_METHOD ossl_v3_info = { NID_info_access, X509V3_EXT_MULTILINE,
29     ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
30     0, 0, 0, 0,
31     0, 0,
32     (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
33     (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
34     0, 0,
35     NULL
36 };
37 
38 const X509V3_EXT_METHOD ossl_v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE,
39     ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
40     0, 0, 0, 0,
41     0, 0,
42     (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS,
43     (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS,
44     0, 0,
45     NULL
46 };
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) =
56         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
57 ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
58 
59 IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
60 
61 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
62     X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo,
63     STACK_OF(CONF_VALUE) *ret)
64 {
65     ACCESS_DESCRIPTION *desc;
66     int i, nlen;
67     char objtmp[80], *ntmp;
68     CONF_VALUE *vtmp;
69     STACK_OF(CONF_VALUE) *tret = ret;
70 
71     for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
72         STACK_OF(CONF_VALUE) *tmp;
73 
74         desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
75         tmp = i2v_GENERAL_NAME(method, desc->location, tret);
76         if (tmp == NULL)
77             goto err;
78         tret = tmp;
79         vtmp = sk_CONF_VALUE_value(tret, i);
80         i2t_ASN1_OBJECT(objtmp, sizeof(objtmp), desc->method);
81         nlen = strlen(objtmp) + 3 + strlen(vtmp->name) + 1;
82         ntmp = OPENSSL_malloc(nlen);
83         if (ntmp == NULL)
84             goto err;
85         BIO_snprintf(ntmp, nlen, "%s - %s", objtmp, vtmp->name);
86         OPENSSL_free(vtmp->name);
87         vtmp->name = ntmp;
88     }
89     if (ret == NULL && tret == NULL)
90         return sk_CONF_VALUE_new_null();
91 
92     return tret;
93  err:
94     ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
95     if (ret == NULL && tret != NULL)
96         sk_CONF_VALUE_pop_free(tret, X509V3_conf_free);
97     return NULL;
98 }
99 
v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD * method,X509V3_CTX * ctx,STACK_OF (CONF_VALUE)* nval)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_MALLOC_FAILURE);
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_MALLOC_FAILURE);
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             ERR_raise(ERR_LIB_X509V3, ERR_R_MALLOC_FAILURE);
135             goto err;
136         }
137         acc->method = OBJ_txt2obj(objtmp, 0);
138         if (!acc->method) {
139             ERR_raise_data(ERR_LIB_X509V3, X509V3_R_BAD_OBJECT,
140                            "value=%s", objtmp);
141             OPENSSL_free(objtmp);
142             goto err;
143         }
144         OPENSSL_free(objtmp);
145     }
146     return ainfo;
147  err:
148     sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
149     return NULL;
150 }
151 
i2a_ACCESS_DESCRIPTION(BIO * bp,const ACCESS_DESCRIPTION * a)152 int i2a_ACCESS_DESCRIPTION(BIO *bp, const ACCESS_DESCRIPTION *a)
153 {
154     i2a_ASN1_OBJECT(bp, a->method);
155     return 2;
156 }
157