2 * Copyright (C) 2011-2017 Tobias Brunner
3 * HSR Hochschule fuer Technik Rapperswil
5 * Copyright (C) 2010 Martin Willi
6 * Copyright (C) 2010 revosec AG
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>.
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
20 * Copyright (C) 2013 Michael Rossberg
21 * Copyright (C) 2013 Technische Universität Ilmenau
23 * Copyright (C) 2010 secunet Security Networks AG
24 * Copyright (C) 2010 Thomas Egerer
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:
33 * The above copyright notice and this permission notice shall be included in
34 * all copies or substantial portions of the Software.
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
47 #include <openssl/x509.h>
48 #include <openssl/x509v3.h>
50 #include "openssl_x509.h"
51 #include "openssl_util.h"
53 #include <utils/debug.h>
55 #include <collections/linked_list.h>
56 #include <selectors/traffic_selector.h>
58 /* IP Addr block extension support was introduced with 0.9.8e */
59 #if OPENSSL_VERSION_NUMBER < 0x0090805fL
60 #define OPENSSL_NO_RFC3779
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
; }
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 #define X509_get0_notBefore X509_get_notBefore
81 #define X509_get0_notAfter X509_get_notAfter
84 typedef struct private_openssl_x509_t private_openssl_x509_t
;
87 * Private data of an openssl_x509_t object.
89 struct private_openssl_x509_t
{
92 * Public openssl_x509_t interface.
94 openssl_x509_t
public;
97 * OpenSSL certificate representation
102 * DER encoded certificate
107 * SHA1 hash of the certificate
122 * certificate subject
124 identification_t
*subject
;
129 identification_t
*issuer
;
132 * Certificates public key
134 public_key_t
*pubkey
;
137 * subjectKeyIdentifier as read from cert
139 chunk_t subjectKeyIdentifier
;
142 * authorityKeyIdentifier as read from cert
144 chunk_t authKeyIdentifier
;
147 * Start time of certificate validity
152 * End time of certificate validity
157 * Signature scheme of the certificate
159 signature_params_t
*scheme
;
164 linked_list_t
*subjectAltNames
;
169 linked_list_t
*issuerAltNames
;
172 * List of CRL URIs, as x509_cdp_t
174 linked_list_t
*crl_uris
;
179 linked_list_t
*ocsp_uris
;
182 * List of ipAddrBlocks as traffic_selector_t
184 linked_list_t
*ipAddrBlocks
;
188 * References to this cert
194 * Convert a GeneralName to an identification_t.
196 static identification_t
*general_name2id(GENERAL_NAME
*name
)
205 return identification_create_from_encoding(ID_RFC822_ADDR
,
206 openssl_asn1_str2chunk(name
->d
.rfc822Name
));
208 return identification_create_from_encoding(ID_FQDN
,
209 openssl_asn1_str2chunk(name
->d
.dNSName
));
211 return identification_create_from_encoding(ID_DER_ASN1_GN_URI
,
212 openssl_asn1_str2chunk(name
->d
.uniformResourceIdentifier
));
215 chunk_t chunk
= openssl_asn1_str2chunk(name
->d
.iPAddress
);
218 return identification_create_from_encoding(ID_IPV4_ADDR
, chunk
);
222 return identification_create_from_encoding(ID_IPV6_ADDR
, chunk
);
227 return openssl_x509_name2id(name
->d
.directoryName
);
229 if (OBJ_obj2nid(name
->d
.otherName
->type_id
) == NID_ms_upn
&&
230 name
->d
.otherName
->value
->type
== V_ASN1_UTF8STRING
)
232 return identification_create_from_encoding(ID_RFC822_ADDR
,
233 openssl_asn1_str2chunk(
234 name
->d
.otherName
->value
->value
.utf8string
));
242 METHOD(x509_t
, get_flags
, x509_flag_t
,
243 private_openssl_x509_t
*this)
248 METHOD(x509_t
, get_serial
, chunk_t
,
249 private_openssl_x509_t
*this)
251 return openssl_asn1_str2chunk(X509_get_serialNumber(this->x509
));
254 METHOD(x509_t
, get_subjectKeyIdentifier
, chunk_t
,
255 private_openssl_x509_t
*this)
259 if (this->subjectKeyIdentifier
.len
)
261 return this->subjectKeyIdentifier
;
263 if (this->pubkey
->get_fingerprint(this->pubkey
, KEYID_PUBKEY_SHA1
,
271 METHOD(x509_t
, get_authKeyIdentifier
, chunk_t
,
272 private_openssl_x509_t
*this)
274 if (this->authKeyIdentifier
.len
)
276 return this->authKeyIdentifier
;
281 METHOD(x509_t
, get_constraint
, u_int
,
282 private_openssl_x509_t
*this, x509_constraint_t type
)
287 return this->pathlen
;
289 return X509_NO_CONSTRAINT
;
293 METHOD(x509_t
, create_subjectAltName_enumerator
, enumerator_t
*,
294 private_openssl_x509_t
*this)
296 return this->subjectAltNames
->create_enumerator(this->subjectAltNames
);
299 METHOD(x509_t
, create_crl_uri_enumerator
, enumerator_t
*,
300 private_openssl_x509_t
*this)
302 return this->crl_uris
->create_enumerator(this->crl_uris
);
305 METHOD(x509_t
, create_ocsp_uri_enumerator
, enumerator_t
*,
306 private_openssl_x509_t
*this)
308 return this->ocsp_uris
->create_enumerator(this->ocsp_uris
);
311 METHOD(x509_t
, create_ipAddrBlock_enumerator
, enumerator_t
*,
312 private_openssl_x509_t
*this)
314 return this->ipAddrBlocks
->create_enumerator(this->ipAddrBlocks
);
317 METHOD(certificate_t
, get_type
, certificate_type_t
,
318 private_openssl_x509_t
*this)
323 METHOD(certificate_t
, get_subject
, identification_t
*,
324 private_openssl_x509_t
*this)
326 return this->subject
;
329 METHOD(certificate_t
, get_issuer
, identification_t
*,
330 private_openssl_x509_t
*this)
335 METHOD(certificate_t
, has_subject
, id_match_t
,
336 private_openssl_x509_t
*this, identification_t
*subject
)
338 identification_t
*current
;
339 enumerator_t
*enumerator
;
340 id_match_t match
, best
;
343 if (subject
->get_type(subject
) == ID_KEY_ID
)
345 encoding
= subject
->get_encoding(subject
);
347 if (chunk_equals(this->hash
, encoding
))
349 return ID_MATCH_PERFECT
;
351 if (this->subjectKeyIdentifier
.len
&&
352 chunk_equals(this->subjectKeyIdentifier
, encoding
))
354 return ID_MATCH_PERFECT
;
357 this->pubkey
->has_fingerprint(this->pubkey
, encoding
))
359 return ID_MATCH_PERFECT
;
361 if (chunk_equals(get_serial(this), encoding
))
363 return ID_MATCH_PERFECT
;
366 best
= this->subject
->matches(this->subject
, subject
);
367 enumerator
= create_subjectAltName_enumerator(this);
368 while (enumerator
->enumerate(enumerator
, ¤t
))
370 match
= current
->matches(current
, subject
);
376 enumerator
->destroy(enumerator
);
380 METHOD(certificate_t
, has_issuer
, id_match_t
,
381 private_openssl_x509_t
*this, identification_t
*issuer
)
383 /* issuerAltNames currently not supported */
384 return this->issuer
->matches(this->issuer
, issuer
);
387 METHOD(certificate_t
, issued_by
, bool,
388 private_openssl_x509_t
*this, certificate_t
*issuer
,
389 signature_params_t
**scheme
)
393 x509_t
*x509
= (x509_t
*)issuer
;
394 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
395 const ASN1_BIT_STRING
*sig
;
397 ASN1_BIT_STRING
*sig
;
401 if (&this->public.x509
.interface
== issuer
)
403 if (this->flags
& X509_SELF_SIGNED
)
411 if (issuer
->get_type(issuer
) != CERT_X509
)
415 if (!(x509
->get_flags(x509
) & X509_CA
))
419 if (!this->issuer
->equals(this->issuer
, issuer
->get_subject(issuer
)))
424 key
= issuer
->get_public_key(issuer
);
429 /* i2d_re_X509_tbs() was added with 1.1.0 when X509 was made opaque */
430 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
431 tbs
= openssl_i2chunk(re_X509_tbs
, this->x509
);
433 tbs
= openssl_i2chunk(X509_CINF
, this->x509
->cert_info
);
435 X509_get0_signature(&sig
, NULL
, this->x509
);
436 valid
= key
->verify(key
, this->scheme
->scheme
, this->scheme
->params
, tbs
,
437 openssl_asn1_str2chunk(sig
));
444 *scheme
= signature_params_clone(this->scheme
);
449 METHOD(certificate_t
, get_public_key
, public_key_t
*,
450 private_openssl_x509_t
*this)
452 return this->pubkey
->get_ref(this->pubkey
);
455 METHOD(certificate_t
, get_validity
, bool,
456 private_openssl_x509_t
*this,
457 time_t *when
, time_t *not_before
, time_t *not_after
)
471 *not_before
= this->notBefore
;
475 *not_after
= this->notAfter
;
477 return (t
>= this->notBefore
&& t
<= this->notAfter
);
480 METHOD(certificate_t
, get_encoding
, bool,
481 private_openssl_x509_t
*this, cred_encoding_type_t type
, chunk_t
*encoding
)
483 if (type
== CERT_ASN1_DER
)
485 *encoding
= chunk_clone(this->encoding
);
488 return lib
->encoding
->encode(lib
->encoding
, type
, NULL
, encoding
,
489 CRED_PART_X509_ASN1_DER
, this->encoding
, CRED_PART_END
);
493 METHOD(certificate_t
, equals
, bool,
494 private_openssl_x509_t
*this, certificate_t
*other
)
499 if (this == (private_openssl_x509_t
*)other
)
503 if (other
->get_type(other
) != CERT_X509
)
507 if (other
->equals
== (void*)equals
)
508 { /* skip allocation if we have the same implementation */
509 encoding
= ((private_openssl_x509_t
*)other
)->encoding
;
510 return chunk_equals(this->encoding
, encoding
);
512 if (!other
->get_encoding(other
, CERT_ASN1_DER
, &encoding
))
516 equal
= chunk_equals(this->encoding
, encoding
);
521 METHOD(certificate_t
, get_ref
, certificate_t
*,
522 private_openssl_x509_t
*this)
525 return &this->public.x509
.interface
;
528 METHOD(certificate_t
, destroy
, void,
529 private_openssl_x509_t
*this)
531 if (ref_put(&this->ref
))
535 X509_free(this->x509
);
537 signature_params_destroy(this->scheme
);
538 DESTROY_IF(this->subject
);
539 DESTROY_IF(this->issuer
);
540 DESTROY_IF(this->pubkey
);
541 free(this->subjectKeyIdentifier
.ptr
);
542 free(this->authKeyIdentifier
.ptr
);
543 free(this->encoding
.ptr
);
544 free(this->hash
.ptr
);
545 this->subjectAltNames
->destroy_offset(this->subjectAltNames
,
546 offsetof(identification_t
, destroy
));
547 this->issuerAltNames
->destroy_offset(this->issuerAltNames
,
548 offsetof(identification_t
, destroy
));
549 this->crl_uris
->destroy_function(this->crl_uris
,
550 (void*)x509_cdp_destroy
);
551 this->ocsp_uris
->destroy_function(this->ocsp_uris
, free
);
552 this->ipAddrBlocks
->destroy_offset(this->ipAddrBlocks
,
553 offsetof(traffic_selector_t
, destroy
));
559 * Create an empty certificate
561 static private_openssl_x509_t
*create_empty()
563 private_openssl_x509_t
*this;
569 .get_type
= _get_type
,
570 .get_subject
= _get_subject
,
571 .get_issuer
= _get_issuer
,
572 .has_subject
= _has_subject
,
573 .has_issuer
= _has_issuer
,
574 .issued_by
= _issued_by
,
575 .get_public_key
= _get_public_key
,
576 .get_validity
= _get_validity
,
577 .get_encoding
= _get_encoding
,
582 .get_flags
= _get_flags
,
583 .get_serial
= _get_serial
,
584 .get_subjectKeyIdentifier
= _get_subjectKeyIdentifier
,
585 .get_authKeyIdentifier
= _get_authKeyIdentifier
,
586 .get_constraint
= _get_constraint
,
587 .create_subjectAltName_enumerator
= _create_subjectAltName_enumerator
,
588 .create_crl_uri_enumerator
= _create_crl_uri_enumerator
,
589 .create_ocsp_uri_enumerator
= _create_ocsp_uri_enumerator
,
590 .create_ipAddrBlock_enumerator
= _create_ipAddrBlock_enumerator
,
591 .create_name_constraint_enumerator
= (void*)enumerator_create_empty
,
592 .create_cert_policy_enumerator
= (void*)enumerator_create_empty
,
593 .create_policy_mapping_enumerator
= (void*)enumerator_create_empty
,
596 .subjectAltNames
= linked_list_create(),
597 .issuerAltNames
= linked_list_create(),
598 .crl_uris
= linked_list_create(),
599 .ocsp_uris
= linked_list_create(),
600 .ipAddrBlocks
= linked_list_create(),
601 .pathlen
= X509_NO_CONSTRAINT
,
609 * parse an extionsion containing GENERAL_NAMES into a list
611 static bool parse_generalNames_ext(linked_list_t
*list
,
614 GENERAL_NAMES
*names
;
616 identification_t
*id
;
619 names
= X509V3_EXT_d2i(ext
);
625 num
= sk_GENERAL_NAME_num(names
);
626 for (i
= 0; i
< num
; i
++)
628 name
= sk_GENERAL_NAME_value(names
, i
);
629 id
= general_name2id(name
);
632 list
->insert_last(list
, id
);
634 GENERAL_NAME_free(name
);
636 sk_GENERAL_NAME_free(names
);
641 * parse basic constraints
643 static bool parse_basicConstraints_ext(private_openssl_x509_t
*this,
646 BASIC_CONSTRAINTS
*constraints
;
649 constraints
= (BASIC_CONSTRAINTS
*)X509V3_EXT_d2i(ext
);
654 this->flags
|= X509_CA
;
656 if (constraints
->pathlen
)
659 pathlen
= ASN1_INTEGER_get(constraints
->pathlen
);
660 this->pathlen
= (pathlen
>= 0 && pathlen
< 128) ?
661 pathlen
: X509_NO_CONSTRAINT
;
663 BASIC_CONSTRAINTS_free(constraints
);
672 static bool parse_keyUsage_ext(private_openssl_x509_t
*this,
675 ASN1_BIT_STRING
*usage
;
677 /* to be compliant with RFC 4945 specific KUs have to be included */
678 this->flags
&= ~X509_IKE_COMPLIANT
;
680 usage
= X509V3_EXT_d2i(ext
);
683 if (usage
->length
> 0)
685 int flags
= usage
->data
[0];
686 if (usage
->length
> 1)
688 flags
|= usage
->data
[1] << 8;
690 if (flags
& X509v3_KU_CRL_SIGN
)
692 this->flags
|= X509_CRL_SIGN
;
694 if (flags
& X509v3_KU_DIGITAL_SIGNATURE
||
695 flags
& X509v3_KU_NON_REPUDIATION
)
697 this->flags
|= X509_IKE_COMPLIANT
;
699 if (flags
& X509v3_KU_KEY_CERT_SIGN
)
701 /* we use the caBasicContraint, MUST be set */
704 ASN1_BIT_STRING_free(usage
);
711 * Parse ExtendedKeyUsage
713 static bool parse_extKeyUsage_ext(private_openssl_x509_t
*this,
716 EXTENDED_KEY_USAGE
*usage
;
719 usage
= X509V3_EXT_d2i(ext
);
722 for (i
= 0; i
< sk_ASN1_OBJECT_num(usage
); i
++)
724 switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(usage
, i
)))
726 case NID_server_auth
:
727 this->flags
|= X509_SERVER_AUTH
;
729 case NID_client_auth
:
730 this->flags
|= X509_CLIENT_AUTH
;
733 this->flags
|= X509_OCSP_SIGNER
;
739 sk_ASN1_OBJECT_pop_free(usage
, ASN1_OBJECT_free
);
746 * Parse CRL distribution points
748 bool openssl_parse_crlDistributionPoints(X509_EXTENSION
*ext
,
751 CRL_DIST_POINTS
*cdps
;
753 identification_t
*id
, *issuer
;
756 int i
, j
, k
, point_num
, name_num
, issuer_num
, len
;
758 cdps
= X509V3_EXT_d2i(ext
);
763 point_num
= sk_DIST_POINT_num(cdps
);
764 for (i
= 0; i
< point_num
; i
++)
766 cdp
= sk_DIST_POINT_value(cdps
, i
);
769 if (cdp
->distpoint
&& cdp
->distpoint
->type
== 0 &&
770 cdp
->distpoint
->name
.fullname
)
772 name_num
= sk_GENERAL_NAME_num(cdp
->distpoint
->name
.fullname
);
773 for (j
= 0; j
< name_num
; j
++)
775 id
= general_name2id(sk_GENERAL_NAME_value(
776 cdp
->distpoint
->name
.fullname
, j
));
779 len
= asprintf(&uri
, "%Y", id
);
788 issuer_num
= sk_GENERAL_NAME_num(cdp
->CRLissuer
);
789 for (k
= 0; k
< issuer_num
; k
++)
791 issuer
= general_name2id(
792 sk_GENERAL_NAME_value(cdp
->CRLissuer
, k
));
799 list
->insert_last(list
, entry
);
809 list
->insert_last(list
, entry
);
817 DIST_POINT_free(cdp
);
820 sk_DIST_POINT_free(cdps
);
825 * Parse authorityInfoAccess with OCSP URIs
827 static bool parse_authorityInfoAccess_ext(private_openssl_x509_t
*this,
830 AUTHORITY_INFO_ACCESS
*infos
;
831 ACCESS_DESCRIPTION
*desc
;
832 identification_t
*id
;
836 infos
= X509V3_EXT_d2i(ext
);
841 num
= sk_ACCESS_DESCRIPTION_num(infos
);
842 for (i
= 0; i
< num
; i
++)
844 desc
= sk_ACCESS_DESCRIPTION_value(infos
, i
);
847 if (openssl_asn1_known_oid(desc
->method
) == OID_OCSP
)
849 id
= general_name2id(desc
->location
);
852 len
= asprintf(&uri
, "%Y", id
);
859 this->ocsp_uris
->insert_last(this->ocsp_uris
, uri
);
864 ACCESS_DESCRIPTION_free(desc
);
867 sk_ACCESS_DESCRIPTION_free(infos
);
871 #ifndef OPENSSL_NO_RFC3779
874 * Parse a single block of ipAddrBlock extension
876 static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t
*this,
877 IPAddressFamily
*fam
)
879 const IPAddressOrRanges
*list
;
880 IPAddressOrRange
*aor
;
881 traffic_selector_t
*ts
;
886 if (fam
->ipAddressChoice
->type
!= IPAddressChoice_addressesOrRanges
)
891 afi
= X509v3_addr_get_afi(fam
);
895 from
= chunk_alloca(4);
896 to
= chunk_alloca(4);
897 type
= TS_IPV4_ADDR_RANGE
;
900 from
= chunk_alloca(16);
901 to
= chunk_alloca(16);
902 type
= TS_IPV6_ADDR_RANGE
;
908 list
= fam
->ipAddressChoice
->u
.addressesOrRanges
;
909 for (i
= 0; i
< sk_IPAddressOrRange_num(list
); i
++)
911 aor
= sk_IPAddressOrRange_value(list
, i
);
912 if (X509v3_addr_get_range(aor
, afi
, from
.ptr
, to
.ptr
, from
.len
) > 0)
914 ts
= traffic_selector_create_from_bytes(0, type
, from
, 0, to
, 65535);
917 this->ipAddrBlocks
->insert_last(this->ipAddrBlocks
, ts
);
924 * Parse ipAddrBlock extension
926 static bool parse_ipAddrBlock_ext(private_openssl_x509_t
*this,
929 STACK_OF(IPAddressFamily
) *blocks
;
930 IPAddressFamily
*fam
;
932 blocks
= (STACK_OF(IPAddressFamily
)*)X509V3_EXT_d2i(ext
);
938 if (!X509v3_addr_is_canonical(blocks
))
940 sk_IPAddressFamily_free(blocks
);
944 while (sk_IPAddressFamily_num(blocks
) > 0)
946 fam
= sk_IPAddressFamily_pop(blocks
);
947 parse_ipAddrBlock_ext_fam(this, fam
);
948 IPAddressFamily_free(fam
);
950 sk_IPAddressFamily_free(blocks
);
952 this->flags
|= X509_IP_ADDR_BLOCKS
;
955 #endif /* !OPENSSL_NO_RFC3779 */
958 * Parse authorityKeyIdentifier extension
960 static bool parse_authKeyIdentifier_ext(private_openssl_x509_t
*this,
963 AUTHORITY_KEYID
*keyid
;
965 keyid
= (AUTHORITY_KEYID
*)X509V3_EXT_d2i(ext
);
968 free(this->authKeyIdentifier
.ptr
);
969 this->authKeyIdentifier
= chunk_clone(
970 openssl_asn1_str2chunk(keyid
->keyid
));
971 AUTHORITY_KEYID_free(keyid
);
978 * Parse subjectKeyIdentifier extension
980 static bool parse_subjectKeyIdentifier_ext(private_openssl_x509_t
*this,
985 ostr
= openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext
));
986 /* quick and dirty unwrap of octet string */
988 ostr
.ptr
[0] == V_ASN1_OCTET_STRING
&& ostr
.ptr
[1] == ostr
.len
- 2)
990 free(this->subjectKeyIdentifier
.ptr
);
991 this->subjectKeyIdentifier
= chunk_clone(chunk_skip(ostr
, 2));
998 * Parse X509 extensions we are interested in
1000 static bool parse_extensions(private_openssl_x509_t
*this)
1002 const STACK_OF(X509_EXTENSION
) *extensions
;
1005 /* unless we see a keyUsage extension we are compliant with RFC 4945 */
1006 this->flags
|= X509_IKE_COMPLIANT
;
1008 extensions
= X509_get0_extensions(this->x509
);
1011 num
= sk_X509_EXTENSION_num(extensions
);
1013 for (i
= 0; i
< num
; i
++)
1015 X509_EXTENSION
*ext
;
1018 ext
= sk_X509_EXTENSION_value(extensions
, i
);
1019 switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext
)))
1021 case NID_info_access
:
1022 ok
= parse_authorityInfoAccess_ext(this, ext
);
1024 case NID_authority_key_identifier
:
1025 ok
= parse_authKeyIdentifier_ext(this, ext
);
1027 case NID_subject_key_identifier
:
1028 ok
= parse_subjectKeyIdentifier_ext(this, ext
);
1030 case NID_subject_alt_name
:
1031 ok
= parse_generalNames_ext(this->subjectAltNames
, ext
);
1033 case NID_issuer_alt_name
:
1034 ok
= parse_generalNames_ext(this->issuerAltNames
, ext
);
1036 case NID_basic_constraints
:
1037 ok
= parse_basicConstraints_ext(this, ext
);
1040 ok
= parse_keyUsage_ext(this, ext
);
1042 case NID_ext_key_usage
:
1043 ok
= parse_extKeyUsage_ext(this, ext
);
1045 case NID_crl_distribution_points
:
1046 ok
= openssl_parse_crlDistributionPoints(ext
, this->crl_uris
);
1048 #ifndef OPENSSL_NO_RFC3779
1049 case NID_sbgp_ipAddrBlock
:
1050 ok
= parse_ipAddrBlock_ext(this, ext
);
1052 #endif /* !OPENSSL_NO_RFC3779 */
1054 ok
= X509_EXTENSION_get_critical(ext
) == 0 ||
1055 !lib
->settings
->get_bool(lib
->settings
,
1056 "%s.x509.enforce_critical", TRUE
, lib
->ns
);
1061 OBJ_obj2txt(buf
, sizeof(buf
),
1062 X509_EXTENSION_get_object(ext
), 0);
1063 DBG1(DBG_LIB
, "found unsupported critical X.509 "
1064 "extension: %s", buf
);
1078 * Parse a DER encoded x509 certificate
1080 static bool parse_certificate(private_openssl_x509_t
*this)
1082 const unsigned char *ptr
= this->encoding
.ptr
;
1084 chunk_t chunk
, sig_scheme
, sig_scheme_tbs
;
1086 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1087 const X509_ALGOR
*alg
;
1092 this->x509
= d2i_X509(NULL
, &ptr
, this->encoding
.len
);
1097 if (X509_get_version(this->x509
) < 0 || X509_get_version(this->x509
) > 2)
1099 DBG1(DBG_LIB
, "unsupported x509 version: %d",
1100 X509_get_version(this->x509
) + 1);
1104 this->subject
= openssl_x509_name2id(X509_get_subject_name(this->x509
));
1105 this->issuer
= openssl_x509_name2id(X509_get_issuer_name(this->x509
));
1107 if (!X509_PUBKEY_get0_param(&oid
, NULL
, NULL
, NULL
,
1108 X509_get_X509_PUBKEY(this->x509
)))
1112 switch (openssl_asn1_known_oid(oid
))
1114 case OID_RSASSA_PSS
:
1115 /* TODO: we should treat such keys special and use the params as
1116 * restrictions regarding the use of this key (or rather the
1117 * associated private key) */
1118 case OID_RSA_ENCRYPTION
:
1119 this->pubkey
= lib
->creds
->create(lib
->creds
,
1120 CRED_PUBLIC_KEY
, KEY_RSA
, BUILD_BLOB_ASN1_DER
,
1121 openssl_asn1_str2chunk(X509_get0_pubkey_bitstr(this->x509
)),
1124 case OID_EC_PUBLICKEY
:
1125 /* for ECDSA, we need the full subjectPublicKeyInfo, as it contains
1126 * the curve parameters. */
1127 chunk
= openssl_i2chunk(X509_PUBKEY
, X509_get_X509_PUBKEY(this->x509
));
1128 this->pubkey
= lib
->creds
->create(lib
->creds
,
1129 CRED_PUBLIC_KEY
, KEY_ECDSA
, BUILD_BLOB_ASN1_DER
,
1134 DBG1(DBG_LIB
, "unsupported public key algorithm");
1137 if (!this->subject
|| !this->issuer
|| !this->pubkey
)
1142 this->notBefore
= openssl_asn1_to_time(X509_get0_notBefore(this->x509
));
1143 this->notAfter
= openssl_asn1_to_time(X509_get0_notAfter(this->x509
));
1145 /* while X509_ALGOR_cmp() is declared in the headers of older OpenSSL
1146 * versions, at least on Ubuntu 14.04 it is not actually defined */
1147 X509_get0_signature(NULL
, &alg
, this->x509
);
1148 sig_scheme
= openssl_i2chunk(X509_ALGOR
, (X509_ALGOR
*)alg
);
1149 alg
= X509_get0_tbs_sigalg(this->x509
);
1150 sig_scheme_tbs
= openssl_i2chunk(X509_ALGOR
, (X509_ALGOR
*)alg
);
1151 if (!chunk_equals(sig_scheme
, sig_scheme_tbs
))
1153 free(sig_scheme_tbs
.ptr
);
1154 free(sig_scheme
.ptr
);
1157 free(sig_scheme_tbs
.ptr
);
1160 if (!signature_params_parse(sig_scheme
, 0, this->scheme
))
1162 DBG1(DBG_ASN
, "unable to parse signature algorithm");
1163 free(sig_scheme
.ptr
);
1166 free(sig_scheme
.ptr
);
1168 if (!parse_extensions(this))
1173 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
1174 if (!hasher
|| !hasher
->allocate_hash(hasher
, this->encoding
, &this->hash
))
1179 hasher
->destroy(hasher
);
1181 if (issued_by(this, &this->public.x509
.interface
, NULL
))
1183 this->flags
|= X509_SELF_SIGNED
;
1188 openssl_x509_t
*openssl_x509_load(certificate_type_t type
, va_list args
)
1190 chunk_t blob
= chunk_empty
;
1191 x509_flag_t flags
= 0;
1195 switch (va_arg(args
, builder_part_t
))
1197 case BUILD_BLOB_ASN1_DER
:
1198 blob
= va_arg(args
, chunk_t
);
1200 case BUILD_X509_FLAG
:
1201 flags
|= va_arg(args
, x509_flag_t
);
1213 private_openssl_x509_t
*this;
1215 this = create_empty();
1216 this->encoding
= chunk_clone(blob
);
1217 this->flags
|= flags
;
1218 if (parse_certificate(this))
1220 return &this->public;
1222 DBG1(DBG_LIB
, "OpenSSL X.509 parsing failed");