* pubkey.c (setup_pubkey_table): Don't allow signatures to and from
[gnupg.git] / cipher / pubkey.c
1 /* pubkey.c  -  pubkey dispatcher
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG 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  * GnuPG 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 <errno.h>
26 #include <assert.h>
27 #include "util.h"
28 #include "errors.h"
29 #include "mpi.h"
30 #include "cipher.h"
31 #include "elgamal.h"
32 #include "dsa.h"
33 #include "rsa.h"
34
35 #define TABLE_SIZE 10
36
37 struct pubkey_table_s {
38     const char *name;
39     int algo;
40     int npkey;
41     int nskey;
42     int nenc;
43     int nsig;
44     int use;
45     int (*generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
46     int (*check_secret_key)( int algo, MPI *skey );
47     int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey );
48     int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey );
49     int (*sign)( int algo, MPI *resarr, MPI data, MPI *skey );
50     int (*verify)( int algo, MPI hash, MPI *data, MPI *pkey,
51                    int (*cmp)(void *, MPI), void *opaquev );
52     unsigned (*get_nbits)( int algo, MPI *pkey );
53 };
54
55 static struct pubkey_table_s pubkey_table[TABLE_SIZE];
56 static int disabled_algos[TABLE_SIZE];
57
58
59 #if 0
60 static int
61 dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
62 { log_bug("no generate() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
63
64 static int
65 dummy_check_secret_key( int algo, MPI *skey )
66 { log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
67 #endif
68
69 static int
70 dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
71 { log_bug("no encrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
72
73 static int
74 dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
75 { log_bug("no decrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
76
77 static int
78 dummy_sign( int algo, MPI *resarr, MPI data, MPI *skey )
79 { log_bug("no sign() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
80
81 static int
82 dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey,
83                 int (*cmp)(void *, MPI), void *opaquev )
84 { log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
85
86 #if 0
87 static unsigned
88 dummy_get_nbits( int algo, MPI *pkey )
89 { log_bug("no get_nbits() for %d\n", algo ); return 0; }
90 #endif
91
92 /****************
93  * Put the static entries into the table.
94  * This is out constructor function which fill the table
95  * of algorithms with the one we have statically linked.
96  */
97 static void
98 setup_pubkey_table(void)
99 {
100     int i=0;
101
102     pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL;
103     pubkey_table[i].name = elg_get_info( pubkey_table[i].algo,
104                                          &pubkey_table[i].npkey,
105                                          &pubkey_table[i].nskey,
106                                          &pubkey_table[i].nenc,
107                                          &pubkey_table[i].nsig,
108                                          &pubkey_table[i].use );
109     pubkey_table[i].generate         = elg_generate;
110     pubkey_table[i].check_secret_key = elg_check_secret_key;
111     pubkey_table[i].encrypt          = elg_encrypt;
112     pubkey_table[i].decrypt          = elg_decrypt;
113     pubkey_table[i].sign             = elg_sign;
114     pubkey_table[i].verify           = elg_verify;
115     pubkey_table[i].get_nbits        = elg_get_nbits;
116     if( !pubkey_table[i].name )
117         BUG();
118     i++;
119     pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL_E;
120     pubkey_table[i].name = elg_get_info( pubkey_table[i].algo,
121                                          &pubkey_table[i].npkey,
122                                          &pubkey_table[i].nskey,
123                                          &pubkey_table[i].nenc,
124                                          &pubkey_table[i].nsig,
125                                          &pubkey_table[i].use );
126     pubkey_table[i].generate         = elg_generate;
127     pubkey_table[i].check_secret_key = elg_check_secret_key;
128     pubkey_table[i].encrypt          = elg_encrypt;
129     pubkey_table[i].decrypt          = elg_decrypt;
130     pubkey_table[i].sign             = dummy_sign;
131     pubkey_table[i].verify           = dummy_verify;
132     pubkey_table[i].get_nbits        = elg_get_nbits;
133     if( !pubkey_table[i].name )
134         BUG();
135     i++;
136     pubkey_table[i].algo = PUBKEY_ALGO_DSA;
137     pubkey_table[i].name = dsa_get_info( pubkey_table[i].algo,
138                                          &pubkey_table[i].npkey,
139                                          &pubkey_table[i].nskey,
140                                          &pubkey_table[i].nenc,
141                                          &pubkey_table[i].nsig,
142                                          &pubkey_table[i].use );
143     pubkey_table[i].generate         = dsa_generate;
144     pubkey_table[i].check_secret_key = dsa_check_secret_key;
145     pubkey_table[i].encrypt          = dummy_encrypt;
146     pubkey_table[i].decrypt          = dummy_decrypt;
147     pubkey_table[i].sign             = dsa_sign;
148     pubkey_table[i].verify           = dsa_verify;
149     pubkey_table[i].get_nbits        = dsa_get_nbits;
150     if( !pubkey_table[i].name )
151         BUG();
152     i++;
153
154 #ifdef USE_RSA
155     pubkey_table[i].algo = PUBKEY_ALGO_RSA;
156     pubkey_table[i].name = rsa_get_info( pubkey_table[i].algo,
157                                          &pubkey_table[i].npkey,
158                                          &pubkey_table[i].nskey,
159                                          &pubkey_table[i].nenc,
160                                          &pubkey_table[i].nsig,
161                                          &pubkey_table[i].use );
162     pubkey_table[i].generate         = rsa_generate;
163     pubkey_table[i].check_secret_key = rsa_check_secret_key;
164     pubkey_table[i].encrypt          = rsa_encrypt;
165     pubkey_table[i].decrypt          = rsa_decrypt;
166     pubkey_table[i].sign             = rsa_sign;
167     pubkey_table[i].verify           = rsa_verify;
168     pubkey_table[i].get_nbits        = rsa_get_nbits;
169     if( !pubkey_table[i].name )
170         BUG();
171     i++;
172     pubkey_table[i].algo = PUBKEY_ALGO_RSA_E;
173     pubkey_table[i].name = rsa_get_info( pubkey_table[i].algo,
174                                          &pubkey_table[i].npkey,
175                                          &pubkey_table[i].nskey,
176                                          &pubkey_table[i].nenc,
177                                          &pubkey_table[i].nsig,
178                                          &pubkey_table[i].use );
179     pubkey_table[i].generate         = rsa_generate;
180     pubkey_table[i].check_secret_key = rsa_check_secret_key;
181     pubkey_table[i].encrypt          = rsa_encrypt;
182     pubkey_table[i].decrypt          = rsa_decrypt;
183     pubkey_table[i].sign             = dummy_sign;
184     pubkey_table[i].verify           = dummy_verify;
185     pubkey_table[i].get_nbits        = rsa_get_nbits;
186     if( !pubkey_table[i].name )
187         BUG();
188     i++;
189     pubkey_table[i].algo = PUBKEY_ALGO_RSA_S;
190     pubkey_table[i].name = rsa_get_info( pubkey_table[i].algo,
191                                          &pubkey_table[i].npkey,
192                                          &pubkey_table[i].nskey,
193                                          &pubkey_table[i].nenc,
194                                          &pubkey_table[i].nsig,
195                                          &pubkey_table[i].use );
196     pubkey_table[i].generate         = rsa_generate;
197     pubkey_table[i].check_secret_key = rsa_check_secret_key;
198     pubkey_table[i].encrypt          = dummy_encrypt;
199     pubkey_table[i].decrypt          = dummy_decrypt;
200     pubkey_table[i].sign             = rsa_sign;
201     pubkey_table[i].verify           = rsa_verify;
202     pubkey_table[i].get_nbits        = rsa_get_nbits;
203     if( !pubkey_table[i].name )
204         BUG();
205     i++;
206 #endif /* USE_RSA */
207
208     for( ; i < TABLE_SIZE; i++ )
209         pubkey_table[i].name = NULL;
210 }
211
212
213 /****************
214  * Try to load all modules and return true if new modules are available
215  */
216 static int
217 load_pubkey_modules(void)
218 {
219     static int initialized = 0;
220
221     if( !initialized ) {
222         setup_pubkey_table();
223         initialized = 1;
224         return 1;
225     }
226     return 0;
227 }
228
229
230 /****************
231  * Map a string to the pubkey algo
232  */
233 int
234 string_to_pubkey_algo( const char *string )
235 {
236     int i;
237     const char *s;
238
239     do {
240         for(i=0; (s=pubkey_table[i].name); i++ )
241             if( !ascii_strcasecmp( s, string ) )
242                 return pubkey_table[i].algo;
243     } while( load_pubkey_modules() );
244     return 0;
245 }
246
247
248 /****************
249  * Map a pubkey algo to a string
250  */
251 const char *
252 pubkey_algo_to_string( int algo )
253 {
254     int i;
255
256     do {
257         for(i=0; pubkey_table[i].name; i++ )
258             if( pubkey_table[i].algo == algo )
259                 return pubkey_table[i].name;
260     } while( load_pubkey_modules() );
261     return NULL;
262 }
263
264
265 void
266 disable_pubkey_algo( int algo )
267 {
268     int i;
269
270     for(i=0; i < DIM(disabled_algos); i++ ) {
271         if( !disabled_algos[i] || disabled_algos[i] == algo ) {
272             disabled_algos[i] = algo;
273             return;
274         }
275     }
276     log_fatal("can't disable pubkey algo %d: table full\n", algo );
277 }
278
279
280 int
281 check_pubkey_algo( int algo )
282 {
283     return check_pubkey_algo2( algo, 0 );
284 }
285
286 /****************
287  * a use of 0 means: don't care
288  */
289 int
290 check_pubkey_algo2( int algo, unsigned use )
291 {
292     int i;
293
294     do {
295         for(i=0; pubkey_table[i].name; i++ )
296             if( pubkey_table[i].algo == algo ) {
297                 if( (use & PUBKEY_USAGE_SIG)
298                     && !(pubkey_table[i].use & PUBKEY_USAGE_SIG) )
299                     return G10ERR_WR_PUBKEY_ALGO;
300                 if( (use & PUBKEY_USAGE_ENC)
301                     && !(pubkey_table[i].use & PUBKEY_USAGE_ENC) )
302                     return G10ERR_WR_PUBKEY_ALGO;
303
304                 for(i=0; i < DIM(disabled_algos); i++ ) {
305                     if( disabled_algos[i] == algo )
306                         return G10ERR_PUBKEY_ALGO;
307                 }
308                 return 0; /* okay */
309             }
310     } while( load_pubkey_modules() );
311     return G10ERR_PUBKEY_ALGO;
312 }
313
314
315
316
317 /****************
318  * Return the number of public key material numbers
319  */
320 int
321 pubkey_get_npkey( int algo )
322 {
323     int i;
324     do {
325         for(i=0; pubkey_table[i].name; i++ )
326             if( pubkey_table[i].algo == algo )
327                 return pubkey_table[i].npkey;
328     } while( load_pubkey_modules() );
329
330 #ifndef USE_RSA
331     if( is_RSA(algo) )    /* special hack, so that we are able to */
332         return 2;         /* see the RSA keyids */
333 #endif /* USE_RSA */
334
335     if(algo==PUBKEY_ALGO_ELGAMAL)
336       return 3;
337
338     return 0;
339 }
340
341 /****************
342  * Return the number of secret key material numbers
343  */
344 int
345 pubkey_get_nskey( int algo )
346 {
347     int i;
348     do {
349         for(i=0; pubkey_table[i].name; i++ )
350             if( pubkey_table[i].algo == algo )
351                 return pubkey_table[i].nskey;
352     } while( load_pubkey_modules() );
353
354 #ifndef USE_RSA
355     if( is_RSA(algo) )    /* special hack, so that we are able to */
356         return 6;         /* see the RSA keyids */
357 #endif /* USE_RSA */
358
359     if(algo==PUBKEY_ALGO_ELGAMAL)
360       return 4;
361
362     return 0;
363 }
364
365 /****************
366  * Return the number of signature material numbers
367  */
368 int
369 pubkey_get_nsig( int algo )
370 {
371     int i;
372     do {
373         for(i=0; pubkey_table[i].name; i++ )
374             if( pubkey_table[i].algo == algo )
375                 return pubkey_table[i].nsig;
376     } while( load_pubkey_modules() );
377
378 #ifndef USE_RSA
379     if( is_RSA(algo) )    /* special hack, so that we are able to */
380         return 1;         /* see the RSA keyids */
381 #endif /* USE_RSA */
382
383     if(algo==PUBKEY_ALGO_ELGAMAL)
384       return 2;
385
386     return 0;
387 }
388
389 /****************
390  * Return the number of encryption material numbers
391  */
392 int
393 pubkey_get_nenc( int algo )
394 {
395     int i;
396     do {
397         for(i=0; pubkey_table[i].name; i++ )
398             if( pubkey_table[i].algo == algo )
399                 return pubkey_table[i].nenc;
400     } while( load_pubkey_modules() );
401
402 #ifndef USE_RSA
403     if( is_RSA(algo) )    /* special hack, so that we are able to */
404         return 1;         /* see the RSA keyids */
405 #endif /* USE_RSA */
406
407     if(algo==PUBKEY_ALGO_ELGAMAL)
408       return 2;
409
410     return 0;
411 }
412
413 /****************
414  * Get the number of nbits from the public key
415  */
416 unsigned
417 pubkey_nbits( int algo, MPI *pkey )
418 {
419     int i;
420
421     do {
422         for(i=0; pubkey_table[i].name; i++ )
423             if( pubkey_table[i].algo == algo )
424                 return (*pubkey_table[i].get_nbits)( algo, pkey );
425     } while( load_pubkey_modules() );
426
427 #ifndef USE_RSA
428     if( is_RSA(algo) )  /* we always wanna see the length of a key :-) */
429         return mpi_get_nbits( pkey[0] );
430 #endif /* USE_RSA */
431
432     if(algo==PUBKEY_ALGO_ELGAMAL)
433       return mpi_get_nbits(pkey[0]);
434
435     return 0;
436 }
437
438
439 int
440 pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
441 {
442     int i;
443
444     do {
445         for(i=0; pubkey_table[i].name; i++ )
446             if( pubkey_table[i].algo == algo )
447                 return (*pubkey_table[i].generate)( algo, nbits,
448                                                     skey, retfactors );
449     } while( load_pubkey_modules() );
450     return G10ERR_PUBKEY_ALGO;
451 }
452
453
454 int
455 pubkey_check_secret_key( int algo, MPI *skey )
456 {
457     int i;
458
459     do {
460         for(i=0; pubkey_table[i].name; i++ )
461             if( pubkey_table[i].algo == algo )
462                 return (*pubkey_table[i].check_secret_key)( algo, skey );
463     } while( load_pubkey_modules() );
464     return G10ERR_PUBKEY_ALGO;
465 }
466
467
468 /****************
469  * This is the interface to the public key encryption.
470  * Encrypt DATA with PKEY and put it into RESARR which
471  * should be an array of MPIs of size PUBKEY_MAX_NENC (or less if the
472  * algorithm allows this - check with pubkey_get_nenc() )
473  */
474 int
475 pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
476 {
477     int i, rc;
478
479     if( DBG_CIPHER ) {
480         log_debug("pubkey_encrypt: algo=%d\n", algo );
481         for(i=0; i < pubkey_get_npkey(algo); i++ )
482             log_mpidump("  pkey:", pkey[i] );
483         log_mpidump("  data:", data );
484     }
485
486     do {
487         for(i=0; pubkey_table[i].name; i++ )
488             if( pubkey_table[i].algo == algo ) {
489                 rc = (*pubkey_table[i].encrypt)( algo, resarr, data, pkey );
490                 goto ready;
491             }
492     } while( load_pubkey_modules() );
493     rc = G10ERR_PUBKEY_ALGO;
494   ready:
495     if( !rc && DBG_CIPHER ) {
496         for(i=0; i < pubkey_get_nenc(algo); i++ )
497             log_mpidump("  encr:", resarr[i] );
498     }
499     return rc;
500 }
501
502
503
504 /****************
505  * This is the interface to the public key decryption.
506  * ALGO gives the algorithm to use and this implicitly determines
507  * the size of the arrays.
508  * result is a pointer to a mpi variable which will receive a
509  * newly allocated mpi or NULL in case of an error.
510  */
511 int
512 pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
513 {
514     int i, rc;
515
516     *result = NULL; /* so the caller can always do an mpi_free */
517     if( DBG_CIPHER ) {
518         log_debug("pubkey_decrypt: algo=%d\n", algo );
519         for(i=0; i < pubkey_get_nskey(algo); i++ )
520             log_mpidump("  skey:", skey[i] );
521         for(i=0; i < pubkey_get_nenc(algo); i++ )
522             log_mpidump("  data:", data[i] );
523     }
524
525     do {
526         for(i=0; pubkey_table[i].name; i++ )
527             if( pubkey_table[i].algo == algo ) {
528                 rc = (*pubkey_table[i].decrypt)( algo, result, data, skey );
529                 goto ready;
530             }
531     } while( load_pubkey_modules() );
532     rc = G10ERR_PUBKEY_ALGO;
533   ready:
534     if( !rc && DBG_CIPHER ) {
535         log_mpidump(" plain:", *result );
536     }
537     return rc;
538 }
539
540
541 /****************
542  * This is the interface to the public key signing.
543  * Sign data with skey and put the result into resarr which
544  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
545  * algorithm allows this - check with pubkey_get_nsig() )
546  */
547 int
548 pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
549 {
550     int i, rc;
551
552     if( DBG_CIPHER ) {
553         log_debug("pubkey_sign: algo=%d\n", algo );
554         for(i=0; i < pubkey_get_nskey(algo); i++ )
555             log_mpidump("  skey:", skey[i] );
556         log_mpidump("  data:", data );
557     }
558
559     do {
560         for(i=0; pubkey_table[i].name; i++ )
561             if( pubkey_table[i].algo == algo ) {
562                 rc = (*pubkey_table[i].sign)( algo, resarr, data, skey );
563                 goto ready;
564             }
565     } while( load_pubkey_modules() );
566     rc = G10ERR_PUBKEY_ALGO;
567   ready:
568     if( !rc && DBG_CIPHER ) {
569         for(i=0; i < pubkey_get_nsig(algo); i++ )
570             log_mpidump("   sig:", resarr[i] );
571     }
572     return rc;
573 }
574
575 /****************
576  * Verify a public key signature.
577  * Return 0 if the signature is good
578  */
579 int
580 pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
581                     int (*cmp)(void *, MPI), void *opaquev )
582 {
583     int i, rc;
584
585     do {
586         for(i=0; pubkey_table[i].name; i++ )
587             if( pubkey_table[i].algo == algo ) {
588                 rc = (*pubkey_table[i].verify)( algo, hash, data, pkey,
589                                                             cmp, opaquev );
590                 goto ready;
591             }
592     } while( load_pubkey_modules() );
593     rc = G10ERR_PUBKEY_ALGO;
594   ready:
595     return rc;
596 }