45ceece4281a27599e09361de653a0f03df62a28
[libgcrypt.git] / tests / ac-schemes.c
1 /* ac-schemes.c - Tests for ES/SSA
2    Copyright (C) 2003, 2005 Free Software Foundation, Inc.
3
4    This file is part of Libgcrypt.
5
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19    USA.  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30
31 #include "../src/gcrypt.h"
32
33 static unsigned int verbose;
34
35 static void
36 die (const char *format, ...)
37 {
38   va_list arg_ptr ;
39
40   va_start( arg_ptr, format ) ;
41   vfprintf (stderr, format, arg_ptr );
42   va_end(arg_ptr);
43   exit (1);
44 }
45
46 typedef struct scheme_spec
47 {
48   unsigned int idx;
49   gcry_ac_scheme_t scheme;
50   unsigned int flags;
51   unsigned char *m;
52   size_t m_n;
53 } scheme_spec_t;
54
55 #define SCHEME_SPEC_FLAG_GET_OPTS (1 << 0)
56
57 #define FILL(idx, scheme, flags, m) \
58     { idx, GCRY_AC_##scheme, flags, m, sizeof (m) }
59
60 scheme_spec_t es_specs[] =
61   {
62     FILL (0, ES_PKCS_V1_5, 0, "foobar"),
63     FILL (1, ES_PKCS_V1_5, 0, "")
64   };
65
66 scheme_spec_t ssa_specs[] =
67   {
68     FILL (0, SSA_PKCS_V1_5, SCHEME_SPEC_FLAG_GET_OPTS, "foobar")
69   };
70
71 #undef FILL
72
73 gcry_err_code_t
74 scheme_get_opts (scheme_spec_t specs, void **opts)
75 {
76   gcry_err_code_t err = GPG_ERR_NO_ERROR;
77   void *opts_new = NULL;
78
79   switch (specs.scheme)
80     {
81     case GCRY_AC_SSA_PKCS_V1_5:
82       {
83         gcry_ac_ssa_pkcs_v1_5_t *opts_pkcs_v1_5 = NULL;
84         
85         opts_new = gcry_malloc (sizeof (gcry_ac_ssa_pkcs_v1_5_t));
86         if (! opts_new)
87           err = gpg_err_code_from_errno (ENOMEM);
88         else
89           {
90             opts_pkcs_v1_5 = (gcry_ac_ssa_pkcs_v1_5_t *) opts_new;
91
92             switch (specs.idx)
93               {
94               case 0:
95                 opts_pkcs_v1_5->md = GCRY_MD_SHA1;
96                 break;
97               case 1:
98                 opts_pkcs_v1_5->md = GCRY_MD_MD5;
99                 break;
100               }
101           }
102       }
103     case GCRY_AC_ES_PKCS_V1_5:
104       break;
105     }
106
107   if (! err)
108     *opts = opts_new;
109
110   return err;
111 }
112
113 gcry_error_t
114 es_check (gcry_ac_handle_t handle, scheme_spec_t spec,
115           gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
116 {
117   gcry_error_t err = GPG_ERR_NO_ERROR;
118   unsigned char *c = NULL, *m2 = NULL;
119   size_t c_n = 0, m2_n = 0;
120   void *opts = NULL;
121   gcry_ac_io_t io_m;
122   gcry_ac_io_t io_c;
123   gcry_ac_io_t io_m2;
124   
125   if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS)
126     err = scheme_get_opts (spec, &opts);
127   if (! err)
128     {
129       c = NULL;
130       m2 = NULL;
131
132       gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
133                        GCRY_AC_IO_STRING, spec.m, spec.m_n);
134       gcry_ac_io_init (&io_c, GCRY_AC_IO_WRITABLE,
135                        GCRY_AC_IO_STRING, &c, &c_n);
136
137       err = gcry_ac_data_encrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0, opts, key_public,
138                                          &io_m, &io_c);
139       if (! err)
140         {
141           gcry_ac_io_init (&io_c, GCRY_AC_IO_READABLE,
142                            GCRY_AC_IO_STRING, c, c_n);
143           gcry_ac_io_init (&io_m2, GCRY_AC_IO_WRITABLE,
144                            GCRY_AC_IO_STRING, &m2, &m2_n);
145
146           err = gcry_ac_data_decrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0,
147                                              opts, key_secret, &io_c, &io_m2);
148         }
149       if (! err)
150         assert ((spec.m_n == m2_n) && (! strncmp (spec.m, m2, spec.m_n)));
151
152       if (c)
153         gcry_free (c);
154       if (m2)
155         gcry_free (m2);
156     }
157
158   if (opts)
159     gcry_free (opts);
160
161   return err;
162 }
163
164 gcry_error_t
165 ssa_check (gcry_ac_handle_t handle, scheme_spec_t spec,
166            gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
167 {
168   gcry_error_t err = GPG_ERR_NO_ERROR;
169   unsigned char *s = NULL;
170   size_t s_n = 0;
171   void *opts = NULL;
172   gcry_ac_io_t io_m;
173   gcry_ac_io_t io_s;
174   
175   if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS)
176     err = scheme_get_opts (spec, &opts);
177   if (! err)
178     {
179       gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
180                        GCRY_AC_IO_STRING, spec.m, spec.m_n);
181       gcry_ac_io_init (&io_s, GCRY_AC_IO_WRITABLE,
182                        GCRY_AC_IO_STRING, &s, &s_n);
183
184       err = gcry_ac_data_sign_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_secret,
185                                       &io_m, &io_s);
186       if (! err)
187         {
188           gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
189                            GCRY_AC_IO_STRING, spec.m, spec.m_n);
190           gcry_ac_io_init (&io_s, GCRY_AC_IO_READABLE,
191                            GCRY_AC_IO_STRING, s, s_n);
192           err = gcry_ac_data_verify_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_public,
193                                             &io_m, &io_s);
194         }
195       assert (! err);
196
197       if (s)
198         gcry_free (s);
199     }
200
201   if (opts)
202     gcry_free (opts);
203
204   return err;
205 }
206
207 void
208 es_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
209 {
210   gcry_error_t err = GPG_ERR_NO_ERROR;
211   unsigned int i = 0;
212
213   for (i = 0; (i < (sizeof (es_specs) / sizeof (*es_specs))) && (! err); i++)
214     err = es_check (handle, es_specs[i], key_public, key_secret);
215
216   assert (! err);
217 }
218
219 void
220 ssa_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
221 {
222   gcry_error_t err = GPG_ERR_NO_ERROR;
223   unsigned int i = 0;
224
225   for (i = 0; (i < (sizeof (ssa_specs) / sizeof (*ssa_specs))) && (! err); i++)
226     err = ssa_check (handle, ssa_specs[i], key_public, key_secret);
227
228   assert (! err);
229 }
230
231 #define KEY_TYPE_PUBLIC (1 << 0)
232 #define KEY_TYPE_SECRET (1 << 1)
233
234 typedef struct key_spec
235 {
236   const char *name;
237   unsigned int flags;
238   const char *mpi_string;
239 } key_spec_t;
240
241 key_spec_t key_specs[] =
242   {
243     { "n", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
244       "e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
245       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
246       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
247       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251" },
248     { "e", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
249       "010001" },
250     { "d", KEY_TYPE_SECRET,
251       "046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
252       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
253       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
254       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" },
255     { "p", KEY_TYPE_SECRET,
256       "00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
257       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1" },
258     { "q", KEY_TYPE_SECRET,
259       "00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
260       "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361" },
261     { "u", KEY_TYPE_SECRET,
262       "304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
263       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" },
264     { NULL },
265   };
266
267 gcry_error_t
268 key_init (gcry_ac_key_type_t type, gcry_ac_key_t *key)
269 {
270   gcry_error_t err = GPG_ERR_NO_ERROR;
271   gcry_ac_data_t key_data = NULL;
272   gcry_ac_key_t key_new = NULL;
273   gcry_mpi_t mpi = NULL;
274   unsigned int i = 0;
275
276   err = gcry_ac_data_new (&key_data);
277   for (i = 0; key_specs[i].name && (! err); i++)
278     {
279       if (((type == GCRY_AC_KEY_PUBLIC) && (key_specs[i].flags & KEY_TYPE_PUBLIC))
280           || ((type == GCRY_AC_KEY_SECRET) && (key_specs[i].flags & KEY_TYPE_SECRET)))
281         {
282           err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, key_specs[i].mpi_string, 0, NULL);
283           if (! err)
284             {
285               gcry_ac_data_set (key_data, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
286                                 key_specs[i].name, mpi);
287               gcry_mpi_release (mpi);
288             }
289         }
290     }
291   if (! err)
292     err = gcry_ac_key_init (&key_new, NULL, type, key_data);
293
294   if (key_data)
295     gcry_ac_data_destroy (key_data);
296   
297   if (! err)
298     *key = key_new;
299
300   return err;
301 }
302
303 static void
304 check_run (void)
305 {
306   gcry_ac_handle_t handle = NULL;
307   gcry_error_t err = GPG_ERR_NO_ERROR;
308   gcry_ac_key_t key_public = NULL, key_secret = NULL;
309
310   err = key_init (GCRY_AC_KEY_PUBLIC, &key_public);
311   if (! err)
312     err = key_init (GCRY_AC_KEY_SECRET, &key_secret);
313   
314   if (! err)
315     err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
316   if (! err)
317     {
318       es_checks (handle, key_public, key_secret);
319       ssa_checks (handle, key_public, key_secret);
320     }
321   
322   assert (! err);
323 }
324
325 int
326 main (int argc, char **argv)
327 {
328   unsigned int debug = 0;
329
330   if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
331     verbose = 1;
332   else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
333     verbose = debug = 1;
334
335   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
336   if (! gcry_check_version (GCRYPT_VERSION))
337     die ("version mismatch\n");
338   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
339   if (debug)
340     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
341
342   check_run ();
343   
344   return 0;
345 }