1 | /*
|
---|
2 | * Copyright 1995-2018 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 "crypto/ctype.h"
|
---|
12 | #include "internal/cryptlib.h"
|
---|
13 | #include <openssl/asn1t.h>
|
---|
14 | #include <openssl/x509.h>
|
---|
15 | #include "crypto/x509.h"
|
---|
16 | #include "crypto/asn1.h"
|
---|
17 | #include "x509_local.h"
|
---|
18 |
|
---|
19 | /*
|
---|
20 | * Maximum length of X509_NAME: much larger than anything we should
|
---|
21 | * ever see in practice.
|
---|
22 | */
|
---|
23 |
|
---|
24 | #define X509_NAME_MAX (1024 * 1024)
|
---|
25 |
|
---|
26 | static int x509_name_ex_d2i(ASN1_VALUE **val,
|
---|
27 | const unsigned char **in, long len,
|
---|
28 | const ASN1_ITEM *it,
|
---|
29 | int tag, int aclass, char opt, ASN1_TLC *ctx);
|
---|
30 |
|
---|
31 | static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
|
---|
32 | const ASN1_ITEM *it, int tag, int aclass);
|
---|
33 | static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
|
---|
34 | static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
|
---|
35 |
|
---|
36 | static int x509_name_encode(X509_NAME *a);
|
---|
37 | static int x509_name_canon(X509_NAME *a);
|
---|
38 | static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in);
|
---|
39 | static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
|
---|
40 | unsigned char **in);
|
---|
41 |
|
---|
42 | static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
|
---|
43 | int indent,
|
---|
44 | const char *fname, const ASN1_PCTX *pctx);
|
---|
45 |
|
---|
46 | ASN1_SEQUENCE(X509_NAME_ENTRY) = {
|
---|
47 | ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
|
---|
48 | ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
|
---|
49 | } ASN1_SEQUENCE_END(X509_NAME_ENTRY)
|
---|
50 |
|
---|
51 | IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
|
---|
52 | IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
|
---|
53 |
|
---|
54 | /*
|
---|
55 | * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
|
---|
56 | * declare two template wrappers for this
|
---|
57 | */
|
---|
58 |
|
---|
59 | ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
|
---|
60 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
|
---|
61 | static_ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
|
---|
62 |
|
---|
63 | ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
|
---|
64 | ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
|
---|
65 | static_ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
|
---|
66 |
|
---|
67 | /*
|
---|
68 | * Normally that's where it would end: we'd have two nested STACK structures
|
---|
69 | * representing the ASN1. Unfortunately X509_NAME uses a completely different
|
---|
70 | * form and caches encodings so we have to process the internal form and
|
---|
71 | * convert to the external form.
|
---|
72 | */
|
---|
73 |
|
---|
74 | static const ASN1_EXTERN_FUNCS x509_name_ff = {
|
---|
75 | NULL,
|
---|
76 | x509_name_ex_new,
|
---|
77 | x509_name_ex_free,
|
---|
78 | 0, /* Default clear behaviour is OK */
|
---|
79 | x509_name_ex_d2i,
|
---|
80 | x509_name_ex_i2d,
|
---|
81 | x509_name_ex_print
|
---|
82 | };
|
---|
83 |
|
---|
84 | IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
|
---|
85 |
|
---|
86 | IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
|
---|
87 |
|
---|
88 | IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
|
---|
89 |
|
---|
90 | static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
|
---|
91 | {
|
---|
92 | X509_NAME *ret = OPENSSL_zalloc(sizeof(*ret));
|
---|
93 |
|
---|
94 | if (ret == NULL)
|
---|
95 | goto memerr;
|
---|
96 | if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
|
---|
97 | goto memerr;
|
---|
98 | if ((ret->bytes = BUF_MEM_new()) == NULL)
|
---|
99 | goto memerr;
|
---|
100 | ret->modified = 1;
|
---|
101 | *val = (ASN1_VALUE *)ret;
|
---|
102 | return 1;
|
---|
103 |
|
---|
104 | memerr:
|
---|
105 | ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
|
---|
106 | if (ret) {
|
---|
107 | sk_X509_NAME_ENTRY_free(ret->entries);
|
---|
108 | OPENSSL_free(ret);
|
---|
109 | }
|
---|
110 | return 0;
|
---|
111 | }
|
---|
112 |
|
---|
113 | static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
---|
114 | {
|
---|
115 | X509_NAME *a;
|
---|
116 |
|
---|
117 | if (!pval || !*pval)
|
---|
118 | return;
|
---|
119 | a = (X509_NAME *)*pval;
|
---|
120 |
|
---|
121 | BUF_MEM_free(a->bytes);
|
---|
122 | sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
|
---|
123 | OPENSSL_free(a->canon_enc);
|
---|
124 | OPENSSL_free(a);
|
---|
125 | *pval = NULL;
|
---|
126 | }
|
---|
127 |
|
---|
128 | static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
|
---|
129 | {
|
---|
130 | sk_X509_NAME_ENTRY_free(ne);
|
---|
131 | }
|
---|
132 |
|
---|
133 | static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
|
---|
134 | {
|
---|
135 | sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
|
---|
136 | }
|
---|
137 |
|
---|
138 | static int x509_name_ex_d2i(ASN1_VALUE **val,
|
---|
139 | const unsigned char **in, long len,
|
---|
140 | const ASN1_ITEM *it, int tag, int aclass,
|
---|
141 | char opt, ASN1_TLC *ctx)
|
---|
142 | {
|
---|
143 | const unsigned char *p = *in, *q;
|
---|
144 | union {
|
---|
145 | STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
|
---|
146 | ASN1_VALUE *a;
|
---|
147 | } intname = {
|
---|
148 | NULL
|
---|
149 | };
|
---|
150 | union {
|
---|
151 | X509_NAME *x;
|
---|
152 | ASN1_VALUE *a;
|
---|
153 | } nm = {
|
---|
154 | NULL
|
---|
155 | };
|
---|
156 | int i, j, ret;
|
---|
157 | STACK_OF(X509_NAME_ENTRY) *entries;
|
---|
158 | X509_NAME_ENTRY *entry;
|
---|
159 | if (len > X509_NAME_MAX)
|
---|
160 | len = X509_NAME_MAX;
|
---|
161 | q = p;
|
---|
162 |
|
---|
163 | /* Get internal representation of Name */
|
---|
164 | ret = ASN1_item_ex_d2i(&intname.a,
|
---|
165 | &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
|
---|
166 | tag, aclass, opt, ctx);
|
---|
167 |
|
---|
168 | if (ret <= 0)
|
---|
169 | return ret;
|
---|
170 |
|
---|
171 | if (*val)
|
---|
172 | x509_name_ex_free(val, NULL);
|
---|
173 | if (!x509_name_ex_new(&nm.a, NULL))
|
---|
174 | goto err;
|
---|
175 | /* We've decoded it: now cache encoding */
|
---|
176 | if (!BUF_MEM_grow(nm.x->bytes, p - q))
|
---|
177 | goto err;
|
---|
178 | memcpy(nm.x->bytes->data, q, p - q);
|
---|
179 |
|
---|
180 | /* Convert internal representation to X509_NAME structure */
|
---|
181 | for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
|
---|
182 | entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
|
---|
183 | for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
|
---|
184 | entry = sk_X509_NAME_ENTRY_value(entries, j);
|
---|
185 | entry->set = i;
|
---|
186 | if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
|
---|
187 | goto err;
|
---|
188 | sk_X509_NAME_ENTRY_set(entries, j, NULL);
|
---|
189 | }
|
---|
190 | }
|
---|
191 | ret = x509_name_canon(nm.x);
|
---|
192 | if (!ret)
|
---|
193 | goto err;
|
---|
194 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
---|
195 | local_sk_X509_NAME_ENTRY_free);
|
---|
196 | nm.x->modified = 0;
|
---|
197 | *val = nm.a;
|
---|
198 | *in = p;
|
---|
199 | return ret;
|
---|
200 |
|
---|
201 | err:
|
---|
202 | if (nm.x != NULL)
|
---|
203 | X509_NAME_free(nm.x);
|
---|
204 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
---|
205 | local_sk_X509_NAME_ENTRY_pop_free);
|
---|
206 | ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
|
---|
207 | return 0;
|
---|
208 | }
|
---|
209 |
|
---|
210 | static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
|
---|
211 | const ASN1_ITEM *it, int tag, int aclass)
|
---|
212 | {
|
---|
213 | int ret;
|
---|
214 | X509_NAME *a = (X509_NAME *)*val;
|
---|
215 | if (a->modified) {
|
---|
216 | ret = x509_name_encode(a);
|
---|
217 | if (ret < 0)
|
---|
218 | return ret;
|
---|
219 | ret = x509_name_canon(a);
|
---|
220 | if (ret < 0)
|
---|
221 | return ret;
|
---|
222 | }
|
---|
223 | ret = a->bytes->length;
|
---|
224 | if (out != NULL) {
|
---|
225 | memcpy(*out, a->bytes->data, ret);
|
---|
226 | *out += ret;
|
---|
227 | }
|
---|
228 | return ret;
|
---|
229 | }
|
---|
230 |
|
---|
231 | static int x509_name_encode(X509_NAME *a)
|
---|
232 | {
|
---|
233 | union {
|
---|
234 | STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
|
---|
235 | ASN1_VALUE *a;
|
---|
236 | } intname = {
|
---|
237 | NULL
|
---|
238 | };
|
---|
239 | int len;
|
---|
240 | unsigned char *p;
|
---|
241 | STACK_OF(X509_NAME_ENTRY) *entries = NULL;
|
---|
242 | X509_NAME_ENTRY *entry;
|
---|
243 | int i, set = -1;
|
---|
244 | intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
|
---|
245 | if (!intname.s)
|
---|
246 | goto memerr;
|
---|
247 | for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
|
---|
248 | entry = sk_X509_NAME_ENTRY_value(a->entries, i);
|
---|
249 | if (entry->set != set) {
|
---|
250 | entries = sk_X509_NAME_ENTRY_new_null();
|
---|
251 | if (!entries)
|
---|
252 | goto memerr;
|
---|
253 | if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) {
|
---|
254 | sk_X509_NAME_ENTRY_free(entries);
|
---|
255 | goto memerr;
|
---|
256 | }
|
---|
257 | set = entry->set;
|
---|
258 | }
|
---|
259 | if (!sk_X509_NAME_ENTRY_push(entries, entry))
|
---|
260 | goto memerr;
|
---|
261 | }
|
---|
262 | len = ASN1_item_ex_i2d(&intname.a, NULL,
|
---|
263 | ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
|
---|
264 | if (!BUF_MEM_grow(a->bytes, len))
|
---|
265 | goto memerr;
|
---|
266 | p = (unsigned char *)a->bytes->data;
|
---|
267 | ASN1_item_ex_i2d(&intname.a,
|
---|
268 | &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
|
---|
269 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
---|
270 | local_sk_X509_NAME_ENTRY_free);
|
---|
271 | a->modified = 0;
|
---|
272 | return len;
|
---|
273 | memerr:
|
---|
274 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
---|
275 | local_sk_X509_NAME_ENTRY_free);
|
---|
276 | ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
|
---|
277 | return -1;
|
---|
278 | }
|
---|
279 |
|
---|
280 | static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
|
---|
281 | int indent,
|
---|
282 | const char *fname, const ASN1_PCTX *pctx)
|
---|
283 | {
|
---|
284 | if (X509_NAME_print_ex(out, (const X509_NAME *)*pval,
|
---|
285 | indent, pctx->nm_flags) <= 0)
|
---|
286 | return 0;
|
---|
287 | return 2;
|
---|
288 | }
|
---|
289 |
|
---|
290 | /*
|
---|
291 | * This function generates the canonical encoding of the Name structure. In
|
---|
292 | * it all strings are converted to UTF8, leading, trailing and multiple
|
---|
293 | * spaces collapsed, converted to lower case and the leading SEQUENCE header
|
---|
294 | * removed. In future we could also normalize the UTF8 too. By doing this
|
---|
295 | * comparison of Name structures can be rapidly performed by just using
|
---|
296 | * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
|
---|
297 | * constraints of type dirName can also be checked with a simple memcmp().
|
---|
298 | */
|
---|
299 |
|
---|
300 | static int x509_name_canon(X509_NAME *a)
|
---|
301 | {
|
---|
302 | unsigned char *p;
|
---|
303 | STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname;
|
---|
304 | STACK_OF(X509_NAME_ENTRY) *entries = NULL;
|
---|
305 | X509_NAME_ENTRY *entry, *tmpentry = NULL;
|
---|
306 | int i, set = -1, ret = 0, len;
|
---|
307 |
|
---|
308 | OPENSSL_free(a->canon_enc);
|
---|
309 | a->canon_enc = NULL;
|
---|
310 | /* Special case: empty X509_NAME => null encoding */
|
---|
311 | if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
|
---|
312 | a->canon_enclen = 0;
|
---|
313 | return 1;
|
---|
314 | }
|
---|
315 | intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
|
---|
316 | if (intname == NULL) {
|
---|
317 | X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
|
---|
318 | goto err;
|
---|
319 | }
|
---|
320 | for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
|
---|
321 | entry = sk_X509_NAME_ENTRY_value(a->entries, i);
|
---|
322 | if (entry->set != set) {
|
---|
323 | entries = sk_X509_NAME_ENTRY_new_null();
|
---|
324 | if (entries == NULL)
|
---|
325 | goto err;
|
---|
326 | if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
|
---|
327 | sk_X509_NAME_ENTRY_free(entries);
|
---|
328 | X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
|
---|
329 | goto err;
|
---|
330 | }
|
---|
331 | set = entry->set;
|
---|
332 | }
|
---|
333 | tmpentry = X509_NAME_ENTRY_new();
|
---|
334 | if (tmpentry == NULL) {
|
---|
335 | X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
|
---|
336 | goto err;
|
---|
337 | }
|
---|
338 | tmpentry->object = OBJ_dup(entry->object);
|
---|
339 | if (tmpentry->object == NULL) {
|
---|
340 | X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
|
---|
341 | goto err;
|
---|
342 | }
|
---|
343 | if (!asn1_string_canon(tmpentry->value, entry->value))
|
---|
344 | goto err;
|
---|
345 | if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) {
|
---|
346 | X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
|
---|
347 | goto err;
|
---|
348 | }
|
---|
349 | tmpentry = NULL;
|
---|
350 | }
|
---|
351 |
|
---|
352 | /* Finally generate encoding */
|
---|
353 | len = i2d_name_canon(intname, NULL);
|
---|
354 | if (len < 0)
|
---|
355 | goto err;
|
---|
356 | a->canon_enclen = len;
|
---|
357 |
|
---|
358 | p = OPENSSL_malloc(a->canon_enclen);
|
---|
359 | if (p == NULL) {
|
---|
360 | X509err(X509_F_X509_NAME_CANON, ERR_R_MALLOC_FAILURE);
|
---|
361 | goto err;
|
---|
362 | }
|
---|
363 |
|
---|
364 | a->canon_enc = p;
|
---|
365 |
|
---|
366 | i2d_name_canon(intname, &p);
|
---|
367 |
|
---|
368 | ret = 1;
|
---|
369 |
|
---|
370 | err:
|
---|
371 | X509_NAME_ENTRY_free(tmpentry);
|
---|
372 | sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
|
---|
373 | local_sk_X509_NAME_ENTRY_pop_free);
|
---|
374 | return ret;
|
---|
375 | }
|
---|
376 |
|
---|
377 | /* Bitmap of all the types of string that will be canonicalized. */
|
---|
378 |
|
---|
379 | #define ASN1_MASK_CANON \
|
---|
380 | (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
|
---|
381 | | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
|
---|
382 | | B_ASN1_VISIBLESTRING)
|
---|
383 |
|
---|
384 | static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in)
|
---|
385 | {
|
---|
386 | unsigned char *to, *from;
|
---|
387 | int len, i;
|
---|
388 |
|
---|
389 | /* If type not in bitmask just copy string across */
|
---|
390 | if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
|
---|
391 | if (!ASN1_STRING_copy(out, in))
|
---|
392 | return 0;
|
---|
393 | return 1;
|
---|
394 | }
|
---|
395 |
|
---|
396 | out->type = V_ASN1_UTF8STRING;
|
---|
397 | out->length = ASN1_STRING_to_UTF8(&out->data, in);
|
---|
398 | if (out->length == -1)
|
---|
399 | return 0;
|
---|
400 |
|
---|
401 | to = out->data;
|
---|
402 | from = to;
|
---|
403 |
|
---|
404 | len = out->length;
|
---|
405 |
|
---|
406 | /*
|
---|
407 | * Convert string in place to canonical form. Ultimately we may need to
|
---|
408 | * handle a wider range of characters but for now ignore anything with
|
---|
409 | * MSB set and rely on the ossl_isspace() to fail on bad characters without
|
---|
410 | * needing isascii or range checks as well.
|
---|
411 | */
|
---|
412 |
|
---|
413 | /* Ignore leading spaces */
|
---|
414 | while (len > 0 && ossl_isspace(*from)) {
|
---|
415 | from++;
|
---|
416 | len--;
|
---|
417 | }
|
---|
418 |
|
---|
419 | to = from + len;
|
---|
420 |
|
---|
421 | /* Ignore trailing spaces */
|
---|
422 | while (len > 0 && ossl_isspace(to[-1])) {
|
---|
423 | to--;
|
---|
424 | len--;
|
---|
425 | }
|
---|
426 |
|
---|
427 | to = out->data;
|
---|
428 |
|
---|
429 | i = 0;
|
---|
430 | while (i < len) {
|
---|
431 | /* If not ASCII set just copy across */
|
---|
432 | if (!ossl_isascii(*from)) {
|
---|
433 | *to++ = *from++;
|
---|
434 | i++;
|
---|
435 | }
|
---|
436 | /* Collapse multiple spaces */
|
---|
437 | else if (ossl_isspace(*from)) {
|
---|
438 | /* Copy one space across */
|
---|
439 | *to++ = ' ';
|
---|
440 | /*
|
---|
441 | * Ignore subsequent spaces. Note: don't need to check len here
|
---|
442 | * because we know the last character is a non-space so we can't
|
---|
443 | * overflow.
|
---|
444 | */
|
---|
445 | do {
|
---|
446 | from++;
|
---|
447 | i++;
|
---|
448 | }
|
---|
449 | while (ossl_isspace(*from));
|
---|
450 | } else {
|
---|
451 | *to++ = ossl_tolower(*from);
|
---|
452 | from++;
|
---|
453 | i++;
|
---|
454 | }
|
---|
455 | }
|
---|
456 |
|
---|
457 | out->length = to - out->data;
|
---|
458 |
|
---|
459 | return 1;
|
---|
460 |
|
---|
461 | }
|
---|
462 |
|
---|
463 | static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
|
---|
464 | unsigned char **in)
|
---|
465 | {
|
---|
466 | int i, len, ltmp;
|
---|
467 | ASN1_VALUE *v;
|
---|
468 | STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
|
---|
469 |
|
---|
470 | len = 0;
|
---|
471 | for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
|
---|
472 | v = sk_ASN1_VALUE_value(intname, i);
|
---|
473 | ltmp = ASN1_item_ex_i2d(&v, in,
|
---|
474 | ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
|
---|
475 | if (ltmp < 0)
|
---|
476 | return ltmp;
|
---|
477 | len += ltmp;
|
---|
478 | }
|
---|
479 | return len;
|
---|
480 | }
|
---|
481 |
|
---|
482 | int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
|
---|
483 | {
|
---|
484 | if (*xn == name)
|
---|
485 | return *xn != NULL;
|
---|
486 | if ((name = X509_NAME_dup(name)) == NULL)
|
---|
487 | return 0;
|
---|
488 | X509_NAME_free(*xn);
|
---|
489 | *xn = name;
|
---|
490 | return 1;
|
---|
491 | }
|
---|
492 |
|
---|
493 | int X509_NAME_print(BIO *bp, const X509_NAME *name, int obase)
|
---|
494 | {
|
---|
495 | char *s, *c, *b;
|
---|
496 | int l, i;
|
---|
497 |
|
---|
498 | l = 80 - 2 - obase;
|
---|
499 |
|
---|
500 | b = X509_NAME_oneline(name, NULL, 0);
|
---|
501 | if (!b)
|
---|
502 | return 0;
|
---|
503 | if (!*b) {
|
---|
504 | OPENSSL_free(b);
|
---|
505 | return 1;
|
---|
506 | }
|
---|
507 | s = b + 1; /* skip the first slash */
|
---|
508 |
|
---|
509 | c = s;
|
---|
510 | for (;;) {
|
---|
511 | if (((*s == '/') &&
|
---|
512 | (ossl_isupper(s[1]) && ((s[2] == '=') ||
|
---|
513 | (ossl_isupper(s[2]) && (s[3] == '='))
|
---|
514 | ))) || (*s == '\0'))
|
---|
515 | {
|
---|
516 | i = s - c;
|
---|
517 | if (BIO_write(bp, c, i) != i)
|
---|
518 | goto err;
|
---|
519 | c = s + 1; /* skip following slash */
|
---|
520 | if (*s != '\0') {
|
---|
521 | if (BIO_write(bp, ", ", 2) != 2)
|
---|
522 | goto err;
|
---|
523 | }
|
---|
524 | l--;
|
---|
525 | }
|
---|
526 | if (*s == '\0')
|
---|
527 | break;
|
---|
528 | s++;
|
---|
529 | l--;
|
---|
530 | }
|
---|
531 |
|
---|
532 | OPENSSL_free(b);
|
---|
533 | return 1;
|
---|
534 | err:
|
---|
535 | X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
|
---|
536 | OPENSSL_free(b);
|
---|
537 | return 0;
|
---|
538 | }
|
---|
539 |
|
---|
540 | int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder,
|
---|
541 | size_t *pderlen)
|
---|
542 | {
|
---|
543 | /* Make sure encoding is valid */
|
---|
544 | if (i2d_X509_NAME(nm, NULL) <= 0)
|
---|
545 | return 0;
|
---|
546 | if (pder != NULL)
|
---|
547 | *pder = (unsigned char *)nm->bytes->data;
|
---|
548 | if (pderlen != NULL)
|
---|
549 | *pderlen = nm->bytes->length;
|
---|
550 | return 1;
|
---|
551 | }
|
---|