5#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
9#include <openssl/bio.h>
10#include <openssl/ssl.h>
11#include <openssl/x509.h>
21#define RETURN_IF_ERROR(handle) \
23 Dart_Handle __handle = handle; \
24 if (Dart_IsError((__handle))) { \
32bool SSLFilter::library_initialized_ =
false;
34Mutex* SSLFilter::mutex_ =
nullptr;
39 ASSERT(SSLFilter::mutex_ ==
nullptr);
40 SSLFilter::mutex_ =
new Mutex();
44 ASSERT(SSLFilter::mutex_ !=
nullptr);
45 delete SSLFilter::mutex_;
46 SSLFilter::mutex_ =
nullptr;
49const intptr_t SSLFilter::kInternalBIOSize = 10 *
KB;
51 sizeof(
SSLFilter) + (2 * SSLFilter::kInternalBIOSize);
59 reinterpret_cast<intptr_t*
>(&filter)));
60 if (filter ==
nullptr) {
67static void DeleteFilter(
void* isolate_data,
void* context_pointer) {
79 reinterpret_cast<intptr_t
>(filter));
94 err = filter->
Init(dart_this);
107 bool request_client_certificate =
109 bool require_client_certificate =
113 const char* host_name =
nullptr;
121 reinterpret_cast<intptr_t*
>(&context)));
128 request_client_certificate,
129 require_client_certificate, protocols_handle);
165#if !defined(DART_HOST_OS_MACOS)
166 FATAL(
"This is to be used only on mac/ios platforms");
169 X509* x509 =
reinterpret_cast<X509*
>(x509_pointer);
184 "Illegal argument to RegisterHandshakeCompleteCallback"));
186 GetFilter(
args)->RegisterHandshakeCompleteCallback(handshake_complete);
194 "Illegal argument to RegisterBadCertificateCallback"));
218 intptr_t filter_pointer =
reinterpret_cast<intptr_t
>(filter);
265 int32_t error_code =
static_cast<int32_t
>(ERR_peek_error());
277 int ends[kNumBuffers],
283 int size = IsBufferEncrypted(
i) ? encrypted_buffer_size_ : buffer_size_;
285 FATAL(
"Out-of-bounds internal buffer access in dart:io SecureSocket");
301 if (bytes < 0)
return false;
310 if (bytes < 0)
return false;
326 if (bytes < 0)
return false;
335 if (bytes < 0)
return false;
349 if (!library_initialized_) {
352 ASSERT(string_start_ ==
nullptr);
354 ASSERT(string_start_ !=
nullptr);
355 ASSERT(string_length_ ==
nullptr);
357 ASSERT(string_length_ !=
nullptr);
358 ASSERT(bad_certificate_callback_ ==
nullptr);
360 ASSERT(bad_certificate_callback_ !=
nullptr);
362 return InitializeBuffers(dart_this);
387 Dart_GetField(secure_filter_impl_type, encrypted_size_string);
390 int64_t encrypted_buffer_size = 0;
394 if (buffer_size <= 0 || buffer_size > 1 *
MB) {
395 FATAL(
"Invalid buffer size in _ExternalBuffer");
397 if (encrypted_buffer_size <= 0 || encrypted_buffer_size > 1 *
MB) {
398 FATAL(
"Invalid encrypted buffer size in _ExternalBuffer");
401 encrypted_buffer_size_ =
static_cast<int>(encrypted_buffer_size);
407 int size = IsBufferEncrypted(
i) ? encrypted_buffer_size_ : buffer_size_;
408 buffers_[
i] =
new uint8_t[
size];
409 ASSERT(buffers_[
i] !=
nullptr);
410 memset(buffers_[
i], 0,
size);
411 dart_buffer_objects_[
i] =
nullptr;
416 int size = IsBufferEncrypted(
i) ? encrypted_buffer_size_ : buffer_size_;
423 ASSERT(dart_buffer_objects_[
i] !=
nullptr);
445 ASSERT(
nullptr == handshake_complete_);
448 ASSERT(handshake_complete_ !=
nullptr);
452 ASSERT(bad_certificate_callback_ !=
nullptr);
455 ASSERT(bad_certificate_callback_ !=
nullptr);
459 X509* ca = SSL_get_peer_certificate(ssl_);
472 if (!library_initialized_) {
475 SSL_get_ex_new_index(0,
nullptr,
nullptr,
nullptr,
nullptr);
478 SSL_get_ex_new_index(0,
nullptr,
nullptr,
nullptr,
nullptr);
480 library_initialized_ =
true;
487 bool request_client_certificate,
488 bool require_client_certificate,
492 FATAL(
"Connect called twice on the same _SecureFilter.");
498 status = BIO_new_bio_pair(&ssl_side, kInternalBIOSize, &socket_side_,
503 ASSERT(context !=
nullptr);
505 ssl_ = SSL_new(context->
context());
506 SSL_set_bio(ssl_, ssl_side, ssl_side);
507 SSL_set_mode(ssl_, SSL_MODE_AUTO_RETRY);
511 SSL_set_renegotiate_mode(ssl_, ssl_renegotiate_freely);
518 if (trust_evaluate_handler !=
nullptr) {
520 "SSLCertContextTrustEvaluate", trust_evaluate_handler,
524 int certificate_mode =
525 request_client_certificate ? SSL_VERIFY_PEER : SSL_VERIFY_NONE;
526 if (require_client_certificate) {
527 certificate_mode |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
529 SSL_set_verify(ssl_, certificate_mode,
nullptr);
532 status = SSL_set_tlsext_host_name(ssl_,
hostname);
534 "Set SNI host name", ssl_);
537 X509_VERIFY_PARAM* certificate_checking_parameters = SSL_get0_param(ssl_);
539 X509_VERIFY_PARAM_set_flags(
540 certificate_checking_parameters,
541 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_TRUSTED_FIRST);
542 X509_VERIFY_PARAM_set_hostflags(certificate_checking_parameters, 0);
547 status = X509_VERIFY_PARAM_set1_ip_asc(certificate_checking_parameters,
550 status = X509_VERIFY_PARAM_set1_host(certificate_checking_parameters,
551 hostname_, strlen(hostname_));
554 status,
"TlsException",
"Set hostname for certificate checking", ssl_);
558 status = SSL_accept(ssl_);
564 error = SSL_get_error(ssl_, status);
570 status = SSL_connect(ssl_);
576 error = SSL_get_error(ssl_, status);
590 ASSERT(certificate_pointer != 0);
591 certificate_trust_state_.reset(
596 certificate_trust_state_->x509(),
597 certificate_trust_state_->is_trusted() ?
"" :
"not ");
608 int status = SSL_do_handshake(ssl_);
609 int error = SSL_get_error(ssl_, status);
610 if (
error == SSL_ERROR_WANT_CERTIFICATE_VERIFY) {
611 return SSL_ERROR_WANT_CERTIFICATE_VERIFY;
624 if (SSL_want_write(ssl_) || SSL_want_read(ssl_)) {
625 in_handshake_ =
true;
629 status,
"HandshakeException",
630 is_server_ ?
"Handshake error in server" :
"Handshake error in client",
636 int result = SSL_get_verify_result(ssl_);
639 X509* peer_certificate = SSL_get_peer_certificate(ssl_);
640 if (peer_certificate ==
nullptr) {
643 X509_NAME* s_name = X509_get_subject_name(peer_certificate);
644 printf(
"Peer certificate SN: ");
645 X509_NAME_print_ex_fp(stdout, s_name, 4, 0);
651 in_handshake_ =
false;
658 const uint8_t* protocol;
660 SSL_get0_alpn_selected(ssl_, &protocol, &
length);
669 if (ssl_ !=
nullptr) {
673 if (socket_side_ !=
nullptr) {
674 BIO_free(socket_side_);
675 socket_side_ =
nullptr;
677 if (hostname_ !=
nullptr) {
682 if (buffers_[
i] !=
nullptr) {
683 delete[] buffers_[
i];
684 buffers_[
i] =
nullptr;
695 if (dart_buffer_objects_[
i] !=
nullptr) {
697 dart_buffer_objects_[
i] =
nullptr;
700 if (string_start_ !=
nullptr) {
702 string_start_ =
nullptr;
704 if (string_length_ !=
nullptr) {
706 string_length_ =
nullptr;
708 if (handshake_complete_ !=
nullptr) {
710 handshake_complete_ =
nullptr;
712 if (bad_certificate_callback_ !=
nullptr) {
714 bad_certificate_callback_ =
nullptr;
726 int bytes_processed = 0;
728 Syslog::Print(
"Entering ProcessReadPlaintextBuffer with %d bytes\n",
732 bytes_processed = SSL_read(
735 if (bytes_processed < 0) {
736 int error = SSL_get_error(ssl_, bytes_processed);
741 case SSL_ERROR_SYSCALL:
751 Syslog::Print(
"Leaving ProcessReadPlaintextBuffer read %d bytes\n",
754 return bytes_processed;
760 Syslog::Print(
"Entering ProcessWritePlaintextBuffer with %d bytes\n",
763 int bytes_processed =
765 if (bytes_processed < 0) {
767 Syslog::Print(
"SSL_write returned error %d\n", bytes_processed);
772 Syslog::Print(
"Leaving ProcessWritePlaintextBuffer wrote %d bytes\n",
775 return bytes_processed;
782 Syslog::Print(
"Entering ProcessReadEncryptedBuffer with %d bytes\n",
785 int bytes_processed = 0;
789 if (bytes_processed <= 0) {
790 bool retry = BIO_should_retry(socket_side_) != 0;
800 Syslog::Print(
"Leaving ProcessReadEncryptedBuffer read %d bytes\n",
803 return bytes_processed;
808 int bytes_processed = 0;
810 Syslog::Print(
"Entering ProcessWriteEncryptedBuffer with %d bytes\n",
816 if (bytes_processed < 0) {
829 return bytes_processed;
static uint32_t buffer_size(uint32_t offset, uint32_t maxAlignment)
#define FUNCTION_NAME(name)
static void Print(const char *format,...) PRINTF_ATTRIBUTE(1
static char * StrDup(const char *s)
static Dart_CObject * NewString(const char *str)
static Dart_CObject * NewArray(intptr_t length)
static Dart_CObject * NewInt32(int32_t value)
static bool GetBooleanValue(Dart_Handle bool_obj)
static intptr_t GetNativeIntptrArgument(Dart_NativeArguments args, intptr_t index)
static Dart_Handle NewString(const char *str)
static Dart_Handle NewDartArgumentError(const char *message)
static Dart_Handle NewInternalError(const char *message)
static bool GetNativeBooleanArgument(Dart_NativeArguments args, intptr_t index)
void RegisterCallbacks(SSL *ssl)
SSL_CTX * context() const
bool allow_tls_renegotiation() const
TrustEvaluateHandlerFunc GetTrustEvaluateHandler() const
static void SetAlpnProtocolList(Dart_Handle protocols_handle, SSL *ssl, SSLCertContext *context, bool is_server)
static constexpr int kSecurityContextNativeFieldIndex
void Connect(const char *hostname, SSLCertContext *context, bool is_server, bool request_client_certificate, bool require_client_certificate, Dart_Handle protocols_handle)
int ProcessReadEncryptedBuffer(int start, int end)
void RegisterHandshakeCompleteCallback(Dart_Handle handshake_complete)
void RegisterKeyLogPort(Dart_Port key_log_port)
int ProcessWritePlaintextBuffer(int start, int end)
void MarkAsTrusted(Dart_NativeArguments args)
Dart_Handle PeerCertificate()
void RegisterBadCertificateCallback(Dart_Handle callback)
static void InitializeLibrary()
void GetSelectedProtocol(Dart_NativeArguments args)
bool ProcessAllBuffers(int starts[kNumBuffers], int ends[kNumBuffers], bool in_handshake)
static CObject * ProcessFilterRequest(const CObjectArray &request)
int Handshake(Dart_Port reply_port)
static int ssl_cert_context_index
static const intptr_t kApproximateSize
Dart_Handle callback_error
static int filter_ssl_index
static constexpr int kSSLFilterNativeFieldIndex
int ProcessReadPlaintextBuffer(int start, int end)
int ProcessWriteEncryptedBuffer(int start, int end)
Dart_Port reply_port() const
static constexpr int SSL_ERROR_MESSAGE_BUFFER_SIZE
static uint32_t FetchErrorString(const SSL *ssl, TextBuffer *text_buffer)
static void CheckStatusSSL(int status, const char *type, const char *message, const SSL *ssl)
static bool IsValidAddress(const char *address)
static Dart_Handle WrappedX509Certificate(X509 *certificate)
struct _Dart_Handle * Dart_Handle
struct _Dart_NativeArguments * Dart_NativeArguments
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
const bool SSL_LOG_STATUS
static Dart_Handle ThrowIfError(Dart_Handle handle)
void FUNCTION_NAME() SecureSocket_Connect(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_RegisterHandshakeCompleteCallback(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_PeerCertificate(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_Destroy(Dart_NativeArguments args)
static void DeleteFilter(void *isolate_data, void *filter_pointer)
void FUNCTION_NAME() SecureSocket_NewX509CertificateWrapper(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_Init(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_RegisterKeyLogPort(Dart_NativeArguments args)
void(* TrustEvaluateHandlerFunc)(Dart_Port dest_port_id, Dart_CObject *message)
void FUNCTION_NAME() SecureSocket_FilterPointer(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_MarkAsTrusted(Dart_NativeArguments args)
static Dart_Handle SetFilter(Dart_NativeArguments args, SSLFilter *filter)
void FUNCTION_NAME() SecureSocket_RegisterBadCertificateCallback(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_GetSelectedProtocol(Dart_NativeArguments args)
void FUNCTION_NAME() SecureSocket_Handshake(Dart_NativeArguments args)
static Dart_Handle GetFilter(Dart_Handle filter_obj, Filter **filter)
DART_EXPORT Dart_Handle Dart_ListGetAt(Dart_Handle list, intptr_t index)
DART_EXPORT bool Dart_IsInstance(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t *value)
DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception)
DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value)
DART_EXPORT Dart_Handle Dart_NewStringFromUTF8(const uint8_t *utf8_array, intptr_t length)
DART_EXPORT void Dart_PropagateError(Dart_Handle handle)
DART_EXPORT Dart_FinalizableHandle Dart_NewFinalizableHandle(Dart_Handle object, void *peer, intptr_t external_allocation_size, Dart_HandleFinalizer callback)
DART_EXPORT void Dart_SetReturnValue(Dart_NativeArguments args, Dart_Handle retval)
DART_EXPORT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT Dart_Handle Dart_SetNativeInstanceField(Dart_Handle obj, int index, intptr_t value)
DART_EXPORT Dart_Handle Dart_NewExternalTypedData(Dart_TypedData_Type type, void *data, intptr_t length)
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
DART_EXPORT Dart_Handle Dart_InstanceGetType(Dart_Handle instance)
DART_EXPORT bool Dart_CloseNativePort(Dart_Port native_port_id)
DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value)
DART_EXPORT Dart_Handle Dart_InvokeClosure(Dart_Handle closure, int number_of_arguments, Dart_Handle *arguments)
DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception)
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT Dart_Port Dart_NewNativePort(const char *name, Dart_NativeMessageHandler handler, bool handle_concurrently)
DART_EXPORT Dart_Handle Dart_Null()
static int8_t data[kExtLength]
DART_EXPORT Dart_Handle Dart_StringToCString(Dart_Handle object, const char **cstr)
DART_EXPORT Dart_Handle Dart_SendPortGetId(Dart_Handle port, Dart_Port *port_id)
DART_EXPORT Dart_Handle Dart_HandleFromPersistent(Dart_PersistentHandle object)
DART_EXPORT bool Dart_IsClosure(Dart_Handle object)
DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_IntegerToInt64(Dart_Handle integer, int64_t *value)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service port
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
#define RETURN_IF_ERROR(handle)