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