TLS from android client to python server

0

Im using grpc for java android, im usuing mutual ssl (tls), my server generated 2 certificates for me (server.ca and client.ca) and a private key (key.key), i changed the key from how i got it(basic key encryption to PKCS8) from

-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----

to:

   -----END PRIVATE KEY-----

and used this code to generated my sslcontext with okhttp with grpc.

    private static byte[] getBytesFromInputStream(InputStream is) throws IOException {
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            byte[] buffer = new byte[0xFFFF];
            for (int len = is.read(buffer); len != -1; len = is.read(buffer)) {
                os.write(buffer, 0, len);
            }
            return os.toByteArray();
        }

        // build a key store from a set of raw certificates
        private static KeyStore createKeyStore(Resources resources, int certsId, boolean ca) {
            KeyStore ks = null;
            try {
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                if (ca) {
                    ks = KeyStore.getInstance(KeyStore.getDefaultType());
                    ks.load(null, null);
                    InputStream certIS = resources.openRawResource(R.raw.server);
                    X509Certificate cert = (X509Certificate) cf.generateCertificate(certIS);
                    ks.setCertificateEntry("ca", cert);
                } else {
                    ks = KeyStore.getInstance("AndroidKeyStore");
                    ks.load(null, null);
                    InputStream certIS = resources.openRawResource(R.raw.client);
                    Certificate cert = cf.generateCertificate(certIS);
                    InputStream privateKeyIS = resources.openRawResource(R.raw.key);
                    byte[] privateKeyBytes = getBytesFromInputStream(privateKeyIS);
                    KeyFactory kf = KeyFactory.getInstance("RSA");
                    PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(privateKeyBytes)));
                    Certificate[] certChain = new Certificate[1];
                    certChain[0] = cert;
                    ks.setKeyEntry("client", privateKey, null, certChain);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return ks;
        }

        public static ManagedChannel build(String host, int port, Resources resources,
                                           @Nullable String serverHostOverride) {
            KeyStore ca = createKeyStore(resources, R.array.certs, true);
            KeyStore client = createKeyStore(resources, R.array.certs, false);
            OkHttpChannelBuilder channelBuilder =
                    OkHttpChannelBuilder.forAddress(host, port);
            if (serverHostOverride != null) {
                // Force the hostname to match the cert the server uses.
                channelBuilder.overrideAuthority(serverHostOverride);
            }
            try {
                channelBuilder.negotiationType(io.grpc.okhttp.NegotiationType.TLS);
                channelBuilder.useTransportSecurity();
                channelBuilder.sslSocketFactory(getSslSocketFactory(ca, client));
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
            return channelBuilder.build();
        }

        private static SSLSocketFactory getSslSocketFactory(KeyStore ca, KeyStore client)
                throws Exception {
            KeyManagerFactory kmf =
                    KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            String password = "";
            kmf.init(client, password.toCharArray());

            // initialize trust manager factor from certs keystore
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            tmf.init(ca);

            // initialize SSL context from trust manager factory
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

            // return socket factory from the SSL context
            return context.getSocketFactory();
        }

    public void connectGrpc() throws Exception {
            ManagedChannel c = build("MyPc", 5051, this.getResources(), null);
            TabletServiceGrpc.TabletServiceBlockingStub bs = TabletServiceGrpc.newBlockingStub(c);
            GetName g= GetName.newBuilder().setField(1).build();
            GetNameResponse res=bs.getNameByField(g);
            Log.e(TAG,res.getCategoryName());

    }

and im getting the following errors:


    Read error: ssl=0x7890e89c88: Failure in SSL library, usually a protocol error
        error:100000d7:SSL routines:OPENSSL_internal:SSL_HANDSHAKE_FAILURE 
    (third_party/openssl/boringssl/src/ssl/ssl_lib.cc:1017 0x787007e1bb:0x00000000)

io.grpc.StatusRuntimeException: UNAVAILABLE: End of stream or IOException

Is there a problem with me converting my key from PKCS#1 to PKCS#8 ? Or is there something else? I tried changing my code according to the android docs, but it matched it, and should work.

java
android
security
ssl
grpc
asked on Stack Overflow Nov 17, 2019 by thenewguyhere

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0