3 // Currently only supported for iOS
11 #include <CoreFoundation/CoreFoundation.h>
13 #include <AssertMacros.h>
14 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
15 #include <Security/SecureTransport.h>
16 #include <Security/SecPolicy.h>
17 #include <Security/SecTrust.h>
18 #include <Security/SecIdentity.h>
19 #include <Security/SecIdentityPriv.h>
20 #include <Security/SecCertificatePriv.h>
21 #include <Security/SecKeyPriv.h>
22 #include <Security/SecItem.h>
23 #include <Security/SecRandom.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
30 #include <mach/mach_time.h>
32 #include <Security/SecRSAKey.h>
39 Below are all the ciphers that are individually tested. The first element
40 is the SecureTransport/RFC name; the second is what openssl calls it, which
41 can be looked up in ciphers(1).
43 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
44 securetransport support them:
45 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
46 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
47 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
48 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
49 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
51 DSS is unimplemented by securetransport on the phone:
52 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
53 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
54 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
56 SSLv2 ciphersuites disabled by securetransport on phone:
57 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
58 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
60 SSLv3 ciphersuites disabled by securetransport on phone:
61 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
65 typedef struct _CipherSuiteName
{
66 SSLCipherSuite cipher
;
71 #define CIPHER(cipher, dh_anonymous) { cipher, #cipher, dh_anonymous }
73 static const CipherSuiteName ciphers
[] = {
75 /* TODO: Generate an ecdsa private key and certificate for the tests. */
76 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
, false),
77 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
, false),
78 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
, false),
79 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
, false),
80 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
, false),
81 CIPHER(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
, false),
82 CIPHER(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
, false),
83 CIPHER(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
, false),
84 CIPHER(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
, false),
85 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
, false),
86 CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
, false),
87 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
, false),
88 CIPHER(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
, false),
89 CIPHER(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
, false),
90 CIPHER(TLS_ECDHE_RSA_WITH_RC4_128_SHA
, false),
91 CIPHER(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
, false),
92 CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
, false),
93 CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
, false),
94 CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
, false),
95 CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
, false),
96 CIPHER(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
, false),
97 CIPHER(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
, false),
98 CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
, false),
99 CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
, false),
100 CIPHER(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
, false),
101 CIPHER(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
, false),
102 CIPHER(TLS_ECDH_ECDSA_WITH_RC4_128_SHA
, false),
103 CIPHER(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
, false),
104 CIPHER(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
, false),
105 CIPHER(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
, false),
106 CIPHER(TLS_ECDH_RSA_WITH_RC4_128_SHA
, false),
107 CIPHER(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
, false),
109 CIPHER(TLS_RSA_WITH_AES_256_GCM_SHA384
, false),
110 CIPHER(TLS_RSA_WITH_AES_128_GCM_SHA256
, false),
111 CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA256
, false),
112 CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA256
, false),
113 CIPHER(TLS_RSA_WITH_AES_128_CBC_SHA
, false),
114 CIPHER(SSL_RSA_WITH_RC4_128_SHA
, false),
115 CIPHER(SSL_RSA_WITH_RC4_128_MD5
, false),
116 CIPHER(TLS_RSA_WITH_AES_256_CBC_SHA
, false),
117 CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_SHA
, false),
118 CIPHER(SSL_RSA_WITH_3DES_EDE_CBC_MD5
, false),
119 CIPHER(SSL_RSA_WITH_DES_CBC_SHA
, false),
120 CIPHER(SSL_RSA_WITH_DES_CBC_MD5
, false),
121 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5
, false),
122 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
, false),
123 CIPHER(SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
, false),
124 CIPHER(SSL_RSA_WITH_RC2_CBC_MD5
, false),
125 CIPHER(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
, false),
126 CIPHER(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
, false),
127 CIPHER(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
, false),
128 CIPHER(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
, false),
129 CIPHER(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
, false),
130 CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
, false),
131 CIPHER(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
, false),
132 CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
, false),
133 CIPHER(TLS_DHE_DSS_WITH_AES_128_CBC_SHA
, false),
134 CIPHER(TLS_DHE_RSA_WITH_AES_128_CBC_SHA
, false),
135 CIPHER(TLS_DHE_DSS_WITH_AES_256_CBC_SHA
, false),
136 CIPHER(TLS_DHE_RSA_WITH_AES_256_CBC_SHA
, false),
137 CIPHER(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, false),
138 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA
, false),
139 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, false),
140 CIPHER(SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
, false),
141 CIPHER(SSL_DHE_DSS_WITH_DES_CBC_SHA
, false),
142 CIPHER(SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
, false),
143 CIPHER(TLS_DH_anon_WITH_AES_256_GCM_SHA384
, true),
144 CIPHER(TLS_DH_anon_WITH_AES_128_GCM_SHA256
, true),
145 CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA256
, true),
146 CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA256
, true),
147 CIPHER(TLS_DH_anon_WITH_AES_128_CBC_SHA
, true),
148 CIPHER(TLS_DH_anon_WITH_AES_256_CBC_SHA
, true),
149 CIPHER(SSL_DH_anon_WITH_RC4_128_MD5
, true),
150 CIPHER(SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
, true),
151 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA
, true),
152 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, true),
153 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, true),
155 CIPHER(TLS_ECDHE_ECDSA_WITH_NULL_SHA
, false),
156 CIPHER(TLS_ECDHE_RSA_WITH_NULL_SHA
, false),
157 CIPHER(TLS_ECDH_ECDSA_WITH_NULL_SHA
, false),
158 CIPHER(TLS_ECDH_RSA_WITH_NULL_SHA
, false),
160 CIPHER(TLS_RSA_WITH_NULL_SHA256
, false),
161 CIPHER(SSL_RSA_WITH_NULL_SHA
, false),
162 CIPHER(SSL_RSA_WITH_NULL_MD5
, false),
164 /* We don't support these yet. */
165 CIPHER(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
, false),
166 CIPHER(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, false),
167 CIPHER(TLS_RSA_WITH_RC4_128_SHA
, false),
168 CIPHER(TLS_RSA_WITH_3DES_EDE_CBC_SHA
, false),
169 CIPHER(TLS_RSA_WITH_RC4_128_MD5
, false),
170 CIPHER(TLS_DH_DSS_WITH_AES_256_GCM_SHA384
, false),
171 CIPHER(TLS_DH_DSS_WITH_AES_128_GCM_SHA256
, false),
172 CIPHER(TLS_DH_RSA_WITH_AES_256_GCM_SHA384
, false),
173 CIPHER(TLS_DH_RSA_WITH_AES_128_GCM_SHA256
, false),
174 CIPHER(TLS_DH_DSS_WITH_AES_256_CBC_SHA256
, false),
175 CIPHER(TLS_DH_RSA_WITH_AES_256_CBC_SHA256
, false),
176 CIPHER(TLS_DH_DSS_WITH_AES_128_CBC_SHA256
, false),
177 CIPHER(TLS_DH_RSA_WITH_AES_128_CBC_SHA256
, false),
178 CIPHER(TLS_DH_DSS_WITH_AES_256_CBC_SHA
, false),
179 CIPHER(TLS_DH_RSA_WITH_AES_256_CBC_SHA
, false),
180 CIPHER(TLS_DH_DSS_WITH_AES_128_CBC_SHA
, false),
181 CIPHER(TLS_DH_RSA_WITH_AES_128_CBC_SHA
, false),
182 CIPHER(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
, false),
183 CIPHER(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
, false),
184 CIPHER(TLS_ECDH_anon_WITH_AES_256_CBC_SHA
, false),
185 CIPHER(TLS_ECDH_anon_WITH_AES_128_CBC_SHA
, false),
186 CIPHER(TLS_ECDH_anon_WITH_RC4_128_SHA
, false),
187 CIPHER(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
, false),
188 CIPHER(TLS_ECDH_anon_WITH_NULL_SHA
, false),
194 static int ciphers_len
= array_size(ciphers
);
196 #if 0 // currently unused
197 static SSLCipherSuite
sslcipher_atoi(const char *name
)
199 const CipherSuiteName
*a
= ciphers
;
201 if (0 == strcmp(a
->name
, name
)) break;
207 static const char * sslcipher_itoa(SSLCipherSuite num
)
209 const CipherSuiteName
*a
= ciphers
;
210 while(a
->cipher
>= 0) {
211 if (num
== a
->cipher
) break;
216 #endif // currently unused
218 static unsigned char dh_param_512_bytes
[] = {
219 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
220 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
221 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
222 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
223 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
224 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
226 static unsigned char *dh_param_512_der
= dh_param_512_bytes
;
227 static unsigned int dh_param_512_der_len
= 72;
229 /* openssl req -newkey rsa:512 -sha1 -days 365 -subj "/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=localhost" -x509 -nodes -outform DER -keyout privkey.der -outform der -out cert.der */
230 static unsigned char pkey_der
[] = {
231 0x30, 0x82, 0x01, 0x3b, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00, 0xc0, 0x80,
232 0x43, 0xf1, 0x4d, 0xdc, 0x9a, 0x24, 0xe7, 0x25, 0x7c, 0x8b, 0x8b, 0x65,
233 0x87, 0x97, 0xed, 0x3f, 0xfa, 0xfe, 0xbe, 0xcb, 0x12, 0x43, 0x1f, 0x0c,
234 0xb5, 0xbf, 0x6b, 0x81, 0xee, 0x1b, 0x46, 0x6a, 0x02, 0x86, 0x92, 0xec,
235 0x8a, 0xb3, 0x65, 0x77, 0x15, 0xd0, 0x49, 0xb4, 0x22, 0x84, 0xf4, 0x85,
236 0x56, 0x53, 0xf5, 0x5a, 0x3b, 0xad, 0x23, 0xa8, 0x0c, 0x24, 0xb7, 0xf5,
237 0xf4, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x41, 0x00, 0xb8, 0x7f,
238 0xf7, 0x1e, 0xa7, 0x0e, 0xc1, 0x9a, 0x8f, 0x04, 0x49, 0xcb, 0x81, 0x4e,
239 0x4d, 0x58, 0x5a, 0xe7, 0x10, 0x8c, 0xea, 0x96, 0xbd, 0xa9, 0x21, 0x70,
240 0x50, 0x1d, 0xe8, 0x4f, 0x7e, 0xc2, 0x71, 0xff, 0x55, 0xc5, 0xa7, 0x28,
241 0xc8, 0xf2, 0xc7, 0x19, 0xd1, 0x2c, 0x10, 0x40, 0x39, 0xa8, 0xe1, 0x5b,
242 0xbd, 0x97, 0x04, 0xff, 0xd3, 0x27, 0x9b, 0xce, 0x5e, 0x8d, 0x2f, 0x0e,
243 0xd9, 0xf1, 0x02, 0x21, 0x00, 0xde, 0xfc, 0x18, 0x88, 0xa4, 0xef, 0x3b,
244 0x18, 0xca, 0x54, 0x3f, 0xa8, 0x14, 0x96, 0x9a, 0xd7, 0x67, 0x57, 0x55,
245 0xdc, 0x6b, 0xd4, 0x8e, 0x7d, 0xb4, 0x32, 0x00, 0x63, 0x67, 0x6a, 0x57,
246 0x65, 0x02, 0x21, 0x00, 0xdd, 0x00, 0xba, 0xdc, 0xa1, 0xe2, 0x5c, 0xda,
247 0xfe, 0xfc, 0x50, 0x1e, 0x9b, 0x95, 0x28, 0x34, 0xf2, 0x52, 0x31, 0x7a,
248 0x15, 0x00, 0x6f, 0xcc, 0x08, 0x2c, 0x6d, 0x55, 0xb0, 0x24, 0x6a, 0x8d,
249 0x02, 0x20, 0x14, 0xf5, 0x7d, 0x18, 0xda, 0xe7, 0xe1, 0x96, 0x22, 0xee,
250 0x68, 0x4d, 0x54, 0x22, 0x13, 0xcb, 0xcb, 0x5a, 0xda, 0x27, 0x2d, 0xbb,
251 0x7c, 0xe9, 0x33, 0xd6, 0xbf, 0x52, 0x98, 0x95, 0xd6, 0x41, 0x02, 0x21,
252 0x00, 0xaa, 0x58, 0x8c, 0xaf, 0xd1, 0x6b, 0xdc, 0x6c, 0xc4, 0xcc, 0x10,
253 0xa9, 0x76, 0xfc, 0xc2, 0x50, 0x05, 0x53, 0xcb, 0x65, 0x31, 0x58, 0xf3,
254 0xd3, 0x4d, 0x9d, 0x88, 0xec, 0xda, 0x67, 0x47, 0x65, 0x02, 0x20, 0x53,
255 0xf2, 0x49, 0x77, 0x7e, 0x10, 0xc1, 0xc4, 0xed, 0xc0, 0xaf, 0x99, 0x79,
256 0xab, 0x7b, 0x25, 0x0e, 0x70, 0x36, 0xd2, 0xd1, 0xa3, 0x81, 0x0d, 0x83,
257 0x4f, 0x6b, 0x1b, 0x48, 0xec, 0x87, 0x90
259 static unsigned int pkey_der_len
= 319;
261 static unsigned char cert_der
[] = {
262 0x30, 0x82, 0x02, 0x79, 0x30, 0x82, 0x02, 0x23, 0xa0, 0x03, 0x02, 0x01,
263 0x02, 0x02, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29, 0x2b,
264 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
265 0x05, 0x05, 0x00, 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
266 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
267 0x55, 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49,
268 0x6e, 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b,
269 0x13, 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74,
270 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75,
271 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06,
272 0x03, 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68,
273 0x6f, 0x73, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x39, 0x31,
274 0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x39,
275 0x30, 0x39, 0x31, 0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 0x30,
276 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
277 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
278 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31,
279 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41, 0x70,
280 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
281 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
282 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03,
283 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30,
284 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
285 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00,
286 0xc0, 0x80, 0x43, 0xf1, 0x4d, 0xdc, 0x9a, 0x24, 0xe7, 0x25, 0x7c, 0x8b,
287 0x8b, 0x65, 0x87, 0x97, 0xed, 0x3f, 0xfa, 0xfe, 0xbe, 0xcb, 0x12, 0x43,
288 0x1f, 0x0c, 0xb5, 0xbf, 0x6b, 0x81, 0xee, 0x1b, 0x46, 0x6a, 0x02, 0x86,
289 0x92, 0xec, 0x8a, 0xb3, 0x65, 0x77, 0x15, 0xd0, 0x49, 0xb4, 0x22, 0x84,
290 0xf4, 0x85, 0x56, 0x53, 0xf5, 0x5a, 0x3b, 0xad, 0x23, 0xa8, 0x0c, 0x24,
291 0xb7, 0xf5, 0xf4, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc3,
292 0x30, 0x81, 0xc0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
293 0x04, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca,
294 0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0x30, 0x81,
295 0x90, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x88, 0x30, 0x81, 0x85,
296 0x80, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca,
297 0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0xa1, 0x62,
298 0xa4, 0x60, 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
299 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
300 0x04, 0x0a, 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e,
301 0x63, 0x2e, 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13,
302 0x1d, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
303 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
304 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03,
305 0x55, 0x04, 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f,
306 0x73, 0x74, 0x82, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29,
307 0x2b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03,
308 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
309 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x41, 0x40, 0x07,
310 0xde, 0x1f, 0xd0, 0x00, 0x62, 0x75, 0x36, 0xb3, 0x94, 0xa8, 0xac, 0x3b,
311 0x98, 0xbb, 0x28, 0x56, 0xf6, 0x9f, 0xe3, 0x87, 0xd4, 0xa1, 0x7a, 0x85,
312 0xce, 0x40, 0x8a, 0xfd, 0x12, 0xb4, 0x99, 0x8c, 0x1d, 0x05, 0x61, 0xdb,
313 0x35, 0xb8, 0x04, 0x7c, 0xfb, 0xe4, 0x97, 0x88, 0x66, 0xa0, 0x54, 0x7b,
314 0x1c, 0xce, 0x99, 0xd8, 0xd3, 0x99, 0x80, 0x40, 0x9b, 0xa2, 0x73, 0x8b,
317 static unsigned int cert_der_len
= 637;
321 bool is_session_resume
;
322 SSLContextRef handle
;
325 bool client_side_auth
;
331 #if 0 // currently unused
332 static CFArrayRef
SecIdentityCopySSLClientAuthenticationChain(SecIdentityRef identity
)
334 CFMutableArrayRef chain
= NULL
;
335 SecPolicyRef policy
= NULL
;
336 SecTrustRef trust
= NULL
;
337 SecTrustResultType trust_result
;
340 policy
= SecPolicyCreateSSL(false, NULL
);
344 SecCertificateRef cert
= NULL
;
345 if (SecIdentityCopyCertificate(identity
, &cert
))
348 CFArrayRef certs
= CFArrayCreate(NULL
, (const void **)&cert
,
349 1, &kCFTypeArrayCallBacks
);
354 if (SecTrustCreateWithCertificates(certs
, policy
, &trust
))
358 if (SecTrustEvaluate(trust
, &trust_result
))
361 int i
, count
= SecTrustGetCertificateCount(trust
);
362 chain
= CFArrayCreateMutable(NULL
, count
, &kCFTypeArrayCallBacks
);
363 CFArrayAppendValue(chain
, identity
);
364 for (i
= 1; i
< count
; i
++) {
365 if ((i
+1 == count
) && (trust_result
== kSecTrustResultUnspecified
))
366 continue; /* skip anchor if chain is complete */
367 SecCertificateRef s
= SecTrustGetCertificateAtIndex(trust
, i
);
368 CFArrayAppendValue(chain
, s
);
377 #endif // currently unused
379 static CFArrayRef
server_chain()
381 SecKeyRef pkey
= SecKeyCreateRSAPrivateKey(kCFAllocatorDefault
,
382 pkey_der
, pkey_der_len
, kSecKeyEncodingPkcs1
);
383 SecCertificateRef cert
= SecCertificateCreateWithBytes(kCFAllocatorDefault
,
384 cert_der
, cert_der_len
);
385 SecIdentityRef ident
= SecIdentityCreate(kCFAllocatorDefault
, cert
, pkey
);
388 CFArrayRef items
= CFArrayCreate(kCFAllocatorDefault
,
389 (const void **)&ident
, 1, &kCFTypeArrayCallBacks
);
395 // MARK: SecureTransport support
398 static void hexdump(const uint8_t *bytes
, size_t len
) {
400 printf("socket write(%p, %lu)\n", bytes
, len
);
401 for (ix
= 0; ix
< len
; ++ix
) {
404 printf("%02X ", bytes
[ix
]);
409 #define hexdump(bytes, len)
412 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
414 size_t len
= *length
;
415 uint8_t *ptr
= (uint8_t *)data
;
421 ret
= write((int)conn
, ptr
, len
);
424 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
433 *length
= *length
- len
;
434 return errSecSuccess
;
437 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
439 size_t len
= *length
;
440 uint8_t *ptr
= (uint8_t *)data
;
445 ret
= read((int)conn
, ptr
, len
);
448 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
457 *length
= *length
- len
;
458 return errSecSuccess
;
461 static unsigned char dn
[] = {
462 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
463 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
464 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
465 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
466 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
467 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
468 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
469 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
471 static unsigned int dn_len
= 96;
473 static SSLContextRef
make_ssl_ref(bool server
, bool client_side_auth
, bool dh_anonymous
,
474 bool dtls
, int sock
, CFArrayRef certs
)
476 SSLContextRef ctx
= NULL
;
478 require_noerr(SSLNewDatagramContext(server
, &ctx
), out
);
480 require_noerr(SSLNewContext(server
, &ctx
), out
);
481 require_noerr(SSLSetIOFuncs(ctx
,
482 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
483 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)sock
), out
);
484 static const char *peer_domain_name
= "localhost";
485 require_noerr(SSLSetPeerDomainName(ctx
, peer_domain_name
,
486 strlen(peer_domain_name
)), out
);
490 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
491 if (client_side_auth
&& server
) {
492 require_noerr(SSLSetClientSideAuthenticate(ctx
, kAlwaysAuthenticate
), out
);
493 require_noerr(SSLAddDistinguishedName(ctx
, dn
, dn_len
), out
);
495 #if 0 /* Setting client certificate in advance */
496 if (client_side_auth
&& !server
)
497 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
499 if (client_side_auth
&& !server
) /* enable break from SSLHandshake */
500 require_noerr(SSLSetSessionOption(ctx
,
501 kSSLSessionOptionBreakOnCertRequested
, true), out
);
502 require_noerr(SSLSetSessionOption(ctx
,
503 kSSLSessionOptionBreakOnServerAuth
, true), out
);
506 /* Tell SecureTransport to not check certs itself: it will break out of the
507 handshake to let us take care of it instead. */
508 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
511 require_noerr(SSLSetDiffieHellmanParams(ctx
,
512 dh_param_512_der
, dh_param_512_der_len
), out
);
514 else /* if client */ {
520 SSLDisposeContext(ctx
);
524 static void *securetransport_ssl_thread(void *arg
)
527 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
528 SSLContextRef ctx
= ssl
->handle
;
529 SecTrustRef trust
= NULL
;
530 bool got_server_auth
= false, got_client_cert_req
= false;
532 //uint64_t start = mach_absolute_time();
534 ortn
= SSLHandshake(ctx
);
536 if (ortn
== errSSLServerAuthCompleted
)
538 require_string(!got_server_auth
, out
, "second server auth");
539 require_string(!got_client_cert_req
, out
, "got client cert req before server auth");
540 got_server_auth
= true;
541 require_string(!trust
, out
, "Got errSSLServerAuthCompleted twice?");
542 /* verify peer cert chain */
543 require_noerr(SSLCopyPeerTrust(ctx
, &trust
), out
);
544 SecTrustResultType trust_result
= 0;
545 /* this won't verify without setting up a trusted anchor */
546 require_noerr(SecTrustEvaluate(trust
, &trust_result
), out
);
548 CFIndex n_certs
= SecTrustGetCertificateCount(trust
);
549 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
551 CFMutableArrayRef peer_cert_array
=
552 CFArrayCreateMutable(NULL
, n_certs
, &kCFTypeArrayCallBacks
);
553 CFMutableArrayRef orig_peer_cert_array
=
554 CFArrayCreateMutableCopy(NULL
, n_certs
, ssl
->certs
);
556 CFArrayInsertValueAtIndex(peer_cert_array
, 0,
557 SecTrustGetCertificateAtIndex(trust
, n_certs
));
559 SecIdentityRef ident
=
560 (SecIdentityRef
)CFArrayGetValueAtIndex(orig_peer_cert_array
, 0);
561 SecCertificateRef peer_cert
= NULL
;
562 require_noerr(SecIdentityCopyCertificate(ident
, &peer_cert
), out
);
563 CFArraySetValueAtIndex(orig_peer_cert_array
, 0, peer_cert
);
564 CFRelease(peer_cert
);
566 require(CFEqual(orig_peer_cert_array
, peer_cert_array
), out
);
567 CFRelease(orig_peer_cert_array
);
568 CFRelease(peer_cert_array
);
571 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
572 char cert_name_buffer[1024];
573 require(CFStringGetFileSystemRepresentation(cert_name,
574 cert_name_buffer, sizeof(cert_name_buffer)), out);
575 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
578 } else if (ortn
== errSSLClientCertRequested
) {
579 require_string(!got_client_cert_req
, out
, "second client cert req");
580 require_string(got_server_auth
, out
, "didn't get server auth first");
581 got_client_cert_req
= true;
583 /* set client cert */
584 require_string(!ssl
->is_server
, out
, "errSSLClientCertRequested while running server");
585 require_string(!ssl
->dh_anonymous
, out
, "errSSLClientCertRequested while running anon DH");
587 CFArrayRef DNs
= NULL
;
588 require_noerr(SSLCopyDistinguishedNames (ctx
, &DNs
), out
);
592 require_string(ssl
->client_side_auth
, out
, "errSSLClientCertRequested in run not testing that");
593 require_noerr(SSLSetCertificate(ctx
, ssl
->certs
), out
);
595 } while (ortn
== errSSLWouldBlock
596 || ortn
== errSSLServerAuthCompleted
597 || ortn
== errSSLClientCertRequested
);
598 require_noerr_action_quiet(ortn
, out
,
599 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
601 if (!ssl
->is_server
&& !ssl
->dh_anonymous
&& !ssl
->is_session_resume
) {
602 require_string(got_server_auth
, out
, "never got server auth");
603 if (ssl
->client_side_auth
)
604 require_string(got_client_cert_req
, out
, "never got client cert req");
606 //uint64_t elapsed = mach_absolute_time() - start;
607 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
610 SSLProtocol proto = kSSLProtocolUnknown;
611 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
613 SSLCipherSuite cipherSuite
;
614 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
615 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
617 Boolean sessionWasResumed
= false;
618 uint8_t session_id_data
[MAX_SESSION_ID_LENGTH
];
619 size_t session_id_length
= sizeof(session_id_data
);
620 require_noerr_quiet(ortn
= SSLGetResumableSessionInfo(ctx
, &sessionWasResumed
, session_id_data
, &session_id_length
), out
);
621 require_action(ssl
->dh_anonymous
|| (ssl
->is_session_resume
== sessionWasResumed
), out
, ortn
= -1);
622 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
623 //hexdump(session_id_data, session_id_length);
625 unsigned char ibuf
[4096], obuf
[4096];
627 if (ssl
->is_server
) {
628 require_action(errSecSuccess
==SecRandomCopyBytes(kSecRandomDefault
, sizeof(obuf
), obuf
),out
, ortn
= -1);
629 require_noerr_quiet(ortn
= SSLWrite(ctx
, obuf
, sizeof(obuf
), &len
), out
);
630 require_action_quiet(len
== sizeof(obuf
), out
, ortn
= -1);
632 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
633 require_action_quiet(len
== sizeof(ibuf
), out
, ortn
= -1);
635 if (ssl
->is_server
) {
636 require_noerr(memcmp(ibuf
, obuf
, sizeof(ibuf
)), out
);
638 require_noerr_quiet(ortn
= SSLWrite(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
639 require_action_quiet(len
== sizeof(ibuf
), out
, ortn
= -1);
644 SSLDisposeContext(ctx
);
645 if (trust
) CFRelease(trust
);
647 pthread_exit((void *)(intptr_t)ortn
);
653 static ssl_test_handle
*
654 ssl_test_handle_create(uint32_t session_id
, bool resume
, bool server
, bool client_side_auth
, bool dh_anonymous
, bool dtls
,
655 int comm
, CFArrayRef certs
)
657 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
659 handle
->session_id
= session_id
;
660 handle
->is_session_resume
= resume
;
661 handle
->is_server
= server
;
662 handle
->client_side_auth
= client_side_auth
;
663 handle
->dh_anonymous
= dh_anonymous
;
665 handle
->certs
= certs
;
666 handle
->handle
= make_ssl_ref(server
, client_side_auth
, dh_anonymous
, dtls
, comm
, certs
);
674 pthread_t client_thread
, server_thread
;
675 CFArrayRef server_certs
= server_chain();
676 ok(server_certs
, "got server certs");
682 for (d
=0;d
<2; d
++) /* dtls or not dtls */
684 for (i
=0; ciphers
[i
].cipher
!= (SSLCipherSuite
)(-1); i
++)
685 for (l
= 0; l
<2; l
++) {
688 skip("ST doesn't support resumption", 1, l
!= 1);
691 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
693 ssl_test_handle
*server
, *client
;
695 bool client_side_auth
= (k
);
697 uint32_t session_id
= (k
+1) << 16 | 1 << 8 | (i
+1);
698 //fprintf(stderr, "session_id: %d\n", session_id);
699 server
= ssl_test_handle_create(session_id
, (l
== 1), true /*server*/,
700 client_side_auth
, ciphers
[i
].dh_anonymous
, d
,
701 sp
[0], server_certs
);
702 client
= ssl_test_handle_create(session_id
, (l
== 1), false/*client*/,
703 client_side_auth
, ciphers
[i
].dh_anonymous
, d
,
704 sp
[1], server_certs
);
706 require_noerr(SSLSetPeerID(server
->handle
, &session_id
, sizeof(session_id
)), out
);
707 require_noerr(SSLSetPeerID(client
->handle
, &session_id
, sizeof(session_id
)), out
);
709 /* set fixed cipher on client and server */
710 require_noerr(SSLSetEnabledCiphers(client
->handle
, &ciphers
[i
].cipher
, 1), out
);
711 require_noerr(SSLSetEnabledCiphers(server
->handle
, &ciphers
[i
].cipher
, 1), out
);
713 char test_description
[1024];
714 snprintf(test_description
, sizeof(test_description
),
715 "%40s ADH:%d CSA:%d DTLS:%d",
717 server
->dh_anonymous
,
718 server
->client_side_auth
,
721 printf("Echo test: %s\n", test_description
);
723 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
724 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
726 intptr_t server_err
, client_err
;
727 pthread_join(client_thread
, (void*)&client_err
);
728 pthread_join(server_thread
, (void*)&server_err
);
730 ok(!server_err
&& !client_err
, "%40s ADH:%d CSA:%d DTLS:%d",
732 server
->dh_anonymous
,
733 server
->client_side_auth
,
741 CFRelease(server_certs
);
745 int ssl_39_echo(int argc
, char *const *argv
)
747 plan_tests(2 * 2 * 2 * 3 * (ciphers_len
-1)/* client auth on/off * #configs * #ciphers */
759 TODO: count errSSLWouldBlock
760 TODO: skip tests that don't matter: client_auth and anonymous dh
761 TODO: we seem to only be negotiating tls - force a round of sslv3
762 TODO: allow secure transport to also defer client side auth to client
763 TODO: make sure anonymous dh is never selected if not expicitly enabled
764 TODO: make sure DHE is not available if not explicitly enabled and no parameters
766 TODO: resumable sessions