compress stuff implemented
[gnupg.git] / g10 / getkey.c
1 /* getkey.c -  Get a key from the database
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 <assert.h>
26 #include "util.h"
27 #include "packet.h"
28 #include "memory.h"
29 #include "iobuf.h"
30 #include "keydb.h"
31 #include "options.h"
32
33 #define MAX_PKC_CACHE_ENTRIES 500
34
35
36 typedef struct keyid_list {
37     struct keyid_list *next;
38     u32 keyid[2];
39 } *keyid_list_t;
40
41 typedef struct user_id_db {
42     struct user_id_db *next;
43     u32 keyid[2];
44     int len;
45     char name[1];
46 } *user_id_db_t;
47
48 typedef struct pkc_cache_entry {
49     struct pkc_cache_entry *next;
50     u32 keyid[2];
51     PKT_pubkey_cert *pkc;
52 } *pkc_cache_entry_t;
53
54 static STRLIST keyrings;
55
56 static keyid_list_t unknown_keyids;
57 static user_id_db_t user_id_db;
58 static pkc_cache_entry_t pkc_cache;
59 static int pkc_cache_entries;   /* number of entries in pkc cache */
60
61
62 static int scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid,
63                          const char *name, const char *filename );
64 static int scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename);
65
66
67 void
68 add_keyring( const char *name )
69 {
70     STRLIST sl;
71
72     /* FIXME: check wether this one is available etc */
73     /* my be we should do this later */
74     sl = m_alloc( sizeof *sl + strlen(name) );
75     strcpy(sl->d, name );
76     sl->next = keyrings;
77     keyrings = sl;
78 }
79
80
81 void
82 cache_pubkey_cert( PKT_pubkey_cert *pkc )
83 {
84     pkc_cache_entry_t ce;
85     u32 keyid[2];
86
87     if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
88         mpi_get_keyid( pkc->d.rsa.rsa_n, keyid );
89     }
90     else
91         return; /* don't know how to get the keyid */
92
93     for( ce = pkc_cache; ce; ce = ce->next )
94         if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
95             if( DBG_CACHE )
96                 log_debug("cache_pubkey_cert: already in cache\n");
97             return;
98         }
99
100     if( pkc_cache_entries > MAX_PKC_CACHE_ENTRIES ) {
101         /* FIMXE: use another algorithm to free some cache slots */
102         if( pkc_cache_entries == MAX_PKC_CACHE_ENTRIES )  {
103             pkc_cache_entries++;
104             log_info("too many entries in pkc cache - disabled\n");
105         }
106         ce = pkc_cache;
107         free_pubkey_cert( ce->pkc );
108     }
109     else {
110         pkc_cache_entries++;
111         ce = m_alloc( sizeof *ce );
112         ce->next = pkc_cache;
113         pkc_cache = ce;
114     }
115     ce->pkc = copy_pubkey_cert( NULL, pkc );
116     ce->keyid[0] = keyid[0];
117     ce->keyid[1] = keyid[1];
118 }
119
120
121 /****************
122  * Store the association of keyid and userid
123  */
124 void
125 cache_user_id( PKT_user_id *uid, u32 *keyid )
126 {
127     user_id_db_t r;
128
129     for(r=user_id_db; r; r = r->next )
130         if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
131             if( DBG_CACHE )
132                 log_debug("cache_user_id: already in cache\n");
133             return;
134         }
135
136     r = m_alloc( sizeof *r + uid->len-1 );
137     r->keyid[0] = keyid[0];
138     r->keyid[1] = keyid[1];
139     r->len = uid->len;
140     memcpy(r->name, uid->name, r->len);
141     r->next = user_id_db;
142     user_id_db = r;
143 }
144
145
146
147 /****************
148  * Get a public key and store it into the allocated pkc
149  * can be called with PKC set to NULL to just read it into some
150  * internal structures.
151  */
152 int
153 get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid )
154 {
155     keyid_list_t kl;
156     int internal = 0;
157     int rc = 0;
158     pkc_cache_entry_t ce;
159     STRLIST sl;
160
161
162     if( opt.cache_all && !pkc_cache ) {
163         log_info("reading all entries ...\n");
164         for(sl = keyrings; sl; sl = sl->next )
165             if( !scan_keyring( NULL, NULL, NULL, sl->d ) )
166                 goto leave;
167         log_info("cached %d entries\n", pkc_cache_entries);
168     }
169
170
171     /* lets see wether we checked the keyid already */
172     for( kl = unknown_keyids; kl; kl = kl->next )
173         if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] )
174             return G10ERR_NO_PUBKEY; /* already checked and not found */
175
176     /* 1. Try to get it from our cache */
177     for( ce = pkc_cache; ce; ce = ce->next )
178         if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
179             if( pkc )
180                 copy_pubkey_cert( pkc, ce->pkc );
181             return 0;
182         }
183
184     /* more init stuff */
185     if( !pkc ) {
186         pkc = m_alloc_clear( sizeof *pkc );
187         internal++;
188     }
189
190
191     /* 2. Try to get it from the keyrings */
192     for(sl = keyrings; sl; sl = sl->next )
193         if( !scan_keyring( pkc, keyid, NULL, sl->d ) )
194             goto leave;
195
196     /* 3. Try to get it from a key server */
197
198     /* 4. not found: store it for future reference */
199     kl = m_alloc( sizeof *kl );
200     kl->keyid[0] = keyid[0];
201     kl->keyid[1] = keyid[1];
202     kl->next = unknown_keyids;
203     unknown_keyids = kl;
204     rc = G10ERR_NO_PUBKEY;
205
206   leave:
207     if( !rc )
208         cache_pubkey_cert( pkc );
209     if( internal )
210         m_free(pkc);
211     return rc;
212 }
213
214
215 /****************
216  * Try to get the pubkey by the userid. This functions looks for the
217  * first pubkey certificate which has the given name in a user_id.
218  * if pkc has the pubkey algo set, the function will only return
219  * a pubkey with that algo.
220  */
221 int
222 get_pubkey_by_name( PKT_pubkey_cert *pkc, const char *name )
223 {
224     int internal = 0;
225     int rc = 0;
226     STRLIST sl;
227
228     if( !pkc ) {
229         pkc = m_alloc_clear( sizeof *pkc );
230         internal++;
231     }
232
233     /* 2. Try to get it from the keyrings */
234     for(sl = keyrings; sl; sl = sl->next )
235         if( !scan_keyring( pkc, NULL, name, sl->d ) )
236             goto leave;
237
238     /* 3. Try to get it from a key server */
239
240     /* 4. not found: store it for future reference */
241     rc = G10ERR_NO_PUBKEY;
242
243   leave:
244     if( internal )
245         m_free(pkc);
246     return rc;
247 }
248
249
250 /****************
251  * Get a secret key and store it into skey
252  */
253 int
254 get_seckey( RSA_secret_key *skey, u32 *keyid )
255 {
256     int rc=0;
257     PACKET pkt;
258
259     init_packet( &pkt );
260     if( !(rc=scan_secret_keyring( &pkt, keyid, "../keys/secring.g10" ) ) )
261         goto found;
262     /* fixme: look at other places */
263     goto leave;
264
265   found:
266     /* get the secret key (this may prompt for a passprase to
267      * unlock the secret key
268      */
269     if( (rc = check_secret_key( pkt.pkt.seckey_cert )) )
270         goto leave;
271     if( pkt.pkt.seckey_cert->pubkey_algo != PUBKEY_ALGO_RSA ) {
272         rc = G10ERR_PUBKEY_ALGO; /* unsupport algorithm */
273         goto leave;
274     }
275     /* copy the stuff to SKEY. skey is then the owner */
276     skey->e = pkt.pkt.seckey_cert->d.rsa.rsa_e;
277     skey->n = pkt.pkt.seckey_cert->d.rsa.rsa_n;
278     skey->p = pkt.pkt.seckey_cert->d.rsa.rsa_p;
279     skey->q = pkt.pkt.seckey_cert->d.rsa.rsa_q;
280     skey->d = pkt.pkt.seckey_cert->d.rsa.rsa_d;
281     skey->u = pkt.pkt.seckey_cert->d.rsa.rsa_u;
282     /* set all these to NULL, so that free_packet will not destroy
283      * these integers. */
284     pkt.pkt.seckey_cert->d.rsa.rsa_e = NULL;
285     pkt.pkt.seckey_cert->d.rsa.rsa_n = NULL;
286     pkt.pkt.seckey_cert->d.rsa.rsa_p = NULL;
287     pkt.pkt.seckey_cert->d.rsa.rsa_q = NULL;
288     pkt.pkt.seckey_cert->d.rsa.rsa_d = NULL;
289     pkt.pkt.seckey_cert->d.rsa.rsa_u = NULL;
290
291   leave:
292     free_packet(&pkt);
293     return rc;
294 }
295
296
297 /****************
298  * scan the keyring and look for either the keyid or the name.
299  */
300 static int
301 scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid,
302               const char *name, const char *filename )
303 {
304     int rc=0;
305     int found = 0;
306     IOBUF a;
307     PACKET pkt;
308     int save_mode;
309     u32 akeyid[2];
310     PKT_pubkey_cert *last_pk = NULL;
311
312     assert( !keyid || !name );
313
314     if( opt.cache_all && (name || keyid) )
315         return G10ERR_NO_PUBKEY;
316
317     if( !(a = iobuf_open( filename ) ) ) {
318         log_debug("scan_keyring: can't open '%s'\n", filename );
319         return G10ERR_KEYRING_OPEN;
320     }
321
322     if( !DBG_CACHE )
323         ;
324     else if( name )
325         log_debug("scan_keyring %s for '%s'\n",  filename, name );
326     else if( keyid )
327         log_debug("scan_keyring %s for %08lx %08lx\n",  filename,
328                                                 keyid[0], keyid[1] );
329     else
330         log_debug("scan_keyring %s (all)\n",  filename );
331
332     save_mode = set_packet_list_mode(0);
333     init_packet(&pkt);
334     while( (rc=parse_packet(a, &pkt)) != -1 ) {
335         if( rc )
336             ; /* e.g. unknown packet */
337         else if( keyid && found && pkt.pkttype == PKT_PUBKEY_CERT ) {
338             log_error("Hmmm, pubkey without an user id in '%s'\n", filename);
339             goto leave;
340         }
341         else if( keyid && pkt.pkttype == PKT_PUBKEY_CERT ) {
342             switch( pkt.pkt.pubkey_cert->pubkey_algo ) {
343               case PUBKEY_ALGO_RSA:
344                 mpi_get_keyid( pkt.pkt.pubkey_cert->d.rsa.rsa_n , akeyid );
345                 if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
346                     copy_pubkey_cert( pkc, pkt.pkt.pubkey_cert );
347                     found++;
348                 }
349                 break;
350               default:
351                 log_error("cannot handle pubkey algo %d\n",
352                                      pkt.pkt.pubkey_cert->pubkey_algo);
353             }
354         }
355         else if( keyid && found && pkt.pkttype == PKT_USER_ID ) {
356             cache_user_id( pkt.pkt.user_id, keyid );
357             goto leave;
358         }
359         else if( name && pkt.pkttype == PKT_PUBKEY_CERT ) {
360             if( last_pk )
361                 free_pubkey_cert(last_pk);
362             last_pk = pkt.pkt.pubkey_cert;
363             pkt.pkt.pubkey_cert = NULL;
364         }
365         else if( name && pkt.pkttype == PKT_USER_ID ) {
366             if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) {
367                 if( !last_pk )
368                     log_error("Ooops: no pubkey for userid '%.*s'\n",
369                                 pkt.pkt.user_id->len, pkt.pkt.user_id->name);
370                 else if( pkc->pubkey_algo &&
371                          pkc->pubkey_algo != last_pk->pubkey_algo )
372                     log_info("skipping id '%.*s': want algo %d, found %d\n",
373                                 pkt.pkt.user_id->len, pkt.pkt.user_id->name,
374                                 pkc->pubkey_algo, last_pk->pubkey_algo );
375                 else {
376                     copy_pubkey_cert( pkc, last_pk );
377                     goto leave;
378                 }
379             }
380         }
381         else if( !keyid && !name && pkt.pkttype == PKT_PUBKEY_CERT ) {
382             if( last_pk )
383                 free_pubkey_cert(last_pk);
384             last_pk = pkt.pkt.pubkey_cert;
385             pkt.pkt.pubkey_cert = NULL;
386         }
387         else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) {
388             if( !last_pk )
389                 log_error("Ooops: no pubkey for userid '%.*s'\n",
390                             pkt.pkt.user_id->len, pkt.pkt.user_id->name);
391             else {
392                 if( last_pk->pubkey_algo == PUBKEY_ALGO_RSA ) {
393                      mpi_get_keyid( last_pk->d.rsa.rsa_n , akeyid );
394                      cache_user_id( pkt.pkt.user_id, akeyid );
395                 }
396                 cache_pubkey_cert( last_pk );
397             }
398         }
399         free_packet(&pkt);
400     }
401     rc = G10ERR_NO_PUBKEY;
402
403   leave:
404     if( last_pk )
405         free_pubkey_cert(last_pk);
406     free_packet(&pkt);
407     iobuf_close(a);
408     set_packet_list_mode(save_mode);
409     return rc;
410 }
411
412
413 /****************
414  * This is the function to get a secret key. We use an extra function,
415  * so that we can easily add special handling for secret keyrings
416  * PKT returns the secret key certificate.
417  */
418 static int
419 scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename )
420 {
421     IOBUF a;
422     int save_mode, rc;
423     u32 akeyid[2];
424
425     if( !(a = iobuf_open( filename ) ) ) {
426         log_debug("scan_secret_keyring: can't open '%s'\n", filename );
427         return G10ERR_KEYRING_OPEN;
428     }
429
430     save_mode = set_packet_list_mode(0);
431     init_packet(pkt);
432     while( (rc=parse_packet(a, pkt)) != -1 ) {
433         if( rc )
434             ;
435         else if( pkt->pkttype == PKT_SECKEY_CERT ) {
436             mpi_get_keyid( pkt->pkt.seckey_cert->d.rsa.rsa_n , akeyid );
437             if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
438                 iobuf_close(a);
439                 set_packet_list_mode(save_mode);
440                 return 0; /* got it */
441             }
442         }
443         free_packet(pkt);
444     }
445
446     iobuf_close(a);
447     set_packet_list_mode(save_mode);
448     return G10ERR_NO_SECKEY;
449 }
450
451
452
453 /****************
454  * Return a string with a printable representation of the user_id.
455  * this string must be freed by m_free.
456  */
457 char*
458 get_user_id_string( u32 *keyid )
459 {
460     user_id_db_t r;
461     char *p;
462     int pass=0;
463     /* try it two times; second pass reads from keyrings */
464     do {
465         for(r=user_id_db; r; r = r->next )
466             if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
467                 p = m_alloc( r->len + 10 );
468                 sprintf(p, "%08lX %.*s", keyid[1], r->len, r->name );
469                 return p;
470             }
471     } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
472     p = m_alloc( 15 );
473     sprintf(p, "%08lX [?]", keyid[1] );
474     return p;
475 }
476
477