]> git.saurik.com Git - apple/security.git/blame - OSX/sec/Security/Regressions/secitem/si-61-pkcs12.c
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-61-pkcs12.c
CommitLineData
427c49bc 1/*
d8f41ccd 2 * Copyright (c) 2008-2010,2012-2014 Apple Inc. All Rights Reserved.
427c49bc 3 *
d8f41ccd
A
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@
427c49bc
A
22 */
23
d8f41ccd 24
427c49bc
A
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>
866f8763 34#include <Security/SecCertificate.h>
427c49bc
A
35
36#include <Security/SecInternal.h>
37#include <CoreFoundation/CoreFoundation.h>
38#include <stdlib.h>
39#include <unistd.h>
40
866f8763
A
41#include "shared_regressions.h"
42#include "si-61-pkcs12.h"
43
44#if TARGET_OS_OSX
45static 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
5c19dc3a
A
59
60
427c49bc
A
61static 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
5c19dc3a
A
69#pragma clang diagnostic push
70#pragma clang diagnostic ignored "-Wnonnull"
71 // Disable compile-time nullability checks, otherwise the code below won't compile.
866f8763 72#if TARGET_OS_IPHONE
427c49bc
A
73 is_status(SecPKCS12Import(message, NULL, NULL), errSecAuthFailed,
74 "try null password on a known good p12");
866f8763
A
75#else
76 is_status(SecPKCS12Import(message, NULL, NULL), errSecPassphraseRequired,
77 "try null password on a known good p12");
78#endif
5c19dc3a 79#pragma clang diagnostic pop
427c49bc
A
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
866f8763
A
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
427c49bc
A
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
866f8763
A
130#if TARGET_OS_OSX
131 delete_identity(cert, pkey);
132#endif
133
134
427c49bc
A
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");
866f8763
A
155#if TARGET_OS_OSX
156 is(CFArrayGetCount(items), 2, "two identities"); //macOS implementation doesn't dedup
157#else
427c49bc 158 is(CFArrayGetCount(items), 1, "one identity");
866f8763 159#endif
427c49bc
A
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
427c49bc 167 SecKeyRef pubkey = NULL;
866f8763 168#if TARGET_OS_OSX
79b9da22 169 ok(pubkey = SecCertificateCopyKey(cert), "get public key from cert");
866f8763
A
170#else
171 ok(pubkey = SecKeyCopyPublicKey(pkey), "get public key from private key");
172#endif
173 CFReleaseNull(message);
427c49bc
A
174
175 /* Sign something. */
176 uint8_t something[20] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
866f8763
A
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");
427c49bc 182
866f8763
A
183#if TARGET_OS_OSX
184 delete_identity(cert, pkey);
185#endif
427c49bc 186
427c49bc
A
187 CFReleaseNull(pubkey);
188 CFReleaseNull(pkey);
189
866f8763 190 CFDataRef pubdata = NULL;
427c49bc
A
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");
866f8763 198 ok(SecKeyVerifySignature(pubkey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, message, signature, &error), "verify sig on something");
427c49bc
A
199
200 CFReleaseNull(pubdata);
201 CFReleaseNull(pubkey);
202 CFReleaseNull(pkey);
866f8763 203 CFReleaseNull(signature);
427c49bc
A
204 CFReleaseNull(items);
205 CFReleaseNull(message);
206 CFReleaseNull(options);
207 CFReleaseNull(password);
208 CFReleaseNull(cert);
209
5c19dc3a
A
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");
866f8763
A
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
5c19dc3a
A
233 CFReleaseNull(items);
234 CFReleaseNull(cert_p521_p12);
235 CFReleaseNull(password_p521);
236 CFReleaseNull(options_p521);
866f8763
A
237 CFReleaseNull(pkey);
238 CFReleaseNull(cert);
239}
240
241static 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
427c49bc
A
260}
261
262int si_61_pkcs12(int argc, char *const *argv)
263{
866f8763 264 plan_tests(33);
427c49bc
A
265
266 tests();
866f8763 267 test_cert_decode_error();
427c49bc
A
268
269 return 0;
270}