From 20cce329ccfac11960863b88f501430b04dbbfeb Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Mon, 6 Apr 2020 18:39:34 +0200 Subject: [PATCH 01/17] Initial SSL socket on android --- README.md | 1 + .../react/tcpsocket/TcpSocketClient.java | 20 +++++++++++++++---- examples/tcpsockets/package.json | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bf570e2..c999ff2 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,7 @@ server.on('close', () => { | `localAddress` | `` | ✅ | ✅ | Local address the socket should connect from. If not specified, the OS will decide. It is **highly recommended** to specify a `localAddress` to prevent overload errors and improve performance. | | `localPort` | `` | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. | | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | +| `tls`| `` | ❌ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | **Note**: The platforms marked as ❌ use the default value. diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java index 4db6067..7d12282 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java @@ -12,6 +12,9 @@ import java.net.InetSocketAddress; import java.net.Socket; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -44,7 +47,14 @@ public Socket getSocket() { public void connect(@NonNull final String address, @NonNull final Integer port, @NonNull final ReadableMap options, @Nullable final Network network) throws IOException { if (socket != null) throw new IOException("Already connected"); - socket = new Socket(); + final boolean isTls = options.hasKey("tls") && options.getBoolean("tls"); + if (isTls) { + final SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); + sslSocket.setUseClientMode(true); + socket = sslSocket; + } else { + socket = new Socket(); + } // Get the addresses final String localAddress = options.hasKey("localAddress") ? options.getString("localAddress") : "0.0.0.0"; final InetAddress localInetAddress = InetAddress.getByName(localAddress); @@ -63,6 +73,7 @@ public void connect(@NonNull final String address, @NonNull final Integer port, // bind socket.bind(new InetSocketAddress(localInetAddress, localPort)); socket.connect(new InetSocketAddress(remoteInetAddress, port)); + if (isTls) ((SSLSocket) socket).startHandshake(); startListening(); } @@ -77,10 +88,11 @@ public void startListening() { * @param data data to be sent */ public void write(final byte[] data) throws IOException { - if (socket != null && !socket.isClosed()) { - OutputStream output = socket.getOutputStream(); - output.write(data); + if (socket == null) { + throw new IOException("Socket is not connected."); } + OutputStream output = socket.getOutputStream(); + output.write(data); } /** diff --git a/examples/tcpsockets/package.json b/examples/tcpsockets/package.json index 416fb7f..4726048 100644 --- a/examples/tcpsockets/package.json +++ b/examples/tcpsockets/package.json @@ -14,7 +14,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.1", - "react-native-tcp-socket": "^3.4.1" + "react-native-tcp-socket": "^3.4.2" }, "devDependencies": { "@babel/core": "^7.7.2", From 508ecb4ae73e7c605e361ec547c39edfc7972aa3 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 13:35:33 +0200 Subject: [PATCH 02/17] Fix example set-up --- examples/tcpsockets/.gitignore | 3 +++ .../java/com/tcpsockets/ReactNativeFlipper.java | 0 examples/tcpsockets/metro.config.js | 5 +++++ 3 files changed, 8 insertions(+) rename examples/tcpsockets/android/app/src/{main => debug}/java/com/tcpsockets/ReactNativeFlipper.java (100%) diff --git a/examples/tcpsockets/.gitignore b/examples/tcpsockets/.gitignore index 57331d6..ea0571e 100644 --- a/examples/tcpsockets/.gitignore +++ b/examples/tcpsockets/.gitignore @@ -59,3 +59,6 @@ buck-out/ # CocoaPods /ios/Pods/ + +# TLS Cert +*.pem \ No newline at end of file diff --git a/examples/tcpsockets/android/app/src/main/java/com/tcpsockets/ReactNativeFlipper.java b/examples/tcpsockets/android/app/src/debug/java/com/tcpsockets/ReactNativeFlipper.java similarity index 100% rename from examples/tcpsockets/android/app/src/main/java/com/tcpsockets/ReactNativeFlipper.java rename to examples/tcpsockets/android/app/src/debug/java/com/tcpsockets/ReactNativeFlipper.java diff --git a/examples/tcpsockets/metro.config.js b/examples/tcpsockets/metro.config.js index 13a9642..46be6e2 100644 --- a/examples/tcpsockets/metro.config.js +++ b/examples/tcpsockets/metro.config.js @@ -4,8 +4,13 @@ * * @format */ +const {getDefaultConfig} = require('metro-config'); +const defaultConfig = getDefaultConfig.getDefaultValues(__dirname); module.exports = { + resolver: { + assetExts: [...defaultConfig.resolver.assetExts, 'pem'], + }, transformer: { getTransformOptions: async () => ({ transform: { From 20fb4b6131f650b9bb30452b168194da5e142fc2 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 15:05:31 +0200 Subject: [PATCH 03/17] Self-Signed certificates --- .eslintrc.json | 2 +- README.md | 39 +++++++++-- .../react/tcpsocket/SSLCertificateHelper.java | 67 +++++++++++++++++++ .../react/tcpsocket/TcpSocketClient.java | 9 ++- .../react/tcpsocket/TcpSocketModule.java | 4 +- .../android/app/src/main/AndroidManifest.xml | 1 - src/TcpSocket.js | 41 +++++++++--- 7 files changed, 140 insertions(+), 23 deletions(-) create mode 100644 android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java diff --git a/.eslintrc.json b/.eslintrc.json index 54b3bec..3faa9d8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -23,7 +23,7 @@ "ignoreReadBeforeAssign": false } ], - "curly": ["error", "multi", "consistent"], + "curly": ["error", "multi-line", "consistent"], "no-var": "error", "prefer-template": 2, "require-atomic-updates": "off", diff --git a/README.md b/README.md index c999ff2..5a88ac5 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![](https://github.com/Rapsssito/react-native-tcp-socket/workflows/tests/badge.svg) -React Native TCP socket API for Android & iOS. It allows you to create TCP clients and servers sockets, simulating node's [net](https://nodejs.org/api/net.html) API. +React Native TCP socket API for Android & iOS with SSL/TLS support. It allows you to create TCP clients and servers sockets, simulating node's [net](https://nodejs.org/api/net.html) API. ## Table of Contents @@ -48,11 +48,23 @@ Linking the package manually is not required anymore with [Autolinking](https:// } ``` - Modify your **`android/app/src/main/AndroidManifest.xml`** and add the following: - ``` - - ``` - +#### Self-Signed SSL (only available for React Native > 0.60) +You will need a [metro.config.js](https://facebook.github.io/metro/docs/en/configuration.html) file in order to use a self-signed SSL certificate library. You should already have this file in your root project directory, but if you don't, create it. +Inside a `module.exports` object, create a key called `resolver` with another object called `assetExts`. The value of `assetExts` should be an array of the resource file extensions you want to support. + +For example, if you want to support `.pem` files (plus all the already supported files), your `metro.config.js` would like like this: +```javascript +const {getDefaultConfig} = require('metro-config'); +const defaultConfig = getDefaultConfig.getDefaultValues(__dirname); + +module.exports = { + resolver: { + assetExts: [...defaultConfig.resolver.assetExts, 'pem'], + }, + // ... +}; +``` + #### Using React Native < 0.60 @@ -125,6 +137,7 @@ client.write('Hello server!'); // Close socket client.destroy(); ``` + ### Server ```javascript var server = TcpSocket.createServer(function(socket) { @@ -150,6 +163,17 @@ server.on('close', () => { }); ``` +### SSL Client +```javascript +var client = TcpSocket.createConnection({ + port: 8443, + host: "example.com", + tls: true, + tlsCert: require('./test.pem') // Self-signed certificate +}); +``` +_Note: In order to use self-signed certificates make sure to [update your metro.config.js configuration]()._ + ## API ### Client * **Methods:** @@ -168,8 +192,9 @@ server.on('close', () => { | `host` | `` | ✅ | ✅ | Host the socket should connect to. IP address in IPv4 format or `'localhost'`. **Default**: `'localhost'`. | | `localAddress` | `` | ✅ | ✅ | Local address the socket should connect from. If not specified, the OS will decide. It is **highly recommended** to specify a `localAddress` to prevent overload errors and improve performance. | | `localPort` | `` | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. | -| `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `tls`| `` | ❌ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | +| `tlsCert`| `` | ❌ | ✅ | Resource file to a CA (in .crt or .cer format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#SSL_Client)_. **Default**: `null`. | +| `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | **Note**: The platforms marked as ❌ use the default value. diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java b/android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java new file mode 100644 index 0000000..3dc7d5d --- /dev/null +++ b/android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java @@ -0,0 +1,67 @@ +package com.asterinet.react.tcpsocket; + +import android.content.Context; +import android.util.Log; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManagerFactory; + +import androidx.annotation.NonNull; +import androidx.annotation.RawRes; + +final class SSLCertificateHelper { + /** + * Creates an SSLSocketFactory instance for use with the CA provided in the resource file. + * + * @param context Context used to open up the CA file + * @param rawResourceUri Raw resource file to the CA (in .crt or .cer format, for instance) + * @return An SSLSocketFactory which trusts the provided CA when provided to network clients + */ + static SSLSocketFactory create(@NonNull final Context context, @NonNull final String rawResourceUri) { + try (InputStream caInput = getRawResourceStream(context, rawResourceUri)) { + // Generate the CA Certificate from the raw resource file + Certificate ca = CertificateFactory.getInstance("X.509").generateCertificate(caInput); + + // Load the key store using the CA + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, null); + keyStore.setCertificateEntry("ca", ca); + + // Initialize the TrustManager with this CA + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); + + // Create an SSL context that uses the created trust manager + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); + return sslContext.getSocketFactory(); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + private static InputStream getRawResourceStream(@NonNull final Context context, @NonNull final String resourceUri) throws IOException { + final int resId = getResourceId(context, resourceUri); + if (resId == 0) return URI.create(resourceUri).toURL().openStream(); // From metro on development + else return context.getResources().openRawResource(resId); // From bundle in production + } + + @RawRes + private static int getResourceId(@NonNull final Context context, @NonNull final String resourceUri) { + String name = resourceUri.toLowerCase().replace("-", "_"); + try { + return Integer.parseInt(name); + } catch (NumberFormatException ex) { + return context.getResources().getIdentifier(name, "raw", context.getPackageName()); + } + } +} diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java index 7d12282..635c4da 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java @@ -1,5 +1,6 @@ package com.asterinet.react.tcpsocket; +import android.content.Context; import android.net.Network; import android.os.AsyncTask; import android.util.Pair; @@ -12,6 +13,7 @@ import java.net.InetSocketAddress; import java.net.Socket; +import javax.net.SocketFactory; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; @@ -45,11 +47,13 @@ public Socket getSocket() { return socket; } - public void connect(@NonNull final String address, @NonNull final Integer port, @NonNull final ReadableMap options, @Nullable final Network network) throws IOException { + public void connect(@NonNull final Context context, @NonNull final String address, @NonNull final Integer port, @NonNull final ReadableMap options, @Nullable final Network network) throws IOException { if (socket != null) throw new IOException("Already connected"); final boolean isTls = options.hasKey("tls") && options.getBoolean("tls"); if (isTls) { - final SSLSocket sslSocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(); + final String customTlsCert = options.hasKey("tlsCert") ? options.getString("tlsCert") : null; + final SocketFactory sf = customTlsCert != null ? SSLCertificateHelper.create(context, customTlsCert) : SSLSocketFactory.getDefault(); + final SSLSocket sslSocket = (SSLSocket) sf.createSocket(); sslSocket.setUseClientMode(true); socket = sslSocket; } else { @@ -77,6 +81,7 @@ public void connect(@NonNull final String address, @NonNull final Integer port, startListening(); } + @SuppressWarnings("WeakerAccess") public void startListening() { //noinspection unchecked receiverTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new Pair<>(this, mReceiverListener)); diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java index bce0750..abbccca 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketModule.java @@ -83,7 +83,7 @@ protected void doInBackgroundGuarded(Void... params) { selectNetwork(iface, localAddress); client = new TcpSocketClient(TcpSocketModule.this, cId, null); socketClients.put(cId, client); - client.connect(host, port, options, currentNetwork.getNetwork()); + client.connect(mReactContext, host, port, options, currentNetwork.getNetwork()); onConnect(cId, host, port); } catch (Exception e) { onError(cId, e.getMessage()); @@ -288,7 +288,7 @@ public void onConnection(Integer serverId, Integer clientId, InetSocketAddress s sendEvent("connection", eventParams); } - private class CurrentNetwork { + private static class CurrentNetwork { @Nullable Network network = null; diff --git a/examples/tcpsockets/android/app/src/main/AndroidManifest.xml b/examples/tcpsockets/android/app/src/main/AndroidManifest.xml index 21fa74a..826a0a2 100644 --- a/examples/tcpsockets/android/app/src/main/AndroidManifest.xml +++ b/examples/tcpsockets/android/app/src/main/AndroidManifest.xml @@ -2,7 +2,6 @@ package="com.tcpsockets"> - { connectListener.remove(); if (callback) callback(ev.address); }); - if (options.timeout) this.setTimeout(options.timeout); + // Timeout + if (customOptions.timeout) this.setTimeout(customOptions.timeout); else if (this._timeout) this._activeTimer(this._timeout.msecs); + // TLS Cert + if (customOptions.tlsCert) { + customOptions.tlsCert = Image.resolveAssetSource(customOptions.tlsCert).uri; + } + // console.log(getAndroidResourceIdentifier(customOptions.tlsCert)); this._state = STATE.CONNECTING; this._destroyed = false; - Sockets.connect(this._id, options.host, options.port, options); + Sockets.connect(this._id, customOptions.host, customOptions.port, customOptions); return this; } @@ -293,13 +310,17 @@ export default class TcpSocket { * @param {BufferEncoding} [encoding] */ _generateSendBuffer(buffer, encoding) { - if (typeof buffer === 'string') return Buffer.from(buffer, encoding); - else if (Buffer.isBuffer(buffer)) return buffer; - else if (buffer instanceof Uint8Array || Array.isArray(buffer)) return Buffer.from(buffer); - else + if (typeof buffer === 'string') { + return Buffer.from(buffer, encoding); + } else if (Buffer.isBuffer(buffer)) { + return buffer; + } else if (buffer instanceof Uint8Array || Array.isArray(buffer)) { + return Buffer.from(buffer); + } else { throw new TypeError( `Invalid data, chunk must be a string or buffer, not ${typeof buffer}` ); + } } /** From e0c1220de2d23415ef52e1fafb5a1e8039a99f91 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 15:07:02 +0200 Subject: [PATCH 04/17] Update README docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a88ac5..f084d1a 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,7 @@ var client = TcpSocket.createConnection({ tlsCert: require('./test.pem') // Self-signed certificate }); ``` -_Note: In order to use self-signed certificates make sure to [update your metro.config.js configuration]()._ +_Note: In order to use self-signed certificates make sure to [update your metro.config.js configuration](#self-signed-ssl-only-available-for-react-native--060)._ ## API ### Client From 364def8e80611252d861b8ecaea1454773e620bc Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 15:07:25 +0200 Subject: [PATCH 05/17] Update readme links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f084d1a..0b1a187 100644 --- a/README.md +++ b/README.md @@ -193,7 +193,7 @@ _Note: In order to use self-signed certificates make sure to [update your metro. | `localAddress` | `` | ✅ | ✅ | Local address the socket should connect from. If not specified, the OS will decide. It is **highly recommended** to specify a `localAddress` to prevent overload errors and improve performance. | | `localPort` | `` | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. | | `tls`| `` | ❌ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | -| `tlsCert`| `` | ❌ | ✅ | Resource file to a CA (in .crt or .cer format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#SSL_Client)_. **Default**: `null`. | +| `tlsCert`| `` | ❌ | ✅ | Resource file to a CA (in .crt or .cer format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client)_. **Default**: `null`. | | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | From 3bff59ff9a2930e1fbf126c418fd6a5ec59be738 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 15:13:55 +0200 Subject: [PATCH 06/17] Improve README index --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0b1a187..daf0c6b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ React Native TCP socket API for Android & iOS with SSL/TLS support. It allows yo ## Table of Contents - [Getting started](#getting-started) + - [Self-Signed SSL](#self-signed-ssl-only-available-for-react-native--060) - [Compatibility](#react-native-compatibility) - [Usage](#usage) - [API](#icon-component) @@ -117,7 +118,7 @@ import TcpSocket from 'react-native-tcp-socket'; ### Client ```javascript // Create socket -var client = TcpSocket.createConnection(options); +const client = TcpSocket.createConnection(options); client.on('data', function(data) { console.log('message was received', data); @@ -140,7 +141,7 @@ client.destroy(); ### Server ```javascript -var server = TcpSocket.createServer(function(socket) { +const server = TcpSocket.createServer(function(socket) { socket.on('data', (data) => { socket.write('Echo server', data); }); @@ -165,12 +166,14 @@ server.on('close', () => { ### SSL Client ```javascript -var client = TcpSocket.createConnection({ +const client = TcpSocket.createConnection({ port: 8443, host: "example.com", tls: true, tlsCert: require('./test.pem') // Self-signed certificate }); + +// ... ``` _Note: In order to use self-signed certificates make sure to [update your metro.config.js configuration](#self-signed-ssl-only-available-for-react-native--060)._ From bbb5cf6fc78342ffa495d84598bf5505f16d2a4b Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 15:15:49 +0200 Subject: [PATCH 07/17] Better explanation ``tlsCert` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index daf0c6b..c7ace6b 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ _Note: In order to use self-signed certificates make sure to [update your metro. | `localAddress` | `` | ✅ | ✅ | Local address the socket should connect from. If not specified, the OS will decide. It is **highly recommended** to specify a `localAddress` to prevent overload errors and improve performance. | | `localPort` | `` | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. | | `tls`| `` | ❌ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | -| `tlsCert`| `` | ❌ | ✅ | Resource file to a CA (in .crt or .cer format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client)_. **Default**: `null`. | +| `tlsCert`| `` | ❌ | ✅ | CA file (in .crt or .pem format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | From 390f72537f996889bbbd41984dcf1a31a66289ca Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 15:19:45 +0200 Subject: [PATCH 08/17] Git information --- README.md | 2 +- package.json | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c7ace6b..63d9cd1 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![](https://github.com/Rapsssito/react-native-tcp-socket/workflows/tests/badge.svg) -React Native TCP socket API for Android & iOS with SSL/TLS support. It allows you to create TCP clients and servers sockets, simulating node's [net](https://nodejs.org/api/net.html) API. +React Native TCP socket API for Android & iOS with **SSL/TLS support**. It allows you to create TCP clients and servers sockets, simulating node's [net](https://nodejs.org/api/net.html) API. ## Table of Contents diff --git a/package.json b/package.json index 4fddf6b..5a0dabd 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "react-native-tcp-socket", "title": "React Native Tcp Socket", "version": "3.4.2", - "description": "React Native TCP socket API for Android & iOS", + "description": "React Native TCP socket API for Android & iOS with SSL/TLS support", "main": "src/index.js", "types": "lib/types/index.d.ts", "scripts": { @@ -34,6 +34,8 @@ "iOS", "Android", "tcp-socket", + "tls", + "ssl", "tcp-server", "tcp-client", "tcp", From 02b5bce2c2f876ba7346c2aac1a748edf9cc9d2f Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 15:24:35 +0200 Subject: [PATCH 09/17] Example testing --- examples/tcpsockets/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tcpsockets/package.json b/examples/tcpsockets/package.json index 4726048..a4d7b29 100644 --- a/examples/tcpsockets/package.json +++ b/examples/tcpsockets/package.json @@ -14,7 +14,7 @@ "dependencies": { "react": "16.11.0", "react-native": "0.62.1", - "react-native-tcp-socket": "^3.4.2" + "react-native-tcp-socket": "https://github.com/Rapsssito/react-native-tcp-socket#tls" }, "devDependencies": { "@babel/core": "^7.7.2", From 5b57135a2f078f53d8dbb718f3f1e3ae0dacd17b Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 17:14:22 +0200 Subject: [PATCH 10/17] iOS default TLS --- README.md | 2 +- examples/tcpsockets/ios/Podfile.lock | 4 +- ios/Podfile.lock | 304 +++++++++++++-------------- ios/TcpSocketClient.m | 23 +- 4 files changed, 174 insertions(+), 159 deletions(-) diff --git a/README.md b/README.md index 63d9cd1..f652e52 100644 --- a/README.md +++ b/README.md @@ -195,7 +195,7 @@ _Note: In order to use self-signed certificates make sure to [update your metro. | `host` | `` | ✅ | ✅ | Host the socket should connect to. IP address in IPv4 format or `'localhost'`. **Default**: `'localhost'`. | | `localAddress` | `` | ✅ | ✅ | Local address the socket should connect from. If not specified, the OS will decide. It is **highly recommended** to specify a `localAddress` to prevent overload errors and improve performance. | | `localPort` | `` | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. | -| `tls`| `` | ❌ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | +| `tls`| `` | ✅ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | | `tlsCert`| `` | ❌ | ✅ | CA file (in .crt or .pem format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | diff --git a/examples/tcpsockets/ios/Podfile.lock b/examples/tcpsockets/ios/Podfile.lock index e8503eb..cab7a23 100644 --- a/examples/tcpsockets/ios/Podfile.lock +++ b/examples/tcpsockets/ios/Podfile.lock @@ -233,7 +233,7 @@ PODS: - React-cxxreact (= 0.62.1) - React-jsi (= 0.62.1) - React-jsinspector (0.62.1) - - react-native-tcp-socket (3.4.1): + - react-native-tcp-socket (3.4.2): - CocoaAsyncSocket - React - React-RCTActionSheet (0.62.1): @@ -430,7 +430,7 @@ SPEC CHECKSUMS: React-jsi: 600d8e42510c3254fd2abd702f4b9d3f598d8f52 React-jsiexecutor: e9698dee4fd43ceb44832baf15d5745f455b0157 React-jsinspector: f74a62727e5604119abd4a1eda52c0a12144bcd5 - react-native-tcp-socket: 8399fdf6128c294e52654d50f45649df1fde6cfb + react-native-tcp-socket: a100fffbe7c96f92f457fa7fad6a29ec24bb8187 React-RCTActionSheet: af8f28dd82fec89b8fe29637b8c779829e016a88 React-RCTAnimation: 0d21fff7c20fb8ee41de5f2ebb63221127febd96 React-RCTBlob: 9496bd93130b22069bfbc5d35e98653dae7c35c6 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index bb7c0f4..fc16322 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2,14 +2,14 @@ PODS: - boost-for-react-native (1.63.0) - CocoaAsyncSocket (7.6.3) - DoubleConversion (1.1.6) - - FBLazyVector (0.61.4) - - FBReactNativeSpec (0.61.4): + - FBLazyVector (0.61.5) + - FBReactNativeSpec (0.61.5): - Folly (= 2018.10.22.00) - - RCTRequired (= 0.61.4) - - RCTTypeSafety (= 0.61.4) - - React-Core (= 0.61.4) - - React-jsi (= 0.61.4) - - ReactCommon/turbomodule/core (= 0.61.4) + - RCTRequired (= 0.61.5) + - RCTTypeSafety (= 0.61.5) + - React-Core (= 0.61.5) + - React-jsi (= 0.61.5) + - ReactCommon/turbomodule/core (= 0.61.5) - Folly (2018.10.22.00): - boost-for-react-native - DoubleConversion @@ -20,204 +20,204 @@ PODS: - DoubleConversion - glog - glog (0.3.5) - - RCTRequired (0.61.4) - - RCTTypeSafety (0.61.4): - - FBLazyVector (= 0.61.4) + - RCTRequired (0.61.5) + - RCTTypeSafety (0.61.5): + - FBLazyVector (= 0.61.5) - Folly (= 2018.10.22.00) - - RCTRequired (= 0.61.4) - - React-Core (= 0.61.4) - - React (0.61.4): - - React-Core (= 0.61.4) - - React-Core/DevSupport (= 0.61.4) - - React-Core/RCTWebSocket (= 0.61.4) - - React-RCTActionSheet (= 0.61.4) - - React-RCTAnimation (= 0.61.4) - - React-RCTBlob (= 0.61.4) - - React-RCTImage (= 0.61.4) - - React-RCTLinking (= 0.61.4) - - React-RCTNetwork (= 0.61.4) - - React-RCTSettings (= 0.61.4) - - React-RCTText (= 0.61.4) - - React-RCTVibration (= 0.61.4) - - React-Core (0.61.4): + - RCTRequired (= 0.61.5) + - React-Core (= 0.61.5) + - React (0.61.5): + - React-Core (= 0.61.5) + - React-Core/DevSupport (= 0.61.5) + - React-Core/RCTWebSocket (= 0.61.5) + - React-RCTActionSheet (= 0.61.5) + - React-RCTAnimation (= 0.61.5) + - React-RCTBlob (= 0.61.5) + - React-RCTImage (= 0.61.5) + - React-RCTLinking (= 0.61.5) + - React-RCTNetwork (= 0.61.5) + - React-RCTSettings (= 0.61.5) + - React-RCTText (= 0.61.5) + - React-RCTVibration (= 0.61.5) + - React-Core (0.61.5): - Folly (= 2018.10.22.00) - glog - - React-Core/Default (= 0.61.4) - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-Core/Default (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/CoreModulesHeaders (0.61.4): + - React-Core/CoreModulesHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/Default (0.61.4): + - React-Core/Default (0.61.5): - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/DevSupport (0.61.4): + - React-Core/DevSupport (0.61.5): - Folly (= 2018.10.22.00) - glog - - React-Core/Default (= 0.61.4) - - React-Core/RCTWebSocket (= 0.61.4) - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) - - React-jsinspector (= 0.61.4) + - React-Core/Default (= 0.61.5) + - React-Core/RCTWebSocket (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - React-jsinspector (= 0.61.5) - Yoga - - React-Core/RCTActionSheetHeaders (0.61.4): + - React-Core/RCTActionSheetHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTAnimationHeaders (0.61.4): + - React-Core/RCTAnimationHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTBlobHeaders (0.61.4): + - React-Core/RCTBlobHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTImageHeaders (0.61.4): + - React-Core/RCTImageHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTLinkingHeaders (0.61.4): + - React-Core/RCTLinkingHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTNetworkHeaders (0.61.4): + - React-Core/RCTNetworkHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTSettingsHeaders (0.61.4): + - React-Core/RCTSettingsHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTTextHeaders (0.61.4): + - React-Core/RCTTextHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTVibrationHeaders (0.61.4): + - React-Core/RCTVibrationHeaders (0.61.5): - Folly (= 2018.10.22.00) - glog - React-Core/Default - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-Core/RCTWebSocket (0.61.4): + - React-Core/RCTWebSocket (0.61.5): - Folly (= 2018.10.22.00) - glog - - React-Core/Default (= 0.61.4) - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsiexecutor (= 0.61.4) + - React-Core/Default (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) - Yoga - - React-CoreModules (0.61.4): - - FBReactNativeSpec (= 0.61.4) + - React-CoreModules (0.61.5): + - FBReactNativeSpec (= 0.61.5) - Folly (= 2018.10.22.00) - - RCTTypeSafety (= 0.61.4) - - React-Core/CoreModulesHeaders (= 0.61.4) - - React-RCTImage (= 0.61.4) - - ReactCommon/turbomodule/core (= 0.61.4) - - React-cxxreact (0.61.4): + - RCTTypeSafety (= 0.61.5) + - React-Core/CoreModulesHeaders (= 0.61.5) + - React-RCTImage (= 0.61.5) + - ReactCommon/turbomodule/core (= 0.61.5) + - React-cxxreact (0.61.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsinspector (= 0.61.4) - - React-jsi (0.61.4): + - React-jsinspector (= 0.61.5) + - React-jsi (0.61.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsi/Default (= 0.61.4) - - React-jsi/Default (0.61.4): + - React-jsi/Default (= 0.61.5) + - React-jsi/Default (0.61.5): - boost-for-react-native (= 1.63.0) - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-jsiexecutor (0.61.4): + - React-jsiexecutor (0.61.5): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - React-jsinspector (0.61.4) - - React-RCTActionSheet (0.61.4): - - React-Core/RCTActionSheetHeaders (= 0.61.4) - - React-RCTAnimation (0.61.4): - - React-Core/RCTAnimationHeaders (= 0.61.4) - - React-RCTBlob (0.61.4): - - React-Core/RCTBlobHeaders (= 0.61.4) - - React-Core/RCTWebSocket (= 0.61.4) - - React-jsi (= 0.61.4) - - React-RCTNetwork (= 0.61.4) - - React-RCTImage (0.61.4): - - React-Core/RCTImageHeaders (= 0.61.4) - - React-RCTNetwork (= 0.61.4) - - React-RCTLinking (0.61.4): - - React-Core/RCTLinkingHeaders (= 0.61.4) - - React-RCTNetwork (0.61.4): - - React-Core/RCTNetworkHeaders (= 0.61.4) - - React-RCTSettings (0.61.4): - - React-Core/RCTSettingsHeaders (= 0.61.4) - - React-RCTText (0.61.4): - - React-Core/RCTTextHeaders (= 0.61.4) - - React-RCTVibration (0.61.4): - - React-Core/RCTVibrationHeaders (= 0.61.4) - - ReactCommon/jscallinvoker (0.61.4): + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsinspector (0.61.5) + - React-RCTActionSheet (0.61.5): + - React-Core/RCTActionSheetHeaders (= 0.61.5) + - React-RCTAnimation (0.61.5): + - React-Core/RCTAnimationHeaders (= 0.61.5) + - React-RCTBlob (0.61.5): + - React-Core/RCTBlobHeaders (= 0.61.5) + - React-Core/RCTWebSocket (= 0.61.5) + - React-jsi (= 0.61.5) + - React-RCTNetwork (= 0.61.5) + - React-RCTImage (0.61.5): + - React-Core/RCTImageHeaders (= 0.61.5) + - React-RCTNetwork (= 0.61.5) + - React-RCTLinking (0.61.5): + - React-Core/RCTLinkingHeaders (= 0.61.5) + - React-RCTNetwork (0.61.5): + - React-Core/RCTNetworkHeaders (= 0.61.5) + - React-RCTSettings (0.61.5): + - React-Core/RCTSettingsHeaders (= 0.61.5) + - React-RCTText (0.61.5): + - React-Core/RCTTextHeaders (= 0.61.5) + - React-RCTVibration (0.61.5): + - React-Core/RCTVibrationHeaders (= 0.61.5) + - ReactCommon/jscallinvoker (0.61.5): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-cxxreact (= 0.61.4) - - ReactCommon/turbomodule/core (0.61.4): + - React-cxxreact (= 0.61.5) + - ReactCommon/turbomodule/core (0.61.5): - DoubleConversion - Folly (= 2018.10.22.00) - glog - - React-Core (= 0.61.4) - - React-cxxreact (= 0.61.4) - - React-jsi (= 0.61.4) - - ReactCommon/jscallinvoker (= 0.61.4) + - React-Core (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - ReactCommon/jscallinvoker (= 0.61.5) - Yoga (1.14.0) DEPENDENCIES: @@ -312,30 +312,30 @@ SPEC CHECKSUMS: boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c CocoaAsyncSocket: eafaa68a7e0ec99ead0a7b35015e0bf25d2c8987 DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 - FBLazyVector: feb35a6b7f7b50f367be07f34012f34a79282fa3 - FBReactNativeSpec: 51477b84b1bf7ab6f9ef307c24e3dd675391be44 + FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f + FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 glog: 1f3da668190260b06b429bb211bfbee5cd790c28 - RCTRequired: f3b3fb6f4723e8e52facb229d0c75fdc76773849 - RCTTypeSafety: 2ec60de6abb1db050b56ecc4b60188026078fd10 - React: 10e0130b57e55a7cd8c3dee37c1261102ce295f4 - React-Core: 636212410772d05f3a1eb79d965df2962ca1c70b - React-CoreModules: 6f70d5e41919289c582f88c9ad9923fe5c87400a - React-cxxreact: ddecbe9157ec1743f52ea17bf8d95debc0d6e846 - React-jsi: ca921f4041505f9d5197139b2d09eeb020bb12e8 - React-jsiexecutor: 8dfb73b987afa9324e4009bdce62a18ce23d983c - React-jsinspector: d15478d0a8ada19864aa4d1cc1c697b41b3fa92f - React-RCTActionSheet: 7369b7c85f99b6299491333affd9f01f5a130c22 - React-RCTAnimation: d07be15b2bd1d06d89417eb0343f98ffd2b099a7 - React-RCTBlob: 8e0b23d95c9baa98f6b0e127e07666aaafd96c34 - React-RCTImage: 443050d14a66e8c2332e9c055f45689d23e15cc7 - React-RCTLinking: ce9a90ba155aec41be49e75ec721bbae2d48a47e - React-RCTNetwork: 41fe54bacc67dd00e6e4c4d30dd98a13e4beabc8 - React-RCTSettings: 45e3e0a6470310b2dab2ccc6d1d73121ba3ea936 - React-RCTText: 21934e0a51d522abcd0a275407e80af45d6fd9ec - React-RCTVibration: 0f76400ee3cec6edb9c125da49fed279340d145a - ReactCommon: a6a294e7028ed67b926d29551aa9394fd989c24c - Yoga: ba3d99dbee6c15ea6bbe3783d1f0cb1ffb79af0f + RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 + RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 + React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78 + React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04 + React-CoreModules: d04f8494c1a328b69ec11db9d1137d667f916dcb + React-cxxreact: d0f7bcafa196ae410e5300736b424455e7fb7ba7 + React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7 + React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386 + React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 + React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 + React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360 + React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72 + React-RCTImage: 6b8e8df449eb7c814c99a92d6b52de6fe39dea4e + React-RCTLinking: 121bb231c7503cf9094f4d8461b96a130fabf4a5 + React-RCTNetwork: fb353640aafcee84ca8b78957297bd395f065c9a + React-RCTSettings: 8db258ea2a5efee381fcf7a6d5044e2f8b68b640 + React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe + React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad + ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd + Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b PODFILE CHECKSUM: c17fa9414d86be6752251d37471f1e2e374a215b diff --git a/ios/TcpSocketClient.m b/ios/TcpSocketClient.m index 9f6d1c6..f500459 100644 --- a/ios/TcpSocketClient.m +++ b/ios/TcpSocketClient.m @@ -14,6 +14,7 @@ @interface TcpSocketClient() { @private + BOOL _tls; GCDAsyncSocket *_tcpSocket; NSMutableDictionary *_pendingSends; NSLock *_lock; @@ -84,7 +85,10 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti withTimeout:-1 error:error]; } - + _tls = (options?[options[@"tls"] boolValue]:false); + if (_tls) { + [_tcpSocket startTLS:nil]; + } return result; } @@ -225,15 +229,26 @@ - (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSo [newSocket readDataWithTimeout:-1 tag:inComing.id.longValue]; } -- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port +- (void)socketDidSecure:(GCDAsyncSocket *)sock { + // Only for TLS if (!_clientDelegate) { - RCTLogWarn(@"didConnectToHost with nil clientDelegate for %@", [sock userData]); + RCTLogWarn(@"socketDidSecure with nil clientDelegate for %@", [sock userData]); return; } - [_clientDelegate onConnect:self]; +} +- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port +{ + if (!_clientDelegate) { + RCTLogWarn(@"didConnectToHost with nil clientDelegate for %@", [sock userData]); + return; + } + // Show up if SSL handsake is done + if (!_tls) { + [_clientDelegate onConnect:self]; + } [sock readDataWithTimeout:-1 tag:_id.longValue]; } From 3de30013d0e1b87711f2611549da35ebad0a2d60 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 19:47:40 +0200 Subject: [PATCH 11/17] iOS Allow self-signed certs --- README.md | 4 +-- ios/TcpSocketClient.h | 5 --- ios/TcpSocketClient.m | 72 ++++++++++++++++++++++++++++++++++++++----- ios/TcpSockets.h | 5 --- ios/TcpSockets.m | 5 --- 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index f652e52..3174812 100644 --- a/README.md +++ b/README.md @@ -195,10 +195,10 @@ _Note: In order to use self-signed certificates make sure to [update your metro. | `host` | `` | ✅ | ✅ | Host the socket should connect to. IP address in IPv4 format or `'localhost'`. **Default**: `'localhost'`. | | `localAddress` | `` | ✅ | ✅ | Local address the socket should connect from. If not specified, the OS will decide. It is **highly recommended** to specify a `localAddress` to prevent overload errors and improve performance. | | `localPort` | `` | ✅ | ✅ | Local port the socket should connect from. If not specified, the OS will decide. | -| `tls`| `` | ✅ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | -| `tlsCert`| `` | ❌ | ✅ | CA file (in .crt or .pem format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | +| `tls`| `` | ✅ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | +| `tlsCert`| `` | ✅ | ✅ | CA file (in .crt or .pem format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | **Note**: The platforms marked as ❌ use the default value. diff --git a/ios/TcpSocketClient.h b/ios/TcpSocketClient.h index 1f760c0..5706f0b 100644 --- a/ios/TcpSocketClient.h +++ b/ios/TcpSocketClient.h @@ -1,8 +1,3 @@ -/** - * Copyright (c) 2015-present, Peel Technologies, Inc. - * All rights reserved. - */ - #import #import "CocoaAsyncSocket/GCDAsyncSocket.h" diff --git a/ios/TcpSocketClient.m b/ios/TcpSocketClient.m index f500459..f0eac7a 100644 --- a/ios/TcpSocketClient.m +++ b/ios/TcpSocketClient.m @@ -1,8 +1,3 @@ -/** - * Copyright (c) 2015-present, Peel Technologies, Inc. - * All rights reserved. - */ - #import #import #import "TcpSocketClient.h" @@ -15,6 +10,7 @@ @interface TcpSocketClient() { @private BOOL _tls; + NSString *_certPath; GCDAsyncSocket *_tcpSocket; NSMutableDictionary *_pendingSends; NSLock *_lock; @@ -86,8 +82,18 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti error:error]; } _tls = (options?[options[@"tls"] boolValue]:false); - if (_tls) { - [_tcpSocket startTLS:nil]; + if (result && _tls){ + NSMutableDictionary *settings = [NSMutableDictionary dictionary]; + NSString *certResourcePath = (options?options[@"tlsCert"]:nil); + if (certResourcePath != nil) { + // Self-signed certificate + _certPath = certResourcePath; + [settings setObject:[NSNumber numberWithBool:YES] forKey:GCDAsyncSocketManuallyEvaluateTrust]; + } else { + // Default certificates + [settings setObject:host forKey:(NSString *) kCFStreamSSLPeerName]; + } + [_tcpSocket startTLS:settings]; } return result; } @@ -236,15 +242,67 @@ - (void)socketDidSecure:(GCDAsyncSocket *)sock RCTLogWarn(@"socketDidSecure with nil clientDelegate for %@", [sock userData]); return; } + [_clientDelegate onConnect:self]; } +- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler { + // Server certificate + SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(trust, 0); + CFDataRef serverCertificateData = SecCertificateCopyData(serverCertificate); + const UInt8* const serverData = CFDataGetBytePtr(serverCertificateData); + const CFIndex serverDataSize = CFDataGetLength(serverCertificateData); + NSData* cert1 = [NSData dataWithBytes:serverData length:(NSUInteger)serverDataSize]; + + // Local certificate + NSURL *certUrl = [[NSURL alloc] initWithString:_certPath]; + NSString *pem = [[NSString alloc] initWithContentsOfURL:certUrl encoding:NSUTF8StringEncoding error:NULL]; + + // Strip PEM header and footers. We don't support multi-certificate PEM. + NSMutableString *pemMutable = [pem stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet].mutableCopy; + + // Strip PEM header and footer + [pemMutable replaceOccurrencesOfString:@"-----BEGIN CERTIFICATE-----" + withString:@"" + options:(NSStringCompareOptions)(NSAnchoredSearch | NSLiteralSearch) + range:NSMakeRange(0, pemMutable.length)]; + + [pemMutable replaceOccurrencesOfString:@"-----END CERTIFICATE-----" + withString:@"" + options:(NSStringCompareOptions)(NSAnchoredSearch | NSBackwardsSearch | NSLiteralSearch) + range:NSMakeRange(0, pemMutable.length)]; + + NSData *pemData = [[NSData alloc] initWithBase64EncodedString:pemMutable options:NSDataBase64DecodingIgnoreUnknownCharacters]; + SecCertificateRef localCertificate = SecCertificateCreateWithData(NULL, (CFDataRef)pemData); + if (!localCertificate) + { + [NSException raise:@"Configuration invalid" format:@"Failed to parse PEM certificate"]; + } + + CFDataRef myCertData = SecCertificateCopyData(localCertificate); + const UInt8* const localData = CFDataGetBytePtr(myCertData); + const CFIndex localDataSize = CFDataGetLength(myCertData); + NSData* cert2 = [NSData dataWithBytes:localData length:(NSUInteger)localDataSize]; + + if (cert1 == nil || cert2 == nil) { + RCTLogWarn(@"BAD SSL CERTIFICATE"); + completionHandler(NO); + return; + } + if ([cert1 isEqualToData:cert2]) { + completionHandler(YES); + }else { + completionHandler(NO); + } +} + - (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port { if (!_clientDelegate) { RCTLogWarn(@"didConnectToHost with nil clientDelegate for %@", [sock userData]); return; } + // Show up if SSL handsake is done if (!_tls) { [_clientDelegate onConnect:self]; diff --git a/ios/TcpSockets.h b/ios/TcpSockets.h index 47ba018..cf63914 100644 --- a/ios/TcpSockets.h +++ b/ios/TcpSockets.h @@ -1,8 +1,3 @@ -/** - * Copyright (c) 2015-present, Peel Technologies, Inc. - * All rights reserved. - */ - #import "TcpSocketClient.h" #import diff --git a/ios/TcpSockets.m b/ios/TcpSockets.m index 1135f51..81473cb 100644 --- a/ios/TcpSockets.m +++ b/ios/TcpSockets.m @@ -1,8 +1,3 @@ -/** - * Copyright (c) 2015-present, Peel Technologies, Inc. - * All rights reserved. - */ - #import #import #import From 0d9a52af5443fde3505a2567487c47362624b0e9 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 20:17:14 +0200 Subject: [PATCH 12/17] Android: Ignore all certs --- README.md | 3 +- .../react/tcpsocket/SSLCertificateHelper.java | 71 +++++++++++++------ .../react/tcpsocket/TcpSocketClient.java | 15 ++-- src/TcpSocket.js | 5 +- 4 files changed, 64 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 3174812..de99daa 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,8 @@ _Note: In order to use self-signed certificates make sure to [update your metro. | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | | `tls`| `` | ✅ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | -| `tlsCert`| `` | ✅ | ✅ | CA file (in .crt or .pem format, for instance) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | +| `tlsCheckValidity`| `` | ❌ | ✅ | Enable/disable SSL/TLS certificate validity check. **NOT RECOMMENDED to disable**. **Default**: `true`. | +| `tlsCert`| `` | ✅ | ✅ | CA file (.pem format) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | **Note**: The platforms marked as ❌ use the default value. diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java b/android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java index 3dc7d5d..b938d75 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java @@ -1,57 +1,70 @@ package com.asterinet.react.tcpsocket; +import android.annotation.SuppressLint; import android.content.Context; -import android.util.Log; import java.io.IOException; import java.io.InputStream; import java.net.URI; +import java.security.GeneralSecurityException; import java.security.KeyStore; import java.security.SecureRandom; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import androidx.annotation.NonNull; import androidx.annotation.RawRes; final class SSLCertificateHelper { + /** + * Creates an SSLSocketFactory instance for use with all CAs provided. + * + * @return An SSLSocketFactory which trusts all CAs when provided to network clients + */ + static SSLSocketFactory createBlindSocketFactory() throws GeneralSecurityException { + SSLContext ctx = SSLContext.getInstance("TLS"); + ctx.init(null, new TrustManager[]{new BlindTrustManager()}, null); + return ctx.getSocketFactory(); + } + /** * Creates an SSLSocketFactory instance for use with the CA provided in the resource file. * - * @param context Context used to open up the CA file + * @param context Context used to open up the CA file * @param rawResourceUri Raw resource file to the CA (in .crt or .cer format, for instance) * @return An SSLSocketFactory which trusts the provided CA when provided to network clients */ - static SSLSocketFactory create(@NonNull final Context context, @NonNull final String rawResourceUri) { - try (InputStream caInput = getRawResourceStream(context, rawResourceUri)) { - // Generate the CA Certificate from the raw resource file - Certificate ca = CertificateFactory.getInstance("X.509").generateCertificate(caInput); - - // Load the key store using the CA - KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - keyStore.load(null, null); - keyStore.setCertificateEntry("ca", ca); + static SSLSocketFactory createCustomTrustedSocketFactory(@NonNull final Context context, @NonNull final String rawResourceUri) throws IOException, GeneralSecurityException { + InputStream caInput = getRawResourceStream(context, rawResourceUri); + // Generate the CA Certificate from the raw resource file + Certificate ca = CertificateFactory.getInstance("X.509").generateCertificate(caInput); + caInput.close(); + // Load the key store using the CA + KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); + keyStore.load(null, null); + keyStore.setCertificateEntry("ca", ca); - // Initialize the TrustManager with this CA - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(keyStore); + // Initialize the TrustManager with this CA + TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + tmf.init(keyStore); - // Create an SSL context that uses the created trust manager - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); - return sslContext.getSocketFactory(); - } catch (Exception ex) { - throw new RuntimeException(ex); - } + // Create an SSL context that uses the created trust manager + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(null, tmf.getTrustManagers(), new SecureRandom()); + return sslContext.getSocketFactory(); } private static InputStream getRawResourceStream(@NonNull final Context context, @NonNull final String resourceUri) throws IOException { final int resId = getResourceId(context, resourceUri); - if (resId == 0) return URI.create(resourceUri).toURL().openStream(); // From metro on development + if (resId == 0) + return URI.create(resourceUri).toURL().openStream(); // From metro on development else return context.getResources().openRawResource(resId); // From bundle in production } @@ -64,4 +77,18 @@ private static int getResourceId(@NonNull final Context context, @NonNull final return context.getResources().getIdentifier(name, "raw", context.getPackageName()); } } + + private static class BlindTrustManager implements X509TrustManager { + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @SuppressLint("TrustAllX509TrustManager") + public void checkClientTrusted(X509Certificate[] chain, String authType) { + } + + @SuppressLint("TrustAllX509TrustManager") + public void checkServerTrusted(X509Certificate[] chain, String authType) { + } + } } diff --git a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java index 635c4da..ce259e4 100644 --- a/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java +++ b/android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java @@ -12,6 +12,7 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; +import java.security.GeneralSecurityException; import javax.net.SocketFactory; import javax.net.ssl.SSLSocket; @@ -21,12 +22,11 @@ import androidx.annotation.Nullable; class TcpSocketClient { + private final int id; private TcpReceiverTask receiverTask; private Socket socket; private TcpReceiverTask.OnDataReceivedListener mReceiverListener; - private final int id; - TcpSocketClient(final int id) { this.id = id; } @@ -47,12 +47,17 @@ public Socket getSocket() { return socket; } - public void connect(@NonNull final Context context, @NonNull final String address, @NonNull final Integer port, @NonNull final ReadableMap options, @Nullable final Network network) throws IOException { + public void connect(@NonNull final Context context, @NonNull final String address, @NonNull final Integer port, @NonNull final ReadableMap options, @Nullable final Network network) throws IOException, GeneralSecurityException { if (socket != null) throw new IOException("Already connected"); final boolean isTls = options.hasKey("tls") && options.getBoolean("tls"); if (isTls) { - final String customTlsCert = options.hasKey("tlsCert") ? options.getString("tlsCert") : null; - final SocketFactory sf = customTlsCert != null ? SSLCertificateHelper.create(context, customTlsCert) : SSLSocketFactory.getDefault(); + SocketFactory sf; + if (options.hasKey("tlsCheckValidity") && !options.getBoolean("tlsCheckValidity")){ + sf = SSLCertificateHelper.createBlindSocketFactory(); + } else { + final String customTlsCert = options.hasKey("tlsCert") ? options.getString("tlsCert") : null; + sf = customTlsCert != null ? SSLCertificateHelper.createCustomTrustedSocketFactory(context, customTlsCert) : SSLSocketFactory.getDefault(); + } final SSLSocket sslSocket = (SSLSocket) sf.createSocket(); sslSocket.setUseClientMode(true); socket = sslSocket; diff --git a/src/TcpSocket.js b/src/TcpSocket.js index 83fc765..a08f818 100644 --- a/src/TcpSocket.js +++ b/src/TcpSocket.js @@ -38,10 +38,11 @@ class RemovableListener { * timeout?: number; * localAddress?: string, * localPort?: number, + * interface?: 'wifi' | 'cellular' | 'ethernet', + * reuseAddress?: boolean, * tls?: boolean, + * tlsCheckValidity?: boolean, * tlsCert?: any, - * interface?: 'wifi' | 'cellular' | 'ethernet', - * reuseAddress?: boolean * }} ConnectionOptions */ export default class TcpSocket { From 0ca8daf661f5a8c3fb9efc3849fa3c8109f8e243 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 20:26:00 +0200 Subject: [PATCH 13/17] Better docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de99daa..c5a12bc 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ _Note: In order to use self-signed certificates make sure to [update your metro. | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | | `tls`| `` | ✅ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | -| `tlsCheckValidity`| `` | ❌ | ✅ | Enable/disable SSL/TLS certificate validity check. **NOT RECOMMENDED to disable**. **Default**: `true`. | +| `tlsCheckValidity`| `` | ❌ | ✅ | Enable/disable SSL/TLS certificate validity check. **Default**: `true`. | | `tlsCert`| `` | ✅ | ✅ | CA file (.pem format) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | **Note**: The platforms marked as ❌ use the default value. From beaac8c9919cfaff3150203187bde298f581cbd1 Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 20:59:03 +0200 Subject: [PATCH 14/17] iOS allow disabling check validity --- README.md | 2 +- ios/TcpSocketClient.m | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index c5a12bc..3f27a1c 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ _Note: In order to use self-signed certificates make sure to [update your metro. | `interface`| `` | ❌ | ✅ | Interface the socket should connect from. If not specified, it will use the current active connection. The options are: `'wifi', 'ethernet', 'cellular'`. | | `reuseAddress`| `` | ❌ | ✅ | Enable/disable the reuseAddress socket option. **Default**: `true`. | | `tls`| `` | ✅ | ✅ | Enable/disable SSL/TLS socket creation. **Default**: `false`. | -| `tlsCheckValidity`| `` | ❌ | ✅ | Enable/disable SSL/TLS certificate validity check. **Default**: `true`. | +| `tlsCheckValidity`| `` | ✅ | ✅ | Enable/disable SSL/TLS certificate validity check. **Default**: `true`. | | `tlsCert`| `` | ✅ | ✅ | CA file (.pem format) to trust. If `null`, it will use the device's default SSL trusted list. Useful for self-signed certificates. _See [example](#ssl-client) for more info_. **Default**: `null`. | **Note**: The platforms marked as ❌ use the default value. diff --git a/ios/TcpSocketClient.m b/ios/TcpSocketClient.m index f0eac7a..4df8096 100644 --- a/ios/TcpSocketClient.m +++ b/ios/TcpSocketClient.m @@ -10,6 +10,7 @@ @interface TcpSocketClient() { @private BOOL _tls; + BOOL _checkValidity; NSString *_certPath; GCDAsyncSocket *_tcpSocket; NSMutableDictionary *_pendingSends; @@ -64,8 +65,8 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti BOOL result = false; - NSString *localAddress = (options?options[@"localAddress"]:nil); - NSNumber *localPort = (options?options[@"localPort"]:nil); + NSString *localAddress = options[@"localAddress"]; + NSNumber *localPort = options[@"localPort"]; if (!localAddress && !localPort) { result = [_tcpSocket connectToHost:host onPort:port error:error]; @@ -81,11 +82,16 @@ - (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)opti withTimeout:-1 error:error]; } - _tls = (options?[options[@"tls"] boolValue]:false); + _tls = (options[@"tls"]?[options[@"tls"] boolValue]:false); if (result && _tls){ NSMutableDictionary *settings = [NSMutableDictionary dictionary]; - NSString *certResourcePath = (options?options[@"tlsCert"]:nil); - if (certResourcePath != nil) { + NSString *certResourcePath = options[@"tlsCert"]; + BOOL checkValidity = (options[@"tlsCheckValidity"]?[options[@"tlsCheckValidity"] boolValue]:true); + if (!checkValidity) { + // Do not validate + _checkValidity = false; + [settings setObject:[NSNumber numberWithBool:YES] forKey:GCDAsyncSocketManuallyEvaluateTrust]; + } else if (certResourcePath != nil) { // Self-signed certificate _certPath = certResourcePath; [settings setObject:[NSNumber numberWithBool:YES] forKey:GCDAsyncSocketManuallyEvaluateTrust]; @@ -247,6 +253,12 @@ - (void)socketDidSecure:(GCDAsyncSocket *)sock } - (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler { + // Check if we should check the validity + if (!_checkValidity) { + completionHandler(YES); + return; + } + // Server certificate SecCertificateRef serverCertificate = SecTrustGetCertificateAtIndex(trust, 0); CFDataRef serverCertificateData = SecCertificateCopyData(serverCertificate); From ede941967f9cfd35b951926c39e1f1e28a42b9bf Mon Sep 17 00:00:00 2001 From: Rapsssito Date: Tue, 7 Apr 2020 21:00:21 +0200 Subject: [PATCH 15/17] Better docs --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f27a1c..3e61c84 100644 --- a/README.md +++ b/README.md @@ -170,7 +170,8 @@ const client = TcpSocket.createConnection({ port: 8443, host: "example.com", tls: true, - tlsCert: require('./test.pem') // Self-signed certificate + // tlsCheckValidity: false, // Disable validity checking + // tlsCert: require('./selfmade.pem') // Self-signed certificate }); // ... From ab5ae148d9a76acc6a614c9d4c5f8266d5c42caa Mon Sep 17 00:00:00 2001 From: Rodrigo Martin Date: Wed, 8 Apr 2020 16:54:26 +0200 Subject: [PATCH 16/17] Update README.md --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3e61c84..f85db7e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![](https://github.com/Rapsssito/react-native-tcp-socket/workflows/tests/badge.svg) -React Native TCP socket API for Android & iOS with **SSL/TLS support**. It allows you to create TCP clients and servers sockets, simulating node's [net](https://nodejs.org/api/net.html) API. +React Native TCP socket API for Android & iOS with **client SSL/TLS support**. It allows you to create TCP clients and servers sockets, imitating some of node's [net](https://nodejs.org/api/net.html) API functionalities. ## Table of Contents @@ -50,10 +50,10 @@ Linking the package manually is not required anymore with [Autolinking](https:// ``` #### Self-Signed SSL (only available for React Native > 0.60) -You will need a [metro.config.js](https://facebook.github.io/metro/docs/en/configuration.html) file in order to use a self-signed SSL certificate library. You should already have this file in your root project directory, but if you don't, create it. +You will need a [metro.config.js](https://facebook.github.io/metro/docs/en/configuration.html) file in order to use a self-signed SSL certificate. You should already have this file in your root project directory, but if you don't, create it. Inside a `module.exports` object, create a key called `resolver` with another object called `assetExts`. The value of `assetExts` should be an array of the resource file extensions you want to support. -For example, if you want to support `.pem` files (plus all the already supported files), your `metro.config.js` would like like this: +If you want to support `.pem` files (plus all the already supported files), your `metro.config.js` would like like this: ```javascript const {getDefaultConfig} = require('metro-config'); const defaultConfig = getDefaultConfig.getDefaultValues(__dirname); @@ -232,7 +232,6 @@ _Note: In order to use self-signed certificates make sure to [update your metro. **Note**: The platforms marked as ❌ use the default value. ## Maintainers -Looking for maintainers! * [Rapsssito](https://github.com/rapsssito) From e7f17162db7deb7731d53b6f60c65577bfcbfcc6 Mon Sep 17 00:00:00 2001 From: Rodrigo Martin Date: Wed, 8 Apr 2020 16:55:41 +0200 Subject: [PATCH 17/17] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f85db7e..cd6ea10 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![](https://github.com/Rapsssito/react-native-tcp-socket/workflows/tests/badge.svg) -React Native TCP socket API for Android & iOS with **client SSL/TLS support**. It allows you to create TCP clients and servers sockets, imitating some of node's [net](https://nodejs.org/api/net.html) API functionalities. +React Native TCP socket API for Android & iOS with **client SSL/TLS support**. It allows you to create TCP clients and servers sockets, imitating some of node's [net](https://nodejs.org/api/net.html) API functionalities (check the available [API](#api) for more information). ## Table of Contents @@ -10,7 +10,7 @@ React Native TCP socket API for Android & iOS with **client SSL/TLS support**. I - [Self-Signed SSL](#self-signed-ssl-only-available-for-react-native--060) - [Compatibility](#react-native-compatibility) - [Usage](#usage) -- [API](#icon-component) +- [API](#api) - [Client](#client) - [Server](#server) - [Maintainers](#maintainers)