SSl hand-shaking getting failed on enterprise Android but working good with ordinary devices
Asked Answered
P

0

2

I am facing the issue in making SSL connection with the enterprise devices. When I run my application on normal android devices the SSL hand-shaking get successful. I don't know why this is happening the code should work with both the devices.

Here is my code for choosing a certificate and extracting alias private and certificate chain :

public void userAliasCertificateSelection() {
        boolean isGranted = appPreferences.getPrefrenceBoolean("mycertificate");
        if (!isGranted) {
            //Get cert and private key from internal android store
            KeyChain.choosePrivateKeyAlias(this, new KeyChainAliasCallback() {
                @Override
                public void alias(@Nullable String s) {
                    appPreferences.setPrefrenceString("CertificateAlias",s);
                    appPreferences.setPrefrenceBoolean("mycertificate", true);
                    asyncTask.execute();
                }
            }, new String[]{KeyProperties.KEY_ALGORITHM_RSA}, null, null, -1, null);
        } else {

            asyncTask.execute();
        }
    }
    @SuppressLint("StaticFieldLeak")
    AsyncTask<Void, Void, Boolean> asyncTask = new AsyncTask<Void, Void, Boolean>() {

        private Exception error;

        @Override
        protected Boolean doInBackground(Void... arg) {
            try {

                PrivateKey pk = KeyChain.getPrivateKey(DiallerViewActivity.this, appPreferences.getPrefrenceString("CertificateAlias"));
                X509Certificate[] chain = KeyChain.getCertificateChain(DiallerViewActivity.this, appPreferences.getPrefrenceString("CertificateAlias"));

                byte[] data = "foobar".getBytes("ASCII");
                Signature sig = Signature.getInstance("SHA1withRSA");
                sig.initSign(pk);
                sig.update(data);
                byte[] signed = sig.sign();

                PublicKey pubk = chain[0].getPublicKey();
                sig.initVerify(pubk);
                sig.update(data);
                boolean valid = sig.verify(signed);
                Log.d(TAG, "signature is valid: " + valid);

                if(valid) {
                    mPrivateKey = pk;
                    mCertificates = chain;
                }

                return valid;
            } catch (Exception e) {
                e.printStackTrace();
                error = e;

                return null;
            }
        }

        @Override
        protected void onPostExecute(Boolean valid) {
            if (error != null) {
                return;
            }else{
                connect(appPreferences.getPrefrenceString("CertificateAlias"));
            }
        }
    };

Now Binding it with OkHttpClient :

private void connect(String mAlias){
        String alias = mAlias;


        KeyStore trustStore = null;
        try {
            trustStore = KeyStore.getInstance(KeyStore
                    .getDefaultType());
        } catch (KeyStoreException e) {
            e.printStackTrace();
        }


        X509ExtendedKeyManager keyManager = new X509ExtendedKeyManager() {

            @Override
            public String chooseClientAlias(String[] strings, Principal[] principals, Socket socket) {
                return alias;
            }

            @Override
            public String chooseServerAlias(String s, Principal[] principals, Socket socket) {
                return alias;
            }

            @Override
            public X509Certificate[] getCertificateChain(String s) {
                return mCertificates;
            }

            @Override
            public String[] getClientAliases(String s, Principal[] principals) {
                return new String[]{alias};
            }

            @Override
            public String[] getServerAliases(String s, Principal[] principals) {
                return new String[]{alias};
            }

            @Override
            public PrivateKey getPrivateKey(String s) {
                return mPrivateKey;
            }
        };

        TrustManagerFactory trustFactory = null;
        try {
            trustFactory = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustFactory.init(trustStore);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        catch (KeyStoreException e) {
            e.printStackTrace();
        }

        TrustManager[] trustManagers = trustFactory.getTrustManagers();

        X509TrustManager[] tm = new X509TrustManager[] { new X509TrustManager() {

            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }



            public X509Certificate[] getAcceptedIssuers() {
                return mCertificates;
            }



        } };
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(new KeyManager[] {keyManager}, tm, null);
            SSLContext.setDefault(sslContext);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        okClient = new OkHttpClient.Builder()
                .sslSocketFactory(sslContext.getSocketFactory())
                .build();
    }

This code is working fine with ordinary devices but not with Enterprise Devices.

Please let me know if I need to do something for Enterprise Devices.

Regards

Peterus answered 2/8, 2018 at 11:53 Comment(2)
Has this issue been solved somehow because I am facing the same problemGregorygregrory
Has this issue been solved?Clericals

© 2022 - 2024 — McMap. All rights reserved.