121
* Primitive functions for the manipulation of `data sets'.
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)
128
gcry_err_code_t err = GPG_ERR_NO_ERROR;
129
gcry_ac_data_t data_new;
133
/* Allocate data set. */
134
err = _gcry_malloc (sizeof (struct gcry_ac_data), 0, &p);
137
data_new->data_n = data->data_n;
140
/* Allocate space for named MPIs. */
141
err = _gcry_malloc (sizeof (gcry_ac_mpi_t) * data->data_n, 0,
142
(void **) &data_new->data);
146
/* Copy named MPIs. */
148
for (i = 0; i < data_new->data_n && (! err); i++)
150
data_new->data[i].name = NULL;
151
data_new->data[i].mpi = NULL;
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);
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);
175
/* Deallocate resources. */
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);
187
gcry_free (data_new->data);
189
gcry_free (data_new);
199
* Functions for converting data between the native ac and the
200
* S-expression structure.
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
207
(IDENTIFIER <data to be ignored>
208
(ALGORITHM <list of named MPI values>))
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)
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;
224
gcry_mpi_t data_elem_mpi = NULL;
225
char *data_elem_name = NULL;
227
gcry_ac_data_t data_new = NULL;
231
/* Verify that the S-expression contains the correct identifier. */
232
name = gcry_sexp_nth_data (data_sexp, 0, &name_n);
234
err = GPG_ERR_INTERNAL;
235
else if (strncmp (identifier, name, name_n))
236
err = GPG_ERR_INTERNAL;
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;
245
/* Count data elements, this includes the name of the
247
inner_data_n = gcry_sexp_length (inner_data_sexp);
252
/* Allocate new data set. */
253
data_new = gcry_malloc (sizeof (struct gcry_ac_data));
255
err = gpg_err_code_from_errno (errno);
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);
267
/* Iterate through list of data elements and add them to the
270
for (i = 1; i < inner_data_n; i++)
272
data_new->data[i - 1].name = NULL;
273
data_new->data[i - 1].mpi = NULL;
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;
283
/* Extract the name. */
284
name = gcry_sexp_nth_data (data_element_sexp, 0, &name_n);
286
err = GPG_ERR_INTERNAL;
291
/* Extract the MPI value. */
292
data_elem_mpi = gcry_sexp_nth_mpi (data_element_sexp, 1,
295
err = GPG_ERR_INTERNAL;
300
/* Duplicate the name. */
301
data_elem_name = gcry_malloc (name_n + 1);
302
if (! data_elem_name)
304
err = gpg_err_code_from_errno (errno);
307
strncpy (data_elem_name, name, name_n);
308
data_elem_name[name_n] = 0;
314
if (data_element_sexp)
315
gcry_sexp_release (data_element_sexp);
319
data_new->data[i - 1].name = data_elem_name;
320
data_new->data[i - 1].mpi = data_elem_mpi;
330
data_new->data_n = inner_data_n - 1;
335
/* Deallocate resources. */
343
for (j = 0; j < i - 1; j++)
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);
351
gcry_free (data_new->data);
353
gcry_free (data_new);
360
/* Construct an S-expression from the DATA and store it in
361
DATA_SEXP. The S-expression will be of the following structure:
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)
370
gcry_err_code_t err = GPG_ERR_NO_ERROR;
371
void **arg_list = NULL;
373
gcry_sexp_t data_sexp_new = NULL;
375
size_t data_format_n = 0;
376
char *data_format = NULL;
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);
384
err = gpg_err_code_from_errno (errno);
386
/* Fill list with MPIs. */
387
for (i = 0; i < data->data_n; i++)
388
arg_list[i] = (void *) &data->data[i].mpi;
392
/* Calculate size of format string. */
394
data_format_n = (5 + (include_flags ? 7 : 0)
395
+ strlen (identifier) + strlen (algorithm));
397
for (i = 0; i < data->data_n; i++)
399
/* Per-element sizes. */
400
data_format_n += 4 + strlen (data->data[i].name);
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;
412
data_format = gcry_malloc (data_format_n);
414
err = gpg_err_code_from_errno (errno);
419
/* Construct the format string. */
422
strcat (data_format, "(");
423
strcat (data_format, identifier);
426
strcat (data_format, "(flags");
427
for (i = 0; gcry_ac_flags[i].number; i++)
428
if (flags & gcry_ac_flags[i].number)
430
strcat (data_format, " ");
431
strcat (data_format, gcry_ac_flags[i].string);
433
strcat (data_format, ")");
435
strcat (data_format, "(");
436
strcat (data_format, algorithm);
437
for (i = 0; i < data->data_n; i++)
439
strcat (data_format, "(");
440
strcat (data_format, data->data[i].name);
441
strcat (data_format, "%m)");
443
strcat (data_format, "))");
445
/* Create final S-expression. */
446
err = gcry_sexp_build_array (&data_sexp_new, NULL,
447
data_format, arg_list);
452
/* Deallocate resources. */
455
gcry_free (arg_list);
457
gcry_free (data_format);
459
gcry_sexp_release (data_sexp_new);
464
*data_sexp = data_sexp_new;
472
120
* Functions for working with data sets.
475
/* Creates a new, empty data set and stores it in DATA. */
123
/* Creates a new, empty data set and store it in DATA. */
477
gcry_ac_data_new (gcry_ac_data_t *data)
125
_gcry_ac_data_new (gcry_ac_data_t *data)
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;
482
data_new = gcry_malloc (sizeof (struct gcry_ac_data));
130
data_new = gcry_malloc (sizeof (*data_new));
484
err = gpg_err_code_from_errno (errno);
488
data_new->data = NULL;
489
data_new->data_n = 0;
133
err = gcry_error_from_errno (errno);
493
return gcry_error (err);
137
data_new->data = NULL;
138
data_new->data_n = 0;
147
/* Destroys all the entries in DATA, but not DATA itself. */
149
ac_data_values_destroy (gcry_ac_data_t data)
153
for (i = 0; i < data->data_n; i++)
154
if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
156
gcry_mpi_release (data->data[i].mpi);
157
gcry_free (data->data[i].name);
496
161
/* Destroys the data set DATA. */
498
gcry_ac_data_destroy (gcry_ac_data_t data)
163
_gcry_ac_data_destroy (gcry_ac_data_t data)
502
for (i = 0; i < data->data_n; i++)
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);
507
gcry_free (data->data);
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. */
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
177
ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
178
gcry_ac_mpi_t **data_mpis_cp)
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;
526
if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
527
err = GPG_ERR_INV_ARG;
530
if (flags & GCRY_AC_FLAG_COPY)
534
name_add = gcry_strdup (name);
536
err = GPG_ERR_ENOMEM;
539
mpi_add = gcry_mpi_copy (mpi);
541
err = GPG_ERR_ENOMEM;
546
name_add = (char *) name;
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;
557
/* An entry for NAME does already exist. */
558
if (ac_mpi->flags & GCRY_AC_FLAG_DEALLOC)
560
/* Deallocate old values. */
561
gcry_free ((char *) ac_mpi->name);
562
gcry_mpi_release (ac_mpi->mpi);
567
/* Create a new entry. */
569
gcry_ac_mpi_t *ac_mpis = NULL;
571
ac_mpis = realloc (data->data, sizeof (*data->data) * (data->data_n + 1));
573
err = gpg_err_code_from_errno (errno);
575
if (data->data != ac_mpis)
576
data->data = ac_mpis;
577
ac_mpi = data->data + data->data_n;
581
ac_mpi->flags = flags;
582
ac_mpi->name = name_add;
583
ac_mpi->mpi = mpi_add;
586
return gcry_error (err);
180
gcry_ac_mpi_t *data_mpis_new;
186
data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
189
err = gcry_error_from_errno (errno);
192
memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
195
for (i = 0; i < data_mpis_n; i++)
199
label = gcry_strdup (data_mpis[i].name);
200
mpi = gcry_mpi_copy (data_mpis[i].mpi);
201
if (! (label && mpi))
203
err = gcry_error_from_errno (errno);
204
gcry_mpi_release (mpi);
209
data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
210
data_mpis_new[i].name = label;
211
data_mpis_new[i].mpi = mpi;
216
*data_mpis_cp = data_mpis_new;
224
for (i = 0; i < data_mpis_n; i++)
226
gcry_mpi_release (data_mpis_new[i].mpi);
227
gcry_free (data_mpis_new[i].name);
229
gcry_free (data_mpis_new);
589
235
/* Create a copy of the data set DATA and store it in DATA_CP. */
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)
593
gcry_err_code_t err = GPG_ERR_NO_ERROR;
595
err = gcry_ac_data_copy_internal (data_cp, data);
597
return gcry_error (err);
239
gcry_ac_mpi_t *data_mpis = NULL;
240
gcry_ac_data_t data_new;
243
/* Allocate data set. */
244
data_new = gcry_malloc (sizeof (*data_new));
247
err = gcry_error_from_errno (errno);
251
err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
255
data_new->data_n = data->data_n;
256
data_new->data = data_mpis;
262
gcry_free (data_new);
600
267
/* Returns the number of named MPI values inside of the data set
603
gcry_ac_data_length (gcry_ac_data_t data)
270
_gcry_ac_data_length (gcry_ac_data_t data)
605
272
return data->data_n;
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. */
612
gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
613
const char *name, gcry_mpi_t *mpi)
615
gcry_err_code_t err = GPG_ERR_NO_DATA;
616
gcry_mpi_t mpi_found = NULL;
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. */
282
_gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
283
const char *name, gcry_mpi_t mpi)
293
if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
295
err = gcry_error (GPG_ERR_INV_ARG);
299
if (flags & GCRY_AC_FLAG_COPY)
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))
308
err = gcry_error_from_errno (errno);
313
/* Search for existing entry. */
314
for (i = 0; i < data->data_n; i++)
315
if (! strcmp (name, data->data[i].name))
317
if (i < data->data_n)
319
/* An entry for NAME does already exist. */
320
if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
322
gcry_mpi_release (data->data[i].mpi);
323
gcry_free (data->data[i].name);
328
/* Create a new entry. */
330
gcry_ac_mpi_t *ac_mpis;
332
ac_mpis = gcry_realloc (data->data,
333
sizeof (*data->data) * (data->data_n + 1));
336
err = gcry_error_from_errno (errno);
340
if (data->data != ac_mpis)
341
data->data = ac_mpis;
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;
354
gcry_mpi_release (mpi_cp);
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. */
366
_gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
367
const char *name, gcry_mpi_t *mpi)
369
gcry_mpi_t mpi_return;
619
373
if (flags & ~(GCRY_AC_FLAG_COPY))
620
err = GPG_ERR_INV_ARG;
375
err = gcry_error (GPG_ERR_INV_ARG);
379
for (i = 0; i < data->data_n; i++)
380
if (! strcmp (name, data->data[i].name))
382
if (i == data->data_n)
384
err = gcry_error (GPG_ERR_NOT_FOUND);
388
if (flags & GCRY_AC_FLAG_COPY)
390
mpi_return = gcry_mpi_copy (data->data[i].mpi);
393
err = gcry_error_from_errno (errno); /* FIXME? */
623
for (i = 0; i < data->data_n && (! mpi_found); i++)
624
if (! strcmp (data->data[i].name, name))
626
if (flags & GCRY_AC_FLAG_COPY)
628
mpi_found = gcry_mpi_copy (data->data[i].mpi);
630
err = GPG_ERR_ENOMEM;
633
mpi_found = data->data[i].mpi;
636
err = GPG_ERR_NO_ERROR;
644
return gcry_error (err);
398
mpi_return = data->data[i].mpi;
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
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. */
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,
415
const char **name, gcry_mpi_t *mpi)
655
gcry_err_code_t err = GPG_ERR_NO_ERROR;
656
gcry_mpi_t mpi_return = NULL;
657
char *name_return = NULL;
659
424
if (flags & ~(GCRY_AC_FLAG_COPY))
660
err = GPG_ERR_INV_ARG;
663
if (idx < data->data_n)
665
if (flags & GCRY_AC_FLAG_COPY)
667
/* Return copies to the user. */
669
name_return = gcry_strdup (data->data[idx].name);
671
mpi_return = gcry_mpi_copy (data->data[idx].mpi);
673
if (! (name_return && mpi_return))
678
gcry_mpi_release (mpi_return);
679
err = GPG_ERR_ENOMEM;
684
name_return = (char *) data->data[idx].name;
685
mpi_return = data->data[idx].mpi;
689
err = GPG_ERR_NO_DATA;
426
err = gcry_error (GPG_ERR_INV_ARG);
430
if (idx >= data->data_n)
432
err = gcry_error (GPG_ERR_INV_ARG);
436
if (flags & GCRY_AC_FLAG_COPY)
438
/* Return copies to the user. */
441
name_cp = gcry_strdup (data->data[idx].name);
444
err = gcry_error_from_errno (errno);
700
return gcry_error (err);
450
mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
453
err = gcry_error_from_errno (errno);
460
*name = name_cp ? name_cp : data->data[idx].name;
462
*mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
469
gcry_mpi_release (mpi_cp);
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
480
_gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
481
const char **identifiers)
483
gcry_sexp_t sexp_new;
486
size_t sexp_buffer_n;
487
size_t identifiers_n;
499
/* Calculate size of S-expression representation. */
503
while (identifiers[i])
505
/* For each identifier, we add "(<IDENTIFIER>)". */
506
sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
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. */
517
data_n = _gcry_ac_data_length (data);
518
for (i = 0; i < data_n; i++)
520
err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
523
/* For each MPI we add "(<LABEL> %m)". */
524
sexp_buffer_n += 1 + strlen (label) + 4;
529
/* Allocate buffer. */
531
sexp_buffer = gcry_malloc (sexp_buffer_n);
534
err = gcry_error_from_errno (errno);
543
/* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)). */
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",
553
/* Add special list. */
554
sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
558
arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
561
err = gcry_error_from_errno (errno);
564
for (i = 0; i < data_n; i++)
566
err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
569
sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
571
arg_list[i] = &data->data[i].mpi;
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, ")");
584
/* Add closing braces for special list. */
585
sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
589
err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
597
gcry_free (sexp_buffer);
598
gcry_free (arg_list);
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
607
_gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
608
const char **identifiers)
610
gcry_ac_data_t data_set_new;
612
gcry_sexp_t sexp_cur;
613
gcry_sexp_t sexp_tmp;
629
/* Process S-expression/identifiers. */
633
for (i = 0; identifiers[i]; i++)
635
/* Next identifier. Extract first data item from
637
data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
639
if (! ((data_n == strlen (identifiers[i]))
640
&& (! strncmp (data, identifiers[i], data_n))))
642
/* Identifier mismatch -> error. */
643
err = gcry_error (GPG_ERR_INV_SEXP);
647
/* Identifier matches. Now we have to distinguish two
650
(i) we are at the last identifier:
653
(ii) we are not at the last identifier:
654
extract next element, which is supposed to be a
657
if (! identifiers[i + 1])
658
/* Last identifier. */
662
/* Not the last identifier, extract next sublist. */
664
sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
667
/* Missing sublist. */
668
err = gcry_error (GPG_ERR_INV_SEXP);
672
/* Release old SEXP_CUR, in case it is not equal to the
674
if (sexp_cur != sexp)
675
gcry_sexp_release (sexp_cur);
677
/* Make SEXP_CUR point to the new current sublist. */
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. */
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. */
702
/* Since there is no identifiers list, the list of named MPI
703
values is not prefixed with a list name, therefore the offset
707
/* Create data set from S-expression data. */
709
err = gcry_ac_data_new (&data_set_new);
713
/* Figure out amount of named MPIs in SEXP_CUR. */
715
sexp_n = gcry_sexp_length (sexp_cur) - skip_name;
719
/* Extracte the named MPIs sequentially. */
720
for (i = 0; i < sexp_n; i++)
722
/* Store next S-Expression pair, which is supposed to consist of
723
a name and an MPI value, in SEXP_TMP. */
725
sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name);
728
err = gcry_error (GPG_ERR_INV_SEXP);
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);
737
err = gcry_error_from_errno (errno);
740
memcpy (string, data, data_n);
743
/* Extract MPI value. */
744
mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
747
err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
751
/* Store named MPI in data_set_new. */
752
err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
756
/* gcry_free (string); */
758
/* gcry_mpi_release (mpi); */
761
gcry_sexp_release (sexp_tmp);
767
*data_set = data_set_new;
771
if (sexp_cur != sexp)
772
gcry_sexp_release (sexp_cur);
773
gcry_sexp_release (sexp_tmp);
774
gcry_mpi_release (mpi);
778
gcry_ac_data_destroy (data_set_new);
785
_gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
787
unsigned char *mpi_buffer;
800
data_n = _gcry_ac_data_length (data);
801
for (i = 0; i < data_n; i++)
803
err = gcry_ac_data_get_index (data, 0, i, &name, &mpi);
806
log_error ("failed to dump data set");
810
err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi);
813
log_error ("failed to dump data set");
817
log_printf ("%s%s%s: %s\n",
818
prefix ? prefix : "",
822
gcry_free (mpi_buffer);
826
gcry_free (mpi_buffer);
829
/* Dump the named MPI values contained in the data set DATA to
830
Libgcrypt's logging stream. */
832
gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
834
_gcry_ac_data_dump (prefix, data);
703
837
/* Destroys any values contained in the data set DATA. */
705
gcry_ac_data_clear (gcry_ac_data_t data)
839
_gcry_ac_data_clear (gcry_ac_data_t data)
841
ac_data_values_destroy (data);
707
842
gcry_free (data->data);
708
843
data->data = NULL;
709
844
data->data_n = 0;
850
* Implementation of `ac io' objects.
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
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)
860
memset (ac_io, 0, sizeof (*ac_io));
862
assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
863
assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
870
case GCRY_AC_IO_READABLE:
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);
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 *);
884
case GCRY_AC_IO_WRITABLE:
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 *);
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 *);
901
/* Initialize AC_IO according to MODE, TYPE and the variable list of
902
arguments. The list of variable arguments to specify depends on
905
_gcry_ac_io_init (gcry_ac_io_t *ac_io,
906
gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
911
_gcry_ac_io_init_va (ac_io, mode, type, ap);
916
/* Write to the IO object AC_IO BUFFER_N bytes from BUFFER. Return
917
zero on success or error code. */
919
_gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
923
assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
928
case GCRY_AC_IO_STRING:
932
if (*ac_io->io.writable.string.data)
934
p = gcry_realloc (*ac_io->io.writable.string.data,
935
*ac_io->io.writable.string.data_n + buffer_n);
937
err = gcry_error_from_errno (errno);
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;
948
if (gcry_is_secure (buffer))
949
p = gcry_malloc_secure (buffer_n);
951
p = gcry_malloc (buffer_n);
953
err = gcry_error_from_errno (errno);
956
memcpy (p, buffer, buffer_n);
957
*ac_io->io.writable.string.data = p;
958
*ac_io->io.writable.string.data_n = buffer_n;
964
case GCRY_AC_IO_CALLBACK:
965
err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque,
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. */
978
_gcry_ac_io_read (gcry_ac_io_t *ac_io,
979
unsigned int nread, unsigned char *buffer, size_t *buffer_n)
983
assert (ac_io->mode == GCRY_AC_IO_READABLE);
988
case GCRY_AC_IO_STRING:
990
size_t bytes_available;
991
size_t bytes_to_read;
994
bytes_available = ac_io->io.readable.string.data_n - nread;
995
bytes_wanted = *buffer_n;
997
if (bytes_wanted > bytes_available)
998
bytes_to_read = bytes_available;
1000
bytes_to_read = bytes_wanted;
1002
memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read);
1003
*buffer_n = bytes_to_read;
1008
case GCRY_AC_IO_CALLBACK:
1009
err = (*ac_io->io.readable.callback.cb)
1010
(ac_io->io.readable.callback.opaque, buffer, buffer_n);
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
1022
_gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
1024
unsigned char *buffer_new;
1025
size_t buffer_new_n;
1026
unsigned char buf[BUFSIZ];
1036
buf_n = sizeof (buf);
1037
err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
1043
p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
1046
err = gcry_error_from_errno (errno);
1050
if (buffer_new != p)
1053
memcpy (buffer_new + buffer_new_n, buf, buf_n);
1054
buffer_new_n += buf_n;
1062
*buffer_n = buffer_new_n;
1063
*buffer = buffer_new;
1068
gcry_free (buffer_new);
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
1077
_gcry_ac_io_process (gcry_ac_io_t *ac_io,
1078
gcry_ac_data_write_cb_t cb, void *opaque)
1080
unsigned char buffer[BUFSIZ];
1089
buffer_n = sizeof (buffer);
1090
err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
1095
err = (*cb) (opaque, buffer, buffer_n);
1110
* Functions for converting data between the native ac and the
1111
* S-expression structure used by the pk interface.
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:
1119
(ALGORITHM <list of named MPI values>)) */
1121
ac_data_extract (const char *identifier, const char *algorithm,
1122
gcry_sexp_t sexp, gcry_ac_data_t *data)
1125
gcry_sexp_t value_sexp;
1126
gcry_sexp_t data_sexp;
1128
gcry_mpi_t value_mpi;
1130
const char *data_raw;
1132
gcry_ac_data_t data_new;
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))
1145
err = gcry_error (GPG_ERR_INV_SEXP);
1149
/* Extract inner S-expression. */
1150
data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
1153
err = gcry_error (GPG_ERR_INV_SEXP);
1157
/* Count data elements. */
1158
data_sexp_n = gcry_sexp_length (data_sexp);
1161
/* Allocate new data set. */
1162
err = _gcry_ac_data_new (&data_new);
1166
/* Iterate through list of data elements and add them to the data
1168
for (i = 0; i < data_sexp_n; i++)
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);
1175
err = gcry_error (GPG_ERR_INV_SEXP);
1179
/* Extract the name. */
1180
data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
1183
err = gcry_error (GPG_ERR_INV_SEXP);
1187
/* Extract the MPI value. */
1188
value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
1191
err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
1195
/* Duplicate the name. */
1196
value_name = gcry_malloc (data_raw_n + 1);
1199
err = gcry_error_from_errno (errno);
1202
strncpy (value_name, data_raw, data_raw_n);
1203
value_name[data_raw_n] = 0;
1205
err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
1209
gcry_sexp_release (value_sexp);
1222
/* Deallocate resources. */
1225
_gcry_ac_data_destroy (data_new);
1226
gcry_mpi_release (value_mpi);
1227
gcry_free (value_name);
1228
gcry_sexp_release (value_sexp);
1230
gcry_sexp_release (data_sexp);
1235
/* Construct an S-expression from the DATA and store it in
1236
DATA_SEXP. The S-expression will be of the following structure:
1238
(IDENTIFIER [(flags [...])]
1239
(ALGORITHM <list of named MPI values>)) */
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)
1245
unsigned int data_length;
1246
gcry_sexp_t sexp_new;
1248
size_t sexp_format_n;
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));
1263
err = gcry_error_from_errno (errno);
1267
/* Fill list with MPIs. */
1268
for (i = 0; i < data_length; i++)
1270
char **nameaddr = &data->data[i].name;
1272
arg_list[(i * 2) + 0] = nameaddr;
1273
arg_list[(i * 2) + 1] = &data->data[i].mpi;
1276
/* Calculate size of format string. */
1278
+ (include_flags ? 7 : 0)
1279
+ (algorithm ? (2 + strlen (algorithm)) : 0)
1280
+ strlen (identifier));
1282
for (i = 0; i < data_length; i++)
1283
/* Per-element sizes. */
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;
1293
sexp_format = gcry_malloc (sexp_format_n);
1296
err = gcry_error_from_errno (errno);
1300
/* Construct the format string. */
1303
strcat (sexp_format, "(");
1304
strcat (sexp_format, identifier);
1307
strcat (sexp_format, "(flags");
1308
for (i = 0; i < DIM (ac_flags); i++)
1309
if (flags & ac_flags[i].number)
1311
strcat (sexp_format, " ");
1312
strcat (sexp_format, ac_flags[i].string);
1314
strcat (sexp_format, ")");
1318
strcat (sexp_format, "(");
1319
strcat (sexp_format, algorithm);
1321
for (i = 0; i < data_length; i++)
1322
strcat (sexp_format, "(%s%m)");
1324
strcat (sexp_format, ")");
1325
strcat (sexp_format, ")");
1327
/* Create final S-expression. */
1328
err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
1336
/* Deallocate resources. */
1337
gcry_free (sexp_format);
1338
gcry_free (arg_list);
1340
gcry_sexp_release (sexp_new);
715
1348
* Handle management.
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. */
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)
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;
732
1366
algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
733
1367
if (! algorithm_name)
734
err = GPG_ERR_PUBKEY_ALGO;
736
if (! err) /* Acquire reference to the pubkey module. */
737
err = _gcry_pk_module_lookup (algorithm, &module);
742
handle_new = gcry_malloc (sizeof (struct gcry_ac_handle));
744
err = gpg_err_code_from_errno (errno);
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;
758
/* Deallocate resources. */
760
_gcry_pk_module_release (module);
763
return gcry_error (err);
1369
err = gcry_error (GPG_ERR_PUBKEY_ALGO);
1373
/* Acquire reference to the pubkey module. */
1374
err = _gcry_pk_module_lookup (algorithm, &module);
1379
handle_new = gcry_malloc (sizeof (*handle_new));
1382
err = gcry_error_from_errno (errno);
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;
1395
/* Deallocate resources. */
1397
_gcry_pk_module_release (module);
766
1403
/* Destroys the handle HANDLE. */
768
gcry_ac_close (gcry_ac_handle_t handle)
1405
_gcry_ac_close (gcry_ac_handle_t handle)
770
1407
/* Release reference to pubkey module. */
781
1418
* Key management.
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. */
787
gcry_ac_key_init (gcry_ac_key_t *key,
788
gcry_ac_handle_t handle,
789
gcry_ac_key_type_t type,
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)
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;
798
key_new = gcry_malloc (sizeof (struct gcry_ac_key));
1435
key_new = gcry_malloc (sizeof (*key_new));
800
err = gpg_err_code_from_errno (errno);
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);
812
err = gcry_ac_data_copy_internal (&data_new, data);
818
key_new->data_sexp = data_sexp;
819
key_new->data = data_new;
820
key_new->type = type;
825
/* Deallocate resources. */
829
gcry_sexp_release (data_sexp);
832
return gcry_error (err);
1438
err = gcry_error_from_errno (errno);
1442
/* Copy data set. */
1443
err = _gcry_ac_data_copy (&data_new, data);
1448
key_new->data = data_new;
1449
key_new->type = type;
1455
/* Deallocate resources. */
1456
gcry_free (key_new);
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. */
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,
1470
gcry_ac_key_pair_t *key_pair,
1471
gcry_mpi_t **misc_data)
844
gcry_err_code_t err = GPG_ERR_NO_ERROR;
846
gcry_ac_key_pair_t key_pair_new = NULL;
848
gcry_sexp_t genkey_sexp_request = NULL;
849
gcry_sexp_t genkey_sexp_reply = NULL;
851
char *genkey_format = NULL;
852
size_t genkey_format_n = 0;
854
void **arg_list = NULL;
855
size_t arg_list_n = 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;
1482
char *genkey_format;
1483
size_t genkey_format_n;
1491
key_data_secret = NULL;
1492
key_data_public = NULL;
1495
genkey_format = NULL;
1497
genkey_sexp_request = NULL;
1498
genkey_sexp_reply = NULL;
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);
867
key_pair_new->secret = gcry_malloc (sizeof (struct gcry_ac_key));
868
key_pair_new->public = gcry_malloc (sizeof (struct gcry_ac_key));
870
if (! (key_pair_new->secret || key_pair_new->public))
871
err = gpg_err_code_from_errno (errno);
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;
885
/* Calculate size of the format string, that is used for
886
creating the request S-expression. */
887
genkey_format_n = 23;
889
/* Respect any relevant algorithm specific commands. */
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;
895
/* Create format string. */
896
genkey_format = gcry_malloc (genkey_format_n);
898
err = gpg_err_code_from_errno (errno);
901
/* Fill format string. */
903
strcat (genkey_format, "(genkey(%s(nbits%d)");
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, "))");
914
/* Build list of argument pointers, the algorithm name and the
915
nbits are needed always. */
918
/* Now the algorithm specific arguments. */
920
for (i = 0; gcry_ac_key_generate_specs[i].algorithm; i++)
921
if (handle->algorithm == gcry_ac_key_generate_specs[i].algorithm)
925
arg_list = gcry_malloc (sizeof (void *) * arg_list_n);
927
err = gpg_err_code_from_errno (errno);
930
/* Fill argument list. */
934
arg_list[0] = (void *) &handle->algorithm_name;
935
arg_list[1] = (void *) &nbits;
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)
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 *)
946
+ gcry_ac_key_generate_specs[i].offset);
952
/* Construct final request S-expression. */
953
err = gcry_err_code (gcry_sexp_build_array (&genkey_sexp_request, NULL,
954
genkey_format, arg_list));
957
/* Perform genkey operation. */
958
err = gcry_err_code (gcry_pk_genkey (&genkey_sexp_reply,
959
genkey_sexp_request));
964
key_pair_new->secret->data_sexp = gcry_sexp_find_token (genkey_sexp_reply,
966
if (! key_pair_new->secret->data_sexp)
967
err = GPG_ERR_INTERNAL;
971
key_pair_new->public->data_sexp = gcry_sexp_find_token (genkey_sexp_reply,
973
if (! key_pair_new->public->data_sexp)
974
err = GPG_ERR_INTERNAL;
977
/* Extract key material. */
979
err = gcry_ac_data_extract ("private-key", handle->algorithm_name,
980
key_pair_new->secret->data_sexp,
981
&key_pair_new->secret->data);
983
err = gcry_ac_data_extract ("public-key", handle->algorithm_name,
984
key_pair_new->public->data_sexp,
985
&key_pair_new->public->data);
1504
err = gcry_error_from_errno (errno);
1508
/* Allocate keys. */
1509
key_secret = gcry_malloc (sizeof (*key_secret));
1512
err = gcry_error_from_errno (errno);
1515
key_public = gcry_malloc (sizeof (*key_public));
1518
err = gcry_error_from_errno (errno);
1522
/* Calculate size of the format string, that is used for creating
1523
the request S-expression. */
1524
genkey_format_n = 22;
1526
/* Respect any relevant algorithm specific commands. */
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;
1532
/* Create format string. */
1533
genkey_format = gcry_malloc (genkey_format_n);
1534
if (! genkey_format)
1536
err = gcry_error_from_errno (errno);
1540
/* Fill format string. */
1542
strcat (genkey_format, "(genkey(%s(nbits%d)");
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, "))");
1549
/* Build list of argument pointers, the algorithm name and the nbits
1550
are always needed. */
1553
/* Now the algorithm specific arguments. */
1555
for (i = 0; i < DIM (ac_key_generate_specs); i++)
1556
if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1559
/* Allocate list. */
1560
arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
1563
err = gcry_error_from_errno (errno);
1567
arg_list[0] = (void *) &handle->algorithm_name;
1568
arg_list[1] = (void *) &nbits;
1570
for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
1571
if (handle->algorithm == ac_key_generate_specs[i].algorithm)
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. */
1582
/* Construct final request S-expression. */
1583
err = gcry_sexp_build_array (&genkey_sexp_request,
1584
NULL, genkey_format, arg_list);
1588
/* Perform genkey operation. */
1589
err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
1593
key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
1596
err = gcry_error (GPG_ERR_INTERNAL);
1599
err = ac_data_extract ("private-key", handle->algorithm_name,
1600
key_sexp, &key_data_secret);
1604
gcry_sexp_release (key_sexp);
1605
key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
1608
err = gcry_error (GPG_ERR_INTERNAL);
1611
err = ac_data_extract ("public-key", handle->algorithm_name,
1612
key_sexp, &key_data_public);
990
*key_pair = key_pair_new;
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;
1628
/* Deallocate resources. */
1630
gcry_free (genkey_format);
1631
gcry_free (arg_list);
1632
gcry_sexp_release (genkey_sexp_request);
1633
gcry_sexp_release (genkey_sexp_reply);
993
/* Deallocate resources. */
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);
1002
gcry_free (key_pair_new);
1006
gcry_free (arg_list);
1009
gcry_free (genkey_format);
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);
1017
return gcry_error (err);
1020
1646
/* Returns the key of type WHICH out of the key pair KEY_PAIR. */
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)
1025
gcry_ac_key_t key = NULL;
1029
1655
case GCRY_AC_KEY_SECRET:
1030
1656
key = key_pair->secret;
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. */
1273
gcry_ac_data_sign (gcry_ac_handle_t handle,
1276
gcry_ac_data_t *data_signature)
1953
_gcry_ac_data_sign (gcry_ac_handle_t handle,
1956
gcry_ac_data_t *data_signature)
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;
1967
sexp_request = NULL;
1283
1971
if (key->type != GCRY_AC_KEY_SECRET)
1284
err = GPG_ERR_WRONG_KEY_USAGE;
1287
/* Create S-expression holding the data. */
1288
err = gcry_sexp_build (&sexp_request, NULL,
1289
"(data(flags)(value%m))", data);
1292
err = gcry_pk_sign (&sexp_reply, sexp_request, key->data_sexp);
1296
err = gcry_ac_data_extract ("sig-val", handle->algorithm_name,
1297
sexp_reply, &ac_data);
1973
err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1977
err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1978
handle->algorithm_name, key->data, &sexp_key);
1982
err = _gcry_ac_data_new (&data_value);
1986
err = _gcry_ac_data_set (data_value, 0, "value", data);
1990
/* Create S-expression holding the data. */
1991
err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
1996
err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
2001
err = ac_data_extract ("sig-val", handle->algorithm_name,
2002
sexp_reply, &data_signed);
1302
gcry_sexp_release (sexp_request);
1304
gcry_sexp_release (sexp_reply);
1307
*data_signature = ac_data;
2007
*data_signature = data_signed;
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);
1309
2016
return gcry_error (err);
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. */
1316
gcry_ac_data_verify (gcry_ac_handle_t handle,
1319
gcry_ac_data_t data_signature)
2024
_gcry_ac_data_verify (gcry_ac_handle_t handle,
2027
gcry_ac_data_t data_signature)
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;
2035
sexp_signature = NULL;
2040
err = ac_data_construct ("public-key", 0, 0,
2041
handle->algorithm_name, key->data, &sexp_key);
1325
2045
if (key->type != GCRY_AC_KEY_PUBLIC)
1326
err = GPG_ERR_WRONG_KEY_USAGE;
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);
1334
/* Construct S-expression holding the data. */
1335
err = gcry_sexp_build (&sexp_data, NULL,
1336
"(data(flags)(value%m))", data);
1339
/* Verify signature. */
1340
err = gcry_pk_verify (sexp_request, sexp_data, key->data_sexp);
1345
gcry_sexp_release (sexp_request);
1347
gcry_sexp_release (sexp_data);
2047
err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
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);
2057
err = _gcry_ac_data_new (&data_value);
2061
err = _gcry_ac_data_set (data_value, 0, "value", data);
2065
/* Construct S-expression holding the data. */
2066
err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
2070
/* Verify signature. */
2071
err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
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);
1349
2080
return gcry_error (err);
2087
* Implementation of encoding methods (em).
2090
/* Type for functions that encode or decode (hence the name) a
2092
typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
2094
gcry_ac_io_t *ac_io_read,
2095
gcry_ac_io_t *ac_io_write);
2097
/* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
2098
random bytes of random level LEVEL. */
2100
em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
2101
gcry_random_level_t level)
2103
unsigned char *buffer_rand;
2104
unsigned int buffer_rand_n;
2109
for (i = 0; i < buffer_n; i++)
2115
for (i = zeros = 0; i < buffer_n; i++)
2121
/* Get random bytes. */
2122
buffer_rand_n = zeros + (zeros / 128);
2123
buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
2125
/* Substitute zeros with non-zero random bytes. */
2126
for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
2129
while ((j < buffer_rand_n) && (! buffer_rand[j]))
2131
if (j < buffer_rand_n)
2133
buffer[i] = buffer_rand[j++];
2139
gcry_free (buffer_rand);
2145
/* Encode a message according to the Encoding Method for Encryption
2146
`PKCS-V1_5' (EME-PKCS-V1_5). */
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)
2152
gcry_ac_eme_pkcs_v1_5_t *options;
2154
unsigned char *buffer;
2167
err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
2171
/* Figure out key length in bytes. */
2172
k = options->key_size / 8;
2176
/* Key is too short for message. */
2177
err = gcry_error (GPG_ERR_TOO_SHORT);
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
2186
/* Allocate buffer. */
2187
buffer = gcry_malloc (k - 1);
2190
err = gcry_error_from_errno (errno);
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. */
2199
em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
2201
/* Concatenate PS, the message M, and other padding to form an
2202
encoded message EM of length k octets as:
2204
EM = 0x00 || 0x02 || PS || 0x00 || M. */
2207
buffer[ps_n + 1] = 0x00;
2208
memcpy (buffer + ps_n + 2, m, m_n);
2210
err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
2220
/* Decode a message according to the Encoding Method for Encryption
2221
`PKCS-V1_5' (EME-PKCS-V1_5). */
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)
2227
gcry_ac_eme_pkcs_v1_5_t *options;
2228
unsigned char *buffer;
2241
err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
2245
/* Figure out key size. */
2246
k = options->key_size / 8;
2248
/* Search for zero byte. */
2249
for (i = 0; (i < em_n) && em[i]; i++);
2251
/* According to this encoding method, the first byte of the encoded
2252
message should be zero. This byte is lost. */
2255
&& (em_n == (k - 1))
2260
err = gcry_error (GPG_ERR_DECRYPT_FAILED);
2265
buffer = gcry_malloc (em_n - i);
2268
err = gcry_error_from_errno (errno);
2272
memcpy (buffer, em + i, em_n - i);
2273
err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
2284
emsa_pkcs_v1_5_encode_data_cb (void *opaque,
2285
unsigned char *buffer, size_t buffer_n)
2287
gcry_md_hd_t md_handle;
2290
gcry_md_write (md_handle, buffer, buffer_n);
2296
/* Encode a message according to the Encoding Method for Signatures
2297
with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5). */
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)
2303
gcry_ac_emsa_pkcs_v1_5_t *options;
2312
unsigned char *buffer;
2314
unsigned char asn[100]; /* FIXME, always enough? */
2326
/* Create hashing handle and get the necessary information. */
2327
err = gcry_md_open (&md, options->md, 0);
2332
err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
2336
h_n = gcry_md_get_algo_dlen (options->md);
2338
err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
2342
h = gcry_md_read (md, 0);
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:
2348
DigestInfo ::== SEQUENCE {
2349
digestAlgorithm AlgorithmIdentifier,
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. */
2358
t = gcry_malloc (t_n);
2361
err = gcry_error_from_errno (errno);
2365
for (i = 0; i < asn_n; i++)
2367
for (i = 0; i < h_n; i++)
2368
t[asn_n + i] = h[i];
2370
/* If emLen < tLen + 11, output "intended encoded message length
2371
too short" and stop. */
2372
if (options->em_n < t_n + 11)
2374
err = gcry_error (GPG_ERR_TOO_SHORT);
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
2381
ps_n = options->em_n - t_n - 3;
2382
ps = gcry_malloc (ps_n);
2385
err = gcry_error_from_errno (errno);
2388
for (i = 0; i < ps_n; i++)
2391
/* Concatenate PS, the DER encoding T, and other padding to form the
2392
encoded message EM as:
2394
EM = 0x00 || 0x01 || PS || 0x00 || T. */
2396
buffer_n = ps_n + t_n + 3;
2397
buffer = gcry_malloc (buffer_n);
2400
err = gcry_error_from_errno (errno);
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];
2412
err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
2425
/* `Actions' for data_dencode(). */
2426
typedef enum dencode_action
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. */
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)
2446
gcry_ac_em_t method;
2447
gcry_ac_em_dencode_t encode;
2448
gcry_ac_em_dencode_t decode;
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 },
2460
methods_n = sizeof (methods) / sizeof (*methods);
2462
for (i = 0; i < methods_n; i++)
2463
if (methods[i].method == method)
2467
err = gcry_error (GPG_ERR_NOT_FOUND); /* FIXME? */
2475
if (methods[i].encode)
2477
err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
2481
if (methods[i].decode)
2483
err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
2487
err = gcry_error (GPG_ERR_INV_ARG);
2496
/* Encode a message according to the encoding method METHOD. OPTIONS
2497
must be a pointer to a method-specific structure
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)
2505
return ac_data_dencode (method, DATA_ENCODE, flags, options,
2506
ac_io_read, ac_io_write);
2509
/* Dencode a message according to the encoding method METHOD. OPTIONS
2510
must be a pointer to a method-specific structure
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)
2518
return ac_data_dencode (method, DATA_DECODE, flags, options,
2519
ac_io_read, ac_io_write);
2522
/* Convert an MPI into an octet string. */
2524
_gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2526
unsigned long digit;
2533
base = gcry_mpi_new (0);
2534
gcry_mpi_set_ui (base, 256);
2537
m = gcry_mpi_copy (mpi);
2538
while (gcry_mpi_cmp_ui (m, 0))
2541
gcry_mpi_div (m, NULL, m, base, 0);
2544
gcry_mpi_set (m, mpi);
2545
d = gcry_mpi_new (0);
2546
for (i = 0; (i < n) && (i < os_n); i++)
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);
2554
for (; i < os_n; i++)
2555
os[os_n - i - 1] = 0;
2557
gcry_mpi_release (base);
2558
gcry_mpi_release (d);
2559
gcry_mpi_release (m);
2562
/* Convert an MPI into an newly allocated octet string. */
2564
_gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
2566
unsigned char *buffer;
2571
nbits = gcry_mpi_get_nbits (mpi);
2572
buffer_n = (nbits + 7) / 8;
2573
buffer = gcry_malloc (buffer_n);
2576
err = gcry_error_from_errno (errno);
2580
_gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
2591
/* Convert an octet string into an MPI. */
2593
_gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
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);
2606
for (i = 0; i < os_n; i++)
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);
2613
gcry_mpi_release (xi);
2614
gcry_mpi_release (a);
2616
gcry_mpi_set (mpi, x);
2617
gcry_mpi_release (x); /* FIXME: correct? */
2623
* Implementation of Encryption Schemes (ES) and Signature Schemes
2624
* with Appendix (SSA).
2627
/* Schemes consist of two things: encoding methods and cryptographic
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
2636
typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
2641
/* The `dencode_prepare' function for ES-PKCS-V1_5. */
2643
ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2644
void *opts, void *opts_em)
2646
gcry_ac_eme_pkcs_v1_5_t *options_em;
2652
err = _gcry_ac_key_get_nbits (handle, key, &nbits);
2656
options_em = opts_em;
2657
options_em->key_size = nbits;
2664
/* The `dencode_prepare' function for SSA-PKCS-V1_5. */
2666
ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2667
void *opts, void *opts_em)
2669
gcry_ac_emsa_pkcs_v1_5_t *options_em;
2670
gcry_ac_ssa_pkcs_v1_5_t *options;
2674
options_em = opts_em;
2677
err = _gcry_ac_key_get_nbits (handle, key, &k);
2682
options_em->md = options->md;
2683
options_em->em_n = k;
2690
/* Type holding the information about each supported
2691
Encryption/Signature Scheme. */
2692
typedef struct ac_scheme
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;
2700
/* List of supported Schemes. */
2701
static ac_scheme_t ac_schemes[] =
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) }
2711
/* Lookup a scheme by it's ID. */
2712
static ac_scheme_t *
2713
ac_scheme_get (gcry_ac_scheme_t scheme)
2715
ac_scheme_t *ac_scheme;
2718
for (i = 0; i < DIM (ac_schemes); i++)
2719
if (scheme == ac_schemes[i].scheme)
2721
if (i == DIM (ac_schemes))
2724
ac_scheme = ac_schemes + i;
2729
/* Prepares the encoding/decoding by creating an according option
2732
ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
2733
ac_scheme_t scheme, void **opts_em)
2738
options_em = gcry_malloc (scheme.options_em_n);
2741
err = gcry_error_from_errno (errno);
2745
err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
2749
*opts_em = options_em;
2759
/* Convert a data set into a single MPI; currently, this is only
2760
supported for data sets containing a single MPI. */
2762
ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
2768
elems = _gcry_ac_data_length (data);
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);
2779
err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
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. */
2797
_gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
2798
gcry_ac_scheme_t scheme_id,
2799
unsigned int flags, void *opts,
2801
gcry_ac_io_t *io_message,
2802
gcry_ac_io_t *io_cipher)
2808
gcry_mpi_t mpi_plain;
2809
gcry_ac_data_t data_encrypted;
2810
gcry_mpi_t mpi_encrypted;
2811
unsigned char *buffer;
2814
ac_scheme_t *scheme;
2818
data_encrypted = NULL;
2819
mpi_encrypted = NULL;
2825
scheme = ac_scheme_get (scheme_id);
2828
err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
2832
if (key->type != GCRY_AC_KEY_PUBLIC)
2834
err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2838
err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
2842
_gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
2843
GCRY_AC_IO_STRING, &em, &em_n);
2845
err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
2846
io_message, &io_em);
2850
mpi_plain = gcry_mpi_snew (0);
2851
gcry_ac_os_to_mpi (mpi_plain, em, em_n);
2853
err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
2857
err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
2861
err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
2865
err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
2869
gcry_ac_data_destroy (data_encrypted);
2870
gcry_mpi_release (mpi_encrypted);
2871
gcry_mpi_release (mpi_plain);
2872
gcry_free (opts_em);
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. */
2886
_gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
2887
gcry_ac_scheme_t scheme_id,
2888
unsigned int flags, void *opts,
2890
gcry_ac_io_t *io_cipher,
2891
gcry_ac_io_t *io_message)
2895
gcry_ac_data_t data_encrypted;
2898
gcry_mpi_t mpi_encrypted;
2899
gcry_mpi_t mpi_decrypted;
2901
ac_scheme_t *scheme;
2903
size_t elements_enc_n;
2909
data_encrypted = NULL;
2910
mpi_encrypted = NULL;
2911
mpi_decrypted = NULL;
2912
elements_enc = NULL;
2917
scheme = ac_scheme_get (scheme_id);
2920
err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
2924
if (key->type != GCRY_AC_KEY_SECRET)
2926
err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2930
err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
2934
mpi_encrypted = gcry_mpi_snew (0);
2935
gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
2937
err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
2941
elements_enc_n = strlen (elements_enc);
2942
if (elements_enc_n != 1)
2945
err = gcry_error (GPG_ERR_CONFLICT);
2949
err = _gcry_ac_data_new (&data_encrypted);
2953
err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
2954
elements_enc, mpi_encrypted);
2958
err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
2962
err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
2966
err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
2970
_gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
2971
GCRY_AC_IO_STRING, em, em_n);
2973
err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
2974
&io_em, io_message);
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);
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. */
2999
_gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
3000
gcry_ac_scheme_t scheme_id,
3001
unsigned int flags, void *opts,
3003
gcry_ac_io_t *io_message,
3004
gcry_ac_io_t *io_signature)
3008
gcry_ac_data_t data_signed;
3013
unsigned char *buffer;
3015
gcry_mpi_t mpi_signed;
3016
ac_scheme_t *scheme;
3027
if (key->type != GCRY_AC_KEY_SECRET)
3029
err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3033
scheme = ac_scheme_get (scheme_id);
3036
/* FIXME: adjust api of scheme_get in respect to err codes. */
3037
err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3041
err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3045
_gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3046
GCRY_AC_IO_STRING, &em, &em_n);
3048
err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3049
io_message, &io_em);
3053
mpi = gcry_mpi_new (0);
3054
_gcry_ac_os_to_mpi (mpi, em, em_n);
3056
err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
3060
err = ac_data_set_to_mpi (data_signed, &mpi_signed);
3064
err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
3068
err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
3072
_gcry_ac_data_destroy (data_signed);
3073
gcry_mpi_release (mpi_signed);
3074
gcry_mpi_release (mpi);
3075
gcry_free (opts_em);
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. */
3089
_gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
3090
gcry_ac_scheme_t scheme_id,
3091
unsigned int flags, void *opts,
3093
gcry_ac_io_t *io_message,
3094
gcry_ac_io_t *io_signature)
3098
gcry_ac_data_t data_signed;
3102
gcry_mpi_t mpi_signature;
3103
gcry_mpi_t mpi_data;
3104
ac_scheme_t *scheme;
3106
size_t elements_sig_n;
3112
mpi_signature = NULL;
3113
elements_sig = NULL;
3120
if (key->type != GCRY_AC_KEY_PUBLIC)
3122
err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3126
scheme = ac_scheme_get (scheme_id);
3129
err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3133
err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3137
_gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3138
GCRY_AC_IO_STRING, &em, &em_n);
3140
err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3141
io_message, &io_em);
3145
mpi_data = gcry_mpi_new (0);
3146
_gcry_ac_os_to_mpi (mpi_data, em, em_n);
3148
err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
3152
mpi_signature = gcry_mpi_new (0);
3153
_gcry_ac_os_to_mpi (mpi_signature, s, s_n);
3155
err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
3159
elements_sig_n = strlen (elements_sig);
3160
if (elements_sig_n != 1)
3163
err = gcry_error (GPG_ERR_CONFLICT);
3167
err = _gcry_ac_data_new (&data_signed);
3171
err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
3172
elements_sig, mpi_signature);
3176
gcry_mpi_release (mpi_signature);
3177
mpi_signature = NULL;
3179
err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
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);
1355
3196
* General functions.
1358
/* Stores the textual representation of the algorithm whose id is
1359
given in ALGORITHM in NAME. */
1361
gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name)
1363
gcry_err_code_t err = GPG_ERR_NO_ERROR;
1366
n = gcry_pk_algo_name (algorithm);
1370
err = GPG_ERR_PUBKEY_ALGO;
1372
return gcry_error (err);
1375
/* Stores the numeric ID of the algorithm whose textual representation
1376
is contained in NAME in ALGORITHM. */
1378
gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm)
1380
gcry_err_code_t err = GPG_ERR_NO_ERROR;
1383
algo = gcry_pk_map_name (name);
1387
err = GPG_ERR_PUBKEY_ALGO;
1389
return gcry_error (err);
1392
3199
gcry_err_code_t
1393
3200
_gcry_ac_init (void)