diff options
author | Magnus Henoch <[email protected]> | 2016-02-16 15:09:07 +0000 |
---|---|---|
committer | Magnus Henoch <[email protected]> | 2016-04-01 15:45:15 +0100 |
commit | 8fbd0e8dd05ba1f76f2d02a2e4c16e7973adfd4c (patch) | |
tree | 505be567f4349063f00ece003b711333ad18ccba | |
parent | d166fec5d5c901a93e21a1ea7b3165b6fe68d320 (diff) | |
download | otp-8fbd0e8dd05ba1f76f2d02a2e4c16e7973adfd4c.tar.gz otp-8fbd0e8dd05ba1f76f2d02a2e4c16e7973adfd4c.tar.bz2 otp-8fbd0e8dd05ba1f76f2d02a2e4c16e7973adfd4c.zip |
Add issuer arg to ssl_crl_cache_api lookup callback
Change the ssl_crl_cache_api callback specification, passing the
certificate issuer name as an argument to the lookup callback
function. Support the previous API too, for the time being.
The purpose of this change is to accomodate CRL cache modules that
index CRLs by issuer name, not by distribution point URL.
While in most cases such lookups could be performed using the select/2
callback function, that doesn't work when the CRL in question contains
an Issuing Distribution Point (IDP) extension, since RFC 5280
specifies different processing rules for CRLs specified in a
distribution point (DP) and other CRLs. For the latter, a DP is
assumed that most likely will not match the IDP of the CRL.
In order to accommodate cache modules that index CRLs by issuer name,
let's pass them the issuer as well.
-rw-r--r-- | lib/ssl/doc/src/ssl_crl_cache_api.xml | 15 | ||||
-rw-r--r-- | lib/ssl/src/ssl_crl_cache.erl | 5 | ||||
-rw-r--r-- | lib/ssl/src/ssl_crl_cache_api.erl | 7 | ||||
-rw-r--r-- | lib/ssl/src/ssl_handshake.erl | 31 |
4 files changed, 42 insertions, 16 deletions
diff --git a/lib/ssl/doc/src/ssl_crl_cache_api.xml b/lib/ssl/doc/src/ssl_crl_cache_api.xml index 03ac010bfe..7440b6ef04 100644 --- a/lib/ssl/doc/src/ssl_crl_cache_api.xml +++ b/lib/ssl/doc/src/ssl_crl_cache_api.xml @@ -76,10 +76,13 @@ </func> <func> + <name>lookup(DistributionPoint, Issuer, DbHandle) -> not_available | CRLs </name> <name>lookup(DistributionPoint, DbHandle) -> not_available | CRLs </name> <fsummary> </fsummary> <type> <v> DistributionPoint = dist_point() </v> + <v> Issuer = <seealso + marker="public_key:public_key">public_key:issuer_name()</seealso> </v> <v> DbHandle = cache_ref() </v> <v> CRLs = [<seealso marker="public_key:public_key">public_key:der_encoded()</seealso>] </v> @@ -87,6 +90,18 @@ <desc> <p>Lookup the CRLs belonging to the distribution point <c> Distributionpoint</c>. This function may choose to only look in the cache or to follow distribution point links depending on how the cache is administrated. </p> + + <p>The <c>Issuer</c> argument contains the issuer name of the + certificate to be checked. Normally the returned CRL should + be issued by this issuer, except if the <c>cRLIssuer</c> field + of <c>DistributionPoint</c> has a value, in which case that + value should be used instead.</p> + + <p>In an earlier version of this API, the <c>lookup</c> + function received two arguments, omitting <c>Issuer</c>. For + compatibility, this is still supported: if there is no + <c>lookup/3</c> function in the callback module, + <c>lookup/2</c> is called instead.</p> </desc> </func> diff --git a/lib/ssl/src/ssl_crl_cache.erl b/lib/ssl/src/ssl_crl_cache.erl index 60e7427737..647e0465fe 100644 --- a/lib/ssl/src/ssl_crl_cache.erl +++ b/lib/ssl/src/ssl_crl_cache.erl @@ -28,7 +28,7 @@ -behaviour(ssl_crl_cache_api). --export([lookup/2, select/2, fresh_crl/2]). +-export([lookup/3, select/2, fresh_crl/2]). -export([insert/1, insert/2, delete/1]). %%==================================================================== @@ -36,9 +36,10 @@ %%==================================================================== lookup(#'DistributionPoint'{distributionPoint = {fullName, Names}}, + _Issuer, CRLDbInfo) -> get_crls(Names, CRLDbInfo); -lookup(_,_) -> +lookup(_,_,_) -> not_available. select(Issuer, {{_Cache, Mapping},_}) -> diff --git a/lib/ssl/src/ssl_crl_cache_api.erl b/lib/ssl/src/ssl_crl_cache_api.erl index d7b31f280e..c3a57e2f49 100644 --- a/lib/ssl/src/ssl_crl_cache_api.erl +++ b/lib/ssl/src/ssl_crl_cache_api.erl @@ -24,8 +24,9 @@ -include_lib("public_key/include/public_key.hrl"). --type db_handle() :: term(). +-type db_handle() :: term(). +-type issuer_name() :: {rdnSequence, [#'AttributeTypeAndValue'{}]}. --callback lookup(#'DistributionPoint'{}, db_handle()) -> not_available | [public_key:der_encoded()]. --callback select(term(), db_handle()) -> [public_key:der_encoded()]. +-callback lookup(#'DistributionPoint'{}, issuer_name(), db_handle()) -> not_available | [public_key:der_encoded()]. +-callback select(issuer_name(), db_handle()) -> [public_key:der_encoded()]. -callback fresh_crl(#'DistributionPoint'{}, public_key:der_encoded()) -> public_key:der_encoded(). diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl index e98073080a..5e8987fba9 100644 --- a/lib/ssl/src/ssl_handshake.erl +++ b/lib/ssl/src/ssl_handshake.erl @@ -2097,13 +2097,14 @@ crl_check_same_issuer(OtpCert, _, Dps, Options) -> public_key:pkix_crls_validate(OtpCert, Dps, Options). dps_and_crls(OtpCert, Callback, CRLDbHandle, ext) -> - case public_key:pkix_dist_points(OtpCert) of - [] -> - no_dps; - DistPoints -> - distpoints_lookup(DistPoints, Callback, CRLDbHandle) - end; - + case public_key:pkix_dist_points(OtpCert) of + [] -> + no_dps; + DistPoints -> + Issuer = OtpCert#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.issuer, + distpoints_lookup(DistPoints, Issuer, Callback, CRLDbHandle) + end; + dps_and_crls(OtpCert, Callback, CRLDbHandle, same_issuer) -> DP = #'DistributionPoint'{distributionPoint = {fullName, GenNames}} = public_key:pkix_dist_point(OtpCert), @@ -2114,12 +2115,20 @@ dps_and_crls(OtpCert, Callback, CRLDbHandle, same_issuer) -> end, GenNames), [{DP, {CRL, public_key:der_decode('CertificateList', CRL)}} || CRL <- CRLs]. -distpoints_lookup([], _, _) -> +distpoints_lookup([], _, _, _) -> []; -distpoints_lookup([DistPoint | Rest], Callback, CRLDbHandle) -> - case Callback:lookup(DistPoint, CRLDbHandle) of +distpoints_lookup([DistPoint | Rest], Issuer, Callback, CRLDbHandle) -> + Result = + try Callback:lookup(DistPoint, Issuer, CRLDbHandle) + catch + error:undef -> + %% The callback module still uses the 2-argument + %% version of the lookup function. + Callback:lookup(DistPoint, CRLDbHandle) + end, + case Result of not_available -> - distpoints_lookup(Rest, Callback, CRLDbHandle); + distpoints_lookup(Rest, Issuer, Callback, CRLDbHandle); CRLs -> [{DistPoint, {CRL, public_key:der_decode('CertificateList', CRL)}} || CRL <- CRLs] end. |