aboutsummaryrefslogtreecommitdiffstats
path: root/common/ssh-utils.c
diff options
context:
space:
mode:
authorJustus Winter <[email protected]>2017-05-24 15:03:58 +0000
committerJustus Winter <[email protected]>2017-05-24 15:07:13 +0000
commit3a07a69dfc87b4fff610740d3dde8e23f0d2f8bc (patch)
treea7b8c993bc26ba9c2c6d86373cf63e3c09c0f8ff /common/ssh-utils.c
parentcommon: Support different digest algorithms for ssh fingerprints. (diff)
downloadgnupg-3a07a69dfc87b4fff610740d3dde8e23f0d2f8bc.tar.gz
gnupg-3a07a69dfc87b4fff610740d3dde8e23f0d2f8bc.zip
common: Correctly render SHA256-based ssh fingerprints.
* common/ssh-utils.c (dummy_realloc): New function. (dummy_free): Likewise. (get_fingerprint): Prepend the fingerprint with the name of the digest algorithm. Correctly render SHA256-based ssh fingerprints. * common/t-ssh-utils.c (sample_keys): Add SHA256 hashes for the keys. (main): Add an option to dump the keys to gather fingerprints, also print the SHA256 fingerprint for keys given as arguments, and check the SHA256 fingerprints of the test keys. GnuPG-bug-id: 2106 Signed-off-by: Justus Winter <[email protected]>
Diffstat (limited to 'common/ssh-utils.c')
-rw-r--r--common/ssh-utils.c73
1 files changed, 70 insertions, 3 deletions
diff --git a/common/ssh-utils.c b/common/ssh-utils.c
index 3925602a1..38d6e8aa2 100644
--- a/common/ssh-utils.c
+++ b/common/ssh-utils.c
@@ -64,6 +64,9 @@ is_eddsa (gcry_sexp_t keyparms)
return result;
}
+/* Dummy functions for es_mopen. */
+static void *dummy_realloc (void *mem, size_t size) { (void) size; return mem; }
+static void dummy_free (void *mem) { (void) mem; }
/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
The length of the fingerprint is returned at R_LEN and the
@@ -232,10 +235,74 @@ get_fingerprint (gcry_sexp_t key, int algo,
if (as_string)
{
- *r_fpr = (algo == GCRY_MD_MD5 ? bin2hexcolon : /* XXX we need base64 */ bin2hex)
- (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), NULL);
+ const char *algo_name;
+ char *fpr;
+
+ /* Prefix string with the algorithm name and a colon. */
+ algo_name = gcry_md_algo_name (algo);
+ *r_fpr = xtrymalloc (strlen (algo_name) + 1 + 3 * gcry_md_get_algo_dlen (algo) + 1);
+ if (*r_fpr == NULL)
+ {
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ goto leave;
+ }
+
+ strncpy (*r_fpr, algo_name, strlen (algo_name));
+ fpr = (char *) *r_fpr + strlen (algo_name);
+ *fpr++ = ':';
+
+ if (algo == GCRY_MD_MD5)
+ {
+ bin2hexcolon (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), fpr);
+ strlwr (fpr);
+ }
+ else
+ {
+ struct b64state b64s;
+ estream_t stream;
+ char *p;
+ long int len;
+
+ /* Write the base64-encoded hash to fpr. */
+ stream = es_mopen (fpr, 3 * gcry_md_get_algo_dlen (algo) + 1, 0,
+ 0, dummy_realloc, dummy_free, "w");
+ if (stream == NULL)
+ {
+ err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+ goto leave;
+ }
+
+ err = b64enc_start_es (&b64s, stream, "");
+ if (err)
+ {
+ es_fclose (stream);
+ goto leave;
+ }
+
+ err = b64enc_write (&b64s,
+ gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo));
+ if (err)
+ {
+ es_fclose (stream);
+ goto leave;
+ }
+
+ /* Finish, get the length, and close the stream. */
+ err = b64enc_finish (&b64s);
+ len = es_ftell (stream);
+ es_fclose (stream);
+ if (err)
+ goto leave;
+
+ /* Terminate. */
+ fpr[len] = 0;
+
+ /* Strip the trailing padding characters. */
+ for (p = fpr + len - 1; p > fpr && *p == '='; p--)
+ *p = 0;
+ }
+
*r_len = strlen (*r_fpr) + 1;
- strlwr (*r_fpr);
}
else
{