Skip to content
This repository has been archived by the owner on Dec 30, 2020. It is now read-only.

Allow Passwords as arrays of Uint8 and Salts as UTF-8 strings #10

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This plugin is for use with [Cordova](http://incubator.apache.org/cordova/) and
- [Plugin API](#plugin-api)
- [LICENSE](#license)

##<a name="installation"></a>Installation
## <a name="installation"></a>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).

Expand All @@ -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
```

##<a name="plugin_api"></a> Plugin API
## <a name="plugin_api"></a> Plugin API

Grab the plugin instance variable.

Expand All @@ -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,
Expand Down Expand Up @@ -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.

##<a name="license"></a> LICENSE
## <a name="license"></a> LICENSE

The MIT License

Expand Down
21 changes: 4 additions & 17 deletions jni/scrypt-jni.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.";
Expand All @@ -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.";
Expand Down Expand Up @@ -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;
}
Expand Down
Binary file modified libs/arm64-v8a/libscrypt_crypho.so
Binary file not shown.
Binary file modified libs/armeabi-v7a/libscrypt_crypho.so
Binary file not shown.
Binary file removed libs/armeabi/libscrypt_crypho.so
Binary file not shown.
Binary file removed libs/mips/libscrypt_crypho.so
Binary file not shown.
Binary file removed libs/mips64/libscrypt_crypho.so
Binary file not shown.
Binary file modified libs/x86/libscrypt_crypho.so
Binary file not shown.
Binary file modified libs/x86_64/libscrypt_crypho.so
Binary file not shown.
6 changes: 0 additions & 6 deletions plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,18 +65,12 @@
<source-file src="src/android/com/crypho/plugins/ScryptPlugin.java" target-dir="src/com/crypho/plugins/"/>

<source-file src="libs/arm64-v8a/libscrypt_crypho.so" target-dir="src/main/jniLibs/arm64-v8a/"/>
<source-file src="libs/armeabi/libscrypt_crypho.so" target-dir="src/main/jniLibs/armeabi/"/>
<source-file src="libs/armeabi-v7a/libscrypt_crypho.so" target-dir="src/main/jniLibs/armeabi-v7a/"/>
<source-file src="libs/mips/libscrypt_crypho.so" target-dir="src/main/jniLibs/mips/"/>
<source-file src="libs/mips64/libscrypt_crypho.so" target-dir="src/main/jniLibs/mips64/"/>
<source-file src="libs/x86/libscrypt_crypho.so" target-dir="src/main/jniLibs/x86/"/>
<source-file src="libs/x86_64/libscrypt_crypho.so" target-dir="src/main/jniLibs/x86_64/"/>

<source-file src="libs/arm64-v8a/libscrypt_crypho.so" target-dir="libs/arm64-v8a/"/>
<source-file src="libs/armeabi/libscrypt_crypho.so" target-dir="libs/armeabi/"/>
<source-file src="libs/armeabi-v7a/libscrypt_crypho.so" target-dir="libs/armeabi-v7a/"/>
<source-file src="libs/mips/libscrypt_crypho.so" target-dir="libs/mips/"/>
<source-file src="libs/mips64/libscrypt_crypho.so" target-dir="libs/mips64/"/>
<source-file src="libs/x86/libscrypt_crypho.so" target-dir="libs/x86/"/>
<source-file src="libs/x86_64/libscrypt_crypho.so" target-dir="libs/x86_64/"/>
</platform>
Expand Down
20 changes: 10 additions & 10 deletions src/android/com/crypho/plugins/ScryptPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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) {
Expand Down Expand Up @@ -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");
}
}
}
42 changes: 31 additions & 11 deletions src/ios/ScryptPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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];
Expand All @@ -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
Expand Down
36 changes: 36 additions & 0 deletions tests/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}


Expand Down