react-native-tcp-socket icon indicating copy to clipboard operation
react-native-tcp-socket copied to clipboard

Open to Pull Request to access a server using a self-signed certificate.

Open vricosti opened this issue 1 year ago • 3 comments

I was not able to use your library to connect to a server using a self-signed certificate (see my issue report here).

On node it's as a simple as writing this:

let options = {
                port: this.port,
                host: this.host,
                key: this.certs.key,
                cert: this.certs.cert,
                rejectUnauthorized: false
            };
this.client = tls.connect(options, () => {
                    console.debug(this.host + " Pairing connected");
});

But with TcpSockets.connectTLS it never worked so am I missing something ?

To make it work I had to pass ca and cakey:

let options = {
                port: this.port,
                host : this.host,
                rejectUnauthorized: true,
                ca: require('../../../../client-selfsigned.crt'),
                caKey: require('../../../../client-selfsigned.key'),
            };
            
            this.client = TcpSockets.connectTLS(options, () => {
                console.debug(this.host + " Pairing connected");
            });

And then modified to store ca AND caKey inside keyStore:

KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null, null);
keyStore.setKeyEntry("my-key-atv", privateKey, null, new Certificate[]{ca});
keyStore.setCertificateEntry("my-key-atv-atv-cert", ca);

and as you can see I hardcoded my key alias inside the store because there is not option to pass the key alias

So was it necessary to hack the code or is there any trick to make it work and if not are you open to discuss an implementation because I would like to avoid to use a forked library. What would be possible is either keep the node:tls syntax and when key and cert is available inside options to store them inside keystore and use the ClientTrustManager class but I also need to specify the keystore name, the key/cert alias because in my app I generate the certificate if it's not already available. So basically it would implement the following options:

let options = {
   port: this.port,
   host : this.host,
   rejectUnauthorized: true,
   // new options (compatible with node:tls)
   key: this.certs.key,
   cert: this.certs.cert,
   // new options (specific to android/ios?)
   keyStoreName: 'AndroidKeyStore',
   keyAlias: 'my-key-atv',
   certAlias: 'my-key-atv-cert',
};

What do you think ?

vricosti avatar May 21 '24 14:05 vricosti

https://github.com/Rapsssito/react-native-tcp-socket/compare/master...vricosti:react-native-tcp-socket:dev/more-node-tls-compliant

vricosti avatar May 23 '24 17:05 vricosti

Try to put the option legacy when you are going to generate the PKC12 certifacte of server. example:

openssl pkcs12 -export -out cert.p12
-inkey priv.pem -in cert.pem
-legacy
-keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-RC2-40 -passout pass:

Where priv.pem is the private key, cert.pem is the certificate. Thats worked for me, looks like the library only works with old cipher algorithms

ManuelLatorre98 avatar May 23 '24 18:05 ManuelLatorre98

I don't manager the server ... I am talking to server running on a device (android tv) with a self signed cert

vricosti avatar May 23 '24 18:05 vricosti

Should be fixed by #208

Rapsssito avatar Apr 23 '25 21:04 Rapsssito