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