summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandru Scvortov <alexandru@rabbitmq.com>2010-09-07 14:41:40 +0100
committerAlexandru Scvortov <alexandru@rabbitmq.com>2010-09-07 14:41:40 +0100
commit32e9c7288a4096af57b85ac59f2e580f1a2df591 (patch)
tree580113b3b0997cf7b5d427b79b8e1ed389de75c4
parent1250c50a0286a8aaf69bfb87f18ef14eaa81a720 (diff)
downloadrabbitmq-server-git-32e9c7288a4096af57b85ac59f2e580f1a2df591.tar.gz
more RDNs + refactoring
-rw-r--r--src/rabbit_reader.erl18
-rw-r--r--src/rabbit_ssl.erl61
2 files changed, 48 insertions, 31 deletions
diff --git a/src/rabbit_reader.erl b/src/rabbit_reader.erl
index 8d2d6a6223..866442b74e 100644
--- a/src/rabbit_reader.erl
+++ b/src/rabbit_reader.erl
@@ -819,11 +819,11 @@ i(peer_address, #v1{sock = Sock}) ->
{ok, {A, _}} = rabbit_net:peername(Sock),
A;
i(ssl_issuer, #v1{sock = Sock}) ->
- get_ssl_info(fun rabbit_ssl:ssl_issuer/1, Sock);
+ rabbit_ssl:ssl_info(fun rabbit_ssl:ssl_issuer/1, Sock);
i(ssl_subject, #v1{sock = Sock}) ->
- get_ssl_info(fun rabbit_ssl:ssl_subject/1, Sock);
+ rabbit_ssl:ssl_info(fun rabbit_ssl:ssl_subject/1, Sock);
i(ssl_validity, #v1{sock = Sock}) ->
- get_ssl_info(fun rabbit_ssl:ssl_validity/1, Sock);
+ rabbit_ssl:ssl_info(fun rabbit_ssl:ssl_validity/1, Sock);
i(peer_port, #v1{sock = Sock}) ->
{ok, {_, P}} = rabbit_net:peername(Sock),
P;
@@ -861,18 +861,6 @@ i(client_properties, #v1{connection = #connection{
i(Item, #v1{}) ->
throw({bad_argument, Item}).
-get_ssl_info(F, Sock) ->
- case rabbit_net:peercert(Sock) of
- nossl -> nossl;
- no_peer_certificate -> no_peer_certificate;
- {ok, Cert} ->
- try F(Cert) %% here be dragons; decompose an undocumented
- %% structure
- catch
- _:_ -> unknown
- end
- end.
-
%%--------------------------------------------------------------------------
diff --git a/src/rabbit_ssl.erl b/src/rabbit_ssl.erl
index 86c8e21e02..1a9342a292 100644
--- a/src/rabbit_ssl.erl
+++ b/src/rabbit_ssl.erl
@@ -32,14 +32,19 @@
-module(rabbit_ssl).
-include_lib("public_key/include/public_key.hrl").
+-include_lib("ssl/src/ssl_int.hrl").
--export([ssl_issuer/1, ssl_subject/1, ssl_validity/1]).
+-export([ssl_issuer/1, ssl_subject/1, ssl_validity/1, ssl_info/2]).
%%--------------------------------------------------------------------------
-ifdef(use_specs).
+-type(ssl_info_fun() :: fun((#'OTPCertificate'{}) -> string())).
+
+-spec(ssl_info/2 :: (ssl_info_fun(), #'sslsocket'{}) -> any()).
+
-spec(ssl_issuer/1 :: (#'OTPCertificate'{}) -> string()).
-spec(ssl_subject/1 :: (#'OTPCertificate'{}) -> string()).
-spec(ssl_validity/1 :: (#'OTPCertificate'{}) -> string()).
@@ -51,13 +56,29 @@
%% High-level functions used by reader
%%--------------------------------------------------------------------------
+%% Wrapper for applying a function to a socket's certificate.
+ssl_info(F, Sock) ->
+ case rabbit_net:peercert(Sock) of
+ nossl -> nossl;
+ no_peer_certificate -> no_peer_certificate;
+ {ok, Cert} ->
+ try F(Cert) %% here be dragons; decompose an undocumented
+ %% structure
+ catch
+ C:E ->
+ rabbit_log:info("Problems while processing SSL info: ~p:~p~n",
+ [C, E]),
+ unknown
+ end
+ end.
+
%% Return a string describing the certificate's issuer.
ssl_issuer(#'OTPCertificate' {
tbsCertificate = #'OTPTBSCertificate' {
issuer = Issuer }}) ->
format_ssl_subject(extract_ssl_values(Issuer)).
-%% Return a string describing the certificate's subject, as per RFC2253.
+%% Return a string describing the certificate's subject, as per RFC4514.
ssl_subject(#'OTPCertificate' {
tbsCertificate = #'OTPTBSCertificate' {
subject = Subject }}) ->
@@ -90,9 +111,8 @@ extract_ssl_values(V) ->
extract_ssl_values_list([[#'AttributeTypeAndValue'{type = T, value = V}]
| Rest]) ->
[{T, V} | extract_ssl_values_list(Rest)];
-extract_ssl_values_list([V|Rest]) ->
- rabbit_log:info("Found unexpected element ~p in an rdnSequence~n", [V]),
- extract_ssl_values_list(Rest);
+extract_ssl_values_list([V|_]) ->
+ throw({unknown_rdnSequence_element, V});
extract_ssl_values_list([]) ->
[].
@@ -101,13 +121,14 @@ extract_ssl_values_list([]) ->
%% Formatting functions
%%--------------------------------------------------------------------------
-%% Convert a proplist to a RFC2253 subject string.
+%% Convert a proplist to a RFC4514 subject string.
format_ssl_subject(RDNs) ->
rabbit_misc:intersperse(
- ",", [escape_ssl_string(format_ssl_type_and_value(T, V), start)
- || {T, V} <- RDNs]).
+ ",", lists:reverse(
+ [escape_ssl_string(format_ssl_type_and_value(T, V), start)
+ || {T, V} <- RDNs])).
-%% Escape a string as per RFC2253.
+%% Escape a string as per RFC4514.
escape_ssl_string([], _) ->
[];
escape_ssl_string([$ | S], start) ->
@@ -130,17 +151,25 @@ escape_ssl_string([$ | S], ending) ->
["\\ " | escape_ssl_string(S, ending)].
%% Format a type-value pair as an RDN. If the type name is unknown,
-%% use the dotted decimal representation. See RFC2253, section 2.3.
+%% use the dotted decimal representation. See RFC4514, section 2.3.
format_ssl_type_and_value(Type, Value) ->
FV = format_ssl_value(Value),
- Fmts = [{?'id-at-commonName' , "CN"},
- {?'id-at-countryName' , "C"},
+ Fmts = [{?'id-at-surname' , "SN"},
+ {?'id-at-givenName' , "GIVENNAME"},
+ {?'id-at-initials' , "INITIALS"},
+ {?'id-at-generationQualifier' , "GENERATIONQUALIFIER"},
+ {?'id-at-commonName' , "CN"},
+ {?'id-at-localityName' , "L"},
+ {?'id-at-stateOrProvinceName' , "ST"},
{?'id-at-organizationName' , "O"},
{?'id-at-organizationalUnitName' , "OU"},
- {?'street-address' , "STREET"},
- {?'id-domainComponent' , "DC"},
- {?'id-at-stateOrProvinceName' , "ST"},
- {?'id-at-localityName' , "L"}],
+ {?'id-at-title' , "TITLE"},
+ {?'id-at-countryName' , "C"},
+ {?'id-at-serialNumber' , "SERIALNUMBER"},
+ {?'id-at-pseudonym' , "PSEUDONYM"},
+ {?'id-domainComponent' , "DC"},
+ {?'id-emailAddress' , "EMAILADDRESS"},
+ {?'street-address' , "STREET"}],
case proplists:lookup(Type, Fmts) of
{_, Fmt} ->
io_lib:format(Fmt ++ "=~s", [FV]);