Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
Signed-off-by: Asura <[email protected]>
  • Loading branch information
G-Asura committed May 11, 2024
2 parents 06ef987 + 7e8c441 commit 6706830
Show file tree
Hide file tree
Showing 18 changed files with 1,118 additions and 286 deletions.
10 changes: 8 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ RustyVault's RESTful API is designed to be fully compatible with Hashicorp Vault
"""
repository = "https://github.com/Tongsuo-Project/RustyVault"
documentation = "https://docs.rs/rusty_vault/latest/rusty_vault/"
build = "build.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand All @@ -24,8 +25,8 @@ serde_json = "^1.0"
serde_bytes = "0.11"
go-defer = "^0.1"
rand = "^0.8"
openssl = "0.10"
openssl-sys = "0.9.92"
openssl = { version = "0.10" }
openssl-sys = { version = "0.9" }
derivative = "2.2.0"
enum-map = "2.6.1"
strum = { version = "0.25", features = ["derive"] }
Expand Down Expand Up @@ -60,6 +61,11 @@ serde_asn1_der = "0.8"
base64 = "0.22"
etcd-client = { version = "0.12.4", features = ["tls"] }
tokio = "1.37.0"
ipnetwork = "0.20"

[patch.crates-io]
openssl = { git = "https://github.com/Tongsuo-Project/rust-tongsuo.git" }
openssl-sys = { git = "https://github.com/Tongsuo-Project/rust-tongsuo.git" }

[features]
storage_mysql = ["diesel", "r2d2", "r2d2-diesel"]
Expand Down
7 changes: 7 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use std::env;

fn main() {
if let Ok(_) = env::var("DEP_OPENSSL_TONGSUO") {
println!("cargo:rustc-cfg=tongsuo");
}
}
10 changes: 10 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,16 @@ pub enum RvError {
#[from]
source: crate::storage::physical::error::BackendError,
},
#[error("Some net addr parse error happened, {:?}", .source)]
AddrParseError {
#[from]
source: std::net::AddrParseError,
},
#[error("Some ipnetwork error happened, {:?}", .source)]
IpNetworkError {
#[from]
source: ipnetwork::IpNetworkError,
},

/// Database Errors Begin
///
Expand Down
2 changes: 1 addition & 1 deletion src/modules/pki/path_config_ca.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ For security reasons, you can only view the certificate when reading this endpoi
impl PkiBackendInner {
pub fn write_path_ca(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let pem_bundle_value = req.get_data("pem_bundle")?;
let pem_bundle = pem_bundle_value.as_str().unwrap();
let pem_bundle = pem_bundle_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;

let items = pem::parse_many(pem_bundle)?;
let mut key_found = false;
Expand Down
2 changes: 1 addition & 1 deletion src/modules/pki/path_fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl PkiBackendInner {

pub fn read_path_fetch_cert(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let serial_number_value = req.get_data("serial")?;
let serial_number = serial_number_value.as_str().unwrap();
let serial_number = serial_number_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let serial_number_hex = serial_number.replace(":", "-").to_lowercase();
let cert = self.fetch_cert(req, &serial_number_hex)?;
let ca_bundle = self.fetch_ca_bundle(req)?;
Expand Down
9 changes: 4 additions & 5 deletions src/modules/pki/path_issue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,12 @@ requested common name is allowed by the role policy.

impl PkiBackendInner {
pub fn issue_cert(&self, backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let role_value = req.get_data("role")?;
let role_name = role_value.as_str().unwrap();
//let role_name = req.get_data("role")?.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;

let mut common_names = Vec::new();

let common_name_value = req.get_data("common_name")?;
let common_name = common_name_value.as_str().unwrap();
let common_name = common_name_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
if common_name != "" {
common_names.push(common_name.to_string());
}
Expand All @@ -87,7 +86,7 @@ impl PkiBackendInner {
}
}

let role = self.get_role(req, &role_name)?;
let role = self.get_role(req, req.get_data("role")?.as_str().ok_or(RvError::ErrRequestFieldInvalid)?)?;
if role.is_none() {
return Err(RvError::ErrPkiRoleNotFound);
}
Expand All @@ -111,7 +110,7 @@ impl PkiBackendInner {
let mut not_after = not_before + parse_duration("30d").unwrap();

let ttl_value = req.get_data("ttl")?;
let ttl = ttl_value.as_str().unwrap();
let ttl = ttl_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
if ttl != "" {
let ttl_dur = parse_duration(ttl)?;
let req_ttl_not_after_dur = SystemTime::now() + ttl_dur;
Expand Down
79 changes: 38 additions & 41 deletions src/modules/pki/path_keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,11 +212,10 @@ used for sign,verify,encrypt,decrypt.
impl PkiBackendInner {
pub fn generate_key(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let key_name_value = req.get_data("key_name")?;
let key_name = key_name_value.as_str().unwrap();
let key_name = key_name_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let key_type_value = req.get_data("key_type")?;
let key_type = key_type_value.as_str().unwrap();
let key_bits_value = req.get_data("key_bits")?;
let key_bits = key_bits_value.as_u64().unwrap();
let key_type = key_type_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let key_bits = req.get_data("key_bits")?.as_u64().ok_or(RvError::ErrRequestFieldInvalid)?;

let mut export_private_key = false;
if req.path.ends_with("/exported") {
Expand Down Expand Up @@ -245,7 +244,7 @@ impl PkiBackendInner {

if export_private_key {
match key_type {
"rsa" | "ec" => {
"rsa" | "ec" | "sm2" => {
resp_data.insert(
"private_key".to_string(),
Value::String(String::from_utf8_lossy(&key_bundle.key).to_string()),
Expand All @@ -266,13 +265,13 @@ impl PkiBackendInner {

pub fn import_key(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let key_name_value = req.get_data("key_name")?;
let key_name = key_name_value.as_str().unwrap();
let key_name = key_name_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let key_type_value = req.get_data("key_type")?;
let key_type = key_type_value.as_str().unwrap();
let key_type = key_type_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let pem_bundle_value = req.get_data("pem_bundle")?;
let pem_bundle = pem_bundle_value.as_str().unwrap();
let pem_bundle = pem_bundle_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let hex_bundle_value = req.get_data("hex_bundle")?;
let hex_bundle = hex_bundle_value.as_str().unwrap();
let hex_bundle = hex_bundle_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;

if pem_bundle.len() == 0 && hex_bundle.len() == 0 {
return Err(RvError::ErrRequestFieldNotFound);
Expand All @@ -292,7 +291,7 @@ impl PkiBackendInner {
let rsa = Rsa::private_key_from_pem(&key_bundle.key)?;
key_bundle.bits = rsa.size() * 8;
},
"ec" => {
"ec" | "sm2" => {
let ec_key = EcKey::private_key_from_pem(&key_bundle.key)?;
key_bundle.bits = ec_key.group().degree();
},
Expand All @@ -312,19 +311,25 @@ impl PkiBackendInner {
}
};
let iv_value = req.get_data("iv")?;
match key_type {
"aes-gcm" | "aes-cbc" => {
if let Some(iv) = iv_value.as_str() {
key_bundle.iv = hex::decode(&iv)?;
} else {
return Err(RvError::ErrRequestFieldNotFound);
}
},
"aes-ecb" => {},
_ => {
return Err(RvError::ErrPkiKeyTypeInvalid);
let is_iv_required = matches!(key_type, "aes-gcm" | "aes-cbc" | "sm4-gcm" | "sm4-ccm");
#[cfg(tongsuo)]
let is_valid_key_type = matches!(key_type, "aes-gcm" | "aes-cbc" | "aes-ecb" | "sm4-gcm" | "sm4-ccm");
#[cfg(not(tongsuo))]
let is_valid_key_type = matches!(key_type, "aes-gcm" | "aes-cbc" | "aes-ecb");

// Check if the key type is valid, if not return an error.
if !is_valid_key_type {
return Err(RvError::ErrPkiKeyTypeInvalid);
}

// Proceed to check IV only if required by the key type.
if is_iv_required {
if let Some(iv) = iv_value.as_str() {
key_bundle.iv = hex::decode(&iv)?;
} else {
return Err(RvError::ErrRequestFieldNotFound);
}
};
}
}

self.write_key(req, &key_bundle)?;
Expand All @@ -343,12 +348,10 @@ impl PkiBackendInner {
}

pub fn key_sign(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let key_name_value = req.get_data("key_name")?;
let key_name = key_name_value.as_str().unwrap();
let data_value = req.get_data("data")?;
let data = data_value.as_str().unwrap();
let data = data_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;

let key_bundle = self.fetch_key(req, key_name)?;
let key_bundle = self.fetch_key(req, req.get_data("key_name")?.as_str().ok_or(RvError::ErrRequestFieldInvalid)?)?;

let decoded_data = hex::decode(data.as_bytes())?;
let result = key_bundle.sign(&decoded_data)?;
Expand All @@ -364,14 +367,12 @@ impl PkiBackendInner {
}

pub fn key_verify(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let key_name_value = req.get_data("key_name")?;
let key_name = key_name_value.as_str().unwrap();
let data_value = req.get_data("data")?;
let data = data_value.as_str().unwrap();
let data = data_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let signature_value = req.get_data("signature")?;
let signature = signature_value.as_str().unwrap();
let signature = signature_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;

let key_bundle = self.fetch_key(req, key_name)?;
let key_bundle = self.fetch_key(req, req.get_data("key_name")?.as_str().ok_or(RvError::ErrRequestFieldInvalid)?)?;

let decoded_data = hex::decode(data.as_bytes())?;
let decoded_signature = hex::decode(signature.as_bytes())?;
Expand All @@ -388,14 +389,12 @@ impl PkiBackendInner {
}

pub fn key_encrypt(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let key_name_value = req.get_data("key_name")?;
let key_name = key_name_value.as_str().unwrap();
let data_value = req.get_data("data")?;
let data = data_value.as_str().unwrap();
let data = data_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let aad_value = req.get_data("aad")?;
let aad = aad_value.as_str().unwrap();
let aad = aad_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;

let key_bundle = self.fetch_key(req, key_name)?;
let key_bundle = self.fetch_key(req, req.get_data("key_name")?.as_str().ok_or(RvError::ErrRequestFieldInvalid)?)?;

let decoded_data = hex::decode(data.as_bytes())?;
let result = key_bundle.encrypt(&decoded_data, Some(EncryptExtraData::Aad(aad.as_bytes())))?;
Expand All @@ -411,14 +410,12 @@ impl PkiBackendInner {
}

pub fn key_decrypt(&self, _backend: &dyn Backend, req: &mut Request) -> Result<Option<Response>, RvError> {
let key_name_value = req.get_data("key_name")?;
let key_name = key_name_value.as_str().unwrap();
let data_value = req.get_data("data")?;
let data = data_value.as_str().unwrap();
let data = data_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;
let aad_value = req.get_data("aad")?;
let aad = aad_value.as_str().unwrap();
let aad = aad_value.as_str().ok_or(RvError::ErrRequestFieldInvalid)?;

let key_bundle = self.fetch_key(req, key_name)?;
let key_bundle = self.fetch_key(req, req.get_data("key_name")?.as_str().ok_or(RvError::ErrRequestFieldInvalid)?)?;

let decoded_data = hex::decode(data.as_bytes())?;
let result = key_bundle.decrypt(&decoded_data, Some(EncryptExtraData::Aad(aad.as_bytes())))?;
Expand Down
Loading

0 comments on commit 6706830

Please sign in to comment.