2 * Copyright (c) 2003-2007,2009-2010,2013-2014 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@
26 #include <TargetConditionals.h>
27 #if TARGET_OS_EMBEDDED
29 #include "SecurityCommands.h"
32 #include "SecurityTool/print_cert.h"
33 #include "SecBase64.h"
39 #include <sys/types.h>
42 #include <SecurityTool/tool_errors.h>
44 #include <Security/SecItem.h>
46 #include <CoreFoundation/CFArray.h>
47 #include <CoreFoundation/CFDate.h>
48 #include <CoreFoundation/CFNumber.h>
49 #include <CoreFoundation/CFString.h>
51 #include <Security/SecCertificatePriv.h>
52 #include <Security/SecPolicyPriv.h>
53 #include <Security/SecTrustPriv.h>
54 #include <Security/SecInternal.h>
55 #include <Security/SecTrustStore.h>
57 #include <SecurityTool/readline.h>
59 #include <utilities/SecCFWrappers.h>
60 #include "keychain_util.h"
62 typedef uint32_t SecProtocolType
;
63 typedef uint32_t SecAuthenticationType
;
66 static void show_cert_eval(CFArrayRef certs
, bool verbose
) {
67 SecPolicyRef policy
= SecPolicyCreateSSL(true, NULL
);
68 SecTrustRef trust
= NULL
;
69 SecTrustCreateWithCertificates(certs
, policy
, &trust
);
70 SecTrustResultType trustResult
;
71 const char *trustResults
[] = {
77 "recoverable trust failure",
78 "fatal trust failure",
81 (void) SecTrustEvaluate(trust
, &trustResult
);
82 printf("* trust: %s *\n", trustResults
[trustResult
]);
83 CFArrayRef properties
= SecTrustCopyProperties(trust
);
84 print_plist(properties
);
85 CFReleaseNull(properties
);
86 CFIndex ix
, count
= SecTrustGetCertificateCount(trust
);
87 for (ix
= 0; ix
< count
; ++ix
) {
88 printf("* cert %ld summary properties *\n", ix
);
89 properties
= SecTrustCopySummaryPropertiesAtIndex(trust
, ix
);
90 print_plist(properties
);
91 CFReleaseNull(properties
);
93 printf("* cert %ld detail properties *\n", ix
);
94 properties
= SecTrustCopyDetailedPropertiesAtIndex(trust
, ix
);
95 print_plist(properties
);
96 CFReleaseNull(properties
);
100 CFDictionaryRef info
= SecTrustCopyInfo(trust
);
102 printf("* info *\n");
106 CFReleaseNull(policy
);
109 static size_t print_buffer_pem(FILE *stream
, const char *pem_name
, size_t length
,
110 const uint8_t *bytes
) {
111 size_t pem_name_len
= strlen(pem_name
);
112 size_t b64_len
= SecBase64Encode2(NULL
, length
, NULL
, 0,
113 kSecB64_F_LINE_LEN_USE_PARAM
, 64, NULL
);
114 char *buffer
= malloc(33 + 2 * pem_name_len
+ b64_len
);
116 p
+= sprintf(buffer
, "-----BEGIN %s-----\n", pem_name
);
117 SecBase64Result result
;
118 p
+= SecBase64Encode2(bytes
, length
, p
, b64_len
,\
119 kSecB64_F_LINE_LEN_USE_PARAM
, 64, &result
);
124 p
+= sprintf(p
, "\n-----END %s-----\n", pem_name
);
125 size_t res
= fwrite(buffer
, 1, p
- buffer
, stream
);
127 bzero(buffer
, p
- buffer
);
132 int keychain_show_certificates(int argc
, char * const *argv
)
135 bool output_subject
= false;
136 bool verbose
= false;
137 bool trust_eval
= false;
138 bool keychain_certs
= false;
139 bool output_pem
= false;
140 bool output_finger_print
= false;
141 CFMutableArrayRef certs
= NULL
;
142 CFMutableDictionaryRef query
= CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
144 while ((ch
= getopt(argc
, argv
, "kfq:pstv")) != -1)
149 keychain_certs
= true;
155 output_subject
= true;
164 output_finger_print
= true;
167 if (!keychain_query_parse_cstring(query
, optarg
)) {
168 CFReleaseNull(query
);
171 keychain_certs
= true;
175 return 2; /* @@@ Return 2 triggers usage message. */
182 if ((keychain_certs
&& argc
> 0) || (!keychain_certs
&& argc
< 1))
186 certs
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
);
188 CFArrayRef kc_certs
= NULL
;
190 if (keychain_certs
) {
191 for (arg
= 0; arg
< argc
; ++arg
) {
192 if (!keychain_query_parse_cstring(query
, argv
[arg
])) {
193 CFReleaseSafe(query
);
194 CFReleaseSafe(certs
);
198 CFDictionarySetValue(query
, kSecClass
, kSecClassCertificate
);
199 CFDictionarySetValue(query
, kSecMatchLimit
, kSecMatchLimitAll
);
200 CFDictionarySetValue(query
, kSecReturnRef
, kCFBooleanTrue
);
202 if (!SecItemCopyMatching(query
, &results
)) {
204 argc
= (int) CFArrayGetCount(kc_certs
);
208 for (arg
= 0; arg
< argc
; ++arg
) {
209 SecCertificateRef cert
= NULL
;
210 if (keychain_certs
) {
211 cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(kc_certs
, arg
);
213 CFDataRef data
= copyFileContents(argv
[arg
]);
215 cert
= SecCertificateCreateWithData(
216 kCFAllocatorDefault
, data
);
218 /* DER failed, try PEM. */
219 cert
= SecCertificateCreateWithPEM(kCFAllocatorDefault
, data
);
228 if (!keychain_certs
) {
230 "*******************************************************\n"
232 "*******************************************************\n"
236 if (keychain_certs
) {
237 CFArraySetValueAtIndex(certs
, 0, cert
);
238 show_cert_eval(certs
, verbose
);
240 CFArrayAppendValue(certs
, cert
);
244 print_cert(cert
, verbose
);
245 } else if (output_subject
) {
246 CFStringRef subject
= SecCertificateCopySubjectString(cert
);
248 CFStringWriteToFileWithNewline(subject
, stdout
);
251 } else if (!output_pem
) {
252 print_cert(cert
, verbose
);
255 if (output_finger_print
) {
256 CFDataRef key_fingerprint
= SecCertificateCopyPublicKeySHA1Digest(cert
);
257 if (key_fingerprint
) {
259 CFIndex j
= CFDataGetLength(key_fingerprint
);
260 const uint8_t *byte
= CFDataGetBytePtr(key_fingerprint
);
262 fprintf(stdout
, "Key fingerprint:");
263 for (i
= 0; i
< j
; i
++) {
264 fprintf(stdout
, " %02X", byte
[i
]);
266 fprintf(stdout
, "\n");
268 CFReleaseSafe(key_fingerprint
);
271 print_buffer_pem(stdout
, "CERTIFICATE",
272 SecCertificateGetLength(cert
),
273 SecCertificateGetBytePtr(cert
));
275 if (!keychain_certs
) {
280 fprintf(stderr
, "file %s: does not contain a valid certificate",
285 if (trust_eval
&& !keychain_certs
)
286 show_cert_eval(certs
, verbose
);
288 CFReleaseSafe(kc_certs
);
289 CFReleaseSafe(certs
);
294 int trust_store_show_certificates(int argc
, char * const *argv
)
297 bool output_subject
= false;
298 bool verbose
= false;
299 bool trust_settings
= false;
300 bool output_pem
= false;
301 bool output_finger_print
= false;
302 bool output_keyid
= false;
303 CFArrayRef certs
= NULL
;
305 while ((ch
= getopt(argc
, argv
, "fpstvk")) != -1)
313 output_subject
= true;
319 trust_settings
= true;
322 output_finger_print
= true;
329 return 2; /* @@@ Return 2 triggers usage message. */
333 if(SecTrustStoreCopyAll(SecTrustStoreForDomain(kSecTrustStoreDomainUser
),
335 fprintf(stderr
, "failed to get trust store contents for user\n");
339 CFIndex ix
, count
= CFArrayGetCount(certs
);
340 if (count
) printf("*******************************************************\n");
341 for (ix
= 0; ix
< count
; ix
++) {
342 CFArrayRef certSettingsPair
= NULL
;
343 CFDataRef certData
= NULL
;
344 SecCertificateRef cert
= NULL
;
346 certSettingsPair
= CFArrayGetValueAtIndex(certs
, ix
);
347 certData
= (CFDataRef
)CFArrayGetValueAtIndex(certSettingsPair
, 0);
348 cert
= SecCertificateCreateWithData(kCFAllocatorDefault
, certData
);
350 fprintf(stderr
, "failed to get cert at %ld\n",ix
);
354 print_cert(cert
, verbose
);
355 } else if (output_subject
) {
356 CFStringRef subject
= SecCertificateCopySubjectString(cert
);
358 CFStringWriteToFileWithNewline(subject
, stdout
);
361 } else if (output_pem
) {
362 print_buffer_pem(stdout
, "CERTIFICATE",
363 SecCertificateGetLength(cert
),
364 SecCertificateGetBytePtr(cert
));
366 print_cert(cert
, verbose
);
369 CFDataRef key_fingerprint
= SecCertificateCopyPublicKeySHA1Digest(cert
);
370 if (key_fingerprint
) {
372 CFIndex j
= CFDataGetLength(key_fingerprint
);
373 const uint8_t *byte
= CFDataGetBytePtr(key_fingerprint
);
375 fprintf(stdout
, "Keyid:");
376 for (i
= 0; i
< j
; i
++) {
377 fprintf(stdout
, " %02X", byte
[i
]);
379 fprintf(stdout
, "\n");
381 CFReleaseSafe(key_fingerprint
);
383 if (output_finger_print
) {
384 CFDataRef fingerprint
= SecCertificateGetSHA1Digest(cert
);
387 CFIndex j
= CFDataGetLength(fingerprint
);
388 const uint8_t *byte
= CFDataGetBytePtr(fingerprint
);
390 fprintf(stdout
, "Fingerprint:");
391 for (i
= 0; i
< j
; i
++) {
392 fprintf(stdout
, " %02X", byte
[i
]);
394 fprintf(stdout
, "\n");
397 if (trust_settings
) {
398 CFPropertyListRef trust_settings
= NULL
;
399 trust_settings
= CFArrayGetValueAtIndex(certSettingsPair
, 1);
400 if (trust_settings
&& CFGetTypeID(trust_settings
) != CFArrayGetTypeID()) {
401 fprintf(stderr
, "failed to get trust settings for cert %ld\n", ix
);
405 // place-holder until there are actual trust settings
406 CFStringRef settings
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%@"), trust_settings
);
407 char *settingsStr
= NULL
;
408 settingsStr
= CFStringToCString(settings
);
409 fprintf(stdout
, "%s\n", settingsStr
);
414 printf("*******************************************************\n");
422 #endif // TARGET_OS_EMBEDDED