Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(317)

Side by Side Diff: runtime/bin/secure_socket_ios.cc

Issue 1852783003: Implements remaining SecurityContext calls for iOS (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add RefCntReleaseScope Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED) 5 #if !defined(DART_IO_DISABLED) && !defined(DART_IO_SECURE_SOCKET_DISABLED)
6 6
7 #include "platform/globals.h" 7 #include "platform/globals.h"
8 #if TARGET_OS_IOS 8 #if TARGET_OS_IOS
9 9
10 #include "bin/secure_socket.h" 10 #include "bin/secure_socket.h"
11 #include "bin/secure_socket_macos.h" 11 #include "bin/secure_socket_ios.h"
12 12
13 #include <errno.h> 13 #include <errno.h>
14 #include <fcntl.h> 14 #include <fcntl.h>
15 #include <sys/stat.h> 15 #include <sys/stat.h>
16 #include <sys/syslimits.h> 16 #include <sys/syslimits.h>
17 #include <stdio.h> 17 #include <stdio.h>
18 #include <string.h> 18 #include <string.h>
19 19
20 #include <CoreFoundation/CoreFoundation.h> 20 #include <CoreFoundation/CoreFoundation.h>
21 #include <Security/SecureTransport.h> 21 #include <Security/SecureTransport.h>
(...skipping 23 matching lines...) Expand all
45 45
46 namespace dart { 46 namespace dart {
47 namespace bin { 47 namespace bin {
48 48
49 static const int kSSLFilterNativeFieldIndex = 0; 49 static const int kSSLFilterNativeFieldIndex = 0;
50 static const int kSecurityContextNativeFieldIndex = 0; 50 static const int kSecurityContextNativeFieldIndex = 0;
51 static const int kX509NativeFieldIndex = 0; 51 static const int kX509NativeFieldIndex = 0;
52 52
53 static const bool SSL_LOG_STATUS = false; 53 static const bool SSL_LOG_STATUS = false;
54 static const bool SSL_LOG_DATA = false; 54 static const bool SSL_LOG_DATA = false;
55 static const bool SSL_LOG_CERTS = false;
55 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; 56 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000;
57 static const intptr_t PEM_BUFSIZE = 1024;
56 58
57 // SSLCertContext wraps the certificates needed for a SecureTransport 59 static char* CFStringRefToCString(CFStringRef cfstring) {
58 // connection. Fields are protected by the mutex_ field, and may only be set 60 CFIndex len = CFStringGetLength(cfstring);
59 // once. This is to allow access by both the Dart thread and the IOService 61 CFIndex max_len =
60 // thread. Setters return false if the field was already set. 62 CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8) + 1;
61 class SSLCertContext { 63 char* result = reinterpret_cast<char*>(Dart_ScopeAllocate(max_len));
62 public: 64 ASSERT(result != NULL);
63 SSLCertContext() : 65 bool success =
64 mutex_(new Mutex()), 66 CFStringGetCString(cfstring, result, max_len, kCFStringEncodingUTF8);
65 trusted_certs_(NULL), 67 return success ? result : NULL;
66 trust_builtin_(false) {} 68 }
67 69
68 ~SSLCertContext() {
69 delete mutex_;
70 if (trusted_certs_ != NULL) {
71 CFRelease(trusted_certs_);
72 }
73 }
74
75 CFMutableArrayRef trusted_certs() {
76 MutexLocker m(mutex_);
77 return trusted_certs_;
78 }
79 void add_trusted_cert(SecCertificateRef trusted_cert) {
80 // Takes ownership of trusted_cert.
81 MutexLocker m(mutex_);
82 if (trusted_certs_ == NULL) {
83 trusted_certs_ = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
84 }
85 CFArrayAppendValue(trusted_certs_, trusted_cert);
86 CFRelease(trusted_cert); // trusted_cert is retained by the array.
87 }
88
89 bool trust_builtin() {
90 MutexLocker m(mutex_);
91 return trust_builtin_;
92 }
93 void set_trust_builtin(bool trust_builtin) {
94 MutexLocker m(mutex_);
95 trust_builtin_ = trust_builtin;
96 }
97
98 private:
99 // The context is accessed both by Dart code and the IOService. This mutex
100 // protects all fields.
101 Mutex* mutex_;
102 CFMutableArrayRef trusted_certs_;
103 bool trust_builtin_;
104
105 DISALLOW_COPY_AND_ASSIGN(SSLCertContext);
106 };
107 70
108 // Handle an error reported from the SecureTransport library. 71 // Handle an error reported from the SecureTransport library.
109 static void ThrowIOException(OSStatus status, 72 static void ThrowIOException(OSStatus status,
110 const char* exception_type, 73 const char* exception_type,
111 const char* message) { 74 const char* message) {
112 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); 75 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE);
113 status_message.Printf("OSStatus = %ld: https://www.osstatus.com", 76 status_message.Printf("OSStatus = %ld: https://www.osstatus.com",
114 static_cast<intptr_t>(status)); 77 static_cast<intptr_t>(status));
115 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL); 78 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL);
116 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); 79 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
(...skipping 24 matching lines...) Expand all
141 kSSLFilterNativeFieldIndex, 104 kSSLFilterNativeFieldIndex,
142 reinterpret_cast<intptr_t*>(&filter))); 105 reinterpret_cast<intptr_t*>(&filter)));
143 return filter; 106 return filter;
144 } 107 }
145 108
146 109
147 static void DeleteFilter(void* isolate_data, 110 static void DeleteFilter(void* isolate_data,
148 Dart_WeakPersistentHandle handle, 111 Dart_WeakPersistentHandle handle,
149 void* context_pointer) { 112 void* context_pointer) {
150 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer); 113 SSLFilter* filter = reinterpret_cast<SSLFilter*>(context_pointer);
151 delete filter; 114 filter->Release();
152 } 115 }
153 116
154 117
155 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) { 118 static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter* filter) {
156 ASSERT(filter != NULL); 119 ASSERT(filter != NULL);
157 const int approximate_size_of_filter = 1500; 120 const int approximate_size_of_filter = 1500;
158 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); 121 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
159 RETURN_IF_ERROR(dart_this); 122 RETURN_IF_ERROR(dart_this);
160 ASSERT(Dart_IsInstance(dart_this)); 123 ASSERT(Dart_IsInstance(dart_this));
161 Dart_Handle err = Dart_SetNativeInstanceField( 124 Dart_Handle err = Dart_SetNativeInstanceField(
(...skipping 18 matching lines...) Expand all
180 kSecurityContextNativeFieldIndex, 143 kSecurityContextNativeFieldIndex,
181 reinterpret_cast<intptr_t*>(&context))); 144 reinterpret_cast<intptr_t*>(&context)));
182 return context; 145 return context;
183 } 146 }
184 147
185 148
186 static void DeleteCertContext(void* isolate_data, 149 static void DeleteCertContext(void* isolate_data,
187 Dart_WeakPersistentHandle handle, 150 Dart_WeakPersistentHandle handle,
188 void* context_pointer) { 151 void* context_pointer) {
189 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer); 152 SSLCertContext* context = static_cast<SSLCertContext*>(context_pointer);
190 delete context; 153 context->Release();
191 } 154 }
192 155
193 156
194 static Dart_Handle SetSecurityContext(Dart_NativeArguments args, 157 static Dart_Handle SetSecurityContext(Dart_NativeArguments args,
195 SSLCertContext* context) { 158 SSLCertContext* context) {
196 const int approximate_size_of_context = 1500; 159 const int approximate_size_of_context = 1500;
197 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0); 160 Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
198 RETURN_IF_ERROR(dart_this); 161 RETURN_IF_ERROR(dart_this);
199 ASSERT(Dart_IsInstance(dart_this)); 162 ASSERT(Dart_IsInstance(dart_this));
200 Dart_Handle err = Dart_SetNativeInstanceField( 163 Dart_Handle err = Dart_SetNativeInstanceField(
201 dart_this, 164 dart_this,
202 kSecurityContextNativeFieldIndex, 165 kSecurityContextNativeFieldIndex,
203 reinterpret_cast<intptr_t>(context)); 166 reinterpret_cast<intptr_t>(context));
204 RETURN_IF_ERROR(err); 167 RETURN_IF_ERROR(err);
205 Dart_NewWeakPersistentHandle(dart_this, 168 Dart_NewWeakPersistentHandle(dart_this,
206 context, 169 context,
207 approximate_size_of_context, 170 approximate_size_of_context,
208 DeleteCertContext); 171 DeleteCertContext);
209 return Dart_Null(); 172 return Dart_Null();
210 } 173 }
211 174
212 175
176 static SecCertificateRef GetX509Certificate(Dart_NativeArguments args) {
177 SecCertificateRef certificate;
178 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
179 ASSERT(Dart_IsInstance(dart_this));
180 ThrowIfError(Dart_GetNativeInstanceField(
181 dart_this,
182 kX509NativeFieldIndex,
183 reinterpret_cast<intptr_t*>(&certificate)));
184 return certificate;
185 }
186
187
213 static void ReleaseCertificate(void* isolate_data, 188 static void ReleaseCertificate(void* isolate_data,
214 Dart_WeakPersistentHandle handle, 189 Dart_WeakPersistentHandle handle,
215 void* context_pointer) { 190 void* context_pointer) {
216 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer); 191 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer);
217 CFRelease(cert); 192 CFRelease(cert);
218 } 193 }
219 194
220 195
221 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) { 196 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) {
222 const intptr_t approximate_size_of_certificate = 1500; 197 const intptr_t approximate_size_of_certificate = 1500;
(...skipping 26 matching lines...) Expand all
249 result, 224 result,
250 kX509NativeFieldIndex, 225 kX509NativeFieldIndex,
251 reinterpret_cast<intptr_t>(certificate)); 226 reinterpret_cast<intptr_t>(certificate));
252 if (Dart_IsError(status)) { 227 if (Dart_IsError(status)) {
253 return status; 228 return status;
254 } 229 }
255 return result; 230 return result;
256 } 231 }
257 232
258 233
234 static const char* GetPasswordArgument(Dart_NativeArguments args,
235 intptr_t index) {
236 Dart_Handle password_object =
237 ThrowIfError(Dart_GetNativeArgument(args, index));
238 const char* password = NULL;
239 if (Dart_IsString(password_object)) {
240 ThrowIfError(Dart_StringToCString(password_object, &password));
241 if (strlen(password) > PEM_BUFSIZE - 1) {
242 Dart_ThrowException(DartUtils::NewDartArgumentError(
243 "Password length is greater than 1023 bytes."));
244 }
245 } else if (Dart_IsNull(password_object)) {
246 password = "";
247 } else {
248 Dart_ThrowException(DartUtils::NewDartArgumentError(
249 "Password is not a String or null"));
250 }
251 return password;
252 }
253
254
255 static OSStatus TryPKCS12Import(CFDataRef cfdata,
256 CFStringRef password,
257 CFArrayRef* out_certs,
258 SecIdentityRef* out_identity) {
259 const void* keys[] = { kSecImportExportPassphrase };
260 const void* values[] = { password };
261 CFDictionaryRef params =
262 CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
263 CFArrayRef items = NULL;
264 OSStatus status = SecPKCS12Import(cfdata, params, &items);
265 CFRelease(params);
266
267 if (status != noErr) {
268 if (SSL_LOG_STATUS) {
269 Log::PrintErr("SecPKCS12Import: status = %ld",
270 static_cast<intptr_t>(status));
271 return status;
272 }
273 }
274
275 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items);
276 if (SSL_LOG_CERTS) {
277 Log::PrintErr("TryPKCS12Import succeeded, count = %ld\n", items_length);
278 }
279
280 // Empty list indicates a decoding failure of some sort.
281 if ((items != NULL) && (items_length == 0)) {
282 CFRelease(items);
283 return errSSLBadCert;
284 }
285
286 CFMutableArrayRef result_certs =
287 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
288 SecIdentityRef result_identity = NULL;
289
290 for (CFIndex i = 0; i < items_length; i++) {
291 CFTypeRef item =
292 reinterpret_cast<CFTypeRef>(CFArrayGetValueAtIndex(items, i));
293 ASSERT(CFGetTypeID(item) == CFDictionaryGetTypeID());
294 CFDictionaryRef dict = reinterpret_cast<CFDictionaryRef>(item);
295
296 // Trust.
297 CFTypeRef trust_item = CFDictionaryGetValue(dict, kSecImportItemTrust);
298 if (trust_item != NULL) {
299 ASSERT(CFGetTypeID(trust_item) == SecTrustGetTypeID());
300 if (SSL_LOG_CERTS) {
301 Log::PrintErr("\titem %ld has a trust object\n", i);
302 }
303 // TODO(zra): Is this useful for anything?
304 }
305
306 // Identity.
307 CFTypeRef identity_item =
308 CFDictionaryGetValue(dict, kSecImportItemIdentity);
309 if (identity_item != NULL) {
310 ASSERT(CFGetTypeID(identity_item) == SecIdentityGetTypeID());
311 if (SSL_LOG_CERTS) {
312 Log::PrintErr("\titem %ld has an identity object\n", i);
313 }
314 // Only extract the first identity we find.
315 if (result_identity == NULL) {
316 result_identity =
317 reinterpret_cast<SecIdentityRef>(const_cast<void*>(identity_item));
318 CFRetain(result_identity);
319 }
320 }
321
322 // Certificates.
323 CFTypeRef cert_items = CFDictionaryGetValue(dict, kSecImportItemCertChain);
324 if (cert_items != NULL) {
325 ASSERT(CFGetTypeID(cert_items) == CFArrayGetTypeID());
326 CFArrayRef certs = reinterpret_cast<CFArrayRef>(cert_items);
327 if (SSL_LOG_CERTS) {
328 CFIndex count = CFArrayGetCount(certs);
329 Log::PrintErr("\titem %ld has a cert chain %ld certs long\n", i, count);
330 }
331 CFArrayAppendArray(
332 result_certs, certs, CFRangeMake(0, CFArrayGetCount(certs)));
333 }
334 }
335
336 if (out_certs == NULL) {
337 if (result_certs != NULL) {
338 CFRelease(result_certs);
339 }
340 } else {
341 *out_certs = result_certs;
342 }
343
344 if (out_identity == NULL) {
345 if (result_identity != NULL) {
346 CFRelease(result_identity);
347 }
348 } else {
349 *out_identity = result_identity;
350 }
351
352 // On failure, don't return any objects.
353 ASSERT((status == noErr) ||
354 ((result_certs == NULL) && (result_identity == NULL)));
355 return status;
356 }
357
358
359 static OSStatus ExtractSecItems(uint8_t* buffer,
360 intptr_t length,
361 const char* password,
362 CFArrayRef* out_certs,
363 SecIdentityRef* out_identity) {
364 ASSERT(buffer != NULL);
365 ASSERT(password != NULL);
366 OSStatus status = noErr;
367
368 CFDataRef cfdata = CFDataCreateWithBytesNoCopy(
369 NULL, buffer, length, kCFAllocatorNull);
370 CFStringRef cfpassword = CFStringCreateWithCStringNoCopy(
371 NULL, password, kCFStringEncodingUTF8, kCFAllocatorNull);
372 ASSERT(cfdata != NULL);
373 ASSERT(cfpassword != NULL);
374
375 status = TryPKCS12Import(cfdata, cfpassword, out_certs, out_identity);
376
377 CFRelease(cfdata);
378 CFRelease(cfpassword);
379 return status;
380 }
381
382
259 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { 383 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) {
260 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 384 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
261 SSLFilter* filter = new SSLFilter(); // Deleted in DeleteFilter finalizer. 385 SSLFilter* filter = new SSLFilter(); // Deleted in DeleteFilter finalizer.
386 filter->Retain();
262 Dart_Handle err = SetFilter(args, filter); 387 Dart_Handle err = SetFilter(args, filter);
263 if (Dart_IsError(err)) { 388 if (Dart_IsError(err)) {
264 delete filter; 389 filter->Release();
265 Dart_PropagateError(err); 390 Dart_PropagateError(err);
266 } 391 }
267 err = filter->Init(dart_this); 392 err = filter->Init(dart_this);
268 if (Dart_IsError(err)) { 393 if (Dart_IsError(err)) {
269 // The finalizer was set up by SetFilter. It will delete `filter` if there 394 // The finalizer was set up by SetFilter. It will delete `filter` if there
270 // is an error. 395 // is an error.
271 filter->Destroy(); 396 filter->Destroy();
272 Dart_PropagateError(err); 397 Dart_PropagateError(err);
273 } 398 }
274 } 399 }
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 GetFilter(args)->RegisterBadCertificateCallback(callback); 490 GetFilter(args)->RegisterBadCertificateCallback(callback);
366 } 491 }
367 492
368 493
369 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) { 494 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) {
370 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); 495 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate());
371 } 496 }
372 497
373 498
374 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { 499 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
375 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); 500 SSLFilter* filter = GetFilter(args);
501 // This filter pointer is passed to the IO Service thread. The IO Service
502 // thread must Release() the pointer when it is done with it.
503 filter->Retain();
504 intptr_t filter_pointer = reinterpret_cast<intptr_t>(filter);
376 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); 505 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
377 } 506 }
378 507
379 508
380 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { 509 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
381 SSLCertContext* cert_context = new SSLCertContext(); 510 SSLCertContext* cert_context = new SSLCertContext();
511 cert_context->Retain();
382 // cert_context deleted in DeleteCertContext finalizer. 512 // cert_context deleted in DeleteCertContext finalizer.
383 Dart_Handle err = SetSecurityContext(args, cert_context); 513 Dart_Handle err = SetSecurityContext(args, cert_context);
384 if (Dart_IsError(err)) { 514 if (Dart_IsError(err)) {
385 delete cert_context; 515 cert_context->Release();
386 Dart_PropagateError(err); 516 Dart_PropagateError(err);
387 } 517 }
388 } 518 }
389 519
390 520
391 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( 521 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
392 Dart_NativeArguments args) { 522 Dart_NativeArguments args) {
393 Dart_ThrowException(DartUtils::NewDartUnsupportedError( 523 SSLCertContext* context = GetSecurityContext(args);
394 "SecurityContext.usePrivateKeyBytes is not yet implemented.")); 524 const char* password = GetPasswordArgument(args, 2);
525
526 OSStatus status;
527 CFArrayRef cert_chain = NULL;
528 SecIdentityRef identity = NULL;
529 {
530 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1)));
531 status = ExtractSecItems(
532 buffer.get(), buffer.length(), password, &cert_chain, &identity);
533 }
534
535 // Set the context fields. Repeated calls to usePrivateKeyBytes are an error.
536 bool set_failure = false;
537 if ((identity != NULL) && !context->set_identity(identity)) {
538 CFRelease(identity);
539 if (cert_chain != NULL) {
540 CFRelease(cert_chain);
541 }
542 set_failure = true;
543 }
544
545 // We can't have set a cert_chain without also having set an identity.
546 // That is, if context->set_identity() succeeds, then it is impossible for
547 // context->set_cert_chain() to fail. This is because SecPKCS12Import never
548 // returns a cert chain without also returning a private key.
549 ASSERT(set_failure || (context->cert_chain() == NULL));
550 if (!set_failure && (cert_chain != NULL)) {
551 context->set_cert_chain(cert_chain);
552 }
553
554 if (set_failure) {
555 Dart_ThrowException(DartUtils::NewDartArgumentError(
556 "usePrivateKeyBytes has already been called on the given context."));
557 }
558 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes");
395 } 559 }
396 560
397 561
398 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( 562 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
399 Dart_NativeArguments args) { 563 Dart_NativeArguments args) {
400 SSLCertContext* context = GetSecurityContext(args); 564 SSLCertContext* context = GetSecurityContext(args);
401 565
402 OSStatus status = noErr; 566 OSStatus status = noErr;
403 SecCertificateRef cert = NULL; 567 SecCertificateRef cert = NULL;
404 { 568 {
(...skipping 21 matching lines...) Expand all
426 590
427 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( 591 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
428 Dart_NativeArguments args) { 592 Dart_NativeArguments args) {
429 SSLCertContext* context = GetSecurityContext(args); 593 SSLCertContext* context = GetSecurityContext(args);
430 context->set_trust_builtin(true); 594 context->set_trust_builtin(true);
431 } 595 }
432 596
433 597
434 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( 598 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
435 Dart_NativeArguments args) { 599 Dart_NativeArguments args) {
436 Dart_ThrowException(DartUtils::NewDartUnsupportedError( 600 // This is a no-op on iOS. We get the cert chain along with the private key
437 "SecurityContext.useCertificateChainBytes is not yet implemented.")); 601 // in UsePrivateyKeyBytes().
438 } 602 }
439 603
440 604
441 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( 605 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
442 Dart_NativeArguments args) { 606 Dart_NativeArguments args) {
443 Dart_ThrowException(DartUtils::NewDartUnsupportedError( 607 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
444 "SecurityContext.setClientAuthoritiesBytes is not yet implemented.")); 608 "SecurityContext.setClientAuthoritiesBytes is not supported on this "
609 "platform."));
445 } 610 }
446 611
447 612
448 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( 613 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
449 Dart_NativeArguments args) { 614 Dart_NativeArguments args) {
450 Dart_ThrowException(DartUtils::NewDartUnsupportedError( 615 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
451 "ALPN is not supported on this platform")); 616 "ALPN is not supported on this platform"));
452 } 617 }
453 618
454 619
455 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) { 620 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
456 Dart_ThrowException(DartUtils::NewDartUnsupportedError( 621 SecCertificateRef certificate = GetX509Certificate(args);
457 "X509Certificate.subject is not yet implemented.")); 622 CFStringRef cfsubject = SecCertificateCopySubjectSummary(certificate);
623 if (cfsubject != NULL) {
624 char* csubject = CFStringRefToCString(cfsubject);
625 CFRelease(cfsubject);
626 Dart_SetReturnValue(args, Dart_NewStringFromCString(csubject));
627 } else {
628 Dart_ThrowException(DartUtils::NewDartArgumentError(
629 "X509.subject failed to find subject's common name."));
630 }
458 } 631 }
459 632
460 633
461 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) { 634 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) {
462 Dart_ThrowException(DartUtils::NewDartUnsupportedError( 635 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
463 "X509Certificate.issuer is not supported on this platform.")); 636 "X509Certificate.issuer is not supported on this platform."));
464 } 637 }
465 638
466 639
467 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { 640 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) {
(...skipping 23 matching lines...) Expand all
491 // end for output buffers. Therefore, the Dart thread can simultaneously 664 // end for output buffers. Therefore, the Dart thread can simultaneously
492 // write to the free space and end pointer of input buffers, and read from 665 // write to the free space and end pointer of input buffers, and read from
493 // the data space of output buffers, and modify the start pointer. 666 // the data space of output buffers, and modify the start pointer.
494 // 667 //
495 // When ProcessFilter returns, the Dart thread is responsible for combining 668 // When ProcessFilter returns, the Dart thread is responsible for combining
496 // the updated pointers from Dart and C++, to make the new valid state of 669 // the updated pointers from Dart and C++, to make the new valid state of
497 // the circular buffer. 670 // the circular buffer.
498 CObject* SSLFilter::ProcessFilterRequest(const CObjectArray& request) { 671 CObject* SSLFilter::ProcessFilterRequest(const CObjectArray& request) {
499 CObjectIntptr filter_object(request[0]); 672 CObjectIntptr filter_object(request[0]);
500 SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value()); 673 SSLFilter* filter = reinterpret_cast<SSLFilter*>(filter_object.Value());
674 RefCntReleaseScope<SSLFilter> rs(filter);
675
501 bool in_handshake = CObjectBool(request[1]).Value(); 676 bool in_handshake = CObjectBool(request[1]).Value();
502 intptr_t starts[SSLFilter::kNumBuffers]; 677 intptr_t starts[SSLFilter::kNumBuffers];
503 intptr_t ends[SSLFilter::kNumBuffers]; 678 intptr_t ends[SSLFilter::kNumBuffers];
504 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { 679 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) {
505 starts[i] = CObjectInt32(request[2 * i + 2]).Value(); 680 starts[i] = CObjectInt32(request[2 * i + 2]).Value();
506 ends[i] = CObjectInt32(request[2 * i + 3]).Value(); 681 ends[i] = CObjectInt32(request[2 * i + 3]).Value();
507 } 682 }
508 683
509 OSStatus status = filter->ProcessAllBuffers(starts, ends, in_handshake); 684 OSStatus status = filter->ProcessAllBuffers(starts, ends, in_handshake);
510 if (status == noErr) { 685 if (status == noErr) {
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 ssl_context, kSSLSessionOptionBreakOnServerAuth, true); 1032 ssl_context, kSSLSessionOptionBreakOnServerAuth, true);
858 CheckStatus(status, 1033 CheckStatus(status,
859 "TlsException", 1034 "TlsException",
860 "Failed to set BreakOnServerAuth option"); 1035 "Failed to set BreakOnServerAuth option");
861 1036
862 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1); 1037 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1);
863 CheckStatus(status, 1038 CheckStatus(status,
864 "TlsException", 1039 "TlsException",
865 "Failed to set minimum protocol version to kTLSProtocol1"); 1040 "Failed to set minimum protocol version to kTLSProtocol1");
866 1041
1042 // If the context has an identity pass it to SSLSetCertificate().
1043 if (context->identity() != NULL) {
1044 CFMutableArrayRef chain =
1045 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
1046 CFArrayAppendValue(chain, context->identity());
1047
1048 // Append the certificate chain if there is one.
1049 if (context->cert_chain() != NULL) {
1050 // Skip the first one, it's already included in the identity.
1051 CFIndex chain_length = CFArrayGetCount(context->cert_chain());
1052 if (chain_length > 1) {
1053 CFArrayAppendArray(
1054 chain, context->cert_chain(), CFRangeMake(1, chain_length));
1055 }
1056 }
1057
1058 status = SSLSetCertificate(ssl_context, chain);
1059 CFRelease(chain);
1060 CheckStatus(status, "TlsException", "SSLSetCertificate failed");
1061 }
1062
867 if (is_server) { 1063 if (is_server) {
868 SSLAuthenticate auth = 1064 SSLAuthenticate auth =
869 require_client_certificate 1065 require_client_certificate
870 ? kAlwaysAuthenticate 1066 ? kAlwaysAuthenticate
871 : (request_client_certificate ? kTryAuthenticate : kNeverAuthenticate); 1067 : (request_client_certificate ? kTryAuthenticate : kNeverAuthenticate);
872 status = SSLSetClientSideAuthenticate(ssl_context, auth); 1068 status = SSLSetClientSideAuthenticate(ssl_context, auth);
873 CheckStatus(status, 1069 CheckStatus(status,
874 "TlsException", 1070 "TlsException",
875 "Failed to set client authentication mode"); 1071 "Failed to set client authentication mode");
876 1072
877 // If we're at least trying client authentication, then break handshake 1073 // If we're at least trying client authentication, then break handshake
878 // for client authentication. 1074 // for client authentication.
879 if (auth != kNeverAuthenticate) { 1075 if (auth != kNeverAuthenticate) {
880 status = SSLSetSessionOption( 1076 status = SSLSetSessionOption(
881 ssl_context, kSSLSessionOptionBreakOnClientAuth, true); 1077 ssl_context, kSSLSessionOptionBreakOnClientAuth, true);
882 CheckStatus(status, 1078 CheckStatus(status,
883 "TlsException", 1079 "TlsException",
884 "Failed to set client authentication mode"); 1080 "Failed to set client authentication mode");
885 } 1081 }
886 } 1082 }
887 1083
888 // Add the contexts to our wrapper. 1084 // Add the contexts to our wrapper.
889 cert_context_ = context; 1085 cert_context_.set(context);
890 ssl_context_ = ssl_context; 1086 ssl_context_ = ssl_context;
891 is_server_ = is_server; 1087 is_server_ = is_server;
892 1088
893 // Kick-off the handshake. Expect the handshake to need more data. 1089 // Kick-off the handshake. Expect the handshake to need more data.
894 // SSLHandshake calls our SSLReadCallback and SSLWriteCallback. 1090 // SSLHandshake calls our SSLReadCallback and SSLWriteCallback.
895 status = SSLHandshake(ssl_context); 1091 status = SSLHandshake(ssl_context);
896 ASSERT(status != noErr); 1092 ASSERT(status != noErr);
897 if (status == errSSLWouldBlock) { 1093 if (status == errSSLWouldBlock) {
898 status = noErr; 1094 status = noErr;
899 in_handshake_ = true; 1095 in_handshake_ = true;
900 } 1096 }
901 CheckStatus(status, 1097 CheckStatus(status,
902 "HandshakeException", 1098 "HandshakeException",
903 is_server_ ? "Handshake error in server" : "Handshake error in client"); 1099 is_server_ ? "Handshake error in server" : "Handshake error in client");
904 } 1100 }
905 1101
906 1102
907 OSStatus SSLFilter::EvaluatePeerTrust() { 1103 OSStatus SSLFilter::EvaluatePeerTrust() {
908 OSStatus status = noErr; 1104 OSStatus status = noErr;
909 1105
910 if (SSL_LOG_STATUS) { 1106 if (SSL_LOG_STATUS) {
911 Log::Print("Handshake evaluating trust.\n"); 1107 Log::PrintErr("Handshake evaluating trust.\n");
912 } 1108 }
913 SecTrustRef peer_trust = NULL; 1109 SecTrustRef peer_trust = NULL;
914 status = SSLCopyPeerTrust(ssl_context_, &peer_trust); 1110 status = SSLCopyPeerTrust(ssl_context_, &peer_trust);
915 if (status != noErr) { 1111 if (status != noErr) {
916 if (is_server_ && (status == errSSLBadCert)) { 1112 if (is_server_ && (status == errSSLBadCert)) {
917 // A client certificate was requested, but not required, and wasn't sent. 1113 // A client certificate was requested, but not required, and wasn't sent.
918 return noErr; 1114 return noErr;
919 } 1115 }
920 if (SSL_LOG_STATUS) { 1116 if (SSL_LOG_STATUS) {
921 Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n", 1117 Log::PrintErr("Handshake error from SSLCopyPeerTrust(): %ld.\n",
922 static_cast<intptr_t>(status)); 1118 static_cast<intptr_t>(status));
923 } 1119 }
924 return status; 1120 return status;
925 } 1121 }
926 1122
927 CFArrayRef trusted_certs = NULL; 1123 CFArrayRef trusted_certs = NULL;
928 if (cert_context_->trusted_certs() != NULL) { 1124 if (cert_context_.get()->trusted_certs() != NULL) {
929 trusted_certs = CFArrayCreateCopy(NULL, cert_context_->trusted_certs()); 1125 trusted_certs =
1126 CFArrayCreateCopy(NULL, cert_context_.get()->trusted_certs());
930 } else { 1127 } else {
931 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks); 1128 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
932 } 1129 }
933 1130
934 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); 1131 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs);
935 if (status != noErr) { 1132 if (status != noErr) {
936 if (SSL_LOG_STATUS) { 1133 if (SSL_LOG_STATUS) {
937 Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n", 1134 Log::PrintErr("Handshake error from SecTrustSetAnchorCertificates: %ld\n",
938 static_cast<intptr_t>(status)); 1135 static_cast<intptr_t>(status));
939 } 1136 }
940 CFRelease(trusted_certs); 1137 CFRelease(trusted_certs);
941 CFRelease(peer_trust); 1138 CFRelease(peer_trust);
942 return status; 1139 return status;
943 } 1140 }
944 1141
945 if (SSL_LOG_STATUS) { 1142 if (SSL_LOG_STATUS) {
946 Log::Print("Handshake %s built in root certs\n", 1143 Log::PrintErr("Handshake %s built in root certs\n",
947 cert_context_->trust_builtin() ? "trusting" : "not trusting"); 1144 cert_context_.get()->trust_builtin() ? "trusting" : "not trusting");
948 } 1145 }
949 1146
950 status = SecTrustSetAnchorCertificatesOnly( 1147 status = SecTrustSetAnchorCertificatesOnly(
951 peer_trust, !cert_context_->trust_builtin()); 1148 peer_trust, !cert_context_.get()->trust_builtin());
952 if (status != noErr) { 1149 if (status != noErr) {
953 CFRelease(trusted_certs); 1150 CFRelease(trusted_certs);
954 CFRelease(peer_trust); 1151 CFRelease(peer_trust);
955 return status; 1152 return status;
956 } 1153 }
957 1154
958 SecTrustResultType trust_result; 1155 SecTrustResultType trust_result;
959 status = SecTrustEvaluate(peer_trust, &trust_result); 1156 status = SecTrustEvaluate(peer_trust, &trust_result);
960 if (status != noErr) { 1157 if (status != noErr) {
961 CFRelease(trusted_certs); 1158 CFRelease(trusted_certs);
(...skipping 13 matching lines...) Expand all
975 1172
976 CFRelease(trusted_certs); 1173 CFRelease(trusted_certs);
977 CFRelease(peer_trust); 1174 CFRelease(peer_trust);
978 1175
979 if ((trust_result == kSecTrustResultProceed) || 1176 if ((trust_result == kSecTrustResultProceed) ||
980 (trust_result == kSecTrustResultUnspecified)) { 1177 (trust_result == kSecTrustResultUnspecified)) {
981 // Trusted. 1178 // Trusted.
982 return noErr; 1179 return noErr;
983 } else { 1180 } else {
984 if (SSL_LOG_STATUS) { 1181 if (SSL_LOG_STATUS) {
985 Log::Print("Trust eval failed: trust_restul = %d\n", trust_result); 1182 Log::PrintErr("Trust eval failed: trust_result = %d\n", trust_result);
986 } 1183 }
987 bad_cert_ = true; 1184 bad_cert_ = true;
988 return errSSLBadCert; 1185 return errSSLBadCert;
989 } 1186 }
990 } 1187 }
991 1188
992 1189
993 OSStatus SSLFilter::Handshake() { 1190 OSStatus SSLFilter::Handshake() {
994 ASSERT(cert_context_ != NULL); 1191 ASSERT(cert_context_.get() != NULL);
995 ASSERT(ssl_context_ != NULL); 1192 ASSERT(ssl_context_ != NULL);
996 // Try and push handshake along. 1193 // Try and push handshake along.
997 if (SSL_LOG_STATUS) { 1194 if (SSL_LOG_STATUS) {
998 Log::Print("Doing SSLHandshake\n"); 1195 Log::PrintErr("Doing SSLHandshake\n");
999 } 1196 }
1000 OSStatus status = SSLHandshake(ssl_context_); 1197 OSStatus status = SSLHandshake(ssl_context_);
1001 if (SSL_LOG_STATUS) { 1198 if (SSL_LOG_STATUS) {
1002 Log::Print("SSLHandshake returned %ld\n", static_cast<intptr_t>(status)); 1199 Log::PrintErr("SSLHandshake returned %ld\n", static_cast<intptr_t>(status));
1003 } 1200 }
1004 1201
1005 if ((status == errSSLServerAuthCompleted) || 1202 if ((status == errSSLServerAuthCompleted) ||
1006 (status == errSSLClientAuthCompleted)) { 1203 (status == errSSLClientAuthCompleted)) {
1007 status = EvaluatePeerTrust(); 1204 status = EvaluatePeerTrust();
1008 if (status == errSSLBadCert) { 1205 if (status == errSSLBadCert) {
1009 // Need to invoke the bad certificate callback. 1206 // Need to invoke the bad certificate callback.
1010 return noErr; 1207 return noErr;
1011 } else if (status != noErr) { 1208 } else if (status != noErr) {
1012 return status; 1209 return status;
1013 } 1210 }
1014 // When trust evaluation succeeds, we can call SSLHandshake again 1211 // When trust evaluation succeeds, we can call SSLHandshake again
1015 // immediately. 1212 // immediately.
1016 status = SSLHandshake(ssl_context_); 1213 status = SSLHandshake(ssl_context_);
1017 } 1214 }
1018 1215
1019 if (status == errSSLWouldBlock) { 1216 if (status == errSSLWouldBlock) {
1020 in_handshake_ = true; 1217 in_handshake_ = true;
1021 return noErr; 1218 return noErr;
1022 } 1219 }
1023 1220
1024 // Handshake succeeded. 1221 // Handshake succeeded.
1025 if ((in_handshake_) && (status == noErr)) { 1222 if ((in_handshake_) && (status == noErr)) {
1026 if (SSL_LOG_STATUS) { 1223 if (SSL_LOG_STATUS) {
1027 Log::Print("Finished with the Handshake\n"); 1224 Log::PrintErr("Finished with the Handshake\n");
1028 } 1225 }
1029 connected_ = true; 1226 connected_ = true;
1030 } 1227 }
1031 return status; 1228 return status;
1032 } 1229 }
1033 1230
1034 1231
1035 // Returns false if Handshake should fail, and true if Handshake should 1232 // Returns false if Handshake should fail, and true if Handshake should
1036 // proceed. 1233 // proceed.
1037 Dart_Handle SSLFilter::InvokeBadCertCallback(SecCertificateRef peer_cert) { 1234 Dart_Handle SSLFilter::InvokeBadCertCallback(SecCertificateRef peer_cert) {
(...skipping 13 matching lines...) Expand all
1051 "BadCertificateCallback returned a value that was not a boolean", 1248 "BadCertificateCallback returned a value that was not a boolean",
1052 Dart_Null())); 1249 Dart_Null()));
1053 } 1250 }
1054 return result; 1251 return result;
1055 } 1252 }
1056 1253
1057 1254
1058 OSStatus SSLFilter::CheckHandshake() { 1255 OSStatus SSLFilter::CheckHandshake() {
1059 if (bad_cert_ && in_handshake_) { 1256 if (bad_cert_ && in_handshake_) {
1060 if (SSL_LOG_STATUS) { 1257 if (SSL_LOG_STATUS) {
1061 Log::Print("Invoking bad certificate callback\n"); 1258 Log::PrintErr("Invoking bad certificate callback\n");
1062 } 1259 }
1063 ASSERT(peer_certs_ != NULL); 1260 ASSERT(peer_certs_ != NULL);
1064 CFIndex peer_certs_len = CFArrayGetCount(peer_certs_); 1261 CFIndex peer_certs_len = CFArrayGetCount(peer_certs_);
1065 ASSERT(peer_certs_len > 0); 1262 ASSERT(peer_certs_len > 0);
1066 CFTypeRef item = CFArrayGetValueAtIndex(peer_certs_, peer_certs_len - 1); 1263 CFTypeRef item = CFArrayGetValueAtIndex(peer_certs_, peer_certs_len - 1);
1067 ASSERT(item != NULL); 1264 ASSERT(item != NULL);
1068 ASSERT(CFGetTypeID(item) == SecCertificateGetTypeID()); 1265 ASSERT(CFGetTypeID(item) == SecCertificateGetTypeID());
1069 SecCertificateRef peer_cert = 1266 SecCertificateRef peer_cert =
1070 reinterpret_cast<SecCertificateRef>(const_cast<void*>(item)); 1267 reinterpret_cast<SecCertificateRef>(const_cast<void*>(item));
1071 Dart_Handle result = InvokeBadCertCallback(peer_cert); 1268 Dart_Handle result = InvokeBadCertCallback(peer_cert);
1072 ThrowIfError(result); 1269 ThrowIfError(result);
1073 if (Dart_IsNull(result)) { 1270 if (Dart_IsNull(result)) {
1074 return errSSLBadCert; 1271 return errSSLBadCert;
1075 } else { 1272 } else {
1076 bool good_cert = DartUtils::GetBooleanValue(result); 1273 bool good_cert = DartUtils::GetBooleanValue(result);
1077 bad_cert_ = !good_cert; 1274 bad_cert_ = !good_cert;
1078 return good_cert ? noErr : errSSLBadCert; 1275 return good_cert ? noErr : errSSLBadCert;
1079 } 1276 }
1080 } 1277 }
1081 1278
1082 if (connected_ && in_handshake_) { 1279 if (connected_ && in_handshake_) {
1083 if (SSL_LOG_STATUS) { 1280 if (SSL_LOG_STATUS) {
1084 Log::Print("Invoking handshake complete callback\n"); 1281 Log::PrintErr("Invoking handshake complete callback\n");
1085 } 1282 }
1086 ThrowIfError(Dart_InvokeClosure( 1283 ThrowIfError(Dart_InvokeClosure(
1087 Dart_HandleFromPersistent(handshake_complete_), 0, NULL)); 1284 Dart_HandleFromPersistent(handshake_complete_), 0, NULL));
1088 in_handshake_ = false; 1285 in_handshake_ = false;
1089 } 1286 }
1090 return noErr; 1287 return noErr;
1091 } 1288 }
1092 1289
1093 1290
1094 void SSLFilter::Renegotiate(bool use_session_cache, 1291 void SSLFilter::Renegotiate(bool use_session_cache,
1095 bool request_client_certificate, 1292 bool request_client_certificate,
1096 bool require_client_certificate) { 1293 bool require_client_certificate) {
1097 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the 1294 // The SSL_REQUIRE_CERTIFICATE option only takes effect if the
1098 // SSL_REQUEST_CERTIFICATE option is also set, so set it. 1295 // SSL_REQUEST_CERTIFICATE option is also set, so set it.
1099 request_client_certificate = 1296 request_client_certificate =
1100 request_client_certificate || require_client_certificate; 1297 request_client_certificate || require_client_certificate;
1101 // TODO(24070, 24069): Implement setting the client certificate parameters, 1298 // TODO(24070, 24069): Implement setting the client certificate parameters,
1102 // and triggering rehandshake. 1299 // and triggering rehandshake.
1103 } 1300 }
1104 1301
1105 1302
1106 SSLFilter::~SSLFilter() { 1303 SSLFilter::~SSLFilter() {
1107 // cert_context_ deleted by finalizer. Don't delete here.
1108 cert_context_ = NULL;
1109 if (ssl_context_ != NULL) { 1304 if (ssl_context_ != NULL) {
1110 CFRelease(ssl_context_); 1305 CFRelease(ssl_context_);
1111 ssl_context_ = NULL; 1306 ssl_context_ = NULL;
1112 } 1307 }
1113 if (peer_certs_ != NULL) { 1308 if (peer_certs_ != NULL) {
1114 CFRelease(peer_certs_); 1309 CFRelease(peer_certs_);
1115 peer_certs_ = NULL; 1310 peer_certs_ = NULL;
1116 } 1311 }
1117 if (hostname_ != NULL) { 1312 if (hostname_ != NULL) {
1118 free(hostname_); 1313 free(hostname_);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 intptr_t bytes = requested < available ? requested : available; 1390 intptr_t bytes = requested < available ? requested : available;
1196 memmove(datap, &buffer[start], bytes); 1391 memmove(datap, &buffer[start], bytes);
1197 start += bytes; 1392 start += bytes;
1198 datap += bytes; 1393 datap += bytes;
1199 data_read += bytes; 1394 data_read += bytes;
1200 requested -= bytes; 1395 requested -= bytes;
1201 ASSERT(start <= end); 1396 ASSERT(start <= end);
1202 } 1397 }
1203 1398
1204 if (SSL_LOG_DATA) { 1399 if (SSL_LOG_DATA) {
1205 Log::Print("SSLReadCallback: requested: %ld, read %ld bytes\n", 1400 Log::PrintErr("SSLReadCallback: requested: %ld, read %ld bytes\n",
1206 *data_requested, data_read); 1401 *data_requested, data_read);
1207 } 1402 }
1208 1403
1209 filter->SetBufferStart(kReadEncrypted, start); 1404 filter->SetBufferStart(kReadEncrypted, start);
1210 bool short_read = data_read < static_cast<intptr_t>(*data_requested); 1405 bool short_read = data_read < static_cast<intptr_t>(*data_requested);
1211 *data_requested = data_read; 1406 *data_requested = data_read;
1212 return short_read ? errSSLWouldBlock : noErr; 1407 return short_read ? errSSLWouldBlock : noErr;
1213 } 1408 }
1214 1409
1215 1410
1216 // Read decrypted data from the filter to the circular buffer. 1411 // Read decrypted data from the filter to the circular buffer.
1217 OSStatus SSLFilter::ProcessReadPlaintextBuffer(intptr_t start, 1412 OSStatus SSLFilter::ProcessReadPlaintextBuffer(intptr_t start,
1218 intptr_t end, 1413 intptr_t end,
1219 intptr_t* bytes_processed) { 1414 intptr_t* bytes_processed) {
1220 ASSERT(bytes_processed != NULL); 1415 ASSERT(bytes_processed != NULL);
1221 intptr_t length = end - start; 1416 intptr_t length = end - start;
1222 OSStatus status = noErr; 1417 OSStatus status = noErr;
1223 size_t bytes = 0; 1418 size_t bytes = 0;
1224 if (length > 0) { 1419 if (length > 0) {
1225 status = SSLRead( 1420 status = SSLRead(
1226 ssl_context_, 1421 ssl_context_,
1227 reinterpret_cast<void*>((buffers_[kReadPlaintext] + start)), 1422 reinterpret_cast<void*>((buffers_[kReadPlaintext] + start)),
1228 length, 1423 length,
1229 &bytes); 1424 &bytes);
1230 if (SSL_LOG_STATUS) { 1425 if (SSL_LOG_STATUS) {
1231 Log::Print("SSLRead: status = %ld\n", static_cast<intptr_t>(status)); 1426 Log::PrintErr("SSLRead: status = %ld\n", static_cast<intptr_t>(status));
1232 } 1427 }
1233 if ((status != noErr) && (status != errSSLWouldBlock)) { 1428 if ((status != noErr) && (status != errSSLWouldBlock)) {
1234 *bytes_processed = 0; 1429 *bytes_processed = 0;
1235 return status; 1430 return status;
1236 } 1431 }
1237 } 1432 }
1238 if (SSL_LOG_DATA) { 1433 if (SSL_LOG_DATA) {
1239 Log::Print("ProcessReadPlaintextBuffer: requested: %ld, read %ld bytes\n", 1434 Log::PrintErr(
1435 "ProcessReadPlaintextBuffer: requested: %ld, read %ld bytes\n",
1240 length, bytes); 1436 length, bytes);
1241 } 1437 }
1242 *bytes_processed = static_cast<intptr_t>(bytes); 1438 *bytes_processed = static_cast<intptr_t>(bytes);
1243 return status; 1439 return status;
1244 } 1440 }
1245 1441
1246 1442
1247 OSStatus SSLFilter::SSLWriteCallback(SSLConnectionRef connection, 1443 OSStatus SSLFilter::SSLWriteCallback(SSLConnectionRef connection,
1248 const void* data, size_t* data_provided) { 1444 const void* data, size_t* data_provided) {
1249 // Copy at most `data_provided` bytes from data into 1445 // Copy at most `data_provided` bytes from data into
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 intptr_t bytes = provided < available ? provided : available; 1482 intptr_t bytes = provided < available ? provided : available;
1287 memmove(&buffer[end], datap, bytes); 1483 memmove(&buffer[end], datap, bytes);
1288 end += bytes; 1484 end += bytes;
1289 datap += bytes; 1485 datap += bytes;
1290 data_written += bytes; 1486 data_written += bytes;
1291 provided -= bytes; 1487 provided -= bytes;
1292 ASSERT(end < start); 1488 ASSERT(end < start);
1293 } 1489 }
1294 1490
1295 if (SSL_LOG_DATA) { 1491 if (SSL_LOG_DATA) {
1296 Log::Print("SSLWriteCallback: provided: %ld, written %ld bytes\n", 1492 Log::PrintErr("SSLWriteCallback: provided: %ld, written %ld bytes\n",
1297 *data_provided, data_written); 1493 *data_provided, data_written);
1298 } 1494 }
1299 1495
1300 filter->SetBufferEnd(kWriteEncrypted, end); 1496 filter->SetBufferEnd(kWriteEncrypted, end);
1301 *data_provided = data_written; 1497 *data_provided = data_written;
1302 return (data_written == 0) ? errSSLWouldBlock : noErr; 1498 return (data_written == 0) ? errSSLWouldBlock : noErr;
1303 } 1499 }
1304 1500
1305 1501
1306 OSStatus SSLFilter::ProcessWritePlaintextBuffer(intptr_t start, 1502 OSStatus SSLFilter::ProcessWritePlaintextBuffer(intptr_t start,
1307 intptr_t end, 1503 intptr_t end,
1308 intptr_t* bytes_processed) { 1504 intptr_t* bytes_processed) {
1309 ASSERT(bytes_processed != NULL); 1505 ASSERT(bytes_processed != NULL);
1310 intptr_t length = end - start; 1506 intptr_t length = end - start;
1311 OSStatus status = noErr; 1507 OSStatus status = noErr;
1312 size_t bytes = 0; 1508 size_t bytes = 0;
1313 if (length > 0) { 1509 if (length > 0) {
1314 status = SSLWrite( 1510 status = SSLWrite(
1315 ssl_context_, 1511 ssl_context_,
1316 reinterpret_cast<void*>(buffers_[kWritePlaintext] + start), 1512 reinterpret_cast<void*>(buffers_[kWritePlaintext] + start),
1317 length, 1513 length,
1318 &bytes); 1514 &bytes);
1319 if (SSL_LOG_STATUS) { 1515 if (SSL_LOG_STATUS) {
1320 Log::Print("SSLWrite: status = %ld\n", static_cast<intptr_t>(status)); 1516 Log::PrintErr("SSLWrite: status = %ld\n", static_cast<intptr_t>(status));
1321 } 1517 }
1322 if ((status != noErr) && (status != errSSLWouldBlock)) { 1518 if ((status != noErr) && (status != errSSLWouldBlock)) {
1323 *bytes_processed = 0; 1519 *bytes_processed = 0;
1324 return status; 1520 return status;
1325 } 1521 }
1326 } 1522 }
1327 if (SSL_LOG_DATA) { 1523 if (SSL_LOG_DATA) {
1328 Log::Print("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n", 1524 Log::PrintErr("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n",
1329 length, bytes); 1525 length, bytes);
1330 } 1526 }
1331 *bytes_processed = static_cast<intptr_t>(bytes); 1527 *bytes_processed = static_cast<intptr_t>(bytes);
1332 return status; 1528 return status;
1333 } 1529 }
1334 1530
1335 } // namespace bin 1531 } // namespace bin
1336 } // namespace dart 1532 } // namespace dart
1337 1533
1338 #endif // TARGET_OS_IOS 1534 #endif // TARGET_OS_IOS
1339 1535
1340 #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED) 1536 #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698