Skip to content

Commit

Permalink
ssh, public_key: Change EC Public Key representation to what was inte…
Browse files Browse the repository at this point in the history
…nded
  • Loading branch information
HansN committed Oct 16, 2015
1 parent ba49561 commit 01d1e4d
Show file tree
Hide file tree
Showing 10 changed files with 204 additions and 207 deletions.
76 changes: 37 additions & 39 deletions lib/public_key/src/pubkey_ssh.erl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@

-include("public_key.hrl").

-export([decode/2, encode/2]).
-export([decode/2, encode/2
]).

-define(UINT32(X), X:32/unsigned-big-integer).
-define(STRING(X), ?UINT32((size(X))), (X)/binary).
Expand All @@ -33,6 +34,7 @@
%% are still compliant.)" So we choose to use 68 also.
-define(ENCODED_LINE_LENGTH, 68).


%%====================================================================
%% Internal application API
%%====================================================================
Expand Down Expand Up @@ -133,12 +135,11 @@ rfc4716_pubkey_decode(<<?UINT32(Len), Type:Len/binary,
#'Dss-Parms'{p = erlint(SizeP, P),
q = erlint(SizeQ, Q),
g = erlint(SizeG, G)}};
rfc4716_pubkey_decode(<<?UINT32(Len), Type:Len/binary,
rfc4716_pubkey_decode(<<?UINT32(Len), ECDSA_SHA2_etc:Len/binary,
?UINT32(SizeId), Id:SizeId/binary,
?UINT32(SizeQ), Q:SizeQ/binary>>) when Type == <<"ecdsa-sha2-nistp256">>;
Type == <<"ecdsa-sha2-nistp384">>;
Type == <<"ecdsa-sha2-nistp521">> ->
{#'ECPoint'{point = Q}, Id}.
?UINT32(SizeQ), Q:SizeQ/binary>>) ->
<<"ecdsa-sha2-", Id/binary>> = ECDSA_SHA2_etc,
{#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}}.

openssh_decode(Bin, FileType) ->
Lines = binary:split(Bin, <<"\n">>, [global]),
Expand Down Expand Up @@ -192,26 +193,28 @@ do_openssh_decode(known_hosts = FileType, [Line | Lines], Acc) ->
end;

do_openssh_decode(openssh_public_key = FileType, [Line | Lines], Acc) ->
case split_n(2, Line, []) of
[KeyType, Base64Enc] when KeyType == <<"ssh-rsa">>;
KeyType == <<"ssh-dss">>;
KeyType == <<"ecdsa-sha2-nistp256">>;
KeyType == <<"ecdsa-sha2-nistp384">>;
KeyType == <<"ecdsa-sha2-nistp521">> ->
[KeyType, Base64Enc | Comment0] = split_n(2, Line, []),
KnownKeyType =
case KeyType of
<<"ssh-rsa">> -> true;
<<"ssh-dss">> -> true;
<<"ecdsa-sha2-",Curve/binary>> -> is_ssh_curvename(Curve);
_ -> false
end,

case Comment0 of
[] when KnownKeyType==true ->
do_openssh_decode(FileType, Lines,
[{openssh_pubkey_decode(KeyType, Base64Enc),
[]} | Acc]);
[KeyType, Base64Enc | Comment0] when KeyType == <<"ssh-rsa">>;
KeyType == <<"ssh-dss">>;
KeyType == <<"ecdsa-sha2-nistp256">>;
KeyType == <<"ecdsa-sha2-nistp384">>;
KeyType == <<"ecdsa-sha2-nistp521">> ->
_ when KnownKeyType==true ->
Comment = string:strip(string_decode(iolist_to_binary(Comment0)), right, $\n),
do_openssh_decode(FileType, Lines,
[{openssh_pubkey_decode(KeyType, Base64Enc),
[{comment, Comment}]} | Acc])
end.


decode_comment([]) ->
[];
decode_comment(Comment) ->
Expand Down Expand Up @@ -244,7 +247,7 @@ openssh_pubkey_decode(<<"ecdsa-sha2-", Id/binary>>, Base64Enc) ->
?UINT32(SizeId), Id:SizeId/binary,
?UINT32(SizeQ), Q:SizeQ/binary>>
= base64:mime_decode(Base64Enc),
{#'ECPoint'{point = Q}, Id};
{#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}};

openssh_pubkey_decode(KeyType, Base64Enc) ->
{KeyType, base64:mime_decode(Base64Enc)}.
Expand Down Expand Up @@ -372,12 +375,9 @@ line_end("") ->
line_end(Comment) ->
[" ", Comment, "\n"].

key_type(#'RSAPublicKey'{}) ->
<<"ssh-rsa">>;
key_type({_, #'Dss-Parms'{}}) ->
<<"ssh-dss">>;
key_type({#'ECPoint'{}, Id}) ->
<<"ecdsa-sha2-",Id/binary>>.
key_type(#'RSAPublicKey'{}) -> <<"ssh-rsa">>;
key_type({_, #'Dss-Parms'{}}) -> <<"ssh-dss">>;
key_type({#'ECPoint'{}, {namedCurve,Curve}}) -> <<"ecdsa-sha2-", (public_key:oid2ssh_curvename(Curve))/binary>>.

comma_list_encode([Option], []) ->
Option;
Expand Down Expand Up @@ -408,25 +408,18 @@ ssh2_pubkey_encode({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
QBin/binary,
GBin/binary,
YBin/binary>>;
ssh2_pubkey_encode({#'ECPoint'{point = Q}, Id}) ->
TypeStr = <<"ecdsa-sha2-", Id/binary>>,
ssh2_pubkey_encode(Key={#'ECPoint'{point = Q}, {namedCurve,OID}}) ->
TypeStr = key_type(Key),
StrLen = size(TypeStr),
IdB = public_key:oid2ssh_curvename(OID),
<<?UINT32(StrLen), TypeStr:StrLen/binary,
(string(Id))/binary,
(string(IdB))/binary,
(string(Q))/binary>>.

is_key_field(<<"ssh-dss">>) ->
true;
is_key_field(<<"ssh-rsa">>) ->
true;
is_key_field(<<"ecdsa-sha2-nistp256">>) ->
true;
is_key_field(<<"ecdsa-sha2-nistp384">>) ->
true;
is_key_field(<<"ecdsa-sha2-nistp521">>) ->
true;
is_key_field(_) ->
false.
is_key_field(<<"ssh-dss">>) -> true;
is_key_field(<<"ssh-rsa">>) -> true;
is_key_field(<<"ecdsa-sha2-",Id/binary>>) -> is_ssh_curvename(Id);
is_key_field(_) -> false.

is_bits_field(Part) ->
try list_to_integer(binary_to_list(Part)) of
Expand Down Expand Up @@ -546,3 +539,8 @@ string(X) when is_binary(X) ->
<< ?STRING(X) >>;
string(X) ->
<< ?STRING(list_to_binary(X)) >>.

is_ssh_curvename(Id) -> try public_key:ssh_curvename2oid(Id) of _ -> true
catch _:_ -> false
end.

16 changes: 16 additions & 0 deletions lib/public_key/src/public_key.erl
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
pkix_normalize_name/1,
pkix_path_validation/3,
ssh_decode/2, ssh_encode/2,
ssh_curvename2oid/1, oid2ssh_curvename/1,
pkix_crls_validate/3,
pkix_dist_point/1,
pkix_dist_points/1,
Expand Down Expand Up @@ -741,6 +742,21 @@ ssh_encode(Entries, Type) when is_list(Entries),
Type == known_hosts ->
pubkey_ssh:encode(Entries, Type).

%%--------------------------------------------------------------------
%% Description: Converts from the ssh name of elliptic curves to
%% the OIDs.
%%--------------------------------------------------------------------
ssh_curvename2oid(<<"nistp256">>) -> ?'secp256r1';
ssh_curvename2oid(<<"nistp384">>) -> ?'secp384r1';
ssh_curvename2oid(<<"nistp521">>) -> ?'secp521r1'.

%%--------------------------------------------------------------------
%% Description: Converts from elliptic curve OIDs to the ssh name.
%%--------------------------------------------------------------------
oid2ssh_curvename(?'secp256r1') -> <<"nistp256">>;
oid2ssh_curvename(?'secp384r1') -> <<"nistp384">>;
oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>.

%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
Expand Down
13 changes: 8 additions & 5 deletions lib/ssh/src/ssh.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,16 @@
-define(FALSE, 0).
-define(TRUE, 1).
%% basic binary constructors
-define(BOOLEAN(X), X:8/unsigned-big-integer).
-define(BYTE(X), X:8/unsigned-big-integer).
-define(UINT16(X), X:16/unsigned-big-integer).
-define(UINT32(X), X:32/unsigned-big-integer).
-define(UINT64(X), X:64/unsigned-big-integer).
-define(BOOLEAN(X), (X):8/unsigned-big-integer).
-define(BYTE(X), (X):8/unsigned-big-integer).
-define(UINT16(X), (X):16/unsigned-big-integer).
-define(UINT32(X), (X):32/unsigned-big-integer).
-define(UINT64(X), (X):64/unsigned-big-integer).
-define(STRING(X), ?UINT32((size(X))), (X)/binary).

-define(DEC_BIN(X,Len), ?UINT32(Len), X:Len/binary ).
-define(DEC_MPINT(I,Len), ?UINT32(Len), I:Len/big-signed-integer-unit:8 ).

%% building macros
-define(boolean(X),
case X of
Expand Down
17 changes: 8 additions & 9 deletions lib/ssh/src/ssh_auth.erl
Original file line number Diff line number Diff line change
Expand Up @@ -500,16 +500,15 @@ decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
, "ssh-dss") ->
{ok, {Y, #'Dss-Parms'{p = P, q = Q, g = G}}};
decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
?UINT32(Len1), Id:Len1/binary, %% Id = <<"nistp256">> for example
?UINT32(Len1), IdB:Len1/binary, %% Id = <<"nistp256">> for example
?UINT32(Len2), Blob:Len2/binary>>,
Curve) ->
Id =
case Curve of
"ecdsa-sha2-nistp256" -> <<"nistp256">>;
"ecdsa-sha2-nistp384" -> <<"nistp384">>;
"ecdsa-sha2-nistp521" -> <<"nistp521">>
end,
{ok, {#'ECPoint'{point=Blob}, Id}};
"ecdsa-sha2-" ++ IdS) ->
case binary_to_list(IdB) of
IdS ->
{ok, {#'ECPoint'{point=Blob}, {namedCurve,public_key:ssh_curvename2oid(IdB)}} };
_ ->
{error, bad_format}
end;
decode_public_key_v2(_, _) ->
{error, bad_format}.

Expand Down
1 change: 1 addition & 0 deletions lib/ssh/src/ssh_connection_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,7 @@ event(Event, StateName, State) ->
throw:{ErrorToDisplay, #ssh_msg_disconnect{} = DisconnectMsg} ->
handle_disconnect(DisconnectMsg, State, ErrorToDisplay);
_C:_Error ->
ct:pal("*** FAIL ~p:~p(~p,...~n -> ~p:~p ",[?MODULE,StateName,Event,_C,_Error]),
handle_disconnect(#ssh_msg_disconnect{code = error_code(StateName),
description = "Invalid state",
language = "en"}, State)
Expand Down
13 changes: 7 additions & 6 deletions lib/ssh/src/ssh_file.erl
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,13 @@ key_match(#'RSAPublicKey'{}, 'ssh-rsa') ->
true;
key_match({_, #'Dss-Parms'{}}, 'ssh-dss') ->
true;
key_match({#'ECPoint'{},<<"nistp256">>}, 'ecdsa-sha2-nistp256') ->
true;
key_match({#'ECPoint'{},<<"nistp384">>}, 'ecdsa-sha2-nistp384') ->
true;
key_match({#'ECPoint'{},<<"nistp521">>}, 'ecdsa-sha2-nistp521') ->
true;
key_match({#'ECPoint'{},{namedCurve,Curve}}, Alg) ->
case atom_to_list(Alg) of
"ecdsa-sha2-"++IdS ->
Curve == public_key:ssh_curvename2oid(list_to_binary(IdS));
_ ->
false
end;
key_match(_, _) ->
false.

Expand Down
Loading

0 comments on commit 01d1e4d

Please sign in to comment.