]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Tool/show_certificates.c
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / sec / Security / Tool / show_certificates.c
1 /*
2 * Copyright (c) 2003-2007,2009-2010,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 * keychain_find.c
24 */
25
26 #include <TargetConditionals.h>
27 #if TARGET_OS_EMBEDDED
28
29 #include "SecurityCommands.h"
30
31 #include "security.h"
32 #include "SecurityTool/print_cert.h"
33 #include "SecBase64.h"
34 #include <errno.h>
35 #include <fcntl.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41
42 #include <SecurityTool/tool_errors.h>
43
44 #include <Security/SecItem.h>
45
46 #include <CoreFoundation/CFArray.h>
47 #include <CoreFoundation/CFDate.h>
48 #include <CoreFoundation/CFNumber.h>
49 #include <CoreFoundation/CFString.h>
50
51 #include <Security/SecCertificatePriv.h>
52 #include <Security/SecPolicyPriv.h>
53 #include <Security/SecTrustPriv.h>
54 #include <Security/SecInternal.h>
55
56 #include <SecurityTool/readline.h>
57
58 #include <utilities/SecCFWrappers.h>
59 #include "keychain_util.h"
60
61 typedef uint32_t SecProtocolType;
62 typedef uint32_t SecAuthenticationType;
63
64
65 static void show_cert_eval(CFArrayRef certs, bool verbose) {
66 SecPolicyRef policy = SecPolicyCreateSSL(true, NULL);
67 SecTrustRef trust = NULL;
68 SecTrustCreateWithCertificates(certs, policy, &trust);
69 SecTrustResultType trustResult;
70 const char *trustResults[] = {
71 "invalid",
72 "proceed",
73 "confirm",
74 "deny",
75 "unspecified",
76 "recoverable trust failure",
77 "fatal trust failure",
78 "other error",
79 };
80 (void) SecTrustEvaluate(trust, &trustResult);
81 printf("* trust: %s *\n", trustResults[trustResult]);
82 CFArrayRef properties = SecTrustCopyProperties(trust);
83 print_plist(properties);
84 CFReleaseNull(properties);
85 CFIndex ix, count = SecTrustGetCertificateCount(trust);
86 for (ix = 0; ix < count; ++ix) {
87 printf("* cert %ld summary properties *\n", ix);
88 properties = SecTrustCopySummaryPropertiesAtIndex(trust, ix);
89 print_plist(properties);
90 CFReleaseNull(properties);
91 if (verbose) {
92 printf("* cert %ld detail properties *\n", ix);
93 properties = SecTrustCopyDetailedPropertiesAtIndex(trust, ix);
94 print_plist(properties);
95 CFReleaseNull(properties);
96 }
97 }
98
99 CFDictionaryRef info = SecTrustCopyInfo(trust);
100 if (info) {
101 printf("* info *\n");
102 CFShow(info);
103 CFReleaseNull(info);
104 }
105 CFReleaseNull(policy);
106 }
107
108 static size_t print_buffer_pem(FILE *stream, const char *pem_name, size_t length,
109 const uint8_t *bytes) {
110 size_t pem_name_len = strlen(pem_name);
111 size_t b64_len = SecBase64Encode2(NULL, length, NULL, 0,
112 kSecB64_F_LINE_LEN_USE_PARAM, 64, NULL);
113 char *buffer = malloc(33 + 2 * pem_name_len + b64_len);
114 char *p = buffer;
115 p += sprintf(buffer, "-----BEGIN %s-----\n", pem_name);
116 SecBase64Result result;
117 p += SecBase64Encode2(bytes, length, p, b64_len,\
118 kSecB64_F_LINE_LEN_USE_PARAM, 64, &result);
119 if (result) {
120 free(buffer);
121 return result;
122 }
123 p += sprintf(p, "\n-----END %s-----\n", pem_name);
124 size_t res = fwrite(buffer, 1, p - buffer, stream);
125 fflush(stream);
126 bzero(buffer, p - buffer);
127 free(buffer);
128 return res;
129 }
130
131 int keychain_show_certificates(int argc, char * const *argv)
132 {
133 int ch, result = 0;
134 bool output_subject = false;
135 bool verbose = false;
136 bool trust_eval = false;
137 bool keychain_certs = false;
138 bool output_pem = false;
139 bool output_finger_print = false;
140 CFMutableArrayRef certs = NULL;
141 CFMutableDictionaryRef query = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
142
143 while ((ch = getopt(argc, argv, "kfq:pstv")) != -1)
144 {
145 switch (ch)
146 {
147 case 'k':
148 keychain_certs = true;
149 break;
150 case 'p':
151 output_pem = true;
152 break;
153 case 's':
154 output_subject = true;
155 break;
156 case 'v':
157 verbose = true;
158 break;
159 case 't':
160 trust_eval = true;
161 break;
162 case 'f':
163 output_finger_print = true;
164 break;
165 case 'q':
166 if (!keychain_query_parse_cstring(query, optarg)) {
167 CFReleaseNull(query);
168 return 1;
169 }
170 keychain_certs = true;
171 break;
172 case '?':
173 default:
174 return 2; /* @@@ Return 2 triggers usage message. */
175 }
176 }
177
178 argc -= optind;
179 argv += optind;
180
181 if ((keychain_certs && argc > 0) || (!keychain_certs && argc < 1))
182 result = 2;
183
184 if (trust_eval)
185 certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
186
187 CFArrayRef kc_certs = NULL;
188 int arg;
189 if (keychain_certs) {
190 for (arg = 0; arg < argc; ++arg) {
191 if (!keychain_query_parse_cstring(query, argv[arg])) {
192 CFReleaseSafe(query);
193 CFReleaseSafe(certs);
194 return 1;
195 }
196 }
197 CFDictionarySetValue(query, kSecClass, kSecClassCertificate);
198 CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
199 CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
200 CFTypeRef results;
201 if (!SecItemCopyMatching(query, &results)) {
202 kc_certs = results;
203 argc = (int) CFArrayGetCount(kc_certs);
204 }
205 }
206
207 for (arg = 0; arg < argc; ++arg) {
208 SecCertificateRef cert = NULL;
209 if (keychain_certs) {
210 cert = (SecCertificateRef)CFArrayGetValueAtIndex(kc_certs, arg);
211 } else {
212 CFDataRef data = copyFileContents(argv[arg]);
213 if (data) {
214 cert = SecCertificateCreateWithData(
215 kCFAllocatorDefault, data);
216 if (!cert) {
217 /* DER failed, try PEM. */
218 cert = SecCertificateCreateWithPEM(kCFAllocatorDefault, data);
219 }
220 CFRelease(data);
221 } else {
222 result = 1;
223 }
224 }
225
226 if (cert) {
227 if (!keychain_certs) {
228 printf(
229 "*******************************************************\n"
230 "%s\n"
231 "*******************************************************\n"
232 , argv[arg]);
233 }
234 if (trust_eval) {
235 if (keychain_certs) {
236 CFArraySetValueAtIndex(certs, 0, cert);
237 show_cert_eval(certs, verbose);
238 } else {
239 CFArrayAppendValue(certs, cert);
240 }
241 } else {
242 if (verbose) {
243 print_cert(cert, verbose);
244 } else if (output_subject) {
245 CFStringRef subject = SecCertificateCopySubjectString(cert);
246 if (subject) {
247 CFStringWriteToFileWithNewline(subject, stdout);
248 CFRelease(subject);
249 }
250 } else if (!output_pem) {
251 print_cert(cert, verbose);
252 }
253 }
254 if (output_finger_print) {
255 CFDataRef key_fingerprint = SecCertificateCopyPublicKeySHA1Digest(cert);
256 if (key_fingerprint) {
257 int i;
258 CFIndex j = CFDataGetLength(key_fingerprint);
259 const uint8_t *byte = CFDataGetBytePtr(key_fingerprint);
260
261 fprintf(stdout, "Key fingerprint:");
262 for (i = 0; i < j; i++) {
263 fprintf(stdout, " %02X", byte[i]);
264 }
265 fprintf(stdout, "\n");
266 }
267 CFReleaseSafe(key_fingerprint);
268 }
269 if (output_pem) {
270 print_buffer_pem(stdout, "CERTIFICATE",
271 SecCertificateGetLength(cert),
272 SecCertificateGetBytePtr(cert));
273 }
274 if (!keychain_certs) {
275 CFRelease(cert);
276 }
277 } else {
278 result = 1;
279 fprintf(stderr, "file %s: does not contain a valid certificate",
280 argv[arg]);
281 }
282 }
283
284 if (trust_eval && !keychain_certs)
285 show_cert_eval(certs, verbose);
286
287 CFReleaseSafe(kc_certs);
288 CFReleaseSafe(certs);
289
290 return result;
291 }
292
293 #endif // TARGET_OS_EMBEDDED