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

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

Issue 1839123003: Begin work on ios secure sockets (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Add comment 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
« no previous file with comments | « runtime/bin/platform_macos.cc ('k') | runtime/bin/secure_socket_macos.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 defined(TARGET_OS_MACOS) 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_macos.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>
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 55
56 namespace dart { 56 namespace dart {
57 namespace bin { 57 namespace bin {
58 58
59 static const int kSSLFilterNativeFieldIndex = 0; 59 static const int kSSLFilterNativeFieldIndex = 0;
60 static const int kSecurityContextNativeFieldIndex = 0; 60 static const int kSecurityContextNativeFieldIndex = 0;
61 static const int kX509NativeFieldIndex = 0; 61 static const int kX509NativeFieldIndex = 0;
62 62
63 static const bool SSL_LOG_STATUS = false; 63 static const bool SSL_LOG_STATUS = false;
64 static const bool SSL_LOG_DATA = false; 64 static const bool SSL_LOG_DATA = false;
65 static const bool SSL_LOG_CERTS = false;
66 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000; 65 static const int SSL_ERROR_MESSAGE_BUFFER_SIZE = 1000;
67 static const intptr_t PEM_BUFSIZE = 1024;
68 66
69 // SSLCertContext wraps the certificates needed for a SecureTransport 67 // SSLCertContext wraps the certificates needed for a SecureTransport
70 // connection. Fields are protected by the mutex_ field, and may only be set 68 // connection. Fields are protected by the mutex_ field, and may only be set
71 // once. This is to allow access by both the Dart thread and the IOService 69 // once. This is to allow access by both the Dart thread and the IOService
72 // thread. Setters return false if the field was already set. 70 // thread. Setters return false if the field was already set.
73 class SSLCertContext { 71 class SSLCertContext {
74 public: 72 public:
75 SSLCertContext() : 73 SSLCertContext() :
76 mutex_(new Mutex()), 74 mutex_(new Mutex()),
77 private_key_(NULL),
78 keychain_(NULL),
79 cert_chain_(NULL),
80 trusted_certs_(NULL),
81 cert_authorities_(NULL),
82 trust_builtin_(false) {} 75 trust_builtin_(false) {}
83 76
84 ~SSLCertContext() { 77 ~SSLCertContext() {
85 if (private_key_ != NULL) {
86 CFRelease(private_key_);
87 }
88 if (keychain_ != NULL) {
89 SecKeychainDelete(keychain_);
90 CFRelease(keychain_);
91 }
92 if (cert_chain_ != NULL) {
93 CFRelease(cert_chain_);
94 }
95 if (trusted_certs_ != NULL) {
96 CFRelease(trusted_certs_);
97 }
98 if (cert_authorities_ != NULL) {
99 CFRelease(cert_authorities_);
100 }
101 delete mutex_; 78 delete mutex_;
102 } 79 }
103 80
104 SecKeyRef private_key() {
105 MutexLocker m(mutex_);
106 return private_key_;
107 }
108 bool set_private_key(SecKeyRef private_key) {
109 MutexLocker m(mutex_);
110 if (private_key_ != NULL) {
111 return false;
112 }
113 private_key_ = private_key;
114 return true;
115 }
116
117 SecKeychainRef keychain() {
118 MutexLocker m(mutex_);
119 return keychain_;
120 }
121 bool set_keychain(SecKeychainRef keychain) {
122 MutexLocker m(mutex_);
123 if (keychain_ != NULL) {
124 return false;
125 }
126 keychain_ = keychain;
127 return true;
128 }
129
130 CFArrayRef cert_chain() {
131 MutexLocker m(mutex_);
132 return cert_chain_;
133 }
134 bool set_cert_chain(CFArrayRef cert_chain) {
135 MutexLocker m(mutex_);
136 if (cert_chain_ != NULL) {
137 return false;
138 }
139 cert_chain_ = cert_chain;
140 return true;
141 }
142
143 CFArrayRef trusted_certs() {
144 MutexLocker m(mutex_);
145 return trusted_certs_;
146 }
147 bool set_trusted_certs(CFArrayRef trusted_certs) {
148 MutexLocker m(mutex_);
149 if (trusted_certs_ != NULL) {
150 return false;
151 }
152 trusted_certs_ = trusted_certs;
153 return true;
154 }
155
156 CFArrayRef cert_authorities() {
157 MutexLocker m(mutex_);
158 return cert_authorities_;
159 }
160 bool set_cert_authorities(CFArrayRef cert_authorities) {
161 MutexLocker m(mutex_);
162 if (cert_authorities_ != NULL) {
163 return false;
164 }
165 cert_authorities_ = cert_authorities;
166 return true;
167 }
168
169 bool trust_builtin() { 81 bool trust_builtin() {
170 MutexLocker m(mutex_); 82 MutexLocker m(mutex_);
171 return trust_builtin_; 83 return trust_builtin_;
172 } 84 }
173 void set_trust_builtin(bool trust_builtin) { 85 void set_trust_builtin(bool trust_builtin) {
174 MutexLocker m(mutex_); 86 MutexLocker m(mutex_);
175 trust_builtin_ = trust_builtin; 87 trust_builtin_ = trust_builtin;
176 } 88 }
177 89
178 private: 90 private:
179 // The context is accessed both by Dart code and the IOService. This mutex 91 // The context is accessed both by Dart code and the IOService. This mutex
180 // protects all fields. 92 // protects all fields.
181 Mutex* mutex_; 93 Mutex* mutex_;
182
183 SecKeyRef private_key_;
184 SecKeychainRef keychain_;
185
186 // CFArrays of SecCertificateRef.
187 CFArrayRef cert_chain_;
188 CFArrayRef trusted_certs_;
189 CFArrayRef cert_authorities_;
190
191 bool trust_builtin_; 94 bool trust_builtin_;
192 95
193 DISALLOW_COPY_AND_ASSIGN(SSLCertContext); 96 DISALLOW_COPY_AND_ASSIGN(SSLCertContext);
194 }; 97 };
195 98
196
197 static char* CFStringRefToCString(CFStringRef cfstring) {
198 CFIndex len = CFStringGetLength(cfstring);
199 CFIndex max_len =
200 CFStringGetMaximumSizeForEncoding(len, kCFStringEncodingUTF8) + 1;
201 char* result = reinterpret_cast<char*>(Dart_ScopeAllocate(max_len));
202 ASSERT(result != NULL);
203 bool success =
204 CFStringGetCString(cfstring, result, max_len, kCFStringEncodingUTF8);
205 return success ? result : NULL;
206 }
207
208
209 // Handle an error reported from the SecureTransport library. 99 // Handle an error reported from the SecureTransport library.
210 static void ThrowIOException(OSStatus status, 100 static void ThrowIOException(OSStatus status,
211 const char* exception_type, 101 const char* exception_type,
212 const char* message) { 102 const char* message) {
213 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); 103 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE);
214 CFStringRef error_string = SecCopyErrorMessageString(status, NULL); 104 status_message.Printf("OSStatus = %ld: https://www.osstatus.com",
215 if (error_string == NULL) { 105 static_cast<intptr_t>(status));
216 status_message.Printf("OSStatus = %ld: https://www.osstatus.com",
217 static_cast<intptr_t>(status));
218 } else {
219 char* error = CFStringRefToCString(error_string);
220 status_message.Printf("OSStatus = %ld: %s",
221 static_cast<intptr_t>(status), error);
222 CFRelease(error_string);
223 }
224 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL); 106 OSError os_error_struct(status, status_message.buf(), OSError::kBoringSSL);
225 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct); 107 Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
226 Dart_Handle exception = 108 Dart_Handle exception =
227 DartUtils::NewDartIOException(exception_type, message, os_error); 109 DartUtils::NewDartIOException(exception_type, message, os_error);
228 ASSERT(!Dart_IsError(exception)); 110 ASSERT(!Dart_IsError(exception));
229 Dart_ThrowException(exception); 111 Dart_ThrowException(exception);
230 UNREACHABLE(); 112 UNREACHABLE();
231 } 113 }
232 114
233 115
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 reinterpret_cast<intptr_t>(context)); 194 reinterpret_cast<intptr_t>(context));
313 RETURN_IF_ERROR(err); 195 RETURN_IF_ERROR(err);
314 Dart_NewWeakPersistentHandle(dart_this, 196 Dart_NewWeakPersistentHandle(dart_this,
315 context, 197 context,
316 approximate_size_of_context, 198 approximate_size_of_context,
317 DeleteCertContext); 199 DeleteCertContext);
318 return Dart_Null(); 200 return Dart_Null();
319 } 201 }
320 202
321 203
322 static SecCertificateRef GetX509Certificate(Dart_NativeArguments args) {
323 SecCertificateRef certificate;
324 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
325 ASSERT(Dart_IsInstance(dart_this));
326 ThrowIfError(Dart_GetNativeInstanceField(
327 dart_this,
328 kX509NativeFieldIndex,
329 reinterpret_cast<intptr_t*>(&certificate)));
330 return certificate;
331 }
332
333
334 static void ReleaseCertificate(void* isolate_data, 204 static void ReleaseCertificate(void* isolate_data,
335 Dart_WeakPersistentHandle handle, 205 Dart_WeakPersistentHandle handle,
336 void* context_pointer) { 206 void* context_pointer) {
337 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer); 207 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(context_pointer);
338 CFRelease(cert); 208 CFRelease(cert);
339 } 209 }
340 210
341 211
342 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) { 212 static Dart_Handle WrappedX509Certificate(SecCertificateRef certificate) {
343 const intptr_t approximate_size_of_certificate = 1500; 213 const intptr_t approximate_size_of_certificate = 1500;
(...skipping 26 matching lines...) Expand all
370 result, 240 result,
371 kX509NativeFieldIndex, 241 kX509NativeFieldIndex,
372 reinterpret_cast<intptr_t>(certificate)); 242 reinterpret_cast<intptr_t>(certificate));
373 if (Dart_IsError(status)) { 243 if (Dart_IsError(status)) {
374 return status; 244 return status;
375 } 245 }
376 return result; 246 return result;
377 } 247 }
378 248
379 249
380 // Where the argument to the constructor is the handle for an object
381 // implementing List<int>, this class creates a scope in which the memory
382 // backing the list can be accessed.
383 //
384 // Do not make Dart_ API calls while in a ScopedMemBuffer.
385 // Do not call Dart_PropagateError while in a ScopedMemBuffer.
386 class ScopedMemBuffer {
387 public:
388 explicit ScopedMemBuffer(Dart_Handle object) {
389 if (!Dart_IsTypedData(object) && !Dart_IsList(object)) {
390 Dart_ThrowException(DartUtils::NewDartArgumentError(
391 "Argument is not a List<int>"));
392 }
393
394 uint8_t* bytes = NULL;
395 intptr_t bytes_len = 0;
396 bool is_typed_data = false;
397 if (Dart_IsTypedData(object)) {
398 is_typed_data = true;
399 Dart_TypedData_Type typ;
400 ThrowIfError(Dart_TypedDataAcquireData(
401 object,
402 &typ,
403 reinterpret_cast<void**>(&bytes),
404 &bytes_len));
405 } else {
406 ASSERT(Dart_IsList(object));
407 ThrowIfError(Dart_ListLength(object, &bytes_len));
408 bytes = Dart_ScopeAllocate(bytes_len);
409 ASSERT(bytes != NULL);
410 ThrowIfError(Dart_ListGetAsBytes(object, 0, bytes, bytes_len));
411 }
412
413 object_ = object;
414 bytes_ = bytes;
415 bytes_len_ = bytes_len;
416 is_typed_data_ = is_typed_data;
417 }
418
419 ~ScopedMemBuffer() {
420 if (is_typed_data_) {
421 ThrowIfError(Dart_TypedDataReleaseData(object_));
422 }
423 }
424
425 uint8_t* get() const { return bytes_; }
426 intptr_t length() const { return bytes_len_; }
427
428 private:
429 Dart_Handle object_;
430 uint8_t* bytes_;
431 intptr_t bytes_len_;
432 bool is_typed_data_;
433
434 DISALLOW_ALLOCATION();
435 DISALLOW_COPY_AND_ASSIGN(ScopedMemBuffer);
436 };
437
438
439 static const char* GetPasswordArgument(Dart_NativeArguments args,
440 intptr_t index) {
441 Dart_Handle password_object =
442 ThrowIfError(Dart_GetNativeArgument(args, index));
443 const char* password = NULL;
444 if (Dart_IsString(password_object)) {
445 ThrowIfError(Dart_StringToCString(password_object, &password));
446 if (strlen(password) > PEM_BUFSIZE - 1) {
447 Dart_ThrowException(DartUtils::NewDartArgumentError(
448 "Password length is greater than 1023 bytes."));
449 }
450 } else if (Dart_IsNull(password_object)) {
451 password = "";
452 } else {
453 Dart_ThrowException(DartUtils::NewDartArgumentError(
454 "Password is not a String or null"));
455 }
456 return password;
457 }
458
459
460 static OSStatus GetKeyAndCerts(CFArrayRef items,
461 CFIndex items_length,
462 CFArrayRef* out_certs,
463 SecKeyRef* out_key) {
464 OSStatus status = noErr;
465
466 // Loop through the items, take only the first private key/identity, ignore
467 // any others, populate out_certs.
468 CFMutableArrayRef certs =
469 CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
470 SecKeyRef key = NULL;
471
472 for (CFIndex i = 0; i < items_length; ++i) {
473 CFTypeRef item =
474 reinterpret_cast<CFTypeRef>(CFArrayGetValueAtIndex(items, i));
475 CFTypeID item_type = CFGetTypeID(item);
476 if (item_type == SecCertificateGetTypeID()) {
477 if (SSL_LOG_CERTS) {
478 Log::Print("\titem %ld: Certificate\n", i);
479 }
480 CFArrayAppendValue(certs, item);
481 } else if ((item_type == SecKeyGetTypeID()) && (key == NULL)) {
482 if (SSL_LOG_CERTS) {
483 Log::Print("\titem %ld: Key\n", i);
484 }
485 key = reinterpret_cast<SecKeyRef>(const_cast<void*>(item));
486 CFRetain(key);
487 } else if ((item_type == SecIdentityGetTypeID()) && (key == NULL)) {
488 if (SSL_LOG_CERTS) {
489 Log::Print("\titem %ld: Identity\n", i);
490 }
491 SecIdentityRef identity =
492 reinterpret_cast<SecIdentityRef>(const_cast<void*>(item));
493 SecCertificateRef cert = NULL;
494
495 status = SecIdentityCopyPrivateKey(identity, &key);
496 if (status != noErr) {
497 CFRelease(certs);
498 return status;
499 }
500
501 status = SecIdentityCopyCertificate(identity, &cert);
502 if (status != noErr) {
503 CFRelease(key);
504 CFRelease(certs);
505 return status;
506 }
507 CFArrayAppendValue(certs, cert);
508 CFRelease(cert);
509 }
510 // Other item types are ignored.
511 }
512
513 if (out_key == NULL) {
514 if (key != NULL) {
515 CFRelease(key);
516 }
517 } else {
518 *out_key = key;
519 }
520
521 if (out_certs == NULL) {
522 if (certs != NULL) {
523 CFRelease(certs);
524 }
525 } else {
526 *out_certs = certs;
527 }
528 return status;
529 }
530
531
532 static OSStatus TryPEMImport(CFDataRef cfdata,
533 CFStringRef password,
534 CFArrayRef* out_certs,
535 SecKeyRef* out_key) {
536 OSStatus status = noErr;
537
538 SecExternalFormat format = kSecFormatPEMSequence;
539 SecExternalItemType sitem_type = kSecItemTypeAggregate;
540
541 SecItemImportExportKeyParameters params;
542 memset(&params, 0, sizeof(params));
543 params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
544 params.flags = kSecKeyNoAccessControl;
545 params.passphrase = password;
546
547 CFArrayRef items = NULL;
548 status = SecItemImport(
549 cfdata, NULL, &format, &sitem_type, 0, &params, NULL, &items);
550
551 if (status != noErr) {
552 if (SSL_LOG_CERTS) {
553 Log::Print("TrySecItemImport failed with: %ld, type = %d, format = %d\n",
554 static_cast<intptr_t>(status), sitem_type, format);
555 }
556 return status;
557 }
558
559 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items);
560 if (SSL_LOG_CERTS) {
561 Log::Print(
562 "TrySecItemImport succeeded, type = %d, format = %d, count = %ld\n",
563 sitem_type, format, items_length);
564 }
565
566 // Empty list indicates a decoding failure of some sort.
567 if ((items != NULL) && (items_length == 0)) {
568 CFRelease(items);
569 return errSSLBadCert;
570 }
571
572 status = GetKeyAndCerts(items, items_length, out_certs, out_key);
573 CFRelease(items);
574 return status;
575 }
576
577
578 static char* TempKeychainPath() {
579 const char* exes = "keychaindir.XXXX";
580 const char* fname = "keychain";
581 const char* temp_dir = getenv("TMPDIR");
582 if (temp_dir == NULL) {
583 temp_dir = getenv("TMP");
584 }
585 if (temp_dir == NULL) {
586 temp_dir = "/tmp/";
587 }
588 ASSERT(temp_dir != NULL);
589
590 TextBuffer path(PATH_MAX);
591 path.Printf("%s/%s", temp_dir, exes);
592 char* ret = mkdtemp(path.buf());
593 ASSERT(ret != NULL);
594 path.Printf("/%s", fname);
595
596 char* result =
597 reinterpret_cast<char*>(Dart_ScopeAllocate(path.length() + 1));
598 return strncpy(result, path.buf(), path.length() + 1);
599 }
600
601
602 static OSStatus CreateKeychain(SecKeychainRef* keychain) {
603 ASSERT(keychain != NULL);
604 OSStatus status = noErr;
605 const char* temp_keychain_pwd = "dartdart";
606 char* temp_file_path = TempKeychainPath();
607 ASSERT(temp_file_path != NULL);
608 if (SSL_LOG_CERTS) {
609 Log::Print("Temporary keychain at: '%s'\n", temp_file_path);
610 }
611 status = SecKeychainCreate(temp_file_path,
612 strlen(temp_keychain_pwd) + 1,
613 reinterpret_cast<const void*>(temp_keychain_pwd),
614 FALSE, // Prompt user? Definitely no.
615 NULL, // Default access rights.
616 keychain);
617 if (status != noErr) {
618 return status;
619 }
620 ASSERT(*keychain != NULL);
621 return status;
622 }
623
624
625 static OSStatus TryPKCS12Import(CFDataRef cfdata,
626 CFStringRef password,
627 CFArrayRef* out_certs,
628 SecKeyRef* out_key,
629 SecKeychainRef* out_keychain) {
630 OSStatus status = noErr;
631
632 SecExternalFormat format = kSecFormatPKCS12;
633 SecExternalItemType sitem_type = kSecItemTypeAggregate;
634
635 SecItemImportExportKeyParameters params;
636 memset(&params, 0, sizeof(params));
637 params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
638 params.flags = kSecKeyNoAccessControl;
639 params.passphrase = password;
640
641 CFArrayRef items = NULL;
642 if (SSL_LOG_CERTS) {
643 Log::Print("Trying PKCS12 import with: type = %d, format = %d\n",
644 sitem_type, format);
645 }
646
647 // The documentation for SecKeychainItemImport here:
648 //
649 // https://developer.apple.com/library/mac/documentation/Security/Reference/ke ychainservices/index.html
650 //
651 // states that when the SecKeychainRef argument is NULL, the CFArrayRef*
652 // argument will be populated by an array containing all keys, identities,
653 // and certificates from the data in the CFDataRef argument.
654 //
655 // Unfortunately, this is not true. The code to populate the CFArrayRef with
656 // keys and identities from PKCS12 data has been skipped and/or commented out,
657 // here:
658 //
659 // https://github.com/Apple-FOSS-Mirror/Security/blob/master/libsecurity_keych ain/lib/SecImportExportAgg.cpp#L636
660 //
661 // as "floating" SecKeyRefs from the PKCS12 decoder haven't been implemented.
662 // That is, each private key instance coming from the PKCS12 decoder has to be
663 // associated with a keychain instance. Thus, as a workaround, we create a
664 // temporary keychain here if one is needed, and stash it below in a
665 // SecurityContext. This has the drawbacks:
666 // 1.) We need to make a temporary directory to hold the keychain file, and
667 // 2.) SecKeychainItemImport() probably does blocking IO to create and
668 // manipulate the keychain file.
669 // So if the API is updated, this keychain should not be used.
670 SecKeychainRef keychain = NULL;
671 if (out_key != NULL) {
672 ASSERT(out_keychain != NULL);
673 status = CreateKeychain(&keychain);
674 if (status != noErr) {
675 return status;
676 }
677 *out_keychain = keychain;
678 }
679
680 status = SecItemImport(
681 cfdata, NULL, &format, &sitem_type, 0, &params, keychain, &items);
682 if (status != noErr) {
683 if (SSL_LOG_CERTS) {
684 Log::Print("TrySecItemImport failed with: %ld, it = %d, format = %d\n",
685 static_cast<intptr_t>(status), sitem_type, format);
686 }
687 return status;
688 }
689
690 CFIndex items_length = (items == NULL) ? 0 : CFArrayGetCount(items);
691 if (SSL_LOG_CERTS) {
692 Log::Print("TrySecItemImport succeeded, count = %ld\n", items_length);
693 }
694
695 // Empty list indicates a decoding failure of some sort.
696 if ((items != NULL) && (items_length == 0)) {
697 CFRelease(items);
698 return errSSLBadCert;
699 }
700
701 status = GetKeyAndCerts(items, items_length, out_certs, out_key);
702 CFRelease(items);
703 return status;
704 }
705
706
707 static OSStatus ExtractSecItems(uint8_t* buffer,
708 intptr_t length,
709 const char* password,
710 CFArrayRef* out_certs,
711 SecKeyRef* out_key,
712 SecKeychainRef* out_keychain) {
713 ASSERT(buffer != NULL);
714 ASSERT(password != NULL);
715 OSStatus status = noErr;
716
717 CFDataRef cfdata = CFDataCreateWithBytesNoCopy(
718 NULL, buffer, length, kCFAllocatorNull);
719 CFStringRef cfpassword = CFStringCreateWithCStringNoCopy(
720 NULL, password, kCFStringEncodingUTF8, kCFAllocatorNull);
721 ASSERT(cfdata != NULL);
722 ASSERT(cfpassword != NULL);
723
724 status = TryPEMImport(cfdata, cfpassword, out_certs, out_key);
725 if (status != noErr) {
726 status =
727 TryPKCS12Import(cfdata, cfpassword, out_certs, out_key, out_keychain);
728 }
729
730 CFRelease(cfdata);
731 CFRelease(cfpassword);
732 return status;
733 }
734
735
736 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) { 250 void FUNCTION_NAME(SecureSocket_Init)(Dart_NativeArguments args) {
737 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0)); 251 Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
738 SSLFilter* filter = new SSLFilter(); // Deleted in DeleteFilter finalizer. 252 SSLFilter* filter = new SSLFilter(); // Deleted in DeleteFilter finalizer.
739 Dart_Handle err = SetFilter(args, filter); 253 Dart_Handle err = SetFilter(args, filter);
740 if (Dart_IsError(err)) { 254 if (Dart_IsError(err)) {
741 delete filter; 255 delete filter;
742 Dart_PropagateError(err); 256 Dart_PropagateError(err);
743 } 257 }
744 err = filter->Init(dart_this); 258 err = filter->Init(dart_this);
745 if (Dart_IsError(err)) { 259 if (Dart_IsError(err)) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 Dart_Handle callback = 350 Dart_Handle callback =
837 ThrowIfError(Dart_GetNativeArgument(args, 1)); 351 ThrowIfError(Dart_GetNativeArgument(args, 1));
838 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) { 352 if (!Dart_IsClosure(callback) && !Dart_IsNull(callback)) {
839 Dart_ThrowException(DartUtils::NewDartArgumentError( 353 Dart_ThrowException(DartUtils::NewDartArgumentError(
840 "Illegal argument to RegisterBadCertificateCallback")); 354 "Illegal argument to RegisterBadCertificateCallback"));
841 } 355 }
842 GetFilter(args)->RegisterBadCertificateCallback(callback); 356 GetFilter(args)->RegisterBadCertificateCallback(callback);
843 } 357 }
844 358
845 359
846 void FUNCTION_NAME(SecureSocket_PeerCertificate) 360 void FUNCTION_NAME(SecureSocket_PeerCertificate)(Dart_NativeArguments args) {
847 (Dart_NativeArguments args) {
848 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); 361 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate());
849 } 362 }
850 363
851 364
852 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { 365 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
853 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); 366 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args));
854 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); 367 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
855 } 368 }
856 369
857 370
858 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) { 371 void FUNCTION_NAME(SecurityContext_Allocate)(Dart_NativeArguments args) {
859 SSLCertContext* cert_context = new SSLCertContext(); 372 SSLCertContext* cert_context = new SSLCertContext();
860 // cert_context deleted in DeleteCertContext finalizer. 373 // cert_context deleted in DeleteCertContext finalizer.
861 Dart_Handle err = SetSecurityContext(args, cert_context); 374 Dart_Handle err = SetSecurityContext(args, cert_context);
862 if (Dart_IsError(err)) { 375 if (Dart_IsError(err)) {
863 delete cert_context; 376 delete cert_context;
864 Dart_PropagateError(err); 377 Dart_PropagateError(err);
865 } 378 }
866 } 379 }
867 380
868 381
869 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)( 382 void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
870 Dart_NativeArguments args) { 383 Dart_NativeArguments args) {
871 SSLCertContext* context = GetSecurityContext(args); 384 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
872 const char* password = GetPasswordArgument(args, 2); 385 "SecurityContext.usePrivateKeyBytes is not yet implemented."));
873
874 OSStatus status;
875 SecKeyRef key = NULL;
876 SecKeychainRef keychain = NULL;
877 {
878 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1)));
879 status = ExtractSecItems(
880 buffer.get(), buffer.length(), password, NULL, &key, &keychain);
881 }
882
883 // Set the context fields. If there's a failure, release the items.
884 bool set_failure = false;
885 if ((key != NULL) && !context->set_private_key(key)) {
886 CFRelease(key);
887 SecKeychainDelete(keychain);
888 CFRelease(keychain);
889 set_failure = true;
890 }
891 if (!set_failure && (keychain != NULL) && !context->set_keychain(keychain)) {
892 SecKeychainDelete(keychain);
893 CFRelease(keychain);
894 }
895
896 if (set_failure) {
897 Dart_ThrowException(DartUtils::NewDartArgumentError(
898 "usePrivateKeyBytes has already been called on the given context."));
899 }
900 CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes");
901 } 386 }
902 387
903 388
904 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)( 389 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
905 Dart_NativeArguments args) { 390 Dart_NativeArguments args) {
906 SSLCertContext* context = GetSecurityContext(args); 391 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
907 const char* password = GetPasswordArgument(args, 2); 392 "SecurityContext.setTrustedCertificatesBytes is not yet implemented."));
908
909 OSStatus status;
910 CFArrayRef certs = NULL;
911 {
912 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1)));
913 status = ExtractSecItems(
914 buffer.get(), buffer.length(), password, &certs, NULL, NULL);
915 }
916
917 // Set the field in the context. If there's a failure, release the certs,
918 // and throw an exception.
919 if ((certs != NULL) && !context->set_trusted_certs(certs)) {
920 CFRelease(certs);
921 Dart_ThrowException(DartUtils::NewDartArgumentError(
922 "setTrustedCertificatesBytes has already been called "
923 "on the given context."));
924 }
925
926 CheckStatus(status, "TlsException", "Failure in setTrustedCertificatesBytes");
927 } 393 }
928 394
929 395
930 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) { 396 void FUNCTION_NAME(SecurityContext_AlpnSupported)(Dart_NativeArguments args) {
931 Dart_SetReturnValue(args, Dart_NewBoolean(false)); 397 Dart_SetReturnValue(args, Dart_NewBoolean(false));
932 } 398 }
933 399
934 400
935 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)( 401 void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
936 Dart_NativeArguments args) { 402 Dart_NativeArguments args) {
937 SSLCertContext* context = GetSecurityContext(args); 403 SSLCertContext* context = GetSecurityContext(args);
938 context->set_trust_builtin(true); 404 context->set_trust_builtin(true);
939 } 405 }
940 406
941 407
942 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)( 408 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
943 Dart_NativeArguments args) { 409 Dart_NativeArguments args) {
944 SSLCertContext* context = GetSecurityContext(args); 410 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
945 411 "SecurityContext.useCertificateChainBytes is not yet implemented."));
946 const char* password = GetPasswordArgument(args, 2);
947 OSStatus status;
948 CFArrayRef certs = NULL;
949 {
950 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1)));
951 status = ExtractSecItems(
952 buffer.get(), buffer.length(), password, &certs, NULL, NULL);
953 }
954
955 // Set the field in the context. If there's a failure, release the certs,
956 // and throw an exception.
957 if ((certs != NULL) && !context->set_cert_chain(certs)) {
958 CFRelease(certs);
959 Dart_ThrowException(DartUtils::NewDartArgumentError(
960 "useCertificateChainBytes has already been called "
961 "on the given context."));
962 }
963
964 CheckStatus(status, "TlsException", "Failure in useCertificateChainBytes");
965 } 412 }
966 413
967 414
968 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)( 415 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
969 Dart_NativeArguments args) { 416 Dart_NativeArguments args) {
970 SSLCertContext* context = GetSecurityContext(args); 417 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
971 const char* password = GetPasswordArgument(args, 2); 418 "SecurityContext.setClientAuthoritiesBytes is not yet implemented."));
972
973 OSStatus status;
974 CFArrayRef certs = NULL;
975 {
976 ScopedMemBuffer buffer(ThrowIfError(Dart_GetNativeArgument(args, 1)));
977 status = ExtractSecItems(
978 buffer.get(), buffer.length(), password, &certs, NULL, NULL);
979 }
980
981 // Set the field in the context. If there's a failure, release the certs,
982 // and throw an exception.
983 if ((certs != NULL) && !context->set_cert_authorities(certs)) {
984 CFRelease(certs);
985 Dart_ThrowException(DartUtils::NewDartArgumentError(
986 "setClientAuthoritiesBytes has already been called "
987 "on the given context."));
988 }
989
990 CheckStatus(status, "TlsException", "Failure in setClientAuthoritiesBytes");
991 } 419 }
992 420
993 421
994 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)( 422 void FUNCTION_NAME(SecurityContext_SetAlpnProtocols)(
995 Dart_NativeArguments args) { 423 Dart_NativeArguments args) {
996 Dart_ThrowException(DartUtils::NewDartUnsupportedError( 424 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
997 "ALPN is not supported on this platform")); 425 "ALPN is not supported on this platform"));
998 } 426 }
999 427
1000 428
1001 static char* GetNameFromCert(SecCertificateRef certificate,
1002 CFTypeRef field,
1003 CFStringRef name) {
1004 char* issuer_name = NULL;
1005
1006 CFTypeRef keys[] = { field };
1007 CFArrayRef key_array = CFArrayCreate(NULL, keys, 1, &kCFTypeArrayCallBacks);
1008 CFErrorRef error = NULL;
1009 CFDictionaryRef cert_dict =
1010 SecCertificateCopyValues(certificate, key_array, &error);
1011 if (cert_dict == NULL) {
1012 CFRelease(key_array);
1013 Dart_ThrowException(DartUtils::NewDartArgumentError(
1014 "X509.issuer failed to copy issuer field out of certificate"));
1015 }
1016
1017 CFTypeRef item = CFDictionaryGetValue(cert_dict, keys[0]);
1018 ASSERT(CFGetTypeID(item) == CFDictionaryGetTypeID());
1019 CFDictionaryRef val_dict = reinterpret_cast<CFDictionaryRef>(item);
1020
1021 item = CFDictionaryGetValue(val_dict, kSecPropertyKeyValue);
1022 ASSERT(CFGetTypeID(item) == CFArrayGetTypeID());
1023 CFArrayRef val_array = reinterpret_cast<CFArrayRef>(item);
1024
1025 for (intptr_t i = 0; i < CFArrayGetCount(val_array); i++) {
1026 item = CFArrayGetValueAtIndex(val_array, i);
1027 ASSERT(CFGetTypeID(item) == CFDictionaryGetTypeID());
1028 CFDictionaryRef val_dict2 = reinterpret_cast<CFDictionaryRef>(item);
1029
1030 item = CFDictionaryGetValue(val_dict2, kSecPropertyKeyLabel);
1031 ASSERT(CFGetTypeID(item) == CFStringGetTypeID());
1032 CFStringRef label = reinterpret_cast<CFStringRef>(item);
1033
1034 if (CFStringCompare(label, name, 0) == kCFCompareEqualTo) {
1035 item = CFDictionaryGetValue(val_dict2, kSecPropertyKeyValue);
1036 ASSERT(CFGetTypeID(item) == CFStringGetTypeID());
1037 CFStringRef value = reinterpret_cast<CFStringRef>(item);
1038 issuer_name = CFStringRefToCString(value);
1039 break;
1040 }
1041 }
1042
1043 CFRelease(cert_dict);
1044 CFRelease(key_array);
1045 return issuer_name;
1046 }
1047
1048
1049 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) { 429 void FUNCTION_NAME(X509_Subject)(Dart_NativeArguments args) {
1050 SecCertificateRef certificate = GetX509Certificate(args); 430 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
1051 char* subject_name = GetNameFromCert( 431 "X509Certificate.subject is not yet implemented."));
1052 certificate,
1053 kSecOIDX509V1SubjectName,
1054 reinterpret_cast<CFStringRef>(kSecOIDCommonName));
1055 if (subject_name == NULL) {
1056 Dart_ThrowException(DartUtils::NewDartArgumentError(
1057 "X509.subject failed to find issuer's common name."));
1058 } else {
1059 Dart_SetReturnValue(args, Dart_NewStringFromCString(subject_name));
1060 }
1061 } 432 }
1062 433
1063 434
1064 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) { 435 void FUNCTION_NAME(X509_Issuer)(Dart_NativeArguments args) {
1065 SecCertificateRef certificate = GetX509Certificate(args); 436 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
1066 char* issuer_name = GetNameFromCert( 437 "X509Certificate.issuer is not supported on this platform."));
1067 certificate,
1068 kSecOIDX509V1IssuerName,
1069 reinterpret_cast<CFStringRef>(kSecOIDCommonName));
1070 if (issuer_name == NULL) {
1071 Dart_ThrowException(DartUtils::NewDartArgumentError(
1072 "X509.issuer failed to find issuer's common name."));
1073 } else {
1074 Dart_SetReturnValue(args, Dart_NewStringFromCString(issuer_name));
1075 }
1076 }
1077
1078
1079 // Returns the number of seconds since the epoch from 'field'.
1080 static int64_t GetTimeFromCert(SecCertificateRef certificate, CFTypeRef field) {
1081 CFTypeRef keys[] = { field };
1082 CFArrayRef key_array = CFArrayCreate(NULL, keys, 1, &kCFTypeArrayCallBacks);
1083 CFErrorRef error = NULL;
1084 CFDictionaryRef cert_dict =
1085 SecCertificateCopyValues(certificate, key_array, &error);
1086 if (cert_dict == NULL) {
1087 CFRelease(key_array);
1088 Dart_ThrowException(DartUtils::NewDartArgumentError(
1089 "X509.startValidity: failed to copy issuer field out of certificate"));
1090 }
1091
1092 CFTypeRef item = CFDictionaryGetValue(cert_dict, keys[0]);
1093 ASSERT(CFGetTypeID(item) == CFDictionaryGetTypeID());
1094 CFDictionaryRef val_dict = reinterpret_cast<CFDictionaryRef>(item);
1095
1096 item = CFDictionaryGetValue(val_dict, kSecPropertyKeyValue);
1097 ASSERT(CFGetTypeID(item) == CFNumberGetTypeID());
1098 CFNumberRef date_number = reinterpret_cast<CFNumberRef>(item);
1099
1100 CFAbsoluteTime date_abs_time;
1101 CFNumberGetValue(date_number, kCFNumberDoubleType, &date_abs_time);
1102 CFAbsoluteTime seconds_since_epoch =
1103 date_abs_time + kCFAbsoluteTimeIntervalSince1970;
1104 return static_cast<int64_t>(seconds_since_epoch) * 1000LL;
1105 } 438 }
1106 439
1107 440
1108 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) { 441 void FUNCTION_NAME(X509_StartValidity)(Dart_NativeArguments args) {
1109 SecCertificateRef certificate = GetX509Certificate(args); 442 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
1110 int64_t seconds_since_epoch = GetTimeFromCert(certificate, 443 "X509Certificate.startValidity is not supported on this platform."));
1111 kSecOIDX509V1ValidityNotBefore);
1112 Dart_SetReturnValue(args,
1113 Dart_NewInteger(static_cast<int64_t>(seconds_since_epoch) * 1000LL));
1114 } 444 }
1115 445
1116 446
1117 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) { 447 void FUNCTION_NAME(X509_EndValidity)(Dart_NativeArguments args) {
1118 SecCertificateRef certificate = GetX509Certificate(args); 448 Dart_ThrowException(DartUtils::NewDartUnsupportedError(
1119 int64_t seconds_since_epoch = GetTimeFromCert(certificate, 449 "X509Certificate.endValidity is not supported on this platform."));
1120 kSecOIDX509V1ValidityNotAfter);
1121 Dart_SetReturnValue(args,
1122 Dart_NewInteger(static_cast<int64_t>(seconds_since_epoch) * 1000LL));
1123 } 450 }
1124 451
1125 452
1126 // Pushes data through the SSL filter, reading and writing from circular 453 // Pushes data through the SSL filter, reading and writing from circular
1127 // buffers shared with Dart. Called from the IOService thread. 454 // buffers shared with Dart. Called from the IOService thread.
1128 // 455 //
1129 // The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to 456 // The Dart _SecureFilterImpl class contains 4 ExternalByteArrays used to
1130 // pass encrypted and plaintext data to and from the C++ SSLFilter object. 457 // pass encrypted and plaintext data to and from the C++ SSLFilter object.
1131 // 458 //
1132 // ProcessFilter is called with a CObject array containing the pointer to 459 // ProcessFilter is called with a CObject array containing the pointer to
(...skipping 24 matching lines...) Expand all
1157 if (status == noErr) { 484 if (status == noErr) {
1158 CObjectArray* result = new CObjectArray( 485 CObjectArray* result = new CObjectArray(
1159 CObject::NewArray(SSLFilter::kNumBuffers * 2)); 486 CObject::NewArray(SSLFilter::kNumBuffers * 2));
1160 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) { 487 for (intptr_t i = 0; i < SSLFilter::kNumBuffers; ++i) {
1161 result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i]))); 488 result->SetAt(2 * i, new CObjectInt32(CObject::NewInt32(starts[i])));
1162 result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i]))); 489 result->SetAt(2 * i + 1, new CObjectInt32(CObject::NewInt32(ends[i])));
1163 } 490 }
1164 return result; 491 return result;
1165 } else { 492 } else {
1166 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE); 493 TextBuffer status_message(SSL_ERROR_MESSAGE_BUFFER_SIZE);
1167 CFStringRef error_string = SecCopyErrorMessageString(status, NULL); 494 status_message.Printf("OSStatus = %ld: https://www.osstatus.com",
1168 if (error_string == NULL) { 495 static_cast<intptr_t>(status));
1169 status_message.Printf("OSStatus = %ld: https://www.osstatus.com",
1170 static_cast<intptr_t>(status));
1171 } else {
1172 char* error = CFStringRefToCString(error_string);
1173 status_message.Printf("OSStatus = %ld: %s",
1174 static_cast<intptr_t>(status), error);
1175 CFRelease(error_string);
1176 }
1177 CObjectArray* result = new CObjectArray(CObject::NewArray(2)); 496 CObjectArray* result = new CObjectArray(CObject::NewArray(2));
1178 result->SetAt(0, new CObjectInt32(CObject::NewInt32(status))); 497 result->SetAt(0, new CObjectInt32(CObject::NewInt32(status)));
1179 result->SetAt(1, new CObjectString(CObject::NewString( 498 result->SetAt(1, new CObjectString(CObject::NewString(
1180 status_message.buf()))); 499 status_message.buf())));
1181 return result; 500 return result;
1182 } 501 }
1183 } 502 }
1184 503
1185 504
1186 // Usually buffer_starts_ and buffer_ends_ are populated by ProcessAllBuffers, 505 // Usually buffer_starts_ and buffer_ends_ are populated by ProcessAllBuffers,
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 ssl_context, kSSLSessionOptionBreakOnServerAuth, true); 831 ssl_context, kSSLSessionOptionBreakOnServerAuth, true);
1513 CheckStatus(status, 832 CheckStatus(status,
1514 "TlsException", 833 "TlsException",
1515 "Failed to set BreakOnServerAuth option"); 834 "Failed to set BreakOnServerAuth option");
1516 835
1517 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1); 836 status = SSLSetProtocolVersionMin(ssl_context, kTLSProtocol1);
1518 CheckStatus(status, 837 CheckStatus(status,
1519 "TlsException", 838 "TlsException",
1520 "Failed to set minimum protocol version to kTLSProtocol1"); 839 "Failed to set minimum protocol version to kTLSProtocol1");
1521 840
1522 // If the context has a private key and certificate chain, combine the
1523 // private key and first certificate into a SecIdentityRef, and place that
1524 // and the remaining certs in an array to pass to SSLSetCertificate().
1525 if ((context->private_key() != NULL) && (context->cert_chain() != NULL)) {
1526 CFIndex chain_length = CFArrayGetCount(context->cert_chain());
1527 CFMutableArrayRef certs =
1528 CFArrayCreateMutable(NULL, chain_length, &kCFTypeArrayCallBacks);
1529 CFTypeRef item = CFArrayGetValueAtIndex(context->cert_chain(), 0);
1530 ASSERT(CFGetTypeID(item) == SecCertificateGetTypeID());
1531 SecCertificateRef first_cert =
1532 reinterpret_cast<SecCertificateRef>(const_cast<void*>(item));
1533 SecIdentityRef identity =
1534 SecIdentityCreate(NULL, first_cert, context->private_key());
1535 CFArrayAppendValue(certs, identity);
1536 for (CFIndex i = 0; i < chain_length; i++) {
1537 CFArrayAppendValue(certs,
1538 CFArrayGetValueAtIndex(context->cert_chain(), i));
1539 }
1540 CFRelease(identity);
1541 status = SSLSetCertificate(ssl_context, certs);
1542 CFRelease(certs);
1543 CheckStatus(status, "TlsException", "SSLSetCertificate failed");
1544 }
1545
1546 if (context->cert_authorities() != NULL) {
1547 status = SSLSetCertificateAuthorities(
1548 ssl_context, context->cert_authorities(), true);
1549 CheckStatus(status,
1550 "TlsException",
1551 "Failed to set certificate authorities");
1552 }
1553
1554 if (is_server) { 841 if (is_server) {
1555 SSLAuthenticate auth = 842 SSLAuthenticate auth =
1556 require_client_certificate 843 require_client_certificate
1557 ? kAlwaysAuthenticate 844 ? kAlwaysAuthenticate
1558 : (request_client_certificate ? kTryAuthenticate : kNeverAuthenticate); 845 : (request_client_certificate ? kTryAuthenticate : kNeverAuthenticate);
1559 status = SSLSetClientSideAuthenticate(ssl_context, auth); 846 status = SSLSetClientSideAuthenticate(ssl_context, auth);
1560 CheckStatus(status, 847 CheckStatus(status,
1561 "TlsException", 848 "TlsException",
1562 "Failed to set client authentication mode"); 849 "Failed to set client authentication mode");
1563 850
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1604 // A client certificate was requested, but not required, and wasn't sent. 891 // A client certificate was requested, but not required, and wasn't sent.
1605 return noErr; 892 return noErr;
1606 } 893 }
1607 if (SSL_LOG_STATUS) { 894 if (SSL_LOG_STATUS) {
1608 Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n", 895 Log::Print("Handshake error from SSLCopyPeerTrust(): %ld.\n",
1609 static_cast<intptr_t>(status)); 896 static_cast<intptr_t>(status));
1610 } 897 }
1611 return status; 898 return status;
1612 } 899 }
1613 900
1614 CFArrayRef trusted_certs = NULL; 901 CFArrayRef trusted_certs =
1615 if (cert_context_->trusted_certs() != NULL) { 902 CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
1616 trusted_certs = CFArrayCreateCopy(NULL, cert_context_->trusted_certs());
1617 } else {
1618 trusted_certs = CFArrayCreate(NULL, NULL, 0, &kCFTypeArrayCallBacks);
1619 }
1620 903
1621 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs); 904 status = SecTrustSetAnchorCertificates(peer_trust, trusted_certs);
1622 if (status != noErr) { 905 if (status != noErr) {
1623 if (SSL_LOG_STATUS) { 906 if (SSL_LOG_STATUS) {
1624 Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n", 907 Log::Print("Handshake error from SecTrustSetAnchorCertificates: %ld\n",
1625 static_cast<intptr_t>(status)); 908 static_cast<intptr_t>(status));
1626 } 909 }
1627 CFRelease(trusted_certs); 910 CFRelease(trusted_certs);
1628 CFRelease(peer_trust); 911 CFRelease(peer_trust);
1629 return status; 912 return status;
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 Log::Print("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n", 1298 Log::Print("ProcessWritePlaintextBuffer: requested: %ld, written: %ld\n",
2016 length, bytes); 1299 length, bytes);
2017 } 1300 }
2018 *bytes_processed = static_cast<intptr_t>(bytes); 1301 *bytes_processed = static_cast<intptr_t>(bytes);
2019 return status; 1302 return status;
2020 } 1303 }
2021 1304
2022 } // namespace bin 1305 } // namespace bin
2023 } // namespace dart 1306 } // namespace dart
2024 1307
2025 #endif // defined(TARGET_OS_MACOS) 1308 #endif // TARGET_OS_IOS
2026 1309
2027 #endif // !defined(DART_IO_DISABLED) && 1310 #endif // !defined(DART_IO_SECURE_SOCKET_DISABLED)
2028 // !defined(DART_IO_SECURE_SOCKET_DISABLED)
OLDNEW
« no previous file with comments | « runtime/bin/platform_macos.cc ('k') | runtime/bin/secure_socket_macos.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698