From b5ec77bf908877d7471997527959e3d98d45bd96 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 24 Apr 2018 09:34:51 +0200 Subject: Parse cert primarily for host names --- lib/ssl/src/inet_tls_dist.erl | 65 +++++++++++++++++++---------------- lib/ssl/test/ssl_dist_bench_SUITE.erl | 29 ++++++++++------ 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl index d4215c8f83..3fab89fa97 100644 --- a/lib/ssl/src/inet_tls_dist.erl +++ b/lib/ssl/src/inet_tls_dist.erl @@ -585,7 +585,10 @@ get_ifs(#sslsocket{fd = {gen_tcp, Socket, _}}) -> %% Look in Extensions, in all subjectAltName:s -%% to find node names in this certificate +%% to find node names in this certificate. +%% Host names are picked up as a subjectAltName containing +%% a dNSName, and the first subjectAltName containing +%% a commonName is the node name. %% cert_nodes( #'OTPCertificate'{ @@ -594,48 +597,52 @@ cert_nodes( parse_extensions(Extensions) when is_list(Extensions) -> - parse_extensions(Extensions, []); + parse_extensions(Extensions, [], none); parse_extensions(asn1_NOVALUE) -> []. %% -parse_extensions([], CertNodes) -> - CertNodes; -%% -%% XXX Why are all extnValue:s sequences? -%% Should we parse all members? -%% -parse_extensions( - [#'Extension'{ - extnID = ?'id-ce-subjectAltName', - extnValue = [{dNSName,OtherNode}|_]} - |Extensions], - CertNodes) -> - parse_extensions(Extensions, [OtherNode|CertNodes]); -parse_extensions( - [#'Extension'{ - extnID = ?'id-ce-subjectAltName', - extnValue = [{rfc822Name,OtherNode}|_]} - |Extensions], - CertNodes) -> - parse_extensions(Extensions, [OtherNode|CertNodes]); +parse_extensions([], Hosts, none) -> + lists:reverse(Hosts); +parse_extensions([], Hosts, Name) -> + [Name ++ "@" ++ Host || Host <- lists:reverse(Hosts)]; parse_extensions( [#'Extension'{ extnID = ?'id-ce-subjectAltName', - extnValue = [{directoryName,{rdnSequence,[Rdn|_]}}|_]} + extnValue = AltNames} |Extensions], - CertNodes) -> + Hosts, Name) -> + case parse_subject_altname(AltNames) of + none -> + parse_extensions(Extensions, Hosts, Name); + {host,Host} -> + parse_extensions(Extensions, [Host|Hosts], Name); + {name,NewName} when Name =:= none -> + parse_extensions(Extensions, Hosts, NewName); + {Name,_} -> + parse_extensions(Extensions, Hosts, Name) + end; +parse_extensions([_|Extensions], Hosts, Name) -> + parse_extensions(Extensions, Hosts, Name). + +parse_subject_altname([]) -> + none; +parse_subject_altname([{dNSName,Host}|_AltNames]) -> + {host,Host}; +parse_subject_altname( + [{directoryName,{rdnSequence,[Rdn|_]}}|AltNames]) -> %% %% XXX Why is rdnSequence a sequence? %% Should we parse all members? %% case parse_rdn(Rdn) of none -> - parse_extensions(Extensions, CertNodes); - OtherNode -> - parse_extensions(Extensions, [OtherNode|CertNodes]) + parse_subject_altname(AltNames); + Name -> + {name,Name} end; -parse_extensions([_|Extensions], CertNodes) -> - parse_extensions(Extensions, CertNodes). +parse_subject_altname([_|AltNames]) -> + parse_subject_altname(AltNames). + parse_rdn([]) -> none; diff --git a/lib/ssl/test/ssl_dist_bench_SUITE.erl b/lib/ssl/test/ssl_dist_bench_SUITE.erl index 8852b6f3c6..31de0936f9 100644 --- a/lib/ssl/test/ssl_dist_bench_SUITE.erl +++ b/lib/ssl/test/ssl_dist_bench_SUITE.erl @@ -181,6 +181,7 @@ end_per_testcase(_Func, _Conf) -> write_node_conf( ConfFile, Node, ServerConf, ClientConf, CertOptions, RootCert) -> + [_Name,Host] = string:split(atom_to_list(Node), "@"), Conf = public_key:pkix_test_data( #{root => RootCert, @@ -188,17 +189,23 @@ write_node_conf( [{extensions, [#'Extension'{ extnID = ?'id-ce-subjectAltName', - %% extnValue = [{dNSName, atom_to_list(Node)}], - %% extnValue = [{rfc822Name, atom_to_list(Node)}], - extnValue = - [{directoryName, - {rdnSequence, - [[#'AttributeTypeAndValue'{ - type = ?'id-at-commonName', - value = - {utf8String, - atom_to_binary(Node, utf8)}}]]}}], - critical = true}]} | CertOptions]}), + extnValue = [{dNSName, Host}], + critical = true}%, + %% #'Extension'{ + %% extnID = ?'id-ce-subjectAltName', + %% extnValue = + %% [{directoryName, + %% {rdnSequence, + %% [[#'AttributeTypeAndValue'{ + %% type = ?'id-at-commonName', + %% value = + %% {utf8String, + %% unicode:characters_to_binary( + %% Name, utf8) + %% } + %% }]]}}], + %% critical = true} + ]} | CertOptions]}), NodeConf = [{server, ServerConf ++ Conf}, {client, ClientConf ++ Conf}], {ok, Fd} = file:open(ConfFile, [write]), -- cgit v1.2.1