diff --git a/Directory.Build.props b/Directory.Build.props
index 56c99dd0f760f8..e9d93efb2aecfa 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -27,19 +27,21 @@
- eng/native/build-commons.sh
- eng/native/gen-buildsys.cmd
- src/native/libs/build-native.sh
- - src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachObjectWriter.cs
+ - src/coreclr/tools/Common/Compiler/ObjectWriter/MachObjectWriter.cs
- src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
- - src/mono/mono/tools/offsets-tool/offsets-tool.py
+ - src/mono/mono/offsets/offsets-tool.py
- src/mono/msbuild/apple/build/AppleBuild.targets
- src/installer/pkg/sfx/bundle/shared-framework-distribution-template-x64.xml
- src/installer/pkg/sfx/bundle/shared-framework-distribution-template-arm64.xml
- src/mono/msbuild/common/MonoAOTCompiler.props
- src/tasks/AppleAppBuilder/Xcode.cs
- src/tasks/MobileBuildTasks/Apple/AppleProject.cs
+ - src/tasks/MobileBuildTasks/Android/AndroidProject.cs
+ - src/tasks/AndroidAppBuilder/ApkBuilder.cs
- src/tasks/Crossgen2Tasks/Microsoft.NET.CrossGen.targets
- https://github.com/dotnet/sdk repo > src/Installer/redist-installer/targets/GeneratePKG.targets
-->
- 21
+ 24
13.0
13.0
14.0
diff --git a/docs/workflow/building/coreclr/android.md b/docs/workflow/building/coreclr/android.md
index 81f2d52b7262a1..f23bfaa9295554 100644
--- a/docs/workflow/building/coreclr/android.md
+++ b/docs/workflow/building/coreclr/android.md
@@ -44,7 +44,7 @@ Supported target architectures:
- Download and install [OpenJDK 23](https://openjdk.org/projects/jdk/23/)
- Download and install [Android Studio](https://developer.android.com/studio/install) and the following:
- - Android SDK (minimum supported API level is 21)
+ - Android SDK (minimum supported API level is 24)
- Android NDK r27c
> [!NOTE]
diff --git a/eng/common/cross/build-android-rootfs.sh b/eng/common/cross/build-android-rootfs.sh
index fbd8d80848a6ce..09d65eaff91237 100755
--- a/eng/common/cross/build-android-rootfs.sh
+++ b/eng/common/cross/build-android-rootfs.sh
@@ -21,7 +21,7 @@ usage()
exit 1
}
-__ApiLevel=28 # The minimum platform for arm64 is API level 21 but the minimum version that support glob(3) is 28. See $ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/glob.h
+__ApiLevel=28 # The minimum platform for arm64 is API level 24 but the minimum version that supports glob(3) is 28. See $ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/glob.h
__BuildArch=arm64
__AndroidArch=aarch64
__AndroidToolchain=aarch64-linux-android
diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh
index c0631ecda1308e..2a036677feaf66 100755
--- a/eng/native/build-commons.sh
+++ b/eng/native/build-commons.sh
@@ -101,7 +101,7 @@ build_native()
if [[ "$targetOS" == android || "$targetOS" == linux-bionic ]]; then
# Keep in sync with $(AndroidApiLevelMin) in Directory.Build.props in the repository rooot
- local ANDROID_API_LEVEL=21
+ local ANDROID_API_LEVEL=24
if [[ -z "$ANDROID_NDK_ROOT" ]]; then
echo "Error: You need to set the ANDROID_NDK_ROOT environment variable pointing to the Android NDK root."
exit 1
diff --git a/eng/native/gen-buildsys.cmd b/eng/native/gen-buildsys.cmd
index 0f5cccf8c89aed..4782c4723ab27f 100644
--- a/eng/native/gen-buildsys.cmd
+++ b/eng/native/gen-buildsys.cmd
@@ -76,7 +76,7 @@ if /i "%__Arch%" == "wasm" (
if /i "%__Os%" == "android" (
:: Keep in sync with $(AndroidApiLevelMin) in Directory.Build.props in the repository rooot
- set __ANDROID_API_LEVEL=21
+ set __ANDROID_API_LEVEL=24
if "%ANDROID_NDK_ROOT%" == "" (
echo Error: You need to set the ANDROID_NDK_ROOT environment variable pointing to the Android NDK root.
exit /B 1
diff --git a/eng/pipelines/helix-platforms.yml b/eng/pipelines/helix-platforms.yml
index dbceeb4b25eca2..3641106827121a 100644
--- a/eng/pipelines/helix-platforms.yml
+++ b/eng/pipelines/helix-platforms.yml
@@ -288,9 +288,9 @@ variables:
- name: helix_android_ubuntu_latest
value: Ubuntu.2204.Amd64.Android.29.Open
- # Oldest: API 21
+ # Oldest: API 24
- name: helix_android_ubuntu_oldest
- value: Ubuntu.2204.Amd64.Android.21.Open
+ value: Ubuntu.2204.Amd64.Android.24.Open
# ===========================================
# Common Aliases (default to latest)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index 48b8e6ef368054..997d2dd6cdcb3f 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -48,10 +48,10 @@ The .NET Foundation licenses this file to you under the MIT license.
armv7
gnu
- android21
+ android24
musl
gnueabihf
- androideabi21
+ androideabi24
musleabihf
diff --git a/src/coreclr/nativeaot/docs/android-bionic.md b/src/coreclr/nativeaot/docs/android-bionic.md
index 8a7aa566466f88..389ee69756a98a 100644
--- a/src/coreclr/nativeaot/docs/android-bionic.md
+++ b/src/coreclr/nativeaot/docs/android-bionic.md
@@ -4,7 +4,7 @@ Starting with .NET 8 Preview 7, it's possible to build shared libraries and comm
Not a full Android experience is available - it's only possible to publish for two Bionic RID: linux-bionic-arm64 and linux-bionic-x64. Publishing for Android RIDs (android-arm64/android-x64) is not possible. This limited experience corresponds to building with [Android NDK](https://developer.android.com/ndk) from Native code - the limitations are similar. Interop with Java needs to be done manually through JNI, if necessary.
-The minimum API level is 21 at the time of writing the document, but search for AndroidApiLevelMin in this repo for more up-to-date information.
+The minimum API level has been raised to 24 in .NET 11. Search for `AndroidApiLevelMin` in this repo for the current value.
To build for Bionic:
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs
index 89715afadead85..6c2f1867e67d40 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Extensions.Tests/System/OperatingSystemTests.cs
@@ -107,7 +107,7 @@ public static void IsOSPlatformVersionAtLeast_InvalidArgs_Throws()
public static void TestIsOSVersionAtLeast_Android() => TestIsOSVersionAtLeast("Android");
[Fact, PlatformSpecific(TestPlatforms.Android)]
- public static void TestIsOSVersionAtLeast_Android_21() => Assert.True(OperatingSystem.IsAndroidVersionAtLeast(21)); // 21 is our min supported version
+ public static void TestIsOSVersionAtLeast_Android_24() => Assert.True(OperatingSystem.IsAndroidVersionAtLeast(24)); // 24 is our min supported version
[Fact, PlatformSpecific(TestPlatforms.iOS)]
public static void TestIsOSPlatform_IOS() => TestIsOSPlatform("iOS", OperatingSystem.IsIOS);
diff --git a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs
index 72824f6a004cd4..647b8caaf02d20 100644
--- a/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs
+++ b/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/StorePal.Android.AndroidKeyStore.cs
@@ -53,9 +53,6 @@ public void Add(ICertificatePal cert)
{
Interop.AndroidCrypto.PAL_KeyAlgorithm algorithm = certPal.PrivateKeyHandle switch
{
- // The AndroidKeyStore doesn't support adding DSA private key entries in newer versions (API 23+)
- // Our minimum supported version (API 21) does support it, but for simplicity, we simply block adding
- // certificates with DSA private keys on all versions instead of trying to support it on two versions.
SafeDsaHandle => throw new PlatformNotSupportedException(SR.Cryptography_X509_StoreDSAPrivateKeyNotSupported),
SafeEcKeyHandle => Interop.AndroidCrypto.PAL_KeyAlgorithm.EC,
SafeRsaHandle => Interop.AndroidCrypto.PAL_KeyAlgorithm.RSA,
diff --git a/src/mono/mono/offsets/offsets-tool.py b/src/mono/mono/offsets/offsets-tool.py
index aec4a637dd614b..5e788412726480 100644
--- a/src/mono/mono/offsets/offsets-tool.py
+++ b/src/mono/mono/offsets/offsets-tool.py
@@ -109,7 +109,7 @@ def require_emscipten_path (args):
self.sys_includes=[]
self.target = None
self.target_args = []
- android_api_level = "-D__ANDROID_API=21"
+ android_api_level = "-D__ANDROID_API=24"
if args.libclang_headers:
self.sys_includes+= [args.libclang_headers]
diff --git a/src/mono/msbuild/android/build/AndroidBuild.targets b/src/mono/msbuild/android/build/AndroidBuild.targets
index 96e8607dd80dab..f393985c8a3d38 100644
--- a/src/mono/msbuild/android/build/AndroidBuild.targets
+++ b/src/mono/msbuild/android/build/AndroidBuild.targets
@@ -137,7 +137,7 @@
- 21
+ 24
diff --git a/src/native/libs/System.Native/CMakeLists.txt b/src/native/libs/System.Native/CMakeLists.txt
index 0beca0c2bb0ba2..90cac1c0cae2e3 100644
--- a/src/native/libs/System.Native/CMakeLists.txt
+++ b/src/native/libs/System.Native/CMakeLists.txt
@@ -116,14 +116,6 @@ include(${CMAKE_CURRENT_LIST_DIR}/extra_libs.cmake)
set(NATIVE_LIBS_EXTRA)
append_extra_system_libs(NATIVE_LIBS_EXTRA)
-if (CLR_CMAKE_TARGET_ANDROID AND NOT HAVE_GETIFADDRS)
- add_definitions(-DANDROID_GETIFADDRS_WORKAROUND)
- add_compile_options(-Wno-gnu-zero-variadic-macro-arguments)
-
- list (APPEND NATIVE_LIBS_EXTRA -llog)
- list (APPEND NATIVE_SOURCES pal_ifaddrs.c)
-endif ()
-
if (GEN_SHARED_LIB)
add_library(System.Native
SHARED
diff --git a/src/native/libs/System.Native/pal_ifaddrs.c b/src/native/libs/System.Native/pal_ifaddrs.c
deleted file mode 100644
index e95265afbfa235..00000000000000
--- a/src/native/libs/System.Native/pal_ifaddrs.c
+++ /dev/null
@@ -1,760 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#include "pal_ifaddrs.h"
-#include "pal_safecrt.h"
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-#define LOG(level, ...) __android_log_print(level, "DOTNET_NETLINK", ## __VA_ARGS__)
-#define LOG_INFO(...) LOG(ANDROID_LOG_INFO, ## __VA_ARGS__)
-#define LOG_WARN(...) LOG(ANDROID_LOG_WARN, ## __VA_ARGS__)
-#ifdef DEBUG
-#define LOG_DEBUG(...) LOG(ANDROID_LOG_DEBUG, ## __VA_ARGS__)
-#else
-#define LOG_DEBUG(...) do {} while (0)
-#endif
-
-/* Maximum interface address label size, should be more than enough */
-#define MAX_IFA_LABEL_SIZE 1024
-
-/* This is the message we send to the kernel */
-struct netlink_request {
- struct nlmsghdr header;
- struct rtgenmsg message;
-};
-
-struct netlink_session {
- int sock_fd;
- int seq;
- struct sockaddr_nl them; /* kernel end */
- struct sockaddr_nl us; /* our end */
- struct msghdr message_header; /* for use with sendmsg */
- struct iovec payload_vector; /* Used to send netlink_request */
-};
-
-struct sockaddr_ll_extended {
- unsigned short int sll_family;
- unsigned short int sll_protocol;
- int sll_ifindex;
- unsigned short int sll_hatype;
- unsigned char sll_pkttype;
- unsigned char sll_halen;
- unsigned char sll_addr[24];
-};
-
-static void free_single_ifaddrs(struct ifaddrs **ifap)
-{
- struct ifaddrs *ifa = ifap ? *ifap : NULL;
- if (!ifa)
- return;
-
- if (ifa->ifa_name)
- free(ifa->ifa_name);
-
- if (ifa->ifa_addr)
- free(ifa->ifa_addr);
-
- if (ifa->ifa_netmask)
- free(ifa->ifa_netmask);
-
- if (ifa->ifa_broadaddr)
- free(ifa->ifa_broadaddr);
-
- if (ifa->ifa_data)
- free(ifa->ifa_data);
-
- free(ifa);
- *ifap = NULL;
-}
-
-static int open_netlink_session(struct netlink_session *session)
-{
- abort_if_invalid_pointer_argument(session);
-
- memset(session, 0, sizeof(*session));
- session->sock_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (session->sock_fd == -1) {
- LOG_WARN("Failed to create a netlink socket. %s\n", strerror(errno));
- return -1;
- }
-
- /* Fill out addresses */
- session->us.nl_family = AF_NETLINK;
-
- /* We have previously used `getpid()` here but it turns out that WebView/Chromium does the same
- and there can only be one session with the same PID. Setting it to 0 will cause the kernel to
- assign some PID that's unique and valid instead.
- See: https://bugzilla.xamarin.com/show_bug.cgi?id=41860
- */
- session->us.nl_pid = 0;
- session->us.nl_groups = 0;
-
- session->them.nl_family = AF_NETLINK;
-
- if (bind (session->sock_fd, (struct sockaddr *)&session->us, sizeof(session->us)) < 0) {
- LOG_WARN("Failed to bind to the netlink socket. %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static int send_netlink_dump_request(struct netlink_session *session, int type)
-{
- struct netlink_request request;
-
- memset(&request, 0, sizeof(request));
- request.header.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtgenmsg));
- /* Flags (from netlink.h):
- NLM_F_REQUEST - it's a request message
- NLM_F_DUMP - gives us the root of the link tree and returns all links matching our requested
- AF, which in our case means all of them (AF_PACKET)
- */
- request.header.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT | NLM_F_MATCH;
- request.header.nlmsg_seq = (uint32_t)++session->seq;
- request.header.nlmsg_pid = session->us.nl_pid;
- request.header.nlmsg_type = (uint16_t)type;
-
- /* AF_PACKET means we want to see everything */
- request.message.rtgen_family = AF_PACKET;
-
- memset(&session->payload_vector, 0, sizeof(session->payload_vector));
- session->payload_vector.iov_len = request.header.nlmsg_len;
- session->payload_vector.iov_base = &request;
-
- memset(&session->message_header, 0, sizeof(session->message_header));
- session->message_header.msg_namelen = sizeof(session->them);
- session->message_header.msg_name = &session->them;
- session->message_header.msg_iovlen = 1;
- session->message_header.msg_iov = &session->payload_vector;
-
- if (sendmsg(session->sock_fd, (const struct msghdr*)&session->message_header, 0) < 0) {
- LOG_WARN("Failed to send netlink message. %s\n", strerror(errno));
- return -1;
- }
-
- return 0;
-}
-
-static int append_ifaddr(struct ifaddrs *addr, struct ifaddrs **ifaddrs_head, struct ifaddrs **last_ifaddr)
-{
- abort_if_invalid_pointer_argument(addr);
- abort_if_invalid_pointer_argument(ifaddrs_head);
- abort_if_invalid_pointer_argument(last_ifaddr);
-
- if (addr->ifa_name == NULL) {
- LOG_WARN("ifa_name is NULL -- skipping");
- return 0; // skip this addr
- }
-
- if (!*ifaddrs_head) {
- *ifaddrs_head = *last_ifaddr = addr;
- if (!*ifaddrs_head)
- return -1;
- } else if (!*last_ifaddr) {
- struct ifaddrs *last = *ifaddrs_head;
-
- while (last->ifa_next)
- last = last->ifa_next;
- *last_ifaddr = last;
- }
-
- addr->ifa_next = NULL;
- if (addr == *last_ifaddr)
- return 0;
-
- (*last_ifaddr)->ifa_next = addr;
- *last_ifaddr = addr;
-
- return 0;
-}
-
-static int fill_sa_address(struct sockaddr **sa, struct ifaddrmsg *net_address, void *rta_data, size_t rta_payload_length)
-{
- abort_if_invalid_pointer_argument(sa);
- abort_if_invalid_pointer_argument(net_address);
- abort_if_invalid_pointer_argument(rta_data);
-
- switch (net_address->ifa_family) {
- case AF_INET: {
- struct sockaddr_in *sa4;
- if (rta_payload_length != 4) /* IPv4 address length */ {
- LOG_WARN("Unexpected IPv4 address payload length %zu", rta_payload_length);
- return -1;
- }
- sa4 = (struct sockaddr_in*)calloc(1, sizeof(*sa4));
- if (sa4 == NULL)
- return -1;
-
- sa4->sin_family = AF_INET;
- memcpy(&sa4->sin_addr, rta_data, rta_payload_length);
- *sa = (struct sockaddr*)sa4;
- break;
- }
-
- case AF_INET6: {
- struct sockaddr_in6 *sa6;
- if (rta_payload_length != 16) /* IPv6 address length */ {
- LOG_WARN("Unexpected IPv6 address payload length %zu", rta_payload_length);
- return -1;
- }
- sa6 = (struct sockaddr_in6*)calloc(1, sizeof(*sa6));
- if (sa6 == NULL)
- return -1;
-
- sa6->sin6_family = AF_INET6;
- memcpy(&sa6->sin6_addr, rta_data, rta_payload_length);
- if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL (&sa6->sin6_addr))
- sa6->sin6_scope_id = net_address->ifa_index;
- *sa = (struct sockaddr*)sa6;
- break;
- }
-
- default: {
- struct sockaddr *sagen;
- if (rta_payload_length > sizeof(sagen->sa_data)) {
- LOG_WARN("Unexpected RTA payload length %zu (wanted at most %zu)", rta_payload_length, sizeof(sagen->sa_data));
- return -1;
- }
-
- *sa = sagen = (struct sockaddr*)calloc(1, sizeof(*sagen));
- if (!sagen)
- return -1;
-
- sagen->sa_family = net_address->ifa_family;
- memcpy(&sagen->sa_data, rta_data, rta_payload_length);
- break;
- }
- }
-
- return 0;
-}
-
-static int fill_ll_address(struct sockaddr_ll_extended **sa, struct ifinfomsg *net_interface, void *rta_data, size_t rta_payload_length)
-{
- abort_if_invalid_pointer_argument(sa);
- abort_if_invalid_pointer_argument(net_interface);
-
- /* Always allocate, do not free - caller may reuse the same variable */
- *sa = (struct sockaddr_ll_extended*)calloc(1, sizeof(**sa));
- if (!*sa)
- return -1;
-
- (*sa)->sll_family = AF_PACKET; /* Always for physical links */
-
- /* The assert can only fail for Iniband links, which are quite unlikely to be found
- * in any mobile devices
- */
- LOG_DEBUG("rta_payload_length == %zu; sizeof sll_addr == %zu; hw type == 0x%X\n", rta_payload_length, sizeof((*sa)->sll_addr), net_interface->ifi_type);
- if ((size_t)(rta_payload_length) > sizeof((*sa)->sll_addr)) {
- LOG_INFO("Address is too long to place in sockaddr_ll (%zu > %zu)", rta_payload_length, sizeof((*sa)->sll_addr));
- free(*sa);
- *sa = NULL;
- return -1;
- }
-
- if (rta_payload_length > UCHAR_MAX) {
- LOG_INFO("Payload length too big to fit in the address structure");
- free(*sa);
- *sa = NULL;
- return -1;
- }
-
- (*sa)->sll_ifindex = net_interface->ifi_index;
- (*sa)->sll_hatype = net_interface->ifi_type;
- (*sa)->sll_halen = (unsigned char)(rta_payload_length);
- memcpy((*sa)->sll_addr, rta_data, rta_payload_length);
-
- return 0;
-}
-
-
-static struct ifaddrs *get_link_info(struct nlmsghdr *message)
-{
- ssize_t length;
- struct rtattr *attribute;
- struct ifinfomsg *net_interface;
- struct ifaddrs *ifa = NULL;
- struct sockaddr_ll_extended *sa = NULL;
-
- abort_if_invalid_pointer_argument(message);
- net_interface = (struct ifinfomsg*)(NLMSG_DATA(message));
- length = (ssize_t)(message->nlmsg_len - NLMSG_LENGTH(sizeof(*net_interface)));
- if (length <= 0) {
- goto error;
- }
-
- ifa = (struct ifaddrs*)calloc(1, sizeof(*ifa));
- if (!ifa) {
- goto error;
- }
-
- ifa->ifa_flags = net_interface->ifi_flags;
- attribute = IFLA_RTA(net_interface);
- while (RTA_OK(attribute, length)) {
- switch (attribute->rta_type) {
- case IFLA_IFNAME:
- ifa->ifa_name = strdup((const char*)(RTA_DATA(attribute)));
- if (!ifa->ifa_name) {
- goto error;
- }
- LOG_DEBUG(" interface name (payload length: %zu; string length: %zu)\n", RTA_PAYLOAD(attribute), strlen(ifa->ifa_name));
- LOG_DEBUG(" %s\n", ifa->ifa_name);
- break;
-
- case IFLA_BROADCAST:
- LOG_DEBUG(" interface broadcast (%zu bytes)\n", RTA_PAYLOAD(attribute));
- if (fill_ll_address(&sa, net_interface, RTA_DATA(attribute), RTA_PAYLOAD(attribute)) < 0) {
- goto error;
- }
- ifa->ifa_broadaddr = (struct sockaddr*)sa;
- break;
-
- case IFLA_ADDRESS:
- LOG_DEBUG(" interface address (%zu bytes)\n", RTA_PAYLOAD(attribute));
- if (fill_ll_address(&sa, net_interface, RTA_DATA(attribute), RTA_PAYLOAD(attribute)) < 0) {
- goto error;
- }
- ifa->ifa_addr = (struct sockaddr*)sa;
- break;
-
- default:
- break;
- }
-
- attribute = RTA_NEXT (attribute, length);
- }
-
- LOG_DEBUG("link flags: 0x%X", ifa->ifa_flags);
- return ifa;
-
- error:
- if (sa)
- free(sa);
- free_single_ifaddrs(&ifa);
-
- return NULL;
-}
-
-static struct ifaddrs *find_interface_by_index(int index, struct ifaddrs **ifaddrs_head)
-{
- struct ifaddrs *cur;
- if (!ifaddrs_head || !*ifaddrs_head)
- return NULL;
-
- /* Normally expensive, but with the small amount of links in the chain we'll deal with it's not
- * worth the extra housekeeping and memory overhead
- */
- cur = *ifaddrs_head;
- while (cur) {
- if (cur->ifa_addr && cur->ifa_addr->sa_family == AF_PACKET && ((struct sockaddr_ll_extended*)cur->ifa_addr)->sll_ifindex == index)
- return cur;
- if (cur == cur->ifa_next)
- break;
- cur = cur->ifa_next;
- }
-
- return NULL;
-}
-
-static char *get_interface_name_by_index(int index, struct ifaddrs **ifaddrs_head)
-{
- struct ifaddrs *iface = find_interface_by_index(index, ifaddrs_head);
- if (!iface || !iface->ifa_name)
- return NULL;
-
- return iface->ifa_name;
-}
-
-static int get_interface_flags_by_index(int index, struct ifaddrs **ifaddrs_head)
-{
- struct ifaddrs *iface = find_interface_by_index(index, ifaddrs_head);
- if (!iface)
- return 0;
-
- return (int)(iface->ifa_flags);
-}
-
-static int calculate_address_netmask(struct ifaddrs *ifa, struct ifaddrmsg *net_address)
-{
- if (ifa->ifa_addr && ifa->ifa_addr->sa_family != AF_UNSPEC && ifa->ifa_addr->sa_family != AF_PACKET) {
- uint32_t prefix_length = 0;
- uint32_t data_length = 0;
- unsigned char *netmask_data = NULL;
-
- switch (ifa->ifa_addr->sa_family) {
- case AF_INET: {
- struct sockaddr_in *sa = (struct sockaddr_in*)calloc(1, sizeof(struct sockaddr_in));
- if (!sa)
- return -1;
-
- ifa->ifa_netmask = (struct sockaddr*)sa;
- prefix_length = net_address->ifa_prefixlen;
- if (prefix_length > 32)
- prefix_length = 32;
- data_length = sizeof(sa->sin_addr);
- netmask_data = (unsigned char*)&sa->sin_addr;
- break;
- }
-
- case AF_INET6: {
- struct sockaddr_in6 *sa = (struct sockaddr_in6*)calloc(1, sizeof(struct sockaddr_in6));
- if (!sa)
- return -1;
-
- ifa->ifa_netmask = (struct sockaddr*)sa;
- prefix_length = net_address->ifa_prefixlen;
- if (prefix_length > 128)
- prefix_length = 128;
- data_length = sizeof(sa->sin6_addr);
- netmask_data = (unsigned char*)&sa->sin6_addr;
- break;
- }
- }
-
- if (ifa->ifa_netmask && netmask_data) {
- /* Fill the first X bytes with 255 */
- uint32_t prefix_bytes = prefix_length / 8;
- uint32_t postfix_bytes;
-
- if (prefix_bytes > data_length) {
- errno = EINVAL;
- return -1;
- }
- postfix_bytes = data_length - prefix_bytes;
- memset(netmask_data, 0xFF, prefix_bytes);
- if (postfix_bytes > 0)
- memset(netmask_data + prefix_bytes + 1, 0x00, postfix_bytes);
- LOG_DEBUG(" calculating netmask, prefix length is %u bits (%u bytes), data length is %u bytes\n", prefix_length, prefix_bytes, data_length);
- if (prefix_bytes + 2 < data_length)
- /* Set the rest of the mask bits in the byte following the last 0xFF value */
- netmask_data[prefix_bytes + 1] = (unsigned char)(0xff << (8 - (prefix_length % 8)));
- }
- }
-
- return 0;
-}
-
-
-static struct ifaddrs *get_link_address(struct nlmsghdr *message, struct ifaddrs **ifaddrs_head)
-{
- ssize_t length = 0;
- struct rtattr *attribute;
- struct ifaddrmsg *net_address;
- struct ifaddrs *ifa = NULL;
- struct sockaddr **sa;
- size_t payload_size;
-
- abort_if_invalid_pointer_argument(message);
- net_address = (struct ifaddrmsg*)(NLMSG_DATA(message));
- length = (ssize_t)(IFA_PAYLOAD(message));
- LOG_DEBUG(" address data length: %zd", length);
- if (length <= 0) {
- goto error;
- }
-
- ifa = (struct ifaddrs*)(calloc(1, sizeof(*ifa)));
- if (!ifa) {
- goto error;
- }
-
- // values < 0 are never returned, the cast is safe
- ifa->ifa_flags = (unsigned int)(get_interface_flags_by_index((int)(net_address->ifa_index), ifaddrs_head));
-
- attribute = IFA_RTA(net_address);
- LOG_DEBUG(" reading attributes");
- while (RTA_OK(attribute, length)) {
- payload_size = RTA_PAYLOAD(attribute);
- LOG_DEBUG(" attribute payload_size == %zu\n", payload_size);
- sa = NULL;
-
- switch (attribute->rta_type) {
- case IFA_LABEL: {
- size_t room_for_trailing_null = 0;
-
- LOG_DEBUG(" attribute type: LABEL");
- if (payload_size > MAX_IFA_LABEL_SIZE) {
- payload_size = MAX_IFA_LABEL_SIZE;
- room_for_trailing_null = 1;
- }
-
- if (payload_size > 0) {
- size_t alloc_size;
- if (!multiply_s(payload_size, room_for_trailing_null, &alloc_size)) {
- goto error;
- }
-
- ifa->ifa_name = (char*)malloc(alloc_size);
- if (!ifa->ifa_name) {
- goto error;
- }
-
- memcpy(ifa->ifa_name, RTA_DATA (attribute), payload_size);
- if (room_for_trailing_null)
- ifa->ifa_name[payload_size] = '\0';
- }
- break;
- }
-
- case IFA_LOCAL:
- LOG_DEBUG(" attribute type: LOCAL");
- if (ifa->ifa_addr) {
- /* P2P protocol, set the dst/broadcast address union from the original address.
- * Since ifa_addr is set it means IFA_ADDRESS occurred earlier and that address
- * is indeed the P2P destination one.
- */
- ifa->ifa_dstaddr = ifa->ifa_addr;
- ifa->ifa_addr = 0;
- }
- sa = &ifa->ifa_addr;
- break;
-
- case IFA_BROADCAST:
- LOG_DEBUG(" attribute type: BROADCAST");
- if (ifa->ifa_dstaddr) {
- /* IFA_LOCAL happened earlier, undo its effect here */
- free(ifa->ifa_dstaddr);
- ifa->ifa_dstaddr = NULL;
- }
- sa = &ifa->ifa_broadaddr;
- break;
-
- case IFA_ADDRESS:
- LOG_DEBUG(" attribute type: ADDRESS");
- if (ifa->ifa_addr) {
- /* Apparently IFA_LOCAL occurred earlier and we have a P2P connection
- * here. IFA_LOCAL carries the destination address, move it there
- */
- ifa->ifa_dstaddr = ifa->ifa_addr;
- ifa->ifa_addr = NULL;
- }
- sa = &ifa->ifa_addr;
- break;
-
- case IFA_UNSPEC:
- LOG_DEBUG(" attribute type: UNSPEC");
- break;
-
- case IFA_ANYCAST:
- LOG_DEBUG(" attribute type: ANYCAST");
- break;
-
- case IFA_CACHEINFO:
- LOG_DEBUG(" attribute type: CACHEINFO");
- break;
-
- case IFA_MULTICAST:
- LOG_DEBUG(" attribute type: MULTICAST");
- break;
-
- default:
- LOG_DEBUG(" attribute type: %u", attribute->rta_type);
- break;
- }
-
- if (sa) {
- if (fill_sa_address(sa, net_address, RTA_DATA(attribute), RTA_PAYLOAD(attribute)) < 0) {
- goto error;
- }
- }
-
- attribute = RTA_NEXT(attribute, length);
- }
-
- /* glibc stores the associated interface name in the address if IFA_LABEL never occurred */
- if (!ifa->ifa_name) {
- char *name = get_interface_name_by_index((int)(net_address->ifa_index), ifaddrs_head);
- LOG_DEBUG(" address has no name/label, getting one from interface\n");
- ifa->ifa_name = name ? strdup(name) : NULL;
- }
- LOG_DEBUG(" address label: %s\n", ifa->ifa_name);
-
- if (calculate_address_netmask(ifa, net_address) < 0) {
- goto error;
- }
-
- return ifa;
-
- error:
- {
- /* errno may be modified by free, or any other call inside the free_single_xamarin_ifaddrs
- * function. We don't care about errors in there since it is more important to know how we
- * failed to obtain the link address and not that we went OOM. Save and restore the value
- * after the resources are freed.
- */
- int errno_save = errno;
- free_single_ifaddrs (&ifa);
- errno = errno_save;
- return NULL;
- }
-
-}
-
-static int parse_netlink_reply(struct netlink_session *session, struct ifaddrs **ifaddrs_head, struct ifaddrs **last_ifaddr)
-{
- struct msghdr netlink_reply;
- struct iovec reply_vector;
- struct nlmsghdr *current_message;
- struct ifaddrs *addr;
- int ret = -1;
- unsigned char *response = NULL;
-
- abort_if_invalid_pointer_argument(session);
- abort_if_invalid_pointer_argument(ifaddrs_head);
- abort_if_invalid_pointer_argument(last_ifaddr);
-
- size_t buf_size = (size_t)(getpagesize());
- LOG_DEBUG("receive buffer size == %zu", buf_size);
-
- size_t alloc_size;
- if (!multiply_s(sizeof(*response), buf_size, &alloc_size)) {
- goto cleanup;
- }
-
- response = (unsigned char*)malloc(alloc_size);
- ssize_t length = 0;
- if (!response) {
- goto cleanup;
- }
-
- while (1) {
- memset(response, 0, buf_size);
- memset(&reply_vector, 0, sizeof(reply_vector));
- reply_vector.iov_len = buf_size;
- reply_vector.iov_base = response;
-
- memset(&netlink_reply, 0, sizeof(netlink_reply));
- netlink_reply.msg_namelen = sizeof(&session->them);
- netlink_reply.msg_name = &session->them;
- netlink_reply.msg_iovlen = 1;
- netlink_reply.msg_iov = &reply_vector;
-
- length = recvmsg(session->sock_fd, &netlink_reply, 0);
- LOG_DEBUG(" length == %d\n", (int)length);
-
- if (length < 0) {
- LOG_DEBUG("Failed to receive reply from netlink. %s\n", strerror(errno));
- goto cleanup;
- }
-
-#ifdef DEBUG
- LOG_DEBUG("response flags:");
- if (netlink_reply.msg_flags == 0)
- LOG_DEBUG(" [NONE]");
- else {
- if (netlink_reply.msg_flags & MSG_EOR)
- LOG_DEBUG(" MSG_EOR");
- if (netlink_reply.msg_flags & MSG_TRUNC)
- LOG_DEBUG(" MSG_TRUNC");
- if (netlink_reply.msg_flags & MSG_CTRUNC)
- LOG_DEBUG(" MSG_CTRUNC");
- if (netlink_reply.msg_flags & MSG_OOB)
- LOG_DEBUG(" MSG_OOB");
- if (netlink_reply.msg_flags & MSG_ERRQUEUE)
- LOG_DEBUG(" MSG_ERRQUEUE");
- }
-#endif
-
- if (length == 0)
- break;
-
- for (current_message = (struct nlmsghdr*)response; current_message && NLMSG_OK(current_message, (size_t)length); current_message = NLMSG_NEXT(current_message, length)) {
- LOG_DEBUG("next message... (type: %u)\n", current_message->nlmsg_type);
- switch (current_message->nlmsg_type) {
- /* See rtnetlink.h */
- case RTM_NEWLINK:
- LOG_DEBUG(" dumping link...\n");
- addr = get_link_info(current_message);
- if (!addr || append_ifaddr(addr, ifaddrs_head, last_ifaddr) < 0) {
- ret = -1;
- goto cleanup;
- }
- LOG_DEBUG(" done\n");
- break;
-
- case RTM_NEWADDR:
- LOG_DEBUG(" got an address\n");
- addr = get_link_address(current_message, ifaddrs_head);
- if (!addr || append_ifaddr(addr, ifaddrs_head, last_ifaddr) < 0) {
- ret = -1;
- goto cleanup;
- }
- break;
-
- case NLMSG_DONE:
- LOG_DEBUG(" message done\n");
- ret = 0;
- goto cleanup;
-
- default:
- LOG_DEBUG(" message type: %u", current_message->nlmsg_type);
- break;
- }
- }
- }
-
- cleanup:
- if (response)
- free(response);
- return ret;
-}
-
-int _netlink_getifaddrs(struct ifaddrs **ifap)
-{
- int ret = -1;
-
- *ifap = NULL;
- struct ifaddrs *ifaddrs_head = 0;
- struct ifaddrs *last_ifaddr = 0;
- struct netlink_session session;
-
- if (open_netlink_session(&session) < 0) {
- goto cleanup;
- }
-
- /* Request information about the specified link. In our case it will be all of them since we
- request the root of the link tree below
- */
- if ((send_netlink_dump_request(&session, RTM_GETLINK) < 0) ||
- (parse_netlink_reply(&session, &ifaddrs_head, &last_ifaddr) < 0) ||
- (send_netlink_dump_request(&session, RTM_GETADDR) < 0) ||
- (parse_netlink_reply(&session, &ifaddrs_head, &last_ifaddr) < 0)) {
- _netlink_freeifaddrs (ifaddrs_head);
- goto cleanup;
- }
-
- ret = 0;
- *ifap = ifaddrs_head;
-
-cleanup:
- if (session.sock_fd >= 0) {
- close(session.sock_fd);
- session.sock_fd = -1;
- }
-
- return ret;
-}
-
-void _netlink_freeifaddrs(struct ifaddrs *ifa)
-{
- struct ifaddrs *cur, *next;
-
- if (!ifa)
- return;
-
- cur = ifa;
- while (cur) {
- next = cur->ifa_next;
- free_single_ifaddrs (&cur);
- cur = next;
- }
-}
diff --git a/src/native/libs/System.Native/pal_ifaddrs.h b/src/native/libs/System.Native/pal_ifaddrs.h
deleted file mode 100644
index 0944eeb43eb9f1..00000000000000
--- a/src/native/libs/System.Native/pal_ifaddrs.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#pragma once
-
-#ifndef TARGET_ANDROID
-#error The pal_ifaddrs.h shim is intended only for Android
-#endif
-
-#if __ANDROID_API__ >= 24
-#error The pal_ifaddrs.h shim is only necessary for Android API 21-23 and it should be removed now that the minimum supported API level is 24 or higher
-#endif
-
-// Android doesn't include the getifaddrs and freeifaddrs functions in older Bionic libc (pre API 24).
-// This shim is a port of Xamarin Android's implementation of getifaddrs using Netlink.
-// https://github.com/xamarin/xamarin-android/blob/681887ebdbd192ce7ce1cd02221d4939599ba762/src/monodroid/jni/xamarin_getifaddrs.h
-
-#include
-
-int _netlink_getifaddrs (struct ifaddrs **ifap);
-void _netlink_freeifaddrs (struct ifaddrs *ifap);
diff --git a/src/native/libs/System.Native/pal_interfaceaddresses.c b/src/native/libs/System.Native/pal_interfaceaddresses.c
index e93eeb07b97731..ed0be3a880b1d1 100644
--- a/src/native/libs/System.Native/pal_interfaceaddresses.c
+++ b/src/native/libs/System.Native/pal_interfaceaddresses.c
@@ -11,18 +11,9 @@
#include
#include
#include
-#if HAVE_GETIFADDRS || defined(ANDROID_GETIFADDRS_WORKAROUND)
+#if HAVE_GETIFADDRS
#include
#endif
-#ifdef ANDROID_GETIFADDRS_WORKAROUND
-#if HAVE_DLFCN_H
-#include
-#endif
-#if HAVE_PTHREAD_H
-#include
-#endif
-#include "pal_ifaddrs.h" // fallback for Android API 21-23
-#endif
#if HAVE_NET_IF_H
#include
#endif
@@ -118,56 +109,12 @@ static inline uint8_t mask2prefix(uint8_t* mask, int length)
}
#endif /* TARGET_WASI */
-#ifdef ANDROID_GETIFADDRS_WORKAROUND
-// This workaround is necessary as long as we support Android API 21-23 and it can be removed once
-// we drop support for these old Android versions.
-static int (*getifaddrs)(struct ifaddrs**) = NULL;
-static void (*freeifaddrs)(struct ifaddrs*) = NULL;
-
-static void try_loading_getifaddrs(void)
-{
- if (android_get_device_api_level() >= 24)
- {
- // Bionic on API 24+ contains the getifaddrs/freeifaddrs functions but the NDK doesn't expose those functions
- // in ifaddrs.h when the minimum supported SDK is lower than 24 and therefore we need to load them manually
- void *libc = dlopen("libc.so", RTLD_NOW);
- if (libc)
- {
- getifaddrs = (int (*)(struct ifaddrs**)) dlsym(libc, "getifaddrs");
- freeifaddrs = (void (*)(struct ifaddrs*)) dlsym(libc, "freeifaddrs");
- }
- }
- else
- {
- // Bionic on API 21-23 doesn't contain the implementation of getifaddrs/freeifaddrs at all
- // and we need to reimplement it using netlink (see pal_ifaddrs)
- getifaddrs = _netlink_getifaddrs;
- freeifaddrs = _netlink_freeifaddrs;
- }
-}
-
-static bool ensure_getifaddrs_is_loaded(void)
-{
- static pthread_once_t getifaddrs_is_loaded = PTHREAD_ONCE_INIT;
- pthread_once(&getifaddrs_is_loaded, try_loading_getifaddrs);
- return getifaddrs != NULL && freeifaddrs != NULL;
-}
-#endif
-
int32_t SystemNative_EnumerateInterfaceAddresses(void* context,
IPv4AddressFound onIpv4Found,
IPv6AddressFound onIpv6Found,
LinkLayerAddressFound onLinkLayerFound)
{
-#ifdef ANDROID_GETIFADDRS_WORKAROUND
- if (!ensure_getifaddrs_is_loaded())
- {
- errno = ENOTSUP;
- return -1;
- }
-#endif
-
-#if HAVE_GETIFADDRS || defined(ANDROID_GETIFADDRS_WORKAROUND)
+#if HAVE_GETIFADDRS
struct ifaddrs* headAddr;
if (getifaddrs(&headAddr) == -1)
{
@@ -316,15 +263,7 @@ c_static_assert(sizeof(NetworkInterfaceInfo) >= sizeof(IpAddressInfo));
int32_t SystemNative_GetNetworkInterfaces(int32_t * interfaceCount, NetworkInterfaceInfo **interfaceList, int32_t * addressCount, IpAddressInfo **addressList )
{
-#ifdef ANDROID_GETIFADDRS_WORKAROUND
- if (!ensure_getifaddrs_is_loaded())
- {
- errno = ENOTSUP;
- return -1;
- }
-#endif
-
-#if HAVE_GETIFADDRS || defined(ANDROID_GETIFADDRS_WORKAROUND)
+#if HAVE_GETIFADDRS
struct ifaddrs* head; // Pointer to block allocated by getifaddrs().
struct ifaddrs* ifaddrsEntry;
IpAddressInfo *ai;
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c
index ecb0c1f8ec43f9..81f11ab25c2ea7 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.c
@@ -83,15 +83,6 @@ jmethodID g_SSLParametersGetProtocols;
jmethodID g_SSLParametersSetApplicationProtocols;
jmethodID g_SSLParametersSetServerNames;
-// com/android/org/conscrypt/OpenSSLEngineImpl
-jclass g_ConscryptOpenSSLEngineImplClass;
-jfieldID g_ConscryptOpenSSLEngineImplSslParametersField;
-jfieldID g_ConscryptOpenSSLEngineImplHandshakeSessionField;
-
-// com/android/org/conscrypt/SSLParametersImpl
-jclass g_ConscryptSSLParametersImplClass;
-jmethodID g_ConscryptSSLParametersImplSetUseSni;
-
// javax/net/ssl/SSLContext
jclass g_sslCtxClass;
jmethodID g_sslCtxGetDefaultMethod;
@@ -199,14 +190,14 @@ jmethodID g_CertPathBuilderBuild;
jclass g_CertPathValidatorClass;
jmethodID g_CertPathValidatorGetInstance;
jmethodID g_CertPathValidatorValidate;
-jmethodID g_CertPathValidatorGetRevocationChecker; // only in API level 24+
+jmethodID g_CertPathValidatorGetRevocationChecker;
// java/security/cert/CertPathValidatorException
jclass g_CertPathValidatorExceptionClass;
jmethodID g_CertPathValidatorExceptionGetIndex;
-jmethodID g_CertPathValidatorExceptionGetReason; // only in API level 24+
+jmethodID g_CertPathValidatorExceptionGetReason;
-// java/security/cert/CertPathValidatorException$BasicReason - only in API level 24+
+// java/security/cert/CertPathValidatorException$BasicReason
jclass g_CertPathExceptionBasicReasonClass;
// java/security/cert/CertStore
@@ -231,14 +222,14 @@ jclass g_PKIXCertPathBuilderResultClass;
jmethodID g_PKIXCertPathBuilderResultGetCertPath;
jmethodID g_PKIXCertPathBuilderResultGetTrustAnchor;
-// java/security/cert/PKIXReason - only in API level 24+
+// java/security/cert/PKIXReason
jclass g_PKIXReasonClass;
-// java/security/cert/PKIXRevocationChecker - only in API level 24+
+// java/security/cert/PKIXRevocationChecker
jclass g_PKIXRevocationCheckerClass;
jmethodID g_PKIXRevocationCheckerSetOptions;
-// java/security/cert/PKIXRevocationChecker$Option - only in API level 24+
+// java/security/cert/PKIXRevocationChecker$Option
jclass g_PKIXRevocationCheckerOptionClass;
jfieldID g_PKIXRevocationCheckerOptionOnlyEndEntity;
@@ -474,7 +465,6 @@ jmethodID g_SSLSessionGetProtocol;
jclass g_SSLEngineResult;
jmethodID g_SSLEngineResultGetStatus;
jmethodID g_SSLEngineResultGetHandshakeStatus;
-bool g_SSLEngineResultStatusLegacyOrder;
jmethodID g_SSLEngineResultBytesConsumed;
// javax/crypto/KeyAgreement
@@ -778,16 +768,6 @@ jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved)
g_SSLParametersGetProtocols = GetMethod(env, false, g_SSLParametersClass, "getProtocols", "()[Ljava/lang/String;");
g_SSLParametersSetApplicationProtocols = GetOptionalMethod(env, false, g_SSLParametersClass, "setApplicationProtocols", "([Ljava/lang/String;)V");
- g_ConscryptOpenSSLEngineImplClass = GetOptionalClassGRef(env, "com/android/org/conscrypt/OpenSSLEngineImpl");
- if (g_ConscryptOpenSSLEngineImplClass != NULL)
- {
- g_ConscryptOpenSSLEngineImplSslParametersField = GetField(env, false, g_ConscryptOpenSSLEngineImplClass, "sslParameters", "Lcom/android/org/conscrypt/SSLParametersImpl;");
- g_ConscryptOpenSSLEngineImplHandshakeSessionField = GetOptionalField(env, false, g_ConscryptOpenSSLEngineImplClass, "handshakeSession", "Lcom/android/org/conscrypt/OpenSSLSessionImpl;");
-
- g_ConscryptSSLParametersImplClass = GetClassGRef(env, "com/android/org/conscrypt/SSLParametersImpl");
- g_ConscryptSSLParametersImplSetUseSni = GetMethod(env, false, g_ConscryptSSLParametersImplClass, "setUseSni", "(Z)V");
- }
-
g_sslCtxClass = GetClassGRef(env, "javax/net/ssl/SSLContext");
g_sslCtxGetDefaultMethod = GetMethod(env, true, g_sslCtxClass, "getDefault", "()Ljavax/net/ssl/SSLContext;");
g_sslCtxGetDefaultSslParamsMethod = GetMethod(env, false, g_sslCtxClass, "getDefaultSSLParameters", "()Ljavax/net/ssl/SSLParameters;");
@@ -810,13 +790,13 @@ jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved)
g_CertPathValidatorClass = GetClassGRef(env, "java/security/cert/CertPathValidator");
g_CertPathValidatorGetInstance = GetMethod(env, true, g_CertPathValidatorClass, "getInstance", "(Ljava/lang/String;)Ljava/security/cert/CertPathValidator;");
g_CertPathValidatorValidate = GetMethod(env, false, g_CertPathValidatorClass, "validate", "(Ljava/security/cert/CertPath;Ljava/security/cert/CertPathParameters;)Ljava/security/cert/CertPathValidatorResult;");
- g_CertPathValidatorGetRevocationChecker = GetOptionalMethod(env, false, g_CertPathValidatorClass, "getRevocationChecker", "()Ljava/security/cert/CertPathChecker;");
+ g_CertPathValidatorGetRevocationChecker = GetMethod(env, false, g_CertPathValidatorClass, "getRevocationChecker", "()Ljava/security/cert/CertPathChecker;");
g_CertPathValidatorExceptionClass = GetClassGRef(env, "java/security/cert/CertPathValidatorException");
g_CertPathValidatorExceptionGetIndex = GetMethod(env, false, g_CertPathValidatorExceptionClass, "getIndex", "()I");
- g_CertPathValidatorExceptionGetReason = GetOptionalMethod(env, false, g_CertPathValidatorExceptionClass, "getReason", "()Ljava/security/cert/CertPathValidatorException$Reason;");
+ g_CertPathValidatorExceptionGetReason = GetMethod(env, false, g_CertPathValidatorExceptionClass, "getReason", "()Ljava/security/cert/CertPathValidatorException$Reason;");
- g_CertPathExceptionBasicReasonClass = GetOptionalClassGRef(env, "java/security/cert/CertPathValidatorException$BasicReason");
+ g_CertPathExceptionBasicReasonClass = GetClassGRef(env, "java/security/cert/CertPathValidatorException$BasicReason");
g_CertStoreClass = GetClassGRef(env, "java/security/cert/CertStore");
g_CertStoreGetInstance = GetMethod(env, true, g_CertStoreClass, "getInstance", "(Ljava/lang/String;Ljava/security/cert/CertStoreParameters;)Ljava/security/cert/CertStore;");
@@ -836,16 +816,12 @@ jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved)
g_PKIXCertPathBuilderResultGetCertPath = GetMethod(env, false, g_PKIXCertPathBuilderResultClass, "getCertPath", "()Ljava/security/cert/CertPath;");
g_PKIXCertPathBuilderResultGetTrustAnchor = GetMethod(env, false, g_PKIXCertPathBuilderResultClass, "getTrustAnchor", "()Ljava/security/cert/TrustAnchor;");
- g_PKIXReasonClass = GetOptionalClassGRef(env, "java/security/cert/PKIXReason");
+ g_PKIXReasonClass = GetClassGRef(env, "java/security/cert/PKIXReason");
+ g_PKIXRevocationCheckerClass = GetClassGRef(env, "java/security/cert/PKIXRevocationChecker");
+ g_PKIXRevocationCheckerSetOptions = GetMethod(env, false, g_PKIXRevocationCheckerClass, "setOptions", "(Ljava/util/Set;)V");
- if (g_CertPathValidatorGetRevocationChecker != NULL)
- {
- g_PKIXRevocationCheckerClass = GetClassGRef(env, "java/security/cert/PKIXRevocationChecker");
- g_PKIXRevocationCheckerSetOptions = GetMethod(env, false, g_PKIXRevocationCheckerClass, "setOptions", "(Ljava/util/Set;)V");
-
- g_PKIXRevocationCheckerOptionClass = GetClassGRef(env, "java/security/cert/PKIXRevocationChecker$Option");
- g_PKIXRevocationCheckerOptionOnlyEndEntity = GetField(env, true, g_PKIXRevocationCheckerOptionClass, "ONLY_END_ENTITY", "Ljava/security/cert/PKIXRevocationChecker$Option;");
- }
+ g_PKIXRevocationCheckerOptionClass = GetClassGRef(env, "java/security/cert/PKIXRevocationChecker$Option");
+ g_PKIXRevocationCheckerOptionOnlyEndEntity = GetField(env, true, g_PKIXRevocationCheckerOptionClass, "ONLY_END_ENTITY", "Ljava/security/cert/PKIXRevocationChecker$Option;");
g_TrustAnchorClass = GetClassGRef(env, "java/security/cert/TrustAnchor");
g_TrustAnchorCtor = GetMethod(env, false, g_TrustAnchorClass, "", "(Ljava/security/cert/X509Certificate;[B)V");
@@ -1040,19 +1016,15 @@ jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved)
g_KeyManagerFactoryInit = GetMethod(env, false, g_KeyManagerFactory, "init", "(Ljava/security/KeyStore;[C)V");
g_KeyManagerFactoryGetKeyManagers = GetMethod(env, false, g_KeyManagerFactory, "getKeyManagers", "()[Ljavax/net/ssl/KeyManager;");
- // Supported on API Level 24 and above
- g_SNIHostName = GetOptionalClassGRef(env, "javax/net/ssl/SNIHostName");
- if (g_SNIHostName != NULL)
- {
- g_SNIHostNameCtor = GetMethod(env, false, g_SNIHostName, "", "(Ljava/lang/String;)V");
- g_SSLParametersSetServerNames = GetOptionalMethod(env, false, g_SSLParametersClass, "setServerNames", "(Ljava/util/List;)V");
- }
+ g_SNIHostName = GetClassGRef(env, "javax/net/ssl/SNIHostName");
+ g_SNIHostNameCtor = GetMethod(env, false, g_SNIHostName, "", "(Ljava/lang/String;)V");
+ g_SSLParametersSetServerNames = GetMethod(env, false, g_SSLParametersClass, "setServerNames", "(Ljava/util/List;)V");
g_SSLEngine = GetClassGRef(env, "javax/net/ssl/SSLEngine");
g_SSLEngineBeginHandshake = GetMethod(env, false, g_SSLEngine, "beginHandshake", "()V");
g_SSLEngineCloseOutbound = GetMethod(env, false, g_SSLEngine, "closeOutbound", "()V");
g_SSLEngineGetApplicationProtocol = GetOptionalMethod(env, false, g_SSLEngine, "getApplicationProtocol", "()Ljava/lang/String;");
- g_SSLEngineGetHandshakeSession = GetOptionalMethod(env, false, g_SSLEngine, "getHandshakeSession", "()Ljavax/net/ssl/SSLSession;");
+ g_SSLEngineGetHandshakeSession = GetMethod(env, false, g_SSLEngine, "getHandshakeSession", "()Ljavax/net/ssl/SSLSession;");
g_SSLEngineGetHandshakeStatus = GetMethod(env, false, g_SSLEngine, "getHandshakeStatus", "()Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;");
g_SSLEngineGetSession = GetMethod(env, false, g_SSLEngine, "getSession", "()Ljavax/net/ssl/SSLSession;");
g_SSLEngineGetSSLParameters = GetMethod(env, false, g_SSLEngine, "getSSLParameters", "()Ljavax/net/ssl/SSLParameters;");
@@ -1093,7 +1065,6 @@ jint AndroidCryptoNative_InitLibraryOnLoad (JavaVM *vm, void *reserved)
g_SSLEngineResultGetStatus = GetMethod(env, false, g_SSLEngineResult, "getStatus", "()Ljavax/net/ssl/SSLEngineResult$Status;");
g_SSLEngineResultGetHandshakeStatus = GetMethod(env, false, g_SSLEngineResult, "getHandshakeStatus", "()Ljavax/net/ssl/SSLEngineResult$HandshakeStatus;");
g_SSLEngineResultBytesConsumed = GetMethod(env, false, g_SSLEngineResult, "bytesConsumed", "()I");
- g_SSLEngineResultStatusLegacyOrder = android_get_device_api_level() < 24;
g_KeyAgreementClass = GetClassGRef(env, "javax/crypto/KeyAgreement");
g_KeyAgreementGetInstance = GetMethod(env, true, g_KeyAgreementClass, "getInstance", "(Ljava/lang/String;)Ljavax/crypto/KeyAgreement;");
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h
index 2828a68dc03c03..9285c123525a27 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_jni.h
@@ -95,15 +95,6 @@ extern jmethodID g_SSLParametersGetProtocols;
extern jmethodID g_SSLParametersSetApplicationProtocols;
extern jmethodID g_SSLParametersSetServerNames;
-// com/android/org/conscrypt/OpenSSLEngineImpl
-extern jclass g_ConscryptOpenSSLEngineImplClass;
-extern jfieldID g_ConscryptOpenSSLEngineImplSslParametersField;
-extern jfieldID g_ConscryptOpenSSLEngineImplHandshakeSessionField;
-
-// com/android/org/conscrypt/SSLParametersImpl
-extern jclass g_ConscryptSSLParametersImplClass;
-extern jmethodID g_ConscryptSSLParametersImplSetUseSni;
-
// javax/net/ssl/SSLContext
extern jclass g_sslCtxClass;
extern jmethodID g_sslCtxGetDefaultMethod;
@@ -150,14 +141,14 @@ extern jmethodID g_CertPathBuilderBuild;
extern jclass g_CertPathValidatorClass;
extern jmethodID g_CertPathValidatorGetInstance;
extern jmethodID g_CertPathValidatorValidate;
-extern jmethodID g_CertPathValidatorGetRevocationChecker; // only in API level 24+
+extern jmethodID g_CertPathValidatorGetRevocationChecker;
// java/security/cert/CertPathValidatorException
extern jclass g_CertPathValidatorExceptionClass;
extern jmethodID g_CertPathValidatorExceptionGetIndex;
extern jmethodID g_CertPathValidatorExceptionGetReason;
-// java/security/cert/CertPathValidatorException$BasicReason - only in API level 24+
+// java/security/cert/CertPathValidatorException$BasicReason
extern jclass g_CertPathExceptionBasicReasonClass;
// java/security/cert/CertStore
@@ -182,14 +173,14 @@ extern jclass g_PKIXCertPathBuilderResultClass;
extern jmethodID g_PKIXCertPathBuilderResultGetCertPath;
extern jmethodID g_PKIXCertPathBuilderResultGetTrustAnchor;
-// java/security/cert/PKIXReason - only in API level 24+
+// java/security/cert/PKIXReason
extern jclass g_PKIXReasonClass;
-// java/security/cert/PKIXRevocationChecker - only in API level 24+
+// java/security/cert/PKIXRevocationChecker
extern jclass g_PKIXRevocationCheckerClass;
extern jmethodID g_PKIXRevocationCheckerSetOptions;
-// java/security/cert/PKIXRevocationChecker$Option - only in API level 24+
+// java/security/cert/PKIXRevocationChecker$Option
extern jclass g_PKIXRevocationCheckerOptionClass;
extern jfieldID g_PKIXRevocationCheckerOptionOnlyEndEntity;
@@ -488,7 +479,6 @@ extern jmethodID g_SSLSessionGetProtocol;
extern jclass g_SSLEngineResult;
extern jmethodID g_SSLEngineResultGetStatus;
extern jmethodID g_SSLEngineResultGetHandshakeStatus;
-extern bool g_SSLEngineResultStatusLegacyOrder;
extern jmethodID g_SSLEngineResultBytesConsumed;
// javax/crypto/KeyAgreement
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c
index a7fda9f371fbd5..c45e12b1319d6e 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_sslstream.c
@@ -16,7 +16,6 @@ enum
};
// javax/net/ssl/SSLEngineResult$Status
-// Android API 24+
enum
{
STATUS__BUFFER_UNDERFLOW = 0,
@@ -25,16 +24,6 @@ enum
STATUS__CLOSED = 3,
};
-// javax/net/ssl/SSLEngineResult$Status
-// Android API 21-23
-enum
-{
- LEGACY__STATUS__BUFFER_OVERFLOW = 0,
- LEGACY__STATUS__BUFFER_UNDERFLOW = 1,
- LEGACY__STATUS__OK = 3,
- LEGACY__STATUS__CLOSED = 2,
-};
-
struct ApplicationProtocolData_t
{
uint8_t* data;
@@ -64,39 +53,13 @@ static bool IsHandshaking(int handshakeStatus)
ARGS_NON_NULL(1, 2) static jobject GetSslSession(JNIEnv* env, SSLStream* sslStream, int handshakeStatus)
{
- // During the initial handshake our sslStream->sslSession doesn't have access to the peer certificates
- // which we need for hostname verification. There are different ways to access the handshake session
- // in different Android API levels.
- // SSLEngine.getHandshakeSession() is available since API 24.
- // In older Android versions (API 21-23) we need to access the handshake session by accessing
- // a private field instead.
-
- if (g_SSLEngineGetHandshakeSession != NULL)
- {
- jobject sslSession = IsHandshaking(handshakeStatus)
- ? (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeSession)
- : (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession);
- if (CheckJNIExceptions(env))
- return NULL;
-
- return sslSession;
- }
- else if (g_ConscryptOpenSSLEngineImplHandshakeSessionField != NULL)
- {
- jobject sslSession = IsHandshaking(handshakeStatus)
- ? (*env)->GetObjectField(env, sslStream->sslEngine, g_ConscryptOpenSSLEngineImplHandshakeSessionField)
- : (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession);
- if (CheckJNIExceptions(env))
- return NULL;
-
- return sslSession;
- }
- else
- {
- LOG_ERROR("Unable to get the current SSLSession from SSLEngine.");
- assert(false && "Unable to get the current SSLSession from SSLEngine.");
+ jobject sslSession = IsHandshaking(handshakeStatus)
+ ? (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetHandshakeSession)
+ : (*env)->CallObjectMethod(env, sslStream->sslEngine, g_SSLEngineGetSession);
+ if (CheckJNIExceptions(env))
return NULL;
- }
+
+ return sslSession;
}
ARGS_NON_NULL_ALL static jobject GetCurrentSslSession(JNIEnv* env, SSLStream* sslStream)
@@ -187,27 +150,6 @@ ARGS_NON_NULL_ALL static jobject EnsureRemaining(JNIEnv* env, jobject oldBuffer,
}
}
-// There has been a change in the SSLEngineResult.Status enum between API 23 and 24 that changed
-// the order/interger values of the enum options.
-static int MapLegacySSLEngineResultStatus(int legacyStatus)
-{
- switch (legacyStatus)
- {
- case LEGACY__STATUS__BUFFER_OVERFLOW:
- return STATUS__BUFFER_OVERFLOW;
- case LEGACY__STATUS__BUFFER_UNDERFLOW:
- return STATUS__BUFFER_UNDERFLOW;
- case LEGACY__STATUS__CLOSED:
- return STATUS__CLOSED;
- case LEGACY__STATUS__OK:
- return STATUS__OK;
- default:
- LOG_ERROR("Unknown legacy SSLEngineResult status: %d", legacyStatus);
- assert(false && "Unknown SSLEngineResult status");
- return -1;
- }
-}
-
ARGS_NON_NULL_ALL static PAL_SSLStreamStatus WrapAndProcessResult(JNIEnv* env, SSLStream* sslStream, int* handshakeStatus, int* bytesConsumed, bool* repeat)
{
// SSLEngineResult result = sslEngine.wrap(appOutBuffer, netOutBuffer);
@@ -224,11 +166,6 @@ ARGS_NON_NULL_ALL static PAL_SSLStreamStatus WrapAndProcessResult(JNIEnv* env, S
int status = GetEnumAsInt(env, (*env)->CallObjectMethod(env, result, g_SSLEngineResultGetStatus));
(*env)->DeleteLocalRef(env, result);
- if (g_SSLEngineResultStatusLegacyOrder)
- {
- status = MapLegacySSLEngineResultStatus(status);
- }
-
switch (status)
{
case STATUS__OK:
@@ -332,11 +269,6 @@ ARGS_NON_NULL_ALL static PAL_SSLStreamStatus DoUnwrap(JNIEnv* env, SSLStream* ss
int status = GetEnumAsInt(env, (*env)->CallObjectMethod(env, result, g_SSLEngineResultGetStatus));
(*env)->DeleteLocalRef(env, result);
- if (g_SSLEngineResultStatusLegacyOrder)
- {
- status = MapLegacySSLEngineResultStatus(status);
- }
-
switch (status)
{
case STATUS__OK:
@@ -717,48 +649,12 @@ int32_t AndroidCryptoNative_SSLStreamInitialize(
return ret;
}
-// This method calls internal Android APIs that are specific to Android API 21-23 and it won't work
-// on newer API levels. By calling the sslEngine.sslParameters.useSni(true) method, the SSLEngine
-// will include the peerHost that was passed in to the SSLEngine factory method in the client hello
-// message.
-ARGS_NON_NULL_ALL static int32_t ApplyLegacyAndroidSNIWorkaround(JNIEnv* env, SSLStream* sslStream)
-{
- if (g_ConscryptOpenSSLEngineImplClass == NULL || !(*env)->IsInstanceOf(env, sslStream->sslEngine, g_ConscryptOpenSSLEngineImplClass))
- return FAIL;
-
- int32_t ret = FAIL;
- INIT_LOCALS(loc, sslParameters);
-
- loc[sslParameters] = (*env)->GetObjectField(env, sslStream->sslEngine, g_ConscryptOpenSSLEngineImplSslParametersField);
- ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
-
- if (!loc[sslParameters])
- goto cleanup;
-
- (*env)->CallVoidMethod(env, loc[sslParameters], g_ConscryptSSLParametersImplSetUseSni, true);
- ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
-
- ret = SUCCESS;
-
-cleanup:
- RELEASE_LOCALS(loc, env);
- return ret;
-}
-
int32_t AndroidCryptoNative_SSLStreamSetTargetHost(SSLStream* sslStream, char* targetHost)
{
abort_if_invalid_pointer_argument (sslStream);
abort_if_invalid_pointer_argument (targetHost);
JNIEnv* env = GetJNIEnv();
-
- if (g_SNIHostName == NULL || g_SSLParametersSetServerNames == NULL)
- {
- // SNIHostName is only available since API 24
- // on APIs 21-23 we use a workaround to force the SSLEngine to use SNI
- return ApplyLegacyAndroidSNIWorkaround(env, sslStream);
- }
-
int32_t ret = FAIL;
INIT_LOCALS(loc, hostStr, nameList, hostName, params);
diff --git a/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c b/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c
index f3d99362967c3b..d33bef23de4454 100644
--- a/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c
+++ b/src/native/libs/System.Security.Cryptography.Native.Android/pal_x509chain.c
@@ -255,8 +255,7 @@ enum
static PAL_X509ChainStatusFlags ChainStatusFromValidatorExceptionReason(JNIEnv* env, jobject reason)
{
int value = (*env)->CallIntMethod(env, reason, g_EnumOrdinal);
- if (g_CertPathExceptionBasicReasonClass != NULL &&
- (*env)->IsInstanceOf(env, reason, g_CertPathExceptionBasicReasonClass))
+ if ((*env)->IsInstanceOf(env, reason, g_CertPathExceptionBasicReasonClass))
{
switch (value)
{
@@ -275,7 +274,7 @@ static PAL_X509ChainStatusFlags ChainStatusFromValidatorExceptionReason(JNIEnv*
return PAL_X509ChainPartialChain;
}
}
- else if (g_PKIXReasonClass != NULL && (*env)->IsInstanceOf(env, reason, g_PKIXReasonClass))
+ else if ((*env)->IsInstanceOf(env, reason, g_PKIXReasonClass))
{
switch (value)
{
@@ -309,10 +308,10 @@ static void PopulateValidationError(JNIEnv* env, jobject error, bool isRevocatio
{
index = (*env)->CallIntMethod(env, error, g_CertPathValidatorExceptionGetIndex);
- // Get the reason (if the API is available) and convert it to a chain status flag
- if (g_CertPathValidatorExceptionGetReason != NULL)
+ // Get the reason and convert it to a chain status flag.
+ jobject reason = (*env)->CallObjectMethod(env, error, g_CertPathValidatorExceptionGetReason);
+ if (!CheckJNIExceptions(env) && reason != NULL)
{
- jobject reason = (*env)->CallObjectMethod(env, error, g_CertPathValidatorExceptionGetReason);
chainStatus = ChainStatusFromValidatorExceptionReason(env, reason);
(*env)->DeleteLocalRef(env, reason);
}
@@ -428,11 +427,6 @@ int32_t AndroidCryptoNative_X509ChainSetCustomTrustStore(X509ChainContext* ctx,
return CheckJNIExceptions(env) ? FAIL : SUCCESS;
}
-static bool X509ChainSupportsRevocationOptions(void)
-{
- return g_CertPathValidatorGetRevocationChecker != NULL && g_PKIXRevocationCheckerClass != NULL;
-}
-
static jobject /*CertPath*/ CreateCertPathFromAnchor(JNIEnv* env, jobject /*TrustAnchor*/ trustAnchor)
{
jobject ret = NULL;
@@ -507,24 +501,14 @@ static int32_t ValidateWithRevocation(JNIEnv* env,
else
{
certPathToUse = ctx->certPath;
- if (X509ChainSupportsRevocationOptions())
- {
- // Only add the ONLY_END_ENTITY if we are not just checking the trust anchor. If ONLY_END_ENTITY is
- // specified, revocation checking will skip the trust anchor even if it is the only certificate.
-
- // HashSet options = new HashSet(3);
- // options.add(PKIXRevocationChecker.Option.ONLY_END_ENTITY);
- loc[options] = (*env)->NewObject(env, g_HashSetClass, g_HashSetCtorWithCapacity, 3);
- jobject endOnly = (*env)->GetStaticObjectField(
- env, g_PKIXRevocationCheckerOptionClass, g_PKIXRevocationCheckerOptionOnlyEndEntity);
- (*env)->CallBooleanMethod(env, loc[options], g_HashSetAdd, endOnly);
- (*env)->DeleteLocalRef(env, endOnly);
- }
- else
- {
- LOG_INFO("Treating revocation flag 'EndCertificateOnly' as 'ExcludeRoot'. "
- "Revocation will be checked for non-end certificates.");
- }
+
+ // Only add the ONLY_END_ENTITY if we are not just checking the trust anchor. If ONLY_END_ENTITY is
+ // specified, revocation checking will skip the trust anchor even if it is the only certificate.
+ loc[options] = (*env)->NewObject(env, g_HashSetClass, g_HashSetCtorWithCapacity, 3);
+ jobject endOnly = (*env)->GetStaticObjectField(
+ env, g_PKIXRevocationCheckerOptionClass, g_PKIXRevocationCheckerOptionOnlyEndEntity);
+ (*env)->CallBooleanMethod(env, loc[options], g_HashSetAdd, endOnly);
+ (*env)->DeleteLocalRef(env, endOnly);
}
(*env)->DeleteLocalRef(env, certPathList);
@@ -536,23 +520,21 @@ static int32_t ValidateWithRevocation(JNIEnv* env,
}
jobject params = ctx->params;
- if (X509ChainSupportsRevocationOptions())
- {
- // PKIXRevocationChecker checker = validator.getRevocationChecker();
- loc[checker] = (*env)->CallObjectMethod(env, validator, g_CertPathValidatorGetRevocationChecker);
- ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
- // Set any specific options
- if (loc[options] != NULL)
- {
- // checker.setOptions(options);
- (*env)->CallVoidMethod(env, loc[checker], g_PKIXRevocationCheckerSetOptions, loc[options]);
- }
+ // PKIXRevocationChecker checker = validator.getRevocationChecker();
+ loc[checker] = (*env)->CallObjectMethod(env, validator, g_CertPathValidatorGetRevocationChecker);
+ ON_EXCEPTION_PRINT_AND_GOTO(cleanup);
- // params.addCertPathChecker(checker);
- (*env)->CallVoidMethod(env, params, g_PKIXBuilderParametersAddCertPathChecker, loc[checker]);
+ // Set any specific options
+ if (loc[options] != NULL)
+ {
+ // checker.setOptions(options);
+ (*env)->CallVoidMethod(env, loc[checker], g_PKIXRevocationCheckerSetOptions, loc[options]);
}
+ // params.addCertPathChecker(checker);
+ (*env)->CallVoidMethod(env, params, g_PKIXBuilderParametersAddCertPathChecker, loc[checker]);
+
// params.setRevocationEnabled(true);
// PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult)validator.validate(certPathToUse, params);
(*env)->CallVoidMethod(env, params, g_PKIXBuilderParametersSetRevocationEnabled, true);
diff --git a/src/native/minipal/memorybarrierprocesswide.c b/src/native/minipal/memorybarrierprocesswide.c
index 6a9704c9920a98..2ab74040c09256 100644
--- a/src/native/minipal/memorybarrierprocesswide.c
+++ b/src/native/minipal/memorybarrierprocesswide.c
@@ -44,7 +44,7 @@
static bool CanFlushUsingMembarrier(void)
{
#ifdef TARGET_ANDROID
- // Avoid calling membarrier on older Android versions where membarrier
+ // Avoid calling membarrier on older Android versions (older than API 29) where membarrier
// may be barred by seccomp causing the process to be killed.
int apiLevel = android_get_device_api_level();
if (apiLevel < __ANDROID_API_Q__)
diff --git a/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
index df0a274e9d4895..bb2caee5b25850 100644
--- a/src/tasks/AndroidAppBuilder/ApkBuilder.cs
+++ b/src/tasks/AndroidAppBuilder/ApkBuilder.cs
@@ -23,7 +23,7 @@ public enum RuntimeFlavorEnum
public partial class ApkBuilder
{
- private const string DefaultMinApiLevel = "21";
+ private const string DefaultMinApiLevel = "24";
private const string DefaultTargetApiLevel = "31";
public string? ProjectName { get; set; }
diff --git a/src/tasks/MobileBuildTasks/Android/AndroidProject.cs b/src/tasks/MobileBuildTasks/Android/AndroidProject.cs
index b3c3ab55ba85da..c83155fdbd2cd6 100644
--- a/src/tasks/MobileBuildTasks/Android/AndroidProject.cs
+++ b/src/tasks/MobileBuildTasks/Android/AndroidProject.cs
@@ -14,7 +14,7 @@ namespace Microsoft.Android.Build
{
public sealed class AndroidProject
{
- private const string DefaultMinApiLevel = "21";
+ private const string DefaultMinApiLevel = "24";
private const string Cmake = "cmake";
private TaskLoggingHelper logger;