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