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