2005-04-15 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / g10 / keyid.c
blobaaa70cccb1f71ab63a4f1c069deb884cfacdd230
1 /* keyid.c - key ID and fingerprint handling
2 * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
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>
29 #include "gpg.h"
30 #include "util.h"
31 #include "main.h"
32 #include "packet.h"
33 #include "options.h"
34 #include "mpi.h"
35 #include "keydb.h"
36 #include "i18n.h"
39 int
40 pubkey_letter( int algo )
42 switch( algo ) {
43 case PUBKEY_ALGO_RSA: return 'R' ;
44 case PUBKEY_ALGO_RSA_E: return 'r' ;
45 case PUBKEY_ALGO_RSA_S: return 's' ;
46 case PUBKEY_ALGO_ELGAMAL_E: return 'g';
47 case PUBKEY_ALGO_ELGAMAL: return 'G' ;
48 case PUBKEY_ALGO_DSA: return 'D' ;
49 default: return '?';
53 static gcry_md_hd_t
54 do_fingerprint_md( PKT_public_key *pk )
56 gcry_md_hd_t md;
57 unsigned int n;
58 unsigned int nn[PUBKEY_MAX_NPKEY];
59 byte *pp[PUBKEY_MAX_NPKEY];
60 int i;
61 int npkey = pubkey_get_npkey( pk->pubkey_algo );
63 gcry_md_open (&md, pk->version < 4 ? DIGEST_ALGO_RMD160
64 : DIGEST_ALGO_SHA1, 0);
66 n = pk->version < 4 ? 8 : 6;
67 for(i=0; i < npkey; i++ ) {
68 size_t nbytes;
70 if (gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i] ))
71 BUG ();
72 /* fixme: we should try to allocate a buffer on the stack */
73 pp[i] = xmalloc(nbytes);
74 if (gcry_mpi_print ( GCRYMPI_FMT_PGP, pp[i], nbytes, &nbytes,
75 pk->pkey[i] ))
76 BUG ();
77 nn[i] = nbytes;
78 n += nn[i];
81 gcry_md_putc ( md, 0x99 ); /* ctb */
82 gcry_md_putc ( md, n >> 8 ); /* 2 byte length header */
83 gcry_md_putc ( md, n );
84 if( pk->version < 4 )
85 gcry_md_putc ( md, 3 );
86 else
87 gcry_md_putc ( md, 4 );
89 { u32 a = pk->timestamp;
90 gcry_md_putc ( md, a >> 24 );
91 gcry_md_putc ( md, a >> 16 );
92 gcry_md_putc ( md, a >> 8 );
93 gcry_md_putc ( md, a );
95 if( pk->version < 4 ) {
96 u16 a;
98 if( pk->expiredate )
99 a = (u16)((pk->expiredate - pk->timestamp) / 86400L);
100 else
101 a = 0;
102 gcry_md_putc ( md, a >> 8 );
103 gcry_md_putc ( md, a );
105 gcry_md_putc ( md, pk->pubkey_algo );
106 for(i=0; i < npkey; i++ ) {
107 gcry_md_write( md, pp[i], nn[i] );
108 xfree (pp[i]);
110 gcry_md_final ( md );
112 return md;
115 static gcry_md_hd_t
116 do_fingerprint_md_sk( PKT_secret_key *sk )
118 PKT_public_key pk;
119 int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */
120 int i;
122 pk.pubkey_algo = sk->pubkey_algo;
123 pk.version = sk->version;
124 pk.timestamp = sk->timestamp;
125 pk.expiredate = sk->expiredate;
126 pk.pubkey_algo = sk->pubkey_algo;
127 for( i=0; i < npkey; i++ )
128 pk.pkey[i] = sk->skey[i];
129 return do_fingerprint_md( &pk );
134 v3_keyid (gcry_mpi_t a, u32 *ki)
136 byte *buffer;
137 size_t nbytes;
139 if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nbytes, a ))
140 BUG ();
141 /* fixme: allocate it on the stack */
142 buffer = xmalloc (nbytes);
143 if (gcry_mpi_print( GCRYMPI_FMT_USG, buffer, nbytes, NULL, a ))
144 BUG ();
145 if (nbytes < 8) /* oops */
146 ki[0] = ki[1] = 0;
147 else
149 memcpy (ki+0, buffer+nbytes-8, 4);
150 memcpy (ki+1, buffer+nbytes-4, 4);
152 xfree (buffer);
153 return ki[1];
158 /****************
159 * Get the keyid from the secret key and put it into keyid
160 * if this is not NULL. Return the 32 low bits of the keyid.
163 keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
165 u32 lowbits;
166 u32 dummy_keyid[2];
168 if( !keyid )
169 keyid = dummy_keyid;
171 if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
172 keyid[0] = keyid[1] = 0;
173 lowbits = pubkey_get_npkey(sk->pubkey_algo) ?
174 v3_keyid (sk->skey[0], keyid) : 0;
176 else {
177 const byte *dp;
178 gcry_md_hd_t md;
179 md = do_fingerprint_md_sk(sk);
180 dp = gcry_md_read ( md, 0 );
181 keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
182 keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
183 lowbits = keyid[1];
184 gcry_md_close (md);
187 return lowbits;
191 /****************
192 * Get the keyid from the public key and put it into keyid
193 * if this is not NULL. Return the 32 low bits of the keyid.
196 keyid_from_pk( PKT_public_key *pk, u32 *keyid )
198 u32 lowbits;
199 u32 dummy_keyid[2];
201 if( !keyid )
202 keyid = dummy_keyid;
204 if( pk->keyid[0] || pk->keyid[1] ) {
205 keyid[0] = pk->keyid[0];
206 keyid[1] = pk->keyid[1];
207 lowbits = keyid[1];
209 else if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
210 keyid[0] = keyid[1] = 0;
211 lowbits = pubkey_get_npkey(pk->pubkey_algo) ?
212 v3_keyid (pk->pkey[0], keyid) : 0 ;
213 pk->keyid[0] = keyid[0];
214 pk->keyid[1] = keyid[1];
216 else {
217 const byte *dp;
218 gcry_md_hd_t md;
219 md = do_fingerprint_md(pk);
220 dp = gcry_md_read ( md, 0 );
221 keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
222 keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
223 lowbits = keyid[1];
224 gcry_md_close (md);
225 pk->keyid[0] = keyid[0];
226 pk->keyid[1] = keyid[1];
229 return lowbits;
233 /****************
234 * Get the keyid from the fingerprint. This function is simple for most
235 * keys, but has to do a keylookup for old stayle keys.
238 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
240 u32 dummy_keyid[2];
242 if( !keyid )
243 keyid = dummy_keyid;
245 if( fprint_len != 20 ) {
246 /* This is special as we have to lookup the key first */
247 PKT_public_key pk;
248 int rc;
250 memset( &pk, 0, sizeof pk );
251 rc = get_pubkey_byfprint( &pk, fprint, fprint_len );
252 if( rc ) {
253 log_error("Oops: keyid_from_fingerprint: no pubkey\n");
254 keyid[0] = 0;
255 keyid[1] = 0;
257 else
258 keyid_from_pk( &pk, keyid );
260 else {
261 const byte *dp = fprint;
262 keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
263 keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
266 return keyid[1];
271 keyid_from_sig( PKT_signature *sig, u32 *keyid )
273 if( keyid ) {
274 keyid[0] = sig->keyid[0];
275 keyid[1] = sig->keyid[1];
277 return sig->keyid[1];
280 byte *
281 namehash_from_uid(PKT_user_id *uid)
283 if(uid->namehash==NULL)
285 uid->namehash=xmalloc (20);
287 if(uid->attrib_data)
288 gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash,
289 uid->attrib_data,uid->attrib_len);
290 else
291 gcry_md_hash_buffer (GCRY_MD_RMD160, uid->namehash,
292 uid->name,uid->len);
295 return uid->namehash;
298 /****************
299 * return the number of bits used in the pk
301 unsigned
302 nbits_from_pk( PKT_public_key *pk )
304 return pubkey_nbits( pk->pubkey_algo, pk->pkey );
307 /****************
308 * return the number of bits used in the sk
310 unsigned
311 nbits_from_sk( PKT_secret_key *sk )
313 return pubkey_nbits( sk->pubkey_algo, sk->skey );
316 static const char *
317 mk_datestr (char *buffer, time_t atime)
319 struct tm *tp;
321 if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
322 strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
323 else {
324 tp = gmtime (&atime);
325 sprintf (buffer,"%04d-%02d-%02d",
326 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
328 return buffer;
331 /****************
332 * return a string with the creation date of the pk
333 * Note: this is alloced in a static buffer.
334 * Format is: yyyy-mm-dd
336 const char *
337 datestr_from_pk( PKT_public_key *pk )
339 static char buffer[11+5];
340 time_t atime = pk->timestamp;
342 return mk_datestr (buffer, atime);
345 const char *
346 datestr_from_sk( PKT_secret_key *sk )
348 static char buffer[11+5];
349 time_t atime = sk->timestamp;
351 return mk_datestr (buffer, atime);
354 const char *
355 datestr_from_sig( PKT_signature *sig )
357 static char buffer[11+5];
358 time_t atime = sig->timestamp;
360 return mk_datestr (buffer, atime);
363 const char *
364 expirestr_from_pk( PKT_public_key *pk )
366 static char buffer[11+5];
367 time_t atime;
369 if( !pk->expiredate )
370 return _("never ");
371 atime = pk->expiredate;
372 return mk_datestr (buffer, atime);
375 const char *
376 expirestr_from_sk( PKT_secret_key *sk )
378 static char buffer[11+5];
379 time_t atime;
381 if( !sk->expiredate )
382 return _("never ");
383 atime = sk->expiredate;
384 return mk_datestr (buffer, atime);
387 const char *
388 expirestr_from_sig( PKT_signature *sig )
390 static char buffer[11+5];
391 time_t atime;
393 if(!sig->expiredate)
394 return _("never ");
395 atime=sig->expiredate;
396 return mk_datestr (buffer, atime);
399 const char *
400 colon_strtime (u32 t)
402 if (!t)
403 return "";
404 if (opt.fixed_list_mode) {
405 static char buf[15];
406 sprintf (buf, "%lu", (ulong)t);
407 return buf;
409 return strtimestamp(t);
412 const char *
413 colon_datestr_from_pk (PKT_public_key *pk)
415 if (opt.fixed_list_mode) {
416 static char buf[15];
417 sprintf (buf, "%lu", (ulong)pk->timestamp);
418 return buf;
420 return datestr_from_pk (pk);
423 const char *
424 colon_datestr_from_sk (PKT_secret_key *sk)
426 if (opt.fixed_list_mode) {
427 static char buf[15];
428 sprintf (buf, "%lu", (ulong)sk->timestamp);
429 return buf;
431 return datestr_from_sk (sk);
434 const char *
435 colon_datestr_from_sig (PKT_signature *sig)
437 if (opt.fixed_list_mode) {
438 static char buf[15];
439 sprintf (buf, "%lu", (ulong)sig->timestamp);
440 return buf;
442 return datestr_from_sig (sig);
445 const char *
446 colon_expirestr_from_sig (PKT_signature *sig)
448 if(!sig->expiredate)
449 return "";
450 if (opt.fixed_list_mode) {
451 static char buf[15];
452 sprintf (buf, "%lu", (ulong)sig->expiredate);
453 return buf;
455 return expirestr_from_sig (sig);
459 /**************** .
460 * Return a byte array with the fingerprint for the given PK/SK
461 * The length of the array is returned in ret_len. Caller must free
462 * the array or provide an array of length MAX_FINGERPRINT_LEN.
465 byte *
466 fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
468 byte *buf;
469 const byte *dp;
470 size_t len;
472 if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
473 /* RSA in version 3 packets is special */
474 gcry_md_hd_t md;
476 gcry_md_open (&md, DIGEST_ALGO_MD5, 0);
477 if( pubkey_get_npkey( pk->pubkey_algo ) > 1 ) {
478 size_t nbytes;
480 if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes,
481 pk->pkey[0]))
482 BUG ();
483 /* fixme: allocate it on the stack */
484 buf = xmalloc(nbytes);
485 if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[0]))
486 BUG ();
487 gcry_md_write (md, buf, nbytes);
488 xfree (buf);
489 if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, pk->pkey[1]))
490 BUG ();
491 /* fixme: allocate it on the stack */
492 buf = xmalloc(nbytes);
493 if (gcry_mpi_print( GCRYMPI_FMT_USG, buf, nbytes, NULL,pk->pkey[1]))
494 BUG ();
495 gcry_md_write( md, buf, nbytes );
496 xfree(buf);
498 gcry_md_final (md);
499 if( !array )
500 array = xmalloc ( 16 );
501 len = 16;
502 memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 );
503 gcry_md_close (md);
505 else {
506 gcry_md_hd_t md;
507 md = do_fingerprint_md(pk);
508 dp = gcry_md_read ( md, 0 );
509 len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
510 assert( len <= MAX_FINGERPRINT_LEN );
511 if( !array )
512 array = xmalloc ( len );
513 memcpy(array, dp, len );
514 pk->keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
515 pk->keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
516 gcry_md_close (md);
519 *ret_len = len;
520 return array;
523 byte *
524 fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
526 byte *buf;
527 const char *dp;
528 size_t len;
530 if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
531 /* RSA in version 3 packets is special */
532 gcry_md_hd_t md;
534 gcry_md_open (&md, DIGEST_ALGO_MD5, 0);
535 if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) {
536 size_t nbytes;
538 if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[0]))
539 BUG ();
540 /* fixme: allocate it on the stack */
541 buf = xmalloc(nbytes);
542 if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes, NULL,sk->skey[0]))
543 BUG ();
544 gcry_md_write (md, buf, nbytes);
545 xfree (buf);
546 if (gcry_mpi_print( GCRYMPI_FMT_USG, NULL, 0, &nbytes, sk->skey[1]))
547 BUG ();
548 /* fixme: allocate it on the stack */
549 buf = xmalloc(nbytes);
550 if (gcry_mpi_print( GCRYMPI_FMT_USG, buf,nbytes, NULL, sk->skey[1]))
551 BUG ();
552 gcry_md_write( md, buf, nbytes );
553 xfree(buf);
555 gcry_md_final (md);
556 if( !array )
557 array = xmalloc ( 16 );
558 len = 16;
559 memcpy(array, gcry_md_read (md, DIGEST_ALGO_MD5), 16 );
560 gcry_md_close (md);
562 else {
563 gcry_md_hd_t md;
565 md = do_fingerprint_md_sk(sk);
566 dp = gcry_md_read ( md, 0 );
567 len = gcry_md_get_algo_dlen (gcry_md_get_algo (md));
568 assert( len <= MAX_FINGERPRINT_LEN );
569 if( !array )
570 array = xmalloc ( len );
571 memcpy(array, dp, len );
572 gcry_md_close (md);
575 *ret_len = len;
576 return array;
580 /* Create a serialno/fpr string from the serial number and the secret
581 * key. caller must free the returned string. There is no error
582 * return. */
583 char *
584 serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
585 PKT_secret_key *sk)
587 unsigned char fpr[MAX_FINGERPRINT_LEN];
588 size_t fprlen;
589 char *buffer, *p;
590 int i;
592 fingerprint_from_sk (sk, fpr, &fprlen);
593 buffer = p= xmalloc (snlen*2 + 1 + fprlen*2 + 1);
594 for (i=0; i < snlen; i++, p+=2)
595 sprintf (p, "%02X", sn[i]);
596 *p++ = '/';
597 for (i=0; i < fprlen; i++, p+=2)
598 sprintf (p, "%02X", fpr[i]);
599 *p = 0;
600 return buffer;