Are you sure negotiation completed from the Android client POV? Since the
android code uses OkHTTP framing and a thread per connection, you should be
able to see where it is hung up by getting a stack trace.
On Monday, March 19, 2018 at 3:53:16 AM UTC-7, yz wrote:
>
> I am trying to make gRPC over TLS working on Android using a self-signed
> cert. The code is as following:
>
> InputStream testCA = new ByteArrayInputStream(CA.getBytes("UTF8"));
>> mChannel = ZnzGrpcChannelBuilder.build(mHost, mPort, null, true, testCA,
>> "alpn");
>> GRPCDummyServerGrpc.GRPCDummyServerBlockingStub stub =
>> GRPCDummyServerGrpc.newBlockingStub(mChannel);
>> SumRequest sumRequest = SumRequest.newBuilder().setStart(start).setCount(
>> 20).build();
>> SumResponse sumResponse = stub.sum(sumRequest);
>
>
>
> ZnzGrpcChannelBuilder is a customized channel builder to enable self-signed
> cert. As can be seen from Wireshark, the TLS negotiation has completed and
> the server starts
>
> to send SETTINGS to the Android client. But the client did not send any
> SETTINGS frames.
>
> What I am missing here? Thank you very much.
>
>
> public class ZnzGrpcChannelBuilder {
> public static ManagedChannel build(String host, int port, @Nullable String
> serverHostOverride,
> boolean useTls, @Nullable InputStream testCa, @Nullable String
> androidSocketFactoryTls) {
> ManagedChannelBuilder<?> channelBuilder =
> ManagedChannelBuilder.forAddress(host,
> port);
> if (serverHostOverride != null) {
> // Force the hostname to match the cert the server uses.
> channelBuilder.overrideAuthority(serverHostOverride);
> }
> if (useTls) {
> try {
> SSLSocketFactory factory;
> if (androidSocketFactoryTls != null) {
> factory = getSslCertificateSocketFactory(testCa, androidSocketFactoryTls);
> } else {
> factory = getSslSocketFactory(testCa);
> }
> ((OkHttpChannelBuilder) channelBuilder).negotiationType(NegotiationType.
> TLS);
> ((OkHttpChannelBuilder) channelBuilder).sslSocketFactory(factory);
> } catch (Exception e) {
> throw new RuntimeException(e);
> }
> } else {
> channelBuilder.usePlaintext(true);
> }
> return channelBuilder.build();
> }
> private static SSLSocketFactory getSslSocketFactory(@Nullable InputStream
> testCa)
> throws Exception {
> if (testCa == null) {
> return (SSLSocketFactory) SSLSocketFactory.getDefault();
> }
> SSLContext context = SSLContext.getInstance("TLS");
> context.init(null, getTrustManagers(testCa), null);
> return context.getSocketFactory();
> }
> @TargetApi(14)
> private static SSLCertificateSocketFactory getSslCertificateSocketFactory(
> @Nullable InputStream testCa, String androidSocketFatoryTls) throws Exception
> {
> if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH /* API
> level 14 */) {
> throw new RuntimeException(
> "android_socket_factory_tls doesn't work with API level less than 14.");
> }
> SSLCertificateSocketFactory factory = (SSLCertificateSocketFactory)
> SSLCertificateSocketFactory.getDefault(5000 /* Timeout in ms*/);
> // Use HTTP/2.0
> byte[] h2 = "h2".getBytes();
> byte[][] protocols = new byte[][]{h2};
> if (androidSocketFatoryTls.equals("alpn")) {
> Method setAlpnProtocols =
> factory.getClass().getDeclaredMethod("setAlpnProtocols", byte[][].class);
> setAlpnProtocols.invoke(factory, new Object[]{protocols});
> } else if (androidSocketFatoryTls.equals("npn")) {
> Method setNpnProtocols =
> factory.getClass().getDeclaredMethod("setNpnProtocols", byte[][].class);
> setNpnProtocols.invoke(factory, new Object[]{protocols});
> } else {
> throw new RuntimeException("Unknown protocol: " + androidSocketFatoryTls);
> }
> if (testCa != null) {
> factory.setTrustManagers(getTrustManagers(testCa));
> }
> return factory;
> }
> private static TrustManager[] getTrustManagers(InputStream testCa) throws
> Exception
> {
> KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
> ks.load(null);
> CertificateFactory cf = CertificateFactory.getInstance("X.509");
> X509Certificate cert = (X509Certificate) cf.generateCertificate(testCa);
> X500Principal principal = cert.getSubjectX500Principal();
> ks.setCertificateEntry(principal.getName("RFC2253"), cert);
> // Set up trust manager factory to use our key store.
> TrustManagerFactory trustManagerFactory =
> TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm
> ());
> trustManagerFactory.init(ks);
> return trustManagerFactory.getTrustManagers();
> }
> }
>
>
--
You received this message because you are subscribed to the Google Groups
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit
https://groups.google.com/d/msgid/grpc-io/68ae9c07-ffef-4f8b-bfee-854a0e690639%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.