Coverage Report

Created: 2022-08-24 06:31

/src/libressl/crypto/asn1/x_name.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: x_name.c,v 1.37 2021/12/25 13:17:48 jsing Exp $ */
2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3
 * All rights reserved.
4
 *
5
 * This package is an SSL implementation written
6
 * by Eric Young (eay@cryptsoft.com).
7
 * The implementation was written so as to conform with Netscapes SSL.
8
 *
9
 * This library is free for commercial and non-commercial use as long as
10
 * the following conditions are aheared to.  The following conditions
11
 * apply to all code found in this distribution, be it the RC4, RSA,
12
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13
 * included with this distribution is covered by the same copyright terms
14
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15
 *
16
 * Copyright remains Eric Young's, and as such any Copyright notices in
17
 * the code are not to be removed.
18
 * If this package is used in a product, Eric Young should be given attribution
19
 * as the author of the parts of the library used.
20
 * This can be in the form of a textual message at program startup or
21
 * in documentation (online or textual) provided with the package.
22
 *
23
 * Redistribution and use in source and binary forms, with or without
24
 * modification, are permitted provided that the following conditions
25
 * are met:
26
 * 1. Redistributions of source code must retain the copyright
27
 *    notice, this list of conditions and the following disclaimer.
28
 * 2. Redistributions in binary form must reproduce the above copyright
29
 *    notice, this list of conditions and the following disclaimer in the
30
 *    documentation and/or other materials provided with the distribution.
31
 * 3. All advertising materials mentioning features or use of this software
32
 *    must display the following acknowledgement:
33
 *    "This product includes cryptographic software written by
34
 *     Eric Young (eay@cryptsoft.com)"
35
 *    The word 'cryptographic' can be left out if the rouines from the library
36
 *    being used are not cryptographic related :-).
37
 * 4. If you include any Windows specific code (or a derivative thereof) from
38
 *    the apps directory (application code) you must include an acknowledgement:
39
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51
 * SUCH DAMAGE.
52
 *
53
 * The licence and distribution terms for any publically available version or
54
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
55
 * copied and put under another distribution licence
56
 * [including the GNU Public Licence.]
57
 */
58
59
#include <ctype.h>
60
#include <stdio.h>
61
#include <string.h>
62
63
#include <openssl/asn1t.h>
64
#include <openssl/err.h>
65
#include <openssl/x509.h>
66
67
#include "asn1_locl.h"
68
#include "x509_lcl.h"
69
70
typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
71
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
72
73
static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
74
    long len, const ASN1_ITEM *it, int tag, int aclass, char opt,
75
    ASN1_TLC *ctx);
76
77
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
78
    const ASN1_ITEM *it, int tag, int aclass);
79
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
80
static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
81
82
static int x509_name_encode(X509_NAME *a);
83
static int x509_name_canon(X509_NAME *a);
84
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
85
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
86
    unsigned char **in);
87
88
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent,
89
    const char *fname, const ASN1_PCTX *pctx);
90
91
static const ASN1_TEMPLATE X509_NAME_ENTRY_seq_tt[] = {
92
  {
93
    .offset = offsetof(X509_NAME_ENTRY, object),
94
    .field_name = "object",
95
    .item = &ASN1_OBJECT_it,
96
  },
97
  {
98
    .offset = offsetof(X509_NAME_ENTRY, value),
99
    .field_name = "value",
100
    .item = &ASN1_PRINTABLE_it,
101
  },
102
};
103
104
const ASN1_ITEM X509_NAME_ENTRY_it = {
105
  .itype = ASN1_ITYPE_SEQUENCE,
106
  .utype = V_ASN1_SEQUENCE,
107
  .templates = X509_NAME_ENTRY_seq_tt,
108
  .tcount = sizeof(X509_NAME_ENTRY_seq_tt) / sizeof(ASN1_TEMPLATE),
109
  .size = sizeof(X509_NAME_ENTRY),
110
  .sname = "X509_NAME_ENTRY",
111
};
112
113
114
X509_NAME_ENTRY *
115
d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len)
116
0
{
117
0
  return (X509_NAME_ENTRY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
118
0
      &X509_NAME_ENTRY_it);
119
0
}
120
121
int
122
i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out)
123
0
{
124
0
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_ENTRY_it);
125
0
}
126
127
X509_NAME_ENTRY *
128
X509_NAME_ENTRY_new(void)
129
844k
{
130
844k
  return (X509_NAME_ENTRY *)ASN1_item_new(&X509_NAME_ENTRY_it);
131
844k
}
132
133
void
134
X509_NAME_ENTRY_free(X509_NAME_ENTRY *a)
135
1.56M
{
136
1.56M
  ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_ENTRY_it);
137
1.56M
}
138
139
X509_NAME_ENTRY *
140
X509_NAME_ENTRY_dup(X509_NAME_ENTRY *x)
141
440
{
142
440
  return ASN1_item_dup(&X509_NAME_ENTRY_it, x);
143
440
}
144
145
/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
146
 * so declare two template wrappers for this
147
 */
148
149
static const ASN1_TEMPLATE X509_NAME_ENTRIES_item_tt = {
150
  .flags = ASN1_TFLG_SET_OF,
151
  .tag = 0,
152
  .offset = 0,
153
  .field_name = "RDNS",
154
  .item = &X509_NAME_ENTRY_it,
155
};
156
157
const ASN1_ITEM X509_NAME_ENTRIES_it = {
158
  .itype = ASN1_ITYPE_PRIMITIVE,
159
  .utype = -1,
160
  .templates = &X509_NAME_ENTRIES_item_tt,
161
  .tcount = 0,
162
  .funcs = NULL,
163
  .size = 0,
164
  .sname = "X509_NAME_ENTRIES",
165
};
166
167
static const ASN1_TEMPLATE X509_NAME_INTERNAL_item_tt = {
168
  .flags = ASN1_TFLG_SEQUENCE_OF,
169
  .tag = 0,
170
  .offset = 0,
171
  .field_name = "Name",
172
  .item = &X509_NAME_ENTRIES_it,
173
};
174
175
const ASN1_ITEM X509_NAME_INTERNAL_it = {
176
  .itype = ASN1_ITYPE_PRIMITIVE,
177
  .utype = -1,
178
  .templates = &X509_NAME_INTERNAL_item_tt,
179
  .tcount = 0,
180
  .funcs = NULL,
181
  .size = 0,
182
  .sname = "X509_NAME_INTERNAL",
183
};
184
185
/* Normally that's where it would end: we'd have two nested STACK structures
186
 * representing the ASN1. Unfortunately X509_NAME uses a completely different
187
 * form and caches encodings so we have to process the internal form and convert
188
 * to the external form.
189
 */
190
191
const ASN1_EXTERN_FUNCS x509_name_ff = {
192
  NULL,
193
  x509_name_ex_new,
194
  x509_name_ex_free,
195
  0,  /* Default clear behaviour is OK */
196
  x509_name_ex_d2i,
197
  x509_name_ex_i2d,
198
  x509_name_ex_print
199
};
200
201
const ASN1_ITEM X509_NAME_it = {
202
  .itype = ASN1_ITYPE_EXTERN,
203
  .utype = V_ASN1_SEQUENCE,
204
  .templates = NULL,
205
  .tcount = 0,
206
  .funcs = &x509_name_ff,
207
  .size = 0,
208
  .sname = "X509_NAME",
209
};
210
211
X509_NAME *
212
d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len)
213
13
{
214
13
  return (X509_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
215
13
      &X509_NAME_it);
216
13
}
217
218
int
219
i2d_X509_NAME(X509_NAME *a, unsigned char **out)
220
445
{
221
445
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_it);
222
445
}
223
224
X509_NAME *
225
X509_NAME_new(void)
226
0
{
227
0
  return (X509_NAME *)ASN1_item_new(&X509_NAME_it);
228
0
}
229
230
void
231
X509_NAME_free(X509_NAME *a)
232
1.40k
{
233
1.40k
  ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_it);
234
1.40k
}
235
236
X509_NAME *
237
X509_NAME_dup(X509_NAME *x)
238
443
{
239
443
  return ASN1_item_dup(&X509_NAME_it, x);
240
443
}
241
242
static int
243
x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
244
359k
{
245
359k
  X509_NAME *ret = NULL;
246
247
359k
  ret = malloc(sizeof(X509_NAME));
248
359k
  if (!ret)
249
0
    goto memerr;
250
359k
  if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
251
0
    goto memerr;
252
359k
  if ((ret->bytes = BUF_MEM_new()) == NULL)
253
0
    goto memerr;
254
359k
  ret->canon_enc = NULL;
255
359k
  ret->canon_enclen = 0;
256
359k
  ret->modified = 1;
257
359k
  *val = (ASN1_VALUE *)ret;
258
359k
  return 1;
259
260
0
 memerr:
261
0
  ASN1error(ERR_R_MALLOC_FAILURE);
262
0
  if (ret) {
263
0
    if (ret->entries)
264
0
      sk_X509_NAME_ENTRY_free(ret->entries);
265
0
    free(ret);
266
0
  }
267
0
  return 0;
268
359k
}
269
270
static void
271
x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
272
359k
{
273
359k
  X509_NAME *a;
274
275
359k
  if (!pval || !*pval)
276
0
    return;
277
359k
  a = (X509_NAME *)*pval;
278
279
359k
  BUF_MEM_free(a->bytes);
280
359k
  sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
281
359k
  free(a->canon_enc);
282
359k
  free(a);
283
359k
  *pval = NULL;
284
359k
}
285
286
static int
287
x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
288
    const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
289
135k
{
290
135k
  const unsigned char *p = *in, *q;
291
135k
  union {
292
135k
    STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
293
135k
    ASN1_VALUE *a;
294
135k
  } intname = {NULL};
295
135k
  union {
296
135k
    X509_NAME *x;
297
135k
    ASN1_VALUE *a;
298
135k
  } nm = {NULL};
299
135k
  int i, j, ret;
300
135k
  STACK_OF(X509_NAME_ENTRY) *entries;
301
135k
  X509_NAME_ENTRY *entry;
302
135k
  q = p;
303
304
  /* Get internal representation of Name */
305
135k
  ret = ASN1_item_ex_d2i(&intname.a, &p, len,
306
135k
      &X509_NAME_INTERNAL_it, tag, aclass, opt, ctx);
307
308
135k
  if (ret <= 0)
309
60.1k
    return ret;
310
311
75.8k
  if (*val)
312
67.2k
    x509_name_ex_free(val, NULL);
313
75.8k
  if (!x509_name_ex_new(&nm.a, NULL))
314
0
    goto err;
315
  /* We've decoded it: now cache encoding */
316
75.8k
  if (!BUF_MEM_grow(nm.x->bytes, p - q))
317
0
    goto err;
318
75.8k
  memcpy(nm.x->bytes->data, q, p - q);
319
320
  /* Convert internal representation to X509_NAME structure */
321
6.87M
  for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
322
6.80M
    entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
323
7.52M
    for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
324
724k
      entry = sk_X509_NAME_ENTRY_value(entries, j);
325
724k
      entry->set = i;
326
724k
      if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
327
0
        goto err;
328
724k
    }
329
6.80M
    sk_X509_NAME_ENTRY_free(entries);
330
6.80M
  }
331
75.8k
  sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
332
75.8k
  ret = x509_name_canon(nm.x);
333
75.8k
  if (!ret)
334
913
    goto err;
335
74.9k
  nm.x->modified = 0;
336
74.9k
  *val = nm.a;
337
74.9k
  *in = p;
338
74.9k
  return ret;
339
340
913
 err:
341
913
  if (nm.x != NULL)
342
913
    X509_NAME_free(nm.x);
343
913
  ASN1error(ERR_R_NESTED_ASN1_ERROR);
344
913
  return 0;
345
75.8k
}
346
347
static int
348
x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it,
349
    int tag, int aclass)
350
19.0k
{
351
19.0k
  int ret;
352
19.0k
  X509_NAME *a = (X509_NAME *)*val;
353
354
19.0k
  if (a->modified) {
355
424
    ret = x509_name_encode(a);
356
424
    if (ret < 0)
357
0
      return ret;
358
424
    ret = x509_name_canon(a);
359
424
    if (ret < 0)
360
0
      return ret;
361
424
  }
362
19.0k
  ret = a->bytes->length;
363
19.0k
  if (out != NULL) {
364
3.29k
    memcpy(*out, a->bytes->data, ret);
365
3.29k
    *out += ret;
366
3.29k
  }
367
19.0k
  return ret;
368
19.0k
}
369
370
static void
371
local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
372
20.8k
{
373
20.8k
  sk_X509_NAME_ENTRY_free(ne);
374
20.8k
}
375
376
static void
377
local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
378
291k
{
379
291k
  sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
380
291k
}
381
382
static int
383
x509_name_encode(X509_NAME *a)
384
424
{
385
424
  union {
386
424
    STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
387
424
    ASN1_VALUE *a;
388
424
  } intname = {NULL};
389
424
  int len;
390
424
  unsigned char *p;
391
424
  STACK_OF(X509_NAME_ENTRY) *entries = NULL;
392
424
  X509_NAME_ENTRY *entry;
393
424
  int i, set = -1;
394
395
424
  intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
396
424
  if (!intname.s)
397
0
    goto memerr;
398
121k
  for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
399
120k
    entry = sk_X509_NAME_ENTRY_value(a->entries, i);
400
120k
    if (entry->set != set) {
401
20.8k
      entries = sk_X509_NAME_ENTRY_new_null();
402
20.8k
      if (!entries)
403
0
        goto memerr;
404
20.8k
      if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
405
20.8k
          entries))
406
0
        goto memerr;
407
20.8k
      set = entry->set;
408
20.8k
    }
409
120k
    if (entries == NULL /* if entry->set is bogusly -1 */ ||
410
120k
        !sk_X509_NAME_ENTRY_push(entries, entry))
411
0
      goto memerr;
412
120k
  }
413
424
  len = ASN1_item_ex_i2d(&intname.a, NULL,
414
424
      &X509_NAME_INTERNAL_it, -1, -1);
415
424
  if (!BUF_MEM_grow(a->bytes, len))
416
0
    goto memerr;
417
424
  p = (unsigned char *)a->bytes->data;
418
424
  ASN1_item_ex_i2d(&intname.a, &p, &X509_NAME_INTERNAL_it,
419
424
      -1, -1);
420
424
  sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
421
424
      local_sk_X509_NAME_ENTRY_free);
422
424
  a->modified = 0;
423
424
  return len;
424
425
0
 memerr:
426
0
  sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
427
0
      local_sk_X509_NAME_ENTRY_free);
428
0
  ASN1error(ERR_R_MALLOC_FAILURE);
429
0
  return -1;
430
424
}
431
432
static int
433
x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent, const char *fname,
434
    const ASN1_PCTX *pctx)
435
2.09k
{
436
2.09k
  if (X509_NAME_print_ex(out, (X509_NAME *)*pval, indent,
437
2.09k
      pctx->nm_flags) <= 0)
438
0
    return 0;
439
2.09k
  return 2;
440
2.09k
}
441
442
/* This function generates the canonical encoding of the Name structure.
443
 * In it all strings are converted to UTF8, leading, trailing and
444
 * multiple spaces collapsed, converted to lower case and the leading
445
 * SEQUENCE header removed.
446
 *
447
 * In future we could also normalize the UTF8 too.
448
 *
449
 * By doing this comparison of Name structures can be rapidly
450
 * performed by just using memcmp() of the canonical encoding.
451
 * By omitting the leading SEQUENCE name constraints of type
452
 * dirName can also be checked with a simple memcmp().
453
 */
454
455
static int
456
x509_name_canon(X509_NAME *a)
457
76.2k
{
458
76.2k
  unsigned char *p;
459
76.2k
  STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
460
76.2k
  STACK_OF(X509_NAME_ENTRY) *entries = NULL;
461
76.2k
  X509_NAME_ENTRY *entry, *tmpentry = NULL;
462
76.2k
  int i, len, set = -1, ret = 0;
463
464
76.2k
  if (a->canon_enc) {
465
277
    free(a->canon_enc);
466
277
    a->canon_enc = NULL;
467
277
  }
468
  /* Special case: empty X509_NAME => null encoding */
469
76.2k
  if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
470
35.3k
    a->canon_enclen = 0;
471
35.3k
    return 1;
472
35.3k
  }
473
40.9k
  intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
474
40.9k
  if (!intname)
475
0
    goto err;
476
884k
  for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
477
844k
    entry = sk_X509_NAME_ENTRY_value(a->entries, i);
478
844k
    if (entry->set != set) {
479
291k
      entries = sk_X509_NAME_ENTRY_new_null();
480
291k
      if (!entries)
481
0
        goto err;
482
291k
      if (sk_STACK_OF_X509_NAME_ENTRY_push(intname,
483
291k
          entries) == 0) {
484
0
        sk_X509_NAME_ENTRY_free(entries);
485
0
        goto err;
486
0
      }
487
291k
      set = entry->set;
488
291k
    }
489
844k
    tmpentry = X509_NAME_ENTRY_new();
490
844k
    if (tmpentry == NULL)
491
0
      goto err;
492
844k
    tmpentry->object = OBJ_dup(entry->object);
493
844k
    if (tmpentry->object == NULL)
494
0
      goto err;
495
844k
    if (!asn1_string_canon(tmpentry->value, entry->value))
496
1.03k
      goto err;
497
843k
    if (entries == NULL /* if entry->set is bogusly -1 */ ||
498
843k
        !sk_X509_NAME_ENTRY_push(entries, tmpentry))
499
0
      goto err;
500
843k
    tmpentry = NULL;
501
843k
  }
502
503
  /* Finally generate encoding */
504
39.8k
  len = i2d_name_canon(intname, NULL);
505
39.8k
  if (len < 0)
506
0
    goto err;
507
39.8k
  p = malloc(len);
508
39.8k
  if (p == NULL)
509
0
    goto err;
510
39.8k
  a->canon_enc = p;
511
39.8k
  a->canon_enclen = len;
512
39.8k
  i2d_name_canon(intname, &p);
513
39.8k
  ret = 1;
514
515
40.9k
 err:
516
40.9k
  if (tmpentry)
517
1.03k
    X509_NAME_ENTRY_free(tmpentry);
518
40.9k
  if (intname)
519
40.9k
    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
520
40.9k
        local_sk_X509_NAME_ENTRY_pop_free);
521
40.9k
  return ret;
522
39.8k
}
523
524
/* Bitmap of all the types of string that will be canonicalized. */
525
526
#define ASN1_MASK_CANON \
527
844k
  (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
528
844k
  | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
529
844k
  | B_ASN1_VISIBLESTRING)
530
531
532
static int
533
asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
534
844k
{
535
844k
  unsigned char *to, *from;
536
844k
  int len, i;
537
538
  /* If type not in bitmask just copy string across */
539
844k
  if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
540
458k
    if (!ASN1_STRING_copy(out, in))
541
0
      return 0;
542
458k
    return 1;
543
458k
  }
544
545
386k
  out->type = V_ASN1_UTF8STRING;
546
386k
  out->length = ASN1_STRING_to_UTF8(&out->data, in);
547
386k
  if (out->length == -1)
548
1.03k
    return 0;
549
550
385k
  to = out->data;
551
385k
  from = to;
552
553
385k
  len = out->length;
554
555
  /* Convert string in place to canonical form.
556
   * Ultimately we may need to handle a wider range of characters
557
   * but for now ignore anything with MSB set and rely on the
558
   * isspace() and tolower() functions.
559
   */
560
561
  /* Ignore leading spaces */
562
388k
  while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
563
3.35k
    from++;
564
3.35k
    len--;
565
3.35k
  }
566
567
385k
  to = from + len - 1;
568
569
  /* Ignore trailing spaces */
570
387k
  while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
571
1.88k
    to--;
572
1.88k
    len--;
573
1.88k
  }
574
575
385k
  to = out->data;
576
577
385k
  i = 0;
578
87.5M
  while (i < len) {
579
    /* If MSB set just copy across */
580
87.1M
    if (*from & 0x80) {
581
79.2M
      *to++ = *from++;
582
79.2M
      i++;
583
79.2M
    }
584
    /* Collapse multiple spaces */
585
7.92M
    else if (isspace(*from)) {
586
      /* Copy one space across */
587
115k
      *to++ = ' ';
588
      /* Ignore subsequent spaces. Note: don't need to
589
       * check len here because we know the last
590
       * character is a non-space so we can't overflow.
591
       */
592
474k
      do {
593
474k
        from++;
594
474k
        i++;
595
474k
      } while (!(*from & 0x80) && isspace(*from));
596
7.81M
    } else {
597
7.81M
      *to++ = tolower(*from);
598
7.81M
      from++;
599
7.81M
      i++;
600
7.81M
    }
601
87.1M
  }
602
603
385k
  out->length = to - out->data;
604
605
385k
  return 1;
606
386k
}
607
608
static int
609
i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, unsigned char **in)
610
79.7k
{
611
79.7k
  int i, len, ltmp;
612
79.7k
  ASN1_VALUE *v;
613
79.7k
  STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
614
615
79.7k
  len = 0;
616
658k
  for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
617
578k
    v = sk_ASN1_VALUE_value(intname, i);
618
578k
    ltmp = ASN1_item_ex_i2d(&v, in,
619
578k
        &X509_NAME_ENTRIES_it, -1, -1);
620
578k
    if (ltmp < 0)
621
0
      return ltmp;
622
578k
    len += ltmp;
623
578k
  }
624
79.7k
  return len;
625
79.7k
}
626
627
int
628
X509_NAME_set(X509_NAME **xn, X509_NAME *name)
629
0
{
630
0
  if (*xn == name)
631
0
    return *xn != NULL;
632
0
  if ((name = X509_NAME_dup(name)) == NULL)
633
0
    return 0;
634
0
  X509_NAME_free(*xn);
635
0
  *xn = name;
636
0
  return 1;
637
0
}
638
639
int
640
X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, size_t *pderlen)
641
0
{
642
  /* Make sure encoding is valid. */
643
0
  if (i2d_X509_NAME(nm, NULL) <= 0)
644
0
    return 0;
645
0
  if (pder != NULL)
646
0
    *pder = (unsigned char *)nm->bytes->data;
647
0
  if (pderlen != NULL)
648
0
    *pderlen = nm->bytes->length;
649
0
  return 1;
650
0
}