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

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson, Colin Watson, Robert Millan, Updated translations
  • Date: 2010-11-22 12:24:56 UTC
  • mfrom: (1.26.4 upstream) (17.3.36 sid)
  • mto: (17.3.43 sid)
  • mto: This revision was merged to the branch mainline in revision 89.
  • Revision ID: james.westby@ubuntu.com-20101122122456-y82z3sfb7k4zfdcc
Tags: 1.99~20101122-1
[ Colin Watson ]
* New Bazaar snapshot.  Too many changes to list in full, but some of the
  more user-visible ones are as follows:
  - GRUB script:
    + Function parameters, "break", "continue", "shift", "setparams",
      "return", and "!".
    + "export" command supports multiple variable names.
    + Multi-line quoted strings support.
    + Wildcard expansion.
  - sendkey support.
  - USB hotunplugging and USB serial support.
  - Rename CD-ROM to cd on BIOS.
  - Add new --boot-directory option to grub-install, grub-reboot, and
    grub-set-default; the old --root-directory option is still accepted
    but was often confusing.
  - Basic btrfs detection/UUID support (but no file reading yet).
  - bash-completion for utilities.
  - If a device is listed in device.map, always assume that it is
    BIOS-visible rather than using extra layers such as LVM or RAID.
  - Add grub-mknetdir script (closes: #550658).
  - Remove deprecated "root" command.
  - Handle RAID devices containing virtio components.
  - GRUB Legacy configuration file support (via grub-menulst2cfg).
  - Keyboard layout support (via grub-mklayout and grub-kbdcomp).
  - Check generated grub.cfg for syntax errors before saving.
  - Pause execution for at most ten seconds if any errors are displayed,
    so that the user has a chance to see them.
  - Support submenus.
  - Write embedding zone using Reed-Solomon, so that it's robust against
    being partially overwritten (closes: #550702, #591416, #593347).
  - GRUB_DISABLE_LINUX_RECOVERY and GRUB_DISABLE_NETBSD_RECOVERY merged
    into a single GRUB_DISABLE_RECOVERY variable.
  - Fix loader memory allocation failure (closes: #551627).
  - Don't call savedefault on recovery entries (closes: #589325).
  - Support triple-indirect blocks on ext2 (closes: #543924).
  - Recognise DDF1 fake RAID (closes: #603354).

[ Robert Millan ]
* Use dpkg architecture wildcards.

[ Updated translations ]
* Slovenian (Vanja Cvelbar).  Closes: #604003
* Dzongkha (dawa pemo via Tenzin Dendup).  Closes: #604102

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
 
}