diff --git a/Cargo.lock b/Cargo.lock index 9541a6d1e83..61e8f2a39de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2175,7 +2175,6 @@ dependencies = [ "anyhow", "async-stream", "async-trait", - "oak_attestation", "oak_crypto", "oak_grpc_utils", "prost", @@ -2197,7 +2196,6 @@ dependencies = [ "futures-util", "nix", "oak_attestation", - "oak_crypto", "oak_dice", "oak_grpc_utils", "p256", diff --git a/oak_containers/README.md b/oak_containers/README.md deleted file mode 100644 index 271d7e3384e..00000000000 --- a/oak_containers/README.md +++ /dev/null @@ -1,5 +0,0 @@ - - - -

Project Oak Containers Logo

- diff --git a/oak_containers/proto/interfaces.proto b/oak_containers/proto/interfaces.proto index 35a0ea19f81..4cde02521d0 100644 --- a/oak_containers/proto/interfaces.proto +++ b/oak_containers/proto/interfaces.proto @@ -16,65 +16,12 @@ syntax = "proto3"; -package oak.containers; - -import "google/protobuf/empty.proto"; -import "oak_crypto/proto/v1/crypto.proto"; -import "proto/attestation/endorsement.proto"; -import "proto/attestation/evidence.proto"; -import "proto/session/messages.proto"; - -// As images can be large (hundreds of megabytes), the launcher chunks up the response into smaller -// pieces to respect proto/gRPC limits. The image needs to be reassembled in the stage1 or the -// orchestrator. -message GetImageResponse { - bytes image_chunk = 1; -} - -message GetApplicationConfigResponse { - // Arbitrary config that the container can retrieve from the orchestrator. - // Included in the attestation measurements conducted by the orchestrator. - bytes config = 1; -} - -message SendAttestationEvidenceRequest { - oak.session.v1.AttestationEvidence evidence = 1 [deprecated = true]; - oak.attestation.v1.Evidence dice_evidence = 2; -} - -// Defines the service exposed by the launcher, that can be invoked by the stage1 and the -// orchestrator. -service Launcher { - // Provides stage1 with the Oak system image (which contains the Linux distribution and the - // orchestrator binary). - rpc GetOakSystemImage(google.protobuf.Empty) returns (stream GetImageResponse) {} +// TODO(#4392): Remove this file once the migration is complete. +// This file is deprecated. The relevant functionality is available in the +// publicly imported protos instead. Do not add new dependencies on this file. - // Provides orchestrator with the trusted container image. - rpc GetContainerBundle(google.protobuf.Empty) returns (stream GetImageResponse) {} - - // This method is used by the orchestrator to load and measure the trusted - // application config. The orchestrator will later, separately expose this - // config to the application. - rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {} - - // Sends Attestation Evidence containing the Attestation Report with corresponding measurements - // and public keys to the Launcher. - // This API is called exactly once after the Attestation Evidence is generated. Calling this API - // a second time will result in an error. - rpc SendAttestationEvidence(SendAttestationEvidenceRequest) returns (google.protobuf.Empty) {} - - // Notifies the launcher that the trusted app is ready to serve requests and listening on the - // pre-arranged port (8080). - rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {} -} - -// Defines the service exposed by the orchestrator, that can be invoked by the application. -service Orchestrator { - // Exposes the previously loaded trusted application config to the application, - // which may choose to retrieve it. - rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {} +package oak.containers; - // Notifies the orchestrator that the trusted app is ready to serve requests and listening on the - // pre-arranged port (8080). - rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {} -} +import public "proto/containers/common.proto"; +import public "proto/containers/launcher.proto"; +import public "proto/containers/application_interfaces.proto"; diff --git a/oak_containers_launcher/build.rs b/oak_containers_launcher/build.rs index 6ab1f018814..75643f832c5 100644 --- a/oak_containers_launcher/build.rs +++ b/oak_containers_launcher/build.rs @@ -19,7 +19,7 @@ fn main() -> Result<(), Box> { // Generate gRPC code for connecting to the launcher. generate_grpc_code( &[ - "../oak_containers/proto/interfaces.proto", + "../proto/containers/launcher.proto", "../oak_crypto/proto/v1/crypto.proto", "../proto/key_provisioning/key_provisioning.proto", "../proto/containers/hostlib_key_provisioning.proto", diff --git a/oak_containers_launcher/src/lib.rs b/oak_containers_launcher/src/lib.rs index 84b0f5431b1..f85cb0a8f85 100644 --- a/oak_containers_launcher/src/lib.rs +++ b/oak_containers_launcher/src/lib.rs @@ -16,8 +16,6 @@ pub mod proto { pub mod oak { pub mod containers { - #![allow(clippy::return_self_not_must_use)] - tonic::include_proto!("oak.containers"); pub mod v1 { #![allow(clippy::return_self_not_must_use)] tonic::include_proto!("oak.containers.v1"); diff --git a/oak_containers_launcher/src/server.rs b/oak_containers_launcher/src/server.rs index 2ff49e1b51b..d0871619fbf 100644 --- a/oak_containers_launcher/src/server.rs +++ b/oak_containers_launcher/src/server.rs @@ -43,15 +43,11 @@ use tokio_stream::wrappers::TcpListenerStream; use tonic::{transport::Server, Request, Response, Status}; use crate::proto::oak::{ - containers::{ + containers::v1::{ + hostlib_key_provisioning_server::{HostlibKeyProvisioning, HostlibKeyProvisioningServer}, launcher_server::{Launcher, LauncherServer}, - v1::{ - hostlib_key_provisioning_server::{ - HostlibKeyProvisioning, HostlibKeyProvisioningServer, - }, - GetGroupKeysResponse, GetKeyProvisioningRoleResponse, KeyProvisioningRole, - }, - GetApplicationConfigResponse, GetImageResponse, SendAttestationEvidenceRequest, + GetApplicationConfigResponse, GetGroupKeysResponse, GetImageResponse, + GetKeyProvisioningRoleResponse, KeyProvisioningRole, SendAttestationEvidenceRequest, }, session::v1::AttestationEvidence, }; diff --git a/oak_containers_orchestrator/build.rs b/oak_containers_orchestrator/build.rs index 888e1c210e4..a1d7c579f95 100644 --- a/oak_containers_orchestrator/build.rs +++ b/oak_containers_orchestrator/build.rs @@ -19,9 +19,9 @@ fn main() -> Result<(), Box> { // Generate gRPC code for Orchestrator services. generate_grpc_code( &[ - "../oak_containers/proto/interfaces.proto", "../proto/key_provisioning/key_provisioning.proto", - "../proto/containers/orchestrator_crypto.proto", + "../proto/containers/application_interfaces.proto", + "../proto/containers/launcher.proto", "../proto/containers/hostlib_key_provisioning.proto", "../proto/session/messages.proto", ], diff --git a/oak_containers_orchestrator/src/ipc_server.rs b/oak_containers_orchestrator/src/ipc_server.rs index a37dbdab918..ff2222bb9a1 100644 --- a/oak_containers_orchestrator/src/ipc_server.rs +++ b/oak_containers_orchestrator/src/ipc_server.rs @@ -24,9 +24,9 @@ use tonic::{transport::Server, Request, Response}; use crate::{ crypto::{CryptoService, KeyStore}, launcher_client::LauncherClient, - proto::oak::containers::{ + proto::oak::containers::v1::{ + orchestrator_crypto_server::OrchestratorCryptoServer, orchestrator_server::{Orchestrator, OrchestratorServer}, - v1::orchestrator_crypto_server::OrchestratorCryptoServer, GetApplicationConfigResponse, }, }; diff --git a/oak_containers_orchestrator/src/launcher_client.rs b/oak_containers_orchestrator/src/launcher_client.rs index 6eb26ad1319..9cf85974e79 100644 --- a/oak_containers_orchestrator/src/launcher_client.rs +++ b/oak_containers_orchestrator/src/launcher_client.rs @@ -19,9 +19,9 @@ use tonic::transport::Channel; use crate::proto::oak::{ attestation::v1::Evidence, - containers::{ - launcher_client::LauncherClient as GrpcLauncherClient, - v1::{hostlib_key_provisioning_client::HostlibKeyProvisioningClient, KeyProvisioningRole}, + containers::v1::{ + hostlib_key_provisioning_client::HostlibKeyProvisioningClient, + launcher_client::LauncherClient as GrpcLauncherClient, KeyProvisioningRole, SendAttestationEvidenceRequest, }, key_provisioning::v1::GroupKeys, diff --git a/oak_containers_orchestrator/src/lib.rs b/oak_containers_orchestrator/src/lib.rs index 90a5bd59fa0..82e358237c0 100644 --- a/oak_containers_orchestrator/src/lib.rs +++ b/oak_containers_orchestrator/src/lib.rs @@ -16,8 +16,6 @@ pub mod proto { pub mod oak { pub mod containers { - #![allow(clippy::return_self_not_must_use)] - tonic::include_proto!("oak.containers"); pub mod v1 { #![allow(clippy::return_self_not_must_use)] tonic::include_proto!("oak.containers.v1"); diff --git a/oak_containers_sdk/Cargo.toml b/oak_containers_sdk/Cargo.toml index 0824a8b39c5..3d033853178 100644 --- a/oak_containers_sdk/Cargo.toml +++ b/oak_containers_sdk/Cargo.toml @@ -11,7 +11,6 @@ oak_grpc_utils = { workspace = true } [dependencies] anyhow = "*" async-trait = { version = "*", default-features = false } -oak_attestation = { workspace = true } oak_crypto = { workspace = true } prost = "*" prost-types = "*" diff --git a/oak_containers_sdk/build.rs b/oak_containers_sdk/build.rs index e8aa0df1408..5ecc31803a0 100644 --- a/oak_containers_sdk/build.rs +++ b/oak_containers_sdk/build.rs @@ -19,10 +19,9 @@ fn main() -> Result<(), Box> { // Generate gRPC code for connecting to the Orchestrator. generate_grpc_code( &[ - "../oak_containers/proto/interfaces.proto", "../oak_crypto/proto/v1/crypto.proto", "../proto/session/messages.proto", - "../proto/containers/orchestrator_crypto.proto", + "../proto/containers/application_interfaces.proto", ], "..", CodegenOptions { diff --git a/oak_containers_sdk/src/lib.rs b/oak_containers_sdk/src/lib.rs index 6fdc69374d6..9252824b865 100644 --- a/oak_containers_sdk/src/lib.rs +++ b/oak_containers_sdk/src/lib.rs @@ -16,13 +16,11 @@ mod proto { pub mod oak { pub mod containers { - tonic::include_proto!("oak.containers"); pub mod v1 { #![allow(clippy::return_self_not_must_use)] tonic::include_proto!("oak.containers.v1"); } } - pub use oak_attestation::proto::oak::{attestation, session}; pub use oak_crypto::proto::oak::crypto; } } diff --git a/oak_containers_sdk/src/orchestrator_client.rs b/oak_containers_sdk/src/orchestrator_client.rs index dfd91f39d1d..a3a785b9d7a 100644 --- a/oak_containers_sdk/src/orchestrator_client.rs +++ b/oak_containers_sdk/src/orchestrator_client.rs @@ -17,7 +17,7 @@ use anyhow::{Context, Result}; use tonic::transport::{Endpoint, Uri}; use tower::service_fn; -use crate::proto::oak::containers::orchestrator_client::OrchestratorClient as GrpcOrchestratorClient; +use crate::proto::oak::containers::v1::orchestrator_client::OrchestratorClient as GrpcOrchestratorClient; // Unix Domain Sockets do not use URIs, hence this URI will never be used. // It is defined purely since in order to create a channel, since a URI has to diff --git a/oak_containers_stage1/Cargo.toml b/oak_containers_stage1/Cargo.toml index 1acc045a2cb..1778412b06b 100644 --- a/oak_containers_stage1/Cargo.toml +++ b/oak_containers_stage1/Cargo.toml @@ -15,7 +15,6 @@ clap = { version = "*", features = ["derive"] } coset = { version = "*", features = ["std"] } futures-util = "*" oak_attestation = { workspace = true } -oak_crypto = { workspace = true } oak_dice = { workspace = true } nix = { version = "*", features = ["mman"] } p256 = { version = "*" } diff --git a/oak_containers_stage1/build.rs b/oak_containers_stage1/build.rs index db121450dc6..f1bbabe20d1 100644 --- a/oak_containers_stage1/build.rs +++ b/oak_containers_stage1/build.rs @@ -20,9 +20,9 @@ fn main() -> Result<(), Box> { // Generate gRPC code for loading the system image. generate_grpc_code( &[ - "../oak_containers/proto/interfaces.proto", "../oak_crypto/proto/v1/crypto.proto", "../proto/session/messages.proto", + "../proto/containers/launcher.proto", ], "..", CodegenOptions { diff --git a/oak_containers_stage1/src/client.rs b/oak_containers_stage1/src/client.rs index fdebe741a1d..3ed9486d00f 100644 --- a/oak_containers_stage1/src/client.rs +++ b/oak_containers_stage1/src/client.rs @@ -17,14 +17,17 @@ mod proto { pub mod oak { pub mod containers { - tonic::include_proto!("oak.containers"); + pub mod v1 { + #![allow(clippy::return_self_not_must_use)] + tonic::include_proto!("oak.containers.v1"); + } } pub use oak_attestation::proto::oak::{attestation, session}; } } use anyhow::{Context, Result}; -use proto::oak::containers::launcher_client::LauncherClient as GrpcLauncherClient; +use proto::oak::containers::v1::launcher_client::LauncherClient as GrpcLauncherClient; use tonic::transport::{Channel, Uri}; pub struct LauncherClient { diff --git a/oak_functions_containers_app/build.rs b/oak_functions_containers_app/build.rs index 955a9e2cbe9..4dd125fb5af 100644 --- a/oak_functions_containers_app/build.rs +++ b/oak_functions_containers_app/build.rs @@ -38,7 +38,8 @@ fn main() -> Result<(), Box> { generate_grpc_code( &[ - "../oak_containers/proto/interfaces.proto", + "../oak_crypto/proto/v1/crypto.proto", + "../proto/containers/application_interfaces.proto", "../proto/session/messages.proto", ], "..", diff --git a/oak_functions_containers_app/src/lib.rs b/oak_functions_containers_app/src/lib.rs index c34f0f549af..2ba52fa24cd 100644 --- a/oak_functions_containers_app/src/lib.rs +++ b/oak_functions_containers_app/src/lib.rs @@ -53,8 +53,10 @@ pub mod proto { tonic::include_proto!("oak.functions"); } pub mod containers { - #![allow(clippy::return_self_not_must_use)] - tonic::include_proto!("oak.containers"); + pub mod v1 { + #![allow(clippy::return_self_not_must_use)] + tonic::include_proto!("oak.containers.v1"); + } } pub use oak_attestation::proto::oak::{attestation, session}; pub use oak_crypto::proto::oak::crypto; diff --git a/proto/containers/BUILD b/proto/containers/BUILD index 10b7f99bd3c..c03bc5c229f 100644 --- a/proto/containers/BUILD +++ b/proto/containers/BUILD @@ -16,6 +16,7 @@ load("@bazel_skylib//rules:build_test.bzl", "build_test") load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library") +load("@com_github_grpc_grpc//bazel:python_rules.bzl", "py_grpc_library", "py_proto_library") load("@rules_cc//cc:defs.bzl", "cc_proto_library") load("@rules_proto//proto:defs.bzl", "proto_library") @@ -25,10 +26,50 @@ package( ) proto_library( - name = "orchestrator_crypto_proto", - srcs = ["orchestrator_crypto.proto"], + name = "common_proto", + srcs = ["common.proto"], +) + +proto_library( + name = "application_interfaces_proto", + srcs = ["application_interfaces.proto"], deps = [ + ":common_proto", "//oak_crypto/proto/v1:crypto_proto", + "//oak_remote_attestation/proto/v1:messages_proto", + "@com_google_protobuf//:empty_proto", + ], +) + +cc_proto_library( + name = "application_interfaces_cc_proto", + deps = [":application_interfaces_proto"], +) + +cc_grpc_library( + name = "application_interfaces_cc_grpc", + srcs = [":application_interfaces_proto"], + grpc_only = True, + generate_mocks = True, + deps = [":application_interfaces_proto"], +) + +py_proto_library( + name = "application_interfaces_py_proto", + deps = [":application_interfaces_proto"], +) + +py_grpc_library( + name = "application_interfaces_py_grpc", + srcs = [":application_interfaces_proto"], + deps = [":application_interfaces_py_proto"], +) + +proto_library( + name = "launcher_proto", + srcs = ["launcher.proto"], + deps = [ + ":common_proto", ], ) @@ -52,10 +93,20 @@ proto_library( ], ) +# TODO(#4392): Remove once the migration is complete. +proto_library( + name = "orchestrator_crypto_proto", + srcs = ["orchestrator_crypto.proto"], + deps = [ + "//oak_crypto/proto/v1:crypto_proto", + ], +) + build_test( name = "build_test", targets = [ ":hostlib_key_provisioning_proto", - ":orchestrator_crypto_proto", + ":application_interfaces_proto", + ":launcher_proto", ], ) diff --git a/proto/containers/application_interfaces.proto b/proto/containers/application_interfaces.proto new file mode 100644 index 00000000000..fdfae9e396b --- /dev/null +++ b/proto/containers/application_interfaces.proto @@ -0,0 +1,74 @@ +// +// Copyright 2023 The Project Oak Authors +// +// 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. +// + +// Interfaces that may be invoked by the application + +syntax = "proto3"; + +package oak.containers.v1; + +import "oak_crypto/proto/v1/crypto.proto"; +import "google/protobuf/empty.proto"; +import "proto/containers/common.proto"; + +// Defines the service exposed by the orchestrator, that can be invoked by the application. +service Orchestrator { + // Exposes the previously loaded trusted application config to the application, + // which may choose to retrieve it. + rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {} + + // Notifies the orchestrator that the trusted app is ready to serve requests and listening on the + // pre-arranged port (8080). + rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {} +} + +// Choice between a key generated by the enclave instance and the key distributed to the enclave +// group with Key Provisioning. +enum KeyOrigin { + KEY_ORIGIN_UNSPECIFIED = 0; + INSTANCE = 1; + GROUP = 2; +} + +message DeriveSessionKeysRequest { + KeyOrigin key_origin = 1; + // Ephemeral Diffie-Hellman client public key that is needed to derive session keys. + bytes serialized_encapsulated_public_key = 2; +} + +message DeriveSessionKeysResponse { + // Session keys for decrypting client requests and encrypting enclave responses. + oak.crypto.v1.SessionKeys session_keys = 1; +} + +message SignRequest { + KeyOrigin key_origin = 1; + bytes message = 2; +} + +message SignResponse { + oak.crypto.v1.Signature signature = 1; +} + +// RPC service that is exposed to an enclave application and allows it to: +// - Encrypt/decrypt messages +// - Sign arbitrary data +service OrchestratorCrypto { + // Derives session keys for decrypting client requests and encrypting enclave responses. + rpc DeriveSessionKeys(DeriveSessionKeysRequest) returns (DeriveSessionKeysResponse) {} + // Signs the provided message using the hardware rooted signing key. + rpc Sign(SignRequest) returns (SignResponse) {} +} diff --git a/oak_containers_syslogd/build.rs b/proto/containers/common.proto similarity index 58% rename from oak_containers_syslogd/build.rs rename to proto/containers/common.proto index b24dee1632e..9a688abe789 100644 --- a/oak_containers_syslogd/build.rs +++ b/proto/containers/common.proto @@ -14,19 +14,12 @@ // limitations under the License. // -use oak_grpc_utils::{generate_grpc_code, CodegenOptions}; +syntax = "proto3"; -fn main() -> Result<(), Box> { - // Generate gRPC code for connecting to the launcher. - generate_grpc_code( - &[ - "../oak_containers/proto/interfaces.proto", - "../oak_crypto/proto/v1/crypto.proto", - "../proto/session/messages.proto", - ], - "..", - CodegenOptions::default(), - )?; +package oak.containers.v1; - Ok(()) +message GetApplicationConfigResponse { + // Arbitrary config that the container can retrieve from the orchestrator. + // Included in the attestation measurements conducted by the orchestrator. + bytes config = 1; } diff --git a/proto/containers/launcher.proto b/proto/containers/launcher.proto new file mode 100644 index 00000000000..c64192f8efb --- /dev/null +++ b/proto/containers/launcher.proto @@ -0,0 +1,62 @@ +// +// Copyright 2023 The Project Oak Authors +// +// 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. +// + +syntax = "proto3"; + +package oak.containers.v1; + +import "google/protobuf/empty.proto"; +import "proto/attestation/evidence.proto"; +import "proto/session/messages.proto"; +import "proto/containers/common.proto"; + +// As images can be large (hundreds of megabytes), the launcher chunks up the response into smaller +// pieces to respect proto/gRPC limits. The image needs to be reassembled in the stage1 or the +// orchestrator. +message GetImageResponse { + bytes image_chunk = 1; +} + +message SendAttestationEvidenceRequest { + oak.session.v1.AttestationEvidence evidence = 1 [deprecated = true]; + oak.attestation.v1.Evidence dice_evidence = 2; +} + +// Defines the service exposed by the launcher, that can be invoked by the stage1 and the +// orchestrator. +service Launcher { + // Provides stage1 with the Oak system image (which contains the Linux distribution and the + // orchestrator binary). + rpc GetOakSystemImage(google.protobuf.Empty) returns (stream GetImageResponse) {} + + // Provides orchestrator with the trusted container image. + rpc GetContainerBundle(google.protobuf.Empty) returns (stream GetImageResponse) {} + + // This method is used by the orchestrator to load and measure the trusted + // application config. The orchestrator will later, separately expose this + // config to the application. + rpc GetApplicationConfig(google.protobuf.Empty) returns (GetApplicationConfigResponse) {} + + // Sends Attestation Evidence containing the Attestation Report with corresponding measurements + // and public keys to the Launcher. + // This API is called exactly once after the Attestation Evidence is generated. Calling this API + // a second time will result in an error. + rpc SendAttestationEvidence(SendAttestationEvidenceRequest) returns (google.protobuf.Empty) {} + + // Notifies the launcher that the trusted app is ready to serve requests and listening on the + // pre-arranged port (8080). + rpc NotifyAppReady(google.protobuf.Empty) returns (google.protobuf.Empty) {} +} diff --git a/proto/containers/orchestrator_crypto.proto b/proto/containers/orchestrator_crypto.proto index 3e881f56f35..1386b4296b3 100644 --- a/proto/containers/orchestrator_crypto.proto +++ b/proto/containers/orchestrator_crypto.proto @@ -16,6 +16,11 @@ syntax = "proto3"; +// TODO(#4392): Remove this file once the migration is complete. +// This file is deprecated, the relevant functionality is available in +// `proto/containers/application_interfaces.proto`. DO NOT MODIFY THIS FILE, DO NOT ADD NEW +// DEPENDENCIES ON IT. + package oak.containers.v1; import "oak_crypto/proto/v1/crypto.proto";