-more libexec fixes for OpenSUSE
[oweals/gnunet.git] / src / util / test_crypto_rsa.c
1 /*
2      This file is part of GNUnet.
3      (C) 2002, 2003, 2004, 2006, 2009 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19
20 */
21 /**
22  * @file util/test_crypto_rsa.c
23  * @brief testcase for RSA public key crypto
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_common.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_signatures.h"
30
31 #define TESTSTRING "Hello World\0"
32 #define MAX_TESTVAL sizeof(struct GNUNET_CRYPTO_AesSessionKey)
33 #define ITER 25
34 #define KEYFILE "/tmp/test-gnunet-crypto-rsa.key"
35
36 #define PERF GNUNET_YES
37
38 static struct GNUNET_CRYPTO_RsaPrivateKey *key;
39
40
41 static int
42 testEncryptDecrypt ()
43 {
44   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
45   struct GNUNET_CRYPTO_RsaEncryptedData target;
46   char result[MAX_TESTVAL];
47   int i;
48   struct GNUNET_TIME_Absolute start;
49   int ok;
50
51   FPRINTF (stderr, "%s",  "W");
52   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
53   ok = 0;
54   start = GNUNET_TIME_absolute_get ();
55   for (i = 0; i < ITER; i++)
56   {
57     FPRINTF (stderr, "%s",  ".");
58     if (GNUNET_SYSERR ==
59         GNUNET_CRYPTO_rsa_encrypt (TESTSTRING, strlen (TESTSTRING) + 1, &pkey,
60                                    &target))
61     {
62       FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_encrypt returned SYSERR\n");
63       ok++;
64       continue;
65     }
66     if (-1 ==
67         GNUNET_CRYPTO_rsa_decrypt (key, &target, result,
68                                    strlen (TESTSTRING) + 1))
69     {
70       FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_decrypt returned SYSERR\n");
71       ok++;
72       continue;
73
74     }
75     if (strncmp (TESTSTRING, result, strlen (TESTSTRING)) != 0)
76     {
77       printf ("%s != %.*s - testEncryptDecrypt failed!\n", TESTSTRING,
78               (int) MAX_TESTVAL, result);
79       ok++;
80       continue;
81     }
82   }
83   printf ("%d RSA encrypt/decrypt operations %s (%d failures)\n", 
84           ITER,
85           GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES), 
86           ok);
87   if (ok == 0)
88     return GNUNET_OK;
89   return GNUNET_SYSERR;
90 }
91
92
93 #if PERF
94 static int
95 testEncryptPerformance ()
96 {
97   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
98   struct GNUNET_CRYPTO_RsaEncryptedData target;
99   int i;
100   struct GNUNET_TIME_Absolute start;
101   int ok;
102
103   FPRINTF (stderr, "%s",  "W");
104   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
105   ok = 0;
106   start = GNUNET_TIME_absolute_get ();
107   for (i = 0; i < ITER; i++)
108   {
109     FPRINTF (stderr, "%s",  ".");
110     if (GNUNET_SYSERR ==
111         GNUNET_CRYPTO_rsa_encrypt (TESTSTRING, strlen (TESTSTRING) + 1, &pkey,
112                                    &target))
113     {
114       FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_encrypt returned SYSERR\n");
115       ok++;
116       continue;
117     }
118   }
119   printf ("%d RSA encrypt operations %llu ms (%d failures)\n", ITER,
120           (unsigned long long)
121           GNUNET_TIME_absolute_get_duration (start).rel_value, ok);
122   if (ok != 0)
123     return GNUNET_SYSERR;
124   return GNUNET_OK;
125 }
126 #endif
127
128 static int
129 testEncryptDecryptSK ()
130 {
131   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
132   struct GNUNET_CRYPTO_RsaEncryptedData target;
133   struct GNUNET_CRYPTO_AesSessionKey insk;
134   struct GNUNET_CRYPTO_AesSessionKey outsk;
135   int i;
136   struct GNUNET_TIME_Absolute start;
137   int ok;
138
139   FPRINTF (stderr, "%s",  "W");
140   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
141   ok = 0;
142   start = GNUNET_TIME_absolute_get ();
143   for (i = 0; i < ITER; i++)
144   {
145     FPRINTF (stderr, "%s",  ".");
146     GNUNET_CRYPTO_aes_create_session_key (&insk);
147     if (GNUNET_SYSERR ==
148         GNUNET_CRYPTO_rsa_encrypt (&insk,
149                                    sizeof (struct GNUNET_CRYPTO_AesSessionKey),
150                                    &pkey, &target))
151     {
152       FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_encrypt returned SYSERR\n");
153       ok++;
154       continue;
155     }
156     if (-1 ==
157         GNUNET_CRYPTO_rsa_decrypt (key, &target, &outsk,
158                                    sizeof (struct GNUNET_CRYPTO_AesSessionKey)))
159     {
160       FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_decrypt returned SYSERR\n");
161       ok++;
162       continue;
163     }
164     if (0 !=
165         memcmp (&insk, &outsk, sizeof (struct GNUNET_CRYPTO_AesSessionKey)))
166     {
167       printf ("testEncryptDecryptSK failed!\n");
168       ok++;
169       continue;
170     }
171   }
172   printf ("%d RSA encrypt/decrypt SK operations %s (%d failures)\n", 
173           ITER,
174           GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES), 
175           ok);
176   if (ok != 0)
177     return GNUNET_SYSERR;
178   return GNUNET_OK;
179 }
180
181
182 static int
183 testSignVerify ()
184 {
185   struct GNUNET_CRYPTO_RsaSignature sig;
186   struct GNUNET_CRYPTO_RsaSignaturePurpose purp;
187   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
188   int i;
189   struct GNUNET_TIME_Absolute start;
190   int ok = GNUNET_OK;
191
192   FPRINTF (stderr, "%s",  "W");
193   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
194   start = GNUNET_TIME_absolute_get ();
195   purp.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose));
196   purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
197
198   for (i = 0; i < ITER; i++)
199   {
200     FPRINTF (stderr, "%s",  ".");
201     if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_sign (key, &purp, &sig))
202     {
203       FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_sign returned SYSERR\n");
204       ok = GNUNET_SYSERR;
205       continue;
206     }
207     if (GNUNET_SYSERR ==
208         GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST, &purp, &sig,
209                                   &pkey))
210     {
211       printf ("GNUNET_CRYPTO_rsa_verify failed!\n");
212       ok = GNUNET_SYSERR;
213       continue;
214     }
215     if (GNUNET_SYSERR !=
216         GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
217                                   &purp, &sig, &pkey))
218     {
219       printf ("GNUNET_CRYPTO_rsa_verify failed to fail!\n");
220       ok = GNUNET_SYSERR;
221       continue;
222     }
223   }
224   printf ("%d RSA sign/verify operations %s\n", ITER,
225           GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start), GNUNET_YES));
226   return ok;
227 }
228
229
230 #if PERF
231 static int
232 testSignPerformance ()
233 {
234   struct GNUNET_CRYPTO_RsaSignaturePurpose purp;
235   struct GNUNET_CRYPTO_RsaSignature sig;
236   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
237   int i;
238   struct GNUNET_TIME_Absolute start;
239   int ok = GNUNET_OK;
240
241   purp.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose));
242   purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
243   FPRINTF (stderr, "%s",  "W");
244   GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
245   start = GNUNET_TIME_absolute_get ();
246   for (i = 0; i < ITER; i++)
247   {
248     FPRINTF (stderr, "%s",  ".");
249     if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_sign (key, &purp, &sig))
250     {
251       FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_sign returned SYSERR\n");
252       ok = GNUNET_SYSERR;
253       continue;
254     }
255   }
256   printf ("%d RSA sign operations %llu ms\n", ITER,
257           (unsigned long long)
258           GNUNET_TIME_absolute_get_duration (start).rel_value);
259   return ok;
260 }
261 #endif
262
263
264 static int
265 testCreateFromFile ()
266 {
267   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded p1;
268   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded p2;
269
270   key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE);
271   GNUNET_assert (NULL != key);
272   GNUNET_CRYPTO_rsa_key_get_public (key, &p1);
273   GNUNET_CRYPTO_rsa_key_free (key);
274   key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE);
275   GNUNET_assert (NULL != key);
276   GNUNET_CRYPTO_rsa_key_get_public (key, &p2);
277   GNUNET_assert (0 == memcmp (&p1, &p2, sizeof (p1)));
278   GNUNET_CRYPTO_rsa_key_free (key);
279   GNUNET_assert (0 == UNLINK (KEYFILE));
280   key = GNUNET_CRYPTO_rsa_key_create_from_file (KEYFILE);
281   GNUNET_assert (NULL != key);
282   GNUNET_CRYPTO_rsa_key_get_public (key, &p2);
283   GNUNET_assert (0 != memcmp (&p1, &p2, sizeof (p1)));
284   return GNUNET_OK;
285 }
286
287
288 static void
289 key_cont (void *cls,
290           struct GNUNET_CRYPTO_RsaPrivateKey *pk,
291           const char *emsg)
292 {
293   const char *txt = cls;
294   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub1;
295   struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub2;
296
297   GNUNET_assert (0 == strcmp ("ok", txt));
298   GNUNET_CRYPTO_rsa_key_get_public (pk, &pub1);
299   GNUNET_CRYPTO_rsa_key_get_public (key, &pub2);
300   GNUNET_assert (0 == memcmp (&pub1, &pub2, 
301                               sizeof (pub1)));
302   GNUNET_CRYPTO_rsa_key_free (pk);
303 }
304
305
306 static void
307 test_async_creation (void *cls,
308                      const struct GNUNET_SCHEDULER_TaskContext *tc)
309 {
310   struct GNUNET_CRYPTO_RsaKeyGenerationContext *gc;
311
312   gc = GNUNET_CRYPTO_rsa_key_create_start (KEYFILE,
313                                            &key_cont, 
314                                            (void*) "bug");
315   GNUNET_CRYPTO_rsa_key_create_stop (gc);
316   gc = GNUNET_CRYPTO_rsa_key_create_start (KEYFILE,
317                                            &key_cont, 
318                                            (void*) "ok");
319 }
320
321
322 int
323 main (int argc, char *argv[])
324 {
325   int failureCount = 0;
326
327   GNUNET_log_setup ("test-crypto-rsa", "WARNING", NULL);
328   GNUNET_CRYPTO_random_disable_entropy_gathering ();
329   if (GNUNET_OK != testCreateFromFile ())
330     failureCount++;
331   GNUNET_SCHEDULER_run (&test_async_creation, NULL);
332 #if PERF
333   if (GNUNET_OK != testEncryptPerformance ())
334     failureCount++;
335   if (GNUNET_OK != testSignPerformance ())
336     failureCount++;
337 #endif
338   if (GNUNET_OK != testEncryptDecryptSK ())
339     failureCount++;
340   if (GNUNET_OK != testEncryptDecrypt ())
341     failureCount++;
342   if (GNUNET_OK != testSignVerify ())
343     failureCount++;
344   GNUNET_CRYPTO_rsa_key_free (key);
345   GNUNET_assert (0 == UNLINK (KEYFILE));
346
347   if (failureCount != 0)
348   {
349     printf ("\n\n%d TESTS FAILED!\n\n", failureCount);
350     return -1;
351   }
352   return 0;
353 }                               /* end of main */