Skip to content

Commit

Permalink
Refactor signing key loading into module
Browse files Browse the repository at this point in the history
Move the function to load the signing keys into a module. Add errors
messages with information about which file/dir failed to open/read.
  • Loading branch information
Felix Obenhuber committed Sep 7, 2020
1 parent 490ba7d commit 89009a8
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 32 deletions.
52 changes: 52 additions & 0 deletions north/src/keys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2020 ESRLabs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::SETTINGS;
use anyhow::{Context, Result};
use async_std::fs;
use ed25519_dalek::PublicKey;
use futures::{AsyncReadExt, StreamExt};
use log::info;
use std::collections::HashMap;

pub async fn load() -> Result<HashMap<String, PublicKey>> {
let key_dir = &SETTINGS.directories.key_dir;
let mut signing_keys = HashMap::new();
let mut key_dir = fs::read_dir(&key_dir)
.await
.with_context(|| format!("Failed to open {}", key_dir.display()))?;
while let Some(entry) = key_dir.next().await {
let entry = entry.context("Invalid key dir entry")?;
let path = entry.path();
if let Some(extension) = path.extension() {
if extension == "pub" && path.is_file().await {
if let Some(key_id) = path.file_stem().map(|s| s.to_string_lossy().to_string()) {
info!("Loading signing key {}", key_id);
let mut sign_key_file = fs::File::open(&path)
.await
.with_context(|| format!("Failed to open {}", path.display()))?;
let mut key_bytes = Vec::new();
sign_key_file
.read_to_end(&mut key_bytes)
.await
.with_context(|| format!("Failed to read {}", path.display()))?;
let key = PublicKey::from_bytes(&key_bytes)
.with_context(|| format!("Failed to load key from {}", path.display()))?;
signing_keys.insert(key_id, key);
}
}
}
}
Ok(signing_keys)
}
31 changes: 3 additions & 28 deletions north/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@
extern crate structure;

use anyhow::{Context, Error, Result};
use async_std::{fs, path::PathBuf, prelude::*, sync};
use ed25519_dalek::PublicKey;
use async_std::{fs, sync};
use log::*;
use nix::unistd::{self, chown};
use north_common::manifest::Name;
use std::collections::HashMap;

mod console;
mod keys;
#[cfg(any(target_os = "android", target_os = "linux"))]
pub mod linux;
mod npk;
Expand Down Expand Up @@ -93,12 +92,10 @@ async fn main() -> Result<()> {
#[cfg(any(target_os = "android", target_os = "linux"))]
linux::init().await?;

let signing_keys = load_signing_keys(&SETTINGS.directories.key_dir).await?;

// Northstar runs in a event loop. Moduls get a Sender<Event> to the main
// loop.
let (tx, rx) = sync::channel::<Event>(1000);
let mut state = State::new(tx.clone(), signing_keys);
let mut state = State::new(tx.clone()).await?;

// Ensure the configured run_dir exists
// TODO: permission check of SETTINGS.directories.run_dir
Expand Down Expand Up @@ -201,28 +198,6 @@ async fn main() -> Result<()> {
Ok(())
}

async fn load_signing_keys(key_dir: &PathBuf) -> Result<HashMap<String, PublicKey>> {
let mut signing_keys = HashMap::new();
let mut key_dir = fs::read_dir(&key_dir).await?;
while let Some(entry) = key_dir.next().await {
let entry = entry?;
let path = entry.path();
if let Some(extension) = path.extension() {
if extension == "pub" && path.is_file().await {
if let Some(key_id) = path.file_stem() {
let mut sign_key_file = fs::File::open(&path).await?;
let mut key_bytes = Vec::new();
sign_key_file.read_to_end(&mut key_bytes).await?;
let key = PublicKey::from_bytes(&key_bytes)?;
signing_keys.insert(key_id.to_string_lossy().to_string(), key);
info!("Loaded signing key {:?}", key_id);
}
}
}
}
Ok(signing_keys)
}

/// This is a starting point for doing something meaningful with the childs outputs.
fn on_child_output(state: &mut State, name: &str, fd: i32, line: &str) {
if let Some(p) = state.application(name) {
Expand Down
11 changes: 7 additions & 4 deletions north/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::{npk, npk::Container, process::Process, EventTx, Name, TerminationReason};
use crate::{keys, npk, npk::Container, process::Process, EventTx, Name, TerminationReason};
use anyhow::{anyhow, Result};
use ed25519_dalek::PublicKey;
use log::{info, warn};
Expand Down Expand Up @@ -88,12 +88,15 @@ impl fmt::Display for Application {

impl State {
/// Create a new empty State instance
pub fn new(tx: EventTx, signing_keys: HashMap<String, PublicKey>) -> State {
State {
pub async fn new(tx: EventTx) -> Result<State> {
// Load keys for manifest verification
let signing_keys = keys::load().await?;

Ok(State {
tx,
signing_keys,
applications: HashMap::new(),
}
})
}

/// Return an owned copy of the main loop tx handle
Expand Down

0 comments on commit 89009a8

Please sign in to comment.