Skip to content
Merged
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
52 changes: 47 additions & 5 deletions common/src/main/java/org/conscrypt/NativeSsl.java
Original file line number Diff line number Diff line change
Expand Up @@ -396,14 +396,14 @@ void initialize(String hostname, OpenSSLKey channelIdPrivateKey) throws IOExcept
NativeCrypto.SSL_set1_groups(ssl, this, toBoringSslGroups(paramsNamedGroups));
} else {
// Use default named group.
String namedGroupsProperty = System.getProperty("jdk.tls.namedGroups");
if (namedGroupsProperty == null || namedGroupsProperty.isEmpty()) {
// If the property is not set or empty, use the default named groups. See:
int[] parsedNamedGroups = getParsedTlsNamedGroupsPropertyOrNull();
if (parsedNamedGroups == null) {
// The jdk.tls.namedGroups property has not been set or is empty. We have to use the
// default named groups. See:
// https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html
setDefaultNamedGroups(ssl, this);
} else {
int[] groups = parseNamedGroupsProperty(namedGroupsProperty);
NativeCrypto.SSL_set1_groups(ssl, this, groups);
NativeCrypto.SSL_set1_groups(ssl, this, parsedNamedGroups);
}
}

Expand Down Expand Up @@ -798,4 +798,46 @@ void close() {
}
}
}

/**
* Returns the parsed value of the "jdk.tls.namedGroups" property.
*
* <p>Is null if the property is not set or empty.
*/
static synchronized int[] getParsedTlsNamedGroupsPropertyOrNull() {
try {
parseTlsNamedGroupsProperty();
} catch (IllegalArgumentException e) {
// This may happen if the user set the property to an invalid value.
// Since the last time the property was parsed successfully. We ignore it
// and return the previously parsed value.
}
return parsedTlsNamedGroupsProperty;
}

private static int[] parsedTlsNamedGroupsProperty = null;
private static String unparsedTlsNamedGroupsProperty = "";

/**
* Parses the "jdk.tls.namedGroups" property and stores the result in {@code
* parsedTlsNamedGroupsProperty}.
*
* <p>May throw an {@link IllegalArgumentException} if the property contains invalid values.
*/
static synchronized void parseTlsNamedGroupsProperty() {
String property = System.getProperty("jdk.tls.namedGroups");
if (property == null || property.isEmpty()) {
parsedTlsNamedGroupsProperty = null;
unparsedTlsNamedGroupsProperty = "";
} else {
if (!property.equals(unparsedTlsNamedGroupsProperty)) {
unparsedTlsNamedGroupsProperty = property;
parsedTlsNamedGroupsProperty = parseNamedGroupsProperty(property);
}
}
}

static {
parseTlsNamedGroupsProperty();
}
}
24 changes: 12 additions & 12 deletions common/src/main/java/org/conscrypt/OpenSSLRSAPrivateCrtKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -217,26 +217,26 @@ public boolean equals(Object o) {
RSAPrivateCrtKey other = (RSAPrivateCrtKey) o;

if (getOpenSSLKey().isHardwareBacked()) {
return getModulus().equals(other.getModulus())
&& publicExponent.equals(other.getPublicExponent());
return equalsBigInteger(getModulus(), other.getModulus())
&& equalsBigInteger(publicExponent, other.getPublicExponent());
} else {
return getModulus().equals(other.getModulus())
&& publicExponent.equals(other.getPublicExponent())
&& getPrivateExponent().equals(other.getPrivateExponent())
&& primeP.equals(other.getPrimeP()) && primeQ.equals(other.getPrimeQ())
&& primeExponentP.equals(other.getPrimeExponentP())
&& primeExponentQ.equals(other.getPrimeExponentQ())
&& crtCoefficient.equals(other.getCrtCoefficient());
return equalsBigInteger(getModulus(), other.getModulus())
&& equalsBigInteger(publicExponent, other.getPublicExponent())
&& equalsBigInteger(getPrivateExponent(), other.getPrivateExponent())
&& equalsBigInteger(primeP, other.getPrimeP()) && equalsBigInteger(primeQ, other.getPrimeQ())
&& equalsBigInteger(primeExponentP, other.getPrimeExponentP())
&& equalsBigInteger(primeExponentQ, other.getPrimeExponentQ())
&& equalsBigInteger(crtCoefficient, other.getCrtCoefficient());
}
} else if (o instanceof RSAPrivateKey) {
ensureReadParams();
RSAPrivateKey other = (RSAPrivateKey) o;

if (getOpenSSLKey().isHardwareBacked()) {
return getModulus().equals(other.getModulus());
return equalsBigInteger(getModulus(), other.getModulus());
} else {
return getModulus().equals(other.getModulus())
&& getPrivateExponent().equals(other.getPrivateExponent());
return equalsBigInteger(getModulus(), other.getModulus())
&& equalsBigInteger(getPrivateExponent(), other.getPrivateExponent());
}
}

Expand Down
9 changes: 7 additions & 2 deletions common/src/main/java/org/conscrypt/OpenSSLRSAPrivateKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAKey;
Expand Down Expand Up @@ -203,6 +204,10 @@ public final String getAlgorithm() {
return "RSA";
}

boolean equalsBigInteger(BigInteger a, BigInteger b) {
return MessageDigest.isEqual(a.toByteArray(), b.toByteArray());
}

@Override
public boolean equals(Object o) {
if (o == this) {
Expand All @@ -218,8 +223,8 @@ public boolean equals(Object o) {
ensureReadParams();
RSAPrivateKey other = (RSAPrivateKey) o;

return modulus.equals(other.getModulus())
&& privateExponent.equals(other.getPrivateExponent());
return equalsBigInteger(modulus, other.getModulus())
&& equalsBigInteger(privateExponent, other.getPrivateExponent());
}

return false;
Expand Down
66 changes: 48 additions & 18 deletions common/src/test/java/org/conscrypt/javax/net/ssl/SSLSocketTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1319,26 +1319,56 @@ public void handshake_namedGroupsDontIntersect_throwsException() throws Exceptio
}

@Test
public void handshake_namedGroupsProperty_failsIfAllValuesAreInvalid() throws Exception {
public void setNamedGroupsProperty_invalidValue_isIgnored() throws Exception {
// Set the property to a valid value.
System.setProperty("jdk.tls.namedGroups", "MLKEM1024");

{
TestSSLContext context = TestSSLContext.create();
final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
context.host, context.port);
final SSLSocket server = (SSLSocket) context.serverSocket.accept();
Future<Void> s = runAsync(() -> {
server.startHandshake();
return null;
});
Future<Void> c = runAsync(() -> {
client.startHandshake();
return null;
});
s.get();
c.get();
assertEquals("MLKEM1024", getCurveName(client));
assertEquals("MLKEM1024", getCurveName(server));
client.close();
server.close();
context.close();
}

// Now, set the property to an invalid value.
System.setProperty("jdk.tls.namedGroups", "invalid,invalid2");

TestSSLContext context = TestSSLContext.create();
final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
context.host, context.port);
final SSLSocket server = (SSLSocket) context.serverSocket.accept();
Future<Void> s = runAsync(() -> {
server.startHandshake();
return null;
});
Future<Void> c = runAsync(() -> {
client.startHandshake();
return null;
});
assertThrows(ExecutionException.class, s::get);
assertThrows(ExecutionException.class, c::get);
client.close();
server.close();
context.close();
{
TestSSLContext context = TestSSLContext.create();
final SSLSocket client = (SSLSocket) context.clientContext.getSocketFactory().createSocket(
context.host, context.port);
final SSLSocket server = (SSLSocket) context.serverSocket.accept();
Future<Void> s = runAsync(() -> {
server.startHandshake();
return null;
});
Future<Void> c = runAsync(() -> {
client.startHandshake();
return null;
});
s.get();
c.get();
assertEquals("MLKEM1024", getCurveName(client));
assertEquals("MLKEM1024", getCurveName(server));
client.close();
server.close();
context.close();
}
}

@Test
Expand Down
14 changes: 14 additions & 0 deletions openjdk/src/test/java/org/conscrypt/ConscryptAndroidSuite.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,14 @@
import org.conscrypt.javax.net.ssl.KeyManagerFactoryTest;
import org.conscrypt.javax.net.ssl.KeyStoreBuilderParametersTest;
import org.conscrypt.javax.net.ssl.SNIHostNameTest;
import org.conscrypt.javax.net.ssl.SSLContextTest;
import org.conscrypt.javax.net.ssl.SSLEngineTest;
import org.conscrypt.javax.net.ssl.SSLEngineVersionCompatibilityTest;
import org.conscrypt.javax.net.ssl.SSLParametersTest;
import org.conscrypt.javax.net.ssl.SSLServerSocketTest;
import org.conscrypt.javax.net.ssl.SSLSessionContextTest;
import org.conscrypt.javax.net.ssl.SSLSessionTest;
import org.conscrypt.javax.net.ssl.SSLSocketTest;
import org.conscrypt.javax.net.ssl.X509KeyManagerTest;
import org.conscrypt.metrics.CipherSuiteTest;
import org.conscrypt.metrics.OptionalMethodTest;
Expand Down Expand Up @@ -150,7 +157,14 @@
ProtocolTest.class,
ScryptTest.class,
SNIHostNameTest.class,
SSLContextTest.class,
SSLEngineTest.class,
SSLEngineVersionCompatibilityTest.class,
SSLParametersTest.class,
SSLServerSocketTest.class,
SSLSessionContextTest.class,
SSLSessionTest.class,
SSLSocketTest.class,
VeryBasicHttpServerTest.class,
X509KeyManagerTest.class,
})
Expand Down
Loading
Loading