From 7bf54f35e5328bd21f6eaaaf32159a85fa542d1d Mon Sep 17 00:00:00 2001 From: Hanwen Cheng Date: Sat, 19 Oct 2019 19:37:09 +0200 Subject: [PATCH] use promise and fix ios bug --- .../java/io/parity/signer/ECCryptoModule.java | 16 ++++----- .../io/parity/signer/MainApplication.java | 1 + ios/ECCrypto/ECCrypto.m | 35 ++++++++++++++----- src/util/native.js | 8 ++--- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/android/app/src/main/java/io/parity/signer/ECCryptoModule.java b/android/app/src/main/java/io/parity/signer/ECCryptoModule.java index 8dae609acf..1c33e4540c 100644 --- a/android/app/src/main/java/io/parity/signer/ECCryptoModule.java +++ b/android/app/src/main/java/io/parity/signer/ECCryptoModule.java @@ -74,7 +74,7 @@ public String getName() { } @ReactMethod - public void encrypt(ReadableMap map, Callback function) { + public void encrypt(ReadableMap map, Promise promise) { try { KeysetHandle keysetHandle = getOrGenerateNewKeysetHandle(map.getString("label")); KeysetHandle publicKeysetHandle = keysetHandle.getPublicKeysetHandle(); @@ -85,16 +85,16 @@ public void encrypt(ReadableMap map, Callback function) { HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive(publicKeysetHandle); byte[] cipherText = hybridEncrypt.encrypt(plainText, contextInfo); - function.invoke(null, toBase64(cipherText)); + promise.resolve(toBase64(cipherText)); } catch (Exception e) { Log.e("ECCrypto", "encryption error", e); - function.invoke(e.toString(), null); + promise.reject("ECCrypto error", e); return; } } @ReactMethod - public void decrypt(ReadableMap map, Callback function) { + public void decrypt(ReadableMap map, Promise promise) { try { KeysetHandle keysetHandle = getOrGenerateNewKeysetHandle(map.getString("label")); String cipherTextString = map.getString("data"); @@ -104,10 +104,10 @@ public void decrypt(ReadableMap map, Callback function) { HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive(keysetHandle); byte[] clearText = hybridDecrypt.decrypt(cipherText, contextInfo); - function.invoke(null, new String(clearText, "UTF-8")); - } catch (Exception ex) { - Log.e("ECCrypto", "decrypt error", ex); - function.invoke(ex.toString(), null); + promise.resolve(new String(clearText, "UTF-8")); + } catch (Exception e) { + Log.e("ECCrypto", "decrypt error", e); + promise.reject("ECCrypto error", e); return; } } diff --git a/android/app/src/main/java/io/parity/signer/MainApplication.java b/android/app/src/main/java/io/parity/signer/MainApplication.java index 58dc83fdf9..f04d0ee5c6 100644 --- a/android/app/src/main/java/io/parity/signer/MainApplication.java +++ b/android/app/src/main/java/io/parity/signer/MainApplication.java @@ -36,6 +36,7 @@ protected List getPackages() { new NetInfoPackage(), new RandomBytesPackage(), new EthkeyBridgePackage(), + new ECCryptoPackage(), new RNGestureHandlerPackage() ); } diff --git a/ios/ECCrypto/ECCrypto.m b/ios/ECCrypto/ECCrypto.m index 5d96de1a5a..a5d3b04e0f 100644 --- a/ios/ECCrypto/ECCrypto.m +++ b/ios/ECCrypto/ECCrypto.m @@ -84,26 +84,42 @@ - (SecKeyRef) generateECPair:(nonnull NSDictionary*) options &error); if (!privateKey) { *errMsg = [CFBridgingRelease(error) description]; // ARC takes ownership - CFRelease(privateKey); return nil; } SecKeyRef publicKey = SecKeyCopyPublicKey(privateKey); + + // Save public Key + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)@{ + (__bridge id)kSecClass: (__bridge id)kSecClassKey, + (__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPublic, + (__bridge id)kSecAttrApplicationTag: publicKeyTag, + (__bridge id)kSecValueRef: (__bridge id)publicKey + }, nil); + + if (status != errSecSuccess) { + CFRelease(privateKey); + CFRelease(publicKey); + *errMsg = keychainStatusToString(status); + return nil; + } + CFRelease(privateKey); return publicKey; } RCT_EXPORT_METHOD(decrypt:(nonnull NSDictionary *)options - callback:(RCTResponseSenderBlock)callback) { + findEventsWithResolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSString* errMsg; NSData* clearText = [self decrypt:options errMsg:&errMsg]; if (!clearText) { - callback(@[eccryptoMakeError(errMsg)]); + reject(@"ECCrypto", errMsg, eccryptoMakeError(errMsg)); return; } NSString* base64ClearText = [[NSString alloc] initWithData:clearText encoding:NSUTF8StringEncoding]; - callback(@[[NSNull null], base64ClearText]); + resolve(base64ClearText); }); } @@ -139,17 +155,18 @@ -(NSData *)decrypt:(nonnull NSDictionary *)options } RCT_EXPORT_METHOD(encrypt:(nonnull NSDictionary *)options - callback:(RCTResponseSenderBlock)callback) { + findEventsWithResolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSString* errMsg; NSData* cipherText = [self encrypt:options errMsg:&errMsg]; if (!cipherText) { - callback(@[eccryptoMakeError(errMsg)]); + reject(@"ECCrypto", errMsg, eccryptoMakeError(errMsg)); return; } NSString* base64cipherText = [cipherText base64EncodedStringWithOptions:0]; - callback(@[[NSNull null], base64cipherText]); + resolve(base64cipherText); }); } @@ -294,9 +311,9 @@ - (NSString *)uuidString { return uuidString; } -NSDictionary* eccryptoMakeError(NSString* errMsg) +NSError* eccryptoMakeError(NSString* errMsg) { - return RCTMakeAndLogError(errMsg, nil, nil); + return [NSError errorWithDomain:@"ECCrypto" code:1 userInfo:@{NSLocalizedDescriptionKey:errMsg}]; } @end diff --git a/src/util/native.js b/src/util/native.js index b083b889e1..9113c7a08a 100644 --- a/src/util/native.js +++ b/src/util/native.js @@ -107,12 +107,12 @@ export function decryptData(data, password) { return EthkeyBridge.decryptData(data, password); } -export function encryptWithSecureKeystore ({data, label}, callback) { - return ECCrypto.encrypt({data, label}, callback); +export function encryptWithSecureKeystore(data, label) { + return ECCrypto.encrypt({ data, label }); } -export function decryptWithSecureKeystore ({data, label}, callback) { - return ECCrypto.decrypt({data, label}, callback); +export function decryptWithSecureKeystore(data, label) { + return ECCrypto.decrypt({ data, label }); } // Creates a QR code for the UTF-8 representation of a string