]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/Regressions/secitem/si-68-secmatchissuer.c
Security-57336.10.29.tar.gz
[apple/security.git] / OSX / sec / Security / Regressions / secitem / si-68-secmatchissuer.c
1 /*
2 * Copyright (c) 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 //
26 // si-68-secmatchissuer.c
27 // regressions
28 //
29 //
30 //
31 #include <CoreFoundation/CoreFoundation.h>
32 #include <Security/Security.h>
33 #include <libDER/libDER.h>
34 #include <libDER/DER_Decode.h>
35 #include <libDER/asn1Types.h>
36 #include <Security/SecCertificateInternal.h>
37 #include <Security/SecCertificatePriv.h>
38 #include <Security/SecIdentityPriv.h>
39 #include <Security/SecItem.h>
40 #include <Security/SecInternal.h>
41 #include <utilities/array_size.h>
42
43 #include "Security_regressions.h"
44 #include <test/testcert.h>
45
46 /*
47 static OSStatus add_item_to_keychain(CFTypeRef item, CFDataRef * persistent_ref)
48 {
49 const void *keys[] = { kSecValueRef, kSecReturnPersistentRef };
50 const void *vals[] = { item, kCFBooleanTrue };
51 CFDictionaryRef add_query = CFDictionaryCreate(NULL, keys, vals, array_size(keys), NULL, NULL);
52 OSStatus status = errSecAllocate;
53 if (add_query) {
54 status = SecItemAdd(add_query, (CFTypeRef *)persistent_ref);
55 CFRelease(add_query);
56 }
57 return status;
58 }
59
60 static OSStatus remove_item_from_keychain(CFTypeRef item, CFDataRef * persistent_ref)
61 {
62 const void *keys[] = { kSecValueRef, kSecReturnPersistentRef };
63 const void *vals[] = { item, kCFBooleanTrue };
64 CFDictionaryRef add_query = CFDictionaryCreate(NULL, keys, vals, array_size(keys), NULL, NULL);
65 OSStatus status = errSecAllocate;
66 if (add_query) {
67 status = SecItemAdd(add_query, (CFTypeRef *)persistent_ref);
68 CFRelease(add_query);
69 }
70 return status;
71 }
72 */
73
74 static OSStatus add_item(CFTypeRef item)
75 {
76 CFDictionaryRef add_query = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, &item, 1, NULL, NULL);
77 OSStatus status = SecItemAdd(add_query, NULL);
78 CFRelease(add_query);
79 return status;
80 }
81
82 static OSStatus remove_item(CFTypeRef item)
83 {
84 CFDictionaryRef remove_query = CFDictionaryCreate(NULL, (const void **)&kSecValueRef, &item, 1, NULL, NULL);
85 OSStatus status = SecItemDelete(remove_query);
86 CFRelease(remove_query);
87 return status;
88 }
89
90 static void tests(void)
91 {
92
93 // MARK: test SecDistinguishedNameCopyNormalizedContent
94
95 unsigned char example_dn[] = {
96 0x30, 0x4f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
97 0x02, 0x43, 0x5a, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0a,
98 0x0c, 0x1e, 0x4d, 0x69, 0x6e, 0x69, 0x73, 0x74, 0x65, 0x72, 0x73, 0x74,
99 0x76, 0x6f, 0x20, 0x73, 0x70, 0x72, 0x61, 0x76, 0x65, 0x64, 0x6c, 0x6e,
100 0x6f, 0x73, 0x74, 0x69, 0x20, 0xc4, 0x8c, 0x52, 0x31, 0x17, 0x30, 0x15,
101 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0e, 0x4d, 0x53, 0x70, 0x20, 0x52,
102 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41, 0x20, 0x30, 0x31
103 };
104 unsigned int example_dn_len = 81;
105
106 CFDataRef normalized_dn = NULL, dn = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, example_dn, example_dn_len, kCFAllocatorNull);
107 ok(dn, "got dn as data");
108 ok(normalized_dn = SecDistinguishedNameCopyNormalizedContent(dn), "convert to normalized form");
109 //CFShow(dn);
110 //CFShow(normalized_dn);
111 CFReleaseNull(dn);
112 CFReleaseNull(normalized_dn);
113
114 // MARK: generate certificate hierarchy
115
116 SecKeyRef public_key = NULL, private_key = NULL;
117 ok_status(test_cert_generate_key(512, kSecAttrKeyTypeRSA, &private_key, &public_key), "generate keypair");
118 // make organization random uuid to avoid previous run to spoil the fun
119
120 CFUUIDRef UUID = CFUUIDCreate(kCFAllocatorDefault);
121 CFStringRef uuidString = CFUUIDCreateString(kCFAllocatorDefault, UUID);
122 CFStringRef root_authority_name = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("O=%@,CN=Root CA"), uuidString);
123 CFStringRef intermediate_authority_name = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("O=%@,CN=Intermediate CA"), uuidString);
124 CFStringRef leaf_name = CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("O=%@,CN=Client"), uuidString);
125 CFRelease(uuidString);
126 CFRelease(UUID);
127
128 SecIdentityRef ca_identity =
129 test_cert_create_root_certificate(root_authority_name, public_key, private_key);
130 CFRelease(root_authority_name);
131
132 SecCertificateRef ca_cert = NULL;
133 SecIdentityCopyCertificate(ca_identity, &ca_cert);
134 //CFShow(ca_cert);
135
136 SecCertificateRef intermediate_cert =
137 test_cert_issue_certificate(ca_identity, public_key, intermediate_authority_name, 42, kSecKeyUsageKeyCertSign);
138 CFRelease(intermediate_authority_name);
139 SecIdentityRef intermediate_identity = SecIdentityCreate(kCFAllocatorDefault, intermediate_cert, private_key);
140
141 ok_status(add_item(intermediate_cert), "add intermediate");
142 //CFShow(intermediate_cert);
143
144 SecCertificateRef leaf_cert = test_cert_issue_certificate(intermediate_identity, public_key,
145 leaf_name, 4242, kSecKeyUsageDigitalSignature);
146 CFRelease(leaf_name);
147 SecIdentityRef leaf_identity = SecIdentityCreate(kCFAllocatorDefault, leaf_cert, private_key);
148
149 ok_status(add_item(leaf_identity), "add leaf");
150 //CFShow(leaf_cert);
151
152 // this is already canonical - see if we can get the raw one
153 CFDataRef issuer = SecCertificateGetNormalizedIssuerContent(intermediate_cert);
154 ok(CFDataGetLength(issuer) < 128, "max 127 bytes of content - or else you'll need to properly encode issuer sequence");
155 CFMutableDataRef canonical_issuer = CFDataCreateMutable(kCFAllocatorDefault, CFDataGetLength(issuer) + 2);
156 CFDataSetLength(canonical_issuer, CFDataGetLength(issuer) + 2);
157 uint8_t * ptr = CFDataGetMutableBytePtr(canonical_issuer);
158 memcpy(ptr+2, CFDataGetBytePtr(issuer), CFDataGetLength(issuer));
159 ptr[0] = 0x30;
160 ptr[1] = CFDataGetLength(issuer);
161
162 CFMutableArrayRef all_distinguished_names = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
163 CFArrayAppendValue(all_distinguished_names, canonical_issuer);
164
165 {
166 CFReleaseNull(canonical_issuer);
167 const void *keys[] = { kSecClass, kSecReturnRef, kSecMatchLimit, kSecMatchIssuers };
168 const void *vals[] = { kSecClassIdentity, kCFBooleanTrue, kSecMatchLimitAll, all_distinguished_names };
169 CFDictionaryRef all_identities_query = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, array_size(keys), NULL, NULL);
170 CFTypeRef all_matching_identities = NULL;
171 ok_status(SecItemCopyMatching(all_identities_query, &all_matching_identities), "find all identities matching");
172 CFReleaseNull(all_identities_query);
173 ok(((CFArrayGetTypeID() == CFGetTypeID(all_matching_identities)) && (CFArrayGetCount(all_matching_identities) == 2)), "return 2");
174 //CFShow(all_matching_identities);
175 }
176
177 {
178 int limit = 0x7fff; // To regress-test <rdar://problem/14603111>
179 CFNumberRef cfLimit = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &limit);
180 const void *keys[] = { kSecClass, kSecReturnRef, kSecMatchLimit, kSecMatchIssuers };
181 const void *vals[] = { kSecClassCertificate, kCFBooleanTrue, cfLimit, all_distinguished_names };
182 CFDictionaryRef all_identities_query = CFDictionaryCreate(kCFAllocatorDefault, keys, vals, array_size(keys), NULL, NULL);
183 CFTypeRef all_matching_certificates = NULL;
184 ok_status(SecItemCopyMatching(all_identities_query, &all_matching_certificates), "find all certificates matching");
185 CFReleaseNull(all_identities_query);
186 ok(((CFArrayGetTypeID() == CFGetTypeID(all_matching_certificates)) && (CFArrayGetCount(all_matching_certificates) == 2)), "return 2");
187 //CFShow(all_matching_certificates);
188 CFReleaseSafe(cfLimit);
189 }
190
191 remove_item(leaf_identity);
192 CFRelease(leaf_identity);
193 CFRelease(leaf_cert);
194
195 remove_item(intermediate_cert);
196 CFRelease(intermediate_cert);
197 CFRelease(intermediate_identity);
198
199 CFRelease(ca_cert);
200 CFRelease(ca_identity);
201
202 CFRelease(public_key);
203 CFRelease(private_key);
204
205 }
206
207 int si_68_secmatchissuer(int argc, char *const *argv)
208 {
209 plan_tests(10);
210
211 tests();
212
213 return 0;
214 }