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
40 pubkey_letter( int 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' ;
54 do_fingerprint_md( PKT_public_key
*pk
)
58 unsigned int nn
[PUBKEY_MAX_NPKEY
];
59 byte
*pp
[PUBKEY_MAX_NPKEY
];
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
++ ) {
70 if (gcry_mpi_print( GCRYMPI_FMT_PGP
, NULL
, 0, &nbytes
, pk
->pkey
[i
] ))
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
,
81 gcry_md_putc ( md
, 0x99 ); /* ctb */
82 gcry_md_putc ( md
, n
>> 8 ); /* 2 byte length header */
83 gcry_md_putc ( md
, n
);
85 gcry_md_putc ( md
, 3 );
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 ) {
99 a
= (u16
)((pk
->expiredate
- pk
->timestamp
) / 86400L);
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
] );
110 gcry_md_final ( md
);
116 do_fingerprint_md_sk( PKT_secret_key
*sk
)
119 int npkey
= pubkey_get_npkey( sk
->pubkey_algo
); /* npkey is correct! */
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
)
139 if (gcry_mpi_print (GCRYMPI_FMT_USG
, NULL
, 0, &nbytes
, a
))
141 /* fixme: allocate it on the stack */
142 buffer
= xmalloc (nbytes
);
143 if (gcry_mpi_print( GCRYMPI_FMT_USG
, buffer
, nbytes
, NULL
, a
))
145 if (nbytes
< 8) /* oops */
149 memcpy (ki
+0, buffer
+nbytes
-8, 4);
150 memcpy (ki
+1, buffer
+nbytes
-4, 4);
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
)
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;
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] ;
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
)
204 if( pk
->keyid
[0] || pk
->keyid
[1] ) {
205 keyid
[0] = pk
->keyid
[0];
206 keyid
[1] = pk
->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];
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] ;
225 pk
->keyid
[0] = keyid
[0];
226 pk
->keyid
[1] = keyid
[1];
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
)
245 if( fprint_len
!= 20 ) {
246 /* This is special as we have to lookup the key first */
250 memset( &pk
, 0, sizeof pk
);
251 rc
= get_pubkey_byfprint( &pk
, fprint
, fprint_len
);
253 log_error("Oops: keyid_from_fingerprint: no pubkey\n");
258 keyid_from_pk( &pk
, keyid
);
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] ;
271 keyid_from_sig( PKT_signature
*sig
, u32
*keyid
)
274 keyid
[0] = sig
->keyid
[0];
275 keyid
[1] = sig
->keyid
[1];
277 return sig
->keyid
[1];
281 namehash_from_uid(PKT_user_id
*uid
)
283 if(uid
->namehash
==NULL
)
285 uid
->namehash
=xmalloc (20);
288 gcry_md_hash_buffer (GCRY_MD_RMD160
, uid
->namehash
,
289 uid
->attrib_data
,uid
->attrib_len
);
291 gcry_md_hash_buffer (GCRY_MD_RMD160
, uid
->namehash
,
295 return uid
->namehash
;
299 * return the number of bits used in the pk
302 nbits_from_pk( PKT_public_key
*pk
)
304 return pubkey_nbits( pk
->pubkey_algo
, pk
->pkey
);
308 * return the number of bits used in the sk
311 nbits_from_sk( PKT_secret_key
*sk
)
313 return pubkey_nbits( sk
->pubkey_algo
, sk
->skey
);
317 mk_datestr (char *buffer
, time_t atime
)
321 if ( atime
< 0 ) /* 32 bit time_t and after 2038-01-19 */
322 strcpy (buffer
, "????" "-??" "-??"); /* mark this as invalid */
324 tp
= gmtime (&atime
);
325 sprintf (buffer
,"%04d-%02d-%02d",
326 1900+tp
->tm_year
, tp
->tm_mon
+1, tp
->tm_mday
);
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
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
);
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
);
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
);
364 expirestr_from_pk( PKT_public_key
*pk
)
366 static char buffer
[11+5];
369 if( !pk
->expiredate
)
371 atime
= pk
->expiredate
;
372 return mk_datestr (buffer
, atime
);
376 expirestr_from_sk( PKT_secret_key
*sk
)
378 static char buffer
[11+5];
381 if( !sk
->expiredate
)
383 atime
= sk
->expiredate
;
384 return mk_datestr (buffer
, atime
);
388 expirestr_from_sig( PKT_signature
*sig
)
390 static char buffer
[11+5];
395 atime
=sig
->expiredate
;
396 return mk_datestr (buffer
, atime
);
400 colon_strtime (u32 t
)
404 if (opt
.fixed_list_mode
) {
406 sprintf (buf
, "%lu", (ulong
)t
);
409 return strtimestamp(t
);
413 colon_datestr_from_pk (PKT_public_key
*pk
)
415 if (opt
.fixed_list_mode
) {
417 sprintf (buf
, "%lu", (ulong
)pk
->timestamp
);
420 return datestr_from_pk (pk
);
424 colon_datestr_from_sk (PKT_secret_key
*sk
)
426 if (opt
.fixed_list_mode
) {
428 sprintf (buf
, "%lu", (ulong
)sk
->timestamp
);
431 return datestr_from_sk (sk
);
435 colon_datestr_from_sig (PKT_signature
*sig
)
437 if (opt
.fixed_list_mode
) {
439 sprintf (buf
, "%lu", (ulong
)sig
->timestamp
);
442 return datestr_from_sig (sig
);
446 colon_expirestr_from_sig (PKT_signature
*sig
)
450 if (opt
.fixed_list_mode
) {
452 sprintf (buf
, "%lu", (ulong
)sig
->expiredate
);
455 return expirestr_from_sig (sig
);
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.
466 fingerprint_from_pk( PKT_public_key
*pk
, byte
*array
, size_t *ret_len
)
472 if( pk
->version
< 4 && is_RSA(pk
->pubkey_algo
) ) {
473 /* RSA in version 3 packets is special */
476 gcry_md_open (&md
, DIGEST_ALGO_MD5
, 0);
477 if( pubkey_get_npkey( pk
->pubkey_algo
) > 1 ) {
480 if (gcry_mpi_print( GCRYMPI_FMT_USG
, NULL
, 0, &nbytes
,
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]))
487 gcry_md_write (md
, buf
, nbytes
);
489 if (gcry_mpi_print( GCRYMPI_FMT_USG
, NULL
, 0, &nbytes
, pk
->pkey
[1]))
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]))
495 gcry_md_write( md
, buf
, nbytes
);
500 array
= xmalloc ( 16 );
502 memcpy(array
, gcry_md_read (md
, DIGEST_ALGO_MD5
), 16 );
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
);
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] ;
524 fingerprint_from_sk( PKT_secret_key
*sk
, byte
*array
, size_t *ret_len
)
530 if( sk
->version
< 4 && is_RSA(sk
->pubkey_algo
) ) {
531 /* RSA in version 3 packets is special */
534 gcry_md_open (&md
, DIGEST_ALGO_MD5
, 0);
535 if( pubkey_get_npkey( sk
->pubkey_algo
) > 1 ) {
538 if (gcry_mpi_print( GCRYMPI_FMT_USG
, NULL
, 0, &nbytes
, sk
->skey
[0]))
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]))
544 gcry_md_write (md
, buf
, nbytes
);
546 if (gcry_mpi_print( GCRYMPI_FMT_USG
, NULL
, 0, &nbytes
, sk
->skey
[1]))
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]))
552 gcry_md_write( md
, buf
, nbytes
);
557 array
= xmalloc ( 16 );
559 memcpy(array
, gcry_md_read (md
, DIGEST_ALGO_MD5
), 16 );
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
);
570 array
= xmalloc ( len
);
571 memcpy(array
, dp
, len
);
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
584 serialno_and_fpr_from_sk (const unsigned char *sn
, size_t snlen
,
587 unsigned char fpr
[MAX_FINGERPRINT_LEN
];
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
]);
597 for (i
=0; i
< fprlen
; i
++, p
+=2)
598 sprintf (p
, "%02X", fpr
[i
]);