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 : * Copyright (C) 2016 g10 Code GmbH
6 : *
7 : * This file is part of GnuPG.
8 : *
9 : * GnuPG is free software; you can redistribute it and/or modify
10 : * it under the terms of the GNU General Public License as published by
11 : * the Free Software Foundation; either version 3 of the License, or
12 : * (at your option) any later version.
13 : *
14 : * GnuPG is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program; if not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include <config.h>
24 : #include <stdio.h>
25 : #include <stdlib.h>
26 : #include <string.h>
27 : #include <errno.h>
28 : #include <time.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 44 : pubkey_string (PKT_public_key *pk, char *buffer, size_t bufsize)
94 : {
95 44 : const char *prefix = NULL;
96 :
97 44 : 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 44 : switch (pk->pubkey_algo)
105 : {
106 : case PUBKEY_ALGO_RSA:
107 : case PUBKEY_ALGO_RSA_E:
108 15 : case PUBKEY_ALGO_RSA_S: prefix = "rsa"; break;
109 14 : case PUBKEY_ALGO_ELGAMAL_E: prefix = "elg"; break;
110 15 : 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 0 : case PUBKEY_ALGO_EDDSA: prefix = ""; break;
115 : }
116 :
117 44 : if (prefix && *prefix)
118 44 : snprintf (buffer, bufsize, "%s%u", prefix, nbits_from_pk (pk));
119 0 : else if (prefix)
120 : {
121 0 : char *curve = openpgp_oid_to_str (pk->pkey[0]);
122 0 : const char *name = openpgp_oid_to_curve (curve, 0);
123 :
124 0 : if (name)
125 0 : 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 0 : xfree (curve);
131 : }
132 : else
133 0 : snprintf (buffer, bufsize, "unknown_%u", (unsigned int)pk->pubkey_algo);
134 :
135 44 : 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 10148 : hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
143 : {
144 10148 : 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 10148 : 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 10148 : 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 40169 : for (i=0; i < npkey; i++ )
167 : {
168 30021 : 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 30021 : else if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
177 : {
178 : const void *p;
179 :
180 945 : p = gcry_mpi_get_opaque (pk->pkey[i], &nbits);
181 945 : pp[i] = xmalloc ((nbits+7)/8);
182 945 : if (p)
183 945 : memcpy (pp[i], p, (nbits+7)/8);
184 : else
185 0 : pp[i] = NULL;
186 945 : nn[i] = (nbits+7)/8;
187 945 : n += nn[i];
188 : }
189 : else
190 : {
191 29076 : if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0,
192 : &nbytes, pk->pkey[i]))
193 0 : BUG ();
194 29076 : pp[i] = xmalloc (nbytes);
195 29076 : if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
196 : &nbytes, pk->pkey[i]))
197 0 : BUG ();
198 29076 : nn[i] = nbytes;
199 29076 : n += nn[i];
200 : }
201 : }
202 : }
203 :
204 10148 : gcry_md_putc ( md, 0x99 ); /* ctb */
205 : /* What does it mean if n is greater than than 0xFFFF ? */
206 10148 : gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
207 10148 : gcry_md_putc ( md, n );
208 10148 : gcry_md_putc ( md, pk->version );
209 :
210 10148 : gcry_md_putc ( md, pk->timestamp >> 24 );
211 10148 : gcry_md_putc ( md, pk->timestamp >> 16 );
212 10148 : gcry_md_putc ( md, pk->timestamp >> 8 );
213 10148 : gcry_md_putc ( md, pk->timestamp );
214 :
215 10148 : gcry_md_putc ( md, pk->pubkey_algo );
216 :
217 10148 : 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 40169 : for(i=0; i < npkey; i++ )
226 : {
227 30021 : if (pp[i])
228 30021 : gcry_md_write ( md, pp[i], nn[i] );
229 30021 : xfree(pp[i]);
230 : }
231 : }
232 10148 : }
233 :
234 :
235 : static gcry_md_hd_t
236 8638 : do_fingerprint_md( PKT_public_key *pk )
237 : {
238 : gcry_md_hd_t md;
239 :
240 8638 : if (gcry_md_open (&md, DIGEST_ALGO_SHA1, 0))
241 0 : BUG ();
242 8638 : hash_public_key(md,pk);
243 8638 : gcry_md_final( md );
244 :
245 8638 : 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 : /* Return PK's keyid. The memory is owned by PK. */
278 : u32 *
279 800 : pk_keyid (PKT_public_key *pk)
280 : {
281 800 : keyid_from_pk (pk, NULL);
282 :
283 : /* Uncomment this for help tracking down bugs related to keyid or
284 : main_keyid not being set correctly. */
285 : #if 0
286 : if (! (pk->main_keyid[0] || pk->main_keyid[1]))
287 : log_bug ("pk->main_keyid not set!\n");
288 : if (keyid_cmp (pk->keyid, pk->main_keyid) == 0
289 : && ! pk->flags.primary)
290 : log_bug ("keyid and main_keyid are the same, but primary flag not set!\n");
291 : if (keyid_cmp (pk->keyid, pk->main_keyid) != 0
292 : && pk->flags.primary)
293 : log_bug ("keyid and main_keyid are different, but primary flag set!\n");
294 : #endif
295 :
296 800 : return pk->keyid;
297 : }
298 :
299 : /* Return the keyid of the primary key associated with PK. The memory
300 : is owned by PK. */
301 : u32 *
302 3231 : pk_main_keyid (PKT_public_key *pk)
303 : {
304 : /* Uncomment this for help tracking down bugs related to keyid or
305 : main_keyid not being set correctly. */
306 : #if 0
307 : if (! (pk->main_keyid[0] || pk->main_keyid[1]))
308 : log_bug ("pk->main_keyid not set!\n");
309 : #endif
310 :
311 3231 : return pk->main_keyid;
312 : }
313 :
314 : /* Copy the keyid in SRC to DEST and return DEST. */
315 : u32 *
316 3 : keyid_copy (u32 *dest, const u32 *src)
317 : {
318 3 : dest[0] = src[0];
319 3 : dest[1] = src[1];
320 3 : return dest;
321 : }
322 :
323 : char *
324 1312 : format_keyid (u32 *keyid, int format, char *buffer, int len)
325 : {
326 : char tmp[KEYID_STR_SIZE];
327 1312 : if (! buffer)
328 : {
329 0 : buffer = tmp;
330 0 : len = sizeof (tmp);
331 : }
332 :
333 1312 : if (format == KF_DEFAULT)
334 0 : format = opt.keyid_format;
335 1312 : if (format == KF_DEFAULT)
336 0 : format = KF_NONE;
337 :
338 1312 : switch (format)
339 : {
340 : case KF_NONE:
341 0 : if (len)
342 0 : *buffer = 0;
343 0 : break;
344 :
345 : case KF_SHORT:
346 0 : snprintf (buffer, len, "%08lX", (ulong)keyid[1]);
347 0 : break;
348 :
349 : case KF_LONG:
350 1312 : snprintf (buffer, len, "%08lX%08lX", (ulong)keyid[0], (ulong)keyid[1]);
351 1312 : break;
352 :
353 : case KF_0xSHORT:
354 0 : snprintf (buffer, len, "0x%08lX", (ulong)keyid[1]);
355 0 : break;
356 :
357 : case KF_0xLONG:
358 0 : snprintf (buffer, len, "0x%08lX%08lX", (ulong)keyid[0],(ulong)keyid[1]);
359 0 : break;
360 :
361 : default:
362 0 : BUG();
363 : }
364 :
365 1312 : if (buffer == tmp)
366 0 : return xstrdup (buffer);
367 1312 : return buffer;
368 : }
369 :
370 : size_t
371 51 : keystrlen(void)
372 : {
373 51 : int format = opt.keyid_format;
374 51 : if (format == KF_DEFAULT)
375 1 : format = KF_NONE;
376 :
377 51 : switch(format)
378 : {
379 : case KF_NONE:
380 51 : return 0;
381 :
382 : case KF_SHORT:
383 0 : return 8;
384 :
385 : case KF_LONG:
386 0 : return 16;
387 :
388 : case KF_0xSHORT:
389 0 : return 10;
390 :
391 : case KF_0xLONG:
392 0 : return 18;
393 :
394 : default:
395 0 : BUG();
396 : }
397 : }
398 :
399 :
400 : const char *
401 1293 : keystr (u32 *keyid)
402 : {
403 : static char keyid_str[KEYID_STR_SIZE];
404 1293 : int format = opt.keyid_format;
405 :
406 1293 : if (format == KF_DEFAULT)
407 1 : format = KF_NONE;
408 1293 : if (format == KF_NONE)
409 1293 : format = KF_LONG;
410 :
411 1293 : return format_keyid (keyid, format, keyid_str, sizeof (keyid_str));
412 : }
413 :
414 : /* This function returns the key id of the main and possible the
415 : * subkey as one string. It is used by error messages. */
416 : const char *
417 0 : keystr_with_sub (u32 *main_kid, u32 *sub_kid)
418 : {
419 : static char buffer[KEYID_STR_SIZE+1+KEYID_STR_SIZE];
420 : char *p;
421 0 : int format = opt.keyid_format;
422 :
423 0 : if (format == KF_NONE)
424 0 : format = KF_LONG;
425 :
426 0 : format_keyid (main_kid, format, buffer, KEYID_STR_SIZE);
427 0 : if (sub_kid)
428 : {
429 0 : p = buffer + strlen (buffer);
430 0 : *p++ = '/';
431 0 : format_keyid (sub_kid, format, p, KEYID_STR_SIZE);
432 : }
433 0 : return buffer;
434 : }
435 :
436 :
437 : const char *
438 303 : keystr_from_pk(PKT_public_key *pk)
439 : {
440 303 : keyid_from_pk(pk,NULL);
441 :
442 303 : return keystr(pk->keyid);
443 : }
444 :
445 :
446 : const char *
447 0 : keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
448 : {
449 0 : keyid_from_pk (main_pk, NULL);
450 0 : if (sub_pk)
451 0 : keyid_from_pk (sub_pk, NULL);
452 :
453 0 : return keystr_with_sub (main_pk->keyid, sub_pk? sub_pk->keyid:NULL);
454 : }
455 :
456 :
457 : /* Return PK's key id as a string using the default format. PK owns
458 : the storage. */
459 : const char *
460 0 : pk_keyid_str (PKT_public_key *pk)
461 : {
462 0 : return keystr (pk_keyid (pk));
463 : }
464 :
465 :
466 : const char *
467 0 : keystr_from_desc(KEYDB_SEARCH_DESC *desc)
468 : {
469 0 : switch(desc->mode)
470 : {
471 : case KEYDB_SEARCH_MODE_LONG_KID:
472 : case KEYDB_SEARCH_MODE_SHORT_KID:
473 0 : return keystr(desc->u.kid);
474 :
475 : case KEYDB_SEARCH_MODE_FPR20:
476 : {
477 : u32 keyid[2];
478 :
479 0 : keyid[0] = buf32_to_u32 (desc->u.fpr+12);
480 0 : keyid[1] = buf32_to_u32 (desc->u.fpr+16);
481 0 : return keystr(keyid);
482 : }
483 :
484 : case KEYDB_SEARCH_MODE_FPR16:
485 0 : return "?v3 fpr?";
486 :
487 : default:
488 0 : BUG();
489 : }
490 : }
491 :
492 :
493 : /*
494 : * Get the keyid from the public key and put it into keyid
495 : * if this is not NULL. Return the 32 low bits of the keyid.
496 : */
497 : u32
498 13961 : keyid_from_pk (PKT_public_key *pk, u32 *keyid)
499 : {
500 : u32 lowbits;
501 : u32 dummy_keyid[2];
502 :
503 13961 : if (!keyid)
504 1140 : keyid = dummy_keyid;
505 :
506 13961 : if( pk->keyid[0] || pk->keyid[1] )
507 : {
508 10420 : keyid[0] = pk->keyid[0];
509 10420 : keyid[1] = pk->keyid[1];
510 10420 : lowbits = keyid[1];
511 : }
512 : else
513 : {
514 : const byte *dp;
515 : gcry_md_hd_t md;
516 :
517 3541 : md = do_fingerprint_md(pk);
518 3541 : if(md)
519 : {
520 3541 : dp = gcry_md_read ( md, 0 );
521 3541 : keyid[0] = buf32_to_u32 (dp+12);
522 3541 : keyid[1] = buf32_to_u32 (dp+16);
523 3541 : lowbits = keyid[1];
524 3541 : gcry_md_close (md);
525 3541 : pk->keyid[0] = keyid[0];
526 3541 : pk->keyid[1] = keyid[1];
527 : }
528 : else
529 0 : pk->keyid[0]=pk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
530 : }
531 :
532 13961 : return lowbits;
533 : }
534 :
535 :
536 : /*
537 : * Get the keyid from the fingerprint. This function is simple for most
538 : * keys, but has to do a keylookup for old stayle keys.
539 : */
540 : u32
541 29 : keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
542 : {
543 : u32 dummy_keyid[2];
544 :
545 29 : if( !keyid )
546 0 : keyid = dummy_keyid;
547 :
548 29 : if (fprint_len != 20)
549 : {
550 : /* This is special as we have to lookup the key first. */
551 : PKT_public_key pk;
552 : int rc;
553 :
554 0 : memset (&pk, 0, sizeof pk);
555 0 : rc = get_pubkey_byfprint (&pk, NULL, fprint, fprint_len);
556 0 : if( rc )
557 : {
558 0 : log_error("Oops: keyid_from_fingerprint: no pubkey\n");
559 0 : keyid[0] = 0;
560 0 : keyid[1] = 0;
561 : }
562 : else
563 0 : keyid_from_pk (&pk, keyid);
564 : }
565 : else
566 : {
567 29 : const byte *dp = fprint;
568 29 : keyid[0] = buf32_to_u32 (dp+12);
569 29 : keyid[1] = buf32_to_u32 (dp+16);
570 : }
571 :
572 29 : return keyid[1];
573 : }
574 :
575 :
576 : u32
577 0 : keyid_from_sig (PKT_signature *sig, u32 *keyid)
578 : {
579 0 : if( keyid )
580 : {
581 0 : keyid[0] = sig->keyid[0];
582 0 : keyid[1] = sig->keyid[1];
583 : }
584 0 : return sig->keyid[1];
585 : }
586 :
587 :
588 : byte *
589 795 : namehash_from_uid (PKT_user_id *uid)
590 : {
591 795 : if (!uid->namehash)
592 : {
593 700 : uid->namehash = xmalloc (20);
594 :
595 700 : if (uid->attrib_data)
596 0 : rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
597 : else
598 700 : rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
599 : }
600 :
601 795 : return uid->namehash;
602 : }
603 :
604 :
605 : /*
606 : * Return the number of bits used in PK.
607 : */
608 : unsigned int
609 964 : nbits_from_pk (PKT_public_key *pk)
610 : {
611 964 : return pubkey_nbits (pk->pubkey_algo, pk->pkey);
612 : }
613 :
614 :
615 : static const char *
616 52 : mk_datestr (char *buffer, time_t atime)
617 : {
618 : struct tm *tp;
619 :
620 52 : if (IS_INVALID_TIME_T (atime))
621 0 : strcpy (buffer, "????" "-??" "-??"); /* Mark this as invalid. */
622 : else
623 : {
624 52 : tp = gmtime (&atime);
625 156 : sprintf (buffer,"%04d-%02d-%02d",
626 104 : 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
627 : }
628 52 : return buffer;
629 : }
630 :
631 :
632 : /*
633 : * return a string with the creation date of the pk
634 : * Note: this is alloced in a static buffer.
635 : * Format is: yyyy-mm-dd
636 : */
637 : const char *
638 44 : datestr_from_pk (PKT_public_key *pk)
639 : {
640 : static char buffer[11+5];
641 44 : time_t atime = pk->timestamp;
642 :
643 44 : return mk_datestr (buffer, atime);
644 : }
645 :
646 :
647 : const char *
648 0 : datestr_from_sig (PKT_signature *sig )
649 : {
650 : static char buffer[11+5];
651 0 : time_t atime = sig->timestamp;
652 :
653 0 : return mk_datestr (buffer, atime);
654 : }
655 :
656 :
657 : const char *
658 8 : expirestr_from_pk (PKT_public_key *pk)
659 : {
660 : static char buffer[11+5];
661 : time_t atime;
662 :
663 8 : if (!pk->expiredate)
664 0 : return _("never ");
665 8 : atime = pk->expiredate;
666 8 : return mk_datestr (buffer, atime);
667 : }
668 :
669 :
670 : const char *
671 0 : expirestr_from_sig (PKT_signature *sig)
672 : {
673 : static char buffer[11+5];
674 : time_t atime;
675 :
676 0 : if (!sig->expiredate)
677 0 : return _("never ");
678 0 : atime=sig->expiredate;
679 0 : return mk_datestr (buffer, atime);
680 : }
681 :
682 :
683 : const char *
684 0 : revokestr_from_pk( PKT_public_key *pk )
685 : {
686 : static char buffer[11+5];
687 : time_t atime;
688 :
689 0 : if(!pk->revoked.date)
690 0 : return _("never ");
691 0 : atime=pk->revoked.date;
692 0 : return mk_datestr (buffer, atime);
693 : }
694 :
695 :
696 : const char *
697 44 : usagestr_from_pk (PKT_public_key *pk, int fill)
698 : {
699 : static char buffer[10];
700 44 : int i = 0;
701 44 : unsigned int use = pk->pubkey_usage;
702 :
703 44 : if ( use & PUBKEY_USAGE_SIG )
704 27 : buffer[i++] = 'S';
705 :
706 44 : if ( use & PUBKEY_USAGE_CERT )
707 25 : buffer[i++] = 'C';
708 :
709 44 : if ( use & PUBKEY_USAGE_ENC )
710 18 : buffer[i++] = 'E';
711 :
712 44 : if ( (use & PUBKEY_USAGE_AUTH) )
713 2 : buffer[i++] = 'A';
714 :
715 88 : while (fill && i < 4)
716 0 : buffer[i++] = ' ';
717 :
718 44 : buffer[i] = 0;
719 44 : return buffer;
720 : }
721 :
722 :
723 : const char *
724 428 : colon_strtime (u32 t)
725 : {
726 : static char buf[20];
727 :
728 428 : if (!t)
729 159 : return "";
730 269 : snprintf (buf, sizeof buf, "%lu", (ulong)t);
731 269 : return buf;
732 : }
733 :
734 : const char *
735 212 : colon_datestr_from_pk (PKT_public_key *pk)
736 : {
737 : static char buf[20];
738 :
739 212 : snprintf (buf, sizeof buf, "%lu", (ulong)pk->timestamp);
740 212 : return buf;
741 : }
742 :
743 :
744 : const char *
745 0 : colon_datestr_from_sig (PKT_signature *sig)
746 : {
747 : static char buf[20];
748 :
749 0 : snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp);
750 0 : return buf;
751 : }
752 :
753 : const char *
754 0 : colon_expirestr_from_sig (PKT_signature *sig)
755 : {
756 : static char buf[20];
757 :
758 0 : if (!sig->expiredate)
759 0 : return "";
760 :
761 0 : snprintf (buf, sizeof buf,"%lu", (ulong)sig->expiredate);
762 0 : return buf;
763 : }
764 :
765 :
766 : /*
767 : * Return a byte array with the fingerprint for the given PK/SK
768 : * The length of the array is returned in ret_len. Caller must free
769 : * the array or provide an array of length MAX_FINGERPRINT_LEN.
770 : */
771 : byte *
772 5097 : fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
773 : {
774 : const byte *dp;
775 : size_t len;
776 : gcry_md_hd_t md;
777 :
778 5097 : md = do_fingerprint_md(pk);
779 5097 : dp = gcry_md_read( md, 0 );
780 5097 : len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
781 5097 : log_assert( len <= MAX_FINGERPRINT_LEN );
782 5097 : if (!array)
783 0 : array = xmalloc ( len );
784 5097 : memcpy (array, dp, len );
785 5097 : pk->keyid[0] = buf32_to_u32 (dp+12);
786 5097 : pk->keyid[1] = buf32_to_u32 (dp+16);
787 5097 : gcry_md_close( md);
788 :
789 5097 : if (ret_len)
790 1349 : *ret_len = len;
791 5097 : return array;
792 : }
793 :
794 :
795 : /* Return an allocated buffer with the fingerprint of PK formatted as
796 : a plain hexstring. If BUFFER is NULL the result is a malloc'd
797 : string. If BUFFER is not NULL the result will be copied into this
798 : buffer. In the latter case BUFLEN describes the length of the
799 : buffer; if this is too short the function terminates the process.
800 : Returns a malloc'ed string or BUFFER. A suitable length for BUFFER
801 : is (2*MAX_FINGERPRINT_LEN + 1). */
802 : char *
803 589 : hexfingerprint (PKT_public_key *pk, char *buffer, size_t buflen)
804 : {
805 : unsigned char fpr[MAX_FINGERPRINT_LEN];
806 : size_t len;
807 :
808 589 : fingerprint_from_pk (pk, fpr, &len);
809 589 : if (!buffer)
810 272 : buffer = xmalloc (2 * len + 1);
811 317 : else if (buflen < 2*len+1)
812 0 : log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
813 589 : bin2hex (fpr, len, buffer);
814 589 : return buffer;
815 : }
816 :
817 :
818 : /* Pretty print a hex fingerprint. If BUFFER is NULL the result is a
819 : malloc'd string. If BUFFER is not NULL the result will be copied
820 : into this buffer. In the latter case BUFLEN describes the length
821 : of the buffer; if this is too short the function terminates the
822 : process. Returns a malloc'ed string or BUFFER. A suitable length
823 : for BUFFER is (MAX_FORMATTED_FINGERPRINT_LEN + 1). */
824 : char *
825 132 : format_hexfingerprint (const char *fingerprint, char *buffer, size_t buflen)
826 : {
827 132 : int hexlen = strlen (fingerprint);
828 : int space;
829 : int i, j;
830 :
831 132 : if (hexlen == 40) /* v4 fingerprint */
832 : {
833 132 : space = (/* The characters and the NUL. */
834 : 40 + 1
835 : /* After every fourth character, we add a space (except
836 : the last). */
837 : + 40 / 4 - 1
838 : /* Half way through we add a second space. */
839 : + 1);
840 : }
841 : else /* Other fingerprint versions - print as is. */
842 : {
843 0 : space = hexlen + 1;
844 : }
845 :
846 132 : if (!buffer)
847 108 : buffer = xmalloc (space);
848 24 : else if (buflen < space)
849 0 : log_fatal ("%s: buffer too short (%zu)\n", __func__, buflen);
850 :
851 132 : if (hexlen == 40) /* v4 fingerprint */
852 : {
853 5412 : for (i = 0, j = 0; i < 40; i ++)
854 : {
855 5280 : if (i && i % 4 == 0)
856 1188 : buffer[j ++] = ' ';
857 5280 : if (i == 40 / 2)
858 132 : buffer[j ++] = ' ';
859 :
860 5280 : buffer[j ++] = fingerprint[i];
861 : }
862 132 : buffer[j ++] = 0;
863 132 : log_assert (j == space);
864 : }
865 : else
866 : {
867 0 : strcpy (buffer, fingerprint);
868 : }
869 :
870 132 : return buffer;
871 : }
872 :
873 :
874 :
875 : /* Return the so called KEYGRIP which is the SHA-1 hash of the public
876 : key parameters expressed as an canoncial encoded S-Exp. ARRAY must
877 : be 20 bytes long. Returns 0 on success or an error code. */
878 : gpg_error_t
879 2107 : keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
880 : {
881 : gpg_error_t err;
882 : gcry_sexp_t s_pkey;
883 :
884 2107 : if (DBG_PACKET)
885 0 : log_debug ("get_keygrip for public key\n");
886 :
887 2107 : switch (pk->pubkey_algo)
888 : {
889 : case GCRY_PK_DSA:
890 494 : err = gcry_sexp_build (&s_pkey, NULL,
891 : "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
892 : pk->pkey[0], pk->pkey[1],
893 : pk->pkey[2], pk->pkey[3]);
894 494 : break;
895 :
896 : case GCRY_PK_ELG:
897 : case GCRY_PK_ELG_E:
898 1064 : err = gcry_sexp_build (&s_pkey, NULL,
899 : "(public-key(elg(p%m)(g%m)(y%m)))",
900 : pk->pkey[0], pk->pkey[1], pk->pkey[2]);
901 1064 : break;
902 :
903 : case GCRY_PK_RSA:
904 : case GCRY_PK_RSA_S:
905 : case GCRY_PK_RSA_E:
906 359 : err = gcry_sexp_build (&s_pkey, NULL,
907 : "(public-key(rsa(n%m)(e%m)))",
908 : pk->pkey[0], pk->pkey[1]);
909 359 : break;
910 :
911 : case PUBKEY_ALGO_EDDSA:
912 : case PUBKEY_ALGO_ECDSA:
913 : case PUBKEY_ALGO_ECDH:
914 : {
915 190 : char *curve = openpgp_oid_to_str (pk->pkey[0]);
916 190 : if (!curve)
917 0 : err = gpg_error_from_syserror ();
918 : else
919 : {
920 569 : err = gcry_sexp_build (&s_pkey, NULL,
921 190 : pk->pubkey_algo == PUBKEY_ALGO_EDDSA?
922 189 : "(public-key(ecc(curve%s)(flags eddsa)(q%m)))":
923 189 : (pk->pubkey_algo == PUBKEY_ALGO_ECDH
924 117 : && openpgp_oid_is_cv25519 (pk->pkey[0]))?
925 : "(public-key(ecc(curve%s)(flags djb-tweak)(q%m)))":
926 : "(public-key(ecc(curve%s)(q%m)))",
927 : curve, pk->pkey[1]);
928 190 : xfree (curve);
929 : }
930 : }
931 190 : break;
932 :
933 : default:
934 0 : err = gpg_error (GPG_ERR_PUBKEY_ALGO);
935 0 : break;
936 : }
937 :
938 2107 : if (err)
939 0 : return err;
940 :
941 2107 : if (!gcry_pk_get_keygrip (s_pkey, array))
942 : {
943 0 : log_info ("error computing keygrip\n");
944 0 : memset (array, 0, 20);
945 0 : err = gpg_error (GPG_ERR_GENERAL);
946 : }
947 : else
948 : {
949 2107 : if (DBG_PACKET)
950 0 : log_printhex ("keygrip=", array, 20);
951 : /* FIXME: Save the keygrip in PK. */
952 : }
953 2107 : gcry_sexp_release (s_pkey);
954 :
955 2107 : return err;
956 : }
957 :
958 :
959 : /* Store an allocated buffer with the keygrip of PK encoded as a
960 : hexstring at r_GRIP. Returns 0 on success. */
961 : gpg_error_t
962 1239 : hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
963 : {
964 : gpg_error_t err;
965 : unsigned char grip[20];
966 :
967 1239 : *r_grip = NULL;
968 1239 : err = keygrip_from_pk (pk, grip);
969 1239 : if (!err)
970 : {
971 1239 : char * buf = xtrymalloc (20*2+1);
972 1239 : if (!buf)
973 0 : err = gpg_error_from_syserror ();
974 : else
975 : {
976 1239 : bin2hex (grip, 20, buf);
977 1239 : *r_grip = buf;
978 : }
979 : }
980 1239 : return err;
981 : }
|