]> git.saurik.com Git - apple/security.git/blob - OSX/regressions/test/testcert.c
Security-57337.40.85.tar.gz
[apple/security.git] / OSX / regressions / test / testcert.c
1 /*
2 * Copyright (c) 2009,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 * testcert.c
24 */
25
26 #include <TargetConditionals.h>
27
28 #if TARGET_OS_IPHONE
29
30 #include <CoreFoundation/CoreFoundation.h>
31 #include <Security/SecIdentityPriv.h>
32 #include <Security/SecItem.h>
33 #include <Security/SecCertificateRequest.h>
34 #include <Security/SecInternal.h>
35 #include <utilities/array_size.h>
36
37 #include <AssertMacros.h>
38
39 #include "testcert.h"
40
41 static inline CF_RETURNS_RETAINED CFMutableArrayRef maa(CFMutableArrayRef array CF_CONSUMED, CFTypeRef a CF_CONSUMED) {
42 CFMutableArrayRef ma = array;
43 if (!ma)
44 ma = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
45 if (ma) {
46 CFArrayAppendValue(ma, a);
47 }
48 CFRelease(a);
49 return ma;
50 }
51
52
53 CF_RETURNS_RETAINED
54 CFArrayRef test_cert_string_to_subject(CFStringRef subject)
55 {
56 CFMutableArrayRef subject_array = NULL;
57 char buffer[1024];
58
59 if (!CFStringGetCString(subject, buffer, sizeof(buffer), kCFStringEncodingASCII))
60 goto out;
61
62 char *s = buffer, *e = NULL;
63 while ( (e = strchr(s, ',')) || (e = strchr(s, '\0')) ) {
64 if (s == e)
65 break;
66 if (*e && (*(e-1) == '\\'))
67 continue;
68 char *k;
69 while ((k = strchr(s, '=')) &&
70 (*(k-1) == '\\'));
71 if ( ((k - s) > 0) && ((e - k) > 1) ) {
72 CFStringRef key = CFStringCreateWithBytes(kCFAllocatorDefault, (uint8_t *)s, k - s, kCFStringEncodingASCII, false);
73 CFStringRef value = CFStringCreateWithBytes(kCFAllocatorDefault, (uint8_t *)k + 1, e - k - 1, kCFStringEncodingASCII, false);
74 subject_array = maa(subject_array, maa(NULL, maa(maa(NULL, key), value)));
75 }
76 if (*e == '\0')
77 break;
78 s = e + 1;
79 }
80
81 out:
82 return subject_array;
83 }
84
85
86 static void test_cert_key_usage(CFMutableDictionaryRef extensions_dict, unsigned int key_usage)
87 {
88 int key_usage_int = key_usage;
89 CFNumberRef key_usage_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_usage_int);
90 CFDictionarySetValue(extensions_dict, kSecCertificateKeyUsage, key_usage_num);
91 CFRelease(key_usage_num);
92 }
93
94
95 static void test_cert_path_length(CFMutableDictionaryRef extensions_dict, unsigned int path_length)
96 {
97 int path_len_int = path_length;
98 CFNumberRef path_len_num = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &path_len_int);
99 CFDictionarySetValue(extensions_dict, kSecCSRBasicContraintsPathLen, path_len_num);
100 CFRelease(path_len_num);
101 }
102
103
104 SecIdentityRef test_cert_create_root_certificate(CFStringRef subject, SecKeyRef public_key, SecKeyRef private_key)
105 {
106 SecCertificateRef ca_cert = NULL;
107 SecIdentityRef ca_identity = NULL;
108 CFMutableDictionaryRef extensions = NULL;
109
110 CFArrayRef ca_subject = NULL;
111 require(ca_subject = test_cert_string_to_subject(subject), out);
112 extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
113 test_cert_key_usage(extensions, kSecKeyUsageKeyCertSign | kSecKeyUsageCRLSign);
114 test_cert_path_length(extensions, 0);
115 ca_cert = SecGenerateSelfSignedCertificate(ca_subject, extensions, public_key, private_key);
116 if (private_key && ca_cert)
117 ca_identity = SecIdentityCreate(kCFAllocatorDefault, ca_cert, private_key);
118
119 out:
120 CFReleaseSafe(extensions);
121 CFReleaseSafe(ca_subject);
122 CFReleaseSafe(ca_cert);
123
124 return ca_identity;
125 }
126
127 SecCertificateRef test_cert_issue_certificate(SecIdentityRef ca_identity,
128 SecKeyRef public_key, CFStringRef subject,
129 unsigned int serial_no, unsigned int key_usage)
130 {
131 SecCertificateRef cert = NULL;
132 CFArrayRef cert_subject = NULL;
133 CFDataRef serialno = NULL;
134 CFMutableDictionaryRef extensions = NULL;
135
136 unsigned int serial = htonl(serial_no);
137 unsigned int serial_length = sizeof(serial);
138 uint8_t *serial_non_zero = (uint8_t*)&serial;
139 while (!*serial_non_zero && serial_length)
140 { serial_non_zero++; serial_length--; }
141 serialno = CFDataCreate(kCFAllocatorDefault,
142 serial_non_zero, serial_length);
143 require(cert_subject = test_cert_string_to_subject(subject), out);
144 //extensions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
145 //require(extensions, out);
146 //test_cert_key_usage(extensions, key_usage);
147
148 cert = SecIdentitySignCertificate(ca_identity, serialno,
149 public_key, cert_subject, NULL);
150
151 out:
152 CFReleaseSafe(extensions);
153 CFReleaseSafe(cert_subject);
154 CFReleaseSafe(serialno);
155
156 return cert;
157 }
158
159 OSStatus
160 test_cert_generate_key(uint32_t key_size_in_bits, CFTypeRef sec_attr_key_type,
161 SecKeyRef *private_key, SecKeyRef *public_key)
162 {
163 CFNumberRef key_size = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &key_size_in_bits);
164 const void *keygen_keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
165 const void *keygen_vals[] = { sec_attr_key_type, key_size };
166 CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault,
167 keygen_keys, keygen_vals, array_size(keygen_vals),
168 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
169 CFRelease(key_size);
170
171 return SecKeyGeneratePair(parameters, public_key, private_key);
172 }
173
174 #endif /* TARGET_OS_IPHONE */