diff options
Diffstat (limited to 'lib/ssl/src/ssl_certificate.erl')
-rw-r--r-- | lib/ssl/src/ssl_certificate.erl | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index d97b61a5ce..37d5646673 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2007-2010. 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% %% @@ -29,10 +29,12 @@ -include("ssl_alert.hrl"). -include("ssl_internal.hrl"). -include("ssl_debug.hrl"). +-include_lib("public_key/include/public_key.hrl"). -export([trusted_cert_and_path/3, certificate_chain/2, - file_to_certificats/1]). + file_to_certificats/1, + validate_extensions/6]). %%==================================================================== %% Internal application API @@ -65,7 +67,7 @@ trusted_cert_and_path(CertChain, CertDbRef, Verify) -> %% The root CA was not sent and can not be found, we fail if verify = true not_valid(?ALERT_REC(?FATAL, ?UNKNOWN_CA), Verify, {Cert, RestPath}); {{SerialNr, Issuer}, Path} -> - case ssl_certificate_db:lookup_trusted_cert(CertDbRef, + case ssl_manager:lookup_trusted_cert(CertDbRef, SerialNr, Issuer) of {ok, {BinCert,_}} -> {BinCert, Path, []}; @@ -83,10 +85,34 @@ certificate_chain(OwnCert, CertsDbRef) -> {ok, ErlCert} = public_key:pkix_decode_cert(OwnCert, otp), certificate_chain(ErlCert, OwnCert, CertsDbRef, [OwnCert]). -file_to_certificats(File) -> +file_to_certificats(File) -> {ok, List} = ssl_manager:cache_pem_file(File), [Bin || {cert, Bin, not_encrypted} <- List]. + +%% Validates ssl/tls specific extensions +validate_extensions([], ValidationState, UnknownExtensions, _, AccErr, _) -> + {UnknownExtensions, ValidationState, AccErr}; + +validate_extensions([#'Extension'{extnID = ?'id-ce-extKeyUsage', + extnValue = KeyUse, + critical = true} | Rest], + ValidationState, UnknownExtensions, Verify, AccErr0, Role) -> + case is_valid_extkey_usage(KeyUse, Role) of + true -> + validate_extensions(Rest, ValidationState, UnknownExtensions, + Verify, AccErr0, Role); + false -> + AccErr = + not_valid_extension({bad_cert, invalid_ext_key_usage}, Verify, AccErr0), + validate_extensions(Rest, ValidationState, UnknownExtensions, Verify, AccErr, Role) + end; + +validate_extensions([Extension | Rest], ValidationState, UnknownExtensions, + Verify, AccErr, Role) -> + validate_extensions(Rest, ValidationState, [Extension | UnknownExtensions], + Verify, AccErr, Role). + %%-------------------------------------------------------------------- %%% Internal functions %%-------------------------------------------------------------------- @@ -122,7 +148,7 @@ certificate_chain(_CertsDbRef, Chain, _SerialNr, _Issuer, true) -> {ok, lists:reverse(Chain)}; certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) -> - case ssl_certificate_db:lookup_trusted_cert(CertsDbRef, + case ssl_manager:lookup_trusted_cert(CertsDbRef, SerialNr, Issuer) of {ok, {IssuerCert, ErlCert}} -> {ok, ErlCert} = public_key:pkix_decode_cert(IssuerCert, otp), @@ -138,7 +164,7 @@ certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) -> end. find_issuer(OtpCert, PrevCandidateKey) -> - case ssl_certificate_db:issuer_candidate(PrevCandidateKey) of + case ssl_manager:issuer_candidate(PrevCandidateKey) of no_more_candidates -> {error, issuer_not_found}; {Key, {_Cert, ErlCertCandidate}} -> @@ -154,3 +180,18 @@ not_valid(Alert, true, _) -> throw(Alert); not_valid(_, false, {ErlCert, Path}) -> {ErlCert, Path, [{bad_cert, unknown_ca}]}. + +is_valid_extkey_usage(KeyUse, client) -> + %% Client wants to verify server + is_valid_key_usage(KeyUse,?'id-kp-serverAuth'); +is_valid_extkey_usage(KeyUse, server) -> + %% Server wants to verify client + is_valid_key_usage(KeyUse, ?'id-kp-clientAuth'). + +is_valid_key_usage(KeyUse, Use) -> + lists:member(Use, KeyUse). + +not_valid_extension(Error, true, _) -> + throw(Error); +not_valid_extension(Error, false, AccErrors) -> + [Error | AccErrors]. |