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