* keygen.c: New.
[libgcrypt.git] / tests / keygen.c
1 /* keygen.c  -  key generation regression tests
2  *      Copyright (C) 2003 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdarg.h>
25 #include "../src/gcrypt.h"
26
27
28
29 static int verbose;
30 static int error_count;
31
32 static void
33 fail ( const char *format, ... )
34 {
35     va_list arg_ptr ;
36
37     va_start( arg_ptr, format ) ;
38     vfprintf (stderr, format, arg_ptr );
39     va_end(arg_ptr);
40     error_count++;
41 }
42
43 static void
44 die ( const char *format, ... )
45 {
46     va_list arg_ptr ;
47
48     va_start( arg_ptr, format ) ;
49     vfprintf (stderr, format, arg_ptr );
50     va_end(arg_ptr);
51     exit (1);
52 }
53
54
55 static void
56 print_mpi (const char *text, GcryMPI a)
57 {
58   char *buf;
59   void *bufaddr = &buf;
60   int rc;
61
62   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
63   if (rc)
64     fprintf (stderr, "%s=[error printing number: %s]\n",
65              text, gcry_strerror (rc));
66   else
67     {
68       fprintf (stderr, "%s=0x%s\n", text, buf);
69       gcry_free (buf);
70     }
71 }
72
73
74
75 static void
76 check_generated_rsa_key (GcrySexp key, unsigned long expected_e)
77 {
78   GcrySexp skey, pkey, list;
79
80  pkey = gcry_sexp_find_token (key, "public-key", 0);
81   if (!pkey)
82     fail ("public part missing in return value\n");
83   else
84     {
85       GcryMPI e = NULL;
86
87       list = gcry_sexp_find_token (pkey, "e", 0);
88       if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) )
89         fail ("public exponent not found\n");
90       else if (gcry_mpi_cmp_ui (e, expected_e)) 
91         {
92           print_mpi ("e", e);
93           fail ("public exponent is not %lu\n", expected_e);
94         }
95       gcry_sexp_release (list);
96       gcry_mpi_release (e);
97       gcry_sexp_release (pkey);
98     }
99  
100   skey = gcry_sexp_find_token (key, "private-key", 0);
101   if (!skey)
102     fail ("private part missing in return value\n");
103   else
104     {
105       int rc = gcry_pk_testkey (skey);
106       if (rc)
107         fail ("gcry_pk_testkey failed: %s\n", gcry_strerror (rc));
108       gcry_sexp_release (skey);
109     }
110
111  }
112
113 static void
114 check_rsa_keys (void)
115 {
116   GcrySexp keyparm, key;
117   int rc;
118
119   if (verbose)
120     fprintf (stderr, "creating 1024 bit RSA key using old interface\n");
121   rc = gcry_sexp_new (&keyparm, 
122                       "(genkey\n"
123                       " (rsa\n"
124                       "  (nbits 4:1024)\n"
125                       " ))", 0, 1);
126   if (rc)
127     die ("error creating S-expression: %s\n", gcry_strerror (rc));
128   rc = gcry_pk_genkey (&key, keyparm);
129   gcry_sexp_release (keyparm);
130   if (rc)
131     die ("error generating RSA key: %s\n", gcry_strerror (rc));
132
133   check_generated_rsa_key (key, 65537);
134   gcry_sexp_release (key);
135
136   if (verbose)
137     fprintf (stderr, "creating 512 bit RSA key with e=257\n");
138   rc = gcry_sexp_new (&keyparm, 
139                       "(genkey\n"
140                       " (rsa\n"
141                       "  (nbits 3:512)\n"
142                       "  (rsa-use-e 3:257)\n"
143                       " ))", 0, 1);
144   if (rc)
145     die ("error creating S-expression: %s\n", gcry_strerror (rc));
146   rc = gcry_pk_genkey (&key, keyparm);
147   gcry_sexp_release (keyparm);
148   if (rc)
149     die ("error generating RSA key: %s\n", gcry_strerror (rc));
150
151   check_generated_rsa_key (key, 257);
152   gcry_sexp_release (key);
153
154   if (verbose)
155     fprintf (stderr, "creating 512 bit RSA key with default e=41\n");
156   rc = gcry_sexp_new (&keyparm, 
157                       "(genkey\n"
158                       " (rsa\n"
159                       "  (nbits 3:512)\n"
160                       "  (rsa-use-e 1:0)\n"
161                       " ))", 0, 1);
162   if (rc)
163     die ("error creating S-expression: %s\n", gcry_strerror (rc));
164   rc = gcry_pk_genkey (&key, keyparm);
165   gcry_sexp_release (keyparm);
166   if (rc)
167     die ("error generating RSA key: %s\n", gcry_strerror (rc));
168
169   check_generated_rsa_key (key, 41);
170   gcry_sexp_release (key);
171
172 }
173
174
175
176
177 int
178 main (int argc, char **argv)
179 {
180   int debug = 0;
181
182   if (argc > 1 && !strcmp (argv[1], "--verbose"))
183     verbose = 1;
184   else if (argc > 1 && !strcmp (argv[1], "--debug"))
185     verbose = debug = 1;
186
187   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
188   if (!gcry_check_version (GCRYPT_VERSION))
189     die ("version mismatch\n");
190   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
191   if (debug)
192     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
193   /* No valuable keys are create, so we can speed up our RNG. */
194   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
195   check_rsa_keys ();
196   
197   return error_count? 1:0;
198 }