From 86c0ed7230401f7b117c85db6291c46deee1b034 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Fri, 29 Sep 2023 21:05:07 +0800 Subject: [PATCH] feat: updates --- Cargo.lock | 116 +++++++++++++++++++++++++++++++++++++++------ Cargo.toml | 1 + src/cmd_encrypt.rs | 5 +- src/config.rs | 17 +++++-- src/crypto_rsa.rs | 9 ++-- src/util.rs | 6 +-- 6 files changed, 126 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4409ae1..46335ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -78,6 +78,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "aho-corasick" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +dependencies = [ + "memchr", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -151,7 +160,7 @@ dependencies = [ "asn1-rs-impl", "displaydoc", "nom", - "num-traits", + "num-traits 0.2.16", "rusticata-macros", "thiserror", "time", @@ -329,7 +338,7 @@ dependencies = [ "android-tzdata", "iana-time-zone", "js-sys", - "num-traits", + "num-traits 0.2.16", "wasm-bindgen", "windows-targets", ] @@ -510,7 +519,7 @@ dependencies = [ "displaydoc", "nom", "num-bigint", - "num-traits", + "num-traits 0.2.16", "rusticata-macros", ] @@ -1106,6 +1115,16 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linked-hash-map" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd" +dependencies = [ + "serde 0.8.23", + "serde_test", +] + [[package]] name = "linux-raw-sys" version = "0.4.5" @@ -1192,7 +1211,7 @@ checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", - "num-traits", + "num-traits 0.2.16", ] [[package]] @@ -1206,9 +1225,9 @@ dependencies = [ "libm", "num-integer", "num-iter", - "num-traits", + "num-traits 0.2.16", "rand", - "serde", + "serde 1.0.188", "smallvec", "zeroize", ] @@ -1220,7 +1239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", - "num-traits", + "num-traits 0.2.16", ] [[package]] @@ -1231,7 +1250,16 @@ checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ "autocfg", "num-integer", - "num-traits", + "num-traits 0.2.16", +] + +[[package]] +name = "num-traits" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" +dependencies = [ + "num-traits 0.2.16", ] [[package]] @@ -1592,6 +1620,35 @@ dependencies = [ "thiserror", ] +[[package]] +name = "regex" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + [[package]] name = "reqwest" version = "0.11.20" @@ -1619,7 +1676,7 @@ dependencies = [ "pin-project-lite", "rustls", "rustls-pemfile", - "serde", + "serde 1.0.188", "serde_json", "serde_urlencoded", "tokio", @@ -1682,7 +1739,7 @@ dependencies = [ "num-bigint-dig", "num-integer", "num-iter", - "num-traits", + "num-traits 0.2.16", "pkcs1", "pkcs8", "rand_core", @@ -1861,6 +1918,12 @@ dependencies = [ "libc", ] +[[package]] +name = "serde" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" + [[package]] name = "serde" version = "1.0.188" @@ -1870,6 +1933,19 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-hjson" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" +dependencies = [ + "lazy_static", + "linked-hash-map", + "num-traits 0.1.43", + "regex", + "serde 0.8.23", +] + [[package]] name = "serde_derive" version = "1.0.188" @@ -1889,7 +1965,16 @@ checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ "itoa", "ryu", - "serde", + "serde 1.0.188", +] + +[[package]] +name = "serde_test" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5" +dependencies = [ + "serde 0.8.23", ] [[package]] @@ -1901,7 +1986,7 @@ dependencies = [ "form_urlencoded", "itoa", "ryu", - "serde", + "serde 1.0.188", ] [[package]] @@ -2152,7 +2237,7 @@ checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", - "serde", + "serde 1.0.188", "time-core", "time-macros", ] @@ -2191,7 +2276,8 @@ dependencies = [ "rpassword", "rsa", "rust_util", - "serde", + "serde 1.0.188", + "serde-hjson", "serde_json", "sha256", "simpledateformat", @@ -2657,7 +2743,7 @@ dependencies = [ "nom", "num-bigint-dig", "num-integer", - "num-traits", + "num-traits 0.2.16", "p256", "p384", "pbkdf2", diff --git a/Cargo.toml b/Cargo.toml index bcb1ac8..c18a5cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ rpassword = "7.2.0" rsa = { version = "0.9.2", features = ["pem"] } rust_util = "0.6.42" serde = { version = "1.0.152", features = ["derive"] } +serde-hjson = "0.9.1" serde_json = "1.0.93" sha256 = "1.4.0" simpledateformat = "0.1.4" diff --git a/src/cmd_encrypt.rs b/src/cmd_encrypt.rs index f2fef57..f0eb577 100644 --- a/src/cmd_encrypt.rs +++ b/src/cmd_encrypt.rs @@ -13,7 +13,7 @@ use rust_util::{debugging, failure, opt_result, simple_error, success, XResult}; use crate::config::{TinyEncryptConfig, TinyEncryptConfigEnvelop}; use crate::crypto_rsa::parse_spki; use crate::spec::{EncMetadata, TinyEncryptEnvelop, TinyEncryptEnvelopType, TinyEncryptMeta}; -use crate::util::{encode_base64, TINY_ENC_CONFIG_FILE}; +use crate::util::{encode_base64, simple_kdf, TINY_ENC_CONFIG_FILE}; #[derive(Debug, Args)] pub struct CmdEncrypt { @@ -29,7 +29,7 @@ pub struct CmdEncrypt { pub fn encrypt(cmd_encrypt: CmdEncrypt) -> XResult<()> { let config = TinyEncryptConfig::load(TINY_ENC_CONFIG_FILE)?; - let envelops = config.find_envelops(&cmd_encrypt.profile); + let envelops = config.find_envelops(&cmd_encrypt.profile)?; if envelops.is_empty() { return simple_error!("Cannot find any valid envelops"); } debugging!("Cmd encrypt: {:?}", cmd_encrypt); @@ -87,6 +87,7 @@ fn encrypt_envelop_ecdh(key: &[u8], envelop: &TinyEncryptConfigEnvelop) -> XResu let epk_bytes = EphemeralKeyBytes::from_public_key(&epk); let public_key_encoded_point = public_key.to_encoded_point(false); let shared_secret = esk.diffie_hellman(&public_key); + let key = simple_kdf(shared_secret.raw_secret_bytes().as_slice()); // PORT Java Implementation // public static WrapKey encryptEcdhP256(String kid, PublicKey publicKey, byte[] data) { diff --git a/src/config.rs b/src/config.rs index b823167..718dce4 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use std::fs; -use rust_util::{opt_result, XResult}; +use rust_util::{debugging, opt_result, simple_error, XResult}; use rust_util::util_file::resolve_file_path; use serde::{Deserialize, Serialize}; @@ -25,7 +25,7 @@ use crate::spec::TinyEncryptEnvelopType; /// } /// ], /// "profiles": { -/// "default": ["KID-1", "KID-2"], +/// "default": ["KID-1", "KID-2", "type:pgp"], /// "leve2": ["KID-2"] /// } /// } @@ -53,10 +53,14 @@ impl TinyEncryptConfig { Ok(opt_result!(serde_json::from_str(&config_contents), "Parse file: {}, failed: {}", file)) } - pub fn find_envelops(&self, profile: &Option) -> Vec<&TinyEncryptConfigEnvelop> { + pub fn find_envelops(&self, profile: &Option) -> XResult> { let profile = profile.as_ref().map(String::as_str).unwrap_or("default"); + debugging!("Profile: {}", profile); let mut matched_envelops_map = HashMap::new(); if let Some(key_ids) = self.profiles.get(profile) { + if key_ids.is_empty() { + return simple_error!("Profile: {} contains no valid envelopes", profile); + } for key_id in key_ids { self.envelops.iter().for_each(|envelop| { let is_matched = (&envelop.kid == key_id) @@ -67,6 +71,11 @@ impl TinyEncryptConfig { }); } } - matched_envelops_map.values().map(|envelop| *envelop).collect() + let envelops: Vec<_> = matched_envelops_map.values().map(|envelop| *envelop).collect(); + if envelops.is_empty() { + return simple_error!("Profile: {} has no valid envelopes found", profile); + } + debugging!("Found envelopes: {:#?}", envelops); + Ok(envelops) } } diff --git a/src/crypto_rsa.rs b/src/crypto_rsa.rs index 9bc4ab4..dc90ce0 100644 --- a/src/crypto_rsa.rs +++ b/src/crypto_rsa.rs @@ -1,7 +1,4 @@ -use rsa::{BigUint, Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey}; -use rsa::pkcs1::der::Decode; -use rsa::pkcs8::PrivateKeyInfo; -use rsa::traits::PublicKeyParts; +use rsa::{BigUint, RsaPublicKey}; use rust_util::{opt_result, XResult}; use x509_parser::prelude::FromDer; use x509_parser::public_key::RSAPublicKey; @@ -43,6 +40,7 @@ fn pem_to_der_bytes(pem: &str) -> XResult> { #[test] fn test_parse_spki() { + use rsa::traits::PublicKeyParts; let public_key_pem = "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgK\ CAgEApUM8M+QRMUw0dIvXISFx\n43j4h9CK38Y9HD6kPcc3Z0dCGPiFy7Ze0OQebPWHyUZ2YmqsdyzFuOQuV9P2pxxj\n/W\ LIgRqZV8Jk8tWhtAjOOvm0MTc2rg+EJHfa+zhX4eFEMsj4DvQBMJDXiKnpXTM/\nj7oMKpIUQHqfXBwsEJHLmHZTLeEBEYK\ @@ -71,6 +69,9 @@ fn test_parse_spki() { #[test] fn test_parse_spki_and_test() { + use rsa::{Pkcs1v15Encrypt, RsaPrivateKey}; + use rsa::pkcs1::der::Decode; + use rsa::pkcs8::PrivateKeyInfo; let private_key_pem = "-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCsuTaS34xvrgr5 ZXEuE8lYDYuLxATq1ds6/8YlNOeKReCGwRkObfKl0uyj79WLka2RCZELDiHyQcDG diff --git a/src/util.rs b/src/util.rs index 5c85c6f..4001e68 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,10 +1,10 @@ use std::{fs, io}; use std::io::Write; -use std::path::{Path, PathBuf}; +use std::path::Path; use base64::Engine; use base64::engine::general_purpose; -use rust_util::{opt_result, simple_error, warning, XResult}; +use rust_util::{simple_error, warning, XResult}; use zeroize::Zeroize; pub const ENC_AES256_GCM_P256: &str = "aes256-gcm-p256"; @@ -25,7 +25,7 @@ pub fn require_file_exists(path: impl AsRef) -> XResult<()> { let path = path.as_ref(); match fs::metadata(path) { Ok(_) => Ok(()), - Err(e) => simple_error!("File: {} not exists", path.display()), + Err(_) => simple_error!("File: {} not exists", path.display()), } }