]> git.saurik.com Git - apple/security.git/blob - OSX/sec/SecurityTool/print_cert.c
Security-57337.20.44.tar.gz
[apple/security.git] / OSX / sec / SecurityTool / print_cert.c
1 /*
2 * Copyright (c) 2003-2008,2011,2013-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 *
23 * print_cert.c
24 *
25 */
26
27
28 #include "print_cert.h"
29 #include <CoreFoundation/CoreFoundation.h>
30 #include <Security/SecCertificatePriv.h>
31 #include <Security/SecTrustPriv.h>
32 #include <utilities/SecIOFormat.h>
33 #include <utilities/SecCFWrappers.h>
34
35
36 static void printPlist(CFArrayRef plist, CFIndex indent, CFIndex maxWidth) {
37 CFIndex count = CFArrayGetCount(plist);
38 CFIndex ix;
39 for (ix = 0; ix < count ; ++ix) {
40 CFDictionaryRef prop = (CFDictionaryRef)CFArrayGetValueAtIndex(plist,
41 ix);
42 CFStringRef pType = (CFStringRef)CFDictionaryGetValue(prop,
43 kSecPropertyKeyType);
44 CFStringRef label = (CFStringRef)CFDictionaryGetValue(prop,
45 kSecPropertyKeyLabel);
46 CFStringRef llabel = (CFStringRef)CFDictionaryGetValue(prop,
47 kSecPropertyKeyLocalizedLabel);
48 CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(prop,
49 kSecPropertyKeyValue);
50
51 bool isSection = CFEqual(pType, kSecPropertyTypeSection);
52 CFMutableStringRef line = CFStringCreateMutable(NULL, 0);
53 CFIndex jx = 0;
54 for (jx = 0; jx < indent; ++jx) {
55 CFStringAppend(line, CFSTR(" "));
56 }
57 if (llabel) {
58 CFStringAppend(line, llabel);
59 if (!isSection) {
60 for (jx = CFStringGetLength(llabel) + indent * 4;
61 jx < maxWidth; ++jx) {
62 CFStringAppend(line, CFSTR(" "));
63 }
64 CFStringAppend(line, CFSTR(" : "));
65 }
66 }
67 if (CFEqual(pType, kSecPropertyTypeWarning)) {
68 CFStringAppend(line, CFSTR("*WARNING* "));
69 CFStringAppend(line, (CFStringRef)value);
70 } else if (CFEqual(pType, kSecPropertyTypeError)) {
71 CFStringAppend(line, CFSTR("*ERROR* "));
72 CFStringAppend(line, (CFStringRef)value);
73 } else if (CFEqual(pType, kSecPropertyTypeSuccess)) {
74 CFStringAppend(line, CFSTR("*OK* "));
75 CFStringAppend(line, (CFStringRef)value);
76 } else if (CFEqual(pType, kSecPropertyTypeTitle)) {
77 CFStringAppend(line, CFSTR("*"));
78 CFStringAppend(line, (CFStringRef)value);
79 CFStringAppend(line, CFSTR("*"));
80 } else if (CFEqual(pType, kSecPropertyTypeSection)) {
81 } else if (CFEqual(pType, kSecPropertyTypeData)) {
82 CFDataRef data = (CFDataRef)value;
83 CFIndex length = CFDataGetLength(data);
84 if (length > 20)
85 CFStringAppendFormat(line, NULL, CFSTR("[%" PRIdCFIndex " bytes] "), length);
86 const UInt8 *bytes = CFDataGetBytePtr(data);
87 for (jx = 0; jx < length; ++jx) {
88 if (jx == 0)
89 CFStringAppendFormat(line, NULL, CFSTR("%02X"), bytes[jx]);
90 else if (jx < 15 || length <= 20)
91 CFStringAppendFormat(line, NULL, CFSTR(" %02X"),
92 bytes[jx]);
93 else {
94 CFStringAppend(line, CFSTR(" ..."));
95 break;
96 }
97 }
98 } else if (CFEqual(pType, kSecPropertyTypeString)) {
99 CFStringAppend(line, (CFStringRef)value);
100 } else if (CFEqual(pType, kSecPropertyTypeDate)) {
101 CFDateRef date = (CFDateRef)value;
102 CFLocaleRef lc = CFLocaleCopyCurrent();
103 CFDateFormatterRef df = CFDateFormatterCreate(NULL, lc, kCFDateFormatterMediumStyle, kCFDateFormatterLongStyle);
104 CFStringRef ds;
105 if (df) {
106 CFTimeZoneRef tz = CFTimeZoneCreateWithTimeIntervalFromGMT(NULL, 0.0);
107 CFDateFormatterSetProperty(df, kCFDateFormatterTimeZone, tz);
108 CFRelease(tz);
109 ds = CFDateFormatterCreateStringWithDate(NULL, df, date);
110 CFRelease(df);
111 } else {
112 ds = CFStringCreateWithFormat(NULL, NULL, CFSTR("%g"), CFDateGetAbsoluteTime(date));
113 }
114 CFStringAppend(line, ds);
115 CFRelease(ds);
116 CFRelease(lc);
117 } else if (CFEqual(pType, kSecPropertyTypeURL)) {
118 CFURLRef url = (CFURLRef)value;
119 CFStringAppend(line, CFSTR("<"));
120 CFStringAppend(line, CFURLGetString(url));
121 CFStringAppend(line, CFSTR(">"));
122 } else {
123 CFStringAppendFormat(line, NULL, CFSTR("*unknown type %@* = %@"),
124 pType, value);
125 }
126
127 if (!isSection || label)
128 CFStringWriteToFileWithNewline(line, stdout);
129 CFRelease(line);
130 if (isSection) {
131 printPlist((CFArrayRef)value, indent + 1, maxWidth);
132 }
133 }
134 }
135
136 static CFIndex maxLabelWidth(CFArrayRef plist, CFIndex indent) {
137 CFIndex count = CFArrayGetCount(plist);
138 CFIndex ix;
139 CFIndex maxWidth = 0;
140 for (ix = 0; ix < count ; ++ix) {
141 CFDictionaryRef prop = (CFDictionaryRef)CFArrayGetValueAtIndex(plist,
142 ix);
143 CFStringRef pType = (CFStringRef)CFDictionaryGetValue(prop,
144 kSecPropertyKeyType);
145 CFStringRef llabel = (CFStringRef)CFDictionaryGetValue(prop,
146 kSecPropertyKeyLocalizedLabel);
147 CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(prop,
148 kSecPropertyKeyValue);
149
150 if (CFEqual(pType, kSecPropertyTypeSection)) {
151 CFIndex width = maxLabelWidth((CFArrayRef)value, indent + 1);
152 if (width > maxWidth)
153 maxWidth = width;
154 } else if (llabel) {
155 CFIndex width = indent * 4 + CFStringGetLength(llabel);
156 if (width > maxWidth)
157 maxWidth = width;
158 }
159 }
160
161 return maxWidth;
162 }
163
164 void print_plist(CFArrayRef plist) {
165 if (plist)
166 printPlist(plist, 0, maxLabelWidth(plist, 0));
167 else
168 printf("NULL plist\n");
169 }
170
171 void print_cert(SecCertificateRef cert, bool verbose) {
172 #if TARGET_OS_IPHONE
173 CFArrayRef plist;
174 if (verbose)
175 plist = SecCertificateCopyProperties(cert);
176 else {
177 CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
178 plist = SecCertificateCopySummaryProperties(cert, now);
179 }
180
181 CFStringRef subject = SecCertificateCopySubjectString(cert);
182 if (subject) {
183 CFStringWriteToFileWithNewline(subject, stdout);
184 CFRelease(subject);
185 } else {
186 CFStringWriteToFileWithNewline(CFSTR("no subject"), stdout);
187 }
188
189 print_plist(plist);
190 CFReleaseSafe(plist);
191 #else
192 (void)cert;
193 (void)verbose;
194 #endif
195 }