From a3634355852781e23490b2093dfa6303d049e335 Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Tue, 16 Jan 2024 15:11:07 +0100 Subject: [PATCH 1/2] Remove `encrypt_buffer` and `decrypt_buffer` functions from API The `encrypt_buffer` and `decrypt_buffer` functions use the `rustc_serialize::from_hex` function, but it is not constant time and leads to secret dependent control flow. These functions shouldn't have been in the API in the first place, and are removed. --- .github/workflows/build.yml | 8 +- Cargo.lock | 59 ------ Cargo.toml | 1 - em-app/examples/harmonize/Cargo.toml | 22 --- em-app/examples/harmonize/README.md | 5 - em-app/examples/harmonize/certs/aws_s3.pem | 26 --- .../examples/harmonize/certs/em_ca_cert.pem | 26 --- em-app/examples/harmonize/src/main.rs | 179 ------------------ em-app/src/lib.rs | 1 - em-app/src/utils.rs | 54 +----- 10 files changed, 5 insertions(+), 376 deletions(-) delete mode 100644 em-app/examples/harmonize/Cargo.toml delete mode 100644 em-app/examples/harmonize/README.md delete mode 100644 em-app/examples/harmonize/certs/aws_s3.pem delete mode 100644 em-app/examples/harmonize/certs/em_ca_cert.pem delete mode 100644 em-app/examples/harmonize/src/main.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3d535630..1abd9430 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -87,11 +87,11 @@ jobs: ln -sf /usr/include/x86_64-linux-gnu/openssl /tmp/muslinclude/openssl PKG_CONFIG_ALLOW_CROSS=1 CFLAGS=-I/tmp/muslinclude CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_LINKER=true cargo build --locked -p fortanix-sgx-tools --target x86_64-unknown-linux-musl - - name: Build em-app, get-certificate, harmonize for x86_64-unknown-linux-musl - run: cargo build --verbose --locked -p em-app -p get-certificate -p harmonize --target=x86_64-unknown-linux-musl + - name: Build em-app, get-certificate for x86_64-unknown-linux-musl + run: cargo build --verbose --locked -p em-app -p get-certificate --target=x86_64-unknown-linux-musl - - name: Build em-app, get-certificate, harmonize for x86_64-fortanix-unknown-sgx - run: cargo build --verbose --locked -p em-app -p get-certificate -p harmonize --target=x86_64-fortanix-unknown-sgx + - name: Build em-app, get-certificate for x86_64-fortanix-unknown-sgx + run: cargo build --verbose --locked -p em-app -p get-certificate --target=x86_64-fortanix-unknown-sgx - name: Generate API docs run: ./doc/generate-api-docs.sh diff --git a/Cargo.lock b/Cargo.lock index d0382bdd..3da35c28 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -245,18 +245,6 @@ dependencies = [ "byte-tools", ] -[[package]] -name = "bstr" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" -dependencies = [ - "lazy_static", - "memchr", - "regex-automata", - "serde", -] - [[package]] name = "build_const" version = "0.2.2" @@ -588,28 +576,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "csv" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" -dependencies = [ - "bstr", - "csv-core", - "itoa 0.4.6", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" -dependencies = [ - "memchr", -] - [[package]] name = "darling" version = "0.12.4" @@ -1397,25 +1363,6 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" -[[package]] -name = "harmonize" -version = "0.2.0" -dependencies = [ - "b64-ct", - "csv", - "em-app", - "hyper 0.10.16", - "mbedtls", - "pkix", - "rustc-serialize", - "sdkms", - "serde", - "serde_derive 1.0.132", - "serde_json", - "url 1.7.2", - "uuid 0.6.5", -] - [[package]] name = "hashbrown" version = "0.9.1" @@ -3086,12 +3033,6 @@ dependencies = [ "thread_local", ] -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" - [[package]] name = "regex-syntax" version = "0.6.20" diff --git a/Cargo.toml b/Cargo.toml index ba4ac1a6..2863d494 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,6 @@ members = [ "rs-libc", "em-app", "em-app/examples/get-certificate/", - "em-app/examples/harmonize/", ] exclude = ["examples"] diff --git a/em-app/examples/harmonize/Cargo.toml b/em-app/examples/harmonize/Cargo.toml deleted file mode 100644 index a899aa7e..00000000 --- a/em-app/examples/harmonize/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -# Minimal application for testing purposes - used to fetch app config via cert auth. -[package] -name = "harmonize" -version = "0.2.0" -authors = ["fortanix.com"] -edition = "2018" -license = "MPL-2.0" - -[dependencies] -em-app = { path = "../../" } -mbedtls = { version = "0.9", features = [ "rdrand", "std", "force_aesni_support", "mpi_force_c_code" ], default-features = false } -serde_json = "1.0.62" -serde = "1.0.123" -serde_derive = "1.0.123" -uuid = { version = "0.6.3", features = ["v4", "serde"] } -b64-ct = "0.1.0" -hyper = "0.10" -sdkms = { version = "0.2.1", default-features = false } -rustc-serialize = "0.3.24" -csv = "1.1" -pkix = "0.1.2" -url = "1" diff --git a/em-app/examples/harmonize/README.md b/em-app/examples/harmonize/README.md deleted file mode 100644 index 38e081dd..00000000 --- a/em-app/examples/harmonize/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Fortanix Enclave Manager example - -This crate provides an example on how to obtain a certificate from Fortanix Enclave Manager for both SGX and Nitro Enclaves. - -For recommended build flags and patches, please check em-app README.md. diff --git a/em-app/examples/harmonize/certs/aws_s3.pem b/em-app/examples/harmonize/certs/aws_s3.pem deleted file mode 100644 index 834b6560..00000000 --- a/em-app/examples/harmonize/certs/aws_s3.pem +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIQAYL4CY6i5ia5GjsnhB+5rzANBgkqhkiG9w0BAQsFADBa -MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl -clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE1 -MTIwODEyMDUwN1oXDTI1MDUxMDEyMDAwMFowZDELMAkGA1UEBhMCVVMxFTATBgNV -BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEjMCEG -A1UEAxMaRGlnaUNlcnQgQmFsdGltb3JlIENBLTIgRzIwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQC75wD+AAFz75uI8FwIdfBccHMf/7V6H40II/3HwRM/ -sSEGvU3M2y24hxkx3tprDcFd0lHVsF5y1PBm1ITykRhBtQkmsgOWBGmVU/oHTz6+ -hjpDK7JZtavRuvRZQHJaZ7bN5lX8CSukmLK/zKkf1L+Hj4Il/UWAqeydjPl0kM8c -+GVQr834RavIL42ONh3e6onNslLZ5QnNNnEr2sbQm8b2pFtbObYfAB8ZpPvTvgzm -+4/dDoDmpOdaxMAvcu6R84Nnyc3KzkqwIIH95HKvCRjnT0LsTSdCTQeg3dUNdfc2 -YMwmVJihiDfwg/etKVkgz7sl4dWe5vOuwQHrtQaJ4gqPAgMBAAGjggEZMIIBFTAd -BgNVHQ4EFgQUwBKyKHRoRmfpcCV0GgBFWwZ9XEQwHwYDVR0jBBgwFoAU5Z1ZMIJH -WMys+ghUNoZ7OrUETfAwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMC -AYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp -Y2VydC5jb20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQu -Y29tL09tbmlyb290MjAyNS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYB -BQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQEL -BQADggEBAC/iN2bDGs+RVe4pFPpQEL6ZjeIo8XQWB2k7RDA99blJ9Wg2/rcwjang -B0lCY0ZStWnGm0nyGg9Xxva3vqt1jQ2iqzPkYoVDVKtjlAyjU6DqHeSmpqyVDmV4 -7DOMvpQ+2HCr6sfheM4zlbv7LFjgikCmbUHY2Nmz+S8CxRtwa+I6hXsdGLDRS5rB -bxcQKegOw+FUllSlkZUIII1pLJ4vP1C0LuVXH6+kc9KhJLsNkP5FEx2noSnYZgvD -0WyzT7QrhExHkOyL4kGJE7YHRndC/bseF/r/JUuOUFfrjsxOFT+xJd1BDKCcYm1v -upcHi9nzBhDFKdT3uhaQqNBU4UtJx5g= ------END CERTIFICATE----- diff --git a/em-app/examples/harmonize/certs/em_ca_cert.pem b/em-app/examples/harmonize/certs/em_ca_cert.pem deleted file mode 100644 index 1d82449a..00000000 --- a/em-app/examples/harmonize/certs/em_ca_cert.pem +++ /dev/null @@ -1,26 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIEZTCCA02gAwIBAgIQQAF1BIMUpMghjISpDBbN3zANBgkqhkiG9w0BAQsFADA/ -MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT -DkRTVCBSb290IENBIFgzMB4XDTIwMTAwNzE5MjE0MFoXDTIxMDkyOTE5MjE0MFow -MjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxCzAJBgNVBAMT -AlIzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuwIVKMz2oJTTDxLs -jVWSw/iC8ZmmekKIp10mqrUrucVMsa+Oa/l1yKPXD0eUFFU1V4yeqKI5GfWCPEKp -Tm71O8Mu243AsFzzWTjn7c9p8FoLG77AlCQlh/o3cbMT5xys4Zvv2+Q7RVJFlqnB -U840yFLuta7tj95gcOKlVKu2bQ6XpUA0ayvTvGbrZjR8+muLj1cpmfgwF126cm/7 -gcWt0oZYPRfH5wm78Sv3htzB2nFd1EbjzK0lwYi8YGd1ZrPxGPeiXOZT/zqItkel -/xMY6pgJdz+dU/nPAeX1pnAXFK9jpP+Zs5Od3FOnBv5IhR2haa4ldbsTzFID9e1R -oYvbFQIDAQABo4IBaDCCAWQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8E -BAMCAYYwSwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5p -ZGVudHJ1c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTE -p7Gkeyxx+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEE -AYLfEwEBATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2Vu -Y3J5cHQub3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0 -LmNvbS9EU1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYf -r52LFMLGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0B -AQsFAAOCAQEA2UzgyfWEiDcx27sT4rP8i2tiEmxYt0l+PAK3qB8oYevO4C5z70kH -ejWEHx2taPDY/laBL21/WKZuNTYQHHPD5b1tXgHXbnL7KqC401dk5VvCadTQsvd8 -S8MXjohyc9z9/G2948kLjmE6Flh9dDYrVYA9x2O+hEPGOaEOa1eePynBgPayvUfL -qjBstzLhWVQLGAkXXmNs+5ZnPBxzDJOLxhF2JIbeQAcH5H0tZrUlo5ZYyOqA7s9p -O5b85o3AM/OJ+CktFBQtfvBhcJVd9wvlwPsk+uyOy2HI7mNxKKgsBTt375teA2Tw -UdHkhVNcsAKX1H7GNNLOEADksd86wuoXvg== ------END CERTIFICATE----- diff --git a/em-app/examples/harmonize/src/main.rs b/em-app/examples/harmonize/src/main.rs deleted file mode 100644 index df48cdd8..00000000 --- a/em-app/examples/harmonize/src/main.rs +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (c) Fortanix, Inc. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#[macro_use] -pub extern crate serde_derive; - -use std::env; -use std::sync::Arc; -use std::collections::HashMap; - -use b64_ct::{FromBase64}; -use em_app::*; -use mbedtls::alloc::{List as MbedtlsList}; -use mbedtls::pk::Pk; -use mbedtls::x509::{Certificate, Crl}; -use sdkms::api_model::Blob; -use url::Url; - -use em_app::utils::{CredentialsEncryption, get_runtime_configuration, get_sdkms_dataset, https_get, https_put, decrypt_buffer, encrypt_buffer}; -use em_app::utils::models::{RuntimeAppConfig, ApplicationConfigConnectionDataset}; - -fn main() -> Result<(), String> { - env::set_var("RUST_BACKTRACE", "full"); - - let args: Vec = env::args().collect(); - if args.len() < 2 { - return Err(format!("Usage: ftxsgx-runner {} app-config-id", args[0])); - } - - // Generate key - mbedtls::Pk has required trait implemented - customers may choose any other mechanism to create certificates - let mut rng = FtxRng; - let mut key = Pk::generate_rsa(&mut rng, 3072, 0x10001).unwrap(); - - // This is always on localhost but the port might be different - let node_agent_url = "http://localhost:9092"; - - // This must be on localhost otherwise local attestation will not work - let em_server = "ccm.fortanix.com"; - let em_port = 443; - - let em_ca_cert = Some(Arc::new(Certificate::from_pem_multiple(concat!(include_str!("../certs/em_ca_cert.pem"), "\0").as_bytes()).map_err(|e| format!("Invalid CA Cert for CCM: {:?}", e))?)); - let em_crl = None; - let sdkms_ca_cert = em_ca_cert.clone(); - let sdkms_crl = None; - - let storage_ca = Some(Arc::new(Certificate::from_pem_multiple(concat!(include_str!("../certs/aws_s3.pem"), "\0").as_bytes()).map_err(|e| format!("Invalid CA Cert for CCM: {:?}", e))?)); - let storage_crl = None; - - let config_id = args[1].clone(); - - let result = get_certificate(node_agent_url,"localhost", &mut key, None, Some(&config_id)).map_err(|e| format!("Error: {}", e))?; - println!("\na. Public certificate is signed: \n{}", serde_json::to_string_pretty(&result.certificate_response).map_err(|e| format!("Failed decoding certificate response: {:?}", e))?); - - let mut cert_pem = result.certificate_response.certificate.ok_or("Missing certificate in response")?; - cert_pem.push('\0'); - - let app_cert = Arc::new(Certificate::from_pem_multiple(&cert_pem.as_bytes()).map_err(|e| format!("Parsing certificate failed: {:?}", e))?); - let key = Arc::new(key); - - let config = get_runtime_configuration(em_server, em_port, app_cert.clone(), key.clone(), em_ca_cert, em_crl).map_err(|e| format!("Error in client: {:?}", e))?; - println!("\nb. Application configuration: \n{}", serde_json::to_string_pretty(&config).map_err(|e| format!("Failed decoding response: {:?}", e))?); - - let (input, input_credentials) = get_credentials("input", &config, app_cert.clone(), key.clone(), sdkms_ca_cert.clone(), sdkms_crl.clone())?; - println!("\nc.1. 'input' port dataset value from SDKMS: \n{}", serde_json::to_string_pretty(&input_credentials).unwrap()); - - let (output, output_credentials) = get_credentials("output", &config, app_cert.clone(), key.clone(), sdkms_ca_cert.clone(), sdkms_crl.clone())?; - println!("\nd.2. 'output' port dataset value from SDKMS: \n{}", serde_json::to_string_pretty(&output_credentials).unwrap()); - - let query_string = input_credentials.query_string.from_base64().map_err(|e| format!("Failed decoding query string: {:?}", e))?; - let query_string = &String::from_utf8(query_string).map_err(|e| format!("Query string is not utf-8: {:?}", e))?; - - let url = input.location.to_owned() + "?" + query_string; - let url = Url::parse(&url).map_err(|e| format!("Failed parsing input url, error: {:?}", e))?; - - let body: Vec = https_get(url, storage_ca.clone(), storage_crl.clone())?; - println!("\ne. Downloaded input."); - - let decrypted = decrypt_buffer(&body, &input_credentials.encryption)?; - println!("\nf. Decrypted input."); - - let data = process(decrypted).map_err(|e| format!("Failed processing CSV file, error: {:?}", e))?; - - let encrypted = encrypt_buffer(&data.as_bytes(), &output_credentials.encryption)?; - println!("\nh.Encrypted output: \n{}", get_ascii(&encrypted, false)); - - let query_string = output_credentials.query_string.from_base64().map_err(|e| format!("Failed decoding query string: {:?}", e))?; - let query_string = &String::from_utf8(query_string).map_err(|e| format!("Query string is not utf-8: {:?}", e))?; - - let url = output.location.to_owned() + "?" + query_string; - let url = Url::parse(&url).map_err(|e| format!("Failed parsing input url, error: {:?}", e))?; - https_put(url, encrypted, storage_ca.clone(), storage_crl.clone())?; - - println!("\ni. Upload finished at location: {}", output.location); - Ok(()) -} - - -pub fn get_credentials<'a>(port: &str, - config: &'a RuntimeAppConfig, - app_cert: Arc>, - key: Arc, - ca_cert_list: Option>>, - ca_crl: Option> -) -> Result<(&'a ApplicationConfigConnectionDataset, Credentials), String> { - - let dataset = config.extra.connections.as_ref().ok_or("Missing connections in runtime config")? - .get(port).ok_or(format!("Missing connection in runtime config for port: {}", port))? - .values().next().ok_or(format!("No dataset provided in runtime config for port: {}", port))? - .dataset.as_ref().ok_or(format!("first connection is not a dataset for port: {}", port))?; - - let sdkms_info = dataset.credentials.sdkms.as_ref().ok_or(format!("dataset.sdkms field is not present for connection on port: {}.", port))?; - - let response = get_sdkms_dataset(sdkms_info.credentials_url.clone(), - sdkms_info.credentials_key_name.clone(), - sdkms_info.sdkms_app_id, - app_cert.clone(), - key.clone(), - ca_cert_list, - ca_crl).map_err(|e| format!("Failed retrieving dataset: {:?}", e))?; - - Ok((dataset, decode_credentials(response)?)) -} - -fn process(decrypted: Vec) -> Result { - #[allow(non_snake_case)] - #[derive(Debug, Deserialize)] - struct Record { - START: String, - STOP: String, - PATIENT: String, - ENCOUNTER: String, - CODE: String, - DESCRIPTION: String, - } - - let mut statistics = HashMap::::new(); - let mut count : u32 = 0; - let mut rdr = csv::Reader::from_reader(&*decrypted); - for i in rdr.deserialize() { - let record: Record = i.map_err(|_| "Invalid CSV data".to_string())?; - statistics.entry(record.DESCRIPTION).and_modify(|e| *e += 1).or_insert(1); - count += 1; - } - - let last_entry = statistics.iter().max_by(|a, b| a.1.cmp(&b.1)).ok_or("No entries in CSV")?; - let top = last_entry.0; - let freq = last_entry.1; - let unique = statistics.len(); - - let result = format!("count {:<50}\nunique {:<50}\ntop {:<50}\nfreq {:<50}\nName: DESCRIPTION, dtype: object\n", - count, unique, top, freq); - - Ok(result) -} - -pub fn get_ascii(bytes: &Vec, allow_newline: bool) -> String { - bytes.iter().map(|b| { - if (*b >= 32u8 && *b <= 126u8) || (allow_newline && *b == '\n' as u8) { - *b as char - } else { - '.' - } - }).collect() -} - -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct Credentials { - pub query_string: String, - pub encryption: CredentialsEncryption, -} - -pub fn decode_credentials(credentials: Blob) -> Result { - let credentials = String::from_utf8(credentials.to_vec()).map_err(|e| format!("Failed UTF-8 decoding on credentials field: {:?}", e))?; - let credentials : Credentials = serde_json::from_str(&credentials).map_err(|e| format!("Failed json deserialization for credentials, error: {:?}, credentials {}", e, credentials))?; - Ok(credentials) -} diff --git a/em-app/src/lib.rs b/em-app/src/lib.rs index f6ba7633..42a28c57 100644 --- a/em-app/src/lib.rs +++ b/em-app/src/lib.rs @@ -3,7 +3,6 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#[macro_use] pub extern crate serde_derive; pub mod mbedtls_hyper; diff --git a/em-app/src/utils.rs b/em-app/src/utils.rs index 0a50e731..84ea480b 100644 --- a/em-app/src/utils.rs +++ b/em-app/src/utils.rs @@ -12,15 +12,10 @@ use hyper::client::Pool; use hyper::net::HttpsConnector; use em_client::{Api, Client}; use mbedtls::alloc::{List as MbedtlsList}; -use mbedtls::cipher::raw::{CipherId, CipherMode}; -use mbedtls::cipher::{Decryption, Encryption, Fresh, Authenticated}; -use mbedtls::cipher; use mbedtls::pk::Pk; -use mbedtls::rng::{Rdrand, Random}; use mbedtls::ssl::Config; use mbedtls::ssl::config::{Endpoint, Preset, Transport, AuthMode, Version}; use mbedtls::x509::{Certificate, Crl}; -use rustc_serialize::hex::FromHex; use sdkms::api_model::Blob; use uuid::Uuid; use url::Url; @@ -165,53 +160,6 @@ pub fn https_put(url: Url, Ok(()) } -const NONCE_SIZE : usize = 12; -const TAG_SIZE : usize = 16; - -// Basic AES-256-GCM encrypt/decrypt utility functions. -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] -pub struct CredentialsEncryption { - pub key: String, -} - -pub fn encrypt_buffer(body: &[u8], encryption: &CredentialsEncryption) -> Result, String>{ - let key = encryption.key.from_hex().map_err(|e| format!("Failed decoding key as a hex string: {:?}", e))?; - - let mut nonce = [0; NONCE_SIZE]; - Rdrand.random(&mut nonce[..]).map_err(|e| format!("Could not generate random nonce {}", e))?; - - let cipher = cipher::Cipher::::new(CipherId::Aes, CipherMode::GCM, 256).map_err(|e| format!("Failed creating cypher: {:?}", e))?; - let cipher_k = cipher.set_key_iv(&key, &nonce).map_err(|e| format!("Failed setting key, error: {:?}", e))?; - - let mut output = Vec::new(); - output.resize(body.len() + NONCE_SIZE + TAG_SIZE + cipher_k.block_size(), 0); - - let size = cipher_k.encrypt_auth(&[], &body[..], &mut output[NONCE_SIZE..], TAG_SIZE).map_err(|e| format!("Failed encrypting body, error: {:?}", e))?.0; - output.resize(size + NONCE_SIZE, 0); - - output[0..NONCE_SIZE].copy_from_slice(&nonce); - - Ok(output) -} - -pub fn decrypt_buffer(body: &Vec, encryption: &CredentialsEncryption) -> Result, String>{ - let key = encryption.key.from_hex().map_err(|e| format!("Failed deconding key as a hex string: {:?}", e))?; - - let cipher = cipher::Cipher::::new(CipherId::Aes, CipherMode::GCM, 256).map_err(|e| format!("Failed creating cypher: {:?}", e))?; - let cipher_k = cipher.set_key_iv(&key, &body[0..NONCE_SIZE]).map_err(|e| format!("Failed setting key, error: {:?}", e))?; - - let mut decrypted = Vec::new(); - - // Allocate the length + 1 block size more to have enough space for decrypted content - decrypted.resize(body.len() + cipher_k.block_size(), 0); - - // Decrypt starting from byte 12 after our nonce and up to -TAG_SIZE which is 16 bytes - let (size, _cipher_f) = cipher_k.decrypt_auth(&[], &body[NONCE_SIZE..], &mut decrypted, TAG_SIZE).map_err(|e| format!("Failed decrypting body, error: {:?}", e))?; - - decrypted.resize(size, 0); - Ok(decrypted) -} - const CONNECTION_IDLE_TIMEOUT_SECS: u64 = 30; pub fn get_hyper_connector_pool(ca_chain: Vec>) -> Result, String> { @@ -247,4 +195,4 @@ pub fn get_mbedtls_hyper_connector_pool(ca_chain: Vec>, client_pki: Opti pool.set_idle_timeout(Some(Duration::from_secs(CONNECTION_IDLE_TIMEOUT_SECS))); Ok(Arc::new(hyper::Client::with_connector(pool))) -} \ No newline at end of file +} From 7c46bec8c199fab5a1cfded67e54f51505eafbee Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Tue, 16 Jan 2024 15:15:58 +0100 Subject: [PATCH 2/2] Bump `em-app` version --- Cargo.lock | 2 +- em-app/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3da35c28..b3cb52e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -768,7 +768,7 @@ dependencies = [ [[package]] name = "em-app" -version = "0.4.0" +version = "0.5.0" dependencies = [ "aws-nitro-enclaves-nsm-api", "b64-ct", diff --git a/em-app/Cargo.toml b/em-app/Cargo.toml index acf9778a..aee6d126 100644 --- a/em-app/Cargo.toml +++ b/em-app/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "em-app" -version = "0.4.0" +version = "0.5.0" authors = ["fortanix.com"] license = "MPL-2.0" edition = "2018"