diff --git a/mobile/.bazelproject b/mobile/.bazelproject
new file mode 100644
index 000000000000..abae58ffe896
--- /dev/null
+++ b/mobile/.bazelproject
@@ -0,0 +1,7 @@
+# Uncomment the examples you'd like to use!
+import examples/kotlin/hello_world/.bazelproject
+import examples/java/hello_world/.bazelproject
+import test/kotlin/apps/baseline/.bazelproject
+import test/kotlin/apps/experimental/.bazelproject
+
+android_sdk_platform: android-31
diff --git a/mobile/.bazelrc b/mobile/.bazelrc
index c1581d320d11..242fa4760b0b 100644
--- a/mobile/.bazelrc
+++ b/mobile/.bazelrc
@@ -101,7 +101,7 @@ build:tsan-dev --test_env="TSAN_OPTIONS=report_atomic_races=0"
build:release-common --define=no_debug_info=1
# Compile releases optimizing for size (eg -Os, etc).
-build:release-common --config=sizeopt
+build:release-common --config=sizeopt --define=admin_functionality=disabled
# Set default symbols visibility to hidden to reduce .dynstr and the symbol table size
build:release-common --copt=-fvisibility=hidden
diff --git a/mobile/dist/envoy-pom.xml b/mobile/dist/envoy-pom.xml
deleted file mode 100755
index e98f5e184aa5..000000000000
--- a/mobile/dist/envoy-pom.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-
-
- 4.0.0
-
- io.envoyproxy.envoymobile
- envoy
- LOCAL-SNAPSHOT
- aar
-
-
-
-
- Envoy Mobile
- Client networking libraries based on the Envoy project.
- https://github.com/envoyproxy/envoy-mobile
-
-
-
- The Apache Software License, Version 2.0
- http://www.apache.org/licenses/LICENSE-2.0.txt
- repo
-
-
-
-
- buildbreaker
- Alan Chiu
- awlchiu@gmail.com
-
-
- rebello95
- Michael Rebello
- me@michaelrebello.com
-
-
- junr03
- Jose Ulises Nino Rivera
- jnino@lyft.com
-
-
- goaway
- Mike Schore
- mike.schore@gmail.com
-
-
-
- https://github.com/envoyproxy/envoy-mobile
- scm:git:git@github.com:envoyproxy/envoy-mobile.git
- scm:git:git@github.com:envoyproxy/envoy-mobile.git
- HEAD
-
-
-
diff --git a/mobile/dist/envoy.aar b/mobile/dist/envoy.aar
deleted file mode 100755
index be7f3ff691fa..000000000000
Binary files a/mobile/dist/envoy.aar and /dev/null differ
diff --git a/mobile/docs/root/intro/version_history.rst b/mobile/docs/root/intro/version_history.rst
index e732e84f4453..bfb3119212f4 100644
--- a/mobile/docs/root/intro/version_history.rst
+++ b/mobile/docs/root/intro/version_history.rst
@@ -10,6 +10,7 @@ Breaking changes:
- build: building on macOS now requires Xcode 14.1. (:issue:`#2664 <2664>`)
- iOS: remove experimental option to force all connections to use IPv6.
- kotlin: always use ``getaddrinfo`` DNS resolver. Remove ``addDNSFallbackNameservers``, ``enableDNSFilterUnroutableFamilies``, and ``enableDNSUseSystemResolver`` methods from the Kotlin engine builder. (:issue:`#2618 <2618>`)
+- Envoy Mobile's release builds compile without admin support by default. (``--define=admin_functionality=disabled``) (:issue`#2693 <2693>`)
Bugfixes:
diff --git a/mobile/experimental/swift/QUICStreamTest.swift b/mobile/experimental/swift/QUICStreamTest.swift
new file mode 100644
index 000000000000..f4e941c87b0a
--- /dev/null
+++ b/mobile/experimental/swift/QUICStreamTest.swift
@@ -0,0 +1,189 @@
+import Envoy
+import EnvoyEngine
+import Foundation
+import XCTest
+
+final class QUICStreamTests: XCTestCase {
+ func testQUICStream() throws {
+ // swiftlint:disable:next line_length
+ let hcmType = "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
+ // swiftlint:disable:next line_length
+ let quicDownstreamType = "type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicDownstreamTransport"
+ // swiftlint:disable:next line_length
+ let quicUpstreamType = "type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicUpstreamTransport"
+ let config =
+ """
+ static_resources:
+ listeners:
+ - name: h3_remote_listener
+ address:
+ socket_address: { protocol: UDP, address: 127.0.0.1, port_value: 10101 }
+ reuse_port: true
+ udp_listener_config:
+ quic_options: {}
+ downstream_socket_config:
+ prefer_gro: true
+ filter_chains:
+ transport_socket:
+ name: envoy.transport_sockets.quic
+ typed_config:
+ "@type": \(quicDownstreamType)
+ downstream_tls_context:
+ common_tls_context:
+ alpn_protocols: h3
+ tls_certificates:
+ certificate_chain:
+ inline_string: |
+ -----BEGIN CERTIFICATE-----
+ MIIEbDCCA1SgAwIBAgIUJuVBh0FKfFgIcO++ljWm7D47eYUwDQYJKoZIhvcNAQEL
+ BQAwdjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
+ DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsMEEx5ZnQgRW5n
+ aW5lZXJpbmcxEDAOBgNVBAMMB1Rlc3QgQ0EwHhcNMjAwODA1MTkxNjAxWhcNMjIw
+ ODA1MTkxNjAxWjCBpjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx
+ FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBEx5ZnQxGTAXBgNVBAsM
+ EEx5ZnQgRW5naW5lZXJpbmcxGjAYBgNVBAMMEVRlc3QgQmFja2VuZCBUZWFtMSQw
+ IgYJKoZIhvcNAQkBFhViYWNrZW5kLXRlYW1AbHlmdC5jb20wggEiMA0GCSqGSIb3
+ DQEBAQUAA4IBDwAwggEKAoIBAQC9JgaI7hxjPM0tsUna/QmivBdKbCrLnLW9Teak
+ RH/Ebg68ovyvrRIlybDT6XhKi+iVpzVY9kqxhGHgrFDgGLBakVMiYJ5EjIgHfoo4
+ UUAHwIYbunJluYCgANzpprBsvTC/yFYDVMqUrjvwHsoYYVm36io994k9+t813b70
+ o0l7/PraBsKkz8NcY2V2mrd/yHn/0HAhv3hl6iiJme9yURuDYQrae2ACSrQtsbel
+ KwdZ/Re71Z1awz0OQmAjMa2HuCop+Q/1QLnqBekT5+DH1qKUzJ3Jkq6NRkERXOpi
+ 87j04rtCBteCogrO67qnuBZ2lH3jYEMb+lQdLkyNMLltBSdLAgMBAAGjgcAwgb0w
+ DAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIG
+ CCsGAQUFBwMBMEEGA1UdEQQ6MDiGHnNwaWZmZTovL2x5ZnQuY29tL2JhY2tlbmQt
+ dGVhbYIIbHlmdC5jb22CDHd3dy5seWZ0LmNvbTAdBgNVHQ4EFgQU2XcTZbc0xKZf
+ gNVKSvAbMZJCBoYwHwYDVR0jBBgwFoAUlkvaLFO0vpXGk3Pip6SfLg1yGIcwDQYJ
+ KoZIhvcNAQELBQADggEBAFW05aca3hSiEz/g593GAV3XP4lI5kYUjGjbPSy/HmLr
+ rdv/u3bGfacywAPo7yld+arMzd35tIYEqnhoq0+/OxPeyhwZXVVUatg5Oknut5Zv
+ 2+8l+mVW+8oFCXRqr2gwc8Xt4ByYN+HaNUYfoucnjDplOPukkfSuRhbxqnkhA14v
+ Lri2EbISX14sXf2VQ9I0dkm1hXUxiO0LlA1Z7tvJac9zPSoa6Oljke4D1iH2jzwF
+ Yn7S/gGvVQgkTmWrs3S3TGyBDi4GTDhCF1R+ESvXz8z4UW1MrCSdYUXbRtsT7sbE
+ CjlFYuUyxCi1oe3IHCeXVDo/bmzwGQPDuF3WaDNSYWU=
+ -----END CERTIFICATE-----
+ private_key:
+ inline_string: |
+ -----BEGIN RSA PRIVATE KEY-----
+ MIIEpAIBAAKCAQEAvSYGiO4cYzzNLbFJ2v0JorwXSmwqy5y1vU3mpER/xG4OvKL8
+ r60SJcmw0+l4Sovolac1WPZKsYRh4KxQ4BiwWpFTImCeRIyIB36KOFFAB8CGG7py
+ ZbmAoADc6aawbL0wv8hWA1TKlK478B7KGGFZt+oqPfeJPfrfNd2+9KNJe/z62gbC
+ pM/DXGNldpq3f8h5/9BwIb94ZeooiZnvclEbg2EK2ntgAkq0LbG3pSsHWf0Xu9Wd
+ WsM9DkJgIzGth7gqKfkP9UC56gXpE+fgx9ailMydyZKujUZBEVzqYvO49OK7QgbX
+ gqIKzuu6p7gWdpR942BDG/pUHS5MjTC5bQUnSwIDAQABAoIBADEMwlcSAFSPuNln
+ hzJ9udj0k8md4T8p5Usw/2WLyeJDdBjg30wjQniAJBXgDmyueWMNmFz4iYgdP1CG
+ /vYOEPV7iCZ7Da/TDZd77hYKo+MevuhD4lSU1VEoyCDjNA8OxKyHJB77BwmlYS+0
+ nE3UOPLji47EOVfUTbvnRBSmn3DCSHkQiRIUP1xMivoiZgKJn+D+FxSMwwiq2pQR
+ 5tdo7nh2A8RxlYUbaD6i4poUB26HVm8vthXahNEkLpXQOz8MWRzs6xOdDHRzi9kT
+ ItRLa4A/3LIATqviQ2EpwcALHXcULcNUMTHORC1EHPvheWR5nLuRllYzN4ReoeHC
+ 3+A5KEkCgYEA52rlh/22/rLckCWugjyJic17vkg46feSOGhjuP2LelrIxNlg491y
+ o28n8lQPSVnEp3/sT7Y3quVvdboq4DC9LTzq52f6/mCYh9UQRpljuSmFqC2MPG46
+ Zl5KLEVLzhjC8aTWkhVINSpz9vauXderOpFYlPW32lnRTjJWE276kj8CgYEA0T2t
+ ULnn7TBvRSpmeWzEBA5FFo2QYkYvwrcVe0pfUltV6pf05xUmMXYFjpezSTEmPhh6
+ +dZdhwxDk+6j8Oo61rTWucDsIqMj5ZT1hPNph8yQtb5LRlRbLGVrirU9Tp7xTgMq
+ 3uRA2Eka1d98dDBsEbMIVFSZ2MX3iezSGRL6j/UCgYEAxZQ82HjEDn2DVwb1EXjC
+ LQdliTZ8cTXQf5yQ19aRiSuNkpPN536ga+1xe7JNQuEDx8auafg3Ww98tFT4WmUC
+ f2ctX9klMJ4kXISK2twHioVq+gW5X7b04YXLajTX3eTCPDHyiNLmzY2raMWAZdrG
+ 9MA3kyafjCt3Sn4rg3gTM10CgYEAtJ8WRpJEd8aQttcUIItYZdvfnclUMtE9l0su
+ GwCnalN3xguol/X0w0uLHn0rgeoQhhfhyFtY3yQiDcg58tRvODphBXZZIMlNSnic
+ vEjW9ygKXyjGmA5nqdpezB0JsB2aVep8Dm5g35Ozu52xNCc8ksbGUO265Jp3xbMN
+ 5iEw9CUCgYBmfoPnJwzA5S1zMIqESUdVH6p3UwHU/+XTY6JHAnEVsE+BuLe3ioi7
+ 6dU4rFd845MCkunBlASLV8MmMbod9xU0vTVHPtmANaUCPxwUIxXQket09t19Dzg7
+ A23sE+5myXtcfz6YrPhbLkijV4Nd7fmecodwDckvpBaWTMrv52/Www==
+ -----END RSA PRIVATE KEY-----
+ filters:
+ - name: envoy.filters.network.http_connection_manager
+ typed_config:
+ "@type": \(hcmType)
+ codec_type: HTTP3
+ stat_prefix: remote_hcm
+ route_config:
+ name: remote_route
+ virtual_hosts:
+ - name: remote_service
+ domains: ["*"]
+ routes:
+ - match: { prefix: "/" }
+ direct_response: { status: 200 }
+ http3_protocol_options:
+ http_filters:
+ - name: envoy.router
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ - name: base_api_listener
+ address:
+ socket_address: { protocol: TCP, address: 0.0.0.0, port_value: 10000 }
+ api_listener:
+ api_listener:
+ "@type": \(hcmType)
+ stat_prefix: api_hcm
+ route_config:
+ name: api_router
+ virtual_hosts:
+ - name: api
+ domains: ["*"]
+ routes:
+ - match: { prefix: "/" }
+ route: { host_rewrite_literal: lyft.com, cluster: h3_remote }
+ http_filters:
+ - name: envoy.router
+ typed_config:
+ "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+ clusters:
+ - name: h3_remote
+ connect_timeout: 10s
+ type: STATIC
+ dns_lookup_family: V4_ONLY
+ lb_policy: ROUND_ROBIN
+ load_assignment:
+ cluster_name: h3_remote
+ endpoints:
+ - lb_endpoints:
+ - endpoint:
+ address:
+ socket_address: { address: 127.0.0.1, port_value: 10101 }
+ typed_extension_protocol_options:
+ envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
+ "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
+ explicit_http_config:
+ http3_protocol_options: {}
+ common_http_protocol_options:
+ idle_timeout: 1s
+ transport_socket:
+ name: envoy.transport_sockets.quic
+ typed_config:
+ "@type": \(quicUpstreamType)
+ upstream_tls_context:
+ sni: lyft.com
+ """
+ let expectation = self.expectation(description: "Complete response received.")
+
+ let client = EngineBuilder(yaml: config)
+ .addLogLevel(.trace)
+ .build()
+ .streamClient()
+
+ let requestHeaders = RequestHeadersBuilder(method: .get, scheme: "https",
+ authority: "lyft.com", path: "/test")
+ .build()
+
+ client
+ .newStreamPrototype()
+ .setOnResponseHeaders { responseHeaders, endStream, _ in
+ XCTAssertEqual(200, responseHeaders.httpStatus)
+ if endStream {
+ expectation.fulfill()
+ }
+ }
+ .setOnResponseData { _, endStream, _ in
+ if endStream {
+ expectation.fulfill()
+ }
+ }
+ .setOnError { _, _ in
+ XCTFail("Unexpected error")
+ }
+ .start()
+ .sendHeaders(requestHeaders, endStream: true)
+
+ XCTAssertEqual(XCTWaiter.wait(for: [expectation], timeout: 1), .completed)
+ }
+}
diff --git a/mobile/library/cc/engine_builder.cc b/mobile/library/cc/engine_builder.cc
index 7133c398104e..35fcda4fc669 100644
--- a/mobile/library/cc/engine_builder.cc
+++ b/mobile/library/cc/engine_builder.cc
@@ -70,8 +70,7 @@ EngineBuilder& EngineBuilder::addDnsQueryTimeoutSeconds(int dns_query_timeout_se
return *this;
}
-EngineBuilder&
-EngineBuilder::addDnsPreresolveHostnames(std::string dns_preresolve_hostnames) {
+EngineBuilder& EngineBuilder::addDnsPreresolveHostnames(std::string dns_preresolve_hostnames) {
this->dns_preresolve_hostnames_ = std::move(dns_preresolve_hostnames);
return *this;
}
@@ -207,8 +206,7 @@ EngineBuilder& EngineBuilder::addStringAccessor(std::string name,
return *this;
}
-EngineBuilder& EngineBuilder::addNativeFilter(std::string name,
- std::string typed_config) {
+EngineBuilder& EngineBuilder::addNativeFilter(std::string name, std::string typed_config) {
native_filter_chain_.emplace_back(std::move(name), std::move(typed_config));
return *this;
}
diff --git a/mobile/library/cc/headers_builder.cc b/mobile/library/cc/headers_builder.cc
index a28cc69731af..12a30442e91a 100644
--- a/mobile/library/cc/headers_builder.cc
+++ b/mobile/library/cc/headers_builder.cc
@@ -11,12 +11,11 @@ HeadersBuilder& HeadersBuilder::add(std::string name, std::string value) {
return *this;
}
-HeadersBuilder& HeadersBuilder::set(std::string name,
- std::vector values) {
+HeadersBuilder& HeadersBuilder::set(std::string name, std::vector values) {
if (this->isRestrictedHeader(name)) {
return *this;
}
- this->headers_[std::move(name)] = values;
+ this->headers_[std::move(name)] = std::move(values);
return *this;
}
@@ -30,8 +29,7 @@ HeadersBuilder& HeadersBuilder::remove(const std::string& name) {
HeadersBuilder::HeadersBuilder() {}
-HeadersBuilder& HeadersBuilder::internalSet(std::string name,
- std::vector values) {
+HeadersBuilder& HeadersBuilder::internalSet(std::string name, std::vector values) {
this->headers_[std::move(name)] = std::move(values);
return *this;
}
diff --git a/mobile/library/cc/request_headers_builder.cc b/mobile/library/cc/request_headers_builder.cc
index 595e66f891b0..7302dd579098 100644
--- a/mobile/library/cc/request_headers_builder.cc
+++ b/mobile/library/cc/request_headers_builder.cc
@@ -3,10 +3,8 @@
namespace Envoy {
namespace Platform {
-RequestHeadersBuilder::RequestHeadersBuilder(RequestMethod request_method,
- std::string scheme,
- std::string authority,
- std::string path) {
+RequestHeadersBuilder::RequestHeadersBuilder(RequestMethod request_method, std::string scheme,
+ std::string authority, std::string path) {
this->internalSet(":method", {requestMethodToString(request_method)});
this->internalSet(":scheme", {std::move(scheme)});
this->internalSet(":authority", {std::move(authority)});
diff --git a/mobile/library/cc/request_headers_builder.h b/mobile/library/cc/request_headers_builder.h
index 6fe0f44c96f3..c5bc245b1ad3 100644
--- a/mobile/library/cc/request_headers_builder.h
+++ b/mobile/library/cc/request_headers_builder.h
@@ -16,8 +16,8 @@ struct RetryPolicy;
class RequestHeadersBuilder : public HeadersBuilder {
public:
- RequestHeadersBuilder(RequestMethod request_method, std::string scheme,
- std::string authority, std::string path);
+ RequestHeadersBuilder(RequestMethod request_method, std::string scheme, std::string authority,
+ std::string path);
RequestHeadersBuilder& addRetryPolicy(const RetryPolicy& retry_policy);
RequestHeadersBuilder& addUpstreamHttpProtocol(UpstreamHttpProtocol upstream_http_protocol);
diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/c_types.h b/mobile/library/common/extensions/cert_validator/platform_bridge/c_types.h
index 3925ebe13bfb..cfaf4c036c9b 100644
--- a/mobile/library/common/extensions/cert_validator/platform_bridge/c_types.h
+++ b/mobile/library/common/extensions/cert_validator/platform_bridge/c_types.h
@@ -25,9 +25,9 @@ typedef envoy_cert_validation_result (*envoy_validate_cert_f)(const envoy_data*
const char* host_name);
/**
- * Function signature for calling into platform APIs to clean up after validation completion.
+ * Function signature for calling into platform APIs to clean up after validation is complete.
*/
-typedef void (*envoy_release_validator_f)();
+typedef void (*envoy_validation_cleanup_f)();
#ifdef __cplusplus
} // function pointers
@@ -38,5 +38,5 @@ typedef void (*envoy_release_validator_f)();
*/
typedef struct {
envoy_validate_cert_f validate_cert;
- envoy_release_validator_f release_validator;
+ envoy_validation_cleanup_f validation_cleanup;
} envoy_cert_validator;
diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/config.h b/mobile/library/common/extensions/cert_validator/platform_bridge/config.h
index 435f5bc949a6..46ae690785c1 100644
--- a/mobile/library/common/extensions/cert_validator/platform_bridge/config.h
+++ b/mobile/library/common/extensions/cert_validator/platform_bridge/config.h
@@ -2,6 +2,7 @@
#include "source/extensions/transport_sockets/tls/cert_validator/factory.h"
+#include "library/common/extensions/cert_validator/platform_bridge/platform_bridge.pb.h"
#include "library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h"
#include "library/common/extensions/cert_validator/platform_bridge/platform_bridge.pb.h"
@@ -10,7 +11,9 @@ namespace Extensions {
namespace TransportSockets {
namespace Tls {
+
class PlatformBridgeCertValidatorFactory : public CertValidatorFactory, public Config::TypedFactory {
+
public:
CertValidatorPtr createCertValidator(const Envoy::Ssl::CertificateValidationContextConfig* config,
SslStats& stats, TimeSource& time_source) override;
@@ -19,6 +22,7 @@ class PlatformBridgeCertValidatorFactory : public CertValidatorFactory, public C
return "envoy_mobile.cert_validator.platform_bridge_cert_validator";
}
ProtobufTypes::MessagePtr createEmptyConfigProto() override {
+
return std::make_unique();
}
std::string category() const override { return "envoy.tls.cert_validator"; }
diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto
index c56bcbe72364..e44e0131512a 100644
--- a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto
+++ b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge.proto
@@ -2,4 +2,5 @@ syntax = "proto3";
package envoy_mobile.extensions.cert_validator.platform_bridge;
-message PlatformBridgeCertValidator {}
+message PlatformBridgeCertValidator {
+}
diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc
index b4e025445af1..4f1d366d0e46 100644
--- a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc
+++ b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.cc
@@ -14,15 +14,14 @@ namespace Tls {
PlatformBridgeCertValidator::PlatformBridgeCertValidator(
const Envoy::Ssl::CertificateValidationContextConfig* config, SslStats& stats,
const envoy_cert_validator* platform_validator)
- : config_(config), stats_(stats), platform_validator_(platform_validator) {
+ : allow_untrusted_certificate_(config != nullptr &&
+ config->trustChainVerification() ==
+ envoy::extensions::transport_sockets::tls::v3::
+ CertificateValidationContext::ACCEPT_UNTRUSTED),
+ platform_validator_(platform_validator), stats_(stats) {
ENVOY_BUG(config != nullptr && config->caCert().empty() &&
config->certificateRevocationList().empty(),
"Invalid certificate validation context config.");
- if (config_ != nullptr) {
- allow_untrusted_certificate_ = config_->trustChainVerification() ==
- envoy::extensions::transport_sockets::tls::v3::
- CertificateValidationContext::ACCEPT_UNTRUSTED;
- }
}
PlatformBridgeCertValidator::~PlatformBridgeCertValidator() {
@@ -34,17 +33,12 @@ PlatformBridgeCertValidator::~PlatformBridgeCertValidator() {
}
}
-int PlatformBridgeCertValidator::initializeSslContexts(std::vector /*contexts*/,
- bool /*handshaker_provides_certificates*/) {
- return SSL_VERIFY_PEER;
-}
-
ValidationResults PlatformBridgeCertValidator::doVerifyCertChain(
STACK_OF(X509) & cert_chain, Ssl::ValidateResultCallbackPtr callback,
Ssl::SslExtendedSocketInfo* ssl_extended_info,
const Network::TransportSocketOptionsConstSharedPtr& transport_socket_options,
SSL_CTX& /*ssl_ctx*/, const CertValidator::ExtraValidationContext& /*validation_context*/,
- bool is_server, absl::string_view host_name) {
+ bool is_server, absl::string_view hostname) {
ASSERT(!is_server);
if (sk_X509_num(&cert_chain) == 0) {
if (ssl_extended_info) {
@@ -78,30 +72,37 @@ ValidationResults PlatformBridgeCertValidator::doVerifyCertChain(
!transport_socket_options->verifySubjectAltNameListOverride().empty()) {
host = transport_socket_options->verifySubjectAltNameListOverride()[0];
} else {
- host = host_name;
+ host = hostname;
+ }
+
+ std::vector subject_alt_names;
+ if (transport_socket_options != nullptr) {
+ subject_alt_names = transport_socket_options->verifySubjectAltNameListOverride();
+ } else {
+ subject_alt_names = {std::string(hostname)};
}
- PendingValidation validation(*this, std::move(certs), host, std::move(transport_socket_options),
- std::move(callback));
- auto insert_result = validations_.insert(std::move(validation));
- ASSERT(insert_result.second);
- PendingValidation& ref = const_cast(*insert_result.first);
- std::thread verification_thread(&PendingValidation::verifyCertsByPlatform, &ref);
+
+ auto validation = std::make_unique(
+ *this, std::move(certs), host, std::move(subject_alt_names), std::move(callback));
+ PendingValidation* validation_ptr = validation.get();
+ validations_.insert(std::move(validation));
+ std::thread verification_thread(&PendingValidation::verifyCertsByPlatform, validation_ptr);
std::thread::id thread_id = verification_thread.get_id();
validation_threads_[thread_id] = std::move(verification_thread);
return {ValidationResults::ValidationStatus::Pending, absl::nullopt, absl::nullopt};
}
void PlatformBridgeCertValidator::verifyCertChainByPlatform(
- std::vector& cert_chain, const std::string& host_name,
+ const std::vector& cert_chain, const std::string& hostname,
const std::vector& subject_alt_names, PendingValidation& pending_validation) {
ASSERT(!cert_chain.empty());
- ENVOY_LOG(trace, "Start verifyCertChainByPlatform for host {}", host_name);
+ ENVOY_LOG(trace, "Start verifyCertChainByPlatform for host {}", hostname);
// This is running in a stand alone thread other than the engine thread.
envoy_data leaf_cert_der = cert_chain[0];
bssl::UniquePtr leaf_cert(d2i_X509(
nullptr, const_cast(&leaf_cert_der.bytes), leaf_cert_der.length));
envoy_cert_validation_result result =
- platform_validator_->validate_cert(cert_chain.data(), cert_chain.size(), host_name.c_str());
+ platform_validator_->validate_cert(cert_chain.data(), cert_chain.size(), hostname.c_str());
bool success = result.result == ENVOY_SUCCESS;
if (!success) {
ENVOY_LOG(debug, result.error_details);
@@ -127,40 +128,37 @@ void PlatformBridgeCertValidator::verifyCertChainByPlatform(
}
void PlatformBridgeCertValidator::PendingValidation::verifyCertsByPlatform() {
- parent_.verifyCertChainByPlatform(
- certs_, host_name_,
- (transport_socket_options_ != nullptr
- ? transport_socket_options_->verifySubjectAltNameListOverride()
- : std::vector{host_name_}),
- *this);
+ parent_.verifyCertChainByPlatform(certs_, hostname_, subject_alt_names_, *this);
}
void PlatformBridgeCertValidator::PendingValidation::postVerifyResultAndCleanUp(
bool success, absl::string_view error_details, uint8_t tls_alert,
OptRef error_counter) {
+ ENVOY_LOG(trace,
+ "Finished platform cert validation for {}, post result callback to network thread",
+ hostname_);
+
+ if (parent_.platform_validator_->validation_cleanup) {
+ parent_.platform_validator_->validation_cleanup();
+ }
std::weak_ptr weak_alive_indicator(parent_.alive_indicator_);
+
+ // Once this task runs, `this` will be deleted so this must be the last statement in the file.
result_callback_->dispatcher().post([this, weak_alive_indicator, success,
error = std::string(error_details), tls_alert, error_counter,
thread_id = std::this_thread::get_id()]() {
if (weak_alive_indicator.expired()) {
return;
}
- ENVOY_LOG(trace, "Got validation result for {} from platform", host_name_);
+ ENVOY_LOG(trace, "Got validation result for {} from platform", hostname_);
parent_.validation_threads_[thread_id].join();
parent_.validation_threads_.erase(thread_id);
if (error_counter.has_value()) {
const_cast(error_counter.ref()).inc();
}
result_callback_->onCertValidationResult(success, error, tls_alert);
- parent_.validations_.erase(*this);
+ parent_.validations_.erase(this);
});
- ENVOY_LOG(trace,
- "Finished platform cert validation for {}, post result callback to network thread",
- host_name_);
-
- if (parent_.platform_validator_->release_validator) {
- parent_.platform_validator_->release_validator();
- }
}
} // namespace Tls
diff --git a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h
index ffa0c23fd90b..dc31d2dfeaed 100644
--- a/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h
+++ b/mobile/library/common/extensions/cert_validator/platform_bridge/platform_bridge_cert_validator.h
@@ -56,63 +56,53 @@ class PlatformBridgeCertValidator : public CertValidator, Logger::Loggable contexts,
- bool handshaker_provides_certificates) override;
+ absl::string_view hostname) override;
+ // Returns SSL_VERIFY_PEER so that doVerifyCertChain() will be called from the TLS stack.
+ int initializeSslContexts(std::vector /*contexts*/,
+ bool /*handshaker_provides_certificates*/) override {
+ return SSL_VERIFY_PEER;
+ }
private:
class PendingValidation {
public:
PendingValidation(PlatformBridgeCertValidator& parent, std::vector certs,
- absl::string_view host_name,
- const Network::TransportSocketOptionsConstSharedPtr transport_socket_options,
+ absl::string_view hostname, std::vector subject_alt_names,
Ssl::ValidateResultCallbackPtr result_callback)
- : parent_(parent), certs_(std::move(certs)), host_name_(host_name),
- result_callback_(std::move(result_callback)),
- transport_socket_options_(std::move(transport_socket_options)) {}
+ : parent_(parent), certs_(std::move(certs)), hostname_(hostname),
+ subject_alt_names_(std::move(subject_alt_names)),
+ result_callback_(std::move(result_callback)) {}
+
+ // Ensure that this class is never moved or copied to guarantee pointer stability.
+ PendingValidation(const PendingValidation&) = delete;
+ PendingValidation(PendingValidation&&) = delete;
+ // Calls into platform APIs in a stand-alone thread to verify the given certs.
+ // Once the validation is done, the result will be posted back to the current
+ // thread to trigger callback and update verify stats.
void verifyCertsByPlatform();
void postVerifyResultAndCleanUp(bool success, absl::string_view error_details,
uint8_t tls_alert, OptRef error_counter);
- struct Hash {
- size_t operator()(const PendingValidation& p) const {
- return reinterpret_cast(p.result_callback_.get());
- }
- };
- struct Eq {
- bool operator()(const PendingValidation& a, const PendingValidation& b) const {
- return a.result_callback_.get() == b.result_callback_.get();
- }
- };
-
private:
- Event::SchedulableCallbackPtr next_iteration_callback_;
PlatformBridgeCertValidator& parent_;
- std::vector certs_;
- std::string host_name_;
+ const std::vector certs_;
+ const std::string hostname_;
+ const std::vector subject_alt_names_;
Ssl::ValidateResultCallbackPtr result_callback_;
- const Network::TransportSocketOptionsConstSharedPtr transport_socket_options_;
};
- // Calls into platform APIs in a stand-alone thread to verify the given certs.
- // Once the validation is done, the result will be posted back to the current
- // thread to trigger callback and update verify stats.
- void verifyCertChainByPlatform(std::vector& cert_chain, const std::string& host_name,
+ void verifyCertChainByPlatform(const std::vector& cert_chain,
+ const std::string& hostname,
const std::vector& subject_alt_names,
PendingValidation& pending_validation);
- const Envoy::Ssl::CertificateValidationContextConfig* config_;
- SslStats& stats_;
- bool allow_untrusted_certificate_ = false;
- // latches the platform extension API.
+ const bool allow_untrusted_certificate_;
const envoy_cert_validator* platform_validator_;
+ SslStats& stats_;
absl::flat_hash_map validation_threads_;
- absl::flat_hash_set
- validations_;
+ absl::flat_hash_set> validations_;
std::shared_ptr alive_indicator_{new size_t(1)};
};
diff --git a/mobile/library/common/jni/android_network_utility.cc b/mobile/library/common/jni/android_network_utility.cc
index 8711728646fc..7842835048a5 100644
--- a/mobile/library/common/jni/android_network_utility.cc
+++ b/mobile/library/common/jni/android_network_utility.cc
@@ -144,6 +144,6 @@ static envoy_cert_validation_result verify_x509_cert_chain(const envoy_data* cer
envoy_cert_validator* get_android_cert_validator_api() {
envoy_cert_validator* api = (envoy_cert_validator*)safe_malloc(sizeof(envoy_cert_validator));
api->validate_cert = verify_x509_cert_chain;
- api->release_validator = jvm_detach_thread;
+ api->validation_cleanup = jvm_detach_thread;
return api;
}
diff --git a/mobile/library/common/network/apple_platform_cert_verifier.cc b/mobile/library/common/network/apple_platform_cert_verifier.cc
index 26fcb50e2ac8..e77b693cca86 100644
--- a/mobile/library/common/network/apple_platform_cert_verifier.cc
+++ b/mobile/library/common/network/apple_platform_cert_verifier.cc
@@ -111,7 +111,7 @@ extern "C" {
void register_apple_platform_cert_verifier() {
envoy_cert_validator* api = (envoy_cert_validator*)safe_malloc(sizeof(envoy_cert_validator));
api->validate_cert = verify_cert;
- api->release_validator = NULL;
+ api->validation_cleanup = NULL;
register_platform_api("platform_cert_validator", api);
}
diff --git a/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt b/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt
index b1121f166516..e1e2ef0a1bf1 100644
--- a/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt
+++ b/mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt
@@ -560,6 +560,9 @@ open class EngineBuilder(
* used for development/debugging purposes only. Enabling it in production may open
* your app to security vulnerabilities.
*
+ * Note this will not work with the default production build, as it builds with admin
+ * functionality disabled via --define=admin_functionality=disabled
+ *
* @return this builder.
*/
fun enableAdminInterface(): EngineBuilder {
diff --git a/mobile/library/proguard.txt b/mobile/library/proguard.txt
index fa5602b64dcd..bf717065f448 100644
--- a/mobile/library/proguard.txt
+++ b/mobile/library/proguard.txt
@@ -15,6 +15,10 @@
;
}
+-keep, includedescriptorclasses class org.chromium.net.AndroidCertVerifyResult {
+ ;
+}
+
-keep, includedescriptorclasses class io.envoyproxy.envoymobile.engine.types.EnvoyEventTracker {
;
}
diff --git a/mobile/library/swift/EngineBuilder.swift b/mobile/library/swift/EngineBuilder.swift
index 450b756a3aa9..98248dd9863b 100644
--- a/mobile/library/swift/EngineBuilder.swift
+++ b/mobile/library/swift/EngineBuilder.swift
@@ -487,6 +487,9 @@ open class EngineBuilder: NSObject {
/// used for development/debugging purposes only. Enabling it in production may open
/// your app to security vulnerabilities.
///
+ /// Note this will not work with the default production build, as it builds with admin
+ /// functionality disabled via --define=admin_functionality=disabled
+ ///
/// - returns: This builder.
@discardableResult
public func enableAdminInterface() -> Self {
diff --git a/mobile/test/common/integration/base_client_integration_test.cc b/mobile/test/common/integration/base_client_integration_test.cc
index d7665187ac9d..7ac8701454d2 100644
--- a/mobile/test/common/integration/base_client_integration_test.cc
+++ b/mobile/test/common/integration/base_client_integration_test.cc
@@ -6,8 +6,10 @@
#include "gtest/gtest.h"
#include "library/cc/bridge_utility.h"
+#include "library/cc/log_level.h"
#include "library/common/config/internal.h"
#include "library/common/http/header_utility.h"
+#include "spdlog/spdlog.h"
namespace Envoy {
namespace {
@@ -52,6 +54,31 @@ std::string defaultConfig() {
return config_str;
}
+// Gets the spdlog level from the test options and converts it to the Platform::LogLevel used by
+// the Envoy Mobile engine.
+Platform::LogLevel getPlatformLogLevelFromOptions() {
+ switch (TestEnvironment::getOptions().logLevel()) {
+ case spdlog::level::level_enum::trace:
+ return Platform::LogLevel::trace;
+ case spdlog::level::level_enum::debug:
+ return Platform::LogLevel::debug;
+ case spdlog::level::level_enum::info:
+ return Platform::LogLevel::info;
+ case spdlog::level::level_enum::warn:
+ return Platform::LogLevel::warn;
+ case spdlog::level::level_enum::err:
+ return Platform::LogLevel::error;
+ case spdlog::level::level_enum::critical:
+ return Platform::LogLevel::critical;
+ case spdlog::level::level_enum::off:
+ return Platform::LogLevel::off;
+ default:
+ ENVOY_LOG_MISC(warn, "Couldn't map spdlog level {}. Using `info` level.",
+ TestEnvironment::getOptions().logLevel());
+ return Platform::LogLevel::info;
+ }
+}
+
} // namespace
BaseClientIntegrationTest::BaseClientIntegrationTest(Network::Address::IpVersion ip_version)
@@ -61,6 +88,8 @@ BaseClientIntegrationTest::BaseClientIntegrationTest(Network::Address::IpVersion
use_lds_ = false;
autonomous_upstream_ = true;
defer_listener_finalization_ = true;
+
+ addLogLevel(getPlatformLogLevelFromOptions());
}
void BaseClientIntegrationTest::initialize() {
diff --git a/mobile/test/common/integration/rtds_integration_test.cc b/mobile/test/common/integration/rtds_integration_test.cc
index 720e4843e3dd..67f39cf31944 100644
--- a/mobile/test/common/integration/rtds_integration_test.cc
+++ b/mobile/test/common/integration/rtds_integration_test.cc
@@ -20,8 +20,6 @@ envoy::config::bootstrap::v3::LayeredRuntime layeredRuntimeConfig(const std::str
rtds_layer:
name: some_rtds_layer
rtds_config:
- # TODO(abeyad): Remove the initial_fetch_timeout when
- # https://github.com/envoyproxy/envoy-mobile/issues/2678 is fixed.
initial_fetch_timeout:
seconds: 1
resource_api_version: V3
@@ -96,6 +94,8 @@ TEST_P(RtdsIntegrationTest, RtdsReload) {
)EOF");
sendDiscoveryResponse(
Config::TypeUrl::get().Runtime, {some_rtds_layer}, {some_rtds_layer}, {}, "1");
+ // Wait until the RTDS updates from the DiscoveryResponse have been applied.
+ ASSERT_TRUE(waitForCounterGe("runtime.load_success", 1));
// Verify that the Runtime config values are from the RTDS response.
EXPECT_EQ("bar", getRuntimeKey("foo"));
diff --git a/mobile/test/common/integration/sds_integration_test.cc b/mobile/test/common/integration/sds_integration_test.cc
index 69fe4ab1e2ee..a689e76c4d40 100644
--- a/mobile/test/common/integration/sds_integration_test.cc
+++ b/mobile/test/common/integration/sds_integration_test.cc
@@ -63,8 +63,6 @@ class SdsIntegrationTest : public XdsIntegrationTest {
api_config_source->set_transport_api_version(envoy::config::core::v3::V3);
auto* grpc_service = api_config_source->add_grpc_services();
setGrpcService(*grpc_service, std::string(XDS_CLUSTER), fake_upstreams_.back()->localAddress());
- // TODO(abeyad): Remove the initial_fetch_timeout when
- // https://github.com/envoyproxy/envoy-mobile/issues/2678 is fixed.
config_source->mutable_initial_fetch_timeout()->set_seconds(1);
}
diff --git a/mobile/test/java/org/chromium/net/testing/data/content_length_mismatch.html b/mobile/test/java/org/chromium/net/testing/data/content_length_mismatch.html
index c0e81b12bd01..8b117afa936e 100644
--- a/mobile/test/java/org/chromium/net/testing/data/content_length_mismatch.html
+++ b/mobile/test/java/org/chromium/net/testing/data/content_length_mismatch.html
@@ -1,3 +1,2 @@
Response that lies about content length.
-