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