• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 <string.h>
12 
13 #include <openssl/asn1.h>
14 #include <openssl/asn1t.h>
15 #include <openssl/conf.h>
16 #include <openssl/err.h>
17 #include <openssl/mem.h>
18 #include <openssl/obj.h>
19 #include <openssl/x509.h>
20 
21 #include "ext_dat.h"
22 #include "internal.h"
23 
24 
25 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
26     const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret);
27 static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method,
28                                        const X509V3_CTX *ctx,
29                                        const STACK_OF(CONF_VALUE) *nval);
30 
31 const X509V3_EXT_METHOD v3_info = {
32     NID_info_access,
33     X509V3_EXT_MULTILINE,
34     ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
35     0,
36     0,
37     0,
38     0,
39     0,
40     0,
41     i2v_AUTHORITY_INFO_ACCESS,
42     v2i_AUTHORITY_INFO_ACCESS,
43     0,
44     0,
45     NULL,
46 };
47 
48 const X509V3_EXT_METHOD v3_sinfo = {
49     NID_sinfo_access,
50     X509V3_EXT_MULTILINE,
51     ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS),
52     0,
53     0,
54     0,
55     0,
56     0,
57     0,
58     i2v_AUTHORITY_INFO_ACCESS,
59     v2i_AUTHORITY_INFO_ACCESS,
60     0,
61     0,
62     NULL,
63 };
64 
ASN1_SEQUENCE(ACCESS_DESCRIPTION)65 ASN1_SEQUENCE(ACCESS_DESCRIPTION) = {
66     ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT),
67     ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME),
68 } ASN1_SEQUENCE_END(ACCESS_DESCRIPTION)
69 
70 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ACCESS_DESCRIPTION)
71 
72 ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = ASN1_EX_TEMPLATE_TYPE(
73     ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION)
74 ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
75 
76 IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
77 
78 static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
79     const X509V3_EXT_METHOD *method, void *ext, STACK_OF(CONF_VALUE) *ret) {
80   const AUTHORITY_INFO_ACCESS *ainfo =
81       reinterpret_cast<const AUTHORITY_INFO_ACCESS *>(ext);
82   ACCESS_DESCRIPTION *desc;
83   int name_len;
84   char objtmp[80], *name;
85   CONF_VALUE *vtmp;
86   STACK_OF(CONF_VALUE) *tret = ret;
87 
88   for (size_t i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
89     STACK_OF(CONF_VALUE) *tmp;
90 
91     desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
92     tmp = i2v_GENERAL_NAME(method, desc->location, tret);
93     if (tmp == NULL) {
94       goto err;
95     }
96     tret = tmp;
97     vtmp = sk_CONF_VALUE_value(tret, i);
98     i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
99 
100     name_len = strlen(objtmp) + 3 + strlen(vtmp->name) + 1;
101     name = reinterpret_cast<char *>(OPENSSL_malloc(name_len));
102     if (name == NULL) {
103       goto err;
104     }
105     OPENSSL_strlcpy(name, objtmp, name_len);
106     OPENSSL_strlcat(name, " - ", name_len);
107     OPENSSL_strlcat(name, vtmp->name, name_len);
108     OPENSSL_free(vtmp->name);
109     vtmp->name = name;
110   }
111   if (ret == NULL && tret == NULL) {
112     return sk_CONF_VALUE_new_null();
113   }
114 
115   return tret;
116 err:
117   if (ret == NULL && tret != NULL) {
118     sk_CONF_VALUE_pop_free(tret, X509V3_conf_free);
119   }
120   return NULL;
121 }
122 
v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD * method,const X509V3_CTX * ctx,const STACK_OF (CONF_VALUE)* nval)123 static void *v2i_AUTHORITY_INFO_ACCESS(const X509V3_EXT_METHOD *method,
124                                        const X509V3_CTX *ctx,
125                                        const STACK_OF(CONF_VALUE) *nval) {
126   AUTHORITY_INFO_ACCESS *ainfo = NULL;
127   ACCESS_DESCRIPTION *acc;
128   if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
129     return NULL;
130   }
131   for (size_t i = 0; i < sk_CONF_VALUE_num(nval); i++) {
132     const CONF_VALUE *cnf = sk_CONF_VALUE_value(nval, i);
133     if (!(acc = ACCESS_DESCRIPTION_new()) ||
134         !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
135       goto err;
136     }
137     char *ptmp = strchr(cnf->name, ';');
138     if (!ptmp) {
139       OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
140       goto err;
141     }
142     CONF_VALUE ctmp;
143     ctmp.name = ptmp + 1;
144     ctmp.value = cnf->value;
145     if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) {
146       goto err;
147     }
148     char *objtmp = OPENSSL_strndup(cnf->name, ptmp - cnf->name);
149     if (objtmp == NULL) {
150       goto err;
151     }
152     acc->method = OBJ_txt2obj(objtmp, 0);
153     if (!acc->method) {
154       OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
155       ERR_add_error_data(2, "value=", objtmp);
156       OPENSSL_free(objtmp);
157       goto err;
158     }
159     OPENSSL_free(objtmp);
160   }
161   return ainfo;
162 err:
163   sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free);
164   return NULL;
165 }
166