See ChangeLog: Fri Jul 14 19:38:23 CEST 2000 Werner Koch
[gnupg.git] / g10 / keyid.c
1 /* keyid.c - jeyid and fingerprint handling
2  *      Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
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.
10  *
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.
15  *
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
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 <gcrypt.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
37
38 int
39 pubkey_letter( int algo )
40 {
41     switch( algo ) {
42       case GCRY_PK_RSA: return 'R' ;
43       case GCRY_PK_RSA_E:       return 'r' ;
44       case GCRY_PK_RSA_S:       return 's' ;
45       case GCRY_PK_ELG_E: return 'g';
46       case GCRY_PK_ELG: return 'G' ;
47       case GCRY_PK_DSA: return 'D' ;
48       default: return '?';
49     }
50 }
51
52
53 static GCRY_MD_HD
54 do_fingerprint_md( PKT_public_key *pk )
55 {
56     GCRY_MD_HD md;
57     unsigned int n;
58     unsigned int nn[GNUPG_MAX_NPKEY];
59     byte *pp[GNUPG_MAX_NPKEY];
60     int i;
61     int npkey = pubkey_get_npkey( pk->pubkey_algo );
62
63     md = gcry_md_open( pk->version < 4 ? GCRY_MD_RMD160 : GCRY_MD_SHA1, 0);
64     if( !md )
65         BUG();
66     n = pk->version < 4 ? 8 : 6;
67     for(i=0; i < npkey; i++ ) {
68         int rc;
69         size_t nbytes;
70
71         rc = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, &nbytes, pk->pkey[i] );
72         assert( !rc );
73         /* fixme: we should try to allocate a buffer on the stack */
74         pp[i] = gcry_xmalloc(nbytes);
75         rc = gcry_mpi_print( GCRYMPI_FMT_PGP, pp[i], &nbytes, pk->pkey[i] );
76         assert( !rc );
77         nn[i] = nbytes;
78         n += nn[i];
79     }
80
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 );
88
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       );
94     }
95     if( pk->version < 4 ) {
96         u16 a;
97
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      );
104     }
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         gcry_free(pp[i]);
109     }
110     gcry_md_final( md );
111
112     return md;
113 }
114
115 static GCRY_MD_HD
116 do_fingerprint_md_sk( PKT_secret_key *sk )
117 {
118     PKT_public_key pk;
119     int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */
120     int i;
121
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 );
130 }
131
132
133 static void
134 v3_keyid( MPI a, u32 *ki )
135 {
136     int rc;
137     byte *buffer;
138     size_t nbytes;
139
140     rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, a );
141     assert( !rc );
142     /* fixme: allocate it on the stack */
143     buffer = gcry_xmalloc(nbytes);
144     rc = gcry_mpi_print( GCRYMPI_FMT_USG, buffer, &nbytes, a );
145     assert( !rc );
146     if( nbytes < 8 ) { /* oops */
147         ki[0] = ki[1] = 0;
148     }
149     else  {
150         memcpy( ki+0, buffer+nbytes-8, 4);
151         memcpy( ki+1, buffer+nbytes-4, 4);
152     }
153     gcry_free( buffer );
154 }
155
156
157 /****************
158  * Get the keyid from the secret key and put it into keyid
159  * if this is not NULL. Return the 32 low bits of the keyid.
160  */
161 u32
162 keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
163 {
164     u32 dummy_keyid[2];
165
166     if( !keyid )
167         keyid = dummy_keyid;
168
169     if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
170         if( pubkey_get_npkey(sk->pubkey_algo) )
171             v3_keyid( sk->skey[0], keyid ); /* take n */
172         else
173             keyid[0] = keyid[1] = 0;
174     }
175     else {
176         const byte *dp;
177         GCRY_MD_HD md;
178         md = do_fingerprint_md_sk(sk);
179         dp = gcry_md_read( md, 0 );
180         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
181         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
182         gcry_md_close(md);
183     }
184
185     return keyid[1];
186 }
187
188
189 /****************
190  * Get the keyid from the public key and put it into keyid
191  * if this is not NULL. Return the 32 low bits of the keyid.
192  */
193 u32
194 keyid_from_pk( PKT_public_key *pk, u32 *keyid )
195 {
196     u32 dummy_keyid[2];
197
198     if( !keyid )
199         keyid = dummy_keyid;
200
201     if( pk->keyid[0] || pk->keyid[1] ) {
202         keyid[0] = pk->keyid[0];
203         keyid[1] = pk->keyid[1];
204     }
205     else if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
206         if( pubkey_get_npkey(pk->pubkey_algo) )
207             v3_keyid( pk->pkey[0], keyid ); /* from n */
208         else
209             keyid[0] = keyid[1] = 0;
210         pk->keyid[0] = keyid[0];
211         pk->keyid[1] = keyid[1];
212     }
213     else {
214         const byte *dp;
215         GCRY_MD_HD md;
216         md = do_fingerprint_md(pk);
217         dp = gcry_md_read( md, 0 );
218         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
219         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
220         gcry_md_close(md);
221         pk->keyid[0] = keyid[0];
222         pk->keyid[1] = keyid[1];
223     }
224
225     return keyid[1];
226 }
227
228
229 /****************
230  * Get the keyid from the fingerprint.  This function is simple for most
231  * keys, but has to do a keylookup for old stayle keys.
232  */
233 u32
234 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
235 {
236     u32 dummy_keyid[2];
237
238     if( !keyid )
239         keyid = dummy_keyid;
240
241     if( fprint_len != 20 ) {
242         /* This is special as we have to lookup the key first */
243         PKT_public_key pk;
244         int rc;
245
246         memset( &pk, 0, sizeof pk );
247         rc = get_pubkey_byfprint( &pk, fprint, fprint_len );
248         if( rc ) {
249             log_error("Oops: keyid_from_fingerprint: no pubkey\n");
250             keyid[0] = 0;
251             keyid[1] = 0;
252         }
253         else
254             keyid_from_pk( &pk, keyid );
255     }
256     else {
257         const byte *dp = fprint;
258         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
259         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
260     }
261
262     return keyid[1];
263 }
264
265
266 u32
267 keyid_from_sig( PKT_signature *sig, u32 *keyid )
268 {
269     if( keyid ) {
270         keyid[0] = sig->keyid[0];
271         keyid[1] = sig->keyid[1];
272     }
273     return sig->keyid[1];
274 }
275
276 /****************
277  * return the number of bits used in the pk
278  */
279 unsigned
280 nbits_from_pk( PKT_public_key *pk )
281 {
282     return pubkey_nbits( pk->pubkey_algo, pk->pkey );
283 }
284
285 /****************
286  * return the number of bits used in the sk
287  */
288 unsigned
289 nbits_from_sk( PKT_secret_key *sk )
290 {
291     return pubkey_nbits( sk->pubkey_algo, sk->skey );
292 }
293
294 /****************
295  * return a string with the creation date of the pk
296  * Note: this is alloced in a static buffer.
297  *    Format is: yyyy-mm-dd
298  */
299 const char *
300 datestr_from_pk( PKT_public_key *pk )
301 {
302     static char buffer[11+5];
303     struct tm *tp;
304     time_t atime = pk->timestamp;
305
306     tp = gmtime( &atime );
307     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
308     return buffer;
309 }
310
311 const char *
312 datestr_from_sk( PKT_secret_key *sk )
313 {
314     static char buffer[11+5];
315     struct tm *tp;
316     time_t atime = sk->timestamp;
317
318     tp = gmtime( &atime );
319     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
320     return buffer;
321 }
322
323 const char *
324 datestr_from_sig( PKT_signature *sig )
325 {
326     static char buffer[11+5];
327     struct tm *tp;
328     time_t atime = sig->timestamp;
329
330     tp = gmtime( &atime );
331     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
332     return buffer;
333 }
334
335
336 const char *
337 expirestr_from_pk( PKT_public_key *pk )
338 {
339     static char buffer[11+5];
340     struct tm *tp;
341     time_t atime;
342
343     if( !pk->expiredate )
344         return _("never     ");
345     atime = pk->expiredate;
346     tp = gmtime( &atime );
347     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
348     return buffer;
349 }
350
351 const char *
352 expirestr_from_sk( PKT_secret_key *sk )
353 {
354     static char buffer[11+5];
355     struct tm *tp;
356     time_t atime;
357
358     if( !sk->expiredate )
359         return _("never     ");
360     atime = sk->expiredate;
361     tp = gmtime( &atime );
362     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
363     return buffer;
364 }
365
366
367 /**************** .
368  * Return a byte array with the fingerprint for the given PK/SK
369  * The length of the array is returned in ret_len. Caller must free
370  * the array or provide an array of length MAX_FINGERPRINT_LEN.
371  */
372
373 byte *
374 fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
375 {
376     byte *buf;
377     const char *dp;
378     size_t len;
379
380     if( pk->version < 4 && is_RSA(pk->pubkey_algo) ) {
381         /* RSA in version 3 packets is special */
382         GCRY_MD_HD md;
383
384         md = gcry_md_open( GCRY_MD_MD5, 0);
385         if( !md )
386             BUG();
387         if( pubkey_get_npkey( pk->pubkey_algo ) > 1 ) {
388             int rc;
389             size_t nbytes;
390
391             rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, pk->pkey[0] );
392             assert( !rc );
393             /* fixme: allocate it on the stack */
394             buf = gcry_xmalloc(nbytes);
395             rc = gcry_mpi_print( GCRYMPI_FMT_USG, buf, &nbytes, pk->pkey[0] );
396             assert( !rc );
397             gcry_md_write( md, buf, nbytes );
398             gcry_free(buf);
399             rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, pk->pkey[1] );
400             assert( !rc );
401             /* fixme: allocate it on the stack */
402             buf = gcry_xmalloc(nbytes);
403             rc = gcry_mpi_print( GCRYMPI_FMT_USG, buf, &nbytes, pk->pkey[1] );
404             assert( !rc );
405             gcry_md_write( md, buf, nbytes );
406             gcry_free(buf);
407         }
408         gcry_md_final(md);
409         if( !array )
410             array = gcry_xmalloc( 16 );
411         len = 16;
412         memcpy(array, gcry_md_read(md, GCRY_MD_MD5), 16 );
413         gcry_md_close(md);
414     }
415     else {
416         GCRY_MD_HD md;
417         md = do_fingerprint_md(pk);
418         dp = gcry_md_read( md, 0 );
419         len = gcry_md_get_algo_dlen( gcry_md_get_algo( md ) );
420         assert( len <= MAX_FINGERPRINT_LEN );
421         if( !array )
422             array = gcry_xmalloc( len );
423         memcpy(array, dp, len );
424         gcry_md_close(md);
425     }
426
427     *ret_len = len;
428     return array;
429 }
430
431 byte *
432 fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
433 {
434     byte *buf;
435     const char *dp;
436     size_t len;
437
438     if( sk->version < 4 && is_RSA(sk->pubkey_algo) ) {
439         /* RSA in version 3 packets is special */
440         GCRY_MD_HD md;
441
442         md = gcry_md_open( GCRY_MD_MD5, 0);
443         if( !md )
444             BUG();
445         if( pubkey_get_npkey( sk->pubkey_algo ) > 1 ) {
446             int rc;
447             size_t nbytes;
448
449             #warning Why is the hash sequence for secret keys different
450             rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, sk->skey[1] );
451             assert( !rc );
452             /* fixme: allocate it on the stack */
453             buf = gcry_xmalloc(nbytes);
454             rc = gcry_mpi_print( GCRYMPI_FMT_USG, buf, &nbytes, sk->skey[1] );
455             assert( !rc );
456             gcry_md_write( md, buf, nbytes );
457             gcry_free(buf);
458             rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, sk->skey[0] );
459             assert( !rc );
460             /* fixme: allocate it on the stack */
461             buf = gcry_xmalloc(nbytes);
462             rc = gcry_mpi_print( GCRYMPI_FMT_USG, buf, &nbytes, sk->skey[0] );
463             assert( !rc );
464             gcry_md_write( md, buf, nbytes );
465             gcry_free(buf);
466         }
467         gcry_md_final(md);
468         if( !array )
469             array = gcry_xmalloc( 16 );
470         len = 16;
471         memcpy(array, gcry_md_read(md, GCRY_MD_MD5), 16 );
472         gcry_md_close(md);
473     }
474     else {
475         GCRY_MD_HD md;
476         md = do_fingerprint_md_sk(sk);
477         dp = gcry_md_read( md, 0 );
478         len = gcry_md_get_algo_dlen( gcry_md_get_algo( md ) );
479         assert( len <= MAX_FINGERPRINT_LEN );
480         if( !array )
481             array = gcry_xmalloc( len );
482         memcpy(array, dp, len );
483         gcry_md_close(md);
484     }
485
486     *ret_len = len;
487     return array;
488 }
489
490
491