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
82 typedef struct private_openssl_x509_t private_openssl_x509_t
;
85 * Private data of an openssl_x509_t object.
87 struct private_openssl_x509_t
{
90 * Public openssl_x509_t interface.
92 openssl_x509_t
public;
95 * OpenSSL certificate representation
100 * DER encoded certificate
105 * SHA1 hash of the certificate
120 * certificate subject
122 identification_t
*subject
;
127 identification_t
*issuer
;
130 * Certificates public key
132 public_key_t
*pubkey
;
135 * subjectKeyIdentifier as read from cert
137 chunk_t subjectKeyIdentifier
;
140 * authorityKeyIdentifier as read from cert
142 chunk_t authKeyIdentifier
;
145 * Start time of certificate validity
150 * End time of certificate validity
155 * Signature scheme of the certificate
157 signature_params_t
*scheme
;
162 linked_list_t
*subjectAltNames
;
167 linked_list_t
*issuerAltNames
;
170 * List of CRL URIs, as x509_cdp_t
172 linked_list_t
*crl_uris
;
177 linked_list_t
*ocsp_uris
;
180 * List of ipAddrBlocks as traffic_selector_t
182 linked_list_t
*ipAddrBlocks
;
186 * References to this cert
192 * Convert a GeneralName to an identification_t.
194 static identification_t
*general_name2id(GENERAL_NAME
*name
)
203 return identification_create_from_encoding(ID_RFC822_ADDR
,
204 openssl_asn1_str2chunk(name
->d
.rfc822Name
));
206 return identification_create_from_encoding(ID_FQDN
,
207 openssl_asn1_str2chunk(name
->d
.dNSName
));
209 return identification_create_from_encoding(ID_DER_ASN1_GN_URI
,
210 openssl_asn1_str2chunk(name
->d
.uniformResourceIdentifier
));
213 chunk_t chunk
= openssl_asn1_str2chunk(name
->d
.iPAddress
);
216 return identification_create_from_encoding(ID_IPV4_ADDR
, chunk
);
220 return identification_create_from_encoding(ID_IPV6_ADDR
, chunk
);
225 return openssl_x509_name2id(name
->d
.directoryName
);
227 if (OBJ_obj2nid(name
->d
.otherName
->type_id
) == NID_ms_upn
&&
228 name
->d
.otherName
->value
->type
== V_ASN1_UTF8STRING
)
230 return identification_create_from_encoding(ID_RFC822_ADDR
,
231 openssl_asn1_str2chunk(
232 name
->d
.otherName
->value
->value
.utf8string
));
240 METHOD(x509_t
, get_flags
, x509_flag_t
,
241 private_openssl_x509_t
*this)
246 METHOD(x509_t
, get_serial
, chunk_t
,
247 private_openssl_x509_t
*this)
249 return openssl_asn1_str2chunk(X509_get_serialNumber(this->x509
));
252 METHOD(x509_t
, get_subjectKeyIdentifier
, chunk_t
,
253 private_openssl_x509_t
*this)
257 if (this->subjectKeyIdentifier
.len
)
259 return this->subjectKeyIdentifier
;
261 if (this->pubkey
->get_fingerprint(this->pubkey
, KEYID_PUBKEY_SHA1
,
269 METHOD(x509_t
, get_authKeyIdentifier
, chunk_t
,
270 private_openssl_x509_t
*this)
272 if (this->authKeyIdentifier
.len
)
274 return this->authKeyIdentifier
;
279 METHOD(x509_t
, get_constraint
, u_int
,
280 private_openssl_x509_t
*this, x509_constraint_t type
)
285 return this->pathlen
;
287 return X509_NO_CONSTRAINT
;
291 METHOD(x509_t
, create_subjectAltName_enumerator
, enumerator_t
*,
292 private_openssl_x509_t
*this)
294 return this->subjectAltNames
->create_enumerator(this->subjectAltNames
);
297 METHOD(x509_t
, create_crl_uri_enumerator
, enumerator_t
*,
298 private_openssl_x509_t
*this)
300 return this->crl_uris
->create_enumerator(this->crl_uris
);
303 METHOD(x509_t
, create_ocsp_uri_enumerator
, enumerator_t
*,
304 private_openssl_x509_t
*this)
306 return this->ocsp_uris
->create_enumerator(this->ocsp_uris
);
309 METHOD(x509_t
, create_ipAddrBlock_enumerator
, enumerator_t
*,
310 private_openssl_x509_t
*this)
312 return this->ipAddrBlocks
->create_enumerator(this->ipAddrBlocks
);
315 METHOD(certificate_t
, get_type
, certificate_type_t
,
316 private_openssl_x509_t
*this)
321 METHOD(certificate_t
, get_subject
, identification_t
*,
322 private_openssl_x509_t
*this)
324 return this->subject
;
327 METHOD(certificate_t
, get_issuer
, identification_t
*,
328 private_openssl_x509_t
*this)
333 METHOD(certificate_t
, has_subject
, id_match_t
,
334 private_openssl_x509_t
*this, identification_t
*subject
)
336 identification_t
*current
;
337 enumerator_t
*enumerator
;
338 id_match_t match
, best
;
341 if (subject
->get_type(subject
) == ID_KEY_ID
)
343 encoding
= subject
->get_encoding(subject
);
345 if (chunk_equals(this->hash
, encoding
))
347 return ID_MATCH_PERFECT
;
349 if (this->subjectKeyIdentifier
.len
&&
350 chunk_equals(this->subjectKeyIdentifier
, encoding
))
352 return ID_MATCH_PERFECT
;
355 this->pubkey
->has_fingerprint(this->pubkey
, encoding
))
357 return ID_MATCH_PERFECT
;
359 if (chunk_equals(get_serial(this), encoding
))
361 return ID_MATCH_PERFECT
;
364 best
= this->subject
->matches(this->subject
, subject
);
365 enumerator
= create_subjectAltName_enumerator(this);
366 while (enumerator
->enumerate(enumerator
, ¤t
))
368 match
= current
->matches(current
, subject
);
374 enumerator
->destroy(enumerator
);
378 METHOD(certificate_t
, has_issuer
, id_match_t
,
379 private_openssl_x509_t
*this, identification_t
*issuer
)
381 /* issuerAltNames currently not supported */
382 return this->issuer
->matches(this->issuer
, issuer
);
385 METHOD(certificate_t
, issued_by
, bool,
386 private_openssl_x509_t
*this, certificate_t
*issuer
,
387 signature_params_t
**scheme
)
391 x509_t
*x509
= (x509_t
*)issuer
;
392 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
393 const ASN1_BIT_STRING
*sig
;
395 ASN1_BIT_STRING
*sig
;
399 if (&this->public.x509
.interface
== issuer
)
401 if (this->flags
& X509_SELF_SIGNED
)
409 if (issuer
->get_type(issuer
) != CERT_X509
)
413 if (!(x509
->get_flags(x509
) & X509_CA
))
417 if (!this->issuer
->equals(this->issuer
, issuer
->get_subject(issuer
)))
422 key
= issuer
->get_public_key(issuer
);
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
);
431 tbs
= openssl_i2chunk(X509_CINF
, this->x509
->cert_info
);
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
));
442 *scheme
= signature_params_clone(this->scheme
);
447 METHOD(certificate_t
, get_public_key
, public_key_t
*,
448 private_openssl_x509_t
*this)
450 return this->pubkey
->get_ref(this->pubkey
);
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
)
469 *not_before
= this->notBefore
;
473 *not_after
= this->notAfter
;
475 return (t
>= this->notBefore
&& t
<= this->notAfter
);
478 METHOD(certificate_t
, get_encoding
, bool,
479 private_openssl_x509_t
*this, cred_encoding_type_t type
, chunk_t
*encoding
)
481 if (type
== CERT_ASN1_DER
)
483 *encoding
= chunk_clone(this->encoding
);
486 return lib
->encoding
->encode(lib
->encoding
, type
, NULL
, encoding
,
487 CRED_PART_X509_ASN1_DER
, this->encoding
, CRED_PART_END
);
491 METHOD(certificate_t
, equals
, bool,
492 private_openssl_x509_t
*this, certificate_t
*other
)
497 if (this == (private_openssl_x509_t
*)other
)
501 if (other
->get_type(other
) != CERT_X509
)
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
);
510 if (!other
->get_encoding(other
, CERT_ASN1_DER
, &encoding
))
514 equal
= chunk_equals(this->encoding
, encoding
);
519 METHOD(certificate_t
, get_ref
, certificate_t
*,
520 private_openssl_x509_t
*this)
523 return &this->public.x509
.interface
;
526 METHOD(certificate_t
, destroy
, void,
527 private_openssl_x509_t
*this)
529 if (ref_put(&this->ref
))
533 X509_free(this->x509
);
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
));
557 * Create an empty certificate
559 static private_openssl_x509_t
*create_empty()
561 private_openssl_x509_t
*this;
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
,
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
,
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
,
607 * parse an extionsion containing GENERAL_NAMES into a list
609 static bool parse_generalNames_ext(linked_list_t
*list
,
612 GENERAL_NAMES
*names
;
614 identification_t
*id
;
617 names
= X509V3_EXT_d2i(ext
);
623 num
= sk_GENERAL_NAME_num(names
);
624 for (i
= 0; i
< num
; i
++)
626 name
= sk_GENERAL_NAME_value(names
, i
);
627 id
= general_name2id(name
);
630 list
->insert_last(list
, id
);
632 GENERAL_NAME_free(name
);
634 sk_GENERAL_NAME_free(names
);
639 * parse basic constraints
641 static bool parse_basicConstraints_ext(private_openssl_x509_t
*this,
644 BASIC_CONSTRAINTS
*constraints
;
647 constraints
= (BASIC_CONSTRAINTS
*)X509V3_EXT_d2i(ext
);
652 this->flags
|= X509_CA
;
654 if (constraints
->pathlen
)
657 pathlen
= ASN1_INTEGER_get(constraints
->pathlen
);
658 this->pathlen
= (pathlen
>= 0 && pathlen
< 128) ?
659 pathlen
: X509_NO_CONSTRAINT
;
661 BASIC_CONSTRAINTS_free(constraints
);
670 static bool parse_keyUsage_ext(private_openssl_x509_t
*this,
673 ASN1_BIT_STRING
*usage
;
675 /* to be compliant with RFC 4945 specific KUs have to be included */
676 this->flags
&= ~X509_IKE_COMPLIANT
;
678 usage
= X509V3_EXT_d2i(ext
);
681 if (usage
->length
> 0)
683 int flags
= usage
->data
[0];
684 if (usage
->length
> 1)
686 flags
|= usage
->data
[1] << 8;
688 if (flags
& X509v3_KU_CRL_SIGN
)
690 this->flags
|= X509_CRL_SIGN
;
692 if (flags
& X509v3_KU_DIGITAL_SIGNATURE
||
693 flags
& X509v3_KU_NON_REPUDIATION
)
695 this->flags
|= X509_IKE_COMPLIANT
;
697 if (flags
& X509v3_KU_KEY_CERT_SIGN
)
699 /* we use the caBasicContraint, MUST be set */
702 ASN1_BIT_STRING_free(usage
);
709 * Parse ExtendedKeyUsage
711 static bool parse_extKeyUsage_ext(private_openssl_x509_t
*this,
714 EXTENDED_KEY_USAGE
*usage
;
717 usage
= X509V3_EXT_d2i(ext
);
720 for (i
= 0; i
< sk_ASN1_OBJECT_num(usage
); i
++)
722 switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(usage
, i
)))
724 case NID_server_auth
:
725 this->flags
|= X509_SERVER_AUTH
;
727 case NID_client_auth
:
728 this->flags
|= X509_CLIENT_AUTH
;
731 this->flags
|= X509_OCSP_SIGNER
;
737 sk_ASN1_OBJECT_pop_free(usage
, ASN1_OBJECT_free
);
744 * Parse CRL distribution points
746 bool openssl_parse_crlDistributionPoints(X509_EXTENSION
*ext
,
749 CRL_DIST_POINTS
*cdps
;
751 identification_t
*id
, *issuer
;
754 int i
, j
, k
, point_num
, name_num
, issuer_num
, len
;
756 cdps
= X509V3_EXT_d2i(ext
);
761 point_num
= sk_DIST_POINT_num(cdps
);
762 for (i
= 0; i
< point_num
; i
++)
764 cdp
= sk_DIST_POINT_value(cdps
, i
);
767 if (cdp
->distpoint
&& cdp
->distpoint
->type
== 0 &&
768 cdp
->distpoint
->name
.fullname
)
770 name_num
= sk_GENERAL_NAME_num(cdp
->distpoint
->name
.fullname
);
771 for (j
= 0; j
< name_num
; j
++)
773 id
= general_name2id(sk_GENERAL_NAME_value(
774 cdp
->distpoint
->name
.fullname
, j
));
777 len
= asprintf(&uri
, "%Y", id
);
786 issuer_num
= sk_GENERAL_NAME_num(cdp
->CRLissuer
);
787 for (k
= 0; k
< issuer_num
; k
++)
789 issuer
= general_name2id(
790 sk_GENERAL_NAME_value(cdp
->CRLissuer
, k
));
797 list
->insert_last(list
, entry
);
807 list
->insert_last(list
, entry
);
815 DIST_POINT_free(cdp
);
818 sk_DIST_POINT_free(cdps
);
823 * Parse authorityInfoAccess with OCSP URIs
825 static bool parse_authorityInfoAccess_ext(private_openssl_x509_t
*this,
828 AUTHORITY_INFO_ACCESS
*infos
;
829 ACCESS_DESCRIPTION
*desc
;
830 identification_t
*id
;
834 infos
= X509V3_EXT_d2i(ext
);
839 num
= sk_ACCESS_DESCRIPTION_num(infos
);
840 for (i
= 0; i
< num
; i
++)
842 desc
= sk_ACCESS_DESCRIPTION_value(infos
, i
);
845 if (openssl_asn1_known_oid(desc
->method
) == OID_OCSP
)
847 id
= general_name2id(desc
->location
);
850 len
= asprintf(&uri
, "%Y", id
);
857 this->ocsp_uris
->insert_last(this->ocsp_uris
, uri
);
862 ACCESS_DESCRIPTION_free(desc
);
865 sk_ACCESS_DESCRIPTION_free(infos
);
869 #ifndef OPENSSL_NO_RFC3779
872 * Parse a single block of ipAddrBlock extension
874 static void parse_ipAddrBlock_ext_fam(private_openssl_x509_t
*this,
875 IPAddressFamily
*fam
)
877 const IPAddressOrRanges
*list
;
878 IPAddressOrRange
*aor
;
879 traffic_selector_t
*ts
;
884 if (fam
->ipAddressChoice
->type
!= IPAddressChoice_addressesOrRanges
)
889 afi
= X509v3_addr_get_afi(fam
);
893 from
= chunk_alloca(4);
894 to
= chunk_alloca(4);
895 type
= TS_IPV4_ADDR_RANGE
;
898 from
= chunk_alloca(16);
899 to
= chunk_alloca(16);
900 type
= TS_IPV6_ADDR_RANGE
;
906 list
= fam
->ipAddressChoice
->u
.addressesOrRanges
;
907 for (i
= 0; i
< sk_IPAddressOrRange_num(list
); i
++)
909 aor
= sk_IPAddressOrRange_value(list
, i
);
910 if (X509v3_addr_get_range(aor
, afi
, from
.ptr
, to
.ptr
, from
.len
) > 0)
912 ts
= traffic_selector_create_from_bytes(0, type
, from
, 0, to
, 65535);
915 this->ipAddrBlocks
->insert_last(this->ipAddrBlocks
, ts
);
922 * Parse ipAddrBlock extension
924 static bool parse_ipAddrBlock_ext(private_openssl_x509_t
*this,
927 STACK_OF(IPAddressFamily
) *blocks
;
928 IPAddressFamily
*fam
;
930 blocks
= (STACK_OF(IPAddressFamily
)*)X509V3_EXT_d2i(ext
);
936 if (!X509v3_addr_is_canonical(blocks
))
938 sk_IPAddressFamily_free(blocks
);
942 while (sk_IPAddressFamily_num(blocks
) > 0)
944 fam
= sk_IPAddressFamily_pop(blocks
);
945 parse_ipAddrBlock_ext_fam(this, fam
);
946 IPAddressFamily_free(fam
);
948 sk_IPAddressFamily_free(blocks
);
950 this->flags
|= X509_IP_ADDR_BLOCKS
;
953 #endif /* !OPENSSL_NO_RFC3779 */
956 * Parse authorityKeyIdentifier extension
958 static bool parse_authKeyIdentifier_ext(private_openssl_x509_t
*this,
961 AUTHORITY_KEYID
*keyid
;
963 keyid
= (AUTHORITY_KEYID
*)X509V3_EXT_d2i(ext
);
966 free(this->authKeyIdentifier
.ptr
);
967 this->authKeyIdentifier
= chunk_clone(
968 openssl_asn1_str2chunk(keyid
->keyid
));
969 AUTHORITY_KEYID_free(keyid
);
976 * Parse subjectKeyIdentifier extension
978 static bool parse_subjectKeyIdentifier_ext(private_openssl_x509_t
*this,
983 ostr
= openssl_asn1_str2chunk(X509_EXTENSION_get_data(ext
));
984 /* quick and dirty unwrap of octet string */
986 ostr
.ptr
[0] == V_ASN1_OCTET_STRING
&& ostr
.ptr
[1] == ostr
.len
- 2)
988 free(this->subjectKeyIdentifier
.ptr
);
989 this->subjectKeyIdentifier
= chunk_clone(chunk_skip(ostr
, 2));
996 * Parse X509 extensions we are interested in
998 static bool parse_extensions(private_openssl_x509_t
*this)
1000 const STACK_OF(X509_EXTENSION
) *extensions
;
1003 /* unless we see a keyUsage extension we are compliant with RFC 4945 */
1004 this->flags
|= X509_IKE_COMPLIANT
;
1006 extensions
= X509_get0_extensions(this->x509
);
1009 num
= sk_X509_EXTENSION_num(extensions
);
1011 for (i
= 0; i
< num
; i
++)
1013 X509_EXTENSION
*ext
;
1016 ext
= sk_X509_EXTENSION_value(extensions
, i
);
1017 switch (OBJ_obj2nid(X509_EXTENSION_get_object(ext
)))
1019 case NID_info_access
:
1020 ok
= parse_authorityInfoAccess_ext(this, ext
);
1022 case NID_authority_key_identifier
:
1023 ok
= parse_authKeyIdentifier_ext(this, ext
);
1025 case NID_subject_key_identifier
:
1026 ok
= parse_subjectKeyIdentifier_ext(this, ext
);
1028 case NID_subject_alt_name
:
1029 ok
= parse_generalNames_ext(this->subjectAltNames
, ext
);
1031 case NID_issuer_alt_name
:
1032 ok
= parse_generalNames_ext(this->issuerAltNames
, ext
);
1034 case NID_basic_constraints
:
1035 ok
= parse_basicConstraints_ext(this, ext
);
1038 ok
= parse_keyUsage_ext(this, ext
);
1040 case NID_ext_key_usage
:
1041 ok
= parse_extKeyUsage_ext(this, ext
);
1043 case NID_crl_distribution_points
:
1044 ok
= openssl_parse_crlDistributionPoints(ext
, this->crl_uris
);
1046 #ifndef OPENSSL_NO_RFC3779
1047 case NID_sbgp_ipAddrBlock
:
1048 ok
= parse_ipAddrBlock_ext(this, ext
);
1050 #endif /* !OPENSSL_NO_RFC3779 */
1052 ok
= X509_EXTENSION_get_critical(ext
) == 0 ||
1053 !lib
->settings
->get_bool(lib
->settings
,
1054 "%s.x509.enforce_critical", TRUE
, lib
->ns
);
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
);
1076 * Parse a DER encoded x509 certificate
1078 static bool parse_certificate(private_openssl_x509_t
*this)
1080 const unsigned char *ptr
= this->encoding
.ptr
;
1082 chunk_t chunk
, sig_scheme
, sig_scheme_tbs
;
1084 #if OPENSSL_VERSION_NUMBER >= 0x10100000L
1085 const X509_ALGOR
*alg
;
1090 this->x509
= d2i_X509(NULL
, &ptr
, this->encoding
.len
);
1095 if (X509_get_version(this->x509
) < 0 || X509_get_version(this->x509
) > 2)
1097 DBG1(DBG_LIB
, "unsupported x509 version: %d",
1098 X509_get_version(this->x509
) + 1);
1102 this->subject
= openssl_x509_name2id(X509_get_subject_name(this->x509
));
1103 this->issuer
= openssl_x509_name2id(X509_get_issuer_name(this->x509
));
1105 if (!X509_PUBKEY_get0_param(&oid
, NULL
, NULL
, NULL
,
1106 X509_get_X509_PUBKEY(this->x509
)))
1110 switch (openssl_asn1_known_oid(oid
))
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
)),
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
,
1132 DBG1(DBG_LIB
, "unsupported public key algorithm");
1135 if (!this->subject
|| !this->issuer
|| !this->pubkey
)
1140 this->notBefore
= openssl_asn1_to_time(X509_get_notBefore(this->x509
));
1141 this->notAfter
= openssl_asn1_to_time(X509_get_notAfter(this->x509
));
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
))
1151 free(sig_scheme_tbs
.ptr
);
1152 free(sig_scheme
.ptr
);
1155 free(sig_scheme_tbs
.ptr
);
1158 if (!signature_params_parse(sig_scheme
, 0, this->scheme
))
1160 DBG1(DBG_ASN
, "unable to parse signature algorithm");
1161 free(sig_scheme
.ptr
);
1164 free(sig_scheme
.ptr
);
1166 if (!parse_extensions(this))
1171 hasher
= lib
->crypto
->create_hasher(lib
->crypto
, HASH_SHA1
);
1172 if (!hasher
|| !hasher
->allocate_hash(hasher
, this->encoding
, &this->hash
))
1177 hasher
->destroy(hasher
);
1179 if (issued_by(this, &this->public.x509
.interface
, NULL
))
1181 this->flags
|= X509_SELF_SIGNED
;
1186 openssl_x509_t
*openssl_x509_load(certificate_type_t type
, va_list args
)
1188 chunk_t blob
= chunk_empty
;
1189 x509_flag_t flags
= 0;
1193 switch (va_arg(args
, builder_part_t
))
1195 case BUILD_BLOB_ASN1_DER
:
1196 blob
= va_arg(args
, chunk_t
);
1198 case BUILD_X509_FLAG
:
1199 flags
|= va_arg(args
, x509_flag_t
);
1211 private_openssl_x509_t
*this;
1213 this = create_empty();
1214 this->encoding
= chunk_clone(blob
);
1215 this->flags
|= flags
;
1216 if (parse_certificate(this))
1218 return &this->public;
1220 DBG1(DBG_LIB
, "OpenSSL X.509 parsing failed");