Remove macro hacks for internal vs. external functions. Part 2 and last.
[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_ecc,
42 #endif
43 #if USE_RSA
44     &_gcry_pubkey_spec_rsa,
45 #endif
46 #if USE_DSA
47     &_gcry_pubkey_spec_dsa,
48 #endif
49 #if USE_ELGAMAL
50     &_gcry_pubkey_spec_elg,
51 #endif
52     NULL
53   };
54
55
56 static int
57 map_algo (int algo)
58 {
59  switch (algo)
60    {
61    case GCRY_PK_ECDSA:
62    case GCRY_PK_ECDH:
63      return GCRY_PK_ECC;
64    case GCRY_PK_ELG_E:
65      return GCRY_PK_ELG;
66    default:
67      return algo;
68    }
69 }
70
71
72
73 /* Return the spec structure for the public key algorithm ALGO.  For
74    an unknown algorithm NULL is returned.  */
75 static gcry_pk_spec_t *
76 spec_from_algo (int algo)
77 {
78   int idx;
79   gcry_pk_spec_t *spec;
80
81   algo = map_algo (algo);
82
83   for (idx = 0; (spec = pubkey_list[idx]); idx++)
84     if (algo == spec->algo)
85       return spec;
86   return NULL;
87 }
88
89
90 /* Return the spec structure for the public key algorithm with NAME.
91    For an unknown name NULL is returned.  */
92 static gcry_pk_spec_t *
93 spec_from_name (const char *name)
94 {
95   gcry_pk_spec_t *spec;
96   int idx;
97   const char **aliases;
98
99   for (idx=0; (spec = pubkey_list[idx]); idx++)
100     {
101       if (!stricmp (name, spec->name))
102         return spec;
103       for (aliases = spec->aliases; *aliases; aliases++)
104         if (!stricmp (name, *aliases))
105           return spec;
106     }
107
108   return NULL;
109 }
110
111
112
113 /* Given the s-expression SEXP with the first element be either
114  * "private-key" or "public-key" return the spec structure for it.  We
115  * look through the list to find a list beginning with "private-key"
116  * or "public-key" - the first one found is used.  If WANT_PRIVATE is
117  * set the function will only succeed if a private key has been given.
118  * On success the spec is stored at R_SPEC.  On error NULL is stored
119  * at R_SPEC and an error code returned.  If R_PARMS is not NULL and
120  * the fucntion returns success, the parameter list below
121  * "private-key" or "public-key" is stored there and the caller must
122  * call gcry_sexp_release on it.
123  */
124 static gcry_err_code_t
125 spec_from_sexp (gcry_sexp_t sexp, int want_private,
126                 gcry_pk_spec_t **r_spec, gcry_sexp_t *r_parms)
127 {
128   gcry_sexp_t list, l2;
129   char *name;
130   gcry_pk_spec_t *spec;
131
132   *r_spec = NULL;
133   if (r_parms)
134     *r_parms = NULL;
135
136   /* Check that the first element is valid.  If we are looking for a
137      public key but a private key was supplied, we allow the use of
138      the private key anyway.  The rationale for this is that the
139      private key is a superset of the public key.  */
140   list = sexp_find_token (sexp, want_private? "private-key":"public-key", 0);
141   if (!list && !want_private)
142     list = sexp_find_token (sexp, "private-key", 0);
143   if (!list)
144     return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
145
146   l2 = sexp_cadr (list);
147   sexp_release (list);
148   list = l2;
149   name = sexp_nth_string (list, 0);
150   if (!name)
151     {
152       sexp_release ( list );
153       return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
154     }
155   spec = spec_from_name (name);
156   xfree (name);
157   if (!spec)
158     {
159       sexp_release (list);
160       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
161     }
162   *r_spec = spec;
163   if (r_parms)
164     *r_parms = list;
165   else
166     sexp_release (list);
167   return 0;
168 }
169
170
171
172 /* Disable the use of the algorithm ALGO.  This is not thread safe and
173    should thus be called early.  */
174 static void
175 disable_pubkey_algo (int algo)
176 {
177   gcry_pk_spec_t *spec = spec_from_algo (algo);
178
179   if (spec)
180     spec->flags.disabled = 1;
181 }
182
183
184 \f
185 /*
186  * Map a string to the pubkey algo
187  */
188 int
189 _gcry_pk_map_name (const char *string)
190 {
191   gcry_pk_spec_t *spec;
192
193   if (!string)
194     return 0;
195   spec = spec_from_name (string);
196   if (!spec)
197     return 0;
198   if (spec->flags.disabled)
199     return 0;
200   return spec->algo;
201 }
202
203
204 /* Map the public key algorithm whose ID is contained in ALGORITHM to
205    a string representation of the algorithm name.  For unknown
206    algorithm IDs this functions returns "?". */
207 const char *
208 _gcry_pk_algo_name (int algo)
209 {
210   gcry_pk_spec_t *spec;
211
212   spec = spec_from_algo (algo);
213   if (spec)
214     return spec->name;
215   return "?";
216 }
217
218
219 /****************
220  * A USE of 0 means: don't care.
221  */
222 static gcry_err_code_t
223 check_pubkey_algo (int algo, unsigned use)
224 {
225   gcry_err_code_t err = 0;
226   gcry_pk_spec_t *spec;
227
228   spec = spec_from_algo (algo);
229   if (spec)
230     {
231       if (((use & GCRY_PK_USAGE_SIGN)
232            && (! (spec->use & GCRY_PK_USAGE_SIGN)))
233           || ((use & GCRY_PK_USAGE_ENCR)
234               && (! (spec->use & GCRY_PK_USAGE_ENCR))))
235         err = GPG_ERR_WRONG_PUBKEY_ALGO;
236     }
237   else
238     err = GPG_ERR_PUBKEY_ALGO;
239
240   return err;
241 }
242
243
244 /****************
245  * Return the number of public key material numbers
246  */
247 static int
248 pubkey_get_npkey (int algo)
249 {
250   gcry_pk_spec_t *spec = spec_from_algo (algo);
251
252   return spec? strlen (spec->elements_pkey) : 0;
253 }
254
255
256 /****************
257  * Return the number of secret key material numbers
258  */
259 static int
260 pubkey_get_nskey (int algo)
261 {
262   gcry_pk_spec_t *spec = spec_from_algo (algo);
263
264   return spec? strlen (spec->elements_skey) : 0;
265 }
266
267
268 /****************
269  * Return the number of signature material numbers
270  */
271 static int
272 pubkey_get_nsig (int algo)
273 {
274   gcry_pk_spec_t *spec = spec_from_algo (algo);
275
276   return spec? strlen (spec->elements_sig) : 0;
277 }
278
279 /****************
280  * Return the number of encryption material numbers
281  */
282 static int
283 pubkey_get_nenc (int algo)
284 {
285   gcry_pk_spec_t *spec = spec_from_algo (algo);
286
287   return spec? strlen (spec->elements_enc) : 0;
288 }
289
290
291 \f
292 /*
293    Do a PK encrypt operation
294
295    Caller has to provide a public key as the SEXP pkey and data as a
296    SEXP with just one MPI in it. Alternatively S_DATA might be a
297    complex S-Expression, similar to the one used for signature
298    verification.  This provides a flag which allows to handle PKCS#1
299    block type 2 padding.  The function returns a sexp which may be
300    passed to to pk_decrypt.
301
302    Returns: 0 or an errorcode.
303
304    s_data = See comment for _gcry_pk_util_data_to_mpi
305    s_pkey = <key-as-defined-in-sexp_to_key>
306    r_ciph = (enc-val
307                (<algo>
308                  (<param_name1> <mpi>)
309                  ...
310                  (<param_namen> <mpi>)
311                ))
312
313 */
314 gcry_err_code_t
315 _gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
316 {
317   gcry_err_code_t rc;
318   gcry_pk_spec_t *spec;
319   gcry_sexp_t keyparms;
320
321   *r_ciph = NULL;
322
323   rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
324   if (rc)
325     goto leave;
326
327   if (spec->encrypt)
328     rc = spec->encrypt (r_ciph, s_data, keyparms);
329   else
330     rc = GPG_ERR_NOT_IMPLEMENTED;
331
332  leave:
333   sexp_release (keyparms);
334   return rc;
335 }
336
337
338 /*
339    Do a PK decrypt operation
340
341    Caller has to provide a secret key as the SEXP skey and data in a
342    format as created by gcry_pk_encrypt.  For historic reasons the
343    function returns simply an MPI as an S-expression part; this is
344    deprecated and the new method should be used which returns a real
345    S-expressionl this is selected by adding at least an empty flags
346    list to S_DATA.
347
348    Returns: 0 or an errorcode.
349
350    s_data = (enc-val
351               [(flags [raw, pkcs1, oaep])]
352               (<algo>
353                 (<param_name1> <mpi>)
354                 ...
355                 (<param_namen> <mpi>)
356               ))
357    s_skey = <key-as-defined-in-sexp_to_key>
358    r_plain= Either an incomplete S-expression without the parentheses
359             or if the flags list is used (even if empty) a real S-expression:
360             (value PLAIN).  In raw mode (or no flags given) the returned value
361             is to be interpreted as a signed MPI, thus it may have an extra
362             leading zero octet even if not included in the original data.
363             With pkcs1 or oaep decoding enabled the returned value is a
364             verbatim octet string.
365  */
366 gcry_err_code_t
367 _gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
368 {
369   gcry_err_code_t rc;
370   gcry_pk_spec_t *spec;
371   gcry_sexp_t keyparms;
372
373   *r_plain = NULL;
374
375   rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
376   if (rc)
377     goto leave;
378
379   if (spec->decrypt)
380     rc = spec->decrypt (r_plain, s_data, keyparms);
381   else
382     rc = GPG_ERR_NOT_IMPLEMENTED;
383
384  leave:
385   sexp_release (keyparms);
386   return rc;
387 }
388
389
390
391 /*
392    Create a signature.
393
394    Caller has to provide a secret key as the SEXP skey and data
395    expressed as a SEXP list hash with only one element which should
396    instantly be available as a MPI. Alternatively the structure given
397    below may be used for S_HASH, it provides the abiliy to pass flags
398    to the operation; the flags defined by now are "pkcs1" which does
399    PKCS#1 block type 1 style padding and "pss" for PSS encoding.
400
401    Returns: 0 or an errorcode.
402             In case of 0 the function returns a new SEXP with the
403             signature value; the structure of this signature depends on the
404             other arguments but is always suitable to be passed to
405             gcry_pk_verify
406
407    s_hash = See comment for _gcry-pk_util_data_to_mpi
408
409    s_skey = <key-as-defined-in-sexp_to_key>
410    r_sig  = (sig-val
411               (<algo>
412                 (<param_name1> <mpi>)
413                 ...
414                 (<param_namen> <mpi>))
415              [(hash algo)])
416
417   Note that (hash algo) in R_SIG is not used.
418 */
419 gcry_err_code_t
420 _gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
421 {
422   gcry_err_code_t rc;
423   gcry_pk_spec_t *spec;
424   gcry_sexp_t keyparms;
425
426   *r_sig = NULL;
427
428   rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
429   if (rc)
430     goto leave;
431
432   if (spec->sign)
433     rc = spec->sign (r_sig, s_hash, keyparms);
434   else
435     rc = GPG_ERR_NOT_IMPLEMENTED;
436
437  leave:
438   sexp_release (keyparms);
439   return rc;
440 }
441
442
443 /*
444    Verify a signature.
445
446    Caller has to supply the public key pkey, the signature sig and his
447    hashvalue data.  Public key has to be a standard public key given
448    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
449    must be an S-Exp like the one in sign too.  */
450 gcry_err_code_t
451 _gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
452 {
453   gcry_err_code_t rc;
454   gcry_pk_spec_t *spec;
455   gcry_sexp_t keyparms;
456
457   rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
458   if (rc)
459     goto leave;
460
461   if (spec->verify)
462     rc = spec->verify (s_sig, s_hash, keyparms);
463   else
464     rc = GPG_ERR_NOT_IMPLEMENTED;
465
466  leave:
467   sexp_release (keyparms);
468   return rc;
469 }
470
471
472 /*
473    Test a key.
474
475    This may be used either for a public or a secret key to see whether
476    the internal structure is okay.
477
478    Returns: 0 or an errorcode.
479
480    NOTE: We currently support only secret key checking. */
481 gcry_err_code_t
482 _gcry_pk_testkey (gcry_sexp_t s_key)
483 {
484   gcry_err_code_t rc;
485   gcry_pk_spec_t *spec;
486   gcry_sexp_t keyparms;
487
488   rc = spec_from_sexp (s_key, 1, &spec, &keyparms);
489   if (rc)
490     goto leave;
491
492   if (spec->check_secret_key)
493     rc = spec->check_secret_key (keyparms);
494   else
495     rc = GPG_ERR_NOT_IMPLEMENTED;
496
497  leave:
498   sexp_release (keyparms);
499   return rc;
500 }
501
502
503 /*
504   Create a public key pair and return it in r_key.
505   How the key is created depends on s_parms:
506   (genkey
507    (algo
508      (parameter_name_1 ....)
509       ....
510      (parameter_name_n ....)
511   ))
512   The key is returned in a format depending on the
513   algorithm. Both, private and secret keys are returned
514   and optionally some additional informatin.
515   For elgamal we return this structure:
516   (key-data
517    (public-key
518      (elg
519         (p <mpi>)
520         (g <mpi>)
521         (y <mpi>)
522      )
523    )
524    (private-key
525      (elg
526         (p <mpi>)
527         (g <mpi>)
528         (y <mpi>)
529         (x <mpi>)
530      )
531    )
532    (misc-key-info
533       (pm1-factors n1 n2 ... nn)
534    ))
535  */
536 gcry_err_code_t
537 _gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
538 {
539   gcry_pk_spec_t *spec = NULL;
540   gcry_sexp_t list = NULL;
541   gcry_sexp_t l2 = NULL;
542   char *name = NULL;
543   gcry_err_code_t rc;
544
545   *r_key = NULL;
546
547   list = sexp_find_token (s_parms, "genkey", 0);
548   if (!list)
549     {
550       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
551       goto leave;
552     }
553
554   l2 = sexp_cadr (list);
555   sexp_release (list);
556   list = l2;
557   l2 = NULL;
558   if (! list)
559     {
560       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
561       goto leave;
562     }
563
564   name = _gcry_sexp_nth_string (list, 0);
565   if (!name)
566     {
567       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
568       goto leave;
569     }
570
571   spec = spec_from_name (name);
572   xfree (name);
573   name = NULL;
574   if (!spec)
575     {
576       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
577       goto leave;
578     }
579
580   if (spec->generate)
581     rc = spec->generate (list, r_key);
582   else
583     rc = GPG_ERR_NOT_IMPLEMENTED;
584
585  leave:
586   sexp_release (list);
587   xfree (name);
588   sexp_release (l2);
589
590   return rc;
591 }
592
593
594 /*
595    Get the number of nbits from the public key.
596
597    Hmmm: Should we have really this function or is it better to have a
598    more general function to retrieve different properties of the key?  */
599 unsigned int
600 _gcry_pk_get_nbits (gcry_sexp_t key)
601 {
602   gcry_pk_spec_t *spec;
603   gcry_sexp_t parms;
604   unsigned int nbits;
605
606   /* Parsing KEY might be considered too much overhead.  For example
607      for RSA we would only need to look at P and stop parsing right
608      away.  However, with ECC things are more complicate in that only
609      a curve name might be specified.  Thus we need to tear the sexp
610      apart. */
611
612   if (spec_from_sexp (key, 0, &spec, &parms))
613     return 0; /* Error - 0 is a suitable indication for that.  */
614
615   nbits = spec->get_nbits (parms);
616   sexp_release (parms);
617   return nbits;
618 }
619
620
621 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
622    key parameters expressed in a way depending on the algorithm.
623
624    ARRAY must either be 20 bytes long or NULL; in the latter case a
625    newly allocated array of that size is returned, otherwise ARRAY or
626    NULL is returned to indicate an error which is most likely an
627    unknown algorithm.  The function accepts public or secret keys. */
628 unsigned char *
629 _gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
630 {
631   gcry_sexp_t list = NULL;
632   gcry_sexp_t l2 = NULL;
633   gcry_pk_spec_t *spec = NULL;
634   const char *s;
635   char *name = NULL;
636   int idx;
637   const char *elems;
638   gcry_md_hd_t md = NULL;
639   int okay = 0;
640
641   /* Check that the first element is valid. */
642   list = sexp_find_token (key, "public-key", 0);
643   if (! list)
644     list = sexp_find_token (key, "private-key", 0);
645   if (! list)
646     list = sexp_find_token (key, "protected-private-key", 0);
647   if (! list)
648     list = sexp_find_token (key, "shadowed-private-key", 0);
649   if (! list)
650     return NULL; /* No public- or private-key object. */
651
652   l2 = sexp_cadr (list);
653   sexp_release (list);
654   list = l2;
655   l2 = NULL;
656
657   name = _gcry_sexp_nth_string (list, 0);
658   if (!name)
659     goto fail; /* Invalid structure of object. */
660
661   spec = spec_from_name (name);
662   if (!spec)
663     goto fail; /* Unknown algorithm.  */
664
665   elems = spec->elements_grip;
666   if (!elems)
667     goto fail; /* No grip parameter.  */
668
669   if (_gcry_md_open (&md, GCRY_MD_SHA1, 0))
670     goto fail;
671
672   if (spec->comp_keygrip)
673     {
674       /* Module specific method to compute a keygrip.  */
675       if (spec->comp_keygrip (md, list))
676         goto fail;
677     }
678   else
679     {
680       /* Generic method to compute a keygrip.  */
681       for (idx = 0, s = elems; *s; s++, idx++)
682         {
683           const char *data;
684           size_t datalen;
685           char buf[30];
686
687           l2 = sexp_find_token (list, s, 1);
688           if (! l2)
689             goto fail;
690           data = sexp_nth_data (l2, 1, &datalen);
691           if (! data)
692             goto fail;
693
694           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
695           _gcry_md_write (md, buf, strlen (buf));
696           _gcry_md_write (md, data, datalen);
697           sexp_release (l2);
698           l2 = NULL;
699           _gcry_md_write (md, ")", 1);
700         }
701     }
702
703   if (!array)
704     {
705       array = xtrymalloc (20);
706       if (! array)
707         goto fail;
708     }
709
710   memcpy (array, _gcry_md_read (md, GCRY_MD_SHA1), 20);
711   okay = 1;
712
713  fail:
714   xfree (name);
715   sexp_release (l2);
716   _gcry_md_close (md);
717   sexp_release (list);
718   return okay? array : NULL;
719 }
720
721
722 \f
723 const char *
724 _gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
725 {
726   const char *result = NULL;
727   gcry_pk_spec_t *spec;
728   gcry_sexp_t keyparms = NULL;
729
730   if (r_nbits)
731     *r_nbits = 0;
732
733   if (key)
734     {
735       iterator = 0;
736
737       if (spec_from_sexp (key, 0, &spec, &keyparms))
738         return NULL;
739     }
740   else
741     {
742       spec = spec_from_name ("ecc");
743       if (!spec)
744         return NULL;
745     }
746
747   if (spec->get_curve)
748     result = spec->get_curve (keyparms, iterator, r_nbits);
749
750   sexp_release (keyparms);
751   return result;
752 }
753
754
755 \f
756 gcry_sexp_t
757 _gcry_pk_get_param (int algo, const char *name)
758 {
759   gcry_sexp_t result = NULL;
760   gcry_pk_spec_t *spec = NULL;
761
762   algo = map_algo (algo);
763
764   if (algo != GCRY_PK_ECC)
765     return NULL;
766
767   spec = spec_from_name ("ecc");
768   if (spec)
769     {
770       if (spec && spec->get_curve_param)
771         result = spec->get_curve_param (name);
772     }
773   return result;
774 }
775
776
777 \f
778 gcry_err_code_t
779 _gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
780 {
781   gcry_err_code_t rc = 0;
782
783   switch (cmd)
784     {
785     case GCRYCTL_DISABLE_ALGO:
786       /* This one expects a buffer pointing to an integer with the
787          algo number.  */
788       if ((! buffer) || (buflen != sizeof (int)))
789         rc = GPG_ERR_INV_ARG;
790       else
791         disable_pubkey_algo (*((int *) buffer));
792       break;
793
794     default:
795       rc = GPG_ERR_INV_OP;
796     }
797
798   return rc;
799 }
800
801
802 /* Return information about the given algorithm
803
804    WHAT selects the kind of information returned:
805
806     GCRYCTL_TEST_ALGO:
807         Returns 0 when the specified algorithm is available for use.
808         Buffer must be NULL, nbytes  may have the address of a variable
809         with the required usage of the algorithm. It may be 0 for don't
810         care or a combination of the GCRY_PK_USAGE_xxx flags;
811
812     GCRYCTL_GET_ALGO_USAGE:
813         Return the usage flags for the given algo.  An invalid algo
814         returns 0.  Disabled algos are ignored here because we
815         only want to know whether the algo is at all capable of
816         the usage.
817
818    Note: Because this function is in most cases used to return an
819    integer value, we can make it easier for the caller to just look at
820    the return value.  The caller will in all cases consult the value
821    and thereby detecting whether a error occurred or not (i.e. while
822    checking the block size) */
823 gcry_err_code_t
824 _gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
825 {
826   gcry_err_code_t rc = 0;
827
828   switch (what)
829     {
830     case GCRYCTL_TEST_ALGO:
831       {
832         int use = nbytes ? *nbytes : 0;
833         if (buffer)
834           rc = GPG_ERR_INV_ARG;
835         else if (check_pubkey_algo (algorithm, use))
836           rc = GPG_ERR_PUBKEY_ALGO;
837         break;
838       }
839
840     case GCRYCTL_GET_ALGO_USAGE:
841       {
842         gcry_pk_spec_t *spec;
843
844         spec = spec_from_algo (algorithm);
845         *nbytes = spec? spec->use : 0;
846         break;
847       }
848
849     case GCRYCTL_GET_ALGO_NPKEY:
850       {
851         /* FIXME?  */
852         int npkey = pubkey_get_npkey (algorithm);
853         *nbytes = npkey;
854         break;
855       }
856     case GCRYCTL_GET_ALGO_NSKEY:
857       {
858         /* FIXME?  */
859         int nskey = pubkey_get_nskey (algorithm);
860         *nbytes = nskey;
861         break;
862       }
863     case GCRYCTL_GET_ALGO_NSIGN:
864       {
865         /* FIXME?  */
866         int nsign = pubkey_get_nsig (algorithm);
867         *nbytes = nsign;
868         break;
869       }
870     case GCRYCTL_GET_ALGO_NENCR:
871       {
872         /* FIXME?  */
873         int nencr = pubkey_get_nenc (algorithm);
874         *nbytes = nencr;
875         break;
876       }
877
878     default:
879       rc = GPG_ERR_INV_OP;
880     }
881
882   return rc;
883 }
884
885
886 /* Return an S-expression representing the context CTX.  Depending on
887    the state of that context, the S-expression may either be a public
888    key, a private key or any other object used with public key
889    operations.  On success a new S-expression is stored at R_SEXP and
890    0 is returned, on error NULL is store there and an error code is
891    returned.  MODE is either 0 or one of the GCRY_PK_GET_xxx values.
892
893    As of now it only support certain ECC operations because a context
894    object is right now only defined for ECC.  Over time this function
895    will be extended to cover more algorithms.  Note also that the name
896    of the function is gcry_pubkey_xxx and not gcry_pk_xxx.  The idea
897    is that we will eventually provide variants of the existing
898    gcry_pk_xxx functions which will take a context parameter.   */
899 gcry_err_code_t
900 _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
901 {
902   mpi_ec_t ec;
903
904   if (!r_sexp)
905     return GPG_ERR_INV_VALUE;
906   *r_sexp = NULL;
907   switch (mode)
908     {
909     case 0:
910     case GCRY_PK_GET_PUBKEY:
911     case GCRY_PK_GET_SECKEY:
912       break;
913     default:
914       return GPG_ERR_INV_VALUE;
915     }
916   if (!ctx)
917     return GPG_ERR_NO_CRYPT_CTX;
918
919   ec = _gcry_ctx_find_pointer (ctx, CONTEXT_TYPE_EC);
920   if (ec)
921     return _gcry_pk_ecc_get_sexp (r_sexp, mode, ec);
922
923   return GPG_ERR_WRONG_CRYPT_CTX;
924 }
925
926
927 \f
928 /* Explicitly initialize this module.  */
929 gcry_err_code_t
930 _gcry_pk_init (void)
931 {
932   return 0;
933 }
934
935
936 /* Run the selftests for pubkey algorithm ALGO with optional reporting
937    function REPORT.  */
938 gpg_error_t
939 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
940 {
941   gcry_err_code_t ec;
942   gcry_pk_spec_t *spec;
943
944   algo = map_algo (algo);
945   spec = spec_from_algo (algo);
946   if (spec && !spec->flags.disabled && spec->selftest)
947     ec = spec->selftest (algo, extended, report);
948   else
949     {
950       ec = GPG_ERR_PUBKEY_ALGO;
951       /* Fixme: We need to change the report fucntion to allow passing
952          of an encryption mode (e.g. pkcs1, ecdsa, or ecdh).  */
953       if (report)
954         report ("pubkey", algo, "module",
955                 spec && !spec->flags.disabled?
956                 "no selftest available" :
957                 spec? "algorithm disabled" :
958                 "algorithm not found");
959     }
960
961   return gpg_error (ec);
962 }