diff --git a/README.md b/README.md index cb54c17..dd36782 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ This plugin is for use with [Cordova](http://incubator.apache.org/cordova/) and - [Plugin API](#plugin-api) - [LICENSE](#license) -##Installation +## Installation Below are the methods for installing this plugin automatically using command line tools. For additional info, take a look at the [Plugman Documentation](https://github.com/apache/cordova-plugman/blob/master/README.md) and [Cordova Plugin Specification](https://github.com/alunny/cordova-plugin-spec). @@ -33,7 +33,7 @@ or if you want to be running the development version, cordova plugin add https://github.com/Crypho/cordova-plugin-scrypt.git ``` -## Plugin API +## Plugin API Grab the plugin instance variable. @@ -58,7 +58,7 @@ scrypt( ) ``` -The ``salt`` parameter can be a string or an array of uint8. You can provide custom ``scrypt`` parameters in the options dict. The defaults are +The ``password`` or ``salt`` parameters can be a string or an array of uint8. You can provide custom ``scrypt`` parameters in the options dict. The defaults are ```js { N: 16384, @@ -92,7 +92,7 @@ cordova plugin add PATH_TO_SCRYPT_PLUGIN/tests Just run the app for all platforms. Remember, if you have changes to test you will need to remove the scrypt plugin and add it again for the changes to be seen by the app. -## LICENSE +## LICENSE The MIT License diff --git a/jni/scrypt-jni.c b/jni/scrypt-jni.c index 208abb9..6f01144 100644 --- a/jni/scrypt-jni.c +++ b/jni/scrypt-jni.c @@ -19,7 +19,7 @@ static void throwException(JNIEnv* env, char *msg); JNIEXPORT jbyteArray JNICALL Java_com_crypho_plugins_ScryptPlugin_scrypt( JNIEnv* env, jobject thiz, - jbyteArray pass, jcharArray salt, jobject N, jobject r, jobject p, jobject dkLen) + jbyteArray pass, jbyteArray salt, jobject N, jobject r, jobject p, jobject dkLen) { int i; char *msg_error; @@ -47,20 +47,12 @@ Java_com_crypho_plugins_ScryptPlugin_scrypt( JNIEnv* env, jobject thiz, goto END; } - jchar *salt_chars = (*env)->GetCharArrayElements(env, salt, NULL); + jbyte *salt_bytes = (*env)->GetByteArrayElements(env, salt, NULL); if((*env)->ExceptionOccurred(env)) { LOGE("Failed to get salt elements."); goto END; } - uint8_t *parsedSalt = malloc(sizeof(uint8_t) * saltLen); - if (parsedSalt == NULL) { - msg_error = "Failed to malloc parsedSalt."; - LOGE("%s", msg_error); - throwException(env, msg_error); - goto END; - } - uint8_t *hashbuf = malloc(sizeof(uint8_t) * dkLen_i); if (hashbuf == NULL) { msg_error = "Failed to malloc hashbuf."; @@ -69,11 +61,7 @@ Java_com_crypho_plugins_ScryptPlugin_scrypt( JNIEnv* env, jobject thiz, goto END; } - for (i = 0; i < saltLen; ++i) { - parsedSalt[i] = (uint8_t) salt_chars[i]; - } - - if (libscrypt_scrypt(passphrase, passLen, parsedSalt, saltLen, N_i, r_i, p_i, hashbuf, dkLen_i)) { + if (libscrypt_scrypt(passphrase, passLen, salt_bytes, saltLen, N_i, r_i, p_i, hashbuf, dkLen_i)) { switch (errno) { case EINVAL: msg_error = "N must be a power of 2 greater than 1."; @@ -103,9 +91,8 @@ Java_com_crypho_plugins_ScryptPlugin_scrypt( JNIEnv* env, jobject thiz, END: if (passphrase) (*env)->ReleaseByteArrayElements(env, pass, passphrase, JNI_ABORT); - if (salt_chars) (*env)->ReleaseCharArrayElements(env, salt, salt_chars, JNI_ABORT); + if (salt_bytes) (*env)->ReleaseByteArrayElements(env, salt, salt_bytes, JNI_ABORT); if (hashbuf) free(hashbuf); - if (parsedSalt) free(parsedSalt); return result; } diff --git a/libs/arm64-v8a/libscrypt_crypho.so b/libs/arm64-v8a/libscrypt_crypho.so index 2ed2ddb..93c02e2 100755 Binary files a/libs/arm64-v8a/libscrypt_crypho.so and b/libs/arm64-v8a/libscrypt_crypho.so differ diff --git a/libs/armeabi-v7a/libscrypt_crypho.so b/libs/armeabi-v7a/libscrypt_crypho.so index 9b5f883..35da1e2 100755 Binary files a/libs/armeabi-v7a/libscrypt_crypho.so and b/libs/armeabi-v7a/libscrypt_crypho.so differ diff --git a/libs/armeabi/libscrypt_crypho.so b/libs/armeabi/libscrypt_crypho.so deleted file mode 100755 index a06d664..0000000 Binary files a/libs/armeabi/libscrypt_crypho.so and /dev/null differ diff --git a/libs/mips/libscrypt_crypho.so b/libs/mips/libscrypt_crypho.so deleted file mode 100755 index 95b0212..0000000 Binary files a/libs/mips/libscrypt_crypho.so and /dev/null differ diff --git a/libs/mips64/libscrypt_crypho.so b/libs/mips64/libscrypt_crypho.so deleted file mode 100755 index eaeaa91..0000000 Binary files a/libs/mips64/libscrypt_crypho.so and /dev/null differ diff --git a/libs/x86/libscrypt_crypho.so b/libs/x86/libscrypt_crypho.so index 9964ecd..5af06c1 100755 Binary files a/libs/x86/libscrypt_crypho.so and b/libs/x86/libscrypt_crypho.so differ diff --git a/libs/x86_64/libscrypt_crypho.so b/libs/x86_64/libscrypt_crypho.so index a653295..32f7251 100755 Binary files a/libs/x86_64/libscrypt_crypho.so and b/libs/x86_64/libscrypt_crypho.so differ diff --git a/plugin.xml b/plugin.xml index a2c3233..5858579 100644 --- a/plugin.xml +++ b/plugin.xml @@ -65,18 +65,12 @@ - - - - - - diff --git a/src/android/com/crypho/plugins/ScryptPlugin.java b/src/android/com/crypho/plugins/ScryptPlugin.java index fd67d6e..632771c 100644 --- a/src/android/com/crypho/plugins/ScryptPlugin.java +++ b/src/android/com/crypho/plugins/ScryptPlugin.java @@ -20,14 +20,13 @@ public class ScryptPlugin extends CordovaPlugin { System.loadLibrary("scrypt_crypho"); } - public native byte[] scrypt(byte[] pass, char[] salt, Integer N, Integer r, Integer p, Integer dkLen); + public native byte[] scrypt(byte[] pass, byte[] salt, Integer N, Integer r, Integer p, Integer dkLen); @Override public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException { if ("scrypt".equals(action)) { - String parsedSalt = null; - final String arg_passphrase = args.getString(0); - final char[] arg_salt = getSalt(args.get(1)); + final Object arg_passphrase = args.get(0); + final Object arg_salt = args.get(1); JSONObject options = args.getJSONObject(2); final Integer N = getIntegerOption("N", options); @@ -38,8 +37,9 @@ public boolean execute(String action, CordovaArgs args, final CallbackContext ca cordova.getThreadPool().execute(new Runnable() { public void run() { try { - byte[] passwordBytes = arg_passphrase.getBytes("UTF-8"); - byte[] res = scrypt(passwordBytes, arg_salt, N, r, p, dkLen); + byte[] passwordBytes = getBytes(arg_passphrase); + byte[] saltBytes = getBytes(arg_salt); + byte[] res = scrypt(passwordBytes, saltBytes, N, r, p, dkLen); String result = hexify(res); callbackContext.success(result); } catch (Exception e) { @@ -69,17 +69,17 @@ private Integer getIntegerOption(String option, JSONObject options) { return arg != 0 ? Integer.valueOf(arg) : null; } - private char[] getSalt(Object src){ + private byte[] getBytes(Object src) throws Exception { if (src instanceof JSONArray) { JSONArray tmp = (JSONArray) src; int len = tmp.length(); - char[] result = new char[len]; + byte[] result = new byte[len]; for (int i = 0; i < len ; i++) { - result[i] = (char) tmp.optInt(i); + result[i] = (byte) tmp.optInt(i); } return result; } else { - return ((String) src).toCharArray(); + return ((String) src).getBytes("UTF-8"); } } } \ No newline at end of file diff --git a/src/ios/ScryptPlugin.m b/src/ios/ScryptPlugin.m index 38757b8..65b3850 100644 --- a/src/ios/ScryptPlugin.m +++ b/src/ios/ScryptPlugin.m @@ -9,25 +9,44 @@ @implementation ScryptPlugin - (void)scrypt:(CDVInvokedUrlCommand*)command { - int i, success; - size_t saltLength; + const uint8_t *parsedSalt; - uint8_t *buffer = NULL; - const char* passphrase = [[command argumentAtIndex:0] UTF8String]; + const uint8_t *parsedPassphrase; + + size_t passphraseLength; + size_t saltLength; + + id passphrase = [command argumentAtIndex:0]; id salt = [command argumentAtIndex:1]; + uint8_t *passphraseBuffer = NULL; + uint8_t *saltBuffer = NULL; + + if ([passphrase isKindOfClass:[NSString class]]) { + parsedPassphrase = (uint8_t *)(const char*)[passphrase UTF8String]; + passphraseLength = strlen(parsedPassphrase); + } else if ([passphrase isKindOfClass:[NSArray class]]) { + passphraseLength = (int) [passphrase count]; + passphraseBuffer = malloc(sizeof(uint8_t) * passphraseLength); + + for (i = 0; i < passphraseLength; ++i) { + passphraseBuffer[i] = (uint8_t)[[passphrase objectAtIndex:i] integerValue]; + } + parsedPassphrase = passphraseBuffer; + } + if ([salt isKindOfClass:[NSString class]]) { - parsedSalt = (const uint8_t *)[salt UTF8String]; - saltLength = (size_t) [salt length]; + parsedSalt = (uint8_t *)(const char*)[salt UTF8String]; + saltLength = strlen(parsedSalt); } else if ([salt isKindOfClass:[NSArray class]]) { saltLength = (int) [salt count]; - buffer = malloc(sizeof(uint8_t) * saltLength); + saltBuffer = malloc(sizeof(uint8_t) * saltLength); for (i = 0; i < saltLength; ++i) { - buffer[i] = (uint8_t)[[salt objectAtIndex:i] integerValue]; + saltBuffer[i] = (uint8_t)[[salt objectAtIndex:i] integerValue]; } - parsedSalt = buffer; + parsedSalt = saltBuffer; } // Parse options @@ -41,7 +60,7 @@ - (void)scrypt:(CDVInvokedUrlCommand*)command self.callbackId = command.callbackId; @try { - success = libscrypt_scrypt((uint8_t *)passphrase, strlen(passphrase), parsedSalt, saltLength, N, r, p, hashbuf, dkLen); + success = libscrypt_scrypt(parsedPassphrase, passphraseLength, parsedSalt, saltLength, N, r, p, hashbuf, dkLen); } @catch (NSException * e) { [self failWithMessage: [NSString stringWithFormat:@"%@", e] withError: nil]; @@ -61,7 +80,8 @@ - (void)scrypt:(CDVInvokedUrlCommand*)command NSString *result = [NSString stringWithString: hexResult]; [self successWithMessage: result]; - free(buffer); + free(passphraseBuffer); + free(saltBuffer); } -(void)successWithMessage:(NSString *)message diff --git a/tests/tests.js b/tests/tests.js index 6f26fda..b27d7eb 100644 --- a/tests/tests.js +++ b/tests/tests.js @@ -166,6 +166,42 @@ var testCases = [ "p": 1, "dkLen": 64, "expected": "6837d88873b164bf5692e878fb0f20bd4a1cdc29f5f48a57e94a298984cbc661cb539e2a868498bee67a7a277d962d06ba1d45325eb1c756ff8f685bbacf585a" +}, +{ + "salt": [115, 97, 108, 116], + "password": "Hellø", + "N": 2, + "r": 1, + "p": 1, + "dkLen": 64, + "expected": "6837d88873b164bf5692e878fb0f20bd4a1cdc29f5f48a57e94a298984cbc661cb539e2a868498bee67a7a277d962d06ba1d45325eb1c756ff8f685bbacf585a" +}, +{ + "salt": [115, 97, 108, 116], + "password": [72, 101, 108, 108, 195, 184], + "N": 2, + "r": 1, + "p": 1, + "dkLen": 64, + "expected": "6837d88873b164bf5692e878fb0f20bd4a1cdc29f5f48a57e94a298984cbc661cb539e2a868498bee67a7a277d962d06ba1d45325eb1c756ff8f685bbacf585a" +}, +{ + "salt": "salt", + "password": [72, 101, 108, 108, 195, 184], + "N": 2, + "r": 1, + "p": 1, + "dkLen": 64, + "expected": "6837d88873b164bf5692e878fb0f20bd4a1cdc29f5f48a57e94a298984cbc661cb539e2a868498bee67a7a277d962d06ba1d45325eb1c756ff8f685bbacf585a" +}, +{ + "salt": "🧂", + "password": "🤫", + "N": 2, + "r": 1, + "p": 1, + "dkLen": 64, + "expected": "da79e302d74c384d7d3b3a45d739a54a078c9995a9a4910b05d60303b15eafe191704df3f613b08fdbea8fadd3ea9447b28e9faf068aa02f853daf59224bc79a" }