Skip to content

Commit

Permalink
Overhaul
Browse files Browse the repository at this point in the history
  • Loading branch information
peteraba committed Jun 9, 2020
1 parent 01ae93f commit 3a3e468
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 124 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.vscode/
target/
26 changes: 0 additions & 26 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ aes-soft = "0.4.0"
base64 = "0.12.1"
block-modes = "0.4.0"
hex = "0.4.2"
hex-literal = "0.2.1"
http = "0.2.1"
libc = "0.2.71"
reqwest = { version = "0.10.6", features = ["blocking"] }
Expand Down
77 changes: 59 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
### Build 32-bit
## Installation

### Build 32-bit .dll

```
cargo build --target=i686-pc-windows-msvc --release
Expand All @@ -7,36 +9,75 @@ cargo build --target=i686-pc-windows-msvc --release
Output file: `.\target\i686-pc-windows-msvc\release\rhttp.dll`


### Build 64-bit
### Build 64-bit .dll

```
cargo build --target=x86_64-pc-windows-msvc --release
```

Output file: `.\target\x86_64-pc-windows-msvc\release\rhttp.dll`

### Test via python 3
## Test via python 3

```
> python3 .\test.py --dll .\target\x86_64-pc-windows-msvc\release\rhttp.dll
16
2.25
6.25
5
Szia, Apu!
aaaaa
ő na na na na na Batman! ő
(True, 'YW55IGNhcm5hbCBwbGVhc3VyZS4=', 'any carnal pleasure.')
(True, '7b6f7690ae2a5ecdf66b3db2adf91340a680da1ab82561796b8504db942476967369814aa35050dd86838848c1ba703450f2f5e21b0a8e4cff690b855ae5bd8c', '7b6f7690ae2a5ecdf66b3db2adf91340a680da1ab82561796b8504db942476967369814aa35050dd86838848c1ba703450f2f5e21b0a8e4cff690b855ae5bd8c')
(True, 'ef846feafed891792553756277b48e90784eca281f683920551f36b359833b10aab4897765050e398232e3f213fe49c7c50271f339d4797c25dc58c3d7f33f81', 'ef846feafed891792553756277b48e90784eca281f683920551f36b359833b10aab4897765050e398232e3f213fe49c7c50271f339d4797c25dc58c3d7f33f81')
True
True
True
OK
True
True
```

## Methods

### Base64 encode and decode

```rust
fn base64_decode(s: *const c_char) -> *mut c_char {}
fn base64_encode(s: *const c_char) -> *mut c_char {}
```

### VFP notes
### Hashing via SHA-512

```rust
fn sha512_hash(s: *const c_char) -> *mut c_char {}
```
DECLARE sha3_512_encode "rhttp.dll" @STRING, @STRING

testString = "TestVFP"
sha512_encode(0, @testString )
### Hashing via SHA3-512

```rust
fn sha3_512_hash(s: *const c_char) -> *mut c_char {}
```

### AES encrypt and decrypt

`aes_encrypt` and `aes_decrypt` are used to encrypt and decrypt messages via using [AES-128](https://en.wikipedia.org/wiki/Advanced_Encryption_Standard) block cipher in [ECB mode](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_codebook_(ECB)) and with [PKCS#7 padding](https://en.wikipedia.org/wiki/Padding_(cryptography)#PKCS#5_and_PKCS#7).

Both method works primarily on byte arrays which you can provide as `plain text`, `hexadecimal representation` and `base64 encoding`. These can be configured by setting the plans as designed:

```
Flags can be provided as a 32-bit integer (for compatibility reasons), which then will be converted into an unsigned integer. These flags can be combined, but some combinations will be ignored:
- 0x01 - Input is provided as `hexadecimal representation`
- 0x02 - Input is provided using `base64 encoding`
- 0x04 - Output should be returned in a `hexadecimal representation`
- 0x08 - Output should be returned using `base64 encoding`
- 0x10 - Key is provided as `hexadecimal representation`
- 0x20 - Key is provided using `base64 encoding`

```rust
fn aes_encrypt(c_plaintext: *const c_char, c_key: *const c_char, flags: i32) -> *mut c_char {}

fn aes_decrypt(c_ciphertext: *const c_char, c_key: *const c_char, flags: i32) -> *mut c_char {}
```

### HTTP(s) GET

```rust
fn get(c_url: *const c_char) -> *mut c_char
```

### HTTP(s) POST with XML headers

```rust
fn post_xml(c_url: *const c_char, c_body: *const c_char) -> *mut c_char
```
109 changes: 67 additions & 42 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@ extern crate sha3;
extern crate reqwest;
extern crate aes_soft as aes;
extern crate block_modes;
extern crate hex_literal;

//external crates
use aes::Aes128;
use block_modes::{BlockMode, Cbc};
use block_modes::{BlockMode, Ecb};
use block_modes::block_padding::Pkcs7;
use hex_literal::hex;
use http::HeaderMap;
use http::header::{CONTENT_TYPE, ACCEPT};
use libc::c_char;
Expand All @@ -21,25 +19,7 @@ use sha2::{Sha512, Digest};
use sha3::{Sha3_512};
use std::ffi::CString;
use std::ffi::CStr;

// create an alias for convinience
type Aes128Cbc = Cbc<Aes128, Pkcs7>;

fn c_str_ptr_to_rust(s: *const c_char) -> &'static str {
let c_str = unsafe {
assert!(!s.is_null());

CStr::from_ptr(s)
};

return c_str.to_str().unwrap();
}

fn rust_to_c_str_ptr(s: String) -> *mut c_char {
let c_str = CString::new(s).unwrap();

return c_str.into_raw()
}
use std::str;

#[no_mangle]
pub extern "C" fn free_string(s: *mut c_char) {
Expand Down Expand Up @@ -73,7 +53,7 @@ pub extern "C" fn base64_decode(s: *const c_char) -> *mut c_char {
}

#[no_mangle]
pub extern "C" fn sha512_encode(s: *const c_char) -> *mut c_char {
pub extern "C" fn sha512_hash(s: *const c_char) -> *mut c_char {
let r_str = c_str_ptr_to_rust(s);

let mut hasher = Sha512::new();
Expand All @@ -86,7 +66,7 @@ pub extern "C" fn sha512_encode(s: *const c_char) -> *mut c_char {
}

#[no_mangle]
pub extern "C" fn sha3_512_encode(s: *const c_char) -> *mut c_char {
pub extern "C" fn sha3_512_hash(s: *const c_char) -> *mut c_char {
let r_str = c_str_ptr_to_rust(s);

let mut hasher = Sha3_512::new();
Expand All @@ -99,28 +79,25 @@ pub extern "C" fn sha3_512_encode(s: *const c_char) -> *mut c_char {
}

#[no_mangle]
pub extern "C" fn aes_encode() -> *mut c_char {
let key = hex!("000102030405060708090a0b0c0d0e0f");
let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
let plaintext = b"Hello world!";
let cipher = Aes128Cbc::new_var(&key, &iv).unwrap();

let ciphertext = cipher.encrypt_vec(plaintext);

return rust_to_c_str_ptr(hex::encode(ciphertext));
pub extern "C" fn aes_encrypt(c_plaintext: *const c_char, c_key: *const c_char, flags: i32) -> *mut c_char {
let uflags = flags as u32;
let input = decode_c(c_plaintext, uflags);
let key = decode_c(c_key, uflags >> 4);

let ciphertext = create_cipher(key).encrypt_vec(input.as_slice());

return rust_to_c_str_ptr(encode_c(ciphertext, uflags >> 2));
}

// #[no_mangle]
pub extern "C" fn aes_decode() -> *mut c_char {
let ciphertext = hex!("1b7a4c403124ae2fb52bedc534d82fa8");

let key = hex!("000102030405060708090a0b0c0d0e0f");
let iv = hex!("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff");
let cipher = Aes128Cbc::new_var(&key, &iv).unwrap();
#[no_mangle]
pub extern "C" fn aes_decrypt(c_ciphertext: *const c_char, c_key: *const c_char, flags: i32) -> *mut c_char {
let uflags = flags as u32;
let input = decode_c(c_ciphertext, uflags);
let key = decode_c(c_key, uflags >> 4);

let decrypted_ciphertext = cipher.decrypt_vec(&ciphertext).unwrap();
let plaintext = create_cipher(key).decrypt_vec(input.as_slice()).unwrap();

return rust_to_c_str_ptr(hex::encode(decrypted_ciphertext));
return rust_to_c_str_ptr(encode_c(plaintext, uflags >> 2));
}

#[no_mangle]
Expand Down Expand Up @@ -172,3 +149,51 @@ pub extern "C" fn post_xml(c_url: *const c_char, c_body: *const c_char) -> *mut

return rust_to_c_str_ptr(body);
}

fn decode_c(c_input: *const c_char, flags: u32) -> Vec<u8> {
let input = c_str_ptr_to_rust(c_input);

if flags % 2 == 1 {
return hex::decode(input).unwrap();
}

if (flags >> 1) % 2 == 1 {
return base64::decode_config(input, base64::STANDARD).unwrap();
}

return String::from(input).into_bytes();
}

fn encode_c(raw: Vec<u8>, flags: u32) -> String {
if flags % 2 == 1 {
return hex::encode(raw);
}

if (flags >> 1) % 2 == 1 {
return base64::encode_config(raw, base64::STANDARD);
}

return String::from_utf8(raw).unwrap();
}

fn create_cipher(key: Vec<u8>) -> Ecb::<Aes128, Pkcs7> {
let iv = Default::default();

return Ecb::<Aes128, Pkcs7>::new_var(key.as_slice(), iv).unwrap();
}

fn c_str_ptr_to_rust(s: *const c_char) -> &'static str {
let c_str = unsafe {
assert!(!s.is_null());

CStr::from_ptr(s)
};

return c_str.to_str().unwrap();
}

fn rust_to_c_str_ptr(s: String) -> *mut c_char {
let c_str = CString::new(s).unwrap();

return c_str.into_raw()
}
Loading

0 comments on commit 3a3e468

Please sign in to comment.