added some stuff for signing keys
[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
50 /****************
51  * Get the keyid from the secret key certificate and put it into keyid
52  * if this is not NULL. Return the 32 low bits of the keyid.
53  */
54 u32
55 keyid_from_skc( PKT_secret_cert *skc, u32 *keyid )
56 {
57     u32 lowbits;
58     u32 dummy_keyid[2];
59
60     if( !keyid )
61         keyid = dummy_keyid;
62
63     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
64         lowbits = mpi_get_keyid( skc->d.elg.y, keyid );
65     }
66     else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
67         lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid );
68     }
69     else {
70         keyid[0] = keyid[1] = lowbits = 0;
71     }
72     return lowbits;
73 }
74
75
76 /****************
77  * Get the keyid from the public key certificate and put it into keyid
78  * if this is not NULL. Return the 32 low bits of the keyid.
79  */
80 u32
81 keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid )
82 {
83     u32 lowbits;
84     u32 dummy_keyid[2];
85
86     if( !keyid )
87         keyid = dummy_keyid;
88
89     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
90         lowbits = mpi_get_keyid( pkc->d.elg.y, keyid );
91     }
92     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
93         lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
94     }
95     else {
96         keyid[0] = keyid[1] = lowbits = 0;
97     }
98
99     return lowbits;
100 }
101
102
103 u32
104 keyid_from_sig( PKT_signature *sig, u32 *keyid )
105 {
106     if( keyid ) {
107         keyid[0] = sig->keyid[0];
108         keyid[1] = sig->keyid[1];
109     }
110     return sig->keyid[1];
111 }
112
113 /****************
114  * return the number of bits used in the pkc
115  */
116 unsigned
117 nbits_from_pkc( PKT_public_cert *pkc )
118 {
119     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
120         return mpi_get_nbits( pkc->d.elg.p );
121     }
122     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
123         return mpi_get_nbits( pkc->d.rsa.rsa_n );
124     }
125     else
126         return 0;
127 }
128
129 /****************
130  * return the number of bits used in the skc
131  */
132 unsigned
133 nbits_from_skc( PKT_secret_cert *skc )
134 {
135     if( skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
136         return mpi_get_nbits( skc->d.elg.p );
137     }
138     else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
139         return mpi_get_nbits( skc->d.rsa.rsa_n );
140     }
141     else
142         return 0;
143 }
144
145 /****************
146  * return a string with the creation date of the pkc
147  * Note: this is alloced in a static buffer.
148  *    Format is: yyyy-mm-dd
149  */
150 const char *
151 datestr_from_pkc( PKT_public_cert *pkc )
152 {
153     static char buffer[11+5];
154     struct tm *tp;
155     time_t atime = pkc->timestamp;
156
157     tp = gmtime( &atime );
158     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
159     return buffer;
160 }
161
162 const char *
163 datestr_from_skc( PKT_secret_cert *skc )
164 {
165     static char buffer[11+5];
166     struct tm *tp;
167     time_t atime = skc->timestamp;
168
169     tp = gmtime( &atime );
170     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
171     return buffer;
172 }
173
174 const char *
175 datestr_from_sig( PKT_signature *sig )
176 {
177     static char buffer[11+5];
178     struct tm *tp;
179     time_t atime = sig->timestamp;
180
181     tp = gmtime( &atime );
182     sprintf(buffer,"%04d-%02d-%02d", 1900+tp->tm_year, tp->tm_mon, tp->tm_mday );
183     return buffer;
184 }
185
186
187 /**************** .
188  * Return a byte array with the fingerprint for the given PKC/SKC
189  * The length of the array is returned in ret_len. Caller must free
190  * the array.
191  */
192 byte *
193 fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len )
194 {
195     PKT_public_cert pkc;
196     byte *p;
197
198     pkc.pubkey_algo = skc->pubkey_algo;
199     if( pkc.pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
200         pkc.timestamp = skc->timestamp;
201         pkc.valid_days = skc->valid_days;
202         pkc.pubkey_algo = skc->pubkey_algo;
203         pkc.d.elg.p = skc->d.elg.p;
204         pkc.d.elg.g = skc->d.elg.g;
205         pkc.d.elg.y = skc->d.elg.y;
206     }
207     else if( pkc.pubkey_algo == PUBKEY_ALGO_RSA ) {
208         pkc.d.rsa.rsa_n = skc->d.rsa.rsa_n;
209         pkc.d.rsa.rsa_e = skc->d.rsa.rsa_e;
210     }
211     p = fingerprint_from_pkc( &pkc, ret_len );
212     memset(&pkc, 0, sizeof pkc); /* not really needed */
213     return p;
214 }
215
216 byte *
217 fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len )
218 {
219     byte *p, *buf, *array;
220     size_t len;
221     unsigned n;
222
223     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) {
224         RMDHANDLE md;
225         const char *dp;
226
227         md = rmd160_open(0);
228
229         {   u32 a = pkc->timestamp;
230             rmd160_putchar( md, a >> 24 );
231             rmd160_putchar( md, a >> 16 );
232             rmd160_putchar( md, a >>  8 );
233             rmd160_putchar( md, a       );
234         }
235         {   u16 a = pkc->valid_days;
236             rmd160_putchar( md, a >> 8 );
237             rmd160_putchar( md, a      );
238         }
239         rmd160_putchar( md, pkc->pubkey_algo );
240         p = buf = mpi_get_buffer( pkc->d.elg.p, &n, NULL );
241         for( ; !*p && n; p++, n-- )
242             ;
243         rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
244         m_free(buf);
245         p = buf = mpi_get_buffer( pkc->d.elg.g, &n, NULL );
246         for( ; !*p && n; p++, n-- )
247             ;
248         rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
249         m_free(buf);
250         p = buf = mpi_get_buffer( pkc->d.elg.y, &n, NULL );
251         for( ; !*p && n; p++, n-- )
252             ;
253         rmd160_putchar( md, n>>8); rmd160_putchar( md, n ); rmd160_write( md, p, n );
254         m_free(buf);
255
256         dp = rmd160_final(md);
257         array = m_alloc( 20 );
258         len = 20;
259         memcpy(array, dp, 20 );
260         rmd160_close(md);
261     }
262     else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
263         MD5HANDLE md;
264
265         md = md5_open(0);
266         p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL );
267         for( ; !*p && n; p++, n-- )
268             ;
269         md5_write( md, p, n );
270         m_free(buf);
271         p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL );
272         for( ; !*p && n; p++, n-- )
273             ;
274         md5_write( md, p, n );
275         m_free(buf);
276         md5_final(md);
277         array = m_alloc( 16 );
278         len = 16;
279         memcpy(array, md5_read(md), 16 );
280         md5_close(md);
281     }
282     else {
283         array = m_alloc(1);
284         len = 0; /* ooops */
285     }
286
287     *ret_len = len;
288     return array;
289 }
290
291
292