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