aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2017-02-10 14:34:52 +0100
committerHans Nilsson <[email protected]>2017-02-14 16:24:16 +0100
commitf7bae98de902c597d9f1e5861745e90aecc58191 (patch)
treebfae8a4957bd1a46be8164e41e95d92a7e4748eb
parentaa1a098b46d0a4d8dd122efcc78a7a1a3f6c6e4e (diff)
downloadotp-f7bae98de902c597d9f1e5861745e90aecc58191.tar.gz
otp-f7bae98de902c597d9f1e5861745e90aecc58191.tar.bz2
otp-f7bae98de902c597d9f1e5861745e90aecc58191.zip
public_key: generate a list of ssh fingerprints on request
-rw-r--r--lib/public_key/doc/src/public_key.xml5
-rw-r--r--lib/public_key/src/public_key.erl26
-rw-r--r--lib/public_key/test/public_key_SUITE.erl34
3 files changed, 45 insertions, 20 deletions
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 37aa05e0fd..c97ec361d1 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -857,6 +857,7 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
<func>
<name>ssh_hostkey_fingerprint(HostKey) -> string()</name>
<name>ssh_hostkey_fingerprint(DigestType, HostKey) -> string()</name>
+ <name>ssh_hostkey_fingerprint([DigestType], HostKey) -> [string()]</name>
<fsummary>Calculates a ssh fingerprint for a hostkey.</fsummary>
<type>
<v>Key = public_key()</v>
@@ -880,6 +881,10 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
5> public_key:ssh_hostkey_fingerprint(sha256,Key).
"SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"
+
+ 6> public_key:ssh_hostkey_fingerprint([sha,sha256],Key).
+ ["SHA1:bSLY/C4QXLDL/Iwmhyg0PGW9UbY",
+ "SHA256:aZGXhabfbf4oxglxltItWeHU7ub3Dc31NcNw2cMJePQ"]
</code>
</desc>
</func>
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 402f514803..adc35073d6 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -893,21 +893,31 @@ oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>.
%%--------------------------------------------------------------------
-spec ssh_hostkey_fingerprint(public_key()) -> string().
--spec ssh_hostkey_fingerprint(digest_type(), public_key()) -> string().
+-spec ssh_hostkey_fingerprint( digest_type(), public_key()) -> string()
+ ; ([digest_type()], public_key()) -> [string()]
+ .
ssh_hostkey_fingerprint(Key) ->
- sshfp_string(md5, Key).
+ sshfp_string(md5, public_key:ssh_encode(Key,ssh2_pubkey) ).
+
+ssh_hostkey_fingerprint(HashAlgs, Key) when is_list(HashAlgs) ->
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ [sshfp_full_string(HashAlg,EncKey) || HashAlg <- HashAlgs];
+ssh_hostkey_fingerprint(HashAlg, Key) when is_atom(HashAlg) ->
+ EncKey = public_key:ssh_encode(Key, ssh2_pubkey),
+ sshfp_full_string(HashAlg, EncKey).
-ssh_hostkey_fingerprint(HashAlg, Key) ->
- lists:concat([sshfp_alg_name(HashAlg),
- [$: | sshfp_string(HashAlg, Key)]
- ]).
-sshfp_string(HashAlg, Key) ->
+sshfp_string(HashAlg, EncodedKey) ->
%% Other HashAlgs than md5 will be printed with
%% other formats than hextstr by
%% ssh-keygen -E <alg> -lf <file>
- fp_fmt(sshfp_fmt(HashAlg), crypto:hash(HashAlg, public_key:ssh_encode(Key,ssh2_pubkey))).
+ fp_fmt(sshfp_fmt(HashAlg), crypto:hash(HashAlg, EncodedKey)).
+
+sshfp_full_string(HashAlg, EncKey) ->
+ lists:concat([sshfp_alg_name(HashAlg),
+ [$: | sshfp_string(HashAlg, EncKey)]
+ ]).
sshfp_alg_name(sha) -> "SHA1";
sshfp_alg_name(Alg) -> string:to_upper(atom_to_list(Alg)).
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 615ff32539..68aa152911 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -54,7 +54,8 @@ all() ->
ssh_hostkey_fingerprint_sha,
ssh_hostkey_fingerprint_sha256,
ssh_hostkey_fingerprint_sha384,
- ssh_hostkey_fingerprint_sha512
+ ssh_hostkey_fingerprint_sha512,
+ ssh_hostkey_fingerprint_list
].
groups() ->
@@ -93,20 +94,21 @@ end_per_group(_GroupName, Config) ->
%%-------------------------------------------------------------------
init_per_testcase(TestCase, Config) ->
case TestCase of
- ssh_hostkey_fingerprint_md5_implicit -> init_fingerprint_testcase(md5, Config);
- ssh_hostkey_fingerprint_md5 -> init_fingerprint_testcase(md5, Config);
- ssh_hostkey_fingerprint_sha -> init_fingerprint_testcase(sha, Config);
- ssh_hostkey_fingerprint_sha256 -> init_fingerprint_testcase(sha256, Config);
- ssh_hostkey_fingerprint_sha384 -> init_fingerprint_testcase(sha384, Config);
- ssh_hostkey_fingerprint_sha512 -> init_fingerprint_testcase(sha512, Config);
+ ssh_hostkey_fingerprint_md5_implicit -> init_fingerprint_testcase([md5], Config);
+ ssh_hostkey_fingerprint_md5 -> init_fingerprint_testcase([md5], Config);
+ ssh_hostkey_fingerprint_sha -> init_fingerprint_testcase([sha], Config);
+ ssh_hostkey_fingerprint_sha256 -> init_fingerprint_testcase([sha256], Config);
+ ssh_hostkey_fingerprint_sha384 -> init_fingerprint_testcase([sha384], Config);
+ ssh_hostkey_fingerprint_sha512 -> init_fingerprint_testcase([sha512], Config);
+ ssh_hostkey_fingerprint_list -> init_fingerprint_testcase([sha,md5], Config);
_ -> init_common_per_testcase(Config)
end.
-init_fingerprint_testcase(Alg, Config) ->
- CryptoSupports = lists:member(Alg, proplists:get_value(hashs, crypto:supports())),
- case CryptoSupports of
- false -> {skip,{Alg,not_supported}};
- true -> init_common_per_testcase(Config)
+init_fingerprint_testcase(Algs, Config) ->
+ Hashs = proplists:get_value(hashs, crypto:supports(), []),
+ case Algs -- Hashs of
+ [] -> init_common_per_testcase(Config);
+ UnsupportedAlgs -> {skip,{UnsupportedAlgs,not_supported}}
end.
init_common_per_testcase(Config0) ->
@@ -600,6 +602,14 @@ ssh_hostkey_fingerprint_sha512(_Config) ->
Expected = public_key:ssh_hostkey_fingerprint(sha512, ssh_hostkey(rsa)).
%%--------------------------------------------------------------------
+%% Since this kind of fingerprint is not available yet on standard
+%% distros, we do like this instead.
+ssh_hostkey_fingerprint_list(_Config) ->
+ Expected = ["SHA1:Soammnaqg06jrm2jivMSnzQGlmk",
+ "MD5:4b:0b:63:de:0f:a7:3a:ab:2c:cc:2d:d1:21:37:1d:3a"],
+ Expected = public_key:ssh_hostkey_fingerprint([sha,md5], ssh_hostkey(rsa)).
+
+%%--------------------------------------------------------------------
encrypt_decrypt() ->
[{doc, "Test public_key:encrypt_private and public_key:decrypt_public"}].
encrypt_decrypt(Config) when is_list(Config) ->