]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libstrongswan/plugins/openssl/openssl_x509.c
x509: Encode challenge passwords as PrintableString if possible
[thirdparty/strongswan.git] / src / libstrongswan / plugins / openssl / openssl_x509.c
CommitLineData
5728c6aa 1/*
f781b9d3 2 * Copyright (C) 2011-2023 Tobias Brunner
5728c6aa 3 * Copyright (C) 2010 Martin Willi
19ef2aec
TB
4 *
5 * Copyright (C) secunet Security Networks AG
5728c6aa
MW
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18/*
5e4b1ad2
MR
19 * Copyright (C) 2013 Michael Rossberg
20 * Copyright (C) 2013 Technische Universität Ilmenau
21 *
5728c6aa
MW
22 * Copyright (C) 2010 Thomas Egerer
23 *
24 * Permission is hereby granted, free of charge, to any person obtaining a copy
25 * of this software and associated documentation files (the "Software"), to deal
26 * in the Software without restriction, including without limitation the rights
27 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28 * copies of the Software, and to permit persons to whom the Software is
29 * furnished to do so, subject to the following conditions:
30 *
31 * The above copyright notice and this permission notice shall be included in
32 * all copies or substantial portions of the Software.
33 *
34 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
40 * THE SOFTWARE.
41 */
42
43#define _GNU_SOURCE
44#include <stdio.h>
45#include <openssl/x509.h>
46#include <openssl/x509v3.h>
47
48#include "openssl_x509.h"
49#include "openssl_util.h"
50
f05b4272 51#include <utils/debug.h>
5728c6aa 52#include <asn1/oid.h>
12642a68 53#include <collections/linked_list.h>
5e4b1ad2 54#include <selectors/traffic_selector.h>
5728c6aa 55
5e4b1ad2
MR
56/* IP Addr block extension support was introduced with 0.9.8e */
57#if OPENSSL_VERSION_NUMBER < 0x0090805fL
58#define OPENSSL_NO_RFC3779
59#endif
5728c6aa 60
08d7e1f1
TB
61/* added with 1.0.2 */
62#if OPENSSL_VERSION_NUMBER < 0x10002000L
63static inline void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg, const X509 *x) {
64 if (psig) { *psig = x->signature; }
65 if (palg) { *palg = x->sig_alg; }
66}
67#endif
68
69/* added with 1.1.0 when X509 etc. was made opaque */
70#if OPENSSL_VERSION_NUMBER < 0x10100000L
71#define X509_get0_extensions(x509) ({ (x509)->cert_info->extensions; })
72#define X509_get0_tbs_sigalg(x509) ({ (x509)->cert_info->signature; })
73#define X509_ALGOR_get0(oid, ppt, ppv, alg) ({ *(oid) = (alg)->algorithm; })
74#define X509_PUBKEY_get0_param(oid, pk, len, pa, pub) X509_ALGOR_get0(oid, NULL, NULL, (pub)->algor)
75#define X509v3_addr_get_afi v3_addr_get_afi
76#define X509v3_addr_get_range v3_addr_get_range
77#define X509v3_addr_is_canonical v3_addr_is_canonical
a4abb263
TB
78#define X509_get0_notBefore X509_get_notBefore
79#define X509_get0_notAfter X509_get_notAfter
08d7e1f1
TB
80#endif
81
5728c6aa
MW
82typedef struct private_openssl_x509_t private_openssl_x509_t;
83
84/**
85 * Private data of an openssl_x509_t object.
86 */
87struct private_openssl_x509_t {
88
89 /**
90 * Public openssl_x509_t interface.
91 */
92 openssl_x509_t public;
93
94 /**
95 * OpenSSL certificate representation
96 */
97 X509 *x509;
98
99 /**
100 * DER encoded certificate
101 */
102 chunk_t encoding;
103
104 /**
105 * SHA1 hash of the certificate
106 */
107 chunk_t hash;
108
109 /**
110 * X509 flags
111 */
112 x509_flag_t flags;
113
114 /**
115 * Pathlen constraint
116 */
d390b3b9 117 u_char pathlen;
5728c6aa
MW
118
119 /**
120 * certificate subject
121 */
122 identification_t *subject;
123
124 /**
125 * certificate issuer
126 */
127 identification_t *issuer;
128
129 /**
130 * Certificates public key
131 */
132 public_key_t *pubkey;
133
134 /**
135 * subjectKeyIdentifier as read from cert
136 */
137 chunk_t subjectKeyIdentifier;
138
139 /**
140 * authorityKeyIdentifier as read from cert
141 */
142 chunk_t authKeyIdentifier;
143
144 /**
145 * Start time of certificate validity
146 */
147 time_t notBefore;
148
149 /**
150 * End time of certificate validity
151 */
152 time_t notAfter;
153
154 /**
155 * Signature scheme of the certificate
156 */
fb63012e 157 signature_params_t *scheme;
5728c6aa
MW
158
159 /**
160 * subjectAltNames
161 */
162 linked_list_t *subjectAltNames;
163
164 /**
165 * issuerAltNames
166 */
167 linked_list_t *issuerAltNames;
168
169 /**
a6478a04 170 * List of CRL URIs, as x509_cdp_t
5728c6aa
MW
171 */
172 linked_list_t *crl_uris;
173
174 /**
175 * List of OCSP URIs
176 */
177 linked_list_t *ocsp_uris;
178
5e4b1ad2
MR
179 /**
180 * List of ipAddrBlocks as traffic_selector_t
181 */
182 linked_list_t *ipAddrBlocks;
183
f781b9d3
TB
184 /**
185 * List of permitted name constraints
186 */
187 linked_list_t *permitted_names;
188
189 /**
190 * List of excluded name constraints
191 */
192 linked_list_t *excluded_names;
5e4b1ad2 193
5728c6aa
MW
194 /**
195 * References to this cert
196 */
197 refcount_t ref;
198};
199
200/**
201 * Convert a GeneralName to an identification_t.
202 */
203static identification_t *general_name2id(GENERAL_NAME *name)
204{
205 if (!name)
206 {
207 return NULL;
208 }
209 switch (name->type)
210 {
211 case GEN_EMAIL:
212 return identification_create_from_encoding(ID_RFC822_ADDR,
213 openssl_asn1_str2chunk(name->d.rfc822Name));
214 case GEN_DNS:
215 return identification_create_from_encoding(ID_FQDN,
216 openssl_asn1_str2chunk(name->d.dNSName));
217 case GEN_URI:
218 return identification_create_from_encoding(ID_DER_ASN1_GN_URI,
219 openssl_asn1_str2chunk(name->d.uniformResourceIdentifier));
220 case GEN_IPADD:
07c5aacc
MW
221 {
222 chunk_t chunk = openssl_asn1_str2chunk(name->d.iPAddress);
223 if (chunk.len == 4)
224 {
225 return identification_create_from_encoding(ID_IPV4_ADDR, chunk);
226 }
1c3096fe
TB
227 if (chunk.len == 8)
228 {
229 return identification_create_from_encoding(ID_IPV4_ADDR_SUBNET,
230 chunk);
231 }
07c5aacc
MW
232 if (chunk.len == 16)
233 {
234 return identification_create_from_encoding(ID_IPV6_ADDR, chunk);
235 }
1c3096fe
TB
236 if (chunk.len == 32)
237 {
238 return identification_create_from_encoding(ID_IPV6_ADDR_SUBNET,
239 chunk);
240 }
07c5aacc
MW
241 return NULL;
242 }
5728c6aa
MW
243 case GEN_DIRNAME :
244 return openssl_x509_name2id(name->d.directoryName);
a0a8aaaf
MW
245 case GEN_OTHERNAME:
246 if (OBJ_obj2nid(name->d.otherName->type_id) == NID_ms_upn &&
247 name->d.otherName->value->type == V_ASN1_UTF8STRING)
248 {
249 return identification_create_from_encoding(ID_RFC822_ADDR,
250 openssl_asn1_str2chunk(
251 name->d.otherName->value->value.utf8string));
252 }
253 return NULL;
5728c6aa
MW
254 default:
255 return NULL;
256 }
257}
258
259METHOD(x509_t, get_flags, x509_flag_t,
260 private_openssl_x509_t *this)
261{
262 return this->flags;
263}
264
265METHOD(x509_t, get_serial, chunk_t,
266 private_openssl_x509_t *this)
267{
44e241fc 268 return openssl_asn1_int2chunk(X509_get_serialNumber(this->x509));
5728c6aa
MW
269}
270
271METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
272 private_openssl_x509_t *this)
273{
274 chunk_t fingerprint;
275
276 if (this->subjectKeyIdentifier.len)
277 {
278 return this->subjectKeyIdentifier;
279 }
da9724e6 280 if (this->pubkey->get_fingerprint(this->pubkey, KEYID_PUBKEY_SHA1,
5728c6aa
MW
281 &fingerprint))
282 {
283 return fingerprint;
284 }
285 return chunk_empty;
286}
287
288METHOD(x509_t, get_authKeyIdentifier, chunk_t,
289 private_openssl_x509_t *this)
290{
291 if (this->authKeyIdentifier.len)
292 {
293 return this->authKeyIdentifier;
294 }
295 return chunk_empty;
296}
297
d390b3b9 298METHOD(x509_t, get_constraint, u_int,
b3d359e5 299 private_openssl_x509_t *this, x509_constraint_t type)
a742d97f 300{
b3d359e5
MW
301 switch (type)
302 {
303 case X509_PATH_LEN:
304 return this->pathlen;
305 default:
306 return X509_NO_CONSTRAINT;
307 }
a742d97f
MW
308}
309
5728c6aa
MW
310METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
311 private_openssl_x509_t *this)
312{
313 return this->subjectAltNames->create_enumerator(this->subjectAltNames);
314}
315
316METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
317 private_openssl_x509_t *this)
318{
a6478a04 319 return this->crl_uris->create_enumerator(this->crl_uris);
5728c6aa
MW
320}
321
322METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
323 private_openssl_x509_t *this)
324{
325 return this->ocsp_uris->create_enumerator(this->ocsp_uris);
326}
327
5e4b1ad2
MR
328METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
329 private_openssl_x509_t *this)
330{
331 return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
332}
333
f781b9d3
TB
334METHOD(x509_t, create_name_constraint_enumerator, enumerator_t*,
335 private_openssl_x509_t *this, bool perm)
336{
337 if (perm)
338 {
339 return this->permitted_names->create_enumerator(this->permitted_names);
340 }
341 return this->excluded_names->create_enumerator(this->excluded_names);
342}
343
5728c6aa
MW
344METHOD(certificate_t, get_type, certificate_type_t,
345 private_openssl_x509_t *this)
346{
347 return CERT_X509;
348}
349
350METHOD(certificate_t, get_subject, identification_t*,
351 private_openssl_x509_t *this)
352{
353 return this->subject;
354}
355
356METHOD(certificate_t, get_issuer, identification_t*,
357 private_openssl_x509_t *this)
358{
359 return this->issuer;
360}
361
362METHOD(certificate_t, has_subject, id_match_t,
363 private_openssl_x509_t *this, identification_t *subject)
364{
365 identification_t *current;
366 enumerator_t *enumerator;
367 id_match_t match, best;
663e7355 368 chunk_t encoding;
5728c6aa
MW
369
370 if (subject->get_type(subject) == ID_KEY_ID)
371 {
663e7355
MW
372 encoding = subject->get_encoding(subject);
373
374 if (chunk_equals(this->hash, encoding))
375 {
376 return ID_MATCH_PERFECT;
377 }
378 if (this->subjectKeyIdentifier.len &&
379 chunk_equals(this->subjectKeyIdentifier, encoding))
380 {
381 return ID_MATCH_PERFECT;
382 }
383 if (this->pubkey &&
384 this->pubkey->has_fingerprint(this->pubkey, encoding))
5728c6aa
MW
385 {
386 return ID_MATCH_PERFECT;
387 }
ed1c4303
MW
388 if (chunk_equals(get_serial(this), encoding))
389 {
390 return ID_MATCH_PERFECT;
391 }
5728c6aa
MW
392 }
393 best = this->subject->matches(this->subject, subject);
394 enumerator = create_subjectAltName_enumerator(this);
395 while (enumerator->enumerate(enumerator, &current))
396 {
397 match = current->matches(current, subject);
398 if (match > best)
399 {
400 best = match;
401 }
402 }
403 enumerator->destroy(enumerator);
404 return best;
405}
406
407METHOD(certificate_t, has_issuer, id_match_t,
408 private_openssl_x509_t *this, identification_t *issuer)
409{
410 /* issuerAltNames currently not supported */
411 return this->issuer->matches(this->issuer, issuer);
412}
413
414METHOD(certificate_t, issued_by, bool,
a37f2d20 415 private_openssl_x509_t *this, certificate_t *issuer,
024b9795 416 signature_params_t **scheme)
5728c6aa
MW
417{
418 public_key_t *key;
419 bool valid;
420 x509_t *x509 = (x509_t*)issuer;
f0c25960 421 chunk_t keyid = chunk_empty;
8b4c2a1d
TB
422#if OPENSSL_VERSION_NUMBER >= 0x10100000L
423 const ASN1_BIT_STRING *sig;
424#else
08d7e1f1 425 ASN1_BIT_STRING *sig;
8b4c2a1d 426#endif
5728c6aa
MW
427 chunk_t tbs;
428
429 if (&this->public.x509.interface == issuer)
430 {
431 if (this->flags & X509_SELF_SIGNED)
432 {
024b9795
TB
433 valid = TRUE;
434 goto out;
5728c6aa
MW
435 }
436 }
437 else
438 {
439 if (issuer->get_type(issuer) != CERT_X509)
440 {
441 return FALSE;
442 }
443 if (!(x509->get_flags(x509) & X509_CA))
444 {
445 return FALSE;
446 }
61769fd1 447 }
f0c25960
AKR
448
449 /* compare keyIdentifiers if available, otherwise use DNs */
450 if (this->authKeyIdentifier.ptr)
61769fd1 451 {
f0c25960
AKR
452 keyid = x509->get_subjectKeyIdentifier(x509);
453 if (keyid.len && !chunk_equals(keyid, this->authKeyIdentifier))
454 {
455 return FALSE;
456 }
5728c6aa 457 }
f0c25960
AKR
458 if (!keyid.len)
459 {
460 if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
461 {
462 return FALSE;
463 }
464 }
465
5728c6aa
MW
466 key = issuer->get_public_key(issuer);
467 if (!key)
468 {
469 return FALSE;
470 }
08d7e1f1
TB
471 /* i2d_re_X509_tbs() was added with 1.1.0 when X509 was made opaque */
472#if OPENSSL_VERSION_NUMBER >= 0x10100000L
473 tbs = openssl_i2chunk(re_X509_tbs, this->x509);
474#else
5728c6aa 475 tbs = openssl_i2chunk(X509_CINF, this->x509->cert_info);
08d7e1f1
TB
476#endif
477 X509_get0_signature(&sig, NULL, this->x509);
fb63012e 478 valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs,
a413571f 479 openssl_asn1_str2chunk(sig));
5728c6aa
MW
480 free(tbs.ptr);
481 key->destroy(key);
024b9795
TB
482
483out:
a37f2d20
MW
484 if (valid && scheme)
485 {
fb63012e 486 *scheme = signature_params_clone(this->scheme);
a37f2d20 487 }
5728c6aa
MW
488 return valid;
489}
490
491METHOD(certificate_t, get_public_key, public_key_t*,
492 private_openssl_x509_t *this)
493{
494 return this->pubkey->get_ref(this->pubkey);
495}
496
497METHOD(certificate_t, get_validity, bool,
498 private_openssl_x509_t *this,
499 time_t *when, time_t *not_before, time_t *not_after)
500{
501 time_t t;
502
503 if (when)
504 {
505 t = *when;
506 }
507 else
508 {
509 t = time(NULL);
510 }
511 if (not_before)
512 {
513 *not_before = this->notBefore;
514 }
515 if (not_after)
516 {
517 *not_after = this->notAfter;
518 }
519 return (t >= this->notBefore && t <= this->notAfter);
520}
521
0406eeaa
MW
522METHOD(certificate_t, get_encoding, bool,
523 private_openssl_x509_t *this, cred_encoding_type_t type, chunk_t *encoding)
5728c6aa 524{
0406eeaa
MW
525 if (type == CERT_ASN1_DER)
526 {
527 *encoding = chunk_clone(this->encoding);
528 return TRUE;
529 }
530 return lib->encoding->encode(lib->encoding, type, NULL, encoding,
531 CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
5728c6aa
MW
532}
533
0406eeaa 534
5728c6aa
MW
535METHOD(certificate_t, equals, bool,
536 private_openssl_x509_t *this, certificate_t *other)
537{
538 chunk_t encoding;
539 bool equal;
540
541 if (this == (private_openssl_x509_t*)other)
542 {
543 return TRUE;
544 }
545 if (other->get_type(other) != CERT_X509)
546 {
547 return FALSE;
548 }
549 if (other->equals == (void*)equals)
550 { /* skip allocation if we have the same implementation */
551 encoding = ((private_openssl_x509_t*)other)->encoding;
552 return chunk_equals(this->encoding, encoding);
553 }
0406eeaa
MW
554 if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
555 {
556 return FALSE;
557 }
5728c6aa
MW
558 equal = chunk_equals(this->encoding, encoding);
559 free(encoding.ptr);
560 return equal;
561}
562
563METHOD(certificate_t, get_ref, certificate_t*,
564 private_openssl_x509_t *this)
565{
566 ref_get(&this->ref);
567 return &this->public.x509.interface;
568}
569
570METHOD(certificate_t, destroy, void,
571 private_openssl_x509_t *this)
572{
573 if (ref_put(&this->ref))
574 {
575 if (this->x509)
576 {
577 X509_free(this->x509);
578 }
fb63012e 579 signature_params_destroy(this->scheme);
5728c6aa
MW
580 DESTROY_IF(this->subject);
581 DESTROY_IF(this->issuer);
582 DESTROY_IF(this->pubkey);
583 free(this->subjectKeyIdentifier.ptr);
584 free(this->authKeyIdentifier.ptr);
585 free(this->encoding.ptr);
586 free(this->hash.ptr);
587 this->subjectAltNames->destroy_offset(this->subjectAltNames,
588 offsetof(identification_t, destroy));
589 this->issuerAltNames->destroy_offset(this->issuerAltNames,
590 offsetof(identification_t, destroy));
4e7b7db6
TB
591 this->crl_uris->destroy_function(this->crl_uris,
592 (void*)x509_cdp_destroy);
5728c6aa 593 this->ocsp_uris->destroy_function(this->ocsp_uris, free);
5e4b1ad2
MR
594 this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
595 offsetof(traffic_selector_t, destroy));
f781b9d3
TB
596 this->permitted_names->destroy_offset(this->permitted_names,
597 offsetof(identification_t, destroy));
598 this->excluded_names->destroy_offset(this->excluded_names,
599 offsetof(identification_t, destroy));
5728c6aa
MW
600 free(this);
601 }
602}
603
604/**
605 * Create an empty certificate
606 */
607static private_openssl_x509_t *create_empty()
608{
609 private_openssl_x509_t *this;
610
611 INIT(this,
612 .public = {
613 .x509 = {
614 .interface = {
615 .get_type = _get_type,
616 .get_subject = _get_subject,
617 .get_issuer = _get_issuer,
618 .has_subject = _has_subject,
619 .has_issuer = _has_issuer,
620 .issued_by = _issued_by,
621 .get_public_key = _get_public_key,
622 .get_validity = _get_validity,
5728c6aa
MW
623 .get_encoding = _get_encoding,
624 .equals = _equals,
625 .get_ref = _get_ref,
626 .destroy = _destroy,
627 },
628 .get_flags = _get_flags,
629 .get_serial = _get_serial,
630 .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
631 .get_authKeyIdentifier = _get_authKeyIdentifier,
b3d359e5 632 .get_constraint = _get_constraint,
5728c6aa
MW
633 .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
634 .create_crl_uri_enumerator = _create_crl_uri_enumerator,
635 .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
5e4b1ad2 636 .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
f781b9d3 637 .create_name_constraint_enumerator = _create_name_constraint_enumerator,
20bd7810 638 .create_cert_policy_enumerator = (void*)enumerator_create_empty,
5a0caa4b 639 .create_policy_mapping_enumerator = (void*)enumerator_create_empty,
5728c6aa
MW
640 },
641 },
642 .subjectAltNames = linked_list_create(),
643 .issuerAltNames = linked_list_create(),
644 .crl_uris = linked_list_create(),
645 .ocsp_uris = linked_list_create(),
5e4b1ad2 646 .ipAddrBlocks = linked_list_create(),
f781b9d3
TB
647 .permitted_names = linked_list_create(),
648 .excluded_names = linked_list_create(),
5dba5852 649 .pathlen = X509_NO_CONSTRAINT,
5728c6aa
MW
650 .ref = 1,
651 );
652
653 return this;
654}
655
656/**
b3ab7a48 657 * parse an extension containing GENERAL_NAMES into a list
5728c6aa
MW
658 */
659static bool parse_generalNames_ext(linked_list_t *list,
660 X509_EXTENSION *ext)
661{
662 GENERAL_NAMES *names;
663 GENERAL_NAME *name;
664 identification_t *id;
665 int i, num;
666
667 names = X509V3_EXT_d2i(ext);
668 if (!names)
669 {
670 return FALSE;
671 }
672
673 num = sk_GENERAL_NAME_num(names);
674 for (i = 0; i < num; i++)
675 {
676 name = sk_GENERAL_NAME_value(names, i);
677 id = general_name2id(name);
678 if (id)
679 {
680 list->insert_last(list, id);
681 }
682 GENERAL_NAME_free(name);
683 }
684 sk_GENERAL_NAME_free(names);
685 return TRUE;
686}
687
688/**
689 * parse basic constraints
690 */
691static bool parse_basicConstraints_ext(private_openssl_x509_t *this,
692 X509_EXTENSION *ext)
693{
694 BASIC_CONSTRAINTS *constraints;
d390b3b9 695 long pathlen;
5728c6aa
MW
696
697 constraints = (BASIC_CONSTRAINTS*)X509V3_EXT_d2i(ext);
698 if (constraints)
699 {
700 if (constraints->ca)
701 {
702 this->flags |= X509_CA;
703 }
704 if (constraints->pathlen)
705 {
28bcbc29 706
d390b3b9
AS
707 pathlen = ASN1_INTEGER_get(constraints->pathlen);
708 this->pathlen = (pathlen >= 0 && pathlen < 128) ?
709 pathlen : X509_NO_CONSTRAINT;
5728c6aa
MW
710 }
711 BASIC_CONSTRAINTS_free(constraints);
712 return TRUE;
713 }
714 return FALSE;
715}
716
28bcbc29
TB
717/**
718 * parse key usage
719 */
720static bool parse_keyUsage_ext(private_openssl_x509_t *this,
721 X509_EXTENSION *ext)
722{
723 ASN1_BIT_STRING *usage;
724
725 usage = X509V3_EXT_d2i(ext);
726 if (usage)
727 {
728 if (usage->length > 0)
729 {
730 int flags = usage->data[0];
731 if (usage->length > 1)
732 {
733 flags |= usage->data[1] << 8;
734 }
e793d65a 735 if (flags & X509v3_KU_CRL_SIGN)
28bcbc29 736 {
e793d65a
TB
737 this->flags |= X509_CRL_SIGN;
738 }
504e1232
TB
739 if (flags & X509v3_KU_DIGITAL_SIGNATURE ||
740 flags & X509v3_KU_NON_REPUDIATION)
741 {
742 this->flags |= X509_IKE_COMPLIANT;
743 }
e793d65a
TB
744 if (flags & X509v3_KU_KEY_CERT_SIGN)
745 {
b3ab7a48 746 /* we use the caBasicConstraint, MUST be set */
28bcbc29
TB
747 }
748 }
749 ASN1_BIT_STRING_free(usage);
750 return TRUE;
751 }
752 return FALSE;
753}
754
c3e7b3de
MW
755/**
756 * Parse ExtendedKeyUsage
757 */
758static bool parse_extKeyUsage_ext(private_openssl_x509_t *this,
759 X509_EXTENSION *ext)
760{
761 EXTENDED_KEY_USAGE *usage;
762 int i;
763
764 usage = X509V3_EXT_d2i(ext);
765 if (usage)
766 {
767 for (i = 0; i < sk_ASN1_OBJECT_num(usage); i++)
768 {
769 switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(usage, i)))
770 {
771 case NID_server_auth:
772 this->flags |= X509_SERVER_AUTH;
773 break;
774 case NID_client_auth:
775 this->flags |= X509_CLIENT_AUTH;
776 break;
777 case NID_OCSP_sign:
778 this->flags |= X509_OCSP_SIGNER;
779 break;
780 default:
781 break;
782 }
783 }
784 sk_ASN1_OBJECT_pop_free(usage, ASN1_OBJECT_free);
785 return TRUE;
786 }
787 return FALSE;
788}
789
5728c6aa
MW
790/**
791 * Parse CRL distribution points
792 */
86c10a95
TB
793bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext,
794 linked_list_t *list)
5728c6aa
MW
795{
796 CRL_DIST_POINTS *cdps;
797 DIST_POINT *cdp;
a6478a04
MW
798 identification_t *id, *issuer;
799 x509_cdp_t *entry;
5728c6aa 800 char *uri;
86c10a95 801 int i, j, k, point_num, name_num, issuer_num, len;
5728c6aa
MW
802
803 cdps = X509V3_EXT_d2i(ext);
804 if (!cdps)
805 {
806 return FALSE;
807 }
808 point_num = sk_DIST_POINT_num(cdps);
809 for (i = 0; i < point_num; i++)
810 {
811 cdp = sk_DIST_POINT_value(cdps, i);
812 if (cdp)
813 {
814 if (cdp->distpoint && cdp->distpoint->type == 0 &&
815 cdp->distpoint->name.fullname)
816 {
817 name_num = sk_GENERAL_NAME_num(cdp->distpoint->name.fullname);
818 for (j = 0; j < name_num; j++)
819 {
820 id = general_name2id(sk_GENERAL_NAME_value(
821 cdp->distpoint->name.fullname, j));
822 if (id)
823 {
86c10a95
TB
824 len = asprintf(&uri, "%Y", id);
825 if (!len)
826 {
827 free(uri);
828 }
829 else if (len > 0)
5728c6aa 830 {
a6478a04
MW
831 if (cdp->CRLissuer)
832 {
833 issuer_num = sk_GENERAL_NAME_num(cdp->CRLissuer);
834 for (k = 0; k < issuer_num; k++)
835 {
836 issuer = general_name2id(
837 sk_GENERAL_NAME_value(cdp->CRLissuer, k));
838 if (issuer)
839 {
840 INIT(entry,
841 .uri = strdup(uri),
842 .issuer = issuer,
843 );
86c10a95 844 list->insert_last(list, entry);
a6478a04
MW
845 }
846 }
847 free(uri);
848 }
849 else
850 {
851 INIT(entry,
852 .uri = uri,
853 );
86c10a95 854 list->insert_last(list, entry);
a6478a04 855 }
5728c6aa
MW
856 }
857 id->destroy(id);
858 }
859 }
860 }
a6478a04 861
5728c6aa
MW
862 DIST_POINT_free(cdp);
863 }
864 }
865 sk_DIST_POINT_free(cdps);
866 return TRUE;
867}
868
869/**
870 * Parse authorityInfoAccess with OCSP URIs
871 */
872static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
873 X509_EXTENSION *ext)
874{
875 AUTHORITY_INFO_ACCESS *infos;
876 ACCESS_DESCRIPTION *desc;
877 identification_t *id;
86c10a95 878 int i, num, len;
5728c6aa
MW
879 char *uri;
880
881 infos = X509V3_EXT_d2i(ext);
882 if (!infos)
883 {
884 return FALSE;
885 }
886 num = sk_ACCESS_DESCRIPTION_num(infos);
887 for (i = 0; i < num; i++)
888 {
889 desc = sk_ACCESS_DESCRIPTION_value(infos, i);
890 if (desc)
891 {
892 if (openssl_asn1_known_oid(desc->method) == OID_OCSP)
893 {
894 id = general_name2id(desc->location);
895 if (id)
896 {
86c10a95
TB
897 len = asprintf(&uri, "%Y", id);
898 if (!len)
899 {
900 free(uri);
901 }
902 else if (len > 0)
5728c6aa 903 {
93818392 904 this->ocsp_uris->insert_last(this->ocsp_uris, uri);
5728c6aa
MW
905 }
906 id->destroy(id);
907 }
908 }
909 ACCESS_DESCRIPTION_free(desc);
910 }
911 }
912 sk_ACCESS_DESCRIPTION_free(infos);
913 return TRUE;
914}
915
5e4b1ad2
MR
916#ifndef OPENSSL_NO_RFC3779
917
918/**
919 * Parse a single block of ipAddrBlock extension
920 */
921static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t *this,
922 IPAddressFamily *fam)
923{
924 const IPAddressOrRanges *list;
925 IPAddressOrRange *aor;
926 traffic_selector_t *ts;
927 ts_type_t type;
928 chunk_t from, to;
929 int i, afi;
930
931 if (fam->ipAddressChoice->type != IPAddressChoice_addressesOrRanges)
932 {
933 return;
934 }
935
08d7e1f1 936 afi = X509v3_addr_get_afi(fam);
5e4b1ad2
MR
937 switch (afi)
938 {
939 case IANA_AFI_IPV4:
940 from = chunk_alloca(4);
941 to = chunk_alloca(4);
942 type = TS_IPV4_ADDR_RANGE;
943 break;
944 case IANA_AFI_IPV6:
945 from = chunk_alloca(16);
946 to = chunk_alloca(16);
947 type = TS_IPV6_ADDR_RANGE;
948 break;
949 default:
950 return;
951 }
952
953 list = fam->ipAddressChoice->u.addressesOrRanges;
954 for (i = 0; i < sk_IPAddressOrRange_num(list); i++)
955 {
956 aor = sk_IPAddressOrRange_value(list, i);
08d7e1f1 957 if (X509v3_addr_get_range(aor, afi, from.ptr, to.ptr, from.len) > 0)
5e4b1ad2
MR
958 {
959 ts = traffic_selector_create_from_bytes(0, type, from, 0, to, 65535);
960 if (ts)
961 {
962 this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
963 }
964 }
965 }
966}
967
968/**
969 * Parse ipAddrBlock extension
970 */
971static bool parse_ipAddrBlock_ext(private_openssl_x509_t *this,
972 X509_EXTENSION *ext)
973{
974 STACK_OF(IPAddressFamily) *blocks;
975 IPAddressFamily *fam;
976
977 blocks = (STACK_OF(IPAddressFamily)*)X509V3_EXT_d2i(ext);
978 if (!blocks)
979 {
980 return FALSE;
981 }
982
08d7e1f1 983 if (!X509v3_addr_is_canonical(blocks))
5e4b1ad2
MR
984 {
985 sk_IPAddressFamily_free(blocks);
986 return FALSE;
987 }
988
989 while (sk_IPAddressFamily_num(blocks) > 0)
990 {
991 fam = sk_IPAddressFamily_pop(blocks);
992 parse_ipAddrBlock_ext_fam(this, fam);
993 IPAddressFamily_free(fam);
994 }
995 sk_IPAddressFamily_free(blocks);
996
997 this->flags |= X509_IP_ADDR_BLOCKS;
998 return TRUE;
999}
1000#endif /* !OPENSSL_NO_RFC3779 */
1001
f781b9d3
TB
1002/**
1003 * Parse a "generalSubtree" structure (sequence of generalNames)
1004 */
1005static bool parse_generalSubtrees(linked_list_t *list,
1006 STACK_OF(GENERAL_SUBTREE) *subtrees)
1007{
1008 GENERAL_SUBTREE *subtree;
1009 identification_t *id;
1010 int i;
1011
1012 for (i = 0; i < sk_GENERAL_SUBTREE_num(subtrees); i++)
1013 {
1014 subtree = sk_GENERAL_SUBTREE_value(subtrees, i);
1015 id = general_name2id(subtree->base);
1016 if (id)
1017 {
1018 list->insert_last(list, id);
1019 }
1020 else
1021 {
1022 return FALSE;
1023 }
1024 }
1025 return TRUE;
1026}
1027
1028/**
1029 * Parse permitted/excluded nameConstraints
1030 */
1031static bool parse_nameConstraints_ext(private_openssl_x509_t *this,
1032 X509_EXTENSION *ext)
1033{
1034 NAME_CONSTRAINTS *nc;
1035 bool ok = FALSE;
1036
1037 nc = (NAME_CONSTRAINTS*)X509V3_EXT_d2i(ext);
1038 if (nc)
1039 {
1040 ok = parse_generalSubtrees(this->permitted_names, nc->permittedSubtrees) &&
1041 parse_generalSubtrees(this->excluded_names, nc->excludedSubtrees);
1042 NAME_CONSTRAINTS_free(nc);
1043 }
1044 return ok;
1045}
1046
5728c6aa
MW
1047/**
1048 * Parse authorityKeyIdentifier extension
1049 */
1050static bool parse_authKeyIdentifier_ext(private_openssl_x509_t *this,
1051 X509_EXTENSION *ext)
1052{
1053 AUTHORITY_KEYID *keyid;
1054
1055 keyid = (AUTHORITY_KEYID*)X509V3_EXT_d2i(ext);
1056 if (keyid)
1057 {
1058 free(this->authKeyIdentifier.ptr);
1059 this->authKeyIdentifier = chunk_clone(
1060 openssl_asn1_str2chunk(keyid->keyid));
1061 AUTHORITY_KEYID_free(keyid);
1062 return TRUE;
1063 }
1064 return FALSE;
1065}
1066
1067/**
1068 * Parse subjectKeyIdentifier extension
1069 */
1070static bool parse_subjectKeyIdentifier_ext(private_openssl_x509_t *this,
1071 X509_EXTENSION *ext)
1072{
f00a1015
MW
1073 chunk_t ostr;
1074
1075 ostr = openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext));
1076 /* quick and dirty unwrap of octet string */
1077 if (ostr.len > 2 &&
1078 ostr.ptr[0] == V_ASN1_OCTET_STRING && ostr.ptr[1] == ostr.len - 2)
1079 {
1080 free(this->subjectKeyIdentifier.ptr);
1081 this->subjectKeyIdentifier = chunk_clone(chunk_skip(ostr, 2));
1082 return TRUE;
1083 }
1084 return FALSE;
5728c6aa
MW
1085}
1086
1087/**
1088 * Parse X509 extensions we are interested in
1089 */
1090static bool parse_extensions(private_openssl_x509_t *this)
1091{
8b4c2a1d 1092 const STACK_OF(X509_EXTENSION) *extensions;
d12a4f5d 1093 bool key_usage_parsed = FALSE;
5728c6aa
MW
1094 int i, num;
1095
08d7e1f1 1096 extensions = X509_get0_extensions(this->x509);
5728c6aa
MW
1097 if (extensions)
1098 {
1099 num = sk_X509_EXTENSION_num(extensions);
1100
1101 for (i = 0; i < num; i++)
1102 {
1103 X509_EXTENSION *ext;
1104 bool ok;
1105
1106 ext = sk_X509_EXTENSION_value(extensions, i);
1107 switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext)))
1108 {
1109 case NID_info_access:
1110 ok = parse_authorityInfoAccess_ext(this, ext);
1111 break;
1112 case NID_authority_key_identifier:
1113 ok = parse_authKeyIdentifier_ext(this, ext);
1114 break;
1115 case NID_subject_key_identifier:
1116 ok = parse_subjectKeyIdentifier_ext(this, ext);
1117 break;
1118 case NID_subject_alt_name:
1119 ok = parse_generalNames_ext(this->subjectAltNames, ext);
1120 break;
1121 case NID_issuer_alt_name:
1122 ok = parse_generalNames_ext(this->issuerAltNames, ext);
1123 break;
1124 case NID_basic_constraints:
1125 ok = parse_basicConstraints_ext(this, ext);
1126 break;
28bcbc29
TB
1127 case NID_key_usage:
1128 ok = parse_keyUsage_ext(this, ext);
d12a4f5d 1129 key_usage_parsed = TRUE;
28bcbc29 1130 break;
c3e7b3de
MW
1131 case NID_ext_key_usage:
1132 ok = parse_extKeyUsage_ext(this, ext);
1133 break;
5728c6aa 1134 case NID_crl_distribution_points:
86c10a95 1135 ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris);
5728c6aa 1136 break;
5e4b1ad2
MR
1137#ifndef OPENSSL_NO_RFC3779
1138 case NID_sbgp_ipAddrBlock:
1139 ok = parse_ipAddrBlock_ext(this, ext);
1140 break;
1141#endif /* !OPENSSL_NO_RFC3779 */
f781b9d3
TB
1142 case NID_name_constraints:
1143 ok = parse_nameConstraints_ext(this, ext);
1144 break;
5728c6aa 1145 default:
c4fd3b2f
AS
1146 ok = X509_EXTENSION_get_critical(ext) == 0 ||
1147 !lib->settings->get_bool(lib->settings,
8dc6e716 1148 "%s.x509.enforce_critical", TRUE, lib->ns);
b0892d09
MW
1149 if (!ok)
1150 {
3f55f203
MW
1151 char buf[80] = "";
1152
1153 OBJ_obj2txt(buf, sizeof(buf),
1154 X509_EXTENSION_get_object(ext), 0);
1155 DBG1(DBG_LIB, "found unsupported critical X.509 "
1156 "extension: %s", buf);
b0892d09 1157 }
5728c6aa
MW
1158 break;
1159 }
1160 if (!ok)
1161 {
1162 return FALSE;
1163 }
1164 }
1165 }
d12a4f5d
TB
1166 if (!key_usage_parsed)
1167 {
1168 /* we are compliant with RFC 4945 without keyUsage extension */
1169 this->flags |= X509_IKE_COMPLIANT;
1170 /* allow CA certificates without keyUsage extension to sign CRLs */
1171 if (this->flags & X509_CA)
1172 {
1173 this->flags |= X509_CRL_SIGN;
1174 }
1175 }
5728c6aa
MW
1176 return TRUE;
1177}
1178
1179/**
1180 * Parse a DER encoded x509 certificate
1181 */
1182static bool parse_certificate(private_openssl_x509_t *this)
1183{
1184 const unsigned char *ptr = this->encoding.ptr;
1185 hasher_t *hasher;
fb63012e
TB
1186 chunk_t chunk, sig_scheme, sig_scheme_tbs;
1187 ASN1_OBJECT *oid;
8b4c2a1d
TB
1188#if OPENSSL_VERSION_NUMBER >= 0x10100000L
1189 const X509_ALGOR *alg;
1190#else
08d7e1f1 1191 X509_ALGOR *alg;
8b4c2a1d 1192#endif
85a35fc9 1193 key_type_t ed_type = KEY_ED448;
5728c6aa
MW
1194
1195 this->x509 = d2i_X509(NULL, &ptr, this->encoding.len);
1196 if (!this->x509)
1197 {
1198 return FALSE;
1199 }
a6850b84
MW
1200 if (X509_get_version(this->x509) < 0 || X509_get_version(this->x509) > 2)
1201 {
1202 DBG1(DBG_LIB, "unsupported x509 version: %d",
1203 X509_get_version(this->x509) + 1);
1204 return FALSE;
1205 }
1206
5728c6aa
MW
1207 this->subject = openssl_x509_name2id(X509_get_subject_name(this->x509));
1208 this->issuer = openssl_x509_name2id(X509_get_issuer_name(this->x509));
1209
08d7e1f1
TB
1210 if (!X509_PUBKEY_get0_param(&oid, NULL, NULL, NULL,
1211 X509_get_X509_PUBKEY(this->x509)))
1212 {
1213 return FALSE;
1214 }
1215 switch (openssl_asn1_known_oid(oid))
5728c6aa 1216 {
364395d2
TB
1217 case OID_RSASSA_PSS:
1218 /* TODO: we should treat such keys special and use the params as
1219 * restrictions regarding the use of this key (or rather the
1220 * associated private key) */
5728c6aa
MW
1221 case OID_RSA_ENCRYPTION:
1222 this->pubkey = lib->creds->create(lib->creds,
1223 CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_ASN1_DER,
1224 openssl_asn1_str2chunk(X509_get0_pubkey_bitstr(this->x509)),
1225 BUILD_END);
1226 break;
1227 case OID_EC_PUBLICKEY:
1228 /* for ECDSA, we need the full subjectPublicKeyInfo, as it contains
1229 * the curve parameters. */
1230 chunk = openssl_i2chunk(X509_PUBKEY, X509_get_X509_PUBKEY(this->x509));
1231 this->pubkey = lib->creds->create(lib->creds,
1232 CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER,
1233 chunk, BUILD_END);
1234 free(chunk.ptr);
1235 break;
85a35fc9
TB
1236 case OID_ED25519:
1237 ed_type = KEY_ED25519;
1238 /* fall-through */
1239 case OID_ED448:
1240 /* for EdDSA, the parsers expect the full subjectPublicKeyInfo */
1241 chunk = openssl_i2chunk(X509_PUBKEY, X509_get_X509_PUBKEY(this->x509));
1242 this->pubkey = lib->creds->create(lib->creds,
1243 CRED_PUBLIC_KEY, ed_type, BUILD_BLOB_ASN1_DER,
1244 chunk, BUILD_END);
1245 free(chunk.ptr);
1246 break;
5728c6aa
MW
1247 default:
1248 DBG1(DBG_LIB, "unsupported public key algorithm");
1249 break;
1250 }
1251 if (!this->subject || !this->issuer || !this->pubkey)
1252 {
1253 return FALSE;
1254 }
1255
a4abb263
TB
1256 this->notBefore = openssl_asn1_to_time(X509_get0_notBefore(this->x509));
1257 this->notAfter = openssl_asn1_to_time(X509_get0_notAfter(this->x509));
5728c6aa 1258
08d7e1f1
TB
1259 /* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL
1260 * versions, at least on Ubuntu 14.04 it is not actually defined */
1261 X509_get0_signature(NULL, &alg, this->x509);
8b4c2a1d 1262 sig_scheme = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
08d7e1f1 1263 alg = X509_get0_tbs_sigalg(this->x509);
8b4c2a1d 1264 sig_scheme_tbs = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
fb63012e
TB
1265 if (!chunk_equals(sig_scheme, sig_scheme_tbs))
1266 {
1267 free(sig_scheme_tbs.ptr);
1268 free(sig_scheme.ptr);
1269 return FALSE;
1270 }
1271 free(sig_scheme_tbs.ptr);
1272
1273 INIT(this->scheme);
1274 if (!signature_params_parse(sig_scheme, 0, this->scheme))
5728c6aa 1275 {
fb63012e
TB
1276 DBG1(DBG_ASN, "unable to parse signature algorithm");
1277 free(sig_scheme.ptr);
5728c6aa
MW
1278 return FALSE;
1279 }
fb63012e 1280 free(sig_scheme.ptr);
5728c6aa
MW
1281
1282 if (!parse_extensions(this))
1283 {
c4fd3b2f 1284 return FALSE;
5728c6aa
MW
1285 }
1286
1287 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
87dd205b 1288 if (!hasher || !hasher->allocate_hash(hasher, this->encoding, &this->hash))
5728c6aa 1289 {
87dd205b 1290 DESTROY_IF(hasher);
5728c6aa
MW
1291 return FALSE;
1292 }
5728c6aa
MW
1293 hasher->destroy(hasher);
1294
a37f2d20 1295 if (issued_by(this, &this->public.x509.interface, NULL))
5728c6aa
MW
1296 {
1297 this->flags |= X509_SELF_SIGNED;
1298 }
1299 return TRUE;
1300}
1301
1302openssl_x509_t *openssl_x509_load(certificate_type_t type, va_list args)
1303{
1304 chunk_t blob = chunk_empty;
1305 x509_flag_t flags = 0;
1306
1307 while (TRUE)
1308 {
1309 switch (va_arg(args, builder_part_t))
1310 {
1311 case BUILD_BLOB_ASN1_DER:
1312 blob = va_arg(args, chunk_t);
1313 continue;
1314 case BUILD_X509_FLAG:
1315 flags |= va_arg(args, x509_flag_t);
1316 continue;
1317 case BUILD_END:
1318 break;
1319 default:
1320 return NULL;
1321 }
1322 break;
1323 }
1324
1325 if (blob.ptr)
1326 {
1327 private_openssl_x509_t *this;
1328
1329 this = create_empty();
1330 this->encoding = chunk_clone(blob);
1331 this->flags |= flags;
1332 if (parse_certificate(this))
1333 {
1334 return &this->public;
1335 }
1336 DBG1(DBG_LIB, "OpenSSL X.509 parsing failed");
1337 destroy(this);
1338 }
1339 return NULL;
1340}