Coverage Report

Created: 2022-08-24 06:30

/src/libressl/crypto/x509/x509_cpols.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD: x509_cpols.c,v 1.4 2022/01/14 08:16:13 tb Exp $ */
2
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3
 * project 1999.
4
 */
5
/* ====================================================================
6
 * Copyright (c) 1999-2004 The OpenSSL Project.  All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 *
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 *
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in
17
 *    the documentation and/or other materials provided with the
18
 *    distribution.
19
 *
20
 * 3. All advertising materials mentioning features or use of this
21
 *    software must display the following acknowledgment:
22
 *    "This product includes software developed by the OpenSSL Project
23
 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24
 *
25
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26
 *    endorse or promote products derived from this software without
27
 *    prior written permission. For written permission, please contact
28
 *    licensing@OpenSSL.org.
29
 *
30
 * 5. Products derived from this software may not be called "OpenSSL"
31
 *    nor may "OpenSSL" appear in their names without prior written
32
 *    permission of the OpenSSL Project.
33
 *
34
 * 6. Redistributions of any form whatsoever must retain the following
35
 *    acknowledgment:
36
 *    "This product includes software developed by the OpenSSL Project
37
 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38
 *
39
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 * OF THE POSSIBILITY OF SUCH DAMAGE.
51
 * ====================================================================
52
 *
53
 * This product includes cryptographic software written by Eric Young
54
 * (eay@cryptsoft.com).  This product includes software written by Tim
55
 * Hudson (tjh@cryptsoft.com).
56
 *
57
 */
58
59
#include <stdio.h>
60
#include <string.h>
61
62
#include <openssl/asn1.h>
63
#include <openssl/asn1t.h>
64
#include <openssl/conf.h>
65
#include <openssl/err.h>
66
#include <openssl/x509v3.h>
67
68
#include "pcy_int.h"
69
#include "x509_lcl.h"
70
71
/* Certificate policies extension support: this one is a bit complex... */
72
73
static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol,
74
    BIO *out, int indent);
75
static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
76
    X509V3_CTX *ctx, char *value);
77
static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals,
78
    int indent);
79
static void print_notice(BIO *out, USERNOTICE *notice, int indent);
80
static POLICYINFO *policy_section(X509V3_CTX *ctx,
81
    STACK_OF(CONF_VALUE) *polstrs, int ia5org);
82
static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
83
    STACK_OF(CONF_VALUE) *unot, int ia5org);
84
static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos);
85
86
const X509V3_EXT_METHOD v3_cpols = {
87
  .ext_nid = NID_certificate_policies,
88
  .ext_flags = 0,
89
  .it = &CERTIFICATEPOLICIES_it,
90
  .ext_new = NULL,
91
  .ext_free = NULL,
92
  .d2i = NULL,
93
  .i2d = NULL,
94
  .i2s = NULL,
95
  .s2i = NULL,
96
  .i2v = NULL,
97
  .v2i = NULL,
98
  .i2r = (X509V3_EXT_I2R)i2r_certpol,
99
  .r2i = (X509V3_EXT_R2I)r2i_certpol,
100
  .usr_data = NULL,
101
};
102
103
static const ASN1_TEMPLATE CERTIFICATEPOLICIES_item_tt = {
104
  .flags = ASN1_TFLG_SEQUENCE_OF,
105
  .tag = 0,
106
  .offset = 0,
107
  .field_name = "CERTIFICATEPOLICIES",
108
  .item = &POLICYINFO_it,
109
};
110
111
const ASN1_ITEM CERTIFICATEPOLICIES_it = {
112
  .itype = ASN1_ITYPE_PRIMITIVE,
113
  .utype = -1,
114
  .templates = &CERTIFICATEPOLICIES_item_tt,
115
  .tcount = 0,
116
  .funcs = NULL,
117
  .size = 0,
118
  .sname = "CERTIFICATEPOLICIES",
119
};
120
121
122
CERTIFICATEPOLICIES *
123
d2i_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES **a, const unsigned char **in, long len)
124
0
{
125
0
  return (CERTIFICATEPOLICIES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
126
0
      &CERTIFICATEPOLICIES_it);
127
0
}
128
129
int
130
i2d_CERTIFICATEPOLICIES(CERTIFICATEPOLICIES *a, unsigned char **out)
131
0
{
132
0
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &CERTIFICATEPOLICIES_it);
133
0
}
134
135
CERTIFICATEPOLICIES *
136
CERTIFICATEPOLICIES_new(void)
137
0
{
138
0
  return (CERTIFICATEPOLICIES *)ASN1_item_new(&CERTIFICATEPOLICIES_it);
139
0
}
140
141
void
142
CERTIFICATEPOLICIES_free(CERTIFICATEPOLICIES *a)
143
0
{
144
0
  ASN1_item_free((ASN1_VALUE *)a, &CERTIFICATEPOLICIES_it);
145
0
}
146
147
static const ASN1_TEMPLATE POLICYINFO_seq_tt[] = {
148
  {
149
    .flags = 0,
150
    .tag = 0,
151
    .offset = offsetof(POLICYINFO, policyid),
152
    .field_name = "policyid",
153
    .item = &ASN1_OBJECT_it,
154
  },
155
  {
156
    .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
157
    .tag = 0,
158
    .offset = offsetof(POLICYINFO, qualifiers),
159
    .field_name = "qualifiers",
160
    .item = &POLICYQUALINFO_it,
161
  },
162
};
163
164
const ASN1_ITEM POLICYINFO_it = {
165
  .itype = ASN1_ITYPE_SEQUENCE,
166
  .utype = V_ASN1_SEQUENCE,
167
  .templates = POLICYINFO_seq_tt,
168
  .tcount = sizeof(POLICYINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
169
  .funcs = NULL,
170
  .size = sizeof(POLICYINFO),
171
  .sname = "POLICYINFO",
172
};
173
174
175
POLICYINFO *
176
d2i_POLICYINFO(POLICYINFO **a, const unsigned char **in, long len)
177
0
{
178
0
  return (POLICYINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
179
0
      &POLICYINFO_it);
180
0
}
181
182
int
183
i2d_POLICYINFO(POLICYINFO *a, unsigned char **out)
184
0
{
185
0
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYINFO_it);
186
0
}
187
188
POLICYINFO *
189
POLICYINFO_new(void)
190
0
{
191
0
  return (POLICYINFO *)ASN1_item_new(&POLICYINFO_it);
192
0
}
193
194
void
195
POLICYINFO_free(POLICYINFO *a)
196
0
{
197
0
  ASN1_item_free((ASN1_VALUE *)a, &POLICYINFO_it);
198
0
}
199
200
static const ASN1_TEMPLATE policydefault_tt = {
201
  .flags = 0,
202
  .tag = 0,
203
  .offset = offsetof(POLICYQUALINFO, d.other),
204
  .field_name = "d.other",
205
  .item = &ASN1_ANY_it,
206
};
207
208
static const ASN1_ADB_TABLE POLICYQUALINFO_adbtbl[] = {
209
  {
210
    .value = NID_id_qt_cps,
211
    .tt = {
212
      .flags = 0,
213
      .tag = 0,
214
      .offset = offsetof(POLICYQUALINFO, d.cpsuri),
215
      .field_name = "d.cpsuri",
216
      .item = &ASN1_IA5STRING_it,
217
    },
218
  
219
  },
220
  {
221
    .value = NID_id_qt_unotice,
222
    .tt = {
223
      .flags = 0,
224
      .tag = 0,
225
      .offset = offsetof(POLICYQUALINFO, d.usernotice),
226
      .field_name = "d.usernotice",
227
      .item = &USERNOTICE_it,
228
    },
229
  
230
  },
231
};
232
233
static const ASN1_ADB POLICYQUALINFO_adb = {
234
  .flags = 0,
235
  .offset = offsetof(POLICYQUALINFO, pqualid),
236
  .tbl = POLICYQUALINFO_adbtbl,
237
  .tblcount = sizeof(POLICYQUALINFO_adbtbl) / sizeof(ASN1_ADB_TABLE),
238
  .default_tt = &policydefault_tt,
239
  .null_tt = NULL,
240
};
241
242
static const ASN1_TEMPLATE POLICYQUALINFO_seq_tt[] = {
243
  {
244
    .flags = 0,
245
    .tag = 0,
246
    .offset = offsetof(POLICYQUALINFO, pqualid),
247
    .field_name = "pqualid",
248
    .item = &ASN1_OBJECT_it,
249
  },
250
  {
251
    .flags = ASN1_TFLG_ADB_OID,
252
    .tag = -1,
253
    .offset = 0,
254
    .field_name = "POLICYQUALINFO",
255
    .item = (const ASN1_ITEM *)&POLICYQUALINFO_adb,
256
  },
257
};
258
259
const ASN1_ITEM POLICYQUALINFO_it = {
260
  .itype = ASN1_ITYPE_SEQUENCE,
261
  .utype = V_ASN1_SEQUENCE,
262
  .templates = POLICYQUALINFO_seq_tt,
263
  .tcount = sizeof(POLICYQUALINFO_seq_tt) / sizeof(ASN1_TEMPLATE),
264
  .funcs = NULL,
265
  .size = sizeof(POLICYQUALINFO),
266
  .sname = "POLICYQUALINFO",
267
};
268
269
270
POLICYQUALINFO *
271
d2i_POLICYQUALINFO(POLICYQUALINFO **a, const unsigned char **in, long len)
272
0
{
273
0
  return (POLICYQUALINFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
274
0
      &POLICYQUALINFO_it);
275
0
}
276
277
int
278
i2d_POLICYQUALINFO(POLICYQUALINFO *a, unsigned char **out)
279
0
{
280
0
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &POLICYQUALINFO_it);
281
0
}
282
283
POLICYQUALINFO *
284
POLICYQUALINFO_new(void)
285
0
{
286
0
  return (POLICYQUALINFO *)ASN1_item_new(&POLICYQUALINFO_it);
287
0
}
288
289
void
290
POLICYQUALINFO_free(POLICYQUALINFO *a)
291
0
{
292
0
  ASN1_item_free((ASN1_VALUE *)a, &POLICYQUALINFO_it);
293
0
}
294
295
static const ASN1_TEMPLATE USERNOTICE_seq_tt[] = {
296
  {
297
    .flags = ASN1_TFLG_OPTIONAL,
298
    .tag = 0,
299
    .offset = offsetof(USERNOTICE, noticeref),
300
    .field_name = "noticeref",
301
    .item = &NOTICEREF_it,
302
  },
303
  {
304
    .flags = ASN1_TFLG_OPTIONAL,
305
    .tag = 0,
306
    .offset = offsetof(USERNOTICE, exptext),
307
    .field_name = "exptext",
308
    .item = &DISPLAYTEXT_it,
309
  },
310
};
311
312
const ASN1_ITEM USERNOTICE_it = {
313
  .itype = ASN1_ITYPE_SEQUENCE,
314
  .utype = V_ASN1_SEQUENCE,
315
  .templates = USERNOTICE_seq_tt,
316
  .tcount = sizeof(USERNOTICE_seq_tt) / sizeof(ASN1_TEMPLATE),
317
  .funcs = NULL,
318
  .size = sizeof(USERNOTICE),
319
  .sname = "USERNOTICE",
320
};
321
322
323
USERNOTICE *
324
d2i_USERNOTICE(USERNOTICE **a, const unsigned char **in, long len)
325
0
{
326
0
  return (USERNOTICE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
327
0
      &USERNOTICE_it);
328
0
}
329
330
int
331
i2d_USERNOTICE(USERNOTICE *a, unsigned char **out)
332
0
{
333
0
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &USERNOTICE_it);
334
0
}
335
336
USERNOTICE *
337
USERNOTICE_new(void)
338
0
{
339
0
  return (USERNOTICE *)ASN1_item_new(&USERNOTICE_it);
340
0
}
341
342
void
343
USERNOTICE_free(USERNOTICE *a)
344
0
{
345
0
  ASN1_item_free((ASN1_VALUE *)a, &USERNOTICE_it);
346
0
}
347
348
static const ASN1_TEMPLATE NOTICEREF_seq_tt[] = {
349
  {
350
    .flags = 0,
351
    .tag = 0,
352
    .offset = offsetof(NOTICEREF, organization),
353
    .field_name = "organization",
354
    .item = &DISPLAYTEXT_it,
355
  },
356
  {
357
    .flags = ASN1_TFLG_SEQUENCE_OF,
358
    .tag = 0,
359
    .offset = offsetof(NOTICEREF, noticenos),
360
    .field_name = "noticenos",
361
    .item = &ASN1_INTEGER_it,
362
  },
363
};
364
365
const ASN1_ITEM NOTICEREF_it = {
366
  .itype = ASN1_ITYPE_SEQUENCE,
367
  .utype = V_ASN1_SEQUENCE,
368
  .templates = NOTICEREF_seq_tt,
369
  .tcount = sizeof(NOTICEREF_seq_tt) / sizeof(ASN1_TEMPLATE),
370
  .funcs = NULL,
371
  .size = sizeof(NOTICEREF),
372
  .sname = "NOTICEREF",
373
};
374
375
376
NOTICEREF *
377
d2i_NOTICEREF(NOTICEREF **a, const unsigned char **in, long len)
378
0
{
379
0
  return (NOTICEREF *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
380
0
      &NOTICEREF_it);
381
0
}
382
383
int
384
i2d_NOTICEREF(NOTICEREF *a, unsigned char **out)
385
0
{
386
0
  return ASN1_item_i2d((ASN1_VALUE *)a, out, &NOTICEREF_it);
387
0
}
388
389
NOTICEREF *
390
NOTICEREF_new(void)
391
0
{
392
0
  return (NOTICEREF *)ASN1_item_new(&NOTICEREF_it);
393
0
}
394
395
void
396
NOTICEREF_free(NOTICEREF *a)
397
0
{
398
0
  ASN1_item_free((ASN1_VALUE *)a, &NOTICEREF_it);
399
0
}
400
401
static STACK_OF(POLICYINFO) *
402
r2i_certpol(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *value)
403
0
{
404
0
  STACK_OF(POLICYINFO) *pols = NULL;
405
0
  char *pstr;
406
0
  POLICYINFO *pol;
407
0
  ASN1_OBJECT *pobj;
408
0
  STACK_OF(CONF_VALUE) *vals;
409
0
  CONF_VALUE *cnf;
410
0
  int i, ia5org;
411
412
0
  pols = sk_POLICYINFO_new_null();
413
0
  if (pols == NULL) {
414
0
    X509V3error(ERR_R_MALLOC_FAILURE);
415
0
    return NULL;
416
0
  }
417
0
  vals = X509V3_parse_list(value);
418
0
  if (vals == NULL) {
419
0
    X509V3error(ERR_R_X509V3_LIB);
420
0
    goto err;
421
0
  }
422
0
  ia5org = 0;
423
0
  for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
424
0
    cnf = sk_CONF_VALUE_value(vals, i);
425
0
    if (cnf->value || !cnf->name) {
426
0
      X509V3error(X509V3_R_INVALID_POLICY_IDENTIFIER);
427
0
      X509V3_conf_err(cnf);
428
0
      goto err;
429
0
    }
430
0
    pstr = cnf->name;
431
0
    if (!strcmp(pstr, "ia5org")) {
432
0
      ia5org = 1;
433
0
      continue;
434
0
    } else if (*pstr == '@') {
435
0
      STACK_OF(CONF_VALUE) *polsect;
436
0
      polsect = X509V3_get_section(ctx, pstr + 1);
437
0
      if (!polsect) {
438
0
        X509V3error(X509V3_R_INVALID_SECTION);
439
0
        X509V3_conf_err(cnf);
440
0
        goto err;
441
0
      }
442
0
      pol = policy_section(ctx, polsect, ia5org);
443
0
      X509V3_section_free(ctx, polsect);
444
0
      if (!pol)
445
0
        goto err;
446
0
    } else {
447
0
      if (!(pobj = OBJ_txt2obj(cnf->name, 0))) {
448
0
        X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
449
0
        X509V3_conf_err(cnf);
450
0
        goto err;
451
0
      }
452
0
      pol = POLICYINFO_new();
453
0
      pol->policyid = pobj;
454
0
    }
455
0
    if (!sk_POLICYINFO_push(pols, pol)){
456
0
      POLICYINFO_free(pol);
457
0
      X509V3error(ERR_R_MALLOC_FAILURE);
458
0
      goto err;
459
0
    }
460
0
  }
461
0
  sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
462
0
  return pols;
463
464
0
err:
465
0
  sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
466
0
  sk_POLICYINFO_pop_free(pols, POLICYINFO_free);
467
0
  return NULL;
468
0
}
469
470
static POLICYINFO *
471
policy_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *polstrs, int ia5org)
472
0
{
473
0
  int i;
474
0
  CONF_VALUE *cnf;
475
0
  POLICYINFO *pol;
476
0
  POLICYQUALINFO *nqual = NULL;
477
478
0
  if ((pol = POLICYINFO_new()) == NULL)
479
0
    goto merr;
480
0
  for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) {
481
0
    cnf = sk_CONF_VALUE_value(polstrs, i);
482
0
    if (strcmp(cnf->name, "policyIdentifier") == 0) {
483
0
      ASN1_OBJECT *pobj;
484
485
0
      if ((pobj = OBJ_txt2obj(cnf->value, 0)) == NULL) {
486
0
        X509V3error(X509V3_R_INVALID_OBJECT_IDENTIFIER);
487
0
        X509V3_conf_err(cnf);
488
0
        goto err;
489
0
      }
490
0
      pol->policyid = pobj;
491
0
    } else if (name_cmp(cnf->name, "CPS") == 0) {
492
0
      if ((nqual = POLICYQUALINFO_new()) == NULL)
493
0
        goto merr;
494
0
      nqual->pqualid = OBJ_nid2obj(NID_id_qt_cps);
495
0
      nqual->d.cpsuri = ASN1_IA5STRING_new();
496
0
      if (nqual->d.cpsuri == NULL)
497
0
        goto merr;
498
0
      if (ASN1_STRING_set(nqual->d.cpsuri, cnf->value,
499
0
          strlen(cnf->value)) == 0)
500
0
        goto merr;
501
502
0
      if (pol->qualifiers == NULL) {
503
0
        pol->qualifiers = sk_POLICYQUALINFO_new_null();
504
0
        if (pol->qualifiers == NULL)
505
0
          goto merr;
506
0
      }
507
0
      if (sk_POLICYQUALINFO_push(pol->qualifiers, nqual) == 0)
508
0
        goto merr;
509
0
      nqual = NULL;
510
0
    } else if (name_cmp(cnf->name, "userNotice") == 0) {
511
0
      STACK_OF(CONF_VALUE) *unot;
512
0
      POLICYQUALINFO *qual;
513
514
0
      if (*cnf->value != '@') {
515
0
        X509V3error(X509V3_R_EXPECTED_A_SECTION_NAME);
516
0
        X509V3_conf_err(cnf);
517
0
        goto err;
518
0
      }
519
0
      unot = X509V3_get_section(ctx, cnf->value + 1);
520
0
      if (unot == NULL) {
521
0
        X509V3error(X509V3_R_INVALID_SECTION);
522
0
        X509V3_conf_err(cnf);
523
0
        goto err;
524
0
      }
525
0
      qual = notice_section(ctx, unot, ia5org);
526
0
      X509V3_section_free(ctx, unot);
527
0
      if (qual == NULL)
528
0
        goto err;
529
530
0
      if (pol->qualifiers == NULL) {
531
0
        pol->qualifiers = sk_POLICYQUALINFO_new_null();
532
0
        if (pol->qualifiers == NULL)
533
0
          goto merr;
534
0
      }
535
0
      if (sk_POLICYQUALINFO_push(pol->qualifiers, qual) == 0)
536
0
        goto merr;
537
0
    } else {
538
0
      X509V3error(X509V3_R_INVALID_OPTION);
539
0
      X509V3_conf_err(cnf);
540
0
      goto err;
541
0
    }
542
0
  }
543
0
  if (pol->policyid == NULL) {
544
0
    X509V3error(X509V3_R_NO_POLICY_IDENTIFIER);
545
0
    goto err;
546
0
  }
547
548
0
  return pol;
549
550
0
merr:
551
0
  X509V3error(ERR_R_MALLOC_FAILURE);
552
553
0
err:
554
0
  POLICYQUALINFO_free(nqual);
555
0
  POLICYINFO_free(pol);
556
0
  return NULL;
557
0
}
558
559
static POLICYQUALINFO *
560
notice_section(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *unot, int ia5org)
561
0
{
562
0
  int i, ret;
563
0
  CONF_VALUE *cnf;
564
0
  USERNOTICE *not;
565
0
  POLICYQUALINFO *qual;
566
567
0
  if (!(qual = POLICYQUALINFO_new()))
568
0
    goto merr;
569
0
  qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice);
570
0
  if (!(not = USERNOTICE_new()))
571
0
    goto merr;
572
0
  qual->d.usernotice = not;
573
0
  for (i = 0; i < sk_CONF_VALUE_num(unot); i++) {
574
0
    cnf = sk_CONF_VALUE_value(unot, i);
575
0
    if (!strcmp(cnf->name, "explicitText")) {
576
0
      if (not->exptext == NULL) {
577
0
        not->exptext = ASN1_VISIBLESTRING_new();
578
0
        if (not->exptext == NULL)
579
0
          goto merr;
580
0
      }
581
0
      if (!ASN1_STRING_set(not->exptext, cnf->value,
582
0
          strlen(cnf->value)))
583
0
        goto merr;
584
0
    } else if (!strcmp(cnf->name, "organization")) {
585
0
      NOTICEREF *nref;
586
0
      if (!not->noticeref) {
587
0
        if (!(nref = NOTICEREF_new()))
588
0
          goto merr;
589
0
        not->noticeref = nref;
590
0
      } else
591
0
        nref = not->noticeref;
592
0
      if (ia5org)
593
0
        nref->organization->type = V_ASN1_IA5STRING;
594
0
      else
595
0
        nref->organization->type = V_ASN1_VISIBLESTRING;
596
0
      if (!ASN1_STRING_set(nref->organization, cnf->value,
597
0
          strlen(cnf->value)))
598
0
        goto merr;
599
0
    } else if (!strcmp(cnf->name, "noticeNumbers")) {
600
0
      NOTICEREF *nref;
601
0
      STACK_OF(CONF_VALUE) *nos;
602
0
      if (!not->noticeref) {
603
0
        if (!(nref = NOTICEREF_new()))
604
0
          goto merr;
605
0
        not->noticeref = nref;
606
0
      } else
607
0
        nref = not->noticeref;
608
0
      nos = X509V3_parse_list(cnf->value);
609
0
      if (!nos || !sk_CONF_VALUE_num(nos)) {
610
0
        X509V3error(X509V3_R_INVALID_NUMBERS);
611
0
        X509V3_conf_err(cnf);
612
0
        if (nos != NULL)
613
0
          sk_CONF_VALUE_pop_free(nos,
614
0
              X509V3_conf_free);
615
0
        goto err;
616
0
      }
617
0
      ret = nref_nos(nref->noticenos, nos);
618
0
      sk_CONF_VALUE_pop_free(nos, X509V3_conf_free);
619
0
      if (!ret)
620
0
        goto err;
621
0
    } else {
622
0
      X509V3error(X509V3_R_INVALID_OPTION);
623
0
      X509V3_conf_err(cnf);
624
0
      goto err;
625
0
    }
626
0
  }
627
628
0
  if (not->noticeref &&
629
0
      (!not->noticeref->noticenos || !not->noticeref->organization)) {
630
0
    X509V3error(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
631
0
    goto err;
632
0
  }
633
634
0
  return qual;
635
636
0
merr:
637
0
  X509V3error(ERR_R_MALLOC_FAILURE);
638
639
0
err:
640
0
  POLICYQUALINFO_free(qual);
641
0
  return NULL;
642
0
}
643
644
static int
645
nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
646
0
{
647
0
  CONF_VALUE *cnf;
648
0
  ASN1_INTEGER *aint;
649
0
  int i;
650
651
0
  for (i = 0; i < sk_CONF_VALUE_num(nos); i++) {
652
0
    cnf = sk_CONF_VALUE_value(nos, i);
653
0
    if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
654
0
      X509V3error(X509V3_R_INVALID_NUMBER);
655
0
      goto err;
656
0
    }
657
0
    if (!sk_ASN1_INTEGER_push(nnums, aint))
658
0
      goto merr;
659
0
  }
660
0
  return 1;
661
662
0
merr:
663
0
  X509V3error(ERR_R_MALLOC_FAILURE);
664
665
0
err:
666
0
  sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
667
0
  return 0;
668
0
}
669
670
static int
671
i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, BIO *out,
672
    int indent)
673
0
{
674
0
  int i;
675
0
  POLICYINFO *pinfo;
676
677
  /* First print out the policy OIDs */
678
0
  for (i = 0; i < sk_POLICYINFO_num(pol); i++) {
679
0
    pinfo = sk_POLICYINFO_value(pol, i);
680
0
    BIO_printf(out, "%*sPolicy: ", indent, "");
681
0
    i2a_ASN1_OBJECT(out, pinfo->policyid);
682
0
    BIO_puts(out, "\n");
683
0
    if (pinfo->qualifiers)
684
0
      print_qualifiers(out, pinfo->qualifiers, indent + 2);
685
0
  }
686
0
  return 1;
687
0
}
688
689
static void
690
print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, int indent)
691
0
{
692
0
  POLICYQUALINFO *qualinfo;
693
0
  int i;
694
695
0
  for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) {
696
0
    qualinfo = sk_POLICYQUALINFO_value(quals, i);
697
0
    switch (OBJ_obj2nid(qualinfo->pqualid)) {
698
0
    case NID_id_qt_cps:
699
0
      BIO_printf(out, "%*sCPS: %.*s\n", indent, "",
700
0
          qualinfo->d.cpsuri->length,
701
0
          qualinfo->d.cpsuri->data);
702
0
      break;
703
704
0
    case NID_id_qt_unotice:
705
0
      BIO_printf(out, "%*sUser Notice:\n", indent, "");
706
0
      print_notice(out, qualinfo->d.usernotice, indent + 2);
707
0
      break;
708
709
0
    default:
710
0
      BIO_printf(out, "%*sUnknown Qualifier: ",
711
0
          indent + 2, "");
712
713
0
      i2a_ASN1_OBJECT(out, qualinfo->pqualid);
714
0
      BIO_puts(out, "\n");
715
0
      break;
716
0
    }
717
0
  }
718
0
}
719
720
static void
721
print_notice(BIO *out, USERNOTICE *notice, int indent)
722
0
{
723
0
  int i;
724
725
0
  if (notice->noticeref) {
726
0
    NOTICEREF *ref;
727
0
    ref = notice->noticeref;
728
0
    BIO_printf(out, "%*sOrganization: %.*s\n", indent, "",
729
0
        ref->organization->length, ref->organization->data);
730
0
    BIO_printf(out, "%*sNumber%s: ", indent, "",
731
0
        sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : "");
732
0
    for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) {
733
0
      ASN1_INTEGER *num;
734
0
      char *tmp;
735
0
      num = sk_ASN1_INTEGER_value(ref->noticenos, i);
736
0
      if (i)
737
0
        BIO_puts(out, ", ");
738
0
      tmp = i2s_ASN1_INTEGER(NULL, num);
739
0
      BIO_puts(out, tmp);
740
0
      free(tmp);
741
0
    }
742
0
    BIO_puts(out, "\n");
743
0
  }
744
0
  if (notice->exptext)
745
0
    BIO_printf(out, "%*sExplicit Text: %.*s\n", indent, "",
746
0
        notice->exptext->length, notice->exptext->data);
747
0
}
748
749
void
750
X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent)
751
0
{
752
0
  const X509_POLICY_DATA *dat = node->data;
753
754
0
  BIO_printf(out, "%*sPolicy: ", indent, "");
755
756
0
  i2a_ASN1_OBJECT(out, dat->valid_policy);
757
0
  BIO_puts(out, "\n");
758
0
  BIO_printf(out, "%*s%s\n", indent + 2, "",
759
0
      node_data_critical(dat) ? "Critical" : "Non Critical");
760
0
  if (dat->qualifier_set)
761
0
    print_qualifiers(out, dat->qualifier_set, indent + 2);
762
0
  else
763
0
    BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, "");
764
0
}