Upstream sync.
[shishi.git] / crypto / cipher / pubkey.c
bloba0497d6315e9c15613399deaec7fad3f5d77167e
1 /* pubkey.c - pubkey dispatcher
2 * Copyright (C) 1998,1999,2000,2002,2003 Free Software Foundation, Inc.
4 * This file is part of Libgcrypt.
6 * Libgcrypt is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser general Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
11 * Libgcrypt 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 Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
28 #include "g10lib.h"
29 #include "mpi.h"
30 #include "cipher.h"
31 #include "elgamal.h"
32 #include "dsa.h"
33 #include "rsa.h"
34 #include "dynload.h"
36 /* FIXME: use set_lasterr() */
38 #define TABLE_SIZE 10
42 struct pubkey_table_s {
43 const char *name;
44 int algo;
45 int npkey;
46 int nskey;
47 int nenc;
48 int nsig;
49 int use;
50 int (*generate)(int algo, unsigned int nbits, unsigned long use_e,
51 MPI *skey, MPI **retfactors );
52 int (*check_secret_key)( int algo, MPI *skey );
53 int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey, int flags);
54 int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey, int flags);
55 int (*sign)( int algo, MPI *resarr, MPI data, MPI *skey );
56 int (*verify)( int algo, MPI hash, MPI *data, MPI *pkey,
57 int (*cmp)(void *, MPI), void *opaquev );
58 unsigned (*get_nbits)( int algo, MPI *pkey );
61 static struct pubkey_table_s pubkey_table[TABLE_SIZE];
62 static int disabled_algos[TABLE_SIZE];
64 static struct {
65 const char* name; int algo;
66 const char* common_elements;
67 const char* public_elements;
68 const char* secret_elements;
69 const char* grip_elements;
70 } algo_info_table[] = {
71 { "dsa" , PUBKEY_ALGO_DSA , "pqgy", "", "x", "pqgy" },
72 { "rsa" , PUBKEY_ALGO_RSA , "ne", "", "dpqu", "n" },
73 { "elg" , PUBKEY_ALGO_ELGAMAL , "pgy", "", "x", "pgy" },
74 { "openpgp-dsa", PUBKEY_ALGO_DSA , "pqgy", "", "x", "pqgy" },
75 { "openpgp-rsa", PUBKEY_ALGO_RSA , "ne", "", "dpqu" "n"},
76 { "openpgp-elg", PUBKEY_ALGO_ELGAMAL_E , "pgy", "", "x", "pgy" },
77 { "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "pgy", "", "x", "pgy" },
78 { "oid.1.2.840.113549.1.1.1",
79 PUBKEY_ALGO_RSA , "ne", "", "dpqu", "n" },
80 { NULL }
83 static struct {
84 const char* name; int algo;
85 const char* elements;
86 } sig_info_table[] = {
87 { "dsa" , PUBKEY_ALGO_DSA , "rs" },
88 { "rsa" , PUBKEY_ALGO_RSA , "s" },
89 { "elg" , PUBKEY_ALGO_ELGAMAL , "rs" },
90 { "openpgp-dsa" , PUBKEY_ALGO_DSA , "rs" },
91 { "openpgp-rsa" , PUBKEY_ALGO_RSA , "s" },
92 { "openpgp-elg-sig" , PUBKEY_ALGO_ELGAMAL , "rs" },
93 { "oid.1.2.840.113549.1.1.1", PUBKEY_ALGO_RSA , "s" },
94 { NULL }
97 static struct {
98 const char* name; int algo;
99 const char* elements;
100 } enc_info_table[] = {
101 { "elg" , PUBKEY_ALGO_ELGAMAL , "ab" },
102 { "rsa" , PUBKEY_ALGO_RSA , "a" },
103 { "openpgp-rsa" , PUBKEY_ALGO_RSA , "a" },
104 { "openpgp-elg" , PUBKEY_ALGO_ELGAMAL_E , "ab" },
105 { "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "ab" },
106 { "oid.1.2.840.113549.1.1.1", PUBKEY_ALGO_RSA , "a" },
107 { NULL }
111 static int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags);
112 static int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
113 static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
114 int (*cmp)(void *, MPI), void *opaque );
116 static int
117 dummy_generate( int algo, unsigned int nbits, unsigned long dummy,
118 MPI *skey, MPI **retfactors )
119 { log_bug("no generate() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
121 static int
122 dummy_check_secret_key( int algo, MPI *skey )
123 { log_bug("no check_secret_key() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
125 static int
126 dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey, int flags)
127 { log_bug("no encrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
129 static int
130 dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey, int flags)
131 { log_bug("no decrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
133 static int
134 dummy_sign( int algo, MPI *resarr, MPI data, MPI *skey )
135 { log_bug("no sign() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
137 static int
138 dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey,
139 int (*cmp)(void *, MPI), void *opaquev )
140 { log_bug("no verify() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; }
142 static unsigned
143 dummy_get_nbits( int algo, MPI *pkey )
144 { log_bug("no get_nbits() for %d\n", algo ); return 0; }
147 /****************
148 * Put the static entries into the table.
149 * This is out constructor function which fill the table
150 * of algorithms with the one we have statically linked.
152 static void
153 setup_pubkey_table(void)
155 int i;
157 i = 0;
158 pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL;
159 pubkey_table[i].name = _gcry_elg_get_info( pubkey_table[i].algo,
160 &pubkey_table[i].npkey,
161 &pubkey_table[i].nskey,
162 &pubkey_table[i].nenc,
163 &pubkey_table[i].nsig,
164 &pubkey_table[i].use );
165 pubkey_table[i].generate = _gcry_elg_generate;
166 pubkey_table[i].check_secret_key = _gcry_elg_check_secret_key;
167 pubkey_table[i].encrypt = _gcry_elg_encrypt;
168 pubkey_table[i].decrypt = _gcry_elg_decrypt;
169 pubkey_table[i].sign = _gcry_elg_sign;
170 pubkey_table[i].verify = _gcry_elg_verify;
171 pubkey_table[i].get_nbits = _gcry_elg_get_nbits;
172 if( !pubkey_table[i].name )
173 BUG();
174 i++;
175 pubkey_table[i].algo = PUBKEY_ALGO_ELGAMAL_E;
176 pubkey_table[i].name = _gcry_elg_get_info( pubkey_table[i].algo,
177 &pubkey_table[i].npkey,
178 &pubkey_table[i].nskey,
179 &pubkey_table[i].nenc,
180 &pubkey_table[i].nsig,
181 &pubkey_table[i].use );
182 pubkey_table[i].generate = _gcry_elg_generate;
183 pubkey_table[i].check_secret_key = _gcry_elg_check_secret_key;
184 pubkey_table[i].encrypt = _gcry_elg_encrypt;
185 pubkey_table[i].decrypt = _gcry_elg_decrypt;
186 pubkey_table[i].sign = _gcry_elg_sign;
187 pubkey_table[i].verify = _gcry_elg_verify;
188 pubkey_table[i].get_nbits = _gcry_elg_get_nbits;
189 if( !pubkey_table[i].name )
190 BUG();
191 i++;
192 pubkey_table[i].algo = PUBKEY_ALGO_DSA;
193 pubkey_table[i].name = _gcry_dsa_get_info( pubkey_table[i].algo,
194 &pubkey_table[i].npkey,
195 &pubkey_table[i].nskey,
196 &pubkey_table[i].nenc,
197 &pubkey_table[i].nsig,
198 &pubkey_table[i].use );
199 pubkey_table[i].generate = _gcry_dsa_generate;
200 pubkey_table[i].check_secret_key = _gcry_dsa_check_secret_key;
201 pubkey_table[i].encrypt = dummy_encrypt;
202 pubkey_table[i].decrypt = dummy_decrypt;
203 pubkey_table[i].sign = _gcry_dsa_sign;
204 pubkey_table[i].verify = _gcry_dsa_verify;
205 pubkey_table[i].get_nbits = _gcry_dsa_get_nbits;
206 if( !pubkey_table[i].name )
207 BUG();
208 i++;
210 pubkey_table[i].algo = PUBKEY_ALGO_RSA;
211 pubkey_table[i].name = _gcry_rsa_get_info( pubkey_table[i].algo,
212 &pubkey_table[i].npkey,
213 &pubkey_table[i].nskey,
214 &pubkey_table[i].nenc,
215 &pubkey_table[i].nsig,
216 &pubkey_table[i].use );
217 pubkey_table[i].generate = _gcry_rsa_generate;
218 pubkey_table[i].check_secret_key = _gcry_rsa_check_secret_key;
219 pubkey_table[i].encrypt = _gcry_rsa_encrypt;
220 pubkey_table[i].decrypt = _gcry_rsa_decrypt;
221 pubkey_table[i].sign = _gcry_rsa_sign;
222 pubkey_table[i].verify = _gcry_rsa_verify;
223 pubkey_table[i].get_nbits = _gcry_rsa_get_nbits;
224 if( !pubkey_table[i].name )
225 BUG();
226 i++;
227 pubkey_table[i].algo = PUBKEY_ALGO_RSA_E;
228 pubkey_table[i].name = _gcry_rsa_get_info( pubkey_table[i].algo,
229 &pubkey_table[i].npkey,
230 &pubkey_table[i].nskey,
231 &pubkey_table[i].nenc,
232 &pubkey_table[i].nsig,
233 &pubkey_table[i].use );
234 pubkey_table[i].generate = _gcry_rsa_generate;
235 pubkey_table[i].check_secret_key = _gcry_rsa_check_secret_key;
236 pubkey_table[i].encrypt = _gcry_rsa_encrypt;
237 pubkey_table[i].decrypt = _gcry_rsa_decrypt;
238 pubkey_table[i].sign = dummy_sign;
239 pubkey_table[i].verify = dummy_verify;
240 pubkey_table[i].get_nbits = _gcry_rsa_get_nbits;
241 if( !pubkey_table[i].name )
242 BUG();
243 i++;
244 pubkey_table[i].algo = PUBKEY_ALGO_RSA_S;
245 pubkey_table[i].name = _gcry_rsa_get_info( pubkey_table[i].algo,
246 &pubkey_table[i].npkey,
247 &pubkey_table[i].nskey,
248 &pubkey_table[i].nenc,
249 &pubkey_table[i].nsig,
250 &pubkey_table[i].use );
251 pubkey_table[i].generate = _gcry_rsa_generate;
252 pubkey_table[i].check_secret_key = _gcry_rsa_check_secret_key;
253 pubkey_table[i].encrypt = dummy_encrypt;
254 pubkey_table[i].decrypt = dummy_decrypt;
255 pubkey_table[i].sign = _gcry_rsa_sign;
256 pubkey_table[i].verify = _gcry_rsa_verify;
257 pubkey_table[i].get_nbits = _gcry_rsa_get_nbits;
258 if( !pubkey_table[i].name )
259 BUG();
260 i++;
262 for( ; i < TABLE_SIZE; i++ )
263 pubkey_table[i].name = NULL;
266 static void
267 release_mpi_array( MPI *array )
269 for( ; *array; array++ ) {
270 mpi_free(*array);
271 *array = NULL;
275 /****************
276 * Try to load all modules and return true if new modules are available
278 static int
279 load_pubkey_modules(void)
281 static int initialized = 0;
282 static int done = 0;
283 void *context = NULL;
284 struct pubkey_table_s *ct;
285 int ct_idx;
286 int i;
287 const char *name;
288 int any = 0;
291 if( !initialized ) {
292 _gcry_cipher_modules_constructor();
293 setup_pubkey_table();
294 initialized = 1;
295 return 1;
297 if( done )
298 return 0;
299 done = 1;
300 for(ct_idx=0, ct = pubkey_table; ct_idx < TABLE_SIZE; ct_idx++,ct++ ) {
301 if( !ct->name )
302 break;
304 if( ct_idx >= TABLE_SIZE-1 )
305 BUG(); /* table already full */
306 /* now load all extensions */
307 while( (name = _gcry_enum_gnupgext_pubkeys( &context, &ct->algo,
308 &ct->npkey, &ct->nskey, &ct->nenc,
309 &ct->nsig, &ct->use,
310 &ct->generate,
311 &ct->check_secret_key,
312 &ct->encrypt,
313 &ct->decrypt,
314 &ct->sign,
315 &ct->verify,
316 &ct->get_nbits )) ) {
317 for(i=0; pubkey_table[i].name; i++ )
318 if( pubkey_table[i].algo == ct->algo )
319 break;
320 if( pubkey_table[i].name ) {
321 log_info("skipping pubkey %d: already loaded\n", ct->algo );
322 continue;
325 if( !ct->generate ) ct->generate = dummy_generate;
326 if( !ct->check_secret_key ) ct->check_secret_key =
327 dummy_check_secret_key;
328 if( !ct->encrypt ) ct->encrypt = dummy_encrypt;
329 if( !ct->decrypt ) ct->decrypt = dummy_decrypt;
330 if( !ct->sign ) ct->sign = dummy_sign;
331 if( !ct->verify ) ct->verify = dummy_verify;
332 if( !ct->get_nbits ) ct->get_nbits= dummy_get_nbits;
333 /* put it into the table */
334 if( _gcry_log_verbosity( 2 ) )
335 log_info("loaded pubkey %d (%s)\n", ct->algo, name);
336 ct->name = name;
337 ct_idx++;
338 ct++;
339 any = 1;
340 /* check whether there are more available table slots */
341 if( ct_idx >= TABLE_SIZE-1 ) {
342 log_info("pubkey table full; ignoring other extensions\n");
343 break;
346 _gcry_enum_gnupgext_pubkeys( &context, NULL, NULL, NULL, NULL, NULL, NULL,
347 NULL, NULL, NULL, NULL, NULL, NULL, NULL );
348 return any;
352 /****************
353 * Map a string to the pubkey algo
356 gcry_pk_map_name( const char *string )
358 int i;
359 const char *s;
361 do {
362 for(i=0; (s=pubkey_table[i].name); i++ )
363 if( !stricmp( s, string ) )
364 return pubkey_table[i].algo;
365 } while( load_pubkey_modules() );
366 return 0;
370 /****************
371 * Map a pubkey algo to a string
373 const char *
374 gcry_pk_algo_name( int algo )
376 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].name;
382 } while( load_pubkey_modules() );
383 return NULL;
387 static void
388 disable_pubkey_algo( int algo )
390 int i;
392 for(i=0; i < DIM(disabled_algos); i++ ) {
393 if( !disabled_algos[i] || disabled_algos[i] == algo ) {
394 disabled_algos[i] = algo;
395 return;
398 log_fatal("can't disable pubkey algo %d: table full\n", algo );
402 /****************
403 * a use of 0 means: don't care
405 static int
406 check_pubkey_algo( int algo, unsigned use )
408 int i;
410 do {
411 for(i=0; pubkey_table[i].name; i++ )
412 if( pubkey_table[i].algo == algo ) {
413 if( (use & GCRY_PK_USAGE_SIGN)
414 && !(pubkey_table[i].use & GCRY_PK_USAGE_SIGN) )
415 return GCRYERR_WRONG_PK_ALGO;
416 if( (use & GCRY_PK_USAGE_ENCR)
417 && !(pubkey_table[i].use & GCRY_PK_USAGE_ENCR) )
418 return GCRYERR_WRONG_PK_ALGO;
420 for(i=0; i < DIM(disabled_algos); i++ ) {
421 if( disabled_algos[i] == algo )
422 return GCRYERR_INV_PK_ALGO;
424 return 0; /* okay */
426 } while( load_pubkey_modules() );
427 return GCRYERR_INV_PK_ALGO;
433 /****************
434 * Return the number of public key material numbers
436 static int
437 pubkey_get_npkey( int algo )
439 int i;
440 do {
441 for(i=0; pubkey_table[i].name; i++ )
442 if( pubkey_table[i].algo == algo )
443 return pubkey_table[i].npkey;
444 } while( load_pubkey_modules() );
445 return 0;
448 /****************
449 * Return the number of secret key material numbers
451 static int
452 pubkey_get_nskey( int algo )
454 int i;
455 do {
456 for(i=0; pubkey_table[i].name; i++ )
457 if( pubkey_table[i].algo == algo )
458 return pubkey_table[i].nskey;
459 } while( load_pubkey_modules() );
460 return 0;
463 /****************
464 * Return the number of signature material numbers
466 static int
467 pubkey_get_nsig( int algo )
469 int i;
470 do {
471 for(i=0; pubkey_table[i].name; i++ )
472 if( pubkey_table[i].algo == algo )
473 return pubkey_table[i].nsig;
474 } while( load_pubkey_modules() );
475 return 0;
478 /****************
479 * Return the number of encryption material numbers
481 static int
482 pubkey_get_nenc( int algo )
484 int i;
485 do {
486 for(i=0; pubkey_table[i].name; i++ )
487 if( pubkey_table[i].algo == algo )
488 return pubkey_table[i].nenc;
489 } while( load_pubkey_modules() );
490 return 0;
494 static int
495 pubkey_generate( int algo, unsigned int nbits, unsigned long use_e,
496 MPI *skey, MPI **retfactors )
498 int i;
500 do {
501 for(i=0; pubkey_table[i].name; i++ )
502 if( pubkey_table[i].algo == algo )
503 return (*pubkey_table[i].generate)( algo, nbits, use_e,
504 skey, retfactors );
505 } while( load_pubkey_modules() );
506 return GCRYERR_INV_PK_ALGO;
510 static int
511 pubkey_check_secret_key( int algo, MPI *skey )
513 int i;
515 do {
516 for(i=0; pubkey_table[i].name; i++ )
517 if( pubkey_table[i].algo == algo )
518 return (*pubkey_table[i].check_secret_key)( algo, skey );
519 } while( load_pubkey_modules() );
520 return GCRYERR_INV_PK_ALGO;
524 /****************
525 * This is the interface to the public key encryption.
526 * Encrypt DATA with PKEY and put it into RESARR which
527 * should be an array of MPIs of size PUBKEY_MAX_NENC (or less if the
528 * algorithm allows this - check with pubkey_get_nenc() )
530 static int
531 pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey,
532 int flags )
534 int i, rc;
536 if( DBG_CIPHER ) {
537 log_debug("pubkey_encrypt: algo=%d\n", algo );
538 for(i=0; i < pubkey_get_npkey(algo); i++ )
539 log_mpidump(" pkey:", pkey[i] );
540 log_mpidump(" data:", data );
543 do {
544 for(i=0; pubkey_table[i].name; i++ )
545 if( pubkey_table[i].algo == algo ) {
546 rc = (*pubkey_table[i].encrypt)( algo, resarr, data, pkey, flags);
547 goto ready;
549 } while( load_pubkey_modules() );
550 rc = GCRYERR_INV_PK_ALGO;
551 ready:
552 if( !rc && DBG_CIPHER ) {
553 for(i=0; i < pubkey_get_nenc(algo); i++ )
554 log_mpidump(" encr:", resarr[i] );
556 return rc;
561 /****************
562 * This is the interface to the public key decryption.
563 * ALGO gives the algorithm to use and this implicitly determines
564 * the size of the arrays.
565 * result is a pointer to a mpi variable which will receive a
566 * newly allocated mpi or NULL in case of an error.
568 static int
569 pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey,
570 int flags)
572 int i, rc;
574 *result = NULL; /* so the caller can always do a mpi_free */
575 if( DBG_CIPHER ) {
576 log_debug("pubkey_decrypt: algo=%d\n", algo );
577 for(i=0; i < pubkey_get_nskey(algo); i++ )
578 log_mpidump(" skey:", skey[i] );
579 for(i=0; i < pubkey_get_nenc(algo); i++ )
580 log_mpidump(" data:", data[i] );
583 do {
584 for(i=0; pubkey_table[i].name; i++ )
585 if( pubkey_table[i].algo == algo ) {
586 rc = (*pubkey_table[i].decrypt)( algo, result, data, skey, flags );
587 goto ready;
589 } while( load_pubkey_modules() );
590 rc = GCRYERR_INV_PK_ALGO;
591 ready:
592 if( !rc && DBG_CIPHER ) {
593 log_mpidump(" plain:", *result );
595 return rc;
599 /****************
600 * This is the interface to the public key signing.
601 * Sign data with skey and put the result into resarr which
602 * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
603 * algorithm allows this - check with pubkey_get_nsig() )
605 static int
606 pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
608 int i, rc;
610 if( DBG_CIPHER ) {
611 log_debug("pubkey_sign: algo=%d\n", algo );
612 for(i=0; i < pubkey_get_nskey(algo); i++ )
613 log_mpidump(" skey:", skey[i] );
614 log_mpidump(" data:", data );
617 do {
618 for(i=0; pubkey_table[i].name; i++ )
619 if( pubkey_table[i].algo == algo ) {
620 rc = (*pubkey_table[i].sign)( algo, resarr, data, skey );
621 goto ready;
623 } while( load_pubkey_modules() );
624 rc = GCRYERR_INV_PK_ALGO;
625 ready:
626 if( !rc && DBG_CIPHER ) {
627 for(i=0; i < pubkey_get_nsig(algo); i++ )
628 log_mpidump(" sig:", resarr[i] );
630 return rc;
633 /****************
634 * Verify a public key signature.
635 * Return 0 if the signature is good
637 static int
638 pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
639 int (*cmp)(void *, MPI), void *opaquev )
641 int i, rc;
643 if( DBG_CIPHER ) {
644 log_debug("pubkey_verify: algo=%d\n", algo );
645 for(i=0; i < pubkey_get_npkey(algo); i++ )
646 log_mpidump(" pkey:", pkey[i] );
647 for(i=0; i < pubkey_get_nsig(algo); i++ )
648 log_mpidump(" sig:", data[i] );
649 log_mpidump(" hash:", hash );
652 do {
653 for(i=0; pubkey_table[i].name; i++ )
654 if( pubkey_table[i].algo == algo ) {
655 rc = (*pubkey_table[i].verify)( algo, hash, data, pkey,
656 cmp, opaquev );
657 goto ready;
659 } while( load_pubkey_modules() );
660 rc = GCRYERR_INV_PK_ALGO;
661 ready:
662 return rc;
667 /****************
668 * Convert a S-Exp with either a private or a public key to our
669 * internal format. Currently we do only support the following
670 * algorithms:
671 * dsa
672 * rsa
673 * openpgp-dsa
674 * openpgp-rsa
675 * openpgp-elg
676 * openpgp-elg-sig
677 * Provide a SE with the first element be either "private-key" or
678 * or "public-key". the followed by a list with its first element
679 * be one of the above algorithm identifiers and the following
680 * elements are pairs with parameter-id and value.
681 * NOTE: we look through the list to find a list beginning with
682 * "private-key" or "public-key" - the first one found is used.
684 * FIXME: Allow for encrypted secret keys here.
686 * Returns: A pointer to an allocated array of MPIs if the return value is
687 * zero; the caller has to release this array.
689 * Example of a DSA public key:
690 * (private-key
691 * (dsa
692 * (p <mpi>)
693 * (g <mpi>)
694 * (y <mpi>)
695 * (x <mpi>)
698 * The <mpi> are expected to be in GCRYMPI_FMT_USG
700 static int
701 sexp_to_key( GCRY_SEXP sexp, int want_private, MPI **retarray,
702 int *retalgo, int *r_algotblidx)
704 GCRY_SEXP list, l2;
705 const char *name;
706 const char *s;
707 size_t n;
708 int i, idx;
709 int algo;
710 const char *elems1, *elems2;
711 GCRY_MPI *array;
713 /* check that the first element is valid */
714 list = gcry_sexp_find_token( sexp, want_private? "private-key"
715 :"public-key", 0 );
716 if( !list )
717 return GCRYERR_INV_OBJ; /* Does not contain a public- or private-key object */
718 l2 = gcry_sexp_cadr( list );
719 gcry_sexp_release ( list );
720 list = l2;
721 name = gcry_sexp_nth_data( list, 0, &n );
722 if( !name ) {
723 gcry_sexp_release ( list );
724 return GCRYERR_INV_OBJ; /* invalid structure of object */
726 for(i=0; (s=algo_info_table[i].name); i++ ) {
727 if( strlen(s) == n && !memcmp( s, name, n ) )
728 break;
730 if( !s ) {
731 gcry_sexp_release ( list );
732 return GCRYERR_INV_PK_ALGO; /* unknown algorithm */
734 if (r_algotblidx)
735 *r_algotblidx = i;
736 algo = algo_info_table[i].algo;
737 elems1 = algo_info_table[i].common_elements;
738 elems2 = want_private? algo_info_table[i].secret_elements
739 : algo_info_table[i].public_elements;
740 array = gcry_calloc( strlen(elems1)+strlen(elems2)+1, sizeof *array );
741 if( !array ) {
742 gcry_sexp_release ( list );
743 return GCRYERR_NO_MEM;
746 idx = 0;
747 for(s=elems1; *s; s++, idx++ ) {
748 l2 = gcry_sexp_find_token( list, s, 1 );
749 if( !l2 ) {
750 for(i=0; i<idx; i++)
751 gcry_free( array[i] );
752 gcry_free( array );
753 gcry_sexp_release ( list );
754 return GCRYERR_NO_OBJ; /* required parameter not found */
756 array[idx] = gcry_sexp_nth_mpi( l2, 1, GCRYMPI_FMT_USG );
757 gcry_sexp_release ( l2 );
758 if( !array[idx] ) {
759 for(i=0; i<idx; i++)
760 gcry_free( array[i] );
761 gcry_free( array );
762 gcry_sexp_release ( list );
763 return GCRYERR_INV_OBJ; /* required parameter is invalid */
766 for(s=elems2; *s; s++, idx++ ) {
767 l2 = gcry_sexp_find_token( list, s, 1 );
768 if( !l2 ) {
769 for(i=0; i<idx; i++)
770 gcry_free( array[i] );
771 gcry_free( array );
772 gcry_sexp_release ( list );
773 return GCRYERR_NO_OBJ; /* required parameter not found */
775 array[idx] = gcry_sexp_nth_mpi( l2, 1, GCRYMPI_FMT_USG );
776 gcry_sexp_release ( l2 );
777 if( !array[idx] ) {
778 for(i=0; i<idx; i++)
779 gcry_free( array[i] );
780 gcry_free( array );
781 gcry_sexp_release ( list );
782 return GCRYERR_INV_OBJ; /* required parameter is invalid */
786 gcry_sexp_release ( list );
787 *retarray = array;
788 *retalgo = algo;
790 return 0;
793 static int
794 sexp_to_sig( GCRY_SEXP sexp, MPI **retarray, int *retalgo)
796 GCRY_SEXP list, l2;
797 const char *name;
798 const char *s;
799 size_t n;
800 int i, idx;
801 int algo;
802 const char *elems;
803 GCRY_MPI *array;
805 /* check that the first element is valid */
806 list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
807 if( !list )
808 return GCRYERR_INV_OBJ; /* Does not contain a signature value object */
809 l2 = gcry_sexp_cadr( list );
810 gcry_sexp_release ( list );
811 list = l2;
812 if( !list )
813 return GCRYERR_NO_OBJ; /* no cadr for the sig object */
814 name = gcry_sexp_nth_data( list, 0, &n );
815 if( !name ) {
816 gcry_sexp_release ( list );
817 return GCRYERR_INV_OBJ; /* invalid structure of object */
819 for(i=0; (s=sig_info_table[i].name); i++ ) {
820 if( strlen(s) == n && !memcmp( s, name, n ) )
821 break;
823 if( !s ) {
824 gcry_sexp_release ( list );
825 return GCRYERR_INV_PK_ALGO; /* unknown algorithm */
827 algo = sig_info_table[i].algo;
828 elems = sig_info_table[i].elements;
829 array = gcry_calloc( (strlen(elems)+1) , sizeof *array );
830 if( !array ) {
831 gcry_sexp_release ( list );
832 return GCRYERR_NO_MEM;
835 idx = 0;
836 for(s=elems; *s; s++, idx++ ) {
837 l2 = gcry_sexp_find_token( list, s, 1 );
838 if( !l2 ) {
839 gcry_free( array );
840 gcry_sexp_release ( list );
841 return GCRYERR_NO_OBJ; /* required parameter not found */
843 array[idx] = gcry_sexp_nth_mpi( l2, 1, GCRYMPI_FMT_USG );
844 gcry_sexp_release ( l2 );
845 if( !array[idx] ) {
846 gcry_free( array );
847 gcry_sexp_release ( list );
848 return GCRYERR_INV_OBJ; /* required parameter is invalid */
852 gcry_sexp_release ( list );
853 *retarray = array;
854 *retalgo = algo;
856 return 0;
860 /****************
861 * Take sexp and return an array of MPI as used for our internal decrypt
862 * function.
863 * s_data = (enc-val
864 * [(flags [pkcs1])
865 * (<algo>
866 * (<param_name1> <mpi>)
867 * ...
868 * (<param_namen> <mpi>)
869 * ))
870 * RET_MODERN is set to true when at least an empty flags list has been found.
872 static int
873 sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo,
874 int *ret_modern, int *ret_want_pkcs1,
875 int *flags)
877 GCRY_SEXP list, l2;
878 const char *name;
879 const char *s;
880 size_t n;
881 int i, idx;
882 int algo;
883 int parsed_flags = 0;
884 const char *elems;
885 GCRY_MPI *array;
887 *ret_want_pkcs1 = 0;
888 *ret_modern = 0;
889 /* check that the first element is valid */
890 list = gcry_sexp_find_token( sexp, "enc-val" , 0 );
891 if( !list )
892 return GCRYERR_INV_OBJ; /* Does not contain a encrypted value object */
893 l2 = gcry_sexp_nth (list, 1);
894 if (!l2 ) {
895 gcry_sexp_release (list);
896 return GCRYERR_NO_OBJ; /* no cdr for the data object */
898 name = gcry_sexp_nth_data (l2, 0, &n);
899 if (!name) {
900 gcry_sexp_release (l2);
901 gcry_sexp_release (list);
902 return GCRYERR_INV_OBJ; /* invalid structure of object */
904 if ( n == 5 && !memcmp (name, "flags", 5)) {
905 /* There is a flags element - process it */
906 const char *s;
908 *ret_modern = 1;
909 for (i=gcry_sexp_length (l2)-1; i > 0; i--)
911 s = gcry_sexp_nth_data (l2, i, &n);
912 if (!s)
913 ; /* not a data element - ignore */
914 else if ( n == 3 && !memcmp (s, "raw", 3))
915 ; /* just a dummy because it is the default */
916 else if ( n == 5 && !memcmp (s, "pkcs1", 5))
917 *ret_want_pkcs1 = 1;
918 else if ( n == 11 && !memcmp (s, "no-blinding", 11))
919 parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
920 else
922 gcry_sexp_release (l2);
923 gcry_sexp_release (list);
924 return GCRYERR_INV_FLAG;
928 /* Get the next which has the actual data */
929 gcry_sexp_release (l2);
930 l2 = gcry_sexp_nth (list, 2);
931 if (!l2 ) {
932 gcry_sexp_release (list);
933 return GCRYERR_NO_OBJ; /* no cdr for the data object */
935 name = gcry_sexp_nth_data (l2, 0, &n);
936 if (!name) {
937 gcry_sexp_release (l2);
938 gcry_sexp_release (list);
939 return GCRYERR_INV_OBJ; /* invalid structure of object */
942 gcry_sexp_release (list);
943 list = l2; l2 = NULL;
945 for(i=0; (s=enc_info_table[i].name); i++ ) {
946 if( strlen(s) == n && !memcmp( s, name, n ) )
947 break;
949 if( !s ) {
950 gcry_sexp_release (list);
951 return GCRYERR_INV_PK_ALGO; /* unknown algorithm */
954 algo = enc_info_table[i].algo;
955 elems = enc_info_table[i].elements;
956 array = gcry_calloc( (strlen(elems)+1) , sizeof *array );
957 if( !array ) {
958 gcry_sexp_release ( list );
959 return GCRYERR_NO_MEM;
962 idx = 0;
963 for(s=elems; *s; s++, idx++ ) {
964 l2 = gcry_sexp_find_token( list, s, 1 );
965 if( !l2 ) {
966 gcry_free( array );
967 gcry_sexp_release ( list );
968 return GCRYERR_NO_OBJ; /* required parameter not found */
970 array[idx] = gcry_sexp_nth_mpi( l2, 1, GCRYMPI_FMT_USG );
971 gcry_sexp_release ( l2 );
972 if( !array[idx] ) {
973 gcry_free( array );
974 gcry_sexp_release ( list );
975 return GCRYERR_INV_OBJ; /* required parameter is invalid */
979 gcry_sexp_release ( list );
980 *retarray = array;
981 *retalgo = algo;
983 *flags = parsed_flags;
985 return 0;
988 /* Take the hash value and convert into an MPI, suitable for for
989 passing to the low level functions. We currently support the
990 old style way of passing just a MPI and the modern interface which
991 allows to pass flags so that we can choose between raw and pkcs1
992 padding - may be more padding options later.
994 (<mpi>)
996 (data
997 [(flags [pkcs1])]
998 [(hash <algo> <value>)]
999 [(value <text>)]
1002 Either the VALUE or the HASH element must be present for use
1003 with signatures. VALUE is used for encryption.
1005 NBITS is the length of the key in bits.
1008 static int
1009 sexp_data_to_mpi (GcrySexp input, unsigned int nbits, GcryMPI *ret_mpi,
1010 int for_encryption, int *flags)
1012 int rc = 0;
1013 GcrySexp ldata, lhash, lvalue;
1014 int i;
1015 size_t n;
1016 const char *s;
1017 int is_raw = 0, is_pkcs1 = 0, unknown_flag=0;
1018 int parsed_flags = 0, dummy_flags;
1020 if (! flags)
1021 flags = &dummy_flags;
1023 *ret_mpi = NULL;
1024 ldata = gcry_sexp_find_token (input, "data", 0);
1025 if (!ldata)
1026 { /* assume old style */
1027 *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1028 return *ret_mpi? 0 : GCRYERR_INV_OBJ;
1031 /* see whether there is a flags object */
1033 GcrySexp lflags = gcry_sexp_find_token (ldata, "flags", 0);
1034 if (lflags)
1035 { /* parse the flags list. */
1036 for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1038 s = gcry_sexp_nth_data (lflags, i, &n);
1039 if (!s)
1040 ; /* not a data element*/
1041 else if ( n == 3 && !memcmp (s, "raw", 3))
1042 is_raw = 1;
1043 else if ( n == 5 && !memcmp (s, "pkcs1", 5))
1044 is_pkcs1 = 1;
1045 else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1046 parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1047 else
1048 unknown_flag = 1;
1050 gcry_sexp_release (lflags);
1054 if (!is_pkcs1 && !is_raw)
1055 is_raw = 1; /* default to raw */
1057 /* Get HASH or MPI */
1058 lhash = gcry_sexp_find_token (ldata, "hash", 0);
1059 lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1061 if (!(!lhash ^ !lvalue))
1062 rc = GCRYERR_INV_OBJ; /* none or both given */
1063 else if (unknown_flag)
1064 rc = GCRYERR_INV_FLAG;
1065 else if (is_raw && is_pkcs1 && !for_encryption)
1066 rc = GCRYERR_CONFLICT;
1067 else if (is_raw && lvalue)
1069 *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1070 if (!*ret_mpi)
1071 rc = GCRYERR_INV_OBJ;
1073 else if (is_pkcs1 && lvalue && for_encryption)
1074 { /* create pkcs#1 block type 2 padding */
1075 unsigned char *frame = NULL;
1076 size_t nframe = (nbits+7) / 8;
1077 const void * value;
1078 size_t valuelen;
1079 unsigned char *p;
1081 if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1082 rc = GCRYERR_INV_OBJ;
1083 else if (valuelen + 7 > nframe || !nframe)
1085 /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1086 rc = GCRYERR_TOO_SHORT; /* the key is too short */
1088 else if ( !(frame = gcry_malloc_secure (nframe)))
1089 rc = GCRYERR_NO_MEM;
1090 else
1092 n = 0;
1093 frame[n++] = 0;
1094 frame[n++] = 2; /* block type */
1095 i = nframe - 3 - valuelen;
1096 assert (i > 0);
1097 p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
1098 /* replace zero bytes by new values*/
1099 for (;;)
1101 int j, k;
1102 unsigned char *pp;
1104 /* count the zero bytes */
1105 for (j=k=0; j < i; j++)
1107 if (!p[j])
1108 k++;
1110 if (!k)
1111 break; /* okay: no (more) zero bytes */
1113 k += k/128; /* better get some more */
1114 pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
1115 for (j=0; j < i && k; j++)
1117 if (!p[j])
1118 p[j] = pp[--k];
1120 gcry_free (pp);
1122 memcpy (frame+n, p, i);
1123 n += i;
1124 gcry_free (p);
1126 frame[n++] = 0;
1127 memcpy (frame+n, value, valuelen);
1128 n += valuelen;
1129 assert (n == nframe);
1131 gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, &nframe);
1134 gcry_free(frame);
1136 else if (is_pkcs1 && lhash && !for_encryption)
1137 { /* create pkcs#1 block type 1 padding */
1138 if (gcry_sexp_length (lhash) != 3)
1139 rc = GCRYERR_INV_OBJ;
1140 else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1141 rc = GCRYERR_INV_OBJ;
1142 else
1144 static struct { const char *name; int algo; } hashnames[] =
1145 { { "sha1", GCRY_MD_SHA1 },
1146 { "md5", GCRY_MD_MD5 },
1147 { "rmd160", GCRY_MD_RMD160 },
1148 { "sha256", GCRY_MD_SHA256 },
1149 { "sha384", GCRY_MD_SHA384 },
1150 { "sha512", GCRY_MD_SHA512 },
1151 { "md2", GCRY_MD_MD2 },
1152 { "md4", GCRY_MD_MD4 },
1153 { "tiger", GCRY_MD_TIGER },
1154 { "haval", GCRY_MD_HAVAL },
1155 { NULL }
1157 int algo;
1158 byte asn[100];
1159 byte *frame = NULL;
1160 size_t nframe = (nbits+7) / 8;
1161 const void * value;
1162 size_t valuelen;
1163 size_t asnlen, dlen;
1165 for (i=0; hashnames[i].name; i++)
1167 if ( strlen (hashnames[i].name) == n
1168 && !memcmp (hashnames[i].name, s, n))
1169 break;
1172 algo = hashnames[i].algo;
1173 asnlen = DIM(asn);
1174 dlen = gcry_md_get_algo_dlen (algo);
1176 if (!hashnames[i].name)
1177 rc = GCRYERR_INV_MD_ALGO;
1178 else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1179 || !valuelen )
1180 rc = GCRYERR_INV_OBJ;
1181 else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
1182 rc = GCRYERR_NOT_IMPL; /* we don't have all of the above algos */
1183 else if ( valuelen != dlen )
1185 /* hash value does not match the length of digest for
1186 the given algo */
1187 rc = GCRYERR_CONFLICT;
1189 else if( !dlen || dlen + asnlen + 4 > nframe)
1191 /* can't encode an DLEN byte digest MD into a NFRAME byte frame */
1192 rc = GCRYERR_TOO_SHORT;
1194 else if ( !(frame = gcry_malloc (nframe)) )
1195 rc = GCRYERR_NO_MEM;
1196 else
1197 { /* assemble the pkcs#1 block type 1 */
1198 n = 0;
1199 frame[n++] = 0;
1200 frame[n++] = 1; /* block type */
1201 i = nframe - valuelen - asnlen - 3 ;
1202 assert (i > 1);
1203 memset (frame+n, 0xff, i );
1204 n += i;
1205 frame[n++] = 0;
1206 memcpy (frame+n, asn, asnlen);
1207 n += asnlen;
1208 memcpy (frame+n, value, valuelen );
1209 n += valuelen;
1210 assert (n == nframe);
1212 /* convert it into an MPI */
1213 gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, &nframe);
1216 gcry_free (frame);
1219 else
1220 rc = GCRYERR_CONFLICT;
1222 gcry_sexp_release (ldata);
1223 gcry_sexp_release (lhash);
1224 gcry_sexp_release (lvalue);
1226 if (! rc)
1227 *flags = parsed_flags;
1229 return rc;
1234 Do a PK encrypt operation
1236 Caller has to provide a public key as the SEXP pkey and data as a
1237 SEXP with just one MPI in it. Alternativly S_DATA might be a
1238 complex S-Expression, similar to the one used for signature
1239 verification. This provides a flag which allows to handle PKCS#1
1240 block type 2 padding. The function returns a a sexp which may be
1241 passed to to pk_decrypt.
1243 Returns: 0 or an errorcode.
1245 s_data = See comment for sexp_data_to_mpi
1246 s_pkey = <key-as-defined-in-sexp_to_key>
1247 r_ciph = (enc-val
1248 (<algo>
1249 (<param_name1> <mpi>)
1251 (<param_namen> <mpi>)
1256 gcry_pk_encrypt (GCRY_SEXP *r_ciph, GCRY_SEXP s_data, GCRY_SEXP s_pkey)
1258 MPI *pkey, data, *ciph;
1259 const char *key_algo_name, *algo_name, *algo_elems;
1260 int i, rc, algo, flags;
1262 *r_ciph = NULL;
1263 /* get the key */
1264 rc = sexp_to_key( s_pkey, 0, &pkey, &algo, &i);
1265 if( rc )
1266 return rc;
1267 key_algo_name = algo_info_table[i].name;
1268 assert (key_algo_name);
1270 /* get the name and the required size of the return value */
1271 for(i=0; (algo_name = enc_info_table[i].name); i++ ) {
1272 if( enc_info_table[i].algo == algo )
1273 break;
1275 /* get the name and the required size of the result array. We
1276 compare using the algorithm name and not the algo number - this way
1277 we get the correct name for the return value */
1278 for(i=0; (algo_name = enc_info_table[i].name); i++ ) {
1279 if( !strcmp (algo_name, key_algo_name) )
1280 break;
1282 if( !algo_name ) {
1283 release_mpi_array( pkey );
1284 gcry_free (pkey);
1285 return GCRYERR_INV_PK_ALGO;
1287 algo_elems = enc_info_table[i].elements;
1289 /* get the stuff we want to encrypt */
1290 rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
1291 &flags);
1292 if (rc) {
1293 release_mpi_array( pkey );
1294 gcry_free (pkey);
1295 return GCRYERR_INV_OBJ;
1298 /* Now we can encrypt data to ciph */
1299 ciph = gcry_xcalloc( (strlen(algo_elems)+1) , sizeof *ciph );
1300 rc = pubkey_encrypt( algo, ciph, data, pkey, flags );
1301 release_mpi_array( pkey );
1302 gcry_free (pkey); pkey = NULL;
1303 mpi_free( data );
1304 if( rc ) {
1305 release_mpi_array( ciph );
1306 gcry_free( ciph );
1307 return rc;
1310 /* We did it. Now build the return list */
1312 char *string, *p;
1313 size_t nelem, needed= strlen(algo_name) + 30;
1315 /* FIXME, this calculation needs to be cleaned up.
1316 -moritz */
1318 /* count elements, so that we can allocate enough space */
1319 for(nelem=0; algo_elems[nelem]; nelem++ )
1320 needed += 10; /* 6 + a safety margin */
1321 /* build the string */
1322 string = p = gcry_xmalloc ( needed );
1323 p = stpcpy ( p, "(enc-val(flags " );
1324 if (flags & PUBKEY_FLAG_NO_BLINDING)
1325 p = stpcpy (p, "no-blinding");
1326 p = stpcpy (p, ")(");
1327 p = stpcpy ( p, algo_name );
1328 for(i=0; algo_elems[i]; i++ ) {
1329 *p++ = '(';
1330 *p++ = algo_elems[i];
1331 p = stpcpy ( p, "%m)" );
1333 strcpy ( p, "))" );
1334 /* and now the ugly part: we don't have a function to
1335 * pass an array to a format string, so we have to do it this way :-(
1337 switch ( nelem ) {
1338 case 1: rc = gcry_sexp_build ( r_ciph, NULL, string,
1339 ciph[0]
1340 ); break;
1341 case 2: rc = gcry_sexp_build ( r_ciph, NULL, string,
1342 ciph[0], ciph[1]
1343 ); break;
1344 case 3: rc = gcry_sexp_build ( r_ciph, NULL, string,
1345 ciph[0], ciph[1], ciph[2]
1346 ); break;
1347 case 4: rc = gcry_sexp_build ( r_ciph, NULL, string,
1348 ciph[0], ciph[1], ciph[2], ciph[3]
1349 ); break;
1350 case 5: rc = gcry_sexp_build ( r_ciph, NULL, string,
1351 ciph[0], ciph[1], ciph[2], ciph[3], ciph[4]
1352 ); break;
1353 case 6: rc = gcry_sexp_build ( r_ciph, NULL, string,
1354 ciph[0], ciph[1], ciph[2], ciph[3], ciph[4], ciph[5]
1355 ); break;
1356 default: BUG ();
1358 if ( rc )
1359 BUG ();
1360 gcry_free ( string );
1362 release_mpi_array( ciph );
1363 gcry_free( ciph );
1366 return 0;
1369 /****************
1370 * Do a PK decrypt operation
1372 * Caller has to provide a secret key as the SEXP skey and data in a
1373 * format as created by gcry_pk_encrypt. For historic reasons the
1374 * function returns simply an MPI as an S-expression part; this is
1375 * deprecated and the new method should be used which returns a real
1376 * S-expressionl this is selected by adding at least an empt flags
1377 * list to S_DATA.
1379 * Returns: 0 or an errorcode.
1381 * s_data = (enc-val
1382 * [(flags)]
1383 * (<algo>
1384 * (<param_name1> <mpi>)
1385 * ...
1386 * (<param_namen> <mpi>)
1387 * ))
1388 * s_skey = <key-as-defined-in-sexp_to_key>
1389 * r_plain= Either an incomplete S-expression without the parentheses
1390 * or if the flags list is used (even if empty) a real S-expression:
1391 * (value PLAIN). */
1393 gcry_pk_decrypt( GCRY_SEXP *r_plain, GCRY_SEXP s_data, GCRY_SEXP s_skey )
1395 MPI *skey, *data, plain;
1396 int rc, algo, dataalgo, modern, want_pkcs1, flags;
1398 *r_plain = NULL;
1399 rc = sexp_to_key( s_skey, 1, &skey, &algo, NULL );
1400 if( rc ) {
1401 return rc;
1403 rc = sexp_to_enc( s_data, &data, &dataalgo, &modern, &want_pkcs1,
1404 &flags );
1405 if( rc ) {
1406 release_mpi_array( skey );
1407 gcry_free (skey);
1408 return rc;
1410 if( algo != dataalgo ) {
1411 release_mpi_array( skey );
1412 gcry_free (skey);
1413 release_mpi_array( data );
1414 gcry_free (data);
1415 return GCRYERR_CONFLICT; /* key algo does not match data algo */
1418 rc = pubkey_decrypt( algo, &plain, data, skey, flags );
1419 if( rc ) {
1420 release_mpi_array( skey );
1421 gcry_free (skey);
1422 release_mpi_array( data );
1423 gcry_free (data);
1424 return GCRYERR_GENERAL; /* decryption failed */
1427 if (!modern) {
1428 if ( gcry_sexp_build( r_plain, NULL, "%m", plain ) )
1429 BUG ();
1431 else {
1432 if ( gcry_sexp_build( r_plain, NULL, "(value %m)", plain ) )
1433 BUG ();
1437 mpi_free( plain );
1438 release_mpi_array( data );
1439 gcry_free (data);
1440 release_mpi_array( skey );
1441 gcry_free (skey);
1442 return 0;
1447 /****************
1448 * Create a signature.
1450 * Caller has to provide a secret key as the SEXP skey and data
1451 * expressed as a SEXP list hash with only one element which should
1452 * instantly be available as a MPI. Alternatively the structure given
1453 * below may be used for S_HASH, it provides the abiliy to pass flags
1454 * to the operation; the only flag defined by now is "pkcs1" which
1455 * does PKCS#1 block type 1 style padding.
1457 * Returns: 0 or an errorcode.
1458 * In case of 0 the function returns a new SEXP with the
1459 * signature value; the structure of this signature depends on the
1460 * other arguments but is always suitable to be passed to
1461 * gcry_pk_verify
1463 * s_hash = See comment for sexp_data_to_mpi
1465 * s_skey = <key-as-defined-in-sexp_to_key>
1466 * r_sig = (sig-val
1467 * (<algo>
1468 * (<param_name1> <mpi>)
1469 * ...
1470 * (<param_namen> <mpi>)
1471 * )) */
1473 gcry_pk_sign( GCRY_SEXP *r_sig, GCRY_SEXP s_hash, GCRY_SEXP s_skey )
1475 MPI *skey, hash;
1476 MPI *result;
1477 int i, algo, rc;
1478 const char *key_algo_name, *algo_name, *algo_elems;
1480 *r_sig = NULL;
1481 rc = sexp_to_key( s_skey, 1, &skey, &algo, &i);
1482 if( rc )
1483 return rc;
1484 key_algo_name = algo_info_table[i].name;
1485 assert (key_algo_name);
1487 /* get the name and the required size of the result array. We
1488 compare using the algorithm name and not the algo number - this way
1489 we get the correct name for the return value */
1490 for(i=0; (algo_name = sig_info_table[i].name); i++ ) {
1491 if( !strcmp (algo_name, key_algo_name) )
1492 break;
1494 if( !algo_name ) {
1495 release_mpi_array( skey );
1496 gcry_free (skey);
1497 return -4; /* oops: unknown algorithm */
1499 assert (sig_info_table[i].algo == algo);
1500 algo_elems = sig_info_table[i].elements;
1502 /* get the stuff we want to sign */
1503 /* Note that pk_get_nbits does also work on a private key */
1504 rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey), &hash, 0, NULL);
1505 if (rc) {
1506 release_mpi_array( skey );
1507 gcry_free (skey);
1508 return rc;
1510 result = gcry_xcalloc( (strlen(algo_elems)+1) , sizeof *result );
1511 rc = pubkey_sign( algo, result, hash, skey );
1512 release_mpi_array( skey );
1513 gcry_free (skey); skey = NULL;
1514 mpi_free( hash );
1515 if( rc ) {
1516 gcry_free( result );
1517 return rc;
1521 char *string, *p;
1522 size_t nelem, needed= strlen(algo_name) + 20;
1524 /* count elements, so that we can allocate enough space */
1525 for(nelem=0; algo_elems[nelem]; nelem++ )
1526 needed += 10; /* 6 + a safety margin */
1527 /* build the string */
1528 string = p = gcry_xmalloc ( needed );
1529 p = stpcpy ( p, "(sig-val(" );
1530 p = stpcpy ( p, algo_name );
1531 for(i=0; algo_elems[i]; i++ ) {
1532 *p++ = '(';
1533 *p++ = algo_elems[i];
1534 p = stpcpy ( p, "%m)" );
1536 strcpy ( p, "))" );
1537 /* and now the ugly part: we don't have a function to
1538 * pass an array to a format string, so we have to do it this way :-(
1540 switch ( nelem ) {
1541 case 1: rc = gcry_sexp_build ( r_sig, NULL, string,
1542 result[0]
1543 ); break;
1544 case 2: rc = gcry_sexp_build ( r_sig, NULL, string,
1545 result[0], result[1]
1546 ); break;
1547 case 3: rc = gcry_sexp_build ( r_sig, NULL, string,
1548 result[0], result[1], result[2]
1549 ); break;
1550 case 4: rc = gcry_sexp_build ( r_sig, NULL, string,
1551 result[0], result[1], result[2], result[3]
1552 ); break;
1553 case 5: rc = gcry_sexp_build ( r_sig, NULL, string,
1554 result[0], result[1], result[2], result[3], result[4]
1555 ); break;
1556 case 6: rc = gcry_sexp_build ( r_sig, NULL, string,
1557 result[0], result[1], result[2], result[3], result[4], result[5]
1558 ); break;
1559 default: BUG ();
1561 if ( rc )
1562 BUG ();
1563 gcry_free ( string );
1565 release_mpi_array( result );
1566 gcry_free( result );
1568 return 0;
1572 /****************
1573 * Verify a sgnature. Caller has to supply the public key pkey,
1574 * the signature sig and his hashvalue data. Public key has to be
1575 * a standard public key given as an S-Exp, sig is a S-Exp as returned
1576 * from gcry_pk_sign and data must be an S-Exp like the one in sign too.
1579 gcry_pk_verify( GCRY_SEXP s_sig, GCRY_SEXP s_hash, GCRY_SEXP s_pkey )
1581 MPI *pkey, hash, *sig;
1582 int algo, sigalgo;
1583 int rc;
1585 rc = sexp_to_key( s_pkey, 0, &pkey, &algo, NULL );
1586 if( rc )
1587 return rc;
1588 rc = sexp_to_sig( s_sig, &sig, &sigalgo );
1589 if( rc ) {
1590 release_mpi_array( pkey );
1591 gcry_free (pkey);
1592 return rc;
1594 if( algo != sigalgo ) {
1595 release_mpi_array( pkey );
1596 gcry_free (pkey);
1597 release_mpi_array( sig );
1598 gcry_free (sig);
1599 return GCRYERR_CONFLICT; /* algo does not match */
1602 rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
1603 if (rc) {
1604 release_mpi_array( pkey );
1605 gcry_free (pkey);
1606 release_mpi_array( sig );
1607 gcry_free (sig);
1608 return rc;
1611 rc = pubkey_verify( algo, hash, sig, pkey, NULL, NULL );
1612 release_mpi_array( pkey );
1613 gcry_free (pkey);
1614 release_mpi_array( sig );
1615 gcry_free (sig);
1616 mpi_free(hash);
1618 return rc;
1622 /****************
1623 * Test a key. This may be used either for a public or a secret key
1624 * to see whether internal structre is valid.
1626 * Returns: 0 or an errorcode.
1628 * s_key = <key-as-defined-in-sexp_to_key>
1631 gcry_pk_testkey( GCRY_SEXP s_key )
1633 MPI *key;
1634 int rc, algo;
1636 /* Note we currently support only secret key checking */
1637 rc = sexp_to_key( s_key, 1, &key, &algo, NULL );
1638 if( rc ) {
1639 return rc;
1642 rc = pubkey_check_secret_key( algo, key );
1643 release_mpi_array( key );
1644 gcry_free (key);
1645 return rc;
1649 /****************
1650 * Create a public key pair and return it in r_key.
1651 * How the key is created depends on s_parms:
1652 * (genkey
1653 * (algo
1654 * (parameter_name_1 ....)
1655 * ....
1656 * (parameter_name_n ....)
1657 * ))
1658 * The key is returned in a format depending on the
1659 * algorithm. Both, private and secret keys are returned
1660 * and optionally some additional informatin.
1661 * For elgamal we return this structure:
1662 * (key-data
1663 * (public-key
1664 * (elg
1665 * (p <mpi>)
1666 * (g <mpi>)
1667 * (y <mpi>)
1670 * (private-key
1671 * (elg
1672 * (p <mpi>)
1673 * (g <mpi>)
1674 * (y <mpi>)
1675 * (x <mpi>)
1678 * (misc-key-info
1679 * (pm1-factors n1 n2 ... nn)
1684 gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
1686 GCRY_SEXP list, l2;
1687 const char *name;
1688 const char *s, *s2;
1689 size_t n;
1690 int rc, i;
1691 const char *algo_name;
1692 int algo;
1693 char sec_elems[20], pub_elems[20];
1694 GCRY_MPI skey[10], *factors;
1695 unsigned int nbits;
1696 unsigned long use_e;
1698 *r_key = NULL;
1699 list = gcry_sexp_find_token( s_parms, "genkey", 0 );
1700 if( !list )
1701 return GCRYERR_INV_OBJ; /* Does not contain genkey data */
1702 l2 = gcry_sexp_cadr( list );
1703 gcry_sexp_release ( list );
1704 list = l2;
1705 if( !list )
1706 return GCRYERR_NO_OBJ; /* no cdr for the genkey */
1707 name = gcry_sexp_nth_data( list, 0, &n );
1708 if( !name ) {
1709 gcry_sexp_release ( list );
1710 return GCRYERR_INV_OBJ; /* algo string missing */
1712 for(i=0; (s=algo_info_table[i].name); i++ ) {
1713 if( strlen(s) == n && !memcmp( s, name, n ) )
1714 break;
1716 if( !s ) {
1717 gcry_sexp_release ( list );
1718 return GCRYERR_INV_PK_ALGO; /* unknown algorithm */
1721 algo = algo_info_table[i].algo;
1722 algo_name = algo_info_table[i].name;
1724 s = algo_info_table[i].common_elements;
1725 s2 = algo_info_table[i].public_elements;
1726 if( strlen( s ) + strlen( s2 ) > DIM( pub_elems ) )
1727 return GCRYERR_INTERNAL; /* check bound failed */
1728 strcpy( pub_elems, s );
1729 strcat( pub_elems, s2 );
1731 s = algo_info_table[i].common_elements;
1732 s2 = algo_info_table[i].secret_elements;
1733 if( strlen( s ) + strlen( s2 ) > DIM( sec_elems ) )
1734 return GCRYERR_INTERNAL; /* check bound failed */
1735 strcpy( sec_elems, s );
1736 strcat( sec_elems, s2 );
1738 l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
1739 if (l2)
1741 char buf[50];
1743 name = gcry_sexp_nth_data (l2, 1, &n);
1744 if (!name || n >= DIM (buf)-1 )
1746 gcry_sexp_release (l2);
1747 gcry_sexp_release (list);
1748 return GCRYERR_INV_OBJ; /* no value or value too large */
1751 memcpy (buf, name, n);
1752 buf[n] = 0;
1753 use_e = strtoul (buf, NULL, 0);
1754 gcry_sexp_release (l2);
1756 else
1757 use_e = 65537; /* not given, use the value generated by old versions. */
1759 l2 = gcry_sexp_find_token( list, "nbits", 0 );
1760 gcry_sexp_release ( list );
1761 list = l2;
1762 if( !list )
1763 return GCRYERR_NO_OBJ; /* no nbits parameter */
1764 name = gcry_sexp_nth_data( list, 1, &n );
1765 if( !name ) {
1766 gcry_sexp_release ( list );
1767 return GCRYERR_INV_OBJ; /* nbits without a cdr */
1770 char *p = gcry_xmalloc(n+1);
1771 memcpy(p, name, n );
1772 p[n] = 0;
1773 nbits = (unsigned int)strtol( p, NULL, 0 );
1774 gcry_free( p );
1776 gcry_sexp_release ( list );
1778 rc = pubkey_generate( algo, nbits, use_e, skey, &factors );
1779 if( rc ) {
1780 return rc;
1784 char *string, *p;
1785 size_t nelem=0, needed=0;
1786 GCRY_MPI mpis[30];
1789 /* count elements, so that we can allocate enough space */
1790 for(i=0; pub_elems[i]; i++, nelem++ )
1791 needed += 10; /* 6 + a safety margin */
1792 for(i=0; sec_elems[i]; i++, nelem++ )
1793 needed += 10; /* 6 + a safety margin */
1794 for(i=0; factors[i]; i++, nelem++ )
1795 needed += 10; /* 6 + a safety margin */
1796 needed += 2* strlen(algo_name) + 300;
1797 if ( nelem > DIM(mpis) )
1798 BUG ();
1800 /* build the string */
1801 nelem = 0;
1802 string = p = gcry_xmalloc ( needed );
1803 p = stpcpy ( p, "(key-data" );
1805 p = stpcpy ( p, "(public-key(" );
1806 p = stpcpy ( p, algo_name );
1807 for(i=0; pub_elems[i]; i++ ) {
1808 *p++ = '(';
1809 *p++ = pub_elems[i];
1810 p = stpcpy ( p, "%m)" );
1811 mpis[nelem++] = skey[i];
1813 p = stpcpy ( p, "))" );
1815 p = stpcpy ( p, "(private-key(" );
1816 p = stpcpy ( p, algo_name );
1817 for(i=0; sec_elems[i]; i++ ) {
1818 *p++ = '(';
1819 *p++ = sec_elems[i];
1820 p = stpcpy ( p, "%m)" );
1821 mpis[nelem++] = skey[i];
1823 p = stpcpy ( p, "))" );
1824 /* Very ugly hack to make release_mpi_array() work FIXME */
1825 skey[i] = NULL;
1827 p = stpcpy ( p, "(misc-key-info(pm1-factors" );
1828 for(i=0; factors[i]; i++ ) {
1829 p = stpcpy ( p, "%m" );
1830 mpis[nelem++] = factors[i];
1832 strcpy ( p, ")))" );
1834 while ( nelem < DIM(mpis) )
1835 mpis[nelem++] = NULL;
1837 /* and now the ugly part: we don't have a function to
1838 * pass an array to a format string, so we have just pass everything
1839 * we have. which normally should be no problem as only those
1840 * with a corresponding %m are used
1842 if ( gcry_sexp_build ( r_key, NULL, string,
1843 mpis[0], mpis[1], mpis[2], mpis[3], mpis[4], mpis[5],
1844 mpis[6], mpis[7], mpis[8], mpis[9], mpis[10], mpis[11],
1845 mpis[12], mpis[13], mpis[14], mpis[15], mpis[16], mpis[17],
1846 mpis[18], mpis[19], mpis[20], mpis[21], mpis[22], mpis[23],
1847 mpis[24], mpis[25], mpis[26], mpis[27], mpis[28], mpis[29]
1849 BUG ();
1850 assert ( DIM(mpis) == 30 );
1851 gcry_free ( string );
1853 release_mpi_array ( skey );
1854 /* no free: skey is a static array */
1855 release_mpi_array ( factors );
1856 gcry_free (factors);
1858 return 0;
1861 /****************
1862 * Get the number of nbits from the public key
1863 * Hmmm: Should we have really this function or is it
1864 * better to have a more general function to retrieve
1865 * different propoerties of the key?
1867 unsigned int
1868 gcry_pk_get_nbits( GCRY_SEXP key )
1870 int rc, i, algo;
1871 MPI *keyarr;
1872 unsigned int nbits = 0;
1874 rc = sexp_to_key( key, 0, &keyarr, &algo, NULL );
1875 if( rc == GCRYERR_INV_OBJ )
1876 rc = sexp_to_key( key, 1, &keyarr, &algo, NULL );
1877 if( rc )
1878 return 0;
1880 do {
1881 for(i=0; pubkey_table[i].name; i++ )
1882 if( pubkey_table[i].algo == algo ) {
1883 nbits = (*pubkey_table[i].get_nbits)( algo, keyarr );
1884 goto leave;
1886 } while( load_pubkey_modules() );
1887 if( is_RSA(algo) ) /* we always wanna see the length of a key :-) */
1888 nbits = mpi_get_nbits( keyarr[0] );
1889 leave:
1890 release_mpi_array( keyarr );
1891 gcry_free (keyarr);
1892 return nbits;
1895 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
1896 key parameters expressed in a way depended on the algorithm.
1898 ARRAY must either be 20 bytes long or NULL; in the latter case a
1899 newly allocated array of that size is returned, otherwise ARRAY or
1900 NULL is returned to indicate an error which is most likely an
1901 unknown algorithm. The function accepts public or secret keys. */
1902 unsigned char *
1903 gcry_pk_get_keygrip (GCRY_SEXP key, unsigned char *array)
1905 GCRY_SEXP list=NULL, l2;
1906 const char *s, *name;
1907 size_t n;
1908 int i, idx;
1909 int is_rsa;
1910 const char *elems;
1911 GCRY_MD_HD md = NULL;
1913 /* check that the first element is valid */
1914 list = gcry_sexp_find_token (key, "public-key", 0);
1915 if (!list)
1916 list = gcry_sexp_find_token (key, "private-key", 0);
1917 if (!list)
1918 list = gcry_sexp_find_token (key, "protected-private-key", 0);
1919 if (!list)
1920 return NULL; /* no public- or private-key object */
1922 l2 = gcry_sexp_cadr (list);
1923 gcry_sexp_release (list);
1924 list = l2;
1926 name = gcry_sexp_nth_data( list, 0, &n );
1927 if (!name)
1928 goto fail; /* invalid structure of object */
1930 for (i=0; (s=algo_info_table[i].name); i++ )
1932 if (strlen(s) == n && !memcmp (s, name, n))
1933 break;
1936 if(!s)
1937 goto fail; /* unknown algorithm */
1939 is_rsa = algo_info_table[i].algo == PUBKEY_ALGO_RSA;
1940 elems = algo_info_table[i].grip_elements;
1941 if (!elems)
1942 goto fail; /* no grip parameter */
1944 md = gcry_md_open (GCRY_MD_SHA1, 0);
1945 if (!md)
1946 goto fail;
1948 idx = 0;
1949 for (s=elems; *s; s++, idx++)
1951 const char *data;
1952 size_t datalen;
1954 l2 = gcry_sexp_find_token (list, s, 1);
1955 if (!l2)
1956 goto fail;
1957 data = gcry_sexp_nth_data (l2, 1, &datalen);
1958 gcry_sexp_release (l2);
1959 if (!data)
1960 goto fail;
1961 if (!is_rsa)
1963 char buf[30];
1965 sprintf (buf, "(1:%c%u:", *s, (unsigned int)datalen);
1966 gcry_md_write (md, buf, strlen (buf));
1968 /* pkcs-15 says that for RSA only the modulus should be hashed -
1969 however, it is not clear wether this is meant to has the raw
1970 bytes assuming this is an unsigned integer or whether the DER
1971 required 0 should be prefixed. We hash th raw bytes. For
1972 non-RSA we hash S-expressions. */
1973 gcry_md_write (md, data, datalen);
1974 if (!is_rsa)
1975 gcry_md_write (md, ")", 1);
1978 if (!array)
1980 array = gcry_malloc (20);
1981 if (!array)
1982 goto fail;
1984 memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
1985 gcry_md_close (md);
1986 gcry_sexp_release (list);
1987 return array;
1989 fail:
1990 gcry_md_close (md);
1991 gcry_sexp_release (list);
1992 return NULL;
1998 gcry_pk_ctl( int cmd, void *buffer, size_t buflen)
2000 switch( cmd ) {
2001 case GCRYCTL_DISABLE_ALGO:
2002 /* this one expects a buffer pointing to an
2003 * integer with the algo number.
2005 if( !buffer || buflen != sizeof(int) )
2006 return set_lasterr( GCRYERR_INV_CIPHER_ALGO );
2007 disable_pubkey_algo( *(int*)buffer );
2008 break;
2010 default:
2011 return set_lasterr( GCRYERR_INV_OP );
2013 return 0;
2017 /****************
2018 * Return information about the given algorithm
2019 * WHAT select the kind of information returned:
2020 * GCRYCTL_TEST_ALGO:
2021 * Returns 0 when the specified algorithm is available for use.
2022 * Buffer must be NULL, nbytes may have the address of a variable
2023 * with the required usage of the algorithm. It may be 0 for don't
2024 * care or a combination of the GCRY_PK_USAGE_xxx flags;
2025 * GCRYCTL_GET_ALGO_USAGE:
2026 * Return the usage glafs for the give algo. An invalid alog
2027 * does return 0. Disabled algos are ignored here becuase we
2028 * only want to know whether the algo is at all capable of
2029 * the usage.
2031 * On error the value -1 is returned and the error reason may be
2032 * retrieved by gcry_errno().
2033 * Note: Because this function is in most cases used to return an
2034 * integer value, we can make it easier for the caller to just look at
2035 * the return value. The caller will in all cases consult the value
2036 * and thereby detecting whether a error occured or not (i.e. while checking
2037 * the block size)
2040 gcry_pk_algo_info( int algo, int what, void *buffer, size_t *nbytes)
2042 switch( what ) {
2043 case GCRYCTL_TEST_ALGO: {
2044 int use = nbytes? *nbytes: 0;
2045 if( buffer ) {
2046 set_lasterr( GCRYERR_INV_ARG );
2047 return -1;
2049 if( check_pubkey_algo( algo, use ) ) {
2050 set_lasterr( GCRYERR_INV_PK_ALGO );
2051 return -1;
2054 break;
2056 case GCRYCTL_GET_ALGO_USAGE:
2057 do {
2058 int i;
2059 for(i=0; pubkey_table[i].name; i++ )
2060 if( pubkey_table[i].algo == algo )
2061 return pubkey_table[i].use;
2062 } while( load_pubkey_modules() );
2063 return 0;
2065 case GCRYCTL_GET_ALGO_NPKEY: return pubkey_get_npkey( algo );
2066 case GCRYCTL_GET_ALGO_NSKEY: return pubkey_get_nskey( algo );
2067 case GCRYCTL_GET_ALGO_NSIGN: return pubkey_get_nsig( algo );
2068 case GCRYCTL_GET_ALGO_NENCR: return pubkey_get_nenc( algo );
2070 default:
2071 set_lasterr( GCRYERR_INV_OP );
2072 return -1;
2074 return 0;