diff --git a/Cargo.lock b/Cargo.lock index ba71f18..93595d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,20 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "addr2line" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e" - [[package]] name = "aes" version = "0.4.0" @@ -85,26 +70,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "backtrace" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - [[package]] name = "base64" version = "0.12.3" @@ -280,7 +245,6 @@ dependencies = [ "cbindgen", "dart-bindgen", "dup-crypto", - "ffi_helpers", "thiserror", ] @@ -306,39 +270,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "synstructure", -] - -[[package]] -name = "ffi_helpers" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36a21261040ffbc3999698b39170d6e951f2823dd9ad7b50469309156060a50c" -dependencies = [ - "failure", - "failure_derive", - "libc", -] - [[package]] name = "generic-array" version = "0.14.4" @@ -362,12 +293,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce" - [[package]] name = "glob" version = "0.3.0" @@ -428,22 +353,6 @@ dependencies = [ "cfg-if 0.1.10", ] -[[package]] -name = "miniz_oxide" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d" -dependencies = [ - "adler", - "autocfg", -] - -[[package]] -name = "object" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397" - [[package]] name = "once_cell" version = "1.5.2" @@ -551,12 +460,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "rustc-demangle" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232" - [[package]] name = "ryu" version = "1.0.5" diff --git a/native/dubp_rs/Cargo.toml b/native/dubp_rs/Cargo.toml index c3d7073..feeb05b 100644 --- a/native/dubp_rs/Cargo.toml +++ b/native/dubp_rs/Cargo.toml @@ -11,7 +11,6 @@ crate-type = ["rlib"] [dependencies] allo-isolate = "0.1.6" dup-crypto = { version = "0.36.0", features = ["dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] } -ffi_helpers = "0.2" thiserror = "1.0.23" [build-dependencies] diff --git a/native/dubp_rs/src/dewif.rs b/native/dubp_rs/src/dewif.rs index 372db6e..7d07565 100644 --- a/native/dubp_rs/src/dewif.rs +++ b/native/dubp_rs/src/dewif.rs @@ -35,11 +35,16 @@ pub(super) fn gen_pin10() -> Result { } pub(super) fn change_pin( - currency: &str, - dewif: &str, - old_pin: &str, - new_pin: &str, + currency: *const raw::c_char, + dewif: *const raw::c_char, + old_pin: *const raw::c_char, + new_pin: *const raw::c_char, ) -> Result { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let old_pin = char_ptr_to_str(old_pin)?; + let new_pin = char_ptr_to_str(new_pin)?; + let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), @@ -57,11 +62,15 @@ pub(super) fn change_pin( } pub(super) fn gen_dewif( - currency: &str, + currency: *const raw::c_char, language: u32, - mnemonic: &str, - pin: &str, + mnemonic: *const raw::c_char, + pin: *const raw::c_char, ) -> Result { + let currency = char_ptr_to_str(currency)?; + let mnemonic = char_ptr_to_str(mnemonic)?; + let pin = char_ptr_to_str(pin)?; + let currency = parse_currency(currency)?; let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?) .map_err(|_| DubpError::WrongLanguage)?; @@ -72,12 +81,20 @@ pub(super) fn gen_dewif( )) } -pub(super) fn get_pubkey(currency: &str, dewif: &str, pin: &str) -> Result { +pub(super) fn get_pubkey( + currency: *const raw::c_char, + dewif: *const raw::c_char, + pin: *const raw::c_char, +) -> Result { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let pin = char_ptr_to_str(pin)?; + let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), dewif, - &pin, + &pin.to_ascii_uppercase(), ) .map_err(DubpError::DewifReadError)?; if let Some(KeyPairEnum::Ed25519(keypair)) = keypairs.next() { @@ -87,12 +104,22 @@ pub(super) fn get_pubkey(currency: &str, dewif: &str, pin: &str) -> Result Result { +pub(super) fn sign( + currency: *const raw::c_char, + dewif: *const raw::c_char, + pin: *const raw::c_char, + msg: *const raw::c_char, +) -> Result { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let pin = char_ptr_to_str(pin)?; + let msg = char_ptr_to_str(msg)?; + let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), dewif, - &pin, + &pin.to_ascii_uppercase(), ) .map_err(DubpError::DewifReadError)?; if let Some(KeyPairEnum::Ed25519(keypair)) = keypairs.next() { @@ -103,16 +130,27 @@ pub(super) fn sign(currency: &str, dewif: &str, pin: &str, msg: &str) -> Result< } pub(super) fn sign_several( - currency: &str, - dewif: &str, - pin: &str, - msgs: &[&str], + currency: *const raw::c_char, + dewif: *const raw::c_char, + pin: *const raw::c_char, + msgs_len: usize, + msgs: *const *const raw::c_char, ) -> Result, DubpError> { + let currency = char_ptr_to_str(currency)?; + let dewif = char_ptr_to_str(dewif)?; + let pin = char_ptr_to_str(pin)?; + + let msgs_slice: &[*const raw::c_char] = unsafe { std::slice::from_raw_parts(msgs, msgs_len) }; + let mut msgs = Vec::with_capacity(msgs_len); + for ptr_c_char in msgs_slice { + msgs.push(char_ptr_to_str(*ptr_c_char)?); + } + let currency = parse_currency(currency)?; let mut keypairs = dup_crypto::dewif::read_dewif_file_content( ExpectedCurrency::Specific(currency), dewif, - &pin, + &pin.to_ascii_uppercase(), ) .map_err(DubpError::DewifReadError)?; if let Some(KeyPairEnum::Ed25519(keypair)) = keypairs.next() { diff --git a/native/dubp_rs/src/lib.rs b/native/dubp_rs/src/lib.rs index ae1a4a7..8d2f03a 100644 --- a/native/dubp_rs/src/lib.rs +++ b/native/dubp_rs/src/lib.rs @@ -18,7 +18,7 @@ mod dewif; mod mnemonic; -use allo_isolate::Isolate; +use allo_isolate::{IntoDart, Isolate}; use dup_crypto::{ bases::b58::ToBase58, dewif::{Currency, DewifReadError, ExpectedCurrency, G1_CURRENCY, G1_TEST_CURRENCY}, @@ -28,7 +28,6 @@ use dup_crypto::{ }, mnemonic::{Language, Mnemonic, MnemonicType}, }; -use ffi_helpers::null_pointer_check; use std::{ffi::CStr, io, os::raw}; use thiserror::Error; @@ -39,12 +38,16 @@ pub enum DubpError { DewifReadError(DewifReadError), #[error("I/O error: {0}")] IoErr(io::Error), + #[error("A given parameter is null")] + NullParamErr, #[error("fail to generate random bytes")] RandErr, #[error("Unknown currency name")] UnknownCurrencyName, #[error("Unknown language")] UnknownLanguage, + #[error("{0}")] + Utf8Error(std::str::Utf8Error), #[error("Wrong language")] WrongLanguage, } @@ -55,39 +58,41 @@ impl From for DubpError { } } -macro_rules! error { - ($result:expr) => { - error!($result, 0); - }; - ($result:expr, $error:expr) => { - match $result { - Ok(value) => value, - Err(e) => { - ffi_helpers::update_last_error(e); - return $error; - } +struct DartRes(allo_isolate::ffi::DartCObject); +impl IntoDart for DartRes { + fn into_dart(self) -> allo_isolate::ffi::DartCObject { + self.0.into_dart() + } +} +impl From> for DartRes +where + E: ToString, +{ + fn from(res: Result) -> Self { + match res { + Ok(string) => Self(vec![string].into_dart()), + Err(e) => Self(vec![String::from("_"), e.to_string()].into_dart()), } - }; + } +} +impl From, E>> for DartRes +where + E: ToString, +{ + fn from(res: Result, E>) -> Self { + match res { + Ok(vec_string) => Self(vec_string.into_dart()), + Err(e) => Self(vec![String::with_capacity(0), e.to_string()].into_dart()), + } + } } -macro_rules! cstr { - ($ptr:expr) => { - cstr!($ptr, 0); - }; - ($ptr:expr, $error:expr) => {{ - null_pointer_check!($ptr); - error!(unsafe { CStr::from_ptr($ptr).to_str() }, $error) - }}; -} - -#[no_mangle] -pub unsafe extern "C" fn last_error_length() -> i32 { - ffi_helpers::error_handling::last_error_length() -} - -#[no_mangle] -pub unsafe extern "C" fn error_message_utf8(buf: *mut raw::c_char, length: i32) -> i32 { - ffi_helpers::error_handling::error_message_utf8(buf, length) +pub(crate) fn char_ptr_to_str<'a>(c_char_ptr: *const raw::c_char) -> Result<&'a str, DubpError> { + if c_char_ptr.is_null() { + Err(DubpError::NullParamErr) + } else { + unsafe { CStr::from_ptr(c_char_ptr).to_str() }.map_err(DubpError::Utf8Error) + } } #[no_mangle] @@ -97,13 +102,10 @@ pub extern "C" fn change_dewif_pin( dewif: *const raw::c_char, old_pin: *const raw::c_char, new_pin: *const raw::c_char, -) -> i32 { - let currency = cstr!(currency); - let dewif = cstr!(dewif); - let old_pin = cstr!(old_pin); - let new_pin = cstr!(new_pin); - Isolate::new(port).post(error!(dewif::change_pin(currency, dewif, old_pin, new_pin))); - 1 +) { + Isolate::new(port).post(DartRes::from(dewif::change_pin( + currency, dewif, old_pin, new_pin, + ))); } #[no_mangle] @@ -113,36 +115,30 @@ pub extern "C" fn gen_dewif( language: u32, mnemonic: *const raw::c_char, pin: *const raw::c_char, -) -> i32 { - let currency = cstr!(currency); - let mnemonic = cstr!(mnemonic); - let pin = cstr!(pin); - Isolate::new(port).post(error!(dewif::gen_dewif(currency, language, mnemonic, pin))); - 1 +) { + Isolate::new(port).post(DartRes::from(dewif::gen_dewif( + currency, language, mnemonic, pin, + ))); } #[no_mangle] -pub extern "C" fn gen_mnemonic(port: i64, language: u32) -> i32 { - Isolate::new(port).post(error!(mnemonic::gen_mnemonic(language))); - 1 +pub extern "C" fn gen_mnemonic(port: i64, language: u32) { + Isolate::new(port).post(DartRes::from(mnemonic::gen_mnemonic(language))); } #[no_mangle] -pub extern "C" fn gen_pin6(port: i64) -> i32 { - Isolate::new(port).post(error!(dewif::gen_pin6())); - 1 +pub extern "C" fn gen_pin6(port: i64) { + Isolate::new(port).post(DartRes::from(dewif::gen_pin6())); } #[no_mangle] -pub extern "C" fn gen_pin8(port: i64) -> i32 { - Isolate::new(port).post(error!(dewif::gen_pin8())); - 1 +pub extern "C" fn gen_pin8(port: i64) { + Isolate::new(port).post(DartRes::from(dewif::gen_pin8())); } #[no_mangle] -pub extern "C" fn gen_pin10(port: i64) -> i32 { - Isolate::new(port).post(error!(dewif::gen_pin10())); - 1 +pub extern "C" fn gen_pin10(port: i64) { + Isolate::new(port).post(DartRes::from(dewif::gen_pin10())); } #[no_mangle] @@ -151,16 +147,8 @@ pub extern "C" fn get_dewif_pubkey( currency: *const raw::c_char, dewif: *const raw::c_char, pin: *const raw::c_char, -) -> i32 { - let currency = cstr!(currency); - let dewif = cstr!(dewif); - let pin = cstr!(pin); - Isolate::new(port).post(error!(dewif::get_pubkey( - currency, - dewif, - &pin.to_ascii_uppercase() - ))); - 1 +) { + Isolate::new(port).post(DartRes::from(dewif::get_pubkey(currency, dewif, pin))); } #[no_mangle] @@ -168,13 +156,11 @@ pub extern "C" fn mnemonic_to_pubkey( port: i64, language: u32, mnemonic_phrase: *const raw::c_char, -) -> i32 { - let mnemonic_phrase = cstr!(mnemonic_phrase); - Isolate::new(port).post(error!(mnemonic::mnemonic_to_pubkey( +) { + Isolate::new(port).post(DartRes::from(mnemonic::mnemonic_to_pubkey( language, - mnemonic_phrase + mnemonic_phrase, ))); - 1 } #[no_mangle] @@ -184,18 +170,8 @@ pub extern "C" fn sign( dewif: *const raw::c_char, pin: *const raw::c_char, msg: *const raw::c_char, -) -> i32 { - let currency = cstr!(currency); - let dewif = cstr!(dewif); - let pin = cstr!(pin); - let msg = cstr!(msg); - Isolate::new(port).post(error!(dewif::sign( - currency, - dewif, - &pin.to_ascii_uppercase(), - msg - ))); - 1 +) { + Isolate::new(port).post(DartRes::from(dewif::sign(currency, dewif, pin, msg))); } #[no_mangle] @@ -206,24 +182,8 @@ pub extern "C" fn sign_several( pin: *const raw::c_char, msgs_len: usize, msgs: *const *const raw::c_char, -) -> i32 { - let currency = cstr!(currency); - let dewif = cstr!(dewif); - let pin = cstr!(pin); - - let msgs_slice: &[*const raw::c_char] = unsafe { std::slice::from_raw_parts(msgs, msgs_len) }; - let mut vec = Vec::with_capacity(msgs_len); - for ptr_c_char in msgs_slice { - vec.push(cstr!(*ptr_c_char)); - } - - Isolate::new(port).post(error!(dewif::sign_several( - currency, - dewif, - &pin.to_ascii_uppercase(), - &vec - ))); - 1 +) { + Isolate::new(port).post(dewif::sign_several(currency, dewif, pin, msgs_len, msgs)); } fn u32_to_language(i: u32) -> Result { diff --git a/native/dubp_rs/src/mnemonic.rs b/native/dubp_rs/src/mnemonic.rs index 765427d..ac17486 100644 --- a/native/dubp_rs/src/mnemonic.rs +++ b/native/dubp_rs/src/mnemonic.rs @@ -21,7 +21,12 @@ pub(super) fn gen_mnemonic(language: u32) -> Result { Ok(mnemonic.phrase().to_owned()) } -pub(super) fn mnemonic_to_pubkey(language: u32, mnemonic: &str) -> Result { +pub(super) fn mnemonic_to_pubkey( + language: u32, + mnemonic: *const raw::c_char, +) -> Result { + let mnemonic = char_ptr_to_str(mnemonic)?; + let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?) .map_err(|_| DubpError::WrongLanguage)?; let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic); diff --git a/packages/dubp_rs/lib/dubp.dart b/packages/dubp_rs/lib/dubp.dart index 0d96d5b..a3384e8 100644 --- a/packages/dubp_rs/lib/dubp.dart +++ b/packages/dubp_rs/lib/dubp.dart @@ -54,45 +54,35 @@ class DubpRust { /// Generate a random mnemonic static Future genMnemonic({Language language = Language.english}) { final completer = Completer(); - final sendPort = singleCompletePort(completer); - final res = native.gen_mnemonic( + final sendPort = + singleCompletePort(completer, callback: _handleErr); + native.gen_mnemonic( sendPort.nativePort, language.index, ); - if (res != 1) { - _throwError(); - } return completer.future; } static Future _genPin(PinLength pinLength) { final completer = Completer(); - final sendPort = singleCompletePort(completer); + final sendPort = + singleCompletePort(completer, callback: _handleErr); switch (pinLength) { case PinLength.ten: - final res = native.gen_pin10( + native.gen_pin10( sendPort.nativePort, ); - if (res != 1) { - DubpRust._throwError(); - } break; case PinLength.eight: - final res = native.gen_pin8( + native.gen_pin8( sendPort.nativePort, ); - if (res != 1) { - DubpRust._throwError(); - } break; case PinLength.six: default: - final res = native.gen_pin6( + native.gen_pin6( sendPort.nativePort, ); - if (res != 1) { - DubpRust._throwError(); - } break; } return completer.future; @@ -110,33 +100,29 @@ class DubpRust { String newDewif; { final completer = Completer(); - final sendPort = singleCompletePort(completer); - final res = native.change_dewif_pin( + final sendPort = + singleCompletePort(completer, callback: _handleErr); + native.change_dewif_pin( sendPort.nativePort, Utf8.toUtf8(currency), Utf8.toUtf8(dewif), Utf8.toUtf8(oldPin), Utf8.toUtf8(newPin), ); - if (res != 1) { - DubpRust._throwError(); - } newDewif = await completer.future; } // publicKey String publicKey; { final completer = Completer(); - final sendPort = singleCompletePort(completer); - final res = native.get_dewif_pubkey( + final sendPort = + singleCompletePort(completer, callback: _handleErr); + native.get_dewif_pubkey( sendPort.nativePort, Utf8.toUtf8(currency), Utf8.toUtf8(newDewif), Utf8.toUtf8(newPin), ); - if (res != 1) { - _throwError(); - } publicKey = await completer.future; } @@ -161,32 +147,28 @@ class DubpRust { String publicKey; { final completer = Completer(); - final sendPort = singleCompletePort(completer); - final res = native.mnemonic_to_pubkey( + final sendPort = + singleCompletePort(completer, callback: _handleErr); + native.mnemonic_to_pubkey( sendPort.nativePort, language.index, Utf8.toUtf8(mnemonic), ); - if (res != 1) { - DubpRust._throwError(); - } publicKey = await completer.future; } // dewif String dewif; { final completer = Completer(); - final sendPort = singleCompletePort(completer); - final res = native.gen_dewif( + final sendPort = + singleCompletePort(completer, callback: _handleErr); + native.gen_dewif( sendPort.nativePort, Utf8.toUtf8(currency), language.index, Utf8.toUtf8(mnemonic), Utf8.toUtf8(pin), ); - if (res != 1) { - DubpRust._throwError(); - } dewif = await completer.future; } return Future.value(NewWallet._(dewif, pin, publicKey)); @@ -194,18 +176,16 @@ class DubpRust { /// Get pulblic key (in base 58) of `dewif` keypair. static Future getDewifPublicKey( - {String currency = "g1", String dewif, String pin}) { + {String currency = "g1", String dewif, String pin}) async { final completer = Completer(); - final sendPort = singleCompletePort(completer); - final res = native.get_dewif_pubkey( + final sendPort = + singleCompletePort(completer, callback: _handleErr); + native.get_dewif_pubkey( sendPort.nativePort, Utf8.toUtf8(currency), Utf8.toUtf8(dewif), Utf8.toUtf8(pin), ); - if (res != 1) { - _throwError(); - } return completer.future; } @@ -215,17 +195,15 @@ class DubpRust { static Future sign( {String currency = "g1", String dewif, String pin, String message}) { final completer = Completer(); - final sendPort = singleCompletePort(completer); - final res = native.sign( + final sendPort = + singleCompletePort(completer, callback: _handleErr); + native.sign( sendPort.nativePort, Utf8.toUtf8(currency), Utf8.toUtf8(dewif), Utf8.toUtf8(pin), Utf8.toUtf8(message), ); - if (res != 1) { - _throwError(); - } return completer.future; } @@ -241,9 +219,10 @@ class DubpRust { String pin, List messages}) { final completer = Completer>(); - final sendPort = singleCompletePort, List>(completer); + final sendPort = singleCompletePort, List>(completer, + callback: _handleErrList); - final res = native.sign_several( + native.sign_several( sendPort.nativePort, Utf8.toUtf8(currency), Utf8.toUtf8(dewif), @@ -251,9 +230,7 @@ class DubpRust { messages.length, _listStringToPtr(messages), ); - if (res != 1) { - _throwError(); - } + return completer.future; } @@ -266,12 +243,25 @@ class DubpRust { return ptr; } - static void _throwError() { - final length = native.last_error_length(); - final Pointer message = allocate(count: length); - native.error_message_utf8(message, length); - final error = Utf8.fromUtf8(message); - print(error); - throw error; + static String _handleErr(List res) { + final List arr = res.cast(); + if (arr.length == 1) { + return arr[0]; + } else { + final error = arr[1]; + print(error); + throw error; + } + } + + static List _handleErrList(List res) { + final List arr = res.cast(); + if (arr.isNotEmpty && arr[0].isEmpty) { + final error = arr[1]; + print(error); + throw error; + } else { + return arr; + } } }