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