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