aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2015-10-14 17:47:13 +0200
committerHans Nilsson <[email protected]>2015-10-16 12:38:25 +0200
commit19eec0552c6b4e5024e307d2376c061665007e4f (patch)
treebe29b54766992a84b6dce232b41b4a63a7d31bbd
parent01d1e4dc9a6e7ea958683ab419dea38bf576a39f (diff)
downloadotp-19eec0552c6b4e5024e307d2376c061665007e4f.tar.gz
otp-19eec0552c6b4e5024e307d2376c061665007e4f.tar.bz2
otp-19eec0552c6b4e5024e307d2376c061665007e4f.zip
ssh, public_key: use pubkey encode/decode in app public_key
-rw-r--r--lib/public_key/src/pubkey_ssh.erl71
-rw-r--r--lib/public_key/src/public_key.erl6
-rw-r--r--lib/ssh/src/ssh_auth.erl68
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl1
-rw-r--r--lib/ssh/src/ssh_message.erl49
-rw-r--r--lib/ssh/src/ssh_transport.erl13
6 files changed, 78 insertions, 130 deletions
diff --git a/lib/public_key/src/pubkey_ssh.erl b/lib/public_key/src/pubkey_ssh.erl
index 3addbfe3c6..ba67abb4eb 100644
--- a/lib/public_key/src/pubkey_ssh.erl
+++ b/lib/public_key/src/pubkey_ssh.erl
@@ -54,6 +54,8 @@ decode(Bin, public_key)->
end;
decode(Bin, rfc4716_public_key) ->
rfc4716_decode(Bin);
+decode(Bin, ssh2_pubkey) ->
+ ssh2_pubkey_decode(Bin);
decode(Bin, Type) ->
openssh_decode(Bin, Type).
@@ -63,6 +65,8 @@ decode(Bin, Type) ->
%%
%% Description: Encodes a list of ssh file entries.
%%--------------------------------------------------------------------
+encode(Bin, ssh2_pubkey) ->
+ ssh2_pubkey_encode(Bin);
encode(Entries, Type) ->
iolist_to_binary(lists:map(fun({Key, Attributes}) ->
do_encode(Type, Key, Attributes)
@@ -221,36 +225,13 @@ decode_comment(Comment) ->
[{comment, string_decode(iolist_to_binary(Comment))}].
-openssh_pubkey_decode(<<"ssh-rsa">>, Base64Enc) ->
- <<?UINT32(StrLen), _:StrLen/binary,
- ?UINT32(SizeE), E:SizeE/binary,
- ?UINT32(SizeN), N:SizeN/binary>>
- = base64:mime_decode(Base64Enc),
- #'RSAPublicKey'{modulus = erlint(SizeN, N),
- publicExponent = erlint(SizeE, E)};
-
-openssh_pubkey_decode(<<"ssh-dss">>, Base64Enc) ->
- <<?UINT32(StrLen), _:StrLen/binary,
- ?UINT32(SizeP), P:SizeP/binary,
- ?UINT32(SizeQ), Q:SizeQ/binary,
- ?UINT32(SizeG), G:SizeG/binary,
- ?UINT32(SizeY), Y:SizeY/binary>>
- = base64:mime_decode(Base64Enc),
- {erlint(SizeY, Y),
- #'Dss-Parms'{p = erlint(SizeP, P),
- q = erlint(SizeQ, Q),
- g = erlint(SizeG, G)}};
-
-openssh_pubkey_decode(<<"ecdsa-sha2-", Id/binary>>, Base64Enc) ->
- %% rfc5656#section-3.1
- <<?UINT32(StrLen), _:StrLen/binary,
- ?UINT32(SizeId), Id:SizeId/binary,
- ?UINT32(SizeQ), Q:SizeQ/binary>>
- = base64:mime_decode(Base64Enc),
- {#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}};
-
-openssh_pubkey_decode(KeyType, Base64Enc) ->
- {KeyType, base64:mime_decode(Base64Enc)}.
+openssh_pubkey_decode(Type, Base64Enc) ->
+ try
+ ssh2_pubkey_decode(Type, base64:mime_decode(Base64Enc))
+ catch
+ _:_ ->
+ {Type, base64:mime_decode(Base64Enc)}
+ end.
erlint(MPIntSize, MPIntValue) ->
@@ -416,6 +397,36 @@ ssh2_pubkey_encode(Key={#'ECPoint'{point = Q}, {namedCurve,OID}}) ->
(string(IdB))/binary,
(string(Q))/binary>>.
+
+ssh2_pubkey_decode(Bin = <<?UINT32(Len), Type:Len/binary, _/binary>>) ->
+ ssh2_pubkey_decode(Type, Bin).
+
+ssh2_pubkey_decode(<<"ssh-rsa">>,
+ <<?UINT32(Len), _:Len/binary,
+ ?UINT32(SizeE), E:SizeE/binary,
+ ?UINT32(SizeN), N:SizeN/binary>>) ->
+ #'RSAPublicKey'{modulus = erlint(SizeN, N),
+ publicExponent = erlint(SizeE, E)};
+
+ssh2_pubkey_decode(<<"ssh-dss">>,
+ <<?UINT32(Len), _:Len/binary,
+ ?UINT32(SizeP), P:SizeP/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary,
+ ?UINT32(SizeG), G:SizeG/binary,
+ ?UINT32(SizeY), Y:SizeY/binary>>) ->
+ {erlint(SizeY, Y),
+ #'Dss-Parms'{p = erlint(SizeP, P),
+ q = erlint(SizeQ, Q),
+ g = erlint(SizeG, G)}};
+ssh2_pubkey_decode(<<"ecdsa-sha2-",Id/binary>>,
+ <<?UINT32(Len), ECDSA_SHA2_etc:Len/binary,
+ ?UINT32(SizeId), Id:SizeId/binary,
+ ?UINT32(SizeQ), Q:SizeQ/binary>>) ->
+ <<"ecdsa-sha2-", Id/binary>> = ECDSA_SHA2_etc,
+ {#'ECPoint'{point = Q}, {namedCurve,public_key:ssh_curvename2oid(Id)}}.
+
+
+
is_key_field(<<"ssh-dss">>) -> true;
is_key_field(<<"ssh-rsa">>) -> true;
is_key_field(<<"ecdsa-sha2-",Id/binary>>) -> is_ssh_curvename(Id);
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 2b04b3f79b..941ade3dd7 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -725,7 +725,8 @@ ssh_decode(SshBin, Type) when is_binary(SshBin),
Type == rfc4716_public_key;
Type == openssh_public_key;
Type == auth_keys;
- Type == known_hosts ->
+ Type == known_hosts;
+ Type == ssh2_pubkey ->
pubkey_ssh:decode(SshBin, Type).
%%--------------------------------------------------------------------
@@ -739,7 +740,8 @@ ssh_encode(Entries, Type) when is_list(Entries),
Type == rfc4716_public_key;
Type == openssh_public_key;
Type == auth_keys;
- Type == known_hosts ->
+ Type == known_hosts;
+ Type == ssh2_pubkey ->
pubkey_ssh:encode(Entries, Type).
%%--------------------------------------------------------------------
diff --git a/lib/ssh/src/ssh_auth.erl b/lib/ssh/src/ssh_auth.erl
index 8c6ffceb4b..04749fcf8e 100644
--- a/lib/ssh/src/ssh_auth.erl
+++ b/lib/ssh/src/ssh_auth.erl
@@ -44,15 +44,15 @@ publickey_msg([Alg, #ssh{user = User,
Hash = sha, %% Maybe option?!
KeyCb = proplists:get_value(key_cb, Opts, ssh_file),
case KeyCb:user_key(Alg, Opts) of
- {ok, Key} ->
- StrAlgo = algorithm_string(Alg),
- case encode_public_key(StrAlgo, Key) of
+ {ok, PrivKey} ->
+ StrAlgo = atom_to_list(Alg),
+ case encode_public_key(StrAlgo, ssh_transport:extract_public_key(PrivKey)) of
not_ok ->
not_ok;
PubKeyBlob ->
SigData = build_sig_data(SessionId,
User, Service, PubKeyBlob, StrAlgo),
- Sig = ssh_transport:sign(SigData, Hash, Key),
+ Sig = ssh_transport:sign(SigData, Hash, PrivKey),
SigBlob = list_to_binary([?string(StrAlgo), ?binary(Sig)]),
ssh_transport:ssh_packet(
#ssh_msg_userauth_request{user = User,
@@ -430,12 +430,6 @@ build_sig_data(SessionId, User, Service, KeyBlob, Alg) ->
?binary(KeyBlob)],
list_to_binary(Sig).
-algorithm_string('ssh-rsa') -> "ssh-rsa";
-algorithm_string('ssh-dss') -> "ssh-dss";
-algorithm_string('ecdsa-sha2-nistp256') -> "ecdsa-sha2-nistp256";
-algorithm_string('ecdsa-sha2-nistp384') -> "ecdsa-sha2-nistp384";
-algorithm_string('ecdsa-sha2-nistp521') -> "ecdsa-sha2-nistp521".
-
decode_keyboard_interactive_prompts(_NumPrompts, Data) ->
@@ -487,46 +481,18 @@ keyboard_interact_fun(KbdInteractFun, Name, Instr, PromptInfos, NumPrompts) ->
language = "en"}})
end.
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), E:Len1/big-signed-integer-unit:8,
- ?UINT32(Len2), N:Len2/big-signed-integer-unit:8>>
- ,"ssh-rsa") ->
- {ok, #'RSAPublicKey'{publicExponent = E, modulus = N}};
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), P:Len1/big-signed-integer-unit:8,
- ?UINT32(Len2), Q:Len2/big-signed-integer-unit:8,
- ?UINT32(Len3), G:Len3/big-signed-integer-unit:8,
- ?UINT32(Len4), Y:Len4/big-signed-integer-unit:8>>
- , "ssh-dss") ->
- {ok, {Y, #'Dss-Parms'{p = P, q = Q, g = G}}};
-decode_public_key_v2(<<?UINT32(Len0), _:Len0/binary,
- ?UINT32(Len1), IdB:Len1/binary, %% Id = <<"nistp256">> for example
- ?UINT32(Len2), Blob:Len2/binary>>,
- "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}.
-
-encode_public_key("ssh-rsa", #'RSAPrivateKey'{publicExponent = E, modulus = N}) ->
- ssh_bits:encode(["ssh-rsa",E,N], [string,mpint,mpint]);
-encode_public_key("ssh-dss", #'DSAPrivateKey'{p = P, q = Q, g = G, y = Y}) ->
- ssh_bits:encode(["ssh-dss",P,Q,G,Y], [string,mpint,mpint,mpint,mpint]);
-encode_public_key("ecdsa-sha2-"++Curve, #'ECPrivateKey'{parameters = Params,
- publicKey = Pub}) ->
- Id = ecdsa_id(Params),
- if
- Id =/= Curve ->
- not_ok;
- true ->
- ssh_bits:encode(["ecdsa-sha2-"++Id, Id, Pub],
- [string, string, binary])
+decode_public_key_v2(Bin, _Type) ->
+ try
+ public_key:ssh_decode(Bin, ssh2_pubkey)
+ of
+ Key -> {ok, Key}
+ catch
+ _:_ -> {error, bad_format}
end.
-ecdsa_id({namedCurve,?'secp256r1'}) -> "nistp256";
-ecdsa_id({namedCurve,?'secp384r1'}) -> "nistp384";
-ecdsa_id({namedCurve,?'secp521r1'}) -> "nistp521".
+encode_public_key(_Alg, Key) ->
+ try
+ public_key:ssh_encode(Key, ssh2_pubkey)
+ catch
+ _:_ -> not_ok
+ end.
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 09ef03f3f8..7fb86c1108 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -1348,7 +1348,6 @@ 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)
diff --git a/lib/ssh/src/ssh_message.erl b/lib/ssh/src/ssh_message.erl
index 42e9b27b93..b6c4496be2 100644
--- a/lib/ssh/src/ssh_message.erl
+++ b/lib/ssh/src/ssh_message.erl
@@ -30,7 +30,7 @@
-include("ssh_auth.hrl").
-include("ssh_transport.hrl").
--export([encode/1, decode/1, encode_host_key/1, decode_keyboard_interactive_prompts/2]).
+-export([encode/1, decode/1, decode_keyboard_interactive_prompts/2]).
encode(#ssh_msg_global_request{
name = Name,
@@ -227,7 +227,7 @@ encode(#ssh_msg_kexdh_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
EncSign = encode_signature(Key, Signature),
ssh_bits:encode([?SSH_MSG_KEXDH_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
@@ -255,7 +255,7 @@ encode(#ssh_msg_kex_dh_gex_reply{
f = F,
h_sig = Signature
}) ->
- EncKey = encode_host_key(Key),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
EncSign = encode_signature(Key, Signature),
ssh_bits:encode([?SSH_MSG_KEX_DH_GEX_REPLY, EncKey, F, EncSign], [byte, binary, mpint, binary]);
@@ -263,7 +263,7 @@ encode(#ssh_msg_kex_ecdh_init{q_c = Q_c}) ->
ssh_bits:encode([?SSH_MSG_KEX_ECDH_INIT, Q_c], [byte, mpint]);
encode(#ssh_msg_kex_ecdh_reply{public_host_key = Key, q_s = Q_s, h_sig = Sign}) ->
- EncKey = encode_host_key(Key),
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
EncSign = encode_signature(Key, Sign),
ssh_bits:encode([?SSH_MSG_KEX_ECDH_REPLY, EncKey, Q_s, EncSign], [byte, binary, mpint, binary]);
@@ -428,7 +428,7 @@ decode(<<"dh",?BYTE(?SSH_MSG_KEXDH_INIT), ?DEC_MPINT(E,__0)>>) ->
decode(<<"dh", ?BYTE(?SSH_MSG_KEXDH_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
#ssh_msg_kexdh_reply{
- public_host_key = decode_host_key(Key),
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
f = F,
h_sig = decode_signature(Hashsign)
};
@@ -458,7 +458,7 @@ decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_INIT), ?DEC_MPINT(E,__0)>>) ->
decode(<<?BYTE(?SSH_MSG_KEX_DH_GEX_REPLY), ?DEC_BIN(Key,__0), ?DEC_MPINT(F,__1), ?DEC_BIN(Hashsign,__2)>>) ->
#ssh_msg_kex_dh_gex_reply{
- public_host_key = decode_host_key(Key),
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
f = F,
h_sig = decode_signature(Hashsign)
};
@@ -471,7 +471,7 @@ decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_INIT), ?DEC_MPINT(Q_c,__0)>>) ->
decode(<<"ecdh",?BYTE(?SSH_MSG_KEX_ECDH_REPLY),
?DEC_BIN(Key,__1), ?DEC_MPINT(Q_s,__2), ?DEC_BIN(Sig,__3)>>) ->
#ssh_msg_kex_ecdh_reply{
- public_host_key = decode_host_key(Key),
+ public_host_key = public_key:ssh_decode(Key, ssh2_pubkey),
q_s = Q_s,
h_sig = decode_signature(Sig)
};
@@ -545,41 +545,6 @@ decode_kex_init(<<?DEC_BIN(Data,__0), Rest/binary>>, Acc, N) ->
%%%================================================================
%%%
-%%% Host key decode/encode
-%%%
-
-decode_host_key(<<?DEC_BIN(Alg,__0), Rest/binary>>) -> decode_host_key(Alg, Rest).
-
-
-decode_host_key(<<"ssh-rsa">>, <<?DEC_MPINT(E,__0), ?DEC_MPINT(N,__1)>>) ->
- #'RSAPublicKey'{publicExponent = E,
- modulus = N};
-decode_host_key(<<"ssh-dss">>,
- <<?DEC_MPINT(P,__0),
- ?DEC_MPINT(Q,__1),
- ?DEC_MPINT(G,__2),
- ?DEC_MPINT(Y,__3)>>) ->
- {Y, #'Dss-Parms'{p = P,
- q = Q,
- g = G}};
-decode_host_key(<<"ecdsa-sha2-",Id/binary>>,
- <<?DEC_BIN(Id,__0), %% Id = <<"nistp256">> for example
- ?DEC_BIN(Blob,__1)>>) ->
- {#'ECPoint'{point=Blob}, {namedCurve,public_key:ssh_curvename2oid(Id)}}.
-
-
-encode_host_key(#'RSAPublicKey'{modulus = N, publicExponent = E}) ->
- ssh_bits:encode(["ssh-rsa", E, N], [string, mpint, mpint]);
-encode_host_key({Y, #'Dss-Parms'{p = P, q = Q, g = G}}) ->
- ssh_bits:encode(["ssh-dss", P, Q, G, Y],
- [string, mpint, mpint, mpint, mpint]);
-encode_host_key({#'ECPoint'{point = Q}, {namedCurve,OID}}) ->
- CurveName = public_key:oid2ssh_curvename(OID),
- ssh_bits:encode([<<"ecdsa-sha2-",CurveName/binary>>,CurveName,Q], [binary,binary,binary]).
-
-
-%%%================================================================
-%%%
%%% Signature decode/encode
%%%
diff --git a/lib/ssh/src/ssh_transport.erl b/lib/ssh/src/ssh_transport.erl
index 080d6f74f7..500db91df5 100644
--- a/lib/ssh/src/ssh_transport.erl
+++ b/lib/ssh/src/ssh_transport.erl
@@ -44,6 +44,7 @@
handle_kexdh_reply/2,
handle_kex_ecdh_init/2,
handle_kex_ecdh_reply/2,
+ extract_public_key/1,
unpack/3, decompress/2, ssh_packet/2, pack/2, msg_data/1,
sign/3, verify/4]).
@@ -1344,38 +1345,42 @@ hash(K, H, Ki, N, HASH) ->
hash(K, H, <<Ki/binary, Kj/binary>>, N-128, HASH).
kex_h(SSH, Key, E, F, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), E,F,K],
+ KeyBin, E,F,K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).
%% crypto:hash(sha,L).
kex_h(SSH, Curve, Key, Q_c, Q_s, K) ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
L = ssh_bits:encode([SSH#ssh.c_version, SSH#ssh.s_version,
SSH#ssh.c_keyinit, SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Q_c, Q_s, K],
+ KeyBin, Q_c, Q_s, K],
[string,string,binary,binary,binary,
mpint,mpint,mpint]),
crypto:hash(sha(Curve), L).
kex_h(SSH, Key, Min, NBits, Max, Prime, Gen, E, F, K) ->
L = if Min==-1; Max==-1 ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
Ts = [string,string,binary,binary,binary,
uint32,
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), NBits, Prime, Gen, E,F,K],
+ KeyBin, NBits, Prime, Gen, E,F,K],
Ts);
true ->
+ KeyBin = public_key:ssh_encode(Key, ssh2_pubkey),
Ts = [string,string,binary,binary,binary,
uint32,uint32,uint32,
mpint,mpint,mpint,mpint,mpint],
ssh_bits:encode([SSH#ssh.c_version,SSH#ssh.s_version,
SSH#ssh.c_keyinit,SSH#ssh.s_keyinit,
- ssh_message:encode_host_key(Key), Min, NBits, Max,
+ KeyBin, Min, NBits, Max,
Prime, Gen, E,F,K], Ts)
end,
crypto:hash(sha((SSH#ssh.algorithms)#alg.kex), L).