2 * rsatool.c - RSA/DSA/ECDSA key pair generator, en/decrypt, sign/verify with file I/O
9 #include <Security/cssm.h>
12 #include <security_cdsa_utils/cuFileIo.h>
14 /* For 3141770 - defined true when PR-3074739 merged to TOT Security */
15 #define OPENSSL_ENABLE 1
17 #define USAGE_NAME "noUsage"
18 #define USAGE_NAME_LEN (strlen(USAGE_NAME))
19 #define DEFAULT_KEY_SIZE_BITS 512
24 CSSM_CSP_HANDLE cspHand
;
26 char *outKeyFileName
; // for pub key convert
31 char *dsaParamFileOut
;
32 CSSM_BOOL swapKeyClass
;
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
42 static void usage(char **argv
)
44 printf("usage: %s op [options]\n", argv
[0]);
46 printf(" g generate key pair\n");
47 printf(" e encrypt\n");
48 printf(" d decrypt\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");
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
90 CSSM_CC_HANDLE ccHand
;
92 CSSM_ACCESS_CREDENTIALS creds
;
93 CSSM_DATA descData
= {0, 0};
95 memset(rawKey
, 0, sizeof(CSSM_KEY
));
96 memset(&creds
, 0, sizeof(CSSM_ACCESS_CREDENTIALS
));
97 crtn
= CSSM_CSP_CreateSymmetricContext(cspHand
,
100 &creds
, // passPhrase
101 NULL
, // unwrappingKey
107 printError("cspWrapKey/CreateContext", crtn
);
110 if(blobFormat
!= CSSM_KEYBLOB_WRAPPED_FORMAT_NONE
) {
111 /* only add this attribute if it's not the default */
112 CSSM_ATTRIBUTE_TYPE attrType
;
114 switch(refKey
->KeyHeader
.KeyClass
) {
115 case CSSM_KEYCLASS_SESSION_KEY
:
116 attrType
= CSSM_ATTRIBUTE_SYMMETRIC_KEY_FORMAT
;
118 case CSSM_KEYCLASS_PUBLIC_KEY
:
119 attrType
= CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT
;
121 case CSSM_KEYCLASS_PRIVATE_KEY
:
122 attrType
= CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT
;
125 printf("***Bogus KeyClass in nullWrapKey\n");
128 CSSM_CONTEXT_ATTRIBUTE attr
;
129 attr
.AttributeType
= attrType
;
130 attr
.AttributeLength
= sizeof(uint32
);
131 attr
.Attribute
.Uint32
= blobFormat
;
132 crtn
= CSSM_UpdateContextAttributes(
137 printError("CSSM_UpdateContextAttributes", crtn
);
141 crtn
= CSSM_WrapKey(ccHand
,
146 if(crtn
!= CSSM_OK
) {
147 printError("CSSM_WrapKey", crtn
);
149 if(CSSM_DeleteContext(ccHand
)) {
150 printf("CSSM_DeleteContext failure\n");
156 * Sign/verify optional "no padding" context attr
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
,
163 uint32 digestAlg
, // optional for raw signing
164 CSSM_BOOL noPad
) // true --> add PADDING_NONE to context
166 CSSM_CC_HANDLE sigHand
;
169 crtn
= CSSM_CSP_CreateSignatureContext(cspHand
,
175 printError("CSSM_CSP_CreateSignatureContext", crtn
);
179 crtn
= AddContextAttribute(sigHand
,
180 CSSM_ATTRIBUTE_PADDING
,
189 crtn
= CSSM_SignData(sigHand
,
195 printError("CSSM_SignData", crtn
);
197 CSSM_DeleteContext(sigHand
);
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
209 CSSM_CC_HANDLE sigHand
;
212 crtn
= CSSM_CSP_CreateSignatureContext(cspHand
,
218 printError("CSSM_CSP_CreateSignatureContext", crtn
);
222 crtn
= AddContextAttribute(sigHand
,
223 CSSM_ATTRIBUTE_PADDING
,
232 crtn
= CSSM_VerifyData(sigHand
,
238 printError("CSSM_VerifyData", crtn
);
240 CSSM_DeleteContext(sigHand
);
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.
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
270 CSSM_CC_HANDLE ccHand
;
271 CSSM_DATA keyLabelData
;
274 CSSM_RETURN ocrtn
= CSSM_OK
;
276 /* Caller must specify either inParams or outParams, not both */
277 if(inParams
&& outParams
) {
278 return CSSMERR_CSSM_INVALID_POINTER
;
280 if(!inParams
&& !outParams
) {
281 return CSSMERR_CSSM_INVALID_POINTER
;
284 keyLabelData
.Data
= (uint8
*)keyLabel
,
285 keyLabelData
.Length
= keyLabelLen
;
286 memset(pubKey
, 0, sizeof(CSSM_KEY
));
287 memset(privKey
, 0, sizeof(CSSM_KEY
));
289 crtn
= CSSM_CSP_CreateKeyGenContext(cspHand
,
296 inParams
, // Params, may be NULL
299 printError("CSSM_CSP_CreateKeyGenContext", crtn
);
302 /* cook up attribute bits */
304 pubAttr
= CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_EXTRACTABLE
;
307 pubAttr
= CSSM_KEYATTR_RETURN_DATA
| CSSM_KEYATTR_EXTRACTABLE
;
310 privAttr
= CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_EXTRACTABLE
;
313 privAttr
= CSSM_KEYATTR_RETURN_DATA
| CSSM_KEYATTR_EXTRACTABLE
;
317 /* explicitly generate params and return them to caller */
318 outParams
->Data
= NULL
;
319 outParams
->Length
= 0;
320 crtn
= CSSM_GenerateAlgorithmParams(ccHand
,
323 printError("CSSM_GenerateAlgorithmParams", crtn
);
324 CSSM_DeleteContext(ccHand
);
329 /* optional format specifiers */
330 if(pubFormat
!= CSSM_KEYBLOB_RAW_FORMAT_NONE
) {
331 crtn
= AddContextAttribute(ccHand
,
332 CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT
,
338 printError("AddContextAttribute(CSSM_ATTRIBUTE_PUBLIC_KEY_FORMAT)", crtn
);
342 if(privFormat
!= CSSM_KEYBLOB_RAW_FORMAT_NONE
) {
343 crtn
= AddContextAttribute(ccHand
,
344 CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT
,
350 printError("AddContextAttribute(CSSM_ATTRIBUTE_PRIVATE_KEY_FORMAT)", crtn
);
354 crtn
= CSSM_GenerateKeyPair(ccHand
,
361 &keyLabelData
, // same labels
362 NULL
, // CredAndAclEntry
365 printError("CSSM_GenerateKeyPair", crtn
);
369 crtn
= CSSM_DeleteContext(ccHand
);
371 printError("CSSM_DeleteContext", crtn
);
372 ocrtn
= CSSM_ERRCODE_INTERNAL_ERROR
;
379 * Given keyFileBase, obtain name of public or private name. Output names
382 #define KEY_FILE_NAME_MAX_LEN 256
384 static void rtKeyFileName(
385 const char *keyFileBase
,
390 sprintf(outFileName
, "%s_pub.der", keyFileBase
);
393 sprintf(outFileName
, "%s_priv.der", keyFileBase
);
398 * Given keyFileBase and key type, init a CSSM_KEY.
400 static int rt_readKey(
401 CSSM_CSP_HANDLE cspHand
,
402 const char *keyFileBase
,
405 CSSM_KEYBLOB_FORMAT format
, // FORMAT_NONE ==> default
408 char fileName
[KEY_FILE_NAME_MAX_LEN
];
410 CSSM_DATA_PTR keyData
= &key
->KeyData
;
411 CSSM_KEYHEADER_PTR hdr
= &key
->KeyHeader
;
413 CSSM_KEY_SIZE keySize
;
416 memset(key
, 0, sizeof(CSSM_KEY
));
417 rtKeyFileName(keyFileBase
, isPub
, fileName
);
418 irtn
= readFile(fileName
, &keyData
->Data
, &len
);
420 printf("***error %d reading key file %s\n", irtn
, fileName
);
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
;
433 /* ask the CSP for key size */
434 crtn
= CSSM_QueryKeySizeInBits(cspHand
, 0, key
, &keySize
);
436 printError("CSSM_QueryKeySizeInBits", crtn
);
439 hdr
->LogicalKeySizeInBits
= keySize
.LogicalKeySizeInBits
;
443 static int rt_generate(opParams
*op
)
448 char fileName
[KEY_FILE_NAME_MAX_LEN
];
450 CSSM_DATA paramIn
= {0, NULL
};
451 CSSM_DATA paramOut
= {0, NULL
};
452 CSSM_DATA_PTR paramInPtr
= NULL
;
453 CSSM_DATA_PTR paramOutPtr
= NULL
;
455 if(op
->keyFileName
== NULL
) {
456 printf("***Need a keyFileName to generate key pair.\n");
459 memset(&pubKey
, 0, sizeof(CSSM_KEY
));
460 memset(&privKey
, 0, sizeof(CSSM_KEY
));
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");
468 if(!op
->dsaParamFileIn
&& !op
->dsaParamFileOut
) {
469 printf("***DSA key generation requires one parameter file spec.\n");
472 if(op
->dsaParamFileIn
) {
473 /* caller-specified params */
475 irtn
= readFile(op
->dsaParamFileIn
, ¶mIn
.Data
, &len
);
477 printf("***Error reading DSA params from %s. Aborting.\n",
480 paramIn
.Length
= len
;
481 paramInPtr
= ¶mIn
;
484 /* generate params --> paramOut */
485 paramOutPtr
= ¶mOut
;
487 crtn
= genDsaKeyPair(op
->cspHand
,
492 CSSM_FALSE
, // not ref
493 CSSM_KEYUSE_VERIFY
, // not really important
496 CSSM_FALSE
, // not ref
505 irtn
= writeFile(op
->dsaParamFileOut
, paramOut
.Data
, paramOut
.Length
);
507 printf("***Error writing DSA params to %s. Aborting.\n",
508 op
->dsaParamFileOut
);
512 printf("...wrote %lu bytes to %s\n", paramOut
.Length
,
513 op
->dsaParamFileOut
);
515 CSSM_FREE(paramOut
.Data
);
518 /* mallocd by readFile() */
524 crtn
= cspGenKeyPair(op
->cspHand
,
530 CSSM_FALSE
, // not ref
531 CSSM_KEYUSE_VERIFY
, // not really important
534 CSSM_FALSE
, // not ref
537 CSSM_FALSE
); // genSeed, not used here
543 /* write the blobs */
544 rtKeyFileName(op
->keyFileName
, CSSM_TRUE
, fileName
);
545 irtn
= writeFile(fileName
, pubKey
.KeyData
.Data
, pubKey
.KeyData
.Length
);
547 printf("***Error %d writing to %s\n", irtn
, fileName
);
551 printf("...wrote %lu bytes to %s\n", pubKey
.KeyData
.Length
, fileName
);
553 rtKeyFileName(op
->keyFileName
, CSSM_FALSE
, fileName
);
554 irtn
= writeFile(fileName
, privKey
.KeyData
.Data
, privKey
.KeyData
.Length
);
556 printf("***Error %d writing to %s\n", irtn
, fileName
);
560 printf("...wrote %lu bytes to %s\n", privKey
.KeyData
.Length
, fileName
);
562 cspFreeKey(op
->cspHand
, &pubKey
);
563 cspFreeKey(op
->cspHand
, &privKey
);
567 /* encrypt using public key */
568 static int rt_encrypt(opParams
*op
)
576 CSSM_ENCRYPT_MODE mode
= CSSM_ALGMODE_NONE
;
577 CSSM_KEYBLOB_FORMAT format
= op
->pubKeyFormat
;
580 if(op
->keyFileName
== NULL
) {
581 printf("***Need a keyFileName to encrypt.\n");
584 if((op
->plainFileName
== NULL
) || (op
->cipherFileName
== NULL
)) {
585 printf("***Need plainFileName and cipherFileName to encrypt.\n");
588 if(op
->swapKeyClass
) {
590 mode
= CSSM_ALGMODE_PRIVATE_KEY
;
591 format
= op
->privKeyFormat
;
596 irtn
= rt_readKey(op
->cspHand
, op
->keyFileName
, isPub
, op
->alg
,
601 irtn
= readFile(op
->plainFileName
, &ptext
.Data
, &len
);
603 printf("***Error reading %s\n", op
->plainFileName
);
610 crtn
= cspEncrypt(op
->cspHand
,
613 op
->noPad
? CSSM_PADDING_NONE
: CSSM_PADDING_PKCS1
,
616 0, // effectiveKeySize
621 CSSM_FALSE
); // mallocCtext
623 printError("cspEncrypt", crtn
);
626 irtn
= writeFile(op
->cipherFileName
, ctext
.Data
, ctext
.Length
);
628 printf("***Error writing %s\n", op
->cipherFileName
);
632 printf("...wrote %lu bytes to %s\n", ctext
.Length
, op
->cipherFileName
);
636 free(pubKey
.KeyData
.Data
); // allocd by rt_readKey --> readFile
637 free(ptext
.Data
); // allocd by readFile
638 appFreeCssmData(&ctext
, CSSM_FALSE
); // by CSP
642 /* decrypt using private key */
643 static int rt_decrypt(opParams
*op
)
651 CSSM_ENCRYPT_MODE mode
= CSSM_ALGMODE_NONE
;
652 CSSM_KEYBLOB_FORMAT format
= op
->privKeyFormat
;
655 if(op
->keyFileName
== NULL
) {
656 printf("***Need a keyFileName to decrypt.\n");
659 if((op
->plainFileName
== NULL
) || (op
->cipherFileName
== NULL
)) {
660 printf("***Need plainFileName and cipherFileName to decrypt.\n");
663 if(op
->swapKeyClass
) {
665 mode
= CSSM_ALGMODE_PUBLIC_KEY
;
666 format
= op
->pubKeyFormat
;
671 irtn
= rt_readKey(op
->cspHand
, op
->keyFileName
, isPub
, op
->alg
,
676 irtn
= readFile(op
->cipherFileName
, &ctext
.Data
, &len
);
678 printf("***Error reading %s\n", op
->cipherFileName
);
685 crtn
= cspDecrypt(op
->cspHand
,
688 op
->noPad
? CSSM_PADDING_NONE
: CSSM_PADDING_PKCS1
,
691 0, // effectiveKeySize
696 CSSM_FALSE
); // mallocCtext
700 irtn
= writeFile(op
->plainFileName
, ptext
.Data
, ptext
.Length
);
702 printf("***Error writing %s\n", op
->cipherFileName
);
706 printf("...wrote %lu bytes to %s\n", ptext
.Length
, op
->plainFileName
);
709 free(privKey
.KeyData
.Data
); // allocd by rt_readKey --> readFile
710 free(ctext
.Data
); // allocd by readFile
711 appFreeCssmData(&ptext
, CSSM_FALSE
); // by CSP
715 static int rt_sign(opParams
*op
)
725 if(op
->keyFileName
== NULL
) {
726 printf("***Need a keyFileName to sign.\n");
729 if((op
->plainFileName
== NULL
) || (op
->sigFileName
== NULL
)) {
730 printf("***Need plainFileName and sigFileName to sign.\n");
733 irtn
= rt_readKey(op
->cspHand
, op
->keyFileName
, CSSM_FALSE
, op
->alg
,
734 op
->privKeyFormat
, &privKey
);
738 irtn
= readFile(op
->plainFileName
, &ptext
.Data
, &len
);
740 printf("***Error reading %s\n", op
->plainFileName
);
749 alg
= CSSM_ALGID_RSA
;
752 alg
= CSSM_ALGID_SHA1WithRSA
;
756 alg
= CSSM_ALGID_SHA1WithDSA
;
758 case CSSM_ALGID_ECDSA
:
760 alg
= CSSM_ALGID_ECDSA
;
763 alg
= CSSM_ALGID_SHA1WithECDSA
;
767 printf("Hey! Try another alg!\n");
770 crtn
= sigSign(op
->cspHand
,
778 printError("cspSign", crtn
);
781 irtn
= writeFile(op
->sigFileName
, sig
.Data
, sig
.Length
);
783 printf("***Error writing %s\n", op
->sigFileName
);
785 else if(!op
->quiet
) {
786 printf("...wrote %lu bytes to %s\n", sig
.Length
, op
->sigFileName
);
788 free(privKey
.KeyData
.Data
); // allocd by rt_readKey --> readFile
789 free(ptext
.Data
); // allocd by readFile
790 appFreeCssmData(&sig
, CSSM_FALSE
); // by CSP
794 static int rt_verify(opParams
*op
)
804 if(op
->keyFileName
== NULL
) {
805 printf("***Need a keyFileName to verify.\n");
808 if((op
->plainFileName
== NULL
) || (op
->sigFileName
== NULL
)) {
809 printf("***Need plainFileName and sigFileName to verify.\n");
812 irtn
= rt_readKey(op
->cspHand
, op
->keyFileName
, CSSM_TRUE
, op
->alg
,
813 op
->pubKeyFormat
, &pubKey
);
817 irtn
= readFile(op
->plainFileName
, &ptext
.Data
, &len
);
819 printf("***Error reading %s\n", op
->plainFileName
);
823 irtn
= readFile(op
->sigFileName
, &sig
.Data
, (unsigned *)&sig
.Length
);
825 printf("***Error reading %s\n", op
->sigFileName
);
831 alg
= CSSM_ALGID_RSA
;
834 alg
= CSSM_ALGID_SHA1WithRSA
;
838 alg
= CSSM_ALGID_SHA1WithDSA
;
840 case CSSM_ALGID_ECDSA
:
842 alg
= CSSM_ALGID_ECDSA
;
845 alg
= CSSM_ALGID_SHA1WithECDSA
;
849 printf("Hey! Try another alg!\n");
852 crtn
= sigVerify(op
->cspHand
,
860 printError("sigVerify", crtn
);
864 printf("...signature verifies OK\n");
867 free(pubKey
.KeyData
.Data
); // allocd by rt_readKey --> readFile
868 free(ptext
.Data
); // allocd by readFile
869 free(sig
.Data
); // ditto
873 static int rt_digest(opParams
*op
)
877 CSSM_DATA digest
= {0, NULL
};
881 if((op
->plainFileName
== NULL
) || (op
->sigFileName
== NULL
)) {
882 printf("***Need plainFileName and sigFileName to digest.\n");
885 irtn
= readFile(op
->plainFileName
, &ptext
.Data
, &len
);
887 printf("***Error reading %s\n", op
->plainFileName
);
891 crtn
= cspDigest(op
->cspHand
,
893 CSSM_FALSE
, // mallocDigest - let CSP do it
897 printError("cspDigest", crtn
);
900 irtn
= writeFile(op
->sigFileName
, digest
.Data
, digest
.Length
);
902 printf("***Error writing %s\n", op
->sigFileName
);
905 printf("...wrote %lu bytes to %s\n", digest
.Length
, op
->sigFileName
);
907 free(ptext
.Data
); // allocd by readFile
908 appFreeCssmData(&digest
, CSSM_FALSE
); // by CSP
912 static int rt_convertPubKey(opParams
*op
)
919 char fileName
[KEY_FILE_NAME_MAX_LEN
];
921 if((op
->keyFileName
== NULL
) || (op
->outKeyFileName
== NULL
)) {
922 printf("***I need input and output key file names for public key concersion.\n");
925 irtn
= rt_readKey(op
->cspHand
, op
->keyFileName
, CSSM_TRUE
, op
->alg
,
926 op
->pubKeyFormat
, &pubKeyIn
);
930 crtn
= cspRawKeyToRef(op
->cspHand
, &pubKeyIn
, &refKey
);
932 printf("***Error on NULL unwrap of %s\n", op
->keyFileName
);
935 crtn
= nullWrapKey(op
->cspHand
, &refKey
, op
->outPubKeyFormat
, &pubKeyOut
);
937 printf("***Error on NULL wrap\n");
941 /* write the blobs */
942 rtKeyFileName(op
->outKeyFileName
, CSSM_TRUE
, fileName
);
943 irtn
= writeFile(fileName
, pubKeyOut
.KeyData
.Data
, pubKeyOut
.KeyData
.Length
);
945 printf("***Error %d writing to %s\n", irtn
, fileName
);
949 printf("...wrote %lu bytes to %s\n", pubKeyOut
.KeyData
.Length
, fileName
);
951 cspFreeKey(op
->cspHand
, &pubKeyOut
);
952 free(pubKeyIn
.KeyData
.Data
);
953 cspFreeKey(op
->cspHand
, &refKey
);
957 /* parse public key format character */
958 static CSSM_KEYBLOB_FORMAT
parsePubKeyFormat(char c
, char **argv
)
962 return CSSM_KEYBLOB_RAW_FORMAT_PKCS1
;
964 return CSSM_KEYBLOB_RAW_FORMAT_X509
;
966 return CSSM_KEYBLOB_RAW_FORMAT_FIPS186
;
968 return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH
;
970 return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2
;
972 /* This is the "parse a private+public key as public only" option */
973 return CSSM_KEYBLOB_RAW_FORMAT_OPENSSL
;
981 int main(int argc
, char **argv
)
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
;
998 for(arg
=2; arg
<argc
; arg
++) {
1002 if(argp
[1] != '=') {
1007 op
.alg
= CSSM_ALGID_RSA
;
1010 op
.alg
= CSSM_ALGID_DSA
;
1013 op
.alg
= CSSM_ALGID_ECDSA
;
1020 op
.keySizeInBits
= atoi(&argp
[2]);
1023 op
.keyFileName
= &argp
[2];
1026 op
.outKeyFileName
= &argp
[2];
1029 op
.plainFileName
= &argp
[2];
1032 op
.cipherFileName
= &argp
[2];
1035 op
.sigFileName
= &argp
[2];
1038 op
.swapKeyClass
= CSSM_TRUE
;
1041 op
.rawSign
= CSSM_TRUE
;
1044 op
.noPad
= CSSM_TRUE
;
1047 op
.dsaParamFileIn
= &argp
[2];
1050 op
.dsaParamFileOut
= &argp
[2];
1053 op
.quiet
= CSSM_TRUE
;
1056 if(argp
[1] != '=') {
1059 op
.pubKeyFormat
= parsePubKeyFormat(argp
[2], argv
);
1062 if(argp
[1] != '=') {
1065 op
.outPubKeyFormat
= parsePubKeyFormat(argp
[2], argv
);
1068 if(argp
[1] != '=') {
1073 op
.privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_PKCS1
;
1076 op
.privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_PKCS8
;
1079 op
.privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_OPENSSH
;
1082 op
.pubKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_FIPS186
;
1086 op
.privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_OPENSSL
;
1094 if(argp
[1] != '=') {
1099 op
.digestAlg
= CSSM_ALGID_SHA1
;
1102 op
.digestAlg
= CSSM_ALGID_MD5
;
1113 op
.cspHand
= cspDlDbStartup(CSSM_TRUE
, NULL
);
1114 if(op
.cspHand
== 0) {
1118 /* specify blob formats if user didn't */
1119 if(op
.pubKeyFormat
== CSSM_KEYBLOB_RAW_FORMAT_NONE
) {
1121 case CSSM_ALGID_RSA
:
1122 op
.pubKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_PKCS1
;
1124 case CSSM_ALGID_DSA
:
1125 case CSSM_ALGID_ECDSA
:
1126 op
.pubKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_X509
;
1129 printf("BRRZAP!\n");
1133 if(op
.privKeyFormat
== CSSM_KEYBLOB_RAW_FORMAT_NONE
) {
1135 case CSSM_ALGID_RSA
:
1136 op
.privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_PKCS8
;
1138 case CSSM_ALGID_DSA
:
1139 op
.privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_FIPS186
;
1141 case CSSM_ALGID_ECDSA
:
1142 op
.privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_OPENSSL
;
1145 printf("BRRZAP!\n");
1149 switch(argv
[1][0]) {
1151 rtn
= rt_generate(&op
);
1154 rtn
= rt_encrypt(&op
);
1157 rtn
= rt_decrypt(&op
);
1163 rtn
= rt_verify(&op
);
1166 op
.alg
= CSSM_ALGID_SHA1
;
1167 rtn
= rt_digest(&op
);
1170 op
.alg
= CSSM_ALGID_MD5
;
1171 rtn
= rt_digest(&op
);
1174 rtn
= rt_convertPubKey(&op
);
1178 exit(1); // fool the compiler
1180 CSSM_ModuleDetach(op
.cspHand
);