Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
4791-ssl-VerifyFun-can-now-get-the-der-cert-as-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 4791-ssl-VerifyFun-can-now-get-the-der-cert-as-argument.patch of Package erlang
From 9d11335efa6c2b83ec48e26c85d6ac2e46e2bc9f Mon Sep 17 00:00:00 2001 From: Dan Gudmundsson <dgud@erlang.org> Date: Tue, 1 Nov 2022 17:01:54 +0100 Subject: [PATCH] ssl: VerifyFun can now get the der cert as argument In some cases the user may want the original der cert as input to the verify fun. Allow the user to supply VerifyFun/4 as verify_fun option. In later releases one can think that this should be enabled in public_key functions as well. --- lib/ssl/doc/src/ssl.xml | 21 ++++++++++++++++----- lib/ssl/src/ssl_handshake.erl | 18 +++++++++++++----- lib/ssl/test/ssl_cert_SUITE.erl | 24 ++++++++++++++++-------- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/lib/ssl/doc/src/ssl.xml b/lib/ssl/doc/src/ssl.xml index 8c63b1d698..cf62d0979d 100644 --- a/lib/ssl/doc/src/ssl.xml +++ b/lib/ssl/doc/src/ssl.xml @@ -577,11 +577,22 @@ version. <p>The verification fun is to be defined as follows:</p> <code> -fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom() | - {revoked, atom()}} | - {extension, #'Extension'{}} | valid | valid_peer, InitialUserState :: term()) -> +fun(OtpCert :: #'OTPCertificate'{}, + Event, InitialUserState :: term()) -> {valid, UserState :: term()} | {fail, Reason :: term()} | {unknown, UserState :: term()}. + +fun(OtpCert :: #'OTPCertificate'{}, DerCert :: public_key:der_encoded(), + Event, InitialUserState :: term()) -> + {valid, UserState :: term()} | + {fail, Reason :: term()} | {unknown, UserState :: term()}. + +Types: + Event = {bad_cert, Reason :: atom() | + {revoked, atom()}} | + {extension, #'Extension'{}} | + valid | + valid_peer </code> <p>The verification fun is called during the X509-path @@ -591,8 +602,8 @@ fun(OtpCert :: #'OTPCertificate'{}, Event :: {bad_cert, Reason :: atom() | allow access to each certificate in the path to the user application. It differentiates between the peer certificate and the CA certificates by using <c>valid_peer</c> or - <c>valid</c> as second argument to the verification fun. See - the <seeguide marker="public_key:public_key_records">public_key + <c>valid</c> as <c>Event</c> argument to the verification fun. + See the <seeguide marker="public_key:public_key_records">public_key User's Guide</seeguide> for definition of <c>#'OTPCertificate'{}</c> and <c>#'Extension'{}</c>.</p> diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index ee102077af..4e4f243c71 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -2020,8 +2020,8 @@ validation_fun_and_state(undefined, VerifyState, CertPath, LogLevel) -> apply_user_fun(Fun, OtpCert, VerifyResult0, UserState0, SslState, CertPath, LogLevel) when (VerifyResult0 == valid) or (VerifyResult0 == valid_peer) -> VerifyResult = maybe_check_hostname(OtpCert, VerifyResult0, SslState), - case Fun(OtpCert, VerifyResult, UserState0) of - {Valid, UserState} when (Valid == valid) or (Valid == valid_peer) -> + case apply_fun(Fun, OtpCert, VerifyResult, UserState0, CertPath) of + {Valid, UserState} when (Valid == valid) orelse (Valid == valid_peer) -> case cert_status_check(OtpCert, SslState, VerifyResult, CertPath, LogLevel) of valid -> {Valid, {SslState, UserState}}; @@ -2031,9 +2031,9 @@ apply_user_fun(Fun, OtpCert, VerifyResult0, UserState0, SslState, CertPath, LogL {fail, _} = Fail -> Fail end; -apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState, _CertPath, _LogLevel) -> - case Fun(OtpCert, ExtensionOrError, UserState0) of - {Valid, UserState} when (Valid == valid) or (Valid == valid_peer)-> +apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState, CertPath, _LogLevel) -> + case apply_fun(Fun, OtpCert, ExtensionOrError, UserState0, CertPath) of + {Valid, UserState} when (Valid == valid) orelse (Valid == valid_peer)-> {Valid, {SslState, UserState}}; {fail, _} = Fail -> Fail; @@ -2041,6 +2041,14 @@ apply_user_fun(Fun, OtpCert, ExtensionOrError, UserState0, SslState, _CertPath, {unknown, {SslState, UserState}} end. +apply_fun(Fun, OtpCert, ExtensionOrError, UserState, CertPath) -> + if is_function(Fun, 4) -> + #cert{der=DerCert} = lists:keyfind(OtpCert, #cert.otp, CertPath), + Fun(OtpCert, DerCert, ExtensionOrError, UserState); + is_function(Fun, 3) -> + Fun(OtpCert, ExtensionOrError, UserState) + end. + maybe_check_hostname(OtpCert, valid_peer, SslState) -> case ssl_certificate:validate(OtpCert, valid_peer, SslState) of {valid, _} -> diff --git a/lib/ssl/test/ssl_cert_SUITE.erl b/lib/ssl/test/ssl_cert_SUITE.erl index 6b0b6f5f4d..e006146c9a 100644 --- a/lib/ssl/test/ssl_cert_SUITE.erl +++ b/lib/ssl/test/ssl_cert_SUITE.erl @@ -614,13 +614,17 @@ verify_fun_always_run_client(Config) when is_list(Config) -> %% If user verify fun is called correctly we fail the connection. %% otherwise we cannot tell this case apart form where we miss %% to call users verify fun - FunAndState = {fun(_,{extension, _}, UserState) -> + FunAndState = {fun(_, Der, {extension, _}, UserState) -> + true = is_binary(Der), {unknown, UserState}; - (_, valid, [ChainLen]) -> + (_, Der, valid, [ChainLen]) -> + true = is_binary(Der), {valid, [ChainLen + 1]}; - (_, valid_peer, [1]) -> + (_, Der, valid_peer, [1]) -> + true = is_binary(Der), {fail, "verify_fun_was_always_run"}; - (_, valid_peer, UserState) -> + (_, Der, valid_peer, UserState) -> + true = is_binary(Der), {valid, UserState} end, [0]}, @@ -648,13 +652,17 @@ verify_fun_always_run_server(Config) when is_list(Config) -> %% If user verify fun is called correctly we fail the connection. %% otherwise we cannot tell this case apart form where we miss %% to call users verify fun - FunAndState = {fun(_,{extension, _}, UserState) -> + FunAndState = {fun(_, Der, {extension, _}, UserState) -> + true = is_binary(Der), {unknown, UserState}; - (_, valid, [ChainLen]) -> + (_, Der, valid, [ChainLen]) -> + true = is_binary(Der), {valid, [ChainLen + 1]}; - (_, valid_peer, [1]) -> + (_, Der, valid_peer, [1]) -> + true = is_binary(Der), {fail, "verify_fun_was_always_run"}; - (_, valid_peer, UserState) -> + (_, Der, valid_peer, UserState) -> + true = is_binary(Der), {valid, UserState} end, [0]}, -- 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