]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/libstrongswan/plugins/openssl/openssl_x509.c
lib: Add default config fallback for configured namespace
[thirdparty/strongswan.git] / src / libstrongswan / plugins / openssl / openssl_x509.c
CommitLineData
5728c6aa 1/*
28bcbc29
TB
2 * Copyright (C) 2011 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
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
MW
62
63typedef struct private_openssl_x509_t private_openssl_x509_t;
64
65/**
66 * Private data of an openssl_x509_t object.
67 */
68struct private_openssl_x509_t {
69
70 /**
71 * Public openssl_x509_t interface.
72 */
73 openssl_x509_t public;
74
75 /**
76 * OpenSSL certificate representation
77 */
78 X509 *x509;
79
80 /**
81 * DER encoded certificate
82 */
83 chunk_t encoding;
84
85 /**
86 * SHA1 hash of the certificate
87 */
88 chunk_t hash;
89
90 /**
91 * X509 flags
92 */
93 x509_flag_t flags;
94
95 /**
96 * Pathlen constraint
97 */
d390b3b9 98 u_char pathlen;
5728c6aa
MW
99
100 /**
101 * certificate subject
102 */
103 identification_t *subject;
104
105 /**
106 * certificate issuer
107 */
108 identification_t *issuer;
109
110 /**
111 * Certificates public key
112 */
113 public_key_t *pubkey;
114
115 /**
116 * subjectKeyIdentifier as read from cert
117 */
118 chunk_t subjectKeyIdentifier;
119
120 /**
121 * authorityKeyIdentifier as read from cert
122 */
123 chunk_t authKeyIdentifier;
124
125 /**
126 * Start time of certificate validity
127 */
128 time_t notBefore;
129
130 /**
131 * End time of certificate validity
132 */
133 time_t notAfter;
134
135 /**
136 * Signature scheme of the certificate
137 */
138 signature_scheme_t scheme;
139
140 /**
141 * subjectAltNames
142 */
143 linked_list_t *subjectAltNames;
144
145 /**
146 * issuerAltNames
147 */
148 linked_list_t *issuerAltNames;
149
150 /**
a6478a04 151 * List of CRL URIs, as x509_cdp_t
5728c6aa
MW
152 */
153 linked_list_t *crl_uris;
154
155 /**
156 * List of OCSP URIs
157 */
158 linked_list_t *ocsp_uris;
159
5e4b1ad2
MR
160 /**
161 * List of ipAddrBlocks as traffic_selector_t
162 */
163 linked_list_t *ipAddrBlocks;
164
165
5728c6aa
MW
166 /**
167 * References to this cert
168 */
169 refcount_t ref;
170};
171
4e508517
MW
172/**
173 * Destroy a CRL URI struct
174 */
a6478a04 175static void crl_uri_destroy(x509_cdp_t *this)
4e508517 176{
a6478a04 177 free(this->uri);
4e508517
MW
178 DESTROY_IF(this->issuer);
179 free(this);
180}
181
5728c6aa
MW
182/**
183 * Convert a GeneralName to an identification_t.
184 */
185static identification_t *general_name2id(GENERAL_NAME *name)
186{
187 if (!name)
188 {
189 return NULL;
190 }
191 switch (name->type)
192 {
193 case GEN_EMAIL:
194 return identification_create_from_encoding(ID_RFC822_ADDR,
195 openssl_asn1_str2chunk(name->d.rfc822Name));
196 case GEN_DNS:
197 return identification_create_from_encoding(ID_FQDN,
198 openssl_asn1_str2chunk(name->d.dNSName));
199 case GEN_URI:
200 return identification_create_from_encoding(ID_DER_ASN1_GN_URI,
201 openssl_asn1_str2chunk(name->d.uniformResourceIdentifier));
202 case GEN_IPADD:
07c5aacc
MW
203 {
204 chunk_t chunk = openssl_asn1_str2chunk(name->d.iPAddress);
205 if (chunk.len == 4)
206 {
207 return identification_create_from_encoding(ID_IPV4_ADDR, chunk);
208 }
209 if (chunk.len == 16)
210 {
211 return identification_create_from_encoding(ID_IPV6_ADDR, chunk);
212 }
213 return NULL;
214 }
5728c6aa
MW
215 case GEN_DIRNAME :
216 return openssl_x509_name2id(name->d.directoryName);
a0a8aaaf
MW
217 case GEN_OTHERNAME:
218 if (OBJ_obj2nid(name->d.otherName->type_id) == NID_ms_upn &&
219 name->d.otherName->value->type == V_ASN1_UTF8STRING)
220 {
221 return identification_create_from_encoding(ID_RFC822_ADDR,
222 openssl_asn1_str2chunk(
223 name->d.otherName->value->value.utf8string));
224 }
225 return NULL;
5728c6aa
MW
226 default:
227 return NULL;
228 }
229}
230
231METHOD(x509_t, get_flags, x509_flag_t,
232 private_openssl_x509_t *this)
233{
234 return this->flags;
235}
236
237METHOD(x509_t, get_serial, chunk_t,
238 private_openssl_x509_t *this)
239{
240 return openssl_asn1_str2chunk(X509_get_serialNumber(this->x509));
241}
242
243METHOD(x509_t, get_subjectKeyIdentifier, chunk_t,
244 private_openssl_x509_t *this)
245{
246 chunk_t fingerprint;
247
248 if (this->subjectKeyIdentifier.len)
249 {
250 return this->subjectKeyIdentifier;
251 }
da9724e6 252 if (this->pubkey->get_fingerprint(this->pubkey, KEYID_PUBKEY_SHA1,
5728c6aa
MW
253 &fingerprint))
254 {
255 return fingerprint;
256 }
257 return chunk_empty;
258}
259
260METHOD(x509_t, get_authKeyIdentifier, chunk_t,
261 private_openssl_x509_t *this)
262{
263 if (this->authKeyIdentifier.len)
264 {
265 return this->authKeyIdentifier;
266 }
267 return chunk_empty;
268}
269
d390b3b9 270METHOD(x509_t, get_constraint, u_int,
b3d359e5 271 private_openssl_x509_t *this, x509_constraint_t type)
a742d97f 272{
b3d359e5
MW
273 switch (type)
274 {
275 case X509_PATH_LEN:
276 return this->pathlen;
277 default:
278 return X509_NO_CONSTRAINT;
279 }
a742d97f
MW
280}
281
5728c6aa
MW
282METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
283 private_openssl_x509_t *this)
284{
285 return this->subjectAltNames->create_enumerator(this->subjectAltNames);
286}
287
288METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
289 private_openssl_x509_t *this)
290{
a6478a04 291 return this->crl_uris->create_enumerator(this->crl_uris);
5728c6aa
MW
292}
293
294METHOD(x509_t, create_ocsp_uri_enumerator, enumerator_t*,
295 private_openssl_x509_t *this)
296{
297 return this->ocsp_uris->create_enumerator(this->ocsp_uris);
298}
299
5e4b1ad2
MR
300METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
301 private_openssl_x509_t *this)
302{
303 return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
304}
305
5728c6aa
MW
306METHOD(certificate_t, get_type, certificate_type_t,
307 private_openssl_x509_t *this)
308{
309 return CERT_X509;
310}
311
312METHOD(certificate_t, get_subject, identification_t*,
313 private_openssl_x509_t *this)
314{
315 return this->subject;
316}
317
318METHOD(certificate_t, get_issuer, identification_t*,
319 private_openssl_x509_t *this)
320{
321 return this->issuer;
322}
323
324METHOD(certificate_t, has_subject, id_match_t,
325 private_openssl_x509_t *this, identification_t *subject)
326{
327 identification_t *current;
328 enumerator_t *enumerator;
329 id_match_t match, best;
663e7355 330 chunk_t encoding;
5728c6aa
MW
331
332 if (subject->get_type(subject) == ID_KEY_ID)
333 {
663e7355
MW
334 encoding = subject->get_encoding(subject);
335
336 if (chunk_equals(this->hash, encoding))
337 {
338 return ID_MATCH_PERFECT;
339 }
340 if (this->subjectKeyIdentifier.len &&
341 chunk_equals(this->subjectKeyIdentifier, encoding))
342 {
343 return ID_MATCH_PERFECT;
344 }
345 if (this->pubkey &&
346 this->pubkey->has_fingerprint(this->pubkey, encoding))
5728c6aa
MW
347 {
348 return ID_MATCH_PERFECT;
349 }
ed1c4303
MW
350 if (chunk_equals(get_serial(this), encoding))
351 {
352 return ID_MATCH_PERFECT;
353 }
5728c6aa
MW
354 }
355 best = this->subject->matches(this->subject, subject);
356 enumerator = create_subjectAltName_enumerator(this);
357 while (enumerator->enumerate(enumerator, &current))
358 {
359 match = current->matches(current, subject);
360 if (match > best)
361 {
362 best = match;
363 }
364 }
365 enumerator->destroy(enumerator);
366 return best;
367}
368
369METHOD(certificate_t, has_issuer, id_match_t,
370 private_openssl_x509_t *this, identification_t *issuer)
371{
372 /* issuerAltNames currently not supported */
373 return this->issuer->matches(this->issuer, issuer);
374}
375
376METHOD(certificate_t, issued_by, bool,
a37f2d20
MW
377 private_openssl_x509_t *this, certificate_t *issuer,
378 signature_scheme_t *scheme)
5728c6aa
MW
379{
380 public_key_t *key;
381 bool valid;
382 x509_t *x509 = (x509_t*)issuer;
383 chunk_t tbs;
384
385 if (&this->public.x509.interface == issuer)
386 {
387 if (this->flags & X509_SELF_SIGNED)
388 {
389 return TRUE;
390 }
391 }
392 else
393 {
394 if (issuer->get_type(issuer) != CERT_X509)
395 {
396 return FALSE;
397 }
398 if (!(x509->get_flags(x509) & X509_CA))
399 {
400 return FALSE;
401 }
402 if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
403 {
404 return FALSE;
405 }
406 }
407 if (this->scheme == SIGN_UNKNOWN)
408 {
409 return FALSE;
410 }
411 key = issuer->get_public_key(issuer);
412 if (!key)
413 {
414 return FALSE;
415 }
416 tbs = openssl_i2chunk(X509_CINF, this->x509->cert_info);
417 valid = key->verify(key, this->scheme, tbs,
418 openssl_asn1_str2chunk(this->x509->signature));
419 free(tbs.ptr);
420 key->destroy(key);
a37f2d20
MW
421 if (valid && scheme)
422 {
423 *scheme = this->scheme;
424 }
5728c6aa
MW
425 return valid;
426}
427
428METHOD(certificate_t, get_public_key, public_key_t*,
429 private_openssl_x509_t *this)
430{
431 return this->pubkey->get_ref(this->pubkey);
432}
433
434METHOD(certificate_t, get_validity, bool,
435 private_openssl_x509_t *this,
436 time_t *when, time_t *not_before, time_t *not_after)
437{
438 time_t t;
439
440 if (when)
441 {
442 t = *when;
443 }
444 else
445 {
446 t = time(NULL);
447 }
448 if (not_before)
449 {
450 *not_before = this->notBefore;
451 }
452 if (not_after)
453 {
454 *not_after = this->notAfter;
455 }
456 return (t >= this->notBefore && t <= this->notAfter);
457}
458
0406eeaa
MW
459METHOD(certificate_t, get_encoding, bool,
460 private_openssl_x509_t *this, cred_encoding_type_t type, chunk_t *encoding)
5728c6aa 461{
0406eeaa
MW
462 if (type == CERT_ASN1_DER)
463 {
464 *encoding = chunk_clone(this->encoding);
465 return TRUE;
466 }
467 return lib->encoding->encode(lib->encoding, type, NULL, encoding,
468 CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
5728c6aa
MW
469}
470
0406eeaa 471
5728c6aa
MW
472METHOD(certificate_t, equals, bool,
473 private_openssl_x509_t *this, certificate_t *other)
474{
475 chunk_t encoding;
476 bool equal;
477
478 if (this == (private_openssl_x509_t*)other)
479 {
480 return TRUE;
481 }
482 if (other->get_type(other) != CERT_X509)
483 {
484 return FALSE;
485 }
486 if (other->equals == (void*)equals)
487 { /* skip allocation if we have the same implementation */
488 encoding = ((private_openssl_x509_t*)other)->encoding;
489 return chunk_equals(this->encoding, encoding);
490 }
0406eeaa
MW
491 if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
492 {
493 return FALSE;
494 }
5728c6aa
MW
495 equal = chunk_equals(this->encoding, encoding);
496 free(encoding.ptr);
497 return equal;
498}
499
500METHOD(certificate_t, get_ref, certificate_t*,
501 private_openssl_x509_t *this)
502{
503 ref_get(&this->ref);
504 return &this->public.x509.interface;
505}
506
507METHOD(certificate_t, destroy, void,
508 private_openssl_x509_t *this)
509{
510 if (ref_put(&this->ref))
511 {
512 if (this->x509)
513 {
514 X509_free(this->x509);
515 }
516 DESTROY_IF(this->subject);
517 DESTROY_IF(this->issuer);
518 DESTROY_IF(this->pubkey);
519 free(this->subjectKeyIdentifier.ptr);
520 free(this->authKeyIdentifier.ptr);
521 free(this->encoding.ptr);
522 free(this->hash.ptr);
523 this->subjectAltNames->destroy_offset(this->subjectAltNames,
524 offsetof(identification_t, destroy));
525 this->issuerAltNames->destroy_offset(this->issuerAltNames,
526 offsetof(identification_t, destroy));
4e508517 527 this->crl_uris->destroy_function(this->crl_uris, (void*)crl_uri_destroy);
5728c6aa 528 this->ocsp_uris->destroy_function(this->ocsp_uris, free);
5e4b1ad2
MR
529 this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
530 offsetof(traffic_selector_t, destroy));
5728c6aa
MW
531 free(this);
532 }
533}
534
535/**
536 * Create an empty certificate
537 */
538static private_openssl_x509_t *create_empty()
539{
540 private_openssl_x509_t *this;
541
542 INIT(this,
543 .public = {
544 .x509 = {
545 .interface = {
546 .get_type = _get_type,
547 .get_subject = _get_subject,
548 .get_issuer = _get_issuer,
549 .has_subject = _has_subject,
550 .has_issuer = _has_issuer,
551 .issued_by = _issued_by,
552 .get_public_key = _get_public_key,
553 .get_validity = _get_validity,
5728c6aa
MW
554 .get_encoding = _get_encoding,
555 .equals = _equals,
556 .get_ref = _get_ref,
557 .destroy = _destroy,
558 },
559 .get_flags = _get_flags,
560 .get_serial = _get_serial,
561 .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
562 .get_authKeyIdentifier = _get_authKeyIdentifier,
b3d359e5 563 .get_constraint = _get_constraint,
5728c6aa
MW
564 .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
565 .create_crl_uri_enumerator = _create_crl_uri_enumerator,
566 .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
5e4b1ad2 567 .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
dbfbbec3 568 .create_name_constraint_enumerator = (void*)enumerator_create_empty,
20bd7810 569 .create_cert_policy_enumerator = (void*)enumerator_create_empty,
5a0caa4b 570 .create_policy_mapping_enumerator = (void*)enumerator_create_empty,
5728c6aa
MW
571 },
572 },
573 .subjectAltNames = linked_list_create(),
574 .issuerAltNames = linked_list_create(),
575 .crl_uris = linked_list_create(),
576 .ocsp_uris = linked_list_create(),
5e4b1ad2 577 .ipAddrBlocks = linked_list_create(),
5dba5852 578 .pathlen = X509_NO_CONSTRAINT,
5728c6aa
MW
579 .ref = 1,
580 );
581
582 return this;
583}
584
585/**
586 * parse an extionsion containing GENERAL_NAMES into a list
587 */
588static bool parse_generalNames_ext(linked_list_t *list,
589 X509_EXTENSION *ext)
590{
591 GENERAL_NAMES *names;
592 GENERAL_NAME *name;
593 identification_t *id;
594 int i, num;
595
596 names = X509V3_EXT_d2i(ext);
597 if (!names)
598 {
599 return FALSE;
600 }
601
602 num = sk_GENERAL_NAME_num(names);
603 for (i = 0; i < num; i++)
604 {
605 name = sk_GENERAL_NAME_value(names, i);
606 id = general_name2id(name);
607 if (id)
608 {
609 list->insert_last(list, id);
610 }
611 GENERAL_NAME_free(name);
612 }
613 sk_GENERAL_NAME_free(names);
614 return TRUE;
615}
616
617/**
618 * parse basic constraints
619 */
620static bool parse_basicConstraints_ext(private_openssl_x509_t *this,
621 X509_EXTENSION *ext)
622{
623 BASIC_CONSTRAINTS *constraints;
d390b3b9 624 long pathlen;
5728c6aa
MW
625
626 constraints = (BASIC_CONSTRAINTS*)X509V3_EXT_d2i(ext);
627 if (constraints)
628 {
629 if (constraints->ca)
630 {
631 this->flags |= X509_CA;
632 }
633 if (constraints->pathlen)
634 {
28bcbc29 635
d390b3b9
AS
636 pathlen = ASN1_INTEGER_get(constraints->pathlen);
637 this->pathlen = (pathlen >= 0 && pathlen < 128) ?
638 pathlen : X509_NO_CONSTRAINT;
5728c6aa
MW
639 }
640 BASIC_CONSTRAINTS_free(constraints);
641 return TRUE;
642 }
643 return FALSE;
644}
645
28bcbc29
TB
646/**
647 * parse key usage
648 */
649static bool parse_keyUsage_ext(private_openssl_x509_t *this,
650 X509_EXTENSION *ext)
651{
652 ASN1_BIT_STRING *usage;
653
654 usage = X509V3_EXT_d2i(ext);
655 if (usage)
656 {
657 if (usage->length > 0)
658 {
659 int flags = usage->data[0];
660 if (usage->length > 1)
661 {
662 flags |= usage->data[1] << 8;
663 }
664 switch (flags)
665 {
666 case X509v3_KU_CRL_SIGN:
667 this->flags |= X509_CRL_SIGN;
668 break;
669 case X509v3_KU_KEY_CERT_SIGN:
670 /* we use the caBasicContraint, MUST be set */
671 default:
672 break;
673 }
674 }
675 ASN1_BIT_STRING_free(usage);
676 return TRUE;
677 }
678 return FALSE;
679}
680
c3e7b3de
MW
681/**
682 * Parse ExtendedKeyUsage
683 */
684static bool parse_extKeyUsage_ext(private_openssl_x509_t *this,
685 X509_EXTENSION *ext)
686{
687 EXTENDED_KEY_USAGE *usage;
688 int i;
689
690 usage = X509V3_EXT_d2i(ext);
691 if (usage)
692 {
693 for (i = 0; i < sk_ASN1_OBJECT_num(usage); i++)
694 {
695 switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(usage, i)))
696 {
697 case NID_server_auth:
698 this->flags |= X509_SERVER_AUTH;
699 break;
700 case NID_client_auth:
701 this->flags |= X509_CLIENT_AUTH;
702 break;
703 case NID_OCSP_sign:
704 this->flags |= X509_OCSP_SIGNER;
705 break;
706 default:
707 break;
708 }
709 }
710 sk_ASN1_OBJECT_pop_free(usage, ASN1_OBJECT_free);
711 return TRUE;
712 }
713 return FALSE;
714}
715
5728c6aa
MW
716/**
717 * Parse CRL distribution points
718 */
719static bool parse_crlDistributionPoints_ext(private_openssl_x509_t *this,
720 X509_EXTENSION *ext)
721{
722 CRL_DIST_POINTS *cdps;
723 DIST_POINT *cdp;
a6478a04
MW
724 identification_t *id, *issuer;
725 x509_cdp_t *entry;
5728c6aa 726 char *uri;
a6478a04 727 int i, j, k, point_num, name_num, issuer_num;
5728c6aa
MW
728
729 cdps = X509V3_EXT_d2i(ext);
730 if (!cdps)
731 {
732 return FALSE;
733 }
734 point_num = sk_DIST_POINT_num(cdps);
735 for (i = 0; i < point_num; i++)
736 {
737 cdp = sk_DIST_POINT_value(cdps, i);
738 if (cdp)
739 {
740 if (cdp->distpoint && cdp->distpoint->type == 0 &&
741 cdp->distpoint->name.fullname)
742 {
743 name_num = sk_GENERAL_NAME_num(cdp->distpoint->name.fullname);
744 for (j = 0; j < name_num; j++)
745 {
746 id = general_name2id(sk_GENERAL_NAME_value(
747 cdp->distpoint->name.fullname, j));
748 if (id)
749 {
750 if (asprintf(&uri, "%Y", id) > 0)
751 {
a6478a04
MW
752 if (cdp->CRLissuer)
753 {
754 issuer_num = sk_GENERAL_NAME_num(cdp->CRLissuer);
755 for (k = 0; k < issuer_num; k++)
756 {
757 issuer = general_name2id(
758 sk_GENERAL_NAME_value(cdp->CRLissuer, k));
759 if (issuer)
760 {
761 INIT(entry,
762 .uri = strdup(uri),
763 .issuer = issuer,
764 );
765 this->crl_uris->insert_last(
766 this->crl_uris, entry);
767 }
768 }
769 free(uri);
770 }
771 else
772 {
773 INIT(entry,
774 .uri = uri,
775 );
776 this->crl_uris->insert_last(this->crl_uris, entry);
777 }
5728c6aa
MW
778 }
779 id->destroy(id);
780 }
781 }
782 }
a6478a04 783
5728c6aa
MW
784 DIST_POINT_free(cdp);
785 }
786 }
787 sk_DIST_POINT_free(cdps);
788 return TRUE;
789}
790
791/**
792 * Parse authorityInfoAccess with OCSP URIs
793 */
794static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
795 X509_EXTENSION *ext)
796{
797 AUTHORITY_INFO_ACCESS *infos;
798 ACCESS_DESCRIPTION *desc;
799 identification_t *id;
800 int i, num;
801 char *uri;
802
803 infos = X509V3_EXT_d2i(ext);
804 if (!infos)
805 {
806 return FALSE;
807 }
808 num = sk_ACCESS_DESCRIPTION_num(infos);
809 for (i = 0; i < num; i++)
810 {
811 desc = sk_ACCESS_DESCRIPTION_value(infos, i);
812 if (desc)
813 {
814 if (openssl_asn1_known_oid(desc->method) == OID_OCSP)
815 {
816 id = general_name2id(desc->location);
817 if (id)
818 {
819 if (asprintf(&uri, "%Y", id) > 0)
820 {
93818392 821 this->ocsp_uris->insert_last(this->ocsp_uris, uri);
5728c6aa
MW
822 }
823 id->destroy(id);
824 }
825 }
826 ACCESS_DESCRIPTION_free(desc);
827 }
828 }
829 sk_ACCESS_DESCRIPTION_free(infos);
830 return TRUE;
831}
832
5e4b1ad2
MR
833#ifndef OPENSSL_NO_RFC3779
834
835/**
836 * Parse a single block of ipAddrBlock extension
837 */
838static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t *this,
839 IPAddressFamily *fam)
840{
841 const IPAddressOrRanges *list;
842 IPAddressOrRange *aor;
843 traffic_selector_t *ts;
844 ts_type_t type;
845 chunk_t from, to;
846 int i, afi;
847
848 if (fam->ipAddressChoice->type != IPAddressChoice_addressesOrRanges)
849 {
850 return;
851 }
852
853 afi = v3_addr_get_afi(fam);
854 switch (afi)
855 {
856 case IANA_AFI_IPV4:
857 from = chunk_alloca(4);
858 to = chunk_alloca(4);
859 type = TS_IPV4_ADDR_RANGE;
860 break;
861 case IANA_AFI_IPV6:
862 from = chunk_alloca(16);
863 to = chunk_alloca(16);
864 type = TS_IPV6_ADDR_RANGE;
865 break;
866 default:
867 return;
868 }
869
870 list = fam->ipAddressChoice->u.addressesOrRanges;
871 for (i = 0; i < sk_IPAddressOrRange_num(list); i++)
872 {
873 aor = sk_IPAddressOrRange_value(list, i);
874 if (v3_addr_get_range(aor, afi, from.ptr, to.ptr, from.len) > 0)
875 {
876 ts = traffic_selector_create_from_bytes(0, type, from, 0, to, 65535);
877 if (ts)
878 {
879 this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
880 }
881 }
882 }
883}
884
885/**
886 * Parse ipAddrBlock extension
887 */
888static bool parse_ipAddrBlock_ext(private_openssl_x509_t *this,
889 X509_EXTENSION *ext)
890{
891 STACK_OF(IPAddressFamily) *blocks;
892 IPAddressFamily *fam;
893
894 blocks = (STACK_OF(IPAddressFamily)*)X509V3_EXT_d2i(ext);
895 if (!blocks)
896 {
897 return FALSE;
898 }
899
900 if (!v3_addr_is_canonical(blocks))
901 {
902 sk_IPAddressFamily_free(blocks);
903 return FALSE;
904 }
905
906 while (sk_IPAddressFamily_num(blocks) > 0)
907 {
908 fam = sk_IPAddressFamily_pop(blocks);
909 parse_ipAddrBlock_ext_fam(this, fam);
910 IPAddressFamily_free(fam);
911 }
912 sk_IPAddressFamily_free(blocks);
913
914 this->flags |= X509_IP_ADDR_BLOCKS;
915 return TRUE;
916}
917#endif /* !OPENSSL_NO_RFC3779 */
918
5728c6aa
MW
919/**
920 * Parse authorityKeyIdentifier extension
921 */
922static bool parse_authKeyIdentifier_ext(private_openssl_x509_t *this,
923 X509_EXTENSION *ext)
924{
925 AUTHORITY_KEYID *keyid;
926
927 keyid = (AUTHORITY_KEYID*)X509V3_EXT_d2i(ext);
928 if (keyid)
929 {
930 free(this->authKeyIdentifier.ptr);
931 this->authKeyIdentifier = chunk_clone(
932 openssl_asn1_str2chunk(keyid->keyid));
933 AUTHORITY_KEYID_free(keyid);
934 return TRUE;
935 }
936 return FALSE;
937}
938
939/**
940 * Parse subjectKeyIdentifier extension
941 */
942static bool parse_subjectKeyIdentifier_ext(private_openssl_x509_t *this,
943 X509_EXTENSION *ext)
944{
f00a1015
MW
945 chunk_t ostr;
946
947 ostr = openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext));
948 /* quick and dirty unwrap of octet string */
949 if (ostr.len > 2 &&
950 ostr.ptr[0] == V_ASN1_OCTET_STRING && ostr.ptr[1] == ostr.len - 2)
951 {
952 free(this->subjectKeyIdentifier.ptr);
953 this->subjectKeyIdentifier = chunk_clone(chunk_skip(ostr, 2));
954 return TRUE;
955 }
956 return FALSE;
5728c6aa
MW
957}
958
959/**
960 * Parse X509 extensions we are interested in
961 */
962static bool parse_extensions(private_openssl_x509_t *this)
963{
964 STACK_OF(X509_EXTENSION) *extensions;
965 int i, num;
966
967 extensions = this->x509->cert_info->extensions;
968 if (extensions)
969 {
970 num = sk_X509_EXTENSION_num(extensions);
971
972 for (i = 0; i < num; i++)
973 {
974 X509_EXTENSION *ext;
975 bool ok;
976
977 ext = sk_X509_EXTENSION_value(extensions, i);
978 switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext)))
979 {
980 case NID_info_access:
981 ok = parse_authorityInfoAccess_ext(this, ext);
982 break;
983 case NID_authority_key_identifier:
984 ok = parse_authKeyIdentifier_ext(this, ext);
985 break;
986 case NID_subject_key_identifier:
987 ok = parse_subjectKeyIdentifier_ext(this, ext);
988 break;
989 case NID_subject_alt_name:
990 ok = parse_generalNames_ext(this->subjectAltNames, ext);
991 break;
992 case NID_issuer_alt_name:
993 ok = parse_generalNames_ext(this->issuerAltNames, ext);
994 break;
995 case NID_basic_constraints:
996 ok = parse_basicConstraints_ext(this, ext);
997 break;
28bcbc29
TB
998 case NID_key_usage:
999 ok = parse_keyUsage_ext(this, ext);
1000 break;
c3e7b3de
MW
1001 case NID_ext_key_usage:
1002 ok = parse_extKeyUsage_ext(this, ext);
1003 break;
5728c6aa
MW
1004 case NID_crl_distribution_points:
1005 ok = parse_crlDistributionPoints_ext(this, ext);
1006 break;
5e4b1ad2
MR
1007#ifndef OPENSSL_NO_RFC3779
1008 case NID_sbgp_ipAddrBlock:
1009 ok = parse_ipAddrBlock_ext(this, ext);
1010 break;
1011#endif /* !OPENSSL_NO_RFC3779 */
5728c6aa 1012 default:
c4fd3b2f
AS
1013 ok = X509_EXTENSION_get_critical(ext) == 0 ||
1014 !lib->settings->get_bool(lib->settings,
1015 "libstrongswan.x509.enforce_critical", TRUE);
b0892d09
MW
1016 if (!ok)
1017 {
3f55f203
MW
1018 char buf[80] = "";
1019
1020 OBJ_obj2txt(buf, sizeof(buf),
1021 X509_EXTENSION_get_object(ext), 0);
1022 DBG1(DBG_LIB, "found unsupported critical X.509 "
1023 "extension: %s", buf);
b0892d09 1024 }
5728c6aa
MW
1025 break;
1026 }
1027 if (!ok)
1028 {
1029 return FALSE;
1030 }
1031 }
1032 }
1033 return TRUE;
1034}
1035
1036/**
1037 * Parse a DER encoded x509 certificate
1038 */
1039static bool parse_certificate(private_openssl_x509_t *this)
1040{
1041 const unsigned char *ptr = this->encoding.ptr;
1042 hasher_t *hasher;
1043 chunk_t chunk;
1044
1045 this->x509 = d2i_X509(NULL, &ptr, this->encoding.len);
1046 if (!this->x509)
1047 {
1048 return FALSE;
1049 }
a6850b84
MW
1050 if (X509_get_version(this->x509) < 0 || X509_get_version(this->x509) > 2)
1051 {
1052 DBG1(DBG_LIB, "unsupported x509 version: %d",
1053 X509_get_version(this->x509) + 1);
1054 return FALSE;
1055 }
1056
5728c6aa
MW
1057 this->subject = openssl_x509_name2id(X509_get_subject_name(this->x509));
1058 this->issuer = openssl_x509_name2id(X509_get_issuer_name(this->x509));
1059
1060 switch (openssl_asn1_known_oid(this->x509->cert_info->key->algor->algorithm))
1061 {
1062 case OID_RSA_ENCRYPTION:
1063 this->pubkey = lib->creds->create(lib->creds,
1064 CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_ASN1_DER,
1065 openssl_asn1_str2chunk(X509_get0_pubkey_bitstr(this->x509)),
1066 BUILD_END);
1067 break;
1068 case OID_EC_PUBLICKEY:
1069 /* for ECDSA, we need the full subjectPublicKeyInfo, as it contains
1070 * the curve parameters. */
1071 chunk = openssl_i2chunk(X509_PUBKEY, X509_get_X509_PUBKEY(this->x509));
1072 this->pubkey = lib->creds->create(lib->creds,
1073 CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER,
1074 chunk, BUILD_END);
1075 free(chunk.ptr);
1076 break;
1077 default:
1078 DBG1(DBG_LIB, "unsupported public key algorithm");
1079 break;
1080 }
1081 if (!this->subject || !this->issuer || !this->pubkey)
1082 {
1083 return FALSE;
1084 }
1085
1086 this->notBefore = openssl_asn1_to_time(X509_get_notBefore(this->x509));
1087 this->notAfter = openssl_asn1_to_time(X509_get_notAfter(this->x509));
1088
1089 if (!chunk_equals(
1090 openssl_asn1_obj2chunk(this->x509->cert_info->signature->algorithm),
1091 openssl_asn1_obj2chunk(this->x509->sig_alg->algorithm)))
1092 {
1093 return FALSE;
1094 }
1095 this->scheme = signature_scheme_from_oid(openssl_asn1_known_oid(
1096 this->x509->sig_alg->algorithm));
1097
1098 if (!parse_extensions(this))
1099 {
c4fd3b2f 1100 return FALSE;
5728c6aa
MW
1101 }
1102
1103 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
87dd205b 1104 if (!hasher || !hasher->allocate_hash(hasher, this->encoding, &this->hash))
5728c6aa 1105 {
87dd205b 1106 DESTROY_IF(hasher);
5728c6aa
MW
1107 return FALSE;
1108 }
5728c6aa
MW
1109 hasher->destroy(hasher);
1110
a37f2d20 1111 if (issued_by(this, &this->public.x509.interface, NULL))
5728c6aa
MW
1112 {
1113 this->flags |= X509_SELF_SIGNED;
1114 }
1115 return TRUE;
1116}
1117
1118openssl_x509_t *openssl_x509_load(certificate_type_t type, va_list args)
1119{
1120 chunk_t blob = chunk_empty;
1121 x509_flag_t flags = 0;
1122
1123 while (TRUE)
1124 {
1125 switch (va_arg(args, builder_part_t))
1126 {
1127 case BUILD_BLOB_ASN1_DER:
1128 blob = va_arg(args, chunk_t);
1129 continue;
1130 case BUILD_X509_FLAG:
1131 flags |= va_arg(args, x509_flag_t);
1132 continue;
1133 case BUILD_END:
1134 break;
1135 default:
1136 return NULL;
1137 }
1138 break;
1139 }
1140
1141 if (blob.ptr)
1142 {
1143 private_openssl_x509_t *this;
1144
1145 this = create_empty();
1146 this->encoding = chunk_clone(blob);
1147 this->flags |= flags;
1148 if (parse_certificate(this))
1149 {
1150 return &this->public;
1151 }
1152 DBG1(DBG_LIB, "OpenSSL X.509 parsing failed");
1153 destroy(this);
1154 }
1155 return NULL;
1156}