]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libstrongswan/plugins/openssl/openssl_x509.c
fe21b0221debce47558c72d2bc31e3372b072967
[thirdparty/strongswan.git] / src / libstrongswan / plugins / openssl / openssl_x509.c
1 /*
2 * Copyright (C) 2011-2017 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
4 *
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 /*
20 * Copyright (C) 2013 Michael Rossberg
21 * Copyright (C) 2013 Technische Universität Ilmenau
22 *
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
53 #include <utils/debug.h>
54 #include <asn1/oid.h>
55 #include <collections/linked_list.h>
56 #include <selectors/traffic_selector.h>
57
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
62
63 /* added with 1.0.2 */
64 #if OPENSSL_VERSION_NUMBER < 0x10002000L
65 static 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
82 typedef struct private_openssl_x509_t private_openssl_x509_t;
83
84 /**
85 * Private data of an openssl_x509_t object.
86 */
87 struct 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 */
117 u_char pathlen;
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 */
157 signature_params_t *scheme;
158
159 /**
160 * subjectAltNames
161 */
162 linked_list_t *subjectAltNames;
163
164 /**
165 * issuerAltNames
166 */
167 linked_list_t *issuerAltNames;
168
169 /**
170 * List of CRL URIs, as x509_cdp_t
171 */
172 linked_list_t *crl_uris;
173
174 /**
175 * List of OCSP URIs
176 */
177 linked_list_t *ocsp_uris;
178
179 /**
180 * List of ipAddrBlocks as traffic_selector_t
181 */
182 linked_list_t *ipAddrBlocks;
183
184
185 /**
186 * References to this cert
187 */
188 refcount_t ref;
189 };
190
191 /**
192 * Convert a GeneralName to an identification_t.
193 */
194 static 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:
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 }
224 case GEN_DIRNAME :
225 return openssl_x509_name2id(name->d.directoryName);
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;
235 default:
236 return NULL;
237 }
238 }
239
240 METHOD(x509_t, get_flags, x509_flag_t,
241 private_openssl_x509_t *this)
242 {
243 return this->flags;
244 }
245
246 METHOD(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
252 METHOD(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 }
261 if (this->pubkey->get_fingerprint(this->pubkey, KEYID_PUBKEY_SHA1,
262 &fingerprint))
263 {
264 return fingerprint;
265 }
266 return chunk_empty;
267 }
268
269 METHOD(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
279 METHOD(x509_t, get_constraint, u_int,
280 private_openssl_x509_t *this, x509_constraint_t type)
281 {
282 switch (type)
283 {
284 case X509_PATH_LEN:
285 return this->pathlen;
286 default:
287 return X509_NO_CONSTRAINT;
288 }
289 }
290
291 METHOD(x509_t, create_subjectAltName_enumerator, enumerator_t*,
292 private_openssl_x509_t *this)
293 {
294 return this->subjectAltNames->create_enumerator(this->subjectAltNames);
295 }
296
297 METHOD(x509_t, create_crl_uri_enumerator, enumerator_t*,
298 private_openssl_x509_t *this)
299 {
300 return this->crl_uris->create_enumerator(this->crl_uris);
301 }
302
303 METHOD(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
309 METHOD(x509_t, create_ipAddrBlock_enumerator, enumerator_t*,
310 private_openssl_x509_t *this)
311 {
312 return this->ipAddrBlocks->create_enumerator(this->ipAddrBlocks);
313 }
314
315 METHOD(certificate_t, get_type, certificate_type_t,
316 private_openssl_x509_t *this)
317 {
318 return CERT_X509;
319 }
320
321 METHOD(certificate_t, get_subject, identification_t*,
322 private_openssl_x509_t *this)
323 {
324 return this->subject;
325 }
326
327 METHOD(certificate_t, get_issuer, identification_t*,
328 private_openssl_x509_t *this)
329 {
330 return this->issuer;
331 }
332
333 METHOD(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;
339 chunk_t encoding;
340
341 if (subject->get_type(subject) == ID_KEY_ID)
342 {
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))
356 {
357 return ID_MATCH_PERFECT;
358 }
359 if (chunk_equals(get_serial(this), encoding))
360 {
361 return ID_MATCH_PERFECT;
362 }
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
378 METHOD(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
385 METHOD(certificate_t, issued_by, bool,
386 private_openssl_x509_t *this, certificate_t *issuer,
387 signature_params_t **scheme)
388 {
389 public_key_t *key;
390 bool valid;
391 x509_t *x509 = (x509_t*)issuer;
392 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
393 const ASN1_BIT_STRING *sig;
394 #else
395 ASN1_BIT_STRING *sig;
396 #endif
397 chunk_t tbs;
398
399 if (&this->public.x509.interface == issuer)
400 {
401 if (this->flags & X509_SELF_SIGNED)
402 {
403 valid = TRUE;
404 goto out;
405 }
406 }
407 else
408 {
409 if (issuer->get_type(issuer) != CERT_X509)
410 {
411 return FALSE;
412 }
413 if (!(x509->get_flags(x509) & X509_CA))
414 {
415 return FALSE;
416 }
417 if (!this->issuer->equals(this->issuer, issuer->get_subject(issuer)))
418 {
419 return FALSE;
420 }
421 }
422 key = issuer->get_public_key(issuer);
423 if (!key)
424 {
425 return FALSE;
426 }
427 /* i2d_re_X509_tbs() was added with 1.1.0 when X509 was made opaque */
428 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
429 tbs = openssl_i2chunk(re_X509_tbs, this->x509);
430 #else
431 tbs = openssl_i2chunk(X509_CINF, this->x509->cert_info);
432 #endif
433 X509_get0_signature(&sig, NULL, this->x509);
434 valid = key->verify(key, this->scheme->scheme, this->scheme->params, tbs,
435 openssl_asn1_str2chunk(sig));
436 free(tbs.ptr);
437 key->destroy(key);
438
439 out:
440 if (valid && scheme)
441 {
442 *scheme = signature_params_clone(this->scheme);
443 }
444 return valid;
445 }
446
447 METHOD(certificate_t, get_public_key, public_key_t*,
448 private_openssl_x509_t *this)
449 {
450 return this->pubkey->get_ref(this->pubkey);
451 }
452
453 METHOD(certificate_t, get_validity, bool,
454 private_openssl_x509_t *this,
455 time_t *when, time_t *not_before, time_t *not_after)
456 {
457 time_t t;
458
459 if (when)
460 {
461 t = *when;
462 }
463 else
464 {
465 t = time(NULL);
466 }
467 if (not_before)
468 {
469 *not_before = this->notBefore;
470 }
471 if (not_after)
472 {
473 *not_after = this->notAfter;
474 }
475 return (t >= this->notBefore && t <= this->notAfter);
476 }
477
478 METHOD(certificate_t, get_encoding, bool,
479 private_openssl_x509_t *this, cred_encoding_type_t type, chunk_t *encoding)
480 {
481 if (type == CERT_ASN1_DER)
482 {
483 *encoding = chunk_clone(this->encoding);
484 return TRUE;
485 }
486 return lib->encoding->encode(lib->encoding, type, NULL, encoding,
487 CRED_PART_X509_ASN1_DER, this->encoding, CRED_PART_END);
488 }
489
490
491 METHOD(certificate_t, equals, bool,
492 private_openssl_x509_t *this, certificate_t *other)
493 {
494 chunk_t encoding;
495 bool equal;
496
497 if (this == (private_openssl_x509_t*)other)
498 {
499 return TRUE;
500 }
501 if (other->get_type(other) != CERT_X509)
502 {
503 return FALSE;
504 }
505 if (other->equals == (void*)equals)
506 { /* skip allocation if we have the same implementation */
507 encoding = ((private_openssl_x509_t*)other)->encoding;
508 return chunk_equals(this->encoding, encoding);
509 }
510 if (!other->get_encoding(other, CERT_ASN1_DER, &encoding))
511 {
512 return FALSE;
513 }
514 equal = chunk_equals(this->encoding, encoding);
515 free(encoding.ptr);
516 return equal;
517 }
518
519 METHOD(certificate_t, get_ref, certificate_t*,
520 private_openssl_x509_t *this)
521 {
522 ref_get(&this->ref);
523 return &this->public.x509.interface;
524 }
525
526 METHOD(certificate_t, destroy, void,
527 private_openssl_x509_t *this)
528 {
529 if (ref_put(&this->ref))
530 {
531 if (this->x509)
532 {
533 X509_free(this->x509);
534 }
535 signature_params_destroy(this->scheme);
536 DESTROY_IF(this->subject);
537 DESTROY_IF(this->issuer);
538 DESTROY_IF(this->pubkey);
539 free(this->subjectKeyIdentifier.ptr);
540 free(this->authKeyIdentifier.ptr);
541 free(this->encoding.ptr);
542 free(this->hash.ptr);
543 this->subjectAltNames->destroy_offset(this->subjectAltNames,
544 offsetof(identification_t, destroy));
545 this->issuerAltNames->destroy_offset(this->issuerAltNames,
546 offsetof(identification_t, destroy));
547 this->crl_uris->destroy_function(this->crl_uris,
548 (void*)x509_cdp_destroy);
549 this->ocsp_uris->destroy_function(this->ocsp_uris, free);
550 this->ipAddrBlocks->destroy_offset(this->ipAddrBlocks,
551 offsetof(traffic_selector_t, destroy));
552 free(this);
553 }
554 }
555
556 /**
557 * Create an empty certificate
558 */
559 static private_openssl_x509_t *create_empty()
560 {
561 private_openssl_x509_t *this;
562
563 INIT(this,
564 .public = {
565 .x509 = {
566 .interface = {
567 .get_type = _get_type,
568 .get_subject = _get_subject,
569 .get_issuer = _get_issuer,
570 .has_subject = _has_subject,
571 .has_issuer = _has_issuer,
572 .issued_by = _issued_by,
573 .get_public_key = _get_public_key,
574 .get_validity = _get_validity,
575 .get_encoding = _get_encoding,
576 .equals = _equals,
577 .get_ref = _get_ref,
578 .destroy = _destroy,
579 },
580 .get_flags = _get_flags,
581 .get_serial = _get_serial,
582 .get_subjectKeyIdentifier = _get_subjectKeyIdentifier,
583 .get_authKeyIdentifier = _get_authKeyIdentifier,
584 .get_constraint = _get_constraint,
585 .create_subjectAltName_enumerator = _create_subjectAltName_enumerator,
586 .create_crl_uri_enumerator = _create_crl_uri_enumerator,
587 .create_ocsp_uri_enumerator = _create_ocsp_uri_enumerator,
588 .create_ipAddrBlock_enumerator = _create_ipAddrBlock_enumerator,
589 .create_name_constraint_enumerator = (void*)enumerator_create_empty,
590 .create_cert_policy_enumerator = (void*)enumerator_create_empty,
591 .create_policy_mapping_enumerator = (void*)enumerator_create_empty,
592 },
593 },
594 .subjectAltNames = linked_list_create(),
595 .issuerAltNames = linked_list_create(),
596 .crl_uris = linked_list_create(),
597 .ocsp_uris = linked_list_create(),
598 .ipAddrBlocks = linked_list_create(),
599 .pathlen = X509_NO_CONSTRAINT,
600 .ref = 1,
601 );
602
603 return this;
604 }
605
606 /**
607 * parse an extionsion containing GENERAL_NAMES into a list
608 */
609 static bool parse_generalNames_ext(linked_list_t *list,
610 X509_EXTENSION *ext)
611 {
612 GENERAL_NAMES *names;
613 GENERAL_NAME *name;
614 identification_t *id;
615 int i, num;
616
617 names = X509V3_EXT_d2i(ext);
618 if (!names)
619 {
620 return FALSE;
621 }
622
623 num = sk_GENERAL_NAME_num(names);
624 for (i = 0; i < num; i++)
625 {
626 name = sk_GENERAL_NAME_value(names, i);
627 id = general_name2id(name);
628 if (id)
629 {
630 list->insert_last(list, id);
631 }
632 GENERAL_NAME_free(name);
633 }
634 sk_GENERAL_NAME_free(names);
635 return TRUE;
636 }
637
638 /**
639 * parse basic constraints
640 */
641 static bool parse_basicConstraints_ext(private_openssl_x509_t *this,
642 X509_EXTENSION *ext)
643 {
644 BASIC_CONSTRAINTS *constraints;
645 long pathlen;
646
647 constraints = (BASIC_CONSTRAINTS*)X509V3_EXT_d2i(ext);
648 if (constraints)
649 {
650 if (constraints->ca)
651 {
652 this->flags |= X509_CA;
653 }
654 if (constraints->pathlen)
655 {
656
657 pathlen = ASN1_INTEGER_get(constraints->pathlen);
658 this->pathlen = (pathlen >= 0 && pathlen < 128) ?
659 pathlen : X509_NO_CONSTRAINT;
660 }
661 BASIC_CONSTRAINTS_free(constraints);
662 return TRUE;
663 }
664 return FALSE;
665 }
666
667 /**
668 * parse key usage
669 */
670 static bool parse_keyUsage_ext(private_openssl_x509_t *this,
671 X509_EXTENSION *ext)
672 {
673 ASN1_BIT_STRING *usage;
674
675 /* to be compliant with RFC 4945 specific KUs have to be included */
676 this->flags &= ~X509_IKE_COMPLIANT;
677
678 usage = X509V3_EXT_d2i(ext);
679 if (usage)
680 {
681 if (usage->length > 0)
682 {
683 int flags = usage->data[0];
684 if (usage->length > 1)
685 {
686 flags |= usage->data[1] << 8;
687 }
688 if (flags & X509v3_KU_CRL_SIGN)
689 {
690 this->flags |= X509_CRL_SIGN;
691 }
692 if (flags & X509v3_KU_DIGITAL_SIGNATURE ||
693 flags & X509v3_KU_NON_REPUDIATION)
694 {
695 this->flags |= X509_IKE_COMPLIANT;
696 }
697 if (flags & X509v3_KU_KEY_CERT_SIGN)
698 {
699 /* we use the caBasicContraint, MUST be set */
700 }
701 }
702 ASN1_BIT_STRING_free(usage);
703 return TRUE;
704 }
705 return FALSE;
706 }
707
708 /**
709 * Parse ExtendedKeyUsage
710 */
711 static bool parse_extKeyUsage_ext(private_openssl_x509_t *this,
712 X509_EXTENSION *ext)
713 {
714 EXTENDED_KEY_USAGE *usage;
715 int i;
716
717 usage = X509V3_EXT_d2i(ext);
718 if (usage)
719 {
720 for (i = 0; i < sk_ASN1_OBJECT_num(usage); i++)
721 {
722 switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(usage, i)))
723 {
724 case NID_server_auth:
725 this->flags |= X509_SERVER_AUTH;
726 break;
727 case NID_client_auth:
728 this->flags |= X509_CLIENT_AUTH;
729 break;
730 case NID_OCSP_sign:
731 this->flags |= X509_OCSP_SIGNER;
732 break;
733 default:
734 break;
735 }
736 }
737 sk_ASN1_OBJECT_pop_free(usage, ASN1_OBJECT_free);
738 return TRUE;
739 }
740 return FALSE;
741 }
742
743 /**
744 * Parse CRL distribution points
745 */
746 bool openssl_parse_crlDistributionPoints(X509_EXTENSION *ext,
747 linked_list_t *list)
748 {
749 CRL_DIST_POINTS *cdps;
750 DIST_POINT *cdp;
751 identification_t *id, *issuer;
752 x509_cdp_t *entry;
753 char *uri;
754 int i, j, k, point_num, name_num, issuer_num, len;
755
756 cdps = X509V3_EXT_d2i(ext);
757 if (!cdps)
758 {
759 return FALSE;
760 }
761 point_num = sk_DIST_POINT_num(cdps);
762 for (i = 0; i < point_num; i++)
763 {
764 cdp = sk_DIST_POINT_value(cdps, i);
765 if (cdp)
766 {
767 if (cdp->distpoint && cdp->distpoint->type == 0 &&
768 cdp->distpoint->name.fullname)
769 {
770 name_num = sk_GENERAL_NAME_num(cdp->distpoint->name.fullname);
771 for (j = 0; j < name_num; j++)
772 {
773 id = general_name2id(sk_GENERAL_NAME_value(
774 cdp->distpoint->name.fullname, j));
775 if (id)
776 {
777 len = asprintf(&uri, "%Y", id);
778 if (!len)
779 {
780 free(uri);
781 }
782 else if (len > 0)
783 {
784 if (cdp->CRLissuer)
785 {
786 issuer_num = sk_GENERAL_NAME_num(cdp->CRLissuer);
787 for (k = 0; k < issuer_num; k++)
788 {
789 issuer = general_name2id(
790 sk_GENERAL_NAME_value(cdp->CRLissuer, k));
791 if (issuer)
792 {
793 INIT(entry,
794 .uri = strdup(uri),
795 .issuer = issuer,
796 );
797 list->insert_last(list, entry);
798 }
799 }
800 free(uri);
801 }
802 else
803 {
804 INIT(entry,
805 .uri = uri,
806 );
807 list->insert_last(list, entry);
808 }
809 }
810 id->destroy(id);
811 }
812 }
813 }
814
815 DIST_POINT_free(cdp);
816 }
817 }
818 sk_DIST_POINT_free(cdps);
819 return TRUE;
820 }
821
822 /**
823 * Parse authorityInfoAccess with OCSP URIs
824 */
825 static bool parse_authorityInfoAccess_ext(private_openssl_x509_t *this,
826 X509_EXTENSION *ext)
827 {
828 AUTHORITY_INFO_ACCESS *infos;
829 ACCESS_DESCRIPTION *desc;
830 identification_t *id;
831 int i, num, len;
832 char *uri;
833
834 infos = X509V3_EXT_d2i(ext);
835 if (!infos)
836 {
837 return FALSE;
838 }
839 num = sk_ACCESS_DESCRIPTION_num(infos);
840 for (i = 0; i < num; i++)
841 {
842 desc = sk_ACCESS_DESCRIPTION_value(infos, i);
843 if (desc)
844 {
845 if (openssl_asn1_known_oid(desc->method) == OID_OCSP)
846 {
847 id = general_name2id(desc->location);
848 if (id)
849 {
850 len = asprintf(&uri, "%Y", id);
851 if (!len)
852 {
853 free(uri);
854 }
855 else if (len > 0)
856 {
857 this->ocsp_uris->insert_last(this->ocsp_uris, uri);
858 }
859 id->destroy(id);
860 }
861 }
862 ACCESS_DESCRIPTION_free(desc);
863 }
864 }
865 sk_ACCESS_DESCRIPTION_free(infos);
866 return TRUE;
867 }
868
869 #ifndef OPENSSL_NO_RFC3779
870
871 /**
872 * Parse a single block of ipAddrBlock extension
873 */
874 static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t *this,
875 IPAddressFamily *fam)
876 {
877 const IPAddressOrRanges *list;
878 IPAddressOrRange *aor;
879 traffic_selector_t *ts;
880 ts_type_t type;
881 chunk_t from, to;
882 int i, afi;
883
884 if (fam->ipAddressChoice->type != IPAddressChoice_addressesOrRanges)
885 {
886 return;
887 }
888
889 afi = X509v3_addr_get_afi(fam);
890 switch (afi)
891 {
892 case IANA_AFI_IPV4:
893 from = chunk_alloca(4);
894 to = chunk_alloca(4);
895 type = TS_IPV4_ADDR_RANGE;
896 break;
897 case IANA_AFI_IPV6:
898 from = chunk_alloca(16);
899 to = chunk_alloca(16);
900 type = TS_IPV6_ADDR_RANGE;
901 break;
902 default:
903 return;
904 }
905
906 list = fam->ipAddressChoice->u.addressesOrRanges;
907 for (i = 0; i < sk_IPAddressOrRange_num(list); i++)
908 {
909 aor = sk_IPAddressOrRange_value(list, i);
910 if (X509v3_addr_get_range(aor, afi, from.ptr, to.ptr, from.len) > 0)
911 {
912 ts = traffic_selector_create_from_bytes(0, type, from, 0, to, 65535);
913 if (ts)
914 {
915 this->ipAddrBlocks->insert_last(this->ipAddrBlocks, ts);
916 }
917 }
918 }
919 }
920
921 /**
922 * Parse ipAddrBlock extension
923 */
924 static bool parse_ipAddrBlock_ext(private_openssl_x509_t *this,
925 X509_EXTENSION *ext)
926 {
927 STACK_OF(IPAddressFamily) *blocks;
928 IPAddressFamily *fam;
929
930 blocks = (STACK_OF(IPAddressFamily)*)X509V3_EXT_d2i(ext);
931 if (!blocks)
932 {
933 return FALSE;
934 }
935
936 if (!X509v3_addr_is_canonical(blocks))
937 {
938 sk_IPAddressFamily_free(blocks);
939 return FALSE;
940 }
941
942 while (sk_IPAddressFamily_num(blocks) > 0)
943 {
944 fam = sk_IPAddressFamily_pop(blocks);
945 parse_ipAddrBlock_ext_fam(this, fam);
946 IPAddressFamily_free(fam);
947 }
948 sk_IPAddressFamily_free(blocks);
949
950 this->flags |= X509_IP_ADDR_BLOCKS;
951 return TRUE;
952 }
953 #endif /* !OPENSSL_NO_RFC3779 */
954
955 /**
956 * Parse authorityKeyIdentifier extension
957 */
958 static bool parse_authKeyIdentifier_ext(private_openssl_x509_t *this,
959 X509_EXTENSION *ext)
960 {
961 AUTHORITY_KEYID *keyid;
962
963 keyid = (AUTHORITY_KEYID*)X509V3_EXT_d2i(ext);
964 if (keyid)
965 {
966 free(this->authKeyIdentifier.ptr);
967 this->authKeyIdentifier = chunk_clone(
968 openssl_asn1_str2chunk(keyid->keyid));
969 AUTHORITY_KEYID_free(keyid);
970 return TRUE;
971 }
972 return FALSE;
973 }
974
975 /**
976 * Parse subjectKeyIdentifier extension
977 */
978 static bool parse_subjectKeyIdentifier_ext(private_openssl_x509_t *this,
979 X509_EXTENSION *ext)
980 {
981 chunk_t ostr;
982
983 ostr = openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext));
984 /* quick and dirty unwrap of octet string */
985 if (ostr.len > 2 &&
986 ostr.ptr[0] == V_ASN1_OCTET_STRING && ostr.ptr[1] == ostr.len - 2)
987 {
988 free(this->subjectKeyIdentifier.ptr);
989 this->subjectKeyIdentifier = chunk_clone(chunk_skip(ostr, 2));
990 return TRUE;
991 }
992 return FALSE;
993 }
994
995 /**
996 * Parse X509 extensions we are interested in
997 */
998 static bool parse_extensions(private_openssl_x509_t *this)
999 {
1000 const STACK_OF(X509_EXTENSION) *extensions;
1001 int i, num;
1002
1003 /* unless we see a keyUsage extension we are compliant with RFC 4945 */
1004 this->flags |= X509_IKE_COMPLIANT;
1005
1006 extensions = X509_get0_extensions(this->x509);
1007 if (extensions)
1008 {
1009 num = sk_X509_EXTENSION_num(extensions);
1010
1011 for (i = 0; i < num; i++)
1012 {
1013 X509_EXTENSION *ext;
1014 bool ok;
1015
1016 ext = sk_X509_EXTENSION_value(extensions, i);
1017 switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext)))
1018 {
1019 case NID_info_access:
1020 ok = parse_authorityInfoAccess_ext(this, ext);
1021 break;
1022 case NID_authority_key_identifier:
1023 ok = parse_authKeyIdentifier_ext(this, ext);
1024 break;
1025 case NID_subject_key_identifier:
1026 ok = parse_subjectKeyIdentifier_ext(this, ext);
1027 break;
1028 case NID_subject_alt_name:
1029 ok = parse_generalNames_ext(this->subjectAltNames, ext);
1030 break;
1031 case NID_issuer_alt_name:
1032 ok = parse_generalNames_ext(this->issuerAltNames, ext);
1033 break;
1034 case NID_basic_constraints:
1035 ok = parse_basicConstraints_ext(this, ext);
1036 break;
1037 case NID_key_usage:
1038 ok = parse_keyUsage_ext(this, ext);
1039 break;
1040 case NID_ext_key_usage:
1041 ok = parse_extKeyUsage_ext(this, ext);
1042 break;
1043 case NID_crl_distribution_points:
1044 ok = openssl_parse_crlDistributionPoints(ext, this->crl_uris);
1045 break;
1046 #ifndef OPENSSL_NO_RFC3779
1047 case NID_sbgp_ipAddrBlock:
1048 ok = parse_ipAddrBlock_ext(this, ext);
1049 break;
1050 #endif /* !OPENSSL_NO_RFC3779 */
1051 default:
1052 ok = X509_EXTENSION_get_critical(ext) == 0 ||
1053 !lib->settings->get_bool(lib->settings,
1054 "%s.x509.enforce_critical", TRUE, lib->ns);
1055 if (!ok)
1056 {
1057 char buf[80] = "";
1058
1059 OBJ_obj2txt(buf, sizeof(buf),
1060 X509_EXTENSION_get_object(ext), 0);
1061 DBG1(DBG_LIB, "found unsupported critical X.509 "
1062 "extension: %s", buf);
1063 }
1064 break;
1065 }
1066 if (!ok)
1067 {
1068 return FALSE;
1069 }
1070 }
1071 }
1072 return TRUE;
1073 }
1074
1075 /**
1076 * Parse a DER encoded x509 certificate
1077 */
1078 static bool parse_certificate(private_openssl_x509_t *this)
1079 {
1080 const unsigned char *ptr = this->encoding.ptr;
1081 hasher_t *hasher;
1082 chunk_t chunk, sig_scheme, sig_scheme_tbs;
1083 ASN1_OBJECT *oid;
1084 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1085 const X509_ALGOR *alg;
1086 #else
1087 X509_ALGOR *alg;
1088 #endif
1089
1090 this->x509 = d2i_X509(NULL, &ptr, this->encoding.len);
1091 if (!this->x509)
1092 {
1093 return FALSE;
1094 }
1095 if (X509_get_version(this->x509) < 0 || X509_get_version(this->x509) > 2)
1096 {
1097 DBG1(DBG_LIB, "unsupported x509 version: %d",
1098 X509_get_version(this->x509) + 1);
1099 return FALSE;
1100 }
1101
1102 this->subject = openssl_x509_name2id(X509_get_subject_name(this->x509));
1103 this->issuer = openssl_x509_name2id(X509_get_issuer_name(this->x509));
1104
1105 if (!X509_PUBKEY_get0_param(&oid, NULL, NULL, NULL,
1106 X509_get_X509_PUBKEY(this->x509)))
1107 {
1108 return FALSE;
1109 }
1110 switch (openssl_asn1_known_oid(oid))
1111 {
1112 case OID_RSASSA_PSS:
1113 /* TODO: we should treat such keys special and use the params as
1114 * restrictions regarding the use of this key (or rather the
1115 * associated private key) */
1116 case OID_RSA_ENCRYPTION:
1117 this->pubkey = lib->creds->create(lib->creds,
1118 CRED_PUBLIC_KEY, KEY_RSA, BUILD_BLOB_ASN1_DER,
1119 openssl_asn1_str2chunk(X509_get0_pubkey_bitstr(this->x509)),
1120 BUILD_END);
1121 break;
1122 case OID_EC_PUBLICKEY:
1123 /* for ECDSA, we need the full subjectPublicKeyInfo, as it contains
1124 * the curve parameters. */
1125 chunk = openssl_i2chunk(X509_PUBKEY, X509_get_X509_PUBKEY(this->x509));
1126 this->pubkey = lib->creds->create(lib->creds,
1127 CRED_PUBLIC_KEY, KEY_ECDSA, BUILD_BLOB_ASN1_DER,
1128 chunk, BUILD_END);
1129 free(chunk.ptr);
1130 break;
1131 default:
1132 DBG1(DBG_LIB, "unsupported public key algorithm");
1133 break;
1134 }
1135 if (!this->subject || !this->issuer || !this->pubkey)
1136 {
1137 return FALSE;
1138 }
1139
1140 this->notBefore = openssl_asn1_to_time(X509_get_notBefore(this->x509));
1141 this->notAfter = openssl_asn1_to_time(X509_get_notAfter(this->x509));
1142
1143 /* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL
1144 * versions, at least on Ubuntu 14.04 it is not actually defined */
1145 X509_get0_signature(NULL, &alg, this->x509);
1146 sig_scheme = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
1147 alg = X509_get0_tbs_sigalg(this->x509);
1148 sig_scheme_tbs = openssl_i2chunk(X509_ALGOR, (X509_ALGOR*)alg);
1149 if (!chunk_equals(sig_scheme, sig_scheme_tbs))
1150 {
1151 free(sig_scheme_tbs.ptr);
1152 free(sig_scheme.ptr);
1153 return FALSE;
1154 }
1155 free(sig_scheme_tbs.ptr);
1156
1157 INIT(this->scheme);
1158 if (!signature_params_parse(sig_scheme, 0, this->scheme))
1159 {
1160 DBG1(DBG_ASN, "unable to parse signature algorithm");
1161 free(sig_scheme.ptr);
1162 return FALSE;
1163 }
1164 free(sig_scheme.ptr);
1165
1166 if (!parse_extensions(this))
1167 {
1168 return FALSE;
1169 }
1170
1171 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
1172 if (!hasher || !hasher->allocate_hash(hasher, this->encoding, &this->hash))
1173 {
1174 DESTROY_IF(hasher);
1175 return FALSE;
1176 }
1177 hasher->destroy(hasher);
1178
1179 if (issued_by(this, &this->public.x509.interface, NULL))
1180 {
1181 this->flags |= X509_SELF_SIGNED;
1182 }
1183 return TRUE;
1184 }
1185
1186 openssl_x509_t *openssl_x509_load(certificate_type_t type, va_list args)
1187 {
1188 chunk_t blob = chunk_empty;
1189 x509_flag_t flags = 0;
1190
1191 while (TRUE)
1192 {
1193 switch (va_arg(args, builder_part_t))
1194 {
1195 case BUILD_BLOB_ASN1_DER:
1196 blob = va_arg(args, chunk_t);
1197 continue;
1198 case BUILD_X509_FLAG:
1199 flags |= va_arg(args, x509_flag_t);
1200 continue;
1201 case BUILD_END:
1202 break;
1203 default:
1204 return NULL;
1205 }
1206 break;
1207 }
1208
1209 if (blob.ptr)
1210 {
1211 private_openssl_x509_t *this;
1212
1213 this = create_empty();
1214 this->encoding = chunk_clone(blob);
1215 this->flags |= flags;
1216 if (parse_certificate(this))
1217 {
1218 return &this->public;
1219 }
1220 DBG1(DBG_LIB, "OpenSSL X.509 parsing failed");
1221 destroy(this);
1222 }
1223 return NULL;
1224 }