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