1 | /* |
2 | * Copyright 2017-2018 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 | #include <stdio.h> |
10 | #include "internal/cryptlib.h" |
11 | #include <openssl/conf.h> |
12 | #include <openssl/types.h> |
13 | #include <openssl/asn1.h> |
14 | #include <openssl/asn1t.h> |
15 | |
16 | #include <openssl/x509v3.h> |
17 | |
18 | #include <openssl/safestack.h> |
19 | |
20 | #include "v3_admis.h" |
21 | #include "ext_dat.h" |
22 | |
23 | |
24 | ASN1_SEQUENCE(NAMING_AUTHORITY) = { |
25 | ASN1_OPT(NAMING_AUTHORITY, namingAuthorityId, ASN1_OBJECT), |
26 | ASN1_OPT(NAMING_AUTHORITY, namingAuthorityUrl, ASN1_IA5STRING), |
27 | ASN1_OPT(NAMING_AUTHORITY, namingAuthorityText, DIRECTORYSTRING), |
28 | } ASN1_SEQUENCE_END(NAMING_AUTHORITY) |
29 | |
30 | ASN1_SEQUENCE(PROFESSION_INFO) = { |
31 | ASN1_EXP_OPT(PROFESSION_INFO, namingAuthority, NAMING_AUTHORITY, 0), |
32 | ASN1_SEQUENCE_OF(PROFESSION_INFO, professionItems, DIRECTORYSTRING), |
33 | ASN1_SEQUENCE_OF_OPT(PROFESSION_INFO, professionOIDs, ASN1_OBJECT), |
34 | ASN1_OPT(PROFESSION_INFO, registrationNumber, ASN1_PRINTABLESTRING), |
35 | ASN1_OPT(PROFESSION_INFO, addProfessionInfo, ASN1_OCTET_STRING), |
36 | } ASN1_SEQUENCE_END(PROFESSION_INFO) |
37 | |
38 | ASN1_SEQUENCE(ADMISSIONS) = { |
39 | ASN1_EXP_OPT(ADMISSIONS, admissionAuthority, GENERAL_NAME, 0), |
40 | ASN1_EXP_OPT(ADMISSIONS, namingAuthority, NAMING_AUTHORITY, 1), |
41 | ASN1_SEQUENCE_OF(ADMISSIONS, professionInfos, PROFESSION_INFO), |
42 | } ASN1_SEQUENCE_END(ADMISSIONS) |
43 | |
44 | ASN1_SEQUENCE(ADMISSION_SYNTAX) = { |
45 | ASN1_OPT(ADMISSION_SYNTAX, admissionAuthority, GENERAL_NAME), |
46 | ASN1_SEQUENCE_OF(ADMISSION_SYNTAX, contentsOfAdmissions, ADMISSIONS), |
47 | } ASN1_SEQUENCE_END(ADMISSION_SYNTAX) |
48 | |
49 | IMPLEMENT_ASN1_FUNCTIONS(NAMING_AUTHORITY) |
50 | IMPLEMENT_ASN1_FUNCTIONS(PROFESSION_INFO) |
51 | IMPLEMENT_ASN1_FUNCTIONS(ADMISSIONS) |
52 | IMPLEMENT_ASN1_FUNCTIONS(ADMISSION_SYNTAX) |
53 | |
54 | static int i2r_ADMISSION_SYNTAX(const struct v3_ext_method *method, void *in, |
55 | BIO *bp, int ind); |
56 | |
57 | const X509V3_EXT_METHOD v3_ext_admission = { |
58 | NID_x509ExtAdmission, /* .ext_nid = */ |
59 | 0, /* .ext_flags = */ |
60 | ASN1_ITEM_ref(ADMISSION_SYNTAX), /* .it = */ |
61 | NULL, NULL, NULL, NULL, |
62 | NULL, /* .i2s = */ |
63 | NULL, /* .s2i = */ |
64 | NULL, /* .i2v = */ |
65 | NULL, /* .v2i = */ |
66 | &i2r_ADMISSION_SYNTAX, /* .i2r = */ |
67 | NULL, /* .r2i = */ |
68 | NULL /* extension-specific data */ |
69 | }; |
70 | |
71 | |
72 | static int i2r_NAMING_AUTHORITY(const struct v3_ext_method *method, void *in, |
73 | BIO *bp, int ind) |
74 | { |
75 | NAMING_AUTHORITY * namingAuthority = (NAMING_AUTHORITY*) in; |
76 | |
77 | if (namingAuthority == NULL) |
78 | return 0; |
79 | |
80 | if (namingAuthority->namingAuthorityId == NULL |
81 | && namingAuthority->namingAuthorityText == NULL |
82 | && namingAuthority->namingAuthorityUrl == NULL) |
83 | return 0; |
84 | |
85 | if (BIO_printf(bp, "%*snamingAuthority: " , ind, "" ) <= 0) |
86 | goto err; |
87 | |
88 | if (namingAuthority->namingAuthorityId != NULL) { |
89 | char objbuf[128]; |
90 | const char *ln = OBJ_nid2ln(OBJ_obj2nid(namingAuthority->namingAuthorityId)); |
91 | |
92 | if (BIO_printf(bp, "%*s admissionAuthorityId: " , ind, "" ) <= 0) |
93 | goto err; |
94 | |
95 | OBJ_obj2txt(objbuf, sizeof(objbuf), namingAuthority->namingAuthorityId, 1); |
96 | |
97 | if (BIO_printf(bp, "%s%s%s%s\n" , ln ? ln : "" , |
98 | ln ? " (" : "" , objbuf, ln ? ")" : "" ) <= 0) |
99 | goto err; |
100 | } |
101 | if (namingAuthority->namingAuthorityText != NULL) { |
102 | if (BIO_printf(bp, "%*s namingAuthorityText: " , ind, "" ) <= 0 |
103 | || ASN1_STRING_print(bp, namingAuthority->namingAuthorityText) <= 0 |
104 | || BIO_printf(bp, "\n" ) <= 0) |
105 | goto err; |
106 | } |
107 | if (namingAuthority->namingAuthorityUrl != NULL ) { |
108 | if (BIO_printf(bp, "%*s namingAuthorityUrl: " , ind, "" ) <= 0 |
109 | || ASN1_STRING_print(bp, namingAuthority->namingAuthorityUrl) <= 0 |
110 | || BIO_printf(bp, "\n" ) <= 0) |
111 | goto err; |
112 | } |
113 | return 1; |
114 | |
115 | err: |
116 | return 0; |
117 | } |
118 | |
119 | static int i2r_ADMISSION_SYNTAX(const struct v3_ext_method *method, void *in, |
120 | BIO *bp, int ind) |
121 | { |
122 | ADMISSION_SYNTAX * admission = (ADMISSION_SYNTAX *)in; |
123 | int i, j, k; |
124 | |
125 | if (admission->admissionAuthority != NULL) { |
126 | if (BIO_printf(bp, "%*sadmissionAuthority:\n" , ind, "" ) <= 0 |
127 | || BIO_printf(bp, "%*s " , ind, "" ) <= 0 |
128 | || GENERAL_NAME_print(bp, admission->admissionAuthority) <= 0 |
129 | || BIO_printf(bp, "\n" ) <= 0) |
130 | goto err; |
131 | } |
132 | |
133 | for (i = 0; i < sk_ADMISSIONS_num(admission->contentsOfAdmissions); i++) { |
134 | ADMISSIONS* entry = sk_ADMISSIONS_value(admission->contentsOfAdmissions, i); |
135 | |
136 | if (BIO_printf(bp, "%*sEntry %0d:\n" , ind, "" , 1 + i) <= 0) goto err; |
137 | |
138 | if (entry->admissionAuthority != NULL) { |
139 | if (BIO_printf(bp, "%*s admissionAuthority:\n" , ind, "" ) <= 0 |
140 | || BIO_printf(bp, "%*s " , ind, "" ) <= 0 |
141 | || GENERAL_NAME_print(bp, entry->admissionAuthority) <= 0 |
142 | || BIO_printf(bp, "\n" ) <= 0) |
143 | goto err; |
144 | } |
145 | |
146 | if (entry->namingAuthority != NULL) { |
147 | if (i2r_NAMING_AUTHORITY(method, entry->namingAuthority, bp, ind) <= 0) |
148 | goto err; |
149 | } |
150 | |
151 | for (j = 0; j < sk_PROFESSION_INFO_num(entry->professionInfos); j++) { |
152 | PROFESSION_INFO* pinfo = sk_PROFESSION_INFO_value(entry->professionInfos, j); |
153 | |
154 | if (BIO_printf(bp, "%*s Profession Info Entry %0d:\n" , ind, "" , 1 + j) <= 0) |
155 | goto err; |
156 | |
157 | if (pinfo->registrationNumber != NULL) { |
158 | if (BIO_printf(bp, "%*s registrationNumber: " , ind, "" ) <= 0 |
159 | || ASN1_STRING_print(bp, pinfo->registrationNumber) <= 0 |
160 | || BIO_printf(bp, "\n" ) <= 0) |
161 | goto err; |
162 | } |
163 | |
164 | if (pinfo->namingAuthority != NULL) { |
165 | if (i2r_NAMING_AUTHORITY(method, pinfo->namingAuthority, bp, ind + 2) <= 0) |
166 | goto err; |
167 | } |
168 | |
169 | if (pinfo->professionItems != NULL) { |
170 | |
171 | if (BIO_printf(bp, "%*s Info Entries:\n" , ind, "" ) <= 0) |
172 | goto err; |
173 | for (k = 0; k < sk_ASN1_STRING_num(pinfo->professionItems); k++) { |
174 | ASN1_STRING* val = sk_ASN1_STRING_value(pinfo->professionItems, k); |
175 | |
176 | if (BIO_printf(bp, "%*s " , ind, "" ) <= 0 |
177 | || ASN1_STRING_print(bp, val) <= 0 |
178 | || BIO_printf(bp, "\n" ) <= 0) |
179 | goto err; |
180 | } |
181 | } |
182 | |
183 | if (pinfo->professionOIDs != NULL) { |
184 | if (BIO_printf(bp, "%*s Profession OIDs:\n" , ind, "" ) <= 0) |
185 | goto err; |
186 | for (k = 0; k < sk_ASN1_OBJECT_num(pinfo->professionOIDs); k++) { |
187 | ASN1_OBJECT* obj = sk_ASN1_OBJECT_value(pinfo->professionOIDs, k); |
188 | const char *ln = OBJ_nid2ln(OBJ_obj2nid(obj)); |
189 | char objbuf[128]; |
190 | |
191 | OBJ_obj2txt(objbuf, sizeof(objbuf), obj, 1); |
192 | if (BIO_printf(bp, "%*s %s%s%s%s\n" , ind, "" , |
193 | ln ? ln : "" , ln ? " (" : "" , |
194 | objbuf, ln ? ")" : "" ) <= 0) |
195 | goto err; |
196 | } |
197 | } |
198 | } |
199 | } |
200 | return 1; |
201 | |
202 | err: |
203 | return -1; |
204 | } |
205 | |
206 | const ASN1_OBJECT *NAMING_AUTHORITY_get0_authorityId(const NAMING_AUTHORITY *n) |
207 | { |
208 | return n->namingAuthorityId; |
209 | } |
210 | |
211 | void NAMING_AUTHORITY_set0_authorityId(NAMING_AUTHORITY *n, ASN1_OBJECT* id) |
212 | { |
213 | ASN1_OBJECT_free(n->namingAuthorityId); |
214 | n->namingAuthorityId = id; |
215 | } |
216 | |
217 | const ASN1_IA5STRING *NAMING_AUTHORITY_get0_authorityURL( |
218 | const NAMING_AUTHORITY *n) |
219 | { |
220 | return n->namingAuthorityUrl; |
221 | } |
222 | |
223 | void NAMING_AUTHORITY_set0_authorityURL(NAMING_AUTHORITY *n, ASN1_IA5STRING* u) |
224 | { |
225 | ASN1_IA5STRING_free(n->namingAuthorityUrl); |
226 | n->namingAuthorityUrl = u; |
227 | } |
228 | |
229 | const ASN1_STRING *NAMING_AUTHORITY_get0_authorityText( |
230 | const NAMING_AUTHORITY *n) |
231 | { |
232 | return n->namingAuthorityText; |
233 | } |
234 | |
235 | void NAMING_AUTHORITY_set0_authorityText(NAMING_AUTHORITY *n, ASN1_STRING* t) |
236 | { |
237 | ASN1_IA5STRING_free(n->namingAuthorityText); |
238 | n->namingAuthorityText = t; |
239 | } |
240 | |
241 | const GENERAL_NAME *ADMISSION_SYNTAX_get0_admissionAuthority(const ADMISSION_SYNTAX *as) |
242 | { |
243 | return as->admissionAuthority; |
244 | } |
245 | |
246 | void ADMISSION_SYNTAX_set0_admissionAuthority(ADMISSION_SYNTAX *as, |
247 | GENERAL_NAME *aa) |
248 | { |
249 | GENERAL_NAME_free(as->admissionAuthority); |
250 | as->admissionAuthority = aa; |
251 | } |
252 | |
253 | const STACK_OF(ADMISSIONS) *ADMISSION_SYNTAX_get0_contentsOfAdmissions(const ADMISSION_SYNTAX *as) |
254 | { |
255 | return as->contentsOfAdmissions; |
256 | } |
257 | |
258 | void ADMISSION_SYNTAX_set0_contentsOfAdmissions(ADMISSION_SYNTAX *as, |
259 | STACK_OF(ADMISSIONS) *a) |
260 | { |
261 | sk_ADMISSIONS_pop_free(as->contentsOfAdmissions, ADMISSIONS_free); |
262 | as->contentsOfAdmissions = a; |
263 | } |
264 | |
265 | const GENERAL_NAME *ADMISSIONS_get0_admissionAuthority(const ADMISSIONS *a) |
266 | { |
267 | return a->admissionAuthority; |
268 | } |
269 | |
270 | void ADMISSIONS_set0_admissionAuthority(ADMISSIONS *a, GENERAL_NAME *aa) |
271 | { |
272 | GENERAL_NAME_free(a->admissionAuthority); |
273 | a->admissionAuthority = aa; |
274 | } |
275 | |
276 | const NAMING_AUTHORITY *ADMISSIONS_get0_namingAuthority(const ADMISSIONS *a) |
277 | { |
278 | return a->namingAuthority; |
279 | } |
280 | |
281 | void ADMISSIONS_set0_namingAuthority(ADMISSIONS *a, NAMING_AUTHORITY *na) |
282 | { |
283 | NAMING_AUTHORITY_free(a->namingAuthority); |
284 | a->namingAuthority = na; |
285 | } |
286 | |
287 | const PROFESSION_INFOS *ADMISSIONS_get0_professionInfos(const ADMISSIONS *a) |
288 | { |
289 | return a->professionInfos; |
290 | } |
291 | |
292 | void ADMISSIONS_set0_professionInfos(ADMISSIONS *a, PROFESSION_INFOS *pi) |
293 | { |
294 | sk_PROFESSION_INFO_pop_free(a->professionInfos, PROFESSION_INFO_free); |
295 | a->professionInfos = pi; |
296 | } |
297 | |
298 | const ASN1_OCTET_STRING *PROFESSION_INFO_get0_addProfessionInfo(const PROFESSION_INFO *pi) |
299 | { |
300 | return pi->addProfessionInfo; |
301 | } |
302 | |
303 | void PROFESSION_INFO_set0_addProfessionInfo(PROFESSION_INFO *pi, |
304 | ASN1_OCTET_STRING *aos) |
305 | { |
306 | ASN1_OCTET_STRING_free(pi->addProfessionInfo); |
307 | pi->addProfessionInfo = aos; |
308 | } |
309 | |
310 | const NAMING_AUTHORITY *PROFESSION_INFO_get0_namingAuthority(const PROFESSION_INFO *pi) |
311 | { |
312 | return pi->namingAuthority; |
313 | } |
314 | |
315 | void PROFESSION_INFO_set0_namingAuthority(PROFESSION_INFO *pi, |
316 | NAMING_AUTHORITY *na) |
317 | { |
318 | NAMING_AUTHORITY_free(pi->namingAuthority); |
319 | pi->namingAuthority = na; |
320 | } |
321 | |
322 | const STACK_OF(ASN1_STRING) *PROFESSION_INFO_get0_professionItems(const PROFESSION_INFO *pi) |
323 | { |
324 | return pi->professionItems; |
325 | } |
326 | |
327 | void PROFESSION_INFO_set0_professionItems(PROFESSION_INFO *pi, |
328 | STACK_OF(ASN1_STRING) *as) |
329 | { |
330 | sk_ASN1_STRING_pop_free(pi->professionItems, ASN1_STRING_free); |
331 | pi->professionItems = as; |
332 | } |
333 | |
334 | const STACK_OF(ASN1_OBJECT) *PROFESSION_INFO_get0_professionOIDs(const PROFESSION_INFO *pi) |
335 | { |
336 | return pi->professionOIDs; |
337 | } |
338 | |
339 | void PROFESSION_INFO_set0_professionOIDs(PROFESSION_INFO *pi, |
340 | STACK_OF(ASN1_OBJECT) *po) |
341 | { |
342 | sk_ASN1_OBJECT_pop_free(pi->professionOIDs, ASN1_OBJECT_free); |
343 | pi->professionOIDs = po; |
344 | } |
345 | |
346 | const ASN1_PRINTABLESTRING *PROFESSION_INFO_get0_registrationNumber(const PROFESSION_INFO *pi) |
347 | { |
348 | return pi->registrationNumber; |
349 | } |
350 | |
351 | void PROFESSION_INFO_set0_registrationNumber(PROFESSION_INFO *pi, |
352 | ASN1_PRINTABLESTRING *rn) |
353 | { |
354 | ASN1_PRINTABLESTRING_free(pi->registrationNumber); |
355 | pi->registrationNumber = rn; |
356 | } |
357 | |