]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/sigtest/sigtest.c
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / sigtest / sigtest.c
1 /*
2 * Tool to cook up key pair, sign & verify, any which way
3 * with tons of options.
4 */
5 #include <string.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <time.h>
9 #include <Security/cssm.h>
10 #include <Security/cssmapple.h>
11 #include "cspwrap.h"
12 #include "common.h"
13 #include <security_cdsa_utils/cuFileIo.h>
14
15 #define DATA_SIZE_DEF 100
16 #define USAGE_DEF "noUsage"
17 #define LOOPS_DEF 10
18 #define FEE_PASSWD_LEN 32 /* private data length in bytes, FEE only */
19
20 static void usage(char **argv)
21 {
22 printf("usage: %s [options]\n", argv[0]);
23 printf("Options:\n");
24 printf(" a=algorithm\n");
25 printf(" f=FEE/MD5 F=FEE/SHA1 e=ECDSA r=RSA/MD5 2=RSA/MD2 \n");
26 printf(" s=RSA/SHA1 d=DSA R=rawRSA (No digest) \n");
27 printf(" 4=RSA/SHA224 6=RSA/SHA256 3=RSA/SHA384 5=RSA/SHA512;\n");
28 printf(" E=ECDSA/ANSI; 7=ECDSA/SHA256; 8=ECDSA/SHA384; 9=ECDSA/512; default=RSA/SHA1\n");
29 printf(" d=dataSize (default = %d)\n", DATA_SIZE_DEF);
30 printf(" k=keySize\n");
31 printf(" b (pub is blob)\n");
32 printf(" r (priv is blob)\n");
33 printf(" B=[1xboOt] (pub key in PKCS1/X509/BSAFE/OpenSSH1/OpenSSH2/Octet form)\n");
34 printf(" RSA = {PKCS1,X509,OpenSSH1,OpenSSH2} default = PKCS1\n");
35 printf(" DSA = {BSAFE,X509,OpenSSH2} default = X509\n");
36 printf(" ECDSA = {X509, Only!} default = X509\n");
37 printf(" P=primeType (m=Mersenne, f=FEE, g=general; FEE only)\n");
38 printf(" C=curveType (m=Montgomery, w=Weierstrass, a=ANSI; FEE only)\n");
39 printf(" l=loops (0=forever)\n");
40 printf(" s(ign only)\n");
41 printf(" V(erify only)\n");
42 printf(" c(ontexts only)\n");
43 printf(" S (we generate seed, for FEE only)\n");
44 printf(" n(o padding; default is PKCS1)\n");
45 printf(" p=pauseInterval (default=0, no pause)\n");
46 printf(" D (CSP/DL; default = bare CSP)\n");
47 printf(" L (dump key and signature blobs)\n");
48 printf(" o (key blobs in OCTET_STRING format)\n");
49 printf(" q(uiet)\n");
50 printf(" v(erbose))\n");
51 exit(1);
52 }
53
54 /* parse public key format character */
55 static CSSM_KEYBLOB_FORMAT parsePubKeyFormat(char c, char **argv)
56 {
57 switch(c) {
58 case '1':
59 return CSSM_KEYBLOB_RAW_FORMAT_PKCS1;
60 case 'x':
61 return CSSM_KEYBLOB_RAW_FORMAT_X509;
62 case 'b':
63 return CSSM_KEYBLOB_RAW_FORMAT_FIPS186;
64 case 'o':
65 return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH;
66 case 'O':
67 return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2;
68 default:
69 usage(argv);
70 }
71 /* not reached */
72 return -1;
73 }
74
75 int main(int argc, char **argv)
76 {
77 int arg;
78 char *argp;
79 CSSM_CSP_HANDLE cspHand;
80 CSSM_CC_HANDLE pubSigHand;
81 CSSM_CC_HANDLE privSigHand;
82 CSSM_RETURN crtn;
83 CSSM_DATA randData = {0, NULL};
84 CSSM_KEY privKey;
85 CSSM_KEY pubKey;
86 CSSM_DATA sigData = {0, NULL};
87 unsigned loop;
88 int i;
89 unsigned dataSize = DATA_SIZE_DEF;
90 unsigned keySize = CSP_KEY_SIZE_DEFAULT;
91 uint32 sigAlg = CSSM_ALGID_SHA1WithRSA;
92 uint32 keyGenAlg = CSSM_ALGID_RSA;
93 unsigned pauseInterval = 0;
94 unsigned loops = LOOPS_DEF;
95 CSSM_BOOL quiet = CSSM_FALSE;
96 CSSM_BOOL pubIsRef = CSSM_TRUE;
97 CSSM_BOOL privIsRef = CSSM_TRUE;
98 CSSM_BOOL doSign = CSSM_TRUE;
99 CSSM_BOOL doVerify = CSSM_TRUE;
100 CSSM_BOOL contextsOnly = CSSM_FALSE;
101 CSSM_BOOL noPadding = CSSM_FALSE;
102 CSSM_BOOL verbose = CSSM_FALSE;
103 CSSM_BOOL bareCsp = CSSM_TRUE;
104 CSSM_BOOL genSeed = CSSM_FALSE;
105 CSSM_BOOL dumpBlobs = CSSM_FALSE;
106 CSSM_KEYBLOB_FORMAT privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_NONE;
107 CSSM_KEYBLOB_FORMAT pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_NONE;
108 uint32 primeType = CSSM_FEE_PRIME_TYPE_DEFAULT; // FEE only
109 uint32 curveType = CSSM_FEE_CURVE_TYPE_DEFAULT; // FEE only
110
111 for(arg=1; arg<argc; arg++) {
112 argp = argv[arg];
113 switch(argv[arg][0]) {
114 case 'a':
115 if(argp[1] != '=') {
116 usage(argv);
117 }
118 switch(argp[2]) {
119 case 'f':
120 sigAlg = CSSM_ALGID_FEE_MD5;
121 keyGenAlg = CSSM_ALGID_FEE;
122 break;
123 case 'F':
124 sigAlg = CSSM_ALGID_FEE_SHA1;
125 keyGenAlg = CSSM_ALGID_FEE;
126 break;
127 case 'e':
128 sigAlg = CSSM_ALGID_SHA1WithECDSA;
129 keyGenAlg = CSSM_ALGID_FEE;
130 break;
131 case 'E':
132 sigAlg = CSSM_ALGID_SHA1WithECDSA;
133 keyGenAlg = CSSM_ALGID_ECDSA;
134 break;
135 case '7':
136 sigAlg = CSSM_ALGID_SHA256WithECDSA;
137 keyGenAlg = CSSM_ALGID_ECDSA;
138 break;
139 case '8':
140 sigAlg = CSSM_ALGID_SHA384WithECDSA;
141 keyGenAlg = CSSM_ALGID_ECDSA;
142 break;
143 case '9':
144 sigAlg = CSSM_ALGID_SHA512WithECDSA;
145 keyGenAlg = CSSM_ALGID_ECDSA;
146 break;
147 case 'r':
148 sigAlg = CSSM_ALGID_MD5WithRSA;
149 keyGenAlg = CSSM_ALGID_RSA;
150 break;
151 case '2':
152 sigAlg = CSSM_ALGID_MD2WithRSA;
153 keyGenAlg = CSSM_ALGID_RSA;
154 break;
155 case 's':
156 sigAlg = CSSM_ALGID_SHA1WithRSA;
157 keyGenAlg = CSSM_ALGID_RSA;
158 break;
159 case 'd':
160 sigAlg = CSSM_ALGID_SHA1WithDSA;
161 keyGenAlg = CSSM_ALGID_DSA;
162 break;
163 case 'R':
164 sigAlg = CSSM_ALGID_RSA;
165 keyGenAlg = CSSM_ALGID_RSA;
166 break;
167 case '4':
168 sigAlg = CSSM_ALGID_SHA224WithRSA;
169 keyGenAlg = CSSM_ALGID_RSA;
170 break;
171 case '6':
172 sigAlg = CSSM_ALGID_SHA256WithRSA;
173 keyGenAlg = CSSM_ALGID_RSA;
174 break;
175 case '3':
176 sigAlg = CSSM_ALGID_SHA384WithRSA;
177 keyGenAlg = CSSM_ALGID_RSA;
178 break;
179 case '5':
180 sigAlg = CSSM_ALGID_SHA512WithRSA;
181 keyGenAlg = CSSM_ALGID_RSA;
182 break;
183 default:
184 usage(argv);
185 }
186 break;
187 case 'd':
188 dataSize = atoi(&argv[arg][2]);
189 break;
190 case 'k':
191 keySize = atoi(&argv[arg][2]);
192 break;
193 case 'l':
194 loops = atoi(&argv[arg][2]);
195 break;
196 case 'p':
197 pauseInterval = atoi(&argv[arg][2]);
198 break;
199 case 'b':
200 pubIsRef = CSSM_FALSE;
201 break;
202 case 'r':
203 privIsRef = CSSM_FALSE;
204 break;
205 case 'B':
206 if(argp[1] != '=') {
207 usage(argv);
208 }
209 pubKeyFormat = parsePubKeyFormat(argp[2], argv);
210 break;
211 case 's':
212 doVerify = CSSM_FALSE;
213 break;
214 case 'V':
215 doSign = CSSM_FALSE;
216 break;
217 case 'S':
218 genSeed = CSSM_TRUE;
219 break;
220 case 'n':
221 noPadding = CSSM_TRUE;
222 break;
223 case 'L':
224 dumpBlobs = CSSM_TRUE;
225 break;
226 case 'c':
227 contextsOnly = CSSM_TRUE;
228 break;
229 case 'D':
230 bareCsp = CSSM_FALSE;
231 break;
232 case 'q':
233 quiet = CSSM_TRUE;
234 break;
235 case 'v':
236 verbose = CSSM_TRUE;
237 break;
238 case 'o':
239 /* this is for FEE only */
240 pubKeyFormat = privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING;
241 break;
242 case 'C':
243 switch(argp[2]) {
244 case 'm':
245 curveType = CSSM_FEE_CURVE_TYPE_MONTGOMERY;
246 break;
247 case 'w':
248 curveType = CSSM_FEE_CURVE_TYPE_WEIERSTRASS;
249 break;
250 case 'a':
251 curveType = CSSM_FEE_CURVE_TYPE_ANSI_X9_62;
252 break;
253 default:
254 usage(argv);
255 }
256 break;
257 case 'P':
258 switch(argp[2]) {
259 case 'm':
260 primeType = CSSM_FEE_PRIME_TYPE_MERSENNE;
261 break;
262 case 'f':
263 primeType = CSSM_FEE_PRIME_TYPE_FEE;
264 break;
265 case 'g':
266 primeType = CSSM_FEE_PRIME_TYPE_GENERAL;
267 break;
268 default:
269 usage(argv);
270 }
271 break;
272 default:
273 usage(argv);
274 }
275 }
276 if(!doSign && !doVerify) {
277 printf("s and v mutually exclusive\n");
278 exit(1);
279 }
280 cspHand = cspDlDbStartup(bareCsp, NULL);
281 if(cspHand == 0) {
282 exit(1);
283 }
284 printf("Starting sigtest; args: ");
285 for(i=1; i<argc; i++) {
286 printf("%s ", argv[i]);
287 }
288 if(keyGenAlg == CSSM_ALGID_FEE) {
289 uint8 passwd[FEE_PASSWD_LEN];
290 CSSM_DATA pwdData = {FEE_PASSWD_LEN, passwd};
291 CSSM_DATA_PTR pwdDataPtr;
292
293 if(genSeed) {
294 simpleGenData(&pwdData, FEE_PASSWD_LEN, FEE_PASSWD_LEN);
295 pwdDataPtr = &pwdData;
296 }
297 else {
298 pwdDataPtr = NULL;
299 }
300 crtn = cspGenFEEKeyPair(cspHand,
301 USAGE_DEF,
302 strlen(USAGE_DEF),
303 keySize,
304 primeType,
305 curveType,
306 &pubKey,
307 pubIsRef,
308 CSSM_KEYUSE_VERIFY,
309 pubKeyFormat,
310 &privKey,
311 privIsRef,
312 CSSM_KEYUSE_SIGN,
313 CSSM_KEYBLOB_RAW_FORMAT_NONE,
314 pwdDataPtr);
315
316 }
317 else if((keyGenAlg == CSSM_ALGID_DSA) && !bareCsp) {
318 /* CSPDL doesn't do gen alg params */
319 crtn = cspGenDSAKeyPair(cspHand,
320 USAGE_DEF,
321 strlen(USAGE_DEF),
322 keySize,
323 &pubKey,
324 pubIsRef,
325 CSSM_KEYUSE_VERIFY,
326 pubKeyFormat,
327 &privKey,
328 privIsRef,
329 CSSM_KEYUSE_SIGN,
330 CSSM_KEYBLOB_RAW_FORMAT_NONE,
331 CSSM_FALSE,
332 NULL);
333 }
334 else {
335 crtn = cspGenKeyPair(cspHand,
336 keyGenAlg,
337 USAGE_DEF,
338 strlen(USAGE_DEF),
339 keySize,
340 &pubKey,
341 pubIsRef,
342 CSSM_KEYUSE_VERIFY,
343 pubKeyFormat,
344 &privKey,
345 privIsRef,
346 CSSM_KEYUSE_SIGN,
347 privKeyFormat,
348 genSeed);
349 }
350 if(crtn) {
351 CSSM_ModuleDetach(cspHand);
352 exit(1);
353 }
354 if(dumpBlobs) {
355 if(!pubIsRef) {
356 writeFile("pubKey.blob", pubKey.KeyData.Data, pubKey.KeyData.Length);
357 printf("...wrote %lu bytes to pubKey.blob\n", pubKey.KeyData.Length);
358 }
359 if(!privIsRef) {
360 writeFile("privKey.blob", privKey.KeyData.Data, privKey.KeyData.Length);
361 printf("...wrote %lu bytes to privKey.blob\n", privKey.KeyData.Length);
362 }
363 }
364 randData.Data = (uint8 *)CSSM_MALLOC(dataSize);
365 randData.Length = dataSize;
366 simpleGenData(&randData, dataSize, dataSize);
367 printf("\n");
368 for(loop=1; ; loop++) {
369 if(!quiet) {
370 printf("...Loop %d\n", loop);
371 }
372 if((loop == 1) || doSign) {
373 crtn = CSSM_CSP_CreateSignatureContext(cspHand,
374 sigAlg,
375 NULL, // passPhrase
376 &privKey,
377 &privSigHand);
378 if(crtn) {
379 printError("CSSM_CSP_CreateSignatureContext (1)", crtn);
380 break;
381 }
382 if(noPadding) {
383 crtn = AddContextAttribute(privSigHand,
384 CSSM_ATTRIBUTE_PADDING,
385 sizeof(uint32),
386 CAT_Uint32,
387 NULL,
388 CSSM_PADDING_NONE);
389 if(crtn) {
390 break;
391 }
392 }
393 if(!contextsOnly) {
394 crtn = CSSM_SignData(privSigHand,
395 &randData,
396 1,
397 CSSM_ALGID_NONE,
398 &sigData);
399 if(crtn) {
400 printError("CSSM_SignData error", crtn);
401 break;
402 }
403 }
404 crtn = CSSM_DeleteContext(privSigHand);
405 if(crtn) {
406 printError("CSSM_DeleteContext", crtn);
407 break;
408 }
409 if(dumpBlobs) {
410 writeFile("sig.blob", sigData.Data, sigData.Length);
411 printf("...wrote %lu bytes to sig.blob\n", sigData.Length);
412 }
413 }
414 if(doVerify) {
415 crtn = CSSM_CSP_CreateSignatureContext(cspHand,
416 sigAlg,
417 NULL, // passPhrase
418 &pubKey,
419 &pubSigHand);
420 if(crtn) {
421 printError("CSSM_CSP_CreateSignatureContext (2)", crtn);
422 break;
423 }
424 if(noPadding) {
425 crtn = AddContextAttribute(pubSigHand,
426 CSSM_ATTRIBUTE_PADDING,
427 sizeof(uint32),
428 CAT_Uint32,
429 NULL,
430 CSSM_PADDING_NONE);
431 if(crtn) {
432 break;
433 }
434 }
435 if(!contextsOnly) {
436 crtn = CSSM_VerifyData(pubSigHand,
437 &randData,
438 1,
439 CSSM_ALGID_NONE,
440 &sigData);
441 if(crtn) {
442 printError("CSSM_VerifyData", crtn);
443 break;
444 }
445 }
446 crtn = CSSM_DeleteContext(pubSigHand);
447 if(crtn) {
448 printError("CSSM_DeleteContext", crtn);
449 break;
450 }
451 }
452 if(doSign & !contextsOnly) {
453 CSSM_FREE(sigData.Data);
454 sigData.Length = 0;
455 sigData.Data = NULL;
456 }
457 /* else keep it around for next verify */
458
459 if(loops && (loop == loops)) {
460 break;
461 }
462 if(pauseInterval && ((loop % pauseInterval) == 0)) {
463 char inch;
464
465 fpurge(stdin);
466 printf("Hit CR to proceed, q to quit: ");
467 inch = getchar();
468 if(inch == 'q') {
469 break;
470 }
471 }
472 }
473 if(randData.Data != NULL) {
474 CSSM_FREE(randData.Data);
475 }
476 if(CSSM_ModuleDetach(cspHand)) {
477 printError("CSSM_CSP_Detach", crtn);
478 exit(1);
479 }
480 if(crtn == CSSM_OK) {
481 if(!quiet) {
482 printf("OK\n");
483 }
484 }
485 return crtn;
486 }