Skip to content

Commit

Permalink
Upstream multiple AOSP changes (#1221)
Browse files Browse the repository at this point in the history
This should be pretty much the complete set now

e6827ba Validate LogStore against the Policy
3fe1ea3 Filter out SCTs emitted after a log expired
e841e6c Use enum as outcome of doesResultConformToPolicy
dbdd64c Add PolicyImplTest for Certificate Transparency
97918a0 Implement Android CT Policy for embedded SCTs
c9f38db Remove logStore attribute from Policy
9d5f0c3 Fix hashcode for LogInfo
a59840d Keep LogInfo in VerifiedSCT
2eb5e75 Add operator name to LogInfo
d8519cf Remove PolicyImpl minimumLogCount argument
92961a5 Remove "CT" prefix from org.conscrypt.ct classes
81d0929 Use Flags.certificateTransparencyPlatform()
30b8139 Use ByteArray consistently
98f0f2b Support parsing CT v3 JSON log list
bb60a90 TrustedCertificateStore: Mitigate NPE when checking updateable certs directory
feacee5 Add State to CTLogInfo
633a247 Remove ct SystemLogDir
dab378e Remove InternalUtil
4c22413 Remove ct fallback logs
9b48e0e Add a java_library target for conscrypt-tests
e33c851 Gate tls removal by api level
65e6c8e Bring back sslv3
c90bd39 Add caching for cert blocklist
5de9106 Read default SHA256 pubkey blocklist
8e656b1 Add support for SHA256 blocklist entries
12c479a Deprecate the serial-based blocklist
396823d Rename SSL_CONTEXT_ALL
b082573 Filter protocols when creating SSLParameterImpl


Co-authored-by: Miguel Aranda <[email protected]>
Co-authored-by: Thiébaud Weksteen <[email protected]>
Co-authored-by: Syed Zaidi <[email protected]>
  • Loading branch information
4 people authored Sep 9, 2024
1 parent aba2555 commit a9a7e6d
Show file tree
Hide file tree
Showing 45 changed files with 2,052 additions and 1,119 deletions.
16 changes: 12 additions & 4 deletions android/src/main/java/org/conscrypt/Platform.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.StandardConstants;
import javax.net.ssl.X509TrustManager;
import org.conscrypt.ct.CTLogStore;
import org.conscrypt.ct.CTPolicy;
import org.conscrypt.ct.LogStore;
import org.conscrypt.ct.Policy;
import org.conscrypt.metrics.CipherSuite;
import org.conscrypt.metrics.ConscryptStatsLog;
import org.conscrypt.metrics.Protocol;
Expand Down Expand Up @@ -884,11 +884,11 @@ static CertBlocklist newDefaultBlocklist() {
return null;
}

static CTLogStore newDefaultLogStore() {
static LogStore newDefaultLogStore() {
return null;
}

static CTPolicy newDefaultPolicy(CTLogStore logStore) {
static Policy newDefaultPolicy() {
return null;
}

Expand Down Expand Up @@ -955,4 +955,12 @@ public static boolean isJavaxCertificateSupported() {
public static boolean isTlsV1Deprecated() {
return true;
}

public static boolean isTlsV1Filtered() {
return false;
}

public static boolean isTlsV1Supported() {
return false;
}
}
7 changes: 7 additions & 0 deletions common/src/main/java/org/conscrypt/ArrayUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,11 @@ public static byte[] reverse(byte[] array) {
}
return result;
}

/**
* Checks if given array is null or has zero elements.
*/
public static <T> boolean isEmpty(T[] array) {
return array == null || array.length == 0;
}
}
8 changes: 6 additions & 2 deletions common/src/main/java/org/conscrypt/ByteArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@
/**
* Byte array wrapper for hashtable use. Implements equals() and hashCode().
*/
final class ByteArray {
@Internal
public final class ByteArray {
private final byte[] bytes;
private final int hashCode;

ByteArray(byte[] bytes) {
public ByteArray(byte[] bytes) {
this.bytes = bytes;
this.hashCode = Arrays.hashCode(bytes);
}
Expand All @@ -37,6 +38,9 @@ public int hashCode() {

@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ByteArray)) {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions common/src/main/java/org/conscrypt/NativeCrypto.java
Original file line number Diff line number Diff line change
Expand Up @@ -789,8 +789,8 @@ static native long X509_CRL_get_nextUpdate(long x509CrlCtx, OpenSSLX509CRL holde
// --- SSL handling --------------------------------------------------------

static final String OBSOLETE_PROTOCOL_SSLV3 = "SSLv3";
private static final String DEPRECATED_PROTOCOL_TLSV1 = "TLSv1";
private static final String DEPRECATED_PROTOCOL_TLSV1_1 = "TLSv1.1";
static final String DEPRECATED_PROTOCOL_TLSV1 = "TLSv1";
static final String DEPRECATED_PROTOCOL_TLSV1_1 = "TLSv1.1";
private static final String SUPPORTED_PROTOCOL_TLSV1_2 = "TLSv1.2";
static final String SUPPORTED_PROTOCOL_TLSV1_3 = "TLSv1.3";

Expand Down
6 changes: 4 additions & 2 deletions common/src/main/java/org/conscrypt/NativeSsl.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,10 @@ void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOExcept

if (parameters.getEnabledProtocols().length == 0 && parameters.isEnabledProtocolsFiltered) {
throw new SSLHandshakeException("No enabled protocols; "
+ NativeCrypto.OBSOLETE_PROTOCOL_SSLV3
+ " is no longer supported and was filtered from the list");
+ NativeCrypto.OBSOLETE_PROTOCOL_SSLV3 + ", "
+ NativeCrypto.DEPRECATED_PROTOCOL_TLSV1
+ " and " + NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1
+ " are no longer supported and were filtered from the list");
}
NativeCrypto.setEnabledProtocols(ssl, this, parameters.enabledProtocols);
NativeCrypto.setEnabledCipherSuites(
Expand Down
7 changes: 4 additions & 3 deletions common/src/main/java/org/conscrypt/OpenSSLKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
/**
* Represents a BoringSSL {@code EVP_PKEY}.
*/
final class OpenSSLKey {
@Internal
public final class OpenSSLKey {
private final NativeRef.EVP_PKEY ctx;

private final boolean wrapped;
Expand Down Expand Up @@ -255,7 +256,7 @@ static OpenSSLKey fromPublicKey(PublicKey key) throws InvalidKeyException {
*
* @throws InvalidKeyException if parsing fails
*/
static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
public static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
throws InvalidKeyException {
OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(is, true);
try {
Expand All @@ -272,7 +273,7 @@ static OpenSSLKey fromPublicKeyPemInputStream(InputStream is)
}
}

PublicKey getPublicKey() throws NoSuchAlgorithmException {
public PublicKey getPublicKey() throws NoSuchAlgorithmException {
switch (NativeCrypto.EVP_PKEY_type(ctx)) {
case NativeConstants.EVP_PKEY_RSA:
return new OpenSSLRSAPublicKey(this);
Expand Down
24 changes: 21 additions & 3 deletions common/src/main/java/org/conscrypt/SSLParametersImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,20 @@ final class SSLParametersImpl implements Cloneable {
}

// initialize the list of cipher suites and protocols enabled by default
enabledProtocols = NativeCrypto.checkEnabledProtocols(
protocols == null ? NativeCrypto.getDefaultProtocols() : protocols).clone();
if (protocols == null) {
enabledProtocols = NativeCrypto.getDefaultProtocols().clone();
} else {
String[] filteredProtocols =
filterFromProtocols(protocols, Arrays.asList(!Platform.isTlsV1Filtered()
? new String[0]
: new String[] {
NativeCrypto.OBSOLETE_PROTOCOL_SSLV3,
NativeCrypto.DEPRECATED_PROTOCOL_TLSV1,
NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1,
}));
isEnabledProtocolsFiltered = protocols.length != filteredProtocols.length;
enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone();
}
boolean x509CipherSuitesNeeded = (x509KeyManager != null) || (x509TrustManager != null);
boolean pskCipherSuitesNeeded = pskKeyManager != null;
enabledCipherSuites = getDefaultCipherSuites(
Expand Down Expand Up @@ -282,7 +294,13 @@ void setEnabledProtocols(String[] protocols) {
throw new IllegalArgumentException("protocols == null");
}
String[] filteredProtocols =
filterFromProtocols(protocols, NativeCrypto.OBSOLETE_PROTOCOL_SSLV3);
filterFromProtocols(protocols, Arrays.asList(!Platform.isTlsV1Filtered()
? new String[0]
: new String[] {
NativeCrypto.OBSOLETE_PROTOCOL_SSLV3,
NativeCrypto.DEPRECATED_PROTOCOL_TLSV1,
NativeCrypto.DEPRECATED_PROTOCOL_TLSV1_1,
}));
isEnabledProtocolsFiltered = protocols.length != filteredProtocols.length;
enabledProtocols = NativeCrypto.checkEnabledProtocols(filteredProtocols).clone();
}
Expand Down
56 changes: 34 additions & 22 deletions common/src/main/java/org/conscrypt/TrustManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@

package org.conscrypt;

import org.conscrypt.ct.LogStore;
import org.conscrypt.ct.Policy;
import org.conscrypt.ct.PolicyCompliance;
import org.conscrypt.ct.VerificationResult;
import org.conscrypt.ct.Verifier;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
Expand Down Expand Up @@ -63,16 +69,13 @@
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.X509ExtendedTrustManager;
import org.conscrypt.ct.CTLogStore;
import org.conscrypt.ct.CTPolicy;
import org.conscrypt.ct.CTVerificationResult;
import org.conscrypt.ct.CTVerifier;

/**
*
Expand Down Expand Up @@ -139,8 +142,9 @@ public final class TrustManagerImpl extends X509ExtendedTrustManager {
private final Exception err;
private final CertificateFactory factory;
private final CertBlocklist blocklist;
private CTVerifier ctVerifier;
private CTPolicy ctPolicy;
private LogStore ctLogStore;
private Verifier ctVerifier;
private Policy ctPolicy;

private ConscryptHostnameVerifier hostnameVerifier;

Expand All @@ -163,18 +167,16 @@ public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
this(keyStore, manager, certStore, null);
}

public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
ConscryptCertStore certStore,
CertBlocklist blocklist) {
public TrustManagerImpl(KeyStore keyStore, CertPinManager manager, ConscryptCertStore certStore,
CertBlocklist blocklist) {
this(keyStore, manager, certStore, blocklist, null, null, null);
}

/**
* For testing only.
*/
public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
ConscryptCertStore certStore, CertBlocklist blocklist, CTLogStore ctLogStore,
CTVerifier ctVerifier, CTPolicy ctPolicy) {
public TrustManagerImpl(KeyStore keyStore, CertPinManager manager, ConscryptCertStore certStore,
CertBlocklist blocklist, LogStore ctLogStore, Verifier ctVerifier, Policy ctPolicy) {
CertPathValidator validatorLocal = null;
CertificateFactory factoryLocal = null;
KeyStore rootKeyStoreLocal = null;
Expand Down Expand Up @@ -214,7 +216,7 @@ public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
}

if (ctPolicy == null) {
ctPolicy = Platform.newDefaultPolicy(ctLogStore);
ctPolicy = Platform.newDefaultPolicy();
}

this.pinManager = manager;
Expand All @@ -227,8 +229,10 @@ public TrustManagerImpl(KeyStore keyStore, CertPinManager manager,
this.acceptedIssuers = acceptedIssuersLocal;
this.err = errLocal;
this.blocklist = blocklist;
this.ctVerifier = new CTVerifier(ctLogStore);
this.ctLogStore = ctLogStore;
this.ctVerifier = new Verifier(ctLogStore);
this.ctPolicy = ctPolicy;
ctLogStore.setPolicy(ctPolicy);
}

@SuppressWarnings("JdkObsolete") // KeyStore#aliases is the only API available
Expand Down Expand Up @@ -680,7 +684,7 @@ private List<X509Certificate> verifyChain(List<X509Certificate> untrustedChain,
if (!clientAuth &&
(ctEnabledOverride || (host != null && Platform
.isCTVerificationRequired(host)))) {
checkCT(host, wholeChain, ocspData, tlsSctData);
checkCT(wholeChain, ocspData, tlsSctData);
}

if (untrustedChain.isEmpty()) {
Expand Down Expand Up @@ -726,15 +730,23 @@ private void checkBlocklist(X509Certificate cert) throws CertificateException {
}
}

private void checkCT(String host, List<X509Certificate> chain, byte[] ocspData, byte[] tlsData)
private void checkCT(List<X509Certificate> chain, byte[] ocspData, byte[] tlsData)
throws CertificateException {
CTVerificationResult result =
if (ctLogStore.getState() != LogStore.State.COMPLIANT) {
/* Fail open. For some reason, the LogStore is not usable. It could
* be because there is no log list available or that the log list
* is too old (according to the policy). */
return;
}
VerificationResult result =
ctVerifier.verifySignedCertificateTimestamps(chain, tlsData, ocspData);

if (!ctPolicy.doesResultConformToPolicy(result, host,
chain.toArray(new X509Certificate[chain.size()]))) {
X509Certificate leaf = chain.get(0);
PolicyCompliance compliance = ctPolicy.doesResultConformToPolicy(result, leaf);
if (compliance != PolicyCompliance.COMPLY) {
throw new CertificateException(
"Certificate chain does not conform to required transparency policy.");
"Certificate chain does not conform to required transparency policy: "
+ compliance.name());
}
}

Expand Down Expand Up @@ -1025,12 +1037,12 @@ public void setCTEnabledOverride(boolean enabled) {
}

// Replace the CTVerifier. For testing only.
public void setCTVerifier(CTVerifier verifier) {
public void setCTVerifier(Verifier verifier) {
this.ctVerifier = verifier;
}

// Replace the CTPolicy. For testing only.
public void setCTPolicy(CTPolicy policy) {
public void setCTPolicy(Policy policy) {
this.ctPolicy = policy;
}
}
Loading

0 comments on commit a9a7e6d

Please sign in to comment.