2 * Copyright (c) 2003-2008,2011 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * Created by Michael Brouwer on 10/10/06.
29 #include "print_cert.h"
30 #include <CoreFoundation/CoreFoundation.h>
31 #include <Security/SecCertificatePriv.h>
32 #include <Security/SecTrustPriv.h>
33 #include <utilities/SecIOFormat.h>
34 #include <utilities/SecCFWrappers.h>
37 static void printPlist(CFArrayRef plist
, CFIndex indent
, CFIndex maxWidth
) {
38 CFIndex count
= CFArrayGetCount(plist
);
40 for (ix
= 0; ix
< count
; ++ix
) {
41 CFDictionaryRef prop
= (CFDictionaryRef
)CFArrayGetValueAtIndex(plist
,
43 CFStringRef pType
= (CFStringRef
)CFDictionaryGetValue(prop
,
45 CFStringRef label
= (CFStringRef
)CFDictionaryGetValue(prop
,
46 kSecPropertyKeyLabel
);
47 CFStringRef llabel
= (CFStringRef
)CFDictionaryGetValue(prop
,
48 kSecPropertyKeyLocalizedLabel
);
49 CFTypeRef value
= (CFTypeRef
)CFDictionaryGetValue(prop
,
50 kSecPropertyKeyValue
);
52 bool isSection
= CFEqual(pType
, kSecPropertyTypeSection
);
53 CFMutableStringRef line
= CFStringCreateMutable(NULL
, 0);
55 for (jx
= 0; jx
< indent
; ++jx
) {
56 CFStringAppend(line
, CFSTR(" "));
59 CFStringAppend(line
, llabel
);
61 for (jx
= CFStringGetLength(llabel
) + indent
* 4;
62 jx
< maxWidth
; ++jx
) {
63 CFStringAppend(line
, CFSTR(" "));
65 CFStringAppend(line
, CFSTR(" : "));
68 if (CFEqual(pType
, kSecPropertyTypeWarning
)) {
69 CFStringAppend(line
, CFSTR("*WARNING* "));
70 CFStringAppend(line
, (CFStringRef
)value
);
71 } else if (CFEqual(pType
, kSecPropertyTypeError
)) {
72 CFStringAppend(line
, CFSTR("*ERROR* "));
73 CFStringAppend(line
, (CFStringRef
)value
);
74 } else if (CFEqual(pType
, kSecPropertyTypeSuccess
)) {
75 CFStringAppend(line
, CFSTR("*OK* "));
76 CFStringAppend(line
, (CFStringRef
)value
);
77 } else if (CFEqual(pType
, kSecPropertyTypeTitle
)) {
78 CFStringAppend(line
, CFSTR("*"));
79 CFStringAppend(line
, (CFStringRef
)value
);
80 CFStringAppend(line
, CFSTR("*"));
81 } else if (CFEqual(pType
, kSecPropertyTypeSection
)) {
82 } else if (CFEqual(pType
, kSecPropertyTypeData
)) {
83 CFDataRef data
= (CFDataRef
)value
;
84 CFIndex length
= CFDataGetLength(data
);
86 CFStringAppendFormat(line
, NULL
, CFSTR("[%" PRIdCFIndex
" bytes] "), length
);
87 const UInt8
*bytes
= CFDataGetBytePtr(data
);
88 for (jx
= 0; jx
< length
; ++jx
) {
90 CFStringAppendFormat(line
, NULL
, CFSTR("%02X"), bytes
[jx
]);
91 else if (jx
< 15 || length
<= 20)
92 CFStringAppendFormat(line
, NULL
, CFSTR(" %02X"),
95 CFStringAppend(line
, CFSTR(" ..."));
99 } else if (CFEqual(pType
, kSecPropertyTypeString
)) {
100 CFStringAppend(line
, (CFStringRef
)value
);
101 } else if (CFEqual(pType
, kSecPropertyTypeDate
)) {
102 CFDateRef date
= (CFDateRef
)value
;
103 CFLocaleRef lc
= CFLocaleCopyCurrent();
104 CFDateFormatterRef df
= CFDateFormatterCreate(NULL
, lc
, kCFDateFormatterMediumStyle
, kCFDateFormatterLongStyle
);
107 CFTimeZoneRef tz
= CFTimeZoneCreateWithTimeIntervalFromGMT(NULL
, 0.0);
108 CFDateFormatterSetProperty(df
, kCFDateFormatterTimeZone
, tz
);
110 ds
= CFDateFormatterCreateStringWithDate(NULL
, df
, date
);
113 ds
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%g"), CFDateGetAbsoluteTime(date
));
115 CFStringAppend(line
, ds
);
118 } else if (CFEqual(pType
, kSecPropertyTypeURL
)) {
119 CFURLRef url
= (CFURLRef
)value
;
120 CFStringAppend(line
, CFSTR("<"));
121 CFStringAppend(line
, CFURLGetString(url
));
122 CFStringAppend(line
, CFSTR(">"));
124 CFStringAppendFormat(line
, NULL
, CFSTR("*unknown type %@* = %@"),
128 if (!isSection
|| label
)
129 CFStringWriteToFileWithNewline(line
, stdout
);
132 printPlist((CFArrayRef
)value
, indent
+ 1, maxWidth
);
137 static CFIndex
maxLabelWidth(CFArrayRef plist
, CFIndex indent
) {
138 CFIndex count
= CFArrayGetCount(plist
);
140 CFIndex maxWidth
= 0;
141 for (ix
= 0; ix
< count
; ++ix
) {
142 CFDictionaryRef prop
= (CFDictionaryRef
)CFArrayGetValueAtIndex(plist
,
144 CFStringRef pType
= (CFStringRef
)CFDictionaryGetValue(prop
,
145 kSecPropertyKeyType
);
146 CFStringRef llabel
= (CFStringRef
)CFDictionaryGetValue(prop
,
147 kSecPropertyKeyLocalizedLabel
);
148 CFTypeRef value
= (CFTypeRef
)CFDictionaryGetValue(prop
,
149 kSecPropertyKeyValue
);
151 if (CFEqual(pType
, kSecPropertyTypeSection
)) {
152 CFIndex width
= maxLabelWidth((CFArrayRef
)value
, indent
+ 1);
153 if (width
> maxWidth
)
156 CFIndex width
= indent
* 4 + CFStringGetLength(llabel
);
157 if (width
> maxWidth
)
165 void print_plist(CFArrayRef plist
) {
167 printPlist(plist
, 0, maxLabelWidth(plist
, 0));
169 printf("NULL plist\n");
172 void print_cert(SecCertificateRef cert
, bool verbose
) {
175 plist
= SecCertificateCopyProperties(cert
);
177 CFAbsoluteTime now
= CFAbsoluteTimeGetCurrent();
178 plist
= SecCertificateCopySummaryProperties(cert
, now
);
181 CFStringRef subject
= SecCertificateCopySubjectString(cert
);
183 CFStringWriteToFileWithNewline(subject
, stdout
);
186 CFStringWriteToFileWithNewline(CFSTR("no subject"), stdout
);