]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/rootStoreTool/rootUtils.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / rootStoreTool / rootUtils.cpp
1 /*
2 * rootUtils.cpp - utility routines for rootStoreTool
3 */
4
5 #include <stdlib.h>
6 #include <strings.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 #include "rootUtils.h"
10 #include <Security/SecCertificatePriv.h>
11 #include <Security/SecBasePriv.h>
12 #include <Security/SecTrustSettings.h>
13 #include <Security/TrustSettingsSchema.h> /* private header */
14 #include <Security/SecAsn1Coder.h>
15 #include <Security/nameTemplates.h> /* oh frabjous day */
16
17 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
18
19 static int indentSize = 0;
20 void indentIncr(void) { indentSize += 3; }
21 void indentDecr(void) { indentSize -= 3; }
22
23 void indent(void)
24 {
25 if(indentSize < 0) {
26 printf("***indent screwup\n");
27 indentSize = 0;
28 }
29 for (int dex=0; dex<indentSize; dex++) {
30 putchar(' ');
31 }
32 }
33
34 void printAscii(
35 const char *buf,
36 unsigned len,
37 unsigned maxLen)
38 {
39 bool doEllipsis = false;
40 if(len > maxLen) {
41 len = maxLen;
42 doEllipsis = true;
43 }
44 for(unsigned dex=0; dex<len; dex++) {
45 char c = *buf++;
46 if(isalnum(c) || (c == ' ')) {
47 putchar(c);
48 }
49 else {
50 putchar('.');
51 }
52 fflush(stdout);
53 }
54 if(doEllipsis) {
55 printf("...etc.");
56 }
57 }
58
59 void printHex(
60 const unsigned char *buf,
61 unsigned len,
62 unsigned maxLen)
63 {
64 bool doEllipsis = false;
65 if(len > maxLen) {
66 len = maxLen;
67 doEllipsis = true;
68 }
69 for(unsigned dex=0; dex<len; dex++) {
70 printf("%02X ", *buf++);
71 }
72 if(doEllipsis) {
73 printf("...etc.");
74 }
75 }
76
77 void printOid(
78 const void *buf,
79 unsigned len,
80 OidParser &parser)
81 {
82 char outstr[OID_PARSER_STRING_SIZE];
83 parser.oidParse((const unsigned char *)buf, len, outstr);
84 printf("%s", outstr);
85 }
86
87 void printData(
88 const char *label,
89 CFDataRef data,
90 PrintDataType whichType,
91 OidParser &parser)
92 {
93 const unsigned char *buf = CFDataGetBytePtr(data);
94 unsigned len = CFDataGetLength(data);
95
96 printf("%s: ", label);
97 switch(whichType) {
98 case PD_Hex:
99 printHex(buf, len, 16);
100 break;
101 case PD_ASCII:
102 printAscii((const char *)buf, len, 50);
103 break;
104 case PD_OID:
105 printOid(buf, len, parser);
106 }
107 putchar('\n');
108 }
109
110 /* print the contents of a CFString */
111 void printCfStr(
112 CFStringRef cfstr)
113 {
114 CFDataRef strData = CFStringCreateExternalRepresentation(NULL, cfstr,
115 kCFStringEncodingUTF8, true);
116 if(strData == NULL) {
117 printf("<<string decode error>>");
118 return;
119 }
120 const char *cp = (const char *)CFDataGetBytePtr(strData);
121 CFIndex len = CFDataGetLength(strData);
122 for(CFIndex dex=0; dex<len; dex++) {
123 putchar(*cp++);
124 }
125 CFRelease(strData);
126 }
127
128 /* print a CFDateRef */
129 static const char *months[12] = {
130 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
131 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
132 };
133
134 void printCFDate(
135 CFDateRef dateRef)
136 {
137 CFAbsoluteTime absTime = CFDateGetAbsoluteTime(dateRef);
138 if(absTime == 0.0) {
139 printf("<<Malformed CFDateeRef>>\n");
140 return;
141 }
142 CFGregorianDate gregDate = CFAbsoluteTimeGetGregorianDate(absTime, NULL);
143 const char *month = "Unknown";
144 if((gregDate.month > 12) || (gregDate.month <= 0)) {
145 printf("Huh? GregDate.month > 11. These amps only GO to 11.\n");
146 }
147 else {
148 month = months[gregDate.month - 1];
149 }
150 printf("%s %d, %ld %02d:%02d",
151 month, gregDate.day, gregDate.year, gregDate.hour, gregDate.minute);
152 }
153
154 /* print a CFNumber */
155 void printCfNumber(
156 CFNumberRef cfNum)
157 {
158 SInt32 s;
159 if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) {
160 printf("***CFNumber overflow***");
161 return;
162 }
163 printf("%ld", s);
164 }
165
166 /* print a CFNumber as a SecTrustSettingsResult */
167 void printResult(
168 CFNumberRef cfNum)
169 {
170 SInt32 n;
171 if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &n)) {
172 printf("***CFNumber overflow***");
173 return;
174 }
175 const char *s;
176 char bogus[100];
177 switch(n) {
178 case kSecTrustSettingsResultInvalid: s = "kSecTrustSettingsResultInvalid"; break;
179 case kSecTrustSettingsResultTrustRoot: s = "kSecTrustSettingsResultTrustRoot"; break;
180 case kSecTrustSettingsResultTrustAsRoot: s = "kSecTrustSettingsResultTrustAsRoot"; break;
181 case kSecTrustSettingsResultDeny: s = "kSecTrustSettingsResultDeny"; break;
182 case kSecTrustSettingsResultUnspecified: s = "kSecTrustSettingsResultUnspecified"; break;
183 default:
184 sprintf(bogus, "Unknown SecTrustSettingsResult (%ld)", n);
185 s = bogus;
186 break;
187 }
188 printf("%s", s);
189 }
190
191 /* print a CFNumber as SecTrustSettingsKeyUsage */
192 void printKeyUsage(
193 CFNumberRef cfNum)
194 {
195 SInt32 s;
196 if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) {
197 printf("***CFNumber overflow***");
198 return;
199 }
200 uint32 n = (uint32)s;
201 if(n == kSecTrustSettingsKeyUseAny) {
202 printf("<any>");
203 return;
204 }
205 else if(n == 0) {
206 printf("<none>");
207 return;
208 }
209 printf("< ");
210 if(n & kSecTrustSettingsKeyUseSignature) {
211 printf("Signature ");
212 }
213 if(n & kSecTrustSettingsKeyUseEnDecryptData) {
214 printf("EnDecryptData ");
215 }
216 if(n & kSecTrustSettingsKeyUseEnDecryptKey) {
217 printf("EnDecryptKey ");
218 }
219 if(n & kSecTrustSettingsKeyUseSignCert) {
220 printf("SignCert ");
221 }
222 if(n & kSecTrustSettingsKeyUseSignRevocation) {
223 printf("SignRevocation ");
224 }
225 if(n & kSecTrustSettingsKeyUseKeyExchange) {
226 printf("KeyExchange ");
227 }
228 printf(" >");
229 }
230
231 /* print a CFNumber as CSSM_RETURN string */
232 void printCssmErr(
233 CFNumberRef cfNum)
234 {
235 SInt32 s;
236 if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) {
237 printf("***CFNumber overflow***");
238 return;
239 }
240 printf("%s", cssmErrorString((CSSM_RETURN)s));
241 }
242
243 /* print cert's label (the one SecCertificate infers) */
244 OSStatus printCertLabel(
245 SecCertificateRef certRef)
246 {
247 OSStatus ortn;
248 CFStringRef label;
249
250 ortn = SecCertificateInferLabel(certRef, &label);
251 if(ortn) {
252 cssmPerror("SecCertificateInferLabel", ortn);
253 return ortn;
254 }
255 printCfStr(label);
256 CFRelease(label);
257 return noErr;
258 }
259
260 /*
261 * How many items in a NULL-terminated array of pointers?
262 */
263 static unsigned nssArraySize(
264 const void **array)
265 {
266 unsigned count = 0;
267 if (array) {
268 while (*array++) {
269 count++;
270 }
271 }
272 return count;
273 }
274
275 static int compareOids(
276 const CSSM_OID *data1,
277 const CSSM_OID *data2)
278 {
279 if((data1 == NULL) || (data1->Data == NULL) ||
280 (data2 == NULL) || (data2->Data == NULL) ||
281 (data1->Length != data2->Length)) {
282 return 0;
283 }
284 if(data1->Length != data2->Length) {
285 return 0;
286 }
287 return memcmp(data1->Data, data2->Data, data1->Length) == 0;
288 }
289
290 static void printRdn(const NSS_RDN *rdn, OidParser &parser)
291 {
292 unsigned numAtvs = nssArraySize((const void **)rdn->atvs);
293 char *fieldName;
294
295 for(unsigned dex=0; dex<numAtvs; dex++) {
296 const NSS_ATV *atv = rdn->atvs[dex];
297 if(compareOids(&atv->type, &CSSMOID_CountryName)) {
298 fieldName = "Country ";
299 }
300 else if(compareOids(&atv->type, &CSSMOID_OrganizationName)) {
301 fieldName = "Org ";
302 }
303 else if(compareOids(&atv->type, &CSSMOID_LocalityName)) {
304 fieldName = "Locality ";
305 }
306 else if(compareOids(&atv->type, &CSSMOID_OrganizationalUnitName)) {
307 fieldName = "OrgUnit ";
308 }
309 else if(compareOids(&atv->type, &CSSMOID_CommonName)) {
310 fieldName = "Common Name ";
311 }
312 else if(compareOids(&atv->type, &CSSMOID_Surname)) {
313 fieldName = "Surname ";
314 }
315 else if(compareOids(&atv->type, &CSSMOID_Title)) {
316 fieldName = "Title ";
317 }
318 else if(compareOids(&atv->type, &CSSMOID_Surname)) {
319 fieldName = "Surname ";
320 }
321 else if(compareOids(&atv->type, &CSSMOID_StateProvinceName)) {
322 fieldName = "State ";
323 }
324 else if(compareOids(&atv->type, &CSSMOID_CollectiveStateProvinceName)) {
325 fieldName = "Coll. State ";
326 }
327 else if(compareOids(&atv->type, &CSSMOID_EmailAddress)) {
328 /* deprecated, used by Thawte */
329 fieldName = "Email addrs ";
330 }
331 else {
332 fieldName = "Other name ";
333 }
334 indent(); printf("%s : ", fieldName);
335 /* Not strictly true here, but we'll just assume we can print everything */
336 printAscii((char *)atv->value.item.Data, atv->value.item.Length,
337 atv->value.item.Length);
338 putchar('\n');
339 }
340 }
341
342 /* print a CFData as an X509 Name (i.e., subject or issuer) */
343 void printCfName(
344 CFDataRef nameData,
345 OidParser &parser)
346 {
347 SecAsn1CoderRef coder = NULL;
348 OSStatus ortn;
349
350 ortn = SecAsn1CoderCreate(&coder);
351 if(ortn) {
352 cssmPerror("SecAsn1CoderCreate", ortn);
353 return;
354 }
355 /* subsequent errors to errOut: */
356
357 NSS_Name nssName = {NULL};
358 unsigned numRdns;
359
360 ortn = SecAsn1Decode(coder,
361 CFDataGetBytePtr(nameData), CFDataGetLength(nameData),
362 kSecAsn1NameTemplate,
363 &nssName);
364 if(ortn) {
365 printf("***Error decoding NSS_Name\n");
366 goto errOut;
367 }
368 numRdns = nssArraySize((const void **)nssName.rdns);
369 for(unsigned dex=0; dex<numRdns; dex++) {
370 printRdn(nssName.rdns[dex], parser);
371 }
372
373 errOut:
374 if(coder) {
375 SecAsn1CoderRelease(coder);
376 }
377 }
378