| // 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(()) |
| } |