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>
56 #include <SecurityTool/readline.h>
58 #include <utilities/SecCFWrappers.h>
59 #include "keychain_util.h"
61 typedef uint32_t SecProtocolType
;
62 typedef uint32_t SecAuthenticationType
;
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
[] = {
76 "recoverable trust failure",
77 "fatal trust failure",
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
);
92 printf("* cert %ld detail properties *\n", ix
);
93 properties
= SecTrustCopyDetailedPropertiesAtIndex(trust
, ix
);
94 print_plist(properties
);
95 CFReleaseNull(properties
);
99 CFDictionaryRef info
= SecTrustCopyInfo(trust
);
101 printf("* info *\n");
105 CFReleaseNull(policy
);
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
);
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
);
123 p
+= sprintf(p
, "\n-----END %s-----\n", pem_name
);
124 size_t res
= fwrite(buffer
, 1, p
- buffer
, stream
);
126 bzero(buffer
, p
- buffer
);
131 int keychain_show_certificates(int argc
, char * const *argv
)
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
);
143 while ((ch
= getopt(argc
, argv
, "kfq:pstv")) != -1)
148 keychain_certs
= true;
154 output_subject
= true;
163 output_finger_print
= true;
166 if (!keychain_query_parse_cstring(query
, optarg
)) {
167 CFReleaseNull(query
);
170 keychain_certs
= true;
174 return 2; /* @@@ Return 2 triggers usage message. */
181 if ((keychain_certs
&& argc
> 0) || (!keychain_certs
&& argc
< 1))
185 certs
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
);
187 CFArrayRef kc_certs
= NULL
;
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
);
197 CFDictionarySetValue(query
, kSecClass
, kSecClassCertificate
);
198 CFDictionarySetValue(query
, kSecMatchLimit
, kSecMatchLimitAll
);
199 CFDictionarySetValue(query
, kSecReturnRef
, kCFBooleanTrue
);
201 if (!SecItemCopyMatching(query
, &results
)) {
203 argc
= (int) CFArrayGetCount(kc_certs
);
207 for (arg
= 0; arg
< argc
; ++arg
) {
208 SecCertificateRef cert
= NULL
;
209 if (keychain_certs
) {
210 cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(kc_certs
, arg
);
212 CFDataRef data
= copyFileContents(argv
[arg
]);
214 cert
= SecCertificateCreateWithData(
215 kCFAllocatorDefault
, data
);
217 /* DER failed, try PEM. */
218 cert
= SecCertificateCreateWithPEM(kCFAllocatorDefault
, data
);
227 if (!keychain_certs
) {
229 "*******************************************************\n"
231 "*******************************************************\n"
235 if (keychain_certs
) {
236 CFArraySetValueAtIndex(certs
, 0, cert
);
237 show_cert_eval(certs
, verbose
);
239 CFArrayAppendValue(certs
, cert
);
243 print_cert(cert
, verbose
);
244 } else if (output_subject
) {
245 CFStringRef subject
= SecCertificateCopySubjectString(cert
);
247 CFStringWriteToFileWithNewline(subject
, stdout
);
250 } else if (!output_pem
) {
251 print_cert(cert
, verbose
);
254 if (output_finger_print
) {
255 CFDataRef key_fingerprint
= SecCertificateCopyPublicKeySHA1Digest(cert
);
256 if (key_fingerprint
) {
258 CFIndex j
= CFDataGetLength(key_fingerprint
);
259 const uint8_t *byte
= CFDataGetBytePtr(key_fingerprint
);
261 fprintf(stdout
, "Key fingerprint:");
262 for (i
= 0; i
< j
; i
++) {
263 fprintf(stdout
, " %02X", byte
[i
]);
265 fprintf(stdout
, "\n");
267 CFReleaseSafe(key_fingerprint
);
270 print_buffer_pem(stdout
, "CERTIFICATE",
271 SecCertificateGetLength(cert
),
272 SecCertificateGetBytePtr(cert
));
274 if (!keychain_certs
) {
279 fprintf(stderr
, "file %s: does not contain a valid certificate",
284 if (trust_eval
&& !keychain_certs
)
285 show_cert_eval(certs
, verbose
);
287 CFReleaseSafe(kc_certs
);
288 CFReleaseSafe(certs
);
293 #endif // TARGET_OS_EMBEDDED