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
36 /* FIXME: use set_lasterr() */
42 struct pubkey_table_s
{
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
];
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" },
84 const char* name
; int algo
;
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" },
98 const char* name
; int algo
;
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" },
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
);
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
; }
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
; }
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
; }
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
; }
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
; }
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
; }
143 dummy_get_nbits( int algo
, MPI
*pkey
)
144 { log_bug("no get_nbits() for %d\n", algo
); return 0; }
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.
153 setup_pubkey_table(void)
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
)
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
)
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
)
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
)
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
)
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
)
262 for( ; i
< TABLE_SIZE
; i
++ )
263 pubkey_table
[i
].name
= NULL
;
267 release_mpi_array( MPI
*array
)
269 for( ; *array
; array
++ ) {
276 * Try to load all modules and return true if new modules are available
279 load_pubkey_modules(void)
281 static int initialized
= 0;
283 void *context
= NULL
;
284 struct pubkey_table_s
*ct
;
292 _gcry_cipher_modules_constructor();
293 setup_pubkey_table();
300 for(ct_idx
=0, ct
= pubkey_table
; ct_idx
< TABLE_SIZE
; ct_idx
++,ct
++ ) {
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
,
311 &ct
->check_secret_key
,
316 &ct
->get_nbits
)) ) {
317 for(i
=0; pubkey_table
[i
].name
; i
++ )
318 if( pubkey_table
[i
].algo
== ct
->algo
)
320 if( pubkey_table
[i
].name
) {
321 log_info("skipping pubkey %d: already loaded\n", ct
->algo
);
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
);
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");
346 _gcry_enum_gnupgext_pubkeys( &context
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
347 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
353 * Map a string to the pubkey algo
356 gcry_pk_map_name( const char *string
)
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() );
371 * Map a pubkey algo to a string
374 gcry_pk_algo_name( int algo
)
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() );
388 disable_pubkey_algo( int algo
)
392 for(i
=0; i
< DIM(disabled_algos
); i
++ ) {
393 if( !disabled_algos
[i
] || disabled_algos
[i
] == algo
) {
394 disabled_algos
[i
] = algo
;
398 log_fatal("can't disable pubkey algo %d: table full\n", algo
);
403 * a use of 0 means: don't care
406 check_pubkey_algo( int algo
, unsigned use
)
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
;
426 } while( load_pubkey_modules() );
427 return GCRYERR_INV_PK_ALGO
;
434 * Return the number of public key material numbers
437 pubkey_get_npkey( int algo
)
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() );
449 * Return the number of secret key material numbers
452 pubkey_get_nskey( int algo
)
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() );
464 * Return the number of signature material numbers
467 pubkey_get_nsig( int algo
)
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() );
479 * Return the number of encryption material numbers
482 pubkey_get_nenc( int algo
)
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() );
495 pubkey_generate( int algo
, unsigned int nbits
, unsigned long use_e
,
496 MPI
*skey
, MPI
**retfactors
)
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
,
505 } while( load_pubkey_modules() );
506 return GCRYERR_INV_PK_ALGO
;
511 pubkey_check_secret_key( int algo
, MPI
*skey
)
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
;
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() )
531 pubkey_encrypt( int algo
, MPI
*resarr
, MPI data
, MPI
*pkey
,
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
);
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
);
549 } while( load_pubkey_modules() );
550 rc
= GCRYERR_INV_PK_ALGO
;
552 if( !rc
&& DBG_CIPHER
) {
553 for(i
=0; i
< pubkey_get_nenc(algo
); i
++ )
554 log_mpidump(" encr:", resarr
[i
] );
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.
569 pubkey_decrypt( int algo
, MPI
*result
, MPI
*data
, MPI
*skey
,
574 *result
= NULL
; /* so the caller can always do a mpi_free */
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
] );
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
);
589 } while( load_pubkey_modules() );
590 rc
= GCRYERR_INV_PK_ALGO
;
592 if( !rc
&& DBG_CIPHER
) {
593 log_mpidump(" plain:", *result
);
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() )
606 pubkey_sign( int algo
, MPI
*resarr
, MPI data
, MPI
*skey
)
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
);
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
);
623 } while( load_pubkey_modules() );
624 rc
= GCRYERR_INV_PK_ALGO
;
626 if( !rc
&& DBG_CIPHER
) {
627 for(i
=0; i
< pubkey_get_nsig(algo
); i
++ )
628 log_mpidump(" sig:", resarr
[i
] );
634 * Verify a public key signature.
635 * Return 0 if the signature is good
638 pubkey_verify( int algo
, MPI hash
, MPI
*data
, MPI
*pkey
,
639 int (*cmp
)(void *, MPI
), void *opaquev
)
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
);
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
,
659 } while( load_pubkey_modules() );
660 rc
= GCRYERR_INV_PK_ALGO
;
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
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:
698 * The <mpi> are expected to be in GCRYMPI_FMT_USG
701 sexp_to_key( GCRY_SEXP sexp
, int want_private
, MPI
**retarray
,
702 int *retalgo
, int *r_algotblidx
)
710 const char *elems1
, *elems2
;
713 /* check that the first element is valid */
714 list
= gcry_sexp_find_token( sexp
, want_private
? "private-key"
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
);
721 name
= gcry_sexp_nth_data( list
, 0, &n
);
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
) )
731 gcry_sexp_release ( list
);
732 return GCRYERR_INV_PK_ALGO
; /* unknown algorithm */
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
);
742 gcry_sexp_release ( list
);
743 return GCRYERR_NO_MEM
;
747 for(s
=elems1
; *s
; s
++, idx
++ ) {
748 l2
= gcry_sexp_find_token( list
, s
, 1 );
751 gcry_free( array
[i
] );
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
);
760 gcry_free( array
[i
] );
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 );
770 gcry_free( array
[i
] );
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
);
779 gcry_free( array
[i
] );
781 gcry_sexp_release ( list
);
782 return GCRYERR_INV_OBJ
; /* required parameter is invalid */
786 gcry_sexp_release ( list
);
794 sexp_to_sig( GCRY_SEXP sexp
, MPI
**retarray
, int *retalgo
)
805 /* check that the first element is valid */
806 list
= gcry_sexp_find_token( sexp
, "sig-val" , 0 );
808 return GCRYERR_INV_OBJ
; /* Does not contain a signature value object */
809 l2
= gcry_sexp_cadr( list
);
810 gcry_sexp_release ( list
);
813 return GCRYERR_NO_OBJ
; /* no cadr for the sig object */
814 name
= gcry_sexp_nth_data( list
, 0, &n
);
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
) )
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
);
831 gcry_sexp_release ( list
);
832 return GCRYERR_NO_MEM
;
836 for(s
=elems
; *s
; s
++, idx
++ ) {
837 l2
= gcry_sexp_find_token( list
, s
, 1 );
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
);
847 gcry_sexp_release ( list
);
848 return GCRYERR_INV_OBJ
; /* required parameter is invalid */
852 gcry_sexp_release ( list
);
861 * Take sexp and return an array of MPI as used for our internal decrypt
866 * (<param_name1> <mpi>)
868 * (<param_namen> <mpi>)
870 * RET_MODERN is set to true when at least an empty flags list has been found.
873 sexp_to_enc( GCRY_SEXP sexp
, MPI
**retarray
, int *retalgo
,
874 int *ret_modern
, int *ret_want_pkcs1
,
883 int parsed_flags
= 0;
889 /* check that the first element is valid */
890 list
= gcry_sexp_find_token( sexp
, "enc-val" , 0 );
892 return GCRYERR_INV_OBJ
; /* Does not contain a encrypted value object */
893 l2
= gcry_sexp_nth (list
, 1);
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
);
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 */
909 for (i
=gcry_sexp_length (l2
)-1; i
> 0; i
--)
911 s
= gcry_sexp_nth_data (l2
, i
, &n
);
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))
918 else if ( n
== 11 && !memcmp (s
, "no-blinding", 11))
919 parsed_flags
|= PUBKEY_FLAG_NO_BLINDING
;
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);
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
);
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
) )
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
);
958 gcry_sexp_release ( list
);
959 return GCRYERR_NO_MEM
;
963 for(s
=elems
; *s
; s
++, idx
++ ) {
964 l2
= gcry_sexp_find_token( list
, s
, 1 );
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
);
974 gcry_sexp_release ( list
);
975 return GCRYERR_INV_OBJ
; /* required parameter is invalid */
979 gcry_sexp_release ( list
);
983 *flags
= parsed_flags
;
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.
998 [(hash <algo> <value>)]
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.
1009 sexp_data_to_mpi (GcrySexp input
, unsigned int nbits
, GcryMPI
*ret_mpi
,
1010 int for_encryption
, int *flags
)
1013 GcrySexp ldata
, lhash
, lvalue
;
1017 int is_raw
= 0, is_pkcs1
= 0, unknown_flag
=0;
1018 int parsed_flags
= 0, dummy_flags
;
1021 flags
= &dummy_flags
;
1024 ldata
= gcry_sexp_find_token (input
, "data", 0);
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);
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
);
1040 ; /* not a data element*/
1041 else if ( n
== 3 && !memcmp (s
, "raw", 3))
1043 else if ( n
== 5 && !memcmp (s
, "pkcs1", 5))
1045 else if (n
== 11 && ! memcmp (s
, "no-blinding", 11))
1046 parsed_flags
|= PUBKEY_FLAG_NO_BLINDING
;
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);
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;
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
;
1094 frame
[n
++] = 2; /* block type */
1095 i
= nframe
- 3 - valuelen
;
1097 p
= gcry_random_bytes_secure (i
, GCRY_STRONG_RANDOM
);
1098 /* replace zero bytes by new values*/
1104 /* count the zero bytes */
1105 for (j
=k
=0; j
< i
; j
++)
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
++)
1122 memcpy (frame
+n
, p
, i
);
1127 memcpy (frame
+n
, value
, valuelen
);
1129 assert (n
== nframe
);
1131 gcry_mpi_scan (ret_mpi
, GCRYMPI_FMT_USG
, frame
, &nframe
);
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
;
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
},
1160 size_t nframe
= (nbits
+7) / 8;
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
))
1172 algo
= hashnames
[i
].algo
;
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
))
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
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
;
1197 { /* assemble the pkcs#1 block type 1 */
1200 frame
[n
++] = 1; /* block type */
1201 i
= nframe
- valuelen
- asnlen
- 3 ;
1203 memset (frame
+n
, 0xff, i
);
1206 memcpy (frame
+n
, asn
, asnlen
);
1208 memcpy (frame
+n
, value
, valuelen
);
1210 assert (n
== nframe
);
1212 /* convert it into an MPI */
1213 gcry_mpi_scan (ret_mpi
, GCRYMPI_FMT_USG
, frame
, &nframe
);
1220 rc
= GCRYERR_CONFLICT
;
1222 gcry_sexp_release (ldata
);
1223 gcry_sexp_release (lhash
);
1224 gcry_sexp_release (lvalue
);
1227 *flags
= parsed_flags
;
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>
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
;
1264 rc
= sexp_to_key( s_pkey
, 0, &pkey
, &algo
, &i
);
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
)
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
) )
1283 release_mpi_array( 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,
1293 release_mpi_array( 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
;
1305 release_mpi_array( ciph
);
1310 /* We did it. Now build the return list */
1313 size_t nelem
, needed
= strlen(algo_name
) + 30;
1315 /* FIXME, this calculation needs to be cleaned up.
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
++ ) {
1330 *p
++ = algo_elems
[i
];
1331 p
= stpcpy ( p
, "%m)" );
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 :-(
1338 case 1: rc
= gcry_sexp_build ( r_ciph
, NULL
, string
,
1341 case 2: rc
= gcry_sexp_build ( r_ciph
, NULL
, string
,
1344 case 3: rc
= gcry_sexp_build ( r_ciph
, NULL
, string
,
1345 ciph
[0], ciph
[1], ciph
[2]
1347 case 4: rc
= gcry_sexp_build ( r_ciph
, NULL
, string
,
1348 ciph
[0], ciph
[1], ciph
[2], ciph
[3]
1350 case 5: rc
= gcry_sexp_build ( r_ciph
, NULL
, string
,
1351 ciph
[0], ciph
[1], ciph
[2], ciph
[3], ciph
[4]
1353 case 6: rc
= gcry_sexp_build ( r_ciph
, NULL
, string
,
1354 ciph
[0], ciph
[1], ciph
[2], ciph
[3], ciph
[4], ciph
[5]
1360 gcry_free ( string
);
1362 release_mpi_array( ciph
);
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
1379 * Returns: 0 or an errorcode.
1384 * (<param_name1> <mpi>)
1386 * (<param_namen> <mpi>)
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:
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
;
1399 rc
= sexp_to_key( s_skey
, 1, &skey
, &algo
, NULL
);
1403 rc
= sexp_to_enc( s_data
, &data
, &dataalgo
, &modern
, &want_pkcs1
,
1406 release_mpi_array( skey
);
1410 if( algo
!= dataalgo
) {
1411 release_mpi_array( skey
);
1413 release_mpi_array( data
);
1415 return GCRYERR_CONFLICT
; /* key algo does not match data algo */
1418 rc
= pubkey_decrypt( algo
, &plain
, data
, skey
, flags
);
1420 release_mpi_array( skey
);
1422 release_mpi_array( data
);
1424 return GCRYERR_GENERAL
; /* decryption failed */
1428 if ( gcry_sexp_build( r_plain
, NULL
, "%m", plain
) )
1432 if ( gcry_sexp_build( r_plain
, NULL
, "(value %m)", plain
) )
1438 release_mpi_array( data
);
1440 release_mpi_array( skey
);
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
1463 * s_hash = See comment for sexp_data_to_mpi
1465 * s_skey = <key-as-defined-in-sexp_to_key>
1468 * (<param_name1> <mpi>)
1470 * (<param_namen> <mpi>)
1473 gcry_pk_sign( GCRY_SEXP
*r_sig
, GCRY_SEXP s_hash
, GCRY_SEXP s_skey
)
1478 const char *key_algo_name
, *algo_name
, *algo_elems
;
1481 rc
= sexp_to_key( s_skey
, 1, &skey
, &algo
, &i
);
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
) )
1495 release_mpi_array( 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
);
1506 release_mpi_array( skey
);
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
;
1516 gcry_free( result
);
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
++ ) {
1533 *p
++ = algo_elems
[i
];
1534 p
= stpcpy ( p
, "%m)" );
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 :-(
1541 case 1: rc
= gcry_sexp_build ( r_sig
, NULL
, string
,
1544 case 2: rc
= gcry_sexp_build ( r_sig
, NULL
, string
,
1545 result
[0], result
[1]
1547 case 3: rc
= gcry_sexp_build ( r_sig
, NULL
, string
,
1548 result
[0], result
[1], result
[2]
1550 case 4: rc
= gcry_sexp_build ( r_sig
, NULL
, string
,
1551 result
[0], result
[1], result
[2], result
[3]
1553 case 5: rc
= gcry_sexp_build ( r_sig
, NULL
, string
,
1554 result
[0], result
[1], result
[2], result
[3], result
[4]
1556 case 6: rc
= gcry_sexp_build ( r_sig
, NULL
, string
,
1557 result
[0], result
[1], result
[2], result
[3], result
[4], result
[5]
1563 gcry_free ( string
);
1565 release_mpi_array( result
);
1566 gcry_free( result
);
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
;
1585 rc
= sexp_to_key( s_pkey
, 0, &pkey
, &algo
, NULL
);
1588 rc
= sexp_to_sig( s_sig
, &sig
, &sigalgo
);
1590 release_mpi_array( pkey
);
1594 if( algo
!= sigalgo
) {
1595 release_mpi_array( pkey
);
1597 release_mpi_array( 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);
1604 release_mpi_array( pkey
);
1606 release_mpi_array( sig
);
1611 rc
= pubkey_verify( algo
, hash
, sig
, pkey
, NULL
, NULL
);
1612 release_mpi_array( pkey
);
1614 release_mpi_array( sig
);
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
)
1636 /* Note we currently support only secret key checking */
1637 rc
= sexp_to_key( s_key
, 1, &key
, &algo
, NULL
);
1642 rc
= pubkey_check_secret_key( algo
, key
);
1643 release_mpi_array( key
);
1650 * Create a public key pair and return it in r_key.
1651 * How the key is created depends on s_parms:
1654 * (parameter_name_1 ....)
1656 * (parameter_name_n ....)
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:
1679 * (pm1-factors n1 n2 ... nn)
1684 gcry_pk_genkey( GCRY_SEXP
*r_key
, GCRY_SEXP s_parms
)
1691 const char *algo_name
;
1693 char sec_elems
[20], pub_elems
[20];
1694 GCRY_MPI skey
[10], *factors
;
1696 unsigned long use_e
;
1699 list
= gcry_sexp_find_token( s_parms
, "genkey", 0 );
1701 return GCRYERR_INV_OBJ
; /* Does not contain genkey data */
1702 l2
= gcry_sexp_cadr( list
);
1703 gcry_sexp_release ( list
);
1706 return GCRYERR_NO_OBJ
; /* no cdr for the genkey */
1707 name
= gcry_sexp_nth_data( list
, 0, &n
);
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
) )
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);
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
);
1753 use_e
= strtoul (buf
, NULL
, 0);
1754 gcry_sexp_release (l2
);
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
);
1763 return GCRYERR_NO_OBJ
; /* no nbits parameter */
1764 name
= gcry_sexp_nth_data( list
, 1, &n
);
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
);
1773 nbits
= (unsigned int)strtol( p
, NULL
, 0 );
1776 gcry_sexp_release ( list
);
1778 rc
= pubkey_generate( algo
, nbits
, use_e
, skey
, &factors
);
1785 size_t nelem
=0, needed
=0;
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
) )
1800 /* build the string */
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
++ ) {
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
++ ) {
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 */
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]
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
);
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?
1868 gcry_pk_get_nbits( GCRY_SEXP key
)
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
);
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
);
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] );
1890 release_mpi_array( keyarr
);
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. */
1903 gcry_pk_get_keygrip (GCRY_SEXP key
, unsigned char *array
)
1905 GCRY_SEXP list
=NULL
, l2
;
1906 const char *s
, *name
;
1911 GCRY_MD_HD md
= NULL
;
1913 /* check that the first element is valid */
1914 list
= gcry_sexp_find_token (key
, "public-key", 0);
1916 list
= gcry_sexp_find_token (key
, "private-key", 0);
1918 list
= gcry_sexp_find_token (key
, "protected-private-key", 0);
1920 return NULL
; /* no public- or private-key object */
1922 l2
= gcry_sexp_cadr (list
);
1923 gcry_sexp_release (list
);
1926 name
= gcry_sexp_nth_data( list
, 0, &n
);
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
))
1937 goto fail
; /* unknown algorithm */
1939 is_rsa
= algo_info_table
[i
].algo
== PUBKEY_ALGO_RSA
;
1940 elems
= algo_info_table
[i
].grip_elements
;
1942 goto fail
; /* no grip parameter */
1944 md
= gcry_md_open (GCRY_MD_SHA1
, 0);
1949 for (s
=elems
; *s
; s
++, idx
++)
1954 l2
= gcry_sexp_find_token (list
, s
, 1);
1957 data
= gcry_sexp_nth_data (l2
, 1, &datalen
);
1958 gcry_sexp_release (l2
);
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
);
1975 gcry_md_write (md
, ")", 1);
1980 array
= gcry_malloc (20);
1984 memcpy (array
, gcry_md_read (md
, GCRY_MD_SHA1
), 20);
1986 gcry_sexp_release (list
);
1991 gcry_sexp_release (list
);
1998 gcry_pk_ctl( int cmd
, void *buffer
, size_t buflen
)
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
);
2011 return set_lasterr( GCRYERR_INV_OP
);
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
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
2040 gcry_pk_algo_info( int algo
, int what
, void *buffer
, size_t *nbytes
)
2043 case GCRYCTL_TEST_ALGO
: {
2044 int use
= nbytes
? *nbytes
: 0;
2046 set_lasterr( GCRYERR_INV_ARG
);
2049 if( check_pubkey_algo( algo
, use
) ) {
2050 set_lasterr( GCRYERR_INV_PK_ALGO
);
2056 case GCRYCTL_GET_ALGO_USAGE
:
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() );
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
);
2071 set_lasterr( GCRYERR_INV_OP
);