libressl: Fix validation errors in certificate chains with expired certificates
[dragonfly.git] / crypto / libressl / crypto / x509 / x509_genn.c
1 /* $OpenBSD: x509_genn.c,v 1.1.4.1 2020/12/08 15:08:47 tb Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3  * project 1999.
4  */
5 /* ====================================================================
6  * Copyright (c) 1999-2008 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
60 #include <stdio.h>
61
62 #include <openssl/asn1t.h>
63 #include <openssl/conf.h>
64 #include <openssl/x509v3.h>
65
66 static const ASN1_TEMPLATE OTHERNAME_seq_tt[] = {
67         {
68                 .flags = 0,
69                 .tag = 0,
70                 .offset = offsetof(OTHERNAME, type_id),
71                 .field_name = "type_id",
72                 .item = &ASN1_OBJECT_it,
73         },
74         /* Maybe have a true ANY DEFINED BY later */
75         {
76                 .flags = ASN1_TFLG_EXPLICIT,
77                 .tag = 0,
78                 .offset = offsetof(OTHERNAME, value),
79                 .field_name = "value",
80                 .item = &ASN1_ANY_it,
81         },
82 };
83
84 const ASN1_ITEM OTHERNAME_it = {
85         .itype = ASN1_ITYPE_SEQUENCE,
86         .utype = V_ASN1_SEQUENCE,
87         .templates = OTHERNAME_seq_tt,
88         .tcount = sizeof(OTHERNAME_seq_tt) / sizeof(ASN1_TEMPLATE),
89         .funcs = NULL,
90         .size = sizeof(OTHERNAME),
91         .sname = "OTHERNAME",
92 };
93
94
95 OTHERNAME *
96 d2i_OTHERNAME(OTHERNAME **a, const unsigned char **in, long len)
97 {
98         return (OTHERNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
99             &OTHERNAME_it);
100 }
101
102 int
103 i2d_OTHERNAME(OTHERNAME *a, unsigned char **out)
104 {
105         return ASN1_item_i2d((ASN1_VALUE *)a, out, &OTHERNAME_it);
106 }
107
108 OTHERNAME *
109 OTHERNAME_new(void)
110 {
111         return (OTHERNAME *)ASN1_item_new(&OTHERNAME_it);
112 }
113
114 void
115 OTHERNAME_free(OTHERNAME *a)
116 {
117         ASN1_item_free((ASN1_VALUE *)a, &OTHERNAME_it);
118 }
119
120 /* Uses explicit tagging since DIRECTORYSTRING is a CHOICE type */
121 static const ASN1_TEMPLATE EDIPARTYNAME_seq_tt[] = {
122         {
123                 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
124                 .tag = 0,
125                 .offset = offsetof(EDIPARTYNAME, nameAssigner),
126                 .field_name = "nameAssigner",
127                 .item = &DIRECTORYSTRING_it,
128         },
129         {
130                 .flags = ASN1_TFLG_EXPLICIT,
131                 .tag = 1,
132                 .offset = offsetof(EDIPARTYNAME, partyName),
133                 .field_name = "partyName",
134                 .item = &DIRECTORYSTRING_it,
135         },
136 };
137
138 const ASN1_ITEM EDIPARTYNAME_it = {
139         .itype = ASN1_ITYPE_SEQUENCE,
140         .utype = V_ASN1_SEQUENCE,
141         .templates = EDIPARTYNAME_seq_tt,
142         .tcount = sizeof(EDIPARTYNAME_seq_tt) / sizeof(ASN1_TEMPLATE),
143         .funcs = NULL,
144         .size = sizeof(EDIPARTYNAME),
145         .sname = "EDIPARTYNAME",
146 };
147
148
149 EDIPARTYNAME *
150 d2i_EDIPARTYNAME(EDIPARTYNAME **a, const unsigned char **in, long len)
151 {
152         return (EDIPARTYNAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
153             &EDIPARTYNAME_it);
154 }
155
156 int
157 i2d_EDIPARTYNAME(EDIPARTYNAME *a, unsigned char **out)
158 {
159         return ASN1_item_i2d((ASN1_VALUE *)a, out, &EDIPARTYNAME_it);
160 }
161
162 EDIPARTYNAME *
163 EDIPARTYNAME_new(void)
164 {
165         return (EDIPARTYNAME *)ASN1_item_new(&EDIPARTYNAME_it);
166 }
167
168 void
169 EDIPARTYNAME_free(EDIPARTYNAME *a)
170 {
171         ASN1_item_free((ASN1_VALUE *)a, &EDIPARTYNAME_it);
172 }
173
174 static const ASN1_TEMPLATE GENERAL_NAME_ch_tt[] = {
175         {
176                 .flags = ASN1_TFLG_IMPLICIT,
177                 .tag = GEN_OTHERNAME,
178                 .offset = offsetof(GENERAL_NAME, d.otherName),
179                 .field_name = "d.otherName",
180                 .item = &OTHERNAME_it,
181         },
182         {
183                 .flags = ASN1_TFLG_IMPLICIT,
184                 .tag = GEN_EMAIL,
185                 .offset = offsetof(GENERAL_NAME, d.rfc822Name),
186                 .field_name = "d.rfc822Name",
187                 .item = &ASN1_IA5STRING_it,
188         },
189         {
190                 .flags = ASN1_TFLG_IMPLICIT,
191                 .tag = GEN_DNS,
192                 .offset = offsetof(GENERAL_NAME, d.dNSName),
193                 .field_name = "d.dNSName",
194                 .item = &ASN1_IA5STRING_it,
195         },
196         /* Don't decode this */
197         {
198                 .flags = ASN1_TFLG_IMPLICIT,
199                 .tag = GEN_X400,
200                 .offset = offsetof(GENERAL_NAME, d.x400Address),
201                 .field_name = "d.x400Address",
202                 .item = &ASN1_SEQUENCE_it,
203         },
204         /* X509_NAME is a CHOICE type so use EXPLICIT */
205         {
206                 .flags = ASN1_TFLG_EXPLICIT,
207                 .tag = GEN_DIRNAME,
208                 .offset = offsetof(GENERAL_NAME, d.directoryName),
209                 .field_name = "d.directoryName",
210                 .item = &X509_NAME_it,
211         },
212         {
213                 .flags = ASN1_TFLG_IMPLICIT,
214                 .tag = GEN_EDIPARTY,
215                 .offset = offsetof(GENERAL_NAME, d.ediPartyName),
216                 .field_name = "d.ediPartyName",
217                 .item = &EDIPARTYNAME_it,
218         },
219         {
220                 .flags = ASN1_TFLG_IMPLICIT,
221                 .tag = GEN_URI,
222                 .offset = offsetof(GENERAL_NAME, d.uniformResourceIdentifier),
223                 .field_name = "d.uniformResourceIdentifier",
224                 .item = &ASN1_IA5STRING_it,
225         },
226         {
227                 .flags = ASN1_TFLG_IMPLICIT,
228                 .tag = GEN_IPADD,
229                 .offset = offsetof(GENERAL_NAME, d.iPAddress),
230                 .field_name = "d.iPAddress",
231                 .item = &ASN1_OCTET_STRING_it,
232         },
233         {
234                 .flags = ASN1_TFLG_IMPLICIT,
235                 .tag = GEN_RID,
236                 .offset = offsetof(GENERAL_NAME, d.registeredID),
237                 .field_name = "d.registeredID",
238                 .item = &ASN1_OBJECT_it,
239         },
240 };
241
242 const ASN1_ITEM GENERAL_NAME_it = {
243         .itype = ASN1_ITYPE_CHOICE,
244         .utype = offsetof(GENERAL_NAME, type),
245         .templates = GENERAL_NAME_ch_tt,
246         .tcount = sizeof(GENERAL_NAME_ch_tt) / sizeof(ASN1_TEMPLATE),
247         .funcs = NULL,
248         .size = sizeof(GENERAL_NAME),
249         .sname = "GENERAL_NAME",
250 };
251
252
253 GENERAL_NAME *
254 d2i_GENERAL_NAME(GENERAL_NAME **a, const unsigned char **in, long len)
255 {
256         return (GENERAL_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
257             &GENERAL_NAME_it);
258 }
259
260 int
261 i2d_GENERAL_NAME(GENERAL_NAME *a, unsigned char **out)
262 {
263         return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAME_it);
264 }
265
266 GENERAL_NAME *
267 GENERAL_NAME_new(void)
268 {
269         return (GENERAL_NAME *)ASN1_item_new(&GENERAL_NAME_it);
270 }
271
272 void
273 GENERAL_NAME_free(GENERAL_NAME *a)
274 {
275         ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAME_it);
276 }
277
278 static const ASN1_TEMPLATE GENERAL_NAMES_item_tt = {
279         .flags = ASN1_TFLG_SEQUENCE_OF,
280         .tag = 0,
281         .offset = 0,
282         .field_name = "GeneralNames",
283         .item = &GENERAL_NAME_it,
284 };
285
286 const ASN1_ITEM GENERAL_NAMES_it = {
287         .itype = ASN1_ITYPE_PRIMITIVE,
288         .utype = -1,
289         .templates = &GENERAL_NAMES_item_tt,
290         .tcount = 0,
291         .funcs = NULL,
292         .size = 0,
293         .sname = "GENERAL_NAMES",
294 };
295
296
297 GENERAL_NAMES *
298 d2i_GENERAL_NAMES(GENERAL_NAMES **a, const unsigned char **in, long len)
299 {
300         return (GENERAL_NAMES *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
301             &GENERAL_NAMES_it);
302 }
303
304 int
305 i2d_GENERAL_NAMES(GENERAL_NAMES *a, unsigned char **out)
306 {
307         return ASN1_item_i2d((ASN1_VALUE *)a, out, &GENERAL_NAMES_it);
308 }
309
310 GENERAL_NAMES *
311 GENERAL_NAMES_new(void)
312 {
313         return (GENERAL_NAMES *)ASN1_item_new(&GENERAL_NAMES_it);
314 }
315
316 void
317 GENERAL_NAMES_free(GENERAL_NAMES *a)
318 {
319         ASN1_item_free((ASN1_VALUE *)a, &GENERAL_NAMES_it);
320 }
321
322 GENERAL_NAME *
323 GENERAL_NAME_dup(GENERAL_NAME *a)
324 {
325         return ASN1_item_dup(&GENERAL_NAME_it, a);
326 }
327
328 static int
329 EDIPARTYNAME_cmp(const EDIPARTYNAME *a, const EDIPARTYNAME *b)
330 {
331         int res;
332
333         /*
334          * Shouldn't be possible in a valid GENERAL_NAME, but we handle it
335          * anyway. OTHERNAME_cmp treats NULL != NULL, so we do the same here.
336          */
337         if (a == NULL || b == NULL)
338                 return -1;
339         if (a->nameAssigner == NULL && b->nameAssigner != NULL)
340                 return -1;
341         if (a->nameAssigner != NULL && b->nameAssigner == NULL)
342                 return 1;
343         /* If we get here, both have nameAssigner set or both unset. */
344         if (a->nameAssigner != NULL) {
345                 res = ASN1_STRING_cmp(a->nameAssigner, b->nameAssigner);
346                 if (res != 0)
347                         return res;
348         }
349         /*
350          * partyName is required, so these should never be NULL. We treat it in
351          * the same way as the a == NULL || b == NULL case above.
352          */
353         if (a->partyName == NULL || b->partyName == NULL)
354                 return -1;
355
356         return ASN1_STRING_cmp(a->partyName, b->partyName);
357 }
358
359 /* Returns 0 if they are equal, != 0 otherwise. */
360 int
361 GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b)
362 {
363         int result = -1;
364
365         if (!a || !b || a->type != b->type)
366                 return -1;
367         switch (a->type) {
368         case GEN_X400:
369                 result = ASN1_TYPE_cmp(a->d.x400Address, b->d.x400Address);
370                 break;
371
372         case GEN_EDIPARTY:
373                 result = EDIPARTYNAME_cmp(a->d.ediPartyName, b->d.ediPartyName);
374                 break;
375
376         case GEN_OTHERNAME:
377                 result = OTHERNAME_cmp(a->d.otherName, b->d.otherName);
378                 break;
379
380         case GEN_EMAIL:
381         case GEN_DNS:
382         case GEN_URI:
383                 result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5);
384                 break;
385
386         case GEN_DIRNAME:
387                 result = X509_NAME_cmp(a->d.dirn, b->d.dirn);
388                 break;
389
390         case GEN_IPADD:
391                 result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip);
392                 break;
393
394         case GEN_RID:
395                 result = OBJ_cmp(a->d.rid, b->d.rid);
396                 break;
397         }
398         return result;
399 }
400
401 /* Returns 0 if they are equal, != 0 otherwise. */
402 int
403 OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b)
404 {
405         int result = -1;
406
407         if (!a || !b)
408                 return -1;
409         /* Check their type first. */
410         if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0)
411                 return result;
412         /* Check the value. */
413         result = ASN1_TYPE_cmp(a->value, b->value);
414         return result;
415 }
416
417 void
418 GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value)
419 {
420         switch (type) {
421         case GEN_X400:
422                 a->d.x400Address = value;
423                 break;
424
425         case GEN_EDIPARTY:
426                 a->d.ediPartyName = value;
427                 break;
428
429         case GEN_OTHERNAME:
430                 a->d.otherName = value;
431                 break;
432
433         case GEN_EMAIL:
434         case GEN_DNS:
435         case GEN_URI:
436                 a->d.ia5 = value;
437                 break;
438
439         case GEN_DIRNAME:
440                 a->d.dirn = value;
441                 break;
442
443         case GEN_IPADD:
444                 a->d.ip = value;
445                 break;
446
447         case GEN_RID:
448                 a->d.rid = value;
449                 break;
450         }
451         a->type = type;
452 }
453
454 void *
455 GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype)
456 {
457         if (ptype)
458                 *ptype = a->type;
459         switch (a->type) {
460         case GEN_X400:
461                 return a->d.x400Address;
462
463         case GEN_EDIPARTY:
464                 return a->d.ediPartyName;
465
466         case GEN_OTHERNAME:
467                 return a->d.otherName;
468
469         case GEN_EMAIL:
470         case GEN_DNS:
471         case GEN_URI:
472                 return a->d.ia5;
473
474         case GEN_DIRNAME:
475                 return a->d.dirn;
476
477         case GEN_IPADD:
478                 return a->d.ip;
479
480         case GEN_RID:
481                 return a->d.rid;
482
483         default:
484                 return NULL;
485         }
486 }
487
488 int
489 GENERAL_NAME_set0_othername(GENERAL_NAME *gen, ASN1_OBJECT *oid,
490     ASN1_TYPE *value)
491 {
492         OTHERNAME *oth;
493
494         oth = OTHERNAME_new();
495         if (!oth)
496                 return 0;
497         oth->type_id = oid;
498         oth->value = value;
499         GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth);
500         return 1;
501 }
502
503 int
504 GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, ASN1_OBJECT **poid,
505     ASN1_TYPE **pvalue)
506 {
507         if (gen->type != GEN_OTHERNAME)
508                 return 0;
509         if (poid)
510                 *poid = gen->d.otherName->type_id;
511         if (pvalue)
512                 *pvalue = gen->d.otherName->value;
513         return 1;
514 }