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