partial DSA support
[gnupg.git] / g10 / keyid.c
1 /* keyid.c - jeyid and fingerprint handling
2  *      Copyright (C) 1998 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 #include "util.h"
29 #include "main.h"
30 #include "packet.h"
31 #include "options.h"
32 #include "mpi.h"
33 #include "keydb.h"
34
35
36 int
37 pubkey_letter( int algo )
38 {
39     switch( algo ) {
40       case PUBKEY_ALGO_RSA:     return 'R' ;
41       case PUBKEY_ALGO_RSA_E:   return 'r' ;
42       case PUBKEY_ALGO_RSA_S:   return 's' ;
43       case PUBKEY_ALGO_ELGAMAL: return 'G' ;
44       case PUBKEY_ALGO_DSA:     return 'D' ;
45       default: return '?';
46     }
47 }
48
49 /* this is special code for V3 which uses ElGamal and
50  * calculates a fingerprint like V4, but with rmd160
51  * and a version byte of 3. Returns an md handle, caller must
52  * do md_close()
53  */
54
55 static MD_HANDLE
56 v3_elg_fingerprint_md( PKT_public_cert *pkc )
57 {
58     MD_HANDLE md;
59     byte *buf1, *buf2, *buf3;
60     byte *p1, *p2, *p3;
61     unsigned n1, n2, n3;
62     unsigned nb1, nb2, nb3;
63     unsigned n;
64
65     nb1 = mpi_get_nbits(pkc->d.elg.p);
66     p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
67     for( ; !*p1 && n1; p1++, n1-- )  /* skip leading null bytes */
68         ;
69     nb2 = mpi_get_nbits(pkc->d.elg.g);
70     p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
71     for( ; !*p2 && n2; p2++, n2-- )  /* skip leading null bytes */
72         ;
73     nb3 = mpi_get_nbits(pkc->d.elg.y);
74     p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
75     for( ; !*p3 && n3; p3++, n3-- )  /* skip leading null bytes */
76         ;
77
78     /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
79     n = 14 + n1 + n2 + n3;
80     md = md_open( DIGEST_ALGO_RMD160, 0);
81
82     md_putc( md, 0x99 );     /* ctb */
83     md_putc( md, n >> 8 );   /* 2 byte length header */
84     md_putc( md, n );
85     md_putc( md, 3 );        /* version */
86     {   u32 a = pkc->timestamp;
87         md_putc( md, a >> 24 );
88         md_putc( md, a >> 16 );
89         md_putc( md, a >>  8 );
90         md_putc( md, a       );
91     }
92     {   u16 a = pkc->valid_days;
93         md_putc( md, a >> 8 );
94         md_putc( md, a      );
95     }
96     md_putc( md, pkc->pubkey_algo );
97     md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 );
98     md_putc( md, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 );
99     md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 );
100     m_free(buf1);
101     m_free(buf2);
102     m_free(buf3);
103     md_final( md );
104
105     return md;
106 }
107
108 static MD_HANDLE
109 dsa_fingerprint_md( PKT_public_cert *pkc )
110 {
111     MD_HANDLE md;
112     byte *buf1, *buf2, *buf3, *buf4 ;
113     byte *p1, *p2, *p3, *p4;
114     unsigned n1, n2, n3, n4;
115     unsigned nb1, nb2, nb3, nb4;
116     unsigned n;
117
118     nb1 = mpi_get_nbits(pkc->d.dsa.p);
119     p1 = buf1 = mpi_get_buffer( pkc->d.dsa.p, &n1, NULL );
120     for( ; !*p1 && n1; p1++, n1-- )  /* skip leading null bytes */
121         ;
122     nb2 = mpi_get_nbits(pkc->d.dsa.q);
123     p2 = buf2 = mpi_get_buffer( pkc->d.dsa.q, &n2, NULL );
124     for( ; !*p2 && n2; p2++, n2-- )
125         ;
126     nb3 = mpi_get_nbits(pkc->d.dsa.g);
127     p3 = buf3 = mpi_get_buffer( pkc->d.dsa.g, &n3, NULL );
128     for( ; !*p3 && n3; p3++, n3-- )
129         ;
130     nb4 = mpi_get_nbits(pkc->d.dsa.y);
131     p4 = buf4 = mpi_get_buffer( pkc->d.dsa.y, &n4, NULL );
132     for( ; !*p4 && n4; p4++, n4-- )
133         ;
134
135     /* calculate length of packet */
136     n = 14 + n1 + n2 + n3 +n4 ;
137     md = md_open( DIGEST_ALGO_SHA1, 0);
138
139     md_putc( md, 0x99 );     /* ctb */
140     md_putc( md, n >> 8 );   /* 2 byte length header */
141     md_putc( md, n );
142     md_putc( md, 4 );        /* version */
143     {   u32 a = pkc->timestamp;
144         md_putc( md, a >> 24 );
145         md_putc( md, a >> 16 );
146         md_putc( md, a >>  8 );
147         md_putc( md, a       );
148     }
149     md_putc( md, pkc->pubkey_algo );
150     md_putc( md, nb1>>8); md_putc( md, nb1 ); md_write( md, p1, n1 );
151     md_putc( md, nb2>>8); md_putc( md, nb2 ); md_write( md, p2, n2 );
152     md_putc( md, nb3>>8); md_putc( md, nb3 ); md_write( md, p3, n3 );
153     md_putc( md, nb4>>8); md_putc( md, nb4 ); md_write( md, p4, n4 );
154     m_free(buf1);
155     m_free(buf2);
156     m_free(buf3);
157     m_free(buf4);
158     md_final( md );
159
160     return md;
161 }
162
163 static MD_HANDLE
164 v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
165 {
166     PKT_public_cert pkc;
167
168     pkc.pubkey_algo = skc->pubkey_algo;
169     pkc.timestamp = skc->timestamp;
170     pkc.valid_days = skc->valid_days;
171     pkc.pubkey_algo = skc->pubkey_algo;
172     pkc.d.elg.p = skc->d.elg.p;
173     pkc.d.elg.g = skc->d.elg.g;
174     pkc.d.elg.y = skc->d.elg.y;
175     return v3_elg_fingerprint_md( &pkc );
176 }
177
178 static MD_HANDLE
179 dsa_fingerprint_md_skc( PKT_secret_cert *skc )
180 {
181     PKT_public_cert pkc;
182
183     pkc.pubkey_algo = skc->pubkey_algo;
184     pkc.timestamp = skc->timestamp;
185     pkc.pubkey_algo = skc->pubkey_algo;
186     pkc.d.dsa.p = skc->d.dsa.p;
187     pkc.d.dsa.q = skc->d.dsa.q;
188     pkc.d.dsa.g = skc->d.dsa.g;
189     pkc.d.dsa.y = skc->d.dsa.y;
190     return dsa_fingerprint_md( &pkc );
191 }
192
193
194 /****************
195  * Get the keyid from the secret key certificate and put it into keyid
196  * if this is not NULL. Return the 32 low bits of the keyid.
197  */
198 u32
199 keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
200 {
201     u32 lowbits;
202     u32 dummy_keyid[2];
203
204     if( !keyid )
205         keyid = dummy_keyid;
206
207     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
208         const byte *dp;
209         MD_HANDLE md;
210         md = v3_elg_fingerprint_md_skc(skc);
211         dp = md_read( md, DIGEST_ALGO_RMD160 );
212         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
213         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
214         lowbits = keyid[1];
215         md_close(md);
216     }
217     else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
218         const byte *dp;
219         MD_HANDLE md;
220         md = dsa_fingerprint_md_skc(skc);
221         dp = md_read( md, DIGEST_ALGO_SHA1 );
222         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
223         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
224         lowbits = keyid[1];
225         md_close(md);
226     }
227     else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
228         lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
229     }
230     else {
231         keyid[0] = keyid[1] = lowbits = 0;
232     }
233     return lowbits;
234 }
235
236
237 /****************
238  * Get the keyid from the public key certificate and put it into keyid
239  * if this is not NULL. Return the 32 low bits of the keyid.
240  */
241 u32
242 keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
243 {
244     u32 lowbits;
245     u32 dummy_keyid[2];
246
247     if( !keyid )
248         keyid = dummy_keyid;
249
250     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
251         const byte *dp;
252         MD_HANDLE md;
253         md = v3_elg_fingerprint_md(pkc);
254         dp = md_read( md, DIGEST_ALGO_RMD160 );
255         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
256         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
257         lowbits = keyid[1];
258         md_close(md);
259     }
260     else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
261         const byte *dp;
262         MD_HANDLE md;
263         md = dsa_fingerprint_md(pkc);
264         dp = md_read( md, DIGEST_ALGO_SHA1 );
265         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
266         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
267         lowbits = keyid[1];
268         md_close(md);
269     }
270     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
271         lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
272     }
273     else {
274         keyid[0] = keyid[1] = lowbits = 0;
275     }
276
277     return lowbits;
278 }
279
280
281 u32
282 keyid_from_sig( PKT_signature *sig, u32 *keyid )
283 {
284     if( keyid ) {
285         keyid[0] = sig->keyid[0];
286         keyid[1] = sig->keyid[1];
287     }
288     return sig->keyid[1];
289 }
290
291 /****************
292  * return the number of bits used in the pkc
293  */
294 unsigned
295 nbits_from_pkc( PKT_public_cert *pkc )
296 {
297     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
298         return mpi_get_nbits( pkc->d.elg.p );
299     }
300     else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
301         return mpi_get_nbits( pkc->d.dsa.p );
302     }
303     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
304         return mpi_get_nbits( pkc->d.rsa.rsa_n );
305     }
306     else
307         return 0;
308 }
309
310 /****************
311  * return the number of bits used in the skc
312  */
313 unsigned
314 nbits_from_skc( PKT_secret_cert *skc )
315 {
316     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
317         return mpi_get_nbits( skc->d.elg.p );
318     }
319     else if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
320         return mpi_get_nbits( skc->d.dsa.p );
321     }
322     else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
323         return mpi_get_nbits( skc->d.rsa.rsa_n );
324     }
325     else
326         return 0;
327 }
328
329 /****************
330  * return a string with the creation date of the pkc
331  * Note: this is alloced in a static buffer.
332  *    Format is: yyyy-mm-dd
333  */
334 const char *
335 datestr_from_pkc( PKT_public_cert *pkc )
336 {
337     static char buffer[11+5];
338     struct tm *tp;
339     time_t atime = pkc->timestamp;
340
341     tp = gmtime( &atime );
342     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
343     return buffer;
344 }
345
346 const char *
347 datestr_from_skc( PKT_secret_cert *skc )
348 {
349     static char buffer[11+5];
350     struct tm *tp;
351     time_t atime = skc->timestamp;
352
353     tp = gmtime( &atime );
354     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
355     return buffer;
356 }
357
358 const char *
359 datestr_from_sig( PKT_signature *sig )
360 {
361     static char buffer[11+5];
362     struct tm *tp;
363     time_t atime = sig->timestamp;
364
365     tp = gmtime( &atime );
366     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
367     return buffer;
368 }
369
370
371 /**************** .
372  * Return a byte array with the fingerprint for the given PKC/SKC
373  * The length of the array is returned in ret_len. Caller must free
374  * the array.
375  */
376 byte *
377 fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
378 {
379     PKT_public_cert pkc;
380     byte *p;
381
382     pkc.pubkey_algo = skc->pubkey_algo;
383     if( pkc.pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
384         pkc.timestamp = skc->timestamp;
385         pkc.valid_days = skc->valid_days;
386         pkc.pubkey_algo = skc->pubkey_algo;
387         pkc.d.elg.p = skc->d.elg.p;
388         pkc.d.elg.g = skc->d.elg.g;
389         pkc.d.elg.y = skc->d.elg.y;
390     }
391     else if( pkc.pubkey_algo == PUBKEY_ALGO_DSA ) {
392         pkc.timestamp = skc->timestamp;
393         pkc.valid_days = skc->valid_days;
394         pkc.pubkey_algo = skc->pubkey_algo;
395         pkc.d.dsa.p = skc->d.dsa.p;
396         pkc.d.dsa.q = skc->d.dsa.q;
397         pkc.d.dsa.g = skc->d.dsa.g;
398         pkc.d.dsa.y = skc->d.dsa.y;
399     }
400     else if( pkc.pubkey_algo == PUBKEY_ALGO_RSA ) {
401         pkc.d.rsa.rsa_n = skc->d.rsa.rsa_n;
402         pkc.d.rsa.rsa_e = skc->d.rsa.rsa_e;
403     }
404     p = fingerprint_from_pkc( &pkc, ret_len );
405     memset(&pkc, 0, sizeof pkc); /* not really needed */
406     return p;
407 }
408
409
410
411
412 byte *
413 fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
414 {
415     byte *p, *buf, *array;
416     const char *dp;
417     size_t len;
418     unsigned n;
419
420     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
421         MD_HANDLE md;
422         md = v3_elg_fingerprint_md(pkc);
423         dp = md_read( md, DIGEST_ALGO_RMD160 );
424         array = m_alloc( 20 );
425         len = 20;
426         memcpy(array, dp, 20 );
427         md_close(md);
428     }
429     else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
430         MD_HANDLE md;
431         md = dsa_fingerprint_md(pkc);
432         dp = md_read( md, DIGEST_ALGO_SHA1 );
433         array = m_alloc( 20 );
434         len = 20;
435         memcpy(array, dp, 20 );
436         md_close(md);
437     }
438     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
439         MD_HANDLE md;
440
441         md = md_open( DIGEST_ALGO_MD5, 0);
442         p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
443         for( ; !*p && n; p++, n-- )
444             ;
445         md_write( md, p, n );
446         m_free(buf);
447         p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
448         for( ; !*p && n; p++, n-- )
449             ;
450         md_write( md, p, n );
451         m_free(buf);
452         md_final(md);
453         array = m_alloc( 16 );
454         len = 16;
455         memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
456         md_close(md);
457     }
458     else {
459         array = m_alloc(1);
460         len = 0; /* ooops */
461     }
462
463     *ret_len = len;
464     return array;
465 }
466
467
468