]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-61-pkcs12.c
Security-58286.1.32.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-61-pkcs12.c
1 /*
2 * Copyright (c) 2008-2010,2012-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
24
25 #include <Security/SecImportExport.h>
26
27 #include <CommonCrypto/CommonCryptor.h>
28 #include <Security/SecIdentity.h>
29 #include <Security/SecItem.h>
30 #include <Security/SecItemPriv.h>
31 #include <Security/SecBasePriv.h>
32 #include <Security/SecKey.h>
33 #include <Security/SecECKey.h>
34 #include <Security/SecCertificate.h>
35
36 #include <Security/SecInternal.h>
37 #include <CoreFoundation/CoreFoundation.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40
41 #include "shared_regressions.h"
42 #include "si-61-pkcs12.h"
43
44 #if TARGET_OS_OSX
45 static void delete_identity(SecCertificateRef cert, SecKeyRef pkey) {
46 CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 2, &kCFTypeDictionaryKeyCallBacks,
47 &kCFTypeDictionaryValueCallBacks);
48 CFDictionaryAddValue(query, kSecClass, kSecClassCertificate);
49 CFDictionaryAddValue(query, kSecValueRef, cert);
50 SecItemDelete(query);
51
52 CFDictionaryRemoveAllValues(query);
53 CFDictionaryAddValue(query, kSecClass, kSecClassKey);
54 CFDictionaryAddValue(query, kSecValueRef, pkey);
55 SecItemDelete(query);
56 CFReleaseNull(query);
57 }
58 #endif
59
60
61 static void tests(void)
62 {
63 CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
64 _user_one_p12, sizeof(_user_one_p12), kCFAllocatorNull);
65 CFArrayRef items = NULL;
66 SecCertificateRef cert = NULL;
67 SecKeyRef pkey = NULL;
68
69 #pragma clang diagnostic push
70 #pragma clang diagnostic ignored "-Wnonnull"
71 // Disable compile-time nullability checks, otherwise the code below won't compile.
72 #if TARGET_OS_IPHONE
73 is_status(SecPKCS12Import(message, NULL, NULL), errSecAuthFailed,
74 "try null password on a known good p12");
75 #else
76 is_status(SecPKCS12Import(message, NULL, NULL), errSecPassphraseRequired,
77 "try null password on a known good p12");
78 #endif
79 #pragma clang diagnostic pop
80
81 CFStringRef password = CFSTR("user-one");
82 CFDictionaryRef options = CFDictionaryCreate(NULL,
83 (const void **)&kSecImportExportPassphrase,
84 (const void **)&password, 1,
85 &kCFTypeDictionaryKeyCallBacks,
86 &kCFTypeDictionaryValueCallBacks);
87 ok_status(SecPKCS12Import(message, options, &items), "import user one");
88
89 is(CFArrayGetCount(items), 1, "one identity");
90 CFDictionaryRef item = CFArrayGetValueAtIndex(items, 0);
91 SecIdentityRef identity = NULL;
92 ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data");
93
94 ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef");
95 ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key");
96 ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate");
97
98 #if TARGET_OS_OSX
99 /* We need to delete the identity from the keychain because SecPKCS12Import imports to the
100 * keychain on macOS. */
101 delete_identity(cert, pkey);
102 #endif
103
104 CFReleaseNull(items);
105 CFReleaseNull(message);
106 CFReleaseNull(options);
107 CFReleaseNull(password);
108 CFReleaseNull(cert);
109 CFReleaseNull(pkey);
110
111 message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
112 _user_two_p12, sizeof(_user_two_p12), kCFAllocatorNull);
113 items = NULL;
114 password = CFSTR("user-two");
115 options = CFDictionaryCreate(NULL,
116 (const void **)&kSecImportExportPassphrase,
117 (const void **)&password, 1,
118 &kCFTypeDictionaryKeyCallBacks,
119 &kCFTypeDictionaryValueCallBacks);
120
121 ok_status(SecPKCS12Import(message, options, &items), "import user two");
122 is(CFArrayGetCount(items), 1, "one identity");
123 item = CFArrayGetValueAtIndex(items, 0);
124 ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data");
125
126 ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef");
127 ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key");
128 ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate");
129
130 #if TARGET_OS_OSX
131 delete_identity(cert, pkey);
132 #endif
133
134
135 CFReleaseNull(items);
136 CFReleaseNull(message);
137 CFReleaseNull(options);
138 CFReleaseNull(password);
139 CFReleaseNull(cert);
140 CFReleaseNull(pkey);
141
142
143
144 message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
145 ECDSA_fails_import_p12, ECDSA_fails_import_p12_len, kCFAllocatorNull);
146 items = NULL;
147 password = CFSTR("test");
148 options = CFDictionaryCreate(NULL,
149 (const void **)&kSecImportExportPassphrase,
150 (const void **)&password, 1,
151 &kCFTypeDictionaryKeyCallBacks,
152 &kCFTypeDictionaryValueCallBacks);
153
154 ok_status(SecPKCS12Import(message, options, &items), "import ECDSA_fails_import_p12");
155 #if TARGET_OS_OSX
156 is(CFArrayGetCount(items), 2, "two identities"); //macOS implementation doesn't dedup
157 #else
158 is(CFArrayGetCount(items), 1, "one identity");
159 #endif
160 item = CFArrayGetValueAtIndex(items, 0);
161 ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data");
162
163 ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef");
164 ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key");
165 ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate");
166
167 SecKeyRef pubkey = NULL;
168 #if TARGET_OS_OSX
169 ok_status(SecCertificateCopyPublicKey(cert, &pubkey), "get public key from cert");
170 #else
171 ok(pubkey = SecKeyCopyPublicKey(pkey), "get public key from private key");
172 #endif
173 CFReleaseNull(message);
174
175 /* Sign something. */
176 uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
177 message = CFDataCreateWithBytesNoCopy(NULL, something, sizeof(something), kCFAllocatorNull);
178 CFDataRef signature = NULL;
179 CFErrorRef error = NULL;
180 ok(signature = SecKeyCreateSignature(pkey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, message, NULL), "sign something");
181 ok(SecKeyVerifySignature(pubkey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, message, signature, NULL), "verify sig on something");
182
183 #if TARGET_OS_OSX
184 delete_identity(cert, pkey);
185 #endif
186
187 CFReleaseNull(pubkey);
188 CFReleaseNull(pkey);
189
190 CFDataRef pubdata = NULL;
191 ok(pkey = SecKeyCreateECPrivateKey(kCFAllocatorDefault,
192 ECDSA_fails_import_priv_only, ECDSA_fails_import_priv_only_len,
193 kSecKeyEncodingPkcs1), "import privkey without pub");
194 ok_status(SecKeyCopyPublicBytes(pkey, &pubdata), "pub key from priv key");
195 ok(pubkey = SecKeyCreateECPublicKey(kCFAllocatorDefault,
196 CFDataGetBytePtr(pubdata), CFDataGetLength(pubdata), kSecKeyEncodingBytes),
197 "recreate seckey");
198 ok(SecKeyVerifySignature(pubkey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, message, signature, &error), "verify sig on something");
199
200 CFReleaseNull(pubdata);
201 CFReleaseNull(pubkey);
202 CFReleaseNull(pkey);
203 CFReleaseNull(signature);
204 CFReleaseNull(items);
205 CFReleaseNull(message);
206 CFReleaseNull(options);
207 CFReleaseNull(password);
208 CFReleaseNull(cert);
209
210 /* P521 test */
211 CFDataRef cert_p521_p12 = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
212 ec521_host_pfx, sizeof(ec521_host_pfx), kCFAllocatorNull);
213 CFStringRef password_p521 = CFSTR("test!123");
214 CFDictionaryRef options_p521 = CFDictionaryCreate(NULL,
215 (const void **)&kSecImportExportPassphrase,
216 (const void **)&password_p521, 1,
217 &kCFTypeDictionaryKeyCallBacks,
218 &kCFTypeDictionaryValueCallBacks);
219 ok_status(SecPKCS12Import(cert_p521_p12, options_p521, &items), "Import p512 PKCS12 cert");
220 is(CFArrayGetCount(items), 1, "one identity");
221 item = CFArrayGetValueAtIndex(items, 0);
222 ok(identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity), "pull identity from imported data");
223
224 ok(CFGetTypeID(identity)==SecIdentityGetTypeID(),"this is a SecIdentityRef");
225 ok_status(SecIdentityCopyPrivateKey(identity, &pkey),"get private key");
226 ok_status(SecIdentityCopyCertificate(identity, &cert), "get certificate");
227
228
229 #if TARGET_OS_OSX
230 delete_identity(cert, pkey);
231 #endif
232
233 CFReleaseNull(items);
234 CFReleaseNull(cert_p521_p12);
235 CFReleaseNull(password_p521);
236 CFReleaseNull(options_p521);
237 CFReleaseNull(pkey);
238 CFReleaseNull(cert);
239 }
240
241 static void test_cert_decode_error() {
242 CFDataRef message = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _cert_decode_error_p12,
243 sizeof(_cert_decode_error_p12), kCFAllocatorNull);
244 CFArrayRef items = NULL;
245 CFStringRef password = CFSTR("1234");
246 CFDictionaryRef options = CFDictionaryCreate(NULL,
247 (const void **)&kSecImportExportPassphrase,
248 (const void **)&password, 1,
249 &kCFTypeDictionaryKeyCallBacks,
250 &kCFTypeDictionaryValueCallBacks);
251 #if TARGET_OS_IPHONE
252 is(SecPKCS12Import(message, options, &items), errSecDecode, "import cert decode failure p12");
253 #else
254 is(SecPKCS12Import(message, options, &items), errSecUnknownFormat, "import cert decode failure p12");
255 #endif
256 CFReleaseNull(message);
257 CFReleaseNull(items);
258 CFReleaseNull(options);
259
260 }
261
262 int si_61_pkcs12(int argc, char *const *argv)
263 {
264 plan_tests(33);
265
266 tests();
267 test_cert_decode_error();
268
269 return 0;
270 }