]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * rsatool.c - RSA/DSA/ECDSA key pair generator, en/decrypt, sign/verify with file I/O | |
3 | */ | |
4 | ||
5 | #include <stdlib.h> | |
6 | #include <stdio.h> | |
7 | #include <time.h> | |
8 | #include <string.h> | |
9 | #include <Security/cssm.h> | |
10 | #include "cspwrap.h" | |
11 | #include "common.h" | |
12 | #include <security_cdsa_utils/cuFileIo.h> | |
13 | ||
14 | /* For 3141770 - defined true when PR-3074739 merged to TOT Security */ | |
15 | #define OPENSSL_ENABLE 1 | |
16 | ||
17 | #define USAGE_NAME "noUsage" | |
18 | #define USAGE_NAME_LEN (strlen(USAGE_NAME)) | |
19 | #define DEFAULT_KEY_SIZE_BITS 512 | |
20 | ||
21 | typedef struct { | |
22 | CSSM_ALGORITHMS alg; | |
23 | uint32 keySizeInBits; | |
24 | CSSM_CSP_HANDLE cspHand; | |
25 | char *keyFileName; | |
26 | char *outKeyFileName; // for pub key convert | |
27 | char *plainFileName; | |
28 | char *sigFileName; | |
29 | char *cipherFileName; | |
30 | char *dsaParamFileIn; | |
31 | char *dsaParamFileOut; | |
32 | CSSM_BOOL swapKeyClass; | |
33 | CSSM_BOOL rawSign; | |
34 | CSSM_BOOL noPad; | |
35 | CSSM_BOOL quiet; | |
36 | CSSM_KEYBLOB_FORMAT pubKeyFormat; // FORMAT_NONE ==> default | |
37 | CSSM_KEYBLOB_FORMAT privKeyFormat; // FORMAT_NONE ==> default | |
38 | CSSM_KEYBLOB_FORMAT outPubKeyFormat;// FORMAT_NONE ==> default, for pub key convert | |
39 | CSSM_ALGORITHMS digestAlg; // optional digest alg for raw sign/verify | |
40 | } opParams; | |
41 | ||
42 | static void usage(char **argv) | |
43 | { | |
44 | printf("usage: %s op [options]\n", argv[0]); | |
45 | printf(" op:\n"); | |
46 | printf(" g generate key pair\n"); | |
47 | printf(" e encrypt\n"); | |
48 | printf(" d decrypt\n"); | |
49 | printf(" s sign\n"); | |
50 | printf(" v verify\n"); | |
51 | printf(" S SHA-1 digest\n"); | |
52 | printf(" M MD5 digest\n"); | |
53 | printf(" C convert public key format\n"); | |
54 | printf(" options:\n"); | |
55 | printf(" k=keyfileBase keys are keyFileBase_pub.der, " | |
56 | "keyFileBase_priv.der)\n"); | |
57 | printf(" K=outputPublicKey\n"); | |
58 | printf(" p=plainFile\n"); | |
59 | printf(" c=cipherFile\n"); | |
60 | printf(" s=sigfile\n"); | |
61 | printf(" z=keySizeInBits (default %d)\n", DEFAULT_KEY_SIZE_BITS); | |
62 | printf(" w (swap key class)\n"); | |
63 | printf(" r (raw sign/verify)\n"); | |
64 | printf(" P (no padding)\n"); | |
65 | printf(" d=digestAlg digestAlg: s(SHA1) 5(MD5) for raw signing\n"); | |
66 | printf(" m=dsaParamFileIn\n"); | |
67 | printf(" M=dsaParamFileOut (must specify one of dsaParamFile{In,Out}\n"); | |
68 | printf(" b=[1xboOL] (pub key in PKCS1/X509/BSAFE/OpenSSH1/OpenSSH2/OpenSSL form)\n"); | |
69 | printf(" RSA = {PKCS1,X509,OpenSSH1,OpenSSH2} default = PKCS1\n"); | |
70 | printf(" DSA = {BSAFE,X509,OpenSSH2} default = X509\n"); | |
71 | printf(" ECDSA = {X509, OpenSSL} default = X509\n"); | |
72 | printf(" Note: RSA and DSA public keys in OpenSSL form are X509.\n"); | |
73 | printf(" v=[18sbo] (priv key in PKCS1/PKCS8/OpenSSH/BSAFE/OpenSSL form)\n"); | |
74 | printf(" RSA = {PKCS1,PKCS8,OpenSSH1} default = PKCS8\n"); | |
75 | printf(" DSA = {BSAFE,OpenSSL,PKCS8} default = OpenSSL\n"); | |
76 | printf(" ECDSA = {PKCS8,OpenSSL} default = OpenSSL}\n"); | |
77 | printf(" Note: RSA private key in OpenSSL form is PKCS1.\n"); | |
78 | printf(" B=[1xboO] output public key format\n"); | |
79 | printf(" a=alg d=DSA, r=RSA, e=ECDSA; default = RSA\n"); | |
80 | printf(" q(uiet)\n"); | |
81 | exit(1); | |
82 | } | |
83 | ||
84 | /* NULL wrap a key to specified format. */ | |
85 | static CSSM_RETURN nullWrapKey(CSSM_CSP_HANDLE cspHand, | |
86 | const CSSM_KEY *refKey, | |
87 | CSSM_KEYBLOB_FORMAT blobFormat, | |
88 | CSSM_KEY_PTR rawKey) // RETURNED | |
89 | { | |
90 | CSSM_CC_HANDLE ccHand; | |
91 | CSSM_RETURN crtn; | |
92 | CSSM_ACCESS_CREDENTIALS creds; | |
93 | CSSM_DATA descData = {0, 0}; | |
94 | ||
95 | memset(rawKey, 0, sizeof(CSSM_KEY)); | |
96 | memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); | |
97 | crtn = CSSM_CSP_CreateSymmetricContext(cspHand, | |
98 | CSSM_ALGID_NONE, | |
99 | CSSM_ALGMODE_NONE, | |
100 | &creds, // passPhrase | |
101 | NULL, // unwrappingKey | |
102 | NULL, // initVector | |
103 | CSSM_PADDING_NONE, | |
104 | 0, // Params | |
105 | &ccHand); | |
106 | if(crtn) { | |
107 | printError("cspWrapKey/CreateContext", crtn); | |
108 | return crtn; | |
109 | } | |
110 | if(blobFormat != CSSM_KEYBLOB_WRAPPED_FORMAT_NONE) { | |
111 | /* only add this attribute if it's not the default */ | |
112 | CSSM_ATTRIBUTE_TYPE attrType; | |
113 | ||
114 | switch(refKey->KeyHeader.KeyClass) { | |
115 | case CSSM_KEYCLASS_SESSION_KEY: | |
116 | attrType = CSSM_ATTRIBUTE_SYMMETRIC_KEY_FORMAT; | |
117 | break; | |
118 | case CSSM_KEYCLASS_PUBLIC_KEY: | |
119 | attrType = CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT; | |
120 | break; | |
121 | case CSSM_KEYCLASS_PRIVATE_KEY: | |
122 | attrType = CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT; | |
123 | break; | |
124 | default: | |
125 | printf("***Bogus KeyClass in nullWrapKey\n"); | |
126 | return -1; | |
127 | } | |
128 | CSSM_CONTEXT_ATTRIBUTE attr; | |
129 | attr.AttributeType = attrType; | |
130 | attr.AttributeLength = sizeof(uint32); | |
131 | attr.Attribute.Uint32 = blobFormat; | |
132 | crtn = CSSM_UpdateContextAttributes( | |
133 | ccHand, | |
134 | 1, | |
135 | &attr); | |
136 | if(crtn) { | |
137 | printError("CSSM_UpdateContextAttributes", crtn); | |
138 | return crtn; | |
139 | } | |
140 | } | |
141 | crtn = CSSM_WrapKey(ccHand, | |
142 | &creds, | |
143 | refKey, | |
144 | &descData, | |
145 | rawKey); | |
146 | if(crtn != CSSM_OK) { | |
147 | printError("CSSM_WrapKey", crtn); | |
148 | } | |
149 | if(CSSM_DeleteContext(ccHand)) { | |
150 | printf("CSSM_DeleteContext failure\n"); | |
151 | } | |
152 | return crtn; | |
153 | } | |
154 | ||
155 | /* | |
156 | * Sign/verify optional "no padding" context attr | |
157 | */ | |
158 | static CSSM_RETURN sigSign(CSSM_CSP_HANDLE cspHand, | |
159 | uint32 algorithm, // CSSM_ALGID_FEE_MD5, etc. | |
160 | CSSM_KEY_PTR key, // private key | |
161 | const CSSM_DATA *text, | |
162 | CSSM_DATA_PTR sig, | |
163 | uint32 digestAlg, // optional for raw signing | |
164 | CSSM_BOOL noPad) // true --> add PADDING_NONE to context | |
165 | { | |
166 | CSSM_CC_HANDLE sigHand; | |
167 | CSSM_RETURN crtn; | |
168 | ||
169 | crtn = CSSM_CSP_CreateSignatureContext(cspHand, | |
170 | algorithm, | |
171 | NULL, // passPhrase | |
172 | key, | |
173 | &sigHand); | |
174 | if(crtn) { | |
175 | printError("CSSM_CSP_CreateSignatureContext", crtn); | |
176 | return crtn; | |
177 | } | |
178 | if(noPad) { | |
179 | crtn = AddContextAttribute(sigHand, | |
180 | CSSM_ATTRIBUTE_PADDING, | |
181 | sizeof(uint32), | |
182 | CAT_Uint32, | |
183 | NULL, | |
184 | CSSM_PADDING_NONE); | |
185 | if(crtn) { | |
186 | return crtn; | |
187 | } | |
188 | } | |
189 | crtn = CSSM_SignData(sigHand, | |
190 | text, | |
191 | 1, | |
192 | digestAlg, | |
193 | sig); | |
194 | if(crtn) { | |
195 | printError("CSSM_SignData", crtn); | |
196 | } | |
197 | CSSM_DeleteContext(sigHand); | |
198 | return crtn; | |
199 | } | |
200 | ||
201 | static CSSM_RETURN sigVerify(CSSM_CSP_HANDLE cspHand, | |
202 | uint32 algorithm, // CSSM_ALGID_FEE_MD5, etc. | |
203 | CSSM_KEY_PTR key, // public key | |
204 | const CSSM_DATA *text, | |
205 | const CSSM_DATA *sig, | |
206 | uint32 digestAlg, // optional for raw signing | |
207 | CSSM_BOOL noPad) // true --> add PADDING_NONE to context | |
208 | { | |
209 | CSSM_CC_HANDLE sigHand; | |
210 | CSSM_RETURN crtn; | |
211 | ||
212 | crtn = CSSM_CSP_CreateSignatureContext(cspHand, | |
213 | algorithm, | |
214 | NULL, // passPhrase | |
215 | key, | |
216 | &sigHand); | |
217 | if(crtn) { | |
218 | printError("CSSM_CSP_CreateSignatureContext", crtn); | |
219 | return crtn; | |
220 | } | |
221 | if(noPad) { | |
222 | crtn = AddContextAttribute(sigHand, | |
223 | CSSM_ATTRIBUTE_PADDING, | |
224 | sizeof(uint32), | |
225 | CAT_Uint32, | |
226 | NULL, | |
227 | CSSM_PADDING_NONE); | |
228 | if(crtn) { | |
229 | return crtn; | |
230 | } | |
231 | } | |
232 | crtn = CSSM_VerifyData(sigHand, | |
233 | text, | |
234 | 1, | |
235 | digestAlg, | |
236 | sig); | |
237 | if(crtn) { | |
238 | printError("CSSM_VerifyData", crtn); | |
239 | } | |
240 | CSSM_DeleteContext(sigHand); | |
241 | return crtn; | |
242 | } | |
243 | ||
244 | /* | |
245 | * Generate DSA key pair. Algorithm parameters are | |
246 | * either specified by caller via inParams, or are generated here | |
247 | * and returned to caller in outParams. Exactly one of (inParams, | |
248 | * outParams) must be non-NULL. | |
249 | */ | |
250 | static CSSM_RETURN genDsaKeyPair( | |
251 | CSSM_CSP_HANDLE cspHand, | |
252 | const char *keyLabel, | |
253 | unsigned keyLabelLen, | |
254 | uint32 keySize, // in bits | |
255 | CSSM_KEY_PTR pubKey, // mallocd by caller | |
256 | CSSM_BOOL pubIsRef, // true - reference key, false - data | |
257 | uint32 pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc. | |
258 | CSSM_KEYBLOB_FORMAT pubFormat, // Optional. Some algorithms (currently, FEE) | |
259 | // provide for multiple key blob formats. | |
260 | // Specify 0 or CSSM_KEYBLOB_RAW_FORMAT_NONE | |
261 | // to get the default format. | |
262 | CSSM_KEY_PTR privKey, // mallocd by caller | |
263 | CSSM_BOOL privIsRef, // true - reference key, false - data | |
264 | uint32 privKeyUsage, // CSSM_KEYUSE_DECRYPT, etc. | |
265 | CSSM_KEYBLOB_FORMAT privFormat, // optional 0 ==> default | |
266 | const CSSM_DATA *inParams, // optional | |
267 | CSSM_DATA_PTR outParams) // optional, we malloc | |
268 | { | |
269 | CSSM_RETURN crtn; | |
270 | CSSM_CC_HANDLE ccHand; | |
271 | CSSM_DATA keyLabelData; | |
272 | uint32 pubAttr; | |
273 | uint32 privAttr; | |
274 | CSSM_RETURN ocrtn = CSSM_OK; | |
275 | ||
276 | /* Caller must specify either inParams or outParams, not both */ | |
277 | if(inParams && outParams) { | |
278 | return CSSMERR_CSSM_INVALID_POINTER; | |
279 | } | |
280 | if(!inParams && !outParams) { | |
281 | return CSSMERR_CSSM_INVALID_POINTER; | |
282 | } | |
283 | ||
284 | keyLabelData.Data = (uint8 *)keyLabel, | |
285 | keyLabelData.Length = keyLabelLen; | |
286 | memset(pubKey, 0, sizeof(CSSM_KEY)); | |
287 | memset(privKey, 0, sizeof(CSSM_KEY)); | |
288 | ||
289 | crtn = CSSM_CSP_CreateKeyGenContext(cspHand, | |
290 | CSSM_ALGID_DSA, | |
291 | keySize, | |
292 | NULL, // Seed | |
293 | NULL, // Salt | |
294 | NULL, // StartDate | |
295 | NULL, // EndDate | |
296 | inParams, // Params, may be NULL | |
297 | &ccHand); | |
298 | if(crtn) { | |
299 | printError("CSSM_CSP_CreateKeyGenContext", crtn); | |
300 | return crtn; | |
301 | } | |
302 | /* cook up attribute bits */ | |
303 | if(pubIsRef) { | |
304 | pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE; | |
305 | } | |
306 | else { | |
307 | pubAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE; | |
308 | } | |
309 | if(privIsRef) { | |
310 | privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE; | |
311 | } | |
312 | else { | |
313 | privAttr = CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE; | |
314 | } | |
315 | ||
316 | if(outParams) { | |
317 | /* explicitly generate params and return them to caller */ | |
318 | outParams->Data = NULL; | |
319 | outParams->Length = 0; | |
320 | crtn = CSSM_GenerateAlgorithmParams(ccHand, | |
321 | keySize, outParams); | |
322 | if(crtn) { | |
323 | printError("CSSM_GenerateAlgorithmParams", crtn); | |
324 | CSSM_DeleteContext(ccHand); | |
325 | return crtn; | |
326 | } | |
327 | } | |
328 | ||
329 | /* optional format specifiers */ | |
330 | if(pubFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) { | |
331 | crtn = AddContextAttribute(ccHand, | |
332 | CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT, | |
333 | sizeof(uint32), | |
334 | CAT_Uint32, | |
335 | NULL, | |
336 | pubFormat); | |
337 | if(crtn) { | |
338 | printError("AddContextAttribute(CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn); | |
339 | return crtn; | |
340 | } | |
341 | } | |
342 | if(privFormat != CSSM_KEYBLOB_RAW_FORMAT_NONE) { | |
343 | crtn = AddContextAttribute(ccHand, | |
344 | CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT, | |
345 | sizeof(uint32), | |
346 | CAT_Uint32, | |
347 | NULL, | |
348 | privFormat); | |
349 | if(crtn) { | |
350 | printError("AddContextAttribute(CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn); | |
351 | return crtn; | |
352 | } | |
353 | } | |
354 | crtn = CSSM_GenerateKeyPair(ccHand, | |
355 | pubKeyUsage, | |
356 | pubAttr, | |
357 | &keyLabelData, | |
358 | pubKey, | |
359 | privKeyUsage, | |
360 | privAttr, | |
361 | &keyLabelData, // same labels | |
362 | NULL, // CredAndAclEntry | |
363 | privKey); | |
364 | if(crtn) { | |
365 | printError("CSSM_GenerateKeyPair", crtn); | |
366 | ocrtn = crtn; | |
367 | } | |
368 | if(ccHand != 0) { | |
369 | crtn = CSSM_DeleteContext(ccHand); | |
370 | if(crtn) { | |
371 | printError("CSSM_DeleteContext", crtn); | |
372 | ocrtn = CSSM_ERRCODE_INTERNAL_ERROR; | |
373 | } | |
374 | } | |
375 | return ocrtn; | |
376 | } | |
377 | ||
378 | /* | |
379 | * Given keyFileBase, obtain name of public or private name. Output names | |
380 | * mallocd by caller. | |
381 | */ | |
382 | #define KEY_FILE_NAME_MAX_LEN 256 | |
383 | ||
384 | static void rtKeyFileName( | |
385 | const char *keyFileBase, | |
386 | CSSM_BOOL isPub, | |
387 | char *outFileName) | |
388 | { | |
389 | if(isPub) { | |
390 | sprintf(outFileName, "%s_pub.der", keyFileBase); | |
391 | } | |
392 | else { | |
393 | sprintf(outFileName, "%s_priv.der", keyFileBase); | |
394 | } | |
395 | } | |
396 | ||
397 | /* | |
398 | * Given keyFileBase and key type, init a CSSM_KEY. | |
399 | */ | |
400 | static int rt_readKey( | |
401 | CSSM_CSP_HANDLE cspHand, | |
402 | const char *keyFileBase, | |
403 | CSSM_BOOL isPub, | |
404 | CSSM_ALGORITHMS alg, | |
405 | CSSM_KEYBLOB_FORMAT format, // FORMAT_NONE ==> default | |
406 | CSSM_KEY_PTR key) | |
407 | { | |
408 | char fileName[KEY_FILE_NAME_MAX_LEN]; | |
409 | int irtn; | |
410 | CSSM_DATA_PTR keyData = &key->KeyData; | |
411 | CSSM_KEYHEADER_PTR hdr = &key->KeyHeader; | |
412 | CSSM_RETURN crtn; | |
413 | CSSM_KEY_SIZE keySize; | |
414 | unsigned len; | |
415 | ||
416 | memset(key, 0, sizeof(CSSM_KEY)); | |
417 | rtKeyFileName(keyFileBase, isPub, fileName); | |
418 | irtn = readFile(fileName, &keyData->Data, &len); | |
419 | if(irtn) { | |
420 | printf("***error %d reading key file %s\n", irtn, fileName); | |
421 | return irtn; | |
422 | } | |
423 | keyData->Length = len; | |
424 | hdr->HeaderVersion = CSSM_KEYHEADER_VERSION; | |
425 | hdr->BlobType = CSSM_KEYBLOB_RAW; | |
426 | hdr->Format = format; | |
427 | hdr->AlgorithmId = alg; | |
428 | hdr->KeyClass = isPub ? CSSM_KEYCLASS_PUBLIC_KEY : | |
429 | CSSM_KEYCLASS_PRIVATE_KEY; | |
430 | hdr->KeyAttr = CSSM_KEYATTR_EXTRACTABLE; | |
431 | hdr->KeyUsage = CSSM_KEYUSE_ANY; | |
432 | ||
433 | /* ask the CSP for key size */ | |
434 | crtn = CSSM_QueryKeySizeInBits(cspHand, 0, key, &keySize); | |
435 | if(crtn) { | |
436 | printError("CSSM_QueryKeySizeInBits", crtn); | |
437 | return 1; | |
438 | } | |
439 | hdr->LogicalKeySizeInBits = keySize.LogicalKeySizeInBits; | |
440 | return 0; | |
441 | } | |
442 | ||
443 | static int rt_generate(opParams *op) | |
444 | { | |
445 | CSSM_RETURN crtn; | |
446 | CSSM_KEY pubKey; | |
447 | CSSM_KEY privKey; | |
448 | char fileName[KEY_FILE_NAME_MAX_LEN]; | |
449 | int irtn; | |
450 | CSSM_DATA paramIn = {0, NULL}; | |
451 | CSSM_DATA paramOut = {0, NULL}; | |
452 | CSSM_DATA_PTR paramInPtr = NULL; | |
453 | CSSM_DATA_PTR paramOutPtr = NULL; | |
454 | ||
455 | if(op->keyFileName == NULL) { | |
456 | printf("***Need a keyFileName to generate key pair.\n"); | |
457 | return 1; | |
458 | } | |
459 | memset(&pubKey, 0, sizeof(CSSM_KEY)); | |
460 | memset(&privKey, 0, sizeof(CSSM_KEY)); | |
461 | ||
462 | if(op->alg == CSSM_ALGID_DSA) { | |
463 | /* must specify either inParams or outParams, not both */ | |
464 | if(op->dsaParamFileIn && op->dsaParamFileOut) { | |
465 | printf("***DSA key generation requires one parameter file spec.\n"); | |
466 | return 1; | |
467 | } | |
468 | if(!op->dsaParamFileIn && !op->dsaParamFileOut) { | |
469 | printf("***DSA key generation requires one parameter file spec.\n"); | |
470 | return 1; | |
471 | } | |
472 | if(op->dsaParamFileIn) { | |
473 | /* caller-specified params */ | |
474 | unsigned len; | |
475 | irtn = readFile(op->dsaParamFileIn, ¶mIn.Data, &len); | |
476 | if(irtn) { | |
477 | printf("***Error reading DSA params from %s. Aborting.\n", | |
478 | op->dsaParamFileIn); | |
479 | } | |
480 | paramIn.Length = len; | |
481 | paramInPtr = ¶mIn; | |
482 | } | |
483 | else { | |
484 | /* generate params --> paramOut */ | |
485 | paramOutPtr = ¶mOut; | |
486 | } | |
487 | crtn = genDsaKeyPair(op->cspHand, | |
488 | USAGE_NAME, | |
489 | USAGE_NAME_LEN, | |
490 | op->keySizeInBits, | |
491 | &pubKey, | |
492 | CSSM_FALSE, // not ref | |
493 | CSSM_KEYUSE_VERIFY, // not really important | |
494 | op->pubKeyFormat, | |
495 | &privKey, | |
496 | CSSM_FALSE, // not ref | |
497 | CSSM_KEYUSE_SIGN, | |
498 | op->privKeyFormat, | |
499 | paramInPtr, | |
500 | paramOutPtr); | |
501 | if(crtn) { | |
502 | return 1; | |
503 | } | |
504 | if(paramOutPtr) { | |
505 | irtn = writeFile(op->dsaParamFileOut, paramOut.Data, paramOut.Length); | |
506 | if(irtn) { | |
507 | printf("***Error writing DSA params to %s. Aborting.\n", | |
508 | op->dsaParamFileOut); | |
509 | return 1; | |
510 | } | |
511 | if(!op->quiet) { | |
512 | printf("...wrote %lu bytes to %s\n", paramOut.Length, | |
513 | op->dsaParamFileOut); | |
514 | } | |
515 | CSSM_FREE(paramOut.Data); | |
516 | } | |
517 | else { | |
518 | /* mallocd by readFile() */ | |
519 | free(paramIn.Data); | |
520 | } | |
521 | } | |
522 | else { | |
523 | /* RSA, ECDSA */ | |
524 | crtn = cspGenKeyPair(op->cspHand, | |
525 | op->alg, | |
526 | USAGE_NAME, | |
527 | USAGE_NAME_LEN, | |
528 | op->keySizeInBits, | |
529 | &pubKey, | |
530 | CSSM_FALSE, // not ref | |
531 | CSSM_KEYUSE_VERIFY, // not really important | |
532 | op->pubKeyFormat, | |
533 | &privKey, | |
534 | CSSM_FALSE, // not ref | |
535 | CSSM_KEYUSE_SIGN, | |
536 | op->privKeyFormat, | |
537 | CSSM_FALSE); // genSeed, not used here | |
538 | if(crtn) { | |
539 | return 1; | |
540 | } | |
541 | } | |
542 | ||
543 | /* write the blobs */ | |
544 | rtKeyFileName(op->keyFileName, CSSM_TRUE, fileName); | |
545 | irtn = writeFile(fileName, pubKey.KeyData.Data, pubKey.KeyData.Length); | |
546 | if(irtn) { | |
547 | printf("***Error %d writing to %s\n", irtn, fileName); | |
548 | return irtn; | |
549 | } | |
550 | if(!op->quiet) { | |
551 | printf("...wrote %lu bytes to %s\n", pubKey.KeyData.Length, fileName); | |
552 | } | |
553 | rtKeyFileName(op->keyFileName, CSSM_FALSE, fileName); | |
554 | irtn = writeFile(fileName, privKey.KeyData.Data, privKey.KeyData.Length); | |
555 | if(irtn) { | |
556 | printf("***Error %d writing to %s\n", irtn, fileName); | |
557 | return irtn; | |
558 | } | |
559 | if(!op->quiet) { | |
560 | printf("...wrote %lu bytes to %s\n", privKey.KeyData.Length, fileName); | |
561 | } | |
562 | cspFreeKey(op->cspHand, &pubKey); | |
563 | cspFreeKey(op->cspHand, &privKey); | |
564 | return 0; | |
565 | } | |
566 | ||
567 | /* encrypt using public key */ | |
568 | static int rt_encrypt(opParams *op) | |
569 | { | |
570 | CSSM_KEY pubKey; | |
571 | int irtn; | |
572 | CSSM_DATA ptext; | |
573 | CSSM_DATA ctext; | |
574 | CSSM_RETURN crtn; | |
575 | CSSM_BOOL isPub; | |
576 | CSSM_ENCRYPT_MODE mode = CSSM_ALGMODE_NONE; | |
577 | CSSM_KEYBLOB_FORMAT format = op->pubKeyFormat; | |
578 | unsigned len; | |
579 | ||
580 | if(op->keyFileName == NULL) { | |
581 | printf("***Need a keyFileName to encrypt.\n"); | |
582 | return 1; | |
583 | } | |
584 | if((op->plainFileName == NULL) || (op->cipherFileName == NULL)) { | |
585 | printf("***Need plainFileName and cipherFileName to encrypt.\n"); | |
586 | return 1; | |
587 | } | |
588 | if(op->swapKeyClass) { | |
589 | isPub = CSSM_FALSE; | |
590 | mode = CSSM_ALGMODE_PRIVATE_KEY; | |
591 | format = op->privKeyFormat; | |
592 | } | |
593 | else { | |
594 | isPub = CSSM_TRUE; | |
595 | } | |
596 | irtn = rt_readKey(op->cspHand, op->keyFileName, isPub, op->alg, | |
597 | format, &pubKey); | |
598 | if(irtn) { | |
599 | return irtn; | |
600 | } | |
601 | irtn = readFile(op->plainFileName, &ptext.Data, &len); | |
602 | if(irtn) { | |
603 | printf("***Error reading %s\n", op->plainFileName); | |
604 | return irtn; | |
605 | } | |
606 | ptext.Length = len; | |
607 | ctext.Data = NULL; | |
608 | ctext.Length = 0; | |
609 | ||
610 | crtn = cspEncrypt(op->cspHand, | |
611 | op->alg, | |
612 | mode, | |
613 | op->noPad ? CSSM_PADDING_NONE : CSSM_PADDING_PKCS1, | |
614 | &pubKey, | |
615 | NULL, | |
616 | 0, // effectiveKeySize | |
617 | 0, // rounds | |
618 | NULL, // initVector | |
619 | &ptext, | |
620 | &ctext, | |
621 | CSSM_FALSE); // mallocCtext | |
622 | if(crtn) { | |
623 | printError("cspEncrypt", crtn); | |
624 | return 1; | |
625 | } | |
626 | irtn = writeFile(op->cipherFileName, ctext.Data, ctext.Length); | |
627 | if(irtn) { | |
628 | printf("***Error writing %s\n", op->cipherFileName); | |
629 | } | |
630 | else { | |
631 | if(!op->quiet) { | |
632 | printf("...wrote %lu bytes to %s\n", ctext.Length, op->cipherFileName); | |
633 | } | |
634 | } | |
635 | ||
636 | free(pubKey.KeyData.Data); // allocd by rt_readKey --> readFile | |
637 | free(ptext.Data); // allocd by readFile | |
638 | appFreeCssmData(&ctext, CSSM_FALSE); // by CSP | |
639 | return irtn; | |
640 | } | |
641 | ||
642 | /* decrypt using private key */ | |
643 | static int rt_decrypt(opParams *op) | |
644 | { | |
645 | CSSM_KEY privKey; | |
646 | int irtn; | |
647 | CSSM_DATA ptext; | |
648 | CSSM_DATA ctext; | |
649 | CSSM_RETURN crtn; | |
650 | CSSM_BOOL isPub; | |
651 | CSSM_ENCRYPT_MODE mode = CSSM_ALGMODE_NONE; | |
652 | CSSM_KEYBLOB_FORMAT format = op->privKeyFormat; | |
653 | unsigned len; | |
654 | ||
655 | if(op->keyFileName == NULL) { | |
656 | printf("***Need a keyFileName to decrypt.\n"); | |
657 | return 1; | |
658 | } | |
659 | if((op->plainFileName == NULL) || (op->cipherFileName == NULL)) { | |
660 | printf("***Need plainFileName and cipherFileName to decrypt.\n"); | |
661 | return 1; | |
662 | } | |
663 | if(op->swapKeyClass) { | |
664 | isPub = CSSM_TRUE; | |
665 | mode = CSSM_ALGMODE_PUBLIC_KEY; | |
666 | format = op->pubKeyFormat; | |
667 | } | |
668 | else { | |
669 | isPub = CSSM_FALSE; | |
670 | } | |
671 | irtn = rt_readKey(op->cspHand, op->keyFileName, isPub, op->alg, | |
672 | format, &privKey); | |
673 | if(irtn) { | |
674 | return irtn; | |
675 | } | |
676 | irtn = readFile(op->cipherFileName, &ctext.Data, &len); | |
677 | if(irtn) { | |
678 | printf("***Error reading %s\n", op->cipherFileName); | |
679 | return irtn; | |
680 | } | |
681 | ctext.Length = len; | |
682 | ptext.Data = NULL; | |
683 | ptext.Length = 0; | |
684 | ||
685 | crtn = cspDecrypt(op->cspHand, | |
686 | op->alg, | |
687 | mode, | |
688 | op->noPad ? CSSM_PADDING_NONE : CSSM_PADDING_PKCS1, | |
689 | &privKey, | |
690 | NULL, | |
691 | 0, // effectiveKeySize | |
692 | 0, // rounds | |
693 | NULL, // initVector | |
694 | &ctext, | |
695 | &ptext, | |
696 | CSSM_FALSE); // mallocCtext | |
697 | if(crtn) { | |
698 | return 1; | |
699 | } | |
700 | irtn = writeFile(op->plainFileName, ptext.Data, ptext.Length); | |
701 | if(irtn) { | |
702 | printf("***Error writing %s\n", op->cipherFileName); | |
703 | } | |
704 | else { | |
705 | if(!op->quiet) { | |
706 | printf("...wrote %lu bytes to %s\n", ptext.Length, op->plainFileName); | |
707 | } | |
708 | } | |
709 | free(privKey.KeyData.Data); // allocd by rt_readKey --> readFile | |
710 | free(ctext.Data); // allocd by readFile | |
711 | appFreeCssmData(&ptext, CSSM_FALSE); // by CSP | |
712 | return irtn; | |
713 | } | |
714 | ||
715 | static int rt_sign(opParams *op) | |
716 | { | |
717 | CSSM_KEY privKey; | |
718 | int irtn; | |
719 | CSSM_DATA ptext; | |
720 | CSSM_DATA sig; | |
721 | CSSM_RETURN crtn; | |
722 | CSSM_ALGORITHMS alg; | |
723 | unsigned len; | |
724 | ||
725 | if(op->keyFileName == NULL) { | |
726 | printf("***Need a keyFileName to sign.\n"); | |
727 | return 1; | |
728 | } | |
729 | if((op->plainFileName == NULL) || (op->sigFileName == NULL)) { | |
730 | printf("***Need plainFileName and sigFileName to sign.\n"); | |
731 | return 1; | |
732 | } | |
733 | irtn = rt_readKey(op->cspHand, op->keyFileName, CSSM_FALSE, op->alg, | |
734 | op->privKeyFormat, &privKey); | |
735 | if(irtn) { | |
736 | return irtn; | |
737 | } | |
738 | irtn = readFile(op->plainFileName, &ptext.Data, &len); | |
739 | if(irtn) { | |
740 | printf("***Error reading %s\n", op->plainFileName); | |
741 | return irtn; | |
742 | } | |
743 | ptext.Length = len; | |
744 | sig.Data = NULL; | |
745 | sig.Length = 0; | |
746 | switch(op->alg) { | |
747 | case CSSM_ALGID_RSA: | |
748 | if(op->rawSign) { | |
749 | alg = CSSM_ALGID_RSA; | |
750 | } | |
751 | else { | |
752 | alg = CSSM_ALGID_SHA1WithRSA; | |
753 | } | |
754 | break; | |
755 | case CSSM_ALGID_DSA: | |
756 | alg = CSSM_ALGID_SHA1WithDSA; | |
757 | break; | |
758 | case CSSM_ALGID_ECDSA: | |
759 | if(op->rawSign) { | |
760 | alg = CSSM_ALGID_ECDSA; | |
761 | } | |
762 | else { | |
763 | alg = CSSM_ALGID_SHA1WithECDSA; | |
764 | } | |
765 | break; | |
766 | default: | |
767 | printf("Hey! Try another alg!\n"); | |
768 | exit(1); | |
769 | } | |
770 | crtn = sigSign(op->cspHand, | |
771 | alg, | |
772 | &privKey, | |
773 | &ptext, | |
774 | &sig, | |
775 | op->digestAlg, | |
776 | op->noPad); | |
777 | if(crtn) { | |
778 | printError("cspSign", crtn); | |
779 | return 1; | |
780 | } | |
781 | irtn = writeFile(op->sigFileName, sig.Data, sig.Length); | |
782 | if(irtn) { | |
783 | printf("***Error writing %s\n", op->sigFileName); | |
784 | } | |
785 | else if(!op->quiet) { | |
786 | printf("...wrote %lu bytes to %s\n", sig.Length, op->sigFileName); | |
787 | } | |
788 | free(privKey.KeyData.Data); // allocd by rt_readKey --> readFile | |
789 | free(ptext.Data); // allocd by readFile | |
790 | appFreeCssmData(&sig, CSSM_FALSE); // by CSP | |
791 | return irtn; | |
792 | } | |
793 | ||
794 | static int rt_verify(opParams *op) | |
795 | { | |
796 | CSSM_KEY pubKey; | |
797 | int irtn; | |
798 | CSSM_DATA ptext; | |
799 | CSSM_DATA sig; | |
800 | CSSM_RETURN crtn; | |
801 | CSSM_ALGORITHMS alg; | |
802 | unsigned len; | |
803 | ||
804 | if(op->keyFileName == NULL) { | |
805 | printf("***Need a keyFileName to verify.\n"); | |
806 | return 1; | |
807 | } | |
808 | if((op->plainFileName == NULL) || (op->sigFileName == NULL)) { | |
809 | printf("***Need plainFileName and sigFileName to verify.\n"); | |
810 | return 1; | |
811 | } | |
812 | irtn = rt_readKey(op->cspHand, op->keyFileName, CSSM_TRUE, op->alg, | |
813 | op->pubKeyFormat, &pubKey); | |
814 | if(irtn) { | |
815 | return irtn; | |
816 | } | |
817 | irtn = readFile(op->plainFileName, &ptext.Data, &len); | |
818 | if(irtn) { | |
819 | printf("***Error reading %s\n", op->plainFileName); | |
820 | return irtn; | |
821 | } | |
822 | ptext.Length = len; | |
823 | irtn = readFile(op->sigFileName, &sig.Data, (unsigned *)&sig.Length); | |
824 | if(irtn) { | |
825 | printf("***Error reading %s\n", op->sigFileName); | |
826 | return irtn; | |
827 | } | |
828 | switch(op->alg) { | |
829 | case CSSM_ALGID_RSA: | |
830 | if(op->rawSign) { | |
831 | alg = CSSM_ALGID_RSA; | |
832 | } | |
833 | else { | |
834 | alg = CSSM_ALGID_SHA1WithRSA; | |
835 | } | |
836 | break; | |
837 | case CSSM_ALGID_DSA: | |
838 | alg = CSSM_ALGID_SHA1WithDSA; | |
839 | break; | |
840 | case CSSM_ALGID_ECDSA: | |
841 | if(op->rawSign) { | |
842 | alg = CSSM_ALGID_ECDSA; | |
843 | } | |
844 | else { | |
845 | alg = CSSM_ALGID_SHA1WithECDSA; | |
846 | } | |
847 | break; | |
848 | default: | |
849 | printf("Hey! Try another alg!\n"); | |
850 | exit(1); | |
851 | } | |
852 | crtn = sigVerify(op->cspHand, | |
853 | alg, | |
854 | &pubKey, | |
855 | &ptext, | |
856 | &sig, | |
857 | op->digestAlg, | |
858 | op->noPad); | |
859 | if(crtn) { | |
860 | printError("sigVerify", crtn); | |
861 | irtn = 1; | |
862 | } | |
863 | else if(!op->quiet){ | |
864 | printf("...signature verifies OK\n"); | |
865 | irtn = 0; | |
866 | } | |
867 | free(pubKey.KeyData.Data); // allocd by rt_readKey --> readFile | |
868 | free(ptext.Data); // allocd by readFile | |
869 | free(sig.Data); // ditto | |
870 | return irtn; | |
871 | } | |
872 | ||
873 | static int rt_digest(opParams *op) | |
874 | { | |
875 | int irtn; | |
876 | CSSM_DATA ptext; | |
877 | CSSM_DATA digest = {0, NULL}; | |
878 | CSSM_RETURN crtn; | |
879 | unsigned len; | |
880 | ||
881 | if((op->plainFileName == NULL) || (op->sigFileName == NULL)) { | |
882 | printf("***Need plainFileName and sigFileName to digest.\n"); | |
883 | return 1; | |
884 | } | |
885 | irtn = readFile(op->plainFileName, &ptext.Data, &len); | |
886 | if(irtn) { | |
887 | printf("***Error reading %s\n", op->plainFileName); | |
888 | return irtn; | |
889 | } | |
890 | ptext.Length = len; | |
891 | crtn = cspDigest(op->cspHand, | |
892 | op->alg, | |
893 | CSSM_FALSE, // mallocDigest - let CSP do it | |
894 | &ptext, | |
895 | &digest); | |
896 | if(crtn) { | |
897 | printError("cspDigest", crtn); | |
898 | return 1; | |
899 | } | |
900 | irtn = writeFile(op->sigFileName, digest.Data, digest.Length); | |
901 | if(irtn) { | |
902 | printf("***Error writing %s\n", op->sigFileName); | |
903 | } | |
904 | else if(!op->quiet){ | |
905 | printf("...wrote %lu bytes to %s\n", digest.Length, op->sigFileName); | |
906 | } | |
907 | free(ptext.Data); // allocd by readFile | |
908 | appFreeCssmData(&digest, CSSM_FALSE); // by CSP | |
909 | return irtn; | |
910 | } | |
911 | ||
912 | static int rt_convertPubKey(opParams *op) | |
913 | { | |
914 | CSSM_RETURN crtn; | |
915 | int irtn; | |
916 | CSSM_KEY pubKeyIn; | |
917 | CSSM_KEY pubKeyOut; | |
918 | CSSM_KEY refKey; | |
919 | char fileName[KEY_FILE_NAME_MAX_LEN]; | |
920 | ||
921 | if((op->keyFileName == NULL) || (op->outKeyFileName == NULL)) { | |
922 | printf("***I need input and output key file names for public key concersion.\n"); | |
923 | return 1; | |
924 | } | |
925 | irtn = rt_readKey(op->cspHand, op->keyFileName, CSSM_TRUE, op->alg, | |
926 | op->pubKeyFormat, &pubKeyIn); | |
927 | if(irtn) { | |
928 | return irtn; | |
929 | } | |
930 | crtn = cspRawKeyToRef(op->cspHand, &pubKeyIn, &refKey); | |
931 | if(crtn) { | |
932 | printf("***Error on NULL unwrap of %s\n", op->keyFileName); | |
933 | return -1; | |
934 | } | |
935 | crtn = nullWrapKey(op->cspHand, &refKey, op->outPubKeyFormat, &pubKeyOut); | |
936 | if(crtn) { | |
937 | printf("***Error on NULL wrap\n"); | |
938 | return 1; | |
939 | } | |
940 | ||
941 | /* write the blobs */ | |
942 | rtKeyFileName(op->outKeyFileName, CSSM_TRUE, fileName); | |
943 | irtn = writeFile(fileName, pubKeyOut.KeyData.Data, pubKeyOut.KeyData.Length); | |
944 | if(irtn) { | |
945 | printf("***Error %d writing to %s\n", irtn, fileName); | |
946 | return irtn; | |
947 | } | |
948 | if(!op->quiet) { | |
949 | printf("...wrote %lu bytes to %s\n", pubKeyOut.KeyData.Length, fileName); | |
950 | } | |
951 | cspFreeKey(op->cspHand, &pubKeyOut); | |
952 | free(pubKeyIn.KeyData.Data); | |
953 | cspFreeKey(op->cspHand, &refKey); | |
954 | return 0; | |
955 | } | |
956 | ||
957 | /* parse public key format character */ | |
958 | static CSSM_KEYBLOB_FORMAT parsePubKeyFormat(char c, char **argv) | |
959 | { | |
960 | switch(c) { | |
961 | case '1': | |
962 | return CSSM_KEYBLOB_RAW_FORMAT_PKCS1; | |
963 | case 'x': | |
964 | return CSSM_KEYBLOB_RAW_FORMAT_X509; | |
965 | case 'b': | |
966 | return CSSM_KEYBLOB_RAW_FORMAT_FIPS186; | |
967 | case 'o': | |
968 | return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH; | |
969 | case 'O': | |
970 | return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2; | |
971 | case 'L': | |
972 | /* This is the "parse a private+public key as public only" option */ | |
973 | return CSSM_KEYBLOB_RAW_FORMAT_OPENSSL; | |
974 | default: | |
975 | usage(argv); | |
976 | } | |
977 | /* not reached */ | |
978 | return -1; | |
979 | } | |
980 | ||
981 | int main(int argc, char **argv) | |
982 | { | |
983 | int arg; | |
984 | char *argp; | |
985 | int rtn; | |
986 | opParams op; | |
987 | ||
988 | if(argc < 2) { | |
989 | usage(argv); | |
990 | } | |
991 | memset(&op, 0, sizeof(opParams)); | |
992 | op.keySizeInBits = DEFAULT_KEY_SIZE_BITS; | |
993 | op.alg = CSSM_ALGID_RSA; | |
994 | op.swapKeyClass = CSSM_FALSE; | |
995 | op.rawSign = CSSM_FALSE; | |
996 | op.noPad = CSSM_FALSE; | |
997 | ||
998 | for(arg=2; arg<argc; arg++) { | |
999 | argp = argv[arg]; | |
1000 | switch(argp[0]) { | |
1001 | case 'a': | |
1002 | if(argp[1] != '=') { | |
1003 | usage(argv); | |
1004 | } | |
1005 | switch(argp[2]) { | |
1006 | case 'r': | |
1007 | op.alg = CSSM_ALGID_RSA; | |
1008 | break; | |
1009 | case 'd': | |
1010 | op.alg = CSSM_ALGID_DSA; | |
1011 | break; | |
1012 | case 'e': | |
1013 | op.alg = CSSM_ALGID_ECDSA; | |
1014 | break; | |
1015 | default: | |
1016 | usage(argv); | |
1017 | } | |
1018 | break; | |
1019 | case 'z': | |
1020 | op.keySizeInBits = atoi(&argp[2]); | |
1021 | break; | |
1022 | case 'k': | |
1023 | op.keyFileName = &argp[2]; | |
1024 | break; | |
1025 | case 'K': | |
1026 | op.outKeyFileName = &argp[2]; | |
1027 | break; | |
1028 | case 'p': | |
1029 | op.plainFileName = &argp[2]; | |
1030 | break; | |
1031 | case 'c': | |
1032 | op.cipherFileName = &argp[2]; | |
1033 | break; | |
1034 | case 's': | |
1035 | op.sigFileName = &argp[2]; | |
1036 | break; | |
1037 | case 'w': | |
1038 | op.swapKeyClass = CSSM_TRUE; | |
1039 | break; | |
1040 | case 'r': | |
1041 | op.rawSign = CSSM_TRUE; | |
1042 | break; | |
1043 | case 'P': | |
1044 | op.noPad = CSSM_TRUE; | |
1045 | break; | |
1046 | case 'm': | |
1047 | op.dsaParamFileIn = &argp[2]; | |
1048 | break; | |
1049 | case 'M': | |
1050 | op.dsaParamFileOut = &argp[2]; | |
1051 | break; | |
1052 | case 'q': | |
1053 | op.quiet = CSSM_TRUE; | |
1054 | break; | |
1055 | case 'b': | |
1056 | if(argp[1] != '=') { | |
1057 | usage(argv); | |
1058 | } | |
1059 | op.pubKeyFormat = parsePubKeyFormat(argp[2], argv); | |
1060 | break; | |
1061 | case 'B': | |
1062 | if(argp[1] != '=') { | |
1063 | usage(argv); | |
1064 | } | |
1065 | op.outPubKeyFormat = parsePubKeyFormat(argp[2], argv); | |
1066 | break; | |
1067 | case 'v': | |
1068 | if(argp[1] != '=') { | |
1069 | usage(argv); | |
1070 | } | |
1071 | switch(argp[2]) { | |
1072 | case '1': | |
1073 | op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; | |
1074 | break; | |
1075 | case '8': | |
1076 | op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; | |
1077 | break; | |
1078 | case 's': | |
1079 | op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSH; | |
1080 | break; | |
1081 | case 'b': | |
1082 | op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_FIPS186; | |
1083 | break; | |
1084 | #if OPENSSL_ENABLE | |
1085 | case 'o': | |
1086 | op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL; | |
1087 | break; | |
1088 | #endif | |
1089 | default: | |
1090 | usage(argv); | |
1091 | } | |
1092 | break; | |
1093 | case 'd': | |
1094 | if(argp[1] != '=') { | |
1095 | usage(argv); | |
1096 | } | |
1097 | switch(argp[2]) { | |
1098 | case 's': | |
1099 | op.digestAlg = CSSM_ALGID_SHA1; | |
1100 | break; | |
1101 | case '5': | |
1102 | op.digestAlg = CSSM_ALGID_MD5; | |
1103 | break; | |
1104 | default: | |
1105 | usage(argv); | |
1106 | } | |
1107 | break; | |
1108 | case 'h': | |
1109 | default: | |
1110 | usage(argv); | |
1111 | } | |
1112 | } | |
1113 | op.cspHand = cspDlDbStartup(CSSM_TRUE, NULL); | |
1114 | if(op.cspHand == 0) { | |
1115 | exit(1); | |
1116 | } | |
1117 | ||
1118 | /* specify blob formats if user didn't */ | |
1119 | if(op.pubKeyFormat == CSSM_KEYBLOB_RAW_FORMAT_NONE) { | |
1120 | switch(op.alg) { | |
1121 | case CSSM_ALGID_RSA: | |
1122 | op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; | |
1123 | break; | |
1124 | case CSSM_ALGID_DSA: | |
1125 | case CSSM_ALGID_ECDSA: | |
1126 | op.pubKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_X509; | |
1127 | break; | |
1128 | default: | |
1129 | printf("BRRZAP!\n"); | |
1130 | exit(1); | |
1131 | } | |
1132 | } | |
1133 | if(op.privKeyFormat == CSSM_KEYBLOB_RAW_FORMAT_NONE) { | |
1134 | switch(op.alg) { | |
1135 | case CSSM_ALGID_RSA: | |
1136 | op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; | |
1137 | break; | |
1138 | case CSSM_ALGID_DSA: | |
1139 | op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_FIPS186; | |
1140 | break; | |
1141 | case CSSM_ALGID_ECDSA: | |
1142 | op.privKeyFormat = CSSM_KEYBLOB_RAW_FORMAT_OPENSSL; | |
1143 | break; | |
1144 | default: | |
1145 | printf("BRRZAP!\n"); | |
1146 | exit(1); | |
1147 | } | |
1148 | } | |
1149 | switch(argv[1][0]) { | |
1150 | case 'g': | |
1151 | rtn = rt_generate(&op); | |
1152 | break; | |
1153 | case 'e': | |
1154 | rtn = rt_encrypt(&op); | |
1155 | break; | |
1156 | case 'd': | |
1157 | rtn = rt_decrypt(&op); | |
1158 | break; | |
1159 | case 's': | |
1160 | rtn = rt_sign(&op); | |
1161 | break; | |
1162 | case 'v': | |
1163 | rtn = rt_verify(&op); | |
1164 | break; | |
1165 | case 'S': | |
1166 | op.alg = CSSM_ALGID_SHA1; | |
1167 | rtn = rt_digest(&op); | |
1168 | break; | |
1169 | case 'M': | |
1170 | op.alg = CSSM_ALGID_MD5; | |
1171 | rtn = rt_digest(&op); | |
1172 | break; | |
1173 | case 'C': | |
1174 | rtn = rt_convertPubKey(&op); | |
1175 | break; | |
1176 | default: | |
1177 | usage(argv); | |
1178 | exit(1); // fool the compiler | |
1179 | } | |
1180 | CSSM_ModuleDetach(op.cspHand); | |
1181 | return rtn; | |
1182 | } |