Use inline functions to convert buffer data to scalars.
[gnupg.git] / g10 / keyid.c
1 /* keyid.c - key ID and fingerprint handling
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3  *               2004, 2006, 2010 Free Software Foundation, Inc.
4  * Copyright (C) 2014 Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <time.h>
28 #include <assert.h>
29
30 #include "gpg.h"
31 #include "util.h"
32 #include "main.h"
33 #include "packet.h"
34 #include "options.h"
35 #include "keydb.h"
36 #include "i18n.h"
37 #include "rmd160.h"
38 #include "host2net.h"
39
40
41 #define KEYID_STR_SIZE 19
42
43 #ifdef HAVE_UNSIGNED_TIME_T
44 # define IS_INVALID_TIME_T(a) ((a) == (time_t)(-1))
45 #else
46   /* Error or 32 bit time_t and value after 2038-01-19.  */
47 # define IS_INVALID_TIME_T(a) ((a) < 0)
48 #endif
49
50
51 /* Return a letter describing the public key algorithms.  */
52 int
53 pubkey_letter( int algo )
54 {
55   switch (algo)
56     {
57     case PUBKEY_ALGO_RSA:       return 'R' ;
58     case PUBKEY_ALGO_RSA_E:     return 'r' ;
59     case PUBKEY_ALGO_RSA_S:     return 's' ;
60     case PUBKEY_ALGO_ELGAMAL_E: return 'g' ;
61     case PUBKEY_ALGO_ELGAMAL:   return 'G' ;
62     case PUBKEY_ALGO_DSA:       return 'D' ;
63     case PUBKEY_ALGO_ECDH:      return 'e' ;    /* ECC DH (encrypt only) */
64     case PUBKEY_ALGO_ECDSA:     return 'E' ;    /* ECC DSA (sign only)   */
65     case PUBKEY_ALGO_EDDSA:     return 'E' ;    /* ECC EdDSA (sign only) */
66     default: return '?';
67     }
68 }
69
70 /* Return a string describing the public key algorithm and the
71    keysize.  For elliptic curves the functions prints the name of the
72    curve because the keysize is a property of the curve.  The string
73    is copied to the supplied buffer up a length of BUFSIZE-1.
74    Examples for the output are:
75
76    "rsa2048"  - RSA with 2048 bit
77    "elg1024"  - Elgamal with 1024 bit
78    "ed25519"  - ECC using the curve Ed25519.
79    "E_1.2.3.4"  - ECC using the unsupported curve with OID "1.2.3.4".
80    "E_1.3.6.1.4.1.11591.2.12242973" ECC with a bogus OID.
81    "unknown_N"  - Unknown OpenPGP algorithm N.
82
83    If the option --legacy-list-mode is active, the output use the
84    legacy format:
85
86    "2048R" - RSA with 2048 bit
87    "1024g" - Elgamal with 1024 bit
88    "256E"  - ECDSA using a curve with 256 bit
89
90    The macro PUBKEY_STRING_SIZE may be used to allocate a buffer with
91    a suitable size.*/
92 char *
93 pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
94 {
95   const char *prefix = NULL;
96
97   if (opt.legacy_list_mode)
98     {
99       snprintf (buffer, bufsize, "%4u%c",
100                 nbits_from_pk (pk), pubkey_letter (pk->pubkey_algo));
101       return buffer;
102     }
103
104   switch (pk->pubkey_algo)
105     {
106     case PUBKEY_ALGO_RSA:
107     case PUBKEY_ALGO_RSA_E:
108     case PUBKEY_ALGO_RSA_S:     prefix = "rsa"; break;
109     case PUBKEY_ALGO_ELGAMAL_E: prefix = "elg"; break;
110     case PUBKEY_ALGO_DSA:       prefix = "dsa"; break;
111     case PUBKEY_ALGO_ELGAMAL:   prefix = "xxx"; break;
112     case PUBKEY_ALGO_ECDH:
113     case PUBKEY_ALGO_ECDSA:
114     case PUBKEY_ALGO_EDDSA:     prefix = "";    break;
115     }
116
117   if (prefix && *prefix)
118     snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
119   else if (prefix)
120     {
121       char *curve = openpgp_oid_to_str (pk->pkey[0]);
122       const char *name = openpgp_oid_to_curve (curve);
123
124       if (*name && *name != '?')
125         snprintf (buffer, bufsize, "%s", name);
126       else if (curve)
127         snprintf (buffer, bufsize, "E_%s", curve);
128       else
129         snprintf (buffer, bufsize, "E_error");
130       xfree (curve);
131     }
132   else
133     snprintf (buffer, bufsize, "unknown_%u", (unsigned int)pk->pubkey_algo);
134
135   return buffer;
136 }
137
138
139 /* Hash a public key.  This function is useful for v4 fingerprints and
140    for v3 or v4 key signing. */
141 void
142 hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
143 {
144   unsigned int n = 6;
145   unsigned int nn[PUBKEY_MAX_NPKEY];
146   byte *pp[PUBKEY_MAX_NPKEY];
147   int i;
148   unsigned int nbits;
149   size_t nbytes;
150   int npkey = pubkey_get_npkey (pk->pubkey_algo);
151
152   /* FIXME: We can avoid the extra malloc by calling only the first
153      mpi_print here which computes the required length and calling the
154      real mpi_print only at the end.  The speed advantage would only be
155      for ECC (opaque MPIs) or if we could implement an mpi_print
156      variant with a callback handler to do the hashing.  */
157   if (npkey==0 && pk->pkey[0]
158       && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
159     {
160       pp[0] = gcry_mpi_get_opaque (pk->pkey[0], &nbits);
161       nn[0] = (nbits+7)/8;
162       n+=nn[0];
163     }
164   else
165     {
166       for (i=0; i < npkey; i++ )
167         {
168           if (!pk->pkey[i])
169             {
170               /* This case may only happen if the parsing of the MPI
171                  failed but the key was anyway created.  May happen
172                  during "gpg KEYFILE".  */
173               pp[i] = NULL;
174               nn[i] = 0;
175             }
176           else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
177             {
178               const void *p;
179
180               p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
181               pp[i] = xmalloc ((nbits+7)/8);
182               memcpy (pp[i], p, (nbits+7)/8);
183               nn[i] = (nbits+7)/8;
184               n += nn[i];
185             }
186           else
187             {
188               if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
189                                   &nbytes, pk->pkey[i]))
190                 BUG ();
191               pp[i] = xmalloc (nbytes);
192               if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
193                                   &nbytes, pk->pkey[i]))
194                 BUG ();
195               nn[i] = nbytes;
196               n += nn[i];
197             }
198         }
199     }
200
201   gcry_md_putc ( md, 0x99 );     /* ctb */
202   /* What does it mean if n is greater than than 0xFFFF ? */
203   gcry_md_putc ( md, n >> 8 );   /* 2 byte length header */
204   gcry_md_putc ( md, n );
205   gcry_md_putc ( md, pk->version );
206
207   gcry_md_putc ( md, pk->timestamp >> 24 );
208   gcry_md_putc ( md, pk->timestamp >> 16 );
209   gcry_md_putc ( md, pk->timestamp >>  8 );
210   gcry_md_putc ( md, pk->timestamp       );
211
212   gcry_md_putc ( md, pk->pubkey_algo );
213
214   if(npkey==0 && pk->pkey[0]
215      && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
216     {
217       gcry_md_write (md, pp[0], nn[0]);
218     }
219   else
220     for(i=0; i < npkey; i++ )
221       {
222         gcry_md_write ( md, pp[i], nn[i] );
223         xfree(pp[i]);
224       }
225 }
226
227
228 static gcry_md_hd_t
229 do_fingerprint_md( PKT_public_key *pk )
230 {
231   gcry_md_hd_t md;
232
233   if (gcry_md_open (&md, DIGEST_ALGO_SHA1, 0))
234     BUG ();
235   hash_public_key(md,pk);
236   gcry_md_final( md );
237
238   return md;
239 }
240
241
242 /* fixme: Check whether we can replace this function or if not
243    describe why we need it.  */
244 u32
245 v3_keyid (gcry_mpi_t a, u32 *ki)
246 {
247   byte *buffer, *p;
248   size_t nbytes;
249
250   if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a ))
251     BUG ();
252   /* fixme: allocate it on the stack */
253   buffer = xmalloc (nbytes);
254   if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a ))
255     BUG ();
256   if (nbytes < 8) /* oops */
257     ki[0] = ki[1] = 0;
258   else
259     {
260       p = buffer + nbytes - 8;
261       ki[0] = buf32_to_u32 (p);
262       p += 4;
263       ki[1] = buf32_to_u32 (p);
264     }
265   xfree (buffer);
266   return ki[1];
267 }
268
269
270 size_t
271 keystrlen(void)
272 {
273   switch(opt.keyid_format)
274     {
275     case KF_SHORT:
276       return 8;
277
278     case KF_LONG:
279       return 16;
280
281     case KF_0xSHORT:
282       return 10;
283
284     case KF_0xLONG:
285       return 18;
286
287     default:
288       BUG();
289     }
290 }
291
292
293 const char *
294 keystr (u32 *keyid)
295 {
296   static char keyid_str[KEYID_STR_SIZE];
297
298   switch (opt.keyid_format)
299     {
300     case KF_SHORT:
301       snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
302       break;
303
304     case KF_LONG:
305       if (keyid[0])
306         snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
307                   (ulong)keyid[0], (ulong)keyid[1]);
308       else
309         snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
310       break;
311
312     case KF_0xSHORT:
313       snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
314       break;
315
316     case KF_0xLONG:
317       if(keyid[0])
318         snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
319                   (ulong)keyid[0],(ulong)keyid[1]);
320       else
321         snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
322       break;
323
324     default:
325       BUG();
326     }
327
328   return keyid_str;
329 }
330
331
332 const char *
333 keystr_with_sub (u32 *main_kid, u32 *sub_kid)
334 {
335   static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
336   char *p;
337
338   mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
339   if (sub_kid)
340     {
341       p = buffer + strlen (buffer);
342       *p++ = '/';
343       mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
344     }
345   return buffer;
346 }
347
348
349 const char *
350 keystr_from_pk(PKT_public_key *pk)
351 {
352   keyid_from_pk(pk,NULL);
353
354   return keystr(pk->keyid);
355 }
356
357
358 const char *
359 keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
360 {
361   keyid_from_pk (main_pk, NULL);
362   if (sub_pk)
363     keyid_from_pk (sub_pk, NULL);
364
365   return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL);
366 }
367
368
369
370 const char *
371 keystr_from_desc(KEYDB_SEARCH_DESC *desc)
372 {
373   switch(desc->mode)
374     {
375     case KEYDB_SEARCH_MODE_LONG_KID:
376     case KEYDB_SEARCH_MODE_SHORT_KID:
377       return keystr(desc->u.kid);
378
379     case KEYDB_SEARCH_MODE_FPR20:
380       {
381         u32 keyid[2];
382
383         keyid[0] = buf32_to_u32 (desc->u.fpr+12);
384         keyid[1] = buf32_to_u32 (desc->u.fpr+16);
385         return keystr(keyid);
386       }
387
388     case KEYDB_SEARCH_MODE_FPR16:
389       return "?v3 fpr?";
390
391     default:
392       BUG();
393     }
394 }
395
396
397 /*
398  * Get the keyid from the public key and put it into keyid
399  * if this is not NULL. Return the 32 low bits of the keyid.
400  */
401 u32
402 keyid_from_pk (PKT_public_key *pk, u32 *keyid)
403 {
404   u32 lowbits;
405   u32 dummy_keyid[2];
406
407   if (!keyid)
408     keyid = dummy_keyid;
409
410   if( pk->keyid[0] || pk->keyid[1] )
411     {
412       keyid[0] = pk->keyid[0];
413       keyid[1] = pk->keyid[1];
414       lowbits = keyid[1];
415     }
416   else
417     {
418       const byte *dp;
419       gcry_md_hd_t md;
420
421       md = do_fingerprint_md(pk);
422       if(md)
423         {
424           dp = gcry_md_read ( md, 0 );
425           keyid[0] = buf32_to_u32 (dp+12);
426           keyid[1] = buf32_to_u32 (dp+16);
427           lowbits = keyid[1];
428           gcry_md_close (md);
429           pk->keyid[0] = keyid[0];
430           pk->keyid[1] = keyid[1];
431         }
432       else
433         pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
434     }
435
436   return lowbits;
437 }
438
439
440 /*
441  * Get the keyid from the fingerprint.  This function is simple for most
442  * keys, but has to do a keylookup for old stayle keys.
443  */
444 u32
445 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
446 {
447   u32 dummy_keyid[2];
448
449   if( !keyid )
450     keyid = dummy_keyid;
451
452   if (fprint_len != 20)
453     {
454       /* This is special as we have to lookup the key first.  */
455       PKT_public_key pk;
456       int rc;
457
458       memset (&pk, 0, sizeof pk);
459       rc = get_pubkey_byfprint (&pk, fprint, fprint_len);
460       if( rc )
461         {
462           log_error("Oops: keyid_from_fingerprint: no pubkey\n");
463           keyid[0] = 0;
464           keyid[1] = 0;
465         }
466       else
467         keyid_from_pk (&pk, keyid);
468     }
469   else
470     {
471       const byte *dp = fprint;
472       keyid[0] = buf32_to_u32 (dp+12);
473       keyid[1] = buf32_to_u32 (dp+16);
474     }
475
476   return keyid[1];
477 }
478
479
480 u32
481 keyid_from_sig (PKT_signature *sig, u32 *keyid)
482 {
483   if( keyid )
484     {
485       keyid[0] = sig->keyid[0];
486       keyid[1] = sig->keyid[1];
487     }
488   return sig->keyid[1];
489 }
490
491
492 byte *
493 namehash_from_uid (PKT_user_id *uid)
494 {
495   if (!uid->namehash)
496     {
497       uid->namehash = xmalloc (20);
498
499       if (uid->attrib_data)
500         rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
501       else
502         rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
503     }
504
505   return uid->namehash;
506 }
507
508
509 /*
510  * Return the number of bits used in PK.
511  */
512 unsigned int
513 nbits_from_pk (PKT_public_key *pk)
514 {
515     return pubkey_nbits (pk->pubkey_algo, pk->pkey);
516 }
517
518
519 static const char *
520 mk_datestr (char *buffer, time_t atime)
521 {
522   struct tm *tp;
523
524   if (IS_INVALID_TIME_T (atime))
525     strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
526   else
527     {
528       tp = gmtime (&atime);
529       sprintf (buffer,"%04d-%02d-%02d",
530                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
531     }
532   return buffer;
533 }
534
535
536 /*
537  * return a string with the creation date of the pk
538  * Note: this is alloced in a static buffer.
539  *    Format is: yyyy-mm-dd
540  */
541 const char *
542 datestr_from_pk (PKT_public_key *pk)
543 {
544   static char buffer[11+5];
545   time_t atime = pk->timestamp;
546
547   return mk_datestr (buffer, atime);
548 }
549
550
551 const char *
552 datestr_from_sig (PKT_signature *sig )
553 {
554   static char buffer[11+5];
555   time_t atime = sig->timestamp;
556
557   return mk_datestr (buffer, atime);
558 }
559
560
561 const char *
562 expirestr_from_pk (PKT_public_key *pk)
563 {
564   static char buffer[11+5];
565   time_t atime;
566
567   if (!pk->expiredate)
568     return _("never     ");
569   atime = pk->expiredate;
570   return mk_datestr (buffer, atime);
571 }
572
573
574 const char *
575 expirestr_from_sig (PKT_signature *sig)
576 {
577   static char buffer[11+5];
578   time_t atime;
579
580   if (!sig->expiredate)
581     return _("never     ");
582   atime=sig->expiredate;
583   return mk_datestr (buffer, atime);
584 }
585
586
587 const char *
588 revokestr_from_pk( PKT_public_key *pk )
589 {
590   static char buffer[11+5];
591   time_t atime;
592
593   if(!pk->revoked.date)
594     return _("never     ");
595   atime=pk->revoked.date;
596   return mk_datestr (buffer, atime);
597 }
598
599
600 const char *
601 usagestr_from_pk (PKT_public_key *pk, int fill)
602 {
603   static char buffer[10];
604   int i = 0;
605   unsigned int use = pk->pubkey_usage;
606
607   if ( use & PUBKEY_USAGE_SIG )
608     buffer[i++] = 'S';
609
610   if ( use & PUBKEY_USAGE_CERT )
611     buffer[i++] = 'C';
612
613   if ( use & PUBKEY_USAGE_ENC )
614     buffer[i++] = 'E';
615
616   if ( (use & PUBKEY_USAGE_AUTH) )
617     buffer[i++] = 'A';
618
619   while (fill && i < 4)
620     buffer[i++] = ' ';
621
622   buffer[i] = 0;
623   return buffer;
624 }
625
626
627 const char *
628 colon_strtime (u32 t)
629 {
630   static char buf[20];
631
632   if (!t)
633     return "";
634   snprintf (buf, sizeof buf, "%lu", (ulong)t);
635   return buf;
636 }
637
638 const char *
639 colon_datestr_from_pk (PKT_public_key *pk)
640 {
641   static char buf[20];
642
643   snprintf (buf, sizeof buf, "%lu", (ulong)pk->timestamp);
644   return buf;
645 }
646
647
648 const char *
649 colon_datestr_from_sig (PKT_signature *sig)
650 {
651   static char buf[20];
652
653   snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
654   return buf;
655 }
656
657 const char *
658 colon_expirestr_from_sig (PKT_signature *sig)
659 {
660   static char buf[20];
661
662   if (!sig->expiredate)
663     return "";
664
665   snprintf (buf, sizeof buf,"%lu", (ulong)sig->expiredate);
666   return buf;
667 }
668
669
670 /*
671  * Return a byte array with the fingerprint for the given PK/SK
672  * The length of the array is returned in ret_len. Caller must free
673  * the array or provide an array of length MAX_FINGERPRINT_LEN.
674  */
675 byte *
676 fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
677 {
678   const byte *dp;
679   size_t len;
680   gcry_md_hd_t md;
681
682   md = do_fingerprint_md(pk);
683   dp = gcry_md_read( md, 0 );
684   len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
685   assert( len <= MAX_FINGERPRINT_LEN );
686   if (!array)
687     array = xmalloc ( len );
688   memcpy (array, dp, len );
689   pk->keyid[0] = buf32_to_u32 (dp+12);
690   pk->keyid[1] = buf32_to_u32 (dp+16);
691   gcry_md_close( md);
692
693   if (ret_len)
694     *ret_len = len;
695   return array;
696 }
697
698
699 /* Return an allocated buffer with the fingerprint of PK formatted as
700    a plain hexstring.  */
701 char *
702 hexfingerprint (PKT_public_key *pk)
703 {
704   unsigned char fpr[MAX_FINGERPRINT_LEN];
705   size_t len;
706   char *result;
707
708   fingerprint_from_pk (pk, fpr, &len);
709   result = xmalloc (2 * len + 1);
710   bin2hex (fpr, len, result);
711   return result;
712 }
713
714
715 \f
716 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
717    key parameters expressed as an canoncial encoded S-Exp.  ARRAY must
718    be 20 bytes long.  Returns 0 on sucess or an error code.  */
719 gpg_error_t
720 keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
721 {
722   gpg_error_t err;
723   gcry_sexp_t s_pkey;
724
725   if (DBG_PACKET)
726     log_debug ("get_keygrip for public key\n");
727
728   switch (pk->pubkey_algo)
729     {
730     case GCRY_PK_DSA:
731       err = gcry_sexp_build (&s_pkey, NULL,
732                              "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
733                              pk->pkey[0], pk->pkey[1],
734                              pk->pkey[2], pk->pkey[3]);
735       break;
736
737     case GCRY_PK_ELG:
738     case GCRY_PK_ELG_E:
739       err = gcry_sexp_build (&s_pkey, NULL,
740                              "(public-key(elg(p%m)(g%m)(y%m)))",
741                              pk->pkey[0], pk->pkey[1], pk->pkey[2]);
742       break;
743
744     case GCRY_PK_RSA:
745     case GCRY_PK_RSA_S:
746     case GCRY_PK_RSA_E:
747       err = gcry_sexp_build (&s_pkey, NULL,
748                              "(public-key(rsa(n%m)(e%m)))",
749                              pk->pkey[0], pk->pkey[1]);
750       break;
751
752     case PUBKEY_ALGO_EDDSA:
753     case PUBKEY_ALGO_ECDSA:
754     case PUBKEY_ALGO_ECDH:
755       {
756         char *curve = openpgp_oid_to_str (pk->pkey[0]);
757         if (!curve)
758           err = gpg_error_from_syserror ();
759         else
760           {
761             err = gcry_sexp_build (&s_pkey, NULL,
762                                    pk->pubkey_algo == PUBKEY_ALGO_EDDSA ?
763                                    "(public-key(ecc(curve%s)(flags eddsa)(q%m)))"
764                                    : "(public-key(ecc(curve%s)(q%m)))",
765                                    curve, pk->pkey[1]);
766             xfree (curve);
767           }
768       }
769       break;
770
771     default:
772       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
773       break;
774     }
775
776   if (err)
777     return err;
778
779   if (!gcry_pk_get_keygrip (s_pkey, array))
780     {
781       log_info ("error computing keygrip\n");
782       memset (array, 0, 20);
783       err = gpg_error (GPG_ERR_GENERAL);
784     }
785   else
786     {
787       if (DBG_PACKET)
788         log_printhex ("keygrip=", array, 20);
789       /* FIXME: Save the keygrip in PK.  */
790     }
791   gcry_sexp_release (s_pkey);
792
793   return 0;
794 }
795
796
797 /* Store an allocated buffer with the keygrip of PK encoded as a
798    hexstring at r_GRIP.  Returns 0 on success.  */
799 gpg_error_t
800 hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
801 {
802   gpg_error_t err;
803   unsigned char grip[20];
804
805   *r_grip = NULL;
806   err = keygrip_from_pk (pk, grip);
807   if (!err)
808     {
809       char * buf = xtrymalloc (20*2+1);
810       if (!buf)
811         err = gpg_error_from_syserror ();
812       else
813         {
814           bin2hex (grip, 20, buf);
815           *r_grip = buf;
816         }
817     }
818   return err;
819 }