feat: read/write from file

This commit is contained in:
2020-11-07 15:00:26 +08:00
parent 7e8d1e7884
commit 5110732561
3 changed files with 234 additions and 9 deletions

View File

@@ -1,11 +1,52 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]]
name = "blake2b_simd"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]]
name = "bumpalo"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
[[package]]
name = "byteorder"
version = "1.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cc"
version = "1.0.61"
@@ -18,6 +59,45 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "getrandom"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hex"
version = "0.4.2"
@@ -84,6 +164,23 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_users"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom",
"redox_syscall",
"rust-argon2",
]
[[package]]
name = "ring"
version = "0.16.15"
@@ -99,6 +196,30 @@ dependencies = [
"winapi",
]
[[package]]
name = "rust-argon2"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]]
name = "rust_util"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "754278eaff41b86ced9e2913b3f5ee8bd7c2446be81f0739a567e9d0ad6cdb3a"
dependencies = [
"lazy_static",
"libc",
"term",
"term_size",
]
[[package]]
name = "ryu"
version = "1.0.5"
@@ -153,6 +274,27 @@ dependencies = [
"unicode-xid",
]
[[package]]
name = "term"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
dependencies = [
"byteorder",
"dirs",
"winapi",
]
[[package]]
name = "term_size"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
dependencies = [
"libc",
"winapi",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
@@ -171,10 +313,17 @@ version = "0.1.0"
dependencies = [
"hex",
"ring",
"rust_util",
"serde",
"serde_json",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasm-bindgen"
version = "0.2.68"

View File

@@ -7,7 +7,8 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ring = "0.16.13"
hex = "0.4.2"
ring = "0.16"
hex = "0.4"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
rust_util = "0.6"

View File

@@ -1,9 +1,14 @@
use std::fs::File;
use std::io::{ Write, Read };
use serde::{ Deserialize, Serialize };
use ring::{
signature::{ KeyPair, Ed25519KeyPair, UnparsedPublicKey, ED25519 },
hmac, rand, error::Unspecified,
digest,
};
use rust_util::XResult;
#[derive(Serialize, Deserialize)]
pub struct SigningKeyPair {
key_pair: Vec<u8>,
}
@@ -20,22 +25,92 @@ impl SigningKeyPair {
fn parse(&self) -> Ed25519KeyPair {
Ed25519KeyPair::from_pkcs8(&self.key_pair).unwrap() // TODO ...
}
fn public_key(&self) -> Vec<u8> {
self.parse().public_key().as_ref().to_vec()
}
fn unparsed_public_key(&self) -> UnparsedPublicKey<Vec<u8>> {
UnparsedPublicKey::new(&ED25519, self.public_key())
}
fn read_from_file(file: &str) -> XResult<Self> {
match File::open(file) {
Err(e) => Err(rust_util::new_box_ioerror(&format!("Read from file failed: {}", e))),
Ok(mut f) => {
let mut buf = String::new();
match f.read_to_string(&mut buf) {
Err(e) => Err(rust_util::new_box_ioerror(&format!("Read from file failed: {}", e))),
Ok(_) => {
let kp: Self = match serde_json::from_str(&buf) {
Err(e) => return Err(rust_util::new_box_ioerror(&format!("Parse JSON failed: {}", e))),
Ok(k) => k,
};
Ok(kp)
}
}
},
}
}
fn write_to_file(&self, file: &str) -> XResult<()> {
if File::open(file).is_ok() {
return Err(rust_util::new_box_ioerror(&format!("File exists: {}", file)));
}
let ser_bytes = match serde_json::to_string_pretty(self) {
Err(e) => return Err(rust_util::new_box_ioerror(&format!("Serilize key pair failed: {}", e))),
Ok(s) => s,
};
match File::create(file) {
Err(e) => return Err(rust_util::new_box_ioerror(&format!("File create: {}, failed: {}", file, e))),
Ok(mut f) => {
match f.write_all(ser_bytes.as_bytes()) {
Err(e) => Err(rust_util::new_box_ioerror(&format!("File create: {}, failed: {}", file, e))),
Ok(_) => Ok(()),
}
},
}
}
}
#[derive(Serialize, Deserialize)]
pub struct SignedMessage {
msg: Vec<u8>,
sig: Vec<u8>,
desc: String,
sig: Option<Vec<u8>>,
desc: Option<String>,
}
impl SignedMessage {
pub fn sign(key_pair: &Ed25519KeyPair, msg: &[u8]) -> Vec<u8> {
let sig = key_pair.sign(msg);
sig.as_ref().to_vec()
pub fn new(msg: Vec<u8>, desc: Option<String>) -> Self {
Self {
msg,
sig: None,
desc,
}
}
pub fn sign(&mut self, key_pair: &SigningKeyPair) {
let sig = key_pair.parse().sign(&self.msg);
self.sig = Some(sig.as_ref().to_vec());
}
pub fn verify(&self, public_key: &[u8]) -> bool {
let verify_result = UnparsedPublicKey::new(&ED25519, &public_key).verify(&self.msg, &self.sig);
verify_result.is_ok()
match &self.sig {
None => false,
Some(sig) => {
let verify_result = UnparsedPublicKey::new(&ED25519, &public_key).verify(&self.msg, sig);
verify_result.is_ok()
}
}
}
}
#[test]
fn test_sign() {
let signing_key_pair = SigningKeyPair::new();
let mut signed_message = SignedMessage::new(
"Hello".as_bytes().to_vec(), Some("DESC".to_owned())
);
signed_message.sign(&signing_key_pair);
assert!(signed_message.verify(&signing_key_pair.public_key()))
}