aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/pubkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/pubkey.c')
-rw-r--r--[-rwxr-xr-x]linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/pubkey.c4720
1 files changed, 2360 insertions, 2360 deletions
diff --git a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/pubkey.c b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/pubkey.c
index 4bed8a5..35ac8f2 100755..100644
--- a/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/pubkey.c
+++ b/linden/indra/libgcrypt/libgcrypt-1.2.2/cipher/pubkey.c
@@ -1,2360 +1,2360 @@
1/* pubkey.c - pubkey dispatcher 1/* pubkey.c - pubkey dispatcher
2 * Copyright (C) 1998,1999,2000,2002,2003 Free Software Foundation, Inc. 2 * Copyright (C) 1998,1999,2000,2002,2003 Free Software Foundation, Inc.
3 * 3 *
4 * This file is part of Libgcrypt. 4 * This file is part of Libgcrypt.
5 * 5 *
6 * Libgcrypt is free software; you can redistribute it and/or modify 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 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 8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version. 9 * the License, or (at your option) any later version.
10 * 10 *
11 * Libgcrypt is distributed in the hope that it will be useful, 11 * Libgcrypt is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details. 14 * GNU Lesser General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU Lesser General Public 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 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 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19 */ 19 */
20 20
21#include <config.h> 21#include <config.h>
22#include <stdio.h> 22#include <stdio.h>
23#include <stdlib.h> 23#include <stdlib.h>
24#include <string.h> 24#include <string.h>
25#include <errno.h> 25#include <errno.h>
26#include <assert.h> 26#include <assert.h>
27 27
28#include "g10lib.h" 28#include "g10lib.h"
29#include "mpi.h" 29#include "mpi.h"
30#include "cipher.h" 30#include "cipher.h"
31#include "ath.h" 31#include "ath.h"
32 32
33static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result, 33static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
34 gcry_mpi_t *data, gcry_mpi_t *skey, 34 gcry_mpi_t *data, gcry_mpi_t *skey,
35 int flags); 35 int flags);
36static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr, 36static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
37 gcry_mpi_t hash, gcry_mpi_t *skey); 37 gcry_mpi_t hash, gcry_mpi_t *skey);
38static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash, 38static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
39 gcry_mpi_t *data, gcry_mpi_t *pkey, 39 gcry_mpi_t *data, gcry_mpi_t *pkey,
40 int (*cmp) (void *, gcry_mpi_t), 40 int (*cmp) (void *, gcry_mpi_t),
41 void *opaque); 41 void *opaque);
42 42
43/* This is the list of the default public-key ciphers included in 43/* This is the list of the default public-key ciphers included in
44 libgcrypt. */ 44 libgcrypt. */
45static struct pubkey_table_entry 45static struct pubkey_table_entry
46{ 46{
47 gcry_pk_spec_t *pubkey; 47 gcry_pk_spec_t *pubkey;
48 unsigned int algorithm; 48 unsigned int algorithm;
49} pubkey_table[] = 49} pubkey_table[] =
50 { 50 {
51#if USE_RSA 51#if USE_RSA
52 { &_gcry_pubkey_spec_rsa, GCRY_PK_RSA }, 52 { &_gcry_pubkey_spec_rsa, GCRY_PK_RSA },
53#endif 53#endif
54#if USE_ELGAMAL 54#if USE_ELGAMAL
55 { &_gcry_pubkey_spec_elg, GCRY_PK_ELG }, 55 { &_gcry_pubkey_spec_elg, GCRY_PK_ELG },
56 { &_gcry_pubkey_spec_elg, GCRY_PK_ELG_E }, 56 { &_gcry_pubkey_spec_elg, GCRY_PK_ELG_E },
57#endif 57#endif
58#if USE_DSA 58#if USE_DSA
59 { &_gcry_pubkey_spec_dsa, GCRY_PK_DSA }, 59 { &_gcry_pubkey_spec_dsa, GCRY_PK_DSA },
60#endif 60#endif
61 { NULL, 0 }, 61 { NULL, 0 },
62 }; 62 };
63 63
64/* List of registered ciphers. */ 64/* List of registered ciphers. */
65static gcry_module_t pubkeys_registered; 65static gcry_module_t pubkeys_registered;
66 66
67/* This is the lock protecting PUBKEYS_REGISTERED. */ 67/* This is the lock protecting PUBKEYS_REGISTERED. */
68static ath_mutex_t pubkeys_registered_lock; 68static ath_mutex_t pubkeys_registered_lock;
69 69
70/* Flag to check wether the default pubkeys have already been 70/* Flag to check wether the default pubkeys have already been
71 registered. */ 71 registered. */
72static int default_pubkeys_registered; 72static int default_pubkeys_registered;
73 73
74/* Convenient macro for registering the default digests. */ 74/* Convenient macro for registering the default digests. */
75#define REGISTER_DEFAULT_PUBKEYS \ 75#define REGISTER_DEFAULT_PUBKEYS \
76 do \ 76 do \
77 { \ 77 { \
78 ath_mutex_lock (&pubkeys_registered_lock); \ 78 ath_mutex_lock (&pubkeys_registered_lock); \
79 if (! default_pubkeys_registered) \ 79 if (! default_pubkeys_registered) \
80 { \ 80 { \
81 gcry_pk_register_default (); \ 81 gcry_pk_register_default (); \
82 default_pubkeys_registered = 1; \ 82 default_pubkeys_registered = 1; \
83 } \ 83 } \
84 ath_mutex_unlock (&pubkeys_registered_lock); \ 84 ath_mutex_unlock (&pubkeys_registered_lock); \
85 } \ 85 } \
86 while (0) 86 while (0)
87 87
88/* These dummy functions are used in case a cipher implementation 88/* These dummy functions are used in case a cipher implementation
89 refuses to provide it's own functions. */ 89 refuses to provide it's own functions. */
90 90
91static gcry_err_code_t 91static gcry_err_code_t
92dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy, 92dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
93 gcry_mpi_t *skey, gcry_mpi_t **retfactors) 93 gcry_mpi_t *skey, gcry_mpi_t **retfactors)
94{ 94{
95 log_bug ("no generate() for %d\n", algorithm); 95 log_bug ("no generate() for %d\n", algorithm);
96 return GPG_ERR_PUBKEY_ALGO; 96 return GPG_ERR_PUBKEY_ALGO;
97} 97}
98 98
99static gcry_err_code_t 99static gcry_err_code_t
100dummy_check_secret_key (int algorithm, gcry_mpi_t *skey) 100dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
101{ 101{
102 log_bug ("no check_secret_key() for %d\n", algorithm); 102 log_bug ("no check_secret_key() for %d\n", algorithm);
103 return GPG_ERR_PUBKEY_ALGO; 103 return GPG_ERR_PUBKEY_ALGO;
104} 104}
105 105
106static gcry_err_code_t 106static gcry_err_code_t
107dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, 107dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
108 gcry_mpi_t *pkey, int flags) 108 gcry_mpi_t *pkey, int flags)
109{ 109{
110 log_bug ("no encrypt() for %d\n", algorithm); 110 log_bug ("no encrypt() for %d\n", algorithm);
111 return GPG_ERR_PUBKEY_ALGO; 111 return GPG_ERR_PUBKEY_ALGO;
112} 112}
113 113
114static gcry_err_code_t 114static gcry_err_code_t
115dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data, 115dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
116 gcry_mpi_t *skey, int flags) 116 gcry_mpi_t *skey, int flags)
117{ 117{
118 log_bug ("no decrypt() for %d\n", algorithm); 118 log_bug ("no decrypt() for %d\n", algorithm);
119 return GPG_ERR_PUBKEY_ALGO; 119 return GPG_ERR_PUBKEY_ALGO;
120} 120}
121 121
122static gcry_err_code_t 122static gcry_err_code_t
123dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, 123dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
124 gcry_mpi_t *skey) 124 gcry_mpi_t *skey)
125{ 125{
126 log_bug ("no sign() for %d\n", algorithm); 126 log_bug ("no sign() for %d\n", algorithm);
127 return GPG_ERR_PUBKEY_ALGO; 127 return GPG_ERR_PUBKEY_ALGO;
128} 128}
129 129
130static gcry_err_code_t 130static gcry_err_code_t
131dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, 131dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
132 gcry_mpi_t *pkey, 132 gcry_mpi_t *pkey,
133 int (*cmp) (void *, gcry_mpi_t), void *opaquev) 133 int (*cmp) (void *, gcry_mpi_t), void *opaquev)
134{ 134{
135 log_bug ("no verify() for %d\n", algorithm); 135 log_bug ("no verify() for %d\n", algorithm);
136 return GPG_ERR_PUBKEY_ALGO; 136 return GPG_ERR_PUBKEY_ALGO;
137} 137}
138 138
139static unsigned 139static unsigned
140dummy_get_nbits (int algorithm, gcry_mpi_t *pkey) 140dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
141{ 141{
142 log_bug ("no get_nbits() for %d\n", algorithm); 142 log_bug ("no get_nbits() for %d\n", algorithm);
143 return 0; 143 return 0;
144} 144}
145 145
146/* Internal function. Register all the pubkeys included in 146/* Internal function. Register all the pubkeys included in
147 PUBKEY_TABLE. Returns zero on success or an error code. */ 147 PUBKEY_TABLE. Returns zero on success or an error code. */
148static void 148static void
149gcry_pk_register_default (void) 149gcry_pk_register_default (void)
150{ 150{
151 gcry_err_code_t err = 0; 151 gcry_err_code_t err = 0;
152 int i; 152 int i;
153 153
154 for (i = 0; (! err) && pubkey_table[i].pubkey; i++) 154 for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
155 { 155 {
156#define pubkey_use_dummy(func) \ 156#define pubkey_use_dummy(func) \
157 if (! pubkey_table[i].pubkey->func) \ 157 if (! pubkey_table[i].pubkey->func) \
158 pubkey_table[i].pubkey->func = dummy_##func; 158 pubkey_table[i].pubkey->func = dummy_##func;
159 159
160 pubkey_use_dummy (generate); 160 pubkey_use_dummy (generate);
161 pubkey_use_dummy (check_secret_key); 161 pubkey_use_dummy (check_secret_key);
162 pubkey_use_dummy (encrypt); 162 pubkey_use_dummy (encrypt);
163 pubkey_use_dummy (decrypt); 163 pubkey_use_dummy (decrypt);
164 pubkey_use_dummy (sign); 164 pubkey_use_dummy (sign);
165 pubkey_use_dummy (verify); 165 pubkey_use_dummy (verify);
166 pubkey_use_dummy (get_nbits); 166 pubkey_use_dummy (get_nbits);
167#undef pubkey_use_dummy 167#undef pubkey_use_dummy
168 err = _gcry_module_add (&pubkeys_registered, 168 err = _gcry_module_add (&pubkeys_registered,
169 pubkey_table[i].algorithm, 169 pubkey_table[i].algorithm,
170 (void *) pubkey_table[i].pubkey, NULL); 170 (void *) pubkey_table[i].pubkey, NULL);
171 } 171 }
172 172
173 if (err) 173 if (err)
174 BUG (); 174 BUG ();
175} 175}
176 176
177/* Internal callback function. Used via _gcry_module_lookup. */ 177/* Internal callback function. Used via _gcry_module_lookup. */
178static int 178static int
179gcry_pk_lookup_func_name (void *spec, void *data) 179gcry_pk_lookup_func_name (void *spec, void *data)
180{ 180{
181 gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec; 181 gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
182 char *name = (char *) data; 182 char *name = (char *) data;
183 char **aliases = pubkey->aliases; 183 char **aliases = pubkey->aliases;
184 int ret = stricmp (name, pubkey->name); 184 int ret = stricmp (name, pubkey->name);
185 185
186 while (ret && *aliases) 186 while (ret && *aliases)
187 ret = stricmp (name, *aliases++); 187 ret = stricmp (name, *aliases++);
188 188
189 return ! ret; 189 return ! ret;
190} 190}
191 191
192/* Internal function. Lookup a pubkey entry by it's name. */ 192/* Internal function. Lookup a pubkey entry by it's name. */
193static gcry_module_t 193static gcry_module_t
194gcry_pk_lookup_name (const char *name) 194gcry_pk_lookup_name (const char *name)
195{ 195{
196 gcry_module_t pubkey; 196 gcry_module_t pubkey;
197 197
198 pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name, 198 pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
199 gcry_pk_lookup_func_name); 199 gcry_pk_lookup_func_name);
200 200
201 return pubkey; 201 return pubkey;
202} 202}
203 203
204/* Register a new pubkey module whose specification can be found in 204/* Register a new pubkey module whose specification can be found in
205 PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID 205 PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID
206 and a pointer representhing this module is stored in MODULE. */ 206 and a pointer representhing this module is stored in MODULE. */
207gcry_error_t 207gcry_error_t
208gcry_pk_register (gcry_pk_spec_t *pubkey, 208gcry_pk_register (gcry_pk_spec_t *pubkey,
209 unsigned int *algorithm_id, 209 unsigned int *algorithm_id,
210 gcry_module_t *module) 210 gcry_module_t *module)
211{ 211{
212 gcry_err_code_t err = GPG_ERR_NO_ERROR; 212 gcry_err_code_t err = GPG_ERR_NO_ERROR;
213 gcry_module_t mod; 213 gcry_module_t mod;
214 214
215 ath_mutex_lock (&pubkeys_registered_lock); 215 ath_mutex_lock (&pubkeys_registered_lock);
216 err = _gcry_module_add (&pubkeys_registered, 0, 216 err = _gcry_module_add (&pubkeys_registered, 0,
217 (void *) pubkey, &mod); 217 (void *) pubkey, &mod);
218 ath_mutex_unlock (&pubkeys_registered_lock); 218 ath_mutex_unlock (&pubkeys_registered_lock);
219 219
220 if (! err) 220 if (! err)
221 { 221 {
222 *module = mod; 222 *module = mod;
223 *algorithm_id = mod->mod_id; 223 *algorithm_id = mod->mod_id;
224 } 224 }
225 225
226 return err; 226 return err;
227} 227}
228 228
229/* Unregister the pubkey identified by ID, which must have been 229/* Unregister the pubkey identified by ID, which must have been
230 registered with gcry_pk_register. */ 230 registered with gcry_pk_register. */
231void 231void
232gcry_pk_unregister (gcry_module_t module) 232gcry_pk_unregister (gcry_module_t module)
233{ 233{
234 ath_mutex_lock (&pubkeys_registered_lock); 234 ath_mutex_lock (&pubkeys_registered_lock);
235 _gcry_module_release (module); 235 _gcry_module_release (module);
236 ath_mutex_unlock (&pubkeys_registered_lock); 236 ath_mutex_unlock (&pubkeys_registered_lock);
237} 237}
238 238
239static void 239static void
240release_mpi_array (gcry_mpi_t *array) 240release_mpi_array (gcry_mpi_t *array)
241{ 241{
242 for (; *array; array++) 242 for (; *array; array++)
243 { 243 {
244 mpi_free(*array); 244 mpi_free(*array);
245 *array = NULL; 245 *array = NULL;
246 } 246 }
247} 247}
248 248
249/**************** 249/****************
250 * Map a string to the pubkey algo 250 * Map a string to the pubkey algo
251 */ 251 */
252int 252int
253gcry_pk_map_name (const char *string) 253gcry_pk_map_name (const char *string)
254{ 254{
255 gcry_module_t pubkey; 255 gcry_module_t pubkey;
256 int algorithm = 0; 256 int algorithm = 0;
257 257
258 if (!string) 258 if (!string)
259 return 0; 259 return 0;
260 260
261 REGISTER_DEFAULT_PUBKEYS; 261 REGISTER_DEFAULT_PUBKEYS;
262 262
263 ath_mutex_lock (&pubkeys_registered_lock); 263 ath_mutex_lock (&pubkeys_registered_lock);
264 pubkey = gcry_pk_lookup_name (string); 264 pubkey = gcry_pk_lookup_name (string);
265 if (pubkey) 265 if (pubkey)
266 { 266 {
267 algorithm = pubkey->mod_id; 267 algorithm = pubkey->mod_id;
268 _gcry_module_release (pubkey); 268 _gcry_module_release (pubkey);
269 } 269 }
270 ath_mutex_unlock (&pubkeys_registered_lock); 270 ath_mutex_unlock (&pubkeys_registered_lock);
271 271
272 return algorithm; 272 return algorithm;
273} 273}
274 274
275 275
276/**************** 276/****************
277 * Map a pubkey algo to a string 277 * Map a pubkey algo to a string
278 */ 278 */
279const char * 279const char *
280gcry_pk_algo_name (int algorithm) 280gcry_pk_algo_name (int algorithm)
281{ 281{
282 const char *name = NULL; 282 const char *name = NULL;
283 gcry_module_t pubkey; 283 gcry_module_t pubkey;
284 284
285 REGISTER_DEFAULT_PUBKEYS; 285 REGISTER_DEFAULT_PUBKEYS;
286 286
287 ath_mutex_lock (&pubkeys_registered_lock); 287 ath_mutex_lock (&pubkeys_registered_lock);
288 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 288 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
289 if (pubkey) 289 if (pubkey)
290 { 290 {
291 name = ((gcry_pk_spec_t *) pubkey->spec)->name; 291 name = ((gcry_pk_spec_t *) pubkey->spec)->name;
292 _gcry_module_release (pubkey); 292 _gcry_module_release (pubkey);
293 } 293 }
294 ath_mutex_unlock (&pubkeys_registered_lock); 294 ath_mutex_unlock (&pubkeys_registered_lock);
295 295
296 return name; 296 return name;
297} 297}
298 298
299 299
300/* A special version of gcry_pk_algo name to return the first aliased 300/* A special version of gcry_pk_algo name to return the first aliased
301 name of the algorithm. This is required to adhere to the spki 301 name of the algorithm. This is required to adhere to the spki
302 specs where the algorithm names are lowercase. */ 302 specs where the algorithm names are lowercase. */
303const char * 303const char *
304_gcry_pk_aliased_algo_name (int algorithm) 304_gcry_pk_aliased_algo_name (int algorithm)
305{ 305{
306 const char *name = NULL; 306 const char *name = NULL;
307 gcry_module_t module; 307 gcry_module_t module;
308 308
309 REGISTER_DEFAULT_PUBKEYS; 309 REGISTER_DEFAULT_PUBKEYS;
310 310
311 ath_mutex_lock (&pubkeys_registered_lock); 311 ath_mutex_lock (&pubkeys_registered_lock);
312 module = _gcry_module_lookup_id (pubkeys_registered, algorithm); 312 module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
313 if (module) 313 if (module)
314 { 314 {
315 gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec; 315 gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
316 316
317 name = pubkey->aliases? *pubkey->aliases : NULL; 317 name = pubkey->aliases? *pubkey->aliases : NULL;
318 if (!name || !*name) 318 if (!name || !*name)
319 name = pubkey->name; 319 name = pubkey->name;
320 _gcry_module_release (module); 320 _gcry_module_release (module);
321 } 321 }
322 ath_mutex_unlock (&pubkeys_registered_lock); 322 ath_mutex_unlock (&pubkeys_registered_lock);
323 323
324 return name; 324 return name;
325} 325}
326 326
327 327
328static void 328static void
329disable_pubkey_algo (int algorithm) 329disable_pubkey_algo (int algorithm)
330{ 330{
331 gcry_module_t pubkey; 331 gcry_module_t pubkey;
332 332
333 ath_mutex_lock (&pubkeys_registered_lock); 333 ath_mutex_lock (&pubkeys_registered_lock);
334 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 334 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
335 if (pubkey) 335 if (pubkey)
336 { 336 {
337 if (! (pubkey-> flags & FLAG_MODULE_DISABLED)) 337 if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
338 pubkey->flags |= FLAG_MODULE_DISABLED; 338 pubkey->flags |= FLAG_MODULE_DISABLED;
339 _gcry_module_release (pubkey); 339 _gcry_module_release (pubkey);
340 } 340 }
341 ath_mutex_unlock (&pubkeys_registered_lock); 341 ath_mutex_unlock (&pubkeys_registered_lock);
342} 342}
343 343
344 344
345/**************** 345/****************
346 * A USE of 0 means: don't care. 346 * A USE of 0 means: don't care.
347 */ 347 */
348static gcry_err_code_t 348static gcry_err_code_t
349check_pubkey_algo (int algorithm, unsigned use) 349check_pubkey_algo (int algorithm, unsigned use)
350{ 350{
351 gcry_err_code_t err = GPG_ERR_NO_ERROR; 351 gcry_err_code_t err = GPG_ERR_NO_ERROR;
352 gcry_pk_spec_t *pubkey; 352 gcry_pk_spec_t *pubkey;
353 gcry_module_t module; 353 gcry_module_t module;
354 354
355 REGISTER_DEFAULT_PUBKEYS; 355 REGISTER_DEFAULT_PUBKEYS;
356 356
357 ath_mutex_lock (&pubkeys_registered_lock); 357 ath_mutex_lock (&pubkeys_registered_lock);
358 module = _gcry_module_lookup_id (pubkeys_registered, algorithm); 358 module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
359 if (module) 359 if (module)
360 { 360 {
361 pubkey = (gcry_pk_spec_t *) module->spec; 361 pubkey = (gcry_pk_spec_t *) module->spec;
362 362
363 if (((use & GCRY_PK_USAGE_SIGN) 363 if (((use & GCRY_PK_USAGE_SIGN)
364 && (! (pubkey->use & GCRY_PK_USAGE_SIGN))) 364 && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
365 || ((use & GCRY_PK_USAGE_ENCR) 365 || ((use & GCRY_PK_USAGE_ENCR)
366 && (! (pubkey->use & GCRY_PK_USAGE_ENCR)))) 366 && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
367 err = GPG_ERR_WRONG_PUBKEY_ALGO; 367 err = GPG_ERR_WRONG_PUBKEY_ALGO;
368 else if (module->flags & FLAG_MODULE_DISABLED) 368 else if (module->flags & FLAG_MODULE_DISABLED)
369 err = GPG_ERR_PUBKEY_ALGO; 369 err = GPG_ERR_PUBKEY_ALGO;
370 _gcry_module_release (module); 370 _gcry_module_release (module);
371 } 371 }
372 else 372 else
373 err = GPG_ERR_PUBKEY_ALGO; 373 err = GPG_ERR_PUBKEY_ALGO;
374 ath_mutex_unlock (&pubkeys_registered_lock); 374 ath_mutex_unlock (&pubkeys_registered_lock);
375 375
376 return err; 376 return err;
377} 377}
378 378
379 379
380/**************** 380/****************
381 * Return the number of public key material numbers 381 * Return the number of public key material numbers
382 */ 382 */
383static int 383static int
384pubkey_get_npkey (int algorithm) 384pubkey_get_npkey (int algorithm)
385{ 385{
386 gcry_module_t pubkey; 386 gcry_module_t pubkey;
387 int npkey = 0; 387 int npkey = 0;
388 388
389 REGISTER_DEFAULT_PUBKEYS; 389 REGISTER_DEFAULT_PUBKEYS;
390 390
391 ath_mutex_lock (&pubkeys_registered_lock); 391 ath_mutex_lock (&pubkeys_registered_lock);
392 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 392 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
393 if (pubkey) 393 if (pubkey)
394 { 394 {
395 npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey); 395 npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
396 _gcry_module_release (pubkey); 396 _gcry_module_release (pubkey);
397 } 397 }
398 ath_mutex_unlock (&pubkeys_registered_lock); 398 ath_mutex_unlock (&pubkeys_registered_lock);
399 399
400 return npkey; 400 return npkey;
401} 401}
402 402
403/**************** 403/****************
404 * Return the number of secret key material numbers 404 * Return the number of secret key material numbers
405 */ 405 */
406static int 406static int
407pubkey_get_nskey (int algorithm) 407pubkey_get_nskey (int algorithm)
408{ 408{
409 gcry_module_t pubkey; 409 gcry_module_t pubkey;
410 int nskey = 0; 410 int nskey = 0;
411 411
412 REGISTER_DEFAULT_PUBKEYS; 412 REGISTER_DEFAULT_PUBKEYS;
413 413
414 ath_mutex_lock (&pubkeys_registered_lock); 414 ath_mutex_lock (&pubkeys_registered_lock);
415 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 415 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
416 if (pubkey) 416 if (pubkey)
417 { 417 {
418 nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey); 418 nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
419 _gcry_module_release (pubkey); 419 _gcry_module_release (pubkey);
420 } 420 }
421 ath_mutex_unlock (&pubkeys_registered_lock); 421 ath_mutex_unlock (&pubkeys_registered_lock);
422 422
423 return nskey; 423 return nskey;
424} 424}
425 425
426/**************** 426/****************
427 * Return the number of signature material numbers 427 * Return the number of signature material numbers
428 */ 428 */
429static int 429static int
430pubkey_get_nsig (int algorithm) 430pubkey_get_nsig (int algorithm)
431{ 431{
432 gcry_module_t pubkey; 432 gcry_module_t pubkey;
433 int nsig = 0; 433 int nsig = 0;
434 434
435 REGISTER_DEFAULT_PUBKEYS; 435 REGISTER_DEFAULT_PUBKEYS;
436 436
437 ath_mutex_lock (&pubkeys_registered_lock); 437 ath_mutex_lock (&pubkeys_registered_lock);
438 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 438 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
439 if (pubkey) 439 if (pubkey)
440 { 440 {
441 nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig); 441 nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
442 _gcry_module_release (pubkey); 442 _gcry_module_release (pubkey);
443 } 443 }
444 ath_mutex_unlock (&pubkeys_registered_lock); 444 ath_mutex_unlock (&pubkeys_registered_lock);
445 445
446 return nsig; 446 return nsig;
447} 447}
448 448
449/**************** 449/****************
450 * Return the number of encryption material numbers 450 * Return the number of encryption material numbers
451 */ 451 */
452static int 452static int
453pubkey_get_nenc (int algorithm) 453pubkey_get_nenc (int algorithm)
454{ 454{
455 gcry_module_t pubkey; 455 gcry_module_t pubkey;
456 int nenc = 0; 456 int nenc = 0;
457 457
458 REGISTER_DEFAULT_PUBKEYS; 458 REGISTER_DEFAULT_PUBKEYS;
459 459
460 ath_mutex_lock (&pubkeys_registered_lock); 460 ath_mutex_lock (&pubkeys_registered_lock);
461 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 461 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
462 if (pubkey) 462 if (pubkey)
463 { 463 {
464 nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc); 464 nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
465 _gcry_module_release (pubkey); 465 _gcry_module_release (pubkey);
466 } 466 }
467 ath_mutex_unlock (&pubkeys_registered_lock); 467 ath_mutex_unlock (&pubkeys_registered_lock);
468 468
469 return nenc; 469 return nenc;
470} 470}
471 471
472 472
473static gcry_err_code_t 473static gcry_err_code_t
474pubkey_generate (int algorithm, unsigned int nbits, unsigned long use_e, 474pubkey_generate (int algorithm, unsigned int nbits, unsigned long use_e,
475 gcry_mpi_t *skey, gcry_mpi_t **retfactors) 475 gcry_mpi_t *skey, gcry_mpi_t **retfactors)
476{ 476{
477 gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO; 477 gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
478 gcry_module_t pubkey; 478 gcry_module_t pubkey;
479 479
480 REGISTER_DEFAULT_PUBKEYS; 480 REGISTER_DEFAULT_PUBKEYS;
481 481
482 ath_mutex_lock (&pubkeys_registered_lock); 482 ath_mutex_lock (&pubkeys_registered_lock);
483 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 483 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
484 if (pubkey) 484 if (pubkey)
485 { 485 {
486 err = ((gcry_pk_spec_t *) pubkey->spec)->generate 486 err = ((gcry_pk_spec_t *) pubkey->spec)->generate
487 (algorithm, nbits, use_e, skey, retfactors); 487 (algorithm, nbits, use_e, skey, retfactors);
488 _gcry_module_release (pubkey); 488 _gcry_module_release (pubkey);
489 } 489 }
490 ath_mutex_unlock (&pubkeys_registered_lock); 490 ath_mutex_unlock (&pubkeys_registered_lock);
491 491
492 return err; 492 return err;
493} 493}
494 494
495static gcry_err_code_t 495static gcry_err_code_t
496pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey) 496pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
497{ 497{
498 gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO; 498 gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
499 gcry_module_t pubkey; 499 gcry_module_t pubkey;
500 500
501 REGISTER_DEFAULT_PUBKEYS; 501 REGISTER_DEFAULT_PUBKEYS;
502 502
503 ath_mutex_lock (&pubkeys_registered_lock); 503 ath_mutex_lock (&pubkeys_registered_lock);
504 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 504 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
505 if (pubkey) 505 if (pubkey)
506 { 506 {
507 err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key 507 err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
508 (algorithm, skey); 508 (algorithm, skey);
509 _gcry_module_release (pubkey); 509 _gcry_module_release (pubkey);
510 } 510 }
511 ath_mutex_unlock (&pubkeys_registered_lock); 511 ath_mutex_unlock (&pubkeys_registered_lock);
512 512
513 return err; 513 return err;
514} 514}
515 515
516 516
517/**************** 517/****************
518 * This is the interface to the public key encryption. Encrypt DATA 518 * This is the interface to the public key encryption. Encrypt DATA
519 * with PKEY and put it into RESARR which should be an array of MPIs 519 * with PKEY and put it into RESARR which should be an array of MPIs
520 * of size PUBKEY_MAX_NENC (or less if the algorithm allows this - 520 * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
521 * check with pubkey_get_nenc() ) 521 * check with pubkey_get_nenc() )
522 */ 522 */
523static gcry_err_code_t 523static gcry_err_code_t
524pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, 524pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
525 gcry_mpi_t *pkey, int flags) 525 gcry_mpi_t *pkey, int flags)
526{ 526{
527 gcry_pk_spec_t *pubkey; 527 gcry_pk_spec_t *pubkey;
528 gcry_module_t module; 528 gcry_module_t module;
529 gcry_err_code_t rc; 529 gcry_err_code_t rc;
530 int i; 530 int i;
531 531
532 if (DBG_CIPHER) 532 if (DBG_CIPHER)
533 { 533 {
534 log_debug ("pubkey_encrypt: algo=%d\n", algorithm); 534 log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
535 for(i = 0; i < pubkey_get_npkey (algorithm); i++) 535 for(i = 0; i < pubkey_get_npkey (algorithm); i++)
536 log_mpidump (" pkey:", pkey[i]); 536 log_mpidump (" pkey:", pkey[i]);
537 log_mpidump (" data:", data); 537 log_mpidump (" data:", data);
538 } 538 }
539 539
540 ath_mutex_lock (&pubkeys_registered_lock); 540 ath_mutex_lock (&pubkeys_registered_lock);
541 module = _gcry_module_lookup_id (pubkeys_registered, algorithm); 541 module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
542 if (module) 542 if (module)
543 { 543 {
544 pubkey = (gcry_pk_spec_t *) module->spec; 544 pubkey = (gcry_pk_spec_t *) module->spec;
545 rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags); 545 rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
546 _gcry_module_release (module); 546 _gcry_module_release (module);
547 goto ready; 547 goto ready;
548 } 548 }
549 rc = GPG_ERR_PUBKEY_ALGO; 549 rc = GPG_ERR_PUBKEY_ALGO;
550 550
551 ready: 551 ready:
552 ath_mutex_unlock (&pubkeys_registered_lock); 552 ath_mutex_unlock (&pubkeys_registered_lock);
553 553
554 if (!rc && DBG_CIPHER) 554 if (!rc && DBG_CIPHER)
555 { 555 {
556 for(i = 0; i < pubkey_get_nenc (algorithm); i++) 556 for(i = 0; i < pubkey_get_nenc (algorithm); i++)
557 log_mpidump(" encr:", resarr[i] ); 557 log_mpidump(" encr:", resarr[i] );
558 } 558 }
559 return rc; 559 return rc;
560} 560}
561 561
562 562
563/**************** 563/****************
564 * This is the interface to the public key decryption. 564 * This is the interface to the public key decryption.
565 * ALGO gives the algorithm to use and this implicitly determines 565 * ALGO gives the algorithm to use and this implicitly determines
566 * the size of the arrays. 566 * the size of the arrays.
567 * result is a pointer to a mpi variable which will receive a 567 * result is a pointer to a mpi variable which will receive a
568 * newly allocated mpi or NULL in case of an error. 568 * newly allocated mpi or NULL in case of an error.
569 */ 569 */
570static gcry_err_code_t 570static gcry_err_code_t
571pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data, 571pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
572 gcry_mpi_t *skey, int flags) 572 gcry_mpi_t *skey, int flags)
573{ 573{
574 gcry_pk_spec_t *pubkey; 574 gcry_pk_spec_t *pubkey;
575 gcry_module_t module; 575 gcry_module_t module;
576 gcry_err_code_t rc; 576 gcry_err_code_t rc;
577 int i; 577 int i;
578 578
579 *result = NULL; /* so the caller can always do a mpi_free */ 579 *result = NULL; /* so the caller can always do a mpi_free */
580 if (DBG_CIPHER) 580 if (DBG_CIPHER)
581 { 581 {
582 log_debug ("pubkey_decrypt: algo=%d\n", algorithm); 582 log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
583 for(i = 0; i < pubkey_get_nskey (algorithm); i++) 583 for(i = 0; i < pubkey_get_nskey (algorithm); i++)
584 log_mpidump (" skey:", skey[i]); 584 log_mpidump (" skey:", skey[i]);
585 for(i = 0; i < pubkey_get_nenc (algorithm); i++) 585 for(i = 0; i < pubkey_get_nenc (algorithm); i++)
586 log_mpidump (" data:", data[i]); 586 log_mpidump (" data:", data[i]);
587 } 587 }
588 588
589 ath_mutex_lock (&pubkeys_registered_lock); 589 ath_mutex_lock (&pubkeys_registered_lock);
590 module = _gcry_module_lookup_id (pubkeys_registered, algorithm); 590 module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
591 if (module) 591 if (module)
592 { 592 {
593 pubkey = (gcry_pk_spec_t *) module->spec; 593 pubkey = (gcry_pk_spec_t *) module->spec;
594 rc = pubkey->decrypt (algorithm, result, data, skey, flags); 594 rc = pubkey->decrypt (algorithm, result, data, skey, flags);
595 _gcry_module_release (module); 595 _gcry_module_release (module);
596 goto ready; 596 goto ready;
597 } 597 }
598 598
599 rc = GPG_ERR_PUBKEY_ALGO; 599 rc = GPG_ERR_PUBKEY_ALGO;
600 600
601 ready: 601 ready:
602 ath_mutex_unlock (&pubkeys_registered_lock); 602 ath_mutex_unlock (&pubkeys_registered_lock);
603 603
604 if (! rc && DBG_CIPHER) 604 if (! rc && DBG_CIPHER)
605 log_mpidump (" plain:", *result); 605 log_mpidump (" plain:", *result);
606 606
607 return rc; 607 return rc;
608} 608}
609 609
610 610
611/**************** 611/****************
612 * This is the interface to the public key signing. 612 * This is the interface to the public key signing.
613 * Sign data with skey and put the result into resarr which 613 * Sign data with skey and put the result into resarr which
614 * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the 614 * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
615 * algorithm allows this - check with pubkey_get_nsig() ) 615 * algorithm allows this - check with pubkey_get_nsig() )
616 */ 616 */
617static gcry_err_code_t 617static gcry_err_code_t
618pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data, 618pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
619 gcry_mpi_t *skey) 619 gcry_mpi_t *skey)
620{ 620{
621 gcry_pk_spec_t *pubkey; 621 gcry_pk_spec_t *pubkey;
622 gcry_module_t module; 622 gcry_module_t module;
623 gcry_err_code_t rc; 623 gcry_err_code_t rc;
624 int i; 624 int i;
625 625
626 if (DBG_CIPHER) 626 if (DBG_CIPHER)
627 { 627 {
628 log_debug ("pubkey_sign: algo=%d\n", algorithm); 628 log_debug ("pubkey_sign: algo=%d\n", algorithm);
629 for(i = 0; i < pubkey_get_nskey (algorithm); i++) 629 for(i = 0; i < pubkey_get_nskey (algorithm); i++)
630 log_mpidump (" skey:", skey[i]); 630 log_mpidump (" skey:", skey[i]);
631 log_mpidump(" data:", data ); 631 log_mpidump(" data:", data );
632 } 632 }
633 633
634 ath_mutex_lock (&pubkeys_registered_lock); 634 ath_mutex_lock (&pubkeys_registered_lock);
635 module = _gcry_module_lookup_id (pubkeys_registered, algorithm); 635 module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
636 if (module) 636 if (module)
637 { 637 {
638 pubkey = (gcry_pk_spec_t *) module->spec; 638 pubkey = (gcry_pk_spec_t *) module->spec;
639 rc = pubkey->sign (algorithm, resarr, data, skey); 639 rc = pubkey->sign (algorithm, resarr, data, skey);
640 _gcry_module_release (module); 640 _gcry_module_release (module);
641 goto ready; 641 goto ready;
642 } 642 }
643 643
644 rc = GPG_ERR_PUBKEY_ALGO; 644 rc = GPG_ERR_PUBKEY_ALGO;
645 645
646 ready: 646 ready:
647 ath_mutex_unlock (&pubkeys_registered_lock); 647 ath_mutex_unlock (&pubkeys_registered_lock);
648 648
649 if (! rc && DBG_CIPHER) 649 if (! rc && DBG_CIPHER)
650 for (i = 0; i < pubkey_get_nsig (algorithm); i++) 650 for (i = 0; i < pubkey_get_nsig (algorithm); i++)
651 log_mpidump (" sig:", resarr[i]); 651 log_mpidump (" sig:", resarr[i]);
652 652
653 return rc; 653 return rc;
654} 654}
655 655
656/**************** 656/****************
657 * Verify a public key signature. 657 * Verify a public key signature.
658 * Return 0 if the signature is good 658 * Return 0 if the signature is good
659 */ 659 */
660static gcry_err_code_t 660static gcry_err_code_t
661pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data, 661pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
662 gcry_mpi_t *pkey, 662 gcry_mpi_t *pkey,
663 int (*cmp)(void *, gcry_mpi_t), void *opaquev) 663 int (*cmp)(void *, gcry_mpi_t), void *opaquev)
664{ 664{
665 gcry_pk_spec_t *pubkey; 665 gcry_pk_spec_t *pubkey;
666 gcry_module_t module; 666 gcry_module_t module;
667 gcry_err_code_t rc; 667 gcry_err_code_t rc;
668 int i; 668 int i;
669 669
670 if (DBG_CIPHER) 670 if (DBG_CIPHER)
671 { 671 {
672 log_debug ("pubkey_verify: algo=%d\n", algorithm); 672 log_debug ("pubkey_verify: algo=%d\n", algorithm);
673 for (i = 0; i < pubkey_get_npkey (algorithm); i++) 673 for (i = 0; i < pubkey_get_npkey (algorithm); i++)
674 log_mpidump (" pkey:", pkey[i]); 674 log_mpidump (" pkey:", pkey[i]);
675 for (i = 0; i < pubkey_get_nsig (algorithm); i++) 675 for (i = 0; i < pubkey_get_nsig (algorithm); i++)
676 log_mpidump (" sig:", data[i]); 676 log_mpidump (" sig:", data[i]);
677 log_mpidump (" hash:", hash); 677 log_mpidump (" hash:", hash);
678 } 678 }
679 679
680 ath_mutex_lock (&pubkeys_registered_lock); 680 ath_mutex_lock (&pubkeys_registered_lock);
681 module = _gcry_module_lookup_id (pubkeys_registered, algorithm); 681 module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
682 if (module) 682 if (module)
683 { 683 {
684 pubkey = (gcry_pk_spec_t *) module->spec; 684 pubkey = (gcry_pk_spec_t *) module->spec;
685 rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev); 685 rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
686 _gcry_module_release (module); 686 _gcry_module_release (module);
687 goto ready; 687 goto ready;
688 } 688 }
689 689
690 rc = GPG_ERR_PUBKEY_ALGO; 690 rc = GPG_ERR_PUBKEY_ALGO;
691 691
692 ready: 692 ready:
693 ath_mutex_unlock (&pubkeys_registered_lock); 693 ath_mutex_unlock (&pubkeys_registered_lock);
694 return rc; 694 return rc;
695} 695}
696 696
697 697
698/* Internal function. */ 698/* Internal function. */
699static gcry_err_code_t 699static gcry_err_code_t
700sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names, 700sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
701 gcry_mpi_t *elements) 701 gcry_mpi_t *elements)
702{ 702{
703 gcry_err_code_t err = GPG_ERR_NO_ERROR; 703 gcry_err_code_t err = GPG_ERR_NO_ERROR;
704 int i, idx; 704 int i, idx;
705 const char *name; 705 const char *name;
706 gcry_sexp_t list; 706 gcry_sexp_t list;
707 707
708 for (name = element_names, idx = 0; *name && !err; name++, idx++) 708 for (name = element_names, idx = 0; *name && !err; name++, idx++)
709 { 709 {
710 list = gcry_sexp_find_token (key_sexp, name, 1); 710 list = gcry_sexp_find_token (key_sexp, name, 1);
711 if (! list) 711 if (! list)
712 err = GPG_ERR_NO_OBJ; 712 err = GPG_ERR_NO_OBJ;
713 else 713 else
714 { 714 {
715 elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG); 715 elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
716 gcry_sexp_release (list); 716 gcry_sexp_release (list);
717 if (! elements[idx]) 717 if (! elements[idx])
718 err = GPG_ERR_INV_OBJ; 718 err = GPG_ERR_INV_OBJ;
719 } 719 }
720 } 720 }
721 721
722 if (err) 722 if (err)
723 { 723 {
724 for (i = 0; i < idx; i++) 724 for (i = 0; i < idx; i++)
725 if (elements[i]) 725 if (elements[i])
726 gcry_free (elements[i]); 726 gcry_free (elements[i]);
727 } 727 }
728 return err; 728 return err;
729} 729}
730 730
731/**************** 731/****************
732 * Convert a S-Exp with either a private or a public key to our 732 * Convert a S-Exp with either a private or a public key to our
733 * internal format. Currently we do only support the following 733 * internal format. Currently we do only support the following
734 * algorithms: 734 * algorithms:
735 * dsa 735 * dsa
736 * rsa 736 * rsa
737 * openpgp-dsa 737 * openpgp-dsa
738 * openpgp-rsa 738 * openpgp-rsa
739 * openpgp-elg 739 * openpgp-elg
740 * openpgp-elg-sig 740 * openpgp-elg-sig
741 * Provide a SE with the first element be either "private-key" or 741 * Provide a SE with the first element be either "private-key" or
742 * or "public-key". It is followed by a list with its first element 742 * or "public-key". It is followed by a list with its first element
743 * be one of the above algorithm identifiers and the remaning 743 * be one of the above algorithm identifiers and the remaning
744 * elements are pairs with parameter-id and value. 744 * elements are pairs with parameter-id and value.
745 * NOTE: we look through the list to find a list beginning with 745 * NOTE: we look through the list to find a list beginning with
746 * "private-key" or "public-key" - the first one found is used. 746 * "private-key" or "public-key" - the first one found is used.
747 * 747 *
748 * FIXME: Allow for encrypted secret keys here. 748 * FIXME: Allow for encrypted secret keys here.
749 * 749 *
750 * Returns: A pointer to an allocated array of MPIs if the return value is 750 * Returns: A pointer to an allocated array of MPIs if the return value is
751 * zero; the caller has to release this array. 751 * zero; the caller has to release this array.
752 * 752 *
753 * Example of a DSA public key: 753 * Example of a DSA public key:
754 * (private-key 754 * (private-key
755 * (dsa 755 * (dsa
756 * (p <mpi>) 756 * (p <mpi>)
757 * (g <mpi>) 757 * (g <mpi>)
758 * (y <mpi>) 758 * (y <mpi>)
759 * (x <mpi>) 759 * (x <mpi>)
760 * ) 760 * )
761 * ) 761 * )
762 * The <mpi> are expected to be in GCRYMPI_FMT_USG 762 * The <mpi> are expected to be in GCRYMPI_FMT_USG
763 */ 763 */
764static gcry_err_code_t 764static gcry_err_code_t
765sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray, 765sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
766 gcry_module_t *retalgo) 766 gcry_module_t *retalgo)
767{ 767{
768 gcry_sexp_t list, l2; 768 gcry_sexp_t list, l2;
769 const char *name; 769 const char *name;
770 size_t n; 770 size_t n;
771 const char *elems; 771 const char *elems;
772 gcry_mpi_t *array; 772 gcry_mpi_t *array;
773 gcry_err_code_t err = GPG_ERR_NO_ERROR; 773 gcry_err_code_t err = GPG_ERR_NO_ERROR;
774 gcry_module_t module; 774 gcry_module_t module;
775 gcry_pk_spec_t *pubkey; 775 gcry_pk_spec_t *pubkey;
776 776
777 /* check that the first element is valid */ 777 /* check that the first element is valid */
778 list = gcry_sexp_find_token( sexp, want_private? "private-key" 778 list = gcry_sexp_find_token( sexp, want_private? "private-key"
779 :"public-key", 0 ); 779 :"public-key", 0 );
780 if( !list ) 780 if( !list )
781 return GPG_ERR_INV_OBJ; /* Does not contain a public- 781 return GPG_ERR_INV_OBJ; /* Does not contain a public-
782 or private-key object */ 782 or private-key object */
783 l2 = gcry_sexp_cadr( list ); 783 l2 = gcry_sexp_cadr( list );
784 gcry_sexp_release ( list ); 784 gcry_sexp_release ( list );
785 list = l2; 785 list = l2;
786 name = gcry_sexp_nth_data( list, 0, &n ); 786 name = gcry_sexp_nth_data( list, 0, &n );
787 if( !name ) { 787 if( !name ) {
788 gcry_sexp_release ( list ); 788 gcry_sexp_release ( list );
789 return GPG_ERR_INV_OBJ; /* invalid structure of object */ 789 return GPG_ERR_INV_OBJ; /* invalid structure of object */
790 } 790 }
791 791
792 { 792 {
793 char *name_terminated = gcry_xmalloc (n + 1); 793 char *name_terminated = gcry_xmalloc (n + 1);
794 memcpy (name_terminated, name, n); 794 memcpy (name_terminated, name, n);
795 name_terminated[n] = 0; 795 name_terminated[n] = 0;
796 796
797 ath_mutex_lock (&pubkeys_registered_lock); 797 ath_mutex_lock (&pubkeys_registered_lock);
798 module = gcry_pk_lookup_name (name_terminated); 798 module = gcry_pk_lookup_name (name_terminated);
799 ath_mutex_unlock (&pubkeys_registered_lock); 799 ath_mutex_unlock (&pubkeys_registered_lock);
800 800
801 gcry_free (name_terminated); 801 gcry_free (name_terminated);
802 } 802 }
803 803
804 if (! module) 804 if (! module)
805 { 805 {
806 gcry_sexp_release (list); 806 gcry_sexp_release (list);
807 return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */ 807 return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
808 } 808 }
809 else 809 else
810 pubkey = (gcry_pk_spec_t *) module->spec; 810 pubkey = (gcry_pk_spec_t *) module->spec;
811 811
812 elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey; 812 elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey;
813 array = gcry_calloc (strlen (elems) + 1, sizeof (*array)); 813 array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
814 if (! array) 814 if (! array)
815 err = gpg_err_code_from_errno (errno); 815 err = gpg_err_code_from_errno (errno);
816 if (! err) 816 if (! err)
817 err = sexp_elements_extract (list, elems, array); 817 err = sexp_elements_extract (list, elems, array);
818 818
819 if (list) 819 if (list)
820 gcry_sexp_release (list); 820 gcry_sexp_release (list);
821 821
822 if (err) 822 if (err)
823 { 823 {
824 if (array) 824 if (array)
825 gcry_free (array); 825 gcry_free (array);
826 826
827 ath_mutex_lock (&pubkeys_registered_lock); 827 ath_mutex_lock (&pubkeys_registered_lock);
828 _gcry_module_release (module); 828 _gcry_module_release (module);
829 ath_mutex_unlock (&pubkeys_registered_lock); 829 ath_mutex_unlock (&pubkeys_registered_lock);
830 } 830 }
831 else 831 else
832 { 832 {
833 *retarray = array; 833 *retarray = array;
834 *retalgo = module; 834 *retalgo = module;
835 } 835 }
836 836
837 return err; 837 return err;
838} 838}
839 839
840static gcry_err_code_t 840static gcry_err_code_t
841sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray, 841sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
842 gcry_module_t *retalgo) 842 gcry_module_t *retalgo)
843{ 843{
844 gcry_sexp_t list, l2; 844 gcry_sexp_t list, l2;
845 const char *name; 845 const char *name;
846 size_t n; 846 size_t n;
847 const char *elems; 847 const char *elems;
848 gcry_mpi_t *array; 848 gcry_mpi_t *array;
849 gcry_err_code_t err = GPG_ERR_NO_ERROR; 849 gcry_err_code_t err = GPG_ERR_NO_ERROR;
850 gcry_module_t module; 850 gcry_module_t module;
851 gcry_pk_spec_t *pubkey; 851 gcry_pk_spec_t *pubkey;
852 852
853 /* check that the first element is valid */ 853 /* check that the first element is valid */
854 list = gcry_sexp_find_token( sexp, "sig-val" , 0 ); 854 list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
855 if( !list ) 855 if( !list )
856 return GPG_ERR_INV_OBJ; /* Does not contain a signature value object */ 856 return GPG_ERR_INV_OBJ; /* Does not contain a signature value object */
857 l2 = gcry_sexp_nth (list, 1); 857 l2 = gcry_sexp_nth (list, 1);
858 if(! l2) 858 if(! l2)
859 { 859 {
860 gcry_sexp_release (list); 860 gcry_sexp_release (list);
861 return GPG_ERR_NO_OBJ; /* no cadr for the sig object */ 861 return GPG_ERR_NO_OBJ; /* no cadr for the sig object */
862 } 862 }
863 name = gcry_sexp_nth_data( l2, 0, &n ); 863 name = gcry_sexp_nth_data( l2, 0, &n );
864 if( !name ) { 864 if( !name ) {
865 gcry_sexp_release ( list ); 865 gcry_sexp_release ( list );
866 gcry_sexp_release ( l2 ); 866 gcry_sexp_release ( l2 );
867 return GPG_ERR_INV_OBJ; /* invalid structure of object */ 867 return GPG_ERR_INV_OBJ; /* invalid structure of object */
868 } 868 }
869 else if (n == 5 && (! memcmp (name, "flags", 5))) { 869 else if (n == 5 && (! memcmp (name, "flags", 5))) {
870 /* Skip flags, since they are not used but just here for the 870 /* Skip flags, since they are not used but just here for the
871 sake of consistent S-expressions. */ 871 sake of consistent S-expressions. */
872 gcry_sexp_release (l2); 872 gcry_sexp_release (l2);
873 l2 = gcry_sexp_nth (list, 2); 873 l2 = gcry_sexp_nth (list, 2);
874 if (! l2) 874 if (! l2)
875 { 875 {
876 gcry_sexp_release (list); 876 gcry_sexp_release (list);
877 return GPG_ERR_INV_OBJ; 877 return GPG_ERR_INV_OBJ;
878 } 878 }
879 name = gcry_sexp_nth_data (l2, 0, &n); 879 name = gcry_sexp_nth_data (l2, 0, &n);
880 } 880 }
881 881
882 { 882 {
883 char *name_terminated = gcry_xmalloc (n + 1); 883 char *name_terminated = gcry_xmalloc (n + 1);
884 memcpy (name_terminated, name, n); 884 memcpy (name_terminated, name, n);
885 name_terminated[n] = 0; 885 name_terminated[n] = 0;
886 886
887 ath_mutex_lock (&pubkeys_registered_lock); 887 ath_mutex_lock (&pubkeys_registered_lock);
888 module = gcry_pk_lookup_name (name_terminated); 888 module = gcry_pk_lookup_name (name_terminated);
889 ath_mutex_unlock (&pubkeys_registered_lock); 889 ath_mutex_unlock (&pubkeys_registered_lock);
890 890
891 gcry_free (name_terminated); 891 gcry_free (name_terminated);
892 } 892 }
893 893
894 if (! module) 894 if (! module)
895 { 895 {
896 gcry_sexp_release (l2); 896 gcry_sexp_release (l2);
897 gcry_sexp_release (list); 897 gcry_sexp_release (list);
898 return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */ 898 return GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
899 } 899 }
900 else 900 else
901 pubkey = (gcry_pk_spec_t *) module->spec; 901 pubkey = (gcry_pk_spec_t *) module->spec;
902 902
903 elems = pubkey->elements_sig; 903 elems = pubkey->elements_sig;
904 array = gcry_calloc (strlen (elems) + 1 , sizeof (*array)); 904 array = gcry_calloc (strlen (elems) + 1 , sizeof (*array));
905 if (! array) 905 if (! array)
906 err = gpg_err_code_from_errno (errno); 906 err = gpg_err_code_from_errno (errno);
907 907
908 if (! err) 908 if (! err)
909 err = sexp_elements_extract (list, elems, array); 909 err = sexp_elements_extract (list, elems, array);
910 910
911 gcry_sexp_release (l2); 911 gcry_sexp_release (l2);
912 gcry_sexp_release (list); 912 gcry_sexp_release (list);
913 913
914 if (err) 914 if (err)
915 { 915 {
916 ath_mutex_lock (&pubkeys_registered_lock); 916 ath_mutex_lock (&pubkeys_registered_lock);
917 _gcry_module_release (module); 917 _gcry_module_release (module);
918 ath_mutex_unlock (&pubkeys_registered_lock); 918 ath_mutex_unlock (&pubkeys_registered_lock);
919 919
920 if (array) 920 if (array)
921 gcry_free (array); 921 gcry_free (array);
922 } 922 }
923 else 923 else
924 { 924 {
925 *retarray = array; 925 *retarray = array;
926 *retalgo = module; 926 *retalgo = module;
927 } 927 }
928 928
929 return err; 929 return err;
930} 930}
931 931
932 932
933/**************** 933/****************
934 * Take sexp and return an array of MPI as used for our internal decrypt 934 * Take sexp and return an array of MPI as used for our internal decrypt
935 * function. 935 * function.
936 * s_data = (enc-val 936 * s_data = (enc-val
937 * [(flags [pkcs1]) 937 * [(flags [pkcs1])
938 * (<algo> 938 * (<algo>
939 * (<param_name1> <mpi>) 939 * (<param_name1> <mpi>)
940 * ... 940 * ...
941 * (<param_namen> <mpi>) 941 * (<param_namen> <mpi>)
942 * )) 942 * ))
943 * RET_MODERN is set to true when at least an empty flags list has been found. 943 * RET_MODERN is set to true when at least an empty flags list has been found.
944 */ 944 */
945static gcry_err_code_t 945static gcry_err_code_t
946sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo, 946sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
947 int *ret_modern, int *ret_want_pkcs1, int *flags) 947 int *ret_modern, int *ret_want_pkcs1, int *flags)
948{ 948{
949 gcry_sexp_t list = NULL, l2 = NULL; 949 gcry_sexp_t list = NULL, l2 = NULL;
950 gcry_pk_spec_t *pubkey = NULL; 950 gcry_pk_spec_t *pubkey = NULL;
951 gcry_module_t module = NULL; 951 gcry_module_t module = NULL;
952 const char *name; 952 const char *name;
953 size_t n; 953 size_t n;
954 int parsed_flags = 0; 954 int parsed_flags = 0;
955 const char *elems; 955 const char *elems;
956 gcry_mpi_t *array = NULL; 956 gcry_mpi_t *array = NULL;
957 gcry_err_code_t err = GPG_ERR_NO_ERROR; 957 gcry_err_code_t err = GPG_ERR_NO_ERROR;
958 958
959 *ret_want_pkcs1 = 0; 959 *ret_want_pkcs1 = 0;
960 *ret_modern = 0; 960 *ret_modern = 0;
961 961
962 /* check that the first element is valid */ 962 /* check that the first element is valid */
963 list = gcry_sexp_find_token (sexp, "enc-val" , 0); 963 list = gcry_sexp_find_token (sexp, "enc-val" , 0);
964 if (! list) 964 if (! list)
965 { 965 {
966 err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object */ 966 err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object */
967 goto leave; 967 goto leave;
968 } 968 }
969 969
970 l2 = gcry_sexp_nth (list, 1); 970 l2 = gcry_sexp_nth (list, 1);
971 if (! l2) 971 if (! l2)
972 { 972 {
973 err = GPG_ERR_NO_OBJ; /* no cdr for the data object */ 973 err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
974 goto leave; 974 goto leave;
975 } 975 }
976 976
977 /* Extract identifier of sublist. */ 977 /* Extract identifier of sublist. */
978 name = gcry_sexp_nth_data (l2, 0, &n); 978 name = gcry_sexp_nth_data (l2, 0, &n);
979 if (! name) 979 if (! name)
980 { 980 {
981 err = GPG_ERR_INV_OBJ; /* invalid structure of object */ 981 err = GPG_ERR_INV_OBJ; /* invalid structure of object */
982 goto leave; 982 goto leave;
983 } 983 }
984 984
985 if ((n == 5) && (! memcmp (name, "flags", 5))) 985 if ((n == 5) && (! memcmp (name, "flags", 5)))
986 { 986 {
987 /* There is a flags element - process it */ 987 /* There is a flags element - process it */
988 const char *s; 988 const char *s;
989 int i; 989 int i;
990 990
991 *ret_modern = 1; 991 *ret_modern = 1;
992 for (i = gcry_sexp_length (l2) - 1; i > 0; i--) 992 for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
993 { 993 {
994 s = gcry_sexp_nth_data (l2, i, &n); 994 s = gcry_sexp_nth_data (l2, i, &n);
995 if (! s) 995 if (! s)
996 ; /* not a data element - ignore */ 996 ; /* not a data element - ignore */
997 else if (n == 3 && ! memcmp (s, "raw", 3)) 997 else if (n == 3 && ! memcmp (s, "raw", 3))
998 ; /* just a dummy because it is the default */ 998 ; /* just a dummy because it is the default */
999 else if (n == 5 && ! memcmp (s, "pkcs1", 5)) 999 else if (n == 5 && ! memcmp (s, "pkcs1", 5))
1000 *ret_want_pkcs1 = 1; 1000 *ret_want_pkcs1 = 1;
1001 else if (n == 11 && ! memcmp (s, "no-blinding", 11)) 1001 else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1002 parsed_flags |= PUBKEY_FLAG_NO_BLINDING; 1002 parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1003 else 1003 else
1004 { 1004 {
1005 err = GPG_ERR_INV_FLAG; 1005 err = GPG_ERR_INV_FLAG;
1006 goto leave; 1006 goto leave;
1007 } 1007 }
1008 } 1008 }
1009 1009
1010 /* Get the next which has the actual data */ 1010 /* Get the next which has the actual data */
1011 gcry_sexp_release (l2); 1011 gcry_sexp_release (l2);
1012 l2 = gcry_sexp_nth (list, 2); 1012 l2 = gcry_sexp_nth (list, 2);
1013 if (! l2) 1013 if (! l2)
1014 { 1014 {
1015 err = GPG_ERR_NO_OBJ; /* no cdr for the data object */ 1015 err = GPG_ERR_NO_OBJ; /* no cdr for the data object */
1016 goto leave; 1016 goto leave;
1017 } 1017 }
1018 1018
1019 /* Extract sublist identifier. */ 1019 /* Extract sublist identifier. */
1020 name = gcry_sexp_nth_data (l2, 0, &n); 1020 name = gcry_sexp_nth_data (l2, 0, &n);
1021 if (! name) 1021 if (! name)
1022 { 1022 {
1023 err = GPG_ERR_INV_OBJ; /* invalid structure of object */ 1023 err = GPG_ERR_INV_OBJ; /* invalid structure of object */
1024 goto leave; 1024 goto leave;
1025 } 1025 }
1026 1026
1027 gcry_sexp_release (list); 1027 gcry_sexp_release (list);
1028 list = l2; 1028 list = l2;
1029 l2 = NULL; 1029 l2 = NULL;
1030 } 1030 }
1031 1031
1032 { 1032 {
1033 char *name_terminated = gcry_xmalloc (n + 1); 1033 char *name_terminated = gcry_xmalloc (n + 1);
1034 memcpy (name_terminated, name, n); 1034 memcpy (name_terminated, name, n);
1035 name_terminated[n] = 0; 1035 name_terminated[n] = 0;
1036 1036
1037 ath_mutex_lock (&pubkeys_registered_lock); 1037 ath_mutex_lock (&pubkeys_registered_lock);
1038 module = gcry_pk_lookup_name (name_terminated); 1038 module = gcry_pk_lookup_name (name_terminated);
1039 ath_mutex_unlock (&pubkeys_registered_lock); 1039 ath_mutex_unlock (&pubkeys_registered_lock);
1040 1040
1041 gcry_free (name_terminated); 1041 gcry_free (name_terminated);
1042 1042
1043 if (! module) 1043 if (! module)
1044 { 1044 {
1045 err = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */ 1045 err = GPG_ERR_PUBKEY_ALGO; /* unknown algorithm */
1046 goto leave; 1046 goto leave;
1047 } 1047 }
1048 pubkey = (gcry_pk_spec_t *) module->spec; 1048 pubkey = (gcry_pk_spec_t *) module->spec;
1049 } 1049 }
1050 1050
1051 elems = pubkey->elements_enc; 1051 elems = pubkey->elements_enc;
1052 array = gcry_calloc (strlen (elems) + 1, sizeof (*array)); 1052 array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1053 if (! array) 1053 if (! array)
1054 { 1054 {
1055 err = gpg_err_code_from_errno (errno); 1055 err = gpg_err_code_from_errno (errno);
1056 goto leave; 1056 goto leave;
1057 } 1057 }
1058 1058
1059 err = sexp_elements_extract (list, elems, array); 1059 err = sexp_elements_extract (list, elems, array);
1060 1060
1061 leave: 1061 leave:
1062 if (list) 1062 if (list)
1063 gcry_sexp_release (list); 1063 gcry_sexp_release (list);
1064 if (l2) 1064 if (l2)
1065 gcry_sexp_release (l2); 1065 gcry_sexp_release (l2);
1066 1066
1067 if (err) 1067 if (err)
1068 { 1068 {
1069 ath_mutex_lock (&pubkeys_registered_lock); 1069 ath_mutex_lock (&pubkeys_registered_lock);
1070 _gcry_module_release (module); 1070 _gcry_module_release (module);
1071 ath_mutex_unlock (&pubkeys_registered_lock); 1071 ath_mutex_unlock (&pubkeys_registered_lock);
1072 if (array) 1072 if (array)
1073 gcry_free (array); 1073 gcry_free (array);
1074 } 1074 }
1075 else 1075 else
1076 { 1076 {
1077 *retarray = array; 1077 *retarray = array;
1078 *retalgo = module; 1078 *retalgo = module;
1079 *flags = parsed_flags; 1079 *flags = parsed_flags;
1080 } 1080 }
1081 1081
1082 return err; 1082 return err;
1083} 1083}
1084 1084
1085/* Take the hash value and convert into an MPI, suitable for for 1085/* Take the hash value and convert into an MPI, suitable for for
1086 passing to the low level functions. We currently support the 1086 passing to the low level functions. We currently support the
1087 old style way of passing just a MPI and the modern interface which 1087 old style way of passing just a MPI and the modern interface which
1088 allows to pass flags so that we can choose between raw and pkcs1 1088 allows to pass flags so that we can choose between raw and pkcs1
1089 padding - may be more padding options later. 1089 padding - may be more padding options later.
1090 1090
1091 (<mpi>) 1091 (<mpi>)
1092 or 1092 or
1093 (data 1093 (data
1094 [(flags [pkcs1])] 1094 [(flags [pkcs1])]
1095 [(hash <algo> <value>)] 1095 [(hash <algo> <value>)]
1096 [(value <text>)] 1096 [(value <text>)]
1097 ) 1097 )
1098 1098
1099 Either the VALUE or the HASH element must be present for use 1099 Either the VALUE or the HASH element must be present for use
1100 with signatures. VALUE is used for encryption. 1100 with signatures. VALUE is used for encryption.
1101 1101
1102 NBITS is the length of the key in bits. 1102 NBITS is the length of the key in bits.
1103 1103
1104*/ 1104*/
1105static gcry_err_code_t 1105static gcry_err_code_t
1106sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi, 1106sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
1107 int for_encryption, int *flags) 1107 int for_encryption, int *flags)
1108{ 1108{
1109 gcry_err_code_t rc = 0; 1109 gcry_err_code_t rc = 0;
1110 gcry_sexp_t ldata, lhash, lvalue; 1110 gcry_sexp_t ldata, lhash, lvalue;
1111 int i; 1111 int i;
1112 size_t n; 1112 size_t n;
1113 const char *s; 1113 const char *s;
1114 int is_raw = 0, is_pkcs1 = 0, unknown_flag=0; 1114 int is_raw = 0, is_pkcs1 = 0, unknown_flag=0;
1115 int parsed_flags = 0, dummy_flags; 1115 int parsed_flags = 0, dummy_flags;
1116 1116
1117 if (! flags) 1117 if (! flags)
1118 flags = &dummy_flags; 1118 flags = &dummy_flags;
1119 1119
1120 *ret_mpi = NULL; 1120 *ret_mpi = NULL;
1121 ldata = gcry_sexp_find_token (input, "data", 0); 1121 ldata = gcry_sexp_find_token (input, "data", 0);
1122 if (!ldata) 1122 if (!ldata)
1123 { /* assume old style */ 1123 { /* assume old style */
1124 *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0); 1124 *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
1125 return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ; 1125 return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
1126 } 1126 }
1127 1127
1128 /* see whether there is a flags object */ 1128 /* see whether there is a flags object */
1129 { 1129 {
1130 gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0); 1130 gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
1131 if (lflags) 1131 if (lflags)
1132 { /* parse the flags list. */ 1132 { /* parse the flags list. */
1133 for (i=gcry_sexp_length (lflags)-1; i > 0; i--) 1133 for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
1134 { 1134 {
1135 s = gcry_sexp_nth_data (lflags, i, &n); 1135 s = gcry_sexp_nth_data (lflags, i, &n);
1136 if (!s) 1136 if (!s)
1137 ; /* not a data element*/ 1137 ; /* not a data element*/
1138 else if ( n == 3 && !memcmp (s, "raw", 3)) 1138 else if ( n == 3 && !memcmp (s, "raw", 3))
1139 is_raw = 1; 1139 is_raw = 1;
1140 else if ( n == 5 && !memcmp (s, "pkcs1", 5)) 1140 else if ( n == 5 && !memcmp (s, "pkcs1", 5))
1141 is_pkcs1 = 1; 1141 is_pkcs1 = 1;
1142 else if (n == 11 && ! memcmp (s, "no-blinding", 11)) 1142 else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1143 parsed_flags |= PUBKEY_FLAG_NO_BLINDING; 1143 parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1144 else 1144 else
1145 unknown_flag = 1; 1145 unknown_flag = 1;
1146 } 1146 }
1147 gcry_sexp_release (lflags); 1147 gcry_sexp_release (lflags);
1148 } 1148 }
1149 } 1149 }
1150 1150
1151 if (!is_pkcs1 && !is_raw) 1151 if (!is_pkcs1 && !is_raw)
1152 is_raw = 1; /* default to raw */ 1152 is_raw = 1; /* default to raw */
1153 1153
1154 /* Get HASH or MPI */ 1154 /* Get HASH or MPI */
1155 lhash = gcry_sexp_find_token (ldata, "hash", 0); 1155 lhash = gcry_sexp_find_token (ldata, "hash", 0);
1156 lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0); 1156 lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1157 1157
1158 if (!(!lhash ^ !lvalue)) 1158 if (!(!lhash ^ !lvalue))
1159 rc = GPG_ERR_INV_OBJ; /* none or both given */ 1159 rc = GPG_ERR_INV_OBJ; /* none or both given */
1160 else if (unknown_flag) 1160 else if (unknown_flag)
1161 rc = GPG_ERR_INV_FLAG; 1161 rc = GPG_ERR_INV_FLAG;
1162 else if (is_raw && is_pkcs1 && !for_encryption) 1162 else if (is_raw && is_pkcs1 && !for_encryption)
1163 rc = GPG_ERR_CONFLICT; 1163 rc = GPG_ERR_CONFLICT;
1164 else if (is_raw && lvalue) 1164 else if (is_raw && lvalue)
1165 { 1165 {
1166 *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0); 1166 *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
1167 if (!*ret_mpi) 1167 if (!*ret_mpi)
1168 rc = GPG_ERR_INV_OBJ; 1168 rc = GPG_ERR_INV_OBJ;
1169 } 1169 }
1170 else if (is_pkcs1 && lvalue && for_encryption) 1170 else if (is_pkcs1 && lvalue && for_encryption)
1171 { /* Create pkcs#1 block type 2 padding. */ 1171 { /* Create pkcs#1 block type 2 padding. */
1172 unsigned char *frame = NULL; 1172 unsigned char *frame = NULL;
1173 size_t nframe = (nbits+7) / 8; 1173 size_t nframe = (nbits+7) / 8;
1174 const void * value; 1174 const void * value;
1175 size_t valuelen; 1175 size_t valuelen;
1176 unsigned char *p; 1176 unsigned char *p;
1177 1177
1178 if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen ) 1178 if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1179 rc = GPG_ERR_INV_OBJ; 1179 rc = GPG_ERR_INV_OBJ;
1180 else if (valuelen + 7 > nframe || !nframe) 1180 else if (valuelen + 7 > nframe || !nframe)
1181 { 1181 {
1182 /* Can't encode a VALUELEN value in a NFRAME bytes frame. */ 1182 /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1183 rc = GPG_ERR_TOO_SHORT; /* the key is too short */ 1183 rc = GPG_ERR_TOO_SHORT; /* the key is too short */
1184 } 1184 }
1185 else if ( !(frame = gcry_malloc_secure (nframe))) 1185 else if ( !(frame = gcry_malloc_secure (nframe)))
1186 rc = gpg_err_code_from_errno (errno); 1186 rc = gpg_err_code_from_errno (errno);
1187 else 1187 else
1188 { 1188 {
1189 n = 0; 1189 n = 0;
1190 frame[n++] = 0; 1190 frame[n++] = 0;
1191 frame[n++] = 2; /* block type */ 1191 frame[n++] = 2; /* block type */
1192 i = nframe - 3 - valuelen; 1192 i = nframe - 3 - valuelen;
1193 assert (i > 0); 1193 assert (i > 0);
1194 p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM); 1194 p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
1195 /* Replace zero bytes by new values. */ 1195 /* Replace zero bytes by new values. */
1196 for (;;) 1196 for (;;)
1197 { 1197 {
1198 int j, k; 1198 int j, k;
1199 unsigned char *pp; 1199 unsigned char *pp;
1200 1200
1201 /* Count the zero bytes. */ 1201 /* Count the zero bytes. */
1202 for (j=k=0; j < i; j++) 1202 for (j=k=0; j < i; j++)
1203 { 1203 {
1204 if (!p[j]) 1204 if (!p[j])
1205 k++; 1205 k++;
1206 } 1206 }
1207 if (!k) 1207 if (!k)
1208 break; /* Okay: no (more) zero bytes. */ 1208 break; /* Okay: no (more) zero bytes. */
1209 1209
1210 k += k/128 + 3; /* Better get some more. */ 1210 k += k/128 + 3; /* Better get some more. */
1211 pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM); 1211 pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
1212 for (j=0; j < i && k;) 1212 for (j=0; j < i && k;)
1213 { 1213 {
1214 if (!p[j]) 1214 if (!p[j])
1215 p[j] = pp[--k]; 1215 p[j] = pp[--k];
1216 if (p[j]) 1216 if (p[j])
1217 j++; 1217 j++;
1218 } 1218 }
1219 gcry_free (pp); 1219 gcry_free (pp);
1220 } 1220 }
1221 memcpy (frame+n, p, i); 1221 memcpy (frame+n, p, i);
1222 n += i; 1222 n += i;
1223 gcry_free (p); 1223 gcry_free (p);
1224 1224
1225 frame[n++] = 0; 1225 frame[n++] = 0;
1226 memcpy (frame+n, value, valuelen); 1226 memcpy (frame+n, value, valuelen);
1227 n += valuelen; 1227 n += valuelen;
1228 assert (n == nframe); 1228 assert (n == nframe);
1229 1229
1230 /* FIXME, error checking? */ 1230 /* FIXME, error checking? */
1231 gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe); 1231 gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1232 } 1232 }
1233 1233
1234 gcry_free(frame); 1234 gcry_free(frame);
1235 } 1235 }
1236 else if (is_pkcs1 && lhash && !for_encryption) 1236 else if (is_pkcs1 && lhash && !for_encryption)
1237 { /* Create pkcs#1 block type 1 padding. */ 1237 { /* Create pkcs#1 block type 1 padding. */
1238 if (gcry_sexp_length (lhash) != 3) 1238 if (gcry_sexp_length (lhash) != 3)
1239 rc = GPG_ERR_INV_OBJ; 1239 rc = GPG_ERR_INV_OBJ;
1240 else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n ) 1240 else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1241 rc = GPG_ERR_INV_OBJ; 1241 rc = GPG_ERR_INV_OBJ;
1242 else 1242 else
1243 { 1243 {
1244 static struct { const char *name; int algo; } hashnames[] = 1244 static struct { const char *name; int algo; } hashnames[] =
1245 { { "sha1", GCRY_MD_SHA1 }, 1245 { { "sha1", GCRY_MD_SHA1 },
1246 { "md5", GCRY_MD_MD5 }, 1246 { "md5", GCRY_MD_MD5 },
1247 { "rmd160", GCRY_MD_RMD160 }, 1247 { "rmd160", GCRY_MD_RMD160 },
1248 { "sha256", GCRY_MD_SHA256 }, 1248 { "sha256", GCRY_MD_SHA256 },
1249 { "sha384", GCRY_MD_SHA384 }, 1249 { "sha384", GCRY_MD_SHA384 },
1250 { "sha512", GCRY_MD_SHA512 }, 1250 { "sha512", GCRY_MD_SHA512 },
1251 { "md2", GCRY_MD_MD2 }, 1251 { "md2", GCRY_MD_MD2 },
1252 { "md4", GCRY_MD_MD4 }, 1252 { "md4", GCRY_MD_MD4 },
1253 { "tiger", GCRY_MD_TIGER }, 1253 { "tiger", GCRY_MD_TIGER },
1254 { "haval", GCRY_MD_HAVAL }, 1254 { "haval", GCRY_MD_HAVAL },
1255 { NULL } 1255 { NULL }
1256 }; 1256 };
1257 int algo; 1257 int algo;
1258 byte asn[100]; 1258 byte asn[100];
1259 byte *frame = NULL; 1259 byte *frame = NULL;
1260 size_t nframe = (nbits+7) / 8; 1260 size_t nframe = (nbits+7) / 8;
1261 const void * value; 1261 const void * value;
1262 size_t valuelen; 1262 size_t valuelen;
1263 size_t asnlen, dlen; 1263 size_t asnlen, dlen;
1264 1264
1265 for (i=0; hashnames[i].name; i++) 1265 for (i=0; hashnames[i].name; i++)
1266 { 1266 {
1267 if ( strlen (hashnames[i].name) == n 1267 if ( strlen (hashnames[i].name) == n
1268 && !memcmp (hashnames[i].name, s, n)) 1268 && !memcmp (hashnames[i].name, s, n))
1269 break; 1269 break;
1270 } 1270 }
1271 1271
1272 algo = hashnames[i].algo; 1272 algo = hashnames[i].algo;
1273 asnlen = DIM(asn); 1273 asnlen = DIM(asn);
1274 dlen = gcry_md_get_algo_dlen (algo); 1274 dlen = gcry_md_get_algo_dlen (algo);
1275 1275
1276 if (!hashnames[i].name) 1276 if (!hashnames[i].name)
1277 rc = GPG_ERR_DIGEST_ALGO; 1277 rc = GPG_ERR_DIGEST_ALGO;
1278 else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen)) 1278 else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1279 || !valuelen ) 1279 || !valuelen )
1280 rc = GPG_ERR_INV_OBJ; 1280 rc = GPG_ERR_INV_OBJ;
1281 else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen)) 1281 else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
1282 { 1282 {
1283 /* We don't have yet all of the above algorithms. */ 1283 /* We don't have yet all of the above algorithms. */
1284 rc = GPG_ERR_NOT_IMPLEMENTED; 1284 rc = GPG_ERR_NOT_IMPLEMENTED;
1285 } 1285 }
1286 else if ( valuelen != dlen ) 1286 else if ( valuelen != dlen )
1287 { 1287 {
1288 /* Hash value does not match the length of digest for 1288 /* Hash value does not match the length of digest for
1289 the given algorithm. */ 1289 the given algorithm. */
1290 rc = GPG_ERR_CONFLICT; 1290 rc = GPG_ERR_CONFLICT;
1291 } 1291 }
1292 else if( !dlen || dlen + asnlen + 4 > nframe) 1292 else if( !dlen || dlen + asnlen + 4 > nframe)
1293 { 1293 {
1294 /* Can't encode an DLEN byte digest MD into a NFRAME 1294 /* Can't encode an DLEN byte digest MD into a NFRAME
1295 byte frame. */ 1295 byte frame. */
1296 rc = GPG_ERR_TOO_SHORT; 1296 rc = GPG_ERR_TOO_SHORT;
1297 } 1297 }
1298 else if ( !(frame = gcry_malloc (nframe)) ) 1298 else if ( !(frame = gcry_malloc (nframe)) )
1299 rc = gpg_err_code_from_errno (errno); 1299 rc = gpg_err_code_from_errno (errno);
1300 else 1300 else
1301 { /* Assemble the pkcs#1 block type 1. */ 1301 { /* Assemble the pkcs#1 block type 1. */
1302 n = 0; 1302 n = 0;
1303 frame[n++] = 0; 1303 frame[n++] = 0;
1304 frame[n++] = 1; /* block type */ 1304 frame[n++] = 1; /* block type */
1305 i = nframe - valuelen - asnlen - 3 ; 1305 i = nframe - valuelen - asnlen - 3 ;
1306 assert (i > 1); 1306 assert (i > 1);
1307 memset (frame+n, 0xff, i ); 1307 memset (frame+n, 0xff, i );
1308 n += i; 1308 n += i;
1309 frame[n++] = 0; 1309 frame[n++] = 0;
1310 memcpy (frame+n, asn, asnlen); 1310 memcpy (frame+n, asn, asnlen);
1311 n += asnlen; 1311 n += asnlen;
1312 memcpy (frame+n, value, valuelen ); 1312 memcpy (frame+n, value, valuelen );
1313 n += valuelen; 1313 n += valuelen;
1314 assert (n == nframe); 1314 assert (n == nframe);
1315 1315
1316 /* convert it into an MPI, FIXME: error checking? */ 1316 /* convert it into an MPI, FIXME: error checking? */
1317 gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe); 1317 gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
1318 } 1318 }
1319 1319
1320 gcry_free (frame); 1320 gcry_free (frame);
1321 } 1321 }
1322 } 1322 }
1323 else 1323 else
1324 rc = GPG_ERR_CONFLICT; 1324 rc = GPG_ERR_CONFLICT;
1325 1325
1326 gcry_sexp_release (ldata); 1326 gcry_sexp_release (ldata);
1327 gcry_sexp_release (lhash); 1327 gcry_sexp_release (lhash);
1328 gcry_sexp_release (lvalue); 1328 gcry_sexp_release (lvalue);
1329 1329
1330 if (!rc) 1330 if (!rc)
1331 *flags = parsed_flags; 1331 *flags = parsed_flags;
1332 1332
1333 return rc; 1333 return rc;
1334} 1334}
1335 1335
1336 1336
1337/* 1337/*
1338 Do a PK encrypt operation 1338 Do a PK encrypt operation
1339 1339
1340 Caller has to provide a public key as the SEXP pkey and data as a 1340 Caller has to provide a public key as the SEXP pkey and data as a
1341 SEXP with just one MPI in it. Alternativly S_DATA might be a 1341 SEXP with just one MPI in it. Alternativly S_DATA might be a
1342 complex S-Expression, similar to the one used for signature 1342 complex S-Expression, similar to the one used for signature
1343 verification. This provides a flag which allows to handle PKCS#1 1343 verification. This provides a flag which allows to handle PKCS#1
1344 block type 2 padding. The function returns a a sexp which may be 1344 block type 2 padding. The function returns a a sexp which may be
1345 passed to to pk_decrypt. 1345 passed to to pk_decrypt.
1346 1346
1347 Returns: 0 or an errorcode. 1347 Returns: 0 or an errorcode.
1348 1348
1349 s_data = See comment for sexp_data_to_mpi 1349 s_data = See comment for sexp_data_to_mpi
1350 s_pkey = <key-as-defined-in-sexp_to_key> 1350 s_pkey = <key-as-defined-in-sexp_to_key>
1351 r_ciph = (enc-val 1351 r_ciph = (enc-val
1352 (<algo> 1352 (<algo>
1353 (<param_name1> <mpi>) 1353 (<param_name1> <mpi>)
1354 ... 1354 ...
1355 (<param_namen> <mpi>) 1355 (<param_namen> <mpi>)
1356 )) 1356 ))
1357 1357
1358*/ 1358*/
1359gcry_error_t 1359gcry_error_t
1360gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey) 1360gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
1361{ 1361{
1362 gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL; 1362 gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
1363 const char *algo_name, *algo_elems; 1363 const char *algo_name, *algo_elems;
1364 int flags; 1364 int flags;
1365 gcry_err_code_t rc; 1365 gcry_err_code_t rc;
1366 gcry_pk_spec_t *pubkey = NULL; 1366 gcry_pk_spec_t *pubkey = NULL;
1367 gcry_module_t module = NULL; 1367 gcry_module_t module = NULL;
1368 1368
1369 REGISTER_DEFAULT_PUBKEYS; 1369 REGISTER_DEFAULT_PUBKEYS;
1370 1370
1371 *r_ciph = NULL; 1371 *r_ciph = NULL;
1372 /* get the key */ 1372 /* get the key */
1373 rc = sexp_to_key (s_pkey, 0, &pkey, &module); 1373 rc = sexp_to_key (s_pkey, 0, &pkey, &module);
1374 if (rc) 1374 if (rc)
1375 goto leave; 1375 goto leave;
1376 1376
1377 assert (module); 1377 assert (module);
1378 pubkey = (gcry_pk_spec_t *) module->spec; 1378 pubkey = (gcry_pk_spec_t *) module->spec;
1379 1379
1380 /* If aliases for the algorithm name exists, take the first one 1380 /* If aliases for the algorithm name exists, take the first one
1381 instead of the regular name to adhere to SPKI conventions. We 1381 instead of the regular name to adhere to SPKI conventions. We
1382 assume that the first alias name is the lowercase version of the 1382 assume that the first alias name is the lowercase version of the
1383 regular one. This change is required for compatibility with 1383 regular one. This change is required for compatibility with
1384 1.1.12 generated S-expressions. */ 1384 1.1.12 generated S-expressions. */
1385 algo_name = pubkey->aliases? *pubkey->aliases : NULL; 1385 algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1386 if (!algo_name || !*algo_name) 1386 if (!algo_name || !*algo_name)
1387 algo_name = pubkey->name; 1387 algo_name = pubkey->name;
1388 1388
1389 algo_elems = pubkey->elements_enc; 1389 algo_elems = pubkey->elements_enc;
1390 1390
1391 /* Get the stuff we want to encrypt. */ 1391 /* Get the stuff we want to encrypt. */
1392 rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1, 1392 rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
1393 &flags); 1393 &flags);
1394 if (rc) 1394 if (rc)
1395 goto leave; 1395 goto leave;
1396 1396
1397 /* Now we can encrypt DATA to CIPH. */ 1397 /* Now we can encrypt DATA to CIPH. */
1398 ciph = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*ciph)); 1398 ciph = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*ciph));
1399 rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags); 1399 rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
1400 mpi_free (data); 1400 mpi_free (data);
1401 data = NULL; 1401 data = NULL;
1402 if (rc) 1402 if (rc)
1403 goto leave; 1403 goto leave;
1404 1404
1405 /* We did it. Now build the return list */ 1405 /* We did it. Now build the return list */
1406 { 1406 {
1407 char *string, *p; 1407 char *string, *p;
1408 int i; 1408 int i;
1409 size_t nelem = strlen (algo_elems); 1409 size_t nelem = strlen (algo_elems);
1410 size_t needed = 19 + strlen (algo_name) + (nelem * 5); 1410 size_t needed = 19 + strlen (algo_name) + (nelem * 5);
1411 void **arg_list; 1411 void **arg_list;
1412 1412
1413 /* Build the string. */ 1413 /* Build the string. */
1414 string = p = gcry_xmalloc (needed); 1414 string = p = gcry_xmalloc (needed);
1415 p = stpcpy ( p, "(enc-val(" ); 1415 p = stpcpy ( p, "(enc-val(" );
1416 p = stpcpy ( p, algo_name ); 1416 p = stpcpy ( p, algo_name );
1417 for (i=0; algo_elems[i]; i++ ) 1417 for (i=0; algo_elems[i]; i++ )
1418 { 1418 {
1419 *p++ = '('; 1419 *p++ = '(';
1420 *p++ = algo_elems[i]; 1420 *p++ = algo_elems[i];
1421 p = stpcpy ( p, "%m)" ); 1421 p = stpcpy ( p, "%m)" );
1422 } 1422 }
1423 strcpy ( p, "))" ); 1423 strcpy ( p, "))" );
1424 1424
1425 /* And now the ugly part: We don't have a function to pass an 1425 /* And now the ugly part: We don't have a function to pass an
1426 * array to a format string, so we have to do it this way :-(. */ 1426 * array to a format string, so we have to do it this way :-(. */
1427 /* FIXME: There is now such a format spefier, so we can could 1427 /* FIXME: There is now such a format spefier, so we can could
1428 change the code to be more clear. */ 1428 change the code to be more clear. */
1429 arg_list = malloc (nelem * sizeof *arg_list); 1429 arg_list = malloc (nelem * sizeof *arg_list);
1430 if (!arg_list) 1430 if (!arg_list)
1431 { 1431 {
1432 rc = gpg_err_code_from_errno (errno); 1432 rc = gpg_err_code_from_errno (errno);
1433 goto leave; 1433 goto leave;
1434 } 1434 }
1435 1435
1436 for (i = 0; i < nelem; i++) 1436 for (i = 0; i < nelem; i++)
1437 arg_list[i] = ciph + i; 1437 arg_list[i] = ciph + i;
1438 1438
1439 rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list); 1439 rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
1440 free (arg_list); 1440 free (arg_list);
1441 if (rc) 1441 if (rc)
1442 BUG (); 1442 BUG ();
1443 gcry_free (string); 1443 gcry_free (string);
1444 } 1444 }
1445 1445
1446 leave: 1446 leave:
1447 if (pkey) 1447 if (pkey)
1448 { 1448 {
1449 release_mpi_array (pkey); 1449 release_mpi_array (pkey);
1450 gcry_free (pkey); 1450 gcry_free (pkey);
1451 } 1451 }
1452 1452
1453 if (ciph) 1453 if (ciph)
1454 { 1454 {
1455 release_mpi_array (ciph); 1455 release_mpi_array (ciph);
1456 gcry_free (ciph); 1456 gcry_free (ciph);
1457 } 1457 }
1458 1458
1459 if (module) 1459 if (module)
1460 { 1460 {
1461 ath_mutex_lock (&pubkeys_registered_lock); 1461 ath_mutex_lock (&pubkeys_registered_lock);
1462 _gcry_module_release (module); 1462 _gcry_module_release (module);
1463 ath_mutex_unlock (&pubkeys_registered_lock); 1463 ath_mutex_unlock (&pubkeys_registered_lock);
1464 } 1464 }
1465 1465
1466 return gcry_error (rc); 1466 return gcry_error (rc);
1467} 1467}
1468 1468
1469/* 1469/*
1470 Do a PK decrypt operation 1470 Do a PK decrypt operation
1471 1471
1472 Caller has to provide a secret key as the SEXP skey and data in a 1472 Caller has to provide a secret key as the SEXP skey and data in a
1473 format as created by gcry_pk_encrypt. For historic reasons the 1473 format as created by gcry_pk_encrypt. For historic reasons the
1474 function returns simply an MPI as an S-expression part; this is 1474 function returns simply an MPI as an S-expression part; this is
1475 deprecated and the new method should be used which returns a real 1475 deprecated and the new method should be used which returns a real
1476 S-expressionl this is selected by adding at least an empty flags 1476 S-expressionl this is selected by adding at least an empty flags
1477 list to S_DATA. 1477 list to S_DATA.
1478 1478
1479 Returns: 0 or an errorcode. 1479 Returns: 0 or an errorcode.
1480 1480
1481 s_data = (enc-val 1481 s_data = (enc-val
1482 [(flags)] 1482 [(flags)]
1483 (<algo> 1483 (<algo>
1484 (<param_name1> <mpi>) 1484 (<param_name1> <mpi>)
1485 ... 1485 ...
1486 (<param_namen> <mpi>) 1486 (<param_namen> <mpi>)
1487 )) 1487 ))
1488 s_skey = <key-as-defined-in-sexp_to_key> 1488 s_skey = <key-as-defined-in-sexp_to_key>
1489 r_plain= Either an incomplete S-expression without the parentheses 1489 r_plain= Either an incomplete S-expression without the parentheses
1490 or if the flags list is used (even if empty) a real S-expression: 1490 or if the flags list is used (even if empty) a real S-expression:
1491 (value PLAIN). 1491 (value PLAIN).
1492 */ 1492 */
1493gcry_error_t 1493gcry_error_t
1494gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey) 1494gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
1495{ 1495{
1496 gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL; 1496 gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
1497 int modern, want_pkcs1, flags; 1497 int modern, want_pkcs1, flags;
1498 gcry_err_code_t rc; 1498 gcry_err_code_t rc;
1499 gcry_module_t module_enc = NULL, module_key = NULL; 1499 gcry_module_t module_enc = NULL, module_key = NULL;
1500 gcry_pk_spec_t *pubkey = NULL; 1500 gcry_pk_spec_t *pubkey = NULL;
1501 1501
1502 REGISTER_DEFAULT_PUBKEYS; 1502 REGISTER_DEFAULT_PUBKEYS;
1503 1503
1504 *r_plain = NULL; 1504 *r_plain = NULL;
1505 rc = sexp_to_key (s_skey, 1, &skey, &module_key); 1505 rc = sexp_to_key (s_skey, 1, &skey, &module_key);
1506 if (rc) 1506 if (rc)
1507 goto leave; 1507 goto leave;
1508 1508
1509 rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags); 1509 rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
1510 if (rc) 1510 if (rc)
1511 goto leave; 1511 goto leave;
1512 1512
1513 if (module_key->mod_id != module_enc->mod_id) 1513 if (module_key->mod_id != module_enc->mod_id)
1514 { 1514 {
1515 rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */ 1515 rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
1516 goto leave; 1516 goto leave;
1517 } 1517 }
1518 1518
1519 pubkey = (gcry_pk_spec_t *) module_key->spec; 1519 pubkey = (gcry_pk_spec_t *) module_key->spec;
1520 1520
1521 rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags); 1521 rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
1522 if (rc) 1522 if (rc)
1523 goto leave; 1523 goto leave;
1524 1524
1525 if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain)) 1525 if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
1526 BUG (); 1526 BUG ();
1527 1527
1528 leave: 1528 leave:
1529 if (skey) 1529 if (skey)
1530 { 1530 {
1531 release_mpi_array (skey); 1531 release_mpi_array (skey);
1532 gcry_free (skey); 1532 gcry_free (skey);
1533 } 1533 }
1534 1534
1535 if (plain) 1535 if (plain)
1536 mpi_free (plain); 1536 mpi_free (plain);
1537 1537
1538 if (data) 1538 if (data)
1539 { 1539 {
1540 release_mpi_array (data); 1540 release_mpi_array (data);
1541 gcry_free (data); 1541 gcry_free (data);
1542 } 1542 }
1543 1543
1544 if (module_key || module_enc) 1544 if (module_key || module_enc)
1545 { 1545 {
1546 ath_mutex_lock (&pubkeys_registered_lock); 1546 ath_mutex_lock (&pubkeys_registered_lock);
1547 if (module_key) 1547 if (module_key)
1548 _gcry_module_release (module_key); 1548 _gcry_module_release (module_key);
1549 if (module_enc) 1549 if (module_enc)
1550 _gcry_module_release (module_enc); 1550 _gcry_module_release (module_enc);
1551 ath_mutex_unlock (&pubkeys_registered_lock); 1551 ath_mutex_unlock (&pubkeys_registered_lock);
1552 } 1552 }
1553 1553
1554 return gcry_error (rc); 1554 return gcry_error (rc);
1555} 1555}
1556 1556
1557 1557
1558 1558
1559/* 1559/*
1560 Create a signature. 1560 Create a signature.
1561 1561
1562 Caller has to provide a secret key as the SEXP skey and data 1562 Caller has to provide a secret key as the SEXP skey and data
1563 expressed as a SEXP list hash with only one element which should 1563 expressed as a SEXP list hash with only one element which should
1564 instantly be available as a MPI. Alternatively the structure given 1564 instantly be available as a MPI. Alternatively the structure given
1565 below may be used for S_HASH, it provides the abiliy to pass flags 1565 below may be used for S_HASH, it provides the abiliy to pass flags
1566 to the operation; the only flag defined by now is "pkcs1" which 1566 to the operation; the only flag defined by now is "pkcs1" which
1567 does PKCS#1 block type 1 style padding. 1567 does PKCS#1 block type 1 style padding.
1568 1568
1569 Returns: 0 or an errorcode. 1569 Returns: 0 or an errorcode.
1570 In case of 0 the function returns a new SEXP with the 1570 In case of 0 the function returns a new SEXP with the
1571 signature value; the structure of this signature depends on the 1571 signature value; the structure of this signature depends on the
1572 other arguments but is always suitable to be passed to 1572 other arguments but is always suitable to be passed to
1573 gcry_pk_verify 1573 gcry_pk_verify
1574 1574
1575 s_hash = See comment for sexp_data_to_mpi 1575 s_hash = See comment for sexp_data_to_mpi
1576 1576
1577 s_skey = <key-as-defined-in-sexp_to_key> 1577 s_skey = <key-as-defined-in-sexp_to_key>
1578 r_sig = (sig-val 1578 r_sig = (sig-val
1579 (<algo> 1579 (<algo>
1580 (<param_name1> <mpi>) 1580 (<param_name1> <mpi>)
1581 ... 1581 ...
1582 (<param_namen> <mpi>))) 1582 (<param_namen> <mpi>)))
1583*/ 1583*/
1584gcry_error_t 1584gcry_error_t
1585gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey) 1585gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
1586{ 1586{
1587 gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL; 1587 gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
1588 gcry_pk_spec_t *pubkey = NULL; 1588 gcry_pk_spec_t *pubkey = NULL;
1589 gcry_module_t module = NULL; 1589 gcry_module_t module = NULL;
1590 const char *algo_name, *algo_elems; 1590 const char *algo_name, *algo_elems;
1591 int i; 1591 int i;
1592 gcry_err_code_t rc; 1592 gcry_err_code_t rc;
1593 1593
1594 REGISTER_DEFAULT_PUBKEYS; 1594 REGISTER_DEFAULT_PUBKEYS;
1595 1595
1596 *r_sig = NULL; 1596 *r_sig = NULL;
1597 rc = sexp_to_key (s_skey, 1, &skey, &module); 1597 rc = sexp_to_key (s_skey, 1, &skey, &module);
1598 if (rc) 1598 if (rc)
1599 goto leave; 1599 goto leave;
1600 1600
1601 assert (module); 1601 assert (module);
1602 pubkey = (gcry_pk_spec_t *) module->spec; 1602 pubkey = (gcry_pk_spec_t *) module->spec;
1603 algo_name = pubkey->aliases? *pubkey->aliases : NULL; 1603 algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1604 if (!algo_name || !*algo_name) 1604 if (!algo_name || !*algo_name)
1605 algo_name = pubkey->name; 1605 algo_name = pubkey->name;
1606 1606
1607 algo_elems = pubkey->elements_sig; 1607 algo_elems = pubkey->elements_sig;
1608 1608
1609 /* Get the stuff we want to sign. Note that pk_get_nbits does also 1609 /* Get the stuff we want to sign. Note that pk_get_nbits does also
1610 work on a private key. */ 1610 work on a private key. */
1611 rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey), 1611 rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
1612 &hash, 0, NULL); 1612 &hash, 0, NULL);
1613 if (rc) 1613 if (rc)
1614 goto leave; 1614 goto leave;
1615 1615
1616 result = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*result)); 1616 result = gcry_xcalloc (strlen (algo_elems) + 1, sizeof (*result));
1617 rc = pubkey_sign (module->mod_id, result, hash, skey); 1617 rc = pubkey_sign (module->mod_id, result, hash, skey);
1618 if (rc) 1618 if (rc)
1619 goto leave; 1619 goto leave;
1620 1620
1621 { 1621 {
1622 char *string, *p; 1622 char *string, *p;
1623 size_t nelem, needed = strlen (algo_name) + 20; 1623 size_t nelem, needed = strlen (algo_name) + 20;
1624 void **arg_list; 1624 void **arg_list;
1625 1625
1626 nelem = strlen (algo_elems); 1626 nelem = strlen (algo_elems);
1627 1627
1628 /* Count elements, so that we can allocate enough space. */ 1628 /* Count elements, so that we can allocate enough space. */
1629 needed += 10 * nelem; 1629 needed += 10 * nelem;
1630 1630
1631 /* Build the string. */ 1631 /* Build the string. */
1632 string = p = gcry_xmalloc (needed); 1632 string = p = gcry_xmalloc (needed);
1633 p = stpcpy (p, "(sig-val("); 1633 p = stpcpy (p, "(sig-val(");
1634 p = stpcpy (p, algo_name); 1634 p = stpcpy (p, algo_name);
1635 for (i = 0; algo_elems[i]; i++) 1635 for (i = 0; algo_elems[i]; i++)
1636 { 1636 {
1637 *p++ = '('; 1637 *p++ = '(';
1638 *p++ = algo_elems[i]; 1638 *p++ = algo_elems[i];
1639 p = stpcpy (p, "%m)"); 1639 p = stpcpy (p, "%m)");
1640 } 1640 }
1641 strcpy (p, "))"); 1641 strcpy (p, "))");
1642 1642
1643 arg_list = malloc (nelem * sizeof *arg_list); 1643 arg_list = malloc (nelem * sizeof *arg_list);
1644 if (!arg_list) 1644 if (!arg_list)
1645 { 1645 {
1646 rc = gpg_err_code_from_errno (errno); 1646 rc = gpg_err_code_from_errno (errno);
1647 goto leave; 1647 goto leave;
1648 } 1648 }
1649 1649
1650 for (i = 0; i < nelem; i++) 1650 for (i = 0; i < nelem; i++)
1651 arg_list[i] = result + i; 1651 arg_list[i] = result + i;
1652 1652
1653 rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list); 1653 rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
1654 free (arg_list); 1654 free (arg_list);
1655 if (rc) 1655 if (rc)
1656 BUG (); 1656 BUG ();
1657 gcry_free (string); 1657 gcry_free (string);
1658 } 1658 }
1659 1659
1660 leave: 1660 leave:
1661 if (skey) 1661 if (skey)
1662 { 1662 {
1663 release_mpi_array (skey); 1663 release_mpi_array (skey);
1664 gcry_free (skey); 1664 gcry_free (skey);
1665 } 1665 }
1666 1666
1667 if (hash) 1667 if (hash)
1668 mpi_free (hash); 1668 mpi_free (hash);
1669 1669
1670 if (result) 1670 if (result)
1671 { 1671 {
1672 release_mpi_array (result); 1672 release_mpi_array (result);
1673 gcry_free (result); 1673 gcry_free (result);
1674 } 1674 }
1675 1675
1676 return gcry_error (rc); 1676 return gcry_error (rc);
1677} 1677}
1678 1678
1679 1679
1680/* 1680/*
1681 Verify a signature. 1681 Verify a signature.
1682 1682
1683 Caller has to supply the public key pkey, the signature sig and his 1683 Caller has to supply the public key pkey, the signature sig and his
1684 hashvalue data. Public key has to be a standard public key given 1684 hashvalue data. Public key has to be a standard public key given
1685 as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data 1685 as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
1686 must be an S-Exp like the one in sign too. */ 1686 must be an S-Exp like the one in sign too. */
1687gcry_error_t 1687gcry_error_t
1688gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey) 1688gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
1689{ 1689{
1690 gcry_module_t module_key = NULL, module_sig = NULL; 1690 gcry_module_t module_key = NULL, module_sig = NULL;
1691 gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL; 1691 gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
1692 gcry_err_code_t rc; 1692 gcry_err_code_t rc;
1693 1693
1694 REGISTER_DEFAULT_PUBKEYS; 1694 REGISTER_DEFAULT_PUBKEYS;
1695 1695
1696 rc = sexp_to_key (s_pkey, 0, &pkey, &module_key); 1696 rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
1697 if (rc) 1697 if (rc)
1698 goto leave; 1698 goto leave;
1699 1699
1700 rc = sexp_to_sig (s_sig, &sig, &module_sig); 1700 rc = sexp_to_sig (s_sig, &sig, &module_sig);
1701 if (rc) 1701 if (rc)
1702 goto leave; 1702 goto leave;
1703 1703
1704 if (module_key->mod_id != module_sig->mod_id) 1704 if (module_key->mod_id != module_sig->mod_id)
1705 { 1705 {
1706 rc = GPG_ERR_CONFLICT; 1706 rc = GPG_ERR_CONFLICT;
1707 goto leave; 1707 goto leave;
1708 } 1708 }
1709 1709
1710 rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0); 1710 rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
1711 if (rc) 1711 if (rc)
1712 goto leave; 1712 goto leave;
1713 1713
1714 rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL); 1714 rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
1715 1715
1716 leave: 1716 leave:
1717 if (pkey) 1717 if (pkey)
1718 { 1718 {
1719 release_mpi_array (pkey); 1719 release_mpi_array (pkey);
1720 gcry_free (pkey); 1720 gcry_free (pkey);
1721 } 1721 }
1722 if (sig) 1722 if (sig)
1723 { 1723 {
1724 release_mpi_array (sig); 1724 release_mpi_array (sig);
1725 gcry_free (sig); 1725 gcry_free (sig);
1726 } 1726 }
1727 if (hash) 1727 if (hash)
1728 mpi_free (hash); 1728 mpi_free (hash);
1729 1729
1730 if (module_key || module_sig) 1730 if (module_key || module_sig)
1731 { 1731 {
1732 ath_mutex_lock (&pubkeys_registered_lock); 1732 ath_mutex_lock (&pubkeys_registered_lock);
1733 if (module_key) 1733 if (module_key)
1734 _gcry_module_release (module_key); 1734 _gcry_module_release (module_key);
1735 if (module_sig) 1735 if (module_sig)
1736 _gcry_module_release (module_sig); 1736 _gcry_module_release (module_sig);
1737 ath_mutex_unlock (&pubkeys_registered_lock); 1737 ath_mutex_unlock (&pubkeys_registered_lock);
1738 } 1738 }
1739 1739
1740 return gcry_error (rc); 1740 return gcry_error (rc);
1741} 1741}
1742 1742
1743 1743
1744/* 1744/*
1745 Test a key. 1745 Test a key.
1746 1746
1747 This may be used either for a public or a secret key to see whether 1747 This may be used either for a public or a secret key to see whether
1748 internal structre is valid. 1748 internal structre is valid.
1749 1749
1750 Returns: 0 or an errorcode. 1750 Returns: 0 or an errorcode.
1751 1751
1752 s_key = <key-as-defined-in-sexp_to_key> */ 1752 s_key = <key-as-defined-in-sexp_to_key> */
1753gcry_error_t 1753gcry_error_t
1754gcry_pk_testkey (gcry_sexp_t s_key) 1754gcry_pk_testkey (gcry_sexp_t s_key)
1755{ 1755{
1756 gcry_module_t module = NULL; 1756 gcry_module_t module = NULL;
1757 gcry_mpi_t *key = NULL; 1757 gcry_mpi_t *key = NULL;
1758 gcry_err_code_t rc; 1758 gcry_err_code_t rc;
1759 1759
1760 REGISTER_DEFAULT_PUBKEYS; 1760 REGISTER_DEFAULT_PUBKEYS;
1761 1761
1762 /* Note we currently support only secret key checking. */ 1762 /* Note we currently support only secret key checking. */
1763 rc = sexp_to_key (s_key, 1, &key, &module); 1763 rc = sexp_to_key (s_key, 1, &key, &module);
1764 if (! rc) 1764 if (! rc)
1765 { 1765 {
1766 rc = pubkey_check_secret_key (module->mod_id, key); 1766 rc = pubkey_check_secret_key (module->mod_id, key);
1767 release_mpi_array (key); 1767 release_mpi_array (key);
1768 gcry_free (key); 1768 gcry_free (key);
1769 } 1769 }
1770 return gcry_error (rc); 1770 return gcry_error (rc);
1771} 1771}
1772 1772
1773 1773
1774/* 1774/*
1775 Create a public key pair and return it in r_key. 1775 Create a public key pair and return it in r_key.
1776 How the key is created depends on s_parms: 1776 How the key is created depends on s_parms:
1777 (genkey 1777 (genkey
1778 (algo 1778 (algo
1779 (parameter_name_1 ....) 1779 (parameter_name_1 ....)
1780 .... 1780 ....
1781 (parameter_name_n ....) 1781 (parameter_name_n ....)
1782 )) 1782 ))
1783 The key is returned in a format depending on the 1783 The key is returned in a format depending on the
1784 algorithm. Both, private and secret keys are returned 1784 algorithm. Both, private and secret keys are returned
1785 and optionally some additional informatin. 1785 and optionally some additional informatin.
1786 For elgamal we return this structure: 1786 For elgamal we return this structure:
1787 (key-data 1787 (key-data
1788 (public-key 1788 (public-key
1789 (elg 1789 (elg
1790 (p <mpi>) 1790 (p <mpi>)
1791 (g <mpi>) 1791 (g <mpi>)
1792 (y <mpi>) 1792 (y <mpi>)
1793 ) 1793 )
1794 ) 1794 )
1795 (private-key 1795 (private-key
1796 (elg 1796 (elg
1797 (p <mpi>) 1797 (p <mpi>)
1798 (g <mpi>) 1798 (g <mpi>)
1799 (y <mpi>) 1799 (y <mpi>)
1800 (x <mpi>) 1800 (x <mpi>)
1801 ) 1801 )
1802 ) 1802 )
1803 (misc-key-info 1803 (misc-key-info
1804 (pm1-factors n1 n2 ... nn) 1804 (pm1-factors n1 n2 ... nn)
1805 )) 1805 ))
1806 */ 1806 */
1807gcry_error_t 1807gcry_error_t
1808gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms) 1808gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
1809{ 1809{
1810 gcry_pk_spec_t *pubkey = NULL; 1810 gcry_pk_spec_t *pubkey = NULL;
1811 gcry_module_t module = NULL; 1811 gcry_module_t module = NULL;
1812 gcry_sexp_t list = NULL, l2 = NULL; 1812 gcry_sexp_t list = NULL, l2 = NULL;
1813 const char *name; 1813 const char *name;
1814 size_t n; 1814 size_t n;
1815 gcry_err_code_t rc = GPG_ERR_NO_ERROR; 1815 gcry_err_code_t rc = GPG_ERR_NO_ERROR;
1816 int i; 1816 int i;
1817 const char *algo_name = NULL; 1817 const char *algo_name = NULL;
1818 int algo; 1818 int algo;
1819 const char *sec_elems = NULL, *pub_elems = NULL; 1819 const char *sec_elems = NULL, *pub_elems = NULL;
1820 gcry_mpi_t skey[10], *factors = NULL; 1820 gcry_mpi_t skey[10], *factors = NULL;
1821 unsigned int nbits = 0; 1821 unsigned int nbits = 0;
1822 unsigned long use_e = 0; 1822 unsigned long use_e = 0;
1823 char *name_terminated; 1823 char *name_terminated;
1824 1824
1825 REGISTER_DEFAULT_PUBKEYS; 1825 REGISTER_DEFAULT_PUBKEYS;
1826 1826
1827 skey[0] = NULL; 1827 skey[0] = NULL;
1828 *r_key = NULL; 1828 *r_key = NULL;
1829 1829
1830 list = gcry_sexp_find_token (s_parms, "genkey", 0); 1830 list = gcry_sexp_find_token (s_parms, "genkey", 0);
1831 if (!list) 1831 if (!list)
1832 { 1832 {
1833 rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */ 1833 rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
1834 goto leave; 1834 goto leave;
1835 } 1835 }
1836 1836
1837 l2 = gcry_sexp_cadr (list); 1837 l2 = gcry_sexp_cadr (list);
1838 gcry_sexp_release (list); 1838 gcry_sexp_release (list);
1839 list = l2; 1839 list = l2;
1840 l2 = NULL; 1840 l2 = NULL;
1841 if (! list) 1841 if (! list)
1842 { 1842 {
1843 rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */ 1843 rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
1844 goto leave; 1844 goto leave;
1845 } 1845 }
1846 1846
1847 name = gcry_sexp_nth_data (list, 0, &n); 1847 name = gcry_sexp_nth_data (list, 0, &n);
1848 if (! name) 1848 if (! name)
1849 { 1849 {
1850 rc = GPG_ERR_INV_OBJ; /* Algo string missing. */ 1850 rc = GPG_ERR_INV_OBJ; /* Algo string missing. */
1851 goto leave; 1851 goto leave;
1852 } 1852 }
1853 1853
1854 name_terminated = gcry_xmalloc (n + 1); 1854 name_terminated = gcry_xmalloc (n + 1);
1855 memcpy (name_terminated, name, n); 1855 memcpy (name_terminated, name, n);
1856 name_terminated[n] = 0; 1856 name_terminated[n] = 0;
1857 ath_mutex_lock (&pubkeys_registered_lock); 1857 ath_mutex_lock (&pubkeys_registered_lock);
1858 module = gcry_pk_lookup_name (name_terminated); 1858 module = gcry_pk_lookup_name (name_terminated);
1859 ath_mutex_unlock (&pubkeys_registered_lock); 1859 ath_mutex_unlock (&pubkeys_registered_lock);
1860 gcry_free (name_terminated); 1860 gcry_free (name_terminated);
1861 1861
1862 if (! module) 1862 if (! module)
1863 { 1863 {
1864 rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */ 1864 rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
1865 goto leave; 1865 goto leave;
1866 } 1866 }
1867 1867
1868 pubkey = (gcry_pk_spec_t *) module->spec; 1868 pubkey = (gcry_pk_spec_t *) module->spec;
1869 algo = module->mod_id; 1869 algo = module->mod_id;
1870 algo_name = pubkey->aliases? *pubkey->aliases : NULL; 1870 algo_name = pubkey->aliases? *pubkey->aliases : NULL;
1871 if (!algo_name || !*algo_name) 1871 if (!algo_name || !*algo_name)
1872 algo_name = pubkey->name; 1872 algo_name = pubkey->name;
1873 pub_elems = pubkey->elements_pkey; 1873 pub_elems = pubkey->elements_pkey;
1874 sec_elems = pubkey->elements_skey; 1874 sec_elems = pubkey->elements_skey;
1875 1875
1876 /* Handle the optional rsa-use-e element. */ 1876 /* Handle the optional rsa-use-e element. */
1877 l2 = gcry_sexp_find_token (list, "rsa-use-e", 0); 1877 l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
1878 if (l2) 1878 if (l2)
1879 { 1879 {
1880 char buf[50]; 1880 char buf[50];
1881 1881
1882 name = gcry_sexp_nth_data (l2, 1, &n); 1882 name = gcry_sexp_nth_data (l2, 1, &n);
1883 if ((! name) || (n >= DIM (buf) - 1)) 1883 if ((! name) || (n >= DIM (buf) - 1))
1884 { 1884 {
1885 rc = GPG_ERR_INV_OBJ; /* No value or value too large. */ 1885 rc = GPG_ERR_INV_OBJ; /* No value or value too large. */
1886 goto leave; 1886 goto leave;
1887 } 1887 }
1888 memcpy (buf, name, n); 1888 memcpy (buf, name, n);
1889 buf[n] = 0; 1889 buf[n] = 0;
1890 use_e = strtoul (buf, NULL, 0); 1890 use_e = strtoul (buf, NULL, 0);
1891 gcry_sexp_release (l2); 1891 gcry_sexp_release (l2);
1892 l2 = NULL; 1892 l2 = NULL;
1893 } 1893 }
1894 else 1894 else
1895 use_e = 65537; /* Not given, use the value generated by old versions. */ 1895 use_e = 65537; /* Not given, use the value generated by old versions. */
1896 1896
1897 l2 = gcry_sexp_find_token (list, "nbits", 0); 1897 l2 = gcry_sexp_find_token (list, "nbits", 0);
1898 gcry_sexp_release (list); 1898 gcry_sexp_release (list);
1899 list = l2; 1899 list = l2;
1900 l2 = NULL; 1900 l2 = NULL;
1901 1901
1902 if (! list) 1902 if (! list)
1903 { 1903 {
1904 rc = GPG_ERR_NO_OBJ; /* No nbits parameter. */ 1904 rc = GPG_ERR_NO_OBJ; /* No nbits parameter. */
1905 goto leave; 1905 goto leave;
1906 } 1906 }
1907 1907
1908 name = gcry_sexp_nth_data (list, 1, &n); 1908 name = gcry_sexp_nth_data (list, 1, &n);
1909 if (! name) 1909 if (! name)
1910 { 1910 {
1911 rc = GPG_ERR_INV_OBJ; /* nbits without a cdr. */ 1911 rc = GPG_ERR_INV_OBJ; /* nbits without a cdr. */
1912 goto leave; 1912 goto leave;
1913 } 1913 }
1914 1914
1915 name_terminated = gcry_xmalloc (n + 1); 1915 name_terminated = gcry_xmalloc (n + 1);
1916 memcpy (name_terminated, name, n); 1916 memcpy (name_terminated, name, n);
1917 name_terminated[n] = 0; 1917 name_terminated[n] = 0;
1918 nbits = (unsigned int) strtoul (name_terminated, NULL, 0); 1918 nbits = (unsigned int) strtoul (name_terminated, NULL, 0);
1919 gcry_free (name_terminated); 1919 gcry_free (name_terminated);
1920 1920
1921 rc = pubkey_generate (module->mod_id, nbits, use_e, skey, &factors); 1921 rc = pubkey_generate (module->mod_id, nbits, use_e, skey, &factors);
1922 if (rc) 1922 if (rc)
1923 goto leave; 1923 goto leave;
1924 1924
1925 { 1925 {
1926 char *string, *p; 1926 char *string, *p;
1927 size_t nelem=0, nelem_cp = 0, needed=0; 1927 size_t nelem=0, nelem_cp = 0, needed=0;
1928 gcry_mpi_t mpis[30]; 1928 gcry_mpi_t mpis[30];
1929 1929
1930 nelem = strlen (pub_elems) + strlen (sec_elems); 1930 nelem = strlen (pub_elems) + strlen (sec_elems);
1931 for (i = 0; factors[i]; i++) 1931 for (i = 0; factors[i]; i++)
1932 nelem++; 1932 nelem++;
1933 nelem_cp = nelem; 1933 nelem_cp = nelem;
1934 1934
1935 needed += nelem * 10; 1935 needed += nelem * 10;
1936 needed += 2 * strlen (algo_name) + 300; 1936 needed += 2 * strlen (algo_name) + 300;
1937 if (nelem > DIM (mpis)) 1937 if (nelem > DIM (mpis))
1938 BUG (); 1938 BUG ();
1939 1939
1940 /* Build the string. */ 1940 /* Build the string. */
1941 nelem = 0; 1941 nelem = 0;
1942 string = p = gcry_xmalloc (needed); 1942 string = p = gcry_xmalloc (needed);
1943 p = stpcpy (p, "(key-data"); 1943 p = stpcpy (p, "(key-data");
1944 p = stpcpy (p, "(public-key("); 1944 p = stpcpy (p, "(public-key(");
1945 p = stpcpy (p, algo_name); 1945 p = stpcpy (p, algo_name);
1946 for(i = 0; pub_elems[i]; i++) 1946 for(i = 0; pub_elems[i]; i++)
1947 { 1947 {
1948 *p++ = '('; 1948 *p++ = '(';
1949 *p++ = pub_elems[i]; 1949 *p++ = pub_elems[i];
1950 p = stpcpy (p, "%m)"); 1950 p = stpcpy (p, "%m)");
1951 mpis[nelem++] = skey[i]; 1951 mpis[nelem++] = skey[i];
1952 } 1952 }
1953 p = stpcpy (p, "))"); 1953 p = stpcpy (p, "))");
1954 p = stpcpy (p, "(private-key("); 1954 p = stpcpy (p, "(private-key(");
1955 p = stpcpy (p, algo_name); 1955 p = stpcpy (p, algo_name);
1956 for (i = 0; sec_elems[i]; i++) 1956 for (i = 0; sec_elems[i]; i++)
1957 { 1957 {
1958 *p++ = '('; 1958 *p++ = '(';
1959 *p++ = sec_elems[i]; 1959 *p++ = sec_elems[i];
1960 p = stpcpy (p, "%m)"); 1960 p = stpcpy (p, "%m)");
1961 mpis[nelem++] = skey[i]; 1961 mpis[nelem++] = skey[i];
1962 } 1962 }
1963 p = stpcpy (p, "))"); 1963 p = stpcpy (p, "))");
1964 1964
1965 /* Very ugly hack to make release_mpi_array() work FIXME */ 1965 /* Very ugly hack to make release_mpi_array() work FIXME */
1966 skey[i] = NULL; 1966 skey[i] = NULL;
1967 1967
1968 p = stpcpy (p, "(misc-key-info(pm1-factors"); 1968 p = stpcpy (p, "(misc-key-info(pm1-factors");
1969 for(i = 0; factors[i]; i++) 1969 for(i = 0; factors[i]; i++)
1970 { 1970 {
1971 p = stpcpy (p, "%m"); 1971 p = stpcpy (p, "%m");
1972 mpis[nelem++] = factors[i]; 1972 mpis[nelem++] = factors[i];
1973 } 1973 }
1974 strcpy (p, ")))"); 1974 strcpy (p, ")))");
1975 1975
1976 while (nelem < DIM (mpis)) 1976 while (nelem < DIM (mpis))
1977 mpis[nelem++] = NULL; 1977 mpis[nelem++] = NULL;
1978 1978
1979 { 1979 {
1980 int elem_n = strlen (pub_elems) + strlen (sec_elems); 1980 int elem_n = strlen (pub_elems) + strlen (sec_elems);
1981 void **arg_list; 1981 void **arg_list;
1982 1982
1983 arg_list = malloc (nelem_cp * sizeof *arg_list); 1983 arg_list = malloc (nelem_cp * sizeof *arg_list);
1984 if (!arg_list) 1984 if (!arg_list)
1985 { 1985 {
1986 rc = gpg_err_code_from_errno (errno); 1986 rc = gpg_err_code_from_errno (errno);
1987 goto leave; 1987 goto leave;
1988 } 1988 }
1989 for (i = 0; i < elem_n; i++) 1989 for (i = 0; i < elem_n; i++)
1990 arg_list[i] = mpis + i; 1990 arg_list[i] = mpis + i;
1991 for (; i < nelem_cp; i++) 1991 for (; i < nelem_cp; i++)
1992 arg_list[i] = factors + i - elem_n; 1992 arg_list[i] = factors + i - elem_n;
1993 1993
1994 rc = gcry_sexp_build_array (r_key, NULL, string, arg_list); 1994 rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
1995 free (arg_list); 1995 free (arg_list);
1996 if (rc) 1996 if (rc)
1997 BUG (); 1997 BUG ();
1998 assert (DIM (mpis) == 30); /* Reminder to make sure that the 1998 assert (DIM (mpis) == 30); /* Reminder to make sure that the
1999 array gets increased if new 1999 array gets increased if new
2000 parameters are added. */ 2000 parameters are added. */
2001 } 2001 }
2002 gcry_free (string); 2002 gcry_free (string);
2003 } 2003 }
2004 2004
2005 leave: 2005 leave:
2006 release_mpi_array (skey); 2006 release_mpi_array (skey);
2007 /* Don't free SKEY itself, it is a static array. */ 2007 /* Don't free SKEY itself, it is a static array. */
2008 2008
2009 if (factors) 2009 if (factors)
2010 { 2010 {
2011 release_mpi_array ( factors ); 2011 release_mpi_array ( factors );
2012 gcry_free (factors); 2012 gcry_free (factors);
2013 } 2013 }
2014 2014
2015 if (l2) 2015 if (l2)
2016 gcry_sexp_release (l2); 2016 gcry_sexp_release (l2);
2017 if (list) 2017 if (list)
2018 gcry_sexp_release (list); 2018 gcry_sexp_release (list);
2019 2019
2020 if (module) 2020 if (module)
2021 { 2021 {
2022 ath_mutex_lock (&pubkeys_registered_lock); 2022 ath_mutex_lock (&pubkeys_registered_lock);
2023 _gcry_module_release (module); 2023 _gcry_module_release (module);
2024 ath_mutex_unlock (&pubkeys_registered_lock); 2024 ath_mutex_unlock (&pubkeys_registered_lock);
2025 } 2025 }
2026 2026
2027 return gcry_error (rc); 2027 return gcry_error (rc);
2028} 2028}
2029 2029
2030 2030
2031/* 2031/*
2032 Get the number of nbits from the public key. 2032 Get the number of nbits from the public key.
2033 2033
2034 Hmmm: Should we have really this function or is it better to have a 2034 Hmmm: Should we have really this function or is it better to have a
2035 more general function to retrieve different propoerties of the key? */ 2035 more general function to retrieve different propoerties of the key? */
2036unsigned int 2036unsigned int
2037gcry_pk_get_nbits (gcry_sexp_t key) 2037gcry_pk_get_nbits (gcry_sexp_t key)
2038{ 2038{
2039 gcry_module_t module = NULL; 2039 gcry_module_t module = NULL;
2040 gcry_pk_spec_t *pubkey; 2040 gcry_pk_spec_t *pubkey;
2041 gcry_mpi_t *keyarr = NULL; 2041 gcry_mpi_t *keyarr = NULL;
2042 unsigned int nbits = 0; 2042 unsigned int nbits = 0;
2043 gcry_err_code_t rc; 2043 gcry_err_code_t rc;
2044 2044
2045 REGISTER_DEFAULT_PUBKEYS; 2045 REGISTER_DEFAULT_PUBKEYS;
2046 2046
2047 rc = sexp_to_key (key, 0, &keyarr, &module); 2047 rc = sexp_to_key (key, 0, &keyarr, &module);
2048 if (rc == GPG_ERR_INV_OBJ) 2048 if (rc == GPG_ERR_INV_OBJ)
2049 rc = sexp_to_key (key, 1, &keyarr, &module); 2049 rc = sexp_to_key (key, 1, &keyarr, &module);
2050 if (rc) 2050 if (rc)
2051 return 0; /* Error - 0 is a suitable indication for that. */ 2051 return 0; /* Error - 0 is a suitable indication for that. */
2052 2052
2053 pubkey = (gcry_pk_spec_t *) module->spec; 2053 pubkey = (gcry_pk_spec_t *) module->spec;
2054 nbits = (*pubkey->get_nbits) (module->mod_id, keyarr); 2054 nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
2055 2055
2056 ath_mutex_lock (&pubkeys_registered_lock); 2056 ath_mutex_lock (&pubkeys_registered_lock);
2057 _gcry_module_release (module); 2057 _gcry_module_release (module);
2058 ath_mutex_unlock (&pubkeys_registered_lock); 2058 ath_mutex_unlock (&pubkeys_registered_lock);
2059 2059
2060 release_mpi_array (keyarr); 2060 release_mpi_array (keyarr);
2061 gcry_free (keyarr); 2061 gcry_free (keyarr);
2062 2062
2063 return nbits; 2063 return nbits;
2064} 2064}
2065 2065
2066 2066
2067/* Return the so called KEYGRIP which is the SHA-1 hash of the public 2067/* Return the so called KEYGRIP which is the SHA-1 hash of the public
2068 key parameters expressed in a way depended on the algorithm. 2068 key parameters expressed in a way depended on the algorithm.
2069 2069
2070 ARRAY must either be 20 bytes long or NULL; in the latter case a 2070 ARRAY must either be 20 bytes long or NULL; in the latter case a
2071 newly allocated array of that size is returned, otherwise ARRAY or 2071 newly allocated array of that size is returned, otherwise ARRAY or
2072 NULL is returned to indicate an error which is most likely an 2072 NULL is returned to indicate an error which is most likely an
2073 unknown algorithm. The function accepts public or secret keys. */ 2073 unknown algorithm. The function accepts public or secret keys. */
2074unsigned char * 2074unsigned char *
2075gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array) 2075gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2076{ 2076{
2077 gcry_sexp_t list = NULL, l2 = NULL; 2077 gcry_sexp_t list = NULL, l2 = NULL;
2078 gcry_pk_spec_t *pubkey = NULL; 2078 gcry_pk_spec_t *pubkey = NULL;
2079 gcry_module_t module = NULL; 2079 gcry_module_t module = NULL;
2080 const char *s, *name; 2080 const char *s, *name;
2081 size_t n; 2081 size_t n;
2082 int idx; 2082 int idx;
2083 int is_rsa; 2083 int is_rsa;
2084 const char *elems; 2084 const char *elems;
2085 gcry_md_hd_t md = NULL; 2085 gcry_md_hd_t md = NULL;
2086 2086
2087 REGISTER_DEFAULT_PUBKEYS; 2087 REGISTER_DEFAULT_PUBKEYS;
2088 2088
2089 /* Check that the first element is valid. */ 2089 /* Check that the first element is valid. */
2090 list = gcry_sexp_find_token (key, "public-key", 0); 2090 list = gcry_sexp_find_token (key, "public-key", 0);
2091 if (!list) 2091 if (!list)
2092 list = gcry_sexp_find_token (key, "private-key", 0); 2092 list = gcry_sexp_find_token (key, "private-key", 0);
2093 if (!list) 2093 if (!list)
2094 list = gcry_sexp_find_token (key, "protected-private-key", 0); 2094 list = gcry_sexp_find_token (key, "protected-private-key", 0);
2095 if (!list) 2095 if (!list)
2096 list = gcry_sexp_find_token (key, "shadowed-private-key", 0); 2096 list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
2097 if (!list) 2097 if (!list)
2098 return NULL; /* No public- or private-key object. */ 2098 return NULL; /* No public- or private-key object. */
2099 2099
2100 l2 = gcry_sexp_cadr (list); 2100 l2 = gcry_sexp_cadr (list);
2101 gcry_sexp_release (list); 2101 gcry_sexp_release (list);
2102 list = l2; 2102 list = l2;
2103 l2 = NULL; 2103 l2 = NULL;
2104 2104
2105 name = gcry_sexp_nth_data (list, 0, &n); 2105 name = gcry_sexp_nth_data (list, 0, &n);
2106 if (! name) 2106 if (! name)
2107 goto fail; /* Invalid structure of object. */ 2107 goto fail; /* Invalid structure of object. */
2108 2108
2109 { 2109 {
2110 char *name_terminated = gcry_xmalloc (n + 1); 2110 char *name_terminated = gcry_xmalloc (n + 1);
2111 memcpy (name_terminated, name, n); 2111 memcpy (name_terminated, name, n);
2112 name_terminated[n] = 0; 2112 name_terminated[n] = 0;
2113 ath_mutex_lock (&pubkeys_registered_lock); 2113 ath_mutex_lock (&pubkeys_registered_lock);
2114 module = gcry_pk_lookup_name (name_terminated); 2114 module = gcry_pk_lookup_name (name_terminated);
2115 ath_mutex_unlock (&pubkeys_registered_lock); 2115 ath_mutex_unlock (&pubkeys_registered_lock);
2116 gcry_free (name_terminated); 2116 gcry_free (name_terminated);
2117 } 2117 }
2118 2118
2119 if (! module) 2119 if (! module)
2120 goto fail; /* unknown algorithm */ 2120 goto fail; /* unknown algorithm */
2121 2121
2122 pubkey = (gcry_pk_spec_t *) module->spec; 2122 pubkey = (gcry_pk_spec_t *) module->spec;
2123 2123
2124 /* FIXME, special handling should be implemented by the algorithms, 2124 /* FIXME, special handling should be implemented by the algorithms,
2125 not by the libgcrypt core. */ 2125 not by the libgcrypt core. */
2126 is_rsa = module->mod_id == GCRY_PK_RSA; 2126 is_rsa = module->mod_id == GCRY_PK_RSA;
2127 elems = pubkey->elements_grip; 2127 elems = pubkey->elements_grip;
2128 if (! elems) 2128 if (! elems)
2129 goto fail; /* no grip parameter */ 2129 goto fail; /* no grip parameter */
2130 2130
2131 if (gcry_md_open (&md, GCRY_MD_SHA1, 0)) 2131 if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2132 goto fail; 2132 goto fail;
2133 2133
2134 for (idx = 0, s = elems; *s; s++, idx++) 2134 for (idx = 0, s = elems; *s; s++, idx++)
2135 { 2135 {
2136 const char *data; 2136 const char *data;
2137 size_t datalen; 2137 size_t datalen;
2138 2138
2139 l2 = gcry_sexp_find_token (list, s, 1); 2139 l2 = gcry_sexp_find_token (list, s, 1);
2140 if (! l2) 2140 if (! l2)
2141 goto fail; 2141 goto fail;
2142 data = gcry_sexp_nth_data (l2, 1, &datalen); 2142 data = gcry_sexp_nth_data (l2, 1, &datalen);
2143 if (! data) 2143 if (! data)
2144 goto fail; 2144 goto fail;
2145 if (!is_rsa) 2145 if (!is_rsa)
2146 { 2146 {
2147 char buf[30]; 2147 char buf[30];
2148 2148
2149 sprintf (buf, "(1:%c%u:", *s, (unsigned int)datalen); 2149 sprintf (buf, "(1:%c%u:", *s, (unsigned int)datalen);
2150 gcry_md_write (md, buf, strlen (buf)); 2150 gcry_md_write (md, buf, strlen (buf));
2151 } 2151 }
2152 2152
2153 /* PKCS-15 says that for RSA only the modulus should be hashed - 2153 /* PKCS-15 says that for RSA only the modulus should be hashed -
2154 however, it is not clear wether this is meant to has the raw 2154 however, it is not clear wether this is meant to has the raw
2155 bytes assuming this is an unsigned integer or whether the DER 2155 bytes assuming this is an unsigned integer or whether the DER
2156 required 0 should be prefixed. We hash the raw bytes. For 2156 required 0 should be prefixed. We hash the raw bytes. For
2157 non-RSA we hash S-expressions. */ 2157 non-RSA we hash S-expressions. */
2158 gcry_md_write (md, data, datalen); 2158 gcry_md_write (md, data, datalen);
2159 gcry_sexp_release (l2); 2159 gcry_sexp_release (l2);
2160 if (!is_rsa) 2160 if (!is_rsa)
2161 gcry_md_write (md, ")", 1); 2161 gcry_md_write (md, ")", 1);
2162 } 2162 }
2163 2163
2164 if (!array) 2164 if (!array)
2165 { 2165 {
2166 array = gcry_malloc (20); 2166 array = gcry_malloc (20);
2167 if (! array) 2167 if (! array)
2168 goto fail; 2168 goto fail;
2169 } 2169 }
2170 2170
2171 memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20); 2171 memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2172 gcry_md_close (md); 2172 gcry_md_close (md);
2173 gcry_sexp_release (list); 2173 gcry_sexp_release (list);
2174 return array; 2174 return array;
2175 2175
2176 fail: 2176 fail:
2177 if (l2) 2177 if (l2)
2178 gcry_sexp_release (l2); 2178 gcry_sexp_release (l2);
2179 if (md) 2179 if (md)
2180 gcry_md_close (md); 2180 gcry_md_close (md);
2181 gcry_sexp_release (list); 2181 gcry_sexp_release (list);
2182 return NULL; 2182 return NULL;
2183} 2183}
2184 2184
2185 2185
2186gcry_error_t 2186gcry_error_t
2187gcry_pk_ctl (int cmd, void *buffer, size_t buflen) 2187gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
2188{ 2188{
2189 gcry_err_code_t err = GPG_ERR_NO_ERROR; 2189 gcry_err_code_t err = GPG_ERR_NO_ERROR;
2190 2190
2191 REGISTER_DEFAULT_PUBKEYS; 2191 REGISTER_DEFAULT_PUBKEYS;
2192 2192
2193 switch (cmd) 2193 switch (cmd)
2194 { 2194 {
2195 case GCRYCTL_DISABLE_ALGO: 2195 case GCRYCTL_DISABLE_ALGO:
2196 /* This one expects a buffer pointing to an integer with the 2196 /* This one expects a buffer pointing to an integer with the
2197 algo number. */ 2197 algo number. */
2198 if ((! buffer) || (buflen != sizeof (int))) 2198 if ((! buffer) || (buflen != sizeof (int)))
2199 err = GPG_ERR_INV_ARG; 2199 err = GPG_ERR_INV_ARG;
2200 else 2200 else
2201 disable_pubkey_algo (*((int *) buffer)); 2201 disable_pubkey_algo (*((int *) buffer));
2202 break; 2202 break;
2203 2203
2204 default: 2204 default:
2205 err = GPG_ERR_INV_OP; 2205 err = GPG_ERR_INV_OP;
2206 } 2206 }
2207 2207
2208 return gcry_error (err); 2208 return gcry_error (err);
2209} 2209}
2210 2210
2211 2211
2212/* 2212/*
2213 Return information about the given algorithm 2213 Return information about the given algorithm
2214 WHAT select the kind of information returned: 2214 WHAT select the kind of information returned:
2215 GCRYCTL_TEST_ALGO: 2215 GCRYCTL_TEST_ALGO:
2216 Returns 0 when the specified algorithm is available for use. 2216 Returns 0 when the specified algorithm is available for use.
2217 Buffer must be NULL, nbytes may have the address of a variable 2217 Buffer must be NULL, nbytes may have the address of a variable
2218 with the required usage of the algorithm. It may be 0 for don't 2218 with the required usage of the algorithm. It may be 0 for don't
2219 care or a combination of the GCRY_PK_USAGE_xxx flags; 2219 care or a combination of the GCRY_PK_USAGE_xxx flags;
2220 GCRYCTL_GET_ALGO_USAGE: 2220 GCRYCTL_GET_ALGO_USAGE:
2221 Return the usage glafs for the give algo. An invalid alog 2221 Return the usage glafs for the give algo. An invalid alog
2222 does return 0. Disabled algos are ignored here becuase we 2222 does return 0. Disabled algos are ignored here becuase we
2223 only want to know whether the algo is at all capable of 2223 only want to know whether the algo is at all capable of
2224 the usage. 2224 the usage.
2225 2225
2226 Note: Because this function is in most cases used to return an 2226 Note: Because this function is in most cases used to return an
2227 integer value, we can make it easier for the caller to just look at 2227 integer value, we can make it easier for the caller to just look at
2228 the return value. The caller will in all cases consult the value 2228 the return value. The caller will in all cases consult the value
2229 and thereby detecting whether a error occured or not (i.e. while 2229 and thereby detecting whether a error occured or not (i.e. while
2230 checking the block size) */ 2230 checking the block size) */
2231gcry_error_t 2231gcry_error_t
2232gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes) 2232gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
2233{ 2233{
2234 gcry_err_code_t err = GPG_ERR_NO_ERROR; 2234 gcry_err_code_t err = GPG_ERR_NO_ERROR;
2235 2235
2236 switch (what) 2236 switch (what)
2237 { 2237 {
2238 case GCRYCTL_TEST_ALGO: 2238 case GCRYCTL_TEST_ALGO:
2239 { 2239 {
2240 int use = nbytes ? *nbytes : 0; 2240 int use = nbytes ? *nbytes : 0;
2241 if (buffer) 2241 if (buffer)
2242 err = GPG_ERR_INV_ARG; 2242 err = GPG_ERR_INV_ARG;
2243 else if (check_pubkey_algo (algorithm, use)) 2243 else if (check_pubkey_algo (algorithm, use))
2244 err = GPG_ERR_PUBKEY_ALGO; 2244 err = GPG_ERR_PUBKEY_ALGO;
2245 break; 2245 break;
2246 } 2246 }
2247 2247
2248 case GCRYCTL_GET_ALGO_USAGE: 2248 case GCRYCTL_GET_ALGO_USAGE:
2249 { 2249 {
2250 gcry_module_t pubkey; 2250 gcry_module_t pubkey;
2251 int use = 0; 2251 int use = 0;
2252 2252
2253 REGISTER_DEFAULT_PUBKEYS; 2253 REGISTER_DEFAULT_PUBKEYS;
2254 2254
2255 ath_mutex_lock (&pubkeys_registered_lock); 2255 ath_mutex_lock (&pubkeys_registered_lock);
2256 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 2256 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2257 if (pubkey) 2257 if (pubkey)
2258 { 2258 {
2259 use = ((gcry_pk_spec_t *) pubkey->spec)->use; 2259 use = ((gcry_pk_spec_t *) pubkey->spec)->use;
2260 _gcry_module_release (pubkey); 2260 _gcry_module_release (pubkey);
2261 } 2261 }
2262 ath_mutex_unlock (&pubkeys_registered_lock); 2262 ath_mutex_unlock (&pubkeys_registered_lock);
2263 2263
2264 /* FIXME? */ 2264 /* FIXME? */
2265 *nbytes = use; 2265 *nbytes = use;
2266 } 2266 }
2267 2267
2268 case GCRYCTL_GET_ALGO_NPKEY: 2268 case GCRYCTL_GET_ALGO_NPKEY:
2269 { 2269 {
2270 /* FIXME? */ 2270 /* FIXME? */
2271 int npkey = pubkey_get_npkey (algorithm); 2271 int npkey = pubkey_get_npkey (algorithm);
2272 *nbytes = npkey; 2272 *nbytes = npkey;
2273 break; 2273 break;
2274 } 2274 }
2275 case GCRYCTL_GET_ALGO_NSKEY: 2275 case GCRYCTL_GET_ALGO_NSKEY:
2276 { 2276 {
2277 /* FIXME? */ 2277 /* FIXME? */
2278 int nskey = pubkey_get_nskey (algorithm); 2278 int nskey = pubkey_get_nskey (algorithm);
2279 *nbytes = nskey; 2279 *nbytes = nskey;
2280 break; 2280 break;
2281 } 2281 }
2282 case GCRYCTL_GET_ALGO_NSIGN: 2282 case GCRYCTL_GET_ALGO_NSIGN:
2283 { 2283 {
2284 /* FIXME? */ 2284 /* FIXME? */
2285 int nsign = pubkey_get_nsig (algorithm); 2285 int nsign = pubkey_get_nsig (algorithm);
2286 *nbytes = nsign; 2286 *nbytes = nsign;
2287 break; 2287 break;
2288 } 2288 }
2289 case GCRYCTL_GET_ALGO_NENCR: 2289 case GCRYCTL_GET_ALGO_NENCR:
2290 { 2290 {
2291 /* FIXME? */ 2291 /* FIXME? */
2292 int nencr = pubkey_get_nenc (algorithm); 2292 int nencr = pubkey_get_nenc (algorithm);
2293 *nbytes = nencr; 2293 *nbytes = nencr;
2294 break; 2294 break;
2295 } 2295 }
2296 2296
2297 default: 2297 default:
2298 err = GPG_ERR_INV_OP; 2298 err = GPG_ERR_INV_OP;
2299 } 2299 }
2300 2300
2301 return gcry_error (err); 2301 return gcry_error (err);
2302} 2302}
2303 2303
2304 2304
2305gcry_err_code_t 2305gcry_err_code_t
2306_gcry_pk_init (void) 2306_gcry_pk_init (void)
2307{ 2307{
2308 gcry_err_code_t err = GPG_ERR_NO_ERROR; 2308 gcry_err_code_t err = GPG_ERR_NO_ERROR;
2309 2309
2310 REGISTER_DEFAULT_PUBKEYS; 2310 REGISTER_DEFAULT_PUBKEYS;
2311 2311
2312 return err; 2312 return err;
2313} 2313}
2314 2314
2315 2315
2316gcry_err_code_t 2316gcry_err_code_t
2317_gcry_pk_module_lookup (int algorithm, gcry_module_t *module) 2317_gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
2318{ 2318{
2319 gcry_err_code_t err = GPG_ERR_NO_ERROR; 2319 gcry_err_code_t err = GPG_ERR_NO_ERROR;
2320 gcry_module_t pubkey; 2320 gcry_module_t pubkey;
2321 2321
2322 REGISTER_DEFAULT_PUBKEYS; 2322 REGISTER_DEFAULT_PUBKEYS;
2323 2323
2324 ath_mutex_lock (&pubkeys_registered_lock); 2324 ath_mutex_lock (&pubkeys_registered_lock);
2325 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm); 2325 pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
2326 if (pubkey) 2326 if (pubkey)
2327 *module = pubkey; 2327 *module = pubkey;
2328 else 2328 else
2329 err = GPG_ERR_PUBKEY_ALGO; 2329 err = GPG_ERR_PUBKEY_ALGO;
2330 ath_mutex_unlock (&pubkeys_registered_lock); 2330 ath_mutex_unlock (&pubkeys_registered_lock);
2331 2331
2332 return err; 2332 return err;
2333} 2333}
2334 2334
2335 2335
2336void 2336void
2337_gcry_pk_module_release (gcry_module_t module) 2337_gcry_pk_module_release (gcry_module_t module)
2338{ 2338{
2339 ath_mutex_lock (&pubkeys_registered_lock); 2339 ath_mutex_lock (&pubkeys_registered_lock);
2340 _gcry_module_release (module); 2340 _gcry_module_release (module);
2341 ath_mutex_unlock (&pubkeys_registered_lock); 2341 ath_mutex_unlock (&pubkeys_registered_lock);
2342} 2342}
2343 2343
2344/* Get a list consisting of the IDs of the loaded pubkey modules. If 2344/* Get a list consisting of the IDs of the loaded pubkey modules. If
2345 LIST is zero, write the number of loaded pubkey modules to 2345 LIST is zero, write the number of loaded pubkey modules to
2346 LIST_LENGTH and return. If LIST is non-zero, the first 2346 LIST_LENGTH and return. If LIST is non-zero, the first
2347 *LIST_LENGTH algorithm IDs are stored in LIST, which must be of 2347 *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
2348 according size. In case there are less pubkey modules than 2348 according size. In case there are less pubkey modules than
2349 *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */ 2349 *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
2350gcry_error_t 2350gcry_error_t
2351gcry_pk_list (int *list, int *list_length) 2351gcry_pk_list (int *list, int *list_length)
2352{ 2352{
2353 gcry_err_code_t err = GPG_ERR_NO_ERROR; 2353 gcry_err_code_t err = GPG_ERR_NO_ERROR;
2354 2354
2355 ath_mutex_lock (&pubkeys_registered_lock); 2355 ath_mutex_lock (&pubkeys_registered_lock);
2356 err = _gcry_module_list (pubkeys_registered, list, list_length); 2356 err = _gcry_module_list (pubkeys_registered, list, list_length);
2357 ath_mutex_unlock (&pubkeys_registered_lock); 2357 ath_mutex_unlock (&pubkeys_registered_lock);
2358 2358
2359 return err; 2359 return err;
2360} 2360}