List and check sigs works
[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_public_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_public_cert *pkc, u32 *keyid,
63                          const char *name, const char *filename );
64 static int scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid,
65                                 const char *name, const char *filename);
66
67
68 void
69 add_keyring( const char *name )
70 {
71     STRLIST sl;
72
73     /* FIXME: check wether this one is available etc */
74     /* my be we should do this later */
75     sl = m_alloc( sizeof *sl + strlen(name) );
76     strcpy(sl->d, name );
77     sl->next = keyrings;
78     keyrings = sl;
79 }
80
81
82 void
83 cache_public_cert( PKT_public_cert *pkc )
84 {
85     pkc_cache_entry_t ce;
86     u32 keyid[2];
87
88     if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL
89         || pkc->pubkey_algo == PUBKEY_ALGO_RSA ) {
90         keyid_from_pkc( pkc, keyid );
91     }
92     else
93         return; /* don't know how to get the keyid */
94
95     for( ce = pkc_cache; ce; ce = ce->next )
96         if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
97             if( DBG_CACHE )
98                 log_debug("cache_public_cert: already in cache\n");
99             return;
100         }
101
102     if( pkc_cache_entries > MAX_PKC_CACHE_ENTRIES ) {
103         /* FIMXE: use another algorithm to free some cache slots */
104         if( pkc_cache_entries == MAX_PKC_CACHE_ENTRIES )  {
105             pkc_cache_entries++;
106             log_info("too many entries in pkc cache - disabled\n");
107         }
108         ce = pkc_cache;
109         free_public_cert( ce->pkc );
110     }
111     else {
112         pkc_cache_entries++;
113         ce = m_alloc( sizeof *ce );
114         ce->next = pkc_cache;
115         pkc_cache = ce;
116     }
117     ce->pkc = copy_public_cert( NULL, pkc );
118     ce->keyid[0] = keyid[0];
119     ce->keyid[1] = keyid[1];
120 }
121
122
123 /****************
124  * Store the association of keyid and userid
125  */
126 void
127 cache_user_id( PKT_user_id *uid, u32 *keyid )
128 {
129     user_id_db_t r;
130
131     for(r=user_id_db; r; r = r->next )
132         if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
133             if( DBG_CACHE )
134                 log_debug("cache_user_id: already in cache\n");
135             return;
136         }
137
138     r = m_alloc( sizeof *r + uid->len-1 );
139     r->keyid[0] = keyid[0];
140     r->keyid[1] = keyid[1];
141     r->len = uid->len;
142     memcpy(r->name, uid->name, r->len);
143     r->next = user_id_db;
144     user_id_db = r;
145 }
146
147
148
149 /****************
150  * Get a public key and store it into the allocated pkc
151  * can be called with PKC set to NULL to just read it into some
152  * internal structures.
153  */
154 int
155 get_pubkey( PKT_public_cert *pkc, u32 *keyid )
156 {
157     keyid_list_t kl;
158     int internal = 0;
159     int rc = 0;
160     pkc_cache_entry_t ce;
161     STRLIST sl;
162
163
164     if( opt.cache_all && !pkc_cache ) {
165         log_info("reading all entries ...\n");
166         for(sl = keyrings; sl; sl = sl->next )
167             if( !scan_keyring( NULL, NULL, NULL, sl->d ) )
168                 goto leave;
169         log_info("cached %d entries\n", pkc_cache_entries);
170     }
171
172
173     /* lets see wether we checked the keyid already */
174     for( kl = unknown_keyids; kl; kl = kl->next )
175         if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] )
176             return G10ERR_NO_PUBKEY; /* already checked and not found */
177
178     /* 1. Try to get it from our cache */
179     for( ce = pkc_cache; ce; ce = ce->next )
180         if( ce->keyid[0] == keyid[0] && ce->keyid[1] == keyid[1] ) {
181             if( pkc )
182                 copy_public_cert( pkc, ce->pkc );
183             return 0;
184         }
185
186     /* more init stuff */
187     if( !pkc ) {
188         pkc = m_alloc_clear( sizeof *pkc );
189         internal++;
190     }
191
192
193     /* 2. Try to get it from the keyrings */
194     for(sl = keyrings; sl; sl = sl->next )
195         if( !scan_keyring( pkc, keyid, NULL, sl->d ) )
196             goto leave;
197
198     /* 3. Try to get it from a key server */
199
200     /* 4. not found: store it for future reference */
201     kl = m_alloc( sizeof *kl );
202     kl->keyid[0] = keyid[0];
203     kl->keyid[1] = keyid[1];
204     kl->next = unknown_keyids;
205     unknown_keyids = kl;
206     rc = G10ERR_NO_PUBKEY;
207
208   leave:
209     if( !rc )
210         cache_public_cert( pkc );
211     if( internal )
212         m_free(pkc);
213     return rc;
214 }
215
216
217 /****************
218  * Try to get the pubkey by the userid. This functions looks for the
219  * first pubkey certificate which has the given name in a user_id.
220  * if pkc has the pubkey algo set, the function will only return
221  * a pubkey with that algo.
222  */
223 int
224 get_pubkey_by_name( PKT_public_cert *pkc, const char *name )
225 {
226     int internal = 0;
227     int rc = 0;
228     STRLIST sl;
229
230     if( !pkc ) {
231         pkc = m_alloc_clear( sizeof *pkc );
232         internal++;
233     }
234
235     /* 2. Try to get it from the keyrings */
236     for(sl = keyrings; sl; sl = sl->next )
237         if( !scan_keyring( pkc, NULL, name, sl->d ) )
238             goto leave;
239
240     /* 3. Try to get it from a key server */
241
242     /* 4. not found: store it for future reference */
243     rc = G10ERR_NO_PUBKEY;
244
245   leave:
246     if( internal )
247         m_free(pkc);
248     return rc;
249 }
250
251
252 /****************
253  * Get a secret key and store it into skey
254  */
255 int
256 get_seckey( PKT_secret_cert *skc, u32 *keyid )
257 {
258     int rc=0;
259
260     if( !(rc=scan_secret_keyring( skc, keyid, NULL, "../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( skc )) )
270         goto leave;
271
272   leave:
273     return rc;
274 }
275
276 /****************
277  * Get a secret key by name and store it into skc
278  */
279 int
280 get_seckey_by_name( PKT_secret_cert *skc, const char *name )
281 {
282     int rc=0;
283
284     if( !(rc=scan_secret_keyring( skc, NULL, name, "../keys/secring.g10" ) ) )
285         goto found;
286     /* fixme: look at other places */
287     goto leave;
288
289   found:
290     /* get the secret key (this may prompt for a passprase to
291      * unlock the secret key
292      */
293     if( (rc = check_secret_key( skc )) )
294         goto leave;
295
296   leave:
297     return rc;
298 }
299
300
301 /****************
302  * scan the keyring and look for either the keyid or the name.
303  */
304 static int
305 scan_keyring( PKT_public_cert *pkc, u32 *keyid,
306               const char *name, const char *filename )
307 {
308     int rc=0;
309     int found = 0;
310     IOBUF a;
311     PACKET pkt;
312     int save_mode;
313     u32 akeyid[2];
314     PKT_public_cert *last_pk = NULL;
315
316     assert( !keyid || !name );
317
318     if( opt.cache_all && (name || keyid) )
319         return G10ERR_NO_PUBKEY;
320
321     if( !(a = iobuf_open( filename ) ) ) {
322         log_debug("scan_keyring: can't open '%s'\n", filename );
323         return G10ERR_KEYRING_OPEN;
324     }
325
326     if( !DBG_CACHE )
327         ;
328     else if( name )
329         log_debug("scan_keyring %s for '%s'\n",  filename, name );
330     else if( keyid )
331         log_debug("scan_keyring %s for %08lx %08lx\n",  filename,
332                                                 keyid[0], keyid[1] );
333     else
334         log_debug("scan_keyring %s (all)\n",  filename );
335
336     save_mode = set_packet_list_mode(0);
337     init_packet(&pkt);
338     while( (rc=parse_packet(a, &pkt)) != -1 ) {
339         if( rc )
340             ; /* e.g. unknown packet */
341         else if( keyid && found && pkt.pkttype == PKT_PUBLIC_CERT ) {
342             log_error("Hmmm, pubkey without an user id in '%s'\n", filename);
343             goto leave;
344         }
345         else if( keyid && pkt.pkttype == PKT_PUBLIC_CERT ) {
346             switch( pkt.pkt.public_cert->pubkey_algo ) {
347               case PUBKEY_ALGO_ELGAMAL:
348               case PUBKEY_ALGO_RSA:
349                 keyid_from_pkc( pkt.pkt.public_cert, akeyid );
350                 if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
351                     copy_public_cert( pkc, pkt.pkt.public_cert );
352                     found++;
353                 }
354                 break;
355               default:
356                 log_error("cannot handle pubkey algo %d\n",
357                                      pkt.pkt.public_cert->pubkey_algo);
358             }
359         }
360         else if( keyid && found && pkt.pkttype == PKT_USER_ID ) {
361             cache_user_id( pkt.pkt.user_id, keyid );
362             goto leave;
363         }
364         else if( name && pkt.pkttype == PKT_PUBLIC_CERT ) {
365             if( last_pk )
366                 free_public_cert(last_pk);
367             last_pk = pkt.pkt.public_cert;
368             pkt.pkt.public_cert = NULL;
369         }
370         else if( name && pkt.pkttype == PKT_USER_ID ) {
371             if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) {
372                 if( !last_pk )
373                     log_error("Ooops: no pubkey for userid '%.*s'\n",
374                                 pkt.pkt.user_id->len, pkt.pkt.user_id->name);
375                 else if( pkc->pubkey_algo &&
376                          pkc->pubkey_algo != last_pk->pubkey_algo )
377                     log_info("skipping id '%.*s': want algo %d, found %d\n",
378                                 pkt.pkt.user_id->len, pkt.pkt.user_id->name,
379                                 pkc->pubkey_algo, last_pk->pubkey_algo );
380                 else {
381                     copy_public_cert( pkc, last_pk );
382                     goto leave;
383                 }
384             }
385         }
386         else if( !keyid && !name && pkt.pkttype == PKT_PUBLIC_CERT ) {
387             if( last_pk )
388                 free_public_cert(last_pk);
389             last_pk = pkt.pkt.public_cert;
390             pkt.pkt.public_cert = NULL;
391         }
392         else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) {
393             if( !last_pk )
394                 log_error("Ooops: no pubkey for userid '%.*s'\n",
395                             pkt.pkt.user_id->len, pkt.pkt.user_id->name);
396             else {
397                 if( last_pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
398                     || last_pk->pubkey_algo == PUBKEY_ALGO_RSA ) {
399                      keyid_from_pkc( last_pk, akeyid );
400                      cache_user_id( pkt.pkt.user_id, akeyid );
401                 }
402                 cache_public_cert( last_pk );
403             }
404         }
405         free_packet(&pkt);
406     }
407     rc = G10ERR_NO_PUBKEY;
408
409   leave:
410     if( last_pk )
411         free_public_cert(last_pk);
412     free_packet(&pkt);
413     iobuf_close(a);
414     set_packet_list_mode(save_mode);
415     return rc;
416 }
417
418
419 /****************
420  * This is the function to get a secret key. We use an extra function,
421  * so that we can easily add special handling for secret keyrings
422  * PKT returns the secret key certificate.
423  */
424 static int
425 scan_secret_keyring( PKT_secret_cert *skc, u32 *keyid,
426                      const char *name, const char *filename )
427 {
428     int rc=0;
429     int found = 0;
430     IOBUF a;
431     PACKET pkt;
432     int save_mode;
433     u32 akeyid[2];
434     PKT_secret_cert *last_pk = NULL;
435
436     assert( !keyid || !name );
437
438     if( !(a = iobuf_open( filename ) ) ) {
439         log_debug("scan_secret_keyring: can't open '%s'\n", filename );
440         return G10ERR_KEYRING_OPEN;
441     }
442
443     save_mode = set_packet_list_mode(0);
444     init_packet(&pkt);
445     while( (rc=parse_packet(a, &pkt)) != -1 ) {
446         if( rc )
447             ; /* e.g. unknown packet */
448         else if( keyid && found && pkt.pkttype == PKT_SECRET_CERT ) {
449             log_error("Hmmm, seckey without an user id in '%s'\n", filename);
450             goto leave;
451         }
452         else if( keyid && pkt.pkttype == PKT_SECRET_CERT ) {
453             switch( pkt.pkt.secret_cert->pubkey_algo ) {
454               case PUBKEY_ALGO_ELGAMAL:
455               case PUBKEY_ALGO_RSA:
456                 keyid_from_skc( pkt.pkt.secret_cert, akeyid );
457                 if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
458                     copy_secret_cert( skc, pkt.pkt.secret_cert );
459                     found++;
460                 }
461                 break;
462               default:
463                 log_error("cannot handle pubkey algo %d\n",
464                                      pkt.pkt.secret_cert->pubkey_algo);
465             }
466         }
467         else if( keyid && found && pkt.pkttype == PKT_USER_ID ) {
468             goto leave;
469         }
470         else if( name && pkt.pkttype == PKT_SECRET_CERT ) {
471             if( last_pk )
472                 free_secret_cert(last_pk);
473             last_pk = pkt.pkt.secret_cert;
474             pkt.pkt.secret_cert = NULL;
475         }
476         else if( name && pkt.pkttype == PKT_USER_ID ) {
477             if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) {
478                 if( !last_pk )
479                     log_error("Ooops: no seckey for userid '%.*s'\n",
480                                 pkt.pkt.user_id->len, pkt.pkt.user_id->name);
481                 else if( skc->pubkey_algo &&
482                          skc->pubkey_algo != last_pk->pubkey_algo )
483                     log_info("skipping id '%.*s': want algo %d, found %d\n",
484                                 pkt.pkt.user_id->len, pkt.pkt.user_id->name,
485                                 skc->pubkey_algo, last_pk->pubkey_algo );
486                 else {
487                     copy_secret_cert( skc, last_pk );
488                     goto leave;
489                 }
490             }
491         }
492         else if( !keyid && !name && pkt.pkttype == PKT_SECRET_CERT ) {
493             if( last_pk )
494                 free_secret_cert(last_pk);
495             last_pk = pkt.pkt.secret_cert;
496             pkt.pkt.secret_cert = NULL;
497         }
498         else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) {
499             if( !last_pk )
500                 log_error("Ooops: no seckey for userid '%.*s'\n",
501                             pkt.pkt.user_id->len, pkt.pkt.user_id->name);
502             else {
503                 if( last_pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL
504                    || last_pk->pubkey_algo == PUBKEY_ALGO_RSA ) {
505                     keyid_from_skc( last_pk, akeyid );
506                     cache_user_id( pkt.pkt.user_id, akeyid );
507                 }
508             }
509         }
510         free_packet(&pkt);
511     }
512     rc = G10ERR_NO_SECKEY;
513
514   leave:
515     if( last_pk )
516         free_secret_cert(last_pk);
517     free_packet(&pkt);
518     iobuf_close(a);
519     set_packet_list_mode(save_mode);
520     return rc;
521 }
522
523
524 /****************
525  * Return a string with a printable representation of the user_id.
526  * this string must be freed by m_free.
527  */
528 char*
529 get_user_id_string( u32 *keyid )
530 {
531     user_id_db_t r;
532     char *p;
533     int pass=0;
534     /* try it two times; second pass reads from keyrings */
535     do {
536         for(r=user_id_db; r; r = r->next )
537             if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
538                 p = m_alloc( r->len + 10 );
539                 sprintf(p, "%08lX %.*s", keyid[1], r->len, r->name );
540                 return p;
541             }
542     } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
543     p = m_alloc( 15 );
544     sprintf(p, "%08lX [?]", keyid[1] );
545     return p;
546 }
547
548 char*
549 get_user_id( u32 *keyid, size_t *rn )
550 {
551     user_id_db_t r;
552     char *p;
553     int pass=0;
554     /* try it two times; second pass reads from keyrings */
555     do {
556         for(r=user_id_db; r; r = r->next )
557             if( r->keyid[0] == keyid[0] && r->keyid[1] == keyid[1] ) {
558                 p = m_alloc( r->len );
559                 memcpy(p, r->name, r->len );
560                 *rn = r->len;
561                 return p;
562             }
563     } while( ++pass < 2 && !get_pubkey( NULL, keyid ) );
564     p = m_alloc( 19 );
565     memcpy(p, "[User id not found]", 19 );
566     *rn = 19;
567     return p;
568 }
569
570