From 93248e980ab859b3af794788d7a280760a11135e Mon Sep 17 00:00:00 2001 From: Alex Radetsky Date: Mon, 3 Oct 2022 16:32:39 +0300 Subject: [PATCH 1/3] redesigned the framework to make it less vulnerable to native exceptions. Second try. --- .../com/reactnativethemis/ThemisModule.java | 1103 ++++++++--------- .../android/src/main/main.iml | 11 + .../react-native-themis/ios/RCTThemis.h | 18 +- .../react-native-themis/ios/RCTThemis.m | 979 ++++++++------- .../themis/react-native-themis/package.json | 5 +- .../themis/react-native-themis/src/index.d.ts | 9 +- .../themis/react-native-themis/src/index.js | 194 +-- .../themis/react-native-themis/src/index.tsx | 613 ++++----- 8 files changed, 1367 insertions(+), 1565 deletions(-) create mode 100644 src/wrappers/themis/react-native-themis/android/src/main/main.iml diff --git a/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java b/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java index 24e70e4c1..93fe37b5d 100644 --- a/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java +++ b/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java @@ -17,7 +17,6 @@ import com.cossacklabs.themis.SecureMessage; import com.cossacklabs.themis.SecureCompare; - import com.facebook.react.bridge.Callback; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; @@ -33,608 +32,528 @@ import java.util.Map; import java.util.UUID; - - - public class ThemisModule extends ReactContextBaseJavaModule { + public static class ByteOverflowException extends Exception { + public ByteOverflowException(String errorMessage) { + super(errorMessage); + } + } + + Map cmprs = new HashMap<>(); + + private final static int comparator_not_ready = 0; + private final static int comparator_not_match = 22; + private final static int comparator_match = 21; + private final static int comparator_error = -1; + + private final static String contextRequired = "Context required"; + private final static String privateKeyRequired = "Private key can not be null or blank"; + private final static String publicKeyRequired = "Public key can not be null or blank"; + + ThemisModule(ReactApplicationContext context) { + super(context); + } - public static class ByteOverflowException extends Exception { - public ByteOverflowException(String errorMessage) { - super(errorMessage); - } - } - - Map cmprs = new HashMap<>(); - - private final static int comparator_not_ready = 0; - private final static int comparator_not_match = 22; - private final static int comparator_match = 21; - private final static int comparator_error = -1; - - private final static String contextRequired = "Context required"; - private final static String privateKeyRequired = "Private key can not be null or blank"; - private final static String publicKeyRequired = "Public key can not be null or blank"; - - ThemisModule(ReactApplicationContext context) - { - super(context); - } - - @NonNull - @Override - public String getName() - { - return "Themis"; - } - - /* Replace JAVA enum version to equal with iOS version. */ - - @Override - public Map getConstants() - { - final Map constants = new HashMap<>(); - constants.put("COMPARATOR_NOT_READY", comparator_not_ready); - constants.put("COMPARATOR_NOT_MATCH", comparator_not_match); - constants.put("COMPARATOR_MATCH", comparator_match); - constants.put("COMPARATOR_ERROR", comparator_error); - constants.put("KEYTYPE_RSA", AsymmetricKey.KEYTYPE_RSA); - constants.put("KEYTYPE_EC", AsymmetricKey.KEYTYPE_EC); - return constants; - } - - private static int compareResultSerialize(SecureCompare.CompareResult result) - { - switch (result) { - case NOT_READY: return comparator_not_ready; - case NO_MATCH: return comparator_not_match; - case MATCH: return comparator_match; - default: return comparator_error; - } - } - private static WritableArray dataSerialize(byte[] data) - { - if (data == null) { - return null; - } - WritableArray result = new WritableNativeArray(); - for (byte datum : data) result.pushInt(datum); - - return result; - } - - private static byte[] dataDeserialize(ReadableArray serializedData) throws ByteOverflowException { - if (serializedData == null || serializedData.size() == 0) { - return null; - } - byte[] data = new byte[serializedData.size()]; - for (int i = 0; i < serializedData.size(); i++) { - if(serializedData.getInt(i) >= -128 && serializedData.getInt(i) <= 255) { - byte j = (byte) serializedData.getInt(i); - data[i] = j; - } else { - throw new ByteOverflowException("Value " + serializedData.getInt(i) + " is out of range"); - } - } - return data; - } - - @ReactMethod - public void stringSerialize(String text, - Callback callback) - { - byte[] data = text.getBytes(StandardCharsets.UTF_8); - WritableArray response = dataSerialize(data); - callback.invoke(response); - } - - @ReactMethod - public void keyPair(int algorithm, Callback callback) - { - Keypair pair; - switch (algorithm) { - case AsymmetricKey.KEYTYPE_RSA: - pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_RSA); - break; - default: - pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_EC); - } - - KeypairGenerator.generateKeypair(); - PrivateKey privateKey = pair.getPrivateKey(); - PublicKey publicKey = pair.getPublicKey(); - - WritableArray privateSerialized = dataSerialize(privateKey.toByteArray()); - WritableArray publicSerialized = dataSerialize(publicKey.toByteArray()); - - WritableMap response = new WritableNativeMap(); - response.putArray("private", privateSerialized); - response.putArray("public", publicSerialized); - - callback.invoke(response); - } - - @ReactMethod - public void symmetricKey(Callback callback) - { - SymmetricKey masterKey = new SymmetricKey(); - WritableArray response = dataSerialize(masterKey.toByteArray()); - callback.invoke(response); - } - - @ReactMethod - public void secureCellSealWithSymmetricKeyEncrypt(ReadableArray symmetricKey, - String plaintext, - String context, - Callback successCallback, - Callback errorCallback) - { - SecureCell.Seal cell = null; - try { - cell = SecureCell.SealWithKey(dataDeserialize(symmetricKey)); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - - byte[] txt = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - byte[] encrypted = cell.encrypt(txt, ctx); - WritableArray response = dataSerialize(encrypted); - successCallback.invoke(response); - } - - @ReactMethod - public void secureCellSealWithSymmetricKeyDecrypt(ReadableArray symmetricKey, - ReadableArray encrypted, - String context, - Callback successCallback, - Callback errorCallback) - { - SecureCell.Seal cell = null; - try { - cell = SecureCell.SealWithKey(dataDeserialize(symmetricKey)); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - - byte[] enc; - try { - enc = dataDeserialize(encrypted); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - try { - byte[] decrypted = cell.decrypt(enc, ctx); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (SecureCellException e) { - errorCallback.invoke(e.getMessage()); - } - - } - - @ReactMethod - public void secureCellSealWithPassphraseEncrypt(String passphrase, - String plaintext, - String context, - Callback callback) - { - SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); - byte[] txt = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - byte[] encrypted = cell.encrypt(txt, ctx); - WritableArray response = dataSerialize(encrypted); - callback.invoke(response); - } - - @ReactMethod - public void secureCellSealWithPassphraseDecrypt(String passphrase, + @NonNull + @Override + public String getName() { + return "Themis"; + } + + /* Replace JAVA enum version to equal with iOS version. */ + + @Override + public Map getConstants() { + final Map constants = new HashMap<>(); + constants.put("COMPARATOR_NOT_READY", comparator_not_ready); + constants.put("COMPARATOR_NOT_MATCH", comparator_not_match); + constants.put("COMPARATOR_MATCH", comparator_match); + constants.put("COMPARATOR_ERROR", comparator_error); + constants.put("KEYTYPE_RSA", AsymmetricKey.KEYTYPE_RSA); + constants.put("KEYTYPE_EC", AsymmetricKey.KEYTYPE_EC); + return constants; + } + + private static int compareResultSerialize(SecureCompare.CompareResult result) { + switch (result) { + case NOT_READY: + return comparator_not_ready; + case NO_MATCH: + return comparator_not_match; + case MATCH: + return comparator_match; + default: + return comparator_error; + } + } + + private static WritableArray dataSerialize(byte[] data) { + if (data == null) { + return null; + } + WritableArray result = new WritableNativeArray(); + for (byte datum : data) + result.pushInt(datum); + + return result; + } + + private static byte[] dataDeserialize(ReadableArray serializedData) throws ByteOverflowException { + if (serializedData == null || serializedData.size() == 0) { + return null; + } + byte[] data = new byte[serializedData.size()]; + for (int i = 0; i < serializedData.size(); i++) { + if (serializedData.getInt(i) >= 0 && serializedData.getInt(i) <= 255) { + byte j = (byte) serializedData.getInt(i); + data[i] = j; + } else { + throw new ByteOverflowException("Value " + serializedData.getInt(i) + " is out of range"); + } + } + return data; + } + + @ReactMethod + public void stringSerialize(String text, Callback callback) { + byte[] data = text.getBytes(StandardCharsets.UTF_8); + WritableArray response = dataSerialize(data); + callback.invoke(response); + } + + @ReactMethod + public void keyPair(int algorithm, Callback callback) { + Keypair pair; + + switch (algorithm) { + case AsymmetricKey.KEYTYPE_RSA: + pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_RSA); + break; + default: + pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_EC); + } + + KeypairGenerator.generateKeypair(); + PrivateKey privateKey = pair.getPrivateKey(); + PublicKey publicKey = pair.getPublicKey(); + + WritableArray privateSerialized = dataSerialize(privateKey.toByteArray()); + WritableArray publicSerialized = dataSerialize(publicKey.toByteArray()); + + WritableMap response = new WritableNativeMap(); + response.putArray("private", privateSerialized); + response.putArray("public", publicSerialized); + + callback.invoke(response); + } + + @ReactMethod + public void symmetricKey(Callback callback) { + SymmetricKey masterKey = new SymmetricKey(); + WritableArray response = dataSerialize(masterKey.toByteArray()); + callback.invoke(response); + } + + @ReactMethod + public void secureCellSealWithSymmetricKeyEncrypt(ReadableArray symmetricKey, + String plaintext, + String context, + Callback successCallback, + Callback errorCallback) { + + try { + byte[] key = dataDeserialize(symmetricKey); + SecureCell.Seal cell = SecureCell.SealWithKey(key); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); + WritableArray response = dataSerialize(encrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureCellSealWithSymmetricKeyDecrypt(ReadableArray symmetricKey, + ReadableArray encrypted, + String context, + Callback successCallback, + Callback errorCallback) { + + + try { + byte[] key = dataDeserialize(symmetricKey); + SecureCell.Seal cell = SecureCell.SealWithKey(key); + byte[] enc = dataDeserialize(encrypted); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureCellSealWithPassphraseEncrypt(String passphrase, + String plaintext, + String context, + Callback successCallback, + Callback errorCallback) { + + try { + SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); + WritableArray response = dataSerialize(encrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureCellSealWithPassphraseDecrypt(String passphrase, + ReadableArray encrypted, + String context, + Callback successCallback, + Callback errorCallback) { + + try { + SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); + byte[] enc = dataDeserialize(encrypted); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + /* MARK: Token protect mode */ + @ReactMethod + public void secureCellTokenProtectEncrypt(ReadableArray symmetricKey, + String plaintext, + String context, + Callback successCallback, + Callback errorCallback) { + try { + byte[] bkey = dataDeserialize(symmetricKey); + SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + SecureCellData result = cell.encrypt(plaintextBinary, contextBinary); + byte[] encrypted = result.getProtectedData(); + byte[] authToken = result.getAdditionalData(); + WritableMap response = new WritableNativeMap(); + response.putArray("encrypted", dataSerialize(encrypted)); + response.putArray("token", dataSerialize(authToken)); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureCellTokenProtectDecrypt(ReadableArray symmetricKey, ReadableArray encrypted, - String context, - Callback successCallback, - Callback errorCallback) - { - SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); - byte[] enc; - try { - enc = dataDeserialize(encrypted); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - try { - byte[] decrypted = cell.decrypt(enc, ctx); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (SecureCellException e) { - errorCallback.invoke(e.getMessage()); - } - } - - /* MARK: Token protect mode */ - @ReactMethod - public void secureCellTokenProtectEncrypt(ReadableArray symmetricKey, - String plaintext, - String context, - Callback successCallback, - Callback errorCallback) - { - byte[] bkey; - try { - bkey = dataDeserialize(symmetricKey); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; + ReadableArray token, + String context, + Callback successCallback, + Callback errorCallback) { + try { + byte[] bkey = dataDeserialize(symmetricKey); + byte[] enc = dataDeserialize(encrypted); + byte[] tkn = dataDeserialize(token); + SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, tkn, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } } - SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); - byte[] txt = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - SecureCellData result = cell.encrypt(txt, ctx); - byte[] encrypted = result.getProtectedData(); - byte[] authToken = result.getAdditionalData(); - - WritableMap response = new WritableNativeMap(); - response.putArray("encrypted", dataSerialize(encrypted)); - response.putArray("token", dataSerialize(authToken)); - - successCallback.invoke(response); - } - - @ReactMethod - public void secureCellTokenProtectDecrypt(ReadableArray symmetricKey, - ReadableArray encrypted, - ReadableArray token, - String context, - Callback successCallback, - Callback errorCallback) - { - byte[] bkey; - byte[] enc; - byte[] tkn; - try { - bkey = dataDeserialize(symmetricKey); - enc = dataDeserialize(encrypted); - tkn = dataDeserialize(token); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - - try { - byte[] decrypted = cell.decrypt(enc, tkn, ctx); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (SecureCellException e) { - errorCallback.invoke(e.getMessage()); - } - } /* Context imprint mode */ - - @ReactMethod - public void secureCellContextImprintEncrypt(ReadableArray symmetricKey, - String plaintext, - String context, - Callback successCallback, - Callback errorCallback) - { - if (context == null || context.length() == 0) { - errorCallback.invoke(contextRequired); - return; - } - - byte[] bkey; - try { - bkey = dataDeserialize(symmetricKey); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); - - byte[] txt = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - byte[] encrypted = cell.encrypt(txt, ctx); - - WritableArray response = dataSerialize(encrypted); - successCallback.invoke(response); - } - - @ReactMethod - public void secureCellContextImprintDecrypt(ReadableArray symmetricKey, - ReadableArray encrypted, - String context, - Callback successCallback, - Callback errorCallback) - { - if (context == null || context.length() == 0) { - errorCallback.invoke(contextRequired); - return; - } - - byte[] bkey; - byte[] enc; - try { - bkey = dataDeserialize(symmetricKey); - enc = dataDeserialize(encrypted); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); - - byte[] ctx = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, ctx); - - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } - - /* Secure Message */ - @ReactMethod - public void secureMessageSign(String message, - ReadableArray privateKey, - ReadableArray publicKey, + @ReactMethod + public void secureCellContextImprintEncrypt(ReadableArray symmetricKey, + String plaintext, + String context, + Callback successCallback, + Callback errorCallback) { + + if (context == null || context.length() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", contextRequired); + errorCallback.invoke(error); + return; + } + try { + byte[] bkey = dataDeserialize(symmetricKey); + SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); + WritableArray response = dataSerialize(encrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureCellContextImprintDecrypt(ReadableArray symmetricKey, + ReadableArray encrypted, + String context, + Callback successCallback, + Callback errorCallback) { + + + if (context == null || context.length() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", contextRequired); + errorCallback.invoke(error); + return; + } + + try { + byte[] bkey = dataDeserialize(symmetricKey); + byte[] enc = dataDeserialize(encrypted); + SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + /* Secure Message */ + @ReactMethod + public void secureMessageSign(String message, + ReadableArray privateKey, Callback successCallback, - Callback errorCallback) - { - if (privateKey == null || privateKey.size() == 0) { - errorCallback.invoke(privateKeyRequired); - return; - } - byte[] bkey; - try { - bkey = dataDeserialize(privateKey); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - PrivateKey pvtKey = new PrivateKey(bkey); - SecureMessage secureMessage; - byte[] msg = message.getBytes(StandardCharsets.UTF_8); - - if (publicKey == null ) { - secureMessage = new SecureMessage(pvtKey); - } else { - try { - bkey = dataDeserialize(publicKey); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - PublicKey pubKey = new PublicKey(bkey); - secureMessage = new SecureMessage(pvtKey,pubKey); - } - - try { - byte[] signedMessage = secureMessage.sign(msg); - WritableArray response = dataSerialize(signedMessage); - successCallback.invoke(response); - } catch (NullArgumentException | SecureMessageWrapException e) { - errorCallback.invoke(e.getMessage()); - } - - } - - @ReactMethod - public void secureMessageVerify(ReadableArray message, - ReadableArray privateKey, - ReadableArray publicKey, - Callback successCallback, - Callback errorCallback) - { - - if (publicKey == null || publicKey.size() == 0) { - errorCallback.invoke(publicKeyRequired); - return; - } - - byte[] bkey; - byte[] msg; - PrivateKey pvtKey; - PublicKey pubKey; - try { - bkey = dataDeserialize(publicKey); - pubKey = new PublicKey(bkey); - msg = dataDeserialize(message); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - - SecureMessage secureMessage; - - if ( privateKey == null || privateKey.size() == 0) { - secureMessage = new SecureMessage(pubKey); - } else { - try { - bkey = dataDeserialize(privateKey); - pvtKey = new PrivateKey(bkey); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - - secureMessage = new SecureMessage(pvtKey, pubKey); - } - try { - byte[] verifiedMessage = secureMessage.verify(msg, pubKey); - WritableArray response = dataSerialize(verifiedMessage); - successCallback.invoke(response); - } catch (NullArgumentException | SecureMessageWrapException e) { - errorCallback.invoke(e.getMessage()); - } - } - - @ReactMethod - public void secureMessageEncrypt(String message, - ReadableArray privateKey, - ReadableArray publicKey, - Callback successCallback, - Callback errorCallback) - { - - if ( privateKey == null || privateKey.size() == 0) { - errorCallback.invoke(privateKeyRequired); - return; - } - if ( publicKey == null || publicKey.size() == 0 ) { - errorCallback.invoke(publicKeyRequired); - return; - } - - byte[] bkey; - PrivateKey pvtKey; - PublicKey pubKey; - try { - bkey = dataDeserialize(privateKey); - pvtKey = new PrivateKey(bkey); - bkey = dataDeserialize(publicKey); - pubKey = new PublicKey(bkey); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - - byte[] msg = message.getBytes(StandardCharsets.UTF_8); - - SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); - try { - byte[] encrypted = secureMessage.wrap(msg, pubKey); - WritableArray response = dataSerialize(encrypted); - successCallback.invoke(response); - } catch (NullArgumentException | SecureMessageWrapException e) { - errorCallback.invoke(e.getMessage()); - } - } - - @ReactMethod - public void secureMessageDecrypt(ReadableArray message, - ReadableArray privateKey, - ReadableArray publicKey, + Callback errorCallback) { + + if (privateKey == null || privateKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", privateKeyRequired); + errorCallback.invoke(error); + return; + } + + try { + byte[] bkey = dataDeserialize(privateKey); + PrivateKey pvtKey = new PrivateKey(bkey); + byte[] msg = message.getBytes(StandardCharsets.UTF_8); + SecureMessage secureMessage = new SecureMessage(pvtKey); + byte[] signedMessage = secureMessage.sign(msg); + WritableArray response = dataSerialize(signedMessage); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureMessageVerify(ReadableArray message, + ReadableArray publicKey, + Callback successCallback, + Callback errorCallback) { + + if (publicKey == null || publicKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", publicKeyRequired); + errorCallback.invoke(error); + return; + } + + try { + byte[] bkey = dataDeserialize(publicKey); + PublicKey pubKey = new PublicKey(bkey); + byte[] msg = dataDeserialize(message); + SecureMessage secureMessage = new SecureMessage(pubKey); + byte[] verifiedMessage = secureMessage.verify(msg, pubKey); + WritableArray response = dataSerialize(verifiedMessage); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureMessageEncrypt(String message, + ReadableArray privateKey, + ReadableArray publicKey, Callback successCallback, - Callback errorCallback) - { - - if ( privateKey == null || privateKey.size() == 0) { - errorCallback.invoke(privateKeyRequired); - return; - } - if ( publicKey == null || publicKey.size() == 0 ) { - errorCallback.invoke(publicKeyRequired); - return; - } - - byte[] bkey; - byte[] msg; - PrivateKey pvtKey; - PublicKey pubKey; - try { - bkey = dataDeserialize(privateKey); - pvtKey = new PrivateKey(bkey); - bkey = dataDeserialize(publicKey); - pubKey = new PublicKey(bkey); - msg = dataDeserialize(message); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - - SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); - try { - byte[] decrypted = secureMessage.unwrap(msg, pubKey); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (NullArgumentException | SecureMessageWrapException e) { - errorCallback.invoke(e.getMessage()); - } - } - - @ReactMethod - public void initComparator(ReadableArray sharedSecret, - Callback successCallback, - Callback errorCallback) - { - byte[] sharedSecretData; - try { - sharedSecretData = dataDeserialize(sharedSecret); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - SecureCompare cmp = new SecureCompare(sharedSecretData); - final String uuid = UUID.randomUUID().toString(); - cmprs.put(uuid, cmp); - successCallback.invoke(uuid); - } - - @ReactMethod - public void statusOfComparator(String uuid, - Callback callback) - { - SecureCompare cmp = cmprs.get(uuid); - if (cmp == null) { - callback.invoke(comparator_error); - } else { - SecureCompare.CompareResult result = cmp.getResult(); - int status = compareResultSerialize(result); - callback.invoke(status); - } - } - - @ReactMethod - public void beginCompare(String uuid, + Callback errorCallback) { + + if (privateKey == null || privateKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", privateKeyRequired); + errorCallback.invoke(error); + return; + } + + if (publicKey == null || publicKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", publicKeyRequired); + errorCallback.invoke(error); + return; + } + + try { + byte[] bkey = dataDeserialize(privateKey); + PrivateKey pvtKey = new PrivateKey(bkey); + bkey = dataDeserialize(publicKey); + PublicKey pubKey = new PublicKey(bkey); + byte[] msg = message.getBytes(StandardCharsets.UTF_8); + SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); + byte[] encryptedMessage = secureMessage.wrap(msg); + WritableArray response = dataSerialize(encryptedMessage); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureMessageDecrypt(ReadableArray message, + ReadableArray privateKey, + ReadableArray publicKey, + Callback successCallback, + Callback errorCallback) { + + if (privateKey == null || privateKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", privateKeyRequired); + errorCallback.invoke(error); + return; + } + if (publicKey == null || publicKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", publicKeyRequired); + errorCallback.invoke(error); + return; + } + + try { + byte[] bkey = dataDeserialize(privateKey); + PrivateKey pvtKey = new PrivateKey(bkey); + bkey = dataDeserialize(publicKey); + PublicKey pubKey = new PublicKey(bkey); + byte[] msg = dataDeserialize(message); + SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); + byte[] decrypted = secureMessage.unwrap(msg, pubKey); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void initComparator(ReadableArray sharedSecret, + Callback successCallback, + Callback errorCallback) { + + try { + byte[] sharedSecretData = dataDeserialize(sharedSecret); + SecureCompare cmp = new SecureCompare(sharedSecretData); + final String uuid = UUID.randomUUID().toString(); + cmprs.put(uuid, cmp); + successCallback.invoke(uuid); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void statusOfComparator(String uuid, + Callback callback) { + + SecureCompare cmp = cmprs.get(uuid); + if (cmp == null) { + callback.invoke(comparator_error); + } else { + SecureCompare.CompareResult result = cmp.getResult(); + int status = compareResultSerialize(result); + callback.invoke(status); + } + } + + @ReactMethod + public void beginCompare(String uuid, Callback successCallback, - Callback errorCallback) - { - SecureCompare cmp = cmprs.get(uuid); - if (cmp == null) { - errorCallback.invoke(comparator_error); - } else { - byte[] data = cmp.begin(); - WritableArray response = dataSerialize(data); - successCallback.invoke(response); - } - } + Callback errorCallback) { - @ReactMethod - public void proceedCompare(String uuid, - ReadableArray previous, - Callback successCallback, - Callback errorCallback) - { - SecureCompare cmp = cmprs.get(uuid); - if (cmp == null) { - errorCallback.invoke(comparator_error); - return; + SecureCompare cmp = cmprs.get(uuid); + if (cmp == null) { + errorCallback.invoke(comparator_error); + } else { + byte[] data = cmp.begin(); + WritableArray response = dataSerialize(data); + successCallback.invoke(response); + } } - byte[] data; - try { - data = dataDeserialize(previous); - } catch (ByteOverflowException e) { - errorCallback.invoke(e.getMessage()); - return; - } - try { - data = cmp.proceed(data); - WritableArray response = dataSerialize(data); - SecureCompare.CompareResult result = cmp.getResult(); - int status = compareResultSerialize(result); - if (result != SecureCompare.CompareResult.NOT_READY) { - cmprs.remove(uuid); - } - successCallback.invoke(response, status); - } catch (SecureCompareException e) { - errorCallback.invoke(e.getMessage()); + @ReactMethod + public void proceedCompare(String uuid, + ReadableArray previous, + Callback successCallback, + Callback errorCallback) { + + SecureCompare cmp = cmprs.get(uuid); + if (cmp == null) { + errorCallback.invoke(comparator_error); + return; + } + + try { + byte[] data = dataDeserialize(previous); + data = cmp.proceed(data); + WritableArray response = dataSerialize(data); + SecureCompare.CompareResult result = cmp.getResult(); + int status = compareResultSerialize(result); + if (result != SecureCompare.CompareResult.NOT_READY) { + cmprs.remove(uuid); + } + successCallback.invoke(response, status); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } } - } - } diff --git a/src/wrappers/themis/react-native-themis/android/src/main/main.iml b/src/wrappers/themis/react-native-themis/android/src/main/main.iml new file mode 100644 index 000000000..908ad4f52 --- /dev/null +++ b/src/wrappers/themis/react-native-themis/android/src/main/main.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/wrappers/themis/react-native-themis/ios/RCTThemis.h b/src/wrappers/themis/react-native-themis/ios/RCTThemis.h index b9a884ed9..32829b570 100644 --- a/src/wrappers/themis/react-native-themis/ios/RCTThemis.h +++ b/src/wrappers/themis/react-native-themis/ios/RCTThemis.h @@ -10,19 +10,23 @@ #import -#define BYTEOVERFLOW 255 -#define CONTEXTREQUIRED 254 -#define PUBLICKEYREQUIRED 253 -#define PRIVATEKEYREQUIRED 252 - +#define BYTEOVERFLOW 255 +#define CONTEXTREQUIRED 254 +#define PUBLICKEYREQUIRED 253 +#define PRIVATEKEYREQUIRED 252 +#define DESERIALIZE_ERROR 251 +#define DESERIALIZE_MEMORY 250 + +#define BYTEOVERFLOWREASON "Byte overflow: value is out of range" #define CONTEXTREQUIREDREASON "Context required" #define PUBLICKEYREQUIREDREASON "Public key can not be null or blank" #define PRIVATEKEYREQUIREDREASON "Private key can not be null or blank" +#define DESERIALIZE_ERRORREASON "Deserialize error: empty input data" +#define DESERIALIZE_MEMORYREASON "Deserialize error: can not allocate memory" -#define KEYTYPE_EC 0 +#define KEYTYPE_EC 0 #define KEYTYPE_RSA 1 - @interface RCTThemis : NSObject @end diff --git a/src/wrappers/themis/react-native-themis/ios/RCTThemis.m b/src/wrappers/themis/react-native-themis/ios/RCTThemis.m index ebf197a8e..efb2665a9 100644 --- a/src/wrappers/themis/react-native-themis/ios/RCTThemis.m +++ b/src/wrappers/themis/react-native-themis/ios/RCTThemis.m @@ -18,11 +18,17 @@ @implementation RCTThemis // To save the comparators objects NSMutableDictionary* cmprs; +NSNumber *uchar_min; +NSNumber *uchar_max; + - (instancetype)init { - self = [super init]; - cmprs = [[NSMutableDictionary alloc] init]; - return self; + self = [super init]; + cmprs = [[NSMutableDictionary alloc] init]; + uchar_min = [NSNumber numberWithInt:0]; + uchar_max = [NSNumber numberWithInt:255]; + + return self; } /* MARK: Export constants of the module */ @@ -37,7 +43,7 @@ - (NSDictionary *)constantsToExport }; } -// It required by constantsToExport and iOS +// It required by constantsToExport and iOS + (BOOL)requiresMainQueueSetup { return YES; @@ -50,16 +56,16 @@ + (BOOL)requiresMainQueueSetup + (NSArray*)dataSerialize:(NSData*) data { - if (data == nil) return nil; - - const char* buffer = (const char*) data.bytes; - NSMutableArray *array = [[NSMutableArray alloc] init]; - - for (NSInteger i = 0; i < data.length; i++) { - NSNumber *num = [[NSNumber alloc] initWithUnsignedChar: buffer[i]]; - [array addObject:num]; - } - return [array copy]; + if (data == nil || data.length == 0 ) return nil; + + const char* buffer = (const char*) data.bytes; + NSMutableArray *array = [[NSMutableArray alloc] init]; + + for (NSInteger i = 0; i < data.length; i++) { + NSNumber *num = [[NSNumber alloc] initWithUnsignedChar: buffer[i]]; + [array addObject:num]; + } + return [array copy]; } /*************************************************/ @@ -67,114 +73,114 @@ + (NSArray*)dataSerialize:(NSData*) data /* NSData <-- NSArray[NSNumber(unsigned char)] */ /* */ - -+ (NSData*)dataDeserialize:(NSArray*) data ++ (NSData*)dataDeserialize: (NSArray*) data error:(NSError**) error { - if (data == nil) return nil; - - char* buffer = (char*)malloc(data.count); - if (buffer == nil) { - return nil; // malloc returns nil - } - - for (NSInteger i = 0; i < data.count; i++) { - NSNumber *num = data[i]; - const unsigned char c = num.unsignedCharValue; - if (c < 0 || c > 255) { - NSException *e = [NSException - exceptionWithName:@"ByteOverflowException" - reason:@"Value is out of range" - userInfo:nil]; - @throw e; - } - buffer[i] = c; - } - - NSData *result = [NSData dataWithBytesNoCopy:buffer length:data.count freeWhenDone:YES]; - - return result; + + if ( data == nil || data.count == 0 ) { + *error = SCERROR(DESERIALIZE_ERROR, @DESERIALIZE_ERRORREASON); + return nil; + } + + char* buffer = (char*)malloc(data.count); + + if (buffer == nil) { + *error = SCERROR(DESERIALIZE_MEMORY, @DESERIALIZE_MEMORYREASON); + return nil; + } + + for (NSInteger i = 0; i < data.count; i++) { + NSNumber *num = data[i]; + /* Check int value before casting to char */ + if ([num compare:uchar_min] == NSOrderedAscending || [num compare:uchar_max] == NSOrderedDescending) { + free(buffer); // did not forget to free allocated memory + *error = SCERROR(BYTEOVERFLOW, @BYTEOVERFLOWREASON); + return nil; + } + buffer[i] = num.unsignedCharValue; + } + NSData *result = [NSData dataWithBytesNoCopy:buffer length:data.count freeWhenDone:YES]; + return result; } RCT_EXPORT_METHOD(stringSerialize:(NSString*) text callback:(RCTResponseSenderBlock)callback ) { - NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]; + NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]; NSArray *data2 = [RCTThemis dataSerialize: data]; - callback(@[data2]); + callback(@[data2]); } RCT_EXPORT_METHOD(keyPair:(nonnull NSNumber*) algorithm - callback:(RCTResponseSenderBlock)callback) + successCallback: (RCTResponseSenderBlock)successCallback + ) { - TSKeyGen *keypair; - switch (algorithm.intValue) { - case KEYTYPE_RSA: - keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmRSA]; - break; - default: - keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmEC]; - break; - } - - NSArray *privateKey = [RCTThemis dataSerialize: keypair.privateKey]; - NSArray *publicKey = [RCTThemis dataSerialize: keypair.publicKey]; - - NSDictionary *dictionary = @{ - @"private" : privateKey, - @"public" : publicKey - }; - callback(@[dictionary]); + TSKeyGen *keypair; + switch (algorithm.intValue) { + case KEYTYPE_RSA: + keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmRSA]; + break; + default: + keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmEC]; + break; + } + + NSArray *privateKey = [RCTThemis dataSerialize: keypair.privateKey]; + NSArray *publicKey = [RCTThemis dataSerialize: keypair.publicKey]; + + NSDictionary *dictionary = @{ + @"private" : privateKey, + @"public" : publicKey + }; + successCallback(@[dictionary]); } RCT_EXPORT_METHOD(symmetricKey:(RCTResponseSenderBlock)callback) { - NSData *symmetricKey = TSGenerateSymmetricKey(); + NSData *symmetricKey = TSGenerateSymmetricKey(); NSArray *masterKey = [RCTThemis dataSerialize: symmetricKey]; - callback(@[masterKey]); + callback(@[masterKey]); } -- (TSCellSeal *)newSealMode: (NSArray*) symmetricKey +- (TSCellSeal *)newSealMode: (NSArray*) symmetricKey error:(NSError**) error { - @try { - NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey]; + NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; + if (masterKey == nil) { + return nil; + } TSCellSeal *cell = [[TSCellSeal alloc] initWithKey:masterKey]; return cell; - } - @catch (NSException *e) { - @throw e; // rethrow to catch in final function - } - } - - - RCT_EXPORT_METHOD(secureCellSealWithSymmetricKeyEncrypt:(NSArray*) symmetricKey plaintext: (NSString*)plaintext context: (NSString*)context successCallback: (RCTResponseSenderBlock)successCallback errorCallback: (RCTResponseErrorBlock)errorCallback) { + TSCellSeal *cell; + NSError *error; - TSCellSeal *cell; - @try { - cell = [self newSealMode:symmetricKey]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - NSData *txt = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encrypted = [cell encrypt:txt context:ctx]; - NSArray *result = [RCTThemis dataSerialize:encrypted]; - successCallback(@[result]); + cell = [self newSealMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *encrypted = [cell encrypt:plaintextBinary + context:contextBinary + error:&error]; + if (encrypted == nil) { + errorCallback(error); + return; + } + NSArray *result = [RCTThemis dataSerialize:encrypted]; + successCallback(@[result]); } RCT_EXPORT_METHOD(secureCellSealWithSymmetricKeyDecrypt:(NSArray*) symmetricKey @@ -185,57 +191,64 @@ - (TSCellSeal *)newSealMode: (NSArray*) symmetricKey ) { - TSCellSeal *cell; - NSData *enc; - - @try { - cell = [self newSealMode:symmetricKey]; - enc = [RCTThemis dataDeserialize:encrypted]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - - NSError *error; - NSData *decrypted = [cell decrypt:enc - context:ctx - error:&error]; - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); - } - + TSCellSeal *cell; + NSData *enc; + NSError *error; + + cell = [self newSealMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + context:contextBinary + error:&error]; + if (decrypted == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); + } + } - (TSCellSeal *)newSealModeWithPassphrase: (NSString*) passphrase { - TSCellSeal *cell = [[TSCellSeal alloc] initWithPassphrase: passphrase]; - return cell; + TSCellSeal *cell = [[TSCellSeal alloc] initWithPassphrase: passphrase]; + return cell; } RCT_EXPORT_METHOD(secureCellSealWithPassphraseEncrypt:(NSString*) passphrase plaintext: (NSString*)plaintext context: (NSString*)context - callback: (RCTResponseSenderBlock)callback) + successCallback: (RCTResponseSenderBlock)successCallback + errorCallback: (RCTResponseErrorBlock)errorCallback + ) { - TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; - - NSData *txt = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encrypted = [cell encrypt:txt context:ctx]; - - NSArray *result = [RCTThemis dataSerialize:encrypted]; + TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + + NSError *error; + NSData *encrypted = [cell encrypt:plaintextBinary context:contextBinary error:&error]; - callback(@[result]); + if (encrypted == nil) { + errorCallback(error); + } else { + NSArray *result = [RCTThemis dataSerialize:encrypted]; + successCallback(@[result]); + } } RCT_EXPORT_METHOD(secureCellSealWithPassphraseDecrypt:(NSString*) passphrase @@ -246,43 +259,39 @@ - (TSCellSeal *)newSealModeWithPassphrase: (NSString*) passphrase ) { - TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; - NSData *enc; - - @try { - enc = [RCTThemis dataDeserialize:encrypted]; - } @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - } - - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - - NSError *error; - NSData *decrypted = [cell decrypt:enc - context:ctx - error:&error]; - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); - } - + TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; + NSData *enc; + NSError *error; + + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + context:contextBinary + error:&error]; + if (decrypted == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); + } } /* MARK: Token protect mode */ -- (TSCellToken *)newTokenMode:(NSArray*) symmetricKey +- (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error { - @try { - NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey]; + NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; + if (masterKey == nil) { + return nil; + } + TSCellToken *cell = [[TSCellToken alloc] initWithKey:masterKey]; return cell; - } - @catch (NSException *e) { - @throw e; - } } RCT_EXPORT_METHOD(secureCellTokenProtectEncrypt:(NSArray*) symmetricKey @@ -291,30 +300,32 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey successCallback: (RCTResponseSenderBlock)successCallback errorCallback: (RCTResponseErrorBlock)errorCallback) { - - TSCellToken *cell; - - @try { - cell = [self newTokenMode:symmetricKey]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - NSData *txt = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - TSCellTokenEncryptedResult *result = [cell encrypt:txt context:ctx]; - - NSArray *encrypted = [RCTThemis dataSerialize: result.encrypted]; - NSArray *token = [RCTThemis dataSerialize: result.token]; - - NSDictionary *dictionary = @{ - @"encrypted" : encrypted, - @"token" : token - }; - successCallback(@[dictionary]); + NSError *error; + TSCellToken *cell; + + cell = [self newTokenMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + + TSCellTokenEncryptedResult *result = [cell encrypt:plaintextBinary context:contextBinary error:&error]; + if (result == nil ) { + errorCallback(error); + return; + } + + NSArray *encrypted = [RCTThemis dataSerialize: result.encrypted]; + NSArray *token = [RCTThemis dataSerialize: result.token]; + + NSDictionary *dictionary = @{ + @"encrypted" : encrypted, + @"token" : token + }; + successCallback(@[dictionary]); } RCT_EXPORT_METHOD(secureCellTokenProtectDecrypt:(NSArray*) symmetricKey @@ -326,50 +337,54 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey ) { - TSCellToken *cell; - NSData *enc; - NSData *tkn; - - @try { - cell = [self newTokenMode:symmetricKey]; - enc = [RCTThemis dataDeserialize:encrypted]; - tkn = [RCTThemis dataDeserialize:token]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - - NSError *error; - NSData *decrypted = [cell decrypt:enc - token:tkn - context:ctx - error:&error]; - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); - } - + TSCellToken *cell; + NSData *enc; + NSData *tkn; + NSError *error; + + cell = [self newTokenMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + tkn = [RCTThemis dataDeserialize:token error:&error]; + if (tkn == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + token:tkn + context:contextBinary + error:&error]; + if (decrypted == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); + } + } /* MARK: Context imprint mode */ -- (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey +- (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSError**) error { - @try { - NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey]; + NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; + if (masterKey == nil) { + return nil; + } TSCellContextImprint *cell = [[TSCellContextImprint alloc] initWithKey:masterKey]; return cell; - } - @catch (NSException *e) { - @throw e; - } } RCT_EXPORT_METHOD(secureCellContextImprintEncrypt:(NSArray*) symmetricKey @@ -378,30 +393,31 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey successCallback: (RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseErrorBlock)errorCallback) { - if (context == nil || [context isEqual: @""]) { - NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); - errorCallback(error); - return; - } - - TSCellContextImprint *cell; - @try { - cell = [self newContextImprint:symmetricKey]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - - NSData *txt = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encrypted = [cell encrypt:txt context:ctx]; - - NSArray *result = [RCTThemis dataSerialize:encrypted]; - - successCallback(@[result]); + if (context == nil || [context isEqual: @""]) { + NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); + errorCallback(error); + return; + } + + TSCellContextImprint *cell; + NSError *error; + + cell = [self newContextImprint:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *encrypted = [cell encrypt:plaintextBinary context:contextBinary error:&error]; + if (encrypted == nil) { + errorCallback(error); + return; + } + + NSArray *result = [RCTThemis dataSerialize:encrypted]; + successCallback(@[result]); } RCT_EXPORT_METHOD(secureCellContextImprintDecrypt:(NSArray*) symmetricKey @@ -410,117 +426,118 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey successCallback:(RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseErrorBlock)errorCallback) { - - if (context == nil || [context isEqual: @""]) { - NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); - errorCallback(error); - return; - } - - TSCellContextImprint *cell; - NSData *enc; - @try { - cell = [self newContextImprint:symmetricKey]; - enc = [RCTThemis dataDeserialize:encrypted]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - NSData *ctx = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc - context:ctx]; - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); + + if (context == nil || [context isEqual: @""]) { + NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); + errorCallback(error); + return; + } + + TSCellContextImprint *cell; + NSData *enc; + NSError *error; + + cell = [self newContextImprint:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + context:contextBinary + error:&error + ]; + + if (decrypted == nil) { + errorCallback(error); + return; + } + + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); } /* MARK: Secure Message */ RCT_EXPORT_METHOD(secureMessageSign:(NSString*) message privateKey:(NSArray*) privateKey - publicKey:(NSArray*) publicKey successCallback:(RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseErrorBlock) errorCallback ) { - - if (privateKey == nil || privateKey.count == 0) { - NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData* pvtKey; - NSData* pubKey; - @try { - pvtKey = [RCTThemis dataDeserialize:privateKey]; - pubKey = [RCTThemis dataDeserialize:publicKey]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; - - TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; - - NSError *error; - NSData *signedMessage = [secureMessage wrapData:msg error:&error]; - - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:signedMessage]; - successCallback(@[result]); - } + if (privateKey == nil || privateKey.count == 0) { + NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pvtKey; + NSError *error; + + pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; + if (pvtKey == nil) { + errorCallback(error); + return; + } + + NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; + TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:pvtKey + peerPublicKey:nil]; + + NSData *signedMessage = [secureMessage wrapData:msg error:&error]; + if (signedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:signedMessage]; + successCallback(@[result]); + } } RCT_EXPORT_METHOD(secureMessageVerify:(NSArray*) message - privateKey:(NSArray*) privateKey publicKey:(NSArray*) publicKey successCallback:(RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseErrorBlock)errorCallback ) { - if (publicKey == nil || publicKey.count == 0) { - NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData* pvtKey; - NSData* pubKey; - NSData* msg; - - @try { - pvtKey = [RCTThemis dataDeserialize:privateKey]; - pubKey = [RCTThemis dataDeserialize:publicKey]; - msg = [RCTThemis dataDeserialize:message]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; - - NSError *error; - - NSData *verifiedMessage = [secureMessage unwrapData:msg error:&error]; - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:verifiedMessage]; - successCallback(@[result]); - } + if (publicKey == nil || publicKey.count == 0) { + NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pubKey; + NSData *msg; + NSError *error; + + pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; + if (pubKey == nil) { + errorCallback(error); + return; + } + + msg = [RCTThemis dataDeserialize:message error:&error]; + if (msg == nil) { + errorCallback(error); + return; + } + + TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:nil + peerPublicKey:pubKey]; + + NSData *verifiedMessage = [secureMessage unwrapData:msg error:&error]; + if (verifiedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:verifiedMessage]; + successCallback(@[result]); + } } RCT_EXPORT_METHOD(secureMessageEncrypt:(NSString*) message @@ -531,47 +548,46 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey ) { - - if (privateKey == nil || privateKey.count == 0) { - NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); - errorCallback(error); - return; - } - - if (publicKey == nil || publicKey.count == 0) { - NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData* pvtKey; - NSData* pubKey; - - @try { - pvtKey = [RCTThemis dataDeserialize:privateKey]; - pubKey = [RCTThemis dataDeserialize:publicKey]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; - - TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; - - NSError *error; - NSData *encryptedMessage = [secureMessage wrapData:msg error:&error]; - - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:encryptedMessage]; - successCallback(@[result]); - } - + + if (privateKey == nil || privateKey.count == 0) { + NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); + errorCallback(error); + return; + } + + if (publicKey == nil || publicKey.count == 0) { + NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pvtKey; + NSData *pubKey; + NSError *error; + + pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; + if (pvtKey == nil) { + errorCallback(error); + return; + } + pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; + if (pubKey == nil) { + errorCallback(error); + return; + } + + NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; + TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey + peerPublicKey:pubKey]; + + NSData *encryptedMessage = [secureMessage wrapData:msg error:&error]; + if (encryptedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:encryptedMessage]; + successCallback(@[result]); + } + } RCT_EXPORT_METHOD(secureMessageDecrypt:(NSArray*) message @@ -581,47 +597,51 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey errorCallback:(RCTResponseErrorBlock) errorCallback ) { - - if (privateKey == nil || privateKey.count == 0) { - NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); - errorCallback(error); - return; - } - - if (publicKey == nil || publicKey.count == 0) { - NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData* pvtKey; - NSData* pubKey; - NSData* msg; - - @try { - pvtKey = [RCTThemis dataDeserialize:privateKey]; - pubKey = [RCTThemis dataDeserialize:publicKey]; - msg = [RCTThemis dataDeserialize:message]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - - TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; - - NSError *error; - NSData *decryptedMessage = [secureMessage unwrapData:msg error:&error]; - - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decryptedMessage]; - successCallback(@[result]); - } - + + if (privateKey == nil || privateKey.count == 0) { + NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); + errorCallback(error); + return; + } + + if (publicKey == nil || publicKey.count == 0) { + NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pvtKey; + NSData *pubKey; + NSData *msg; + NSError *error; + + pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; + if (pvtKey == nil) { + errorCallback(error); + return; + } + pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; + if (pubKey == nil) { + errorCallback(error); + return; + } + msg = [RCTThemis dataDeserialize:message error:&error]; + if (msg == nil) { + errorCallback(error); + return; + } + + TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey + peerPublicKey:pubKey]; + + NSData *decryptedMessage = [secureMessage unwrapData:msg error:&error]; + if (decryptedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decryptedMessage]; + successCallback(@[result]); + } + } /* MARK: Comparator */ @@ -630,33 +650,31 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey successCallback:(RCTResponseSenderBlock) successCallback errorCallback:(RCTResponseErrorBlock) errorCallback) { - NSData* sharedSecretData; - - @try { - sharedSecretData = [RCTThemis dataDeserialize:sharedSecret]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - TSComparator* cmp = [[TSComparator alloc] initWithMessageToCompare:sharedSecretData]; - NSString *uuid = [[NSUUID UUID] UUIDString]; - cmprs[uuid] = cmp; - successCallback(@[uuid]); + NSData *sharedSecretData; + NSError *error; + sharedSecretData = [RCTThemis dataDeserialize:sharedSecret error:&error]; + if (sharedSecretData == nil) { + errorCallback(error); + return; + } + + TSComparator* cmp = [[TSComparator alloc] initWithMessageToCompare:sharedSecretData]; + NSString *uuid = [[NSUUID UUID] UUIDString]; + cmprs[uuid] = cmp; + successCallback(@[uuid]); } RCT_EXPORT_METHOD(statusOfComparator:(NSString*) uuid successCallback:(RCTResponseSenderBlock) successCallback ) { - TSComparator* cmp = cmprs[uuid]; - if (cmp == nil) { - successCallback(@[@-1]); - } else { - NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; - successCallback(@[status]); - } + TSComparator* cmp = cmprs[uuid]; + if (cmp == nil) { + successCallback(@[@-1]); + } else { + NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; + successCallback(@[status]); + } } @@ -666,59 +684,62 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey errorCallback:(RCTResponseErrorBlock) errorCallback ) { - - TSComparator* cmp = cmprs[uuid]; - if (cmp == nil) { - errorCallback(nil); - return; - } - NSError* error; - - NSData* data = [cmp beginCompare:&error]; - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:data]; - successCallback(@[result]); - } + + TSComparator *cmp = cmprs[uuid]; + if (cmp == nil) { + errorCallback(nil); + return; + } + NSError *error; + + NSData *data = [cmp beginCompare:&error]; + if (data == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:data]; + successCallback(@[result]); + } } + RCT_EXPORT_METHOD(proceedCompare:(NSString*) uuid previous:(NSArray*) previous successCallback:(RCTResponseSenderBlock) successCallback errorCallback:(RCTResponseErrorBlock) errorCallback ) { - TSComparator* cmp = cmprs[uuid]; - if ( cmp == nil ) { - errorCallback(nil); - return; - } - - NSData* data; - - @try { - data = [RCTThemis dataDeserialize:previous]; - } - @catch (NSException *e) { - NSError* error = SCERROR(BYTEOVERFLOW, e.reason); - errorCallback(error); - return; - } - NSError* error; - - data = [cmp proceedCompare:data error:&error]; - if (error) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:data]; - NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; - if (cmp.status != TSComparatorNotReady) { - [cmprs removeObjectForKey:uuid]; - } - successCallback(@[result, status]); - } - + + TSComparator* cmp = cmprs[uuid]; + if ( cmp == nil ) { + NSError* error = SCERROR(-1, @"Comparator does not exist"); + errorCallback(error); + return; + } + + NSData *data; + NSError *error; + + data = [RCTThemis dataDeserialize:previous error:&error]; + if (data == nil) { + errorCallback(error); + return; + } + + data = [cmp proceedCompare:data error:&error]; + if (data == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:data]; + NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; + if (cmp.status != TSComparatorNotReady) { + [cmprs removeObjectForKey:uuid]; + } + if (result != nil) { + successCallback(@[result, status]); + } else { + successCallback(@[@"", status]); + } + } } diff --git a/src/wrappers/themis/react-native-themis/package.json b/src/wrappers/themis/react-native-themis/package.json index 330b6fade..92cb2b817 100644 --- a/src/wrappers/themis/react-native-themis/package.json +++ b/src/wrappers/themis/react-native-themis/package.json @@ -1,6 +1,6 @@ { "name": "react-native-themis", - "version": "0.14.7", + "version": "0.14.10", "description": "Themis React Native is a convenient cryptographic library for data protection", "react-native": "src/index", "source": "src/index", @@ -21,7 +21,8 @@ ], "scripts": { "test": "jest", - "typescript": "tsc --noEmit", + "typescript": "tsc", + "declaration": "tsc --declaration --emitDeclarationOnly", "lint": "eslint \"**/*.{js,ts,tsx}\"", "prepare": "bob build", "release": "release-it" diff --git a/src/wrappers/themis/react-native-themis/src/index.d.ts b/src/wrappers/themis/react-native-themis/src/index.d.ts index 380c88515..b1cfc7995 100644 --- a/src/wrappers/themis/react-native-themis/src/index.d.ts +++ b/src/wrappers/themis/react-native-themis/src/index.d.ts @@ -1,5 +1,7 @@ export declare const COMPARATOR_NOT_READY: any, COMPARATOR_NOT_MATCH: any, COMPARATOR_MATCH: any, COMPARATOR_ERROR: any, KEYTYPE_RSA: any, KEYTYPE_EC: any; -export declare function keyPair64(typeOfKey: any): Promise; +export declare function isBase64(str: String): boolean; +export declare function string64(input: String): String; +export declare function keyPair64(typeOfKey?: any): Promise; export declare function symmetricKey64(): Promise; export declare function secureCellSealWithSymmetricKeyEncrypt64(symmetricKey64: String, plaintext: String, context?: String): Promise; export declare function secureCellSealWithSymmetricKeyDecrypt64(symmetricKey64: String, encrypted64: String, context?: String): Promise; @@ -9,11 +11,10 @@ export declare function secureCellTokenProtectEncrypt64(symmetricKey64: String, export declare function secureCellTokenProtectDecrypt64(symmetricKey64: String, encrypted64: String, token64: String, context?: String): Promise; export declare function secureCellContextImprintEncrypt64(symmetricKey64: String, plaintext: String, context: String): Promise; export declare function secureCellContextImprintDecrypt64(symmetricKey64: String, encrypted64: String, context: String): Promise; -export declare function secureMessageSign64(plaintext: String, privateKey64: String, publicKey64: String): Promise; -export declare function secureMessageVerify64(signed64: String, privateKey64: String, publicKey64: String): Promise; +export declare function secureMessageSign64(plaintext: String, privateKey64: String, _publicKey64?: String): Promise; +export declare function secureMessageVerify64(signed64: String, _privateKey64: String | undefined, publicKey64: String): Promise; export declare function secureMessageEncrypt64(plaintext: String, privateKey64: String, publicKey64: String): Promise; export declare function secureMessageDecrypt64(encrypted64: String, privateKey64: String, publicKey64: String): Promise; -export declare function string64(input: String): String; export declare function comparatorInit64(data64: String): Promise; export declare function comparatorBegin(uuidStr: String): Promise; export declare function comparatorProceed64(uuidStr: String, data64: String): Promise; diff --git a/src/wrappers/themis/react-native-themis/src/index.js b/src/wrappers/themis/react-native-themis/src/index.js index 0cf72885f..c5351d3c3 100644 --- a/src/wrappers/themis/react-native-themis/src/index.js +++ b/src/wrappers/themis/react-native-themis/src/index.js @@ -12,7 +12,27 @@ const Themis = NativeModules.Themis }, }); export const { COMPARATOR_NOT_READY, COMPARATOR_NOT_MATCH, COMPARATOR_MATCH, COMPARATOR_ERROR, KEYTYPE_RSA, KEYTYPE_EC } = Themis.getConstants(); -export function keyPair64(typeOfKey) { +export function isBase64(str) { + const regex64 = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; + return regex64.test(str); +} +export function string64(input) { + return Buffer.from(input).toString('base64'); +} +const checkInput = (param, name) => { + if (param === "" || param === undefined || param === null) { + throw new Error(`Parameter ${name} can not be empty`); + } + return param; +}; +const convertInputBase64 = (param, name) => { + checkInput(param, name); + if (!isBase64(param)) { + throw new Error(`Parameter ${name} is not base64 encoded`); + } + return Array.from(Buffer.from(param, 'base64')); +}; +export function keyPair64(typeOfKey = KEYTYPE_EC) { if (typeOfKey !== KEYTYPE_RSA && typeOfKey !== KEYTYPE_EC) { throw new Error('Invalid key type'); } @@ -37,13 +57,8 @@ export function symmetricKey64() { } ; export function secureCellSealWithSymmetricKeyEncrypt64(symmetricKey64, plaintext, context = "") { - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); + checkInput(plaintext, "plaintext"); // check plaintext is not empty + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); // check symmetricKey64 is not empty and base64 encoded return new Promise((resolve, reject) => { Themis.secureCellSealWithSymmetricKeyEncrypt(symmetricKey, plaintext, context, (encrypted) => { resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")); @@ -54,14 +69,8 @@ export function secureCellSealWithSymmetricKeyEncrypt64(symmetricKey64, plaintex } ; export function secureCellSealWithSymmetricKeyDecrypt64(symmetricKey64, encrypted64, context = "") { - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); return new Promise((resolve, reject) => { Themis.secureCellSealWithSymmetricKeyDecrypt(symmetricKey, encrypted, context, (decrypted) => { resolve(Buffer.from(new Uint8Array(decrypted)).toString()); @@ -72,27 +81,20 @@ export function secureCellSealWithSymmetricKeyDecrypt64(symmetricKey64, encrypte } ; export function secureCellSealWithPassphraseEncrypt64(passphrase, plaintext, context = "") { - if (passphrase === "" || passphrase === undefined || passphrase === null) { - throw new Error("Parameter passphrase can not be empty"); - } - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - return new Promise((resolve) => { + checkInput(plaintext, "plaintext"); + checkInput(passphrase, "passphrase"); + return new Promise((resolve, reject) => { Themis.secureCellSealWithPassphraseEncrypt(passphrase, plaintext, context, (encrypted) => { resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")); + }, (error) => { + reject(error); }); }); } ; export function secureCellSealWithPassphraseDecrypt64(passphrase, encrypted64, context = "") { - if (passphrase === "" || passphrase === undefined || passphrase === null) { - throw new Error("Parameter passphrase can not be empty"); - } - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); + checkInput(passphrase, "passphrase"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); return new Promise((resolve, reject) => { Themis.secureCellSealWithPassphraseDecrypt(passphrase, encrypted, context, (decrypted) => { resolve(Buffer.from(new Uint8Array(decrypted)).toString()); @@ -102,13 +104,8 @@ export function secureCellSealWithPassphraseDecrypt64(passphrase, encrypted64, c }); } export function secureCellTokenProtectEncrypt64(symmetricKey64, plaintext, context = "") { - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); + checkInput(plaintext, "plaintext"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); return new Promise((resolve, reject) => { Themis.secureCellTokenProtectEncrypt(symmetricKey, plaintext, context, (encrypted) => { const data = Buffer.from(new Uint8Array(encrypted.encrypted)).toString("base64"); @@ -123,18 +120,9 @@ export function secureCellTokenProtectEncrypt64(symmetricKey64, plaintext, conte }); } export function secureCellTokenProtectDecrypt64(symmetricKey64, encrypted64, token64, context = "") { - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - if (token64 === "" || token64 === undefined || token64 === null) { - throw new Error("Parameter token64 can not be empty"); - } - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); - const token = Array.from(Buffer.from(token64, 'base64')); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + const token = convertInputBase64(token64, "token64"); return new Promise((resolve, reject) => { Themis.secureCellTokenProtectDecrypt(symmetricKey, encrypted, token, context, (decrypted) => { resolve(Buffer.from(new Uint8Array(decrypted)).toString()); @@ -145,16 +133,9 @@ export function secureCellTokenProtectDecrypt64(symmetricKey64, encrypted64, tok } // context imprint encrypt and decrypt export function secureCellContextImprintEncrypt64(symmetricKey64, plaintext, context) { - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (context === "" || context === undefined || context === null) { - throw new Error("Parameter context can not be empty"); - } - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); + checkInput(plaintext, "plaintext"); + checkInput(context, "context"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); return new Promise((resolve, reject) => { Themis.secureCellContextImprintEncrypt(symmetricKey, plaintext, context, (encrypted) => { resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")); @@ -164,17 +145,9 @@ export function secureCellContextImprintEncrypt64(symmetricKey64, plaintext, con }); } export function secureCellContextImprintDecrypt64(symmetricKey64, encrypted64, context) { - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - if (context === "" || context === undefined || context === null) { - throw new Error("Parameter context can not be empty"); - } - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); + checkInput(context, "context"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); return new Promise((resolve, reject) => { Themis.secureCellContextImprintDecrypt(symmetricKey, encrypted, context, (decrypted) => { resolve(Buffer.from(new Uint8Array(decrypted)).toString()); @@ -184,37 +157,22 @@ export function secureCellContextImprintDecrypt64(symmetricKey64, encrypted64, c }); } // secure message sign and verify -export function secureMessageSign64(plaintext, privateKey64, publicKey64) { - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (privateKey64 === "" || privateKey64 === undefined || privateKey64 === null) { - throw new Error("Parameter privateKey64 can not be empty"); - } - const privateKey = Array.from(Buffer.from(privateKey64, 'base64')); - const publicKey = publicKey64 !== null && publicKey64 !== "" ? - Array.from(Buffer.from(publicKey64, 'base64')) : null; +export function secureMessageSign64(plaintext, privateKey64, _publicKey64 = "") { + checkInput(plaintext, "plaintext"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); return new Promise((resolve, reject) => { - Themis.secureMessageSign(plaintext, privateKey, publicKey, (signed) => { + Themis.secureMessageSign(plaintext, privateKey, (signed) => { resolve(Buffer.from(new Uint8Array(signed)).toString("base64")); }, (error) => { reject(error); }); }); } -export function secureMessageVerify64(signed64, privateKey64, publicKey64) { - if (signed64 === "" || signed64 === undefined || signed64 === null) { - throw new Error("Parameter signed64 can not be empty"); - } - if (publicKey64 === "" || publicKey64 === undefined || publicKey64 === null) { - throw new Error("Parameter publicKey64 can not be empty"); - } - const signed = Array.from(Buffer.from(signed64, 'base64')); - const privateKey = privateKey64 !== null && privateKey64 !== "" ? - Array.from(Buffer.from(privateKey64, 'base64')) : null; - const publicKey = Array.from(Buffer.from(publicKey64, 'base64')); +export function secureMessageVerify64(signed64, _privateKey64 = "", publicKey64) { + const signed = convertInputBase64(signed64, "signed64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); return new Promise((resolve, reject) => { - Themis.secureMessageVerify(signed, privateKey, publicKey, (verified) => { + Themis.secureMessageVerify(signed, publicKey, (verified) => { resolve(Buffer.from(new Uint8Array(verified)).toString()); }, (error) => { reject(error); @@ -223,17 +181,9 @@ export function secureMessageVerify64(signed64, privateKey64, publicKey64) { } // secure message encrypt and decrypt export function secureMessageEncrypt64(plaintext, privateKey64, publicKey64) { - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (privateKey64 === "" || privateKey64 === undefined || privateKey64 === null) { - throw new Error("Parameter privateKey64 can not be empty"); - } - if (publicKey64 === "" || publicKey64 === undefined || publicKey64 === null) { - throw new Error("Parameter publicKey64 can not be empty"); - } - const privateKey = Array.from(Buffer.from(privateKey64, 'base64')); - const publicKey = Array.from(Buffer.from(publicKey64, 'base64')); + checkInput(plaintext, "plaintext"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); return new Promise((resolve, reject) => { Themis.secureMessageEncrypt(plaintext, privateKey, publicKey, (encrypted) => { resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")); @@ -243,18 +193,9 @@ export function secureMessageEncrypt64(plaintext, privateKey64, publicKey64) { }); } export function secureMessageDecrypt64(encrypted64, privateKey64, publicKey64) { - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - if (privateKey64 === "" || privateKey64 === undefined || privateKey64 === null) { - throw new Error("Parameter privateKey64 can not be empty"); - } - if (publicKey64 === "" || publicKey64 === undefined || publicKey64 === null) { - throw new Error("Parameter publicKey64 can not be empty"); - } - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); - const privateKey = Array.from(Buffer.from(privateKey64, 'base64')); - const publicKey = Array.from(Buffer.from(publicKey64, 'base64')); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); return new Promise((resolve, reject) => { Themis.secureMessageDecrypt(encrypted, privateKey, publicKey, (decrypted) => { resolve(Buffer.from(new Uint8Array(decrypted)).toString()); @@ -263,15 +204,9 @@ export function secureMessageDecrypt64(encrypted64, privateKey64, publicKey64) { }); }); } -export function string64(input) { - return Buffer.from(input).toString('base64'); -} /* Returns UUID in string value that corresponds to new comparator */ export function comparatorInit64(data64) { - if (data64 === "" || data64 === undefined || data64 === null) { - throw new Error("Parameter data64 can not be empty"); - } - const data = Array.from(Buffer.from(data64, 'base64')); + const data = convertInputBase64(data64, "data64"); return new Promise((resolve, reject) => { Themis.initComparator(data, (comparator) => { resolve(comparator); @@ -281,9 +216,7 @@ export function comparatorInit64(data64) { }); } export function comparatorBegin(uuidStr) { - if (uuidStr === "" || uuidStr === undefined || uuidStr === null) { - throw new Error("Parameter uuidStr can not be empty"); - } + checkInput(uuidStr, "uuidStr"); return new Promise((resolve, reject) => { Themis.beginCompare(uuidStr, (data) => { resolve(Buffer.from(new Uint8Array(data)).toString("base64")); @@ -294,13 +227,8 @@ export function comparatorBegin(uuidStr) { } /* Returns next part of data and current status */ export function comparatorProceed64(uuidStr, data64) { - if (uuidStr === "" || uuidStr === undefined || uuidStr === null) { - throw new Error("Parameter uuidStr can not be empty"); - } - if (data64 === "" || data64 === undefined || data64 === null) { - throw new Error("Parameter data64 can not be empty"); - } - const data = Array.from(Buffer.from(data64, 'base64')); + checkInput(uuidStr, "uuidStr"); + const data = convertInputBase64(data64, "data64"); return new Promise((resolve, reject) => { Themis.proceedCompare(uuidStr, data, (nextData, status) => { const nextdata64 = Buffer.from(new Uint8Array(nextData)).toString("base64"); diff --git a/src/wrappers/themis/react-native-themis/src/index.tsx b/src/wrappers/themis/react-native-themis/src/index.tsx index 80aeadb9d..9fe729aaa 100644 --- a/src/wrappers/themis/react-native-themis/src/index.tsx +++ b/src/wrappers/themis/react-native-themis/src/index.tsx @@ -3,427 +3,344 @@ import { Buffer } from 'buffer'; const LINKING_ERROR = - `The package 'react-native-themis' doesn't seem to be linked. Make sure: \n\n` + - Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + - '- You rebuilt the app after installing the package\n' + - '- You are not using Expo managed workflow\n'; + `The package 'react-native-themis' doesn't seem to be linked. Make sure: \n\n` + + Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + + '- You rebuilt the app after installing the package\n' + + '- You are not using Expo managed workflow\n'; const Themis = NativeModules.Themis - ? NativeModules.Themis - : new Proxy( - {}, - { - get() { - throw new Error(LINKING_ERROR); - }, - } - ); + ? NativeModules.Themis + : new Proxy( + {}, + { + get() { + throw new Error(LINKING_ERROR); + }, + } + ); export const { - COMPARATOR_NOT_READY, - COMPARATOR_NOT_MATCH, - COMPARATOR_MATCH, - COMPARATOR_ERROR, - KEYTYPE_RSA, - KEYTYPE_EC } = Themis.getConstants() - - -export function keyPair64(typeOfKey: any): Promise { - if (typeOfKey !== KEYTYPE_RSA && typeOfKey !== KEYTYPE_EC) { - throw new Error('Invalid key type'); - } - - return new Promise((resolve) => { - Themis.keyPair(typeOfKey, (pair: any) => { - const pvtKey64 = Buffer.from(new Uint8Array(pair.private)).toString("base64"); - const pubKey64 = Buffer.from(new Uint8Array(pair.public)).toString("base64"); - resolve({ - private64: pvtKey64, - public64: pubKey64, - }); + COMPARATOR_NOT_READY, + COMPARATOR_NOT_MATCH, + COMPARATOR_MATCH, + COMPARATOR_ERROR, + KEYTYPE_RSA, + KEYTYPE_EC } = Themis.getConstants() + + + +export function isBase64(str: String): boolean { + const regex64 = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; + return regex64.test(str as string); +} + +export function string64(input: String): String { + return Buffer.from(input).toString('base64') +} + +const checkInput = (param: String, name: String) => { + if (param === "" || param === undefined || param === null) { + throw new Error(`Parameter ${name} can not be empty`); + } + return param; +} + +const convertInputBase64 = (param: String, name: String): any => { + checkInput(param, name); + if (!isBase64(param)) { + throw new Error(`Parameter ${name} is not base64 encoded`); + } + return Array.from(Buffer.from(param, 'base64')); +} + +export function keyPair64(typeOfKey: any = KEYTYPE_EC): Promise { + if (typeOfKey !== KEYTYPE_RSA && typeOfKey !== KEYTYPE_EC) { + throw new Error('Invalid key type'); + } + + return new Promise((resolve) => { + Themis.keyPair(typeOfKey, (pair: any) => { + const pvtKey64 = Buffer.from(new Uint8Array(pair.private)).toString("base64"); + const pubKey64 = Buffer.from(new Uint8Array(pair.public)).toString("base64"); + resolve({ + private64: pvtKey64, + public64: pubKey64, + }); + }) }) - }) }; export function symmetricKey64(): Promise { - return new Promise((resolve) => { - Themis.symmetricKey((key: any) => { - resolve(Buffer.from(new Uint8Array(key)).toString("base64")); + return new Promise((resolve) => { + Themis.symmetricKey((key: any) => { + resolve(Buffer.from(new Uint8Array(key)).toString("base64")); + }) }) - }) }; export function secureCellSealWithSymmetricKeyEncrypt64( - symmetricKey64: String, - plaintext: String, - context: String = ""): Promise { - - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureCellSealWithSymmetricKeyEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) - }, (error: any) => { - reject(error) + symmetricKey64: String, + plaintext: String, + context: String = ""): Promise { + + checkInput(plaintext, "plaintext"); // check plaintext is not empty + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); // check symmetricKey64 is not empty and base64 encoded + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithSymmetricKeyEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) + }) }) - }) }; export function secureCellSealWithSymmetricKeyDecrypt64( - symmetricKey64: String, - encrypted64: String, - context: String = ""): Promise { - - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureCellSealWithSymmetricKeyDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) + symmetricKey64: String, + encrypted64: String, + context: String = ""): Promise { + + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithSymmetricKeyDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) + }) }) - }) }; export function secureCellSealWithPassphraseEncrypt64( - passphrase: String, - plaintext: String, - context: String = ""): Promise { - - if (passphrase === "" || passphrase === undefined || passphrase === null) { - throw new Error("Parameter passphrase can not be empty"); - } - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - - return new Promise((resolve) => { - Themis.secureCellSealWithPassphraseEncrypt(passphrase, plaintext, context, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + passphrase: String, + plaintext: String, + context: String = ""): Promise { + + checkInput(plaintext, "plaintext"); + checkInput(passphrase, "passphrase"); + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithPassphraseEncrypt(passphrase, plaintext, context, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) + }); }); - }); }; export function secureCellSealWithPassphraseDecrypt64( - passphrase: String, - encrypted64: String, - context: String = ""): Promise { - - if (passphrase === "" || passphrase === undefined || passphrase === null) { - throw new Error("Parameter passphrase can not be empty"); - } - - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureCellSealWithPassphraseDecrypt(passphrase, encrypted, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) - }) - }); + passphrase: String, + encrypted64: String, + context: String = ""): Promise { + + checkInput(passphrase, "passphrase"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithPassphraseDecrypt(passphrase, encrypted, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()); + }, (error: any) => { + reject(error); + }) + }); } export function secureCellTokenProtectEncrypt64( - symmetricKey64: String, - plaintext: String, - context: String = ""): Promise { - - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureCellTokenProtectEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { - const data = Buffer.from(new Uint8Array(encrypted.encrypted)).toString("base64") - const token = Buffer.from(new Uint8Array(encrypted.token)).toString("base64") - resolve({ - encrypted64: data, - token64: token - }) - }, (error: any) => { - reject(error) + symmetricKey64: String, + plaintext: String, + context: String = ""): Promise { + + checkInput(plaintext, "plaintext"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + + return new Promise((resolve, reject) => { + Themis.secureCellTokenProtectEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { + const data = Buffer.from(new Uint8Array(encrypted.encrypted)).toString("base64") + const token = Buffer.from(new Uint8Array(encrypted.token)).toString("base64") + resolve({ + encrypted64: data, + token64: token + }) + }, (error: any) => { + reject(error) + }) }) - }) } export function secureCellTokenProtectDecrypt64( - symmetricKey64: String, - encrypted64: String, - token64: String, - context: String = ""): Promise { - - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - if (token64 === "" || token64 === undefined || token64 === null) { - throw new Error("Parameter token64 can not be empty"); - } - - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); - const token = Array.from(Buffer.from(token64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureCellTokenProtectDecrypt(symmetricKey, encrypted, token, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) + symmetricKey64: String, + encrypted64: String, + token64: String, + context: String = ""): Promise { + + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + const token = convertInputBase64(token64, "token64"); + + return new Promise((resolve, reject) => { + Themis.secureCellTokenProtectDecrypt(symmetricKey, encrypted, token, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) + }) }) - }) } // context imprint encrypt and decrypt export function secureCellContextImprintEncrypt64( - symmetricKey64: String, - plaintext: String, - context: String): Promise { - - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (context === "" || context === undefined || context === null) { - throw new Error("Parameter context can not be empty"); - } - - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - return new Promise((resolve, reject) => { - Themis.secureCellContextImprintEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) - }, (error: any) => { - reject(error) - }) - }); + symmetricKey64: String, + plaintext: String, + context: String): Promise { + + checkInput(plaintext, "plaintext"); + checkInput(context, "context"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + + return new Promise((resolve, reject) => { + Themis.secureCellContextImprintEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) + }) + }); } export function secureCellContextImprintDecrypt64( - symmetricKey64: String, - encrypted64: String, - context: String): Promise { - - if (symmetricKey64 === "" || symmetricKey64 === undefined || symmetricKey64 === null) { - throw new Error("Parameter symmetricKey64 can not be empty"); - } - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - if (context === "" || context === undefined || context === null) { - throw new Error("Parameter context can not be empty"); - } - - const symmetricKey = Array.from(Buffer.from(symmetricKey64, 'base64')); - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureCellContextImprintDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) - }) - }); + symmetricKey64: String, + encrypted64: String, + context: String): Promise { + + checkInput(context, "context"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + + return new Promise((resolve, reject) => { + Themis.secureCellContextImprintDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) + }) + }); } // secure message sign and verify export function secureMessageSign64( - plaintext: String, - privateKey64: String, - publicKey64: String): Promise { - - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (privateKey64 === "" || privateKey64 === undefined || privateKey64 === null) { - throw new Error("Parameter privateKey64 can not be empty"); - } - - const privateKey = Array.from(Buffer.from(privateKey64, 'base64')); - const publicKey = publicKey64 !== null && publicKey64 !== "" ? - Array.from(Buffer.from(publicKey64, 'base64')) : null; - - return new Promise((resolve, reject) => { - Themis.secureMessageSign(plaintext, privateKey, publicKey, (signed: any) => { - resolve(Buffer.from(new Uint8Array(signed)).toString("base64")) - }, (error: any) => { - reject(error) + plaintext: String, + privateKey64: String, + _publicKey64: String = ""): Promise { + + checkInput(plaintext, "plaintext"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageSign(plaintext, privateKey, (signed: any) => { + resolve(Buffer.from(new Uint8Array(signed)).toString("base64")) + }, (error: any) => { + reject(error) + }) }) - }) } export function secureMessageVerify64( - signed64: String, - privateKey64: String, - publicKey64: String): Promise { - - if (signed64 === "" || signed64 === undefined || signed64 === null) { - throw new Error("Parameter signed64 can not be empty"); - } - if (publicKey64 === "" || publicKey64 === undefined || publicKey64 === null) { - throw new Error("Parameter publicKey64 can not be empty"); - } - - const signed = Array.from(Buffer.from(signed64, 'base64')); - const privateKey = privateKey64 !== null && privateKey64 !== "" ? - Array.from(Buffer.from(privateKey64, 'base64')) : null; - const publicKey = Array.from(Buffer.from(publicKey64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureMessageVerify(signed, privateKey, publicKey, (verified: any) => { - resolve(Buffer.from(new Uint8Array(verified)).toString()) - }, (error: any) => { - reject(error) + signed64: String, + _privateKey64: String = "", + publicKey64: String): Promise { + + const signed = convertInputBase64(signed64, "signed64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageVerify(signed, publicKey, (verified: any) => { + resolve(Buffer.from(new Uint8Array(verified)).toString()) + }, (error: any) => { + reject(error) + }) }) - }) } // secure message encrypt and decrypt export function secureMessageEncrypt64( - plaintext: String, - privateKey64: String, - publicKey64: String): Promise { - - if (plaintext === "" || plaintext === undefined || plaintext === null) { - throw new Error("Parameter plaintext can not be empty"); - } - if (privateKey64 === "" || privateKey64 === undefined || privateKey64 === null) { - throw new Error("Parameter privateKey64 can not be empty"); - } - if (publicKey64 === "" || publicKey64 === undefined || publicKey64 === null) { - throw new Error("Parameter publicKey64 can not be empty"); - } - - - const privateKey = Array.from(Buffer.from(privateKey64, 'base64')); - const publicKey = Array.from(Buffer.from(publicKey64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureMessageEncrypt(plaintext, privateKey, publicKey, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) - }, (error: any) => { - reject(error) + plaintext: String, + privateKey64: String, + publicKey64: String): Promise { + + checkInput(plaintext, "plaintext"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageEncrypt(plaintext, privateKey, publicKey, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) + }) }) - }) } export function secureMessageDecrypt64( - encrypted64: String, - privateKey64: String, - publicKey64: String): Promise { - - if (encrypted64 === "" || encrypted64 === undefined || encrypted64 === null) { - throw new Error("Parameter encrypted64 can not be empty"); - } - if (privateKey64 === "" || privateKey64 === undefined || privateKey64 === null) { - throw new Error("Parameter privateKey64 can not be empty"); - } - if (publicKey64 === "" || publicKey64 === undefined || publicKey64 === null) { - throw new Error("Parameter publicKey64 can not be empty"); - } - - - const encrypted = Array.from(Buffer.from(encrypted64, 'base64')); - const privateKey = Array.from(Buffer.from(privateKey64, 'base64')); - const publicKey = Array.from(Buffer.from(publicKey64, 'base64')); - - return new Promise((resolve, reject) => { - Themis.secureMessageDecrypt(encrypted, privateKey, publicKey, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) + encrypted64: String, + privateKey64: String, + publicKey64: String): Promise { + + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageDecrypt(encrypted, privateKey, publicKey, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) + }) }) - }) } -export function string64(input: String): String { - return Buffer.from(input).toString('base64') -} /* Returns UUID in string value that corresponds to new comparator */ export function comparatorInit64(data64: String): Promise { - if (data64 === "" || data64 === undefined || data64 === null) { - throw new Error("Parameter data64 can not be empty"); - } + const data = convertInputBase64(data64, "data64"); - const data = Array.from(Buffer.from(data64, 'base64')) - return new Promise((resolve, reject) => { - Themis.initComparator(data, (comparator: string) => { - resolve(comparator) - }, (error: any) => { - reject(error) + return new Promise((resolve, reject) => { + Themis.initComparator(data, (comparator: string) => { + resolve(comparator) + }, (error: any) => { + reject(error) + }) }) - }) } export function comparatorBegin(uuidStr: String): Promise { - - if (uuidStr === "" || uuidStr === undefined || uuidStr === null) { - throw new Error("Parameter uuidStr can not be empty"); - } - - return new Promise((resolve, reject) => { - Themis.beginCompare(uuidStr, (data: any) => { - resolve(Buffer.from(new Uint8Array(data)).toString("base64")) - }, (error: any) => { - reject(error) + checkInput(uuidStr, "uuidStr"); + + return new Promise((resolve, reject) => { + Themis.beginCompare(uuidStr, (data: any) => { + resolve(Buffer.from(new Uint8Array(data)).toString("base64")) + }, (error: any) => { + reject(error) + }) }) - }) } /* Returns next part of data and current status */ export function comparatorProceed64( - uuidStr: String, - data64: String): Promise { - - if (uuidStr === "" || uuidStr === undefined || uuidStr === null) { - throw new Error("Parameter uuidStr can not be empty"); - } - if (data64 === "" || data64 === undefined || data64 === null) { - throw new Error("Parameter data64 can not be empty"); - } - - - const data = Array.from(Buffer.from(data64, 'base64')) - return new Promise((resolve, reject) => { - Themis.proceedCompare(uuidStr, data, (nextData: any, status: Number) => { - const nextdata64 = Buffer.from(new Uint8Array(nextData)).toString("base64") - resolve({ - data64: nextdata64, - status: status - }) - }, (error: any) => { - reject(error) + uuidStr: String, + data64: String): Promise { + + checkInput(uuidStr, "uuidStr"); + const data = convertInputBase64(data64, "data64"); + + return new Promise((resolve, reject) => { + Themis.proceedCompare(uuidStr, data, (nextData: any, status: Number) => { + const nextdata64 = Buffer.from(new Uint8Array(nextData)).toString("base64") + resolve({ + data64: nextdata64, + status: status + }) + }, (error: any) => { + reject(error) + }) }) - }) } \ No newline at end of file From 10cdf05ab85fe5e50b2108ef57ef12ff42ba087a Mon Sep 17 00:00:00 2001 From: Alex Radetsky Date: Tue, 11 Oct 2022 14:02:37 +0300 Subject: [PATCH 2/3] restore previous format --- .../com/reactnativethemis/ThemisModule.java | 966 +++++++++-------- .../react-native-themis/ios/RCTThemis.m | 972 +++++++++--------- .../themis/react-native-themis/src/index.tsx | 498 ++++----- 3 files changed, 1208 insertions(+), 1228 deletions(-) diff --git a/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java b/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java index 93fe37b5d..1882e5958 100644 --- a/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java +++ b/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java @@ -33,527 +33,523 @@ import java.util.UUID; public class ThemisModule extends ReactContextBaseJavaModule { - public static class ByteOverflowException extends Exception { - public ByteOverflowException(String errorMessage) { - super(errorMessage); - } + public static class ByteOverflowException extends Exception { + public ByteOverflowException(String errorMessage) { + super(errorMessage); } - - Map cmprs = new HashMap<>(); - - private final static int comparator_not_ready = 0; - private final static int comparator_not_match = 22; - private final static int comparator_match = 21; - private final static int comparator_error = -1; - - private final static String contextRequired = "Context required"; - private final static String privateKeyRequired = "Private key can not be null or blank"; - private final static String publicKeyRequired = "Public key can not be null or blank"; - - ThemisModule(ReactApplicationContext context) { - super(context); + } + + Map cmprs = new HashMap<>(); + + private final static int comparator_not_ready = 0; + private final static int comparator_not_match = 22; + private final static int comparator_match = 21; + private final static int comparator_error = -1; + + private final static String contextRequired = "Context required"; + private final static String privateKeyRequired = "Private key can not be null or blank"; + private final static String publicKeyRequired = "Public key can not be null or blank"; + + ThemisModule(ReactApplicationContext context) + { + super(context); + } + + @NonNull + @Override + public String getName() + { + return "Themis"; + } + + /* Replace JAVA enum version to equal with iOS version. */ + + @Override + public Map getConstants() + { + final Map constants = new HashMap<>(); + constants.put("COMPARATOR_NOT_READY", comparator_not_ready); + constants.put("COMPARATOR_NOT_MATCH", comparator_not_match); + constants.put("COMPARATOR_MATCH", comparator_match); + constants.put("COMPARATOR_ERROR", comparator_error); + constants.put("KEYTYPE_RSA", AsymmetricKey.KEYTYPE_RSA); + constants.put("KEYTYPE_EC", AsymmetricKey.KEYTYPE_EC); + return constants; + } + + private static int compareResultSerialize(SecureCompare.CompareResult result) + { + switch (result) { + case NOT_READY: return comparator_not_ready; + case NO_MATCH: return comparator_not_match; + case MATCH: return comparator_match; + default: return comparator_error; } + } - @NonNull - @Override - public String getName() { - return "Themis"; + private static WritableArray dataSerialize(byte[] data) + { + if (data == null) { + return null; } + WritableArray result = new WritableNativeArray(); + for (byte datum : data) result.pushInt(datum); - /* Replace JAVA enum version to equal with iOS version. */ - - @Override - public Map getConstants() { - final Map constants = new HashMap<>(); - constants.put("COMPARATOR_NOT_READY", comparator_not_ready); - constants.put("COMPARATOR_NOT_MATCH", comparator_not_match); - constants.put("COMPARATOR_MATCH", comparator_match); - constants.put("COMPARATOR_ERROR", comparator_error); - constants.put("KEYTYPE_RSA", AsymmetricKey.KEYTYPE_RSA); - constants.put("KEYTYPE_EC", AsymmetricKey.KEYTYPE_EC); - return constants; - } + return result; + } - private static int compareResultSerialize(SecureCompare.CompareResult result) { - switch (result) { - case NOT_READY: - return comparator_not_ready; - case NO_MATCH: - return comparator_not_match; - case MATCH: - return comparator_match; - default: - return comparator_error; - } + private static byte[] dataDeserialize(ReadableArray serializedData) throws ByteOverflowException { + if (serializedData == null || serializedData.size() == 0) { + return null; } - - private static WritableArray dataSerialize(byte[] data) { - if (data == null) { - return null; - } - WritableArray result = new WritableNativeArray(); - for (byte datum : data) - result.pushInt(datum); - - return result; + byte[] data = new byte[serializedData.size()]; + for (int i = 0; i < serializedData.size(); i++) { + if (serializedData.getInt(i) >= 0 && serializedData.getInt(i) <= 255) { + byte j = (byte) serializedData.getInt(i); + data[i] = j; + } else { + throw new ByteOverflowException("Value " + serializedData.getInt(i) + " is out of range"); + } } - - private static byte[] dataDeserialize(ReadableArray serializedData) throws ByteOverflowException { - if (serializedData == null || serializedData.size() == 0) { - return null; - } - byte[] data = new byte[serializedData.size()]; - for (int i = 0; i < serializedData.size(); i++) { - if (serializedData.getInt(i) >= 0 && serializedData.getInt(i) <= 255) { - byte j = (byte) serializedData.getInt(i); - data[i] = j; - } else { - throw new ByteOverflowException("Value " + serializedData.getInt(i) + " is out of range"); - } - } - return data; + return data; + } + + @ReactMethod + public void stringSerialize(String text, + Callback callback) + { + byte[] data = text.getBytes(StandardCharsets.UTF_8); + WritableArray response = dataSerialize(data); + callback.invoke(response); + } + + @ReactMethod + public void keyPair(int algorithm, Callback callback) + { + Keypair pair; + switch (algorithm) { + case AsymmetricKey.KEYTYPE_RSA: + pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_RSA); + break; + default: + pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_EC); } - @ReactMethod - public void stringSerialize(String text, Callback callback) { - byte[] data = text.getBytes(StandardCharsets.UTF_8); - WritableArray response = dataSerialize(data); - callback.invoke(response); + KeypairGenerator.generateKeypair(); + PrivateKey privateKey = pair.getPrivateKey(); + PublicKey publicKey = pair.getPublicKey(); + + WritableArray privateSerialized = dataSerialize(privateKey.toByteArray()); + WritableArray publicSerialized = dataSerialize(publicKey.toByteArray()); + + WritableMap response = new WritableNativeMap(); + response.putArray("private", privateSerialized); + response.putArray("public", publicSerialized); + + callback.invoke(response); + } + + @ReactMethod + public void symmetricKey(Callback callback) + { + SymmetricKey masterKey = new SymmetricKey(); + WritableArray response = dataSerialize(masterKey.toByteArray()); + callback.invoke(response); + } + + @ReactMethod + public void secureCellSealWithSymmetricKeyEncrypt(ReadableArray symmetricKey, + String plaintext, + String context, + Callback successCallback, + Callback errorCallback) + { + try { + byte[] key = dataDeserialize(symmetricKey); + SecureCell.Seal cell = SecureCell.SealWithKey(key); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); + WritableArray response = dataSerialize(encrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void keyPair(int algorithm, Callback callback) { - Keypair pair; - - switch (algorithm) { - case AsymmetricKey.KEYTYPE_RSA: - pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_RSA); - break; - default: - pair = KeypairGenerator.generateKeypair(AsymmetricKey.KEYTYPE_EC); - } - - KeypairGenerator.generateKeypair(); - PrivateKey privateKey = pair.getPrivateKey(); - PublicKey publicKey = pair.getPublicKey(); - - WritableArray privateSerialized = dataSerialize(privateKey.toByteArray()); - WritableArray publicSerialized = dataSerialize(publicKey.toByteArray()); - - WritableMap response = new WritableNativeMap(); - response.putArray("private", privateSerialized); - response.putArray("public", publicSerialized); - - callback.invoke(response); + } + + @ReactMethod + public void secureCellSealWithSymmetricKeyDecrypt(ReadableArray symmetricKey, + ReadableArray encrypted, + String context, + Callback successCallback, + Callback errorCallback) + { + try { + byte[] key = dataDeserialize(symmetricKey); + SecureCell.Seal cell = SecureCell.SealWithKey(key); + byte[] enc = dataDeserialize(encrypted); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void symmetricKey(Callback callback) { - SymmetricKey masterKey = new SymmetricKey(); - WritableArray response = dataSerialize(masterKey.toByteArray()); - callback.invoke(response); + } + + @ReactMethod + public void secureCellSealWithPassphraseEncrypt(String passphrase, + String plaintext, + String context, + Callback successCallback, + Callback errorCallback) + { + try { + SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); + WritableArray response = dataSerialize(encrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void secureCellSealWithSymmetricKeyEncrypt(ReadableArray symmetricKey, - String plaintext, - String context, - Callback successCallback, - Callback errorCallback) { - - try { - byte[] key = dataDeserialize(symmetricKey); - SecureCell.Seal cell = SecureCell.SealWithKey(key); - byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); - WritableArray response = dataSerialize(encrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } - } - - @ReactMethod - public void secureCellSealWithSymmetricKeyDecrypt(ReadableArray symmetricKey, - ReadableArray encrypted, - String context, - Callback successCallback, - Callback errorCallback) { - - - try { - byte[] key = dataDeserialize(symmetricKey); - SecureCell.Seal cell = SecureCell.SealWithKey(key); - byte[] enc = dataDeserialize(encrypted); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, contextBinary); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + } + + @ReactMethod + public void secureCellSealWithPassphraseDecrypt(String passphrase, + ReadableArray encrypted, + String context, + Callback successCallback, + Callback errorCallback) + { + try { + SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); + byte[] enc = dataDeserialize(encrypted); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void secureCellSealWithPassphraseEncrypt(String passphrase, - String plaintext, - String context, - Callback successCallback, - Callback errorCallback) { - - try { - SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); - byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); - WritableArray response = dataSerialize(encrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + } + + /* MARK: Token protect mode */ + @ReactMethod + public void secureCellTokenProtectEncrypt(ReadableArray symmetricKey, + String plaintext, + String context, + Callback successCallback, + Callback errorCallback) + { + try { + byte[] bkey = dataDeserialize(symmetricKey); + SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + SecureCellData result = cell.encrypt(plaintextBinary, contextBinary); + byte[] encrypted = result.getProtectedData(); + byte[] authToken = result.getAdditionalData(); + WritableMap response = new WritableNativeMap(); + response.putArray("encrypted", dataSerialize(encrypted)); + response.putArray("token", dataSerialize(authToken)); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void secureCellSealWithPassphraseDecrypt(String passphrase, - ReadableArray encrypted, - String context, - Callback successCallback, - Callback errorCallback) { - - try { - SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); - byte[] enc = dataDeserialize(encrypted); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, contextBinary); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + } + + @ReactMethod + public void secureCellTokenProtectDecrypt(ReadableArray symmetricKey, + ReadableArray encrypted, + ReadableArray token, + String context, + Callback successCallback, + Callback errorCallback) + { + try { + byte[] bkey = dataDeserialize(symmetricKey); + byte[] enc = dataDeserialize(encrypted); + byte[] tkn = dataDeserialize(token); + SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, tkn, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } + } - /* MARK: Token protect mode */ - @ReactMethod - public void secureCellTokenProtectEncrypt(ReadableArray symmetricKey, + /* Context imprint mode */ + @ReactMethod + public void secureCellContextImprintEncrypt(ReadableArray symmetricKey, String plaintext, String context, Callback successCallback, - Callback errorCallback) { - try { - byte[] bkey = dataDeserialize(symmetricKey); - SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); - byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - SecureCellData result = cell.encrypt(plaintextBinary, contextBinary); - byte[] encrypted = result.getProtectedData(); - byte[] authToken = result.getAdditionalData(); - WritableMap response = new WritableNativeMap(); - response.putArray("encrypted", dataSerialize(encrypted)); - response.putArray("token", dataSerialize(authToken)); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + Callback errorCallback) + { + if (context == null || context.length() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", contextRequired); + errorCallback.invoke(error); + return; + } + try { + byte[] bkey = dataDeserialize(symmetricKey); + SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); + byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); + WritableArray response = dataSerialize(encrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } + } - @ReactMethod - public void secureCellTokenProtectDecrypt(ReadableArray symmetricKey, + @ReactMethod + public void secureCellContextImprintDecrypt(ReadableArray symmetricKey, ReadableArray encrypted, - ReadableArray token, String context, Callback successCallback, - Callback errorCallback) { - try { - byte[] bkey = dataDeserialize(symmetricKey); - byte[] enc = dataDeserialize(encrypted); - byte[] tkn = dataDeserialize(token); - SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, tkn, contextBinary); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + Callback errorCallback) + { + if (context == null || context.length() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", contextRequired); + errorCallback.invoke(error); + return; } - - /* Context imprint mode */ - @ReactMethod - public void secureCellContextImprintEncrypt(ReadableArray symmetricKey, - String plaintext, - String context, - Callback successCallback, - Callback errorCallback) { - - if (context == null || context.length() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", contextRequired); - errorCallback.invoke(error); - return; - } - try { - byte[] bkey = dataDeserialize(symmetricKey); - SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); - byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); - WritableArray response = dataSerialize(encrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + try { + byte[] bkey = dataDeserialize(symmetricKey); + byte[] enc = dataDeserialize(encrypted); + SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); + byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); + byte[] decrypted = cell.decrypt(enc, contextBinary); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void secureCellContextImprintDecrypt(ReadableArray symmetricKey, - ReadableArray encrypted, - String context, - Callback successCallback, - Callback errorCallback) { - - - if (context == null || context.length() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", contextRequired); - errorCallback.invoke(error); - return; - } - - try { - byte[] bkey = dataDeserialize(symmetricKey); - byte[] enc = dataDeserialize(encrypted); - SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); - byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, contextBinary); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + } + + /* Secure Message */ + @ReactMethod + public void secureMessageSign(String message, + ReadableArray privateKey, + Callback successCallback, + Callback errorCallback) + { + if (privateKey == null || privateKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", privateKeyRequired); + errorCallback.invoke(error); + return; } - - /* Secure Message */ - @ReactMethod - public void secureMessageSign(String message, - ReadableArray privateKey, - Callback successCallback, - Callback errorCallback) { - - if (privateKey == null || privateKey.size() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", privateKeyRequired); - errorCallback.invoke(error); - return; - } - - try { - byte[] bkey = dataDeserialize(privateKey); - PrivateKey pvtKey = new PrivateKey(bkey); - byte[] msg = message.getBytes(StandardCharsets.UTF_8); - SecureMessage secureMessage = new SecureMessage(pvtKey); - byte[] signedMessage = secureMessage.sign(msg); - WritableArray response = dataSerialize(signedMessage); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + try { + byte[] bkey = dataDeserialize(privateKey); + PrivateKey pvtKey = new PrivateKey(bkey); + byte[] msg = message.getBytes(StandardCharsets.UTF_8); + SecureMessage secureMessage = new SecureMessage(pvtKey); + byte[] signedMessage = secureMessage.sign(msg); + WritableArray response = dataSerialize(signedMessage); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void secureMessageVerify(ReadableArray message, - ReadableArray publicKey, - Callback successCallback, - Callback errorCallback) { - - if (publicKey == null || publicKey.size() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", publicKeyRequired); - errorCallback.invoke(error); - return; - } - - try { - byte[] bkey = dataDeserialize(publicKey); - PublicKey pubKey = new PublicKey(bkey); - byte[] msg = dataDeserialize(message); - SecureMessage secureMessage = new SecureMessage(pubKey); - byte[] verifiedMessage = secureMessage.verify(msg, pubKey); - WritableArray response = dataSerialize(verifiedMessage); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + } + + @ReactMethod + public void secureMessageVerify(ReadableArray message, + ReadableArray publicKey, + Callback successCallback, + Callback errorCallback) + { + if (publicKey == null || publicKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", publicKeyRequired); + errorCallback.invoke(error); + return; } - - @ReactMethod - public void secureMessageEncrypt(String message, - ReadableArray privateKey, - ReadableArray publicKey, - Callback successCallback, - Callback errorCallback) { - - if (privateKey == null || privateKey.size() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", privateKeyRequired); - errorCallback.invoke(error); - return; - } - - if (publicKey == null || publicKey.size() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", publicKeyRequired); - errorCallback.invoke(error); - return; - } - - try { - byte[] bkey = dataDeserialize(privateKey); - PrivateKey pvtKey = new PrivateKey(bkey); - bkey = dataDeserialize(publicKey); - PublicKey pubKey = new PublicKey(bkey); - byte[] msg = message.getBytes(StandardCharsets.UTF_8); - SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); - byte[] encryptedMessage = secureMessage.wrap(msg); - WritableArray response = dataSerialize(encryptedMessage); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + try { + byte[] bkey = dataDeserialize(publicKey); + PublicKey pubKey = new PublicKey(bkey); + byte[] msg = dataDeserialize(message); + SecureMessage secureMessage = new SecureMessage(pubKey); + byte[] verifiedMessage = secureMessage.verify(msg, pubKey); + WritableArray response = dataSerialize(verifiedMessage); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } - - @ReactMethod - public void secureMessageDecrypt(ReadableArray message, - ReadableArray privateKey, - ReadableArray publicKey, - Callback successCallback, - Callback errorCallback) { - - if (privateKey == null || privateKey.size() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", privateKeyRequired); - errorCallback.invoke(error); - return; - } - if (publicKey == null || publicKey.size() == 0) { - WritableMap error = new WritableNativeMap(); - error.putString("message", publicKeyRequired); - errorCallback.invoke(error); - return; - } - - try { - byte[] bkey = dataDeserialize(privateKey); - PrivateKey pvtKey = new PrivateKey(bkey); - bkey = dataDeserialize(publicKey); - PublicKey pubKey = new PublicKey(bkey); - byte[] msg = dataDeserialize(message); - SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); - byte[] decrypted = secureMessage.unwrap(msg, pubKey); - WritableArray response = dataSerialize(decrypted); - successCallback.invoke(response); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + } + + @ReactMethod + public void secureMessageEncrypt(String message, + ReadableArray privateKey, + ReadableArray publicKey, + Callback successCallback, + Callback errorCallback) + { + if (privateKey == null || privateKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", privateKeyRequired); + errorCallback.invoke(error); + return; } - - @ReactMethod - public void initComparator(ReadableArray sharedSecret, - Callback successCallback, - Callback errorCallback) { - - try { - byte[] sharedSecretData = dataDeserialize(sharedSecret); - SecureCompare cmp = new SecureCompare(sharedSecretData); - final String uuid = UUID.randomUUID().toString(); - cmprs.put(uuid, cmp); - successCallback.invoke(uuid); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + if (publicKey == null || publicKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", publicKeyRequired); + errorCallback.invoke(error); + return; } - - @ReactMethod - public void statusOfComparator(String uuid, - Callback callback) { - - SecureCompare cmp = cmprs.get(uuid); - if (cmp == null) { - callback.invoke(comparator_error); - } else { - SecureCompare.CompareResult result = cmp.getResult(); - int status = compareResultSerialize(result); - callback.invoke(status); - } + try { + byte[] bkey = dataDeserialize(privateKey); + PrivateKey pvtKey = new PrivateKey(bkey); + bkey = dataDeserialize(publicKey); + PublicKey pubKey = new PublicKey(bkey); + byte[] msg = message.getBytes(StandardCharsets.UTF_8); + SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); + byte[] encryptedMessage = secureMessage.wrap(msg); + WritableArray response = dataSerialize(encryptedMessage); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void secureMessageDecrypt(ReadableArray message, + ReadableArray privateKey, + ReadableArray publicKey, + Callback successCallback, + Callback errorCallback) + { + if (privateKey == null || privateKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", privateKeyRequired); + errorCallback.invoke(error); + return; + } + if (publicKey == null || publicKey.size() == 0) { + WritableMap error = new WritableNativeMap(); + error.putString("message", publicKeyRequired); + errorCallback.invoke(error); + return; + } + try { + byte[] bkey = dataDeserialize(privateKey); + PrivateKey pvtKey = new PrivateKey(bkey); + bkey = dataDeserialize(publicKey); + PublicKey pubKey = new PublicKey(bkey); + byte[] msg = dataDeserialize(message); + SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); + byte[] decrypted = secureMessage.unwrap(msg, pubKey); + WritableArray response = dataSerialize(decrypted); + successCallback.invoke(response); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } + } + + @ReactMethod + public void initComparator(ReadableArray sharedSecret, + Callback successCallback, + Callback errorCallback) + { + try { + byte[] sharedSecretData = dataDeserialize(sharedSecret); + SecureCompare cmp = new SecureCompare(sharedSecretData); + final String uuid = UUID.randomUUID().toString(); + cmprs.put(uuid, cmp); + successCallback.invoke(uuid); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); + } + } + + @ReactMethod + public void statusOfComparator(String uuid, + Callback callback) + { + SecureCompare cmp = cmprs.get(uuid); + if (cmp == null) { + callback.invoke(comparator_error); + } else { + SecureCompare.CompareResult result = cmp.getResult(); + int status = compareResultSerialize(result); + callback.invoke(status); + } + } + + @ReactMethod + public void beginCompare(String uuid, + Callback successCallback, + Callback errorCallback) + { + SecureCompare cmp = cmprs.get(uuid); + if (cmp == null) { + errorCallback.invoke(comparator_error); + } else { + byte[] data = cmp.begin(); + WritableArray response = dataSerialize(data); + successCallback.invoke(response); + } + } - @ReactMethod - public void beginCompare(String uuid, + @ReactMethod + public void proceedCompare(String uuid, + ReadableArray previous, Callback successCallback, - Callback errorCallback) { - - SecureCompare cmp = cmprs.get(uuid); - if (cmp == null) { - errorCallback.invoke(comparator_error); - } else { - byte[] data = cmp.begin(); - WritableArray response = dataSerialize(data); - successCallback.invoke(response); - } + Callback errorCallback) + { + SecureCompare cmp = cmprs.get(uuid); + if (cmp == null) { + errorCallback.invoke(comparator_error); + return; } - - @ReactMethod - public void proceedCompare(String uuid, - ReadableArray previous, - Callback successCallback, - Callback errorCallback) { - - SecureCompare cmp = cmprs.get(uuid); - if (cmp == null) { - errorCallback.invoke(comparator_error); - return; - } - - try { - byte[] data = dataDeserialize(previous); - data = cmp.proceed(data); - WritableArray response = dataSerialize(data); - SecureCompare.CompareResult result = cmp.getResult(); - int status = compareResultSerialize(result); - if (result != SecureCompare.CompareResult.NOT_READY) { - cmprs.remove(uuid); - } - successCallback.invoke(response, status); - } catch (Exception e) { - WritableMap error = new WritableNativeMap(); - error.putString("message", e.toString()); - errorCallback.invoke(error); - } + try { + byte[] data = dataDeserialize(previous); + data = cmp.proceed(data); + WritableArray response = dataSerialize(data); + SecureCompare.CompareResult result = cmp.getResult(); + int status = compareResultSerialize(result); + if (result != SecureCompare.CompareResult.NOT_READY) { + cmprs.remove(uuid); + } + successCallback.invoke(response, status); + } catch (Exception e) { + WritableMap error = new WritableNativeMap(); + error.putString("message", e.toString()); + errorCallback.invoke(error); } + } } diff --git a/src/wrappers/themis/react-native-themis/ios/RCTThemis.m b/src/wrappers/themis/react-native-themis/ios/RCTThemis.m index efb2665a9..953df8754 100644 --- a/src/wrappers/themis/react-native-themis/ios/RCTThemis.m +++ b/src/wrappers/themis/react-native-themis/ios/RCTThemis.m @@ -23,12 +23,12 @@ @implementation RCTThemis - (instancetype)init { - self = [super init]; - cmprs = [[NSMutableDictionary alloc] init]; - uchar_min = [NSNumber numberWithInt:0]; - uchar_max = [NSNumber numberWithInt:255]; + self = [super init]; + cmprs = [[NSMutableDictionary alloc] init]; + uchar_min = [NSNumber numberWithInt:0]; + uchar_max = [NSNumber numberWithInt:255]; - return self; + return self; } /* MARK: Export constants of the module */ @@ -46,7 +46,7 @@ - (NSDictionary *)constantsToExport // It required by constantsToExport and iOS + (BOOL)requiresMainQueueSetup { - return YES; + return YES; } /***********************************************/ @@ -56,16 +56,16 @@ + (BOOL)requiresMainQueueSetup + (NSArray*)dataSerialize:(NSData*) data { - if (data == nil || data.length == 0 ) return nil; + if (data == nil || data.length == 0 ) return nil; - const char* buffer = (const char*) data.bytes; - NSMutableArray *array = [[NSMutableArray alloc] init]; + const char* buffer = (const char*) data.bytes; + NSMutableArray *array = [[NSMutableArray alloc] init]; - for (NSInteger i = 0; i < data.length; i++) { - NSNumber *num = [[NSNumber alloc] initWithUnsignedChar: buffer[i]]; - [array addObject:num]; - } - return [array copy]; + for (NSInteger i = 0; i < data.length; i++) { + NSNumber *num = [[NSNumber alloc] initWithUnsignedChar: buffer[i]]; + [array addObject:num]; + } + return [array copy]; } /*************************************************/ @@ -75,40 +75,38 @@ + (NSArray*)dataSerialize:(NSData*) data + (NSData*)dataDeserialize: (NSArray*) data error:(NSError**) error { - - if ( data == nil || data.count == 0 ) { - *error = SCERROR(DESERIALIZE_ERROR, @DESERIALIZE_ERRORREASON); - return nil; - } - - char* buffer = (char*)malloc(data.count); - - if (buffer == nil) { - *error = SCERROR(DESERIALIZE_MEMORY, @DESERIALIZE_MEMORYREASON); - return nil; - } - - for (NSInteger i = 0; i < data.count; i++) { - NSNumber *num = data[i]; - /* Check int value before casting to char */ - if ([num compare:uchar_min] == NSOrderedAscending || [num compare:uchar_max] == NSOrderedDescending) { - free(buffer); // did not forget to free allocated memory - *error = SCERROR(BYTEOVERFLOW, @BYTEOVERFLOWREASON); - return nil; - } - buffer[i] = num.unsignedCharValue; - } - NSData *result = [NSData dataWithBytesNoCopy:buffer length:data.count freeWhenDone:YES]; - return result; + if ( data == nil || data.count == 0 ) { + *error = SCERROR(DESERIALIZE_ERROR, @DESERIALIZE_ERRORREASON); + return nil; + } + + char* buffer = (char*)malloc(data.count); + if (buffer == nil) { + *error = SCERROR(DESERIALIZE_MEMORY, @DESERIALIZE_MEMORYREASON); + return nil; + } + + for (NSInteger i = 0; i < data.count; i++) { + NSNumber *num = data[i]; + /* Check int value before casting to char */ + if ([num compare:uchar_min] == NSOrderedAscending || [num compare:uchar_max] == NSOrderedDescending) { + free(buffer); // did not forget to free allocated memory + *error = SCERROR(BYTEOVERFLOW, @BYTEOVERFLOWREASON); + return nil; + } + buffer[i] = num.unsignedCharValue; + } + NSData *result = [NSData dataWithBytesNoCopy:buffer length:data.count freeWhenDone:YES]; + return result; } RCT_EXPORT_METHOD(stringSerialize:(NSString*) text callback:(RCTResponseSenderBlock)callback ) { - NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]; - NSArray *data2 = [RCTThemis dataSerialize: data]; - callback(@[data2]); + NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]; + NSArray *data2 = [RCTThemis dataSerialize: data]; + callback(@[data2]); } @@ -116,42 +114,42 @@ + (NSData*)dataDeserialize: (NSArray*) data error:(NSError**) error successCallback: (RCTResponseSenderBlock)successCallback ) { - TSKeyGen *keypair; - switch (algorithm.intValue) { - case KEYTYPE_RSA: - keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmRSA]; - break; - default: - keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmEC]; - break; - } - - NSArray *privateKey = [RCTThemis dataSerialize: keypair.privateKey]; - NSArray *publicKey = [RCTThemis dataSerialize: keypair.publicKey]; - - NSDictionary *dictionary = @{ - @"private" : privateKey, - @"public" : publicKey - }; - successCallback(@[dictionary]); + TSKeyGen *keypair; + switch (algorithm.intValue) { + case KEYTYPE_RSA: + keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmRSA]; + break; + default: + keypair = [[TSKeyGen alloc] initWithAlgorithm:TSKeyGenAsymmetricAlgorithmEC]; + break; + } + + NSArray *privateKey = [RCTThemis dataSerialize: keypair.privateKey]; + NSArray *publicKey = [RCTThemis dataSerialize: keypair.publicKey]; + + NSDictionary *dictionary = @{ + @"private" : privateKey, + @"public" : publicKey + }; + successCallback(@[dictionary]); } RCT_EXPORT_METHOD(symmetricKey:(RCTResponseSenderBlock)callback) { - NSData *symmetricKey = TSGenerateSymmetricKey(); - NSArray *masterKey = [RCTThemis dataSerialize: symmetricKey]; - callback(@[masterKey]); + NSData *symmetricKey = TSGenerateSymmetricKey(); + NSArray *masterKey = [RCTThemis dataSerialize: symmetricKey]; + callback(@[masterKey]); } - (TSCellSeal *)newSealMode: (NSArray*) symmetricKey error:(NSError**) error { - NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; - if (masterKey == nil) { - return nil; - } - TSCellSeal *cell = [[TSCellSeal alloc] initWithKey:masterKey]; - return cell; + NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; + if (masterKey == nil) { + return nil; + } + TSCellSeal *cell = [[TSCellSeal alloc] initWithKey:masterKey]; + return cell; } @@ -161,26 +159,26 @@ - (TSCellSeal *)newSealMode: (NSArray*) symmetricKey error:(NSError**) error successCallback: (RCTResponseSenderBlock)successCallback errorCallback: (RCTResponseErrorBlock)errorCallback) { - TSCellSeal *cell; - NSError *error; - - cell = [self newSealMode:symmetricKey error:&error]; - if (cell == nil) { - errorCallback(error); - return; - } - - NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encrypted = [cell encrypt:plaintextBinary - context:contextBinary - error:&error]; - if (encrypted == nil) { - errorCallback(error); - return; - } - NSArray *result = [RCTThemis dataSerialize:encrypted]; - successCallback(@[result]); + TSCellSeal *cell; + NSError *error; + + cell = [self newSealMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *encrypted = [cell encrypt:plaintextBinary + context:contextBinary + error:&error]; + if (encrypted == nil) { + errorCallback(error); + return; + } + NSArray *result = [RCTThemis dataSerialize:encrypted]; + successCallback(@[result]); } RCT_EXPORT_METHOD(secureCellSealWithSymmetricKeyDecrypt:(NSArray*) symmetricKey @@ -191,40 +189,39 @@ - (TSCellSeal *)newSealMode: (NSArray*) symmetricKey error:(NSError**) error ) { - TSCellSeal *cell; - NSData *enc; - NSError *error; - - cell = [self newSealMode:symmetricKey error:&error]; - if (cell == nil) { - errorCallback(error); - return; - } - - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { - errorCallback(error); - return; - } - - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc - context:contextBinary - error:&error]; - if (decrypted == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); - } - + TSCellSeal *cell; + NSData *enc; + NSError *error; + + cell = [self newSealMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + context:contextBinary + error:&error]; + if (decrypted == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); + } } - (TSCellSeal *)newSealModeWithPassphrase: (NSString*) passphrase { - TSCellSeal *cell = [[TSCellSeal alloc] initWithPassphrase: passphrase]; - return cell; + TSCellSeal *cell = [[TSCellSeal alloc] initWithPassphrase: passphrase]; + return cell; } @@ -235,20 +232,19 @@ - (TSCellSeal *)newSealModeWithPassphrase: (NSString*) passphrase errorCallback: (RCTResponseErrorBlock)errorCallback ) { + TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; - NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - - NSError *error; - NSData *encrypted = [cell encrypt:plaintextBinary context:contextBinary error:&error]; + NSError *error; + NSData *encrypted = [cell encrypt:plaintextBinary context:contextBinary error:&error]; - if (encrypted == nil) { - errorCallback(error); - } else { - NSArray *result = [RCTThemis dataSerialize:encrypted]; - successCallback(@[result]); - } + if (encrypted == nil) { + errorCallback(error); + } else { + NSArray *result = [RCTThemis dataSerialize:encrypted]; + successCallback(@[result]); + } } RCT_EXPORT_METHOD(secureCellSealWithPassphraseDecrypt:(NSString*) passphrase @@ -259,39 +255,39 @@ - (TSCellSeal *)newSealModeWithPassphrase: (NSString*) passphrase ) { - TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; - NSData *enc; - NSError *error; - - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { - errorCallback(error); - return; - } - - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc - context:contextBinary - error:&error]; - if (decrypted == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); - } + TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; + NSData *enc; + NSError *error; + + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + context:contextBinary + error:&error]; + if (decrypted == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); + } } /* MARK: Token protect mode */ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error { - NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; - if (masterKey == nil) { - return nil; - } + NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; + if (masterKey == nil) { + return nil; + } - TSCellToken *cell = [[TSCellToken alloc] initWithKey:masterKey]; - return cell; + TSCellToken *cell = [[TSCellToken alloc] initWithKey:masterKey]; + return cell; } RCT_EXPORT_METHOD(secureCellTokenProtectEncrypt:(NSArray*) symmetricKey @@ -300,32 +296,32 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error successCallback: (RCTResponseSenderBlock)successCallback errorCallback: (RCTResponseErrorBlock)errorCallback) { - NSError *error; - TSCellToken *cell; - - cell = [self newTokenMode:symmetricKey error:&error]; - if (cell == nil) { - errorCallback(error); - return; - } - - NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - - TSCellTokenEncryptedResult *result = [cell encrypt:plaintextBinary context:contextBinary error:&error]; - if (result == nil ) { - errorCallback(error); - return; - } - - NSArray *encrypted = [RCTThemis dataSerialize: result.encrypted]; - NSArray *token = [RCTThemis dataSerialize: result.token]; - - NSDictionary *dictionary = @{ - @"encrypted" : encrypted, - @"token" : token - }; - successCallback(@[dictionary]); + NSError *error; + TSCellToken *cell; + + cell = [self newTokenMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + + TSCellTokenEncryptedResult *result = [cell encrypt:plaintextBinary context:contextBinary error:&error]; + if (result == nil ) { + errorCallback(error); + return; + } + + NSArray *encrypted = [RCTThemis dataSerialize: result.encrypted]; + NSArray *token = [RCTThemis dataSerialize: result.token]; + + NSDictionary *dictionary = @{ + @"encrypted" : encrypted, + @"token" : token + }; + successCallback(@[dictionary]); } RCT_EXPORT_METHOD(secureCellTokenProtectDecrypt:(NSArray*) symmetricKey @@ -337,41 +333,40 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error ) { - TSCellToken *cell; - NSData *enc; - NSData *tkn; - NSError *error; - - cell = [self newTokenMode:symmetricKey error:&error]; - if (cell == nil) { - errorCallback(error); - return; - } - - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { - errorCallback(error); - return; - } - - tkn = [RCTThemis dataDeserialize:token error:&error]; - if (tkn == nil) { - errorCallback(error); - return; - } - - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc - token:tkn - context:contextBinary - error:&error]; - if (decrypted == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); - } - + TSCellToken *cell; + NSData *enc; + NSData *tkn; + NSError *error; + + cell = [self newTokenMode:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + tkn = [RCTThemis dataDeserialize:token error:&error]; + if (tkn == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + token:tkn + context:contextBinary + error:&error]; + if (decrypted == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); + } } @@ -379,12 +374,12 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSError**) error { - NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; - if (masterKey == nil) { - return nil; - } - TSCellContextImprint *cell = [[TSCellContextImprint alloc] initWithKey:masterKey]; - return cell; + NSData *masterKey = [RCTThemis dataDeserialize: symmetricKey error:error]; + if (masterKey == nil) { + return nil; + } + TSCellContextImprint *cell = [[TSCellContextImprint alloc] initWithKey:masterKey]; + return cell; } RCT_EXPORT_METHOD(secureCellContextImprintEncrypt:(NSArray*) symmetricKey @@ -393,31 +388,31 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr successCallback: (RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseErrorBlock)errorCallback) { - if (context == nil || [context isEqual: @""]) { - NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); - errorCallback(error); - return; - } - - TSCellContextImprint *cell; - NSError *error; - - cell = [self newContextImprint:symmetricKey error:&error]; - if (cell == nil) { - errorCallback(error); - return; - } - - NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encrypted = [cell encrypt:plaintextBinary context:contextBinary error:&error]; - if (encrypted == nil) { - errorCallback(error); - return; - } - - NSArray *result = [RCTThemis dataSerialize:encrypted]; - successCallback(@[result]); + if (context == nil || [context isEqual: @""]) { + NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); + errorCallback(error); + return; + } + + TSCellContextImprint *cell; + NSError *error; + + cell = [self newContextImprint:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *encrypted = [cell encrypt:plaintextBinary context:contextBinary error:&error]; + if (encrypted == nil) { + errorCallback(error); + return; + } + + NSArray *result = [RCTThemis dataSerialize:encrypted]; + successCallback(@[result]); } RCT_EXPORT_METHOD(secureCellContextImprintDecrypt:(NSArray*) symmetricKey @@ -426,41 +421,40 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr successCallback:(RCTResponseSenderBlock)successCallback errorCallback:(RCTResponseErrorBlock)errorCallback) { - - if (context == nil || [context isEqual: @""]) { - NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); - errorCallback(error); - return; - } - - TSCellContextImprint *cell; - NSData *enc; - NSError *error; - - cell = [self newContextImprint:symmetricKey error:&error]; - if (cell == nil) { - errorCallback(error); - return; - } - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { - errorCallback(error); - return; - } - - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc - context:contextBinary - error:&error - ]; - - if (decrypted == nil) { - errorCallback(error); - return; - } - - NSArray* result = [RCTThemis dataSerialize:decrypted]; - successCallback(@[result]); + if (context == nil || [context isEqual: @""]) { + NSError* error = SCERROR(CONTEXTREQUIRED, @CONTEXTREQUIREDREASON); + errorCallback(error); + return; + } + + TSCellContextImprint *cell; + NSData *enc; + NSError *error; + + cell = [self newContextImprint:symmetricKey error:&error]; + if (cell == nil) { + errorCallback(error); + return; + } + enc = [RCTThemis dataDeserialize:encrypted error:&error]; + if (enc == nil) { + errorCallback(error); + return; + } + + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:enc + context:contextBinary + error:&error + ]; + + if (decrypted == nil) { + errorCallback(error); + return; + } + + NSArray* result = [RCTThemis dataSerialize:decrypted]; + successCallback(@[result]); } /* MARK: Secure Message */ @@ -470,33 +464,32 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr errorCallback:(RCTResponseErrorBlock) errorCallback ) { - - if (privateKey == nil || privateKey.count == 0) { - NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData *pvtKey; - NSError *error; - - pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; - if (pvtKey == nil) { - errorCallback(error); - return; - } - - NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; - TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:pvtKey - peerPublicKey:nil]; - - NSData *signedMessage = [secureMessage wrapData:msg error:&error]; - if (signedMessage == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:signedMessage]; - successCallback(@[result]); - } + if (privateKey == nil || privateKey.count == 0) { + NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pvtKey; + NSError *error; + + pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; + if (pvtKey == nil) { + errorCallback(error); + return; + } + + NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; + TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:pvtKey + peerPublicKey:nil]; + + NSData *signedMessage = [secureMessage wrapData:msg error:&error]; + if (signedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:signedMessage]; + successCallback(@[result]); + } } RCT_EXPORT_METHOD(secureMessageVerify:(NSArray*) message @@ -506,38 +499,38 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr ) { - if (publicKey == nil || publicKey.count == 0) { - NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData *pubKey; - NSData *msg; - NSError *error; - - pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; - if (pubKey == nil) { - errorCallback(error); - return; - } - - msg = [RCTThemis dataDeserialize:message error:&error]; - if (msg == nil) { - errorCallback(error); - return; - } - - TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:nil - peerPublicKey:pubKey]; - - NSData *verifiedMessage = [secureMessage unwrapData:msg error:&error]; - if (verifiedMessage == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:verifiedMessage]; - successCallback(@[result]); - } + if (publicKey == nil || publicKey.count == 0) { + NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pubKey; + NSData *msg; + NSError *error; + + pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; + if (pubKey == nil) { + errorCallback(error); + return; + } + + msg = [RCTThemis dataDeserialize:message error:&error]; + if (msg == nil) { + errorCallback(error); + return; + } + + TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:nil + peerPublicKey:pubKey]; + + NSData *verifiedMessage = [secureMessage unwrapData:msg error:&error]; + if (verifiedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:verifiedMessage]; + successCallback(@[result]); + } } RCT_EXPORT_METHOD(secureMessageEncrypt:(NSString*) message @@ -548,46 +541,44 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr ) { - - if (privateKey == nil || privateKey.count == 0) { - NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); - errorCallback(error); - return; - } - - if (publicKey == nil || publicKey.count == 0) { - NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData *pvtKey; - NSData *pubKey; - NSError *error; - - pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; - if (pvtKey == nil) { - errorCallback(error); - return; - } - pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; - if (pubKey == nil) { - errorCallback(error); - return; - } - - NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; - TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; - - NSData *encryptedMessage = [secureMessage wrapData:msg error:&error]; - if (encryptedMessage == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:encryptedMessage]; - successCallback(@[result]); - } - + if (privateKey == nil || privateKey.count == 0) { + NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); + errorCallback(error); + return; + } + + if (publicKey == nil || publicKey.count == 0) { + NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pvtKey; + NSData *pubKey; + NSError *error; + + pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; + if (pvtKey == nil) { + errorCallback(error); + return; + } + pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; + if (pubKey == nil) { + errorCallback(error); + return; + } + + NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; + TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey + peerPublicKey:pubKey]; + + NSData *encryptedMessage = [secureMessage wrapData:msg error:&error]; + if (encryptedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:encryptedMessage]; + successCallback(@[result]); + } } RCT_EXPORT_METHOD(secureMessageDecrypt:(NSArray*) message @@ -597,51 +588,49 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr errorCallback:(RCTResponseErrorBlock) errorCallback ) { - - if (privateKey == nil || privateKey.count == 0) { - NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); - errorCallback(error); - return; - } - - if (publicKey == nil || publicKey.count == 0) { - NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); - errorCallback(error); - return; - } - - NSData *pvtKey; - NSData *pubKey; - NSData *msg; - NSError *error; - - pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; - if (pvtKey == nil) { - errorCallback(error); - return; - } - pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; - if (pubKey == nil) { - errorCallback(error); - return; - } - msg = [RCTThemis dataDeserialize:message error:&error]; - if (msg == nil) { - errorCallback(error); - return; - } - - TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; - - NSData *decryptedMessage = [secureMessage unwrapData:msg error:&error]; - if (decryptedMessage == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:decryptedMessage]; - successCallback(@[result]); - } - + if (privateKey == nil || privateKey.count == 0) { + NSError* error = SCERROR(PRIVATEKEYREQUIRED, @PRIVATEKEYREQUIREDREASON); + errorCallback(error); + return; + } + + if (publicKey == nil || publicKey.count == 0) { + NSError* error = SCERROR(PUBLICKEYREQUIRED, @PUBLICKEYREQUIREDREASON); + errorCallback(error); + return; + } + + NSData *pvtKey; + NSData *pubKey; + NSData *msg; + NSError *error; + + pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; + if (pvtKey == nil) { + errorCallback(error); + return; + } + pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; + if (pubKey == nil) { + errorCallback(error); + return; + } + msg = [RCTThemis dataDeserialize:message error:&error]; + if (msg == nil) { + errorCallback(error); + return; + } + + TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey + peerPublicKey:pubKey]; + + NSData *decryptedMessage = [secureMessage unwrapData:msg error:&error]; + if (decryptedMessage == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:decryptedMessage]; + successCallback(@[result]); + } } /* MARK: Comparator */ @@ -650,96 +639,91 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr successCallback:(RCTResponseSenderBlock) successCallback errorCallback:(RCTResponseErrorBlock) errorCallback) { - NSData *sharedSecretData; - NSError *error; - sharedSecretData = [RCTThemis dataDeserialize:sharedSecret error:&error]; - if (sharedSecretData == nil) { - errorCallback(error); - return; - } - - TSComparator* cmp = [[TSComparator alloc] initWithMessageToCompare:sharedSecretData]; - NSString *uuid = [[NSUUID UUID] UUIDString]; - cmprs[uuid] = cmp; - successCallback(@[uuid]); + NSData *sharedSecretData; + NSError *error; + sharedSecretData = [RCTThemis dataDeserialize:sharedSecret error:&error]; + if (sharedSecretData == nil) { + errorCallback(error); + return; + } + + TSComparator* cmp = [[TSComparator alloc] initWithMessageToCompare:sharedSecretData]; + NSString *uuid = [[NSUUID UUID] UUIDString]; + cmprs[uuid] = cmp; + successCallback(@[uuid]); } RCT_EXPORT_METHOD(statusOfComparator:(NSString*) uuid successCallback:(RCTResponseSenderBlock) successCallback ) { - TSComparator* cmp = cmprs[uuid]; - if (cmp == nil) { - successCallback(@[@-1]); - } else { - NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; - successCallback(@[status]); - } + TSComparator* cmp = cmprs[uuid]; + if (cmp == nil) { + successCallback(@[@-1]); + } else { + NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; + successCallback(@[status]); + } } - - RCT_EXPORT_METHOD(beginCompare:(NSString*) uuid successCallback:(RCTResponseSenderBlock) successCallback errorCallback:(RCTResponseErrorBlock) errorCallback ) { - - TSComparator *cmp = cmprs[uuid]; - if (cmp == nil) { - errorCallback(nil); - return; - } - NSError *error; - - NSData *data = [cmp beginCompare:&error]; - if (data == nil) { - errorCallback(error); - } else { - NSArray* result = [RCTThemis dataSerialize:data]; - successCallback(@[result]); - } + TSComparator *cmp = cmprs[uuid]; + if (cmp == nil) { + errorCallback(nil); + return; + } + + NSError *error; + NSData *data = [cmp beginCompare:&error]; + if (data == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:data]; + successCallback(@[result]); + } } - RCT_EXPORT_METHOD(proceedCompare:(NSString*) uuid previous:(NSArray*) previous successCallback:(RCTResponseSenderBlock) successCallback errorCallback:(RCTResponseErrorBlock) errorCallback ) { - - TSComparator* cmp = cmprs[uuid]; - if ( cmp == nil ) { - NSError* error = SCERROR(-1, @"Comparator does not exist"); - errorCallback(error); - return; - } - - NSData *data; - NSError *error; - - data = [RCTThemis dataDeserialize:previous error:&error]; - if (data == nil) { - errorCallback(error); - return; - } - - data = [cmp proceedCompare:data error:&error]; - if (data == nil) { - errorCallback(error); + TSComparator* cmp = cmprs[uuid]; + if ( cmp == nil ) { + NSError* error = SCERROR(-1, @"Comparator does not exist"); + errorCallback(error); + return; + } + + NSData *data; + NSError *error; + + data = [RCTThemis dataDeserialize:previous error:&error]; + if (data == nil) { + errorCallback(error); + return; + } + + data = [cmp proceedCompare:data error:&error]; + if (data == nil) { + errorCallback(error); + } else { + NSArray* result = [RCTThemis dataSerialize:data]; + NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; + if (cmp.status != TSComparatorNotReady) { + [cmprs removeObjectForKey:uuid]; + } + if (result != nil) { + successCallback(@[result, status]); } else { - NSArray* result = [RCTThemis dataSerialize:data]; - NSNumber* status = [[NSNumber alloc] initWithInteger:(NSInteger)cmp.status]; - if (cmp.status != TSComparatorNotReady) { - [cmprs removeObjectForKey:uuid]; - } - if (result != nil) { - successCallback(@[result, status]); - } else { - successCallback(@[@"", status]); - } + successCallback(@[@"", status]); } + } } diff --git a/src/wrappers/themis/react-native-themis/src/index.tsx b/src/wrappers/themis/react-native-themis/src/index.tsx index 9fe729aaa..93719f72c 100644 --- a/src/wrappers/themis/react-native-themis/src/index.tsx +++ b/src/wrappers/themis/react-native-themis/src/index.tsx @@ -3,344 +3,344 @@ import { Buffer } from 'buffer'; const LINKING_ERROR = - `The package 'react-native-themis' doesn't seem to be linked. Make sure: \n\n` + - Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + - '- You rebuilt the app after installing the package\n' + - '- You are not using Expo managed workflow\n'; + `The package 'react-native-themis' doesn't seem to be linked. Make sure: \n\n` + + Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + + '- You rebuilt the app after installing the package\n' + + '- You are not using Expo managed workflow\n'; const Themis = NativeModules.Themis - ? NativeModules.Themis - : new Proxy( - {}, - { - get() { - throw new Error(LINKING_ERROR); - }, - } - ); + ? NativeModules.Themis + : new Proxy( + {}, + { + get() { + throw new Error(LINKING_ERROR); + }, + } + ); export const { - COMPARATOR_NOT_READY, - COMPARATOR_NOT_MATCH, - COMPARATOR_MATCH, - COMPARATOR_ERROR, - KEYTYPE_RSA, - KEYTYPE_EC } = Themis.getConstants() + COMPARATOR_NOT_READY, + COMPARATOR_NOT_MATCH, + COMPARATOR_MATCH, + COMPARATOR_ERROR, + KEYTYPE_RSA, + KEYTYPE_EC } = Themis.getConstants() export function isBase64(str: String): boolean { - const regex64 = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; - return regex64.test(str as string); + const regex64 = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; + return regex64.test(str as string); } export function string64(input: String): String { - return Buffer.from(input).toString('base64') + return Buffer.from(input).toString('base64') } const checkInput = (param: String, name: String) => { - if (param === "" || param === undefined || param === null) { - throw new Error(`Parameter ${name} can not be empty`); - } - return param; + if (param === "" || param === undefined || param === null) { + throw new Error(`Parameter ${name} can not be empty`); + } + return param; } const convertInputBase64 = (param: String, name: String): any => { - checkInput(param, name); - if (!isBase64(param)) { - throw new Error(`Parameter ${name} is not base64 encoded`); - } - return Array.from(Buffer.from(param, 'base64')); + checkInput(param, name); + if (!isBase64(param)) { + throw new Error(`Parameter ${name} is not base64 encoded`); + } + return Array.from(Buffer.from(param, 'base64')); } export function keyPair64(typeOfKey: any = KEYTYPE_EC): Promise { - if (typeOfKey !== KEYTYPE_RSA && typeOfKey !== KEYTYPE_EC) { - throw new Error('Invalid key type'); - } - - return new Promise((resolve) => { - Themis.keyPair(typeOfKey, (pair: any) => { - const pvtKey64 = Buffer.from(new Uint8Array(pair.private)).toString("base64"); - const pubKey64 = Buffer.from(new Uint8Array(pair.public)).toString("base64"); - resolve({ - private64: pvtKey64, - public64: pubKey64, - }); - }) + if (typeOfKey !== KEYTYPE_RSA && typeOfKey !== KEYTYPE_EC) { + throw new Error('Invalid key type'); + } + + return new Promise((resolve) => { + Themis.keyPair(typeOfKey, (pair: any) => { + const pvtKey64 = Buffer.from(new Uint8Array(pair.private)).toString("base64"); + const pubKey64 = Buffer.from(new Uint8Array(pair.public)).toString("base64"); + resolve({ + private64: pvtKey64, + public64: pubKey64, + }); }) + }) }; export function symmetricKey64(): Promise { - return new Promise((resolve) => { - Themis.symmetricKey((key: any) => { - resolve(Buffer.from(new Uint8Array(key)).toString("base64")); - }) + return new Promise((resolve) => { + Themis.symmetricKey((key: any) => { + resolve(Buffer.from(new Uint8Array(key)).toString("base64")); }) + }) }; export function secureCellSealWithSymmetricKeyEncrypt64( - symmetricKey64: String, - plaintext: String, - context: String = ""): Promise { - - checkInput(plaintext, "plaintext"); // check plaintext is not empty - const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); // check symmetricKey64 is not empty and base64 encoded - - return new Promise((resolve, reject) => { - Themis.secureCellSealWithSymmetricKeyEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) - }, (error: any) => { - reject(error) - }) + symmetricKey64: String, + plaintext: String, + context: String = ""): Promise { + + checkInput(plaintext, "plaintext"); // check plaintext is not empty + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); // check symmetricKey64 is not empty and base64 encoded + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithSymmetricKeyEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) }) + }) }; export function secureCellSealWithSymmetricKeyDecrypt64( - symmetricKey64: String, - encrypted64: String, - context: String = ""): Promise { - - const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); - const encrypted = convertInputBase64(encrypted64, "encrypted64"); - - return new Promise((resolve, reject) => { - Themis.secureCellSealWithSymmetricKeyDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) - }) + symmetricKey64: String, + encrypted64: String, + context: String = ""): Promise { + + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithSymmetricKeyDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) }) + }) }; export function secureCellSealWithPassphraseEncrypt64( - passphrase: String, - plaintext: String, - context: String = ""): Promise { - - checkInput(plaintext, "plaintext"); - checkInput(passphrase, "passphrase"); - - return new Promise((resolve, reject) => { - Themis.secureCellSealWithPassphraseEncrypt(passphrase, plaintext, context, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) - }, (error: any) => { - reject(error) - }); + passphrase: String, + plaintext: String, + context: String = ""): Promise { + + checkInput(plaintext, "plaintext"); + checkInput(passphrase, "passphrase"); + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithPassphraseEncrypt(passphrase, plaintext, context, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) }); + }); }; export function secureCellSealWithPassphraseDecrypt64( - passphrase: String, - encrypted64: String, - context: String = ""): Promise { - - checkInput(passphrase, "passphrase"); - const encrypted = convertInputBase64(encrypted64, "encrypted64"); - - return new Promise((resolve, reject) => { - Themis.secureCellSealWithPassphraseDecrypt(passphrase, encrypted, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()); - }, (error: any) => { - reject(error); - }) - }); + passphrase: String, + encrypted64: String, + context: String = ""): Promise { + + checkInput(passphrase, "passphrase"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + + return new Promise((resolve, reject) => { + Themis.secureCellSealWithPassphraseDecrypt(passphrase, encrypted, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()); + }, (error: any) => { + reject(error); + }) + }); } export function secureCellTokenProtectEncrypt64( - symmetricKey64: String, - plaintext: String, - context: String = ""): Promise { - - checkInput(plaintext, "plaintext"); - const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); - - return new Promise((resolve, reject) => { - Themis.secureCellTokenProtectEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { - const data = Buffer.from(new Uint8Array(encrypted.encrypted)).toString("base64") - const token = Buffer.from(new Uint8Array(encrypted.token)).toString("base64") - resolve({ - encrypted64: data, - token64: token - }) - }, (error: any) => { - reject(error) - }) + symmetricKey64: String, + plaintext: String, + context: String = ""): Promise { + + checkInput(plaintext, "plaintext"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + + return new Promise((resolve, reject) => { + Themis.secureCellTokenProtectEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { + const data = Buffer.from(new Uint8Array(encrypted.encrypted)).toString("base64") + const token = Buffer.from(new Uint8Array(encrypted.token)).toString("base64") + resolve({ + encrypted64: data, + token64: token + }) + }, (error: any) => { + reject(error) }) + }) } export function secureCellTokenProtectDecrypt64( - symmetricKey64: String, - encrypted64: String, - token64: String, - context: String = ""): Promise { - - const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); - const encrypted = convertInputBase64(encrypted64, "encrypted64"); - const token = convertInputBase64(token64, "token64"); - - return new Promise((resolve, reject) => { - Themis.secureCellTokenProtectDecrypt(symmetricKey, encrypted, token, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) - }) + symmetricKey64: String, + encrypted64: String, + token64: String, + context: String = ""): Promise { + + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + const token = convertInputBase64(token64, "token64"); + + return new Promise((resolve, reject) => { + Themis.secureCellTokenProtectDecrypt(symmetricKey, encrypted, token, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) }) + }) } // context imprint encrypt and decrypt export function secureCellContextImprintEncrypt64( - symmetricKey64: String, - plaintext: String, - context: String): Promise { - - checkInput(plaintext, "plaintext"); - checkInput(context, "context"); - const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); - - return new Promise((resolve, reject) => { - Themis.secureCellContextImprintEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) - }, (error: any) => { - reject(error) - }) - }); + symmetricKey64: String, + plaintext: String, + context: String): Promise { + + checkInput(plaintext, "plaintext"); + checkInput(context, "context"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + + return new Promise((resolve, reject) => { + Themis.secureCellContextImprintEncrypt(symmetricKey, plaintext, context, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) + }) + }); } export function secureCellContextImprintDecrypt64( - symmetricKey64: String, - encrypted64: String, - context: String): Promise { - - checkInput(context, "context"); - const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); - const encrypted = convertInputBase64(encrypted64, "encrypted64"); - - return new Promise((resolve, reject) => { - Themis.secureCellContextImprintDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) - }) - }); + symmetricKey64: String, + encrypted64: String, + context: String): Promise { + + checkInput(context, "context"); + const symmetricKey = convertInputBase64(symmetricKey64, "symmetricKey64"); + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + + return new Promise((resolve, reject) => { + Themis.secureCellContextImprintDecrypt(symmetricKey, encrypted, context, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) + }) + }); } // secure message sign and verify export function secureMessageSign64( - plaintext: String, - privateKey64: String, - _publicKey64: String = ""): Promise { - - checkInput(plaintext, "plaintext"); - const privateKey = convertInputBase64(privateKey64, "privateKey64"); - - return new Promise((resolve, reject) => { - Themis.secureMessageSign(plaintext, privateKey, (signed: any) => { - resolve(Buffer.from(new Uint8Array(signed)).toString("base64")) - }, (error: any) => { - reject(error) - }) + plaintext: String, + privateKey64: String, + _publicKey64: String = ""): Promise { + + checkInput(plaintext, "plaintext"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageSign(plaintext, privateKey, (signed: any) => { + resolve(Buffer.from(new Uint8Array(signed)).toString("base64")) + }, (error: any) => { + reject(error) }) + }) } export function secureMessageVerify64( - signed64: String, - _privateKey64: String = "", - publicKey64: String): Promise { - - const signed = convertInputBase64(signed64, "signed64"); - const publicKey = convertInputBase64(publicKey64, "publicKey64"); - - return new Promise((resolve, reject) => { - Themis.secureMessageVerify(signed, publicKey, (verified: any) => { - resolve(Buffer.from(new Uint8Array(verified)).toString()) - }, (error: any) => { - reject(error) - }) + signed64: String, + _privateKey64: String = "", + publicKey64: String): Promise { + + const signed = convertInputBase64(signed64, "signed64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageVerify(signed, publicKey, (verified: any) => { + resolve(Buffer.from(new Uint8Array(verified)).toString()) + }, (error: any) => { + reject(error) }) + }) } // secure message encrypt and decrypt export function secureMessageEncrypt64( - plaintext: String, - privateKey64: String, - publicKey64: String): Promise { - - checkInput(plaintext, "plaintext"); - const privateKey = convertInputBase64(privateKey64, "privateKey64"); - const publicKey = convertInputBase64(publicKey64, "publicKey64"); - - return new Promise((resolve, reject) => { - Themis.secureMessageEncrypt(plaintext, privateKey, publicKey, (encrypted: any) => { - resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) - }, (error: any) => { - reject(error) - }) + plaintext: String, + privateKey64: String, + publicKey64: String): Promise { + + checkInput(plaintext, "plaintext"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageEncrypt(plaintext, privateKey, publicKey, (encrypted: any) => { + resolve(Buffer.from(new Uint8Array(encrypted)).toString("base64")) + }, (error: any) => { + reject(error) }) + }) } export function secureMessageDecrypt64( - encrypted64: String, - privateKey64: String, - publicKey64: String): Promise { - - const encrypted = convertInputBase64(encrypted64, "encrypted64"); - const privateKey = convertInputBase64(privateKey64, "privateKey64"); - const publicKey = convertInputBase64(publicKey64, "publicKey64"); - - return new Promise((resolve, reject) => { - Themis.secureMessageDecrypt(encrypted, privateKey, publicKey, (decrypted: any) => { - resolve(Buffer.from(new Uint8Array(decrypted)).toString()) - }, (error: any) => { - reject(error) - }) + encrypted64: String, + privateKey64: String, + publicKey64: String): Promise { + + const encrypted = convertInputBase64(encrypted64, "encrypted64"); + const privateKey = convertInputBase64(privateKey64, "privateKey64"); + const publicKey = convertInputBase64(publicKey64, "publicKey64"); + + return new Promise((resolve, reject) => { + Themis.secureMessageDecrypt(encrypted, privateKey, publicKey, (decrypted: any) => { + resolve(Buffer.from(new Uint8Array(decrypted)).toString()) + }, (error: any) => { + reject(error) }) + }) } /* Returns UUID in string value that corresponds to new comparator */ export function comparatorInit64(data64: String): Promise { - const data = convertInputBase64(data64, "data64"); + const data = convertInputBase64(data64, "data64"); - return new Promise((resolve, reject) => { - Themis.initComparator(data, (comparator: string) => { - resolve(comparator) - }, (error: any) => { - reject(error) - }) + return new Promise((resolve, reject) => { + Themis.initComparator(data, (comparator: string) => { + resolve(comparator) + }, (error: any) => { + reject(error) }) + }) } export function comparatorBegin(uuidStr: String): Promise { - checkInput(uuidStr, "uuidStr"); - - return new Promise((resolve, reject) => { - Themis.beginCompare(uuidStr, (data: any) => { - resolve(Buffer.from(new Uint8Array(data)).toString("base64")) - }, (error: any) => { - reject(error) - }) + checkInput(uuidStr, "uuidStr"); + + return new Promise((resolve, reject) => { + Themis.beginCompare(uuidStr, (data: any) => { + resolve(Buffer.from(new Uint8Array(data)).toString("base64")) + }, (error: any) => { + reject(error) }) + }) } /* Returns next part of data and current status */ export function comparatorProceed64( - uuidStr: String, - data64: String): Promise { - - checkInput(uuidStr, "uuidStr"); - const data = convertInputBase64(data64, "data64"); - - return new Promise((resolve, reject) => { - Themis.proceedCompare(uuidStr, data, (nextData: any, status: Number) => { - const nextdata64 = Buffer.from(new Uint8Array(nextData)).toString("base64") - resolve({ - data64: nextdata64, - status: status - }) - }, (error: any) => { - reject(error) - }) + uuidStr: String, + data64: String): Promise { + + checkInput(uuidStr, "uuidStr"); + const data = convertInputBase64(data64, "data64"); + + return new Promise((resolve, reject) => { + Themis.proceedCompare(uuidStr, data, (nextData: any, status: Number) => { + const nextdata64 = Buffer.from(new Uint8Array(nextData)).toString("base64") + resolve({ + data64: nextdata64, + status: status + }) + }, (error: any) => { + reject(error) }) + }) } \ No newline at end of file From 356e01bf001d42c0367932e714f395bfa557ca90 Mon Sep 17 00:00:00 2001 From: Alex Radetsky Date: Fri, 14 Oct 2022 21:39:04 +0300 Subject: [PATCH 3/3] no more short names --- .../com/reactnativethemis/ThemisModule.java | 90 +++++------ .../react-native-themis/ios/RCTThemis.m | 146 +++++++++--------- 2 files changed, 118 insertions(+), 118 deletions(-) diff --git a/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java b/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java index 1882e5958..486195a55 100644 --- a/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java +++ b/src/wrappers/themis/react-native-themis/android/src/main/java/com/reactnativethemis/ThemisModule.java @@ -165,8 +165,8 @@ public void secureCellSealWithSymmetricKeyEncrypt(ReadableArray symmetricKey, Callback errorCallback) { try { - byte[] key = dataDeserialize(symmetricKey); - SecureCell.Seal cell = SecureCell.SealWithKey(key); + byte[] symmetricKeyBinary = dataDeserialize(symmetricKey); + SecureCell.Seal cell = SecureCell.SealWithKey(symmetricKeyBinary); byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); @@ -187,11 +187,11 @@ public void secureCellSealWithSymmetricKeyDecrypt(ReadableArray symmetricKey, Callback errorCallback) { try { - byte[] key = dataDeserialize(symmetricKey); - SecureCell.Seal cell = SecureCell.SealWithKey(key); - byte[] enc = dataDeserialize(encrypted); + byte[] symmetricKeyBinary = dataDeserialize(symmetricKey); + SecureCell.Seal cell = SecureCell.SealWithKey(symmetricKeyBinary); + byte[] encryptedBinary = dataDeserialize(encrypted); byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, contextBinary); + byte[] decrypted = cell.decrypt(encryptedBinary, contextBinary); WritableArray response = dataSerialize(decrypted); successCallback.invoke(response); } catch (Exception e) { @@ -231,9 +231,9 @@ public void secureCellSealWithPassphraseDecrypt(String passphrase, { try { SecureCell.Seal cell = SecureCell.SealWithPassphrase(passphrase); - byte[] enc = dataDeserialize(encrypted); + byte[] encryptedBinary = dataDeserialize(encrypted); byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, contextBinary); + byte[] decrypted = cell.decrypt(encryptedBinary, contextBinary); WritableArray response = dataSerialize(decrypted); successCallback.invoke(response); } catch (Exception e) { @@ -252,8 +252,8 @@ public void secureCellTokenProtectEncrypt(ReadableArray symmetricKey, Callback errorCallback) { try { - byte[] bkey = dataDeserialize(symmetricKey); - SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); + byte[] symmetricKeyBinary = dataDeserialize(symmetricKey); + SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(symmetricKeyBinary); byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); SecureCellData result = cell.encrypt(plaintextBinary, contextBinary); @@ -279,12 +279,12 @@ public void secureCellTokenProtectDecrypt(ReadableArray symmetricKey, Callback errorCallback) { try { - byte[] bkey = dataDeserialize(symmetricKey); - byte[] enc = dataDeserialize(encrypted); - byte[] tkn = dataDeserialize(token); - SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(bkey); + byte[] symmetricKeyBinary = dataDeserialize(symmetricKey); + byte[] encryptedBinary = dataDeserialize(encrypted); + byte[] tokenBinary = dataDeserialize(token); + SecureCell.TokenProtect cell = SecureCell.TokenProtectWithKey(symmetricKeyBinary); byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, tkn, contextBinary); + byte[] decrypted = cell.decrypt(encryptedBinary, tokenBinary, contextBinary); WritableArray response = dataSerialize(decrypted); successCallback.invoke(response); } catch (Exception e) { @@ -309,8 +309,8 @@ public void secureCellContextImprintEncrypt(ReadableArray symmetricKey, return; } try { - byte[] bkey = dataDeserialize(symmetricKey); - SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); + byte[] symmetricKeyBinary = dataDeserialize(symmetricKey); + SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(symmetricKeyBinary); byte[] plaintextBinary = plaintext.getBytes(StandardCharsets.UTF_8); byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); byte[] encrypted = cell.encrypt(plaintextBinary, contextBinary); @@ -337,11 +337,11 @@ public void secureCellContextImprintDecrypt(ReadableArray symmetricKey, return; } try { - byte[] bkey = dataDeserialize(symmetricKey); - byte[] enc = dataDeserialize(encrypted); - SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(bkey); + byte[] symmetricKeyBinary = dataDeserialize(symmetricKey); + byte[] encryptedBinary = dataDeserialize(encrypted); + SecureCell.ContextImprint cell = SecureCell.ContextImprintWithKey(symmetricKeyBinary); byte[] contextBinary = context.getBytes(StandardCharsets.UTF_8); - byte[] decrypted = cell.decrypt(enc, contextBinary); + byte[] decrypted = cell.decrypt(encryptedBinary, contextBinary); WritableArray response = dataSerialize(decrypted); successCallback.invoke(response); } catch (Exception e) { @@ -365,11 +365,11 @@ public void secureMessageSign(String message, return; } try { - byte[] bkey = dataDeserialize(privateKey); - PrivateKey pvtKey = new PrivateKey(bkey); - byte[] msg = message.getBytes(StandardCharsets.UTF_8); - SecureMessage secureMessage = new SecureMessage(pvtKey); - byte[] signedMessage = secureMessage.sign(msg); + byte[] privateKeyBinary = dataDeserialize(privateKey); + PrivateKey keyPrivateKey = new PrivateKey(privateKeyBinary); + byte[] messageBinary = message.getBytes(StandardCharsets.UTF_8); + SecureMessage secureMessage = new SecureMessage(keyPrivateKey); + byte[] signedMessage = secureMessage.sign(messageBinary); WritableArray response = dataSerialize(signedMessage); successCallback.invoke(response); } catch (Exception e) { @@ -392,11 +392,11 @@ public void secureMessageVerify(ReadableArray message, return; } try { - byte[] bkey = dataDeserialize(publicKey); - PublicKey pubKey = new PublicKey(bkey); - byte[] msg = dataDeserialize(message); - SecureMessage secureMessage = new SecureMessage(pubKey); - byte[] verifiedMessage = secureMessage.verify(msg, pubKey); + byte[] publicKeyBinary = dataDeserialize(publicKey); + PublicKey keyPublicKey = new PublicKey(publicKeyBinary); + byte[] messageBinary = dataDeserialize(message); + SecureMessage secureMessage = new SecureMessage(keyPublicKey); + byte[] verifiedMessage = secureMessage.verify(messageBinary, keyPublicKey); WritableArray response = dataSerialize(verifiedMessage); successCallback.invoke(response); } catch (Exception e) { @@ -426,13 +426,13 @@ public void secureMessageEncrypt(String message, return; } try { - byte[] bkey = dataDeserialize(privateKey); - PrivateKey pvtKey = new PrivateKey(bkey); - bkey = dataDeserialize(publicKey); - PublicKey pubKey = new PublicKey(bkey); - byte[] msg = message.getBytes(StandardCharsets.UTF_8); - SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); - byte[] encryptedMessage = secureMessage.wrap(msg); + byte[] privateKeyBinary = dataDeserialize(privateKey); + PrivateKey keyPrivateKey = new PrivateKey(privateKeyBinary); + byte[] publicKeyBinary = dataDeserialize(publicKey); + PublicKey keyPublicKey = new PublicKey(publicKeyBinary); + byte[] messageBinary = message.getBytes(StandardCharsets.UTF_8); + SecureMessage secureMessage = new SecureMessage(keyPrivateKey, keyPublicKey); + byte[] encryptedMessage = secureMessage.wrap(messageBinary); WritableArray response = dataSerialize(encryptedMessage); successCallback.invoke(response); } catch (Exception e) { @@ -462,13 +462,13 @@ public void secureMessageDecrypt(ReadableArray message, return; } try { - byte[] bkey = dataDeserialize(privateKey); - PrivateKey pvtKey = new PrivateKey(bkey); - bkey = dataDeserialize(publicKey); - PublicKey pubKey = new PublicKey(bkey); - byte[] msg = dataDeserialize(message); - SecureMessage secureMessage = new SecureMessage(pvtKey, pubKey); - byte[] decrypted = secureMessage.unwrap(msg, pubKey); + byte[] privateKeyBinary = dataDeserialize(privateKey); + PrivateKey keyPrivateKey = new PrivateKey(privateKeyBinary); + byte[] publicKeyBinary = dataDeserialize(publicKey); + PublicKey keyPublicKey = new PublicKey(publicKeyBinary); + byte[] messageBinary = dataDeserialize(message); + SecureMessage secureMessage = new SecureMessage(keyPrivateKey, keyPublicKey); + byte[] decrypted = secureMessage.unwrap(messageBinary, keyPublicKey); WritableArray response = dataSerialize(decrypted); successCallback.invoke(response); } catch (Exception e) { diff --git a/src/wrappers/themis/react-native-themis/ios/RCTThemis.m b/src/wrappers/themis/react-native-themis/ios/RCTThemis.m index 953df8754..9df265036 100644 --- a/src/wrappers/themis/react-native-themis/ios/RCTThemis.m +++ b/src/wrappers/themis/react-native-themis/ios/RCTThemis.m @@ -104,7 +104,7 @@ + (NSData*)dataDeserialize: (NSArray*) data error:(NSError**) error callback:(RCTResponseSenderBlock)callback ) { - NSData* data = [text dataUsingEncoding:NSUTF8StringEncoding]; + NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding]; NSArray *data2 = [RCTThemis dataSerialize: data]; callback(@[data2]); } @@ -168,11 +168,11 @@ - (TSCellSeal *)newSealMode: (NSArray*) symmetricKey error:(NSError**) error return; } - NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *encrypted = [cell encrypt:plaintextBinary - context:contextBinary - error:&error]; + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *encrypted = [cell encrypt:plaintextBinary + context:contextBinary + error:&error]; if (encrypted == nil) { errorCallback(error); return; @@ -190,7 +190,7 @@ - (TSCellSeal *)newSealMode: (NSArray*) symmetricKey error:(NSError**) error { TSCellSeal *cell; - NSData *enc; + NSData *encryptedBinary; NSError *error; cell = [self newSealMode:symmetricKey error:&error]; @@ -199,16 +199,16 @@ - (TSCellSeal *)newSealMode: (NSArray*) symmetricKey error:(NSError**) error return; } - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { + encryptedBinary = [RCTThemis dataDeserialize:encrypted error:&error]; + if (encryptedBinary == nil) { errorCallback(error); return; } - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc - context:contextBinary - error:&error]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:encryptedBinary + context:contextBinary + error:&error]; if (decrypted == nil) { errorCallback(error); } else { @@ -232,9 +232,9 @@ - (TSCellSeal *)newSealModeWithPassphrase: (NSString*) passphrase errorCallback: (RCTResponseErrorBlock)errorCallback ) { - TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; - NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; NSError *error; NSData *encrypted = [cell encrypt:plaintextBinary context:contextBinary error:&error]; @@ -255,18 +255,18 @@ - (TSCellSeal *)newSealModeWithPassphrase: (NSString*) passphrase ) { - TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; - NSData *enc; + TSCellSeal *cell = [self newSealModeWithPassphrase:passphrase]; + NSData *encryptedBinary; NSError *error; - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { + encryptedBinary = [RCTThemis dataDeserialize:encrypted error:&error]; + if (encryptedBinary == nil) { errorCallback(error); return; } - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:encryptedBinary context:contextBinary error:&error]; if (decrypted == nil) { @@ -305,8 +305,8 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error return; } - NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *plaintextBinary = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; TSCellTokenEncryptedResult *result = [cell encrypt:plaintextBinary context:contextBinary error:&error]; if (result == nil ) { @@ -334,8 +334,8 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error { TSCellToken *cell; - NSData *enc; - NSData *tkn; + NSData *encryptedBinary; + NSData *tokenBinary; NSError *error; cell = [self newTokenMode:symmetricKey error:&error]; @@ -344,21 +344,21 @@ - (TSCellToken *)newTokenMode:(NSArray*) symmetricKey error:(NSError**) error return; } - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { + encryptedBinary = [RCTThemis dataDeserialize:encrypted error:&error]; + if (encryptedBinary == nil) { errorCallback(error); return; } - tkn = [RCTThemis dataDeserialize:token error:&error]; - if (tkn == nil) { + tokenBinary = [RCTThemis dataDeserialize:token error:&error]; + if (tokenBinary == nil) { errorCallback(error); return; } - NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc - token:tkn + NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; + NSData *decrypted = [cell decrypt:encryptedBinary + token:tokenBinary context:contextBinary error:&error]; if (decrypted == nil) { @@ -428,7 +428,7 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr } TSCellContextImprint *cell; - NSData *enc; + NSData *encryptedBinary; NSError *error; cell = [self newContextImprint:symmetricKey error:&error]; @@ -436,14 +436,14 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr errorCallback(error); return; } - enc = [RCTThemis dataDeserialize:encrypted error:&error]; - if (enc == nil) { + encryptedBinary = [RCTThemis dataDeserialize:encrypted error:&error]; + if (encryptedBinary == nil) { errorCallback(error); return; } NSData *contextBinary = [context dataUsingEncoding:NSUTF8StringEncoding]; - NSData *decrypted = [cell decrypt:enc + NSData *decrypted = [cell decrypt:encryptedBinary context:contextBinary error:&error ]; @@ -470,20 +470,20 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr return; } - NSData *pvtKey; + NSData *privateKeyBinary; NSError *error; - pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; - if (pvtKey == nil) { + privateKeyBinary = [RCTThemis dataDeserialize:privateKey error:&error]; + if (privateKeyBinary == nil) { errorCallback(error); return; } - NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; - TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:pvtKey + NSData* messageBinary = [message dataUsingEncoding:NSUTF8StringEncoding]; + TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:privateKeyBinary peerPublicKey:nil]; - NSData *signedMessage = [secureMessage wrapData:msg error:&error]; + NSData *signedMessage = [secureMessage wrapData:messageBinary error:&error]; if (signedMessage == nil) { errorCallback(error); } else { @@ -505,26 +505,26 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr return; } - NSData *pubKey; - NSData *msg; + NSData *publicKeyBinary; + NSData *messageBinary; NSError *error; - pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; - if (pubKey == nil) { + publicKeyBinary = [RCTThemis dataDeserialize:publicKey error:&error]; + if (publicKeyBinary == nil) { errorCallback(error); return; } - msg = [RCTThemis dataDeserialize:message error:&error]; - if (msg == nil) { + messageBinary = [RCTThemis dataDeserialize:message error:&error]; + if (messageBinary == nil) { errorCallback(error); return; } TSMessage *secureMessage = [[TSMessage alloc] initInSignVerifyModeWithPrivateKey:nil - peerPublicKey:pubKey]; + peerPublicKey:publicKeyBinary]; - NSData *verifiedMessage = [secureMessage unwrapData:msg error:&error]; + NSData *verifiedMessage = [secureMessage unwrapData:messageBinary error:&error]; if (verifiedMessage == nil) { errorCallback(error); } else { @@ -553,26 +553,26 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr return; } - NSData *pvtKey; - NSData *pubKey; + NSData *privateKeyBinary; + NSData *publicKeyBinary; NSError *error; - pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; - if (pvtKey == nil) { + privateKeyBinary = [RCTThemis dataDeserialize:privateKey error:&error]; + if (privateKeyBinary == nil) { errorCallback(error); return; } - pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; - if (pubKey == nil) { + publicKeyBinary = [RCTThemis dataDeserialize:publicKey error:&error]; + if (publicKeyBinary == nil) { errorCallback(error); return; } - NSData* msg = [message dataUsingEncoding:NSUTF8StringEncoding]; - TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; + NSData* messageBinary = [message dataUsingEncoding:NSUTF8StringEncoding]; + TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:privateKeyBinary + peerPublicKey:publicKeyBinary]; - NSData *encryptedMessage = [secureMessage wrapData:msg error:&error]; + NSData *encryptedMessage = [secureMessage wrapData:messageBinary error:&error]; if (encryptedMessage == nil) { errorCallback(error); } else { @@ -600,31 +600,31 @@ - (TSCellContextImprint *)newContextImprint:(NSArray*) symmetricKey error: (NSEr return; } - NSData *pvtKey; - NSData *pubKey; - NSData *msg; + NSData *privateKeyBinary; + NSData *publicKeyBinary; + NSData *messageBinary; NSError *error; - pvtKey = [RCTThemis dataDeserialize:privateKey error:&error]; - if (pvtKey == nil) { + privateKeyBinary = [RCTThemis dataDeserialize:privateKey error:&error]; + if (privateKeyBinary == nil) { errorCallback(error); return; } - pubKey = [RCTThemis dataDeserialize:publicKey error:&error]; - if (pubKey == nil) { + publicKeyBinary = [RCTThemis dataDeserialize:publicKey error:&error]; + if (publicKeyBinary == nil) { errorCallback(error); return; } - msg = [RCTThemis dataDeserialize:message error:&error]; - if (msg == nil) { + messageBinary = [RCTThemis dataDeserialize:message error:&error]; + if (messageBinary == nil) { errorCallback(error); return; } - TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:pvtKey - peerPublicKey:pubKey]; + TSMessage *secureMessage = [[TSMessage alloc] initInEncryptModeWithPrivateKey:privateKeyBinary + peerPublicKey:publicKeyBinary]; - NSData *decryptedMessage = [secureMessage unwrapData:msg error:&error]; + NSData *decryptedMessage = [secureMessage unwrapData:messageBinary error:&error]; if (decryptedMessage == nil) { errorCallback(error); } else {