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

« back to all changes in this revision

Viewing changes to grub-core/lib/libgcrypt/cipher/ac.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
/* ac.c - Alternative interface for asymmetric cryptography.
 
2
   Copyright (C) 2003, 2004, 2005, 2006
 
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 <errno.h>
 
23
#include <stdlib.h>
 
24
#include <string.h>
 
25
#include <stdio.h>
 
26
#include <stddef.h>
 
27
 
 
28
#include "g10lib.h"
 
29
#include "cipher.h"
 
30
#include "mpi.h"
 
31
 
 
32
 
 
33
 
 
34
/* At the moment the ac interface is a wrapper around the pk
 
35
   interface, but this might change somewhen in the future, depending
 
36
   on how many people prefer the ac interface.  */
 
37
 
 
38
/* Mapping of flag numbers to the according strings as it is expected
 
39
   for S-expressions.  */
 
40
static struct number_string
 
41
{
 
42
  int number;
 
43
  const char *string;
 
44
} ac_flags[] =
 
45
  {
 
46
    { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" },
 
47
  };
 
48
 
 
49
/* The positions in this list correspond to the values contained in
 
50
   the gcry_ac_key_type_t enumeration list.  */
 
51
static const char *ac_key_identifiers[] =
 
52
  {
 
53
    "private-key",
 
54
    "public-key"
 
55
  };
 
56
 
 
57
/* These specifications are needed for key-pair generation; the caller
 
58
   is allowed to pass additional, algorithm-specific `specs' to
 
59
   gcry_ac_key_pair_generate.  This list is used for decoding the
 
60
   provided values according to the selected algorithm.  */
 
61
struct gcry_ac_key_generate_spec
 
62
{
 
63
  int algorithm;                /* Algorithm for which this flag is
 
64
                                   relevant.  */
 
65
  const char *name;             /* Name of this flag.  */
 
66
  size_t offset;                /* Offset in the cipher-specific spec
 
67
                                   structure at which the MPI value
 
68
                                   associated with this flag is to be
 
69
                                   found.  */
 
70
} ac_key_generate_specs[] =
 
71
  {
 
72
    { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) },
 
73
    { 0 }
 
74
  };
 
75
 
 
76
/* Handle structure.  */
 
77
struct gcry_ac_handle
 
78
{
 
79
  int algorithm;                /* Algorithm ID associated with this
 
80
                                   handle.  */
 
81
  const char *algorithm_name;   /* Name of the algorithm.  */
 
82
  unsigned int flags;           /* Flags, not used yet.  */
 
83
  gcry_module_t module;         /* Reference to the algorithm
 
84
                                   module.  */
 
85
};
 
86
 
 
87
/* A named MPI value.  */
 
88
typedef struct gcry_ac_mpi
 
89
{
 
90
  char *name;                   /* Self-maintained copy of name.  */
 
91
  gcry_mpi_t mpi;               /* MPI value.         */
 
92
  unsigned int flags;           /* Flags.             */
 
93
} gcry_ac_mpi_t;
 
94
 
 
95
/* A data set, that is simply a list of named MPI values.  */
 
96
struct gcry_ac_data
 
97
{
 
98
  gcry_ac_mpi_t *data;          /* List of named values.      */
 
99
  unsigned int data_n;          /* Number of values in DATA.  */
 
100
};
 
101
 
 
102
/* A single key.  */
 
103
struct gcry_ac_key
 
104
{
 
105
  gcry_ac_data_t data;          /* Data in native ac structure.  */
 
106
  gcry_ac_key_type_t type;      /* Type of the key.              */
 
107
};
 
108
 
 
109
/* A key pair.  */
 
110
struct gcry_ac_key_pair
 
111
{
 
112
  gcry_ac_key_t public;
 
113
  gcry_ac_key_t secret;
 
114
};
 
115
 
 
116
 
 
117
 
 
118
/* 
 
119
 * Functions for working with data sets.
 
120
 */
 
121
 
 
122
/* Creates a new, empty data set and store it in DATA.  */
 
123
gcry_error_t
 
124
_gcry_ac_data_new (gcry_ac_data_t *data)
 
125
{
 
126
  gcry_ac_data_t data_new;
 
127
  gcry_error_t err;
 
128
 
 
129
  if (fips_mode ())
 
130
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
131
 
 
132
  data_new = gcry_malloc (sizeof (*data_new));
 
133
  if (! data_new)
 
134
    {
 
135
      err = gcry_error_from_errno (errno);
 
136
      goto out;
 
137
    }
 
138
 
 
139
  data_new->data = NULL;
 
140
  data_new->data_n = 0;
 
141
  *data = data_new;
 
142
  err = 0;
 
143
 
 
144
 out:
 
145
 
 
146
  return err;
 
147
}
 
148
 
 
149
/* Destroys all the entries in DATA, but not DATA itself.  */
 
150
static void
 
151
ac_data_values_destroy (gcry_ac_data_t data)
 
152
{
 
153
  unsigned int i;
 
154
  
 
155
  for (i = 0; i < data->data_n; i++)
 
156
    if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
 
157
      {
 
158
        gcry_mpi_release (data->data[i].mpi);
 
159
        gcry_free (data->data[i].name);
 
160
      }
 
161
}
 
162
 
 
163
/* Destroys the data set DATA.  */
 
164
void
 
165
_gcry_ac_data_destroy (gcry_ac_data_t data)
 
166
{
 
167
  if (data)
 
168
    {
 
169
      ac_data_values_destroy (data);
 
170
      gcry_free (data->data);
 
171
      gcry_free (data);
 
172
    }
 
173
}
 
174
 
 
175
/* This function creates a copy of the array of named MPIs DATA_MPIS,
 
176
   which is of length DATA_MPIS_N; the copy is stored in
 
177
   DATA_MPIS_CP.  */
 
178
static gcry_error_t
 
179
ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
 
180
                  gcry_ac_mpi_t **data_mpis_cp)
 
181
{
 
182
  gcry_ac_mpi_t *data_mpis_new;
 
183
  gcry_error_t err;
 
184
  unsigned int i;
 
185
  gcry_mpi_t mpi;
 
186
  char *label;
 
187
 
 
188
  data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
 
189
  if (! data_mpis_new)
 
190
    {
 
191
      err = gcry_error_from_errno (errno);
 
192
      goto out;
 
193
    }
 
194
  memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
 
195
 
 
196
  err = 0;
 
197
  for (i = 0; i < data_mpis_n; i++)
 
198
    {
 
199
      /* Copy values.  */
 
200
 
 
201
      label = gcry_strdup (data_mpis[i].name);
 
202
      mpi = gcry_mpi_copy (data_mpis[i].mpi);
 
203
      if (! (label && mpi))
 
204
        {
 
205
          err = gcry_error_from_errno (errno);
 
206
          gcry_mpi_release (mpi);
 
207
          gcry_free (label);
 
208
          break;
 
209
        }
 
210
 
 
211
      data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
 
212
      data_mpis_new[i].name = label;
 
213
      data_mpis_new[i].mpi = mpi;
 
214
    }
 
215
  if (err)
 
216
    goto out;
 
217
 
 
218
  *data_mpis_cp = data_mpis_new;
 
219
  err = 0;
 
220
 
 
221
 out:
 
222
 
 
223
  if (err)
 
224
    if (data_mpis_new)
 
225
      {
 
226
        for (i = 0; i < data_mpis_n; i++)
 
227
          {
 
228
            gcry_mpi_release (data_mpis_new[i].mpi);
 
229
            gcry_free (data_mpis_new[i].name);
 
230
          }
 
231
        gcry_free (data_mpis_new);
 
232
      }
 
233
 
 
234
  return err;
 
235
}
 
236
 
 
237
/* Create a copy of the data set DATA and store it in DATA_CP.  */
 
238
gcry_error_t
 
239
_gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
 
240
{
 
241
  gcry_ac_mpi_t *data_mpis = NULL;
 
242
  gcry_ac_data_t data_new;
 
243
  gcry_error_t err;
 
244
 
 
245
  if (fips_mode ())
 
246
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
247
 
 
248
  /* Allocate data set.  */
 
249
  data_new = gcry_malloc (sizeof (*data_new));
 
250
  if (! data_new)
 
251
    {
 
252
      err = gcry_error_from_errno (errno);
 
253
      goto out;
 
254
    }
 
255
 
 
256
  err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
 
257
  if (err)
 
258
    goto out;
 
259
  
 
260
  data_new->data_n = data->data_n;
 
261
  data_new->data = data_mpis;
 
262
  *data_cp = data_new;
 
263
 
 
264
 out:
 
265
 
 
266
  if (err)
 
267
    gcry_free (data_new);
 
268
 
 
269
  return err;
 
270
}
 
271
 
 
272
/* Returns the number of named MPI values inside of the data set
 
273
   DATA.  */
 
274
unsigned int
 
275
_gcry_ac_data_length (gcry_ac_data_t data)
 
276
{
 
277
  return data->data_n;
 
278
}
 
279
 
 
280
 
 
281
/* Add the value MPI to DATA with the label NAME.  If FLAGS contains
 
282
   GCRY_AC_FLAG_COPY, the data set will contain copies of NAME
 
283
   and MPI.  If FLAGS contains GCRY_AC_FLAG_DEALLOC or
 
284
   GCRY_AC_FLAG_COPY, the values contained in the data set will
 
285
   be deallocated when they are to be removed from the data set.  */
 
286
gcry_error_t
 
287
_gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
 
288
                   const char *name, gcry_mpi_t mpi)
 
289
{
 
290
  gcry_error_t err;
 
291
  gcry_mpi_t mpi_cp;
 
292
  char *name_cp;
 
293
  unsigned int i;
 
294
 
 
295
  name_cp = NULL;
 
296
  mpi_cp = NULL;
 
297
 
 
298
  if (fips_mode ())
 
299
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
300
 
 
301
  if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
 
302
    {
 
303
      err = gcry_error (GPG_ERR_INV_ARG);
 
304
      goto out;
 
305
    }
 
306
 
 
307
  if (flags & GCRY_AC_FLAG_COPY)
 
308
    {
 
309
      /* Create copies.  */
 
310
 
 
311
      flags |= GCRY_AC_FLAG_DEALLOC;
 
312
      name_cp = gcry_strdup (name);
 
313
      mpi_cp = gcry_mpi_copy (mpi);
 
314
      if (! (name_cp && mpi_cp))
 
315
        {
 
316
          err = gcry_error_from_errno (errno);
 
317
          goto out;
 
318
        }
 
319
    }
 
320
 
 
321
  /* Search for existing entry.  */
 
322
  for (i = 0; i < data->data_n; i++)
 
323
    if (! strcmp (name, data->data[i].name))
 
324
      break;
 
325
  if (i < data->data_n)
 
326
    {
 
327
      /* An entry for NAME does already exist.  */
 
328
      if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
 
329
        {
 
330
          gcry_mpi_release (data->data[i].mpi);
 
331
          gcry_free (data->data[i].name);
 
332
        }
 
333
    }
 
334
  else
 
335
    {
 
336
      /* Create a new entry.  */
 
337
 
 
338
      gcry_ac_mpi_t *ac_mpis;
 
339
 
 
340
      ac_mpis = gcry_realloc (data->data,
 
341
                              sizeof (*data->data) * (data->data_n + 1));
 
342
      if (! ac_mpis)
 
343
        {
 
344
          err = gcry_error_from_errno (errno);
 
345
          goto out;
 
346
        }
 
347
 
 
348
      if (data->data != ac_mpis)
 
349
        data->data = ac_mpis;
 
350
      data->data_n++;
 
351
    }
 
352
 
 
353
  data->data[i].name = name_cp ? name_cp : ((char *) name);
 
354
  data->data[i].mpi = mpi_cp ? mpi_cp : mpi;
 
355
  data->data[i].flags = flags;
 
356
  err = 0;
 
357
 
 
358
 out:
 
359
 
 
360
  if (err)
 
361
    {
 
362
      gcry_mpi_release (mpi_cp);
 
363
      gcry_free (name_cp);
 
364
    }
 
365
 
 
366
  return err;
 
367
}
 
368
 
 
369
/* Stores the value labelled with NAME found in the data set DATA in
 
370
   MPI.  The returned MPI value will be released in case
 
371
   gcry_ac_data_set is used to associate the label NAME with a
 
372
   different MPI value.  */
 
373
gcry_error_t
 
374
_gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
 
375
                        const char *name, gcry_mpi_t *mpi)
 
376
{
 
377
  gcry_mpi_t mpi_return;
 
378
  gcry_error_t err;
 
379
  unsigned int i;
 
380
 
 
381
  if (fips_mode ())
 
382
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
383
 
 
384
  if (flags & ~(GCRY_AC_FLAG_COPY))
 
385
    {
 
386
      err = gcry_error (GPG_ERR_INV_ARG);
 
387
      goto out;
 
388
    }
 
389
 
 
390
  for (i = 0; i < data->data_n; i++)
 
391
    if (! strcmp (name, data->data[i].name))
 
392
      break;
 
393
  if (i == data->data_n)
 
394
    {
 
395
      err = gcry_error (GPG_ERR_NOT_FOUND);
 
396
      goto out;
 
397
    }
 
398
 
 
399
  if (flags & GCRY_AC_FLAG_COPY)
 
400
    {
 
401
      mpi_return = gcry_mpi_copy (data->data[i].mpi);
 
402
      if (! mpi_return)
 
403
        {
 
404
          err = gcry_error_from_errno (errno); /* FIXME? */
 
405
          goto out;
 
406
        }
 
407
    }
 
408
  else
 
409
    mpi_return = data->data[i].mpi;
 
410
 
 
411
  *mpi = mpi_return;
 
412
  err = 0;
 
413
 
 
414
 out:
 
415
 
 
416
  return err;
 
417
}
 
418
 
 
419
/* Stores in NAME and MPI the named MPI value contained in the data
 
420
   set DATA with the index IDX.  NAME or MPI may be NULL.  The
 
421
   returned MPI value will be released in case gcry_ac_data_set is
 
422
   used to associate the label NAME with a different MPI value.  */
 
423
gcry_error_t
 
424
_gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
 
425
                         unsigned int idx,
 
426
                         const char **name, gcry_mpi_t *mpi)
 
427
{
 
428
  gcry_error_t err;
 
429
  gcry_mpi_t mpi_cp;
 
430
  char *name_cp;
 
431
 
 
432
  name_cp = NULL;
 
433
  mpi_cp = NULL;
 
434
 
 
435
  if (fips_mode ())
 
436
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
437
 
 
438
  if (flags & ~(GCRY_AC_FLAG_COPY))
 
439
    {
 
440
      err = gcry_error (GPG_ERR_INV_ARG);
 
441
      goto out;
 
442
    }
 
443
 
 
444
  if (idx >= data->data_n)
 
445
    {
 
446
      err = gcry_error (GPG_ERR_INV_ARG);
 
447
      goto out;
 
448
    }
 
449
 
 
450
  if (flags & GCRY_AC_FLAG_COPY)
 
451
    {
 
452
      /* Return copies to the user.  */
 
453
      if (name)
 
454
        {
 
455
          name_cp = gcry_strdup (data->data[idx].name);
 
456
          if (! name_cp)
 
457
            {
 
458
              err = gcry_error_from_errno (errno);
 
459
              goto out;
 
460
            }
 
461
        }
 
462
      if (mpi)
 
463
        {
 
464
          mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
 
465
          if (! mpi_cp)
 
466
            {
 
467
              err = gcry_error_from_errno (errno);
 
468
              goto out;
 
469
            }
 
470
        }
 
471
    }
 
472
 
 
473
  if (name)
 
474
    *name = name_cp ? name_cp : data->data[idx].name;
 
475
  if (mpi)
 
476
    *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
 
477
  err = 0;
 
478
 
 
479
 out:
 
480
 
 
481
  if (err)
 
482
    {
 
483
      gcry_mpi_release (mpi_cp);
 
484
      gcry_free (name_cp);
 
485
    }
 
486
 
 
487
  return err;
 
488
}
 
489
 
 
490
/* Convert the data set DATA into a new S-Expression, which is to be
 
491
   stored in SEXP, according to the identifiers contained in
 
492
   IDENTIFIERS.  */
 
493
gcry_error_t
 
494
_gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
 
495
                       const char **identifiers)
 
496
{
 
497
  gcry_sexp_t sexp_new;
 
498
  gcry_error_t err;
 
499
  char *sexp_buffer;
 
500
  size_t sexp_buffer_n;
 
501
  size_t identifiers_n;
 
502
  const char *label;
 
503
  gcry_mpi_t mpi;
 
504
  void **arg_list;
 
505
  size_t data_n;
 
506
  unsigned int i;
 
507
 
 
508
  sexp_buffer_n = 1;
 
509
  sexp_buffer = NULL;
 
510
  arg_list = NULL;
 
511
  err = 0;
 
512
 
 
513
  if (fips_mode ())
 
514
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
515
 
 
516
  /* Calculate size of S-expression representation.  */
 
517
 
 
518
  i = 0;
 
519
  if (identifiers)
 
520
    while (identifiers[i])
 
521
      {
 
522
        /* For each identifier, we add "(<IDENTIFIER>)".  */
 
523
        sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
 
524
        i++;
 
525
      }
 
526
  identifiers_n = i;
 
527
  
 
528
  if (! identifiers_n)
 
529
    /* If there are NO identifiers, we still add surrounding braces so
 
530
       that we have a list of named MPI value lists.  Otherwise it
 
531
       wouldn't be too much fun to process these lists.  */
 
532
    sexp_buffer_n += 2;
 
533
  
 
534
  data_n = _gcry_ac_data_length (data);
 
535
  for (i = 0; i < data_n; i++)
 
536
    {
 
537
      err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
 
538
      if (err)
 
539
        break;
 
540
      /* For each MPI we add "(<LABEL> %m)".  */
 
541
      sexp_buffer_n += 1 + strlen (label) + 4;
 
542
    }
 
543
  if (err)
 
544
    goto out;
 
545
 
 
546
  /* Allocate buffer.  */
 
547
 
 
548
  sexp_buffer = gcry_malloc (sexp_buffer_n);
 
549
  if (! sexp_buffer)
 
550
    {
 
551
      err = gcry_error_from_errno (errno);
 
552
      goto out;
 
553
    }
 
554
 
 
555
  /* Fill buffer.  */
 
556
 
 
557
  *sexp_buffer = 0;
 
558
  sexp_buffer_n = 0;
 
559
 
 
560
  /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)).  */
 
561
  if (identifiers_n)
 
562
    {
 
563
      /* Add nested identifier lists as usual.  */
 
564
      for (i = 0; i < identifiers_n; i++)
 
565
        sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s",
 
566
                                  identifiers[i]);
 
567
    }
 
568
  else
 
569
    {
 
570
      /* Add special list.  */
 
571
      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
 
572
    }
 
573
 
 
574
  /* Add MPI list.  */
 
575
  arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
 
576
  if (! arg_list)
 
577
    {
 
578
      err = gcry_error_from_errno (errno);
 
579
      goto out;
 
580
    }
 
581
  for (i = 0; i < data_n; i++)
 
582
    {
 
583
      err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
 
584
      if (err)
 
585
        break;
 
586
      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
 
587
                                "(%s %%m)", label);
 
588
      arg_list[i] = &data->data[i].mpi;
 
589
    }
 
590
  if (err)
 
591
    goto out;
 
592
 
 
593
  if (identifiers_n)
 
594
    {
 
595
      /* Add closing braces for identifier lists as usual.  */
 
596
      for (i = 0; i < identifiers_n; i++)
 
597
        sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
 
598
    }
 
599
  else
 
600
    {
 
601
      /* Add closing braces for special list.  */
 
602
      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
 
603
    }
 
604
 
 
605
  /* Construct.  */
 
606
  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
 
607
  if (err)
 
608
    goto out;
 
609
 
 
610
  *sexp = sexp_new;
 
611
 
 
612
 out:
 
613
 
 
614
  gcry_free (sexp_buffer);
 
615
  gcry_free (arg_list);
 
616
 
 
617
  return err;
 
618
}
 
619
 
 
620
/* Create a new data set, which is to be stored in DATA_SET, from the
 
621
   S-Expression SEXP, according to the identifiers contained in
 
622
   IDENTIFIERS.  */
 
623
gcry_error_t
 
624
_gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
 
625
                         const char **identifiers)
 
626
{
 
627
  gcry_ac_data_t data_set_new;
 
628
  gcry_error_t err;
 
629
  gcry_sexp_t sexp_cur;
 
630
  gcry_sexp_t sexp_tmp;
 
631
  gcry_mpi_t mpi;
 
632
  char *string;
 
633
  const char *data;
 
634
  size_t data_n;
 
635
  size_t sexp_n;
 
636
  unsigned int i;
 
637
  int skip_name;
 
638
 
 
639
  data_set_new = NULL;
 
640
  sexp_cur = sexp;
 
641
  sexp_tmp = NULL;
 
642
  string = NULL;
 
643
  mpi = NULL;
 
644
  err = 0;
 
645
 
 
646
  if (fips_mode ())
 
647
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
648
 
 
649
  /* Process S-expression/identifiers.  */
 
650
 
 
651
  if (identifiers)
 
652
    {
 
653
      for (i = 0; identifiers[i]; i++)
 
654
        {
 
655
          /* Next identifier.  Extract first data item from
 
656
             SEXP_CUR.  */
 
657
          data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
 
658
 
 
659
          if (! ((data_n == strlen (identifiers[i]))
 
660
                 && (! strncmp (data, identifiers[i], data_n))))
 
661
            {
 
662
              /* Identifier mismatch -> error.  */
 
663
              err = gcry_error (GPG_ERR_INV_SEXP);
 
664
              break;
 
665
            }
 
666
 
 
667
          /* Identifier matches.  Now we have to distinguish two
 
668
             cases:
 
669
             
 
670
             (i)  we are at the last identifier:
 
671
             leave loop
 
672
 
 
673
             (ii) we are not at the last identifier:
 
674
             extract next element, which is supposed to be a
 
675
             sublist.  */
 
676
 
 
677
          if (! identifiers[i + 1])
 
678
            /* Last identifier.  */
 
679
            break;
 
680
          else
 
681
            {
 
682
              /* Not the last identifier, extract next sublist.  */
 
683
 
 
684
              sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
 
685
              if (! sexp_tmp)
 
686
                {
 
687
                  /* Missing sublist.  */
 
688
                  err = gcry_error (GPG_ERR_INV_SEXP);
 
689
                  break;
 
690
                }
 
691
 
 
692
              /* Release old SEXP_CUR, in case it is not equal to the
 
693
                 original SEXP.  */
 
694
              if (sexp_cur != sexp)
 
695
                gcry_sexp_release (sexp_cur);
 
696
 
 
697
              /* Make SEXP_CUR point to the new current sublist.  */
 
698
              sexp_cur = sexp_tmp;
 
699
              sexp_tmp = NULL;
 
700
            }
 
701
        }
 
702
      if (err)
 
703
        goto out;
 
704
 
 
705
      if (i)
 
706
        {
 
707
          /* We have at least one identifier in the list, this means
 
708
             the the list of named MPI values is prefixed, this means
 
709
             that we need to skip the first item (the list name), when
 
710
             processing the MPI values.  */
 
711
          skip_name = 1;
 
712
        }
 
713
      else
 
714
        {
 
715
          /* Since there is no identifiers list, the list of named MPI
 
716
             values is not prefixed with a list name, therefore the
 
717
             offset to use is zero.  */
 
718
          skip_name = 0;
 
719
        }
 
720
    }
 
721
  else
 
722
    /* Since there is no identifiers list, the list of named MPI
 
723
       values is not prefixed with a list name, therefore the offset
 
724
       to use is zero.  */
 
725
    skip_name = 0;
 
726
 
 
727
  /* Create data set from S-expression data.  */
 
728
  
 
729
  err = gcry_ac_data_new (&data_set_new);
 
730
  if (err)
 
731
    goto out;
 
732
 
 
733
  /* Figure out amount of named MPIs in SEXP_CUR.  */
 
734
  if (sexp_cur)
 
735
    sexp_n = gcry_sexp_length (sexp_cur) - skip_name;
 
736
  else
 
737
    sexp_n = 0;
 
738
 
 
739
  /* Extracte the named MPIs sequentially.  */
 
740
  for (i = 0; i < sexp_n; i++)
 
741
    {
 
742
      /* Store next S-Expression pair, which is supposed to consist of
 
743
         a name and an MPI value, in SEXP_TMP.  */
 
744
 
 
745
      sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name);
 
746
      if (! sexp_tmp)
 
747
        {
 
748
          err = gcry_error (GPG_ERR_INV_SEXP);
 
749
          break;
 
750
        }
 
751
 
 
752
      /* Extract name from current S-Expression pair.  */
 
753
      data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n);
 
754
      string = gcry_malloc (data_n + 1);
 
755
      if (! string)
 
756
        {
 
757
          err = gcry_error_from_errno (errno);
 
758
          break;
 
759
        }
 
760
      memcpy (string, data, data_n);
 
761
      string[data_n] = 0;
 
762
 
 
763
      /* Extract MPI value.  */
 
764
      mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
 
765
      if (! mpi)
 
766
        {
 
767
          err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
 
768
          break;
 
769
        }
 
770
 
 
771
      /* Store named MPI in data_set_new.  */
 
772
      err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
 
773
      if (err)
 
774
        break;
 
775
 
 
776
/*       gcry_free (string); */
 
777
      string = NULL;
 
778
/*       gcry_mpi_release (mpi); */
 
779
      mpi = NULL;
 
780
 
 
781
      gcry_sexp_release (sexp_tmp);
 
782
      sexp_tmp = NULL;
 
783
    }
 
784
  if (err)
 
785
    goto out;
 
786
 
 
787
  *data_set = data_set_new;
 
788
 
 
789
 out:
 
790
 
 
791
  if (sexp_cur != sexp)
 
792
    gcry_sexp_release (sexp_cur);
 
793
  gcry_sexp_release (sexp_tmp);
 
794
  gcry_mpi_release (mpi);
 
795
  gcry_free (string);
 
796
  
 
797
  if (err)
 
798
    gcry_ac_data_destroy (data_set_new);
 
799
 
 
800
  return err;
 
801
}
 
802
 
 
803
 
 
804
static void
 
805
_gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
 
806
{
 
807
  unsigned char *mpi_buffer;
 
808
  size_t mpi_buffer_n;
 
809
  unsigned int data_n;
 
810
  gcry_error_t err;
 
811
  const char *name;
 
812
  gcry_mpi_t mpi;
 
813
  unsigned int i;
 
814
 
 
815
  if (! data)
 
816
    return;
 
817
 
 
818
  if (fips_mode ())
 
819
    return;
 
820
 
 
821
  mpi_buffer = NULL;
 
822
 
 
823
  data_n = _gcry_ac_data_length (data);
 
824
  for (i = 0; i < data_n; i++)
 
825
    {
 
826
      err = gcry_ac_data_get_index (data, 0, i, &name, &mpi);
 
827
      if (err)
 
828
        {
 
829
          log_error ("failed to dump data set");
 
830
          break;
 
831
        }
 
832
 
 
833
      err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi);
 
834
      if (err)
 
835
        {
 
836
          log_error ("failed to dump data set");
 
837
          break;
 
838
        }
 
839
 
 
840
      log_printf ("%s%s%s: %s\n",
 
841
                  prefix ? prefix : "",
 
842
                  prefix ? ": " : ""
 
843
                  , name, mpi_buffer);
 
844
 
 
845
      gcry_free (mpi_buffer);
 
846
      mpi_buffer = NULL;
 
847
    }
 
848
 
 
849
  gcry_free (mpi_buffer);
 
850
}
 
851
 
 
852
/* Dump the named MPI values contained in the data set DATA to
 
853
   Libgcrypt's logging stream.  */
 
854
void
 
855
gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
 
856
{
 
857
  _gcry_ac_data_dump (prefix, data);
 
858
}
 
859
 
 
860
/* Destroys any values contained in the data set DATA.  */
 
861
void
 
862
_gcry_ac_data_clear (gcry_ac_data_t data)
 
863
{
 
864
  ac_data_values_destroy (data);
 
865
  gcry_free (data->data);
 
866
  data->data = NULL;
 
867
  data->data_n = 0;
 
868
}
 
869
 
 
870
 
 
871
 
 
872
/*
 
873
 * Implementation of `ac io' objects.
 
874
 */
 
875
 
 
876
/* Initialize AC_IO according to MODE, TYPE and the variable list of
 
877
   arguments AP.  The list of variable arguments to specify depends on
 
878
   the given TYPE.  */
 
879
void
 
880
_gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
 
881
                     gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
 
882
{
 
883
  memset (ac_io, 0, sizeof (*ac_io));
 
884
 
 
885
  if (fips_mode ())
 
886
    return;
 
887
 
 
888
  gcry_assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
 
889
  gcry_assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
 
890
 
 
891
  ac_io->mode = mode;
 
892
  ac_io->type = type;
 
893
 
 
894
  switch (mode)
 
895
    {
 
896
    case GCRY_AC_IO_READABLE:
 
897
      switch (type)
 
898
        {
 
899
        case GCRY_AC_IO_STRING:
 
900
          ac_io->io.readable.string.data = va_arg (ap, unsigned char *);
 
901
          ac_io->io.readable.string.data_n = va_arg (ap, size_t);
 
902
          break;
 
903
 
 
904
        case GCRY_AC_IO_CALLBACK:
 
905
          ac_io->io.readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t);
 
906
          ac_io->io.readable.callback.opaque = va_arg (ap, void *);
 
907
          break;
 
908
        }
 
909
      break;
 
910
    case GCRY_AC_IO_WRITABLE:
 
911
      switch (type)
 
912
        {
 
913
        case GCRY_AC_IO_STRING:
 
914
          ac_io->io.writable.string.data = va_arg (ap, unsigned char **);
 
915
          ac_io->io.writable.string.data_n = va_arg (ap, size_t *);
 
916
          break;
 
917
 
 
918
        case GCRY_AC_IO_CALLBACK:
 
919
          ac_io->io.writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t);
 
920
          ac_io->io.writable.callback.opaque = va_arg (ap, void *);
 
921
          break;
 
922
        }
 
923
      break;
 
924
    }
 
925
}
 
926
 
 
927
/* Initialize AC_IO according to MODE, TYPE and the variable list of
 
928
   arguments.  The list of variable arguments to specify depends on
 
929
   the given TYPE. */
 
930
void
 
931
_gcry_ac_io_init (gcry_ac_io_t *ac_io,
 
932
                  gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
 
933
{
 
934
  va_list ap;
 
935
 
 
936
  va_start (ap, type);
 
937
  _gcry_ac_io_init_va (ac_io, mode, type, ap);
 
938
  va_end (ap);
 
939
}
 
940
 
 
941
 
 
942
/* Write to the IO object AC_IO BUFFER_N bytes from BUFFER.  Return
 
943
   zero on success or error code.  */
 
944
static gcry_error_t
 
945
_gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
 
946
{
 
947
  gcry_error_t err;
 
948
 
 
949
  gcry_assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
 
950
  err = 0;
 
951
 
 
952
  switch (ac_io->type)
 
953
    {
 
954
    case GCRY_AC_IO_STRING:
 
955
      {
 
956
        unsigned char *p;
 
957
 
 
958
        if (*ac_io->io.writable.string.data)
 
959
          {
 
960
            p = gcry_realloc (*ac_io->io.writable.string.data,
 
961
                              *ac_io->io.writable.string.data_n + buffer_n);
 
962
            if (! p)
 
963
              err = gcry_error_from_errno (errno);
 
964
            else
 
965
              {
 
966
                if (*ac_io->io.writable.string.data != p)
 
967
                  *ac_io->io.writable.string.data = p;
 
968
                memcpy (p + *ac_io->io.writable.string.data_n, buffer, buffer_n);
 
969
                *ac_io->io.writable.string.data_n += buffer_n;
 
970
              }
 
971
          }
 
972
        else
 
973
          {
 
974
            if (gcry_is_secure (buffer))
 
975
              p = gcry_malloc_secure (buffer_n);
 
976
            else
 
977
              p = gcry_malloc (buffer_n);
 
978
            if (! p)
 
979
              err = gcry_error_from_errno (errno);
 
980
            else
 
981
              {
 
982
                memcpy (p, buffer, buffer_n);
 
983
                *ac_io->io.writable.string.data = p;
 
984
                *ac_io->io.writable.string.data_n = buffer_n;
 
985
              }
 
986
          }
 
987
      }
 
988
      break;
 
989
 
 
990
    case GCRY_AC_IO_CALLBACK:
 
991
      err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque,
 
992
                                               buffer, buffer_n);
 
993
      break;
 
994
    }
 
995
 
 
996
  return err;
 
997
}
 
998
 
 
999
/* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD
 
1000
   bytes have already been read from the object; on success, store the
 
1001
   amount of bytes read in *BUFFER_N; zero bytes read means EOF.
 
1002
   Return zero on success or error code.  */
 
1003
static gcry_error_t
 
1004
_gcry_ac_io_read (gcry_ac_io_t *ac_io,
 
1005
                  unsigned int nread, unsigned char *buffer, size_t *buffer_n)
 
1006
{
 
1007
  gcry_error_t err;
 
1008
  
 
1009
  gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE);
 
1010
  err = 0;
 
1011
 
 
1012
  switch (ac_io->type)
 
1013
    {
 
1014
    case GCRY_AC_IO_STRING:
 
1015
      {
 
1016
        size_t bytes_available;
 
1017
        size_t bytes_to_read;
 
1018
        size_t bytes_wanted;
 
1019
 
 
1020
        bytes_available = ac_io->io.readable.string.data_n - nread;
 
1021
        bytes_wanted = *buffer_n;
 
1022
 
 
1023
        if (bytes_wanted > bytes_available)
 
1024
          bytes_to_read = bytes_available;
 
1025
        else
 
1026
          bytes_to_read = bytes_wanted;
 
1027
 
 
1028
        memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read);
 
1029
        *buffer_n = bytes_to_read;
 
1030
        err = 0;
 
1031
        break;
 
1032
      }
 
1033
 
 
1034
    case GCRY_AC_IO_CALLBACK:
 
1035
      err = (*ac_io->io.readable.callback.cb)
 
1036
        (ac_io->io.readable.callback.opaque, buffer, buffer_n);
 
1037
      break;
 
1038
    }
 
1039
 
 
1040
  return err;
 
1041
}
 
1042
 
 
1043
/* Read all data available from the IO object AC_IO into newly
 
1044
   allocated memory, storing an appropriate pointer in *BUFFER and the
 
1045
   amount of bytes read in *BUFFER_N.  Return zero on success or error
 
1046
   code.  */
 
1047
static gcry_error_t
 
1048
_gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
 
1049
{
 
1050
  unsigned char *buffer_new;
 
1051
  size_t buffer_new_n;
 
1052
  unsigned char buf[BUFSIZ];
 
1053
  size_t buf_n;
 
1054
  unsigned char *p;
 
1055
  gcry_error_t err;
 
1056
 
 
1057
  buffer_new = NULL;
 
1058
  buffer_new_n = 0;
 
1059
 
 
1060
  while (1)
 
1061
    {
 
1062
      buf_n = sizeof (buf);
 
1063
      err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
 
1064
      if (err)
 
1065
        break;
 
1066
 
 
1067
      if (buf_n)
 
1068
        {
 
1069
          p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
 
1070
          if (! p)
 
1071
            {
 
1072
              err = gcry_error_from_errno (errno);
 
1073
              break;
 
1074
            }
 
1075
          
 
1076
          if (buffer_new != p)
 
1077
            buffer_new = p;
 
1078
 
 
1079
          memcpy (buffer_new + buffer_new_n, buf, buf_n);
 
1080
          buffer_new_n += buf_n;
 
1081
        }
 
1082
      else
 
1083
        break;
 
1084
    }
 
1085
  if (err)
 
1086
    goto out;
 
1087
 
 
1088
  *buffer_n = buffer_new_n;
 
1089
  *buffer = buffer_new;
 
1090
 
 
1091
 out:
 
1092
 
 
1093
  if (err)
 
1094
    gcry_free (buffer_new);
 
1095
 
 
1096
  return err;
 
1097
}
 
1098
 
 
1099
/* Read data chunks from the IO object AC_IO until EOF, feeding them
 
1100
   to the callback function CB.  Return zero on success or error
 
1101
   code.  */
 
1102
static gcry_error_t
 
1103
_gcry_ac_io_process (gcry_ac_io_t *ac_io,
 
1104
                     gcry_ac_data_write_cb_t cb, void *opaque)
 
1105
{
 
1106
  unsigned char buffer[BUFSIZ];
 
1107
  unsigned int nread;
 
1108
  size_t buffer_n;
 
1109
  gcry_error_t err;
 
1110
 
 
1111
  nread = 0;
 
1112
 
 
1113
  while (1)
 
1114
    {
 
1115
      buffer_n = sizeof (buffer);
 
1116
      err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
 
1117
      if (err)
 
1118
        break;
 
1119
      if (buffer_n)
 
1120
        {
 
1121
          err = (*cb) (opaque, buffer, buffer_n);
 
1122
          if (err)
 
1123
            break;
 
1124
          nread += buffer_n;
 
1125
        }
 
1126
      else
 
1127
        break;
 
1128
    }
 
1129
 
 
1130
  return err;
 
1131
}
 
1132
 
 
1133
 
 
1134
 
 
1135
/* 
 
1136
 * Functions for converting data between the native ac and the
 
1137
 * S-expression structure used by the pk interface.
 
1138
 */
 
1139
 
 
1140
/* Extract the S-Expression DATA_SEXP into DATA under the control of
 
1141
   TYPE and NAME.  This function assumes that S-Expressions are of the
 
1142
   following structure:
 
1143
 
 
1144
   (IDENTIFIER [...]
 
1145
   (ALGORITHM <list of named MPI values>)) */
 
1146
static gcry_error_t
 
1147
ac_data_extract (const char *identifier, const char *algorithm,
 
1148
                 gcry_sexp_t sexp, gcry_ac_data_t *data)
 
1149
{
 
1150
  gcry_error_t err;
 
1151
  gcry_sexp_t value_sexp;
 
1152
  gcry_sexp_t data_sexp;
 
1153
  size_t data_sexp_n;
 
1154
  gcry_mpi_t value_mpi;
 
1155
  char *value_name;
 
1156
  const char *data_raw;
 
1157
  size_t data_raw_n;
 
1158
  gcry_ac_data_t data_new;
 
1159
  unsigned int i;
 
1160
 
 
1161
  value_sexp = NULL;
 
1162
  data_sexp = NULL;
 
1163
  value_name = NULL;
 
1164
  value_mpi = NULL;
 
1165
  data_new = NULL;
 
1166
 
 
1167
  /* Verify that the S-expression contains the correct identifier.  */
 
1168
  data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n);
 
1169
  if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n))
 
1170
    {
 
1171
      err = gcry_error (GPG_ERR_INV_SEXP);
 
1172
      goto out;
 
1173
    }
 
1174
 
 
1175
  /* Extract inner S-expression.  */
 
1176
  data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
 
1177
  if (! data_sexp)
 
1178
    {
 
1179
      err = gcry_error (GPG_ERR_INV_SEXP);
 
1180
      goto out;
 
1181
    }
 
1182
 
 
1183
  /* Count data elements.  */
 
1184
  data_sexp_n = gcry_sexp_length (data_sexp);
 
1185
  data_sexp_n--;
 
1186
 
 
1187
  /* Allocate new data set.  */
 
1188
  err = _gcry_ac_data_new (&data_new);
 
1189
  if (err)
 
1190
    goto out;
 
1191
 
 
1192
  /* Iterate through list of data elements and add them to the data
 
1193
     set.  */
 
1194
  for (i = 0; i < data_sexp_n; i++)
 
1195
    {
 
1196
      /* Get the S-expression of the named MPI, that contains the name
 
1197
         and the MPI value.  */
 
1198
      value_sexp = gcry_sexp_nth (data_sexp, i + 1);
 
1199
      if (! value_sexp)
 
1200
        {
 
1201
          err = gcry_error (GPG_ERR_INV_SEXP);
 
1202
          break;
 
1203
        }
 
1204
 
 
1205
      /* Extract the name.  */
 
1206
      data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
 
1207
      if (! data_raw)
 
1208
        {
 
1209
          err = gcry_error (GPG_ERR_INV_SEXP);
 
1210
          break;
 
1211
        }
 
1212
 
 
1213
      /* Extract the MPI value.  */
 
1214
      value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
 
1215
      if (! value_mpi)
 
1216
        {
 
1217
          err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
 
1218
          break;
 
1219
        }
 
1220
 
 
1221
      /* Duplicate the name.  */
 
1222
      value_name = gcry_malloc (data_raw_n + 1);
 
1223
      if (! value_name)
 
1224
        {
 
1225
          err = gcry_error_from_errno (errno);
 
1226
          break;
 
1227
        }
 
1228
      strncpy (value_name, data_raw, data_raw_n);
 
1229
      value_name[data_raw_n] = 0;
 
1230
 
 
1231
      err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
 
1232
      if (err)
 
1233
        break;
 
1234
 
 
1235
      gcry_sexp_release (value_sexp);
 
1236
      value_sexp = NULL;
 
1237
      value_name = NULL;
 
1238
      value_mpi = NULL;
 
1239
    }
 
1240
  if (err)
 
1241
    goto out;
 
1242
 
 
1243
  /* Copy out.  */
 
1244
  *data = data_new;
 
1245
 
 
1246
 out:
 
1247
 
 
1248
  /* Deallocate resources.  */
 
1249
  if (err)
 
1250
    {
 
1251
      _gcry_ac_data_destroy (data_new);
 
1252
      gcry_mpi_release (value_mpi);
 
1253
      gcry_free (value_name);
 
1254
      gcry_sexp_release (value_sexp);
 
1255
    }
 
1256
  gcry_sexp_release (data_sexp);
 
1257
 
 
1258
  return err;
 
1259
}
 
1260
 
 
1261
/* Construct an S-expression from the DATA and store it in
 
1262
   DATA_SEXP. The S-expression will be of the following structure:
 
1263
 
 
1264
   (IDENTIFIER [(flags [...])]
 
1265
   (ALGORITHM <list of named MPI values>))  */
 
1266
static gcry_error_t
 
1267
ac_data_construct (const char *identifier, int include_flags,
 
1268
                   unsigned int flags, const char *algorithm,
 
1269
                   gcry_ac_data_t data, gcry_sexp_t *sexp)
 
1270
{
 
1271
  unsigned int data_length;
 
1272
  gcry_sexp_t sexp_new;
 
1273
  gcry_error_t err;
 
1274
  size_t sexp_format_n;
 
1275
  char *sexp_format;
 
1276
  void **arg_list;
 
1277
  unsigned int i;
 
1278
 
 
1279
  arg_list = NULL;
 
1280
  sexp_new = NULL;
 
1281
  sexp_format = NULL;
 
1282
 
 
1283
  /* We build a list of arguments to pass to
 
1284
     gcry_sexp_build_array().  */
 
1285
  data_length = _gcry_ac_data_length (data);
 
1286
  arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
 
1287
  if (! arg_list)
 
1288
    {
 
1289
      err = gcry_error_from_errno (errno);
 
1290
      goto out;
 
1291
    }
 
1292
 
 
1293
  /* Fill list with MPIs.  */
 
1294
  for (i = 0; i < data_length; i++)
 
1295
    {
 
1296
      char **nameaddr  = &data->data[i].name;
 
1297
 
 
1298
      arg_list[(i * 2) + 0] = nameaddr;
 
1299
      arg_list[(i * 2) + 1] = &data->data[i].mpi;
 
1300
    }
 
1301
 
 
1302
  /* Calculate size of format string.  */
 
1303
  sexp_format_n = (3
 
1304
                   + (include_flags ? 7 : 0)
 
1305
                   + (algorithm ? (2 + strlen (algorithm)) : 0)
 
1306
                   + strlen (identifier));
 
1307
 
 
1308
  for (i = 0; i < data_length; i++)
 
1309
    /* Per-element sizes.  */
 
1310
    sexp_format_n += 6;
 
1311
 
 
1312
  if (include_flags)
 
1313
    /* Add flags.  */
 
1314
    for (i = 0; i < DIM (ac_flags); i++)
 
1315
      if (flags & ac_flags[i].number)
 
1316
        sexp_format_n += strlen (ac_flags[i].string) + 1;
 
1317
 
 
1318
  /* Done.  */
 
1319
  sexp_format = gcry_malloc (sexp_format_n);
 
1320
  if (! sexp_format)
 
1321
    {
 
1322
      err = gcry_error_from_errno (errno);
 
1323
      goto out;
 
1324
    }
 
1325
 
 
1326
  /* Construct the format string.  */
 
1327
 
 
1328
  *sexp_format = 0;
 
1329
  strcat (sexp_format, "(");
 
1330
  strcat (sexp_format, identifier);
 
1331
  if (include_flags)
 
1332
    {
 
1333
      strcat (sexp_format, "(flags");
 
1334
      for (i = 0; i < DIM (ac_flags); i++)
 
1335
        if (flags & ac_flags[i].number)
 
1336
          {
 
1337
            strcat (sexp_format, " ");
 
1338
            strcat (sexp_format, ac_flags[i].string);
 
1339
          }
 
1340
      strcat (sexp_format, ")");
 
1341
    }
 
1342
  if (algorithm)
 
1343
    {
 
1344
      strcat (sexp_format, "(");
 
1345
      strcat (sexp_format, algorithm);
 
1346
    }
 
1347
  for (i = 0; i < data_length; i++)
 
1348
    strcat (sexp_format, "(%s%m)");
 
1349
  if (algorithm)
 
1350
    strcat (sexp_format, ")");
 
1351
  strcat (sexp_format, ")");
 
1352
 
 
1353
  /* Create final S-expression.  */
 
1354
  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
 
1355
  if (err)
 
1356
    goto out;
 
1357
 
 
1358
  *sexp = sexp_new;
 
1359
 
 
1360
 out:
 
1361
 
 
1362
  /* Deallocate resources.  */
 
1363
  gcry_free (sexp_format);
 
1364
  gcry_free (arg_list);
 
1365
  if (err)
 
1366
    gcry_sexp_release (sexp_new);
 
1367
 
 
1368
  return err;
 
1369
}
 
1370
 
 
1371
 
 
1372
 
 
1373
/*
 
1374
 * Handle management.
 
1375
 */
 
1376
 
 
1377
/* Creates a new handle for the algorithm ALGORITHM and stores it in
 
1378
   HANDLE.  FLAGS is not used yet.  */
 
1379
gcry_error_t
 
1380
_gcry_ac_open (gcry_ac_handle_t *handle,
 
1381
               gcry_ac_id_t algorithm, unsigned int flags)
 
1382
{
 
1383
  gcry_ac_handle_t handle_new;
 
1384
  const char *algorithm_name;
 
1385
  gcry_module_t module;
 
1386
  gcry_error_t err;
 
1387
 
 
1388
  *handle = NULL;
 
1389
  module = NULL;
 
1390
 
 
1391
  if (fips_mode ())
 
1392
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1393
 
 
1394
  /* Get name.  */
 
1395
  algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
 
1396
  if (! algorithm_name)
 
1397
    {
 
1398
      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
 
1399
      goto out;
 
1400
    }
 
1401
 
 
1402
  /* Acquire reference to the pubkey module.  */
 
1403
  err = _gcry_pk_module_lookup (algorithm, &module);
 
1404
  if (err)
 
1405
    goto out;
 
1406
  
 
1407
  /* Allocate.  */
 
1408
  handle_new = gcry_malloc (sizeof (*handle_new));
 
1409
  if (! handle_new)
 
1410
    {
 
1411
      err = gcry_error_from_errno (errno);
 
1412
      goto out;
 
1413
    }
 
1414
 
 
1415
  /* Done.  */
 
1416
  handle_new->algorithm = algorithm;
 
1417
  handle_new->algorithm_name = algorithm_name;
 
1418
  handle_new->flags = flags;
 
1419
  handle_new->module = module;
 
1420
  *handle = handle_new;
 
1421
 
 
1422
 out:
 
1423
  
 
1424
  /* Deallocate resources.  */
 
1425
  if (err)
 
1426
    _gcry_pk_module_release (module);
 
1427
 
 
1428
  return err;
 
1429
}
 
1430
 
 
1431
 
 
1432
/* Destroys the handle HANDLE.  */
 
1433
void
 
1434
_gcry_ac_close (gcry_ac_handle_t handle)
 
1435
{
 
1436
  /* Release reference to pubkey module.  */
 
1437
  if (handle)
 
1438
    {
 
1439
      _gcry_pk_module_release (handle->module);
 
1440
      gcry_free (handle);
 
1441
    }
 
1442
}
 
1443
 
 
1444
 
 
1445
 
 
1446
/* 
 
1447
 * Key management.
 
1448
 */
 
1449
 
 
1450
/* Initialize a key from a given data set.  */
 
1451
/* FIXME/Damn: the argument HANDLE is not only unnecessary, it is
 
1452
   completely WRONG here.  */
 
1453
gcry_error_t
 
1454
_gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
 
1455
                   gcry_ac_key_type_t type, gcry_ac_data_t data)
 
1456
{
 
1457
  gcry_ac_data_t data_new;
 
1458
  gcry_ac_key_t key_new;
 
1459
  gcry_error_t err;
 
1460
 
 
1461
  (void)handle;
 
1462
 
 
1463
  if (fips_mode ())
 
1464
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1465
 
 
1466
  /* Allocate.  */
 
1467
  key_new = gcry_malloc (sizeof (*key_new));
 
1468
  if (! key_new)
 
1469
    {
 
1470
      err = gcry_error_from_errno (errno);
 
1471
      goto out;
 
1472
    }
 
1473
 
 
1474
  /* Copy data set.  */
 
1475
  err = _gcry_ac_data_copy (&data_new, data);
 
1476
  if (err)
 
1477
    goto out;
 
1478
 
 
1479
  /* Done.  */
 
1480
  key_new->data = data_new;
 
1481
  key_new->type = type;
 
1482
  *key = key_new;
 
1483
 
 
1484
 out:
 
1485
 
 
1486
  if (err)
 
1487
    /* Deallocate resources.  */
 
1488
    gcry_free (key_new);
 
1489
 
 
1490
  return err;
 
1491
}
 
1492
 
 
1493
 
 
1494
/* Generates a new key pair via the handle HANDLE of NBITS bits and
 
1495
   stores it in KEY_PAIR.  In case non-standard settings are wanted, a
 
1496
   pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
 
1497
   matching the selected algorithm, can be given as KEY_SPEC.
 
1498
   MISC_DATA is not used yet.  */
 
1499
gcry_error_t
 
1500
_gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
 
1501
                            void *key_spec,
 
1502
                            gcry_ac_key_pair_t *key_pair,
 
1503
                            gcry_mpi_t **misc_data)
 
1504
{
 
1505
  gcry_sexp_t genkey_sexp_request;
 
1506
  gcry_sexp_t genkey_sexp_reply;
 
1507
  gcry_ac_data_t key_data_secret;
 
1508
  gcry_ac_data_t key_data_public;
 
1509
  gcry_ac_key_pair_t key_pair_new;
 
1510
  gcry_ac_key_t key_secret;
 
1511
  gcry_ac_key_t key_public;
 
1512
  gcry_sexp_t key_sexp;
 
1513
  gcry_error_t err;
 
1514
  char *genkey_format;
 
1515
  size_t genkey_format_n;
 
1516
  void **arg_list;
 
1517
  size_t arg_list_n;
 
1518
  unsigned int i;
 
1519
  unsigned int j;
 
1520
 
 
1521
  (void)misc_data;
 
1522
 
 
1523
  if (fips_mode ())
 
1524
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1525
 
 
1526
  key_data_secret = NULL;
 
1527
  key_data_public = NULL;
 
1528
  key_secret = NULL;
 
1529
  key_public = NULL;
 
1530
  genkey_format = NULL;
 
1531
  arg_list = NULL;
 
1532
  genkey_sexp_request = NULL;
 
1533
  genkey_sexp_reply = NULL;
 
1534
  key_sexp = NULL;
 
1535
 
 
1536
  /* Allocate key pair.  */
 
1537
  key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
 
1538
  if (! key_pair_new)
 
1539
    {
 
1540
      err = gcry_error_from_errno (errno);
 
1541
      goto out;
 
1542
    }
 
1543
 
 
1544
  /* Allocate keys.  */
 
1545
  key_secret = gcry_malloc (sizeof (*key_secret));
 
1546
  if (! key_secret)
 
1547
    {
 
1548
      err = gcry_error_from_errno (errno);
 
1549
      goto out;
 
1550
    }
 
1551
  key_public = gcry_malloc (sizeof (*key_public));
 
1552
  if (! key_public)
 
1553
    {
 
1554
      err = gcry_error_from_errno (errno);
 
1555
      goto out;
 
1556
    }
 
1557
 
 
1558
  /* Calculate size of the format string, that is used for creating
 
1559
     the request S-expression.  */
 
1560
  genkey_format_n = 22;
 
1561
 
 
1562
  /* Respect any relevant algorithm specific commands.  */
 
1563
  if (key_spec)
 
1564
    for (i = 0; i < DIM (ac_key_generate_specs); i++)
 
1565
      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
 
1566
        genkey_format_n += 6;
 
1567
 
 
1568
  /* Create format string.  */
 
1569
  genkey_format = gcry_malloc (genkey_format_n);
 
1570
  if (! genkey_format)
 
1571
    {
 
1572
      err = gcry_error_from_errno (errno);
 
1573
      goto out;
 
1574
    }
 
1575
 
 
1576
  /* Fill format string.  */
 
1577
  *genkey_format = 0;
 
1578
  strcat (genkey_format, "(genkey(%s(nbits%d)");
 
1579
  if (key_spec)
 
1580
    for (i = 0; i < DIM (ac_key_generate_specs); i++)
 
1581
      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
 
1582
        strcat (genkey_format, "(%s%m)");
 
1583
  strcat (genkey_format, "))");
 
1584
 
 
1585
  /* Build list of argument pointers, the algorithm name and the nbits
 
1586
     are always needed.  */
 
1587
  arg_list_n = 2;
 
1588
 
 
1589
  /* Now the algorithm specific arguments.  */
 
1590
  if (key_spec)
 
1591
    for (i = 0; i < DIM (ac_key_generate_specs); i++)
 
1592
      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
 
1593
        arg_list_n += 2;
 
1594
 
 
1595
  /* Allocate list.  */
 
1596
  arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
 
1597
  if (! arg_list)
 
1598
    {
 
1599
      err = gcry_error_from_errno (errno);
 
1600
      goto out;
 
1601
    }
 
1602
 
 
1603
  arg_list[0] = (void *) &handle->algorithm_name;
 
1604
  arg_list[1] = (void *) &nbits;
 
1605
  if (key_spec)
 
1606
    for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
 
1607
      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
 
1608
        {
 
1609
          /* Add name of this specification flag and the
 
1610
             according member of the spec strucuture.  */
 
1611
          arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
 
1612
          arg_list[j++] = (void *)
 
1613
            (((char *) key_spec)
 
1614
             + ac_key_generate_specs[i].offset);
 
1615
          /* FIXME: above seems to suck.  */
 
1616
        }
 
1617
 
 
1618
  /* Construct final request S-expression.  */
 
1619
  err = gcry_sexp_build_array (&genkey_sexp_request,
 
1620
                               NULL, genkey_format, arg_list);
 
1621
  if (err)
 
1622
    goto out;
 
1623
 
 
1624
  /* Perform genkey operation.  */
 
1625
  err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
 
1626
  if (err)
 
1627
    goto out;
 
1628
 
 
1629
  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
 
1630
  if (! key_sexp)
 
1631
    {
 
1632
      err = gcry_error (GPG_ERR_INTERNAL);
 
1633
      goto out;
 
1634
    }
 
1635
  err = ac_data_extract ("private-key", handle->algorithm_name,
 
1636
                         key_sexp, &key_data_secret);
 
1637
  if (err)
 
1638
    goto out;
 
1639
 
 
1640
  gcry_sexp_release (key_sexp);
 
1641
  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
 
1642
  if (! key_sexp)
 
1643
    {
 
1644
      err = gcry_error (GPG_ERR_INTERNAL);
 
1645
      goto out;
 
1646
    }
 
1647
  err = ac_data_extract ("public-key", handle->algorithm_name,
 
1648
                         key_sexp, &key_data_public);
 
1649
  if (err)
 
1650
    goto out;
 
1651
 
 
1652
  /* Done.  */
 
1653
 
 
1654
  key_secret->type = GCRY_AC_KEY_SECRET;
 
1655
  key_secret->data = key_data_secret;
 
1656
  key_public->type = GCRY_AC_KEY_PUBLIC;
 
1657
  key_public->data = key_data_public;
 
1658
  key_pair_new->secret = key_secret;
 
1659
  key_pair_new->public = key_public;
 
1660
  *key_pair = key_pair_new;
 
1661
 
 
1662
 out:
 
1663
 
 
1664
  /* Deallocate resources.  */
 
1665
  
 
1666
  gcry_free (genkey_format);
 
1667
  gcry_free (arg_list);
 
1668
  gcry_sexp_release (genkey_sexp_request);
 
1669
  gcry_sexp_release (genkey_sexp_reply);
 
1670
  gcry_sexp_release (key_sexp);
 
1671
  if (err)
 
1672
    {
 
1673
      _gcry_ac_data_destroy (key_data_secret);
 
1674
      _gcry_ac_data_destroy (key_data_public);
 
1675
      gcry_free (key_secret);
 
1676
      gcry_free (key_public);
 
1677
      gcry_free (key_pair_new);
 
1678
    }
 
1679
 
 
1680
  return err;
 
1681
}
 
1682
 
 
1683
/* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
 
1684
gcry_ac_key_t
 
1685
_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, 
 
1686
                           gcry_ac_key_type_t which)
 
1687
{
 
1688
  gcry_ac_key_t key;
 
1689
 
 
1690
  if (fips_mode ())
 
1691
    return NULL;
 
1692
 
 
1693
  switch (which)
 
1694
    {
 
1695
    case GCRY_AC_KEY_SECRET:
 
1696
      key = key_pair->secret;
 
1697
      break;
 
1698
 
 
1699
    case GCRY_AC_KEY_PUBLIC:
 
1700
      key = key_pair->public;
 
1701
      break;
 
1702
 
 
1703
    default:
 
1704
      key = NULL;
 
1705
      break;
 
1706
    }
 
1707
 
 
1708
  return key;
 
1709
}
 
1710
 
 
1711
/* Destroys the key KEY.  */
 
1712
void
 
1713
_gcry_ac_key_destroy (gcry_ac_key_t key)
 
1714
{
 
1715
  unsigned int i;
 
1716
 
 
1717
  if (key)
 
1718
    {
 
1719
      if (key->data)
 
1720
        {
 
1721
          for (i = 0; i < key->data->data_n; i++)
 
1722
            {
 
1723
              if (key->data->data[i].mpi)
 
1724
                gcry_mpi_release (key->data->data[i].mpi);
 
1725
              if (key->data->data[i].name)
 
1726
                gcry_free (key->data->data[i].name);
 
1727
            }
 
1728
          gcry_free (key->data->data);
 
1729
          gcry_free (key->data);
 
1730
        }
 
1731
      gcry_free (key);
 
1732
    }
 
1733
}
 
1734
 
 
1735
/* Destroys the key pair KEY_PAIR.  */
 
1736
void
 
1737
_gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
 
1738
{
 
1739
  if (key_pair)
 
1740
    {
 
1741
      gcry_ac_key_destroy (key_pair->secret);
 
1742
      gcry_ac_key_destroy (key_pair->public);
 
1743
      gcry_free (key_pair);
 
1744
    }
 
1745
}
 
1746
 
 
1747
/* Returns the data set contained in the key KEY.  */
 
1748
gcry_ac_data_t
 
1749
_gcry_ac_key_data_get (gcry_ac_key_t key)
 
1750
{
 
1751
  if (fips_mode ())
 
1752
    return NULL;
 
1753
  return key->data;
 
1754
}
 
1755
 
 
1756
/* Verifies that the key KEY is sane via HANDLE.  */
 
1757
gcry_error_t
 
1758
_gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
 
1759
{
 
1760
  gcry_sexp_t key_sexp;
 
1761
  gcry_error_t err;
 
1762
 
 
1763
  if (fips_mode ())
 
1764
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1765
 
 
1766
  key_sexp = NULL;
 
1767
  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
 
1768
                           handle->algorithm_name, key->data, &key_sexp);
 
1769
  if (err)
 
1770
    goto out;
 
1771
 
 
1772
  err = gcry_pk_testkey (key_sexp);
 
1773
 
 
1774
 out:
 
1775
 
 
1776
  gcry_sexp_release (key_sexp);
 
1777
 
 
1778
  return gcry_error (err);
 
1779
}
 
1780
 
 
1781
/* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
 
1782
gcry_error_t
 
1783
_gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
 
1784
                        gcry_ac_key_t key, unsigned int *nbits)
 
1785
{
 
1786
  gcry_sexp_t key_sexp;
 
1787
  gcry_error_t err;
 
1788
  unsigned int n;
 
1789
 
 
1790
  if (fips_mode ())
 
1791
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1792
 
 
1793
  key_sexp = NULL;
 
1794
 
 
1795
  err = ac_data_construct (ac_key_identifiers[key->type],
 
1796
                           0, 0, handle->algorithm_name, key->data, &key_sexp);
 
1797
  if (err)
 
1798
    goto out;
 
1799
 
 
1800
  n = gcry_pk_get_nbits (key_sexp);
 
1801
  if (! n)
 
1802
    {
 
1803
      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
 
1804
      goto out;
 
1805
    }
 
1806
 
 
1807
  *nbits = n;
 
1808
 
 
1809
 out:
 
1810
 
 
1811
  gcry_sexp_release (key_sexp);
 
1812
 
 
1813
  return err;
 
1814
}
 
1815
 
 
1816
/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
 
1817
   HANDLE.  */
 
1818
gcry_error_t
 
1819
_gcry_ac_key_get_grip (gcry_ac_handle_t handle,
 
1820
                       gcry_ac_key_t key, unsigned char *key_grip)
 
1821
{
 
1822
  gcry_sexp_t key_sexp;
 
1823
  gcry_error_t err;
 
1824
  unsigned char *ret;
 
1825
 
 
1826
  if (fips_mode ())
 
1827
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1828
 
 
1829
  key_sexp = NULL;
 
1830
  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
 
1831
                           handle->algorithm_name, key->data, &key_sexp);
 
1832
  if (err)
 
1833
    goto out;
 
1834
 
 
1835
  ret = gcry_pk_get_keygrip (key_sexp, key_grip);
 
1836
  if (! ret)
 
1837
    {
 
1838
      err = gcry_error (GPG_ERR_INV_OBJ);
 
1839
      goto out;
 
1840
    }
 
1841
 
 
1842
  err = 0;
 
1843
 
 
1844
 out:
 
1845
 
 
1846
  gcry_sexp_release (key_sexp);
 
1847
 
 
1848
  return err;
 
1849
}
 
1850
 
 
1851
 
 
1852
 
 
1853
 
 
1854
/* 
 
1855
 * Functions performing cryptographic operations.
 
1856
 */
 
1857
 
 
1858
/* Encrypts the plain text MPI value DATA_PLAIN with the key public
 
1859
   KEY under the control of the flags FLAGS and stores the resulting
 
1860
   data set into DATA_ENCRYPTED.  */
 
1861
gcry_error_t
 
1862
_gcry_ac_data_encrypt (gcry_ac_handle_t handle,
 
1863
                       unsigned int flags,
 
1864
                       gcry_ac_key_t key,
 
1865
                       gcry_mpi_t data_plain,
 
1866
                       gcry_ac_data_t *data_encrypted)
 
1867
{
 
1868
  gcry_ac_data_t data_encrypted_new;
 
1869
  gcry_ac_data_t data_value;
 
1870
  gcry_sexp_t sexp_request;
 
1871
  gcry_sexp_t sexp_reply;
 
1872
  gcry_sexp_t sexp_key;
 
1873
  gcry_error_t err;
 
1874
 
 
1875
  if (fips_mode ())
 
1876
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1877
 
 
1878
  data_encrypted_new = NULL;
 
1879
  sexp_request = NULL;
 
1880
  sexp_reply = NULL;
 
1881
  data_value = NULL;
 
1882
  sexp_key = NULL;
 
1883
 
 
1884
  if (key->type != GCRY_AC_KEY_PUBLIC)
 
1885
    {
 
1886
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
1887
      goto out;
 
1888
    }
 
1889
 
 
1890
  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
 
1891
                           handle->algorithm_name, key->data, &sexp_key);
 
1892
  if (err)
 
1893
    goto out;
 
1894
 
 
1895
  err = _gcry_ac_data_new (&data_value);
 
1896
  if (err)
 
1897
    goto out;
 
1898
 
 
1899
  err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
 
1900
  if (err)
 
1901
    goto out;
 
1902
 
 
1903
  err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
 
1904
                           data_value, &sexp_request);
 
1905
  if (err)
 
1906
    goto out;
 
1907
 
 
1908
  /* FIXME: error vs. errcode? */
 
1909
 
 
1910
  err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
 
1911
  if (err)
 
1912
    goto out;
 
1913
 
 
1914
  /* Extract data.  */
 
1915
  err = ac_data_extract ("enc-val", handle->algorithm_name,
 
1916
                         sexp_reply, &data_encrypted_new);
 
1917
  if (err)
 
1918
    goto out;
 
1919
 
 
1920
  *data_encrypted = data_encrypted_new;
 
1921
 
 
1922
 out:
 
1923
 
 
1924
  /* Deallocate resources.  */
 
1925
 
 
1926
  gcry_sexp_release (sexp_request);
 
1927
  gcry_sexp_release (sexp_reply);
 
1928
  gcry_sexp_release (sexp_key);
 
1929
  _gcry_ac_data_destroy (data_value);
 
1930
 
 
1931
  return err;
 
1932
}
 
1933
 
 
1934
/* Decrypts the encrypted data contained in the data set
 
1935
   DATA_ENCRYPTED with the secret key KEY under the control of the
 
1936
   flags FLAGS and stores the resulting plain text MPI value in
 
1937
   DATA_PLAIN.  */
 
1938
gcry_error_t
 
1939
_gcry_ac_data_decrypt (gcry_ac_handle_t handle,
 
1940
                       unsigned int flags,
 
1941
                       gcry_ac_key_t key,
 
1942
                       gcry_mpi_t *data_plain,
 
1943
                       gcry_ac_data_t data_encrypted)
 
1944
{
 
1945
  gcry_mpi_t data_decrypted;
 
1946
  gcry_sexp_t sexp_request;
 
1947
  gcry_sexp_t sexp_reply;
 
1948
  gcry_sexp_t sexp_value;
 
1949
  gcry_sexp_t sexp_key;
 
1950
  gcry_error_t err;
 
1951
 
 
1952
  if (fips_mode ())
 
1953
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
1954
 
 
1955
  sexp_request = NULL;
 
1956
  sexp_reply = NULL;
 
1957
  sexp_value = NULL;
 
1958
  sexp_key = NULL;
 
1959
 
 
1960
  if (key->type != GCRY_AC_KEY_SECRET)
 
1961
    {
 
1962
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
1963
      goto out;
 
1964
    }
 
1965
 
 
1966
  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
 
1967
                           handle->algorithm_name, key->data, &sexp_key);
 
1968
  if (err)
 
1969
    goto out;
 
1970
 
 
1971
  /* Create S-expression from data.  */
 
1972
  err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
 
1973
                           data_encrypted, &sexp_request);
 
1974
  if (err)
 
1975
    goto out;
 
1976
 
 
1977
  /* Decrypt.  */
 
1978
  err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
 
1979
  if (err)
 
1980
    goto out;
 
1981
 
 
1982
  /* Extract plain text. */
 
1983
  sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
 
1984
  if (! sexp_value)
 
1985
    {
 
1986
      /* FIXME?  */
 
1987
      err = gcry_error (GPG_ERR_GENERAL);
 
1988
      goto out;
 
1989
    }
 
1990
 
 
1991
  data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
 
1992
  if (! data_decrypted)
 
1993
    {
 
1994
      err = gcry_error (GPG_ERR_GENERAL);
 
1995
      goto out;
 
1996
    }
 
1997
 
 
1998
  *data_plain = data_decrypted;
 
1999
 
 
2000
 out:
 
2001
 
 
2002
  /* Deallocate resources.  */
 
2003
  gcry_sexp_release (sexp_request);
 
2004
  gcry_sexp_release (sexp_reply);
 
2005
  gcry_sexp_release (sexp_value);
 
2006
  gcry_sexp_release (sexp_key);
 
2007
 
 
2008
  return gcry_error (err);
 
2009
 
 
2010
}
 
2011
 
 
2012
/* Signs the data contained in DATA with the secret key KEY and stores
 
2013
   the resulting signature data set in DATA_SIGNATURE.  */
 
2014
gcry_error_t
 
2015
_gcry_ac_data_sign (gcry_ac_handle_t handle,
 
2016
                    gcry_ac_key_t key,
 
2017
                    gcry_mpi_t data,
 
2018
                    gcry_ac_data_t *data_signature)
 
2019
{
 
2020
  gcry_ac_data_t data_signed;
 
2021
  gcry_ac_data_t data_value;
 
2022
  gcry_sexp_t sexp_request;
 
2023
  gcry_sexp_t sexp_reply;
 
2024
  gcry_sexp_t sexp_key;
 
2025
  gcry_error_t err;
 
2026
 
 
2027
  if (fips_mode ())
 
2028
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
2029
 
 
2030
  data_signed = NULL;
 
2031
  data_value = NULL;
 
2032
  sexp_request = NULL;
 
2033
  sexp_reply = NULL;
 
2034
  sexp_key = NULL;
 
2035
 
 
2036
  if (key->type != GCRY_AC_KEY_SECRET)
 
2037
    {
 
2038
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
2039
      goto out;
 
2040
    }
 
2041
 
 
2042
  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
 
2043
                           handle->algorithm_name, key->data, &sexp_key);
 
2044
  if (err)
 
2045
    goto out;
 
2046
 
 
2047
  err = _gcry_ac_data_new (&data_value);
 
2048
  if (err)
 
2049
    goto out;
 
2050
 
 
2051
  err = _gcry_ac_data_set (data_value, 0, "value", data);
 
2052
  if (err)
 
2053
    goto out;
 
2054
 
 
2055
  /* Create S-expression holding the data.  */
 
2056
  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
 
2057
  if (err)
 
2058
    goto out;
 
2059
 
 
2060
  /* Sign.  */
 
2061
  err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
 
2062
  if (err)
 
2063
    goto out;
 
2064
 
 
2065
  /* Extract data.  */
 
2066
  err = ac_data_extract ("sig-val", handle->algorithm_name,
 
2067
                         sexp_reply, &data_signed);
 
2068
  if (err)
 
2069
    goto out;
 
2070
 
 
2071
  /* Done.  */
 
2072
  *data_signature = data_signed;
 
2073
 
 
2074
 out:
 
2075
 
 
2076
  gcry_sexp_release (sexp_request);
 
2077
  gcry_sexp_release (sexp_reply);
 
2078
  gcry_sexp_release (sexp_key);
 
2079
  _gcry_ac_data_destroy (data_value);
 
2080
 
 
2081
  return gcry_error (err);
 
2082
}
 
2083
 
 
2084
 
 
2085
/* Verifies that the signature contained in the data set
 
2086
   DATA_SIGNATURE is indeed the result of signing the data contained
 
2087
   in DATA with the secret key belonging to the public key KEY.  */
 
2088
gcry_error_t
 
2089
_gcry_ac_data_verify (gcry_ac_handle_t handle,
 
2090
                      gcry_ac_key_t key,
 
2091
                      gcry_mpi_t data,
 
2092
                      gcry_ac_data_t data_signature)
 
2093
{
 
2094
  gcry_sexp_t sexp_signature;
 
2095
  gcry_ac_data_t data_value;
 
2096
  gcry_sexp_t sexp_data;
 
2097
  gcry_sexp_t sexp_key;
 
2098
  gcry_error_t err;
 
2099
 
 
2100
  if (fips_mode ())
 
2101
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
2102
 
 
2103
  sexp_signature = NULL;
 
2104
  data_value = NULL;
 
2105
  sexp_data = NULL;
 
2106
  sexp_key = NULL;
 
2107
 
 
2108
  err = ac_data_construct ("public-key", 0, 0,
 
2109
                           handle->algorithm_name, key->data, &sexp_key);
 
2110
  if (err)
 
2111
    goto out;
 
2112
 
 
2113
  if (key->type != GCRY_AC_KEY_PUBLIC)
 
2114
    {
 
2115
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
2116
      goto out;
 
2117
    }
 
2118
 
 
2119
  /* Construct S-expression holding the signature data.  */
 
2120
  err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
 
2121
                           data_signature, &sexp_signature);
 
2122
  if (err)
 
2123
    goto out;
 
2124
 
 
2125
  err = _gcry_ac_data_new (&data_value);
 
2126
  if (err)
 
2127
    goto out;
 
2128
 
 
2129
  err = _gcry_ac_data_set (data_value, 0, "value", data);
 
2130
  if (err)
 
2131
    goto out;
 
2132
 
 
2133
  /* Construct S-expression holding the data.  */
 
2134
  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
 
2135
  if (err)
 
2136
    goto out;
 
2137
 
 
2138
  /* Verify signature.  */
 
2139
  err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
 
2140
 
 
2141
 out:
 
2142
 
 
2143
  gcry_sexp_release (sexp_signature);
 
2144
  gcry_sexp_release (sexp_data);
 
2145
  gcry_sexp_release (sexp_key);
 
2146
  _gcry_ac_data_destroy (data_value);
 
2147
 
 
2148
  return gcry_error (err);
 
2149
}
 
2150
 
 
2151
 
 
2152
 
 
2153
 
 
2154
/*
 
2155
 * Implementation of encoding methods (em).
 
2156
 */
 
2157
 
 
2158
/* Type for functions that encode or decode (hence the name) a
 
2159
   message.  */
 
2160
typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
 
2161
                                                 void *options,
 
2162
                                                 gcry_ac_io_t *ac_io_read,
 
2163
                                                 gcry_ac_io_t *ac_io_write);
 
2164
 
 
2165
/* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
 
2166
   random bytes of random level LEVEL.  */
 
2167
static void
 
2168
em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
 
2169
                      gcry_random_level_t level)
 
2170
{
 
2171
  unsigned char *buffer_rand;
 
2172
  unsigned int buffer_rand_n;
 
2173
  unsigned int zeros;
 
2174
  unsigned int i;
 
2175
  unsigned int j;
 
2176
 
 
2177
  for (i = 0; i < buffer_n; i++)
 
2178
    buffer[i] = 0;
 
2179
  
 
2180
  do
 
2181
    {
 
2182
      /* Count zeros.  */
 
2183
      for (i = zeros = 0; i < buffer_n; i++)
 
2184
        if (! buffer[i])
 
2185
          zeros++;
 
2186
 
 
2187
      if (zeros)
 
2188
        {
 
2189
          /* Get random bytes.  */
 
2190
          buffer_rand_n = zeros + (zeros / 128);
 
2191
          buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
 
2192
 
 
2193
          /* Substitute zeros with non-zero random bytes.  */
 
2194
          for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
 
2195
            if (! buffer[i])
 
2196
              {
 
2197
                while ((j < buffer_rand_n) && (! buffer_rand[j]))
 
2198
                  j++;
 
2199
                if (j < buffer_rand_n)
 
2200
                  {
 
2201
                    buffer[i] = buffer_rand[j++];
 
2202
                    zeros--;
 
2203
                  }
 
2204
                else
 
2205
                  break;
 
2206
              }
 
2207
          gcry_free (buffer_rand);
 
2208
        }
 
2209
    }
 
2210
  while (zeros);
 
2211
}
 
2212
 
 
2213
/* Encode a message according to the Encoding Method for Encryption
 
2214
   `PKCS-V1_5' (EME-PKCS-V1_5).  */
 
2215
static gcry_error_t
 
2216
eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
 
2217
                      gcry_ac_io_t *ac_io_read,
 
2218
                      gcry_ac_io_t *ac_io_write)
 
2219
{
 
2220
  gcry_ac_eme_pkcs_v1_5_t *options;
 
2221
  gcry_error_t err;
 
2222
  unsigned char *buffer;
 
2223
  unsigned char *ps;
 
2224
  unsigned char *m;
 
2225
  size_t m_n;
 
2226
  unsigned int ps_n;
 
2227
  unsigned int k;
 
2228
 
 
2229
  (void)flags;
 
2230
 
 
2231
  options = opts;
 
2232
  buffer = NULL;
 
2233
  m = NULL;
 
2234
 
 
2235
  err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
 
2236
  if (err)
 
2237
    goto out;
 
2238
 
 
2239
  /* Figure out key length in bytes.  */
 
2240
  k = options->key_size / 8;
 
2241
 
 
2242
  if (m_n > k - 11)
 
2243
    {
 
2244
      /* Key is too short for message.  */
 
2245
      err = gcry_error (GPG_ERR_TOO_SHORT);
 
2246
      goto out;
 
2247
    }
 
2248
 
 
2249
  /* According to this encoding method, the first byte of the encoded
 
2250
     message is zero.  This byte will be lost anyway, when the encoded
 
2251
     message is to be converted into an MPI, that's why we skip
 
2252
     it.  */
 
2253
 
 
2254
  /* Allocate buffer.  */
 
2255
  buffer = gcry_malloc (k - 1);
 
2256
  if (! buffer)
 
2257
    {
 
2258
      err = gcry_error_from_errno (errno);
 
2259
      goto out;
 
2260
    }
 
2261
 
 
2262
  /* Generate an octet string PS of length k - mLen - 3 consisting
 
2263
     of pseudorandomly generated nonzero octets.  The length of PS
 
2264
     will be at least eight octets.  */
 
2265
  ps_n = k - m_n - 3;
 
2266
  ps = buffer + 1;
 
2267
  em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
 
2268
 
 
2269
  /* Concatenate PS, the message M, and other padding to form an
 
2270
     encoded message EM of length k octets as:
 
2271
 
 
2272
     EM = 0x00 || 0x02 || PS || 0x00 || M.  */
 
2273
 
 
2274
  buffer[0] = 0x02;
 
2275
  buffer[ps_n + 1] = 0x00;
 
2276
  memcpy (buffer + ps_n + 2, m, m_n);
 
2277
 
 
2278
  err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
 
2279
 
 
2280
 out:
 
2281
 
 
2282
  gcry_free (buffer);
 
2283
  gcry_free (m);
 
2284
 
 
2285
  return err;
 
2286
}
 
2287
 
 
2288
/* Decode a message according to the Encoding Method for Encryption
 
2289
   `PKCS-V1_5' (EME-PKCS-V1_5).  */
 
2290
static gcry_error_t
 
2291
eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
 
2292
                      gcry_ac_io_t *ac_io_read,
 
2293
                      gcry_ac_io_t *ac_io_write)
 
2294
{
 
2295
  gcry_ac_eme_pkcs_v1_5_t *options;
 
2296
  unsigned char *buffer;
 
2297
  unsigned char *em;
 
2298
  size_t em_n;
 
2299
  gcry_error_t err;
 
2300
  unsigned int i;
 
2301
  unsigned int k;
 
2302
 
 
2303
  (void)flags;
 
2304
 
 
2305
  options = opts;
 
2306
  buffer = NULL;
 
2307
  em = NULL;
 
2308
 
 
2309
  err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
 
2310
  if (err)
 
2311
    goto out;
 
2312
 
 
2313
  /* Figure out key size.  */
 
2314
  k = options->key_size / 8;
 
2315
 
 
2316
  /* Search for zero byte.  */
 
2317
  for (i = 0; (i < em_n) && em[i]; i++);
 
2318
 
 
2319
  /* According to this encoding method, the first byte of the encoded
 
2320
     message should be zero.  This byte is lost.  */
 
2321
 
 
2322
  if (! ((em_n >= 10)
 
2323
         && (em_n == (k - 1))
 
2324
         && (em[0] == 0x02)
 
2325
         && (i < em_n)
 
2326
         && ((i - 1) >= 8)))
 
2327
    {
 
2328
      err = gcry_error (GPG_ERR_DECRYPT_FAILED);
 
2329
      goto out;
 
2330
    }
 
2331
 
 
2332
  i++;
 
2333
  buffer = gcry_malloc (em_n - i);
 
2334
  if (! buffer)
 
2335
    {
 
2336
      err = gcry_error_from_errno (errno);
 
2337
      goto out;
 
2338
    }
 
2339
 
 
2340
  memcpy (buffer, em + i, em_n - i);
 
2341
  err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
 
2342
 
 
2343
 out:
 
2344
 
 
2345
  gcry_free (buffer);
 
2346
  gcry_free (em);
 
2347
 
 
2348
  return err;
 
2349
}
 
2350
 
 
2351
static gcry_error_t
 
2352
emsa_pkcs_v1_5_encode_data_cb (void *opaque,
 
2353
                               unsigned char *buffer, size_t buffer_n)
 
2354
{
 
2355
  gcry_md_hd_t md_handle;
 
2356
 
 
2357
  md_handle = opaque;
 
2358
  gcry_md_write (md_handle, buffer, buffer_n);
 
2359
 
 
2360
  return 0;
 
2361
}
 
2362
 
 
2363
 
 
2364
/* Encode a message according to the Encoding Method for Signatures
 
2365
   with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5).  */
 
2366
static gcry_error_t
 
2367
emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
 
2368
                       gcry_ac_io_t *ac_io_read,
 
2369
                       gcry_ac_io_t *ac_io_write)
 
2370
{
 
2371
  gcry_ac_emsa_pkcs_v1_5_t *options;
 
2372
  gcry_error_t err;
 
2373
  gcry_md_hd_t md;
 
2374
  unsigned char *t;
 
2375
  size_t t_n;
 
2376
  unsigned char *h;
 
2377
  size_t h_n;
 
2378
  unsigned char *ps;
 
2379
  size_t ps_n;
 
2380
  unsigned char *buffer;
 
2381
  size_t buffer_n;
 
2382
  unsigned char asn[100];       /* FIXME, always enough?  */
 
2383
  size_t asn_n;
 
2384
  unsigned int i;
 
2385
 
 
2386
  (void)flags;
 
2387
  
 
2388
  options = opts;
 
2389
  buffer = NULL;
 
2390
  md = NULL;
 
2391
  ps = NULL;
 
2392
  t = NULL;
 
2393
 
 
2394
  /* Create hashing handle and get the necessary information.  */
 
2395
  err = gcry_md_open (&md, options->md, 0);
 
2396
  if (err)
 
2397
    goto out;
 
2398
 
 
2399
  asn_n = DIM (asn);
 
2400
  err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
 
2401
  if (err)
 
2402
    goto out;
 
2403
 
 
2404
  h_n = gcry_md_get_algo_dlen (options->md);
 
2405
 
 
2406
  err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
 
2407
  if (err)
 
2408
    goto out;
 
2409
 
 
2410
  h = gcry_md_read (md, 0);
 
2411
 
 
2412
  /* Encode the algorithm ID for the hash function and the hash value
 
2413
     into an ASN.1 value of type DigestInfo with the Distinguished
 
2414
     Encoding Rules (DER), where the type DigestInfo has the syntax:
 
2415
 
 
2416
     DigestInfo ::== SEQUENCE {
 
2417
     digestAlgorithm AlgorithmIdentifier,
 
2418
     digest OCTET STRING
 
2419
     }
 
2420
 
 
2421
     The first field identifies the hash function and the second
 
2422
     contains the hash value.  Let T be the DER encoding of the
 
2423
     DigestInfo value and let tLen be the length in octets of T.  */
 
2424
 
 
2425
  t_n = asn_n + h_n;
 
2426
  t = gcry_malloc (t_n);
 
2427
  if (! t)
 
2428
    {
 
2429
      err = gcry_error_from_errno (errno);
 
2430
      goto out;
 
2431
    }
 
2432
 
 
2433
  for (i = 0; i < asn_n; i++)
 
2434
    t[i] = asn[i];
 
2435
  for (i = 0; i < h_n; i++)
 
2436
    t[asn_n + i] = h[i];
 
2437
 
 
2438
  /* If emLen < tLen + 11, output "intended encoded message length
 
2439
     too short" and stop.  */
 
2440
  if (options->em_n < t_n + 11)
 
2441
    {
 
2442
      err = gcry_error (GPG_ERR_TOO_SHORT);
 
2443
      goto out;
 
2444
    }
 
2445
 
 
2446
  /* Generate an octet string PS consisting of emLen - tLen - 3 octets
 
2447
     with hexadecimal value 0xFF.  The length of PS will be at least 8
 
2448
     octets.  */
 
2449
  ps_n = options->em_n - t_n - 3;
 
2450
  ps = gcry_malloc (ps_n);
 
2451
  if (! ps)
 
2452
    {
 
2453
      err = gcry_error_from_errno (errno);
 
2454
      goto out;
 
2455
    }
 
2456
  for (i = 0; i < ps_n; i++)
 
2457
    ps[i] = 0xFF;
 
2458
 
 
2459
  /* Concatenate PS, the DER encoding T, and other padding to form the
 
2460
     encoded message EM as:
 
2461
 
 
2462
     EM = 0x00 || 0x01 || PS || 0x00 || T.  */
 
2463
 
 
2464
  buffer_n = ps_n + t_n + 3;
 
2465
  buffer = gcry_malloc (buffer_n);
 
2466
  if (! buffer)
 
2467
    {
 
2468
      err = gcry_error_from_errno (errno);
 
2469
      goto out;
 
2470
    }
 
2471
 
 
2472
  buffer[0] = 0x00;
 
2473
  buffer[1] = 0x01;
 
2474
  for (i = 0; i < ps_n; i++)
 
2475
    buffer[2 + i] = ps[i];
 
2476
  buffer[2 + ps_n] = 0x00;
 
2477
  for (i = 0; i < t_n; i++)
 
2478
    buffer[3 + ps_n + i] = t[i];
 
2479
 
 
2480
  err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
 
2481
 
 
2482
 out:
 
2483
 
 
2484
  gcry_md_close (md);
 
2485
 
 
2486
  gcry_free (buffer);
 
2487
  gcry_free (ps);
 
2488
  gcry_free (t);
 
2489
 
 
2490
  return err;
 
2491
}
 
2492
 
 
2493
/* `Actions' for data_dencode().  */
 
2494
typedef enum dencode_action
 
2495
  {
 
2496
    DATA_ENCODE,
 
2497
    DATA_DECODE,
 
2498
  }
 
2499
dencode_action_t;
 
2500
 
 
2501
/* Encode or decode a message according to the the encoding method
 
2502
   METHOD; ACTION specifies wether the message that is contained in
 
2503
   BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
 
2504
   The resulting message will be stored in a newly allocated buffer in
 
2505
   BUFFER_OUT and BUFFER_OUT_N.  */
 
2506
static gcry_error_t
 
2507
ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
 
2508
                 unsigned int flags, void *options,
 
2509
                 gcry_ac_io_t *ac_io_read,
 
2510
                 gcry_ac_io_t *ac_io_write)
 
2511
{
 
2512
  struct
 
2513
  {
 
2514
    gcry_ac_em_t method;
 
2515
    gcry_ac_em_dencode_t encode;
 
2516
    gcry_ac_em_dencode_t decode;
 
2517
  } methods[] =
 
2518
    {
 
2519
      { GCRY_AC_EME_PKCS_V1_5,
 
2520
        eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
 
2521
      { GCRY_AC_EMSA_PKCS_V1_5,
 
2522
        emsa_pkcs_v1_5_encode, NULL },
 
2523
    };
 
2524
  size_t methods_n;
 
2525
  gcry_error_t err;
 
2526
  unsigned int i;
 
2527
 
 
2528
  methods_n = sizeof (methods) / sizeof (*methods);
 
2529
 
 
2530
  for (i = 0; i < methods_n; i++)
 
2531
    if (methods[i].method == method)
 
2532
      break;
 
2533
  if (i == methods_n)
 
2534
    {
 
2535
      err = gcry_error (GPG_ERR_NOT_FOUND);     /* FIXME? */
 
2536
      goto out;
 
2537
    }
 
2538
 
 
2539
  err = 0;
 
2540
  switch (action)
 
2541
    {
 
2542
    case DATA_ENCODE:
 
2543
      if (methods[i].encode)
 
2544
        /* FIXME? */
 
2545
        err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
 
2546
      break;
 
2547
 
 
2548
    case DATA_DECODE:
 
2549
      if (methods[i].decode)
 
2550
        /* FIXME? */
 
2551
        err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
 
2552
      break;
 
2553
 
 
2554
    default:
 
2555
      err = gcry_error (GPG_ERR_INV_ARG);
 
2556
      break;
 
2557
    }
 
2558
 
 
2559
 out:
 
2560
 
 
2561
  return err;
 
2562
}
 
2563
 
 
2564
/* Encode a message according to the encoding method METHOD.  OPTIONS
 
2565
   must be a pointer to a method-specific structure
 
2566
   (gcry_ac_em*_t).  */
 
2567
gcry_error_t
 
2568
_gcry_ac_data_encode (gcry_ac_em_t method,
 
2569
                      unsigned int flags, void *options,
 
2570
                      gcry_ac_io_t *ac_io_read,
 
2571
                      gcry_ac_io_t *ac_io_write)
 
2572
{
 
2573
  if (fips_mode ())
 
2574
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
2575
 
 
2576
  return ac_data_dencode (method, DATA_ENCODE, flags, options,
 
2577
                          ac_io_read, ac_io_write);
 
2578
}
 
2579
 
 
2580
/* Dencode a message according to the encoding method METHOD.  OPTIONS
 
2581
   must be a pointer to a method-specific structure
 
2582
   (gcry_ac_em*_t).  */
 
2583
gcry_error_t
 
2584
_gcry_ac_data_decode (gcry_ac_em_t method,
 
2585
                      unsigned int flags, void *options,
 
2586
                      gcry_ac_io_t *ac_io_read,
 
2587
                      gcry_ac_io_t *ac_io_write)
 
2588
{
 
2589
  if (fips_mode ())
 
2590
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
2591
 
 
2592
  return ac_data_dencode (method, DATA_DECODE, flags, options,
 
2593
                          ac_io_read, ac_io_write);
 
2594
}
 
2595
 
 
2596
/* Convert an MPI into an octet string.  */
 
2597
void
 
2598
_gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
 
2599
{
 
2600
  unsigned long digit;
 
2601
  gcry_mpi_t base;
 
2602
  unsigned int i;
 
2603
  unsigned int n;
 
2604
  gcry_mpi_t m;
 
2605
  gcry_mpi_t d;
 
2606
 
 
2607
  if (fips_mode ())
 
2608
    return;
 
2609
 
 
2610
  base = gcry_mpi_new (0);
 
2611
  gcry_mpi_set_ui (base, 256);
 
2612
 
 
2613
  n = 0;
 
2614
  m = gcry_mpi_copy (mpi);
 
2615
  while (gcry_mpi_cmp_ui (m, 0))
 
2616
    {
 
2617
      n++;
 
2618
      gcry_mpi_div (m, NULL, m, base, 0);
 
2619
    }
 
2620
 
 
2621
  gcry_mpi_set (m, mpi);
 
2622
  d = gcry_mpi_new (0);
 
2623
  for (i = 0; (i < n) && (i < os_n); i++)
 
2624
    {
 
2625
      gcry_mpi_mod (d, m, base);
 
2626
      _gcry_mpi_get_ui (d, &digit);
 
2627
      gcry_mpi_div (m, NULL, m, base, 0);
 
2628
      os[os_n - i - 1] = (digit & 0xFF);
 
2629
    }
 
2630
 
 
2631
  for (; i < os_n; i++)
 
2632
    os[os_n - i - 1] = 0;
 
2633
 
 
2634
  gcry_mpi_release (base);
 
2635
  gcry_mpi_release (d);
 
2636
  gcry_mpi_release (m);
 
2637
}
 
2638
 
 
2639
/* Convert an MPI into an newly allocated octet string.  */
 
2640
gcry_error_t
 
2641
_gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
 
2642
{
 
2643
  unsigned char *buffer;
 
2644
  size_t buffer_n;
 
2645
  gcry_error_t err;
 
2646
  unsigned int nbits;
 
2647
 
 
2648
  if (fips_mode ())
 
2649
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
2650
 
 
2651
  nbits = gcry_mpi_get_nbits (mpi);
 
2652
  buffer_n = (nbits + 7) / 8;
 
2653
  buffer = gcry_malloc (buffer_n);
 
2654
  if (! buffer)
 
2655
    {
 
2656
      err = gcry_error_from_errno (errno);
 
2657
      goto out;
 
2658
    }
 
2659
      
 
2660
  _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
 
2661
  *os = buffer;
 
2662
  *os_n = buffer_n;
 
2663
  err = 0;
 
2664
 
 
2665
 out:
 
2666
 
 
2667
  return err;
 
2668
}
 
2669
 
 
2670
 
 
2671
/* Convert an octet string into an MPI.  */
 
2672
void
 
2673
_gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
 
2674
{
 
2675
  unsigned int i;
 
2676
  gcry_mpi_t xi;
 
2677
  gcry_mpi_t x;
 
2678
  gcry_mpi_t a;
 
2679
  
 
2680
  if (fips_mode ())
 
2681
    return;
 
2682
 
 
2683
  a = gcry_mpi_new (0);
 
2684
  gcry_mpi_set_ui (a, 1);
 
2685
  x = gcry_mpi_new (0);
 
2686
  gcry_mpi_set_ui (x, 0);
 
2687
  xi = gcry_mpi_new (0);
 
2688
 
 
2689
  for (i = 0; i < os_n; i++)
 
2690
    {
 
2691
      gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
 
2692
      gcry_mpi_add (x, x, xi);
 
2693
      gcry_mpi_mul_ui (a, a, 256);
 
2694
    }
 
2695
      
 
2696
  gcry_mpi_release (xi);
 
2697
  gcry_mpi_release (a);
 
2698
 
 
2699
  gcry_mpi_set (mpi, x);
 
2700
  gcry_mpi_release (x);         /* FIXME: correct? */
 
2701
}
 
2702
 
 
2703
 
 
2704
 
 
2705
/* 
 
2706
 * Implementation of Encryption Schemes (ES) and Signature Schemes
 
2707
 * with Appendix (SSA).
 
2708
 */
 
2709
 
 
2710
/* Schemes consist of two things: encoding methods and cryptographic
 
2711
   primitives.
 
2712
 
 
2713
   Since encoding methods are accessible through a common API with
 
2714
   method-specific options passed as an anonymous struct, schemes have
 
2715
   to provide functions that construct this method-specific structure;
 
2716
   this is what the functions of type `gcry_ac_dencode_prepare_t' are
 
2717
   there for.  */
 
2718
 
 
2719
typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
 
2720
                                                   gcry_ac_key_t key,
 
2721
                                                   void *opts,
 
2722
                                                   void *opts_em);
 
2723
 
 
2724
/* The `dencode_prepare' function for ES-PKCS-V1_5.  */
 
2725
static gcry_error_t
 
2726
ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
 
2727
                                 void *opts, void *opts_em)
 
2728
{
 
2729
  gcry_ac_eme_pkcs_v1_5_t *options_em;
 
2730
  unsigned int nbits;
 
2731
  gcry_error_t err;
 
2732
 
 
2733
  (void)opts;
 
2734
 
 
2735
  err = _gcry_ac_key_get_nbits (handle, key, &nbits);
 
2736
  if (err)
 
2737
    goto out;
 
2738
 
 
2739
  options_em = opts_em;
 
2740
  options_em->key_size = nbits;
 
2741
 
 
2742
 out:
 
2743
 
 
2744
  return err;
 
2745
}
 
2746
 
 
2747
/* The `dencode_prepare' function for SSA-PKCS-V1_5.  */
 
2748
static gcry_error_t
 
2749
ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
 
2750
                                  void *opts, void *opts_em)
 
2751
{
 
2752
  gcry_ac_emsa_pkcs_v1_5_t *options_em;
 
2753
  gcry_ac_ssa_pkcs_v1_5_t *options;
 
2754
  gcry_error_t err;
 
2755
  unsigned int k;
 
2756
 
 
2757
  options_em = opts_em;
 
2758
  options = opts;
 
2759
 
 
2760
  err = _gcry_ac_key_get_nbits (handle, key, &k);
 
2761
  if (err)
 
2762
    goto out;
 
2763
 
 
2764
  k = (k + 7) / 8;
 
2765
  options_em->md = options->md;
 
2766
  options_em->em_n = k;
 
2767
 
 
2768
 out:
 
2769
 
 
2770
  return err;
 
2771
}
 
2772
 
 
2773
/* Type holding the information about each supported
 
2774
   Encryption/Signature Scheme.  */
 
2775
typedef struct ac_scheme
 
2776
{
 
2777
  gcry_ac_scheme_t scheme;
 
2778
  gcry_ac_em_t scheme_encoding;
 
2779
  gcry_ac_dencode_prepare_t dencode_prepare;
 
2780
  size_t options_em_n;
 
2781
} ac_scheme_t;
 
2782
 
 
2783
/* List of supported Schemes.  */
 
2784
static ac_scheme_t ac_schemes[] =
 
2785
  {
 
2786
    { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
 
2787
      ac_es_dencode_prepare_pkcs_v1_5,
 
2788
      sizeof (gcry_ac_eme_pkcs_v1_5_t) },
 
2789
    { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
 
2790
      ac_ssa_dencode_prepare_pkcs_v1_5,
 
2791
      sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
 
2792
  };
 
2793
 
 
2794
/* Lookup a scheme by it's ID.  */
 
2795
static ac_scheme_t *
 
2796
ac_scheme_get (gcry_ac_scheme_t scheme)
 
2797
{
 
2798
  ac_scheme_t *ac_scheme;
 
2799
  unsigned int i;
 
2800
 
 
2801
  for (i = 0; i < DIM (ac_schemes); i++)
 
2802
    if (scheme == ac_schemes[i].scheme)
 
2803
      break;
 
2804
  if (i == DIM (ac_schemes))
 
2805
    ac_scheme = NULL;
 
2806
  else
 
2807
    ac_scheme = ac_schemes + i;
 
2808
 
 
2809
  return ac_scheme;
 
2810
}
 
2811
 
 
2812
/* Prepares the encoding/decoding by creating an according option
 
2813
   structure.  */
 
2814
static gcry_error_t
 
2815
ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
 
2816
                    ac_scheme_t scheme, void **opts_em)
 
2817
{
 
2818
  gcry_error_t err;
 
2819
  void *options_em;
 
2820
 
 
2821
  options_em = gcry_malloc (scheme.options_em_n);
 
2822
  if (! options_em)
 
2823
    {
 
2824
      err = gcry_error_from_errno (errno);
 
2825
      goto out;
 
2826
    }
 
2827
  
 
2828
  err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
 
2829
  if (err)
 
2830
    goto out;
 
2831
 
 
2832
  *opts_em = options_em;
 
2833
 
 
2834
 out:
 
2835
 
 
2836
  if (err)
 
2837
    free (options_em);
 
2838
 
 
2839
  return err;
 
2840
}
 
2841
 
 
2842
/* Convert a data set into a single MPI; currently, this is only
 
2843
   supported for data sets containing a single MPI.  */
 
2844
static gcry_error_t
 
2845
ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
 
2846
{
 
2847
  gcry_error_t err;
 
2848
  gcry_mpi_t mpi_new;
 
2849
  unsigned int elems;
 
2850
 
 
2851
  elems = _gcry_ac_data_length (data);
 
2852
 
 
2853
  if (elems != 1)
 
2854
    {
 
2855
      /* FIXME: I guess, we should be more flexible in this respect by
 
2856
         allowing the actual encryption/signature schemes to implement
 
2857
         this conversion mechanism.  */
 
2858
      err = gcry_error (GPG_ERR_CONFLICT);
 
2859
      goto out;
 
2860
    }
 
2861
 
 
2862
  err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
 
2863
  if (err)
 
2864
    goto out;
 
2865
 
 
2866
  *mpi = mpi_new;
 
2867
 
 
2868
 out:
 
2869
 
 
2870
  return err;
 
2871
}
 
2872
 
 
2873
/* Encrypts the plain text message contained in M, which is of size
 
2874
   M_N, with the public key KEY_PUBLIC according to the Encryption
 
2875
   Scheme SCHEME_ID.  HANDLE is used for accessing the low-level
 
2876
   cryptographic primitives.  If OPTS is not NULL, it has to be an
 
2877
   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
 
2878
   The encrypted message will be stored in C and C_N.  */
 
2879
gcry_error_t
 
2880
_gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
 
2881
                              gcry_ac_scheme_t scheme_id,
 
2882
                              unsigned int flags, void *opts,
 
2883
                              gcry_ac_key_t key,
 
2884
                              gcry_ac_io_t *io_message,
 
2885
                              gcry_ac_io_t *io_cipher)
 
2886
{
 
2887
  gcry_error_t err;
 
2888
  gcry_ac_io_t io_em;
 
2889
  unsigned char *em;
 
2890
  size_t em_n;
 
2891
  gcry_mpi_t mpi_plain;
 
2892
  gcry_ac_data_t data_encrypted;
 
2893
  gcry_mpi_t mpi_encrypted;
 
2894
  unsigned char *buffer;
 
2895
  size_t buffer_n;
 
2896
  void *opts_em;
 
2897
  ac_scheme_t *scheme;
 
2898
 
 
2899
  (void)flags;
 
2900
 
 
2901
  if (fips_mode ())
 
2902
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
2903
 
 
2904
  data_encrypted = NULL;
 
2905
  mpi_encrypted = NULL;
 
2906
  mpi_plain = NULL;
 
2907
  opts_em = NULL;
 
2908
  buffer = NULL;
 
2909
  em = NULL;
 
2910
 
 
2911
  scheme = ac_scheme_get (scheme_id);
 
2912
  if (! scheme)
 
2913
    {
 
2914
      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
 
2915
      goto out;
 
2916
    }
 
2917
 
 
2918
  if (key->type != GCRY_AC_KEY_PUBLIC)
 
2919
    {
 
2920
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
2921
      goto out;
 
2922
    }
 
2923
 
 
2924
  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
 
2925
  if (err)
 
2926
    goto out;
 
2927
 
 
2928
  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
 
2929
                    GCRY_AC_IO_STRING, &em, &em_n);
 
2930
 
 
2931
  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
 
2932
                              io_message, &io_em);
 
2933
  if (err)
 
2934
    goto out;
 
2935
 
 
2936
  mpi_plain = gcry_mpi_snew (0);
 
2937
  gcry_ac_os_to_mpi (mpi_plain, em, em_n);
 
2938
 
 
2939
  err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
 
2940
  if (err)
 
2941
    goto out;
 
2942
 
 
2943
  err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
 
2944
  if (err)
 
2945
    goto out;
 
2946
 
 
2947
  err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
 
2948
  if (err)
 
2949
    goto out;
 
2950
 
 
2951
  err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
 
2952
 
 
2953
 out:
 
2954
 
 
2955
  gcry_ac_data_destroy (data_encrypted);
 
2956
  gcry_mpi_release (mpi_encrypted);
 
2957
  gcry_mpi_release (mpi_plain);
 
2958
  gcry_free (opts_em);
 
2959
  gcry_free (buffer);
 
2960
  gcry_free (em);
 
2961
 
 
2962
  return err;
 
2963
}
 
2964
 
 
2965
/* Decryptes the cipher message contained in C, which is of size C_N,
 
2966
   with the secret key KEY_SECRET according to the Encryption Scheme
 
2967
   SCHEME_ID.  Handle is used for accessing the low-level
 
2968
   cryptographic primitives.  If OPTS is not NULL, it has to be an
 
2969
   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
 
2970
   The decrypted message will be stored in M and M_N.  */
 
2971
gcry_error_t
 
2972
_gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
 
2973
                              gcry_ac_scheme_t scheme_id,
 
2974
                              unsigned int flags, void *opts,
 
2975
                              gcry_ac_key_t key,
 
2976
                              gcry_ac_io_t *io_cipher,
 
2977
                              gcry_ac_io_t *io_message)
 
2978
{
 
2979
  gcry_ac_io_t io_em;
 
2980
  gcry_error_t err;
 
2981
  gcry_ac_data_t data_encrypted;
 
2982
  unsigned char *em;
 
2983
  size_t em_n;
 
2984
  gcry_mpi_t mpi_encrypted;
 
2985
  gcry_mpi_t mpi_decrypted;
 
2986
  void *opts_em;
 
2987
  ac_scheme_t *scheme;
 
2988
  char *elements_enc;
 
2989
  size_t elements_enc_n;
 
2990
  unsigned char *c;
 
2991
  size_t c_n;
 
2992
 
 
2993
  (void)flags;
 
2994
 
 
2995
  if (fips_mode ())
 
2996
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
2997
 
 
2998
  data_encrypted = NULL;
 
2999
  mpi_encrypted = NULL;
 
3000
  mpi_decrypted = NULL;
 
3001
  elements_enc = NULL;
 
3002
  opts_em = NULL;
 
3003
  em = NULL;
 
3004
  c = NULL;
 
3005
 
 
3006
  scheme = ac_scheme_get (scheme_id);
 
3007
  if (! scheme)
 
3008
    {
 
3009
      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
 
3010
      goto out;
 
3011
    }
 
3012
 
 
3013
  if (key->type != GCRY_AC_KEY_SECRET)
 
3014
    {
 
3015
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
3016
      goto out;
 
3017
    }
 
3018
 
 
3019
  err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
 
3020
  if (err)
 
3021
    goto out;
 
3022
 
 
3023
  mpi_encrypted = gcry_mpi_snew (0);
 
3024
  gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
 
3025
 
 
3026
  err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
 
3027
  if (err)
 
3028
    goto out;
 
3029
 
 
3030
  elements_enc_n = strlen (elements_enc);
 
3031
  if (elements_enc_n != 1)
 
3032
    {
 
3033
      /* FIXME? */
 
3034
      err = gcry_error (GPG_ERR_CONFLICT);
 
3035
      goto out;
 
3036
    }
 
3037
 
 
3038
  err = _gcry_ac_data_new (&data_encrypted);
 
3039
  if (err)
 
3040
    goto out;
 
3041
 
 
3042
  err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
 
3043
                           elements_enc, mpi_encrypted);
 
3044
  if (err)
 
3045
    goto out;
 
3046
 
 
3047
  err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
 
3048
  if (err)
 
3049
    goto out;
 
3050
 
 
3051
  err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
 
3052
  if (err)
 
3053
    goto out;
 
3054
 
 
3055
  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
 
3056
  if (err)
 
3057
    goto out;
 
3058
 
 
3059
  _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
 
3060
                    GCRY_AC_IO_STRING, em, em_n);
 
3061
 
 
3062
  err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
 
3063
                              &io_em, io_message);
 
3064
  if (err)
 
3065
    goto out;
 
3066
 
 
3067
 out:
 
3068
  
 
3069
  _gcry_ac_data_destroy (data_encrypted);
 
3070
  gcry_mpi_release (mpi_encrypted);
 
3071
  gcry_mpi_release (mpi_decrypted);
 
3072
  free (elements_enc);
 
3073
  gcry_free (opts_em);
 
3074
  gcry_free (em);
 
3075
  gcry_free (c);
 
3076
 
 
3077
  return err;
 
3078
}
 
3079
 
 
3080
 
 
3081
/* Signs the message contained in M, which is of size M_N, with the
 
3082
   secret key KEY according to the Signature Scheme SCHEME_ID.  Handle
 
3083
   is used for accessing the low-level cryptographic primitives.  If
 
3084
   OPTS is not NULL, it has to be an anonymous structure specific to
 
3085
   the chosen scheme (gcry_ac_ssa_*_t).  The signed message will be
 
3086
   stored in S and S_N.  */
 
3087
gcry_error_t
 
3088
_gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
 
3089
                           gcry_ac_scheme_t scheme_id,
 
3090
                           unsigned int flags, void *opts,
 
3091
                           gcry_ac_key_t key,
 
3092
                           gcry_ac_io_t *io_message,
 
3093
                           gcry_ac_io_t *io_signature)
 
3094
{
 
3095
  gcry_ac_io_t io_em;
 
3096
  gcry_error_t err;
 
3097
  gcry_ac_data_t data_signed;
 
3098
  unsigned char *em;
 
3099
  size_t em_n;
 
3100
  gcry_mpi_t mpi;
 
3101
  void *opts_em;
 
3102
  unsigned char *buffer;
 
3103
  size_t buffer_n;
 
3104
  gcry_mpi_t mpi_signed;
 
3105
  ac_scheme_t *scheme;
 
3106
 
 
3107
  (void)flags;
 
3108
 
 
3109
  if (fips_mode ())
 
3110
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
3111
 
 
3112
  data_signed = NULL;
 
3113
  mpi_signed = NULL;
 
3114
  opts_em = NULL;
 
3115
  buffer = NULL;
 
3116
  mpi = NULL;
 
3117
  em = NULL;
 
3118
 
 
3119
  if (key->type != GCRY_AC_KEY_SECRET)
 
3120
    {
 
3121
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
3122
      goto out;
 
3123
    }
 
3124
 
 
3125
  scheme = ac_scheme_get (scheme_id);
 
3126
  if (! scheme)
 
3127
    {
 
3128
      /* FIXME: adjust api of scheme_get in respect to err codes.  */
 
3129
      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
 
3130
      goto out;
 
3131
    }
 
3132
 
 
3133
  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
 
3134
  if (err)
 
3135
    goto out;
 
3136
 
 
3137
  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
 
3138
                    GCRY_AC_IO_STRING, &em, &em_n);
 
3139
 
 
3140
  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
 
3141
                              io_message, &io_em);
 
3142
  if (err)
 
3143
    goto out;
 
3144
 
 
3145
  mpi = gcry_mpi_new (0);
 
3146
  _gcry_ac_os_to_mpi (mpi, em, em_n);
 
3147
 
 
3148
  err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
 
3149
  if (err)
 
3150
    goto out;
 
3151
 
 
3152
  err = ac_data_set_to_mpi (data_signed, &mpi_signed);
 
3153
  if (err)
 
3154
    goto out;
 
3155
 
 
3156
  err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
 
3157
  if (err)
 
3158
    goto out;
 
3159
 
 
3160
  err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
 
3161
 
 
3162
 out:
 
3163
 
 
3164
  _gcry_ac_data_destroy (data_signed);
 
3165
  gcry_mpi_release (mpi_signed);
 
3166
  gcry_mpi_release (mpi);
 
3167
  gcry_free (opts_em);
 
3168
  gcry_free (buffer);
 
3169
  gcry_free (em);
 
3170
 
 
3171
  return err;
 
3172
}
 
3173
 
 
3174
/* Verifies that the signature contained in S, which is of length S_N,
 
3175
   is indeed the result of signing the message contained in M, which
 
3176
   is of size M_N, with the secret key belonging to the public key
 
3177
   KEY_PUBLIC.  If OPTS is not NULL, it has to be an anonymous
 
3178
   structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
 
3179
   ID is contained in SCHEME_ID.  */
 
3180
gcry_error_t
 
3181
_gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
 
3182
                             gcry_ac_scheme_t scheme_id,
 
3183
                             unsigned int flags, void *opts,
 
3184
                             gcry_ac_key_t key,
 
3185
                             gcry_ac_io_t *io_message,
 
3186
                             gcry_ac_io_t *io_signature)
 
3187
{
 
3188
  gcry_ac_io_t io_em;
 
3189
  gcry_error_t err;
 
3190
  gcry_ac_data_t data_signed;
 
3191
  unsigned char *em;
 
3192
  size_t em_n;
 
3193
  void *opts_em;
 
3194
  gcry_mpi_t mpi_signature;
 
3195
  gcry_mpi_t mpi_data;
 
3196
  ac_scheme_t *scheme;
 
3197
  char *elements_sig;
 
3198
  size_t elements_sig_n;
 
3199
  unsigned char *s;
 
3200
  size_t s_n;
 
3201
 
 
3202
  (void)flags;
 
3203
 
 
3204
  if (fips_mode ())
 
3205
    return gpg_error (GPG_ERR_NOT_SUPPORTED);
 
3206
 
 
3207
  mpi_signature = NULL;
 
3208
  elements_sig = NULL;
 
3209
  data_signed = NULL;
 
3210
  mpi_data = NULL;
 
3211
  opts_em = NULL;
 
3212
  em = NULL;
 
3213
  s = NULL;
 
3214
 
 
3215
  if (key->type != GCRY_AC_KEY_PUBLIC)
 
3216
    {
 
3217
      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
 
3218
      goto out;
 
3219
    }
 
3220
 
 
3221
  scheme = ac_scheme_get (scheme_id);
 
3222
  if (! scheme)
 
3223
    {
 
3224
      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
 
3225
      goto out;
 
3226
    }
 
3227
 
 
3228
  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
 
3229
  if (err)
 
3230
    goto out;
 
3231
 
 
3232
  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
 
3233
                    GCRY_AC_IO_STRING, &em, &em_n);
 
3234
 
 
3235
  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
 
3236
                              io_message, &io_em);
 
3237
  if (err)
 
3238
    goto out;
 
3239
 
 
3240
  mpi_data = gcry_mpi_new (0);
 
3241
  _gcry_ac_os_to_mpi (mpi_data, em, em_n);
 
3242
 
 
3243
  err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
 
3244
  if (err)
 
3245
    goto out;
 
3246
 
 
3247
  mpi_signature = gcry_mpi_new (0);
 
3248
  _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
 
3249
 
 
3250
  err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
 
3251
  if (err)
 
3252
    goto out;
 
3253
 
 
3254
  elements_sig_n = strlen (elements_sig);
 
3255
  if (elements_sig_n != 1)
 
3256
    {
 
3257
      /* FIXME? */
 
3258
      err = gcry_error (GPG_ERR_CONFLICT);
 
3259
      goto out;
 
3260
    }
 
3261
 
 
3262
  err = _gcry_ac_data_new (&data_signed);
 
3263
  if (err)
 
3264
    goto out;
 
3265
 
 
3266
  err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
 
3267
                           elements_sig, mpi_signature);
 
3268
  if (err)
 
3269
    goto out;
 
3270
 
 
3271
  gcry_mpi_release (mpi_signature);
 
3272
  mpi_signature = NULL;
 
3273
  
 
3274
  err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
 
3275
 
 
3276
 out:
 
3277
 
 
3278
  _gcry_ac_data_destroy (data_signed);
 
3279
  gcry_mpi_release (mpi_signature);
 
3280
  gcry_mpi_release (mpi_data);
 
3281
  free (elements_sig);
 
3282
  gcry_free (opts_em);
 
3283
  gcry_free (em);
 
3284
  gcry_free (s);
 
3285
 
 
3286
  return err;
 
3287
}
 
3288
 
 
3289
 
 
3290
/* 
 
3291
 * General functions.
 
3292
 */
 
3293
 
 
3294
gcry_err_code_t
 
3295
_gcry_ac_init (void)
 
3296
{
 
3297
  if (fips_mode ())
 
3298
    return GPG_ERR_NOT_SUPPORTED;
 
3299
 
 
3300
  return 0;
 
3301
}