d6d1ff1f262bb955158167a08913107504cba8d6
[gnupg.git] / cipher / pubkey.c
1 /* pubkey.c  -  pubkey dispatcher
2  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
3  *               2004 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <assert.h>
29 #include "util.h"
30 #include "errors.h"
31 #include "mpi.h"
32 #include "cipher.h"
33 #include "elgamal.h"
34 #include "dsa.h"
35 #include "rsa.h"
36
37 #define TABLE_SIZE 10
38
39 struct pubkey_table_s {
40     const char *name;
41     int algo;
42     int npkey;
43     int nskey;
44     int nenc;
45     int nsig;
46     int use;
47     int (*generate)( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
48     int (*check_secret_key)( int algo, MPI *skey );
49     int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey );
50     int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey );
51     int (*sign)( int algo, MPI *resarr, MPI data, MPI *skey );
52     int (*verify)( int algo, MPI hash, MPI *data, MPI *pkey );
53     unsigned (*get_nbits)( int algo, MPI *pkey );
54 };
55
56 static struct pubkey_table_s pubkey_table[TABLE_SIZE];
57 static int disabled_algos[TABLE_SIZE];
58
59
60 #if 0
61 static int
62 dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
63 { log_bug("no generate() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
64
65 static int
66 dummy_check_secret_key( int algo, MPI *skey )
67 { log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
68 #endif
69
70 static int
71 dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
72 { log_bug("no encrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
73
74 static int
75 dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
76 { log_bug("no decrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
77
78 static int
79 dummy_sign( int algo, MPI *resarr, MPI data, MPI *skey )
80 { log_bug("no sign() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
81
82 static int
83 dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey )
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_E;
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             = dummy_sign;
114     pubkey_table[i].verify           = dummy_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_DSA;
120     pubkey_table[i].name = dsa_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         = dsa_generate;
127     pubkey_table[i].check_secret_key = dsa_check_secret_key;
128     pubkey_table[i].encrypt          = dummy_encrypt;
129     pubkey_table[i].decrypt          = dummy_decrypt;
130     pubkey_table[i].sign             = dsa_sign;
131     pubkey_table[i].verify           = dsa_verify;
132     pubkey_table[i].get_nbits        = dsa_get_nbits;
133     if( !pubkey_table[i].name )
134         BUG();
135     i++;
136
137 #ifdef USE_RSA
138     pubkey_table[i].algo = PUBKEY_ALGO_RSA;
139     pubkey_table[i].name = rsa_get_info( pubkey_table[i].algo,
140                                          &pubkey_table[i].npkey,
141                                          &pubkey_table[i].nskey,
142                                          &pubkey_table[i].nenc,
143                                          &pubkey_table[i].nsig,
144                                          &pubkey_table[i].use );
145     pubkey_table[i].generate         = rsa_generate;
146     pubkey_table[i].check_secret_key = rsa_check_secret_key;
147     pubkey_table[i].encrypt          = rsa_encrypt;
148     pubkey_table[i].decrypt          = rsa_decrypt;
149     pubkey_table[i].sign             = rsa_sign;
150     pubkey_table[i].verify           = rsa_verify;
151     pubkey_table[i].get_nbits        = rsa_get_nbits;
152     if( !pubkey_table[i].name )
153         BUG();
154     i++;
155     pubkey_table[i].algo = PUBKEY_ALGO_RSA_E;
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             = dummy_sign;
167     pubkey_table[i].verify           = dummy_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_S;
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          = dummy_encrypt;
182     pubkey_table[i].decrypt          = dummy_decrypt;
183     pubkey_table[i].sign             = rsa_sign;
184     pubkey_table[i].verify           = rsa_verify;
185     pubkey_table[i].get_nbits        = rsa_get_nbits;
186     if( !pubkey_table[i].name )
187         BUG();
188     i++;
189 #endif /* USE_RSA */
190
191     for( ; i < TABLE_SIZE; i++ )
192         pubkey_table[i].name = NULL;
193 }
194
195
196 /****************
197  * Try to load all modules and return true if new modules are available
198  */
199 static int
200 load_pubkey_modules(void)
201 {
202     static int initialized = 0;
203
204     if( !initialized ) {
205         setup_pubkey_table();
206         initialized = 1;
207         return 1;
208     }
209     return 0;
210 }
211
212
213 /****************
214  * Map a string to the pubkey algo
215  */
216 int
217 string_to_pubkey_algo( const char *string )
218 {
219     int i;
220     const char *s;
221
222     do {
223         for(i=0; (s=pubkey_table[i].name); i++ )
224             if( !ascii_strcasecmp( s, string ) )
225                 return pubkey_table[i].algo;
226     } while( load_pubkey_modules() );
227     return 0;
228 }
229
230
231 /****************
232  * Map a pubkey algo to a string
233  */
234 const char *
235 pubkey_algo_to_string( int algo )
236 {
237     int i;
238
239     do {
240         for(i=0; pubkey_table[i].name; i++ )
241             if( pubkey_table[i].algo == algo )
242                 return pubkey_table[i].name;
243     } while( load_pubkey_modules() );
244     return NULL;
245 }
246
247
248 void
249 disable_pubkey_algo( int algo )
250 {
251     int i;
252
253     for(i=0; i < DIM(disabled_algos); i++ ) {
254         if( !disabled_algos[i] || disabled_algos[i] == algo ) {
255             disabled_algos[i] = algo;
256             return;
257         }
258     }
259     log_fatal("can't disable pubkey algo %d: table full\n", algo );
260 }
261
262
263 int
264 check_pubkey_algo( int algo )
265 {
266     return check_pubkey_algo2( algo, 0 );
267 }
268
269 /****************
270  * a use of 0 means: don't care
271  */
272 int
273 check_pubkey_algo2( int algo, unsigned use )
274 {
275     int i;
276
277     do {
278         for(i=0; pubkey_table[i].name; i++ )
279             if( pubkey_table[i].algo == algo ) {
280                 if( (use & PUBKEY_USAGE_SIG)
281                     && !(pubkey_table[i].use & PUBKEY_USAGE_SIG) )
282                     return G10ERR_WR_PUBKEY_ALGO;
283                 if( (use & PUBKEY_USAGE_ENC)
284                     && !(pubkey_table[i].use & PUBKEY_USAGE_ENC) )
285                     return G10ERR_WR_PUBKEY_ALGO;
286
287                 for(i=0; i < DIM(disabled_algos); i++ ) {
288                     if( disabled_algos[i] == algo )
289                         return G10ERR_PUBKEY_ALGO;
290                 }
291                 return 0; /* okay */
292             }
293     } while( load_pubkey_modules() );
294     return G10ERR_PUBKEY_ALGO;
295 }
296
297
298
299
300 /****************
301  * Return the number of public key material numbers
302  */
303 int
304 pubkey_get_npkey( int algo )
305 {
306     int i;
307     do {
308         for(i=0; pubkey_table[i].name; i++ )
309             if( pubkey_table[i].algo == algo )
310                 return pubkey_table[i].npkey;
311     } while( load_pubkey_modules() );
312
313 #ifndef USE_RSA
314     if( is_RSA(algo) )    /* special hack, so that we are able to */
315         return 2;         /* see the RSA keyids */
316 #endif /* USE_RSA */
317
318     if(algo==PUBKEY_ALGO_ELGAMAL)
319       return 3;
320
321     return 0;
322 }
323
324 /****************
325  * Return the number of secret key material numbers
326  */
327 int
328 pubkey_get_nskey( int algo )
329 {
330     int i;
331     do {
332         for(i=0; pubkey_table[i].name; i++ )
333             if( pubkey_table[i].algo == algo )
334                 return pubkey_table[i].nskey;
335     } while( load_pubkey_modules() );
336
337 #ifndef USE_RSA
338     if( is_RSA(algo) )    /* special hack, so that we are able to */
339         return 6;         /* see the RSA keyids */
340 #endif /* USE_RSA */
341
342     if(algo==PUBKEY_ALGO_ELGAMAL)
343       return 4;
344
345     return 0;
346 }
347
348 /****************
349  * Return the number of signature material numbers
350  */
351 int
352 pubkey_get_nsig( int algo )
353 {
354     int i;
355     do {
356         for(i=0; pubkey_table[i].name; i++ )
357             if( pubkey_table[i].algo == algo )
358                 return pubkey_table[i].nsig;
359     } while( load_pubkey_modules() );
360
361 #ifndef USE_RSA
362     if( is_RSA(algo) )    /* special hack, so that we are able to */
363         return 1;         /* see the RSA keyids */
364 #endif /* USE_RSA */
365
366     if(algo==PUBKEY_ALGO_ELGAMAL)
367       return 2;
368
369     return 0;
370 }
371
372 /****************
373  * Return the number of encryption material numbers
374  */
375 int
376 pubkey_get_nenc( int algo )
377 {
378     int i;
379     do {
380         for(i=0; pubkey_table[i].name; i++ )
381             if( pubkey_table[i].algo == algo )
382                 return pubkey_table[i].nenc;
383     } while( load_pubkey_modules() );
384
385 #ifndef USE_RSA
386     if( is_RSA(algo) )    /* special hack, so that we are able to */
387         return 1;         /* see the RSA keyids */
388 #endif /* USE_RSA */
389
390     if(algo==PUBKEY_ALGO_ELGAMAL)
391       return 2;
392
393     return 0;
394 }
395
396 /****************
397  * Get the number of nbits from the public key
398  */
399 unsigned
400 pubkey_nbits( int algo, MPI *pkey )
401 {
402     int i;
403
404     do {
405         for(i=0; pubkey_table[i].name; i++ )
406             if( pubkey_table[i].algo == algo )
407                 return (*pubkey_table[i].get_nbits)( algo, pkey );
408     } while( load_pubkey_modules() );
409
410 #ifndef USE_RSA
411     if( is_RSA(algo) )  /* we always wanna see the length of a key :-) */
412         return mpi_get_nbits( pkey[0] );
413 #endif /* USE_RSA */
414
415     if(algo==PUBKEY_ALGO_ELGAMAL)
416       return mpi_get_nbits(pkey[0]);
417
418     return 0;
419 }
420
421
422 int
423 pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
424 {
425     int i;
426
427     do {
428         for(i=0; pubkey_table[i].name; i++ )
429             if( pubkey_table[i].algo == algo )
430                 return (*pubkey_table[i].generate)( algo, nbits,
431                                                     skey, retfactors );
432     } while( load_pubkey_modules() );
433     return G10ERR_PUBKEY_ALGO;
434 }
435
436
437 int
438 pubkey_check_secret_key( int algo, MPI *skey )
439 {
440     int i;
441
442     do {
443         for(i=0; pubkey_table[i].name; i++ )
444             if( pubkey_table[i].algo == algo )
445                 return (*pubkey_table[i].check_secret_key)( algo, skey );
446     } while( load_pubkey_modules() );
447     return G10ERR_PUBKEY_ALGO;
448 }
449
450
451 /****************
452  * This is the interface to the public key encryption.
453  * Encrypt DATA with PKEY and put it into RESARR which
454  * should be an array of MPIs of size PUBKEY_MAX_NENC (or less if the
455  * algorithm allows this - check with pubkey_get_nenc() )
456  */
457 int
458 pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
459 {
460     int i, rc;
461
462     if( DBG_CIPHER ) {
463         log_debug("pubkey_encrypt: algo=%d\n", algo );
464         for(i=0; i < pubkey_get_npkey(algo); i++ )
465             log_mpidump("  pkey:", pkey[i] );
466         log_mpidump("  data:", data );
467     }
468
469     do {
470         for(i=0; pubkey_table[i].name; i++ )
471             if( pubkey_table[i].algo == algo ) {
472                 rc = (*pubkey_table[i].encrypt)( algo, resarr, data, pkey );
473                 goto ready;
474             }
475     } while( load_pubkey_modules() );
476     rc = G10ERR_PUBKEY_ALGO;
477   ready:
478     if( !rc && DBG_CIPHER ) {
479         for(i=0; i < pubkey_get_nenc(algo); i++ )
480             log_mpidump("  encr:", resarr[i] );
481     }
482     return rc;
483 }
484
485
486
487 /****************
488  * This is the interface to the public key decryption.
489  * ALGO gives the algorithm to use and this implicitly determines
490  * the size of the arrays.
491  * result is a pointer to a mpi variable which will receive a
492  * newly allocated mpi or NULL in case of an error.
493  */
494 int
495 pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
496 {
497     int i, rc;
498
499     *result = NULL; /* so the caller can always do an mpi_free */
500     if( DBG_CIPHER ) {
501         log_debug("pubkey_decrypt: algo=%d\n", algo );
502         for(i=0; i < pubkey_get_nskey(algo); i++ )
503             log_mpidump("  skey:", skey[i] );
504         for(i=0; i < pubkey_get_nenc(algo); i++ )
505             log_mpidump("  data:", data[i] );
506     }
507
508     do {
509         for(i=0; pubkey_table[i].name; i++ )
510             if( pubkey_table[i].algo == algo ) {
511                 rc = (*pubkey_table[i].decrypt)( algo, result, data, skey );
512                 goto ready;
513             }
514     } while( load_pubkey_modules() );
515     rc = G10ERR_PUBKEY_ALGO;
516   ready:
517     if( !rc && DBG_CIPHER ) {
518         log_mpidump(" plain:", *result );
519     }
520     return rc;
521 }
522
523
524 /****************
525  * This is the interface to the public key signing.
526  * Sign data with skey and put the result into resarr which
527  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
528  * algorithm allows this - check with pubkey_get_nsig() )
529  */
530 int
531 pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
532 {
533     int i, rc;
534
535     if( DBG_CIPHER ) {
536         log_debug("pubkey_sign: algo=%d\n", algo );
537         for(i=0; i < pubkey_get_nskey(algo); i++ )
538             log_mpidump("  skey:", skey[i] );
539         log_mpidump("  data:", data );
540     }
541
542     do {
543         for(i=0; pubkey_table[i].name; i++ )
544             if( pubkey_table[i].algo == algo ) {
545                 rc = (*pubkey_table[i].sign)( algo, resarr, data, skey );
546                 goto ready;
547             }
548     } while( load_pubkey_modules() );
549     rc = G10ERR_PUBKEY_ALGO;
550   ready:
551     if( !rc && DBG_CIPHER ) {
552         for(i=0; i < pubkey_get_nsig(algo); i++ )
553             log_mpidump("   sig:", resarr[i] );
554     }
555     return rc;
556 }
557
558 /****************
559  * Verify a public key signature.
560  * Return 0 if the signature is good
561  */
562 int
563 pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey )
564 {
565     int i, rc;
566
567     do {
568         for(i=0; pubkey_table[i].name; i++ )
569             if( pubkey_table[i].algo == algo ) {
570                 rc = (*pubkey_table[i].verify)( algo, hash, data, pkey );
571                 goto ready;
572             }
573     } while( load_pubkey_modules() );
574     rc = G10ERR_PUBKEY_ALGO;
575   ready:
576     return rc;
577 }