Skip to content

Commit

Permalink
change function signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
va-an committed Jun 4, 2024
1 parent 15ffb17 commit 8fde10b
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 28 deletions.
1 change: 0 additions & 1 deletion core/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ cookie = { version = "0.18", features = ["percent-encode"] }
futures = { version = "0.3.30", default-features = false, features = ["std"] }
state = "0.6"
aes-gcm = "0.10.3"
base64 = "0.22.1"

[dependencies.hyper-util]
version = "0.1.3"
Expand Down
28 changes: 12 additions & 16 deletions core/lib/src/config/secret_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ use std::fmt;

use aes_gcm::{Aes256Gcm, Nonce};
use aes_gcm::aead::{generic_array::GenericArray, Aead, KeyInit};
use base64::{engine::general_purpose::URL_SAFE, Engine as _};
use rand::RngCore;


use cookie::Key;
use serde::{de, ser, Deserialize, Serialize};

Expand Down Expand Up @@ -194,15 +191,17 @@ impl SecretKey {
///
/// # Example
/// ```rust
/// let plaintext = "I like turtles";
/// use rocket::config::SecretKey;
///
/// let plaintext = "I like turtles".as_bytes();
/// let secret_key = SecretKey::generate().expect("error generate key");
///
/// let encrypted = secret_key.encrypt(&plaintext).expect("can't encrypt");
/// let decrypted = secret_key.decrypt(&encrypted).expect("can't decrypt");
///
/// assert_eq!(decrypted, plaintext);
/// ```
pub fn encrypt(&self, plaintext: &str) -> Result<String, &'static str> {
pub fn encrypt<T: AsRef<[u8]>>(&self, value: T) -> Result<Vec<u8>, &'static str> {
// Convert the encryption key to a fixed-length array
let key: [u8; KEY_LEN] = self.key.encryption().try_into().map_err(|_| "enc key len error")?;

Expand All @@ -216,31 +215,29 @@ impl SecretKey {
let nonce = Nonce::from_slice(&nonce);

// Encrypt the plaintext using the nonce
let ciphertext = aead.encrypt(nonce, plaintext.as_ref()).map_err(|_| "encryption error")?;
let ciphertext = aead.encrypt(nonce, value.as_ref()).map_err(|_| "encryption error")?;

// Prepare a vector to hold the nonce and ciphertext
let mut encrypted_data = Vec::with_capacity(NONCE_LEN + ciphertext.len());
encrypted_data.extend_from_slice(nonce);
encrypted_data.extend_from_slice(&ciphertext);

// Return the base64-encoded result
Ok(URL_SAFE.encode(encrypted_data))
Ok(encrypted_data)
}

/// Decrypts the given base64-encoded encrypted data.
/// Extracts the nonce from the data and uses it for decryption.
/// Returns the decrypted plaintext string.
pub fn decrypt(&self, encrypted: &str) -> Result<String, &'static str> {
// Decode the base64-encoded encrypted data
let decoded = URL_SAFE.decode(encrypted).map_err(|_| "bad base64 value")?;
pub fn decrypt<T: AsRef<[u8]>>(&self, encrypted: T) -> Result<Vec<u8>, &'static str> {
let encrypted = encrypted.as_ref();

// Check if the length of decoded data is at least the length of the nonce
if decoded.len() < NONCE_LEN {
return Err("length of decoded data is < NONCE_LEN");
if encrypted.len() <= NONCE_LEN {
return Err("length of encrypted data is <= NONCE_LEN");
}

// Split the decoded data into nonce and ciphertext
let (nonce, ciphertext) = decoded.split_at(NONCE_LEN);
let (nonce, ciphertext) = encrypted.split_at(NONCE_LEN);
let nonce = Nonce::from_slice(nonce);

// Convert the encryption key to a fixed-length array
Expand All @@ -253,8 +250,7 @@ impl SecretKey {
let decrypted = aead.decrypt(nonce, ciphertext)
.map_err(|_| "invalid key/nonce/value: bad seal")?;

// Convert the decrypted bytes to a UTF-8 string
String::from_utf8(decrypted).map_err(|_| "bad unsealed utf8")
Ok(decrypted)
}
}

Expand Down
1 change: 1 addition & 0 deletions examples/private-data/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ publish = false

[dependencies]
rocket = { path = "../../core/lib", features = ["secrets"] }
base64 = "0.22.1"
40 changes: 30 additions & 10 deletions examples/private-data/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,49 @@ extern crate rocket;

use rocket::{Config, State};
use rocket::fairing::AdHoc;
use rocket::response::status;
use rocket::http::Status;
use base64::{engine::general_purpose::URL_SAFE, Engine as _};

#[cfg(test)] mod tests;

#[get("/encrypt/<msg>")]
fn encrypt_endpoint(msg: &str, config: &State<Config>) -> String{
fn encrypt_endpoint(msg: &str, config: &State<Config>) -> Result<String, status::Custom<String>> {
let secret_key = config.secret_key.clone();
let encrypted = secret_key.encrypt(msg).unwrap();

let encrypted = secret_key.encrypt(msg).map_err(|_| {
status::Custom(Status::InternalServerError, "Failed to encrypt message".to_string())
})?;

let encrypted_msg = URL_SAFE.encode(&encrypted);

info!("received message for encrypt: '{}'", msg);
info!("encrypted msg: '{}'", encrypted);
info!("encrypted msg: '{}'", encrypted_msg);

encrypted
Ok(encrypted_msg)
}

#[get("/decrypt/<msg>")]
fn decrypt_endpoint(msg: &str, config: &State<Config>) -> String {
let secret_key = config.secret_key.clone();
let decrypted = secret_key.decrypt(msg).unwrap();
fn decrypt_endpoint(msg: &str, config: &State<Config>) -> Result<String, status::Custom<String>> {
let secret_key = config.secret_key.clone();

let decoded = URL_SAFE.decode(msg).map_err(|_| {
status::Custom(Status::BadRequest, "Failed to decode base64".to_string())
})?;

let decrypted = secret_key.decrypt(&decoded).map_err(|_| {
status::Custom(Status::InternalServerError, "Failed to decrypt message".to_string())
})?;

let decrypted_msg = String::from_utf8(decrypted).map_err(|_| {
status::Custom(Status::InternalServerError,
"Failed to convert decrypted message to UTF-8".to_string())
})?;

info!("received message for decrypt: '{}'", msg);
info!("decrypted msg: '{}'", decrypted);
info!("received message for decrypt: '{}'", msg);
info!("decrypted msg: '{}'", decrypted_msg);

decrypted
Ok(decrypted_msg)
}

#[launch]
Expand Down
13 changes: 12 additions & 1 deletion examples/private-data/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
use rocket::local::blocking::Client;
use rocket::{config::SecretKey, local::blocking::Client};

#[test]
fn encrypt_decrypt() {
let secret_key = SecretKey::generate().unwrap();
let msg = "very-secret-message".as_bytes();

let encrypted = secret_key.encrypt(msg).unwrap();
let decrypted = secret_key.decrypt(&encrypted).unwrap();

assert_eq!(msg, decrypted);
}

#[test]
fn encrypt_decrypt_api() {
let client = Client::tracked(super::rocket()).unwrap();
let msg = "some-secret-message";

Expand Down

0 comments on commit 8fde10b

Please sign in to comment.