Skip to content

Commit

Permalink
Create Sync GRPC Session transports, add standalone C++ noise test
Browse files Browse the repository at this point in the history
Change-Id: I6609c767827f88a89339bb0d3234c2622bec564b
  • Loading branch information
jblebrun committed Dec 13, 2024
1 parent 9cd5068 commit 4312462
Show file tree
Hide file tree
Showing 9 changed files with 301 additions and 15 deletions.
7 changes: 7 additions & 0 deletions cc/containers/hello_world_enclave_app/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ cc_library(
"//cc/containers/sdk:orchestrator_client",
"//cc/crypto:common",
"//cc/crypto:server_encryptor",
"//cc/oak_session:oak_session_bindings",
"//cc/oak_session/channel",
"//cc/server:session_server",
"//cc/transport:grpc_sync_session_server_transport",
"//oak_containers/examples/hello_world/proto:hello_world_cc_grpc",
"//oak_containers/examples/hello_world/proto:hello_world_cc_proto",
"//proto/crypto:crypto_cc_proto",
Expand Down Expand Up @@ -63,8 +67,11 @@ cc_test(
":app_service",
"//cc/attestation/verification:insecure_attestation_verifier",
"//cc/client",
"//cc/client:session_client",
"//cc/containers/sdk/standalone:oak_standalone",
"//cc/oak_session:client_session",
"//cc/transport:grpc_streaming_transport",
"//cc/transport:grpc_sync_session_client_transport",
"//oak_containers/examples/hello_world/proto:hello_world_cc_grpc",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/status",
Expand Down
45 changes: 36 additions & 9 deletions cc/containers/hello_world_enclave_app/app_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "cc/containers/sdk/oak_session.h"
#include "cc/crypto/common.h"
#include "cc/crypto/server_encryptor.h"
#include "cc/transport/grpc_sync_session_server_transport.h"
#include "grpcpp/server_context.h"
#include "grpcpp/support/status.h"
#include "oak_containers/examples/hello_world/proto/hello_world.grpc.pb.h"
Expand All @@ -34,22 +35,48 @@ namespace oak::containers::hello_world_enclave_app {

using ::oak::session::v1::RequestWrapper;
using ::oak::session::v1::ResponseWrapper;
using ::oak::session::v1::SessionRequest;
using ::oak::session::v1::SessionResponse;

grpc::Status FromAbsl(const absl::Status& status) {
return grpc::Status(static_cast<grpc::StatusCode>(status.code()),
std::string(status.message()));
}

std::string EnclaveApplicationImpl::HandleRequest(absl::string_view request) {
return absl::StrCat("Hello from the enclave, ", request,
"! Btw, the app has a config with a length of ",
application_config_.size(), " bytes.");
}

grpc::Status EnclaveApplicationImpl::LegacySession(
grpc::ServerContext* context,
grpc::ServerReaderWriter<ResponseWrapper, RequestWrapper>* stream) {
absl::string_view application_config = application_config_;
absl::Status status = oak_session_context_.OakSession(
stream,
[&application_config](
absl::string_view request) -> absl::StatusOr<std::string> {
return absl::StrCat("Hello from the enclave, ", request,
"! Btw, the app has a config with a length of ",
application_config.size(), " bytes.");
stream, [this](absl::string_view request) -> absl::StatusOr<std::string> {
return HandleRequest(request);
});

return grpc::Status(static_cast<grpc::StatusCode>(status.code()),
std::string(status.message()));
return FromAbsl(status);
}

grpc::Status EnclaveApplicationImpl::OakSession(
grpc::ServerContext* context,
grpc::ServerReaderWriter<SessionResponse, SessionRequest>* stream) {
auto channel = session_server_.NewChannel(
std::make_unique<transport::GrpcSyncSessionServerTransport>(stream));
while (true) {
absl::StatusOr<std::string> request = (*channel)->Receive();
if (!request.ok()) {
return FromAbsl(request.status());
}
std::string response = HandleRequest(*request);
absl::Status send_result = (*channel)->Send(response);
if (!send_result.ok()) {
return FromAbsl(send_result);
}
}
return grpc::Status();
}

} // namespace oak::containers::hello_world_enclave_app
9 changes: 9 additions & 0 deletions cc/containers/hello_world_enclave_app/app_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "cc/containers/sdk/encryption_key_handle.h"
#include "cc/containers/sdk/oak_session.h"
#include "cc/containers/sdk/orchestrator_client.h"
#include "cc/server/session_server.h"
#include "grpcpp/server_context.h"
#include "grpcpp/support/status.h"
#include "oak_containers/examples/hello_world/proto/hello_world.grpc.pb.h"
Expand All @@ -46,7 +47,15 @@ class EnclaveApplicationImpl
oak::session::v1::RequestWrapper>* stream)
override;

grpc::Status OakSession(
grpc::ServerContext* context,
grpc::ServerReaderWriter<oak::session::v1::SessionResponse,
oak::session::v1::SessionRequest>* stream)
override;

private:
server::OakSessionServer session_server_;
std::string HandleRequest(absl::string_view request);
oak::containers::sdk::OakSessionContext oak_session_context_;
const oak::session::v1::EndorsedEvidence endorsed_evidence_;
const std::string application_config_;
Expand Down
38 changes: 33 additions & 5 deletions cc/containers/hello_world_enclave_app/standalone_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,14 @@
#include "absl/status/status_matchers.h"
#include "cc/attestation/verification/insecure_attestation_verifier.h"
#include "cc/client/client.h"
#include "cc/client/session_client.h"
#include "cc/containers/hello_world_enclave_app/app_service.h"
#include "cc/containers/sdk/standalone/oak_standalone.h"
#include "cc/oak_session/channel/oak_session_channel.h"
#include "cc/oak_session/client_session.h"
#include "cc/transport/grpc_streaming_transport.h"
#include "cc/transport/grpc_sync_session_client_transport.h"
#include "gmock/gmock.h"
#include "grpcpp/server.h"
#include "grpcpp/server_builder.h"
#include "gtest/gtest.h"
Expand All @@ -33,6 +38,7 @@ namespace oak::containers::sdk::standalone {
namespace {

using ::absl_testing::IsOk;
using ::absl_testing::IsOkAndHolds;
using ::oak::attestation::v1::AttestationResults;
using ::oak::attestation::verification::InsecureAttestationVerifier;
using ::oak::client::OakClient;
Expand All @@ -41,9 +47,13 @@ using ::oak::containers::hello_world_enclave_app::EnclaveApplicationImpl;
using ::oak::crypto::EncryptionKeyProvider;
using ::oak::crypto::KeyPair;
using ::oak::session::v1::EndorsedEvidence;
using ::oak::session::v1::SessionRequest;
using ::oak::session::v1::SessionResponse;
using ::oak::transport::GrpcStreamingTransport;
using ::testing::Eq;

constexpr absl::string_view kApplicationConfig = "{}";

class HelloWorldStandaloneTest : public testing::Test {
void SetUp() override {
// Set up our new Keypair and get an EndorsedEvidence from Rust.
Expand All @@ -63,7 +73,7 @@ class HelloWorldStandaloneTest : public testing::Test {
service_ = std::make_unique<EnclaveApplicationImpl>(
OakSessionContext(std::move(*endorsed_evidence),
std::make_unique<EncryptionKeyProvider>(*key_pair)),
"{}");
kApplicationConfig);

grpc::ServerBuilder builder;
builder.AddListeningPort("[::]:8080", grpc::InsecureServerCredentials());
Expand All @@ -86,14 +96,32 @@ TEST_F(HelloWorldStandaloneTest, LegacySessionReturnsResponse) {
std::make_unique<GrpcStreamingTransport>(stub_->LegacySession(&context));
InsecureAttestationVerifier verifier;
auto client = OakClient::Create(std::move(transport), verifier);
ASSERT_TRUE(client.ok());
ASSERT_THAT(client, IsOk());

auto result = (*client)->Invoke("Standalone Test");
ASSERT_TRUE(result.ok());
ASSERT_THAT(result, IsOk());
EXPECT_EQ(*result,
"Hello from the enclave, Standalone Test! Btw, the app has a "
"config with a length of 2 bytes.");
absl::Substitute(
"Hello from the enclave, Standalone Test! Btw, the app has a "
"config with a length of $0 bytes.",
kApplicationConfig.size()));
}

TEST_F(HelloWorldStandaloneTest, OakSessionReturnsResponse) {
client::OakSessionClient session_client;
grpc::ClientContext context;
auto channel = session_client.NewChannel(
std::make_unique<transport::GrpcSyncSessionClientTransport>(
stub_->OakSession(&context)));

ASSERT_THAT((*channel)->Send("Standalone Test"), IsOk());
ASSERT_THAT((*channel)->Receive(),
IsOkAndHolds(absl::Substitute(
"Hello from the enclave, Standalone Test! Btw, the "
"app has a config with a length of $0 bytes.",
kApplicationConfig.size())));
}

} // namespace

} // namespace oak::containers::sdk::standalone
28 changes: 27 additions & 1 deletion cc/transport/BUILD
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# Copyright 2023 The Project Oak Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# 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
#
Expand Down Expand Up @@ -110,3 +110,29 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)

cc_library(
name = "grpc_sync_session_server_transport",
srcs = ["grpc_sync_session_server_transport.cc"],
hdrs = ["grpc_sync_session_server_transport.h"],
deps = [
"//cc/oak_session:server_session",
"//cc/server:session_server",
"@com_github_grpc_grpc//:grpc++",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
],
)

cc_library(
name = "grpc_sync_session_client_transport",
srcs = ["grpc_sync_session_client_transport.cc"],
hdrs = ["grpc_sync_session_client_transport.h"],
deps = [
"//cc/client:session_client",
"//cc/oak_session:client_session",
"@com_github_grpc_grpc//:grpc++",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
],
)
44 changes: 44 additions & 0 deletions cc/transport/grpc_sync_session_client_transport.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2024 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.
*/

#include "cc/transport/grpc_sync_session_client_transport.h"

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "cc/oak_session/client_session.h"
#include "grpcpp/support/sync_stream.h"
#include "proto/session/session.pb.h"

namespace oak::transport {

absl::Status GrpcSyncSessionClientTransport::Send(
session::v1::SessionRequest&& message) {
if (!stream_->Write(message)) {
return absl::AbortedError("Failed to write outgoing message.");
}
return absl::OkStatus();
}

absl::StatusOr<session::v1::SessionResponse>
GrpcSyncSessionClientTransport::Receive() {
session::v1::SessionResponse response;
if (!stream_->Read(&response)) {
return absl::AbortedError("Failed to readin incoming message.");
}
return response;
}

}; // namespace oak::transport
52 changes: 52 additions & 0 deletions cc/transport/grpc_sync_session_client_transport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2024 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.
*/

#ifndef CC_TRANSPORT_GRPC_SYNC_CLIENT_SESSION_TRANSPORT_H_
#define CC_TRANSPORT_GRPC_SYNC_CLIENT_SESSION_TRANSPORT_H_

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "cc/client/session_client.h"
#include "cc/oak_session/channel/oak_session_channel.h"
#include "cc/oak_session/client_session.h"
#include "grpcpp/support/sync_stream.h"
#include "proto/session/session.pb.h"

namespace oak::transport {

// An implementation of `OakSessionChannel::Transport` for use with
// `OakSessionClient` using the gRPC synchronous streaming interface.
class GrpcSyncSessionClientTransport
: public ::oak::client::OakSessionClient::Channel::Transport {
public:
explicit GrpcSyncSessionClientTransport(
std::unique_ptr<grpc::ClientReaderWriterInterface<
session::v1::SessionRequest, session::v1::SessionResponse>>
stream)
: stream_(std::move(stream)) {}

absl::Status Send(session::v1::SessionRequest&& message) override;
absl::StatusOr<session::v1::SessionResponse> Receive() override;

private:
std::unique_ptr<grpc::ClientReaderWriterInterface<
session::v1::SessionRequest, session::v1::SessionResponse>>
stream_;
};

} // namespace oak::transport

#endif // CC_TRANSPORT_GRPC_SYNC_CLIENT_SESSION_TRANSPORT_H_
43 changes: 43 additions & 0 deletions cc/transport/grpc_sync_session_server_transport.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2024 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.
*/

#include "cc/transport/grpc_sync_session_server_transport.h"

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "cc/oak_session/server_session.h"
#include "proto/session/session.pb.h"

namespace oak::transport {

absl::Status GrpcSyncSessionServerTransport::Send(
session::v1::SessionResponse&& message) {
if (!stream_->Write(message)) {
return absl::AbortedError("Failed to write outgoing message.");
}
return absl::OkStatus();
}

absl::StatusOr<session::v1::SessionRequest>
GrpcSyncSessionServerTransport::Receive() {
session::v1::SessionRequest request;
if (!stream_->Read(&request)) {
return absl::AbortedError("Failed to read incoming message.");
}
return request;
}

} // namespace oak::transport
Loading

0 comments on commit 4312462

Please sign in to comment.