~ubuntu-branches/ubuntu/raring/libgcrypt11/raring

« back to all changes in this revision

Viewing changes to cipher/ac.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2008-07-02 18:32:45 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20080702183245-b1p9zumbhmq9wk4g
Tags: 1.4.1-1ubuntu1
* Merge from Debian unstable.
* Remaining Ubuntu changes:
  - Add libgcrypt11-udeb package.
  - Add clean-la.mk, and add a symlink for the .la
* Ubuntu changes dropped:
  - Build-Depends changes.
  - Drop patch 20_socket_nsl_linkage.diff, basically applied upstream.

Show diffs side-by-side

added added

removed removed

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