2 * Tool to cook up key pair, sign & verify, any which way
3 * with tons of options.
9 #include <Security/cssm.h>
10 #include <Security/cssmapple.h>
13 #include <security_cdsa_utils/cuFileIo.h>
15 #define DATA_SIZE_DEF 100
16 #define USAGE_DEF "noUsage"
18 #define FEE_PASSWD_LEN 32 /* private data length in bytes, FEE only */
20 static void usage(char **argv
)
22 printf("usage: %s [options]\n", argv
[0]);
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");
50 printf(" v(erbose))\n");
54 /* parse public key format character */
55 static CSSM_KEYBLOB_FORMAT
parsePubKeyFormat(char c
, char **argv
)
59 return CSSM_KEYBLOB_RAW_FORMAT_PKCS1
;
61 return CSSM_KEYBLOB_RAW_FORMAT_X509
;
63 return CSSM_KEYBLOB_RAW_FORMAT_FIPS186
;
65 return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH
;
67 return CSSM_KEYBLOB_RAW_FORMAT_OPENSSH2
;
75 int main(int argc
, char **argv
)
79 CSSM_CSP_HANDLE cspHand
;
80 CSSM_CC_HANDLE pubSigHand
;
81 CSSM_CC_HANDLE privSigHand
;
83 CSSM_DATA randData
= {0, NULL
};
86 CSSM_DATA sigData
= {0, NULL
};
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
111 for(arg
=1; arg
<argc
; arg
++) {
113 switch(argv
[arg
][0]) {
120 sigAlg
= CSSM_ALGID_FEE_MD5
;
121 keyGenAlg
= CSSM_ALGID_FEE
;
124 sigAlg
= CSSM_ALGID_FEE_SHA1
;
125 keyGenAlg
= CSSM_ALGID_FEE
;
128 sigAlg
= CSSM_ALGID_SHA1WithECDSA
;
129 keyGenAlg
= CSSM_ALGID_FEE
;
132 sigAlg
= CSSM_ALGID_SHA1WithECDSA
;
133 keyGenAlg
= CSSM_ALGID_ECDSA
;
136 sigAlg
= CSSM_ALGID_SHA256WithECDSA
;
137 keyGenAlg
= CSSM_ALGID_ECDSA
;
140 sigAlg
= CSSM_ALGID_SHA384WithECDSA
;
141 keyGenAlg
= CSSM_ALGID_ECDSA
;
144 sigAlg
= CSSM_ALGID_SHA512WithECDSA
;
145 keyGenAlg
= CSSM_ALGID_ECDSA
;
148 sigAlg
= CSSM_ALGID_MD5WithRSA
;
149 keyGenAlg
= CSSM_ALGID_RSA
;
152 sigAlg
= CSSM_ALGID_MD2WithRSA
;
153 keyGenAlg
= CSSM_ALGID_RSA
;
156 sigAlg
= CSSM_ALGID_SHA1WithRSA
;
157 keyGenAlg
= CSSM_ALGID_RSA
;
160 sigAlg
= CSSM_ALGID_SHA1WithDSA
;
161 keyGenAlg
= CSSM_ALGID_DSA
;
164 sigAlg
= CSSM_ALGID_RSA
;
165 keyGenAlg
= CSSM_ALGID_RSA
;
168 sigAlg
= CSSM_ALGID_SHA224WithRSA
;
169 keyGenAlg
= CSSM_ALGID_RSA
;
172 sigAlg
= CSSM_ALGID_SHA256WithRSA
;
173 keyGenAlg
= CSSM_ALGID_RSA
;
176 sigAlg
= CSSM_ALGID_SHA384WithRSA
;
177 keyGenAlg
= CSSM_ALGID_RSA
;
180 sigAlg
= CSSM_ALGID_SHA512WithRSA
;
181 keyGenAlg
= CSSM_ALGID_RSA
;
188 dataSize
= atoi(&argv
[arg
][2]);
191 keySize
= atoi(&argv
[arg
][2]);
194 loops
= atoi(&argv
[arg
][2]);
197 pauseInterval
= atoi(&argv
[arg
][2]);
200 pubIsRef
= CSSM_FALSE
;
203 privIsRef
= CSSM_FALSE
;
209 pubKeyFormat
= parsePubKeyFormat(argp
[2], argv
);
212 doVerify
= CSSM_FALSE
;
221 noPadding
= CSSM_TRUE
;
224 dumpBlobs
= CSSM_TRUE
;
227 contextsOnly
= CSSM_TRUE
;
230 bareCsp
= CSSM_FALSE
;
239 /* this is for FEE only */
240 pubKeyFormat
= privKeyFormat
= CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING
;
245 curveType
= CSSM_FEE_CURVE_TYPE_MONTGOMERY
;
248 curveType
= CSSM_FEE_CURVE_TYPE_WEIERSTRASS
;
251 curveType
= CSSM_FEE_CURVE_TYPE_ANSI_X9_62
;
260 primeType
= CSSM_FEE_PRIME_TYPE_MERSENNE
;
263 primeType
= CSSM_FEE_PRIME_TYPE_FEE
;
266 primeType
= CSSM_FEE_PRIME_TYPE_GENERAL
;
276 if(!doSign
&& !doVerify
) {
277 printf("s and v mutually exclusive\n");
280 cspHand
= cspDlDbStartup(bareCsp
, NULL
);
284 printf("Starting sigtest; args: ");
285 for(i
=1; i
<argc
; i
++) {
286 printf("%s ", argv
[i
]);
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
;
294 simpleGenData(&pwdData
, FEE_PASSWD_LEN
, FEE_PASSWD_LEN
);
295 pwdDataPtr
= &pwdData
;
300 crtn
= cspGenFEEKeyPair(cspHand
,
313 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
317 else if((keyGenAlg
== CSSM_ALGID_DSA
) && !bareCsp
) {
318 /* CSPDL doesn't do gen alg params */
319 crtn
= cspGenDSAKeyPair(cspHand
,
330 CSSM_KEYBLOB_RAW_FORMAT_NONE
,
335 crtn
= cspGenKeyPair(cspHand
,
351 CSSM_ModuleDetach(cspHand
);
356 writeFile("pubKey.blob", pubKey
.KeyData
.Data
, pubKey
.KeyData
.Length
);
357 printf("...wrote %lu bytes to pubKey.blob\n", pubKey
.KeyData
.Length
);
360 writeFile("privKey.blob", privKey
.KeyData
.Data
, privKey
.KeyData
.Length
);
361 printf("...wrote %lu bytes to privKey.blob\n", privKey
.KeyData
.Length
);
364 randData
.Data
= (uint8
*)CSSM_MALLOC(dataSize
);
365 randData
.Length
= dataSize
;
366 simpleGenData(&randData
, dataSize
, dataSize
);
368 for(loop
=1; ; loop
++) {
370 printf("...Loop %d\n", loop
);
372 if((loop
== 1) || doSign
) {
373 crtn
= CSSM_CSP_CreateSignatureContext(cspHand
,
379 printError("CSSM_CSP_CreateSignatureContext (1)", crtn
);
383 crtn
= AddContextAttribute(privSigHand
,
384 CSSM_ATTRIBUTE_PADDING
,
394 crtn
= CSSM_SignData(privSigHand
,
400 printError("CSSM_SignData error", crtn
);
404 crtn
= CSSM_DeleteContext(privSigHand
);
406 printError("CSSM_DeleteContext", crtn
);
410 writeFile("sig.blob", sigData
.Data
, sigData
.Length
);
411 printf("...wrote %lu bytes to sig.blob\n", sigData
.Length
);
415 crtn
= CSSM_CSP_CreateSignatureContext(cspHand
,
421 printError("CSSM_CSP_CreateSignatureContext (2)", crtn
);
425 crtn
= AddContextAttribute(pubSigHand
,
426 CSSM_ATTRIBUTE_PADDING
,
436 crtn
= CSSM_VerifyData(pubSigHand
,
442 printError("CSSM_VerifyData", crtn
);
446 crtn
= CSSM_DeleteContext(pubSigHand
);
448 printError("CSSM_DeleteContext", crtn
);
452 if(doSign
& !contextsOnly
) {
453 CSSM_FREE(sigData
.Data
);
457 /* else keep it around for next verify */
459 if(loops
&& (loop
== loops
)) {
462 if(pauseInterval
&& ((loop
% pauseInterval
) == 0)) {
466 printf("Hit CR to proceed, q to quit: ");
473 if(randData
.Data
!= NULL
) {
474 CSSM_FREE(randData
.Data
);
476 if(CSSM_ModuleDetach(cspHand
)) {
477 printError("CSSM_CSP_Detach", crtn
);
480 if(crtn
== CSSM_OK
) {