Skip to content

Commit 1b3f9a3

Browse files
author
Xudong Ma
committed
Add an option to Android interop test, to configure TLS protocol on SSLCertificateSocketFactory directly.
This is how our current internal users configure the TLS protocol, with this option, we can test and verify future changes will not break internal users.
1 parent 74b5d29 commit 1b3f9a3

3 files changed

Lines changed: 50 additions & 6 deletions

File tree

android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTester.java

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import com.google.protobuf.nano.MessageNano;
3535

36+
import android.net.SSLCertificateSocketFactory;
3637
import android.os.AsyncTask;
3738
import android.support.annotation.Nullable;
3839
import android.util.Log;
@@ -47,6 +48,7 @@
4748
import java.io.InputStream;
4849
import java.io.PrintWriter;
4950
import java.io.StringWriter;
51+
import java.lang.reflect.Method;
5052
import java.security.KeyStore;
5153
import java.security.cert.CertificateFactory;
5254
import java.security.cert.X509Certificate;
@@ -79,6 +81,7 @@ public InteropTester(String testCase,
7981
@Nullable String serverHostOverride,
8082
boolean useTls,
8183
@Nullable InputStream testCa,
84+
@Nullable String androidSocketFactoryTls,
8285
TestListener listener) {
8386
this.testCase = testCase;
8487
this.listener = listener;
@@ -90,7 +93,13 @@ public InteropTester(String testCase,
9093
}
9194
if (useTls) {
9295
try {
93-
channelBuilder.sslSocketFactory(getSslSocketFactory(testCa));
96+
SSLSocketFactory factory;
97+
if (androidSocketFactoryTls != null) {
98+
factory = getSslCertificateSocketFactory(testCa, androidSocketFactoryTls);
99+
} else {
100+
factory = getSslSocketFactory(testCa);
101+
}
102+
channelBuilder.sslSocketFactory(factory);
94103
} catch (Exception e) {
95104
throw new RuntimeException(e);
96105
}
@@ -327,6 +336,39 @@ private SSLSocketFactory getSslSocketFactory(@Nullable InputStream testCa) throw
327336
if (testCa == null) {
328337
return (SSLSocketFactory) SSLSocketFactory.getDefault();
329338
}
339+
340+
SSLContext context = SSLContext.getInstance("TLS");
341+
context.init(null, getTrustManagers(testCa) , null);
342+
return context.getSocketFactory();
343+
}
344+
345+
private SSLCertificateSocketFactory getSslCertificateSocketFactory(
346+
@Nullable InputStream testCa, String androidSocketFatoryTls) throws Exception {
347+
SSLCertificateSocketFactory factory = (SSLCertificateSocketFactory)
348+
SSLCertificateSocketFactory.getDefault(5000 /* Timeout in ms*/);
349+
// Use HTTP/2.0
350+
byte[] h2 = "h2".getBytes();
351+
byte[][] protocols = new byte[][]{h2};
352+
if (androidSocketFatoryTls.equals("alpn")) {
353+
Method setAlpnProtocols =
354+
factory.getClass().getDeclaredMethod("setAlpnProtocols", byte[][].class);
355+
setAlpnProtocols.invoke(factory, new Object[] { protocols });
356+
} else if (androidSocketFatoryTls.equals("npn")) {
357+
Method setNpnProtocols =
358+
factory.getClass().getDeclaredMethod("setNpnProtocols", byte[][].class);
359+
setNpnProtocols.invoke(factory, new Object[]{protocols});
360+
} else {
361+
throw new RuntimeException("Unknown protocol: " + androidSocketFatoryTls);
362+
}
363+
364+
if (testCa != null) {
365+
factory.setTrustManagers(getTrustManagers(testCa));
366+
}
367+
368+
return factory;
369+
}
370+
371+
private TrustManager[] getTrustManagers(InputStream testCa) throws Exception {
330372
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
331373
ks.load(null);
332374
CertificateFactory cf = CertificateFactory.getInstance("X.509");
@@ -337,9 +379,7 @@ private SSLSocketFactory getSslSocketFactory(@Nullable InputStream testCa) throw
337379
TrustManagerFactory trustManagerFactory =
338380
TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
339381
trustManagerFactory.init(ks);
340-
SSLContext context = SSLContext.getInstance("TLS");
341-
context.init(null, trustManagerFactory.getTrustManagers() , null);
342-
return context.getSocketFactory();
382+
return trustManagerFactory.getTrustManagers();
343383
}
344384

345385
public interface TestListener {

android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ private void startTest(String testCase) {
112112

113113
// TODO (madongfly) support server_host_override, useTls and useTestCa in the App UI.
114114
new InteropTester(testCase, host, port, "foo.test.google.fr", true,
115-
getResources().openRawResource(R.raw.ca),
115+
getResources().openRawResource(R.raw.ca), null,
116116
new InteropTester.TestListener() {
117117
@Override public void onPreTest() {
118118
resultText.setText("Testing...");

android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterInstrumentation.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public class TesterInstrumentation extends Instrumentation {
5252
private String serverHostOverride;
5353
private boolean useTls;
5454
private boolean useTestCa;
55+
private String androidSocketFactoryTls;
5556

5657
@Override
5758
public void onCreate(Bundle args) {
@@ -63,6 +64,7 @@ public void onCreate(Bundle args) {
6364
serverHostOverride = args.getString("server_host_override", null);
6465
useTls = Boolean.parseBoolean(args.getString("use_tls", "true"));
6566
useTestCa = Boolean.parseBoolean(args.getString("use_test_ca", "false"));
67+
androidSocketFactoryTls = args.getString("android_socket_factory_tls", null);
6668

6769
InputStream testCa = null;
6870
if (useTestCa) {
@@ -84,6 +86,7 @@ public void onCreate(Bundle args) {
8486
}
8587

8688
new InteropTester(testCase, host, port, serverHostOverride, useTls, testCa,
89+
androidSocketFactoryTls,
8790
new InteropTester.TestListener() {
8891
@Override
8992
public void onPreTest() {
@@ -99,6 +102,7 @@ public void onPostTest(String result) {
99102
finish(1, bundle);
100103
}
101104
}
102-
}).execute();
105+
}
106+
).execute();
103107
}
104108
}

0 commit comments

Comments
 (0)