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