Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:24
erlang
4001-ssl-public_key-Extended-key-extension-hand...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 4001-ssl-public_key-Extended-key-extension-handling.patch of Package erlang
From e7cd7fc40973493096f1582ae9089d87a7e88991 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin <ingela@erlang.org> Date: Mon, 28 Aug 2023 15:48:34 +0200 Subject: [PATCH 1/2] ssl, public_key: Extended key extension handling --- lib/public_key/src/pubkey_cert.erl | 27 ++++++++++++++++++++ lib/public_key/test/public_key_SUITE.erl | 32 ++++++++++++++++++++++++ lib/ssl/src/ssl_certificate.erl | 30 ++++++++++++++-------- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl index 4d448fd42c..39084f3e76 100644 --- a/lib/public_key/src/pubkey_cert.erl +++ b/lib/public_key/src/pubkey_cert.erl @@ -905,6 +905,27 @@ validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-policyConstraints', validate_extensions(OtpCert, Rest, NewValidationState, ExistBasicCon, SelfSigned, UserState, VerifyFun); +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-extKeyUsage', + critical = true, + extnValue = KeyUse} = Extension | Rest], + ValidationState#path_validation_state{last_cert = false}, ExistBasicCon, + SelfSigned, UserState0, VerifyFun) -> + UserState = + case ext_keyusage_includes_any(KeyUse) of + true -> %% CA cert that specifies ?anyExtendedKeyUsage should not be marked critical + verify_fun(OtpCert, {bad_cert, invalid_ext_key_usage}, UserState0, VerifyFun); + false -> + verify_fun(OtpCert, {extension, Extension}, UserState0, VerifyFun); + end, + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, SelfSigned, + UserState, VerifyFun); +validate_extensions(OtpCert, [#'Extension'{extnID = ?'id-ce-extKeyUsage', + extnValue = KeyUse} = Extension | Rest], + ValidationState, ExistBasicCon, + SelfSigned, UserState0, VerifyFun) -> + UserState = verify_fun(OtpCert, {extension, Ext}, UserState0, VerifyFun), + validate_extensions(OtpCert, Rest, ValidationState, ExistBasicCon, SelfSigned, + UserState, VerifyFun); validate_extensions(OtpCert, [#'Extension'{} = Extension | Rest], ValidationState, ExistBasicCon, SelfSigned, UserState0, VerifyFun) -> @@ -1483,3 +1504,9 @@ verify_options(#'RSASSA-PSS-params'{saltLength = SaltLen, [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_pss_saltlen, SaltLen}, {rsa_mgf1_md, HashAlgo}]. + + +ext_keyusage_includes_any(KeyUse) when is_list(KeyUse) -> + lists:member(?anyExtendedKeyUsage, KeyUse); +ext_keyusage_includes_any(_) -> + false. diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index 1a779e03bd..0edf3d29c6 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -95,6 +95,8 @@ pkix_path_validation/1, pkix_path_validation_root_expired/0, pkix_path_validation_root_expired/1, + pkix_ext_key_usage/0, + pkix_ext_key_usage/1, pkix_verify_hostname_cn/1, pkix_verify_hostname_subjAltName/1, pkix_verify_hostname_options/1, @@ -154,6 +156,7 @@ all() -> pkix_decode_cert, pkix_path_validation, pkix_path_validation_root_expired, + pkix_ext_key_usage, pkix_iso_rsa_oid, pkix_iso_dsa_oid, pkix_dsa_sha2_oid, @@ -927,6 +930,35 @@ pkix_path_validation_root_expired(Config) when is_list(Config) -> Peer = proplists:get_value(cert, Conf), {error, {bad_cert, cert_expired}} = public_key:pkix_path_validation(Root, [ICA, Peer], []). +pkix_ext_key_usage() -> + [{doc, "Extended key usage is usually in end entity certs, may be in CA but should not be critical in such case"}]. +pkix_ext_key_usage(Config) when is_list(Config) -> + SRootSpec = public_key:pkix_test_root_cert("OTP test server ROOT", []), + CRootSpec = public_key:pkix_test_root_cert("OTP test client ROOT", []), + + FailCAExt = [#'Extension'{extnID = ?'id-ce-extKeyUsage', + extnValue = [?'anyExtendedKeyUsage'], + critical = true}], + CAExt = [#'Extension'{extnID = ?'id-ce-extKeyUsage', + extnValue = [?'anyExtendedKeyUsage'], + critical = false}], + + #{server_config := SConf, + client_config := CConf} = public_key:pkix_test_data(#{server_chain => #{root => SRootSpec, + intermediates => [[{extensions, FailCAExt}]], + peer => []}, + client_chain => #{root => CRootSpec, + intermediates => [[{extensions, CAExt}]], + peer => []}}), + [_STRoot, SICA, SRoot] = proplists:get_value(cacerts, SConf), + [_CTRoot, CICA, CRoot] = proplists:get_value(cacerts, CConf), + SPeer = proplists:get_value(cert, SConf), + CPeer = proplists:get_value(cert, CConf), + + {error, {bad_cert, invalid_ext_key_usage}} = public_key:pkix_path_validation(SRoot, [SICA, SPeer], []), + + {ok, _} = public_key:pkix_path_validation(CRoot, [CICA, CPeer], []). + %%-------------------------------------------------------------------- %% To generate the PEM file contents: %% diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index 2e2b43f564..cb1ddbfa05 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -203,12 +203,13 @@ file_to_crls(File, DbHandle) -> %% Description: Validates ssl/tls specific extensions %%-------------------------------------------------------------------- validate(_,{extension, #'Extension'{extnID = ?'id-ce-extKeyUsage', - extnValue = KeyUse}}, UserState = #{role := Role}) -> - case is_valid_extkey_usage(KeyUse, Role) of + critical = Critical, + extnValue = KeyUse}}, #{pathlen := 1} = UserState) -> + case is_valid_extkey_usage(KeyUse, Critical, UserState) of true -> {valid, UserState}; false -> - {fail, {bad_cert, invalid_ext_key_usage}} + {unknown, UserState} end; validate(_, {extension, _}, UserState) -> {unknown, UserState}; @@ -216,14 +217,14 @@ validate(Issuer, {bad_cert, cert_expired}, #{issuer := Issuer}) -> {fail, {bad_cert, root_cert_expired}}; validate(_, {bad_cert, _} = Reason, _) -> {fail, Reason}; -validate(Cert, valid, UserState) -> +validate(Cert, valid, #{pathlen := N} = UserState) -> case verify_sign(Cert, UserState) of true -> case maps:get(cert_ext, UserState, undefined) of undefined -> - {valid, UserState}; + {valid, UserState#{pathlen => N-1}}; _ -> - verify_cert_extensions(Cert, UserState) + verify_cert_extensions(Cert, UserState#{pathlen => N -1}) end; false -> {fail, {bad_cert, invalid_signature}} @@ -493,13 +494,20 @@ do_find_issuer(IssuerFun, CertDbHandle, CertDb) -> throw:{ok, _} = Return -> Return end. - -is_valid_extkey_usage(KeyUse, client) -> + +is_valid_extkey_usage(KeyUse, true, #{role := Role, pathlen := 1}) when is_list(KeyUse) -> + is_valid_key_usage(ext_keysage(Role), KeyUse); +is_valid_key_usage(KeyUse, true, #{role := Role, pathlen := 1}) -> + is_valid_key_usage(ext_keysage(Role), [KeyUse]); +is_valid_key_usage(_, false, _) -> + false. + +ext_keysage(client) -> %% Client wants to verify server - is_valid_key_usage(KeyUse,?'id-kp-serverAuth'); -is_valid_extkey_usage(KeyUse, server) -> + ?'id-kp-serverAuth'. +ext_keysage(server) -> %% Server wants to verify client - is_valid_key_usage(KeyUse, ?'id-kp-clientAuth'). + ?'id-kp-serverAuth'. verify_cert_signer(BinCert, SignerTBSCert) -> PublicKey = public_key(SignerTBSCert#'OTPTBSCertificate'.subjectPublicKeyInfo), -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor