853c518be2f9b85bdb6e6773d25cd0a5ed3c2b1e
[gnupg.git] / cipher / pubkey.c
1 /* pubkey.c  -  pubkey dispatcher
2  *      Copyright (C) 1998, 1999, 2000, 2001 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;
101
102     i = 0;
103     pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL;
104     pubkey_table[i].name = elg_get_info( pubkey_table[i].algo,
105                                          &pubkey_table[i].npkey,
106                                          &pubkey_table[i].nskey,
107                                          &pubkey_table[i].nenc,
108                                          &pubkey_table[i].nsig,
109                                          &pubkey_table[i].use );
110     pubkey_table[i].generate         = elg_generate;
111     pubkey_table[i].check_secret_key = elg_check_secret_key;
112     pubkey_table[i].encrypt          = elg_encrypt;
113     pubkey_table[i].decrypt          = elg_decrypt;
114     pubkey_table[i].sign             = elg_sign;
115     pubkey_table[i].verify           = elg_verify;
116     pubkey_table[i].get_nbits        = elg_get_nbits;
117     if( !pubkey_table[i].name )
118         BUG();
119     i++;
120     pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL_E;
121     pubkey_table[i].name = elg_get_info( pubkey_table[i].algo,
122                                          &pubkey_table[i].npkey,
123                                          &pubkey_table[i].nskey,
124                                          &pubkey_table[i].nenc,
125                                          &pubkey_table[i].nsig,
126                                          &pubkey_table[i].use );
127     pubkey_table[i].generate         = elg_generate;
128     pubkey_table[i].check_secret_key = elg_check_secret_key;
129     pubkey_table[i].encrypt          = elg_encrypt;
130     pubkey_table[i].decrypt          = elg_decrypt;
131     pubkey_table[i].sign             = elg_sign;
132     pubkey_table[i].verify           = elg_verify;
133     pubkey_table[i].get_nbits        = elg_get_nbits;
134     if( !pubkey_table[i].name )
135         BUG();
136     i++;
137     pubkey_table[i].algo = PUBKEY_ALGO_DSA;
138     pubkey_table[i].name = dsa_get_info( pubkey_table[i].algo,
139                                          &pubkey_table[i].npkey,
140                                          &pubkey_table[i].nskey,
141                                          &pubkey_table[i].nenc,
142                                          &pubkey_table[i].nsig,
143                                          &pubkey_table[i].use );
144     pubkey_table[i].generate         = dsa_generate;
145     pubkey_table[i].check_secret_key = dsa_check_secret_key;
146     pubkey_table[i].encrypt          = dummy_encrypt;
147     pubkey_table[i].decrypt          = dummy_decrypt;
148     pubkey_table[i].sign             = dsa_sign;
149     pubkey_table[i].verify           = dsa_verify;
150     pubkey_table[i].get_nbits        = dsa_get_nbits;
151     if( !pubkey_table[i].name )
152         BUG();
153     i++;
154
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
207     for( ; i < TABLE_SIZE; i++ )
208         pubkey_table[i].name = NULL;
209 }
210
211
212 /****************
213  * Try to load all modules and return true if new modules are available
214  */
215 static int
216 load_pubkey_modules(void)
217 {
218     static int initialized = 0;
219
220     if( !initialized ) {
221         setup_pubkey_table();
222         initialized = 1;
223         return 1;
224     }
225     return 0;
226 }
227
228
229 /****************
230  * Map a string to the pubkey algo
231  */
232 int
233 string_to_pubkey_algo( const char *string )
234 {
235     int i;
236     const char *s;
237
238     do {
239         for(i=0; (s=pubkey_table[i].name); i++ )
240             if( !ascii_strcasecmp( s, string ) )
241                 return pubkey_table[i].algo;
242     } while( load_pubkey_modules() );
243     return 0;
244 }
245
246
247 /****************
248  * Map a pubkey algo to a string
249  */
250 const char *
251 pubkey_algo_to_string( int algo )
252 {
253     int i;
254
255     do {
256         for(i=0; pubkey_table[i].name; i++ )
257             if( pubkey_table[i].algo == algo )
258                 return pubkey_table[i].name;
259     } while( load_pubkey_modules() );
260     return NULL;
261 }
262
263
264 void
265 disable_pubkey_algo( int algo )
266 {
267     int i;
268
269     for(i=0; i < DIM(disabled_algos); i++ ) {
270         if( !disabled_algos[i] || disabled_algos[i] == algo ) {
271             disabled_algos[i] = algo;
272             return;
273         }
274     }
275     log_fatal("can't disable pubkey algo %d: table full\n", algo );
276 }
277
278
279 int
280 check_pubkey_algo( int algo )
281 {
282     return check_pubkey_algo2( algo, 0 );
283 }
284
285 /****************
286  * a use of 0 means: don't care
287  */
288 int
289 check_pubkey_algo2( int algo, unsigned use )
290 {
291     int i;
292
293     do {
294         for(i=0; pubkey_table[i].name; i++ )
295             if( pubkey_table[i].algo == algo ) {
296                 if( (use & PUBKEY_USAGE_SIG)
297                     && !(pubkey_table[i].use & PUBKEY_USAGE_SIG) )
298                     return G10ERR_WR_PUBKEY_ALGO;
299                 if( (use & PUBKEY_USAGE_ENC)
300                     && !(pubkey_table[i].use & PUBKEY_USAGE_ENC) )
301                     return G10ERR_WR_PUBKEY_ALGO;
302
303                 for(i=0; i < DIM(disabled_algos); i++ ) {
304                     if( disabled_algos[i] == algo )
305                         return G10ERR_PUBKEY_ALGO;
306                 }
307                 return 0; /* okay */
308             }
309     } while( load_pubkey_modules() );
310     return G10ERR_PUBKEY_ALGO;
311 }
312
313
314
315
316 /****************
317  * Return the number of public key material numbers
318  */
319 int
320 pubkey_get_npkey( int algo )
321 {
322     int i;
323     do {
324         for(i=0; pubkey_table[i].name; i++ )
325             if( pubkey_table[i].algo == algo )
326                 return pubkey_table[i].npkey;
327     } while( load_pubkey_modules() );
328     return 0;
329 }
330
331 /****************
332  * Return the number of secret key material numbers
333  */
334 int
335 pubkey_get_nskey( int algo )
336 {
337     int i;
338     do {
339         for(i=0; pubkey_table[i].name; i++ )
340             if( pubkey_table[i].algo == algo )
341                 return pubkey_table[i].nskey;
342     } while( load_pubkey_modules() );
343     if( is_RSA(algo) )    /* special hack, so that we are able to */
344         return 6;         /* see the RSA keyids */
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     if( is_RSA(algo) )    /* special hack, so that we are able to */
361         return 1;         /* see the RSA keyids */
362     return 0;
363 }
364
365 /****************
366  * Return the number of encryption material numbers
367  */
368 int
369 pubkey_get_nenc( 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].nenc;
376     } while( load_pubkey_modules() );
377     if( is_RSA(algo) )    /* special hack, so that we are able to */
378         return 1;         /* see the RSA keyids */
379     return 0;
380 }
381
382 /****************
383  * Get the number of nbits from the public key
384  */
385 unsigned
386 pubkey_nbits( int algo, MPI *pkey )
387 {
388     int i;
389
390     do {
391         for(i=0; pubkey_table[i].name; i++ )
392             if( pubkey_table[i].algo == algo )
393                 return (*pubkey_table[i].get_nbits)( algo, pkey );
394     } while( load_pubkey_modules() );
395     if( is_RSA(algo) )  /* we always wanna see the length of a key :-) */
396         return mpi_get_nbits( pkey[0] );
397     return 0;
398 }
399
400
401 int
402 pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors )
403 {
404     int i;
405
406     do {
407         for(i=0; pubkey_table[i].name; i++ )
408             if( pubkey_table[i].algo == algo )
409                 return (*pubkey_table[i].generate)( algo, nbits,
410                                                     skey, retfactors );
411     } while( load_pubkey_modules() );
412     return G10ERR_PUBKEY_ALGO;
413 }
414
415
416 int
417 pubkey_check_secret_key( int algo, MPI *skey )
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].check_secret_key)( algo, skey );
425     } while( load_pubkey_modules() );
426     return G10ERR_PUBKEY_ALGO;
427 }
428
429
430 /****************
431  * This is the interface to the public key encryption.
432  * Encrypt DATA with PKEY and put it into RESARR which
433  * should be an array of MPIs of size PUBKEY_MAX_NENC (or less if the
434  * algorithm allows this - check with pubkey_get_nenc() )
435  */
436 int
437 pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey )
438 {
439     int i, rc;
440
441     if( DBG_CIPHER ) {
442         log_debug("pubkey_encrypt: algo=%d\n", algo );
443         for(i=0; i < pubkey_get_npkey(algo); i++ )
444             log_mpidump("  pkey:", pkey[i] );
445         log_mpidump("  data:", data );
446     }
447
448     do {
449         for(i=0; pubkey_table[i].name; i++ )
450             if( pubkey_table[i].algo == algo ) {
451                 rc = (*pubkey_table[i].encrypt)( algo, resarr, data, pkey );
452                 goto ready;
453             }
454     } while( load_pubkey_modules() );
455     rc = G10ERR_PUBKEY_ALGO;
456   ready:
457     if( !rc && DBG_CIPHER ) {
458         for(i=0; i < pubkey_get_nenc(algo); i++ )
459             log_mpidump("  encr:", resarr[i] );
460     }
461     return rc;
462 }
463
464
465
466 /****************
467  * This is the interface to the public key decryption.
468  * ALGO gives the algorithm to use and this implicitly determines
469  * the size of the arrays.
470  * result is a pointer to a mpi variable which will receive a
471  * newly allocated mpi or NULL in case of an error.
472  */
473 int
474 pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey )
475 {
476     int i, rc;
477
478     *result = NULL; /* so the caller can always do an mpi_free */
479     if( DBG_CIPHER ) {
480         log_debug("pubkey_decrypt: algo=%d\n", algo );
481         for(i=0; i < pubkey_get_nskey(algo); i++ )
482             log_mpidump("  skey:", skey[i] );
483         for(i=0; i < pubkey_get_nenc(algo); i++ )
484             log_mpidump("  data:", data[i] );
485     }
486
487     do {
488         for(i=0; pubkey_table[i].name; i++ )
489             if( pubkey_table[i].algo == algo ) {
490                 rc = (*pubkey_table[i].decrypt)( algo, result, data, skey );
491                 goto ready;
492             }
493     } while( load_pubkey_modules() );
494     rc = G10ERR_PUBKEY_ALGO;
495   ready:
496     if( !rc && DBG_CIPHER ) {
497         log_mpidump(" plain:", *result );
498     }
499     return rc;
500 }
501
502
503 /****************
504  * This is the interface to the public key signing.
505  * Sign data with skey and put the result into resarr which
506  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
507  * algorithm allows this - check with pubkey_get_nsig() )
508  */
509 int
510 pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
511 {
512     int i, rc;
513
514     if( DBG_CIPHER ) {
515         log_debug("pubkey_sign: algo=%d\n", algo );
516         for(i=0; i < pubkey_get_nskey(algo); i++ )
517             log_mpidump("  skey:", skey[i] );
518         log_mpidump("  data:", data );
519     }
520
521     do {
522         for(i=0; pubkey_table[i].name; i++ )
523             if( pubkey_table[i].algo == algo ) {
524                 rc = (*pubkey_table[i].sign)( algo, resarr, data, skey );
525                 goto ready;
526             }
527     } while( load_pubkey_modules() );
528     rc = G10ERR_PUBKEY_ALGO;
529   ready:
530     if( !rc && DBG_CIPHER ) {
531         for(i=0; i < pubkey_get_nsig(algo); i++ )
532             log_mpidump("   sig:", resarr[i] );
533     }
534     return rc;
535 }
536
537 /****************
538  * Verify a public key signature.
539  * Return 0 if the signature is good
540  */
541 int
542 pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
543                     int (*cmp)(void *, MPI), void *opaquev )
544 {
545     int i, rc;
546
547     do {
548         for(i=0; pubkey_table[i].name; i++ )
549             if( pubkey_table[i].algo == algo ) {
550                 rc = (*pubkey_table[i].verify)( algo, hash, data, pkey,
551                                                             cmp, opaquev );
552                 goto ready;
553             }
554     } while( load_pubkey_modules() );
555     rc = G10ERR_PUBKEY_ALGO;
556   ready:
557     return rc;
558 }
559