blob: d14dc58c11fbb70c3a2c176452185d666183ad4b [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you 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::ConfigSource;
#[cfg(not(feature = "mesalock_sgx"))]
use std::fs;
#[cfg(feature = "mesalock_sgx")]
use std::prelude::v1::*;
#[cfg(feature = "mesalock_sgx")]
use std::untrusted::fs;
use anyhow::{bail, Context, Result};
use serde::{Deserialize, Serialize};
use std::env;
use std::net;
use std::path::{Path, PathBuf};
use std::string::String;
use std::vec::Vec;
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RuntimeConfig {
pub api_endpoints: ApiEndpointsConfig,
pub internal_endpoints: InternalEndpointsConfig,
pub audit: AuditConfig,
pub attestation: AttestationServiceConfig,
pub mount: MountConfig,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ApiEndpointsConfig {
pub frontend: ApiEndpoint,
pub authentication: ApiEndpoint,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct InternalEndpointsConfig {
pub access_control: InternalEndpoint,
pub authentication: InternalEndpoint,
pub management: InternalEndpoint,
pub storage: InternalEndpoint,
pub execution: InternalEndpoint,
pub scheduler: InternalEndpoint,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct ApiEndpoint {
pub listen_address: net::SocketAddr,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct InternalEndpoint {
pub listen_address: net::SocketAddr,
pub advertised_address: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AuditConfig {
#[serde(rename(serialize = "enclave_info", deserialize = "enclave_info"))]
enclave_info_source: ConfigSource,
#[serde(rename(serialize = "auditor_signatures", deserialize = "auditor_signatures"))]
auditor_signatures_source: Vec<ConfigSource>,
#[serde(default = "Default::default")]
pub enclave_info_bytes: Vec<u8>,
#[serde(default = "Default::default")]
pub auditor_signatures_bytes: Vec<Vec<u8>>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct AttestationServiceConfig {
pub algorithm: String,
pub url: String,
pub key: String,
pub spid: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MountConfig {
pub fusion_base_dir: PathBuf,
}
impl RuntimeConfig {
pub fn from_toml<T: AsRef<Path>>(path: T) -> Result<Self> {
let contents = fs::read_to_string(path.as_ref())
.context("Something went wrong when reading the runtime config file")?;
let mut config: RuntimeConfig =
toml::from_str(&contents).context("Cannot parse the runtime config file")?;
config.audit.enclave_info_bytes = match &config.audit.enclave_info_source {
ConfigSource::Path(ref enclave_info_path) => {
fs::read(enclave_info_path).with_context(|| {
format!("Cannot read enclave_info from {:?}", enclave_info_path)
})?
}
};
let mut signatures: Vec<Vec<u8>> = vec![];
for source in &config.audit.auditor_signatures_source {
let signature = match source {
ConfigSource::Path(ref path) => fs::read(path)
.with_context(|| format!("Cannot read auditor file from {:?}", path))?,
};
signatures.push(signature);
}
config.audit.auditor_signatures_bytes = signatures;
if env::var("AS_ALGO").is_ok()
&& env::var("AS_URL").is_ok()
&& env::var("AS_SPID").is_ok()
&& env::var("AS_KEY").is_ok()
{
let algorithm = env::var("AS_ALGO").unwrap();
let url = env::var("AS_URL").unwrap();
let spid = env::var("AS_SPID").unwrap();
let key = env::var("AS_KEY").unwrap();
config.attestation = AttestationServiceConfig {
algorithm,
url,
key,
spid,
};
}
validate_config(&config)?;
log::trace!(
"Loaded config from {}: {:?}",
path.as_ref().display(),
config
);
Ok(config)
}
}
fn validate_config(config: &RuntimeConfig) -> Result<()> {
match config.attestation.algorithm.as_str() {
"sgx_epid" | "sgx_ecdsa" => (),
_ => bail!(
"Invalid attestation algorithm {}",
config.attestation.algorithm
),
}
if config.attestation.spid.len() != 32 || config.attestation.key.len() != 32 {
bail!("Cannot find Attestation Service SPID/key or format error");
}
if url::Url::parse(&config.attestation.url).is_err() {
bail!("Invalid URL of attestation service");
}
Ok(())
}