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