%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 2015-2015. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. %% %% %CopyrightEnd% %---------------------------------------------------------------------- %% Purpose: CRL handling %%---------------------------------------------------------------------- -module(ssl_crl). -include("ssl_alert.hrl"). -include("ssl_internal.hrl"). -include_lib("public_key/include/public_key.hrl"). -export([trusted_cert_and_path/3]). trusted_cert_and_path(CRL, {SerialNumber, Issuer},{Db, DbRef} = DbHandle) -> case ssl_pkix_db:lookup_trusted_cert(Db, DbRef, SerialNumber, Issuer) of undefined -> trusted_cert_and_path(CRL, issuer_not_found, DbHandle); {ok, {_, OtpCert}} -> {ok, Root, Chain} = ssl_certificate:certificate_chain(OtpCert, Db, DbRef), {ok, Root, lists:reverse(Chain)} end; trusted_cert_and_path(CRL, issuer_not_found, {Db, DbRef} = DbHandle) -> try find_issuer(CRL, DbHandle) of OtpCert -> {ok, Root, Chain} = ssl_certificate:certificate_chain(OtpCert, Db, DbRef), {ok, Root, lists:reverse(Chain)} catch throw:_ -> {error, issuer_not_found} end. find_issuer(CRL, {Db,_}) -> Issuer = public_key:pkix_normalize_name(public_key:pkix_crl_issuer(CRL)), IsIssuerFun = fun({_Key, {_Der,ErlCertCandidate}}, Acc) -> verify_crl_issuer(CRL, ErlCertCandidate, Issuer, Acc); (_, Acc) -> Acc end, try ssl_pkix_db:foldl(IsIssuerFun, issuer_not_found, Db) of issuer_not_found -> {error, issuer_not_found} catch {ok, IssuerCert} -> IssuerCert end. verify_crl_issuer(CRL, ErlCertCandidate, Issuer, NotIssuer) -> TBSCert = ErlCertCandidate#'OTPCertificate'.tbsCertificate, case public_key:pkix_normalize_name(TBSCert#'OTPTBSCertificate'.subject) of Issuer -> case public_key:pkix_crl_verify(CRL, ErlCertCandidate) of true -> throw({ok, ErlCertCandidate}); false -> NotIssuer end; _ -> NotIssuer end.