Skip to content

Commit b7fd8fe

Browse files
Changes from gms conscrypt that should be integrated to the other repos (#1389)
* Changes from gms conscrypt that should be integrated to the other repos - Make getPreferred public - add result checking to OpenSSLx509certificateFactory - add reflection fallback for getApplicationProtocol Change-Id: I19549e706aa30b36fc01fc7a6e02e653dc96c5e9 * Changes from gms conscrypt that should be integrated to the other repos - Make getPreferred public - add result checking to OpenSSLx509certificateFactory - add reflection fallback for getApplicationProtocol Change-Id: I19549e706aa30b36fc01fc7a6e02e653dc96c5e9
1 parent 64049fc commit b7fd8fe

3 files changed

Lines changed: 145 additions & 59 deletions

File tree

common/src/main/java/org/conscrypt/Conscrypt.java

Lines changed: 110 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,19 @@
1515
*/
1616
package org.conscrypt;
1717

18+
import org.conscrypt.io.IoUtils;
19+
1820
import java.io.IOException;
1921
import java.io.InputStream;
22+
import java.lang.reflect.InvocationTargetException;
23+
import java.lang.reflect.Method;
2024
import java.nio.ByteBuffer;
2125
import java.security.KeyManagementException;
2226
import java.security.PrivateKey;
2327
import java.security.Provider;
2428
import java.security.cert.X509Certificate;
2529
import java.util.Properties;
30+
2631
import javax.net.ssl.HostnameVerifier;
2732
import javax.net.ssl.HttpsURLConnection;
2833
import javax.net.ssl.SSLContext;
@@ -37,7 +42,6 @@
3742
import javax.net.ssl.SSLSocketFactory;
3843
import javax.net.ssl.TrustManager;
3944
import javax.net.ssl.X509TrustManager;
40-
import org.conscrypt.io.IoUtils;
4145

4246
/**
4347
* Core API for creating and configuring all Conscrypt types.
@@ -80,9 +84,15 @@ private Version(int major, int minor, int patch) {
8084
this.patch = patch;
8185
}
8286

83-
public int major() { return major; }
84-
public int minor() { return minor; }
85-
public int patch() { return patch; }
87+
public int major() {
88+
return major;
89+
}
90+
public int minor() {
91+
return minor;
92+
}
93+
public int patch() {
94+
return patch;
95+
}
8696
}
8797

8898
private static final Version VERSION;
@@ -215,8 +225,8 @@ public ProviderBuilder isTlsV1Enabled(boolean enabledTlsV1) {
215225
}
216226

217227
public Provider build() {
218-
return new OpenSSLProvider(name, provideTrustManager,
219-
defaultTlsProtocol, deprecatedTlsV1, enabledTlsV1);
228+
return new OpenSSLProvider(
229+
name, provideTrustManager, defaultTlsProtocol, deprecatedTlsV1, enabledTlsV1);
220230
}
221231
}
222232

@@ -441,9 +451,23 @@ public static void setChannelIdPrivateKey(SSLSocket socket, PrivateKey privateKe
441451
*
442452
* @param socket the socket
443453
* @return the selected protocol or {@code null} if no protocol was agreed upon.
454+
* @throws IllegalArgumentException if the socket is not a Conscrypt socket.
444455
*/
445456
public static String getApplicationProtocol(SSLSocket socket) {
446-
return toConscrypt(socket).getApplicationProtocol();
457+
if (isConscrypt(socket)) {
458+
return toConscrypt(socket).getApplicationProtocol();
459+
}
460+
try {
461+
if (!Class.forName("com.android.org.conscrypt.AbstractConscryptSocket")
462+
.isInstance(socket)) {
463+
throw new IllegalArgumentException(
464+
"Not a conscrypt socket: " + socket.getClass().getName());
465+
}
466+
return invokeConscryptMethod(socket, "getApplicationProtocol");
467+
} catch (ClassNotFoundException e) {
468+
throw new IllegalArgumentException(
469+
"Not a conscrypt socket: " + socket.getClass().getName(), e);
470+
}
447471
}
448472

449473
/**
@@ -453,8 +477,8 @@ public static String getApplicationProtocol(SSLSocket socket) {
453477
* @param socket the socket
454478
* @param selector the ALPN protocol selector
455479
*/
456-
public static void setApplicationProtocolSelector(SSLSocket socket,
457-
ApplicationProtocolSelector selector) {
480+
public static void setApplicationProtocolSelector(
481+
SSLSocket socket, ApplicationProtocolSelector selector) {
458482
toConscrypt(socket).setApplicationProtocolSelector(selector);
459483
}
460484

@@ -504,8 +528,8 @@ public static byte[] getTlsUnique(SSLSocket socket) {
504528
* completed or the connection has been closed.
505529
* @throws SSLException if the value could not be exported.
506530
*/
507-
public static byte[] exportKeyingMaterial(SSLSocket socket, String label, byte[] context,
508-
int length) throws SSLException {
531+
public static byte[] exportKeyingMaterial(
532+
SSLSocket socket, String label, byte[] context, int length) throws SSLException {
509533
return toConscrypt(socket).exportKeyingMaterial(label, context, length);
510534
}
511535

@@ -711,8 +735,8 @@ public static String[] getApplicationProtocols(SSLEngine engine) {
711735
* @param engine the engine
712736
* @param selector the ALPN protocol selector
713737
*/
714-
public static void setApplicationProtocolSelector(SSLEngine engine,
715-
ApplicationProtocolSelector selector) {
738+
public static void setApplicationProtocolSelector(
739+
SSLEngine engine, ApplicationProtocolSelector selector) {
716740
toConscrypt(engine).setApplicationProtocolSelector(selector);
717741
}
718742

@@ -721,9 +745,23 @@ public static void setApplicationProtocolSelector(SSLEngine engine,
721745
*
722746
* @param engine the engine
723747
* @return the selected protocol or {@code null} if no protocol was agreed upon.
748+
* @throws IllegalArgumentException if the engine is not a Conscrypt engine.
724749
*/
725750
public static String getApplicationProtocol(SSLEngine engine) {
726-
return toConscrypt(engine).getApplicationProtocol();
751+
if (isConscrypt(engine)) {
752+
return toConscrypt(engine).getApplicationProtocol();
753+
}
754+
try {
755+
if (!Class.forName("com.android.org.conscrypt.AbstractConscryptEngine")
756+
.isInstance(engine)) {
757+
throw new IllegalArgumentException(
758+
"Not a conscrypt engine: " + engine.getClass().getName());
759+
}
760+
return invokeConscryptMethod(engine, "getApplicationProtocol");
761+
} catch (ClassNotFoundException e) {
762+
throw new IllegalArgumentException(
763+
"Not a conscrypt engine: " + engine.getClass().getName(), e);
764+
}
727765
}
728766

729767
/**
@@ -748,8 +786,8 @@ public static byte[] getTlsUnique(SSLEngine engine) {
748786
* completed or the connection has been closed.
749787
* @throws SSLException if the value could not be exported.
750788
*/
751-
public static byte[] exportKeyingMaterial(SSLEngine engine, String label, byte[] context,
752-
int length) throws SSLException {
789+
public static byte[] exportKeyingMaterial(
790+
SSLEngine engine, String label, byte[] context, int length) throws SSLException {
753791
return toConscrypt(engine).exportKeyingMaterial(label, context, length);
754792
}
755793

@@ -764,7 +802,7 @@ public static boolean isConscrypt(TrustManager trustManager) {
764802
private static TrustManagerImpl toConscrypt(TrustManager trustManager) {
765803
if (!isConscrypt(trustManager)) {
766804
throw new IllegalArgumentException(
767-
"Not a Conscrypt trust manager: " + trustManager.getClass().getName());
805+
"Not a Conscrypt trust manager: " + trustManager.getClass().getName());
768806
}
769807
return (TrustManagerImpl) trustManager;
770808
}
@@ -784,19 +822,22 @@ public synchronized static void setDefaultHostnameVerifier(ConscryptHostnameVeri
784822
*
785823
* @see #setDefaultHostnameVerifier(ConscryptHostnameVerifier)
786824
*/
787-
public synchronized static ConscryptHostnameVerifier getDefaultHostnameVerifier(TrustManager trustManager) {
825+
public synchronized static ConscryptHostnameVerifier getDefaultHostnameVerifier(
826+
TrustManager trustManager) {
788827
return TrustManagerImpl.getDefaultHostnameVerifier();
789828
}
790829

791830
/**
792831
* Set the hostname verifier that will be used for HTTPS endpoint identification by the
793832
* given trust manager. If {@code null} (the default), endpoint identification will use the
794-
* default hostname verifier set in {@link #setDefaultHostnameVerifier(ConscryptHostnameVerifier)}.
833+
* default hostname verifier set in {@link
834+
* #setDefaultHostnameVerifier(ConscryptHostnameVerifier)}.
795835
*
796836
* @throws IllegalArgumentException if the provided trust manager is not a Conscrypt trust
797837
* manager per {@link #isConscrypt(TrustManager)}
798838
*/
799-
public static void setHostnameVerifier(TrustManager trustManager, ConscryptHostnameVerifier verifier) {
839+
public static void setHostnameVerifier(
840+
TrustManager trustManager, ConscryptHostnameVerifier verifier) {
800841
toConscrypt(trustManager).setHostnameVerifier(verifier);
801842
}
802843

@@ -816,11 +857,58 @@ public static ConscryptHostnameVerifier getHostnameVerifier(TrustManager trustMa
816857
* Wraps the HttpsURLConnection.HostnameVerifier into a ConscryptHostnameVerifier
817858
*/
818859
public static ConscryptHostnameVerifier wrapHostnameVerifier(final HostnameVerifier verifier) {
819-
return new ConscryptHostnameVerifier() {
860+
return new ConscryptHostnameVerifier() {
820861
@Override
821-
public boolean verify(X509Certificate[] certificates, String hostname, SSLSession session) {
862+
public boolean verify(
863+
X509Certificate[] certificates, String hostname, SSLSession session) {
822864
return verifier.verify(hostname, session);
823865
}
824866
};
825867
}
868+
869+
/**
870+
* Generic helper method for invoking methods on potentially non-Conscrypt SSLSocket/SSLEngine
871+
* instances via reflection.
872+
*
873+
* @param instance The SSLSocket or SSLEngine instance.
874+
* @param methodName The name of the method to invoke.
875+
* @return String.
876+
* @throws IllegalArgumentException if the method cannot be invoked or throws a checked
877+
* exception.
878+
* @throws IllegalStateException if the method throws an IllegalStateException.
879+
* @throws RuntimeException if the method throws a RuntimeException.
880+
* @throws Error if the method throws an Error.
881+
*/
882+
private static String invokeConscryptMethod(Object instance, String methodName)
883+
throws IllegalArgumentException {
884+
try {
885+
Method method = instance.getClass().getMethod(methodName);
886+
Object result = method.invoke(instance);
887+
return (String) result;
888+
} catch (InvocationTargetException e) {
889+
Throwable cause = e.getCause();
890+
if (cause instanceof SSLException || cause instanceof IOException) {
891+
IllegalArgumentException wrapped = new IllegalArgumentException(
892+
"Reflected method '" + methodName + "' threw a checked exception.", cause);
893+
throw wrapped;
894+
} else if (cause instanceof IllegalStateException) {
895+
throw (IllegalStateException) cause;
896+
} else if (cause instanceof RuntimeException) {
897+
throw (RuntimeException) cause;
898+
} else if (cause instanceof Error) {
899+
throw (Error) cause;
900+
} else {
901+
throw new RuntimeException(
902+
"Reflected method '" + methodName + "' threw an unexpected exception",
903+
cause);
904+
}
905+
} catch (Exception e) {
906+
String className = instance.getClass().getName();
907+
IllegalArgumentException wrapped = new IllegalArgumentException(
908+
"Failed reflection fallback for method '" + methodName + "' on class '"
909+
+ className + ", message: " + e.getMessage(),
910+
e);
911+
throw wrapped;
912+
}
913+
}
826914
}

common/src/main/java/org/conscrypt/OpenSSLContextImpl.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.security.GeneralSecurityException;
2323
import java.security.KeyManagementException;
2424
import java.security.SecureRandom;
25+
2526
import javax.net.ssl.KeyManager;
2627
import javax.net.ssl.SSLContextSpi;
2728
import javax.net.ssl.SSLEngine;
@@ -56,7 +57,7 @@ public abstract class OpenSSLContextImpl extends SSLContextSpi {
5657
SSLParametersImpl sslParameters;
5758

5859
/** Allows outside callers to get the preferred SSLContext. */
59-
static OpenSSLContextImpl getPreferred() {
60+
public static OpenSSLContextImpl getPreferred() {
6061
return new TLSv13();
6162
}
6263

@@ -85,9 +86,11 @@ static OpenSSLContextImpl getPreferred() {
8586
defaultSslContextImpl = (DefaultSSLContextImpl) this;
8687
} else {
8788
clientSessionContext =
88-
(ClientSessionContext) defaultSslContextImpl.engineGetClientSessionContext();
89+
(ClientSessionContext)
90+
defaultSslContextImpl.engineGetClientSessionContext();
8991
serverSessionContext =
90-
(ServerSessionContext) defaultSslContextImpl.engineGetServerSessionContext();
92+
(ServerSessionContext)
93+
defaultSslContextImpl.engineGetServerSessionContext();
9194
}
9295
sslParameters = new SSLParametersImpl(defaultSslContextImpl.getKeyManagers(),
9396
defaultSslContextImpl.getTrustManagers(), null, clientSessionContext,

common/src/main/java/org/conscrypt/OpenSSLX509CertificateFactory.java

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,7 @@
3939
@Internal
4040
public class OpenSSLX509CertificateFactory extends CertificateFactorySpi {
4141
private static final byte[] PKCS7_MARKER = new byte[] {
42-
'-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' ', 'P', 'K', 'C', 'S', '7'
43-
};
42+
'-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' ', 'P', 'K', 'C', 'S', '7'};
4443
private static final byte[] PEM_MARKER =
4544
new byte[] {'-', '-', '-', '-', '-', 'B', 'E', 'G', 'I', 'N', ' '};
4645
private static final int DASH = 45; // Value of '-'
@@ -152,7 +151,7 @@ T generateItem(InputStream inStream) throws ParsingException {
152151
if (Arrays.equals(buffer, PEM_MARKER)) {
153152
return fromX509PemInputStream(pbis);
154153
}
155-
pbis.read();
154+
int unused = pbis.read();
156155
}
157156
}
158157
throw new ParsingException("No certificate found");
@@ -168,8 +167,7 @@ T generateItem(InputStream inStream) throws ParsingException {
168167
}
169168
}
170169

171-
Collection<? extends T> generateItems(InputStream inStream)
172-
throws ParsingException {
170+
Collection<? extends T> generateItems(InputStream inStream) throws ParsingException {
173171
if (inStream == null) {
174172
throw new ParsingException("inStream == null");
175173
}
@@ -274,44 +272,41 @@ public OpenSSLX509Certificate fromX509DerInputStream(InputStream is)
274272
}
275273

276274
@Override
277-
public List<? extends OpenSSLX509Certificate>
278-
fromPkcs7PemInputStream(InputStream is) throws ParsingException {
275+
public List<? extends OpenSSLX509Certificate> fromPkcs7PemInputStream(
276+
InputStream is) throws ParsingException {
279277
return OpenSSLX509Certificate.fromPkcs7PemInputStream(is);
280278
}
281279

282280
@Override
283-
public List<? extends OpenSSLX509Certificate>
284-
fromPkcs7DerInputStream(InputStream is) throws ParsingException {
281+
public List<? extends OpenSSLX509Certificate> fromPkcs7DerInputStream(
282+
InputStream is) throws ParsingException {
285283
return OpenSSLX509Certificate.fromPkcs7DerInputStream(is);
286284
}
287285
};
288286

289-
private Parser<OpenSSLX509CRL> crlParser =
290-
new Parser<OpenSSLX509CRL>() {
291-
@Override
292-
public OpenSSLX509CRL fromX509PemInputStream(InputStream is)
293-
throws ParsingException {
294-
return OpenSSLX509CRL.fromX509PemInputStream(is);
295-
}
287+
private Parser<OpenSSLX509CRL> crlParser = new Parser<OpenSSLX509CRL>() {
288+
@Override
289+
public OpenSSLX509CRL fromX509PemInputStream(InputStream is) throws ParsingException {
290+
return OpenSSLX509CRL.fromX509PemInputStream(is);
291+
}
296292

297-
@Override
298-
public OpenSSLX509CRL fromX509DerInputStream(InputStream is)
299-
throws ParsingException {
300-
return OpenSSLX509CRL.fromX509DerInputStream(is);
301-
}
293+
@Override
294+
public OpenSSLX509CRL fromX509DerInputStream(InputStream is) throws ParsingException {
295+
return OpenSSLX509CRL.fromX509DerInputStream(is);
296+
}
302297

303-
@Override
304-
public List<? extends OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
305-
throws ParsingException {
306-
return OpenSSLX509CRL.fromPkcs7PemInputStream(is);
307-
}
298+
@Override
299+
public List<? extends OpenSSLX509CRL> fromPkcs7PemInputStream(InputStream is)
300+
throws ParsingException {
301+
return OpenSSLX509CRL.fromPkcs7PemInputStream(is);
302+
}
308303

309-
@Override
310-
public List<? extends OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
311-
throws ParsingException {
312-
return OpenSSLX509CRL.fromPkcs7DerInputStream(is);
313-
}
314-
};
304+
@Override
305+
public List<? extends OpenSSLX509CRL> fromPkcs7DerInputStream(InputStream is)
306+
throws ParsingException {
307+
return OpenSSLX509CRL.fromPkcs7DerInputStream(is);
308+
}
309+
};
315310

316311
public OpenSSLX509CertificateFactory() {}
317312

@@ -325,8 +320,8 @@ public Certificate engineGenerateCertificate(InputStream inStream) throws Certif
325320
}
326321

327322
@Override
328-
public Collection<? extends Certificate> engineGenerateCertificates(
329-
InputStream inStream) throws CertificateException {
323+
public Collection<? extends Certificate> engineGenerateCertificates(InputStream inStream)
324+
throws CertificateException {
330325
try {
331326
return certificateParser.generateItems(inStream);
332327
} catch (ParsingException e) {

0 commit comments

Comments
 (0)