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 33static unsigned int verbose; 34 35static void 36die (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 46typedef struct scheme_spec 47{ 48 unsigned int idx; 49 gcry_ac_scheme_t scheme; 50 unsigned int flags; 51 const 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 60scheme_spec_t es_specs[] = 61 { 62 FILL (0, ES_PKCS_V1_5, 0, "foobar"), 63 FILL (1, ES_PKCS_V1_5, 0, "") 64 }; 65 66scheme_spec_t ssa_specs[] = 67 { 68 FILL (0, SSA_PKCS_V1_5, SCHEME_SPEC_FLAG_GET_OPTS, "foobar") 69 }; 70 71#undef FILL 72 73gcry_err_code_t 74scheme_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 113gcry_error_t 114es_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 char *c = NULL; 119 char *m2 = NULL; 120 size_t c_n = 0; 121 size_t m2_n = 0; 122 void *opts = NULL; 123 gcry_ac_io_t io_m; 124 gcry_ac_io_t io_c; 125 gcry_ac_io_t io_m2; 126 127 if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS) 128 err = scheme_get_opts (spec, &opts); 129 if (! err) 130 { 131 c = NULL; 132 m2 = NULL; 133 134 gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE, 135 GCRY_AC_IO_STRING, spec.m, spec.m_n); 136 gcry_ac_io_init (&io_c, GCRY_AC_IO_WRITABLE, 137 GCRY_AC_IO_STRING, &c, &c_n); 138 139 err = gcry_ac_data_encrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0, opts, key_public, 140 &io_m, &io_c); 141 if (! err) 142 { 143 gcry_ac_io_init (&io_c, GCRY_AC_IO_READABLE, 144 GCRY_AC_IO_STRING, c, c_n); 145 gcry_ac_io_init (&io_m2, GCRY_AC_IO_WRITABLE, 146 GCRY_AC_IO_STRING, &m2, &m2_n); 147 148 err = gcry_ac_data_decrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0, 149 opts, key_secret, &io_c, &io_m2); 150 } 151 if (! err) 152 assert ((spec.m_n == m2_n) && (! strncmp (spec.m, m2, spec.m_n))); 153 154 if (c) 155 gcry_free (c); 156 if (m2) 157 gcry_free (m2); 158 } 159 160 if (opts) 161 gcry_free (opts); 162 163 return err; 164} 165 166gcry_error_t 167ssa_check (gcry_ac_handle_t handle, scheme_spec_t spec, 168 gcry_ac_key_t key_public, gcry_ac_key_t key_secret) 169{ 170 gcry_error_t err = GPG_ERR_NO_ERROR; 171 unsigned char *s = NULL; 172 size_t s_n = 0; 173 void *opts = NULL; 174 gcry_ac_io_t io_m; 175 gcry_ac_io_t io_s; 176 177 if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS) 178 err = scheme_get_opts (spec, &opts); 179 if (! err) 180 { 181 gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE, 182 GCRY_AC_IO_STRING, spec.m, spec.m_n); 183 gcry_ac_io_init (&io_s, GCRY_AC_IO_WRITABLE, 184 GCRY_AC_IO_STRING, &s, &s_n); 185 186 err = gcry_ac_data_sign_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_secret, 187 &io_m, &io_s); 188 if (! err) 189 { 190 gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE, 191 GCRY_AC_IO_STRING, spec.m, spec.m_n); 192 gcry_ac_io_init (&io_s, GCRY_AC_IO_READABLE, 193 GCRY_AC_IO_STRING, s, s_n); 194 err = gcry_ac_data_verify_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_public, 195 &io_m, &io_s); 196 } 197 assert (! err); 198 199 if (s) 200 gcry_free (s); 201 } 202 203 if (opts) 204 gcry_free (opts); 205 206 return err; 207} 208 209void 210es_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret) 211{ 212 gcry_error_t err = GPG_ERR_NO_ERROR; 213 unsigned int i = 0; 214 215 for (i = 0; (i < (sizeof (es_specs) / sizeof (*es_specs))) && (! err); i++) 216 err = es_check (handle, es_specs[i], key_public, key_secret); 217 218 assert (! err); 219} 220 221void 222ssa_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret) 223{ 224 gcry_error_t err = GPG_ERR_NO_ERROR; 225 unsigned int i = 0; 226 227 for (i = 0; (i < (sizeof (ssa_specs) / sizeof (*ssa_specs))) && (! err); i++) 228 err = ssa_check (handle, ssa_specs[i], key_public, key_secret); 229 230 assert (! err); 231} 232 233#define KEY_TYPE_PUBLIC (1 << 0) 234#define KEY_TYPE_SECRET (1 << 1) 235 236typedef struct key_spec 237{ 238 const char *name; 239 unsigned int flags; 240 const char *mpi_string; 241} key_spec_t; 242 243key_spec_t key_specs[] = 244 { 245 { "n", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET, 246 "e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" 247 "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" 248 "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" 249 "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251" }, 250 { "e", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET, 251 "010001" }, 252 { "d", KEY_TYPE_SECRET, 253 "046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" 254 "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" 255 "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" 256 "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" }, 257 { "p", KEY_TYPE_SECRET, 258 "00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" 259 "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1" }, 260 { "q", KEY_TYPE_SECRET, 261 "00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" 262 "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361" }, 263 { "u", KEY_TYPE_SECRET, 264 "304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" 265 "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" }, 266 { NULL }, 267 }; 268 269gcry_error_t 270key_init (gcry_ac_key_type_t type, gcry_ac_key_t *key) 271{ 272 gcry_error_t err = GPG_ERR_NO_ERROR; 273 gcry_ac_data_t key_data = NULL; 274 gcry_ac_key_t key_new = NULL; 275 gcry_mpi_t mpi = NULL; 276 unsigned int i = 0; 277 278 err = gcry_ac_data_new (&key_data); 279 for (i = 0; key_specs[i].name && (! err); i++) 280 { 281 if (((type == GCRY_AC_KEY_PUBLIC) && (key_specs[i].flags & KEY_TYPE_PUBLIC)) 282 || ((type == GCRY_AC_KEY_SECRET) && (key_specs[i].flags & KEY_TYPE_SECRET))) 283 { 284 err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, key_specs[i].mpi_string, 0, NULL); 285 if (! err) 286 { 287 gcry_ac_data_set (key_data, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC, 288 key_specs[i].name, mpi); 289 gcry_mpi_release (mpi); 290 } 291 } 292 } 293 if (! err) 294 err = gcry_ac_key_init (&key_new, NULL, type, key_data); 295 296 if (key_data) 297 gcry_ac_data_destroy (key_data); 298 299 if (! err) 300 *key = key_new; 301 302 return err; 303} 304 305static void 306check_run (void) 307{ 308 gcry_ac_handle_t handle = NULL; 309 gcry_error_t err = GPG_ERR_NO_ERROR; 310 gcry_ac_key_t key_public = NULL, key_secret = NULL; 311 312 err = key_init (GCRY_AC_KEY_PUBLIC, &key_public); 313 if (! err) 314 err = key_init (GCRY_AC_KEY_SECRET, &key_secret); 315 316 if (! err) 317 err = gcry_ac_open (&handle, GCRY_AC_RSA, 0); 318 if (! err) 319 { 320 es_checks (handle, key_public, key_secret); 321 ssa_checks (handle, key_public, key_secret); 322 } 323 324 assert (! err); 325} 326 327int 328main (int argc, char **argv) 329{ 330 unsigned int debug = 0; 331 332 if ((argc > 1) && (! strcmp (argv[1], "--verbose"))) 333 verbose = 1; 334 else if ((argc > 1) && (! strcmp (argv[1], "--debug"))) 335 verbose = debug = 1; 336 337 gcry_control (GCRYCTL_DISABLE_SECMEM, 0); 338 if (! gcry_check_version (GCRYPT_VERSION)) 339 die ("version mismatch\n"); 340 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); 341 if (debug) 342 gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); 343 344 check_run (); 345 346 return 0; 347} 348