Skip to content

Commit

Permalink
Merge pull request #340 from NordSecurity/FILE-613_retrieve_private_k…
Browse files Browse the repository at this point in the history
…ey_always

FILE-613: retrieve private key always
  • Loading branch information
LukasPukenis authored Sep 24, 2024
2 parents d5f4cba + 9704105 commit 4576bd6
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 48 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* Add `base_dir` field to the `FilePending` event
* Update moose tracker to v13.1.0
* Adds the `transfer_intent_received` event
* Added private key retrieval on demand instead of caching it

---
<br>
Expand Down
7 changes: 6 additions & 1 deletion drop-transfer/examples/udrop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,12 @@ async fn main() -> anyhow::Result<()> {

let auth = {
let pubkey = drop_auth::PublicKey::from(PUB_KEY);
auth::Context::new(drop_auth::SecretKey::from(PRIV_KEY), move |_| Some(pubkey))
let privkey = move || {
let privkey = drop_auth::SecretKey::from(PRIV_KEY);
Some(privkey)
};

auth::Context::new(privkey, move |_| Some(pubkey))
};

let storage_file = matches.get_one::<String>("storage").unwrap();
Expand Down
15 changes: 9 additions & 6 deletions drop-transfer/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ use drop_auth::{PublicKey, SecretKey};
use hyper::{http::HeaderValue, Response};

pub struct Context {
secret: SecretKey,
secret: Box<dyn Fn() -> Option<SecretKey> + Send + Sync>,
public: Box<dyn Fn(IpAddr) -> Option<PublicKey> + Send + Sync>,
}

impl Context {
pub fn new(
secret: SecretKey,
secret: impl Fn() -> Option<SecretKey> + Send + Sync + 'static,
public: impl Fn(IpAddr) -> Option<PublicKey> + Send + Sync + 'static,
) -> Self {
Self {
secret,
secret: Box::new(secret),
public: Box::new(public),
}
}
Expand All @@ -28,7 +28,8 @@ impl Context {
tokio::task::block_in_place(|| {
let auth_req = drop_auth::http::Authorization::parse(auth_header_value)?;
let pubkey = (self.public)(peer_ip)?;
drop_auth::authorize(nonce, &self.secret, &pubkey, &auth_req)
let secret = (self.secret)()?;
drop_auth::authorize(nonce, &secret, &pubkey, &auth_req)
})
.is_some()
}
Expand Down Expand Up @@ -74,9 +75,10 @@ impl Context {
.context("Failed to parse 'www-authenticate' header")?;

let public = (self.public)(peer_ip).context("Failed to fetch peer's public key")?;
let secret = (self.secret)().context("Failed to fetch private key")?;

let ticket =
drop_auth::create_ticket_as_client(&self.secret, &public, resp, check_nonce_prefix)
drop_auth::create_ticket_as_client(&secret, &public, resp, check_nonce_prefix)
.context("Failed to create auth ticket")?;

let value = HeaderValue::from_str(&ticket.to_string())?;
Expand All @@ -96,8 +98,9 @@ impl Context {
.context("Failed to parse 'www-authenticate' header")?;

let public = (self.public)(peer_ip).context("Failed to fetch peer's public key")?;
let secret = (self.secret)().context("Failed to fetch private key")?;

let ticket = drop_auth::create_ticket_as_server(&self.secret, &public, resp)
let ticket = drop_auth::create_ticket_as_server(&secret, &public, resp)
.context("Failed to create auth ticket")?;

let value = HeaderValue::from_str(&ticket.to_string())?;
Expand Down
2 changes: 1 addition & 1 deletion drop-transfer/src/ws/server/v6.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<'a> handler::HandlerInit for HandlerInit<'a> {
.context("Failed to receive transfer request")?;

// print msg as ascii
debug!(self.logger, "************** msg:\n\t{msg:?}");
debug!(self.logger, "msg:\n\t{msg:?}");

let msg = msg.to_str().ok().context("Expected JSON message")?;
debug!(self.logger, "Request received:\n\t{msg}");
Expand Down
45 changes: 26 additions & 19 deletions norddrop/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
};

use drop_analytics::DeveloperExceptionEventData;
use drop_auth::{PublicKey, SecretKey};
use drop_auth::{PublicKey, SecretKey, PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH};
use drop_config::{Config, DropConfig, MooseConfig};
use drop_storage::types::Transfer as TransferInfo;
use drop_transfer::{auth, utils::Hidden, Event, FileToSend, OutgoingTransfer, Service, Transfer};
Expand All @@ -15,7 +15,7 @@ use tokio::{
task::JoinHandle,
};

use crate::{event, TransferDescriptor};
use crate::{event, KeyStore, TransferDescriptor};

pub type Result<T = ()> = std::result::Result<T, crate::LibdropError>;

Expand Down Expand Up @@ -52,15 +52,11 @@ impl EventDispatcher {
impl NordDropFFI {
pub(super) fn new(
event_cb: impl Fn(crate::Event) + Send + Sync + 'static,
pubkey_cb: impl Fn(IpAddr) -> Option<PublicKey> + Send + 'static,
privkey: SecretKey,
key_store: Arc<dyn KeyStore>,
logger: Logger,
) -> Result<Self> {
trace!(logger, "norddrop_new()");

// It's a debug print. Not visible in the production build
debug!(logger, "Private key: {:02X?}", privkey.to_bytes());

Ok(NordDropFFI {
instance: Arc::default(),
logger: logger.clone(),
Expand All @@ -69,7 +65,7 @@ impl NordDropFFI {
cb: Arc::new(event_cb) as _,
},
config: DropConfig::default(),
keys: Arc::new(crate_key_context(logger, privkey, pubkey_cb)),
keys: Arc::new(create_key_context(logger, key_store)),
#[cfg(unix)]
fdresolv: None,
})
Expand Down Expand Up @@ -522,22 +518,33 @@ impl NordDropFFI {
}
}

fn crate_key_context(
logger: slog::Logger,
privkey: SecretKey,
pubkey_cb: impl Fn(IpAddr) -> Option<PublicKey> + Send + 'static,
) -> auth::Context {
let pubkey_cb = std::sync::Mutex::new(pubkey_cb);
let public = move |ip: IpAddr| {
fn create_key_context(logger: slog::Logger, key_store: Arc<dyn KeyStore>) -> auth::Context {
let privkey = {
let key_store = key_store.clone();
let logger = logger.clone();
let privkey_cb = std::sync::Mutex::new(key_store);
move || {
let guard = privkey_cb.lock().expect("Failed to lock privkey callback");
let privkey: [u8; SECRET_KEY_LENGTH] = guard.privkey().try_into().ok()?;
drop(guard);

debug!(logger, "Retrieved private key: {:?}", privkey);
Some(SecretKey::from(privkey))
}
};

let pubkey_cb = std::sync::Mutex::new(key_store);
let pubkey = move |ip: IpAddr| {
let guard = pubkey_cb.lock().expect("Failed to lock pubkey callback");
let key = guard(ip)?;
let pubkey = guard.on_pubkey(ip.to_string())?;
drop(guard);

debug!(logger, "Public key for {ip:?}: {key:?}");
Some(key)
let pubkey: [u8; PUBLIC_KEY_LENGTH] = pubkey.try_into().ok()?;
debug!(logger, "Retrieved public key for: {} key: {:?}", ip, pubkey);
Some(PublicKey::from(pubkey))
};

auth::Context::new(privkey, public)
auth::Context::new(privkey, pubkey)
}

fn open_database(
Expand Down
15 changes: 1 addition & 14 deletions norddrop/src/uni.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use std::sync::Mutex;

use drop_auth::{PublicKey, SecretKey, PUBLIC_KEY_LENGTH};

use crate::{device::NordDropFFI, Event, TransferDescriptor, TransferInfo};

pub type Result<T> = std::result::Result<T, crate::LibdropError>;
Expand Down Expand Up @@ -36,20 +34,9 @@ impl NordDrop {
) -> Result<Self> {
let logger = super::log::create(logger);

let privkey = key_store.privkey();
let privkey: [u8; PUBLIC_KEY_LENGTH] = privkey
.try_into()
.map_err(|_| crate::LibdropError::InvalidPrivkey)?;
let privkey = SecretKey::from(privkey);

let dev = NordDropFFI::new(
move |ev| event_callback.on_event(ev),
move |peer_ip| {
let pubkey = key_store.on_pubkey(peer_ip.to_string())?;
let pubkey: [u8; PUBLIC_KEY_LENGTH] = pubkey.try_into().ok()?;
Some(PublicKey::from(pubkey))
},
privkey,
key_store.into(),
logger,
)?;

Expand Down
2 changes: 1 addition & 1 deletion test/drop_test/ffi.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def __init__(self):
def on_event(self, event: norddrop.Event):
event = new_event(event)
if DEBUG_PRINT_EVENT:
tprint(bcolors.HEADER + "--- event: ", event, bcolors.ENDC, flush=True)
tprint(bcolors.HEADER + "event: ", event, bcolors.ENDC, flush=True)

with self._lock:
self._events.append(event)
Expand Down
13 changes: 7 additions & 6 deletions test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import os
import re
import time
import sys
from datetime import timedelta
from threading import Semaphore
from typing import Tuple

Expand Down Expand Up @@ -132,6 +134,7 @@ def run():
for s in scenarios:
total_containers += len(s.runners())

start_time = time.time()
while True:
if len(already_done) == len(scenarios):
break
Expand Down Expand Up @@ -202,8 +205,6 @@ def run():
info = ContainerHolder(container, scenario.id(), TESTCASE_TIMEOUT)
scenario_results[scenario.id()].append(info)

curr_time = time.strftime("%H:%M:%S", time.localtime())

done_containers = 0
failed_container_count = 0
for scenario in scenarios:
Expand All @@ -214,11 +215,11 @@ def run():
success, reason = container.success()
if not success:
failed_container_count += 1

print(
f"*** Test suite progress: {curr_time}: {done_containers}/{total_containers} containers finished, {failed_container_count} failed",
flush=True,
elapsed_time = str(timedelta(seconds=(round(time.time() - start_time))))
sys.stdout.write(
f"Testing in progress. Elapsed time: {elapsed_time}. Container exit stats: {done_containers}/{total_containers}, of those failed: {failed_container_count}\r"
)
sys.stdout.flush()

time.sleep(1)

Expand Down

0 comments on commit 4576bd6

Please sign in to comment.