~hamo/ubuntu/precise/grub2/grub2.hi_res

« back to all changes in this revision

Viewing changes to lib/libgcrypt/cipher/pubkey.c

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Evan Broder, Mario Limonciello
  • Date: 2010-11-24 13:59:55 UTC
  • mfrom: (1.17.6 upstream) (17.6.15 experimental)
  • Revision ID: james.westby@ubuntu.com-20101124135955-r6ii5sepayr7jt53
Tags: 1.99~20101124-1ubuntu1
[ Colin Watson ]
* Resynchronise with Debian experimental.  Remaining changes:
  - Adjust for default Ubuntu boot options ("quiet splash").
  - Default to hiding the menu; holding down Shift at boot will show it.
  - Set a monochromatic theme for Ubuntu.
  - Apply Ubuntu GRUB Legacy changes to legacy update-grub script: title,
    recovery mode, quiet option, tweak how memtest86+ is displayed, and
    use UUIDs where appropriate.
  - Fix backslash-escaping in merge_debconf_into_conf.
  - Remove "GNU/Linux" from default distributor string.
  - Add crashkernel= options if kdump and makedumpfile are available.
  - If other operating systems are installed, then automatically unhide
    the menu.  Otherwise, if GRUB_HIDDEN_TIMEOUT is 0, then use keystatus
    if available to check whether Shift is pressed.  If it is, show the
    menu, otherwise boot immediately.  If keystatus is not available, then
    fall back to a short delay interruptible with Escape.
  - Allow Shift to interrupt 'sleep --interruptible'.
  - Don't display introductory message about line editing unless we're
    actually offering a shell prompt.  Don't clear the screen just before
    booting if we never drew the menu in the first place.
  - Remove some verbose messages printed before reading the configuration
    file.
  - Suppress progress messages as the kernel and initrd load for
    non-recovery kernel menu entries.
  - Change prepare_grub_to_access_device to handle filesystems
    loop-mounted on file images.
  - Ignore devices loop-mounted from files in 10_linux.
  - Show the boot menu if the previous boot failed, that is if it failed
    to get to the end of one of the normal runlevels.
  - Don't generate /boot/grub/device.map during grub-install or
    grub-mkconfig by default.
  - Adjust upgrade version checks for Ubuntu.
  - Don't display "GRUB loading" unless Shift is held down.
  - Adjust versions of grub-doc and grub-legacy-doc conflicts to tolerate
    our backport of the grub-doc split.
  - Fix LVM/RAID probing in the absence of /boot/grub/device.map.
  - Look for .mo files in /usr/share/locale-langpack as well, in
    preference.
  - Make sure GRUB_TIMEOUT isn't quoted unnecessarily.
  - Probe all devices in 'grub-probe --target=drive' if
    /boot/grub/device.map is missing.
  - Build-depend on qemu-kvm rather than qemu-system for grub-pc tests.
  - Use qemu rather than qemu-system-i386.
  - Program vesafb on BIOS systems rather than efifb.
  - Add a grub-rescue-efi-amd64 package containing a rescue CD-ROM image
    for EFI-AMD64.
  - On Wubi, don't ask for an install device, but just update wubildr
    using the diverted grub-install.
  - When embedding the core image in a post-MBR gap, check for and avoid
    sectors matching any of a list of known signatures.
  - Disable video_bochs and video_cirrus on PC BIOS systems, as probing
    PCI space seems to break on some systems.
* Downgrade "ACPI shutdown failed" error to a debug message, since it can
  cause spurious test failures.

[ Evan Broder ]
* Enable lua from grub-extras.
* Incorporate the bitop library into lua.
* Add enum_pci function to grub module in lua.
* Switch back to gfxpayload=keep by default, unless the video hardware
  is known to not support it.

[ Mario Limonciello ]
* Built part_msdos and vfat into bootx64.efi (LP: #677758)

Show diffs side-by-side

added added

removed removed

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