Skip to content

Commit f1ab919

Browse files
committed
final clean and implement same behavior on android
1 parent 89eebc4 commit f1ab919

File tree

4 files changed

+41
-42
lines changed

4 files changed

+41
-42
lines changed

android/src/main/java/com/asterinet/react/tcpsocket/SSLCertificateHelper.java

+29-25
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ static SSLServerSocketFactory createServerSocketFactory(Context context, @NonNul
8181
}
8282

8383
static boolean hasIdentity(ReadableMap options) {
84-
boolean hasId = false;
8584
try {
8685
final String keystoreName = options.hasKey("androidKeyStore") ?
8786
options.getString("androidKeyStore") : KeyStore.getDefaultType();
@@ -92,13 +91,11 @@ static boolean hasIdentity(ReadableMap options) {
9291
return false;
9392
}
9493

95-
// Get keystore instance
9694
KeyStore keyStore = KeyStore.getInstance(keystoreName);
9795
keyStore.load(null, null);
9896

9997
// Check if key entry exists with its certificate chain
100-
hasId = keyStore.isKeyEntry(keyAlias);
101-
return hasId;
98+
return keyStore.isKeyEntry(keyAlias);
10299
} catch (Exception e) {
103100
return false;
104101
}
@@ -151,37 +148,45 @@ static SSLSocketFactory createCustomTrustedSocketFactory(
151148
final KeystoreInfo keystoreInfo) throws IOException, GeneralSecurityException {
152149

153150
SSLSocketFactory ssf = null;
154-
if (optionResCert != null && optionResKey != null) {
155-
final String keyStoreName = keystoreInfo.getKeystoreName().isEmpty() ?
151+
152+
KeyStore keyStore = null;
153+
final String keyStoreName = keystoreInfo.getKeystoreName().isEmpty() ?
156154
KeyStore.getDefaultType() :
157155
keystoreInfo.getKeystoreName();
158-
KeyStore keyStore = KeyStore.getInstance(keyStoreName);
159-
keyStore.load(null, null);
156+
String keyAlias = keystoreInfo.getKeyAlias();
160157

161-
// Check if cert and key if already registered inside our keystore
162-
// If one is missing we insert again
163-
boolean hasCertInStore = keyStore.isCertificateEntry(keystoreInfo.getCertAlias());
164-
boolean hasKeyInStore = keyStore.isKeyEntry(keystoreInfo.getKeyAlias());
165-
if (!hasCertInStore || !hasKeyInStore) {
166-
InputStream certInput = getResolvableinputStream(context, optionResCert);
167-
Certificate cert = CertificateFactory.getInstance("X.509").generateCertificate(certInput);
168-
keyStore.setCertificateEntry(keystoreInfo.getCertAlias(), cert);
169-
170-
InputStream keyInput = getResolvableinputStream(context, optionResKey);
171-
PrivateKey privateKey = getPrivateKeyFromPEM(keyInput);
172-
keyStore.setKeyEntry(keystoreInfo.getKeyAlias(), privateKey, null, new Certificate[]{cert});
158+
// if user provides keyAlias without key it means an identity(cert+key) has already been
159+
// inserted in keychain.
160+
if (keyAlias != null && !keyAlias.isEmpty() && optionResKey == null) {
161+
keyStore = KeyStore.getInstance(keyStoreName);
162+
keyStore.load(null, null);
163+
if (!keyStore.isKeyEntry(keyAlias)) {
164+
keyStore = null;
173165
}
166+
} else if (optionResCert != null && optionResKey != null) {
167+
168+
keyStore = KeyStore.getInstance(keyStoreName);
169+
keyStore.load(null, null);
174170

175-
boolean hasCaInStore = keyStore.isCertificateEntry(keystoreInfo.getCaAlias());
176-
if (optionResCa != null && !hasCaInStore) {
171+
InputStream certInput = getResolvableinputStream(context, optionResCert);
172+
Certificate cert = CertificateFactory.getInstance("X.509").generateCertificate(certInput);
173+
keyStore.setCertificateEntry(keystoreInfo.getCertAlias(), cert);
174+
175+
InputStream keyInput = getResolvableinputStream(context, optionResKey);
176+
PrivateKey privateKey = getPrivateKeyFromPEM(keyInput);
177+
keyStore.setKeyEntry(keystoreInfo.getKeyAlias(), privateKey, null, new Certificate[]{cert});
178+
179+
if (optionResCa != null) {
177180
InputStream caInput = getResolvableinputStream(context, optionResCa);
178181
// Generate the CA Certificate from the raw resource file
179182
Certificate ca = CertificateFactory.getInstance("X.509").generateCertificate(caInput);
180183
caInput.close();
181184
// Load the key store using the CA
182185
keyStore.setCertificateEntry(keystoreInfo.getCaAlias(), ca);
183186
}
184-
187+
}
188+
189+
if (keyStore != null) {
185190
// Initialize the KeyManagerFactory with this cert
186191
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
187192
keyManagerFactory.init(keyStore, new char[0]);
@@ -190,15 +195,14 @@ static SSLSocketFactory createCustomTrustedSocketFactory(
190195
SSLContext sslContext = SSLContext.getInstance("TLS");
191196
sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{new BlindTrustManager()}, null);
192197
return sslContext.getSocketFactory();
193-
194198
} else {
195199
// Keep old behavior
196200
InputStream caInput = getResolvableinputStream(context, optionResCa);
197201
// Generate the CA Certificate from the raw resource file
198202
Certificate ca = CertificateFactory.getInstance("X.509").generateCertificate(caInput);
199203
caInput.close();
200204
// Load the key store using the CA
201-
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
205+
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
202206
keyStore.load(null, null);
203207
keyStore.setCertificateEntry("ca", ca);
204208

android/src/main/java/com/asterinet/react/tcpsocket/TcpSocketClient.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,13 @@ private boolean containsKey(ReadableArray array, String key) {
8787
}
8888
return false;
8989
}
90+
9091
private ResolvableOption getResolvableOption(ReadableMap tlsOptions, String key) {
9192
if (tlsOptions.hasKey(key)) {
9293
String value = tlsOptions.getString(key);
94+
if (value == null || value.isEmpty()) {
95+
return null;
96+
}
9397
ReadableArray resolvedKeys = tlsOptions.hasKey("resolvedKeys") ? tlsOptions.getArray("resolvedKeys") : null;
9498
boolean needsResolution = resolvedKeys != null && containsKey(resolvedKeys, key);
9599
return new ResolvableOption(value, needsResolution);
@@ -110,7 +114,8 @@ private SSLSocketFactory getSSLSocketFactory(Context context, ReadableMap tlsOpt
110114
final KeystoreInfo keystoreInfo = new KeystoreInfo(keystoreName, caAlias, certAlias, keyAlias);
111115

112116
if (tlsOptions.hasKey("rejectUnauthorized") && !tlsOptions.getBoolean("rejectUnauthorized")) {
113-
if (customTlsKey != null && customTlsCert != null ) {
117+
if ((customTlsKey != null && customTlsCert != null) ||
118+
(keyAlias != null && !keyAlias.isEmpty() && customTlsKey == null) ) {
114119
ssf = SSLCertificateHelper.createCustomTrustedSocketFactory(
115120
context,
116121
customTlsCa,

ios/TcpSocketClient.m

+5-14
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,6 @@ - (void)startTLS:(NSDictionary *)tlsOptions {
229229
//RCTLogWarn(@"startTLS: Attempting client certificate authentication");
230230
NSString *pemCert = [resolvableCert resolve];
231231
NSString *pemKey = [resolvableKey resolve];
232-
233-
// RCTLogWarn(
234-
// @"startTLS: Resolved PEM cert exists: %@, PEM key exists: %@",
235-
// pemCert ? @"YES" : @"NO", pemKey ? @"YES" : @"NO");
236-
237232
if (pemCert && pemKey) {
238233
myIdent = [self createIdentityWithCert:pemCert
239234
privateKey:pemKey
@@ -705,8 +700,6 @@ - (NSData *)extractRSAKeyFromPKCS8:(NSData *)pkcs8Data error:(NSError **)error {
705700
- (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
706701
privateKey:(NSString *)pemKey
707702
settings:(NSDictionary *)settings {
708-
RCTLogWarn(@"createIdentity: Starting identity creation");
709-
710703
OSStatus status = -1;
711704
SecIdentityRef identity = NULL;
712705

@@ -732,7 +725,8 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
732725
// Import certificate in keychain
733726
NSDictionary *deleteCertQuery = @{
734727
(__bridge id)kSecClass : (__bridge id)kSecClassCertificate,
735-
(__bridge id)kSecAttrLabel: certAlias
728+
(__bridge id)kSecAttrLabel: certAlias,
729+
(__bridge id)kSecReturnRef : @YES
736730
};
737731
status = SecItemDelete((__bridge CFDictionaryRef)deleteCertQuery);
738732

@@ -751,8 +745,7 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
751745

752746
NSDictionary *privateKeyAttributes = @{
753747
(__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeRSA,
754-
(__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPrivate,
755-
//(__bridge id)kSecReturnPersistentRef : @YES
748+
(__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPrivate
756749
};
757750
CFErrorRef error = NULL;
758751
SecKeyRef privateKey = SecKeyCreateWithData(
@@ -768,8 +761,8 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
768761

769762
NSDictionary *deleteKeyQuery = @{
770763
(__bridge id)kSecClass : (__bridge id)kSecClassKey,
771-
//(__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeRSA,
772-
(__bridge id)kSecAttrLabel: keyAlias
764+
(__bridge id)kSecAttrLabel: keyAlias,
765+
(__bridge id)kSecReturnRef : @YES
773766
};
774767
status = SecItemDelete((__bridge CFDictionaryRef)deleteKeyQuery);
775768

@@ -798,8 +791,6 @@ - (SecIdentityRef)createIdentityWithCert:(NSString *)pemCert
798791
if (status != errSecSuccess || !identity) {
799792
RCTLogWarn(@"createIdentity: Failed to find identity, status: %d",
800793
(int)status);
801-
} else {
802-
RCTLogWarn(@"createIdentity: Successfully found identity");
803794
}
804795

805796
// Clean up

lib/types/Socket.d.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,8 @@ export default class Socket extends EventEmitter<SocketEvents & ReadableEvents,
119119
setTimeout(timeout: number, callback?: (() => void) | undefined): Socket;
120120
/**
121121
* @private
122-
* @param {number} [timeout]
123122
*/
124-
private _activateTimer;
123+
private _resetTimeout;
125124
/**
126125
* @private
127126
*/

0 commit comments

Comments
 (0)