common: Support different digest algorithms for ssh fingerprints.
authorJustus Winter <justus@g10code.com>
Fri, 4 Dec 2015 14:19:07 +0000 (15:19 +0100)
committerJustus Winter <justus@g10code.com>
Wed, 24 May 2017 15:01:48 +0000 (17:01 +0200)
* common/ssh-utils.c (get_fingerprint): Add and honor 'algo' parameter.
(ssh_get_fingerprint{,_string}): Likewise.
* common/ssh-utils.h (ssh_get_fingerprint{,_string}): Update prototypes.
* common/t-ssh-utils.c (main): Adapt accordingly.
* agent/command-ssh.c (agent_raw_key_from_file): Likewise.
(ssh_identity_register): Likewise.
* agent/command.c (do_one_keyinfo): Likewise.
* agent/findkey.c (modify_description): Likewise.
--
This lays the foundation to support other algorithms.

GnuPG-bug-id: 2106
Signed-off-by: Justus Winter <justus@g10code.com>
agent/command-ssh.c
agent/command.c
agent/findkey.c
common/ssh-utils.c
common/ssh-utils.h
common/t-ssh-utils.c

index 99c80c0..3dd3dd7 100644 (file)
@@ -2760,7 +2760,7 @@ data_sign (ctrl_t ctrl, ssh_key_type_spec_t *spec,
       err = agent_raw_key_from_file (ctrl, ctrl->keygrip, &key);
       if (err)
         goto out;
-      err = ssh_get_fingerprint_string (key, &fpr);
+      err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
       if (!err)
         {
           gcry_sexp_t tmpsxp = gcry_sexp_find_token (key, "comment", 0);
@@ -3038,7 +3038,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec,
 
   bin2hex (key_grip_raw, 20, key_grip);
 
-  err = ssh_get_fingerprint_string (key, &key_fpr);
+  err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &key_fpr);
   if (err)
     goto out;
 
index df788ef..d370821 100644 (file)
@@ -1201,7 +1201,7 @@ do_one_keyinfo (ctrl_t ctrl, const unsigned char *grip, assuan_context_t ctx,
 
       if (!agent_raw_key_from_file (ctrl, grip, &key))
         {
-          ssh_get_fingerprint_string (key, &fpr);
+          ssh_get_fingerprint_string (key, GCRY_MD_MD5, &fpr);
           gcry_sexp_release (key);
         }
     }
index b24d8f1..1f547b0 100644 (file)
@@ -412,7 +412,7 @@ agent_modify_description (const char *in, const char *comment,
 
                 case 'F': /* SSH style fingerprint.  */
                   if (!ssh_fpr && key)
-                    ssh_get_fingerprint_string (key, &ssh_fpr);
+                    ssh_get_fingerprint_string (key, GCRY_MD_MD5, &ssh_fpr);
                   if (ssh_fpr)
                     {
                       if (out)
index 60aa07b..3925602 100644 (file)
@@ -65,12 +65,13 @@ is_eddsa (gcry_sexp_t keyparms)
 }
 
 
-/* Return the Secure Shell type fingerprint for KEY.  The length of
-   the fingerprint is returned at R_LEN and the fingerprint itself at
-   R_FPR.  In case of a error code is returned and NULL stored at
-   R_FPR.  */
+/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
+   The length of the fingerprint is returned at R_LEN and the
+   fingerprint itself at R_FPR.  In case of a error code is returned
+   and NULL stored at R_FPR.  */
 static gpg_error_t
-get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
+get_fingerprint (gcry_sexp_t key, int algo,
+                 void **r_fpr, size_t *r_len, int as_string)
 {
   gpg_error_t err;
   gcry_sexp_t list = NULL;
@@ -111,7 +112,7 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
       goto leave;
     }
 
-  err = gcry_md_open (&md, GCRY_MD_MD5, 0);
+  err = gcry_md_open (&md, algo, 0);
   if (err)
     goto leave;
 
@@ -229,23 +230,23 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
         }
     }
 
-  *r_fpr = gcry_malloc (as_string? 61:20);
-  if (!*r_fpr)
-    {
-      err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
-      goto leave;
-    }
-
   if (as_string)
     {
-      bin2hexcolon (gcry_md_read (md, GCRY_MD_MD5), 16, *r_fpr);
-      *r_len = 3*16+1;
+      *r_fpr = (algo == GCRY_MD_MD5 ? bin2hexcolon : /* XXX we need base64 */ bin2hex)
+        (gcry_md_read (md, algo), gcry_md_get_algo_dlen (algo), NULL);
+      *r_len = strlen (*r_fpr) + 1;
       strlwr (*r_fpr);
     }
   else
     {
-      memcpy (*r_fpr, gcry_md_read (md, GCRY_MD_MD5), 16);
-      *r_len = 16;
+      *r_len = gcry_md_get_algo_dlen (algo);
+      *r_fpr = xtrymalloc (*r_len);
+      if (!*r_fpr)
+        {
+          err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
+          goto leave;
+        }
+      memcpy (*r_fpr, gcry_md_read (md, algo), *r_len);
     }
   err = 0;
 
@@ -257,28 +258,30 @@ get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len, int as_string)
   return err;
 }
 
-/* Return the Secure Shell type fingerprint for KEY.  The length of
-   the fingerprint is returned at R_LEN and the fingerprint itself at
-   R_FPR.  In case of an error an error code is returned and NULL
-   stored at R_FPR.  */
+/* Return the Secure Shell type fingerprint for KEY using digest ALGO.
+   The length of the fingerprint is returned at R_LEN and the
+   fingerprint itself at R_FPR.  In case of an error an error code is
+   returned and NULL stored at R_FPR.  */
 gpg_error_t
-ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len)
+ssh_get_fingerprint (gcry_sexp_t key, int algo,
+                     void **r_fpr, size_t *r_len)
 {
-  return get_fingerprint (key, r_fpr, r_len, 0);
+  return get_fingerprint (key, algo, r_fpr, r_len, 0);
 }
 
 
-/* Return the Secure Shell type fingerprint for KEY as a string.  The
-   fingerprint is mallcoed and stored at R_FPRSTR.  In case of an
-   error an error code is returned and NULL stored at R_FPRSTR.  */
+/* Return the Secure Shell type fingerprint for KEY using digest ALGO
+   as a string.  The fingerprint is mallcoed and stored at R_FPRSTR.
+   In case of an error an error code is returned and NULL stored at
+   R_FPRSTR.  */
 gpg_error_t
-ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr)
+ssh_get_fingerprint_string (gcry_sexp_t key, int algo, char **r_fprstr)
 {
   gpg_error_t err;
   size_t dummy;
   void *string;
 
-  err = get_fingerprint (key, &string, &dummy, 1);
+  err = get_fingerprint (key, algo, &string, &dummy, 1);
   *r_fprstr = string;
   return err;
 }
index 36d38a3..53d9f55 100644 (file)
 #define GNUPG_COMMON_SSH_UTILS_H
 
 
-gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, void **r_fpr, size_t *r_len);
+gpg_error_t ssh_get_fingerprint (gcry_sexp_t key, int algo,
+                                void **r_fpr, size_t *r_len);
 
-gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, char **r_fprstr);
+gpg_error_t ssh_get_fingerprint_string (gcry_sexp_t key, int algo,
+                                       char **r_fprstr);
 
 
 #endif /*GNUPG_COMMON_SSH_UTILS_H*/
index f63ea95..a4e948f 100644 (file)
@@ -262,7 +262,7 @@ main (int argc, char **argv)
   if (argc == 2)
     {
       key = read_key (argv[1]);
-      err = ssh_get_fingerprint_string (key, &string);
+      err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
       if (err)
         {
           fprintf (stderr, "%s:%d: error getting fingerprint: %s\n",
@@ -287,7 +287,7 @@ main (int argc, char **argv)
               exit (1);
             }
 
-          err = ssh_get_fingerprint_string (key, &string);
+          err = ssh_get_fingerprint_string (key, GCRY_MD_MD5, &string);
           gcry_sexp_release (key);
           if (err)
             {