gpg: Change format for the key size in --list-key and --edit-key.
[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 (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
171             {
172               const void *p;
173
174               p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
175               pp[i] = xmalloc ((nbits+7)/8);
176               memcpy (pp[i], p, (nbits+7)/8);
177               nn[i] = (nbits+7)/8;
178               n += nn[i];
179             }
180           else
181             {
182               if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
183                                   &nbytes, pk->pkey[i]))
184                 BUG ();
185               pp[i] = xmalloc (nbytes);
186               if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
187                                   &nbytes, pk->pkey[i]))
188                 BUG ();
189               nn[i] = nbytes;
190               n += nn[i];
191             }
192         }
193     }
194
195   gcry_md_putc ( md, 0x99 );     /* ctb */
196   /* What does it mean if n is greater than than 0xFFFF ? */
197   gcry_md_putc ( md, n >> 8 );   /* 2 byte length header */
198   gcry_md_putc ( md, n );
199   gcry_md_putc ( md, pk->version );
200
201   gcry_md_putc ( md, pk->timestamp >> 24 );
202   gcry_md_putc ( md, pk->timestamp >> 16 );
203   gcry_md_putc ( md, pk->timestamp >>  8 );
204   gcry_md_putc ( md, pk->timestamp       );
205
206   if(pk->version<4)
207     {
208       u16 days=0;
209       if(pk->expiredate)
210         days=(u16)((pk->expiredate - pk->timestamp) / 86400L);
211
212       gcry_md_putc ( md, days >> 8 );
213       gcry_md_putc ( md, days );
214     }
215
216   gcry_md_putc ( md, pk->pubkey_algo );
217
218   if(npkey==0 && pk->pkey[0]
219      && gcry_mpi_get_flag (pk->pkey[0], GCRYMPI_FLAG_OPAQUE))
220     {
221       gcry_md_write (md, pp[0], nn[0]);
222     }
223   else
224     for(i=0; i < npkey; i++ )
225       {
226         gcry_md_write ( md, pp[i], nn[i] );
227         xfree(pp[i]);
228       }
229 }
230
231
232 static gcry_md_hd_t
233 do_fingerprint_md( PKT_public_key *pk )
234 {
235   gcry_md_hd_t md;
236
237   if (gcry_md_open (&md, DIGEST_ALGO_SHA1, 0))
238     BUG ();
239   hash_public_key(md,pk);
240   gcry_md_final( md );
241
242   return md;
243 }
244
245
246 /* fixme: Check whether we can replace this function or if not
247    describe why we need it.  */
248 u32
249 v3_keyid (gcry_mpi_t a, u32 *ki)
250 {
251   byte *buffer, *p;
252   size_t nbytes;
253
254   if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a ))
255     BUG ();
256   /* fixme: allocate it on the stack */
257   buffer = xmalloc (nbytes);
258   if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a ))
259     BUG ();
260   if (nbytes < 8) /* oops */
261     ki[0] = ki[1] = 0;
262   else
263     {
264       p = buffer + nbytes - 8;
265       ki[0] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3];
266       p += 4;
267       ki[1] = (p[0] << 24) | (p[1] <<16) | (p[2] << 8) | p[3];
268     }
269   xfree (buffer);
270   return ki[1];
271 }
272
273
274 size_t
275 keystrlen(void)
276 {
277   switch(opt.keyid_format)
278     {
279     case KF_SHORT:
280       return 8;
281
282     case KF_LONG:
283       return 16;
284
285     case KF_0xSHORT:
286       return 10;
287
288     case KF_0xLONG:
289       return 18;
290
291     default:
292       BUG();
293     }
294 }
295
296
297 const char *
298 keystr (u32 *keyid)
299 {
300   static char keyid_str[KEYID_STR_SIZE];
301
302   switch (opt.keyid_format)
303     {
304     case KF_SHORT:
305       snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
306       break;
307
308     case KF_LONG:
309       if (keyid[0])
310         snprintf (keyid_str, sizeof keyid_str, "%08lX%08lX",
311                   (ulong)keyid[0], (ulong)keyid[1]);
312       else
313         snprintf (keyid_str, sizeof keyid_str, "%08lX", (ulong)keyid[1]);
314       break;
315
316     case KF_0xSHORT:
317       snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
318       break;
319
320     case KF_0xLONG:
321       if(keyid[0])
322         snprintf (keyid_str, sizeof keyid_str, "0x%08lX%08lX",
323                   (ulong)keyid[0],(ulong)keyid[1]);
324       else
325         snprintf (keyid_str, sizeof keyid_str, "0x%08lX", (ulong)keyid[1]);
326       break;
327
328     default:
329       BUG();
330     }
331
332   return keyid_str;
333 }
334
335
336 const char *
337 keystr_with_sub (u32 *main_kid, u32 *sub_kid)
338 {
339   static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
340   char *p;
341
342   mem2str (buffer, keystr (main_kid), KEYID_STR_SIZE);
343   if (sub_kid)
344     {
345       p = buffer + strlen (buffer);
346       *p++ = '/';
347       mem2str (p, keystr (sub_kid), KEYID_STR_SIZE);
348     }
349   return buffer;
350 }
351
352
353 const char *
354 keystr_from_pk(PKT_public_key *pk)
355 {
356   keyid_from_pk(pk,NULL);
357
358   return keystr(pk->keyid);
359 }
360
361
362 const char *
363 keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
364 {
365   keyid_from_pk (main_pk, NULL);
366   if (sub_pk)
367     keyid_from_pk (sub_pk, NULL);
368
369   return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL);
370 }
371
372
373
374 const char *
375 keystr_from_desc(KEYDB_SEARCH_DESC *desc)
376 {
377   switch(desc->mode)
378     {
379     case KEYDB_SEARCH_MODE_LONG_KID:
380     case KEYDB_SEARCH_MODE_SHORT_KID:
381       return keystr(desc->u.kid);
382
383     case KEYDB_SEARCH_MODE_FPR20:
384       {
385         u32 keyid[2];
386
387         keyid[0] = ((unsigned char)desc->u.fpr[12] << 24
388                     | (unsigned char)desc->u.fpr[13] << 16
389                     | (unsigned char)desc->u.fpr[14] << 8
390                     | (unsigned char)desc->u.fpr[15]);
391         keyid[1] = ((unsigned char)desc->u.fpr[16] << 24
392                     | (unsigned char)desc->u.fpr[17] << 16
393                     | (unsigned char)desc->u.fpr[18] << 8
394                     | (unsigned char)desc->u.fpr[19]);
395
396         return keystr(keyid);
397       }
398
399     case KEYDB_SEARCH_MODE_FPR16:
400       return "?v3 fpr?";
401
402     default:
403       BUG();
404     }
405 }
406
407
408 /*
409  * Get the keyid from the public key and put it into keyid
410  * if this is not NULL. Return the 32 low bits of the keyid.
411  */
412 u32
413 keyid_from_pk (PKT_public_key *pk, u32 *keyid)
414 {
415   u32 lowbits;
416   u32 dummy_keyid[2];
417
418   if (!keyid)
419     keyid = dummy_keyid;
420
421   if( pk->keyid[0] || pk->keyid[1] )
422     {
423       keyid[0] = pk->keyid[0];
424       keyid[1] = pk->keyid[1];
425       lowbits = keyid[1];
426     }
427   else if( pk->version < 4 )
428     {
429       if( is_RSA(pk->pubkey_algo) )
430         {
431           lowbits = (pubkey_get_npkey (pk->pubkey_algo) ?
432                      v3_keyid ( pk->pkey[0], keyid ) : 0); /* From n. */
433           pk->keyid[0] = keyid[0];
434           pk->keyid[1] = keyid[1];
435         }
436       else
437         pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
438     }
439   else
440     {
441       const byte *dp;
442       gcry_md_hd_t md;
443
444       md = do_fingerprint_md(pk);
445       if(md)
446         {
447           dp = gcry_md_read ( md, 0 );
448           keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
449           keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
450           lowbits = keyid[1];
451           gcry_md_close (md);
452           pk->keyid[0] = keyid[0];
453           pk->keyid[1] = keyid[1];
454         }
455       else
456         pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
457     }
458
459   return lowbits;
460 }
461
462
463 /*
464  * Get the keyid from the fingerprint.  This function is simple for most
465  * keys, but has to do a keylookup for old stayle keys.
466  */
467 u32
468 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
469 {
470   u32 dummy_keyid[2];
471
472   if( !keyid )
473     keyid = dummy_keyid;
474
475   if (fprint_len != 20)
476     {
477       /* This is special as we have to lookup the key first.  */
478       PKT_public_key pk;
479       int rc;
480
481       memset (&pk, 0, sizeof pk);
482       rc = get_pubkey_byfprint (&pk, fprint, fprint_len);
483       if( rc )
484         {
485           log_error("Oops: keyid_from_fingerprint: no pubkey\n");
486           keyid[0] = 0;
487           keyid[1] = 0;
488         }
489       else
490         keyid_from_pk (&pk, keyid);
491     }
492   else
493     {
494       const byte *dp = fprint;
495       keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
496       keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
497     }
498
499   return keyid[1];
500 }
501
502
503 u32
504 keyid_from_sig (PKT_signature *sig, u32 *keyid)
505 {
506   if( keyid )
507     {
508       keyid[0] = sig->keyid[0];
509       keyid[1] = sig->keyid[1];
510     }
511   return sig->keyid[1];
512 }
513
514
515 byte *
516 namehash_from_uid (PKT_user_id *uid)
517 {
518   if (!uid->namehash)
519     {
520       uid->namehash = xmalloc (20);
521
522       if (uid->attrib_data)
523         rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
524       else
525         rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
526     }
527
528   return uid->namehash;
529 }
530
531
532 /*
533  * Return the number of bits used in PK.
534  */
535 unsigned int
536 nbits_from_pk (PKT_public_key *pk)
537 {
538     return pubkey_nbits (pk->pubkey_algo, pk->pkey);
539 }
540
541
542 static const char *
543 mk_datestr (char *buffer, time_t atime)
544 {
545   struct tm *tp;
546
547   if (IS_INVALID_TIME_T (atime))
548     strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
549   else
550     {
551       tp = gmtime (&atime);
552       sprintf (buffer,"%04d-%02d-%02d",
553                1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
554     }
555   return buffer;
556 }
557
558
559 /*
560  * return a string with the creation date of the pk
561  * Note: this is alloced in a static buffer.
562  *    Format is: yyyy-mm-dd
563  */
564 const char *
565 datestr_from_pk (PKT_public_key *pk)
566 {
567   static char buffer[11+5];
568   time_t atime = pk->timestamp;
569
570   return mk_datestr (buffer, atime);
571 }
572
573
574 const char *
575 datestr_from_sig (PKT_signature *sig )
576 {
577   static char buffer[11+5];
578   time_t atime = sig->timestamp;
579
580   return mk_datestr (buffer, atime);
581 }
582
583
584 const char *
585 expirestr_from_pk (PKT_public_key *pk)
586 {
587   static char buffer[11+5];
588   time_t atime;
589
590   if (!pk->expiredate)
591     return _("never     ");
592   atime = pk->expiredate;
593   return mk_datestr (buffer, atime);
594 }
595
596
597 const char *
598 expirestr_from_sig (PKT_signature *sig)
599 {
600   static char buffer[11+5];
601   time_t atime;
602
603   if (!sig->expiredate)
604     return _("never     ");
605   atime=sig->expiredate;
606   return mk_datestr (buffer, atime);
607 }
608
609
610 const char *
611 revokestr_from_pk( PKT_public_key *pk )
612 {
613   static char buffer[11+5];
614   time_t atime;
615
616   if(!pk->revoked.date)
617     return _("never     ");
618   atime=pk->revoked.date;
619   return mk_datestr (buffer, atime);
620 }
621
622
623 const char *
624 usagestr_from_pk( PKT_public_key *pk )
625 {
626   static char buffer[10];
627   int i = 0;
628   unsigned int use = pk->pubkey_usage;
629
630   if ( use & PUBKEY_USAGE_SIG )
631     buffer[i++] = 'S';
632
633   if ( use & PUBKEY_USAGE_CERT )
634     buffer[i++] = 'C';
635
636   if ( use & PUBKEY_USAGE_ENC )
637     buffer[i++] = 'E';
638
639   if ( (use & PUBKEY_USAGE_AUTH) )
640     buffer[i++] = 'A';
641
642   while (i < 4)
643     buffer[i++] = ' ';
644
645   buffer[i] = 0;
646   return buffer;
647 }
648
649
650 const char *
651 colon_strtime (u32 t)
652 {
653   static char buf[20];
654
655   if (!t)
656     return "";
657   snprintf (buf, sizeof buf, "%lu", (ulong)t);
658   return buf;
659 }
660
661 const char *
662 colon_datestr_from_pk (PKT_public_key *pk)
663 {
664   static char buf[20];
665
666   snprintf (buf, sizeof buf, "%lu", (ulong)pk->timestamp);
667   return buf;
668 }
669
670
671 const char *
672 colon_datestr_from_sig (PKT_signature *sig)
673 {
674   static char buf[20];
675
676   snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
677   return buf;
678 }
679
680 const char *
681 colon_expirestr_from_sig (PKT_signature *sig)
682 {
683   static char buf[20];
684
685   if (!sig->expiredate)
686     return "";
687
688   snprintf (buf, sizeof buf,"%lu", (ulong)sig->expiredate);
689   return buf;
690 }
691
692
693 /*
694  * Return a byte array with the fingerprint for the given PK/SK
695  * The length of the array is returned in ret_len. Caller must free
696  * the array or provide an array of length MAX_FINGERPRINT_LEN.
697  */
698 byte *
699 fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
700 {
701   byte *buf;
702   const byte *dp;
703   size_t len, nbytes;
704   int i;
705
706   if ( pk->version < 4 )
707     {
708       if ( is_RSA(pk->pubkey_algo) )
709         {
710           /* RSA in version 3 packets is special. */
711           gcry_md_hd_t md;
712
713           if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
714             BUG ();
715           if ( pubkey_get_npkey (pk->pubkey_algo) > 1 )
716             {
717               for (i=0; i < 2; i++)
718                 {
719                   if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0,
720                                       &nbytes, pk->pkey[i]))
721                     BUG ();
722                   /* fixme: Better allocate BUF on the stack */
723                   buf = xmalloc (nbytes);
724                   if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes,
725                                       NULL, pk->pkey[i]))
726                     BUG ();
727                   gcry_md_write (md, buf, nbytes);
728                   xfree (buf);
729                 }
730             }
731           gcry_md_final (md);
732           if (!array)
733             array = xmalloc (16);
734           len = 16;
735           memcpy (array, gcry_md_read (md, DIGEST_ALGO_MD5), 16);
736           gcry_md_close(md);
737         }
738       else
739         {
740           if (!array)
741             array = xmalloc(16);
742           len = 16;
743           memset (array,0,16);
744         }
745     }
746   else
747     {
748       gcry_md_hd_t md;
749
750       md = do_fingerprint_md(pk);
751       dp = gcry_md_read( md, 0 );
752       len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
753       assert( len <= MAX_FINGERPRINT_LEN );
754       if (!array)
755         array = xmalloc ( len );
756       memcpy (array, dp, len );
757       pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
758       pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
759       gcry_md_close( md);
760     }
761
762   *ret_len = len;
763   return array;
764 }
765
766
767
768
769 \f
770 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
771    key parameters expressed as an canoncial encoded S-Exp.  ARRAY must
772    be 20 bytes long.  Returns 0 on sucess or an error code.  */
773 gpg_error_t
774 keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
775 {
776   gpg_error_t err;
777   gcry_sexp_t s_pkey;
778
779   if (DBG_PACKET)
780     log_debug ("get_keygrip for public key\n");
781
782   switch (pk->pubkey_algo)
783     {
784     case GCRY_PK_DSA:
785       err = gcry_sexp_build (&s_pkey, NULL,
786                              "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
787                              pk->pkey[0], pk->pkey[1],
788                              pk->pkey[2], pk->pkey[3]);
789       break;
790
791     case GCRY_PK_ELG:
792     case GCRY_PK_ELG_E:
793       err = gcry_sexp_build (&s_pkey, NULL,
794                              "(public-key(elg(p%m)(g%m)(y%m)))",
795                              pk->pkey[0], pk->pkey[1], pk->pkey[2]);
796       break;
797
798     case GCRY_PK_RSA:
799     case GCRY_PK_RSA_S:
800     case GCRY_PK_RSA_E:
801       err = gcry_sexp_build (&s_pkey, NULL,
802                              "(public-key(rsa(n%m)(e%m)))",
803                              pk->pkey[0], pk->pkey[1]);
804       break;
805
806     case PUBKEY_ALGO_EDDSA:
807     case PUBKEY_ALGO_ECDSA:
808     case PUBKEY_ALGO_ECDH:
809       {
810         char *curve = openpgp_oid_to_str (pk->pkey[0]);
811         if (!curve)
812           err = gpg_error_from_syserror ();
813         else
814           {
815             err = gcry_sexp_build (&s_pkey, NULL,
816                                    "(public-key(ecc(curve%s)(q%m)))",
817                                    curve, pk->pkey[1]);
818             xfree (curve);
819           }
820       }
821       break;
822
823     default:
824       err = gpg_error (GPG_ERR_PUBKEY_ALGO);
825       break;
826     }
827
828   if (err)
829     return err;
830
831   if (!gcry_pk_get_keygrip (s_pkey, array))
832     {
833       log_error ("error computing keygrip\n");
834       err = gpg_error (GPG_ERR_GENERAL);
835     }
836   else
837     {
838       if (DBG_PACKET)
839         log_printhex ("keygrip=", array, 20);
840       /* FIXME: Save the keygrip in PK.  */
841     }
842   gcry_sexp_release (s_pkey);
843
844   return 0;
845 }
846
847
848 /* Store an allocated buffer with the keygrip of PK encoded as a
849    hexstring at r_GRIP.  Returns 0 on success.  */
850 gpg_error_t
851 hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
852 {
853   gpg_error_t err;
854   unsigned char grip[20];
855
856   *r_grip = NULL;
857   err = keygrip_from_pk (pk, grip);
858   if (!err)
859     {
860       char * buf = xtrymalloc (20*2+1);
861       if (!buf)
862         err = gpg_error_from_syserror ();
863       else
864         {
865           bin2hex (grip, 20, buf);
866           *r_grip = buf;
867         }
868     }
869   return err;
870 }