5#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
8#if defined(DART_HOST_OS_MACOS)
12#include <Availability.h>
13#include <CoreFoundation/CoreFoundation.h>
14#include <Security/SecureTransport.h>
15#include <Security/Security.h>
17#include <openssl/ssl.h>
18#include <openssl/x509.h>
30 explicit ScopedCFType(
T obj) : obj_(obj) {}
33 if (obj_ !=
nullptr) {
38 T get() {
return obj_; }
39 T* ptr() {
return &obj_; }
40 const T get()
const {
return obj_; }
48 void set(
T obj) { obj_ = obj; }
61static void releaseObjects(
const void* val,
void* context) {
66ScopedCFType<CFMutableArrayRef>::~ScopedCFType() {
67 if (obj_ !=
nullptr) {
69 CFArrayApplyFunction(obj_, CFRangeMake(0, CFArrayGetCount(obj_)),
70 releaseObjects, &
count);
75typedef ScopedCFType<CFMutableArrayRef> ScopedCFMutableArrayRef;
76typedef ScopedCFType<CFDataRef> ScopedCFDataRef;
77typedef ScopedCFType<CFStringRef> ScopedCFStringRef;
78typedef ScopedCFType<SecPolicyRef> ScopedSecPolicyRef;
79typedef ScopedCFType<SecCertificateRef> ScopedSecCertificateRef;
80typedef ScopedCFType<SecTrustRef> ScopedSecTrustRef;
82const int kNumTrustEvaluateRequestParams = 5;
84static SecCertificateRef CreateSecCertificateFromX509(X509* cert) {
85 if (cert ==
nullptr) {
88 int length = i2d_X509(cert,
nullptr);
94 auto deb_cert = std::unique_ptr<unsigned char[]>(
new unsigned char[
length]);
95 unsigned char* temp = deb_cert.get();
96 if (i2d_X509(cert, &temp) !=
length) {
103 ScopedCFDataRef cert_buf(CFDataCreate(
nullptr, deb_cert.get(),
length));
104 return SecCertificateCreateWithData(
nullptr, cert_buf.get());
107static ssl_verify_result_t CertificateVerificationCallback(SSL* ssl,
108 uint8_t* out_alert) {
109 SSLFilter* filter =
static_cast<SSLFilter*
>(
111 SSLCertContext* context =
static_cast<SSLCertContext*
>(
114 const X509TrustState* certificate_trust_state =
115 filter->certificate_trust_state();
117 STACK_OF(X509)* chain = SSL_get_peer_full_cert_chain(ssl);
118 const intptr_t chain_length = sk_X509_num(chain);
120 chain_length == 0 ? nullptr : sk_X509_value(chain, chain_length - 1);
121 if (certificate_trust_state !=
nullptr) {
123 if (certificate_trust_state->x509() == root_cert) {
124 return certificate_trust_state->is_trusted() ? ssl_verify_ok
125 : ssl_verify_invalid;
130 ScopedCFMutableArrayRef cert_chain(
nullptr);
131 cert_chain.set(CFArrayCreateMutable(
nullptr, chain_length,
nullptr));
132 for (intptr_t
i = 0;
i < chain_length;
i++) {
133 auto cert = sk_X509_value(chain,
i);
134 ScopedSecCertificateRef sec_cert(CreateSecCertificateFromX509(cert));
135 if (sec_cert ==
nullptr) {
136 return ssl_verify_invalid;
138 CFArrayAppendValue(cert_chain.get(), sec_cert.release());
141 SSL_CTX* ssl_ctx = SSL_get_SSL_CTX(ssl);
142 X509_STORE*
store = SSL_CTX_get_cert_store(ssl_ctx);
145 ScopedCFMutableArrayRef trusted_certs(
146 CFArrayCreateMutable(
nullptr, 0,
nullptr));
149 for (
const X509_OBJECT* obj : X509_STORE_get0_objects(
store)) {
150 X509* ca = X509_OBJECT_get0_X509(obj);
151 ScopedSecCertificateRef cert(CreateSecCertificateFromX509(ca));
152 if (cert ==
nullptr) {
153 return ssl_verify_invalid;
155 CFArrayAppendValue(trusted_certs.get(), cert.release());
159 CFStringRef cfhostname =
nullptr;
160 if (filter->hostname() !=
nullptr) {
161 cfhostname = CFStringCreateWithCString(
nullptr, filter->hostname(),
162 kCFStringEncodingUTF8);
164 ScopedCFStringRef hostname(cfhostname);
165 ScopedSecPolicyRef
policy(
166 SecPolicyCreateSSL(filter->is_client(), hostname.get()));
169 ScopedSecTrustRef trust(
nullptr);
170 OSStatus status = SecTrustCreateWithCertificates(cert_chain.get(),
171 policy.get(), trust.ptr());
172 if (status != noErr) {
173 return ssl_verify_invalid;
178 if (CFArrayGetCount(trusted_certs.get()) > 0) {
179 status = SecTrustSetAnchorCertificates(trust.get(), trusted_certs.get());
180 if (status != noErr) {
181 return ssl_verify_invalid;
188 SecTrustSetAnchorCertificatesOnly(trust.get(), !context->trust_builtin());
189 if (status != noErr) {
190 return ssl_verify_invalid;
197 reinterpret_cast<intptr_t
>(trust.release());
202 reinterpret_cast<intptr_t
>(cert_chain.release());
207 reinterpret_cast<intptr_t
>(trusted_certs.release());
209 if (root_cert !=
nullptr) {
210 X509_up_ref(root_cert);
214 dart_cobject_root_cert.
value.
as_int64 =
reinterpret_cast<intptr_t
>(root_cert);
224 &dart_cobject_trusted_certs,
225 &dart_cobject_root_cert, &reply_send_port};
229 return ssl_verify_retry;
232static void postReply(
Dart_Port reply_port_id,
234 X509* certificate =
nullptr) {
242 reinterpret_cast<intptr_t
>(certificate);
253static void TrustEvaluateHandler(
Dart_Port dest_port_id,
262 usleep(2000 * 1000 );
266 if (request.Length() != kNumTrustEvaluateRequestParams) {
267 FATAL(
"Malformed trust evaluate message: got %" Pd
270 request.Length(), kNumTrustEvaluateRequestParams);
272 CObjectIntptr trust_cobject(request[0]);
273 ScopedSecTrustRef trust(
reinterpret_cast<SecTrustRef
>(trust_cobject.Value()));
274 CObjectIntptr cert_chain_cobject(request[1]);
275 ScopedCFMutableArrayRef cert_chain(
276 reinterpret_cast<CFMutableArrayRef
>(cert_chain_cobject.Value()));
277 CObjectIntptr trusted_certs_cobject(request[2]);
278 ScopedCFMutableArrayRef trusted_certs(
279 reinterpret_cast<CFMutableArrayRef
>(trusted_certs_cobject.Value()));
280 CObjectIntptr root_cert_cobject(request[3]);
281 X509* root_cert =
reinterpret_cast<X509*
>(root_cert_cobject.Value());
282 CObjectSendPort reply_port(request[4]);
283 Dart_Port reply_port_id = reply_port.Value();
285 SecTrustResultType trust_result;
287 usleep(3000 * 1000 );
294 bool res = SecTrustEvaluateWithError(trust.get(),
nullptr);
296 OSStatus status = SecTrustGetTrustResult(trust.get(), &trust_result);
298 postReply(reply_port_id,
299 status == noErr && (trust_result == kSecTrustResultProceed ||
300 trust_result == kSecTrustResultUnspecified),
305 SSL_set_custom_verify(ssl, SSL_VERIFY_PEER, CertificateVerificationCallback);
309 return &TrustEvaluateHandler;
void RegisterCallbacks(SSL *ssl)
static const char * root_certs_file()
TrustEvaluateHandlerFunc GetTrustEvaluateHandler() const
static const intptr_t kApproximateSize
static const char * root_certs_cache()
static bool long_ssl_cert_evaluation()
void set_trust_builtin(bool trust_builtin)
static int ssl_cert_context_index
static int filter_ssl_index
#define DART_WARN_UNUSED_RESULT
void(* TrustEvaluateHandlerFunc)(Dart_Port dest_port_id, Dart_CObject *message)
constexpr bool operator!=(Register r, LinkRegister lr)
constexpr bool operator==(Register r, LinkRegister)
DART_EXPORT bool Dart_PostCObject(Dart_Port port_id, Dart_CObject *message)
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 policy
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 set
const myers::Point & get(const myers::Segment &)
struct _Dart_CObject::@86::@87 as_send_port
union _Dart_CObject::@86 value
struct _Dart_CObject::@86::@89 as_array
struct _Dart_CObject ** values