Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions android/lint.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,10 @@
<issue id="Assert">
<ignore path="**/common/src/main/java/org/conscrypt/OpenSSLCipherChaCha20.java" />
</issue>

<!-- Workaround for "Unexpected failure during lint analysis". -->
<issue id="LintError">
<ignore regexp=".*module-info\.class.*"/>
</issue>

</lint>
Original file line number Diff line number Diff line change
@@ -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;
}
}
60 changes: 6 additions & 54 deletions android/src/main/java/org/conscrypt/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String> 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() {
Expand Down Expand Up @@ -940,7 +891,8 @@ static CertBlocklist newDefaultBlocklist() {
return null;
}

static CertificateTransparency newDefaultCertificateTransparency() {
static CertificateTransparency newDefaultCertificateTransparency(
Supplier<NetworkSecurityPolicy> policySupplier) {
return null;
}

Expand Down
12 changes: 6 additions & 6 deletions common/src/jni/main/cpp/conscrypt/native_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
#include <type_traits>
#include <vector>

#include "jni.h"

using conscrypt::AppData;
using conscrypt::BioInputStream;
using conscrypt::BioOutputStream;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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();
}

Expand Down
8 changes: 8 additions & 0 deletions common/src/jni/main/include/conscrypt/jniutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
15 changes: 10 additions & 5 deletions common/src/main/java/org/conscrypt/BufferUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand All @@ -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();
Expand All @@ -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) {
Expand All @@ -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];
Expand Down
3 changes: 3 additions & 0 deletions common/src/main/java/org/conscrypt/CertBlocklist.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
37 changes: 37 additions & 0 deletions common/src/main/java/org/conscrypt/CertBlocklistEntry.java
Original file line number Diff line number Diff line change
@@ -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();
}
20 changes: 20 additions & 0 deletions common/src/main/java/org/conscrypt/Conscrypt.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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.
*
Expand Down
5 changes: 5 additions & 0 deletions common/src/main/java/org/conscrypt/ConscryptEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
5 changes: 5 additions & 0 deletions common/src/main/java/org/conscrypt/ConscryptEngineSocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading
Loading