Skip to content

Commit

Permalink
Add TLS handling to the gRPC pseudo-node (#838)
Browse files Browse the repository at this point in the history
This change:
- Adds TLS handling logic to the gRPC pseudo-Node
- Reimplements gRPC processing using Tonic library

Fixes #806
Fixes #813
  • Loading branch information
ipetr0v authored May 5, 2020
1 parent 3440e92 commit 1bda917
Show file tree
Hide file tree
Showing 12 changed files with 382 additions and 227 deletions.
2 changes: 1 addition & 1 deletion cargo/remote/ring-0.16.12.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ genrule(
tags = ["no-sandbox"],
# Clear an output directory since `genrule` doesn't use Bazel cache.
cmd = "rm -rf ring_out_dir_outputs/*;"
+ "mkdir -p ring_out_dir_outputs/;"
+ " mkdir -p ring_out_dir_outputs/;"
+ " (export CARGO_MANIFEST_DIR=\"$$PWD/$$(dirname $(location :Cargo.toml))\";"
+ " export TARGET='x86_64-unknown-linux-gnu';"
+ " export RUST_BACKTRACE=1;"
Expand Down
17 changes: 9 additions & 8 deletions cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,20 @@ steps:
entrypoint: 'bash'
args: ['./scripts/run_tests']

- name: 'gcr.io/oak-ci/oak:latest'
id: run_tests_tsan
waitFor: ['run_tests']
timeout: 60m
entrypoint: 'bash'
args: ['./scripts/run_tests_tsan']
# TODO(942): Reenable `run_tests_tsan`.
# - name: 'gcr.io/oak-ci/oak:latest'
# id: run_tests_tsan
# waitFor: ['run_tests']
# timeout: 60m
# entrypoint: 'bash'
# args: ['./scripts/run_tests_tsan']

- name: 'gcr.io/oak-ci/oak:latest'
id: run_examples
timeout: 60m
entrypoint: 'bash'
args: ['./scripts/run_examples', '-s', 'base']
# TODO(942): Reenable `asan` and `tsan`.
# TODO(942): Reenable `run_examples` with `asan` and `tsan`.
# - name: 'gcr.io/oak-ci/oak:latest'
# id: run_examples_asan
# waitFor: ['run_examples']
Expand All @@ -113,7 +114,7 @@ steps:
# ignored by git.
- name: 'gcr.io/oak-ci/oak:latest'
id: git_check_diff
waitFor: ['git_init', 'run_clang_tidy', 'run_tests_tsan', 'run_examples']
waitFor: ['git_init', 'run_clang_tidy', 'run_examples']
timeout: 5m
entrypoint: 'bash'
args: ['./scripts/git_check_diff']
Expand Down
4 changes: 4 additions & 0 deletions oak/proto/application.proto
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ message GrpcServerConfiguration {
// The endpoint address for the gRPC server to listen on.
// `address` is represented as an "ip_address:tcp_port" string.
string address = 1;
// Loaded private RSA key file used by a gRPC server pseudo-Node.
bytes grpc_tls_private_key = 2;
// Loaded PEM encoded X.509 TLS certificate file used by a gRPC server pseudo-Node.
bytes grpc_tls_certificate = 3;
}

// GrpcClientConfiguration describes the configuration of a gRPC client
Expand Down
42 changes: 29 additions & 13 deletions oak/server/rust/oak_loader/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
//!
//! To invoke, run the following command from the root of the repository:
//!
//! ```
//! cargo run --package=oak_loader -- --application=<APP_CONFIG_PATH>
//! ```
//! cargo run --package=oak_loader -- \
//! --application=<APP_CONFIG_PATH> \
//! --grpc-tls-private-key=<PRIVATE_KEY_PATH> \
//! --grpc-tls-certificate=<CERTIFICATE_PATH>

use log::info;
use oak_runtime::{configure_and_run, proto::oak::application::ApplicationConfiguration};
Expand All @@ -35,25 +36,27 @@ use std::{
};
use structopt::StructOpt;

use oak_runtime::proto::oak::application::node_configuration::ConfigType::GrpcServerConfig;

#[derive(StructOpt, Clone)]
#[structopt(about = "Oak Loader")]
pub struct Opt {
#[structopt(long, help = "Application configuration file")]
application: String,
// TODO(#806): Make arguments non-optional once TLS support is enabled.
#[structopt(long, help = "Path to the PEM-encoded CA root certificate")]
ca_cert: Option<String>,
#[structopt(long, help = "Path to the private key")]
private_key: Option<String>,
#[structopt(long, help = "Path to the PEM-encoded certificate chain")]
cert_chain: Option<String>,
#[structopt(long, help = "Private RSA key file used by gRPC server pseudo-Nodes")]
grpc_tls_private_key: String,
#[structopt(
long,
help = "PEM encoded X.509 TLS certificate file used by gRPC server pseudo-Nodes"
)]
grpc_tls_certificate: String,
#[structopt(
long,
default_value = "3030",
help = "Metrics server port number. Defaults to 3030."
help = "Metrics server port number (the default value is 3030)"
)]
metrics_port: u16,
#[structopt(long, help = "Starts the Runtime without a metrics server.")]
#[structopt(long, help = "Starts the Runtime without a metrics server")]
no_metrics: bool,
#[structopt(
long,
Expand All @@ -78,8 +81,21 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
simple_logger::init().expect("failed to initialize logger");
let opt = Opt::from_args();

// Load application configuration.
let app_config_data = read_file(&opt.application)?;
let app_config = ApplicationConfiguration::decode(&app_config_data[..])?;
let mut app_config = ApplicationConfiguration::decode(app_config_data.as_ref())?;

// Assign a TLS identity to all gRPC server nodes in the application configuration.
let grpc_tls_private_key = read_file(&opt.grpc_tls_private_key)?;
let grpc_tls_certificate = read_file(&opt.grpc_tls_certificate)?;
for node in &mut app_config.node_configs {
if let Some(GrpcServerConfig(ref mut grpc_server_config)) = node.config_type {
grpc_server_config.grpc_tls_private_key = grpc_tls_private_key.clone();
grpc_server_config.grpc_tls_certificate = grpc_tls_certificate.clone();
}
}

// Create Runtime config.
let runtime_config = oak_runtime::RuntimeConfiguration {
metrics_port: if opt.no_metrics {
None
Expand Down
2 changes: 1 addition & 1 deletion oak/server/rust/oak_runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ prost = "*"
prost-types = "*"
rand = "*"
regex = { version = "1", optional = true }
tokio = { version = "*", features = ["rt-core", "macros"] }
tokio = { version = "*", features = ["io-driver", "rt-core", "macros"] }
# Using an old version that is supported by `cargo-raze`:
# https://github.com/google/cargo-raze/issues/41#issuecomment-592274128
tonic = { version = "=0.1.1", features = ["tls"] }
Expand Down
33 changes: 17 additions & 16 deletions oak/server/rust/oak_runtime/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,19 @@
// limitations under the License.
//

use crate::proto::oak::application::{
node_configuration::ConfigType, ApplicationConfiguration, GrpcServerConfiguration,
LogConfiguration, NodeConfiguration, WebAssemblyConfiguration,
};
use itertools::Itertools;
use std::{collections::HashMap, net::AddrParseError, sync::Arc};

use log::{error, warn};

use oak_abi::OakStatus;
use std::{collections::HashMap, sync::Arc};
use tonic::transport::Identity;

use crate::{
node,
node::{check_port, load_wasm},
node::load_wasm,
proto::oak::application::{
node_configuration::ConfigType, ApplicationConfiguration, GrpcServerConfiguration,
LogConfiguration, NodeConfiguration, WebAssemblyConfiguration,
},
runtime,
runtime::{Handle, Runtime},
};
Expand Down Expand Up @@ -91,18 +90,20 @@ pub fn from_protobuf(
return Err(OakStatus::ErrInvalidArgs);
}
Some(ConfigType::LogConfig(_)) => node::Configuration::LogNode,
Some(ConfigType::GrpcServerConfig(GrpcServerConfiguration { address })) => address
.parse()
.map_err(|error: AddrParseError| error.into())
.and_then(|address| check_port(&address).map(|_| address))
.map(|address| node::Configuration::GrpcServerNode { address })
.map_err(|error| {
Some(ConfigType::GrpcServerConfig(GrpcServerConfiguration {
address,
grpc_tls_private_key,
grpc_tls_certificate,
})) => node::Configuration::GrpcServerNode {
address: address.parse().map_err(|error| {
error!("Incorrect gRPC server address: {:?}", error);
OakStatus::ErrInvalidArgs
})?,
tls_identity: Identity::from_pem(grpc_tls_certificate, grpc_tls_private_key),
},
Some(ConfigType::WasmConfig(WebAssemblyConfiguration { module_bytes, .. })) => {
load_wasm(&module_bytes).map_err(|e| {
error!("Error loading Wasm module: {}", e);
load_wasm(&module_bytes).map_err(|error| {
error!("Error loading Wasm module: {}", error);
OakStatus::ErrInvalidArgs
})?
}
Expand Down
Loading

0 comments on commit 1bda917

Please sign in to comment.