More chnages to use estream. Add a way to replace the standard
[gnupg.git] / sm / fingerprint.c
index d6a3900..4704f59 100644 (file)
@@ -5,7 +5,7 @@
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -14,9 +14,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -61,6 +59,19 @@ gpgsm_get_fingerprint (ksba_cert_t cert, int algo,
   if (r_len)
     *r_len = len;
 
+  /* Fist check whether we have cached the fingerprint.  */
+  if (algo == GCRY_MD_SHA1)
+    {
+      size_t buflen;
+
+      assert (len >= 20);
+      if (!ksba_cert_get_user_data (cert, "sha1-fingerprint", 
+                                    array, len, &buflen)
+          && buflen == 20)
+        return array;
+    }
+
+  /* No, need to compute it.  */
   rc = gcry_md_open (&md, algo, 0);
   if (rc)
     {
@@ -79,6 +90,12 @@ gpgsm_get_fingerprint (ksba_cert_t cert, int algo,
     }
   gcry_md_final (md);
   memcpy (array, gcry_md_read(md, algo), len );
+  gcry_md_close (md);
+
+  /* Cache an SHA-1 fingerprint.  */
+  if ( algo == GCRY_MD_SHA1 )
+    ksba_cert_set_user_data (cert, "sha1-fingerprint", array, 20);
+
   return array;
 }
 
@@ -89,7 +106,7 @@ gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo)
 {
   unsigned char digest[MAX_DIGEST_LEN];
   char *buf;
-  int len, i;
+  int len;
 
   if (!algo)
     algo = GCRY_MD_SHA1;
@@ -98,9 +115,7 @@ gpgsm_get_fingerprint_string (ksba_cert_t cert, int algo)
   assert (len <= MAX_DIGEST_LEN );
   gpgsm_get_fingerprint (cert, algo, digest, NULL);
   buf = xmalloc (len*3+1);
-  *buf = 0;
-  for (i=0; i < len; i++ )
-    sprintf (buf+strlen(buf), i? ":%02X":"%02X", digest[i]);
+  bin2hexcolon (digest, len, buf);
   return buf;
 }
 
@@ -111,7 +126,7 @@ gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo)
 {
   unsigned char digest[MAX_DIGEST_LEN];
   char *buf;
-  int len, i;
+  int len;
 
   if (!algo)
     algo = GCRY_MD_SHA1;
@@ -119,29 +134,30 @@ gpgsm_get_fingerprint_hexstring (ksba_cert_t cert, int algo)
   len = gcry_md_get_algo_dlen (algo);
   assert (len <= MAX_DIGEST_LEN );
   gpgsm_get_fingerprint (cert, algo, digest, NULL);
-  buf = xmalloc (len*3+1);
-  *buf = 0;
-  for (i=0; i < len; i++ )
-    sprintf (buf+strlen(buf), "%02X", digest[i]);
+  buf = xmalloc (len*2+1);
+  bin2hex (digest, len, buf);
   return buf;
 }
 
 /* Return a certificate ID.  These are the last 4 bytes of the SHA-1
-   fingerprint. */
+   fingerprint.  If R_HIGH is not NULL the next 4 bytes are stored
+   there. */
 unsigned long
-gpgsm_get_short_fingerprint (ksba_cert_t cert)
+gpgsm_get_short_fingerprint (ksba_cert_t cert, unsigned long *r_high)
 {
   unsigned char digest[20];
 
   gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL);
+  if (r_high)
+    *r_high = ((digest[12]<<24)|(digest[13]<<16)|(digest[14]<< 8)|digest[15]);
   return ((digest[16]<<24)|(digest[17]<<16)|(digest[18]<< 8)|digest[19]);
 }
 
 \f
 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
-   key parameters expressed as an canoncial encoded S-Exp.  array must
-   be 20 bytes long. returns the array or a newly allocated one if the
-   passed one was NULL */
+   key parameters expressed as an canoncial encoded S-Exp.  ARRAY must
+   be 20 bytes long.  Returns ARRAY or a newly allocated buffer if ARRAY was
+   given as NULL.  May return NULL on error.  */
 unsigned char *
 gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array)
 {
@@ -183,19 +199,19 @@ gpgsm_get_keygrip (ksba_cert_t cert, unsigned char *array)
   return array;
 }
 
-/* Return an allocated buffer with the keygrip of CERT in from of an
-   hexstring.  NULL is returned in case of error */
+/* Return an allocated buffer with the keygrip of CERT encoded as a
+   hexstring.  NULL is returned in case of error */
 char *
 gpgsm_get_keygrip_hexstring (ksba_cert_t cert)
 {
   unsigned char grip[20];
-  char *buf, *p;
-  int i;
+  char *buf;
 
-  gpgsm_get_keygrip (cert, grip);
-  buf = p = xmalloc (20*2+1);
-  for (i=0; i < 20; i++, p += 2 )
-    sprintf (p, "%02X", grip[i]);
+  if (!gpgsm_get_keygrip (cert, grip))
+    return NULL;
+  buf = xtrymalloc (20*2+1);
+  if (buf)
+    bin2hex (grip, 20, buf);
   return buf;
 }