diff --git a/android/lint.xml b/android/lint.xml
index 5d43d7ff6..8ad971986 100644
--- a/android/lint.xml
+++ b/android/lint.xml
@@ -28,4 +28,10 @@
+
+
+
+
+
+
diff --git a/android/src/main/java/org/conscrypt/ConscryptNetworkSecurityPolicy.java b/android/src/main/java/org/conscrypt/ConscryptNetworkSecurityPolicy.java
new file mode 100644
index 000000000..4f5f0e6ad
--- /dev/null
+++ b/android/src/main/java/org/conscrypt/ConscryptNetworkSecurityPolicy.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.conscrypt;
+
+import org.conscrypt.metrics.CertificateTransparencyVerificationReason;
+
+/**
+ * A default NetworkSecurityPolicy for unbundled Android.
+ */
+@Internal
+public class ConscryptNetworkSecurityPolicy implements NetworkSecurityPolicy {
+ public static ConscryptNetworkSecurityPolicy getDefault() {
+ return new ConscryptNetworkSecurityPolicy();
+ }
+
+ @Override
+ public boolean isCertificateTransparencyVerificationRequired(String hostname) {
+ return false;
+ }
+
+ @Override
+ public CertificateTransparencyVerificationReason getCertificateTransparencyVerificationReason(
+ String hostname) {
+ return CertificateTransparencyVerificationReason.UNKNOWN;
+ }
+
+ @Override
+ public DomainEncryptionMode getDomainEncryptionMode(String hostname) {
+ return DomainEncryptionMode.UNKNOWN;
+ }
+}
diff --git a/android/src/main/java/org/conscrypt/Platform.java b/android/src/main/java/org/conscrypt/Platform.java
index b3433f12c..905835ada 100644
--- a/android/src/main/java/org/conscrypt/Platform.java
+++ b/android/src/main/java/org/conscrypt/Platform.java
@@ -59,11 +59,13 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.function.Supplier;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIMatcher;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
@@ -859,59 +861,8 @@ static boolean supportsX509ExtendedTrustManager() {
return Build.VERSION.SDK_INT > 23;
}
- /**
- * Check if SCT verification is required for a given hostname.
- *
- * SCT Verification is enabled using {@code Security} properties.
- * The "conscrypt.ct.enable" property must be true, as well as a per domain property.
- * The reverse notation of the domain name, prefixed with "conscrypt.ct.enforce."
- * is used as the property name.
- * Basic globbing is also supported.
- *
- * For example, for the domain foo.bar.com, the following properties will be
- * looked up, in order of precedence.
- * - conscrypt.ct.enforce.com.bar.foo
- * - conscrypt.ct.enforce.com.bar.*
- * - conscrypt.ct.enforce.com.*
- * - conscrypt.ct.enforce.*
- */
- public static boolean isCTVerificationRequired(String hostname) {
- if (hostname == null) {
- return false;
- }
- // TODO: Use the platform version on platforms that support it
-
- String property = Security.getProperty("conscrypt.ct.enable");
- if (property == null || !Boolean.parseBoolean(property)) {
- return false;
- }
-
- List parts = Arrays.asList(hostname.split("\\."));
- Collections.reverse(parts);
-
- boolean enable = false;
- String propertyName = "conscrypt.ct.enforce";
- // The loop keeps going on even once we've found a match
- // This allows for finer grained settings on subdomains
- for (String part : parts) {
- property = Security.getProperty(propertyName + ".*");
- if (property != null) {
- enable = Boolean.parseBoolean(property);
- }
-
- propertyName = propertyName + "." + part;
- }
-
- property = Security.getProperty(propertyName);
- if (property != null) {
- enable = Boolean.parseBoolean(property);
- }
- return enable;
- }
-
- public static CertificateTransparencyVerificationReason reasonCTVerificationRequired(
- String hostname) {
- return CertificateTransparencyVerificationReason.UNKNOWN;
+ static SSLException wrapInvalidEchDataException(SSLException e) {
+ return e;
}
static boolean supportsConscryptCertStore() {
@@ -940,7 +891,8 @@ static CertBlocklist newDefaultBlocklist() {
return null;
}
- static CertificateTransparency newDefaultCertificateTransparency() {
+ static CertificateTransparency newDefaultCertificateTransparency(
+ Supplier policySupplier) {
return null;
}
diff --git a/common/src/jni/main/cpp/conscrypt/native_crypto.cc b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
index eaea7717f..7ede18d2b 100644
--- a/common/src/jni/main/cpp/conscrypt/native_crypto.cc
+++ b/common/src/jni/main/cpp/conscrypt/native_crypto.cc
@@ -58,6 +58,8 @@
#include
#include
+#include "jni.h"
+
using conscrypt::AppData;
using conscrypt::BioInputStream;
using conscrypt::BioOutputStream;
@@ -8419,8 +8421,7 @@ static SSL_SESSION* server_session_requested_callback(SSL* ssl, const uint8_t* i
return ssl_session_ptr;
}
-static jint NativeCrypto_EVP_has_aes_hardware(JNIEnv* env, jclass) {
- CHECK_ERROR_QUEUE_ON_RETURN;
+static jint NativeCrypto_EVP_has_aes_hardware(CRITICAL_JNI_PARAMS) {
int ret = 0;
ret = EVP_has_aes_hardware();
JNI_TRACE("EVP_has_aes_hardware => %d", ret);
@@ -10714,9 +10715,8 @@ static jlong NativeCrypto_SSL_get_timeout(JNIEnv* env, jclass, jlong ssl_address
return result;
}
-static jint NativeCrypto_SSL_get_signature_algorithm_key_type(JNIEnv* env, jclass,
- jint signatureAlg) {
- CHECK_ERROR_QUEUE_ON_RETURN;
+static jint NativeCrypto_SSL_get_signature_algorithm_key_type(
+ CRITICAL_JNI_PARAMS_COMMA jint signatureAlg) {
return SSL_get_signature_algorithm_key_type(signatureAlg);
}
@@ -11189,7 +11189,7 @@ static jint NativeCrypto_SSL_get_error(JNIEnv* env, jclass, jlong ssl_address,
return SSL_get_error(ssl, ret);
}
-static void NativeCrypto_SSL_clear_error(JNIEnv*, jclass) {
+static void NativeCrypto_SSL_clear_error(CRITICAL_JNI_PARAMS) {
ERR_clear_error();
}
diff --git a/common/src/jni/main/include/conscrypt/jniutil.h b/common/src/jni/main/include/conscrypt/jniutil.h
index 70ae3965e..4193d49f9 100644
--- a/common/src/jni/main/include/conscrypt/jniutil.h
+++ b/common/src/jni/main/include/conscrypt/jniutil.h
@@ -26,6 +26,14 @@
namespace conscrypt {
namespace jniutil {
+#ifdef __ANDROID__
+ #define CRITICAL_JNI_PARAMS
+ #define CRITICAL_JNI_PARAMS_COMMA
+#else
+ #define CRITICAL_JNI_PARAMS JNIEnv*, jclass
+ #define CRITICAL_JNI_PARAMS_COMMA JNIEnv*, jclass,
+#endif
+
extern JavaVM* gJavaVM;
extern jclass cryptoUpcallsClass;
extern jclass openSslInputStreamClass;
diff --git a/common/src/main/java/org/conscrypt/AbstractConscryptEngine.java b/common/src/main/java/org/conscrypt/AbstractConscryptEngine.java
index 3f0ac2914..6bbd260da 100644
--- a/common/src/main/java/org/conscrypt/AbstractConscryptEngine.java
+++ b/common/src/main/java/org/conscrypt/AbstractConscryptEngine.java
@@ -135,6 +135,13 @@ public abstract SSLEngineResult wrap(ByteBuffer[] srcs, int srcsOffset, int srcs
*/
abstract void setUseSessionTickets(boolean useSessionTickets);
+ /**
+ * This method sets the ECH config data to be used in the TLS handshake.
+ *
+ * @param echConfigList the ECH config data to be used in the TLS handshake
+ */
+ abstract void setEchConfigList(byte[] echConfigList);
+
/**
* Sets the list of ALPN protocols.
*
diff --git a/common/src/main/java/org/conscrypt/AbstractConscryptSocket.java b/common/src/main/java/org/conscrypt/AbstractConscryptSocket.java
index b917fb405..e77e37562 100644
--- a/common/src/main/java/org/conscrypt/AbstractConscryptSocket.java
+++ b/common/src/main/java/org/conscrypt/AbstractConscryptSocket.java
@@ -627,6 +627,13 @@ private boolean isDelegating() {
*/
abstract void setUseSessionTickets(boolean useSessionTickets);
+ /**
+ * This method sets the ECH config data to be used in the TLS handshake.
+ *
+ * @param echConfigList the ECH config data to be used in the TLS handshake
+ */
+ abstract void setEchConfigList(byte[] echConfigList);
+
/**
* Enables/disables TLS Channel ID for this server socket.
*
diff --git a/common/src/main/java/org/conscrypt/BufferUtils.java b/common/src/main/java/org/conscrypt/BufferUtils.java
index 3c5ee965a..a5cd5a208 100644
--- a/common/src/main/java/org/conscrypt/BufferUtils.java
+++ b/common/src/main/java/org/conscrypt/BufferUtils.java
@@ -22,13 +22,18 @@
import java.nio.ByteBuffer;
-final class BufferUtils {
+/**
+ * Utility methods for dealing with arrays of ByteBuffers.
+ *
+ * @hide This class is not part of the Android public SDK API
+ */
+public final class BufferUtils {
private BufferUtils() {}
/**
* Throws {@link IllegalArgumentException} if any of the buffers in the array are null.
*/
- static void checkNotNull(ByteBuffer[] buffers) {
+ public static void checkNotNull(ByteBuffer[] buffers) {
for (ByteBuffer buffer : buffers) {
if (buffer == null) {
throw new IllegalArgumentException("Null buffer in array");
@@ -39,7 +44,7 @@ static void checkNotNull(ByteBuffer[] buffers) {
/**
* Returns the total number of bytes remaining in the buffer array.
*/
- static long remaining(ByteBuffer[] buffers) {
+ public static long remaining(ByteBuffer[] buffers) {
long size = 0;
for (ByteBuffer buffer : buffers) {
size += buffer.remaining();
@@ -52,7 +57,7 @@ static long remaining(ByteBuffer[] buffers) {
*
* @throws IllegalArgumentException if there are fewer than {@code toConsume} bytes remaining
*/
- static void consume(ByteBuffer[] sourceBuffers, int toConsume) {
+ public static void consume(ByteBuffer[] sourceBuffers, int toConsume) {
for (ByteBuffer sourceBuffer : sourceBuffers) {
int amount = min(sourceBuffer.remaining(), toConsume);
if (amount > 0) {
@@ -72,7 +77,7 @@ static void consume(ByteBuffer[] sourceBuffers, int toConsume) {
* Looks for a buffer in the buffer array which EITHER is larger than {@code minSize} AND
* has no preceding non-empty buffers OR is the only non-empty buffer in the array.
*/
- static ByteBuffer getBufferLargerThan(ByteBuffer[] buffers, int minSize) {
+ public static ByteBuffer getBufferLargerThan(ByteBuffer[] buffers, int minSize) {
int length = buffers.length;
for (int i = 0; i < length; i++) {
ByteBuffer buffer = buffers[i];
diff --git a/common/src/main/java/org/conscrypt/CertBlocklist.java b/common/src/main/java/org/conscrypt/CertBlocklist.java
index 0ed68b0ab..056718f02 100644
--- a/common/src/main/java/org/conscrypt/CertBlocklist.java
+++ b/common/src/main/java/org/conscrypt/CertBlocklist.java
@@ -16,12 +16,15 @@
package org.conscrypt;
+import org.conscrypt.Internal;
+
import java.math.BigInteger;
import java.security.PublicKey;
/**
* A set of certificates that are blacklisted from trust.
*/
+@Internal
public interface CertBlocklist {
/**
* Returns whether the given public key is in the blacklist.
diff --git a/common/src/main/java/org/conscrypt/CertBlocklistEntry.java b/common/src/main/java/org/conscrypt/CertBlocklistEntry.java
new file mode 100644
index 000000000..950d568d5
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/CertBlocklistEntry.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.conscrypt;
+
+import org.conscrypt.Internal;
+
+/**
+ * An entry in the blocklist, for the purpose of reporting.
+ */
+@Internal
+public interface CertBlocklistEntry {
+ enum Origin { SHA1_TEST, SHA1_BUILT_IN, SHA1_FILE, SHA256_TEST, SHA256_BUILT_IN, SHA256_FILE }
+
+ /**
+ * Returns the origin of this entry.
+ */
+ Origin getOrigin();
+
+ /**
+ * Returns the index of this entry in its blocklist.
+ */
+ int getIndex();
+}
diff --git a/common/src/main/java/org/conscrypt/Conscrypt.java b/common/src/main/java/org/conscrypt/Conscrypt.java
index b868d6959..819469d27 100644
--- a/common/src/main/java/org/conscrypt/Conscrypt.java
+++ b/common/src/main/java/org/conscrypt/Conscrypt.java
@@ -400,6 +400,16 @@ public static void setUseSessionTickets(SSLSocket socket, boolean useSessionTick
toConscrypt(socket).setUseSessionTickets(useSessionTickets);
}
+ /**
+ * This method sets the ECH config data to be used in the TLS handshake.
+ *
+ * @param socket the socket
+ * @param echConfigList the ECH config data to be used in the TLS handshake
+ */
+ public static void setEchConfigList(SSLSocket socket, byte[] echConfigList) {
+ toConscrypt(socket).setEchConfigList(echConfigList);
+ }
+
/**
* Enables/disables TLS Channel ID for the given server-side socket.
*
@@ -699,6 +709,16 @@ public static void setUseSessionTickets(SSLEngine engine, boolean useSessionTick
toConscrypt(engine).setUseSessionTickets(useSessionTickets);
}
+ /**
+ * This method sets the ECH config data to be used in the TLS handshake.
+ *
+ * @param engine the engine
+ * @param echConfigList the ECH config data to be used in the TLS handshake
+ */
+ public static void setEchConfigList(SSLEngine engine, byte[] echConfigList) {
+ toConscrypt(engine).setEchConfigList(echConfigList);
+ }
+
/**
* Sets the application-layer protocols (ALPN) in prioritization order.
*
diff --git a/common/src/main/java/org/conscrypt/ConscryptEngine.java b/common/src/main/java/org/conscrypt/ConscryptEngine.java
index 8dd220e0d..ac721065a 100644
--- a/common/src/main/java/org/conscrypt/ConscryptEngine.java
+++ b/common/src/main/java/org/conscrypt/ConscryptEngine.java
@@ -1745,6 +1745,11 @@ void setUseSessionTickets(boolean useSessionTickets) {
sslParameters.setUseSessionTickets(useSessionTickets);
}
+ @Override
+ void setEchConfigList(byte[] echConfigList) {
+ sslParameters.setEchConfigList(echConfigList);
+ }
+
@Override
String[] getApplicationProtocols() {
return sslParameters.getApplicationProtocols();
diff --git a/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java
index 93de52def..c4e4bd439 100644
--- a/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java
+++ b/common/src/main/java/org/conscrypt/ConscryptEngineSocket.java
@@ -463,6 +463,11 @@ public final void setUseSessionTickets(boolean useSessionTickets) {
engine.setUseSessionTickets(useSessionTickets);
}
+ @Override
+ public final void setEchConfigList(byte[] echConfigList) {
+ engine.setEchConfigList(echConfigList);
+ }
+
@Override
public final void setChannelIdEnabled(boolean enabled) {
engine.setChannelIdEnabled(enabled);
diff --git a/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
index ba5a525cb..85e36f187 100644
--- a/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
+++ b/common/src/main/java/org/conscrypt/ConscryptFileDescriptorSocket.java
@@ -773,6 +773,11 @@ public final void setUseSessionTickets(boolean useSessionTickets) {
sslParameters.setUseSessionTickets(useSessionTickets);
}
+ @Override
+ public final void setEchConfigList(byte[] echConfigList) {
+ sslParameters.setEchConfigList(echConfigList);
+ }
+
/**
* This method enables Server Name Indication. If the hostname is not a valid SNI hostname,
* the SNI extension will be omitted from the handshake.
diff --git a/common/src/main/java/org/conscrypt/ConscryptX509TrustManager.java b/common/src/main/java/org/conscrypt/ConscryptX509TrustManager.java
new file mode 100644
index 000000000..f3586d6f9
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/ConscryptX509TrustManager.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.conscrypt;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+/**
+ * Interface for TrustManager methods implemented in Conscrypt but not part of
+ * the standard X509TrustManager or X509ExtendedTrustManager.
+ *
+ * These methods can be called by the Android framework. Extend
+ * X509TrustManagerExtensions if these need to be visible to apps.
+ */
+@Internal
+public interface ConscryptX509TrustManager {
+ /**
+ * Verifies the given certificate chain.
+ *
+ *
See {@link X509TrustManager#checkServerTrusted(X509Certificate[], String)} for a
+ * description of the chain and authType parameters. The final parameter, host, should be the
+ * hostname of the server.
+ *
+ * @throws CertificateException if the chain does not verify correctly.
+ * @return the properly ordered chain used for verification as a list of X509Certificates.
+ */
+ public List checkServerTrusted(X509Certificate[] chain, String authType,
+ String hostname) throws CertificateException;
+
+ /**
+ * Verifies the given certificate chain.
+ *
+ *
See {@link X509TrustManager#checkServerTrusted(X509Certificate[], String)} for a
+ * description of the chain and authType parameters. The final parameter, host, should be the
+ * hostname of the server.
+ *
+ *
ocspData and tlsSctData may be provided to verify any Signed Certificate Timestamp (SCT)
+ * attached to the connection. These are ASN.1 octet strings (SignedCertificateTimestampList) as
+ * described in RFC 6962, Section 3.3. Note that SCTs embedded in the certificate chain will
+ * automatically be processed.
+ *
+ * @throws CertificateException if the chain does not verify correctly.
+ * @return the properly ordered chain used for verification as a list of X509Certificates.
+ */
+ public List checkServerTrusted(X509Certificate[] chain, byte[] ocspData,
+ byte[] tlsSctData, String authType,
+ String hostname) throws CertificateException;
+}
diff --git a/common/src/main/java/org/conscrypt/DomainEncryptionMode.java b/common/src/main/java/org/conscrypt/DomainEncryptionMode.java
new file mode 100644
index 000000000..ab878a468
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/DomainEncryptionMode.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.conscrypt;
+
+@Internal enum DomainEncryptionMode { UNKNOWN, DISABLED, OPPORTUNISTIC, ENABLED, REQUIRED }
diff --git a/common/src/main/java/org/conscrypt/EchOptions.java b/common/src/main/java/org/conscrypt/EchOptions.java
new file mode 100644
index 000000000..3715a4819
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/EchOptions.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.conscrypt;
+
+@Internal
+class EchOptions {
+ private final byte[] configList;
+ private final boolean enableGrease;
+
+ EchOptions(byte[] configList, boolean enableGrease) {
+ this.configList = configList;
+ this.enableGrease = enableGrease;
+ }
+
+ byte[] getConfigList() {
+ return configList;
+ }
+
+ boolean isGreaseEnabled() {
+ return enableGrease;
+ }
+}
diff --git a/common/src/main/java/org/conscrypt/Java8EngineWrapper.java b/common/src/main/java/org/conscrypt/Java8EngineWrapper.java
index 62f89d264..c6a0b7d38 100644
--- a/common/src/main/java/org/conscrypt/Java8EngineWrapper.java
+++ b/common/src/main/java/org/conscrypt/Java8EngineWrapper.java
@@ -275,6 +275,11 @@ void setUseSessionTickets(boolean useSessionTickets) {
delegate.setUseSessionTickets(useSessionTickets);
}
+ @Override
+ void setEchConfigList(byte[] echConfigList) {
+ delegate.setEchConfigList(echConfigList);
+ }
+
@Override
void setApplicationProtocols(String[] protocols) {
delegate.setApplicationProtocols(protocols);
diff --git a/common/src/main/java/org/conscrypt/NativeCrypto.java b/common/src/main/java/org/conscrypt/NativeCrypto.java
index e939f43b7..d4fe34101 100644
--- a/common/src/main/java/org/conscrypt/NativeCrypto.java
+++ b/common/src/main/java/org/conscrypt/NativeCrypto.java
@@ -18,6 +18,8 @@
import org.conscrypt.OpenSSLX509CertificateFactory.ParsingException;
+// android-add: import dalvik.annotation.optimization.CriticalNative;
+// android-add: import dalvik.annotation.optimization.FastNative;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.OutputStream;
@@ -61,6 +63,7 @@
public final class NativeCrypto {
// --- OpenSSL library initialization --------------------------------------
private static final UnsatisfiedLinkError loadError;
+
static {
UnsatisfiedLinkError error = null;
try {
@@ -75,8 +78,8 @@ public final class NativeCrypto {
}
/**
- * Checks to see whether or not the native library was successfully loaded. If not, throws
- * the {@link UnsatisfiedLinkError} that was encountered while attempting to load the library.
+ * Checks to see whether or not the native library was successfully loaded. If not, throws the
+ * {@link UnsatisfiedLinkError} that was encountered while attempting to load the library.
*/
static void checkAvailability() {
if (loadError != null) {
@@ -86,23 +89,32 @@ static void checkAvailability() {
// --- DSA/RSA public/private key handling functions -----------------------
+ // android-add: @FastNative
static native long EVP_PKEY_new_RSA(byte[] n, byte[] e, byte[] d, byte[] p, byte[] q,
byte[] dmp1, byte[] dmq1, byte[] iqmp);
+ // android-add: @FastNative
static native int EVP_PKEY_type(NativeRef.EVP_PKEY pkey);
+ // android-add: @FastNative
static native String EVP_PKEY_print_public(NativeRef.EVP_PKEY pkeyRef);
+ // android-add: @FastNative
static native String EVP_PKEY_print_params(NativeRef.EVP_PKEY pkeyRef);
+ // android-add: @FastNative
static native void EVP_PKEY_free(long pkey);
+ // android-add: @FastNative
static native int EVP_PKEY_cmp(NativeRef.EVP_PKEY pkey1, NativeRef.EVP_PKEY pkey2);
+ // android-add: @FastNative
static native byte[] EVP_marshal_private_key(NativeRef.EVP_PKEY pkey);
+ // android-add: @FastNative
static native long EVP_parse_private_key(byte[] data) throws ParsingException;
+ // android-add: @FastNative
static native byte[] EVP_marshal_public_key(NativeRef.EVP_PKEY pkey);
static native long EVP_PKEY_from_private_key_info(byte[] data, int[] algs)
@@ -123,33 +135,44 @@ static native long EVP_PKEY_from_subject_public_key_info(byte[] data, int[] algs
static native byte[] EVP_PKEY_get_private_seed(NativeRef.EVP_PKEY pkey);
+ // android-add: @FastNative
static native byte[] EVP_raw_X25519_private_key(byte[] data)
throws ParsingException, InvalidKeyException;
+ // android-add: @FastNative
static native long EVP_parse_public_key(byte[] data) throws ParsingException;
+ // android-add: @FastNative
static native long PEM_read_bio_PUBKEY(long bioCtx);
+ // android-add: @FastNative
static native long PEM_read_bio_PrivateKey(long bioCtx);
+ // android-add: @FastNative
static native long getRSAPrivateKeyWrapper(PrivateKey key, byte[] modulus);
+ // android-add: @FastNative
static native long getECPrivateKeyWrapper(PrivateKey key, NativeRef.EC_GROUP ecGroupRef);
static native long RSA_generate_key_ex(int modulusBits, byte[] publicExponent);
+ // android-add: @FastNative
static native int RSA_size(NativeRef.EVP_PKEY pkey);
+ // android-add: @FastNative
static native int RSA_private_encrypt(int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey,
int padding);
+ // android-add: @FastNative
static native int RSA_public_decrypt(int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey,
int padding)
throws BadPaddingException, SignatureException;
+ // android-add: @FastNative
static native int RSA_public_encrypt(int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey,
int padding);
+ // android-add: @FastNative
static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, NativeRef.EVP_PKEY pkey,
int padding)
throws BadPaddingException, SignatureException;
@@ -157,11 +180,13 @@ static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, NativeRe
/*
* Returns array of {n, e}
*/
+ // android-add: @FastNative
static native byte[][] get_RSA_public_params(NativeRef.EVP_PKEY rsa);
/*
* Returns array of {n, e, d, p, q, dmp1, dmq1, iqmp}
*/
+ // android-add: @FastNative
static native byte[][] get_RSA_private_params(NativeRef.EVP_PKEY rsa);
// --- ChaCha20 -----------------------
@@ -169,91 +194,122 @@ static native int RSA_private_decrypt(int flen, byte[] from, byte[] to, NativeRe
/*
* Returns the encrypted or decrypted version of the data.
*/
+ // android-add: @FastNative
static native void chacha20_encrypt_decrypt(byte[] in, int inOffset, byte[] out, int outOffset,
int length, byte[] key, byte[] nonce,
int blockCounter);
// --- EC functions --------------------------
+ // android-add: @FastNative
static native long EVP_PKEY_new_EC_KEY(NativeRef.EC_GROUP groupRef,
NativeRef.EC_POINT pubkeyRef, byte[] privkey);
+ // android-add: @FastNative
static native long EC_GROUP_new_by_curve_name(String curveName);
+ // android-add: @FastNative
static native long EC_GROUP_new_arbitrary(byte[] p, byte[] a, byte[] b, byte[] x, byte[] y,
byte[] order, int cofactor);
+ // android-add: @FastNative
static native String EC_GROUP_get_curve_name(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native byte[][] EC_GROUP_get_curve(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native void EC_GROUP_clear_free(long groupRef);
+ // android-add: @FastNative
static native long EC_GROUP_get_generator(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native byte[] EC_GROUP_get_order(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native int EC_GROUP_get_degree(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native byte[] EC_GROUP_get_cofactor(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native long EC_POINT_new(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native void EC_POINT_clear_free(long pointRef);
+ // android-add: @FastNative
static native byte[][] EC_POINT_get_affine_coordinates(NativeRef.EC_GROUP groupRef,
NativeRef.EC_POINT pointRef);
+ // android-add: @FastNative
static native void EC_POINT_set_affine_coordinates(NativeRef.EC_GROUP groupRef,
NativeRef.EC_POINT pointRef, byte[] x,
byte[] y);
static native long EC_KEY_generate_key(NativeRef.EC_GROUP groupRef);
+ // android-add: @FastNative
static native long EC_KEY_get1_group(NativeRef.EVP_PKEY pkeyRef);
+ // android-add: @FastNative
static native byte[] EC_KEY_get_private_key(NativeRef.EVP_PKEY keyRef);
+ // android-add: @FastNative
static native long EC_KEY_get_public_key(NativeRef.EVP_PKEY keyRef);
+ // android-add: @FastNative
static native byte[] EC_KEY_marshal_curve_name(NativeRef.EC_GROUP groupRef) throws IOException;
+ // android-add: @FastNative
static native long EC_KEY_parse_curve_name(byte[] encoded) throws IOException;
+ // android-add: @FastNative
static native int ECDH_compute_key(byte[] out, int outOffset, NativeRef.EVP_PKEY publicKeyRef,
NativeRef.EVP_PKEY privateKeyRef)
throws InvalidKeyException, IndexOutOfBoundsException;
+ // android-add: @FastNative
static native int ECDSA_size(NativeRef.EVP_PKEY pkey);
+ // android-add: @FastNative
static native int ECDSA_sign(byte[] data, int dataLen, byte[] sig, NativeRef.EVP_PKEY pkey);
+ // android-add: @FastNative
static native int ECDSA_verify(byte[] data, int dataLen, byte[] sig, NativeRef.EVP_PKEY pkey);
// --- MLDSA65 --------------------------------------------------------------
+ // android-add: @FastNative
static native byte[] MLDSA65_public_key_from_seed(byte[] privateKeySeed);
// --- MLDSA87 --------------------------------------------------------------
+ // android-add: @FastNative
static native byte[] MLDSA87_public_key_from_seed(byte[] privateKeySeed);
// --- SLHDSA_SHA2_128S --------------------------------------------------------------
static native void SLHDSA_SHA2_128S_generate_key(byte[] outPublicKey, byte[] outPrivateKey);
+ // android-add: @FastNative
static native byte[] SLHDSA_SHA2_128S_sign(byte[] data, int dataLen, byte[] privateKey);
+ // android-add: @FastNative
static native int SLHDSA_SHA2_128S_verify(byte[] data, int dataLen, byte[] sig,
byte[] publicKey);
// --- Curve25519 --------------
+ // android-add: @FastNative
static native boolean X25519(byte[] out, byte[] privateKey, byte[] publicKey)
throws InvalidKeyException;
+ // android-add: @FastNative
static native void X25519_keypair(byte[] outPublicKey, byte[] outPrivateKey);
+ // android-add: @FastNative
static native void ED25519_keypair(byte[] outPublicKey, byte[] outPrivateKey);
// --- X-Wing --------------
@@ -263,154 +319,207 @@ static native boolean X25519(byte[] out, byte[] privateKey, byte[] publicKey)
// --- Message digest functions --------------
// These return const references
+ // android-add: @FastNative
static native long EVP_get_digestbyname(String name);
+ // android-add: @FastNative
static native int EVP_MD_size(long evp_md_const);
// --- Message digest context functions --------------
+ // android-add: @FastNative
static native long EVP_MD_CTX_create();
+ // android-add: @FastNative
static native void EVP_MD_CTX_cleanup(NativeRef.EVP_MD_CTX ctx);
+ // android-add: @FastNative
static native void EVP_MD_CTX_destroy(long ctx);
+ // android-add: @FastNative
static native int EVP_MD_CTX_copy_ex(NativeRef.EVP_MD_CTX dst_ctx,
NativeRef.EVP_MD_CTX src_ctx);
// --- Digest handling functions -------------------------------------------
+ // android-add: @FastNative
static native int EVP_DigestInit_ex(NativeRef.EVP_MD_CTX ctx, long evp_md);
+ // android-add: @FastNative
static native void EVP_DigestUpdate(NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset,
int length);
+ // android-add: @FastNative
static native void EVP_DigestUpdateDirect(NativeRef.EVP_MD_CTX ctx, long ptr, int length);
+ // android-add: @FastNative
static native int EVP_DigestFinal_ex(NativeRef.EVP_MD_CTX ctx, byte[] hash, int offset);
// --- Signature handling functions ----------------------------------------
+ // android-add: @FastNative
static native long EVP_DigestSignInit(NativeRef.EVP_MD_CTX ctx, long evpMdRef,
NativeRef.EVP_PKEY key);
+ // android-add: @FastNative
static native long EVP_DigestVerifyInit(NativeRef.EVP_MD_CTX ctx, long evpMdRef,
NativeRef.EVP_PKEY key);
+ // android-add: @FastNative
static native void EVP_DigestSignUpdate(NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset,
int length);
+ // android-add: @FastNative
static native void EVP_DigestSignUpdateDirect(NativeRef.EVP_MD_CTX ctx, long ptr, int length);
+ // android-add: @FastNative
static native void EVP_DigestVerifyUpdate(NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset,
int length);
+ // android-add: @FastNative
static native void EVP_DigestVerifyUpdateDirect(NativeRef.EVP_MD_CTX ctx, long ptr, int length);
+ // android-add: @FastNative
static native byte[] EVP_DigestSignFinal(NativeRef.EVP_MD_CTX ctx);
+ // android-add: @FastNative
static native boolean EVP_DigestVerifyFinal(NativeRef.EVP_MD_CTX ctx, byte[] signature,
int offset, int length)
throws IndexOutOfBoundsException;
+ // android-add: @FastNative
static native byte[] EVP_DigestSign(NativeRef.EVP_MD_CTX ctx, byte[] buffer, int offset,
int length);
+ // android-add: @FastNative
static native boolean EVP_DigestVerify(NativeRef.EVP_MD_CTX ctx, byte[] sigBuffer,
int sigOffset, int sigLen, byte[] dataBuffer,
int dataOffset, int dataLen);
+ // android-add: @FastNative
static native long EVP_PKEY_encrypt_init(NativeRef.EVP_PKEY pkey) throws InvalidKeyException;
+ // android-add: @FastNative
static native int EVP_PKEY_encrypt(NativeRef.EVP_PKEY_CTX ctx, byte[] out, int outOffset,
byte[] input, int inOffset, int inLength)
throws IndexOutOfBoundsException, BadPaddingException;
+ // android-add: @FastNative
static native long EVP_PKEY_decrypt_init(NativeRef.EVP_PKEY pkey) throws InvalidKeyException;
+ // android-add: @FastNative
static native int EVP_PKEY_decrypt(NativeRef.EVP_PKEY_CTX ctx, byte[] out, int outOffset,
byte[] input, int inOffset, int inLength)
throws IndexOutOfBoundsException, BadPaddingException;
+ // android-add: @FastNative
static native void EVP_PKEY_CTX_free(long pkeyCtx);
+ // android-add: @FastNative
static native void EVP_PKEY_CTX_set_rsa_padding(long ctx, int pad)
throws InvalidAlgorithmParameterException;
+ // android-add: @FastNative
static native void EVP_PKEY_CTX_set_rsa_pss_saltlen(long ctx, int len)
throws InvalidAlgorithmParameterException;
+ // android-add: @FastNative
static native void EVP_PKEY_CTX_set_rsa_mgf1_md(long ctx, long evpMdRef)
throws InvalidAlgorithmParameterException;
+ // android-add: @FastNative
static native void EVP_PKEY_CTX_set_rsa_oaep_md(long ctx, long evpMdRef)
throws InvalidAlgorithmParameterException;
+ // android-add: @FastNative
static native void EVP_PKEY_CTX_set_rsa_oaep_label(long ctx, byte[] label)
throws InvalidAlgorithmParameterException;
// --- Block ciphers -------------------------------------------------------
// These return const references
+ // android-add: @FastNative
static native long EVP_get_cipherbyname(String string);
+ // android-add: @FastNative
static native void EVP_CipherInit_ex(NativeRef.EVP_CIPHER_CTX ctx, long evpCipher, byte[] key,
byte[] iv, boolean encrypting);
+ // android-add: @FastNative
static native int EVP_CipherUpdate(NativeRef.EVP_CIPHER_CTX ctx, byte[] out, int outOffset,
byte[] in, int inOffset, int inLength)
throws IndexOutOfBoundsException;
+ // android-add: @FastNative
static native int EVP_CipherFinal_ex(NativeRef.EVP_CIPHER_CTX ctx, byte[] out, int outOffset)
throws BadPaddingException, IllegalBlockSizeException;
+ // android-add: @FastNative
static native int EVP_CIPHER_iv_length(long evpCipher);
+ // android-add: @FastNative
static native long EVP_CIPHER_CTX_new();
+ // android-add: @FastNative
static native int EVP_CIPHER_CTX_block_size(NativeRef.EVP_CIPHER_CTX ctx);
+ // android-add: @FastNative
static native int get_EVP_CIPHER_CTX_buf_len(NativeRef.EVP_CIPHER_CTX ctx);
+ // android-add: @FastNative
static native boolean get_EVP_CIPHER_CTX_final_used(NativeRef.EVP_CIPHER_CTX ctx);
+ // android-add: @FastNative
static native void EVP_CIPHER_CTX_set_padding(NativeRef.EVP_CIPHER_CTX ctx,
boolean enablePadding);
+ // android-add: @FastNative
static native void EVP_CIPHER_CTX_set_key_length(NativeRef.EVP_CIPHER_CTX ctx, int keyBitSize);
+ // android-add: @FastNative
static native void EVP_CIPHER_CTX_free(long ctx);
// --- AEAD ----------------------------------------------------------------
+ // android-add: @FastNative
static native long EVP_aead_aes_128_gcm();
+ // android-add: @FastNative
static native long EVP_aead_aes_256_gcm();
+ // android-add: @FastNative
static native long EVP_aead_chacha20_poly1305();
+ // android-add: @FastNative
static native long EVP_aead_aes_128_gcm_siv();
+ // android-add: @FastNative
static native long EVP_aead_aes_256_gcm_siv();
+ // android-add: @FastNative
static native int EVP_AEAD_max_overhead(long evpAead);
+ // android-add: @FastNative
static native int EVP_AEAD_nonce_length(long evpAead);
+ // android-add: @FastNative
static native int EVP_AEAD_CTX_seal(long evpAead, byte[] key, int tagLengthInBytes, byte[] out,
int outOffset, byte[] nonce, byte[] in, int inOffset,
int inLength, byte[] ad)
throws ShortBufferException, BadPaddingException;
+ // android-add: @FastNative
static native int EVP_AEAD_CTX_seal_buf(long evpAead, byte[] key, int tagLengthInBytes,
ByteBuffer out, byte[] nonce, ByteBuffer input,
byte[] ad)
throws ShortBufferException, BadPaddingException;
+ // android-add: @FastNative
static native int EVP_AEAD_CTX_open(long evpAead, byte[] key, int tagLengthInBytes, byte[] out,
int outOffset, byte[] nonce, byte[] in, int inOffset,
int inLength, byte[] ad)
throws ShortBufferException, BadPaddingException;
+ // android-add: @FastNative
static native int EVP_AEAD_CTX_open_buf(long evpAead, byte[] key, int tagLengthInBytes,
ByteBuffer out, byte[] nonce, ByteBuffer input,
byte[] ad)
@@ -418,48 +527,66 @@ static native int EVP_AEAD_CTX_open_buf(long evpAead, byte[] key, int tagLengthI
// --- CMAC functions ------------------------------------------------------
+ // android-add: @FastNative
static native long CMAC_CTX_new();
+ // android-add: @FastNative
static native void CMAC_CTX_free(long ctx);
+ // android-add: @FastNative
static native void CMAC_Init(NativeRef.CMAC_CTX ctx, byte[] key);
+ // android-add: @FastNative
static native void CMAC_Update(NativeRef.CMAC_CTX ctx, byte[] in, int inOffset, int inLength);
+ // android-add: @FastNative
static native void CMAC_UpdateDirect(NativeRef.CMAC_CTX ctx, long inPtr, int inLength);
+ // android-add: @FastNative
static native byte[] CMAC_Final(NativeRef.CMAC_CTX ctx);
+ // android-add: @FastNative
static native void CMAC_Reset(NativeRef.CMAC_CTX ctx);
// --- HMAC functions ------------------------------------------------------
+ // android-add: @FastNative
static native long HMAC_CTX_new();
+ // android-add: @FastNative
static native void HMAC_CTX_free(long ctx);
+ // android-add: @FastNative
static native void HMAC_Init_ex(NativeRef.HMAC_CTX ctx, byte[] key, long evp_md);
+ // android-add: @FastNative
static native void HMAC_Update(NativeRef.HMAC_CTX ctx, byte[] in, int inOffset, int inLength);
+ // android-add: @FastNative
static native void HMAC_UpdateDirect(NativeRef.HMAC_CTX ctx, long inPtr, int inLength);
+ // android-add: @FastNative
static native byte[] HMAC_Final(NativeRef.HMAC_CTX ctx);
+ // android-add: @FastNative
static native void HMAC_Reset(NativeRef.HMAC_CTX ctx);
// --- HPKE functions ------------------------------------------------------
+ // android-add: @FastNative
static native byte[] EVP_HPKE_CTX_export(NativeRef.EVP_HPKE_CTX ctx, byte[] exporterCtx,
int length);
static native void EVP_HPKE_CTX_free(long ctx);
+ // android-add: @FastNative
static native byte[] EVP_HPKE_CTX_open(NativeRef.EVP_HPKE_CTX ctx, byte[] ciphertext,
byte[] aad) throws BadPaddingException;
+ // android-add: @FastNative
static native byte[] EVP_HPKE_CTX_seal(NativeRef.EVP_HPKE_CTX ctx, byte[] plaintext,
byte[] aad);
+ // android-add: @FastNative
static native Object EVP_HPKE_CTX_setup_base_mode_recipient(int kem, int kdf, int aead,
byte[] privateKey, byte[] enc,
byte[] info);
@@ -471,6 +598,7 @@ static Object EVP_HPKE_CTX_setup_base_mode_recipient(HpkeSuite suite, byte[] pri
enc, info);
}
+ // android-add: @FastNative
static native Object[] EVP_HPKE_CTX_setup_base_mode_sender(int kem, int kdf, int aead,
byte[] publicKey, byte[] info);
@@ -479,6 +607,8 @@ static Object[] EVP_HPKE_CTX_setup_base_mode_sender(HpkeSuite suite, byte[] publ
return EVP_HPKE_CTX_setup_base_mode_sender(suite.getKem().getId(), suite.getKdf().getId(),
suite.getAead().getId(), publicKey, info);
}
+
+ // android-add: @FastNative
static native Object[] EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing(
int kem, int kdf, int aead, byte[] publicKey, byte[] info, byte[] seed);
@@ -493,6 +623,7 @@ static Object[] EVP_HPKE_CTX_setup_base_mode_sender_with_seed_for_testing(HpkeSu
// --- RAND ----------------------------------------------------------------
+ // android-add: @FastNative
static native void RAND_bytes(byte[] output);
// --- X509_NAME -----------------------------------------------------------
@@ -504,6 +635,7 @@ static int X509_NAME_hash(X500Principal principal) {
public static int X509_NAME_hash_old(X500Principal principal) {
return X509_NAME_hash(principal, "MD5");
}
+
private static int X509_NAME_hash(X500Principal principal, String algorithm) {
try {
byte[] digest = MessageDigest.getInstance(algorithm).digest(principal.getEncoded());
@@ -520,102 +652,128 @@ private static int X509_NAME_hash(X500Principal principal, String algorithm) {
/** Used to request get_X509_GENERAL_NAME_stack get the "altname" field. */
static final int GN_STACK_SUBJECT_ALT_NAME = 1;
- /**
- * Used to request get_X509_GENERAL_NAME_stack get the issuerAlternativeName
- * extension.
- */
+ /** Used to request get_X509_GENERAL_NAME_stack get the issuerAlternativeName extension. */
static final int GN_STACK_ISSUER_ALT_NAME = 2;
- /**
- * Used to request only non-critical types in get_X509*_ext_oids.
- */
+ /** Used to request only non-critical types in get_X509*_ext_oids. */
static final int EXTENSION_TYPE_NON_CRITICAL = 0;
- /**
- * Used to request only critical types in get_X509*_ext_oids.
- */
+ /** Used to request only critical types in get_X509*_ext_oids. */
static final int EXTENSION_TYPE_CRITICAL = 1;
+ // android-add: @FastNative
static native long d2i_X509_bio(long bioCtx);
+ // android-add: @FastNative
static native long d2i_X509(byte[] encoded) throws ParsingException;
+ // android-add: @FastNative
static native long PEM_read_bio_X509(long bioCtx);
+ // android-add: @FastNative
static native byte[] i2d_X509(long x509ctx, OpenSSLX509Certificate holder);
/** Takes an X509 context not an X509_PUBKEY context. */
+ // android-add: @FastNative
static native byte[] i2d_X509_PUBKEY(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native byte[] ASN1_seq_pack_X509(long[] x509CertRefs);
+ // android-add: @FastNative
static native long[] ASN1_seq_unpack_X509_bio(long bioRef) throws ParsingException;
static native void X509_free(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native int X509_cmp(long x509ctx1, OpenSSLX509Certificate holder, long x509ctx2,
OpenSSLX509Certificate holder2);
+ // android-add: @FastNative
static native void X509_print_ex(long bioCtx, long x509ctx, OpenSSLX509Certificate holder,
long nmflag, long certflag);
+ // android-add: @FastNative
static native byte[] X509_get_issuer_name(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native byte[] X509_get_subject_name(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native String get_X509_sig_alg_oid(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native byte[] get_X509_sig_alg_parameter(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native boolean[] get_X509_issuerUID(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native boolean[] get_X509_subjectUID(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native long X509_get_pubkey(long x509ctx, OpenSSLX509Certificate holder)
throws NoSuchAlgorithmException, InvalidKeyException;
+ // android-add: @FastNative
static native String get_X509_pubkey_oid(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native byte[] X509_get_ext_oid(long x509ctx, OpenSSLX509Certificate holder, String oid);
+ // android-add: @FastNative
static native String[] get_X509_ext_oids(long x509ctx, OpenSSLX509Certificate holder,
int critical);
+ // android-add: @FastNative
static native Object[][] get_X509_GENERAL_NAME_stack(long x509ctx,
OpenSSLX509Certificate holder, int type)
throws CertificateParsingException;
+ // android-add: @FastNative
static native boolean[] get_X509_ex_kusage(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native String[] get_X509_ex_xkusage(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native int get_X509_ex_pathlen(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native long X509_get_notBefore(long x509ctx, OpenSSLX509Certificate holder)
throws ParsingException;
+ // android-add: @FastNative
static native long X509_get_notAfter(long x509ctx, OpenSSLX509Certificate holder)
throws ParsingException;
+ // android-add: @FastNative
static native long X509_get_version(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native byte[] X509_get_serialNumber(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native void X509_verify(long x509ctx, OpenSSLX509Certificate holder,
NativeRef.EVP_PKEY pkeyCtx)
throws BadPaddingException, IllegalBlockSizeException;
+ // android-add: @FastNative
static native byte[] get_X509_tbs_cert(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native byte[] get_X509_tbs_cert_without_ext(long x509ctx, OpenSSLX509Certificate holder,
String oid);
+ // android-add: @FastNative
static native byte[] get_X509_signature(long x509ctx, OpenSSLX509Certificate holder);
+ // android-add: @FastNative
static native int get_X509_ex_flags(long x509ctx, OpenSSLX509Certificate holder);
// Used by Android platform TrustedCertificateStore.
@SuppressWarnings("unused")
+ // android-add: @FastNative
static native int X509_check_issued(long ctx, OpenSSLX509Certificate holder, long ctx2,
OpenSSLX509Certificate holder2);
@@ -628,104 +786,138 @@ static native int X509_check_issued(long ctx, OpenSSLX509Certificate holder, lon
static final int PKCS7_CRLS = 2;
/** Returns an array of X509 or X509_CRL pointers. */
+ // android-add: @FastNative
static native long[] d2i_PKCS7_bio(long bioCtx, int which) throws ParsingException;
/** Returns an array of X509 or X509_CRL pointers. */
+ // android-add: @FastNative
static native byte[] i2d_PKCS7(long[] certs);
/** Returns an array of X509 or X509_CRL pointers. */
+ // android-add: @FastNative
static native long[] PEM_read_bio_PKCS7(long bioCtx, int which);
// --- X509_CRL ------------------------------------------------------------
+ // android-add: @FastNative
static native long d2i_X509_CRL_bio(long bioCtx);
+ // android-add: @FastNative
static native long PEM_read_bio_X509_CRL(long bioCtx);
+ // android-add: @FastNative
static native byte[] i2d_X509_CRL(long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native void X509_CRL_free(long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native void X509_CRL_print(long bioCtx, long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native String get_X509_CRL_sig_alg_oid(long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native byte[] get_X509_CRL_sig_alg_parameter(long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native byte[] X509_CRL_get_issuer_name(long x509CrlCtx, OpenSSLX509CRL holder);
/** Returns X509_REVOKED reference that is not duplicated! */
+ // android-add: @FastNative
static native long X509_CRL_get0_by_cert(long x509CrlCtx, OpenSSLX509CRL holder, long x509Ctx,
OpenSSLX509Certificate holder2);
/** Returns X509_REVOKED reference that is not duplicated! */
+ // android-add: @FastNative
static native long X509_CRL_get0_by_serial(long x509CrlCtx, OpenSSLX509CRL holder,
byte[] serial);
/** Returns an array of X509_REVOKED that are owned by the caller. */
+ // android-add: @FastNative
static native long[] X509_CRL_get_REVOKED(long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native String[] get_X509_CRL_ext_oids(long x509Crlctx, OpenSSLX509CRL holder,
int critical);
+ // android-add: @FastNative
static native byte[] X509_CRL_get_ext_oid(long x509CrlCtx, OpenSSLX509CRL holder, String oid);
+ // android-add: @FastNative
static native long X509_CRL_get_version(long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native long X509_CRL_get_ext(long x509CrlCtx, OpenSSLX509CRL holder, String oid);
+ // android-add: @FastNative
static native byte[] get_X509_CRL_signature(long x509ctx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native void X509_CRL_verify(long x509CrlCtx, OpenSSLX509CRL holder,
NativeRef.EVP_PKEY pkeyCtx)
throws BadPaddingException, SignatureException, NoSuchAlgorithmException,
InvalidKeyException, IllegalBlockSizeException;
+ // android-add: @FastNative
static native byte[] get_X509_CRL_crl_enc(long x509CrlCtx, OpenSSLX509CRL holder);
+ // android-add: @FastNative
static native long X509_CRL_get_lastUpdate(long x509CrlCtx, OpenSSLX509CRL holder)
throws ParsingException;
+ // android-add: @FastNative
static native long X509_CRL_get_nextUpdate(long x509CrlCtx, OpenSSLX509CRL holder)
throws ParsingException;
// --- X509_REVOKED --------------------------------------------------------
+ // android-add: @FastNative
static native long X509_REVOKED_dup(long x509RevokedCtx);
+ // android-add: @FastNative
static native byte[] i2d_X509_REVOKED(long x509RevokedCtx, OpenSSLX509CRLEntry holder);
+ // android-add: @FastNative
static native String[] get_X509_REVOKED_ext_oids(long x509ctx, int critical,
OpenSSLX509CRLEntry holder);
+ // android-add: @FastNative
static native byte[] X509_REVOKED_get_ext_oid(long x509RevokedCtx, String oid,
OpenSSLX509CRLEntry holder);
+ // android-add: @FastNative
static native byte[] X509_REVOKED_get_serialNumber(long x509RevokedCtx,
OpenSSLX509CRLEntry holder);
+ // android-add: @FastNative
static native long X509_REVOKED_get_ext(long x509RevokedCtx, String oid,
OpenSSLX509CRLEntry holder);
/** Returns ASN1_TIME reference. */
+ // android-add: @FastNative
static native long get_X509_REVOKED_revocationDate(long x509RevokedCtx,
OpenSSLX509CRLEntry holder);
+ // android-add: @FastNative
static native void X509_REVOKED_print(long bioRef, long x509RevokedCtx,
OpenSSLX509CRLEntry holder);
+ // android-add: @FastNative
static native void X509_REVOKED_free(long x509RevokedCtx, OpenSSLX509CRLEntry holder);
// --- X509_EXTENSION ------------------------------------------------------
+ // android-add: @FastNative
static native int X509_supported_extension(long x509ExtensionRef);
// --- SPAKE ---------------------------------------------------------------
/**
- * Sets the SPAKE credential for the given SSL context using a password.
- * Used for both client and server.
+ * Sets the SPAKE credential for the given SSL context using a password. Used for both client
+ * and server.
*/
+ // android-add: @FastNative
static native void SSL_CTX_set_spake_credential(byte[] context, byte[] pw_array,
byte[] id_prover_array,
byte[] id_verifier_array, boolean is_client,
@@ -735,6 +927,7 @@ static native void SSL_CTX_set_spake_credential(byte[] context, byte[] pw_array,
// --- ASN1_TIME -----------------------------------------------------------
+ // android-add: @FastNative
static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal)
throws ParsingException;
@@ -742,144 +935,151 @@ static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal)
/**
* Allocates and returns an opaque reference to an object that can be used with other
- * asn1_read_* functions to read the ASN.1-encoded data in val. The returned object must
- * be freed after use by calling asn1_read_free.
+ * asn1_read_* functions to read the ASN.1-encoded data in val. The returned object must be
+ * freed after use by calling asn1_read_free.
*/
+ // android-add: @FastNative
static native long asn1_read_init(byte[] val) throws IOException;
/**
* Allocates and returns an opaque reference to an object that can be used with other
- * asn1_read_* functions to read the ASN.1 sequence pointed to by cbsRef. The returned
- * object must be freed after use by calling asn1_read_free.
+ * asn1_read_* functions to read the ASN.1 sequence pointed to by cbsRef. The returned object
+ * must be freed after use by calling asn1_read_free.
*/
+ // android-add: @FastNative
static native long asn1_read_sequence(long cbsRef) throws IOException;
/**
- * Returns whether the next object in the given reference is explicitly tagged with the
- * given tag number.
+ * Returns whether the next object in the given reference is explicitly tagged with the given
+ * tag number.
*/
+ // android-add: @FastNative
static native boolean asn1_read_next_tag_is(long cbsRef, int tag) throws IOException;
/**
- * Allocates and returns an opaque reference to an object that can be used with
- * other asn1_read_* functions to read the ASN.1 data pointed to by cbsRef. The returned
- * object must be freed after use by calling asn1_read_free.
+ * Allocates and returns an opaque reference to an object that can be used with other
+ * asn1_read_* functions to read the ASN.1 data pointed to by cbsRef. The returned object must
+ * be freed after use by calling asn1_read_free.
*/
+ // android-add: @FastNative
static native long asn1_read_tagged(long cbsRef) throws IOException;
- /**
- * Returns the contents of an ASN.1 octet string from the given reference.
- */
+ /** Returns the contents of an ASN.1 octet string from the given reference. */
+ // android-add: @FastNative
static native byte[] asn1_read_octetstring(long cbsRef) throws IOException;
/**
- * Returns an ASN.1 integer from the given reference. If the integer doesn't fit
- * in a uint64, this method will throw an IOException.
+ * Returns an ASN.1 integer from the given reference. If the integer doesn't fit in a uint64,
+ * this method will throw an IOException.
*/
+ // android-add: @FastNative
static native long asn1_read_uint64(long cbsRef) throws IOException;
- /**
- * Consumes an ASN.1 NULL from the given reference.
- */
+ /** Consumes an ASN.1 NULL from the given reference. */
+ // android-add: @FastNative
static native void asn1_read_null(long cbsRef) throws IOException;
/**
* Returns an ASN.1 OID in dotted-decimal notation (eg, "1.3.14.3.2.26" for SHA-1) from the
* given reference.
*/
+ // android-add: @FastNative
static native String asn1_read_oid(long cbsRef) throws IOException;
- /**
- * Returns whether or not the given reference has been read completely.
- */
+ /** Returns whether or not the given reference has been read completely. */
+ // android-add: @FastNative
static native boolean asn1_read_is_empty(long cbsRef);
/**
- * Frees any resources associated with the given reference. After calling, the reference
- * must not be used again. This may be called with a zero reference, in which case nothing
- * will be done.
+ * Frees any resources associated with the given reference. After calling, the reference must
+ * not be used again. This may be called with a zero reference, in which case nothing will be
+ * done.
*/
+ // android-add: @FastNative
static native void asn1_read_free(long cbsRef);
/**
* Allocates and returns an opaque reference to an object that can be used with other
- * asn1_write_* functions to write ASN.1-encoded data. The returned object must be finalized
- * after use by calling either asn1_write_finish or asn1_write_cleanup, and its resources
- * must be freed by calling asn1_write_free.
+ * asn1_write_* functions to write ASN.1-encoded data. The returned object must be finalized
+ * after use by calling either asn1_write_finish or asn1_write_cleanup, and its resources must
+ * be freed by calling asn1_write_free.
*/
+ // android-add: @FastNative
static native long asn1_write_init() throws IOException;
/**
* Allocates and returns an opaque reference to an object that can be used with other
- * asn1_write_* functions to write an ASN.1 sequence into the given reference. The returned
- * reference may only be used until the next call on the parent reference. The returned
- * object must be freed after use by calling asn1_write_free.
+ * asn1_write_* functions to write an ASN.1 sequence into the given reference. The returned
+ * reference may only be used until the next call on the parent reference. The returned object
+ * must be freed after use by calling asn1_write_free.
*/
+ // android-add: @FastNative
static native long asn1_write_sequence(long cbbRef) throws IOException;
/**
* Allocates and returns an opaque reference to an object that can be used with other
- * asn1_write_* functions to write a explicitly-tagged ASN.1 object with the given tag
- * into the given reference. The returned reference may only be used until the next
- * call on the parent reference. The returned object must be freed after use by
- * calling asn1_write_free.
+ * asn1_write_* functions to write a explicitly-tagged ASN.1 object with the given tag into the
+ * given reference. The returned reference may only be used until the next call on the parent
+ * reference. The returned object must be freed after use by calling asn1_write_free.
*/
+ // android-add: @FastNative
static native long asn1_write_tag(long cbbRef, int tag) throws IOException;
- /**
- * Writes the given data into the given reference as an ASN.1-encoded octet string.
- */
+ /** Writes the given data into the given reference as an ASN.1-encoded octet string. */
+ // android-add: @FastNative
static native void asn1_write_octetstring(long cbbRef, byte[] data) throws IOException;
- /**
- * Writes the given value into the given reference as an ASN.1-encoded integer.
- */
+ /** Writes the given value into the given reference as an ASN.1-encoded integer. */
+ // android-add: @FastNative
static native void asn1_write_uint64(long cbbRef, long value) throws IOException;
- /**
- * Writes a NULL value into the given reference.
- */
+ /** Writes a NULL value into the given reference. */
+ // android-add: @FastNative
static native void asn1_write_null(long cbbRef) throws IOException;
- /**
- * Writes the given OID (which must be in dotted-decimal notation) into the given reference.
- */
+ /** Writes the given OID (which must be in dotted-decimal notation) into the given reference. */
+ // android-add: @FastNative
static native void asn1_write_oid(long cbbRef, String oid) throws IOException;
/**
* Flushes the given reference, invalidating any child references and completing their
- * operations. This must be called if the child references are to be freed before
- * asn1_write_finish is called on the ultimate parent. The child references must still
- * be freed.
+ * operations. This must be called if the child references are to be freed before
+ * asn1_write_finish is called on the ultimate parent. The child references must still be freed.
*/
+ // android-add: @FastNative
static native void asn1_write_flush(long cbbRef) throws IOException;
/**
- * Completes any in-progress operations and returns the ASN.1-encoded data. Either this
- * or asn1_write_cleanup must be called on any reference returned from asn1_write_init
- * before it is freed.
+ * Completes any in-progress operations and returns the ASN.1-encoded data. Either this or
+ * asn1_write_cleanup must be called on any reference returned from asn1_write_init before it is
+ * freed.
*/
+ // android-add: @FastNative
static native byte[] asn1_write_finish(long cbbRef) throws IOException;
/**
- * Cleans up intermediate state in the given reference. Either this or asn1_write_finish
- * must be called on any reference returned from asn1_write_init before it is freed.
+ * Cleans up intermediate state in the given reference. Either this or asn1_write_finish must be
+ * called on any reference returned from asn1_write_init before it is freed.
*/
+ // android-add: @FastNative
static native void asn1_write_cleanup(long cbbRef);
/**
- * Frees resources associated with the given reference. After calling, the reference
- * must not be used again. This may be called with a zero reference, in which case nothing
- * will be done.
+ * Frees resources associated with the given reference. After calling, the reference must not be
+ * used again. This may be called with a zero reference, in which case nothing will be done.
*/
+ // android-add: @FastNative
static native void asn1_write_free(long cbbRef);
// --- BIO stream creation -------------------------------------------------
+ // android-add: @FastNative
static native long create_BIO_InputStream(OpenSSLBIOInputStream is, boolean isFinite);
+ // android-add: @FastNative
static native long create_BIO_OutputStream(OutputStream os);
+ // android-add: @FastNative
static native void BIO_free_all(long bioRef);
// --- SSL handling --------------------------------------------------------
@@ -909,23 +1109,18 @@ static native void ASN1_TIME_to_Calendar(long asn1TimeCtx, Calendar cal)
new HashSet(Arrays.asList(SUPPORTED_TLS_1_3_CIPHER_SUITES));
/**
- * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is RFC 5746's renegotiation
- * indication signaling cipher suite value. It is not a real
- * cipher suite. It is just an indication in the default and
- * supported cipher suite lists indicates that the implementation
- * supports secure renegotiation.
- *
- * In the RI, its presence means that the SCSV is sent in the
- * cipher suite list to indicate secure renegotiation support and
- * its absense means to send an empty TLS renegotiation info
+ * TLS_EMPTY_RENEGOTIATION_INFO_SCSV is RFC 5746's renegotiation indication signaling cipher
+ * suite value. It is not a real cipher suite. It is just an indication in the default and
+ * supported cipher suite lists indicates that the implementation supports secure renegotiation.
+ *
+ *
In the RI, its presence means that the SCSV is sent in the cipher suite list to indicate
+ * secure renegotiation support and its absense means to send an empty TLS renegotiation info
* extension instead.
- *
- * However, OpenSSL doesn't provide an API to give this level of
- * control, instead always sending the SCSV and always including
- * the empty renegotiation info if TLS is used (as opposed to
- * SSL). So we simply allow TLS_EMPTY_RENEGOTIATION_INFO_SCSV to
- * be passed for compatibility as to provide the hint that we
- * support secure renegotiation.
+ *
+ *
However, OpenSSL doesn't provide an API to give this level of control, instead always
+ * sending the SCSV and always including the empty renegotiation info if TLS is used (as opposed
+ * to SSL). So we simply allow TLS_EMPTY_RENEGOTIATION_INFO_SCSV to be passed for compatibility
+ * as to provide the hint that we support secure renegotiation.
*/
static final String TLS_EMPTY_RENEGOTIATION_INFO_SCSV = "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
@@ -945,15 +1140,14 @@ static String cipherSuiteFromJava(String javaCipherSuite) {
}
/**
- * TLS_FALLBACK_SCSV is from
- * https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00
- * to indicate to the server that this is a fallback protocol
- * request.
+ * TLS_FALLBACK_SCSV is from https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00 to
+ * indicate to the server that this is a fallback protocol request.
*/
private static final String TLS_FALLBACK_SCSV = "TLS_FALLBACK_SCSV";
private static final boolean HAS_AES_HARDWARE;
private static final String[] SUPPORTED_TLS_1_2_CIPHER_SUITES;
+
static {
if (loadError == null) {
// If loadError is not null, it means the native code was not loaded, so
@@ -987,11 +1181,13 @@ static String cipherSuiteFromJava(String javaCipherSuite) {
}
/**
- * Returns 1 if the BoringSSL believes the CPU has AES accelerated hardware
- * instructions. Used to determine cipher suite ordering.
+ * Returns 1 if the BoringSSL believes the CPU has AES accelerated hardware instructions. Used
+ * to determine cipher suite ordering.
*/
+ // android-add: @FastNative
static native int EVP_has_aes_hardware();
+ // android-add: @FastNative
static native long SSL_CTX_new();
// IMPLEMENTATION NOTE: The default list of cipher suites is a trade-off between what we'd like
@@ -1013,39 +1209,40 @@ static String cipherSuiteFromJava(String javaCipherSuite) {
// prevent apps from connecting to servers they were previously able to connect to.
/** X.509 based cipher suites enabled by default (if requested), in preference order. */
- static final String[] DEFAULT_X509_CIPHER_SUITES = HAS_AES_HARDWARE ?
- new String[] {
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
- "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- "TLS_RSA_WITH_AES_128_GCM_SHA256",
- "TLS_RSA_WITH_AES_256_GCM_SHA384",
- "TLS_RSA_WITH_AES_128_CBC_SHA",
- "TLS_RSA_WITH_AES_256_CBC_SHA",
- } :
- new String[] {
- "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
- "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
- "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
- "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
- "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
- "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
- "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
- "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
- "TLS_RSA_WITH_AES_128_GCM_SHA256",
- "TLS_RSA_WITH_AES_256_GCM_SHA384",
- "TLS_RSA_WITH_AES_128_CBC_SHA",
- "TLS_RSA_WITH_AES_256_CBC_SHA",
- };
+ static final String[] DEFAULT_X509_CIPHER_SUITES =
+ HAS_AES_HARDWARE
+ ? new String[] {
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+ "TLS_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_RSA_WITH_AES_256_CBC_SHA",
+ }
+ : new String[] {
+ "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA",
+ "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA",
+ "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
+ "TLS_RSA_WITH_AES_128_GCM_SHA256",
+ "TLS_RSA_WITH_AES_256_GCM_SHA384",
+ "TLS_RSA_WITH_AES_128_CBC_SHA",
+ "TLS_RSA_WITH_AES_256_CBC_SHA",
+ };
/** TLS-PSK cipher suites enabled by default (if requested), in preference order. */
static final String[] DEFAULT_PSK_CIPHER_SUITES = new String[] {
@@ -1066,21 +1263,28 @@ static String[] getSupportedCipherSuites() {
SUPPORTED_TLS_1_2_CIPHER_SUITES.clone());
}
+ // android-add: @FastNative
static native void SSL_CTX_free(long ssl_ctx, AbstractSessionContext holder);
+ // android-add: @FastNative
static native void SSL_CTX_set_session_id_context(long ssl_ctx, AbstractSessionContext holder,
byte[] sid_ctx);
+ // android-add: @FastNative
static native long SSL_CTX_set_timeout(long ssl_ctx, AbstractSessionContext holder,
long seconds);
+ // android-add: @FastNative
static native long SSL_new(long ssl_ctx, AbstractSessionContext holder) throws SSLException;
+ // android-add: @FastNative
static native void SSL_enable_tls_channel_id(long ssl, NativeSsl ssl_holder)
throws SSLException;
+ // android-add: @FastNative
static native byte[] SSL_get_tls_channel_id(long ssl, NativeSsl ssl_holder) throws SSLException;
+ // android-add: @FastNative
static native void SSL_set1_tls_channel_id(long ssl, NativeSsl ssl_holder,
NativeRef.EVP_PKEY pkey);
@@ -1092,48 +1296,65 @@ static native void SSL_set1_tls_channel_id(long ssl, NativeSsl ssl_holder,
* @param pkey a reference to the private key.
* @throws SSLException if a problem occurs setting the cert/key.
*/
+ // android-add: @FastNative
static native void setLocalCertsAndPrivateKey(long ssl, NativeSsl ssl_holder,
byte[][] encodedCertificates,
NativeRef.EVP_PKEY pkey) throws SSLException;
+ // android-add: @FastNative
static native void SSL_set_client_CA_list(long ssl, NativeSsl ssl_holder,
byte[][] asn1DerEncodedX500Principals)
throws SSLException;
+ // android-add: @FastNative
static native long SSL_set_mode(long ssl, NativeSsl ssl_holder, long mode);
+ // android-add: @FastNative
static native long SSL_set_options(long ssl, NativeSsl ssl_holder, long options);
+ // android-add: @FastNative
static native long SSL_clear_options(long ssl, NativeSsl ssl_holder, long options);
+ // android-add: @FastNative
static native int SSL_set_protocol_versions(long ssl, NativeSsl ssl_holder, int min_version,
int max_version);
+ // android-add: @FastNative
static native void SSL_enable_signed_cert_timestamps(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native byte[] SSL_get_signed_cert_timestamp_list(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native void SSL_set_signed_cert_timestamp_list(long ssl, NativeSsl ssl_holder,
byte[] list);
+ // android-add: @FastNative
static native void SSL_enable_ocsp_stapling(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native byte[] SSL_get_ocsp_response(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native void SSL_set_ocsp_response(long ssl, NativeSsl ssl_holder, byte[] response);
+ // android-add: @FastNative
static native byte[] SSL_get_tls_unique(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native byte[] SSL_export_keying_material(long ssl, NativeSsl ssl_holder, byte[] label,
byte[] context, int num_bytes)
throws SSLException;
+ // android-add: @FastNative
static native void SSL_use_psk_identity_hint(long ssl, NativeSsl ssl_holder,
String identityHint) throws SSLException;
+ // android-add: @FastNative
static native void set_SSL_psk_client_callback_enabled(long ssl, NativeSsl ssl_holder,
boolean enabled);
+ // android-add: @FastNative
static native void set_SSL_psk_server_callback_enabled(long ssl, NativeSsl ssl_holder,
boolean enabled);
@@ -1205,6 +1426,7 @@ static String[] getSupportedProtocols() {
private static class Range {
public final String min;
public final String max;
+
public Range(String min, String max) {
this.min = min;
this.max = max;
@@ -1273,6 +1495,7 @@ static String[] checkEnabledProtocols(String[] protocols) {
return protocols;
}
+ // android-add: @FastNative
static native void SSL_set_cipher_lists(long ssl, NativeSsl ssl_holder, String[] ciphers);
/**
@@ -1280,6 +1503,7 @@ static String[] checkEnabledProtocols(String[] protocols) {
*
* @return array of {@code SSL_CIPHER} references.
*/
+ // android-add: @FastNative
static native long[] SSL_get_ciphers(long ssl, NativeSsl ssl_holder);
static void setEnabledCipherSuites(long ssl, NativeSsl ssl_holder, String[] cipherSuites,
@@ -1341,101 +1565,130 @@ static String[] checkEnabledCipherSuites(String[] cipherSuites) {
return cipherSuites;
}
+ // android-add: @FastNative
static native void SSL_set_accept_state(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native void SSL_set_connect_state(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native void SSL_set_verify(long ssl, NativeSsl ssl_holder, int mode);
+ // android-add: @FastNative
static native void SSL_set_session(long ssl, NativeSsl ssl_holder, long sslSessionNativePointer)
throws SSLException;
+ // android-add: @FastNative
static native void SSL_set_session_creation_enabled(long ssl, NativeSsl ssl_holder,
boolean creationEnabled)
throws SSLException;
+ // android-add: @FastNative
static native boolean SSL_session_reused(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native void SSL_accept_renegotiations(long ssl, NativeSsl ssl_holder)
throws SSLException;
+ // android-add: @FastNative
static native void SSL_set_tlsext_host_name(long ssl, NativeSsl ssl_holder, String hostname)
throws SSLException;
+
+ // android-add: @FastNative
static native String SSL_get_servername(long ssl, NativeSsl ssl_holder);
static native void SSL_do_handshake(long ssl, NativeSsl ssl_holder, FileDescriptor fd,
SSLHandshakeCallbacks shc, int timeoutMillis)
throws SSLException, SocketTimeoutException, CertificateException;
+ // android-add: @FastNative
public static native String SSL_get_current_cipher(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
+ public static native String SSL_get_version(long ssl, NativeSsl ssl_holder);
+
public static native void SSL_set1_groups(long ssl, NativeSsl sslHolder, int[] groups);
public static native String SSL_get_curve_name(long ssl, NativeSsl sslHolder);
- public static native String SSL_get_version(long ssl, NativeSsl ssl_holder);
-
- /**
- * Returns the peer certificate chain.
- */
+ /** Returns the peer certificate chain. */
+ // android-add: @FastNative
static native byte[][] SSL_get0_peer_certificates(long ssl, NativeSsl ssl_holder);
/**
* Reads with the native SSL_read function from the encrypted data stream
+ *
* @return -1 if error or the end of the stream is reached.
*/
static native int SSL_read(long ssl, NativeSsl ssl_holder, FileDescriptor fd,
SSLHandshakeCallbacks shc, byte[] b, int off, int len,
int readTimeoutMillis) throws IOException;
- /**
- * Writes with the native SSL_write function to the encrypted data stream.
- */
+ /** Writes with the native SSL_write function to the encrypted data stream. */
static native void SSL_write(long ssl, NativeSsl ssl_holder, FileDescriptor fd,
SSLHandshakeCallbacks shc, byte[] b, int off, int len,
int writeTimeoutMillis) throws IOException;
+ // android-add: @FastNative
static native void SSL_interrupt(long ssl, NativeSsl ssl_holder);
+
static native void SSL_shutdown(long ssl, NativeSsl ssl_holder, FileDescriptor fd,
SSLHandshakeCallbacks shc) throws IOException;
+ // android-add: @FastNative
static native int SSL_get_shutdown(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native void SSL_free(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native long SSL_get_time(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native long SSL_set_timeout(long ssl, NativeSsl ssl_holder, long millis);
+ // android-add: @FastNative
static native long SSL_get_timeout(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native int SSL_get_signature_algorithm_key_type(int signatureAlg);
+ // android-add: @FastNative
static native byte[] SSL_session_id(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native byte[] SSL_SESSION_session_id(long sslSessionNativePointer);
+ // android-add: @FastNative
static native long SSL_SESSION_get_time(long sslSessionNativePointer);
+ // android-add: @FastNative
static native long SSL_SESSION_get_timeout(long sslSessionNativePointer);
+ // android-add: @FastNative
static native String SSL_SESSION_get_version(long sslSessionNativePointer);
+ // android-add: @FastNative
static native String SSL_SESSION_cipher(long sslSessionNativePointer);
+ // android-add: @FastNative
static native boolean SSL_SESSION_should_be_single_use(long sslSessionNativePointer);
+ // android-add: @FastNative
static native void SSL_SESSION_up_ref(long sslSessionNativePointer);
+ // android-add: @FastNative
static native void SSL_SESSION_free(long sslSessionNativePointer);
+ // android-add: @FastNative
static native byte[] i2d_SSL_SESSION(long sslSessionNativePointer);
+ // android-add: @FastNative
static native long d2i_SSL_SESSION(byte[] data) throws IOException;
/**
- * A collection of callbacks from the native OpenSSL code that are
- * related to the SSL handshake initiated by SSL_do_handshake.
+ * A collection of callbacks from the native OpenSSL code that are related to the SSL handshake
+ * initiated by SSL_do_handshake.
*/
interface SSLHandshakeCallbacks {
/**
@@ -1443,7 +1696,6 @@ interface SSLHandshakeCallbacks {
*
* @param certificateChain chain of X.509 certificates in their encoded form
* @param authMethod auth algorithm name
- *
* @throws CertificateException if the certificate is untrusted
*/
@SuppressWarnings("unused")
@@ -1464,9 +1716,9 @@ void clientCertificateRequested(byte[] keyTypes, int[] signatureAlgs,
throws CertificateEncodingException, SSLException;
/**
- * Called when acting as a server during ClientHello processing before a decision
- * to resume a session is made. This allows the selection of the correct server
- * certificate based on things like Server Name Indication (SNI).
+ * Called when acting as a server during ClientHello processing before a decision to resume
+ * a session is made. This allows the selection of the correct server certificate based on
+ * things like Server Name Indication (SNI).
*
* @throws IOException if there was an error during certificate selection.
*/
@@ -1477,13 +1729,12 @@ void clientCertificateRequested(byte[] keyTypes, int[] signatureAlgs,
* exchange.
*
* @param identityHint PSK identity hint provided by the server or {@code null} if no hint
- * provided.
+ * provided.
* @param identity buffer to be populated with PSK identity (NULL-terminated modified UTF-8)
- * by this method. This identity will be provided to the server.
+ * by this method. This identity will be provided to the server.
* @param key buffer to be populated with key material by this method.
- *
* @return number of bytes this method stored in the {@code key} buffer or {@code 0} if an
- * error occurred in which case the handshake will be aborted.
+ * error occurred in which case the handshake will be aborted.
*/
int clientPSKKeyRequested(String identityHint, byte[] identity, byte[] key);
@@ -1491,33 +1742,30 @@ void clientCertificateRequested(byte[] keyTypes, int[] signatureAlgs,
* Gets the key to be used in server mode for this connection in Pre-Shared Key (PSK) key
* exchange.
*
- * @param identityHint PSK identity hint provided by this server to the client or
- * {@code null} if no hint was provided.
+ * @param identityHint PSK identity hint provided by this server to the client or {@code
+ * null} if no hint was provided.
* @param identity PSK identity provided by the client.
* @param key buffer to be populated with key material by this method.
- *
* @return number of bytes this method stored in the {@code key} buffer or {@code 0} if an
- * error occurred in which case the handshake will be aborted.
+ * error occurred in which case the handshake will be aborted.
*/
int serverPSKKeyRequested(String identityHint, String identity, byte[] key);
- /**
- * Called when SSL state changes. This could be handshake completion.
- */
+ /** Called when SSL state changes. This could be handshake completion. */
@SuppressWarnings("unused") void onSSLStateChange(int type, int val);
/**
- * Called when a new session has been established and may be added to the session cache.
- * The callee is responsible for incrementing the reference count on the returned session.
+ * Called when a new session has been established and may be added to the session cache. The
+ * callee is responsible for incrementing the reference count on the returned session.
*/
@SuppressWarnings("unused") void onNewSessionEstablished(long sslSessionNativePtr);
/**
- * Called for servers where TLS < 1.3 (TLS 1.3 uses session tickets rather than
- * application session caches).
+ * Called for servers where TLS < 1.3 (TLS 1.3 uses session tickets rather than application
+ * session caches).
*
- *
Looks up the session by ID in the application's session cache. If a valid session
- * is returned, this callback is responsible for incrementing the reference count (and any
+ *
Looks up the session by ID in the application's session cache. If a valid session is
+ * returned, this callback is responsible for incrementing the reference count (and any
* required synchronization).
*
* @param id the ID of the session to find.
@@ -1527,7 +1775,7 @@ void clientCertificateRequested(byte[] keyTypes, int[] signatureAlgs,
/**
* Called when acting as a server, the socket has an {@link
- * ApplicationProtocolSelectorAdapter} associated with it, and the application protocol
+ * ApplicationProtocolSelectorAdapter} associated with it, and the application protocol
* needs to be selected.
*
* @param applicationProtocols list of application protocols in length-prefix format
@@ -1536,10 +1784,13 @@ void clientCertificateRequested(byte[] keyTypes, int[] signatureAlgs,
@SuppressWarnings("unused") int selectApplicationProtocol(byte[] applicationProtocols);
}
+ // android-add: @FastNative
static native String SSL_CIPHER_get_kx_name(long cipherAddress);
+ // android-add: @FastNative
static native String[] get_cipher_names(String selection);
+ // android-add: @FastNative
public static native byte[] get_ocsp_single_extension(byte[] ocspResponse, String oid,
long x509Ref,
OpenSSLX509Certificate holder,
@@ -1547,59 +1798,67 @@ public static native byte[] get_ocsp_single_extension(byte[] ocspResponse, Strin
OpenSSLX509Certificate holder2);
/**
- * Returns the starting address of the memory region referenced by the provided direct
- * {@link Buffer} or {@code 0} if the provided buffer is not direct or if such access to direct
- * buffers is not supported by the platform.
+ * Returns the starting address of the memory region referenced by the provided direct {@link
+ * Buffer} or {@code 0} if the provided buffer is not direct or if such access to direct buffers
+ * is not supported by the platform.
*
*
NOTE: This method ignores the buffer's current {@code position}.
*/
+ // android-add: @FastNative
static native long getDirectBufferAddress(Buffer buf);
+ // android-add: @FastNative
static native long SSL_BIO_new(long ssl, NativeSsl ssl_holder) throws SSLException;
+ // android-add: @FastNative
static native int SSL_get_error(long ssl, NativeSsl ssl_holder, int ret);
+ // android-add: @FastNative
static native void SSL_clear_error();
+ // android-add: @FastNative
static native int SSL_pending_readable_bytes(long ssl, NativeSsl ssl_holder);
+ // android-add: @FastNative
static native int SSL_pending_written_bytes_in_BIO(long bio);
- /**
- * Returns the maximum overhead, in bytes, of sealing a record with SSL.
- */
+ /** Returns the maximum overhead, in bytes, of sealing a record with SSL. */
+ // android-add: @FastNative
static native int SSL_max_seal_overhead(long ssl, NativeSsl ssl_holder);
/**
* Enables ALPN for this TLS endpoint and sets the list of supported ALPN protocols in
* wire-format (length-prefixed 8-bit strings).
*/
+ // android-add: @FastNative
static native void setApplicationProtocols(long ssl, NativeSsl ssl_holder, boolean client,
byte[] protocols) throws IOException;
/**
* Called for a server endpoint only. Enables ALPN and indicates that the {@link
- * SSLHandshakeCallbacks#selectApplicationProtocol} will be called to select the
- * correct protocol during a handshake. Calling this method overrides
- * {@link #setApplicationProtocols(long, NativeSsl, boolean, byte[])}.
+ * SSLHandshakeCallbacks#selectApplicationProtocol} will be called to select the correct
+ * protocol during a handshake. Calling this method overrides {@link
+ * #setApplicationProtocols(long, NativeSsl, boolean, byte[])}.
*/
+ // android-add: @FastNative
static native void setHasApplicationProtocolSelector(long ssl, NativeSsl ssl_holder,
boolean hasSelector) throws IOException;
/**
- * Returns the selected ALPN protocol. If the server did not select a
- * protocol, {@code null} will be returned.
+ * Returns the selected ALPN protocol. If the server did not select a protocol, {@code null}
+ * will be returned.
*/
+ // android-add: @FastNative
static native byte[] getApplicationProtocol(long ssl, NativeSsl ssl_holder);
/**
* Variant of the {@link #SSL_do_handshake} used by {@link ConscryptEngine}. This differs
- * slightly from the raw BoringSSL API in that it returns the SSL error code from the
- * operation, rather than the return value from {@code SSL_do_handshake}. This is done in
- * order to allow to properly handle SSL errors and propagate useful exceptions.
+ * slightly from the raw BoringSSL API in that it returns the SSL error code from the operation,
+ * rather than the return value from {@code SSL_do_handshake}. This is done in order to allow to
+ * properly handle SSL errors and propagate useful exceptions.
*
* @return Returns the SSL error code for the operation when the error was {@code
- * SSL_ERROR_NONE}, {@code SSL_ERROR_WANT_READ}, or {@code SSL_ERROR_WANT_WRITE}.
+ * SSL_ERROR_NONE}, {@code SSL_ERROR_WANT_READ}, or {@code SSL_ERROR_WANT_WRITE}.
* @throws IOException when the error code is anything except those returned by this method.
*/
static native int ENGINE_SSL_do_handshake(long ssl, NativeSsl ssl_holder,
@@ -1609,14 +1868,13 @@ static native int ENGINE_SSL_do_handshake(long ssl, NativeSsl ssl_holder,
* Variant of the {@link #SSL_read} for a direct {@link java.nio.ByteBuffer} used by {@link
* ConscryptEngine}.
*
- * @return if positive, represents the number of bytes read into the given buffer.
- * Returns {@code -SSL_ERROR_WANT_READ} if more data is needed. Returns
- * {@code -SSL_ERROR_WANT_WRITE} if data needs to be written out to flush the BIO.
- *
+ * @return if positive, represents the number of bytes read into the given buffer. Returns
+ * {@code -SSL_ERROR_WANT_READ} if more data is needed. Returns {@code
+ * -SSL_ERROR_WANT_WRITE} if data needs to be written out to flush the BIO.
* @throws java.io.InterruptedIOException if the read was interrupted.
* @throws java.io.EOFException if the end of stream has been reached.
* @throws CertificateException if the application's certificate verification callback failed.
- * Only occurs during handshake processing.
+ * Only occurs during handshake processing.
* @throws SSLException if any other error occurs.
*/
static native int ENGINE_SSL_read_direct(long ssl, NativeSsl ssl_holder, long address,
@@ -1664,9 +1922,8 @@ static native void ENGINE_SSL_shutdown(long ssl, NativeSsl ssl_holder,
static native byte[] Scrypt_generate_key(byte[] password, byte[] salt, int n, int r, int p,
int key_len);
- /**
- * Return {@code true} if BoringSSL has been built in FIPS mode.
- */
+ /** Return {@code true} if BoringSSL has been built in FIPS mode. */
+ // android-add: @FastNative
static native boolean usesBoringSsl_FIPS_mode();
/* ECH */
@@ -1698,11 +1955,22 @@ static native boolean SSL_CTX_ech_enable_server(long sslCtx, AbstractSessionCont
/**
* Used for testing only.
*/
+ // android-add: @FastNative
static native int BIO_read(long bioRef, byte[] buffer) throws IOException;
+
+ // android-add: @FastNative
static native void BIO_write(long bioRef, byte[] buffer, int offset, int length)
throws IOException, IndexOutOfBoundsException;
+
+ // android-add: @FastNative
static native long SSL_clear_mode(long ssl, NativeSsl ssl_holder, long mode);
+
+ // android-add: @FastNative
static native long SSL_get_mode(long ssl, NativeSsl ssl_holder);
+
+ // android-add: @FastNative
static native long SSL_get_options(long ssl, NativeSsl ssl_holder);
+
+ // android-add: @FastNative
static native long SSL_get1_session(long ssl, NativeSsl ssl_holder);
}
diff --git a/common/src/main/java/org/conscrypt/NativeSsl.java b/common/src/main/java/org/conscrypt/NativeSsl.java
index 7fe7c49d7..02bc62496 100644
--- a/common/src/main/java/org/conscrypt/NativeSsl.java
+++ b/common/src/main/java/org/conscrypt/NativeSsl.java
@@ -363,6 +363,7 @@ void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOExcept
if (parameters.isCTVerificationEnabled(hostname)) {
NativeCrypto.SSL_enable_signed_cert_timestamps(ssl, this);
}
+ enableEchBasedOnPolicy(hostname);
} else {
NativeCrypto.SSL_set_accept_state(ssl, this);
@@ -584,6 +585,27 @@ private void setTlsChannelId(OpenSSLKey channelIdPrivateKey) throws SSLException
}
}
+ private void enableEchBasedOnPolicy(String hostname) throws SSLException {
+ EchOptions opts = parameters.getEchOptions(hostname);
+ if (opts == null) {
+ return;
+ }
+
+ byte[] configList = opts.getConfigList();
+ if (configList != null) {
+ try {
+ NativeCrypto.SSL_set1_ech_config_list(ssl, this, configList);
+ } catch (SSLException e) {
+ // The platform may provide a more specialized exception type for this error.
+ throw Platform.wrapInvalidEchDataException(e);
+ }
+ }
+
+ if (opts.isGreaseEnabled()) {
+ NativeCrypto.SSL_set_enable_ech_grease(ssl, this, /* enable= */ true);
+ }
+ }
+
private void setCertificateValidation() throws SSLException {
// setup peer certificate verification
if (!isClient()) {
diff --git a/common/src/main/java/org/conscrypt/NetworkSecurityPolicy.java b/common/src/main/java/org/conscrypt/NetworkSecurityPolicy.java
new file mode 100644
index 000000000..499c5eda0
--- /dev/null
+++ b/common/src/main/java/org/conscrypt/NetworkSecurityPolicy.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.conscrypt;
+
+import org.conscrypt.metrics.CertificateTransparencyVerificationReason;
+
+/**
+ * A policy provided by the platform to decide on the behaviour of TrustManagerImpl.
+ *
+ * See the platform-specific implementations in PlatformNetworkSecurityPolicy.
+ */
+@Internal
+public interface NetworkSecurityPolicy {
+ boolean isCertificateTransparencyVerificationRequired(String hostname);
+
+ CertificateTransparencyVerificationReason getCertificateTransparencyVerificationReason(
+ String hostname);
+
+ DomainEncryptionMode getDomainEncryptionMode(String hostname);
+}
diff --git a/common/src/main/java/org/conscrypt/OpenSSLAeadCipher.java b/common/src/main/java/org/conscrypt/OpenSSLAeadCipher.java
index a9368fd28..7ff4b3925 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLAeadCipher.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLAeadCipher.java
@@ -24,6 +24,7 @@
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Arrays;
+import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
@@ -33,6 +34,8 @@
@Internal
public abstract class OpenSSLAeadCipher extends OpenSSLCipher {
+ private static final Logger logger = Logger.getLogger(OpenSSLAeadCipher.class.getName());
+
/**
* Controls whether no-copy optimizations for direct ByteBuffers are enabled.
*/
diff --git a/common/src/main/java/org/conscrypt/OpenSSLContextImpl.java b/common/src/main/java/org/conscrypt/OpenSSLContextImpl.java
index 2b564e7ad..755d63cd8 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLContextImpl.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLContextImpl.java
@@ -67,6 +67,10 @@ public static OpenSSLContextImpl getPreferred() {
serverSessionContext = new ServerSessionContext();
}
+ private OpenSSLContextImpl() throws GeneralSecurityException, IOException {
+ this(NativeCrypto.TLSV13_PROTOCOLS, true);
+ }
+
/**
* Constructor for the DefaultSSLContextImpl. The unused boolean parameter is solely to
* indicate that this constructor is desired.
diff --git a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
index 3e28cec21..327f77e3c 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLSocketImpl.java
@@ -96,6 +96,8 @@ public void setHandshakeTimeout(int handshakeTimeoutMilliseconds) throws SocketE
@Override public abstract void setUseSessionTickets(boolean useSessionTickets);
+ @Override public abstract void setEchConfigList(byte[] echConfigList);
+
@Override public abstract void setChannelIdEnabled(boolean enabled);
@Override public abstract byte[] getChannelId() throws SSLException;
diff --git a/common/src/main/java/org/conscrypt/OpenSSLX25519PrivateKey.java b/common/src/main/java/org/conscrypt/OpenSSLX25519PrivateKey.java
index aa85e29bf..af7bb7767 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLX25519PrivateKey.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLX25519PrivateKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/common/src/main/java/org/conscrypt/OpenSSLX25519PublicKey.java b/common/src/main/java/org/conscrypt/OpenSSLX25519PublicKey.java
index 7ec4c87a6..ddeed1f51 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLX25519PublicKey.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLX25519PublicKey.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2022 The Android Open Source Project
+ * Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/common/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java b/common/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java
index 22b13f87d..b778e69a8 100644
--- a/common/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java
+++ b/common/src/main/java/org/conscrypt/OpenSSLX509CRLEntry.java
@@ -31,7 +31,7 @@
* An implementation of {@link X509CRLEntry} based on BoringSSL.
*/
final class OpenSSLX509CRLEntry extends X509CRLEntry {
- private final long mContext;
+ private long mContext;
private final Date revocationDate;
OpenSSLX509CRLEntry(long ctx) throws ParsingException {
diff --git a/common/src/main/java/org/conscrypt/SSLParametersImpl.java b/common/src/main/java/org/conscrypt/SSLParametersImpl.java
index e1bb9e4de..e85cf203e 100644
--- a/common/src/main/java/org/conscrypt/SSLParametersImpl.java
+++ b/common/src/main/java/org/conscrypt/SSLParametersImpl.java
@@ -17,6 +17,8 @@
package org.conscrypt;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.security.AlgorithmConstraints;
import java.security.KeyManagementException;
import java.security.KeyStore;
@@ -29,11 +31,13 @@
import java.util.Collection;
import java.util.List;
import java.util.Set;
+import java.util.logging.Logger;
import javax.crypto.SecretKey;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SNIMatcher;
+import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509KeyManager;
@@ -49,6 +53,8 @@
* socket or not.
*/
final class SSLParametersImpl implements Cloneable {
+ private static final Logger logger = Logger.getLogger(SSLParametersImpl.class.getName());
+
// default source of X.509 certificate based authentication keys
private static volatile X509KeyManager defaultX509KeyManager;
// default source of X.509 certificate based authentication trust decisions
@@ -73,6 +79,8 @@ final class SSLParametersImpl implements Cloneable {
private final Spake2PlusTrustManager spake2PlusTrustManager;
// source of Spake authentication or null if not provided
private final Spake2PlusKeyManager spake2PlusKeyManager;
+ // getNetworkSecurityPolicy reflected method for x509TrustManager
+ private final Method getNetworkSecurityPolicy;
// protocols enabled for SSL connection
String[] enabledProtocols;
@@ -109,6 +117,7 @@ final class SSLParametersImpl implements Cloneable {
byte[] applicationProtocols = EmptyArray.BYTE;
ApplicationProtocolSelectorAdapter applicationProtocolSelector;
boolean useSessionTickets;
+ byte[] echConfigList;
private Boolean useSni;
/**
@@ -168,6 +177,8 @@ final class SSLParametersImpl implements Cloneable {
"Spake2PlusTrustManager and Spake2PlusKeyManager should be set together");
}
+ getNetworkSecurityPolicy = getNetworkSecurityPolicyMethod(x509TrustManager);
+
// initialize the list of cipher suites and protocols enabled by default
if (isSpake()) {
enabledProtocols = new String[] {NativeCrypto.SUPPORTED_PROTOCOL_TLSV1_3};
@@ -213,6 +224,7 @@ private SSLParametersImpl(ClientSessionContext clientSessionContext,
this.x509KeyManager = x509KeyManager;
this.pskKeyManager = pskKeyManager;
this.x509TrustManager = x509TrustManager;
+ this.getNetworkSecurityPolicy = getNetworkSecurityPolicyMethod(x509TrustManager);
this.spake2PlusKeyManager = spake2PlusKeyManager;
this.spake2PlusTrustManager = spake2PlusTrustManager;
@@ -238,6 +250,8 @@ private SSLParametersImpl(ClientSessionContext clientSessionContext,
: sslParams.applicationProtocols.clone();
this.applicationProtocolSelector = sslParams.applicationProtocolSelector;
this.useSessionTickets = sslParams.useSessionTickets;
+ this.echConfigList =
+ (sslParams.echConfigList == null) ? null : sslParams.echConfigList.clone();
this.useSni = sslParams.useSni;
this.channelIdEnabled = sslParams.channelIdEnabled;
}
@@ -253,6 +267,17 @@ void initSpake() throws KeyManagementException {
}
}
+ private Method getNetworkSecurityPolicyMethod(X509TrustManager tm) {
+ if (tm == null) {
+ return null;
+ }
+ try {
+ return tm.getClass().getMethod("getNetworkSecurityPolicy");
+ } catch (NoSuchMethodException ignored) {
+ return null;
+ }
+ }
+
static SSLParametersImpl getDefault() throws KeyManagementException {
SSLParametersImpl result = defaultParameters;
if (result == null) {
@@ -475,6 +500,10 @@ void setUseSessionTickets(boolean useSessionTickets) {
this.useSessionTickets = useSessionTickets;
}
+ void setEchConfigList(byte[] echConfigList) {
+ this.echConfigList = echConfigList;
+ }
+
/*
* Whether connections using this SSL connection should use the TLS
* extension Server Name Indication (SNI).
@@ -813,6 +842,37 @@ private static String[] getDefaultCipherSuites(boolean x509CipherSuitesNeeded,
}
}
+ private NetworkSecurityPolicy getPolicy() {
+ // Google3-only: Skip getPolicy (b/477326565 b/450387911).
+ //
+ // If the TrustManager has a security policy attached, use it. We are using reflection here.
+ // The Android framework may provide a high-level TrustManager (e.g., RootTrustManager or
+ // NetworkSecurityTrustManager), which we need to query.
+ // if (getNetworkSecurityPolicy != null) {
+ // try {
+ // Object objPolicy = getNetworkSecurityPolicy.invoke(x509TrustManager);
+ // if (objPolicy instanceof NetworkSecurityPolicy) {
+ // return (NetworkSecurityPolicy) objPolicy;
+ // }
+ // } catch (IllegalAccessException | IllegalArgumentException e) {
+ // // This is the unlikely scenario where an external TrustManager is being used and
+ // it
+ // // defines a getNetworkSecurityPolicy method which does not match our
+ // expectations. logger.warning("Unable to call getNetworkSecurityPolicy on
+ // TrustManager: "
+ // + e.getMessage());
+ // } catch (InvocationTargetException e) {
+ // // getNetworkSecurityPolicy raised an exception. Unwrap it.
+ // throw new RuntimeException(
+ // "Unable to retrieve the NetworkSecurityPolicy associated "
+ // + "with the TrustManager",
+ // e.getCause());
+ // }
+ //}
+ // Otherwise, rely on the global platform policy.
+ return ConscryptNetworkSecurityPolicy.getDefault();
+ }
+
/*
* Checks whether SCT verification is enforced for a given hostname.
*/
@@ -825,7 +885,26 @@ boolean isCTVerificationEnabled(String hostname) {
if (ctVerificationEnabled) {
return true;
}
- return Platform.isCTVerificationRequired(hostname);
+
+ return getPolicy().isCertificateTransparencyVerificationRequired(hostname);
+ }
+
+ EchOptions getEchOptions(String hostname) throws SSLException {
+ switch (getPolicy().getDomainEncryptionMode(hostname)) {
+ case DISABLED:
+ return null;
+ case OPPORTUNISTIC:
+ return new EchOptions(echConfigList, /* enableGrease= */ false);
+ case ENABLED:
+ return new EchOptions(echConfigList, /* enableGrease= */ true);
+ case REQUIRED:
+ if (echConfigList == null) {
+ throw new SSLException("No ECH config provided when required");
+ }
+ return new EchOptions(echConfigList, /* enableGrease= */ false);
+ default:
+ return null;
+ }
}
boolean isSpake() {
diff --git a/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java b/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java
index bf44d5531..87c5f0bb0 100644
--- a/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java
+++ b/common/src/main/java/org/conscrypt/ScryptSecretKeyFactory.java
@@ -16,9 +16,9 @@
package org.conscrypt;
+import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
@@ -61,9 +61,13 @@ protected SecretKey engineGenerateSecret(KeySpec inKeySpec) throws InvalidKeySpe
throw new InvalidKeySpecException("Cannot produce fractional-byte outputs");
}
- return new ScryptKey(NativeCrypto.Scrypt_generate_key(
- new String(password).getBytes(StandardCharsets.UTF_8), salt, n, r, p,
- keyOutputBits / 8));
+ try {
+ return new ScryptKey(NativeCrypto.Scrypt_generate_key(
+ new String(password).getBytes("UTF-8"), salt, n, r, p, keyOutputBits / 8));
+ } catch (UnsupportedEncodingException e) {
+ // Impossible according to the Java docs: UTF-8 is always supported.
+ throw new IllegalStateException(e);
+ }
}
private Object getValue(KeySpec spec, String methodName)
@@ -116,8 +120,6 @@ public byte[] getEncoded() {
}
private static class NotImplementedException extends RuntimeException {
- private static final long serialVersionUID = -7755435858585859108L;
-
NotImplementedException() {
super("Not implemented");
}
diff --git a/common/src/main/java/org/conscrypt/TrustManagerImpl.java b/common/src/main/java/org/conscrypt/TrustManagerImpl.java
index adb206e5b..352e0a75a 100644
--- a/common/src/main/java/org/conscrypt/TrustManagerImpl.java
+++ b/common/src/main/java/org/conscrypt/TrustManagerImpl.java
@@ -61,6 +61,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+import java.util.function.Supplier;
import java.util.logging.Logger;
import javax.net.ssl.HttpsURLConnection;
@@ -72,14 +73,16 @@
/**
* TrustManager implementation. The implementation is based on CertPathValidator
- * PKIX and CertificateFactory X509 implementations. This implementations should
+ * PKIX and CertificateFactory X509 implementations. These implementations should
* be provided by some certification provider.
*
* @see javax.net.ssl.X509ExtendedTrustManager
+ * @see org.conscrypt.ConscryptX509TrustManager
*/
@Internal
@SuppressWarnings("CustomX509TrustManager")
-public final class TrustManagerImpl extends X509ExtendedTrustManager {
+public final class TrustManagerImpl
+ extends X509ExtendedTrustManager implements ConscryptX509TrustManager {
private static final Logger logger = Logger.getLogger(TrustManagerImpl.class.getName());
/**
@@ -102,6 +105,15 @@ public final class TrustManagerImpl extends X509ExtendedTrustManager {
*/
private final CertPinManager pinManager;
+ /**
+ * The ConscryptNetworkSecurityPolicy associated with this TrustManager.
+ *
+ * The policy is used to decide if various mechanisms should be enabled,
+ * mostly based on the process configuration and the hostname queried. The
+ * policy is aligned with Android's libcore NetworkSecurityPolicy.
+ */
+ private ConscryptNetworkSecurityPolicy policy;
+
/**
* The backing store for the AndroidCAStore if non-null. This will
* be null when the rootKeyStore is null, implying we are not
@@ -153,12 +165,6 @@ public TrustManagerImpl(KeyStore keyStore, CertPinManager manager) {
public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
ConscryptCertStore certStore) {
- this(keyStore, manager, certStore, null, null);
- }
-
- private TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
- ConscryptCertStore certStore, CertBlocklist blocklist,
- org.conscrypt.ct.CertificateTransparency ct) {
CertPathValidator validatorLocal = null;
CertificateFactory factoryLocal = null;
KeyStore rootKeyStoreLocal = null;
@@ -188,13 +194,6 @@ private TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
errLocal = e;
}
- if (ct == null) {
- ct = Platform.newDefaultCertificateTransparency();
- }
- if (blocklist == null) {
- blocklist = Platform.newDefaultBlocklist();
- }
-
this.pinManager = manager;
this.rootKeyStore = rootKeyStoreLocal;
this.trustedCertificateStore = trustedCertificateStoreLocal;
@@ -204,8 +203,25 @@ private TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
this.intermediateIndex = new TrustedCertificateIndex();
this.acceptedIssuers = acceptedIssuersLocal;
this.err = errLocal;
- this.blocklist = blocklist;
- this.ct = ct;
+ this.policy = ConscryptNetworkSecurityPolicy.getDefault();
+ this.blocklist = Platform.newDefaultBlocklist();
+ this.ct = Platform.newDefaultCertificateTransparency(new Supplier() {
+ @Override
+ public NetworkSecurityPolicy get() {
+ return policy;
+ }
+ });
+ }
+
+ /**
+ * Attach a ConscryptNetworkSecurityPolicy to this TrustManager.
+ */
+ public void setNetworkSecurityPolicy(ConscryptNetworkSecurityPolicy policy) {
+ this.policy = policy;
+ }
+
+ public ConscryptNetworkSecurityPolicy getNetworkSecurityPolicy() {
+ return policy;
}
@SuppressWarnings("JdkObsolete") // KeyStore#aliases is the only API available
@@ -298,12 +314,24 @@ public void checkServerTrusted(X509Certificate[] chain, String authType)
/**
* For backward compatibility with older Android API that used String for the hostname only.
*/
+ @Override
public List checkServerTrusted(X509Certificate[] chain, String authType,
String hostname) throws CertificateException {
return checkTrusted(chain, null /* ocspData */, null /* tlsSctData */, authType, hostname,
false);
}
+ /**
+ * For compatibility with network stacks that cannot provide an SSLSession nor a
+ * Socket (e.g., Cronet).
+ */
+ @Override
+ public List checkServerTrusted(X509Certificate[] chain, byte[] ocspData,
+ byte[] tlsSctData, String authType,
+ String hostname) throws CertificateException {
+ return checkTrusted(chain, ocspData, tlsSctData, authType, hostname, false);
+ }
+
/**
* Returns the full trusted certificate chain found from {@code certs}.
*
@@ -662,7 +690,8 @@ private List verifyChain(List untrustedChain,
}
// Check Certificate Transparency (if required).
- if (!clientAuth && host != null && ct != null && ct.isCTVerificationRequired(host)) {
+ if (!clientAuth && host != null && ct != null
+ && policy.isCertificateTransparencyVerificationRequired(host)) {
ct.checkCT(wholeChain, ocspData, tlsSctData, host);
}
diff --git a/common/src/main/java/org/conscrypt/XdhKeySpec.java b/common/src/main/java/org/conscrypt/XdhKeySpec.java
index 7ac38c188..83d22d907 100644
--- a/common/src/main/java/org/conscrypt/XdhKeySpec.java
+++ b/common/src/main/java/org/conscrypt/XdhKeySpec.java
@@ -43,7 +43,7 @@ public boolean equals(Object o) {
return false;
EncodedKeySpec that = (EncodedKeySpec) o;
return (getFormat().equals(that.getFormat())
- && Arrays.equals(getEncoded(), that.getEncoded()));
+ && (Arrays.equals(getEncoded(), that.getEncoded())));
}
@Override
diff --git a/common/src/main/java/org/conscrypt/ct/CertificateEntry.java b/common/src/main/java/org/conscrypt/ct/CertificateEntry.java
index eae9fbadb..d28b03cd2 100644
--- a/common/src/main/java/org/conscrypt/ct/CertificateEntry.java
+++ b/common/src/main/java/org/conscrypt/ct/CertificateEntry.java
@@ -143,4 +143,17 @@ public void encode(OutputStream output) throws SerializationException {
}
Serialization.writeVariableBytes(output, certificate, Constants.CERTIFICATE_LENGTH_BYTES);
}
+
+ /**
+ * Expected size of the encoded CertificateEntry structure.
+ */
+ public int encodedLength() {
+ int size = Constants.LOG_ENTRY_TYPE_LENGTH;
+ if (entryType == LogEntryType.PRECERT_ENTRY) {
+ size += issuerKeyHash.length;
+ }
+ size += Constants.CERTIFICATE_LENGTH_BYTES;
+ size += certificate.length;
+ return size;
+ }
}
diff --git a/common/src/main/java/org/conscrypt/ct/CertificateTransparency.java b/common/src/main/java/org/conscrypt/ct/CertificateTransparency.java
index 1e13cdf6d..502f33f1b 100644
--- a/common/src/main/java/org/conscrypt/ct/CertificateTransparency.java
+++ b/common/src/main/java/org/conscrypt/ct/CertificateTransparency.java
@@ -17,6 +17,7 @@
package org.conscrypt.ct;
import org.conscrypt.Internal;
+import org.conscrypt.NetworkSecurityPolicy;
import org.conscrypt.Platform;
import org.conscrypt.metrics.CertificateTransparencyVerificationReason;
import org.conscrypt.metrics.StatsLog;
@@ -25,6 +26,7 @@
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Objects;
+import java.util.function.Supplier;
/**
* Certificate Transparency subsystem. The implementation contains references
@@ -36,9 +38,11 @@ public class CertificateTransparency {
private Verifier verifier;
private Policy policy;
private StatsLog statsLog;
+ private Supplier policySupplier;
public CertificateTransparency(LogStore logStore, Policy policy, Verifier verifier,
- StatsLog statsLog) {
+ StatsLog statsLog,
+ Supplier policySupplier) {
Objects.requireNonNull(logStore);
Objects.requireNonNull(policy);
Objects.requireNonNull(verifier);
@@ -48,14 +52,11 @@ public CertificateTransparency(LogStore logStore, Policy policy, Verifier verifi
this.policy = policy;
this.verifier = verifier;
this.statsLog = statsLog;
+ this.policySupplier = policySupplier;
}
- public boolean isCTVerificationRequired(String host) {
- return Platform.isCTVerificationRequired(host);
- }
-
- public CertificateTransparencyVerificationReason reasonCTVerificationRequired(String host) {
- return Platform.reasonCTVerificationRequired(host);
+ public CertificateTransparencyVerificationReason getVerificationReason(String host) {
+ return policySupplier.get().getCertificateTransparencyVerificationReason(host);
}
public void checkCT(List chain, byte[] ocspData, byte[] tlsData, String host)
@@ -67,7 +68,7 @@ public void checkCT(List chain, byte[] ocspData, byte[] tlsData
statsLog.reportCTVerificationResult(logStore,
/* VerificationResult */ null,
/* PolicyCompliance */ null,
- reasonCTVerificationRequired(host));
+ getVerificationReason(host));
return;
}
VerificationResult result =
@@ -76,7 +77,7 @@ public void checkCT(List chain, byte[] ocspData, byte[] tlsData
X509Certificate leaf = chain.get(0);
PolicyCompliance compliance = policy.doesResultConformToPolicy(result, leaf);
statsLog.reportCTVerificationResult(logStore, result, compliance,
- reasonCTVerificationRequired(host));
+ getVerificationReason(host));
if (compliance != PolicyCompliance.COMPLY) {
throw new CertificateException(
"Certificate chain does not conform to required transparency policy: "
diff --git a/common/src/main/java/org/conscrypt/ct/LogInfo.java b/common/src/main/java/org/conscrypt/ct/LogInfo.java
index 8c3b82638..6412f2fe7 100644
--- a/common/src/main/java/org/conscrypt/ct/LogInfo.java
+++ b/common/src/main/java/org/conscrypt/ct/LogInfo.java
@@ -29,7 +29,7 @@
/**
* Properties about a Certificate Transparency Log.
- * This object stores information about a CT log, its public key, description and URL.
+ * This object stores information about a CT log, its public key and URL.
* It allows verification of SCTs against the log's public key.
*/
@Internal
@@ -42,13 +42,16 @@ public class LogInfo {
public static final int STATE_RETIRED = 5;
public static final int STATE_REJECTED = 6;
+ public static final int TYPE_UNKNOWN = 0;
+ public static final int TYPE_RFC6962 = 1;
+ public static final int TYPE_STATIC_CT_API = 2;
+
private final byte[] logId;
private final PublicKey publicKey;
private final int state;
private final long stateTimestamp;
- private final String description;
- private final String url;
private final String operator;
+ private final int type;
private LogInfo(Builder builder) {
/* Based on the required fields for the log list schema v3. Notably,
@@ -56,16 +59,14 @@ private LogInfo(Builder builder) {
* is validated in the builder. */
Objects.requireNonNull(builder.logId);
Objects.requireNonNull(builder.publicKey);
- Objects.requireNonNull(builder.url);
Objects.requireNonNull(builder.operator);
this.logId = builder.logId;
this.publicKey = builder.publicKey;
this.state = builder.state;
this.stateTimestamp = builder.stateTimestamp;
- this.description = builder.description;
- this.url = builder.url;
this.operator = builder.operator;
+ this.type = builder.type;
}
public static class Builder {
@@ -73,9 +74,8 @@ public static class Builder {
private PublicKey publicKey;
private int state;
private long stateTimestamp;
- private String description;
- private String url;
private String operator;
+ private int type;
public Builder setPublicKey(PublicKey publicKey) {
Objects.requireNonNull(publicKey);
@@ -98,24 +98,20 @@ public Builder setState(int state, long timestamp) {
return this;
}
- public Builder setDescription(String description) {
- Objects.requireNonNull(description);
- this.description = description;
- return this;
- }
-
- public Builder setUrl(String url) {
- Objects.requireNonNull(url);
- this.url = url;
- return this;
- }
-
public Builder setOperator(String operator) {
Objects.requireNonNull(operator);
this.operator = operator;
return this;
}
+ public Builder setType(int type) {
+ if (type < 0 || type > TYPE_STATIC_CT_API) {
+ throw new IllegalArgumentException("invalid type value");
+ }
+ this.type = type;
+ return this;
+ }
+
public LogInfo build() {
return new LogInfo(this);
}
@@ -132,14 +128,6 @@ public PublicKey getPublicKey() {
return publicKey;
}
- public String getDescription() {
- return description;
- }
-
- public String getUrl() {
- return url;
- }
-
public int getState() {
return state;
}
@@ -159,6 +147,10 @@ public String getOperator() {
return operator;
}
+ public int getType() {
+ return type;
+ }
+
@Override
public boolean equals(Object other) {
if (this == other) {
@@ -169,16 +161,14 @@ public boolean equals(Object other) {
}
LogInfo that = (LogInfo) other;
- return this.state == that.state && this.description.equals(that.description)
- && this.url.equals(that.url) && this.operator.equals(that.operator)
- && this.stateTimestamp == that.stateTimestamp
+ return this.state == that.state && this.operator.equals(that.operator)
+ && this.stateTimestamp == that.stateTimestamp && this.type == that.type
&& Arrays.equals(this.logId, that.logId);
}
@Override
public int hashCode() {
- return Objects.hash(Arrays.hashCode(logId), description, url, state, stateTimestamp,
- operator);
+ return Objects.hash(Arrays.hashCode(logId), state, stateTimestamp, operator, type);
}
/**
diff --git a/common/src/main/java/org/conscrypt/ct/PolicyCompliance.java b/common/src/main/java/org/conscrypt/ct/PolicyCompliance.java
index 68cffbb6e..c84297937 100644
--- a/common/src/main/java/org/conscrypt/ct/PolicyCompliance.java
+++ b/common/src/main/java/org/conscrypt/ct/PolicyCompliance.java
@@ -18,4 +18,11 @@
import org.conscrypt.Internal;
-@Internal public enum PolicyCompliance { COMPLY, NOT_ENOUGH_SCTS, NOT_ENOUGH_DIVERSE_SCTS }
+@Internal
+public enum PolicyCompliance {
+ COMPLY,
+ NOT_ENOUGH_SCTS,
+
+ NOT_ENOUGH_DIVERSE_SCTS,
+ NO_RFC6962_LOG
+}
diff --git a/common/src/main/java/org/conscrypt/ct/SignedCertificateTimestamp.java b/common/src/main/java/org/conscrypt/ct/SignedCertificateTimestamp.java
index f9a737f66..9e89f5ce9 100644
--- a/common/src/main/java/org/conscrypt/ct/SignedCertificateTimestamp.java
+++ b/common/src/main/java/org/conscrypt/ct/SignedCertificateTimestamp.java
@@ -135,11 +135,22 @@ public void encodeTBS(OutputStream output, CertificateEntry certEntry)
Serialization.writeVariableBytes(output, extensions, Constants.EXTENSIONS_LENGTH_BYTES);
}
+ private int encodedLength(CertificateEntry certEntry) {
+ int size = Constants.VERSION_LENGTH;
+ size += Constants.SIGNATURE_TYPE_LENGTH;
+ size += Constants.TIMESTAMP_LENGTH;
+ size += certEntry.encodedLength();
+ size += Constants.EXTENSIONS_LENGTH_BYTES;
+ size += extensions.length;
+ return size;
+ }
+
/**
* TLS encode the signed part of the SCT, as described by RFC6962 section 3.2.
*/
public byte[] encodeTBS(CertificateEntry certEntry) throws SerializationException {
- ByteArrayOutputStream output = new ByteArrayOutputStream();
+ int bufferSize = encodedLength(certEntry);
+ ByteArrayOutputStream output = new ByteArrayOutputStream(bufferSize);
encodeTBS(output, certEntry);
return output.toByteArray();
}
diff --git a/common/src/main/java/org/conscrypt/metrics/CertificateTransparencyVerificationReason.java b/common/src/main/java/org/conscrypt/metrics/CertificateTransparencyVerificationReason.java
index 0c7fab7aa..ef4a5b999 100644
--- a/common/src/main/java/org/conscrypt/metrics/CertificateTransparencyVerificationReason.java
+++ b/common/src/main/java/org/conscrypt/metrics/CertificateTransparencyVerificationReason.java
@@ -16,8 +16,10 @@
package org.conscrypt.metrics;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_DRY_RUN;
import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_NSCONFIG_APP_OPT_IN;
import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_NSCONFIG_DOMAIN_OPT_IN;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_SDK_TARGET_DEFAULT_ENABLED;
import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_UNKNOWN;
import org.conscrypt.Internal;
@@ -30,7 +32,10 @@ public enum CertificateTransparencyVerificationReason {
UNKNOWN(CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_UNKNOWN),
APP_OPT_IN(CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_NSCONFIG_APP_OPT_IN),
DOMAIN_OPT_IN(
- CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_NSCONFIG_DOMAIN_OPT_IN);
+ CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_NSCONFIG_DOMAIN_OPT_IN),
+ SDK_TARGET_DEFAULT_ENABLED(
+ CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_SDK_TARGET_DEFAULT_ENABLED),
+ DRY_RUN(CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_DRY_RUN);
final int id;
diff --git a/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java b/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java
index a94a4e760..489fd0d4e 100644
--- a/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java
+++ b/common/src/main/java/org/conscrypt/metrics/ConscryptStatsLog.java
@@ -66,6 +66,12 @@ public final class ConscryptStatsLog {
*/
public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED = 989;
+ /**
+ * CertificateBlocklistBlockReported certificate_blocklist_block_reported
+ * Usage: StatsLog.write(StatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED, int source, int index, int uid);
+ */
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED = 1143;
+
// Constants for enum values.
// Values for TlsHandshakeReported.protocol
@@ -179,10 +185,22 @@ public final class ConscryptStatsLog {
public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_SDK_TARGET_DEFAULT_ENABLED = 2;
public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_NSCONFIG_APP_OPT_IN = 3;
public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_NSCONFIG_DOMAIN_OPT_IN = 4;
+ public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__REASON__REASON_DRY_RUN = 5;
+
// Values for CertificateTransparencyVerificationReported.policy_compatibility_version
public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__POLICY_COMPATIBILITY_VERSION__COMPAT_VERSION_UNKNOWN = 0;
public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__POLICY_COMPATIBILITY_VERSION__COMPAT_VERSION_V1 = 1;
+ public static final int CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__POLICY_COMPATIBILITY_VERSION__COMPAT_VERSION_V2 = 2;
+
+ // Values for CertificateBlocklistBlockReported.source
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_UNKNOWN = 0;
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_TEST = 1;
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_BUILT_IN = 2;
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_FILE = 3;
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_TEST = 4;
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_BUILT_IN = 5;
+ public static final int CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_FILE = 6;
// Write methods
public static void write(int code, boolean arg1, int arg2, int arg3, int arg4, int arg5, int[] arg6) {
@@ -224,7 +242,18 @@ public static void write(int code, int arg1, int arg2, int arg3, int arg4, int a
ReflexiveStatsLog.write(builder.build());
}
- public static void write(int code, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8) {
+ public static void write(int code, int arg1, int arg2, int arg3) {
+ final ReflexiveStatsEvent.Builder builder = ReflexiveStatsEvent.newBuilder();
+ builder.setAtomId(code);
+ builder.writeInt(arg1);
+ builder.writeInt(arg2);
+ builder.writeInt(arg3);
+
+ builder.usePooledBuffer();
+ ReflexiveStatsLog.write(builder.build());
+ }
+
+ public static void write(int code, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8, int arg9) {
final ReflexiveStatsEvent.Builder builder = ReflexiveStatsEvent.newBuilder();
builder.setAtomId(code);
builder.writeInt(arg1);
@@ -235,6 +264,7 @@ public static void write(int code, int arg1, int arg2, int arg3, int arg4, int a
builder.writeInt(arg6);
builder.writeInt(arg7);
builder.writeInt(arg8);
+ builder.writeInt(arg9);
builder.usePooledBuffer();
ReflexiveStatsLog.write(builder.build());
diff --git a/common/src/main/java/org/conscrypt/metrics/NoopStatsLog.java b/common/src/main/java/org/conscrypt/metrics/NoopStatsLog.java
index 1144e3350..b4456fea5 100644
--- a/common/src/main/java/org/conscrypt/metrics/NoopStatsLog.java
+++ b/common/src/main/java/org/conscrypt/metrics/NoopStatsLog.java
@@ -15,6 +15,7 @@
*/
package org.conscrypt.metrics;
+import org.conscrypt.CertBlocklistEntry;
import org.conscrypt.Internal;
import org.conscrypt.ct.LogStore;
import org.conscrypt.ct.PolicyCompliance;
@@ -38,4 +39,6 @@ public void updateCTLogListStatusChanged(LogStore logStore) {}
public void reportCTVerificationResult(LogStore logStore, VerificationResult result,
PolicyCompliance compliance,
CertificateTransparencyVerificationReason reason) {}
+
+ public void reportBlocklistHit(CertBlocklistEntry entry) {}
}
diff --git a/common/src/main/java/org/conscrypt/metrics/StatsLog.java b/common/src/main/java/org/conscrypt/metrics/StatsLog.java
index 0779946d7..f5711cc4c 100644
--- a/common/src/main/java/org/conscrypt/metrics/StatsLog.java
+++ b/common/src/main/java/org/conscrypt/metrics/StatsLog.java
@@ -15,6 +15,7 @@
*/
package org.conscrypt.metrics;
+import org.conscrypt.CertBlocklistEntry;
import org.conscrypt.Internal;
import org.conscrypt.ct.LogStore;
import org.conscrypt.ct.PolicyCompliance;
@@ -30,4 +31,6 @@ public void countTlsHandshake(boolean success, String protocol, String cipherSui
public void reportCTVerificationResult(LogStore logStore, VerificationResult result,
PolicyCompliance compliance,
CertificateTransparencyVerificationReason reason);
+
+ public void reportBlocklistHit(CertBlocklistEntry entry);
}
diff --git a/common/src/main/java/org/conscrypt/metrics/StatsLogImpl.java b/common/src/main/java/org/conscrypt/metrics/StatsLogImpl.java
index 9a5365ef1..6b4d1e43c 100644
--- a/common/src/main/java/org/conscrypt/metrics/StatsLogImpl.java
+++ b/common/src/main/java/org/conscrypt/metrics/StatsLogImpl.java
@@ -15,6 +15,14 @@
*/
package org.conscrypt.metrics;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_BUILT_IN;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_FILE;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_TEST;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_BUILT_IN;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_FILE;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_TEST;
+import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_UNKNOWN;
import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_STATE_CHANGED;
import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_STATE_CHANGED__STATUS__STATUS_EXPIRED;
import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_LOG_LIST_STATE_CHANGED__STATUS__STATUS_NOT_FOUND;
@@ -30,21 +38,77 @@
import static org.conscrypt.metrics.ConscryptStatsLog.CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__RESULT__RESULT_UNKNOWN;
import static org.conscrypt.metrics.ConscryptStatsLog.TLS_HANDSHAKE_REPORTED;
+import org.conscrypt.CertBlocklistEntry;
import org.conscrypt.Internal;
import org.conscrypt.Platform;
import org.conscrypt.ct.LogStore;
import org.conscrypt.ct.PolicyCompliance;
import org.conscrypt.ct.VerificationResult;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+
/**
* Implements logging for Conscrypt metrics.
*/
@Internal
public final class StatsLogImpl implements StatsLog {
- private static final StatsLog INSTANCE = new StatsLogImpl();
- private StatsLogImpl() {}
+ private final BlockingQueue logQueue;
+ private final ExecutorService writerThreadExecutor;
+ private boolean running = false;
+
+ private StatsLogImpl() {
+ this.logQueue = new LinkedBlockingQueue<>(100);
+ this.writerThreadExecutor =
+ Executors.newSingleThreadExecutor(new LowPriorityThreadFactory());
+ startWriterThread();
+ }
public static StatsLog getInstance() {
- return INSTANCE;
+ return new StatsLogImpl();
+ }
+
+ public void stop() {
+ running = false;
+ writerThreadExecutor.shutdownNow();
+ try {
+ writerThreadExecutor.awaitTermination(5, java.util.concurrent.TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ private void startWriterThread() {
+ writerThreadExecutor.execute(() -> {
+ while (running) {
+ try {
+ // Blocks until a log task is available
+ Runnable logTask = logQueue.take();
+ logTask.run(); // Execute the specific ConscryptStatsLog.write() call
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ running = false;
+ }
+ }
+ // Process remaining logs
+ while (!logQueue.isEmpty()) {
+ Runnable logTask = logQueue.poll();
+ if (logTask != null) {
+ logTask.run();
+ }
+ }
+ });
+ }
+
+ private static class LowPriorityThreadFactory implements ThreadFactory {
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread thread = new Thread(r, "ConscryptStatsLogWriter");
+ thread.setPriority(Thread.MIN_PRIORITY);
+ return thread;
+ }
}
@Override
@@ -89,12 +153,21 @@ private static int policyComplianceToMetrics(VerificationResult result,
} else if (result.getValidSCTs().size() == 0) {
return CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__RESULT__RESULT_FAILURE_NO_SCTS_FOUND;
} else if (compliance == PolicyCompliance.NOT_ENOUGH_SCTS
- || compliance == PolicyCompliance.NOT_ENOUGH_DIVERSE_SCTS) {
+ || compliance == PolicyCompliance.NOT_ENOUGH_DIVERSE_SCTS
+ || compliance == PolicyCompliance.NO_RFC6962_LOG) {
return CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__RESULT__RESULT_FAILURE_SCTS_NOT_COMPLIANT;
}
return CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__RESULT__RESULT_UNKNOWN;
}
+ private static int getUid() {
+ int[] uids = Platform.getUids();
+ if (uids != null && uids.length != 0) {
+ return uids[0];
+ }
+ return 0;
+ }
+
@Override
public void reportCTVerificationResult(LogStore store, VerificationResult result,
PolicyCompliance compliance,
@@ -103,19 +176,44 @@ public void reportCTVerificationResult(LogStore store, VerificationResult result
|| store.getState() == LogStore.State.MALFORMED) {
write(CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED,
CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__RESULT__RESULT_FAIL_OPEN_NO_LOG_LIST_AVAILABLE,
- reason.getId(), 0, 0, 0, 0, 0, 0);
+ reason.getId(), 0, 0, 0, 0, 0, 0, getUid());
} else if (store.getState() == LogStore.State.NON_COMPLIANT) {
write(CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED,
CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED__RESULT__RESULT_FAIL_OPEN_LOG_LIST_NOT_COMPLIANT,
- reason.getId(), 0, 0, 0, 0, 0, 0);
+ reason.getId(), 0, 0, 0, 0, 0, 0, getUid());
} else if (store.getState() == LogStore.State.COMPLIANT) {
int comp = policyComplianceToMetrics(result, compliance);
write(CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED, comp, reason.getId(),
store.getCompatVersion(), store.getMajorVersion(), store.getMinorVersion(),
- result.numCertSCTs(), result.numOCSPSCTs(), result.numTlsSCTs());
+ result.numCertSCTs(), result.numOCSPSCTs(), result.numTlsSCTs(), getUid());
+ }
+ }
+
+ private static int blocklistOriginToMetrics(CertBlocklistEntry.Origin origin) {
+ switch (origin) {
+ case SHA1_TEST:
+ return CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_TEST;
+ case SHA1_BUILT_IN:
+ return CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_BUILT_IN;
+ case SHA1_FILE:
+ return CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA1_FILE;
+ case SHA256_TEST:
+ return CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_TEST;
+ case SHA256_BUILT_IN:
+ return CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_BUILT_IN;
+ case SHA256_FILE:
+ return CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_SHA256_FILE;
}
+ return CERTIFICATE_BLOCKLIST_BLOCK_REPORTED__SOURCE__BLOCKLIST_SOURCE_UNKNOWN;
}
+ @Override
+ public void reportBlocklistHit(CertBlocklistEntry entry) {
+ write(CERTIFICATE_BLOCKLIST_BLOCK_REPORTED, blocklistOriginToMetrics(entry.getOrigin()),
+ entry.getIndex(), getUid());
+ }
+
+
private static final boolean sdkVersionBiggerThan32;
static {
@@ -137,7 +235,9 @@ private void write(int atomId, boolean success, int protocol, int cipherSuite, i
builder.usePooledBuffer();
ReflexiveStatsLog.write(builder.build());
} else {
- ConscryptStatsLog.write(atomId, success, protocol, cipherSuite, duration, source, uids);
+ logQueue.offer(()
+ -> ConscryptStatsLog.write(atomId, success, protocol,
+ cipherSuite, duration, source, uids));
}
}
@@ -149,9 +249,13 @@ private void write(int atomId, int status, int loadedCompatVersion,
private void write(int atomId, int verificationResult, int verificationReason,
int policyCompatVersion, int majorVersion, int minorVersion,
- int numEmbeddedScts, int numOcspScts, int numTlsScts) {
+ int numEmbeddedScts, int numOcspScts, int numTlsScts, int uid) {
ConscryptStatsLog.write(atomId, verificationResult, verificationReason, policyCompatVersion,
majorVersion, minorVersion, numEmbeddedScts, numOcspScts,
- numTlsScts);
+ numTlsScts, uid);
+ }
+
+ private void write(int atomId, int origin, int index, int uid) {
+ ConscryptStatsLog.write(atomId, origin, index, uid);
}
}
diff --git a/common/src/test/java/org/conscrypt/ArrayUtilsTest.java b/common/src/test/java/org/conscrypt/ArrayUtilsTest.java
index 959cc5638..71836c1c6 100644
--- a/common/src/test/java/org/conscrypt/ArrayUtilsTest.java
+++ b/common/src/test/java/org/conscrypt/ArrayUtilsTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2023 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/common/src/test/java/org/conscrypt/HostnameVerifierTest.java b/common/src/test/java/org/conscrypt/HostnameVerifierTest.java
index 2dc6b0fdf..127f695af 100644
--- a/common/src/test/java/org/conscrypt/HostnameVerifierTest.java
+++ b/common/src/test/java/org/conscrypt/HostnameVerifierTest.java
@@ -64,8 +64,6 @@ public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException {
}
private static final Charset UTF_8 = Charset.forName("UTF-8");
- // BEGIN Android-changed: Run tests for both default and strict verifiers. http://b/144694112
- // private HostnameVerifier verifier = OkHostnameVerifier.INSTANCE;
@Parameters()
public static Collection