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