@fails-components/webtransport 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/readme.md +1 -3
- package/src/http3eventloop.cc +83 -9
- package/src/http3eventloop.h +13 -3
- package/src/http3server.cc +22 -22
- package/src/http3server.h +7 -20
- package/src/http3wtstreamvisitor.cc +31 -10
- package/src/http3wtstreamvisitor.h +38 -11
- package/src/webtransport.js +91 -23
- package/test/echoserver.js +29 -5
- package/test/testsuite.js +242 -220
- package/third_party/boringssl/src/CMakeLists.txt +2 -0
- package/third_party/boringssl/src/crypto/CMakeLists.txt +1 -0
- package/third_party/boringssl/src/crypto/asn1/a_bitstr.c +174 -177
- package/third_party/boringssl/src/crypto/asn1/a_bool.c +46 -48
- package/third_party/boringssl/src/crypto/asn1/a_d2i_fp.c +21 -23
- package/third_party/boringssl/src/crypto/asn1/a_dup.c +21 -23
- package/third_party/boringssl/src/crypto/asn1/a_gentm.c +84 -187
- package/third_party/boringssl/src/crypto/asn1/a_i2d_fp.c +19 -21
- package/third_party/boringssl/src/crypto/asn1/a_int.c +305 -329
- package/third_party/boringssl/src/crypto/asn1/a_mbstr.c +190 -195
- package/third_party/boringssl/src/crypto/asn1/a_object.c +182 -189
- package/third_party/boringssl/src/crypto/asn1/a_octet.c +6 -9
- package/third_party/boringssl/src/crypto/asn1/a_print.c +15 -16
- package/third_party/boringssl/src/crypto/asn1/a_strex.c +386 -399
- package/third_party/boringssl/src/crypto/asn1/a_strnid.c +110 -131
- package/third_party/boringssl/src/crypto/asn1/a_time.c +118 -111
- package/third_party/boringssl/src/crypto/asn1/a_type.c +59 -60
- package/third_party/boringssl/src/crypto/asn1/a_utctm.c +114 -186
- package/third_party/boringssl/src/crypto/asn1/a_utf8.c +171 -159
- package/third_party/boringssl/src/crypto/asn1/asn1_lib.c +245 -260
- package/third_party/boringssl/src/crypto/asn1/asn1_par.c +41 -40
- package/third_party/boringssl/src/crypto/asn1/asn1_test.cc +31 -0
- package/third_party/boringssl/src/crypto/asn1/asn_pack.c +31 -33
- package/third_party/boringssl/src/crypto/asn1/f_int.c +36 -33
- package/third_party/boringssl/src/crypto/asn1/f_string.c +29 -26
- package/third_party/boringssl/src/crypto/asn1/internal.h +62 -61
- package/third_party/boringssl/src/crypto/asn1/tasn_dec.c +706 -702
- package/third_party/boringssl/src/crypto/asn1/tasn_enc.c +507 -524
- package/third_party/boringssl/src/crypto/asn1/tasn_fre.c +141 -133
- package/third_party/boringssl/src/crypto/asn1/tasn_new.c +207 -199
- package/third_party/boringssl/src/crypto/asn1/tasn_typ.c +19 -22
- package/third_party/boringssl/src/crypto/asn1/tasn_utl.c +24 -24
- package/third_party/boringssl/src/crypto/asn1/time_support.c +13 -13
- package/third_party/boringssl/src/crypto/bio/connect.c +9 -3
- package/third_party/boringssl/src/crypto/bytestring/bytestring_test.cc +125 -1
- package/third_party/boringssl/src/crypto/bytestring/cbb.c +4 -7
- package/third_party/boringssl/src/crypto/bytestring/cbs.c +167 -9
- package/third_party/boringssl/src/crypto/cipher_extra/e_aesctrhmac.c +0 -2
- package/third_party/boringssl/src/crypto/cipher_extra/e_aesgcmsiv.c +23 -54
- package/third_party/boringssl/src/crypto/cipher_extra/e_chacha20poly1305.c +0 -2
- package/third_party/boringssl/src/crypto/cipher_extra/e_tls.c +0 -2
- package/third_party/boringssl/src/crypto/curve25519/curve25519.c +6 -8
- package/third_party/boringssl/src/crypto/evp/evp_ctx.c +25 -22
- package/third_party/boringssl/src/crypto/evp/internal.h +15 -9
- package/third_party/boringssl/src/crypto/evp/p_dsa_asn1.c +2 -0
- package/third_party/boringssl/src/crypto/evp/p_ec_asn1.c +2 -0
- package/third_party/boringssl/src/crypto/evp/p_ed25519.c +3 -3
- package/third_party/boringssl/src/crypto/evp/p_ed25519_asn1.c +10 -7
- package/third_party/boringssl/src/crypto/evp/p_hkdf.c +241 -0
- package/third_party/boringssl/src/crypto/evp/p_rsa_asn1.c +2 -0
- package/third_party/boringssl/src/crypto/evp/p_x25519_asn1.c +1 -0
- package/third_party/boringssl/src/crypto/fipsmodule/aes/aes_nohw.c +9 -10
- package/third_party/boringssl/src/crypto/fipsmodule/aes/key_wrap.c +2 -6
- package/third_party/boringssl/src/crypto/fipsmodule/bn/exponentiation.c +5 -11
- package/third_party/boringssl/src/crypto/fipsmodule/bn/internal.h +1 -1
- package/third_party/boringssl/src/crypto/fipsmodule/bn/prime.c +2 -0
- package/third_party/boringssl/src/crypto/fipsmodule/cipher/e_aes.c +10 -26
- package/third_party/boringssl/src/crypto/fipsmodule/cipher/e_aesccm.c +2 -3
- package/third_party/boringssl/src/crypto/fipsmodule/digestsign/digestsign.c +1 -0
- package/third_party/boringssl/src/crypto/fipsmodule/ec/p256-nistz.c +44 -43
- package/third_party/boringssl/src/crypto/fipsmodule/modes/cbc.c +5 -9
- package/third_party/boringssl/src/crypto/fipsmodule/modes/gcm.c +14 -21
- package/third_party/boringssl/src/crypto/fipsmodule/rand/ctrdrbg.c +8 -8
- package/third_party/boringssl/src/crypto/fipsmodule/rand/internal.h +1 -4
- package/third_party/boringssl/src/crypto/hkdf/hkdf_test.cc +104 -0
- package/third_party/boringssl/src/crypto/internal.h +18 -4
- package/third_party/boringssl/src/crypto/lhash/internal.h +13 -1
- package/third_party/boringssl/src/crypto/obj/obj_dat.h +4 -1
- package/third_party/boringssl/src/crypto/obj/obj_mac.num +1 -0
- package/third_party/boringssl/src/crypto/obj/objects.txt +2 -0
- package/third_party/boringssl/src/crypto/pem/pem_all.c +77 -86
- package/third_party/boringssl/src/crypto/pem/pem_info.c +221 -233
- package/third_party/boringssl/src/crypto/pem/pem_lib.c +639 -608
- package/third_party/boringssl/src/crypto/pem/pem_oth.c +17 -16
- package/third_party/boringssl/src/crypto/pem/pem_pk8.c +133 -142
- package/third_party/boringssl/src/crypto/pem/pem_pkey.c +96 -92
- package/third_party/boringssl/src/crypto/poly1305/poly1305_vec.c +12 -28
- package/third_party/boringssl/src/crypto/siphash/siphash.c +8 -11
- package/third_party/boringssl/src/crypto/siphash/siphash_test.cc +5 -7
- package/third_party/boringssl/src/crypto/stack/stack.c +33 -16
- package/third_party/boringssl/src/crypto/thread_pthread.c +0 -2
- package/third_party/boringssl/src/crypto/thread_win.c +0 -2
- package/third_party/boringssl/src/crypto/trust_token/internal.h +14 -0
- package/third_party/boringssl/src/crypto/trust_token/pmbtoken.c +127 -30
- package/third_party/boringssl/src/crypto/trust_token/trust_token.c +40 -0
- package/third_party/boringssl/src/crypto/trust_token/trust_token_test.cc +165 -0
- package/third_party/boringssl/src/crypto/trust_token/voprf.c +55 -6
- package/third_party/boringssl/src/crypto/x509/a_digest.c +23 -24
- package/third_party/boringssl/src/crypto/x509/a_sign.c +52 -55
- package/third_party/boringssl/src/crypto/x509/a_verify.c +33 -34
- package/third_party/boringssl/src/crypto/x509/algorithm.c +17 -18
- package/third_party/boringssl/src/crypto/x509/asn1_gen.c +618 -612
- package/third_party/boringssl/src/crypto/x509/by_dir.c +320 -337
- package/third_party/boringssl/src/crypto/x509/by_file.c +186 -186
- package/third_party/boringssl/src/crypto/x509/i2d_pr.c +11 -14
- package/third_party/boringssl/src/crypto/x509/internal.h +22 -22
- package/third_party/boringssl/src/crypto/x509/name_print.c +155 -150
- package/third_party/boringssl/src/crypto/x509/rsa_pss.c +27 -29
- package/third_party/boringssl/src/crypto/x509/t_crl.c +67 -70
- package/third_party/boringssl/src/crypto/x509/t_req.c +3 -5
- package/third_party/boringssl/src/crypto/x509/t_x509.c +280 -251
- package/third_party/boringssl/src/crypto/x509/t_x509a.c +52 -47
- package/third_party/boringssl/src/crypto/x509/x509.c +3 -4
- package/third_party/boringssl/src/crypto/x509/x509_att.c +234 -223
- package/third_party/boringssl/src/crypto/x509/x509_cmp.c +286 -296
- package/third_party/boringssl/src/crypto/x509/x509_d2.c +37 -32
- package/third_party/boringssl/src/crypto/x509/x509_def.c +14 -30
- package/third_party/boringssl/src/crypto/x509/x509_ext.c +55 -84
- package/third_party/boringssl/src/crypto/x509/x509_lu.c +545 -581
- package/third_party/boringssl/src/crypto/x509/x509_obj.c +131 -121
- package/third_party/boringssl/src/crypto/x509/x509_req.c +120 -139
- package/third_party/boringssl/src/crypto/x509/x509_set.c +128 -142
- package/third_party/boringssl/src/crypto/x509/x509_trs.c +185 -193
- package/third_party/boringssl/src/crypto/x509/x509_txt.c +70 -72
- package/third_party/boringssl/src/crypto/x509/x509_v3.c +172 -161
- package/third_party/boringssl/src/crypto/x509/x509_vfy.c +2041 -2053
- package/third_party/boringssl/src/crypto/x509/x509_vpm.c +441 -461
- package/third_party/boringssl/src/crypto/x509/x509cset.c +152 -170
- package/third_party/boringssl/src/crypto/x509/x509name.c +274 -260
- package/third_party/boringssl/src/crypto/x509/x509rset.c +43 -20
- package/third_party/boringssl/src/crypto/x509/x509spki.c +62 -63
- package/third_party/boringssl/src/crypto/x509/x_algor.c +64 -62
- package/third_party/boringssl/src/crypto/x509/x_all.c +103 -133
- package/third_party/boringssl/src/crypto/x509/x_attrib.c +23 -24
- package/third_party/boringssl/src/crypto/x509/x_crl.c +310 -321
- package/third_party/boringssl/src/crypto/x509/x_exten.c +6 -5
- package/third_party/boringssl/src/crypto/x509/x_info.c +31 -28
- package/third_party/boringssl/src/crypto/x509/x_name.c +361 -365
- package/third_party/boringssl/src/crypto/x509/x_pkey.c +38 -32
- package/third_party/boringssl/src/crypto/x509/x_pubkey.c +114 -117
- package/third_party/boringssl/src/crypto/x509/x_req.c +27 -29
- package/third_party/boringssl/src/crypto/x509/x_sig.c +2 -2
- package/third_party/boringssl/src/crypto/x509/x_spki.c +8 -10
- package/third_party/boringssl/src/crypto/x509/x_val.c +2 -2
- package/third_party/boringssl/src/crypto/x509/x_x509.c +212 -226
- package/third_party/boringssl/src/crypto/x509/x_x509a.c +112 -109
- package/third_party/boringssl/src/crypto/x509v3/ext_dat.h +10 -13
- package/third_party/boringssl/src/crypto/x509v3/internal.h +72 -87
- package/third_party/boringssl/src/crypto/x509v3/pcy_cache.c +184 -176
- package/third_party/boringssl/src/crypto/x509v3/pcy_data.c +58 -56
- package/third_party/boringssl/src/crypto/x509v3/pcy_lib.c +71 -70
- package/third_party/boringssl/src/crypto/x509v3/pcy_map.c +56 -58
- package/third_party/boringssl/src/crypto/x509v3/pcy_node.c +89 -91
- package/third_party/boringssl/src/crypto/x509v3/pcy_tree.c +585 -590
- package/third_party/boringssl/src/crypto/x509v3/v3_akey.c +118 -112
- package/third_party/boringssl/src/crypto/x509v3/v3_akeya.c +3 -3
- package/third_party/boringssl/src/crypto/x509v3/v3_alt.c +447 -451
- package/third_party/boringssl/src/crypto/x509v3/v3_bcons.c +44 -38
- package/third_party/boringssl/src/crypto/x509v3/v3_bitst.c +39 -43
- package/third_party/boringssl/src/crypto/x509v3/v3_conf.c +321 -320
- package/third_party/boringssl/src/crypto/x509v3/v3_cpols.c +352 -327
- package/third_party/boringssl/src/crypto/x509v3/v3_crld.c +437 -383
- package/third_party/boringssl/src/crypto/x509v3/v3_enum.c +23 -16
- package/third_party/boringssl/src/crypto/x509v3/v3_extku.c +62 -53
- package/third_party/boringssl/src/crypto/x509v3/v3_genn.c +118 -115
- package/third_party/boringssl/src/crypto/x509v3/v3_ia5.c +30 -31
- package/third_party/boringssl/src/crypto/x509v3/v3_info.c +112 -98
- package/third_party/boringssl/src/crypto/x509v3/v3_int.c +40 -15
- package/third_party/boringssl/src/crypto/x509v3/v3_lib.c +248 -252
- package/third_party/boringssl/src/crypto/x509v3/v3_ncons.c +390 -386
- package/third_party/boringssl/src/crypto/x509v3/v3_ocsp.c +45 -32
- package/third_party/boringssl/src/crypto/x509v3/v3_pci.c +206 -209
- package/third_party/boringssl/src/crypto/x509v3/v3_pcia.c +6 -8
- package/third_party/boringssl/src/crypto/x509v3/v3_pcons.c +54 -50
- package/third_party/boringssl/src/crypto/x509v3/v3_pmaps.c +66 -65
- package/third_party/boringssl/src/crypto/x509v3/v3_prn.c +144 -133
- package/third_party/boringssl/src/crypto/x509v3/v3_purp.c +695 -709
- package/third_party/boringssl/src/crypto/x509v3/v3_skey.c +75 -69
- package/third_party/boringssl/src/crypto/x509v3/v3_utl.c +1102 -1082
- package/third_party/boringssl/src/include/openssl/base.h +3 -1
- package/third_party/boringssl/src/include/openssl/bn.h +3 -0
- package/third_party/boringssl/src/include/openssl/bytestring.h +20 -0
- package/third_party/boringssl/src/include/openssl/evp.h +6 -5
- package/third_party/boringssl/src/include/openssl/kdf.h +91 -0
- package/third_party/boringssl/src/include/openssl/nid.h +4 -0
- package/third_party/boringssl/src/include/openssl/ssl.h +6 -1
- package/third_party/boringssl/src/include/openssl/stack.h +47 -32
- package/third_party/boringssl/src/include/openssl/trust_token.h +18 -3
- package/third_party/boringssl/src/include/openssl/x509.h +18 -0
- package/third_party/boringssl/src/ssl/ssl_file.cc +61 -99
- package/third_party/boringssl/src/ssl/ssl_test.cc +101 -0
- package/third_party/boringssl/src/util/doc.config +2 -1
- package/third_party/boringssl/src/util/fipstools/acvp/acvptool/subprocess/subprocess.go +8 -0
- package/third_party/googleurl/AUTHORS +16 -2
- package/third_party/googleurl/base/BUILD +1 -0
- package/third_party/googleurl/base/compiler_specific.h +16 -17
- package/third_party/googleurl/base/containers/contiguous_iterator.h +13 -9
- package/third_party/googleurl/base/containers/span.h +23 -8
- package/third_party/googleurl/base/memory/raw_ptr.h +17 -25
- package/third_party/googleurl/base/memory/raw_ptr_exclusion.h +21 -0
- package/third_party/googleurl/base/strings/escape.cc +14 -2
- package/third_party/googleurl/base/strings/safe_sprintf.h +1 -1
- package/third_party/googleurl/base/strings/string_number_conversions.cc +5 -3
- package/third_party/googleurl/base/strings/string_number_conversions_internal.h +5 -5
- package/third_party/googleurl/base/strings/string_piece.h +3 -3
- package/third_party/googleurl/base/strings/string_util.cc +4 -27
- package/third_party/googleurl/base/strings/string_util.h +43 -8
- package/third_party/googleurl/base/strings/string_util_internal.h +11 -12
- package/third_party/googleurl/base/strings/string_util_unittest.cc +33 -0
- package/third_party/googleurl/base/strings/string_util_win.cc +0 -5
- package/third_party/googleurl/base/strings/string_util_win.h +9 -1
- package/third_party/googleurl/base/strings/utf_offset_string_conversions.cc +1 -1
- package/third_party/googleurl/base/strings/utf_string_conversion_utils.cc +5 -8
- package/third_party/googleurl/base/strings/utf_string_conversion_utils.h +13 -10
- package/third_party/googleurl/base/strings/utf_string_conversions.cc +32 -25
- package/third_party/googleurl/base/template_util.h +23 -35
- package/third_party/googleurl/build/build_config.h +14 -3
- package/third_party/googleurl/copy.bara.sky +1 -1
- package/third_party/googleurl/url/gurl.cc +8 -4
- package/third_party/googleurl/url/gurl.h +1 -0
- package/third_party/googleurl/url/gurl_unittest.cc +1 -0
- package/third_party/googleurl/url/origin.h +36 -26
- package/third_party/googleurl/url/scheme_host_port.h +4 -1
- package/third_party/googleurl/url/url_canon.h +2 -1
- package/third_party/googleurl/url/url_canon_internal.cc +9 -7
- package/third_party/googleurl/url/url_canon_internal.h +16 -16
- package/third_party/googleurl/url/url_canon_stdstring.h +2 -1
- package/third_party/googleurl/url/url_util.cc +9 -8
- package/third_party/quiche/build/source_list.bzl +7 -0
- package/third_party/quiche/build/source_list.gni +7 -0
- package/third_party/quiche/build/source_list.json +7 -0
- package/third_party/quiche/quiche/common/platform/api/quiche_mem_slice.h +7 -3
- package/third_party/quiche/quiche/http2/adapter/nghttp2_adapter_test.cc +86 -2
- package/third_party/quiche/quiche/http2/adapter/oghttp2_adapter_test.cc +104 -2
- package/third_party/quiche/quiche/http2/adapter/oghttp2_session.cc +23 -0
- package/third_party/quiche/quiche/http2/adapter/oghttp2_session.h +6 -1
- package/third_party/quiche/quiche/quic/core/congestion_control/send_algorithm_test.cc +0 -16
- package/third_party/quiche/quiche/quic/core/crypto/crypto_protocol.h +1 -1
- package/third_party/quiche/quiche/quic/core/http/end_to_end_test.cc +56 -2
- package/third_party/quiche/quiche/quic/core/http/http_constants.cc +1 -0
- package/third_party/quiche/quiche/quic/core/http/http_constants.h +1 -0
- package/third_party/quiche/quiche/quic/core/http/http_encoder.cc +28 -17
- package/third_party/quiche/quiche/quic/core/http/http_encoder.h +5 -0
- package/third_party/quiche/quiche/quic/core/http/http_encoder_test.cc +26 -30
- package/third_party/quiche/quiche/quic/core/http/http_frames.h +1 -0
- package/third_party/quiche/quiche/quic/core/http/quic_server_session_base.cc +4 -4
- package/third_party/quiche/quiche/quic/core/http/quic_server_session_base_test.cc +1 -1
- package/third_party/quiche/quiche/quic/core/http/quic_spdy_client_session.cc +5 -1
- package/third_party/quiche/quiche/quic/core/http/quic_spdy_stream.cc +6 -33
- package/third_party/quiche/quiche/quic/core/http/quic_spdy_stream.h +0 -17
- package/third_party/quiche/quiche/quic/core/http/quic_spdy_stream_test.cc +5 -20
- package/third_party/quiche/quiche/quic/core/io/quic_event_loop.h +81 -0
- package/third_party/quiche/quiche/quic/core/io/quic_poll_event_loop.cc +265 -0
- package/third_party/quiche/quiche/quic/core/io/quic_poll_event_loop.h +152 -0
- package/third_party/quiche/quiche/quic/core/io/quic_poll_event_loop_test.cc +341 -0
- package/third_party/quiche/quiche/quic/core/quic_buffered_packet_store.cc +3 -1
- package/third_party/quiche/quiche/quic/core/quic_buffered_packet_store.h +7 -7
- package/third_party/quiche/quiche/quic/core/quic_buffered_packet_store_test.cc +4 -3
- package/third_party/quiche/quiche/quic/core/quic_connection.cc +69 -19
- package/third_party/quiche/quiche/quic/core/quic_connection.h +9 -3
- package/third_party/quiche/quiche/quic/core/quic_connection_id_manager.cc +29 -10
- package/third_party/quiche/quiche/quic/core/quic_connection_id_manager.h +5 -3
- package/third_party/quiche/quiche/quic/core/quic_connection_id_manager_test.cc +85 -22
- package/third_party/quiche/quiche/quic/core/quic_connection_test.cc +186 -30
- package/third_party/quiche/quiche/quic/core/quic_crypto_stream.cc +2 -1
- package/third_party/quiche/quiche/quic/core/quic_default_clock.cc +31 -0
- package/third_party/quiche/quiche/quic/core/quic_default_clock.h +34 -0
- package/third_party/quiche/quiche/quic/core/quic_default_connection_helper.h +49 -0
- package/third_party/quiche/quiche/quic/core/quic_dispatcher.cc +53 -37
- package/third_party/quiche/quiche/quic/core/quic_dispatcher.h +19 -11
- package/third_party/quiche/quiche/quic/core/quic_dispatcher_test.cc +15 -2
- package/third_party/quiche/quiche/quic/core/quic_flags_list.h +10 -4
- package/third_party/quiche/quiche/quic/core/quic_idle_network_detector.cc +2 -2
- package/third_party/quiche/quiche/quic/core/quic_idle_network_detector_test.cc +4 -4
- package/third_party/quiche/quiche/quic/core/quic_packet_creator.cc +14 -3
- package/third_party/quiche/quiche/quic/core/quic_packet_creator_test.cc +145 -2
- package/third_party/quiche/quiche/quic/core/quic_packets.cc +3 -1
- package/third_party/quiche/quiche/quic/core/quic_packets.h +4 -0
- package/third_party/quiche/quiche/quic/core/quic_sent_packet_manager.cc +13 -11
- package/third_party/quiche/quiche/quic/core/quic_sent_packet_manager.h +9 -0
- package/third_party/quiche/quiche/quic/core/quic_sent_packet_manager_test.cc +6 -0
- package/third_party/quiche/quiche/quic/core/quic_session.cc +3 -2
- package/third_party/quiche/quiche/quic/core/quic_session.h +8 -3
- package/third_party/quiche/quiche/quic/core/quic_types.cc +18 -0
- package/third_party/quiche/quiche/quic/core/quic_types.h +3 -0
- package/third_party/quiche/quiche/quic/core/tls_chlo_extractor.cc +3 -0
- package/third_party/quiche/quiche/quic/core/tls_chlo_extractor.h +10 -0
- package/third_party/quiche/quiche/quic/test_tools/mock_quic_session_visitor.h +1 -1
- package/third_party/quiche/quiche/quic/test_tools/quic_test_utils.h +1 -1
- package/third_party/quiche/quiche/quic/test_tools/server_thread.cc +3 -2
- package/third_party/quiche/quiche/quic/test_tools/simple_session_notifier.cc +7 -1
- package/third_party/quiche/quiche/quic/test_tools/simple_session_notifier.h +3 -0
- package/third_party/quiche/quiche/quic/test_tools/simulator/quic_endpoint.h +4 -2
- package/certs/ca.cnf +0 -69
- package/certs/generate_certs.sh +0 -53
- package/certs/generate_certs_leaf.sh +0 -53
- package/certs/leaf.cnf +0 -24
- package/certs/readme.txt +0 -2
- package/third_party/quiche/build/BUILD.bazel +0 -7
|
@@ -67,50 +67,51 @@
|
|
|
67
67
|
#include <openssl/x509.h>
|
|
68
68
|
#include <openssl/x509v3.h>
|
|
69
69
|
|
|
70
|
-
#include "internal.h"
|
|
71
70
|
#include "../internal.h"
|
|
72
71
|
#include "../x509v3/internal.h"
|
|
72
|
+
#include "internal.h"
|
|
73
73
|
|
|
74
74
|
static CRYPTO_EX_DATA_CLASS g_ex_data_class =
|
|
75
75
|
CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
// CRL score values
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
// No unhandled critical extensions
|
|
80
80
|
|
|
81
|
-
#define CRL_SCORE_NOCRITICAL
|
|
81
|
+
#define CRL_SCORE_NOCRITICAL 0x100
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
// certificate is within CRL scope
|
|
84
84
|
|
|
85
|
-
#define CRL_SCORE_SCOPE
|
|
85
|
+
#define CRL_SCORE_SCOPE 0x080
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
// CRL times valid
|
|
88
88
|
|
|
89
|
-
#define CRL_SCORE_TIME
|
|
89
|
+
#define CRL_SCORE_TIME 0x040
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
// Issuer name matches certificate
|
|
92
92
|
|
|
93
|
-
#define CRL_SCORE_ISSUER_NAME
|
|
93
|
+
#define CRL_SCORE_ISSUER_NAME 0x020
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
// If this score or above CRL is probably valid
|
|
96
96
|
|
|
97
|
-
#define CRL_SCORE_VALID
|
|
97
|
+
#define CRL_SCORE_VALID \
|
|
98
|
+
(CRL_SCORE_NOCRITICAL | CRL_SCORE_TIME | CRL_SCORE_SCOPE)
|
|
98
99
|
|
|
99
|
-
|
|
100
|
+
// CRL issuer is certificate issuer
|
|
100
101
|
|
|
101
|
-
#define CRL_SCORE_ISSUER_CERT
|
|
102
|
+
#define CRL_SCORE_ISSUER_CERT 0x018
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
// CRL issuer is on certificate path
|
|
104
105
|
|
|
105
|
-
#define CRL_SCORE_SAME_PATH
|
|
106
|
+
#define CRL_SCORE_SAME_PATH 0x008
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
// CRL issuer matches CRL AKID
|
|
108
109
|
|
|
109
|
-
#define CRL_SCORE_AKID
|
|
110
|
+
#define CRL_SCORE_AKID 0x004
|
|
110
111
|
|
|
111
|
-
|
|
112
|
+
// Have a delta CRL with valid times
|
|
112
113
|
|
|
113
|
-
#define CRL_SCORE_TIME_DELTA
|
|
114
|
+
#define CRL_SCORE_TIME_DELTA 0x002
|
|
114
115
|
|
|
115
116
|
static int null_callback(int ok, X509_STORE_CTX *e);
|
|
116
117
|
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
|
|
@@ -125,2323 +126,2310 @@ static int check_policy(X509_STORE_CTX *ctx);
|
|
|
125
126
|
|
|
126
127
|
static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
|
|
127
128
|
unsigned int *preasons, X509_CRL *crl, X509 *x);
|
|
128
|
-
static int get_crl_delta(X509_STORE_CTX *ctx,
|
|
129
|
-
|
|
130
|
-
static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
|
|
131
|
-
|
|
132
|
-
STACK_OF(X509_CRL) *crls);
|
|
129
|
+
static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
|
|
130
|
+
X509 *x);
|
|
131
|
+
static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pcrl_score,
|
|
132
|
+
X509_CRL *base, STACK_OF(X509_CRL) *crls);
|
|
133
133
|
static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
|
|
134
134
|
int *pcrl_score);
|
|
135
135
|
static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
|
|
136
136
|
unsigned int *preasons);
|
|
137
137
|
static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
|
|
138
|
-
static int check_crl_chain(X509_STORE_CTX *ctx,
|
|
139
|
-
STACK_OF(X509) *cert_path,
|
|
138
|
+
static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path,
|
|
140
139
|
STACK_OF(X509) *crl_path);
|
|
141
140
|
|
|
142
141
|
static int internal_verify(X509_STORE_CTX *ctx);
|
|
143
142
|
|
|
144
|
-
static int null_callback(int ok, X509_STORE_CTX *e)
|
|
145
|
-
{
|
|
146
|
-
return ok;
|
|
147
|
-
}
|
|
143
|
+
static int null_callback(int ok, X509_STORE_CTX *e) { return ok; }
|
|
148
144
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
static int cert_self_signed(X509 *x, int *out_is_self_signed)
|
|
153
|
-
{
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return 1;
|
|
145
|
+
// cert_self_signed checks if |x| is self-signed. If |x| is valid, it returns
|
|
146
|
+
// one and sets |*out_is_self_signed| to the result. If |x| is invalid, it
|
|
147
|
+
// returns zero.
|
|
148
|
+
static int cert_self_signed(X509 *x, int *out_is_self_signed) {
|
|
149
|
+
if (!x509v3_cache_extensions(x)) {
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
152
|
+
*out_is_self_signed = (x->ex_flags & EXFLAG_SS) != 0;
|
|
153
|
+
return 1;
|
|
159
154
|
}
|
|
160
155
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
|
|
164
|
-
{
|
|
165
|
-
STACK_OF(X509) *certs;
|
|
166
|
-
X509 *xtmp = NULL;
|
|
167
|
-
size_t i;
|
|
168
|
-
/* Lookup all certs with matching subject name */
|
|
169
|
-
certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
|
|
170
|
-
if (certs == NULL)
|
|
171
|
-
return NULL;
|
|
172
|
-
/* Look for exact match */
|
|
173
|
-
for (i = 0; i < sk_X509_num(certs); i++) {
|
|
174
|
-
xtmp = sk_X509_value(certs, i);
|
|
175
|
-
if (!X509_cmp(xtmp, x))
|
|
176
|
-
break;
|
|
177
|
-
}
|
|
178
|
-
if (i < sk_X509_num(certs))
|
|
179
|
-
X509_up_ref(xtmp);
|
|
180
|
-
else
|
|
181
|
-
xtmp = NULL;
|
|
182
|
-
sk_X509_pop_free(certs, X509_free);
|
|
183
|
-
return xtmp;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
int X509_verify_cert(X509_STORE_CTX *ctx)
|
|
187
|
-
{
|
|
188
|
-
X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
|
|
189
|
-
int bad_chain = 0;
|
|
190
|
-
X509_VERIFY_PARAM *param = ctx->param;
|
|
191
|
-
int depth, i, ok = 0;
|
|
192
|
-
int num, j, retry, trust;
|
|
193
|
-
STACK_OF(X509) *sktmp = NULL;
|
|
194
|
-
|
|
195
|
-
if (ctx->cert == NULL) {
|
|
196
|
-
OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
|
|
197
|
-
ctx->error = X509_V_ERR_INVALID_CALL;
|
|
198
|
-
return -1;
|
|
199
|
-
}
|
|
200
|
-
if (ctx->chain != NULL) {
|
|
201
|
-
/*
|
|
202
|
-
* This X509_STORE_CTX has already been used to verify a cert. We
|
|
203
|
-
* cannot do another one.
|
|
204
|
-
*/
|
|
205
|
-
OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
|
206
|
-
ctx->error = X509_V_ERR_INVALID_CALL;
|
|
207
|
-
return -1;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/*
|
|
211
|
-
* first we make sure the chain we are going to build is present and that
|
|
212
|
-
* the first entry is in place
|
|
213
|
-
*/
|
|
214
|
-
ctx->chain = sk_X509_new_null();
|
|
215
|
-
if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
|
|
216
|
-
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
217
|
-
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
218
|
-
goto end;
|
|
219
|
-
}
|
|
220
|
-
X509_up_ref(ctx->cert);
|
|
221
|
-
ctx->last_untrusted = 1;
|
|
156
|
+
// Given a certificate try and find an exact match in the store
|
|
222
157
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
158
|
+
static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x) {
|
|
159
|
+
STACK_OF(X509) *certs;
|
|
160
|
+
X509 *xtmp = NULL;
|
|
161
|
+
size_t i;
|
|
162
|
+
// Lookup all certs with matching subject name
|
|
163
|
+
certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
|
|
164
|
+
if (certs == NULL) {
|
|
165
|
+
return NULL;
|
|
166
|
+
}
|
|
167
|
+
// Look for exact match
|
|
168
|
+
for (i = 0; i < sk_X509_num(certs); i++) {
|
|
169
|
+
xtmp = sk_X509_value(certs, i);
|
|
170
|
+
if (!X509_cmp(xtmp, x)) {
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (i < sk_X509_num(certs)) {
|
|
175
|
+
X509_up_ref(xtmp);
|
|
176
|
+
} else {
|
|
177
|
+
xtmp = NULL;
|
|
178
|
+
}
|
|
179
|
+
sk_X509_pop_free(certs, X509_free);
|
|
180
|
+
return xtmp;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
int X509_verify_cert(X509_STORE_CTX *ctx) {
|
|
184
|
+
X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
|
|
185
|
+
int bad_chain = 0;
|
|
186
|
+
X509_VERIFY_PARAM *param = ctx->param;
|
|
187
|
+
int depth, i, ok = 0;
|
|
188
|
+
int num, j, retry, trust;
|
|
189
|
+
STACK_OF(X509) *sktmp = NULL;
|
|
190
|
+
|
|
191
|
+
if (ctx->cert == NULL) {
|
|
192
|
+
OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
|
|
193
|
+
ctx->error = X509_V_ERR_INVALID_CALL;
|
|
194
|
+
return -1;
|
|
195
|
+
}
|
|
196
|
+
if (ctx->chain != NULL) {
|
|
197
|
+
// This X509_STORE_CTX has already been used to verify a cert. We
|
|
198
|
+
// cannot do another one.
|
|
199
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
|
200
|
+
ctx->error = X509_V_ERR_INVALID_CALL;
|
|
201
|
+
return -1;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// first we make sure the chain we are going to build is present and that
|
|
205
|
+
// the first entry is in place
|
|
206
|
+
ctx->chain = sk_X509_new_null();
|
|
207
|
+
if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) {
|
|
208
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
209
|
+
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
210
|
+
goto end;
|
|
211
|
+
}
|
|
212
|
+
X509_up_ref(ctx->cert);
|
|
213
|
+
ctx->last_untrusted = 1;
|
|
214
|
+
|
|
215
|
+
// We use a temporary STACK so we can chop and hack at it.
|
|
216
|
+
if (ctx->untrusted != NULL && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
|
|
217
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
218
|
+
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
219
|
+
goto end;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
num = sk_X509_num(ctx->chain);
|
|
223
|
+
x = sk_X509_value(ctx->chain, num - 1);
|
|
224
|
+
depth = param->depth;
|
|
225
|
+
|
|
226
|
+
for (;;) {
|
|
227
|
+
// If we have enough, we break
|
|
228
|
+
if (depth < num) {
|
|
229
|
+
break; // FIXME: If this happens, we should take
|
|
230
|
+
// note of it and, if appropriate, use the
|
|
231
|
+
// X509_V_ERR_CERT_CHAIN_TOO_LONG error code
|
|
232
|
+
// later.
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
int is_self_signed;
|
|
236
|
+
if (!cert_self_signed(x, &is_self_signed)) {
|
|
237
|
+
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
238
|
+
goto end;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// If we are self signed, we break
|
|
242
|
+
if (is_self_signed) {
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
// If asked see if we can find issuer in trusted store first
|
|
246
|
+
if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
|
|
247
|
+
ok = ctx->get_issuer(&xtmp, ctx, x);
|
|
248
|
+
if (ok < 0) {
|
|
249
|
+
ctx->error = X509_V_ERR_STORE_LOOKUP;
|
|
228
250
|
goto end;
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
for (;;) {
|
|
236
|
-
/* If we have enough, we break */
|
|
237
|
-
if (depth < num)
|
|
238
|
-
break; /* FIXME: If this happens, we should take
|
|
239
|
-
* note of it and, if appropriate, use the
|
|
240
|
-
* X509_V_ERR_CERT_CHAIN_TOO_LONG error code
|
|
241
|
-
* later. */
|
|
242
|
-
|
|
243
|
-
int is_self_signed;
|
|
244
|
-
if (!cert_self_signed(x, &is_self_signed)) {
|
|
245
|
-
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
246
|
-
goto end;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/* If we are self signed, we break */
|
|
250
|
-
if (is_self_signed)
|
|
251
|
-
break;
|
|
252
|
-
/*
|
|
253
|
-
* If asked see if we can find issuer in trusted store first
|
|
254
|
-
*/
|
|
255
|
-
if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
|
|
256
|
-
ok = ctx->get_issuer(&xtmp, ctx, x);
|
|
257
|
-
if (ok < 0) {
|
|
258
|
-
ctx->error = X509_V_ERR_STORE_LOOKUP;
|
|
259
|
-
goto end;
|
|
260
|
-
}
|
|
261
|
-
/*
|
|
262
|
-
* If successful for now free up cert so it will be picked up
|
|
263
|
-
* again later.
|
|
264
|
-
*/
|
|
265
|
-
if (ok > 0) {
|
|
266
|
-
X509_free(xtmp);
|
|
267
|
-
break;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/* If we were passed a cert chain, use it first */
|
|
272
|
-
if (sktmp != NULL) {
|
|
273
|
-
xtmp = find_issuer(ctx, sktmp, x);
|
|
274
|
-
if (xtmp != NULL) {
|
|
275
|
-
if (!sk_X509_push(ctx->chain, xtmp)) {
|
|
276
|
-
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
277
|
-
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
278
|
-
ok = 0;
|
|
279
|
-
goto end;
|
|
280
|
-
}
|
|
281
|
-
X509_up_ref(xtmp);
|
|
282
|
-
(void)sk_X509_delete_ptr(sktmp, xtmp);
|
|
283
|
-
ctx->last_untrusted++;
|
|
284
|
-
x = xtmp;
|
|
285
|
-
num++;
|
|
286
|
-
/*
|
|
287
|
-
* reparse the full chain for the next one
|
|
288
|
-
*/
|
|
289
|
-
continue;
|
|
290
|
-
}
|
|
291
|
-
}
|
|
251
|
+
}
|
|
252
|
+
// If successful for now free up cert so it will be picked up
|
|
253
|
+
// again later.
|
|
254
|
+
if (ok > 0) {
|
|
255
|
+
X509_free(xtmp);
|
|
292
256
|
break;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
* Examine last certificate in chain and see if it is self signed.
|
|
306
|
-
*/
|
|
307
|
-
i = sk_X509_num(ctx->chain);
|
|
308
|
-
x = sk_X509_value(ctx->chain, i - 1);
|
|
309
|
-
|
|
310
|
-
int is_self_signed;
|
|
311
|
-
if (!cert_self_signed(x, &is_self_signed)) {
|
|
312
|
-
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
313
|
-
goto end;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (is_self_signed) {
|
|
317
|
-
/* we have a self signed certificate */
|
|
318
|
-
if (sk_X509_num(ctx->chain) == 1) {
|
|
319
|
-
/*
|
|
320
|
-
* We have a single self signed certificate: see if we can
|
|
321
|
-
* find it in the store. We must have an exact match to avoid
|
|
322
|
-
* possible impersonation.
|
|
323
|
-
*/
|
|
324
|
-
ok = ctx->get_issuer(&xtmp, ctx, x);
|
|
325
|
-
if ((ok <= 0) || X509_cmp(x, xtmp)) {
|
|
326
|
-
ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
|
|
327
|
-
ctx->current_cert = x;
|
|
328
|
-
ctx->error_depth = i - 1;
|
|
329
|
-
if (ok == 1)
|
|
330
|
-
X509_free(xtmp);
|
|
331
|
-
bad_chain = 1;
|
|
332
|
-
ok = ctx->verify_cb(0, ctx);
|
|
333
|
-
if (!ok)
|
|
334
|
-
goto end;
|
|
335
|
-
} else {
|
|
336
|
-
/*
|
|
337
|
-
* We have a match: replace certificate with store
|
|
338
|
-
* version so we get any trust settings.
|
|
339
|
-
*/
|
|
340
|
-
X509_free(x);
|
|
341
|
-
x = xtmp;
|
|
342
|
-
(void)sk_X509_set(ctx->chain, i - 1, x);
|
|
343
|
-
ctx->last_untrusted = 0;
|
|
344
|
-
}
|
|
345
|
-
} else {
|
|
346
|
-
/*
|
|
347
|
-
* extract and save self signed certificate for later use
|
|
348
|
-
*/
|
|
349
|
-
chain_ss = sk_X509_pop(ctx->chain);
|
|
350
|
-
ctx->last_untrusted--;
|
|
351
|
-
num--;
|
|
352
|
-
j--;
|
|
353
|
-
x = sk_X509_value(ctx->chain, num - 1);
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
/* We now lookup certs from the certificate store */
|
|
357
|
-
for (;;) {
|
|
358
|
-
/* If we have enough, we break */
|
|
359
|
-
if (depth < num)
|
|
360
|
-
break;
|
|
361
|
-
if (!cert_self_signed(x, &is_self_signed)) {
|
|
362
|
-
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
363
|
-
goto end;
|
|
364
|
-
}
|
|
365
|
-
/* If we are self signed, we break */
|
|
366
|
-
if (is_self_signed)
|
|
367
|
-
break;
|
|
368
|
-
ok = ctx->get_issuer(&xtmp, ctx, x);
|
|
369
|
-
|
|
370
|
-
if (ok < 0) {
|
|
371
|
-
ctx->error = X509_V_ERR_STORE_LOOKUP;
|
|
372
|
-
goto end;
|
|
373
|
-
}
|
|
374
|
-
if (ok == 0)
|
|
375
|
-
break;
|
|
376
|
-
x = xtmp;
|
|
377
|
-
if (!sk_X509_push(ctx->chain, x)) {
|
|
378
|
-
X509_free(xtmp);
|
|
379
|
-
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
380
|
-
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
381
|
-
ok = 0;
|
|
382
|
-
goto end;
|
|
383
|
-
}
|
|
384
|
-
num++;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// If we were passed a cert chain, use it first
|
|
261
|
+
if (sktmp != NULL) {
|
|
262
|
+
xtmp = find_issuer(ctx, sktmp, x);
|
|
263
|
+
if (xtmp != NULL) {
|
|
264
|
+
if (!sk_X509_push(ctx->chain, xtmp)) {
|
|
265
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
266
|
+
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
267
|
+
ok = 0;
|
|
268
|
+
goto end;
|
|
385
269
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
270
|
+
X509_up_ref(xtmp);
|
|
271
|
+
(void)sk_X509_delete_ptr(sktmp, xtmp);
|
|
272
|
+
ctx->last_untrusted++;
|
|
273
|
+
x = xtmp;
|
|
274
|
+
num++;
|
|
275
|
+
// reparse the full chain for the next one
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Remember how many untrusted certs we have
|
|
283
|
+
j = num;
|
|
284
|
+
// at this point, chain should contain a list of untrusted certificates.
|
|
285
|
+
// We now need to add at least one trusted one, if possible, otherwise we
|
|
286
|
+
// complain.
|
|
287
|
+
|
|
288
|
+
do {
|
|
289
|
+
// Examine last certificate in chain and see if it is self signed.
|
|
290
|
+
i = sk_X509_num(ctx->chain);
|
|
291
|
+
x = sk_X509_value(ctx->chain, i - 1);
|
|
292
|
+
|
|
293
|
+
int is_self_signed;
|
|
294
|
+
if (!cert_self_signed(x, &is_self_signed)) {
|
|
295
|
+
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
296
|
+
goto end;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (is_self_signed) {
|
|
300
|
+
// we have a self signed certificate
|
|
301
|
+
if (sk_X509_num(ctx->chain) == 1) {
|
|
302
|
+
// We have a single self signed certificate: see if we can
|
|
303
|
+
// find it in the store. We must have an exact match to avoid
|
|
304
|
+
// possible impersonation.
|
|
305
|
+
ok = ctx->get_issuer(&xtmp, ctx, x);
|
|
306
|
+
if ((ok <= 0) || X509_cmp(x, xtmp)) {
|
|
307
|
+
ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
|
|
308
|
+
ctx->current_cert = x;
|
|
309
|
+
ctx->error_depth = i - 1;
|
|
310
|
+
if (ok == 1) {
|
|
311
|
+
X509_free(xtmp);
|
|
312
|
+
}
|
|
313
|
+
bad_chain = 1;
|
|
314
|
+
ok = ctx->verify_cb(0, ctx);
|
|
315
|
+
if (!ok) {
|
|
393
316
|
goto end;
|
|
394
|
-
|
|
395
|
-
/*
|
|
396
|
-
* If it's not explicitly trusted then check if there is an alternative
|
|
397
|
-
* chain that could be used. We only do this if we haven't already
|
|
398
|
-
* checked via TRUSTED_FIRST and the user hasn't switched off alternate
|
|
399
|
-
* chain checking
|
|
400
|
-
*/
|
|
401
|
-
retry = 0;
|
|
402
|
-
if (trust != X509_TRUST_TRUSTED
|
|
403
|
-
&& !(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
|
|
404
|
-
&& !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
|
|
405
|
-
while (j-- > 1) {
|
|
406
|
-
xtmp2 = sk_X509_value(ctx->chain, j - 1);
|
|
407
|
-
ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
|
|
408
|
-
if (ok < 0)
|
|
409
|
-
goto end;
|
|
410
|
-
/* Check if we found an alternate chain */
|
|
411
|
-
if (ok > 0) {
|
|
412
|
-
/*
|
|
413
|
-
* Free up the found cert we'll add it again later
|
|
414
|
-
*/
|
|
415
|
-
X509_free(xtmp);
|
|
416
|
-
|
|
417
|
-
/*
|
|
418
|
-
* Dump all the certs above this point - we've found an
|
|
419
|
-
* alternate chain
|
|
420
|
-
*/
|
|
421
|
-
while (num > j) {
|
|
422
|
-
xtmp = sk_X509_pop(ctx->chain);
|
|
423
|
-
X509_free(xtmp);
|
|
424
|
-
num--;
|
|
425
|
-
}
|
|
426
|
-
ctx->last_untrusted = sk_X509_num(ctx->chain);
|
|
427
|
-
retry = 1;
|
|
428
|
-
break;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
} while (retry);
|
|
433
|
-
|
|
434
|
-
/*
|
|
435
|
-
* If not explicitly trusted then indicate error unless it's a single
|
|
436
|
-
* self signed certificate in which case we've indicated an error already
|
|
437
|
-
* and set bad_chain == 1
|
|
438
|
-
*/
|
|
439
|
-
if (trust != X509_TRUST_TRUSTED && !bad_chain) {
|
|
440
|
-
if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
|
|
441
|
-
if (ctx->last_untrusted >= num)
|
|
442
|
-
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
|
|
443
|
-
else
|
|
444
|
-
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
|
|
445
|
-
ctx->current_cert = x;
|
|
317
|
+
}
|
|
446
318
|
} else {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
chain_ss = NULL;
|
|
319
|
+
// We have a match: replace certificate with store
|
|
320
|
+
// version so we get any trust settings.
|
|
321
|
+
X509_free(x);
|
|
322
|
+
x = xtmp;
|
|
323
|
+
(void)sk_X509_set(ctx->chain, i - 1, x);
|
|
324
|
+
ctx->last_untrusted = 0;
|
|
454
325
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
326
|
+
} else {
|
|
327
|
+
// extract and save self signed certificate for later use
|
|
328
|
+
chain_ss = sk_X509_pop(ctx->chain);
|
|
329
|
+
ctx->last_untrusted--;
|
|
330
|
+
num--;
|
|
331
|
+
j--;
|
|
332
|
+
x = sk_X509_value(ctx->chain, num - 1);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// We now lookup certs from the certificate store
|
|
336
|
+
for (;;) {
|
|
337
|
+
// If we have enough, we break
|
|
338
|
+
if (depth < num) {
|
|
339
|
+
break;
|
|
340
|
+
}
|
|
341
|
+
if (!cert_self_signed(x, &is_self_signed)) {
|
|
342
|
+
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
467
343
|
goto end;
|
|
344
|
+
}
|
|
345
|
+
// If we are self signed, we break
|
|
346
|
+
if (is_self_signed) {
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
ok = ctx->get_issuer(&xtmp, ctx, x);
|
|
468
350
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
if (!ok)
|
|
351
|
+
if (ok < 0) {
|
|
352
|
+
ctx->error = X509_V_ERR_STORE_LOOKUP;
|
|
472
353
|
goto end;
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
354
|
+
}
|
|
355
|
+
if (ok == 0) {
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
x = xtmp;
|
|
359
|
+
if (!sk_X509_push(ctx->chain, x)) {
|
|
360
|
+
X509_free(xtmp);
|
|
361
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
362
|
+
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
363
|
+
ok = 0;
|
|
481
364
|
goto end;
|
|
365
|
+
}
|
|
366
|
+
num++;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// we now have our chain, lets check it...
|
|
370
|
+
trust = check_trust(ctx);
|
|
371
|
+
|
|
372
|
+
// If explicitly rejected error
|
|
373
|
+
if (trust == X509_TRUST_REJECTED) {
|
|
374
|
+
ok = 0;
|
|
375
|
+
goto end;
|
|
376
|
+
}
|
|
377
|
+
// If it's not explicitly trusted then check if there is an alternative
|
|
378
|
+
// chain that could be used. We only do this if we haven't already
|
|
379
|
+
// checked via TRUSTED_FIRST and the user hasn't switched off alternate
|
|
380
|
+
// chain checking
|
|
381
|
+
retry = 0;
|
|
382
|
+
if (trust != X509_TRUST_TRUSTED &&
|
|
383
|
+
!(ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) &&
|
|
384
|
+
!(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
|
|
385
|
+
while (j-- > 1) {
|
|
386
|
+
xtmp2 = sk_X509_value(ctx->chain, j - 1);
|
|
387
|
+
ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
|
|
388
|
+
if (ok < 0) {
|
|
389
|
+
goto end;
|
|
390
|
+
}
|
|
391
|
+
// Check if we found an alternate chain
|
|
392
|
+
if (ok > 0) {
|
|
393
|
+
// Free up the found cert we'll add it again later
|
|
394
|
+
X509_free(xtmp);
|
|
395
|
+
|
|
396
|
+
// Dump all the certs above this point - we've found an
|
|
397
|
+
// alternate chain
|
|
398
|
+
while (num > j) {
|
|
399
|
+
xtmp = sk_X509_pop(ctx->chain);
|
|
400
|
+
X509_free(xtmp);
|
|
401
|
+
num--;
|
|
402
|
+
}
|
|
403
|
+
ctx->last_untrusted = sk_X509_num(ctx->chain);
|
|
404
|
+
retry = 1;
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
} while (retry);
|
|
410
|
+
|
|
411
|
+
// If not explicitly trusted then indicate error unless it's a single
|
|
412
|
+
// self signed certificate in which case we've indicated an error already
|
|
413
|
+
// and set bad_chain == 1
|
|
414
|
+
if (trust != X509_TRUST_TRUSTED && !bad_chain) {
|
|
415
|
+
if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
|
|
416
|
+
if (ctx->last_untrusted >= num) {
|
|
417
|
+
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
|
|
418
|
+
} else {
|
|
419
|
+
ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
|
|
420
|
+
}
|
|
421
|
+
ctx->current_cert = x;
|
|
422
|
+
} else {
|
|
423
|
+
sk_X509_push(ctx->chain, chain_ss);
|
|
424
|
+
num++;
|
|
425
|
+
ctx->last_untrusted = num;
|
|
426
|
+
ctx->current_cert = chain_ss;
|
|
427
|
+
ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
|
|
428
|
+
chain_ss = NULL;
|
|
429
|
+
}
|
|
482
430
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
ok = ctx->verify_cb(0, ctx);
|
|
489
|
-
if (!ok)
|
|
490
|
-
goto end;
|
|
431
|
+
ctx->error_depth = num - 1;
|
|
432
|
+
bad_chain = 1;
|
|
433
|
+
ok = ctx->verify_cb(0, ctx);
|
|
434
|
+
if (!ok) {
|
|
435
|
+
goto end;
|
|
491
436
|
}
|
|
437
|
+
}
|
|
492
438
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
ok = ctx->verify(ctx);
|
|
496
|
-
else
|
|
497
|
-
ok = internal_verify(ctx);
|
|
498
|
-
if (!ok)
|
|
499
|
-
goto end;
|
|
439
|
+
// We have the chain complete: now we need to check its purpose
|
|
440
|
+
ok = check_chain_extensions(ctx);
|
|
500
441
|
|
|
501
|
-
|
|
442
|
+
if (!ok) {
|
|
443
|
+
goto end;
|
|
444
|
+
}
|
|
502
445
|
|
|
503
|
-
|
|
504
|
-
if (!ok)
|
|
505
|
-
goto end;
|
|
446
|
+
ok = check_id(ctx);
|
|
506
447
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
448
|
+
if (!ok) {
|
|
449
|
+
goto end;
|
|
450
|
+
}
|
|
510
451
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
sk_X509_free(sktmp);
|
|
514
|
-
if (chain_ss != NULL)
|
|
515
|
-
X509_free(chain_ss);
|
|
452
|
+
// Check revocation status: we do this after copying parameters because
|
|
453
|
+
// they may be needed for CRL signature verification.
|
|
516
454
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
}
|
|
455
|
+
ok = ctx->check_revocation(ctx);
|
|
456
|
+
if (!ok) {
|
|
457
|
+
goto end;
|
|
458
|
+
}
|
|
522
459
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
460
|
+
int err = X509_chain_check_suiteb(&ctx->error_depth, NULL, ctx->chain,
|
|
461
|
+
ctx->param->flags);
|
|
462
|
+
if (err != X509_V_OK) {
|
|
463
|
+
ctx->error = err;
|
|
464
|
+
ctx->current_cert = sk_X509_value(ctx->chain, ctx->error_depth);
|
|
465
|
+
ok = ctx->verify_cb(0, ctx);
|
|
466
|
+
if (!ok) {
|
|
467
|
+
goto end;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// At this point, we have a chain and need to verify it
|
|
472
|
+
if (ctx->verify != NULL) {
|
|
473
|
+
ok = ctx->verify(ctx);
|
|
474
|
+
} else {
|
|
475
|
+
ok = internal_verify(ctx);
|
|
476
|
+
}
|
|
477
|
+
if (!ok) {
|
|
478
|
+
goto end;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// Check name constraints
|
|
482
|
+
|
|
483
|
+
ok = check_name_constraints(ctx);
|
|
484
|
+
if (!ok) {
|
|
485
|
+
goto end;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// If we get this far evaluate policies
|
|
489
|
+
if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) {
|
|
490
|
+
ok = ctx->check_policy(ctx);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
end:
|
|
494
|
+
if (sktmp != NULL) {
|
|
495
|
+
sk_X509_free(sktmp);
|
|
496
|
+
}
|
|
497
|
+
if (chain_ss != NULL) {
|
|
498
|
+
X509_free(chain_ss);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Safety net, error returns must set ctx->error
|
|
502
|
+
if (ok <= 0 && ctx->error == X509_V_OK) {
|
|
503
|
+
ctx->error = X509_V_ERR_UNSPECIFIED;
|
|
504
|
+
}
|
|
505
|
+
return ok;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// Given a STACK_OF(X509) find the issuer of cert (if any)
|
|
509
|
+
|
|
510
|
+
static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) {
|
|
511
|
+
size_t i;
|
|
512
|
+
X509 *issuer;
|
|
513
|
+
for (i = 0; i < sk_X509_num(sk); i++) {
|
|
514
|
+
issuer = sk_X509_value(sk, i);
|
|
515
|
+
if (ctx->check_issued(ctx, x, issuer)) {
|
|
516
|
+
return issuer;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return NULL;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// Given a possible certificate and issuer check them
|
|
523
|
+
|
|
524
|
+
static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) {
|
|
525
|
+
int ret;
|
|
526
|
+
ret = X509_check_issued(issuer, x);
|
|
527
|
+
if (ret == X509_V_OK) {
|
|
528
|
+
return 1;
|
|
529
|
+
}
|
|
530
|
+
// If we haven't asked for issuer errors don't set ctx
|
|
531
|
+
if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) {
|
|
532
|
+
return 0;
|
|
533
|
+
}
|
|
526
534
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
for (i = 0; i < sk_X509_num(sk); i++) {
|
|
532
|
-
issuer = sk_X509_value(sk, i);
|
|
533
|
-
if (ctx->check_issued(ctx, x, issuer))
|
|
534
|
-
return issuer;
|
|
535
|
-
}
|
|
536
|
-
return NULL;
|
|
535
|
+
ctx->error = ret;
|
|
536
|
+
ctx->current_cert = x;
|
|
537
|
+
ctx->current_issuer = issuer;
|
|
538
|
+
return ctx->verify_cb(0, ctx);
|
|
537
539
|
}
|
|
538
540
|
|
|
539
|
-
|
|
541
|
+
// Alternative lookup method: look from a STACK stored in other_ctx
|
|
540
542
|
|
|
541
|
-
static int
|
|
542
|
-
|
|
543
|
+
static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) {
|
|
544
|
+
*issuer = find_issuer(ctx, ctx->other_ctx, x);
|
|
545
|
+
if (*issuer) {
|
|
546
|
+
X509_up_ref(*issuer);
|
|
547
|
+
return 1;
|
|
548
|
+
} else {
|
|
549
|
+
return 0;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Check a certificate chains extensions for consistency with the supplied
|
|
554
|
+
// purpose
|
|
555
|
+
|
|
556
|
+
static int check_chain_extensions(X509_STORE_CTX *ctx) {
|
|
557
|
+
int i, ok = 0, plen = 0;
|
|
558
|
+
X509 *x;
|
|
559
|
+
int proxy_path_length = 0;
|
|
560
|
+
int purpose;
|
|
561
|
+
int allow_proxy_certs;
|
|
562
|
+
|
|
563
|
+
enum {
|
|
564
|
+
// ca_or_leaf allows either type of certificate so that direct use of
|
|
565
|
+
// self-signed certificates works.
|
|
566
|
+
ca_or_leaf,
|
|
567
|
+
must_be_ca,
|
|
568
|
+
must_not_be_ca,
|
|
569
|
+
} ca_requirement;
|
|
570
|
+
|
|
571
|
+
// CRL path validation
|
|
572
|
+
if (ctx->parent) {
|
|
573
|
+
allow_proxy_certs = 0;
|
|
574
|
+
purpose = X509_PURPOSE_CRL_SIGN;
|
|
575
|
+
} else {
|
|
576
|
+
allow_proxy_certs = !!(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
|
|
577
|
+
purpose = ctx->param->purpose;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
ca_requirement = ca_or_leaf;
|
|
581
|
+
|
|
582
|
+
// Check all untrusted certificates
|
|
583
|
+
for (i = 0; i < ctx->last_untrusted; i++) {
|
|
543
584
|
int ret;
|
|
544
|
-
|
|
545
|
-
if (
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
{
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
X509_up_ref(*issuer);
|
|
564
|
-
return 1;
|
|
565
|
-
} else
|
|
566
|
-
return 0;
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
/*
|
|
570
|
-
* Check a certificate chains extensions for consistency with the supplied
|
|
571
|
-
* purpose
|
|
572
|
-
*/
|
|
573
|
-
|
|
574
|
-
static int check_chain_extensions(X509_STORE_CTX *ctx)
|
|
575
|
-
{
|
|
576
|
-
int i, ok = 0, plen = 0;
|
|
577
|
-
X509 *x;
|
|
578
|
-
int proxy_path_length = 0;
|
|
579
|
-
int purpose;
|
|
580
|
-
int allow_proxy_certs;
|
|
581
|
-
|
|
582
|
-
enum {
|
|
583
|
-
// ca_or_leaf allows either type of certificate so that direct use of
|
|
584
|
-
// self-signed certificates works.
|
|
585
|
-
ca_or_leaf,
|
|
586
|
-
must_be_ca,
|
|
587
|
-
must_not_be_ca,
|
|
588
|
-
} ca_requirement;
|
|
589
|
-
|
|
590
|
-
/* CRL path validation */
|
|
591
|
-
if (ctx->parent) {
|
|
592
|
-
allow_proxy_certs = 0;
|
|
593
|
-
purpose = X509_PURPOSE_CRL_SIGN;
|
|
594
|
-
} else {
|
|
595
|
-
allow_proxy_certs =
|
|
596
|
-
! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
|
|
597
|
-
purpose = ctx->param->purpose;
|
|
585
|
+
x = sk_X509_value(ctx->chain, i);
|
|
586
|
+
if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
|
|
587
|
+
(x->ex_flags & EXFLAG_CRITICAL)) {
|
|
588
|
+
ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
|
|
589
|
+
ctx->error_depth = i;
|
|
590
|
+
ctx->current_cert = x;
|
|
591
|
+
ok = ctx->verify_cb(0, ctx);
|
|
592
|
+
if (!ok) {
|
|
593
|
+
goto end;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
|
|
597
|
+
ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
|
|
598
|
+
ctx->error_depth = i;
|
|
599
|
+
ctx->current_cert = x;
|
|
600
|
+
ok = ctx->verify_cb(0, ctx);
|
|
601
|
+
if (!ok) {
|
|
602
|
+
goto end;
|
|
603
|
+
}
|
|
598
604
|
}
|
|
599
605
|
|
|
600
|
-
ca_requirement
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
ctx->current_cert = x;
|
|
611
|
-
ok = ctx->verify_cb(0, ctx);
|
|
612
|
-
if (!ok)
|
|
613
|
-
goto end;
|
|
614
|
-
}
|
|
615
|
-
if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
|
|
616
|
-
ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
|
|
617
|
-
ctx->error_depth = i;
|
|
618
|
-
ctx->current_cert = x;
|
|
619
|
-
ok = ctx->verify_cb(0, ctx);
|
|
620
|
-
if (!ok)
|
|
621
|
-
goto end;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
switch (ca_requirement) {
|
|
625
|
-
case ca_or_leaf:
|
|
626
|
-
ret = 1;
|
|
627
|
-
break;
|
|
628
|
-
case must_not_be_ca:
|
|
629
|
-
if (X509_check_ca(x)) {
|
|
630
|
-
ret = 0;
|
|
631
|
-
ctx->error = X509_V_ERR_INVALID_NON_CA;
|
|
632
|
-
} else
|
|
633
|
-
ret = 1;
|
|
634
|
-
break;
|
|
635
|
-
case must_be_ca:
|
|
636
|
-
if (!X509_check_ca(x)) {
|
|
637
|
-
ret = 0;
|
|
638
|
-
ctx->error = X509_V_ERR_INVALID_CA;
|
|
639
|
-
} else
|
|
640
|
-
ret = 1;
|
|
641
|
-
break;
|
|
642
|
-
default:
|
|
643
|
-
// impossible.
|
|
644
|
-
ret = 0;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
if (ret == 0) {
|
|
648
|
-
ctx->error_depth = i;
|
|
649
|
-
ctx->current_cert = x;
|
|
650
|
-
ok = ctx->verify_cb(0, ctx);
|
|
651
|
-
if (!ok)
|
|
652
|
-
goto end;
|
|
653
|
-
}
|
|
654
|
-
if (ctx->param->purpose > 0) {
|
|
655
|
-
ret = X509_check_purpose(x, purpose, ca_requirement == must_be_ca);
|
|
656
|
-
if (ret != 1) {
|
|
657
|
-
ret = 0;
|
|
658
|
-
ctx->error = X509_V_ERR_INVALID_PURPOSE;
|
|
659
|
-
ctx->error_depth = i;
|
|
660
|
-
ctx->current_cert = x;
|
|
661
|
-
ok = ctx->verify_cb(0, ctx);
|
|
662
|
-
if (!ok)
|
|
663
|
-
goto end;
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
/* Check pathlen if not self issued */
|
|
667
|
-
if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
|
|
668
|
-
&& (x->ex_pathlen != -1)
|
|
669
|
-
&& (plen > (x->ex_pathlen + proxy_path_length + 1))) {
|
|
670
|
-
ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
|
|
671
|
-
ctx->error_depth = i;
|
|
672
|
-
ctx->current_cert = x;
|
|
673
|
-
ok = ctx->verify_cb(0, ctx);
|
|
674
|
-
if (!ok)
|
|
675
|
-
goto end;
|
|
606
|
+
switch (ca_requirement) {
|
|
607
|
+
case ca_or_leaf:
|
|
608
|
+
ret = 1;
|
|
609
|
+
break;
|
|
610
|
+
case must_not_be_ca:
|
|
611
|
+
if (X509_check_ca(x)) {
|
|
612
|
+
ret = 0;
|
|
613
|
+
ctx->error = X509_V_ERR_INVALID_NON_CA;
|
|
614
|
+
} else {
|
|
615
|
+
ret = 1;
|
|
676
616
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
* must be another proxy certificate or a EE certificate. If not,
|
|
683
|
-
* the next certificate must be a CA certificate.
|
|
684
|
-
*/
|
|
685
|
-
if (x->ex_flags & EXFLAG_PROXY) {
|
|
686
|
-
if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
|
|
687
|
-
ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
|
|
688
|
-
ctx->error_depth = i;
|
|
689
|
-
ctx->current_cert = x;
|
|
690
|
-
ok = ctx->verify_cb(0, ctx);
|
|
691
|
-
if (!ok)
|
|
692
|
-
goto end;
|
|
693
|
-
}
|
|
694
|
-
proxy_path_length++;
|
|
695
|
-
ca_requirement = must_not_be_ca;
|
|
617
|
+
break;
|
|
618
|
+
case must_be_ca:
|
|
619
|
+
if (!X509_check_ca(x)) {
|
|
620
|
+
ret = 0;
|
|
621
|
+
ctx->error = X509_V_ERR_INVALID_CA;
|
|
696
622
|
} else {
|
|
697
|
-
|
|
623
|
+
ret = 1;
|
|
698
624
|
}
|
|
625
|
+
break;
|
|
626
|
+
default:
|
|
627
|
+
// impossible.
|
|
628
|
+
ret = 0;
|
|
699
629
|
}
|
|
700
|
-
ok = 1;
|
|
701
|
-
end:
|
|
702
|
-
return ok;
|
|
703
|
-
}
|
|
704
630
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
return X509_V_OK;
|
|
713
|
-
}
|
|
714
|
-
|
|
715
|
-
X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i);
|
|
716
|
-
ASN1_STRING *common_name = X509_NAME_ENTRY_get_data(entry);
|
|
717
|
-
unsigned char *idval;
|
|
718
|
-
int idlen = ASN1_STRING_to_UTF8(&idval, common_name);
|
|
719
|
-
if (idlen < 0) {
|
|
720
|
-
return X509_V_ERR_OUT_OF_MEM;
|
|
721
|
-
}
|
|
722
|
-
/* Only process attributes that look like host names. Note it is
|
|
723
|
-
* important that this check be mirrored in |X509_check_host|. */
|
|
724
|
-
int looks_like_dns = x509v3_looks_like_dns_name(idval, (size_t)idlen);
|
|
725
|
-
OPENSSL_free(idval);
|
|
726
|
-
if (looks_like_dns) {
|
|
727
|
-
return X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS;
|
|
728
|
-
}
|
|
631
|
+
if (ret == 0) {
|
|
632
|
+
ctx->error_depth = i;
|
|
633
|
+
ctx->current_cert = x;
|
|
634
|
+
ok = ctx->verify_cb(0, ctx);
|
|
635
|
+
if (!ok) {
|
|
636
|
+
goto end;
|
|
637
|
+
}
|
|
729
638
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
if (i && (x->ex_flags & EXFLAG_SI))
|
|
741
|
-
continue;
|
|
742
|
-
/*
|
|
743
|
-
* Check against constraints for all certificates higher in chain
|
|
744
|
-
* including trust anchor. Trust anchor not strictly speaking needed
|
|
745
|
-
* but if it includes constraints it is to be assumed it expects them
|
|
746
|
-
* to be obeyed.
|
|
747
|
-
*/
|
|
748
|
-
for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
|
|
749
|
-
NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
|
|
750
|
-
if (nc) {
|
|
751
|
-
has_name_constraints = 1;
|
|
752
|
-
rv = NAME_CONSTRAINTS_check(x, nc);
|
|
753
|
-
switch (rv) {
|
|
754
|
-
case X509_V_OK:
|
|
755
|
-
continue;
|
|
756
|
-
case X509_V_ERR_OUT_OF_MEM:
|
|
757
|
-
ctx->error = rv;
|
|
758
|
-
return 0;
|
|
759
|
-
default:
|
|
760
|
-
ctx->error = rv;
|
|
761
|
-
ctx->error_depth = i;
|
|
762
|
-
ctx->current_cert = x;
|
|
763
|
-
if (!ctx->verify_cb(0, ctx))
|
|
764
|
-
return 0;
|
|
765
|
-
break;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
639
|
+
if (ctx->param->purpose > 0) {
|
|
640
|
+
ret = X509_check_purpose(x, purpose, ca_requirement == must_be_ca);
|
|
641
|
+
if (ret != 1) {
|
|
642
|
+
ret = 0;
|
|
643
|
+
ctx->error = X509_V_ERR_INVALID_PURPOSE;
|
|
644
|
+
ctx->error_depth = i;
|
|
645
|
+
ctx->current_cert = x;
|
|
646
|
+
ok = ctx->verify_cb(0, ctx);
|
|
647
|
+
if (!ok) {
|
|
648
|
+
goto end;
|
|
768
649
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
// Check pathlen if not self issued
|
|
653
|
+
if ((i > 1) && !(x->ex_flags & EXFLAG_SI) && (x->ex_pathlen != -1) &&
|
|
654
|
+
(plen > (x->ex_pathlen + proxy_path_length + 1))) {
|
|
655
|
+
ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
|
|
656
|
+
ctx->error_depth = i;
|
|
657
|
+
ctx->current_cert = x;
|
|
658
|
+
ok = ctx->verify_cb(0, ctx);
|
|
659
|
+
if (!ok) {
|
|
660
|
+
goto end;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
// Increment path length if not self issued
|
|
664
|
+
if (!(x->ex_flags & EXFLAG_SI)) {
|
|
665
|
+
plen++;
|
|
666
|
+
}
|
|
667
|
+
// If this certificate is a proxy certificate, the next certificate
|
|
668
|
+
// must be another proxy certificate or a EE certificate. If not,
|
|
669
|
+
// the next certificate must be a CA certificate.
|
|
670
|
+
if (x->ex_flags & EXFLAG_PROXY) {
|
|
671
|
+
if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
|
|
672
|
+
ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
|
|
673
|
+
ctx->error_depth = i;
|
|
674
|
+
ctx->current_cert = x;
|
|
675
|
+
ok = ctx->verify_cb(0, ctx);
|
|
676
|
+
if (!ok) {
|
|
677
|
+
goto end;
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
proxy_path_length++;
|
|
681
|
+
ca_requirement = must_not_be_ca;
|
|
682
|
+
} else {
|
|
683
|
+
ca_requirement = must_be_ca;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
ok = 1;
|
|
687
|
+
end:
|
|
688
|
+
return ok;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
static int reject_dns_name_in_common_name(X509 *x509) {
|
|
692
|
+
X509_NAME *name = X509_get_subject_name(x509);
|
|
693
|
+
int i = -1;
|
|
694
|
+
for (;;) {
|
|
695
|
+
i = X509_NAME_get_index_by_NID(name, NID_commonName, i);
|
|
696
|
+
if (i == -1) {
|
|
697
|
+
return X509_V_OK;
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i);
|
|
701
|
+
ASN1_STRING *common_name = X509_NAME_ENTRY_get_data(entry);
|
|
702
|
+
unsigned char *idval;
|
|
703
|
+
int idlen = ASN1_STRING_to_UTF8(&idval, common_name);
|
|
704
|
+
if (idlen < 0) {
|
|
705
|
+
return X509_V_ERR_OUT_OF_MEM;
|
|
706
|
+
}
|
|
707
|
+
// Only process attributes that look like host names. Note it is
|
|
708
|
+
// important that this check be mirrored in |X509_check_host|.
|
|
709
|
+
int looks_like_dns = x509v3_looks_like_dns_name(idval, (size_t)idlen);
|
|
710
|
+
OPENSSL_free(idval);
|
|
711
|
+
if (looks_like_dns) {
|
|
712
|
+
return X509_V_ERR_NAME_CONSTRAINTS_WITHOUT_SANS;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
static int check_name_constraints(X509_STORE_CTX *ctx) {
|
|
718
|
+
int i, j, rv;
|
|
719
|
+
int has_name_constraints = 0;
|
|
720
|
+
// Check name constraints for all certificates
|
|
721
|
+
for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
|
|
722
|
+
X509 *x = sk_X509_value(ctx->chain, i);
|
|
723
|
+
// Ignore self issued certs unless last in chain
|
|
724
|
+
if (i && (x->ex_flags & EXFLAG_SI)) {
|
|
725
|
+
continue;
|
|
726
|
+
}
|
|
727
|
+
// Check against constraints for all certificates higher in chain
|
|
728
|
+
// including trust anchor. Trust anchor not strictly speaking needed
|
|
729
|
+
// but if it includes constraints it is to be assumed it expects them
|
|
730
|
+
// to be obeyed.
|
|
731
|
+
for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
|
|
732
|
+
NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
|
|
733
|
+
if (nc) {
|
|
734
|
+
has_name_constraints = 1;
|
|
735
|
+
rv = NAME_CONSTRAINTS_check(x, nc);
|
|
784
736
|
switch (rv) {
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
737
|
+
case X509_V_OK:
|
|
738
|
+
continue;
|
|
739
|
+
case X509_V_ERR_OUT_OF_MEM:
|
|
788
740
|
ctx->error = rv;
|
|
789
741
|
return 0;
|
|
790
|
-
|
|
742
|
+
default:
|
|
791
743
|
ctx->error = rv;
|
|
792
744
|
ctx->error_depth = i;
|
|
793
|
-
ctx->current_cert =
|
|
794
|
-
if (!ctx->verify_cb(0, ctx))
|
|
795
|
-
|
|
745
|
+
ctx->current_cert = x;
|
|
746
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
747
|
+
return 0;
|
|
748
|
+
}
|
|
796
749
|
break;
|
|
797
750
|
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Name constraints do not match against the common name, but
|
|
756
|
+
// |X509_check_host| still implements the legacy behavior where, on
|
|
757
|
+
// certificates lacking a SAN list, DNS-like names in the common name are
|
|
758
|
+
// checked instead.
|
|
759
|
+
//
|
|
760
|
+
// While we could apply the name constraints to the common name, name
|
|
761
|
+
// constraints are rare enough that can hold such certificates to a higher
|
|
762
|
+
// standard. Note this does not make "DNS-like" heuristic failures any
|
|
763
|
+
// worse. A decorative common-name misidentified as a DNS name would fail
|
|
764
|
+
// the name constraint anyway.
|
|
765
|
+
X509 *leaf = sk_X509_value(ctx->chain, 0);
|
|
766
|
+
if (has_name_constraints && leaf->altname == NULL) {
|
|
767
|
+
rv = reject_dns_name_in_common_name(leaf);
|
|
768
|
+
switch (rv) {
|
|
769
|
+
case X509_V_OK:
|
|
770
|
+
break;
|
|
771
|
+
case X509_V_ERR_OUT_OF_MEM:
|
|
772
|
+
ctx->error = rv;
|
|
773
|
+
return 0;
|
|
774
|
+
default:
|
|
775
|
+
ctx->error = rv;
|
|
776
|
+
ctx->error_depth = i;
|
|
777
|
+
ctx->current_cert = leaf;
|
|
778
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
779
|
+
return 0;
|
|
780
|
+
}
|
|
781
|
+
break;
|
|
798
782
|
}
|
|
799
|
-
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
return 1;
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
static int check_id_error(X509_STORE_CTX *ctx, int errcode) {
|
|
789
|
+
ctx->error = errcode;
|
|
790
|
+
ctx->current_cert = ctx->cert;
|
|
791
|
+
ctx->error_depth = 0;
|
|
792
|
+
return ctx->verify_cb(0, ctx);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
static int check_hosts(X509 *x, X509_VERIFY_PARAM *param) {
|
|
796
|
+
size_t i;
|
|
797
|
+
size_t n = sk_OPENSSL_STRING_num(param->hosts);
|
|
798
|
+
char *name;
|
|
799
|
+
|
|
800
|
+
if (param->peername != NULL) {
|
|
801
|
+
OPENSSL_free(param->peername);
|
|
802
|
+
param->peername = NULL;
|
|
803
|
+
}
|
|
804
|
+
for (i = 0; i < n; ++i) {
|
|
805
|
+
name = sk_OPENSSL_STRING_value(param->hosts, i);
|
|
806
|
+
if (X509_check_host(x, name, strlen(name), param->hostflags,
|
|
807
|
+
¶m->peername) > 0) {
|
|
808
|
+
return 1;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
return n == 0;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
static int check_id(X509_STORE_CTX *ctx) {
|
|
815
|
+
X509_VERIFY_PARAM *vpm = ctx->param;
|
|
816
|
+
X509 *x = ctx->cert;
|
|
817
|
+
if (vpm->poison) {
|
|
818
|
+
if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL)) {
|
|
819
|
+
return 0;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
if (vpm->hosts && check_hosts(x, vpm) <= 0) {
|
|
823
|
+
if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH)) {
|
|
824
|
+
return 0;
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
if (vpm->email && X509_check_email(x, vpm->email, vpm->emaillen, 0) <= 0) {
|
|
828
|
+
if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH)) {
|
|
829
|
+
return 0;
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
if (vpm->ip && X509_check_ip(x, vpm->ip, vpm->iplen, 0) <= 0) {
|
|
833
|
+
if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH)) {
|
|
834
|
+
return 0;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
return 1;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
static int check_trust(X509_STORE_CTX *ctx) {
|
|
841
|
+
size_t i;
|
|
842
|
+
int ok;
|
|
843
|
+
X509 *x = NULL;
|
|
844
|
+
// Check all trusted certificates in chain
|
|
845
|
+
for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
|
|
846
|
+
x = sk_X509_value(ctx->chain, i);
|
|
847
|
+
ok = X509_check_trust(x, ctx->param->trust, 0);
|
|
848
|
+
// If explicitly trusted return trusted
|
|
849
|
+
if (ok == X509_TRUST_TRUSTED) {
|
|
850
|
+
return X509_TRUST_TRUSTED;
|
|
851
|
+
}
|
|
852
|
+
// If explicitly rejected notify callback and reject if not
|
|
853
|
+
// overridden.
|
|
854
|
+
if (ok == X509_TRUST_REJECTED) {
|
|
855
|
+
ctx->error_depth = i;
|
|
856
|
+
ctx->current_cert = x;
|
|
857
|
+
ctx->error = X509_V_ERR_CERT_REJECTED;
|
|
858
|
+
ok = ctx->verify_cb(0, ctx);
|
|
859
|
+
if (!ok) {
|
|
860
|
+
return X509_TRUST_REJECTED;
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
// If we accept partial chains and have at least one trusted certificate
|
|
865
|
+
// return success.
|
|
866
|
+
if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
|
|
867
|
+
X509 *mx;
|
|
868
|
+
if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain)) {
|
|
869
|
+
return X509_TRUST_TRUSTED;
|
|
870
|
+
}
|
|
871
|
+
x = sk_X509_value(ctx->chain, 0);
|
|
872
|
+
mx = lookup_cert_match(ctx, x);
|
|
873
|
+
if (mx) {
|
|
874
|
+
(void)sk_X509_set(ctx->chain, 0, mx);
|
|
875
|
+
X509_free(x);
|
|
876
|
+
ctx->last_untrusted = 0;
|
|
877
|
+
return X509_TRUST_TRUSTED;
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// If no trusted certs in chain at all return untrusted and allow
|
|
882
|
+
// standard (no issuer cert) etc errors to be indicated.
|
|
883
|
+
return X509_TRUST_UNTRUSTED;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
static int check_revocation(X509_STORE_CTX *ctx) {
|
|
887
|
+
int i, last, ok;
|
|
888
|
+
if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) {
|
|
800
889
|
return 1;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
{
|
|
805
|
-
|
|
806
|
-
ctx->
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
|
|
840
|
-
return 0;
|
|
890
|
+
}
|
|
891
|
+
if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) {
|
|
892
|
+
last = sk_X509_num(ctx->chain) - 1;
|
|
893
|
+
} else {
|
|
894
|
+
// If checking CRL paths this isn't the EE certificate
|
|
895
|
+
if (ctx->parent) {
|
|
896
|
+
return 1;
|
|
897
|
+
}
|
|
898
|
+
last = 0;
|
|
899
|
+
}
|
|
900
|
+
for (i = 0; i <= last; i++) {
|
|
901
|
+
ctx->error_depth = i;
|
|
902
|
+
ok = check_cert(ctx);
|
|
903
|
+
if (!ok) {
|
|
904
|
+
return ok;
|
|
905
|
+
}
|
|
906
|
+
}
|
|
907
|
+
return 1;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
static int check_cert(X509_STORE_CTX *ctx) {
|
|
911
|
+
X509_CRL *crl = NULL, *dcrl = NULL;
|
|
912
|
+
X509 *x;
|
|
913
|
+
int ok = 0, cnum;
|
|
914
|
+
unsigned int last_reasons;
|
|
915
|
+
cnum = ctx->error_depth;
|
|
916
|
+
x = sk_X509_value(ctx->chain, cnum);
|
|
917
|
+
ctx->current_cert = x;
|
|
918
|
+
ctx->current_issuer = NULL;
|
|
919
|
+
ctx->current_crl_score = 0;
|
|
920
|
+
ctx->current_reasons = 0;
|
|
921
|
+
while (ctx->current_reasons != CRLDP_ALL_REASONS) {
|
|
922
|
+
last_reasons = ctx->current_reasons;
|
|
923
|
+
// Try to retrieve relevant CRL
|
|
924
|
+
if (ctx->get_crl) {
|
|
925
|
+
ok = ctx->get_crl(ctx, &crl, x);
|
|
926
|
+
} else {
|
|
927
|
+
ok = get_crl_delta(ctx, &crl, &dcrl, x);
|
|
841
928
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
929
|
+
// If error looking up CRL, nothing we can do except notify callback
|
|
930
|
+
if (!ok) {
|
|
931
|
+
ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
|
|
932
|
+
ok = ctx->verify_cb(0, ctx);
|
|
933
|
+
goto err;
|
|
845
934
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
935
|
+
ctx->current_crl = crl;
|
|
936
|
+
ok = ctx->check_crl(ctx, crl);
|
|
937
|
+
if (!ok) {
|
|
938
|
+
goto err;
|
|
849
939
|
}
|
|
850
|
-
return 1;
|
|
851
|
-
}
|
|
852
940
|
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
return X509_TRUST_TRUSTED;
|
|
865
|
-
/*
|
|
866
|
-
* If explicitly rejected notify callback and reject if not
|
|
867
|
-
* overridden.
|
|
868
|
-
*/
|
|
869
|
-
if (ok == X509_TRUST_REJECTED) {
|
|
870
|
-
ctx->error_depth = i;
|
|
871
|
-
ctx->current_cert = x;
|
|
872
|
-
ctx->error = X509_V_ERR_CERT_REJECTED;
|
|
873
|
-
ok = ctx->verify_cb(0, ctx);
|
|
874
|
-
if (!ok)
|
|
875
|
-
return X509_TRUST_REJECTED;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
/*
|
|
879
|
-
* If we accept partial chains and have at least one trusted certificate
|
|
880
|
-
* return success.
|
|
881
|
-
*/
|
|
882
|
-
if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
|
|
883
|
-
X509 *mx;
|
|
884
|
-
if (ctx->last_untrusted < (int)sk_X509_num(ctx->chain))
|
|
885
|
-
return X509_TRUST_TRUSTED;
|
|
886
|
-
x = sk_X509_value(ctx->chain, 0);
|
|
887
|
-
mx = lookup_cert_match(ctx, x);
|
|
888
|
-
if (mx) {
|
|
889
|
-
(void)sk_X509_set(ctx->chain, 0, mx);
|
|
890
|
-
X509_free(x);
|
|
891
|
-
ctx->last_untrusted = 0;
|
|
892
|
-
return X509_TRUST_TRUSTED;
|
|
893
|
-
}
|
|
941
|
+
if (dcrl) {
|
|
942
|
+
ok = ctx->check_crl(ctx, dcrl);
|
|
943
|
+
if (!ok) {
|
|
944
|
+
goto err;
|
|
945
|
+
}
|
|
946
|
+
ok = ctx->cert_crl(ctx, dcrl, x);
|
|
947
|
+
if (!ok) {
|
|
948
|
+
goto err;
|
|
949
|
+
}
|
|
950
|
+
} else {
|
|
951
|
+
ok = 1;
|
|
894
952
|
}
|
|
895
953
|
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
}
|
|
902
|
-
|
|
903
|
-
static int check_revocation(X509_STORE_CTX *ctx)
|
|
904
|
-
{
|
|
905
|
-
int i, last, ok;
|
|
906
|
-
if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
|
|
907
|
-
return 1;
|
|
908
|
-
if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
|
|
909
|
-
last = sk_X509_num(ctx->chain) - 1;
|
|
910
|
-
else {
|
|
911
|
-
/* If checking CRL paths this isn't the EE certificate */
|
|
912
|
-
if (ctx->parent)
|
|
913
|
-
return 1;
|
|
914
|
-
last = 0;
|
|
915
|
-
}
|
|
916
|
-
for (i = 0; i <= last; i++) {
|
|
917
|
-
ctx->error_depth = i;
|
|
918
|
-
ok = check_cert(ctx);
|
|
919
|
-
if (!ok)
|
|
920
|
-
return ok;
|
|
954
|
+
// Don't look in full CRL if delta reason is removefromCRL
|
|
955
|
+
if (ok != 2) {
|
|
956
|
+
ok = ctx->cert_crl(ctx, crl, x);
|
|
957
|
+
if (!ok) {
|
|
958
|
+
goto err;
|
|
959
|
+
}
|
|
921
960
|
}
|
|
922
|
-
return 1;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
static int check_cert(X509_STORE_CTX *ctx)
|
|
926
|
-
{
|
|
927
|
-
X509_CRL *crl = NULL, *dcrl = NULL;
|
|
928
|
-
X509 *x;
|
|
929
|
-
int ok = 0, cnum;
|
|
930
|
-
unsigned int last_reasons;
|
|
931
|
-
cnum = ctx->error_depth;
|
|
932
|
-
x = sk_X509_value(ctx->chain, cnum);
|
|
933
|
-
ctx->current_cert = x;
|
|
934
|
-
ctx->current_issuer = NULL;
|
|
935
|
-
ctx->current_crl_score = 0;
|
|
936
|
-
ctx->current_reasons = 0;
|
|
937
|
-
while (ctx->current_reasons != CRLDP_ALL_REASONS) {
|
|
938
|
-
last_reasons = ctx->current_reasons;
|
|
939
|
-
/* Try to retrieve relevant CRL */
|
|
940
|
-
if (ctx->get_crl)
|
|
941
|
-
ok = ctx->get_crl(ctx, &crl, x);
|
|
942
|
-
else
|
|
943
|
-
ok = get_crl_delta(ctx, &crl, &dcrl, x);
|
|
944
|
-
/*
|
|
945
|
-
* If error looking up CRL, nothing we can do except notify callback
|
|
946
|
-
*/
|
|
947
|
-
if (!ok) {
|
|
948
|
-
ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
|
|
949
|
-
ok = ctx->verify_cb(0, ctx);
|
|
950
|
-
goto err;
|
|
951
|
-
}
|
|
952
|
-
ctx->current_crl = crl;
|
|
953
|
-
ok = ctx->check_crl(ctx, crl);
|
|
954
|
-
if (!ok)
|
|
955
|
-
goto err;
|
|
956
961
|
|
|
957
|
-
if (dcrl) {
|
|
958
|
-
ok = ctx->check_crl(ctx, dcrl);
|
|
959
|
-
if (!ok)
|
|
960
|
-
goto err;
|
|
961
|
-
ok = ctx->cert_crl(ctx, dcrl, x);
|
|
962
|
-
if (!ok)
|
|
963
|
-
goto err;
|
|
964
|
-
} else
|
|
965
|
-
ok = 1;
|
|
966
|
-
|
|
967
|
-
/* Don't look in full CRL if delta reason is removefromCRL */
|
|
968
|
-
if (ok != 2) {
|
|
969
|
-
ok = ctx->cert_crl(ctx, crl, x);
|
|
970
|
-
if (!ok)
|
|
971
|
-
goto err;
|
|
972
|
-
}
|
|
973
|
-
|
|
974
|
-
X509_CRL_free(crl);
|
|
975
|
-
X509_CRL_free(dcrl);
|
|
976
|
-
crl = NULL;
|
|
977
|
-
dcrl = NULL;
|
|
978
|
-
/*
|
|
979
|
-
* If reasons not updated we wont get anywhere by another iteration,
|
|
980
|
-
* so exit loop.
|
|
981
|
-
*/
|
|
982
|
-
if (last_reasons == ctx->current_reasons) {
|
|
983
|
-
ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
|
|
984
|
-
ok = ctx->verify_cb(0, ctx);
|
|
985
|
-
goto err;
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
err:
|
|
989
962
|
X509_CRL_free(crl);
|
|
990
963
|
X509_CRL_free(dcrl);
|
|
964
|
+
crl = NULL;
|
|
965
|
+
dcrl = NULL;
|
|
966
|
+
// If reasons not updated we wont get anywhere by another iteration,
|
|
967
|
+
// so exit loop.
|
|
968
|
+
if (last_reasons == ctx->current_reasons) {
|
|
969
|
+
ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
|
|
970
|
+
ok = ctx->verify_cb(0, ctx);
|
|
971
|
+
goto err;
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
err:
|
|
975
|
+
X509_CRL_free(crl);
|
|
976
|
+
X509_CRL_free(dcrl);
|
|
977
|
+
|
|
978
|
+
ctx->current_crl = NULL;
|
|
979
|
+
return ok;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
// Check CRL times against values in X509_STORE_CTX
|
|
983
|
+
|
|
984
|
+
static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) {
|
|
985
|
+
time_t *ptime;
|
|
986
|
+
int i;
|
|
987
|
+
if (notify) {
|
|
988
|
+
ctx->current_crl = crl;
|
|
989
|
+
}
|
|
990
|
+
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) {
|
|
991
|
+
ptime = &ctx->param->check_time;
|
|
992
|
+
} else {
|
|
993
|
+
ptime = NULL;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime);
|
|
997
|
+
if (i == 0) {
|
|
998
|
+
if (!notify) {
|
|
999
|
+
return 0;
|
|
1000
|
+
}
|
|
1001
|
+
ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
|
|
1002
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1003
|
+
return 0;
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
if (i > 0) {
|
|
1008
|
+
if (!notify) {
|
|
1009
|
+
return 0;
|
|
1010
|
+
}
|
|
1011
|
+
ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
|
|
1012
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1013
|
+
return 0;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
if (X509_CRL_get0_nextUpdate(crl)) {
|
|
1018
|
+
i = X509_cmp_time(X509_CRL_get0_nextUpdate(crl), ptime);
|
|
991
1019
|
|
|
992
|
-
ctx->current_crl = NULL;
|
|
993
|
-
return ok;
|
|
994
|
-
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
/* Check CRL times against values in X509_STORE_CTX */
|
|
998
|
-
|
|
999
|
-
static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
|
|
1000
|
-
{
|
|
1001
|
-
time_t *ptime;
|
|
1002
|
-
int i;
|
|
1003
|
-
if (notify)
|
|
1004
|
-
ctx->current_crl = crl;
|
|
1005
|
-
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
|
|
1006
|
-
ptime = &ctx->param->check_time;
|
|
1007
|
-
else
|
|
1008
|
-
ptime = NULL;
|
|
1009
|
-
|
|
1010
|
-
i = X509_cmp_time(X509_CRL_get0_lastUpdate(crl), ptime);
|
|
1011
1020
|
if (i == 0) {
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
if (i > 0) {
|
|
1020
|
-
if (!notify)
|
|
1021
|
-
return 0;
|
|
1022
|
-
ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
|
|
1023
|
-
if (!ctx->verify_cb(0, ctx))
|
|
1024
|
-
return 0;
|
|
1021
|
+
if (!notify) {
|
|
1022
|
+
return 0;
|
|
1023
|
+
}
|
|
1024
|
+
ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
|
|
1025
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1026
|
+
return 0;
|
|
1027
|
+
}
|
|
1025
1028
|
}
|
|
1026
|
-
|
|
1027
|
-
if (
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
return 0;
|
|
1036
|
-
}
|
|
1037
|
-
/* Ignore expiry of base CRL is delta is valid */
|
|
1038
|
-
if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
|
|
1039
|
-
if (!notify)
|
|
1040
|
-
return 0;
|
|
1041
|
-
ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
|
|
1042
|
-
if (!ctx->verify_cb(0, ctx))
|
|
1043
|
-
return 0;
|
|
1044
|
-
}
|
|
1029
|
+
// Ignore expiry of base CRL is delta is valid
|
|
1030
|
+
if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
|
|
1031
|
+
if (!notify) {
|
|
1032
|
+
return 0;
|
|
1033
|
+
}
|
|
1034
|
+
ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
|
|
1035
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1036
|
+
return 0;
|
|
1037
|
+
}
|
|
1045
1038
|
}
|
|
1039
|
+
}
|
|
1046
1040
|
|
|
1047
|
-
|
|
1048
|
-
|
|
1041
|
+
if (notify) {
|
|
1042
|
+
ctx->current_crl = NULL;
|
|
1043
|
+
}
|
|
1049
1044
|
|
|
1050
|
-
|
|
1045
|
+
return 1;
|
|
1051
1046
|
}
|
|
1052
1047
|
|
|
1053
1048
|
static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
|
|
1054
1049
|
X509 **pissuer, int *pscore, unsigned int *preasons,
|
|
1055
|
-
STACK_OF(X509_CRL) *crls)
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1050
|
+
STACK_OF(X509_CRL) *crls) {
|
|
1051
|
+
int crl_score, best_score = *pscore;
|
|
1052
|
+
size_t i;
|
|
1053
|
+
unsigned int reasons, best_reasons = 0;
|
|
1054
|
+
X509 *x = ctx->current_cert;
|
|
1055
|
+
X509_CRL *crl, *best_crl = NULL;
|
|
1056
|
+
X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
|
|
1057
|
+
|
|
1058
|
+
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
|
|
1059
|
+
crl = sk_X509_CRL_value(crls, i);
|
|
1060
|
+
reasons = *preasons;
|
|
1061
|
+
crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
|
|
1062
|
+
if (crl_score < best_score || crl_score == 0) {
|
|
1063
|
+
continue;
|
|
1064
|
+
}
|
|
1065
|
+
// If current CRL is equivalent use it if it is newer
|
|
1066
|
+
if (crl_score == best_score && best_crl != NULL) {
|
|
1067
|
+
int day, sec;
|
|
1068
|
+
if (ASN1_TIME_diff(&day, &sec, X509_CRL_get0_lastUpdate(best_crl),
|
|
1069
|
+
X509_CRL_get0_lastUpdate(crl)) == 0) {
|
|
1070
|
+
continue;
|
|
1071
|
+
}
|
|
1072
|
+
// ASN1_TIME_diff never returns inconsistent signs for |day|
|
|
1073
|
+
// and |sec|.
|
|
1074
|
+
if (day <= 0 && sec <= 0) {
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
best_crl = crl;
|
|
1079
|
+
best_crl_issuer = crl_issuer;
|
|
1080
|
+
best_score = crl_score;
|
|
1081
|
+
best_reasons = reasons;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
if (best_crl) {
|
|
1085
|
+
if (*pcrl) {
|
|
1086
|
+
X509_CRL_free(*pcrl);
|
|
1087
|
+
}
|
|
1088
|
+
*pcrl = best_crl;
|
|
1089
|
+
*pissuer = best_crl_issuer;
|
|
1090
|
+
*pscore = best_score;
|
|
1091
|
+
*preasons = best_reasons;
|
|
1092
|
+
X509_CRL_up_ref(best_crl);
|
|
1093
|
+
if (*pdcrl) {
|
|
1094
|
+
X509_CRL_free(*pdcrl);
|
|
1095
|
+
*pdcrl = NULL;
|
|
1096
|
+
}
|
|
1097
|
+
get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
if (best_score >= CRL_SCORE_VALID) {
|
|
1101
|
+
return 1;
|
|
1102
|
+
}
|
|
1106
1103
|
|
|
1107
|
-
|
|
1104
|
+
return 0;
|
|
1108
1105
|
}
|
|
1109
1106
|
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
* both present or both absent. If both present all fields must be identical.
|
|
1113
|
-
*/
|
|
1107
|
+
// Compare two CRL extensions for delta checking purposes. They should be
|
|
1108
|
+
// both present or both absent. If both present all fields must be identical.
|
|
1114
1109
|
|
|
1115
|
-
static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
i = X509_CRL_get_ext_by_NID(b, nid, -1);
|
|
1110
|
+
static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) {
|
|
1111
|
+
ASN1_OCTET_STRING *exta, *extb;
|
|
1112
|
+
int i;
|
|
1113
|
+
i = X509_CRL_get_ext_by_NID(a, nid, -1);
|
|
1114
|
+
if (i >= 0) {
|
|
1115
|
+
// Can't have multiple occurrences
|
|
1116
|
+
if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) {
|
|
1117
|
+
return 0;
|
|
1118
|
+
}
|
|
1119
|
+
exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
|
|
1120
|
+
} else {
|
|
1121
|
+
exta = NULL;
|
|
1122
|
+
}
|
|
1129
1123
|
|
|
1130
|
-
|
|
1124
|
+
i = X509_CRL_get_ext_by_NID(b, nid, -1);
|
|
1131
1125
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1126
|
+
if (i >= 0) {
|
|
1127
|
+
if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) {
|
|
1128
|
+
return 0;
|
|
1129
|
+
}
|
|
1130
|
+
extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
|
|
1131
|
+
} else {
|
|
1132
|
+
extb = NULL;
|
|
1133
|
+
}
|
|
1137
1134
|
|
|
1138
|
-
|
|
1139
|
-
|
|
1135
|
+
if (!exta && !extb) {
|
|
1136
|
+
return 1;
|
|
1137
|
+
}
|
|
1140
1138
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1139
|
+
if (!exta || !extb) {
|
|
1140
|
+
return 0;
|
|
1141
|
+
}
|
|
1143
1142
|
|
|
1144
|
-
|
|
1145
|
-
|
|
1143
|
+
if (ASN1_OCTET_STRING_cmp(exta, extb)) {
|
|
1144
|
+
return 0;
|
|
1145
|
+
}
|
|
1146
1146
|
|
|
1147
|
-
|
|
1147
|
+
return 1;
|
|
1148
1148
|
}
|
|
1149
1149
|
|
|
1150
|
-
|
|
1150
|
+
// See if a base and delta are compatible
|
|
1151
1151
|
|
|
1152
|
-
static int check_delta_base(X509_CRL *delta, X509_CRL *base)
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
/* AKID and IDP must match */
|
|
1164
|
-
if (!crl_extension_match(delta, base, NID_authority_key_identifier))
|
|
1165
|
-
return 0;
|
|
1166
|
-
if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
|
|
1167
|
-
return 0;
|
|
1168
|
-
/* Delta CRL base number must not exceed Full CRL number. */
|
|
1169
|
-
if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
|
|
1170
|
-
return 0;
|
|
1171
|
-
/* Delta CRL number must exceed full CRL number */
|
|
1172
|
-
if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
|
|
1173
|
-
return 1;
|
|
1152
|
+
static int check_delta_base(X509_CRL *delta, X509_CRL *base) {
|
|
1153
|
+
// Delta CRL must be a delta
|
|
1154
|
+
if (!delta->base_crl_number) {
|
|
1155
|
+
return 0;
|
|
1156
|
+
}
|
|
1157
|
+
// Base must have a CRL number
|
|
1158
|
+
if (!base->crl_number) {
|
|
1159
|
+
return 0;
|
|
1160
|
+
}
|
|
1161
|
+
// Issuer names must match
|
|
1162
|
+
if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) {
|
|
1174
1163
|
return 0;
|
|
1164
|
+
}
|
|
1165
|
+
// AKID and IDP must match
|
|
1166
|
+
if (!crl_extension_match(delta, base, NID_authority_key_identifier)) {
|
|
1167
|
+
return 0;
|
|
1168
|
+
}
|
|
1169
|
+
if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) {
|
|
1170
|
+
return 0;
|
|
1171
|
+
}
|
|
1172
|
+
// Delta CRL base number must not exceed Full CRL number.
|
|
1173
|
+
if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) {
|
|
1174
|
+
return 0;
|
|
1175
|
+
}
|
|
1176
|
+
// Delta CRL number must exceed full CRL number
|
|
1177
|
+
if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) {
|
|
1178
|
+
return 1;
|
|
1179
|
+
}
|
|
1180
|
+
return 0;
|
|
1175
1181
|
}
|
|
1176
1182
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
* retrieve a chain of deltas...
|
|
1180
|
-
*/
|
|
1183
|
+
// For a given base CRL find a delta... maybe extend to delta scoring or
|
|
1184
|
+
// retrieve a chain of deltas...
|
|
1181
1185
|
|
|
1182
1186
|
static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
|
|
1183
|
-
X509_CRL *base, STACK_OF(X509_CRL) *crls)
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
}
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1187
|
+
X509_CRL *base, STACK_OF(X509_CRL) *crls) {
|
|
1188
|
+
X509_CRL *delta;
|
|
1189
|
+
size_t i;
|
|
1190
|
+
if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1193
|
+
if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) {
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
|
|
1197
|
+
delta = sk_X509_CRL_value(crls, i);
|
|
1198
|
+
if (check_delta_base(delta, base)) {
|
|
1199
|
+
if (check_crl_time(ctx, delta, 0)) {
|
|
1200
|
+
*pscore |= CRL_SCORE_TIME_DELTA;
|
|
1201
|
+
}
|
|
1202
|
+
X509_CRL_up_ref(delta);
|
|
1203
|
+
*dcrl = delta;
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
*dcrl = NULL;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
// For a given CRL return how suitable it is for the supplied certificate
|
|
1211
|
+
// 'x'. The return value is a mask of several criteria. If the issuer is not
|
|
1212
|
+
// the certificate issuer this is returned in *pissuer. The reasons mask is
|
|
1213
|
+
// also used to determine if the CRL is suitable: if no new reasons the CRL
|
|
1214
|
+
// is rejected, otherwise reasons is updated.
|
|
1211
1215
|
|
|
1212
1216
|
static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
|
|
1213
|
-
unsigned int *preasons, X509_CRL *crl, X509 *x)
|
|
1214
|
-
|
|
1217
|
+
unsigned int *preasons, X509_CRL *crl, X509 *x) {
|
|
1218
|
+
int crl_score = 0;
|
|
1219
|
+
unsigned int tmp_reasons = *preasons, crl_reasons;
|
|
1215
1220
|
|
|
1216
|
-
|
|
1217
|
-
unsigned int tmp_reasons = *preasons, crl_reasons;
|
|
1221
|
+
// First see if we can reject CRL straight away
|
|
1218
1222
|
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
if (
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1223
|
+
// Invalid IDP cannot be processed
|
|
1224
|
+
if (crl->idp_flags & IDP_INVALID) {
|
|
1225
|
+
return 0;
|
|
1226
|
+
}
|
|
1227
|
+
// Reason codes or indirect CRLs need extended CRL support
|
|
1228
|
+
if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
|
|
1229
|
+
if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) {
|
|
1230
|
+
return 0;
|
|
1231
|
+
}
|
|
1232
|
+
} else if (crl->idp_flags & IDP_REASONS) {
|
|
1233
|
+
// If no new reasons reject
|
|
1234
|
+
if (!(crl->idp_reasons & ~tmp_reasons)) {
|
|
1235
|
+
return 0;
|
|
1236
|
+
}
|
|
1237
|
+
}
|
|
1238
|
+
// Don't process deltas at this stage
|
|
1239
|
+
else if (crl->base_crl_number) {
|
|
1240
|
+
return 0;
|
|
1241
|
+
}
|
|
1242
|
+
// If issuer name doesn't match certificate need indirect CRL
|
|
1243
|
+
if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
|
|
1244
|
+
if (!(crl->idp_flags & IDP_INDIRECT)) {
|
|
1245
|
+
return 0;
|
|
1232
1246
|
}
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
/* If issuer name doesn't match certificate need indirect CRL */
|
|
1237
|
-
if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
|
|
1238
|
-
if (!(crl->idp_flags & IDP_INDIRECT))
|
|
1239
|
-
return 0;
|
|
1240
|
-
} else
|
|
1241
|
-
crl_score |= CRL_SCORE_ISSUER_NAME;
|
|
1247
|
+
} else {
|
|
1248
|
+
crl_score |= CRL_SCORE_ISSUER_NAME;
|
|
1249
|
+
}
|
|
1242
1250
|
|
|
1243
|
-
|
|
1244
|
-
|
|
1251
|
+
if (!(crl->flags & EXFLAG_CRITICAL)) {
|
|
1252
|
+
crl_score |= CRL_SCORE_NOCRITICAL;
|
|
1253
|
+
}
|
|
1245
1254
|
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1255
|
+
// Check expiry
|
|
1256
|
+
if (check_crl_time(ctx, crl, 0)) {
|
|
1257
|
+
crl_score |= CRL_SCORE_TIME;
|
|
1258
|
+
}
|
|
1249
1259
|
|
|
1250
|
-
|
|
1251
|
-
|
|
1260
|
+
// Check authority key ID and locate certificate issuer
|
|
1261
|
+
crl_akid_check(ctx, crl, pissuer, &crl_score);
|
|
1252
1262
|
|
|
1253
|
-
|
|
1263
|
+
// If we can't locate certificate issuer at this point forget it
|
|
1254
1264
|
|
|
1255
|
-
|
|
1256
|
-
|
|
1265
|
+
if (!(crl_score & CRL_SCORE_AKID)) {
|
|
1266
|
+
return 0;
|
|
1267
|
+
}
|
|
1257
1268
|
|
|
1258
|
-
|
|
1269
|
+
// Check cert for matching CRL distribution points
|
|
1259
1270
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
tmp_reasons |= crl_reasons;
|
|
1265
|
-
crl_score |= CRL_SCORE_SCOPE;
|
|
1271
|
+
if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
|
|
1272
|
+
// If no new reasons reject
|
|
1273
|
+
if (!(crl_reasons & ~tmp_reasons)) {
|
|
1274
|
+
return 0;
|
|
1266
1275
|
}
|
|
1276
|
+
tmp_reasons |= crl_reasons;
|
|
1277
|
+
crl_score |= CRL_SCORE_SCOPE;
|
|
1278
|
+
}
|
|
1267
1279
|
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
return crl_score;
|
|
1280
|
+
*preasons = tmp_reasons;
|
|
1271
1281
|
|
|
1282
|
+
return crl_score;
|
|
1272
1283
|
}
|
|
1273
1284
|
|
|
1274
|
-
static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
size_t i;
|
|
1285
|
+
static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
|
|
1286
|
+
int *pcrl_score) {
|
|
1287
|
+
X509 *crl_issuer = NULL;
|
|
1288
|
+
X509_NAME *cnm = X509_CRL_get_issuer(crl);
|
|
1289
|
+
int cidx = ctx->error_depth;
|
|
1290
|
+
size_t i;
|
|
1281
1291
|
|
|
1282
|
-
|
|
1283
|
-
|
|
1292
|
+
if ((size_t)cidx != sk_X509_num(ctx->chain) - 1) {
|
|
1293
|
+
cidx++;
|
|
1294
|
+
}
|
|
1284
1295
|
|
|
1285
|
-
|
|
1296
|
+
crl_issuer = sk_X509_value(ctx->chain, cidx);
|
|
1286
1297
|
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
}
|
|
1298
|
+
if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
|
|
1299
|
+
if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
|
|
1300
|
+
*pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
|
|
1301
|
+
*pissuer = crl_issuer;
|
|
1302
|
+
return;
|
|
1293
1303
|
}
|
|
1304
|
+
}
|
|
1294
1305
|
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
|
|
1300
|
-
*pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
|
|
1301
|
-
*pissuer = crl_issuer;
|
|
1302
|
-
return;
|
|
1303
|
-
}
|
|
1306
|
+
for (cidx++; cidx < (int)sk_X509_num(ctx->chain); cidx++) {
|
|
1307
|
+
crl_issuer = sk_X509_value(ctx->chain, cidx);
|
|
1308
|
+
if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) {
|
|
1309
|
+
continue;
|
|
1304
1310
|
}
|
|
1311
|
+
if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
|
|
1312
|
+
*pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
|
|
1313
|
+
*pissuer = crl_issuer;
|
|
1314
|
+
return;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1305
1317
|
|
|
1306
|
-
|
|
1318
|
+
// Anything else needs extended CRL support
|
|
1307
1319
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1320
|
+
if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
|
|
1321
|
+
return;
|
|
1322
|
+
}
|
|
1310
1323
|
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
|
|
1318
|
-
continue;
|
|
1319
|
-
if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
|
|
1320
|
-
*pissuer = crl_issuer;
|
|
1321
|
-
*pcrl_score |= CRL_SCORE_AKID;
|
|
1322
|
-
return;
|
|
1323
|
-
}
|
|
1324
|
+
// Otherwise the CRL issuer is not on the path. Look for it in the set of
|
|
1325
|
+
// untrusted certificates.
|
|
1326
|
+
for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
|
|
1327
|
+
crl_issuer = sk_X509_value(ctx->untrusted, i);
|
|
1328
|
+
if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) {
|
|
1329
|
+
continue;
|
|
1324
1330
|
}
|
|
1331
|
+
if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
|
|
1332
|
+
*pissuer = crl_issuer;
|
|
1333
|
+
*pcrl_score |= CRL_SCORE_AKID;
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1325
1337
|
}
|
|
1326
1338
|
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
* be duplicated by the parent, but this will rarely be used in practice.
|
|
1332
|
-
*/
|
|
1333
|
-
|
|
1334
|
-
static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
|
|
1335
|
-
{
|
|
1336
|
-
X509_STORE_CTX crl_ctx;
|
|
1337
|
-
int ret;
|
|
1338
|
-
/* Don't allow recursive CRL path validation */
|
|
1339
|
-
if (ctx->parent)
|
|
1340
|
-
return 0;
|
|
1341
|
-
if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
|
|
1342
|
-
return -1;
|
|
1343
|
-
|
|
1344
|
-
crl_ctx.crls = ctx->crls;
|
|
1345
|
-
/* Copy verify params across */
|
|
1346
|
-
X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
|
|
1347
|
-
|
|
1348
|
-
crl_ctx.parent = ctx;
|
|
1349
|
-
crl_ctx.verify_cb = ctx->verify_cb;
|
|
1350
|
-
|
|
1351
|
-
/* Verify CRL issuer */
|
|
1352
|
-
ret = X509_verify_cert(&crl_ctx);
|
|
1339
|
+
// Check the path of a CRL issuer certificate. This creates a new
|
|
1340
|
+
// X509_STORE_CTX and populates it with most of the parameters from the
|
|
1341
|
+
// parent. This could be optimised somewhat since a lot of path checking will
|
|
1342
|
+
// be duplicated by the parent, but this will rarely be used in practice.
|
|
1353
1343
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
|
|
1360
|
-
err:
|
|
1361
|
-
X509_STORE_CTX_cleanup(&crl_ctx);
|
|
1362
|
-
return ret;
|
|
1363
|
-
}
|
|
1364
|
-
|
|
1365
|
-
/*
|
|
1366
|
-
* RFC 3280 says nothing about the relationship between CRL path and
|
|
1367
|
-
* certificate path, which could lead to situations where a certificate could
|
|
1368
|
-
* be revoked or validated by a CA not authorised to do so. RFC 5280 is more
|
|
1369
|
-
* strict and states that the two paths must end in the same trust anchor,
|
|
1370
|
-
* though some discussions remain... until this is resolved we use the
|
|
1371
|
-
* RFC 5280 version
|
|
1372
|
-
*/
|
|
1373
|
-
|
|
1374
|
-
static int check_crl_chain(X509_STORE_CTX *ctx,
|
|
1375
|
-
STACK_OF(X509) *cert_path,
|
|
1376
|
-
STACK_OF(X509) *crl_path)
|
|
1377
|
-
{
|
|
1378
|
-
X509 *cert_ta, *crl_ta;
|
|
1379
|
-
cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
|
|
1380
|
-
crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
|
|
1381
|
-
if (!X509_cmp(cert_ta, crl_ta))
|
|
1382
|
-
return 1;
|
|
1344
|
+
static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) {
|
|
1345
|
+
X509_STORE_CTX crl_ctx;
|
|
1346
|
+
int ret;
|
|
1347
|
+
// Don't allow recursive CRL path validation
|
|
1348
|
+
if (ctx->parent) {
|
|
1383
1349
|
return 0;
|
|
1350
|
+
}
|
|
1351
|
+
if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) {
|
|
1352
|
+
return -1;
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
crl_ctx.crls = ctx->crls;
|
|
1356
|
+
// Copy verify params across
|
|
1357
|
+
X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
|
|
1358
|
+
|
|
1359
|
+
crl_ctx.parent = ctx;
|
|
1360
|
+
crl_ctx.verify_cb = ctx->verify_cb;
|
|
1361
|
+
|
|
1362
|
+
// Verify CRL issuer
|
|
1363
|
+
ret = X509_verify_cert(&crl_ctx);
|
|
1364
|
+
|
|
1365
|
+
if (ret <= 0) {
|
|
1366
|
+
goto err;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
// Check chain is acceptable
|
|
1370
|
+
|
|
1371
|
+
ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
|
|
1372
|
+
err:
|
|
1373
|
+
X509_STORE_CTX_cleanup(&crl_ctx);
|
|
1374
|
+
return ret;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
// RFC 3280 says nothing about the relationship between CRL path and
|
|
1378
|
+
// certificate path, which could lead to situations where a certificate could
|
|
1379
|
+
// be revoked or validated by a CA not authorised to do so. RFC 5280 is more
|
|
1380
|
+
// strict and states that the two paths must end in the same trust anchor,
|
|
1381
|
+
// though some discussions remain... until this is resolved we use the
|
|
1382
|
+
// RFC 5280 version
|
|
1383
|
+
|
|
1384
|
+
static int check_crl_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *cert_path,
|
|
1385
|
+
STACK_OF(X509) *crl_path) {
|
|
1386
|
+
X509 *cert_ta, *crl_ta;
|
|
1387
|
+
cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
|
|
1388
|
+
crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
|
|
1389
|
+
if (!X509_cmp(cert_ta, crl_ta)) {
|
|
1390
|
+
return 1;
|
|
1391
|
+
}
|
|
1392
|
+
return 0;
|
|
1384
1393
|
}
|
|
1385
1394
|
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1395
|
+
// Check for match between two dist point names: three separate cases. 1.
|
|
1396
|
+
// Both are relative names and compare X509_NAME types. 2. One full, one
|
|
1397
|
+
// relative. Compare X509_NAME to GENERAL_NAMES. 3. Both are full names and
|
|
1398
|
+
// compare two GENERAL_NAMES. 4. One is NULL: automatic match.
|
|
1399
|
+
|
|
1400
|
+
static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) {
|
|
1401
|
+
X509_NAME *nm = NULL;
|
|
1402
|
+
GENERAL_NAMES *gens = NULL;
|
|
1403
|
+
GENERAL_NAME *gena, *genb;
|
|
1404
|
+
size_t i, j;
|
|
1405
|
+
if (!a || !b) {
|
|
1406
|
+
return 1;
|
|
1407
|
+
}
|
|
1408
|
+
if (a->type == 1) {
|
|
1409
|
+
if (!a->dpname) {
|
|
1410
|
+
return 0;
|
|
1411
|
+
}
|
|
1412
|
+
// Case 1: two X509_NAME
|
|
1413
|
+
if (b->type == 1) {
|
|
1414
|
+
if (!b->dpname) {
|
|
1415
|
+
return 0;
|
|
1416
|
+
}
|
|
1417
|
+
if (!X509_NAME_cmp(a->dpname, b->dpname)) {
|
|
1400
1418
|
return 1;
|
|
1401
|
-
|
|
1402
|
-
if (!a->dpname)
|
|
1403
|
-
return 0;
|
|
1404
|
-
/* Case 1: two X509_NAME */
|
|
1405
|
-
if (b->type == 1) {
|
|
1406
|
-
if (!b->dpname)
|
|
1407
|
-
return 0;
|
|
1408
|
-
if (!X509_NAME_cmp(a->dpname, b->dpname))
|
|
1409
|
-
return 1;
|
|
1410
|
-
else
|
|
1411
|
-
return 0;
|
|
1412
|
-
}
|
|
1413
|
-
/* Case 2: set name and GENERAL_NAMES appropriately */
|
|
1414
|
-
nm = a->dpname;
|
|
1415
|
-
gens = b->name.fullname;
|
|
1416
|
-
} else if (b->type == 1) {
|
|
1417
|
-
if (!b->dpname)
|
|
1418
|
-
return 0;
|
|
1419
|
-
/* Case 2: set name and GENERAL_NAMES appropriately */
|
|
1420
|
-
gens = a->name.fullname;
|
|
1421
|
-
nm = b->dpname;
|
|
1422
|
-
}
|
|
1423
|
-
|
|
1424
|
-
/* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
|
|
1425
|
-
if (nm) {
|
|
1426
|
-
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
|
|
1427
|
-
gena = sk_GENERAL_NAME_value(gens, i);
|
|
1428
|
-
if (gena->type != GEN_DIRNAME)
|
|
1429
|
-
continue;
|
|
1430
|
-
if (!X509_NAME_cmp(nm, gena->d.directoryName))
|
|
1431
|
-
return 1;
|
|
1432
|
-
}
|
|
1419
|
+
} else {
|
|
1433
1420
|
return 0;
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
// Case 2: set name and GENERAL_NAMES appropriately
|
|
1424
|
+
nm = a->dpname;
|
|
1425
|
+
gens = b->name.fullname;
|
|
1426
|
+
} else if (b->type == 1) {
|
|
1427
|
+
if (!b->dpname) {
|
|
1428
|
+
return 0;
|
|
1429
|
+
}
|
|
1430
|
+
// Case 2: set name and GENERAL_NAMES appropriately
|
|
1431
|
+
gens = a->name.fullname;
|
|
1432
|
+
nm = b->dpname;
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
// Handle case 2 with one GENERAL_NAMES and one X509_NAME
|
|
1436
|
+
if (nm) {
|
|
1437
|
+
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
|
|
1438
|
+
gena = sk_GENERAL_NAME_value(gens, i);
|
|
1439
|
+
if (gena->type != GEN_DIRNAME) {
|
|
1440
|
+
continue;
|
|
1441
|
+
}
|
|
1442
|
+
if (!X509_NAME_cmp(nm, gena->d.directoryName)) {
|
|
1443
|
+
return 1;
|
|
1444
|
+
}
|
|
1434
1445
|
}
|
|
1446
|
+
return 0;
|
|
1447
|
+
}
|
|
1435
1448
|
|
|
1436
|
-
|
|
1449
|
+
// Else case 3: two GENERAL_NAMES
|
|
1437
1450
|
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1451
|
+
for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
|
|
1452
|
+
gena = sk_GENERAL_NAME_value(a->name.fullname, i);
|
|
1453
|
+
for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
|
|
1454
|
+
genb = sk_GENERAL_NAME_value(b->name.fullname, j);
|
|
1455
|
+
if (!GENERAL_NAME_cmp(gena, genb)) {
|
|
1456
|
+
return 1;
|
|
1457
|
+
}
|
|
1445
1458
|
}
|
|
1459
|
+
}
|
|
1446
1460
|
|
|
1447
|
-
|
|
1448
|
-
|
|
1461
|
+
return 0;
|
|
1449
1462
|
}
|
|
1450
1463
|
|
|
1451
|
-
static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
if (!X509_NAME_cmp(gen->d.directoryName, nm))
|
|
1463
|
-
return 1;
|
|
1464
|
+
static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) {
|
|
1465
|
+
size_t i;
|
|
1466
|
+
X509_NAME *nm = X509_CRL_get_issuer(crl);
|
|
1467
|
+
// If no CRLissuer return is successful iff don't need a match
|
|
1468
|
+
if (!dp->CRLissuer) {
|
|
1469
|
+
return !!(crl_score & CRL_SCORE_ISSUER_NAME);
|
|
1470
|
+
}
|
|
1471
|
+
for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
|
|
1472
|
+
GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
|
|
1473
|
+
if (gen->type != GEN_DIRNAME) {
|
|
1474
|
+
continue;
|
|
1464
1475
|
}
|
|
1465
|
-
|
|
1476
|
+
if (!X509_NAME_cmp(gen->d.directoryName, nm)) {
|
|
1477
|
+
return 1;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
return 0;
|
|
1466
1481
|
}
|
|
1467
1482
|
|
|
1468
|
-
|
|
1483
|
+
// Check CRLDP and IDP
|
|
1469
1484
|
|
|
1470
1485
|
static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
|
|
1471
|
-
unsigned int *preasons)
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
if (crl->idp_flags & IDP_ONLYATTR)
|
|
1475
|
-
return 0;
|
|
1476
|
-
if (x->ex_flags & EXFLAG_CA) {
|
|
1477
|
-
if (crl->idp_flags & IDP_ONLYUSER)
|
|
1478
|
-
return 0;
|
|
1479
|
-
} else {
|
|
1480
|
-
if (crl->idp_flags & IDP_ONLYCA)
|
|
1481
|
-
return 0;
|
|
1482
|
-
}
|
|
1483
|
-
*preasons = crl->idp_reasons;
|
|
1484
|
-
for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
|
|
1485
|
-
DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
|
|
1486
|
-
if (crldp_check_crlissuer(dp, crl, crl_score)) {
|
|
1487
|
-
if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
|
|
1488
|
-
*preasons &= dp->dp_reasons;
|
|
1489
|
-
return 1;
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1492
|
-
}
|
|
1493
|
-
if ((!crl->idp || !crl->idp->distpoint)
|
|
1494
|
-
&& (crl_score & CRL_SCORE_ISSUER_NAME))
|
|
1495
|
-
return 1;
|
|
1486
|
+
unsigned int *preasons) {
|
|
1487
|
+
size_t i;
|
|
1488
|
+
if (crl->idp_flags & IDP_ONLYATTR) {
|
|
1496
1489
|
return 0;
|
|
1490
|
+
}
|
|
1491
|
+
if (x->ex_flags & EXFLAG_CA) {
|
|
1492
|
+
if (crl->idp_flags & IDP_ONLYUSER) {
|
|
1493
|
+
return 0;
|
|
1494
|
+
}
|
|
1495
|
+
} else {
|
|
1496
|
+
if (crl->idp_flags & IDP_ONLYCA) {
|
|
1497
|
+
return 0;
|
|
1498
|
+
}
|
|
1499
|
+
}
|
|
1500
|
+
*preasons = crl->idp_reasons;
|
|
1501
|
+
for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
|
|
1502
|
+
DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
|
|
1503
|
+
if (crldp_check_crlissuer(dp, crl, crl_score)) {
|
|
1504
|
+
if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
|
|
1505
|
+
*preasons &= dp->dp_reasons;
|
|
1506
|
+
return 1;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
if ((!crl->idp || !crl->idp->distpoint) &&
|
|
1511
|
+
(crl_score & CRL_SCORE_ISSUER_NAME)) {
|
|
1512
|
+
return 1;
|
|
1513
|
+
}
|
|
1514
|
+
return 0;
|
|
1497
1515
|
}
|
|
1498
1516
|
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
* to find a delta CRL too
|
|
1502
|
-
*/
|
|
1517
|
+
// Retrieve CRL corresponding to current certificate. If deltas enabled try
|
|
1518
|
+
// to find a delta CRL too
|
|
1503
1519
|
|
|
1504
|
-
static int get_crl_delta(X509_STORE_CTX *ctx,
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
ok = get_crl_sk(ctx, &crl, &dcrl,
|
|
1516
|
-
&issuer, &crl_score, &reasons, ctx->crls);
|
|
1520
|
+
static int get_crl_delta(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
|
|
1521
|
+
X509 *x) {
|
|
1522
|
+
int ok;
|
|
1523
|
+
X509 *issuer = NULL;
|
|
1524
|
+
int crl_score = 0;
|
|
1525
|
+
unsigned int reasons;
|
|
1526
|
+
X509_CRL *crl = NULL, *dcrl = NULL;
|
|
1527
|
+
STACK_OF(X509_CRL) *skcrl;
|
|
1528
|
+
X509_NAME *nm = X509_get_issuer_name(x);
|
|
1529
|
+
reasons = ctx->current_reasons;
|
|
1530
|
+
ok = get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, ctx->crls);
|
|
1517
1531
|
|
|
1518
|
-
|
|
1519
|
-
|
|
1532
|
+
if (ok) {
|
|
1533
|
+
goto done;
|
|
1534
|
+
}
|
|
1520
1535
|
|
|
1521
|
-
|
|
1536
|
+
// Lookup CRLs from store
|
|
1522
1537
|
|
|
1523
|
-
|
|
1538
|
+
skcrl = ctx->lookup_crls(ctx, nm);
|
|
1524
1539
|
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1540
|
+
// If no CRLs found and a near match from get_crl_sk use that
|
|
1541
|
+
if (!skcrl && crl) {
|
|
1542
|
+
goto done;
|
|
1543
|
+
}
|
|
1528
1544
|
|
|
1529
|
-
|
|
1545
|
+
get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
|
|
1530
1546
|
|
|
1531
|
-
|
|
1547
|
+
sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
|
|
1532
1548
|
|
|
1533
|
-
|
|
1549
|
+
done:
|
|
1534
1550
|
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1551
|
+
// If we got any kind of CRL use it and return success
|
|
1552
|
+
if (crl) {
|
|
1553
|
+
ctx->current_issuer = issuer;
|
|
1554
|
+
ctx->current_crl_score = crl_score;
|
|
1555
|
+
ctx->current_reasons = reasons;
|
|
1556
|
+
*pcrl = crl;
|
|
1557
|
+
*pdcrl = dcrl;
|
|
1558
|
+
return 1;
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
return 0;
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// Check CRL validity
|
|
1565
|
+
static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) {
|
|
1566
|
+
X509 *issuer = NULL;
|
|
1567
|
+
EVP_PKEY *ikey = NULL;
|
|
1568
|
+
int ok = 0, chnum, cnum;
|
|
1569
|
+
cnum = ctx->error_depth;
|
|
1570
|
+
chnum = sk_X509_num(ctx->chain) - 1;
|
|
1571
|
+
// if we have an alternative CRL issuer cert use that
|
|
1572
|
+
if (ctx->current_issuer) {
|
|
1573
|
+
issuer = ctx->current_issuer;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
// Else find CRL issuer: if not last certificate then issuer is next
|
|
1577
|
+
// certificate in chain.
|
|
1578
|
+
else if (cnum < chnum) {
|
|
1579
|
+
issuer = sk_X509_value(ctx->chain, cnum + 1);
|
|
1580
|
+
} else {
|
|
1581
|
+
issuer = sk_X509_value(ctx->chain, chnum);
|
|
1582
|
+
// If not self signed, can't check signature
|
|
1583
|
+
if (!ctx->check_issued(ctx, issuer, issuer)) {
|
|
1584
|
+
ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
|
|
1585
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1586
|
+
if (!ok) {
|
|
1587
|
+
goto err;
|
|
1588
|
+
}
|
|
1543
1589
|
}
|
|
1590
|
+
}
|
|
1544
1591
|
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
{
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
chnum = sk_X509_num(ctx->chain) - 1;
|
|
1556
|
-
/* if we have an alternative CRL issuer cert use that */
|
|
1557
|
-
if (ctx->current_issuer)
|
|
1558
|
-
issuer = ctx->current_issuer;
|
|
1559
|
-
|
|
1560
|
-
/*
|
|
1561
|
-
* Else find CRL issuer: if not last certificate then issuer is next
|
|
1562
|
-
* certificate in chain.
|
|
1563
|
-
*/
|
|
1564
|
-
else if (cnum < chnum)
|
|
1565
|
-
issuer = sk_X509_value(ctx->chain, cnum + 1);
|
|
1566
|
-
else {
|
|
1567
|
-
issuer = sk_X509_value(ctx->chain, chnum);
|
|
1568
|
-
/* If not self signed, can't check signature */
|
|
1569
|
-
if (!ctx->check_issued(ctx, issuer, issuer)) {
|
|
1570
|
-
ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
|
|
1571
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1572
|
-
if (!ok)
|
|
1573
|
-
goto err;
|
|
1592
|
+
if (issuer) {
|
|
1593
|
+
// Skip most tests for deltas because they have already been done
|
|
1594
|
+
if (!crl->base_crl_number) {
|
|
1595
|
+
// Check for cRLSign bit if keyUsage present
|
|
1596
|
+
if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
|
|
1597
|
+
!(issuer->ex_kusage & KU_CRL_SIGN)) {
|
|
1598
|
+
ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
|
|
1599
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1600
|
+
if (!ok) {
|
|
1601
|
+
goto err;
|
|
1574
1602
|
}
|
|
1575
|
-
|
|
1603
|
+
}
|
|
1576
1604
|
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
!(issuer->ex_kusage & KU_CRL_SIGN)) {
|
|
1585
|
-
ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
|
|
1586
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1587
|
-
if (!ok)
|
|
1588
|
-
goto err;
|
|
1589
|
-
}
|
|
1590
|
-
|
|
1591
|
-
if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
|
|
1592
|
-
ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
|
|
1593
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1594
|
-
if (!ok)
|
|
1595
|
-
goto err;
|
|
1596
|
-
}
|
|
1597
|
-
|
|
1598
|
-
if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
|
|
1599
|
-
if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
|
|
1600
|
-
ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
|
|
1601
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1602
|
-
if (!ok)
|
|
1603
|
-
goto err;
|
|
1604
|
-
}
|
|
1605
|
-
}
|
|
1606
|
-
|
|
1607
|
-
if (crl->idp_flags & IDP_INVALID) {
|
|
1608
|
-
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
1609
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1610
|
-
if (!ok)
|
|
1611
|
-
goto err;
|
|
1612
|
-
}
|
|
1605
|
+
if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
|
|
1606
|
+
ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
|
|
1607
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1608
|
+
if (!ok) {
|
|
1609
|
+
goto err;
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1613
1612
|
|
|
1613
|
+
if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
|
|
1614
|
+
if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
|
|
1615
|
+
ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
|
|
1616
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1617
|
+
if (!ok) {
|
|
1618
|
+
goto err;
|
|
1619
|
+
}
|
|
1614
1620
|
}
|
|
1621
|
+
}
|
|
1615
1622
|
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1623
|
+
if (crl->idp_flags & IDP_INVALID) {
|
|
1624
|
+
ctx->error = X509_V_ERR_INVALID_EXTENSION;
|
|
1625
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1626
|
+
if (!ok) {
|
|
1627
|
+
goto err;
|
|
1620
1628
|
}
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
|
|
1633
|
+
ok = check_crl_time(ctx, crl, 1);
|
|
1634
|
+
if (!ok) {
|
|
1635
|
+
goto err;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1621
1638
|
|
|
1622
|
-
|
|
1623
|
-
|
|
1639
|
+
// Attempt to get issuer certificate public key
|
|
1640
|
+
ikey = X509_get_pubkey(issuer);
|
|
1624
1641
|
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
/* Verify CRL signature */
|
|
1640
|
-
if (X509_CRL_verify(crl, ikey) <= 0) {
|
|
1641
|
-
ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
|
|
1642
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1643
|
-
if (!ok)
|
|
1644
|
-
goto err;
|
|
1645
|
-
}
|
|
1642
|
+
if (!ikey) {
|
|
1643
|
+
ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
|
|
1644
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1645
|
+
if (!ok) {
|
|
1646
|
+
goto err;
|
|
1647
|
+
}
|
|
1648
|
+
} else {
|
|
1649
|
+
int rv;
|
|
1650
|
+
rv = X509_CRL_check_suiteb(crl, ikey, ctx->param->flags);
|
|
1651
|
+
if (rv != X509_V_OK) {
|
|
1652
|
+
ctx->error = rv;
|
|
1653
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1654
|
+
if (!ok) {
|
|
1655
|
+
goto err;
|
|
1646
1656
|
}
|
|
1657
|
+
}
|
|
1658
|
+
// Verify CRL signature
|
|
1659
|
+
if (X509_CRL_verify(crl, ikey) <= 0) {
|
|
1660
|
+
ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
|
|
1661
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1662
|
+
if (!ok) {
|
|
1663
|
+
goto err;
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1647
1666
|
}
|
|
1667
|
+
}
|
|
1648
1668
|
|
|
1649
|
-
|
|
1669
|
+
ok = 1;
|
|
1650
1670
|
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1671
|
+
err:
|
|
1672
|
+
EVP_PKEY_free(ikey);
|
|
1673
|
+
return ok;
|
|
1654
1674
|
}
|
|
1655
1675
|
|
|
1656
|
-
|
|
1657
|
-
static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1671
|
-
if (!ok)
|
|
1672
|
-
return 0;
|
|
1676
|
+
// Check certificate against CRL
|
|
1677
|
+
static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) {
|
|
1678
|
+
int ok;
|
|
1679
|
+
X509_REVOKED *rev;
|
|
1680
|
+
// The rules changed for this... previously if a CRL contained unhandled
|
|
1681
|
+
// critical extensions it could still be used to indicate a certificate
|
|
1682
|
+
// was revoked. This has since been changed since critical extension can
|
|
1683
|
+
// change the meaning of CRL entries.
|
|
1684
|
+
if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) &&
|
|
1685
|
+
(crl->flags & EXFLAG_CRITICAL)) {
|
|
1686
|
+
ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
|
|
1687
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1688
|
+
if (!ok) {
|
|
1689
|
+
return 0;
|
|
1673
1690
|
}
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
if (
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1691
|
+
}
|
|
1692
|
+
// Look for serial number of certificate in CRL If found make sure reason
|
|
1693
|
+
// is not removeFromCRL.
|
|
1694
|
+
if (X509_CRL_get0_by_cert(crl, &rev, x)) {
|
|
1695
|
+
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) {
|
|
1696
|
+
return 2;
|
|
1697
|
+
}
|
|
1698
|
+
ctx->error = X509_V_ERR_CERT_REVOKED;
|
|
1699
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1700
|
+
if (!ok) {
|
|
1701
|
+
return 0;
|
|
1685
1702
|
}
|
|
1703
|
+
}
|
|
1686
1704
|
|
|
1687
|
-
|
|
1705
|
+
return 1;
|
|
1688
1706
|
}
|
|
1689
1707
|
|
|
1690
|
-
static int check_policy(X509_STORE_CTX *ctx)
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1708
|
+
static int check_policy(X509_STORE_CTX *ctx) {
|
|
1709
|
+
int ret;
|
|
1710
|
+
if (ctx->parent) {
|
|
1711
|
+
return 1;
|
|
1712
|
+
}
|
|
1713
|
+
ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
|
|
1714
|
+
ctx->param->policies, ctx->param->flags);
|
|
1715
|
+
if (ret == 0) {
|
|
1716
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
1717
|
+
ctx->error = X509_V_ERR_OUT_OF_MEM;
|
|
1718
|
+
return 0;
|
|
1719
|
+
}
|
|
1720
|
+
// Invalid or inconsistent extensions
|
|
1721
|
+
if (ret == -1) {
|
|
1722
|
+
// Locate certificates with bad extensions and notify callback.
|
|
1723
|
+
X509 *x;
|
|
1724
|
+
size_t i;
|
|
1725
|
+
for (i = 1; i < sk_X509_num(ctx->chain); i++) {
|
|
1726
|
+
x = sk_X509_value(ctx->chain, i);
|
|
1727
|
+
if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) {
|
|
1728
|
+
continue;
|
|
1729
|
+
}
|
|
1730
|
+
ctx->current_cert = x;
|
|
1731
|
+
ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
|
|
1732
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1700
1733
|
return 0;
|
|
1734
|
+
}
|
|
1701
1735
|
}
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
return 1;
|
|
1719
|
-
}
|
|
1720
|
-
if (ret == -2) {
|
|
1721
|
-
ctx->current_cert = NULL;
|
|
1722
|
-
ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
|
|
1723
|
-
return ctx->verify_cb(0, ctx);
|
|
1724
|
-
}
|
|
1725
|
-
|
|
1726
|
-
if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
|
|
1727
|
-
ctx->current_cert = NULL;
|
|
1728
|
-
/*
|
|
1729
|
-
* Verification errors need to be "sticky", a callback may have allowed
|
|
1730
|
-
* an SSL handshake to continue despite an error, and we must then
|
|
1731
|
-
* remain in an error state. Therefore, we MUST NOT clear earlier
|
|
1732
|
-
* verification errors by setting the error to X509_V_OK.
|
|
1733
|
-
*/
|
|
1734
|
-
if (!ctx->verify_cb(2, ctx))
|
|
1735
|
-
return 0;
|
|
1736
|
+
return 1;
|
|
1737
|
+
}
|
|
1738
|
+
if (ret == -2) {
|
|
1739
|
+
ctx->current_cert = NULL;
|
|
1740
|
+
ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
|
|
1741
|
+
return ctx->verify_cb(0, ctx);
|
|
1742
|
+
}
|
|
1743
|
+
|
|
1744
|
+
if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
|
|
1745
|
+
ctx->current_cert = NULL;
|
|
1746
|
+
// Verification errors need to be "sticky", a callback may have allowed
|
|
1747
|
+
// an SSL handshake to continue despite an error, and we must then
|
|
1748
|
+
// remain in an error state. Therefore, we MUST NOT clear earlier
|
|
1749
|
+
// verification errors by setting the error to X509_V_OK.
|
|
1750
|
+
if (!ctx->verify_cb(2, ctx)) {
|
|
1751
|
+
return 0;
|
|
1736
1752
|
}
|
|
1753
|
+
}
|
|
1737
1754
|
|
|
1738
|
-
|
|
1755
|
+
return 1;
|
|
1739
1756
|
}
|
|
1740
1757
|
|
|
1741
|
-
static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
int i;
|
|
1758
|
+
static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) {
|
|
1759
|
+
time_t *ptime;
|
|
1760
|
+
int i;
|
|
1745
1761
|
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1762
|
+
if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) {
|
|
1763
|
+
ptime = &ctx->param->check_time;
|
|
1764
|
+
} else {
|
|
1765
|
+
ptime = NULL;
|
|
1766
|
+
}
|
|
1750
1767
|
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1768
|
+
i = X509_cmp_time(X509_get_notBefore(x), ptime);
|
|
1769
|
+
if (i == 0) {
|
|
1770
|
+
ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
|
|
1771
|
+
ctx->current_cert = x;
|
|
1772
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1773
|
+
return 0;
|
|
1757
1774
|
}
|
|
1775
|
+
}
|
|
1758
1776
|
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1777
|
+
if (i > 0) {
|
|
1778
|
+
ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
|
|
1779
|
+
ctx->current_cert = x;
|
|
1780
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1781
|
+
return 0;
|
|
1764
1782
|
}
|
|
1783
|
+
}
|
|
1765
1784
|
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1785
|
+
i = X509_cmp_time(X509_get_notAfter(x), ptime);
|
|
1786
|
+
if (i == 0) {
|
|
1787
|
+
ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
|
|
1788
|
+
ctx->current_cert = x;
|
|
1789
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1790
|
+
return 0;
|
|
1772
1791
|
}
|
|
1792
|
+
}
|
|
1773
1793
|
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1794
|
+
if (i < 0) {
|
|
1795
|
+
ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
|
|
1796
|
+
ctx->current_cert = x;
|
|
1797
|
+
if (!ctx->verify_cb(0, ctx)) {
|
|
1798
|
+
return 0;
|
|
1779
1799
|
}
|
|
1800
|
+
}
|
|
1780
1801
|
|
|
1781
|
-
|
|
1802
|
+
return 1;
|
|
1782
1803
|
}
|
|
1783
1804
|
|
|
1784
|
-
static int internal_verify(X509_STORE_CTX *ctx)
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
EVP_PKEY *pkey = NULL;
|
|
1805
|
+
static int internal_verify(X509_STORE_CTX *ctx) {
|
|
1806
|
+
int ok = 0, n;
|
|
1807
|
+
X509 *xs, *xi;
|
|
1808
|
+
EVP_PKEY *pkey = NULL;
|
|
1789
1809
|
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
if (ctx->check_issued(ctx, xi, xi))
|
|
1796
|
-
xs = xi;
|
|
1797
|
-
else {
|
|
1798
|
-
if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
|
|
1799
|
-
xs = xi;
|
|
1800
|
-
goto check_cert;
|
|
1801
|
-
}
|
|
1802
|
-
if (n <= 0) {
|
|
1803
|
-
ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
|
|
1804
|
-
ctx->current_cert = xi;
|
|
1805
|
-
ok = ctx->verify_cb(0, ctx);
|
|
1806
|
-
goto end;
|
|
1807
|
-
} else {
|
|
1808
|
-
n--;
|
|
1809
|
-
ctx->error_depth = n;
|
|
1810
|
-
xs = sk_X509_value(ctx->chain, n);
|
|
1811
|
-
}
|
|
1812
|
-
}
|
|
1810
|
+
n = sk_X509_num(ctx->chain);
|
|
1811
|
+
ctx->error_depth = n - 1;
|
|
1812
|
+
n--;
|
|
1813
|
+
xi = sk_X509_value(ctx->chain, n);
|
|
1813
1814
|
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1815
|
+
if (ctx->check_issued(ctx, xi, xi)) {
|
|
1816
|
+
xs = xi;
|
|
1817
|
+
} else {
|
|
1818
|
+
if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
|
|
1819
|
+
xs = xi;
|
|
1820
|
+
goto check_cert;
|
|
1821
|
+
}
|
|
1822
|
+
if (n <= 0) {
|
|
1823
|
+
ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
|
|
1824
|
+
ctx->current_cert = xi;
|
|
1825
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1826
|
+
goto end;
|
|
1827
|
+
} else {
|
|
1828
|
+
n--;
|
|
1829
|
+
ctx->error_depth = n;
|
|
1830
|
+
xs = sk_X509_value(ctx->chain, n);
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
// ctx->error=0; not needed
|
|
1835
|
+
while (n >= 0) {
|
|
1836
|
+
ctx->error_depth = n;
|
|
1837
|
+
|
|
1838
|
+
// Skip signature check for self signed certificates unless
|
|
1839
|
+
// explicitly asked for. It doesn't add any security and just wastes
|
|
1840
|
+
// time.
|
|
1841
|
+
if (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)) {
|
|
1842
|
+
if ((pkey = X509_get_pubkey(xi)) == NULL) {
|
|
1843
|
+
ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
|
|
1844
|
+
ctx->current_cert = xi;
|
|
1845
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1846
|
+
if (!ok) {
|
|
1847
|
+
goto end;
|
|
1841
1848
|
}
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
ok = check_cert_time(ctx, xs);
|
|
1845
|
-
if (!ok)
|
|
1846
|
-
goto end;
|
|
1847
|
-
|
|
1848
|
-
/* The last error (if any) is still in the error value */
|
|
1849
|
-
ctx->current_issuer = xi;
|
|
1849
|
+
} else if (X509_verify(xs, pkey) <= 0) {
|
|
1850
|
+
ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
|
|
1850
1851
|
ctx->current_cert = xs;
|
|
1851
|
-
ok = ctx->verify_cb(
|
|
1852
|
-
if (!ok)
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
n--;
|
|
1856
|
-
if (n >= 0) {
|
|
1857
|
-
xi = xs;
|
|
1858
|
-
xs = sk_X509_value(ctx->chain, n);
|
|
1852
|
+
ok = ctx->verify_cb(0, ctx);
|
|
1853
|
+
if (!ok) {
|
|
1854
|
+
EVP_PKEY_free(pkey);
|
|
1855
|
+
goto end;
|
|
1859
1856
|
}
|
|
1857
|
+
}
|
|
1858
|
+
EVP_PKEY_free(pkey);
|
|
1859
|
+
pkey = NULL;
|
|
1860
1860
|
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
int X509_cmp_current_time(const ASN1_TIME *ctm)
|
|
1867
|
-
{
|
|
1868
|
-
return X509_cmp_time(ctm, NULL);
|
|
1869
|
-
}
|
|
1870
|
-
|
|
1871
|
-
int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
|
|
1872
|
-
{
|
|
1873
|
-
static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1;
|
|
1874
|
-
static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1;
|
|
1875
|
-
ASN1_TIME *asn1_cmp_time = NULL;
|
|
1876
|
-
int i, day, sec, ret = 0;
|
|
1877
|
-
|
|
1878
|
-
/*
|
|
1879
|
-
* Note that ASN.1 allows much more slack in the time format than RFC 5280.
|
|
1880
|
-
* In RFC 5280, the representation is fixed:
|
|
1881
|
-
* UTCTime: YYMMDDHHMMSSZ
|
|
1882
|
-
* GeneralizedTime: YYYYMMDDHHMMSSZ
|
|
1883
|
-
*
|
|
1884
|
-
* We do NOT currently enforce the following RFC 5280 requirement:
|
|
1885
|
-
* "CAs conforming to this profile MUST always encode certificate
|
|
1886
|
-
* validity dates through the year 2049 as UTCTime; certificate validity
|
|
1887
|
-
* dates in 2050 or later MUST be encoded as GeneralizedTime."
|
|
1888
|
-
*/
|
|
1889
|
-
switch (ctm->type) {
|
|
1890
|
-
case V_ASN1_UTCTIME:
|
|
1891
|
-
if (ctm->length != (int)(utctime_length))
|
|
1892
|
-
return 0;
|
|
1893
|
-
break;
|
|
1894
|
-
case V_ASN1_GENERALIZEDTIME:
|
|
1895
|
-
if (ctm->length != (int)(generalizedtime_length))
|
|
1896
|
-
return 0;
|
|
1897
|
-
break;
|
|
1898
|
-
default:
|
|
1899
|
-
return 0;
|
|
1861
|
+
|
|
1862
|
+
check_cert:
|
|
1863
|
+
ok = check_cert_time(ctx, xs);
|
|
1864
|
+
if (!ok) {
|
|
1865
|
+
goto end;
|
|
1900
1866
|
}
|
|
1901
1867
|
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
if (!isdigit(ctm->data[i]))
|
|
1909
|
-
return 0;
|
|
1868
|
+
// The last error (if any) is still in the error value
|
|
1869
|
+
ctx->current_issuer = xi;
|
|
1870
|
+
ctx->current_cert = xs;
|
|
1871
|
+
ok = ctx->verify_cb(1, ctx);
|
|
1872
|
+
if (!ok) {
|
|
1873
|
+
goto end;
|
|
1910
1874
|
}
|
|
1911
|
-
|
|
1875
|
+
|
|
1876
|
+
n--;
|
|
1877
|
+
if (n >= 0) {
|
|
1878
|
+
xi = xs;
|
|
1879
|
+
xs = sk_X509_value(ctx->chain, n);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
ok = 1;
|
|
1883
|
+
end:
|
|
1884
|
+
return ok;
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
int X509_cmp_current_time(const ASN1_TIME *ctm) {
|
|
1888
|
+
return X509_cmp_time(ctm, NULL);
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) {
|
|
1892
|
+
static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1;
|
|
1893
|
+
static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1;
|
|
1894
|
+
ASN1_TIME *asn1_cmp_time = NULL;
|
|
1895
|
+
int i, day, sec, ret = 0;
|
|
1896
|
+
|
|
1897
|
+
// Note that ASN.1 allows much more slack in the time format than RFC 5280.
|
|
1898
|
+
// In RFC 5280, the representation is fixed:
|
|
1899
|
+
// UTCTime: YYMMDDHHMMSSZ
|
|
1900
|
+
// GeneralizedTime: YYYYMMDDHHMMSSZ
|
|
1901
|
+
//
|
|
1902
|
+
// We do NOT currently enforce the following RFC 5280 requirement:
|
|
1903
|
+
// "CAs conforming to this profile MUST always encode certificate
|
|
1904
|
+
// validity dates through the year 2049 as UTCTime; certificate validity
|
|
1905
|
+
// dates in 2050 or later MUST be encoded as GeneralizedTime."
|
|
1906
|
+
switch (ctm->type) {
|
|
1907
|
+
case V_ASN1_UTCTIME:
|
|
1908
|
+
if (ctm->length != (int)(utctime_length)) {
|
|
1909
|
+
return 0;
|
|
1910
|
+
}
|
|
1911
|
+
break;
|
|
1912
|
+
case V_ASN1_GENERALIZEDTIME:
|
|
1913
|
+
if (ctm->length != (int)(generalizedtime_length)) {
|
|
1912
1914
|
return 0;
|
|
1915
|
+
}
|
|
1916
|
+
break;
|
|
1917
|
+
default:
|
|
1918
|
+
return 0;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
//*
|
|
1922
|
+
// Verify the format: the ASN.1 functions we use below allow a more
|
|
1923
|
+
// flexible format than what's mandated by RFC 5280.
|
|
1924
|
+
// Digit and date ranges will be verified in the conversion methods.
|
|
1925
|
+
for (i = 0; i < ctm->length - 1; i++) {
|
|
1926
|
+
if (!isdigit(ctm->data[i])) {
|
|
1927
|
+
return 0;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
if (ctm->data[ctm->length - 1] != 'Z') {
|
|
1931
|
+
return 0;
|
|
1932
|
+
}
|
|
1913
1933
|
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1934
|
+
// There is ASN1_UTCTIME_cmp_time_t but no
|
|
1935
|
+
// ASN1_GENERALIZEDTIME_cmp_time_t or ASN1_TIME_cmp_time_t,
|
|
1936
|
+
// so we go through ASN.1
|
|
1937
|
+
asn1_cmp_time = X509_time_adj(NULL, 0, cmp_time);
|
|
1938
|
+
if (asn1_cmp_time == NULL) {
|
|
1939
|
+
goto err;
|
|
1940
|
+
}
|
|
1941
|
+
if (!ASN1_TIME_diff(&day, &sec, ctm, asn1_cmp_time)) {
|
|
1942
|
+
goto err;
|
|
1943
|
+
}
|
|
1924
1944
|
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
*/
|
|
1929
|
-
ret = (day >= 0 && sec >= 0) ? -1 : 1;
|
|
1945
|
+
// X509_cmp_time comparison is <=.
|
|
1946
|
+
// The return value 0 is reserved for errors.
|
|
1947
|
+
ret = (day >= 0 && sec >= 0) ? -1 : 1;
|
|
1930
1948
|
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1949
|
+
err:
|
|
1950
|
+
ASN1_TIME_free(asn1_cmp_time);
|
|
1951
|
+
return ret;
|
|
1934
1952
|
}
|
|
1935
1953
|
|
|
1936
|
-
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec)
|
|
1937
|
-
|
|
1938
|
-
return X509_time_adj(s, offset_sec, NULL);
|
|
1954
|
+
ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long offset_sec) {
|
|
1955
|
+
return X509_time_adj(s, offset_sec, NULL);
|
|
1939
1956
|
}
|
|
1940
1957
|
|
|
1941
|
-
ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
|
|
1942
|
-
|
|
1943
|
-
return X509_time_adj_ex(s, 0, offset_sec, in_tm);
|
|
1958
|
+
ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) {
|
|
1959
|
+
return X509_time_adj_ex(s, 0, offset_sec, in_tm);
|
|
1944
1960
|
}
|
|
1945
1961
|
|
|
1946
|
-
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
time_t t = 0;
|
|
1962
|
+
ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec,
|
|
1963
|
+
time_t *in_tm) {
|
|
1964
|
+
time_t t = 0;
|
|
1950
1965
|
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
return ASN1_TIME_adj(s, t, offset_day, offset_sec);
|
|
1958
|
-
}
|
|
1959
|
-
|
|
1960
|
-
/* Make a delta CRL as the diff between two full CRLs */
|
|
1961
|
-
|
|
1962
|
-
X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
|
|
1963
|
-
EVP_PKEY *skey, const EVP_MD *md, unsigned int flags)
|
|
1964
|
-
{
|
|
1965
|
-
X509_CRL *crl = NULL;
|
|
1966
|
-
int i;
|
|
1967
|
-
size_t j;
|
|
1968
|
-
STACK_OF(X509_REVOKED) *revs = NULL;
|
|
1969
|
-
/* CRLs can't be delta already */
|
|
1970
|
-
if (base->base_crl_number || newer->base_crl_number) {
|
|
1971
|
-
OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
|
|
1972
|
-
return NULL;
|
|
1973
|
-
}
|
|
1974
|
-
/* Base and new CRL must have a CRL number */
|
|
1975
|
-
if (!base->crl_number || !newer->crl_number) {
|
|
1976
|
-
OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
|
|
1977
|
-
return NULL;
|
|
1978
|
-
}
|
|
1979
|
-
/* Issuer names must match */
|
|
1980
|
-
if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
|
|
1981
|
-
OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
|
|
1982
|
-
return NULL;
|
|
1983
|
-
}
|
|
1984
|
-
/* AKID and IDP must match */
|
|
1985
|
-
if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
|
|
1986
|
-
OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
|
|
1987
|
-
return NULL;
|
|
1988
|
-
}
|
|
1989
|
-
if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
|
|
1990
|
-
OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
|
|
1991
|
-
return NULL;
|
|
1992
|
-
}
|
|
1993
|
-
/* Newer CRL number must exceed full CRL number */
|
|
1994
|
-
if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
|
|
1995
|
-
OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
|
|
1996
|
-
return NULL;
|
|
1997
|
-
}
|
|
1998
|
-
/* CRLs must verify */
|
|
1999
|
-
if (skey && (X509_CRL_verify(base, skey) <= 0 ||
|
|
2000
|
-
X509_CRL_verify(newer, skey) <= 0)) {
|
|
2001
|
-
OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
|
|
2002
|
-
return NULL;
|
|
2003
|
-
}
|
|
2004
|
-
/* Create new CRL */
|
|
2005
|
-
crl = X509_CRL_new();
|
|
2006
|
-
if (!crl || !X509_CRL_set_version(crl, X509_CRL_VERSION_2))
|
|
2007
|
-
goto memerr;
|
|
2008
|
-
/* Set issuer name */
|
|
2009
|
-
if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer)))
|
|
2010
|
-
goto memerr;
|
|
1966
|
+
if (in_tm) {
|
|
1967
|
+
t = *in_tm;
|
|
1968
|
+
} else {
|
|
1969
|
+
time(&t);
|
|
1970
|
+
}
|
|
2011
1971
|
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer)))
|
|
2015
|
-
goto memerr;
|
|
1972
|
+
return ASN1_TIME_adj(s, t, offset_day, offset_sec);
|
|
1973
|
+
}
|
|
2016
1974
|
|
|
2017
|
-
|
|
1975
|
+
// Make a delta CRL as the diff between two full CRLs
|
|
2018
1976
|
|
|
2019
|
-
|
|
1977
|
+
X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, EVP_PKEY *skey,
|
|
1978
|
+
const EVP_MD *md, unsigned int flags) {
|
|
1979
|
+
X509_CRL *crl = NULL;
|
|
1980
|
+
int i;
|
|
1981
|
+
size_t j;
|
|
1982
|
+
STACK_OF(X509_REVOKED) *revs = NULL;
|
|
1983
|
+
// CRLs can't be delta already
|
|
1984
|
+
if (base->base_crl_number || newer->base_crl_number) {
|
|
1985
|
+
OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
|
|
1986
|
+
return NULL;
|
|
1987
|
+
}
|
|
1988
|
+
// Base and new CRL must have a CRL number
|
|
1989
|
+
if (!base->crl_number || !newer->crl_number) {
|
|
1990
|
+
OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
|
|
1991
|
+
return NULL;
|
|
1992
|
+
}
|
|
1993
|
+
// Issuer names must match
|
|
1994
|
+
if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(newer))) {
|
|
1995
|
+
OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
|
|
1996
|
+
return NULL;
|
|
1997
|
+
}
|
|
1998
|
+
// AKID and IDP must match
|
|
1999
|
+
if (!crl_extension_match(base, newer, NID_authority_key_identifier)) {
|
|
2000
|
+
OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
|
|
2001
|
+
return NULL;
|
|
2002
|
+
}
|
|
2003
|
+
if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) {
|
|
2004
|
+
OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
|
|
2005
|
+
return NULL;
|
|
2006
|
+
}
|
|
2007
|
+
// Newer CRL number must exceed full CRL number
|
|
2008
|
+
if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0) {
|
|
2009
|
+
OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
|
|
2010
|
+
return NULL;
|
|
2011
|
+
}
|
|
2012
|
+
// CRLs must verify
|
|
2013
|
+
if (skey &&
|
|
2014
|
+
(X509_CRL_verify(base, skey) <= 0 || X509_CRL_verify(newer, skey) <= 0)) {
|
|
2015
|
+
OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
|
|
2016
|
+
return NULL;
|
|
2017
|
+
}
|
|
2018
|
+
// Create new CRL
|
|
2019
|
+
crl = X509_CRL_new();
|
|
2020
|
+
if (!crl || !X509_CRL_set_version(crl, X509_CRL_VERSION_2)) {
|
|
2021
|
+
goto memerr;
|
|
2022
|
+
}
|
|
2023
|
+
// Set issuer name
|
|
2024
|
+
if (!X509_CRL_set_issuer_name(crl, X509_CRL_get_issuer(newer))) {
|
|
2025
|
+
goto memerr;
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
if (!X509_CRL_set1_lastUpdate(crl, X509_CRL_get0_lastUpdate(newer))) {
|
|
2029
|
+
goto memerr;
|
|
2030
|
+
}
|
|
2031
|
+
if (!X509_CRL_set1_nextUpdate(crl, X509_CRL_get0_nextUpdate(newer))) {
|
|
2032
|
+
goto memerr;
|
|
2033
|
+
}
|
|
2034
|
+
|
|
2035
|
+
// Set base CRL number: must be critical
|
|
2036
|
+
|
|
2037
|
+
if (!X509_CRL_add1_ext_i2d(crl, NID_delta_crl, base->crl_number, 1, 0)) {
|
|
2038
|
+
goto memerr;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
// Copy extensions across from newest CRL to delta: this will set CRL
|
|
2042
|
+
// number to correct value too.
|
|
2043
|
+
|
|
2044
|
+
for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
|
|
2045
|
+
X509_EXTENSION *ext;
|
|
2046
|
+
ext = X509_CRL_get_ext(newer, i);
|
|
2047
|
+
if (!X509_CRL_add_ext(crl, ext, -1)) {
|
|
2048
|
+
goto memerr;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
|
|
2052
|
+
// Go through revoked entries, copying as needed
|
|
2053
|
+
|
|
2054
|
+
revs = X509_CRL_get_REVOKED(newer);
|
|
2055
|
+
|
|
2056
|
+
for (j = 0; j < sk_X509_REVOKED_num(revs); j++) {
|
|
2057
|
+
X509_REVOKED *rvn, *rvtmp;
|
|
2058
|
+
rvn = sk_X509_REVOKED_value(revs, j);
|
|
2059
|
+
// Add only if not also in base. TODO: need something cleverer here
|
|
2060
|
+
// for some more complex CRLs covering multiple CAs.
|
|
2061
|
+
if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
|
|
2062
|
+
rvtmp = X509_REVOKED_dup(rvn);
|
|
2063
|
+
if (!rvtmp) {
|
|
2020
2064
|
goto memerr;
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
for (i = 0; i < X509_CRL_get_ext_count(newer); i++) {
|
|
2028
|
-
X509_EXTENSION *ext;
|
|
2029
|
-
ext = X509_CRL_get_ext(newer, i);
|
|
2030
|
-
if (!X509_CRL_add_ext(crl, ext, -1))
|
|
2031
|
-
goto memerr;
|
|
2032
|
-
}
|
|
2033
|
-
|
|
2034
|
-
/* Go through revoked entries, copying as needed */
|
|
2035
|
-
|
|
2036
|
-
revs = X509_CRL_get_REVOKED(newer);
|
|
2037
|
-
|
|
2038
|
-
for (j = 0; j < sk_X509_REVOKED_num(revs); j++) {
|
|
2039
|
-
X509_REVOKED *rvn, *rvtmp;
|
|
2040
|
-
rvn = sk_X509_REVOKED_value(revs, j);
|
|
2041
|
-
/*
|
|
2042
|
-
* Add only if not also in base. TODO: need something cleverer here
|
|
2043
|
-
* for some more complex CRLs covering multiple CAs.
|
|
2044
|
-
*/
|
|
2045
|
-
if (!X509_CRL_get0_by_serial(base, &rvtmp, rvn->serialNumber)) {
|
|
2046
|
-
rvtmp = X509_REVOKED_dup(rvn);
|
|
2047
|
-
if (!rvtmp)
|
|
2048
|
-
goto memerr;
|
|
2049
|
-
if (!X509_CRL_add0_revoked(crl, rvtmp)) {
|
|
2050
|
-
X509_REVOKED_free(rvtmp);
|
|
2051
|
-
goto memerr;
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2065
|
+
}
|
|
2066
|
+
if (!X509_CRL_add0_revoked(crl, rvtmp)) {
|
|
2067
|
+
X509_REVOKED_free(rvtmp);
|
|
2068
|
+
goto memerr;
|
|
2069
|
+
}
|
|
2054
2070
|
}
|
|
2055
|
-
|
|
2071
|
+
}
|
|
2072
|
+
// TODO: optionally prune deleted entries
|
|
2056
2073
|
|
|
2057
|
-
|
|
2058
|
-
|
|
2074
|
+
if (skey && md && !X509_CRL_sign(crl, skey, md)) {
|
|
2075
|
+
goto memerr;
|
|
2076
|
+
}
|
|
2059
2077
|
|
|
2060
|
-
|
|
2078
|
+
return crl;
|
|
2061
2079
|
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2080
|
+
memerr:
|
|
2081
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
2082
|
+
if (crl) {
|
|
2083
|
+
X509_CRL_free(crl);
|
|
2084
|
+
}
|
|
2085
|
+
return NULL;
|
|
2067
2086
|
}
|
|
2068
2087
|
|
|
2069
2088
|
int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
|
|
2070
|
-
CRYPTO_EX_unused *
|
|
2089
|
+
CRYPTO_EX_unused *unused,
|
|
2071
2090
|
CRYPTO_EX_dup *dup_unused,
|
|
2072
|
-
CRYPTO_EX_free *free_func)
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
return -1;
|
|
2082
|
-
}
|
|
2083
|
-
return index;
|
|
2091
|
+
CRYPTO_EX_free *free_func) {
|
|
2092
|
+
// This function is (usually) called only once, by
|
|
2093
|
+
// SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
|
|
2094
|
+
int index;
|
|
2095
|
+
if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp,
|
|
2096
|
+
free_func)) {
|
|
2097
|
+
return -1;
|
|
2098
|
+
}
|
|
2099
|
+
return index;
|
|
2084
2100
|
}
|
|
2085
2101
|
|
|
2086
|
-
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
|
|
2087
|
-
|
|
2088
|
-
return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
|
|
2102
|
+
int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) {
|
|
2103
|
+
return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
|
|
2089
2104
|
}
|
|
2090
2105
|
|
|
2091
|
-
void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
|
|
2092
|
-
|
|
2093
|
-
return CRYPTO_get_ex_data(&ctx->ex_data, idx);
|
|
2106
|
+
void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) {
|
|
2107
|
+
return CRYPTO_get_ex_data(&ctx->ex_data, idx);
|
|
2094
2108
|
}
|
|
2095
2109
|
|
|
2096
|
-
int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
|
|
2097
|
-
{
|
|
2098
|
-
return ctx->error;
|
|
2099
|
-
}
|
|
2110
|
+
int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) { return ctx->error; }
|
|
2100
2111
|
|
|
2101
|
-
void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
|
|
2102
|
-
|
|
2103
|
-
ctx->error = err;
|
|
2112
|
+
void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) {
|
|
2113
|
+
ctx->error = err;
|
|
2104
2114
|
}
|
|
2105
2115
|
|
|
2106
|
-
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
|
|
2107
|
-
|
|
2108
|
-
return ctx->error_depth;
|
|
2116
|
+
int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) {
|
|
2117
|
+
return ctx->error_depth;
|
|
2109
2118
|
}
|
|
2110
2119
|
|
|
2111
|
-
X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
|
|
2112
|
-
|
|
2113
|
-
return ctx->current_cert;
|
|
2120
|
+
X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) {
|
|
2121
|
+
return ctx->current_cert;
|
|
2114
2122
|
}
|
|
2115
2123
|
|
|
2116
|
-
STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
|
|
2117
|
-
|
|
2118
|
-
return ctx->chain;
|
|
2124
|
+
STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) {
|
|
2125
|
+
return ctx->chain;
|
|
2119
2126
|
}
|
|
2120
2127
|
|
|
2121
|
-
STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx)
|
|
2122
|
-
|
|
2123
|
-
return ctx->chain;
|
|
2128
|
+
STACK_OF(X509) *X509_STORE_CTX_get0_chain(X509_STORE_CTX *ctx) {
|
|
2129
|
+
return ctx->chain;
|
|
2124
2130
|
}
|
|
2125
2131
|
|
|
2126
|
-
STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
|
|
2127
|
-
{
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2132
|
+
STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) {
|
|
2133
|
+
if (!ctx->chain) {
|
|
2134
|
+
return NULL;
|
|
2135
|
+
}
|
|
2136
|
+
return X509_chain_up_ref(ctx->chain);
|
|
2131
2137
|
}
|
|
2132
2138
|
|
|
2133
|
-
X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
|
|
2134
|
-
|
|
2135
|
-
return ctx->current_issuer;
|
|
2139
|
+
X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) {
|
|
2140
|
+
return ctx->current_issuer;
|
|
2136
2141
|
}
|
|
2137
2142
|
|
|
2138
|
-
X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
|
|
2139
|
-
|
|
2140
|
-
return ctx->current_crl;
|
|
2143
|
+
X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) {
|
|
2144
|
+
return ctx->current_crl;
|
|
2141
2145
|
}
|
|
2142
2146
|
|
|
2143
|
-
X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
|
|
2144
|
-
|
|
2145
|
-
return ctx->parent;
|
|
2147
|
+
X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) {
|
|
2148
|
+
return ctx->parent;
|
|
2146
2149
|
}
|
|
2147
2150
|
|
|
2148
|
-
void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
|
|
2149
|
-
{
|
|
2150
|
-
ctx->cert = x;
|
|
2151
|
-
}
|
|
2151
|
+
void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) { ctx->cert = x; }
|
|
2152
2152
|
|
|
2153
|
-
void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
|
|
2154
|
-
|
|
2155
|
-
ctx->untrusted = sk;
|
|
2153
|
+
void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) {
|
|
2154
|
+
ctx->untrusted = sk;
|
|
2156
2155
|
}
|
|
2157
2156
|
|
|
2158
|
-
STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx)
|
|
2159
|
-
|
|
2160
|
-
return ctx->untrusted;
|
|
2157
|
+
STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) {
|
|
2158
|
+
return ctx->untrusted;
|
|
2161
2159
|
}
|
|
2162
2160
|
|
|
2163
|
-
void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
|
|
2164
|
-
|
|
2165
|
-
ctx->crls = sk;
|
|
2161
|
+
void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) {
|
|
2162
|
+
ctx->crls = sk;
|
|
2166
2163
|
}
|
|
2167
2164
|
|
|
2168
|
-
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
|
|
2169
|
-
|
|
2170
|
-
return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
|
|
2165
|
+
int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) {
|
|
2166
|
+
return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
|
|
2171
2167
|
}
|
|
2172
2168
|
|
|
2173
|
-
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
|
|
2174
|
-
|
|
2175
|
-
return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
|
|
2169
|
+
int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) {
|
|
2170
|
+
return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
|
|
2176
2171
|
}
|
|
2177
2172
|
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
* client/server.
|
|
2187
|
-
*/
|
|
2173
|
+
// This function is used to set the X509_STORE_CTX purpose and trust values.
|
|
2174
|
+
// This is intended to be used when another structure has its own trust and
|
|
2175
|
+
// purpose values which (if set) will be inherited by the ctx. If they aren't
|
|
2176
|
+
// set then we will usually have a default purpose in mind which should then
|
|
2177
|
+
// be used to set the trust value. An example of this is SSL use: an SSL
|
|
2178
|
+
// structure will have its own purpose and trust settings which the
|
|
2179
|
+
// application can set: if they aren't set then we use the default of SSL
|
|
2180
|
+
// client/server.
|
|
2188
2181
|
|
|
2189
2182
|
int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
|
|
2190
|
-
int purpose, int trust)
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
}
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
}
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2183
|
+
int purpose, int trust) {
|
|
2184
|
+
int idx;
|
|
2185
|
+
// If purpose not set use default
|
|
2186
|
+
if (!purpose) {
|
|
2187
|
+
purpose = def_purpose;
|
|
2188
|
+
}
|
|
2189
|
+
// If we have a purpose then check it is valid
|
|
2190
|
+
if (purpose) {
|
|
2191
|
+
X509_PURPOSE *ptmp;
|
|
2192
|
+
idx = X509_PURPOSE_get_by_id(purpose);
|
|
2193
|
+
if (idx == -1) {
|
|
2194
|
+
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
|
|
2195
|
+
return 0;
|
|
2196
|
+
}
|
|
2197
|
+
ptmp = X509_PURPOSE_get0(idx);
|
|
2198
|
+
if (ptmp->trust == X509_TRUST_DEFAULT) {
|
|
2199
|
+
idx = X509_PURPOSE_get_by_id(def_purpose);
|
|
2200
|
+
if (idx == -1) {
|
|
2201
|
+
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
|
|
2202
|
+
return 0;
|
|
2203
|
+
}
|
|
2204
|
+
ptmp = X509_PURPOSE_get0(idx);
|
|
2205
|
+
}
|
|
2206
|
+
// If trust not set then get from purpose default
|
|
2207
|
+
if (!trust) {
|
|
2208
|
+
trust = ptmp->trust;
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
if (trust) {
|
|
2212
|
+
idx = X509_TRUST_get_by_id(trust);
|
|
2213
|
+
if (idx == -1) {
|
|
2214
|
+
OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
|
|
2215
|
+
return 0;
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
if (purpose && !ctx->param->purpose) {
|
|
2220
|
+
ctx->param->purpose = purpose;
|
|
2221
|
+
}
|
|
2222
|
+
if (trust && !ctx->param->trust) {
|
|
2223
|
+
ctx->param->trust = trust;
|
|
2224
|
+
}
|
|
2225
|
+
return 1;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
X509_STORE_CTX *X509_STORE_CTX_new(void) {
|
|
2229
|
+
X509_STORE_CTX *ctx;
|
|
2230
|
+
ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
|
|
2231
|
+
if (!ctx) {
|
|
2232
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
2233
|
+
return NULL;
|
|
2234
|
+
}
|
|
2235
|
+
X509_STORE_CTX_zero(ctx);
|
|
2236
|
+
return ctx;
|
|
2242
2237
|
}
|
|
2243
2238
|
|
|
2244
|
-
void X509_STORE_CTX_zero(X509_STORE_CTX *ctx)
|
|
2245
|
-
|
|
2246
|
-
OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
|
|
2239
|
+
void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) {
|
|
2240
|
+
OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
|
|
2247
2241
|
}
|
|
2248
2242
|
|
|
2249
|
-
void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
|
|
2250
|
-
{
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
OPENSSL_free(ctx);
|
|
2243
|
+
void X509_STORE_CTX_free(X509_STORE_CTX *ctx) {
|
|
2244
|
+
if (ctx == NULL) {
|
|
2245
|
+
return;
|
|
2246
|
+
}
|
|
2247
|
+
X509_STORE_CTX_cleanup(ctx);
|
|
2248
|
+
OPENSSL_free(ctx);
|
|
2256
2249
|
}
|
|
2257
2250
|
|
|
2258
2251
|
int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
|
|
2259
|
-
STACK_OF(X509) *chain)
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2252
|
+
STACK_OF(X509) *chain) {
|
|
2253
|
+
X509_STORE_CTX_zero(ctx);
|
|
2254
|
+
ctx->ctx = store;
|
|
2255
|
+
ctx->cert = x509;
|
|
2256
|
+
ctx->untrusted = chain;
|
|
2257
|
+
|
|
2258
|
+
CRYPTO_new_ex_data(&ctx->ex_data);
|
|
2259
|
+
|
|
2260
|
+
if (store == NULL) {
|
|
2261
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
|
|
2262
|
+
goto err;
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
ctx->param = X509_VERIFY_PARAM_new();
|
|
2266
|
+
if (!ctx->param) {
|
|
2267
|
+
goto err;
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
// Inherit callbacks and flags from X509_STORE.
|
|
2271
|
+
|
|
2272
|
+
ctx->verify_cb = store->verify_cb;
|
|
2273
|
+
ctx->cleanup = store->cleanup;
|
|
2274
|
+
|
|
2275
|
+
if (!X509_VERIFY_PARAM_inherit(ctx->param, store->param) ||
|
|
2276
|
+
!X509_VERIFY_PARAM_inherit(ctx->param,
|
|
2277
|
+
X509_VERIFY_PARAM_lookup("default"))) {
|
|
2278
|
+
goto err;
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
if (store->check_issued) {
|
|
2282
|
+
ctx->check_issued = store->check_issued;
|
|
2283
|
+
} else {
|
|
2284
|
+
ctx->check_issued = check_issued;
|
|
2285
|
+
}
|
|
2286
|
+
|
|
2287
|
+
if (store->get_issuer) {
|
|
2288
|
+
ctx->get_issuer = store->get_issuer;
|
|
2289
|
+
} else {
|
|
2290
|
+
ctx->get_issuer = X509_STORE_CTX_get1_issuer;
|
|
2291
|
+
}
|
|
2292
|
+
|
|
2293
|
+
if (store->verify_cb) {
|
|
2281
2294
|
ctx->verify_cb = store->verify_cb;
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
ctx->
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
}
|
|
2383
|
-
if (ctx->chain != NULL) {
|
|
2384
|
-
sk_X509_pop_free(ctx->chain, X509_free);
|
|
2385
|
-
ctx->chain = NULL;
|
|
2386
|
-
}
|
|
2387
|
-
CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
|
|
2388
|
-
OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
|
|
2389
|
-
}
|
|
2390
|
-
|
|
2391
|
-
void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
|
|
2392
|
-
{
|
|
2393
|
-
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
|
|
2394
|
-
}
|
|
2395
|
-
|
|
2396
|
-
void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
|
|
2397
|
-
{
|
|
2398
|
-
X509_VERIFY_PARAM_set_flags(ctx->param, flags);
|
|
2295
|
+
} else {
|
|
2296
|
+
ctx->verify_cb = null_callback;
|
|
2297
|
+
}
|
|
2298
|
+
|
|
2299
|
+
if (store->verify) {
|
|
2300
|
+
ctx->verify = store->verify;
|
|
2301
|
+
} else {
|
|
2302
|
+
ctx->verify = internal_verify;
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
if (store->check_revocation) {
|
|
2306
|
+
ctx->check_revocation = store->check_revocation;
|
|
2307
|
+
} else {
|
|
2308
|
+
ctx->check_revocation = check_revocation;
|
|
2309
|
+
}
|
|
2310
|
+
|
|
2311
|
+
if (store->get_crl) {
|
|
2312
|
+
ctx->get_crl = store->get_crl;
|
|
2313
|
+
} else {
|
|
2314
|
+
ctx->get_crl = NULL;
|
|
2315
|
+
}
|
|
2316
|
+
|
|
2317
|
+
if (store->check_crl) {
|
|
2318
|
+
ctx->check_crl = store->check_crl;
|
|
2319
|
+
} else {
|
|
2320
|
+
ctx->check_crl = check_crl;
|
|
2321
|
+
}
|
|
2322
|
+
|
|
2323
|
+
if (store->cert_crl) {
|
|
2324
|
+
ctx->cert_crl = store->cert_crl;
|
|
2325
|
+
} else {
|
|
2326
|
+
ctx->cert_crl = cert_crl;
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2329
|
+
if (store->lookup_certs) {
|
|
2330
|
+
ctx->lookup_certs = store->lookup_certs;
|
|
2331
|
+
} else {
|
|
2332
|
+
ctx->lookup_certs = X509_STORE_get1_certs;
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2335
|
+
if (store->lookup_crls) {
|
|
2336
|
+
ctx->lookup_crls = store->lookup_crls;
|
|
2337
|
+
} else {
|
|
2338
|
+
ctx->lookup_crls = X509_STORE_get1_crls;
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
ctx->check_policy = check_policy;
|
|
2342
|
+
|
|
2343
|
+
return 1;
|
|
2344
|
+
|
|
2345
|
+
err:
|
|
2346
|
+
CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data);
|
|
2347
|
+
if (ctx->param != NULL) {
|
|
2348
|
+
X509_VERIFY_PARAM_free(ctx->param);
|
|
2349
|
+
}
|
|
2350
|
+
|
|
2351
|
+
OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX));
|
|
2352
|
+
OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
|
|
2353
|
+
return 0;
|
|
2354
|
+
}
|
|
2355
|
+
|
|
2356
|
+
// Set alternative lookup method: just a STACK of trusted certificates. This
|
|
2357
|
+
// avoids X509_STORE nastiness where it isn't needed.
|
|
2358
|
+
|
|
2359
|
+
void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) {
|
|
2360
|
+
ctx->other_ctx = sk;
|
|
2361
|
+
ctx->get_issuer = get_issuer_sk;
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) {
|
|
2365
|
+
// We need to be idempotent because, unfortunately, |X509_STORE_CTX_free|
|
|
2366
|
+
// also calls this function.
|
|
2367
|
+
if (ctx->cleanup != NULL) {
|
|
2368
|
+
ctx->cleanup(ctx);
|
|
2369
|
+
ctx->cleanup = NULL;
|
|
2370
|
+
}
|
|
2371
|
+
if (ctx->param != NULL) {
|
|
2372
|
+
if (ctx->parent == NULL) {
|
|
2373
|
+
X509_VERIFY_PARAM_free(ctx->param);
|
|
2374
|
+
}
|
|
2375
|
+
ctx->param = NULL;
|
|
2376
|
+
}
|
|
2377
|
+
if (ctx->tree != NULL) {
|
|
2378
|
+
X509_policy_tree_free(ctx->tree);
|
|
2379
|
+
ctx->tree = NULL;
|
|
2380
|
+
}
|
|
2381
|
+
if (ctx->chain != NULL) {
|
|
2382
|
+
sk_X509_pop_free(ctx->chain, X509_free);
|
|
2383
|
+
ctx->chain = NULL;
|
|
2384
|
+
}
|
|
2385
|
+
CRYPTO_free_ex_data(&g_ex_data_class, ctx, &(ctx->ex_data));
|
|
2386
|
+
OPENSSL_memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) {
|
|
2390
|
+
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) {
|
|
2394
|
+
X509_VERIFY_PARAM_set_flags(ctx->param, flags);
|
|
2399
2395
|
}
|
|
2400
2396
|
|
|
2401
2397
|
void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
|
|
2402
|
-
time_t t)
|
|
2403
|
-
|
|
2404
|
-
X509_VERIFY_PARAM_set_time(ctx->param, t);
|
|
2398
|
+
time_t t) {
|
|
2399
|
+
X509_VERIFY_PARAM_set_time(ctx->param, t);
|
|
2405
2400
|
}
|
|
2406
2401
|
|
|
2407
|
-
X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
|
|
2408
|
-
{
|
|
2409
|
-
return ctx->cert;
|
|
2410
|
-
}
|
|
2402
|
+
X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx) { return ctx->cert; }
|
|
2411
2403
|
|
|
2412
2404
|
void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
|
|
2413
|
-
int (*verify_cb)
|
|
2414
|
-
|
|
2415
|
-
ctx->verify_cb = verify_cb;
|
|
2405
|
+
int (*verify_cb)(int, X509_STORE_CTX *)) {
|
|
2406
|
+
ctx->verify_cb = verify_cb;
|
|
2416
2407
|
}
|
|
2417
2408
|
|
|
2418
|
-
X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
|
|
2419
|
-
|
|
2420
|
-
return ctx->tree;
|
|
2409
|
+
X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) {
|
|
2410
|
+
return ctx->tree;
|
|
2421
2411
|
}
|
|
2422
2412
|
|
|
2423
|
-
int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
|
|
2424
|
-
|
|
2425
|
-
return ctx->explicit_policy;
|
|
2413
|
+
int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) {
|
|
2414
|
+
return ctx->explicit_policy;
|
|
2426
2415
|
}
|
|
2427
2416
|
|
|
2428
|
-
int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2417
|
+
int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) {
|
|
2418
|
+
const X509_VERIFY_PARAM *param;
|
|
2419
|
+
param = X509_VERIFY_PARAM_lookup(name);
|
|
2420
|
+
if (!param) {
|
|
2421
|
+
return 0;
|
|
2422
|
+
}
|
|
2423
|
+
return X509_VERIFY_PARAM_inherit(ctx->param, param);
|
|
2435
2424
|
}
|
|
2436
2425
|
|
|
2437
|
-
X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
|
|
2438
|
-
|
|
2439
|
-
return ctx->param;
|
|
2426
|
+
X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) {
|
|
2427
|
+
return ctx->param;
|
|
2440
2428
|
}
|
|
2441
2429
|
|
|
2442
|
-
void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
|
|
2443
|
-
{
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2430
|
+
void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) {
|
|
2431
|
+
if (ctx->param) {
|
|
2432
|
+
X509_VERIFY_PARAM_free(ctx->param);
|
|
2433
|
+
}
|
|
2434
|
+
ctx->param = param;
|
|
2447
2435
|
}
|