aboutsummaryrefslogtreecommitdiffstats
path: root/common/ssh-utils.c
diff options
context:
space:
mode:
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
{