]> git.saurik.com Git - apple/security.git/blob - SecurityTests/cspxutils/genKeyPair/genKeyPair.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / cspxutils / genKeyPair / genKeyPair.cpp
1 /*
2 * genKeyPair.cpp - create a key pair, store in specified keychain
3 */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <time.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <Security/Security.h>
10 #include "cspwrap.h"
11 #include "common.h"
12
13 static void usage(char **argv)
14 {
15 printf("usage: %s keychain [options]\n", argv[0]);
16 printf("Options:\n");
17 printf(" -l label -- no default\n");
18 printf(" -a r|f|d -- algorithm RSA/FEE/DSA, default = RSA\n");
19 printf(" -k bits -- key size in bits, default is 1024/128/512 for RSA/FEE/DSA\n");
20 exit(1);
21 }
22
23 /*
24 * Generate key pair of arbitrary algorithm.
25 * FEE keys will have random private data.
26 * Like the cspGenKeyPair() in cspwrap.c except this provides a DLDB handle.
27 */
28 static CSSM_RETURN genKeyPair(CSSM_CSP_HANDLE cspHand,
29 CSSM_DL_DB_HANDLE dlDbHand,
30 uint32 algorithm,
31 const char *keyLabel,
32 unsigned keyLabelLen,
33 uint32 keySize, // in bits
34 CSSM_KEY_PTR pubKey, // mallocd by caller
35 uint32 pubKeyUsage, // CSSM_KEYUSE_ENCRYPT, etc.
36 CSSM_KEY_PTR privKey, // mallocd by caller
37 uint32 privKeyUsage) // CSSM_KEYUSE_DECRYPT, etc.
38 {
39 CSSM_RETURN crtn;
40 CSSM_CC_HANDLE ccHand;
41 CSSM_DATA keyLabelData;
42 uint32 pubAttr;
43 uint32 privAttr;
44 CSSM_RETURN ocrtn = CSSM_OK;
45
46 /* pre-context-create algorithm-specific stuff */
47 switch(algorithm) {
48 case CSSM_ALGID_FEE:
49 if(keySize == CSP_KEY_SIZE_DEFAULT) {
50 keySize = CSP_FEE_KEY_SIZE_DEFAULT;
51 }
52 break;
53 case CSSM_ALGID_RSA:
54 if(keySize == CSP_KEY_SIZE_DEFAULT) {
55 keySize = CSP_RSA_KEY_SIZE_DEFAULT;
56 }
57 break;
58 case CSSM_ALGID_DSA:
59 if(keySize == CSP_KEY_SIZE_DEFAULT) {
60 keySize = CSP_DSA_KEY_SIZE_DEFAULT;
61 }
62 break;
63 default:
64 printf("cspGenKeyPair: Unknown algorithm\n");
65 break;
66 }
67 keyLabelData.Data = (uint8 *)keyLabel,
68 keyLabelData.Length = keyLabelLen;
69 memset(pubKey, 0, sizeof(CSSM_KEY));
70 memset(privKey, 0, sizeof(CSSM_KEY));
71
72 crtn = CSSM_CSP_CreateKeyGenContext(cspHand,
73 algorithm,
74 keySize,
75 NULL, // Seed
76 NULL, // Salt
77 NULL, // StartDate
78 NULL, // EndDate
79 NULL, // Params
80 &ccHand);
81 if(crtn) {
82 printError("CSSM_CSP_CreateKeyGenContext", crtn);
83 ocrtn = crtn;
84 goto abort;
85 }
86 /* cook up attribute bits */
87 pubAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT;
88 privAttr = CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT;
89
90 /* post-context-create algorithm-specific stuff */
91 switch(algorithm) {
92 case CSSM_ALGID_DSA:
93 /*
94 * extra step - generate params - this just adds some
95 * info to the context
96 */
97 {
98 CSSM_DATA dummy = {0, NULL};
99 crtn = CSSM_GenerateAlgorithmParams(ccHand,
100 keySize, &dummy);
101 if(crtn) {
102 printError("CSSM_GenerateAlgorithmParams", crtn);
103 return crtn;
104 }
105 appFreeCssmData(&dummy, CSSM_FALSE);
106 }
107 break;
108 default:
109 break;
110 }
111
112 /* add in DL/DB to context */
113 crtn = cspAddDlDbToContext(ccHand, dlDbHand.DLHandle, dlDbHand.DBHandle);
114 if(crtn) {
115 ocrtn = crtn;
116 goto abort;
117 }
118
119 crtn = CSSM_GenerateKeyPair(ccHand,
120 pubKeyUsage,
121 pubAttr,
122 &keyLabelData,
123 pubKey,
124 privKeyUsage,
125 privAttr,
126 &keyLabelData, // same labels
127 NULL, // CredAndAclEntry
128 privKey);
129 if(crtn) {
130 printError("CSSM_GenerateKeyPair", crtn);
131 ocrtn = crtn;
132 goto abort;
133 }
134 abort:
135 if(ccHand != 0) {
136 crtn = CSSM_DeleteContext(ccHand);
137 if(crtn) {
138 printError("CSSM_DeleteContext", crtn);
139 ocrtn = CSSM_ERRCODE_INTERNAL_ERROR;
140 }
141 }
142 return ocrtn;
143 }
144
145 int main(int argc, char **argv)
146 {
147 char *kcName = NULL;
148 char *label = NULL;
149 CSSM_ALGORITHMS keyAlg = CSSM_ALGID_RSA;
150 unsigned keySizeInBits = CSP_KEY_SIZE_DEFAULT;
151
152 if(argc < 2) {
153 usage(argv);
154 }
155 kcName = argv[1];
156
157 extern char *optarg;
158 extern int optind;
159
160 optind = 2;
161 int arg;
162 while ((arg = getopt(argc, argv, "l:a:k:h")) != -1) {
163 switch (arg) {
164 case 'l':
165 label = optarg;
166 break;
167 case 'a':
168 switch(optarg[0]) {
169 case 'r':
170 keyAlg = CSSM_ALGID_RSA;
171 break;
172 case 'f':
173 keyAlg = CSSM_ALGID_FEE;
174 break;
175 case 'd':
176 keyAlg = CSSM_ALGID_DSA;
177 break;
178 default:
179 usage(argv);
180 }
181 break;
182 case 'k':
183 keySizeInBits = atoi(optarg);
184 break;
185 default:
186 usage(argv);
187 }
188 }
189 if(optind != argc) {
190 usage(argv);
191 }
192
193 SecKeychainRef kcRef = nil;
194 OSStatus ortn;
195
196 ortn = SecKeychainOpen(kcName, &kcRef);
197 if(ortn) {
198 cssmPerror("SecKeychainOpen", ortn);
199 exit(1);
200 }
201
202 CSSM_CSP_HANDLE cspHand = 0;
203 CSSM_DL_DB_HANDLE dlDbHand = {0, 0};
204 ortn = SecKeychainGetCSPHandle(kcRef, &cspHand);
205 if(ortn) {
206 cssmPerror("SecKeychainGetCSPHandle", ortn);
207 exit(1);
208 }
209 ortn = SecKeychainGetDLDBHandle(kcRef, &dlDbHand);
210 if(ortn) {
211 cssmPerror("SecKeychainGetDLDBHandle", ortn);
212 exit(1);
213 }
214
215 CSSM_KEY privKey;
216 CSSM_KEY pubKey;
217 CSSM_RETURN crtn;
218
219 crtn = genKeyPair(cspHand, dlDbHand,
220 keyAlg,
221 label, (label ? strlen(label) : 0),
222 keySizeInBits,
223 &pubKey,
224 CSSM_KEYUSE_ANY, // may want to parameterize
225 &privKey,
226 CSSM_KEYUSE_ANY); // may want to parameterize
227 if(crtn) {
228 printf("**Error creating key pair.\n");
229 }
230 else {
231 printf("...key pair created in keychain %s.\n", kcName);
232 }
233
234 cspFreeKey(cspHand, &privKey);
235 cspFreeKey(cspHand, &pubKey);
236 CFRelease(kcRef);
237 return 0;
238 }