started with trust stuff
[gnupg.git] / g10 / keyid.c
1 /* keyid.c - jeyid and fingerprint handling
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 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  * G10 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 n;
63
64     p1 = buf1 = mpi_get_buffer( pkc->d.elg.p, &n1, NULL );
65     for( ; !*p1 && n1; p1++, n1-- )  /* skip leading null bytes */
66         ;
67     p2 = buf2 = mpi_get_buffer( pkc->d.elg.g, &n2, NULL );
68     for( ; !*p2 && n2; p2++, n2-- )  /* skip leading null bytes */
69         ;
70     p3 = buf3 = mpi_get_buffer( pkc->d.elg.y, &n3, NULL );
71     for( ; !*p3 && n3; p3++, n3-- )  /* skip leading null bytes */
72         ;
73
74     /* calculate length of packet (1+4+2+1+2+n1+2+n2+2+n3) */
75     n = 14 + n1 + n2 + n3;
76     md = md_open( DIGEST_ALGO_RMD160, 0);
77
78     md_putc( md, 0x99 );     /* ctb */
79     md_putc( md, n >> 8 );   /* 2 byte length header */
80     md_putc( md, n );
81     md_putc( md, 3 );        /* version */
82     {   u32 a = pkc->timestamp;
83         md_putc( md, a >> 24 );
84         md_putc( md, a >> 16 );
85         md_putc( md, a >>  8 );
86         md_putc( md, a       );
87     }
88     {   u16 a = pkc->valid_days;
89         md_putc( md, a >> 8 );
90         md_putc( md, a      );
91     }
92     md_putc( md, pkc->pubkey_algo );
93     md_putc( md, n1>>8); md_putc( md, n1 ); md_write( md, p1, n1 );
94     md_putc( md, n2>>8); md_putc( md, n2 ); md_write( md, p2, n2 );
95     md_putc( md, n3>>8); md_putc( md, n3 ); md_write( md, p3, n3 );
96     m_free(buf1);
97     m_free(buf2);
98     m_free(buf3);
99     md_final( md );
100
101     return md;
102 }
103
104
105 static MD_HANDLE
106 v3_elg_fingerprint_md_skc( PKT_secret_cert *skc )
107 {
108     PKT_public_cert pkc;
109     byte *p;
110
111     pkc.pubkey_algo = skc->pubkey_algo;
112     pkc.timestamp = skc->timestamp;
113     pkc.valid_days = skc->valid_days;
114     pkc.pubkey_algo = skc->pubkey_algo;
115     pkc.d.elg.p = skc->d.elg.p;
116     pkc.d.elg.g = skc->d.elg.g;
117     pkc.d.elg.y = skc->d.elg.y;
118     return v3_elg_fingerprint_md( &pkc );
119 }
120
121
122 /****************
123  * Get the keyid from the secret key certificate and put it into keyid
124  * if this is not NULL. Return the 32 low bits of the keyid.
125  */
126 u32
127 keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
128 {
129     u32 lowbits;
130     u32 dummy_keyid[2];
131
132     if( !keyid )
133         keyid = dummy_keyid;
134
135     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
136         const byte *dp;
137         MD_HANDLE md;
138         md = v3_elg_fingerprint_md_skc(skc);
139         dp = md_read( md, DIGEST_ALGO_RMD160 );
140         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
141         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
142         lowbits = keyid[1];
143         md_close(md);
144     }
145     else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
146         lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
147     }
148     else {
149         keyid[0] = keyid[1] = lowbits = 0;
150     }
151     return lowbits;
152 }
153
154
155 /****************
156  * Get the keyid from the public key certificate and put it into keyid
157  * if this is not NULL. Return the 32 low bits of the keyid.
158  */
159 u32
160 keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
161 {
162     u32 lowbits;
163     u32 dummy_keyid[2];
164
165     if( !keyid )
166         keyid = dummy_keyid;
167
168     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
169         const byte *dp;
170         MD_HANDLE md;
171         md = v3_elg_fingerprint_md(pkc);
172         dp = md_read( md, DIGEST_ALGO_RMD160 );
173         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
174         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
175         lowbits = keyid[1];
176         md_close(md);
177     }
178     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
179         lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
180     }
181     else {
182         keyid[0] = keyid[1] = lowbits = 0;
183     }
184
185     return lowbits;
186 }
187
188
189 u32
190 keyid_from_sig( PKT_signature *sig, u32 *keyid )
191 {
192     if( keyid ) {
193         keyid[0] = sig->keyid[0];
194         keyid[1] = sig->keyid[1];
195     }
196     return sig->keyid[1];
197 }
198
199 /****************
200  * return the number of bits used in the pkc
201  */
202 unsigned
203 nbits_from_pkc( PKT_public_cert *pkc )
204 {
205     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
206         return mpi_get_nbits( pkc->d.elg.p );
207     }
208     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
209         return mpi_get_nbits( pkc->d.rsa.rsa_n );
210     }
211     else
212         return 0;
213 }
214
215 /****************
216  * return the number of bits used in the skc
217  */
218 unsigned
219 nbits_from_skc( PKT_secret_cert *skc )
220 {
221     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
222         return mpi_get_nbits( skc->d.elg.p );
223     }
224     else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
225         return mpi_get_nbits( skc->d.rsa.rsa_n );
226     }
227     else
228         return 0;
229 }
230
231 /****************
232  * return a string with the creation date of the pkc
233  * Note: this is alloced in a static buffer.
234  *    Format is: yyyy-mm-dd
235  */
236 const char *
237 datestr_from_pkc( PKT_public_cert *pkc )
238 {
239     static char buffer[11+5];
240     struct tm *tp;
241     time_t atime = pkc->timestamp;
242
243     tp = gmtime( &atime );
244     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
245     return buffer;
246 }
247
248 const char *
249 datestr_from_skc( PKT_secret_cert *skc )
250 {
251     static char buffer[11+5];
252     struct tm *tp;
253     time_t atime = skc->timestamp;
254
255     tp = gmtime( &atime );
256     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
257     return buffer;
258 }
259
260 const char *
261 datestr_from_sig( PKT_signature *sig )
262 {
263     static char buffer[11+5];
264     struct tm *tp;
265     time_t atime = sig->timestamp;
266
267     tp = gmtime( &atime );
268     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
269     return buffer;
270 }
271
272
273 /**************** .
274  * Return a byte array with the fingerprint for the given PKC/SKC
275  * The length of the array is returned in ret_len. Caller must free
276  * the array.
277  */
278 byte *
279 fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
280 {
281     PKT_public_cert pkc;
282     byte *p;
283
284     pkc.pubkey_algo = skc->pubkey_algo;
285     if( pkc.pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
286         pkc.timestamp = skc->timestamp;
287         pkc.valid_days = skc->valid_days;
288         pkc.pubkey_algo = skc->pubkey_algo;
289         pkc.d.elg.p = skc->d.elg.p;
290         pkc.d.elg.g = skc->d.elg.g;
291         pkc.d.elg.y = skc->d.elg.y;
292     }
293     else if( pkc.pubkey_algo == PUBKEY_ALGO_RSA ) {
294         pkc.d.rsa.rsa_n = skc->d.rsa.rsa_n;
295         pkc.d.rsa.rsa_e = skc->d.rsa.rsa_e;
296     }
297     p = fingerprint_from_pkc( &pkc, ret_len );
298     memset(&pkc, 0, sizeof pkc); /* not really needed */
299     return p;
300 }
301
302
303
304
305 byte *
306 fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
307 {
308     byte *p, *buf, *array;
309     const char *dp;
310     size_t len;
311     unsigned n;
312
313     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
314         MD_HANDLE md;
315         md = v3_elg_fingerprint_md(pkc);
316         dp = md_read( md, DIGEST_ALGO_RMD160 );
317         array = m_alloc( 20 );
318         len = 20;
319         memcpy(array, dp, 20 );
320         md_close(md);
321     }
322     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
323         MD_HANDLE md;
324
325         md = md_open( DIGEST_ALGO_MD5, 0);
326         p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
327         for( ; !*p && n; p++, n-- )
328             ;
329         md_write( md, p, n );
330         m_free(buf);
331         p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
332         for( ; !*p && n; p++, n-- )
333             ;
334         md_write( md, p, n );
335         m_free(buf);
336         md_final(md);
337         array = m_alloc( 16 );
338         len = 16;
339         memcpy(array, md_read(md, DIGEST_ALGO_MD5), 16 );
340         md_close(md);
341     }
342     else {
343         array = m_alloc(1);
344         len = 0; /* ooops */
345     }
346
347     *ret_len = len;
348     return array;
349 }
350
351
352