]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/clTool/clTool.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / clTool / clTool.cpp
1 /*
2 * clTool.cpp - menu-driven CL exerciser
3 */
4
5 #include <security_cdsa_utils/cuPrintCert.h>
6 #include <security_cdsa_utils/cuOidParser.h>
7 #include <security_cdsa_utils/cuFileIo.h>
8 #include <clAppUtils/clutils.h>
9 #include <utilLib/common.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <time.h>
14 #include <Security/cssmtype.h>
15 #include <Security/cssmapi.h>
16 #include <Security/oidscert.h>
17
18 /*
19 * A list of OIDs we inquire about.
20 */
21 static const CSSM_OID *knownOids[] =
22 {
23 &CSSMOID_X509V1Version, // not always present
24 &CSSMOID_X509V1SerialNumber,
25 &CSSMOID_X509V1IssuerNameCStruct,
26 &CSSMOID_X509V1SubjectNameCStruct,
27 &CSSMOID_CSSMKeyStruct,
28 &CSSMOID_X509V1SubjectPublicKeyCStruct,
29 &CSSMOID_X509V1ValidityNotBefore,
30 &CSSMOID_X509V1ValidityNotAfter,
31 &CSSMOID_X509V1SignatureAlgorithmTBS,
32 &CSSMOID_X509V1SignatureAlgorithm,
33 &CSSMOID_X509V1Signature,
34 &CSSMOID_X509V3CertificateExtensionCStruct,
35 &CSSMOID_KeyUsage,
36 &CSSMOID_BasicConstraints,
37 &CSSMOID_ExtendedKeyUsage,
38 &CSSMOID_CertificatePolicies,
39 &CSSMOID_NetscapeCertType
40 };
41
42 #define NUM_KNOWN_OIDS (sizeof(knownOids) / sizeof(CSSM_OID *))
43
44 static const char *oidNames[] =
45 {
46 "CSSMOID_X509V1Version",
47 "CSSMOID_X509V1SerialNumber",
48 "CSSMOID_X509V1IssuerNameCStruct",
49 "CSSMOID_X509V1SubjectNameCStruct",
50 "CSSMOID_CSSMKeyStruct",
51 "CSSMOID_X509V1SubjectPublicKeyCStruct",
52 "CSSMOID_X509V1ValidityNotBefore",
53 "CSSMOID_X509V1ValidityNotAfter",
54 "CSSMOID_X509V1SignatureAlgorithmTBS",
55 "CSSMOID_X509V1SignatureAlgorithm",
56 "CSSMOID_X509V1Signature",
57 "CSSMOID_X509V3CertificateExtensionCStruct",
58 "CSSMOID_KeyUsage",
59 "CSSMOID_BasicConstraints",
60 "CSSMOID_ExtendedKeyUsage",
61 "CSSMOID_CertificatePolicies",
62 "CSSMOID_NetscapeCertType"
63 };
64
65 static void usage(char **argv)
66 {
67 printf("Usage: %s certFile\n", argv[0]);
68 exit(1);
69 }
70
71 int main(int argc, char **argv)
72 {
73 CSSM_DATA certData = {0, NULL};
74 CSSM_CL_HANDLE clHand = CSSM_INVALID_HANDLE;
75 CSSM_HANDLE cacheHand = CSSM_INVALID_HANDLE;
76 CSSM_HANDLE searchHand = CSSM_INVALID_HANDLE;
77 char resp;
78 CSSM_RETURN crtn;
79 unsigned fieldDex;
80 CSSM_DATA_PTR fieldValue;
81 uint32 numFields;
82 CSSM_FIELD field;
83 CSSM_FIELD_PTR fieldPtr;
84 OidParser parser;
85 unsigned len;
86
87 if(argc != 2) {
88 usage(argv);
89 }
90 if(readFile(argv[1], &certData.Data, &len)) {
91 printf("Can't read file %s' aborting.\n", argv[1]);
92 exit(1);
93 }
94 certData.Length = len;
95
96 while(1) {
97 fpurge(stdin);
98 printf("a load/attach\n");
99 printf("d detach/unload\n");
100 printf("c cache the cert\n");
101 printf("u uncache the cert\n");
102 printf("g get field (uncached)\n");
103 printf("G get field (cached)\n");
104 printf("f get all fields, then free\n");
105 printf("q quit\n");
106 printf("Enter command: ");
107 resp = getchar();
108 switch(resp) {
109 case 'a':
110 if(clHand != CSSM_INVALID_HANDLE) {
111 printf("***Multiple attaches; expect leaks\n");
112 }
113 clHand = clStartup();
114 if(clHand == CSSM_INVALID_HANDLE) {
115 printf("***Error attaching to CL.\n");
116 }
117 else {
118 printf("...ok\n");
119 }
120 break;
121
122 case 'd':
123 /*
124 * Notes:
125 * -- this should cause the CL to free up all cached certs
126 * no matter what - even if we've done multiple certCache
127 * ops. However the plugin framework doesn't delete the
128 * session object on detach (yet) so expect leaks in
129 * that case.
130 * -- we don't clear out cacheHand or searchHand here; this
131 * allows verification of proper handling of bogus handles.
132 */
133 clShutdown(clHand);
134 clHand = CSSM_INVALID_HANDLE;
135 printf("...ok\n");
136 break;
137
138 case 'c':
139 /* cache the cert */
140 if(cacheHand != CSSM_INVALID_HANDLE) {
141 printf("***NOTE: a cert is already cached. Expect leaks.\n"); }
142 crtn = CSSM_CL_CertCache(clHand, &certData, &cacheHand);
143 if(crtn) {
144 printError("CSSM_CL_CertCache", crtn);
145 }
146 else {
147 printf("...ok\n");
148 }
149 break;
150
151 case 'u':
152 /* abort cache */
153 crtn = CSSM_CL_CertAbortCache(clHand, cacheHand);
154 if(crtn) {
155 printError("CSSM_CL_CertAbortCache", crtn);
156 }
157 else {
158 cacheHand = CSSM_INVALID_HANDLE;
159 printf("...ok\n");
160 }
161 break;
162
163 case 'g':
164 /* get one field (uncached) */
165 fieldDex = genRand(0, NUM_KNOWN_OIDS - 1);
166 crtn = CSSM_CL_CertGetFirstFieldValue(clHand,
167 &certData,
168 knownOids[fieldDex],
169 &searchHand,
170 &numFields,
171 &fieldValue);
172 if(crtn) {
173 printf("***Error fetching field %s\n", oidNames[fieldDex]);
174 printError("CSSM_CL_CertGetFirstFieldValue", crtn);
175 break;
176 }
177 printf("%s: %u fields found\n", oidNames[fieldDex], (unsigned)numFields);
178 field.FieldValue = *fieldValue;
179 field.FieldOid = *(knownOids[fieldDex]);
180 printCertField(field, parser, CSSM_TRUE);
181 crtn = CSSM_CL_FreeFieldValue(clHand, knownOids[fieldDex], fieldValue);
182 if(crtn) {
183 printError("CSSM_CL_FreeFieldValue", crtn);
184 /* keep going */
185 }
186 for(unsigned i=1; i<numFields; i++) {
187 crtn = CSSM_CL_CertGetNextFieldValue(clHand,
188 searchHand,
189 &fieldValue);
190 if(crtn) {
191 printError("CSSM_CL_CertGetNextFieldValue", crtn);
192 break;
193 }
194 field.FieldValue = *fieldValue;
195 printCertField(field, parser, CSSM_TRUE);
196 crtn = CSSM_CL_FreeFieldValue(clHand,
197 knownOids[fieldDex], fieldValue);
198 if(crtn) {
199 printError("CSSM_CL_FreeFieldValue", crtn);
200 /* keep going */
201 }
202 } /* for additional fields */
203
204 /* verify one more getField results in error */
205 crtn = CSSM_CL_CertGetNextFieldValue(clHand,
206 searchHand,
207 &fieldValue);
208 if(crtn != CSSMERR_CL_NO_FIELD_VALUES) {
209 if(crtn == CSSM_OK) {
210 printf("***unexpected success on final GetNextFieldValue\n");
211 }
212 else {
213 printError("Wrong error on final GetNextFieldValue", crtn);
214 }
215 }
216 crtn = CSSM_CL_CertAbortQuery(clHand, searchHand);
217 if(crtn) {
218 printError("CSSM_CL_CertAbortQuery", crtn);
219 }
220 break;
221
222 case 'G':
223 /* get one field (uncached) */
224 fieldDex = genRand(0, NUM_KNOWN_OIDS - 1);
225 crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand,
226 cacheHand,
227 knownOids[fieldDex],
228 &searchHand,
229 &numFields,
230 &fieldValue);
231 if(crtn) {
232 printf("***Error fetching field %s\n", oidNames[fieldDex]);
233 printError("CSSM_CL_CertGetFirstCachedFieldValue", crtn);
234 break;
235 }
236 printf("%s: %u fields found\n", oidNames[fieldDex], (unsigned)numFields);
237 field.FieldValue = *fieldValue;
238 field.FieldOid = *(knownOids[fieldDex]);
239 printCertField(field, parser, CSSM_TRUE);
240 crtn = CSSM_CL_FreeFieldValue(clHand, knownOids[fieldDex], fieldValue);
241 if(crtn) {
242 printError("CSSM_CL_FreeFieldValue", crtn);
243 /* keep going */
244 }
245 for(unsigned i=1; i<numFields; i++) {
246 crtn = CSSM_CL_CertGetNextCachedFieldValue(clHand,
247 searchHand,
248 &fieldValue);
249 if(crtn) {
250 printError("CSSM_CL_CertGetNextCachedFieldValue", crtn);
251 break;
252 }
253 field.FieldValue = *fieldValue;
254 printCertField(field, parser, CSSM_TRUE);
255 crtn = CSSM_CL_FreeFieldValue(clHand,
256 knownOids[fieldDex], fieldValue);
257 if(crtn) {
258 printError("CSSM_CL_FreeFieldValue", crtn);
259 /* keep going */
260 }
261 } /* for additional cached fields */
262
263 /* verify one more getField results in error */
264 crtn = CSSM_CL_CertGetNextCachedFieldValue(clHand,
265 searchHand,
266 &fieldValue);
267 if(crtn != CSSMERR_CL_NO_FIELD_VALUES) {
268 if(crtn == CSSM_OK) {
269 printf("***unexpected success on final GetNextCachedFieldValue\n");
270 }
271 else {
272 printError("Wrong error on final GetNextCachedFieldValue", crtn);
273 }
274 }
275 crtn = CSSM_CL_CertAbortQuery(clHand, searchHand);
276 if(crtn) {
277 printError("CSSM_CL_CertAbortQuery", crtn);
278 }
279 break;
280
281 case 'f':
282 /* get all fields (for leak testing) */
283 crtn = CSSM_CL_CertGetAllFields(clHand,
284 &certData,
285 &numFields,
286 &fieldPtr);
287 if(crtn) {
288 printError("CSSM_CL_CertGetAllFields", crtn);
289 break;
290 }
291 printf("...numFields %u\n", (unsigned)numFields);
292 crtn = CSSM_CL_FreeFields(clHand, numFields, &fieldPtr);
293 if(crtn) {
294 printError("CSSM_CL_FreeFields", crtn);
295 }
296 break;
297
298 case 'q':
299 goto quit;
300
301 default:
302 printf("Huh?\n");
303 break;
304 } /* switch resp */
305 }
306 quit:
307 free(certData.Data);
308 if(clHand != CSSM_INVALID_HANDLE) {
309 clShutdown(clHand);
310 }
311 return 0;
312 }