├── .bazelrc
├── AUTHORS
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── WORKSPACE
├── grpc_server
├── BUILD
├── README.md
├── grpc_server_config.proto
├── grpc_server_driver.cc
├── grpc_server_enclave.cc
├── grpc_server_test.cc
├── grpc_server_util.cc
├── grpc_server_util.h
├── translator_client.cc
├── translator_client.h
├── translator_server.proto
├── translator_server_impl.cc
└── translator_server_impl.h
├── hello_world
├── BUILD
├── hello.proto
├── hello_driver.cc
└── hello_enclave.cc
├── java
└── quickstart_client
│ ├── BUILD
│ ├── README.md
│ └── src
│ └── main
│ └── java
│ └── com
│ └── example
│ └── DemoDriver.java
├── quickstart
├── BUILD
├── README.md
├── demo.proto
├── demo_driver.cc
├── demo_enclave.cc
└── solution
│ ├── BUILD
│ ├── demo.proto
│ ├── demo_driver.cc
│ └── demo_enclave.cc
├── redis
├── BUILD
├── README.md
├── redis_enclave_config.cc
└── redis_test.cc
├── remote
├── bouncing_circles
│ ├── BUILD
│ ├── README.md
│ ├── build.sh
│ ├── circle_client.cc
│ ├── circle_client.h
│ ├── circle_enclave.cc
│ ├── circles.proto
│ ├── web_application.cc
│ ├── web_server.cc
│ ├── web_server.h
│ └── web_server_test.cc
├── grpc_server
│ ├── BUILD
│ └── grpc_server_driver.cc
├── provision_server
│ ├── BUILD
│ ├── README.md
│ ├── base64_server_cert
│ ├── base64_server_key
│ └── build.sh
└── quickstart
│ ├── BUILD
│ ├── README.md
│ ├── build.sh
│ ├── demo.proto
│ ├── demo_driver.cc
│ ├── demo_enclave.cc
│ └── demo_enclave_remote_test.cc
├── secure_grpc
├── BUILD
├── README.md
├── acl_isvprodid_2.textproto
├── acl_isvprodid_3.textproto
├── acl_non_debug.textproto
├── attestation_domain.cc
├── attestation_domain.h
├── grpc_client_enclave.cc
├── grpc_client_enclave.h
├── grpc_client_enclave.proto
├── grpc_client_main.cc
├── grpc_client_util.cc
├── grpc_client_util.h
├── grpc_server_config.proto
├── grpc_server_enclave.cc
├── grpc_server_main.cc
├── grpc_server_util.cc
├── grpc_server_util.h
├── secure_grpc_test.cc
├── translator_server_impl.cc
└── translator_server_impl.h
├── sgx_release_enclaves
└── README.md
└── sqlite
└── README.md
/.bazelrc:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2018 Asylo authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | build:asylo --crosstool_top=@com_google_asylo_toolchain//toolchain:crosstool
18 | build:asylo --dynamic_mode=off
19 | build:asylo --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
20 | build:asylo --fission=no
21 | build:asylo --custom_malloc=@com_google_asylo_toolchain//toolchain:malloc
22 | build:asylo --define=grpc_no_ares=true
23 |
24 | build:sgx --config=asylo
25 | build:sgx --define=ASYLO_SGX=1
26 | build:sgx --define=SGX_SIM=0
27 |
28 | build:sgx-sim --config=asylo
29 | build:sgx-sim --define=ASYLO_SGX=1
30 | build:sgx-sim --define=SGX_SIM=1
31 |
32 | # The enclave simulation backend currently makes use of the SGX simulator.
33 | # However, this is subject to change and users of this config should not
34 | # make assumptions about it being related to SGX.
35 | build:enc-sim --config=sgx-sim
36 |
37 | build:asylo-dlopen --config=asylo
38 | build:asylo-dlopen --define=ASYLO_DLOPEN=1
39 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | # This is the list of Asylo's significant contributors.
2 | #
3 | # This does not necessarily list everyone who has contributed code,
4 | # especially since many employees of one corporation may be contributing.
5 | # To see the full list of contributors, see the revision history in
6 | # source control.
7 | Google LLC
8 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project. There are
4 | just a few small guidelines you need to follow.
5 |
6 | ## Contributor License Agreement
7 |
8 | Contributions to this project must be accompanied by a Contributor License
9 | Agreement. You (or your employer) retain the copyright to your contribution,
10 | this simply gives us permission to use and redistribute your contributions as
11 | part of the project. Head over to to see
12 | your current agreements on file or to sign a new one.
13 |
14 | You generally only need to submit a CLA once, so if you've already submitted one
15 | (even if it was for a different project), you probably don't need to do it
16 | again.
17 |
18 | ## Code reviews
19 |
20 | All submissions, including submissions by project members, require review. We
21 | use GitHub pull requests for this purpose. Consult
22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
23 | information on using pull requests.
24 |
--------------------------------------------------------------------------------
/WORKSPACE:
--------------------------------------------------------------------------------
1 | workspace(name = "asylo_examples")
2 |
3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
4 |
5 | # Download and use the Asylo SDK.
6 | http_archive(
7 | name = "com_google_asylo",
8 | sha256 = "21e2798a345d4d508c4f09c4b92c7cdc06a445d8fca4094e3751cde48d1d27c9",
9 | strip_prefix = "asylo-0.6.3",
10 | urls = ["https://github.com/google/asylo/archive/v0.6.3.tar.gz"],
11 | )
12 |
13 | load(
14 | "@com_google_asylo//asylo/bazel:asylo_deps.bzl",
15 | "asylo_deps",
16 | "asylo_testonly_deps",
17 | )
18 |
19 | asylo_deps()
20 |
21 | asylo_testonly_deps()
22 |
23 | # sgx_deps is only needed if @linux_sgx is used.
24 | load("@com_google_asylo//asylo/bazel:sgx_deps.bzl", "sgx_deps")
25 |
26 | sgx_deps()
27 |
28 | # remote_deps is only needed if remote backend is used.
29 | load("@com_google_asylo//asylo/bazel:remote_deps.bzl", "remote_deps")
30 |
31 | remote_deps()
32 |
33 | # grpc_deps is only needed if gRPC is used. Projects using gRPC as an external
34 | # dependency must call both grpc_deps() and grpc_extra_deps().
35 | load("@com_github_grpc_grpc//bazel:grpc_deps.bzl", "grpc_deps")
36 |
37 | grpc_deps()
38 |
39 | load("@com_github_grpc_grpc//bazel:grpc_extra_deps.bzl", "grpc_extra_deps")
40 |
41 | grpc_extra_deps()
42 |
--------------------------------------------------------------------------------
/grpc_server/BUILD:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2018 Asylo authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | load("@com_github_grpc_grpc//bazel:cc_grpc_library.bzl", "cc_grpc_library")
18 | load("@linux_sgx//:sgx_sdk.bzl", "sgx")
19 | load("@rules_cc//cc:defs.bzl", "cc_library", "cc_proto_library")
20 | load("@rules_proto//proto:defs.bzl", "proto_library")
21 | load(
22 | "@com_google_asylo//asylo/bazel:asylo.bzl",
23 | "ASYLO_ALL_BACKEND_TAGS",
24 | "cc_unsigned_enclave",
25 | "debug_sign_enclave",
26 | "enclave_loader",
27 | "enclave_test",
28 | )
29 |
30 | licenses(["notice"]) # Apache v2.0
31 |
32 | # Example demonstrating gRPC in Asylo.
33 |
34 | package(
35 | default_visibility = ["//visibility:public"],
36 | )
37 |
38 | # The generated code for the translator server (and client).
39 | proto_library(
40 | name = "translator_server_proto",
41 | srcs = ["translator_server.proto"],
42 | tags = ASYLO_ALL_BACKEND_TAGS,
43 | )
44 |
45 | cc_proto_library(
46 | name = "translator_server_cc_proto",
47 | tags = ASYLO_ALL_BACKEND_TAGS,
48 | deps = [":translator_server_proto"],
49 | )
50 |
51 | cc_grpc_library(
52 | name = "translator_server",
53 | srcs = [":translator_server_proto"],
54 | grpc_only = True,
55 | tags = ASYLO_ALL_BACKEND_TAGS,
56 | deps = [":translator_server_cc_proto"],
57 | )
58 |
59 | # The implementation of the translation server.
60 | cc_library(
61 | name = "translator_server_impl",
62 | srcs = ["translator_server_impl.cc"],
63 | hdrs = ["translator_server_impl.h"],
64 | tags = ASYLO_ALL_BACKEND_TAGS,
65 | deps = [
66 | ":translator_server",
67 | "@com_github_grpc_grpc//:grpc++",
68 | "@com_google_absl//absl/base:core_headers",
69 | "@com_google_absl//absl/container:flat_hash_map",
70 | "@com_google_absl//absl/strings",
71 | "@com_google_absl//absl/synchronization",
72 | ],
73 | )
74 |
75 | # Contains extensions to enclave protos.
76 | proto_library(
77 | name = "grpc_server_config_proto",
78 | srcs = ["grpc_server_config.proto"],
79 | deps = ["@com_google_asylo//asylo:enclave_proto"],
80 | )
81 |
82 | cc_proto_library(
83 | name = "grpc_server_config_cc_proto",
84 | deps = [":grpc_server_config_proto"],
85 | )
86 |
87 | # The enclave hosting the translation server.
88 | cc_unsigned_enclave(
89 | name = "grpc_server_enclave_unsigned.so",
90 | srcs = ["grpc_server_enclave.cc"],
91 | backends = sgx.backend_labels,
92 | deps = [
93 | ":grpc_server_config_cc_proto",
94 | ":translator_server_impl",
95 | "@com_github_grpc_grpc//:grpc++",
96 | "@com_github_grpc_grpc//:grpc++_reflection",
97 | "@com_google_absl//absl/base:core_headers",
98 | "@com_google_absl//absl/memory",
99 | "@com_google_absl//absl/status",
100 | "@com_google_absl//absl/strings",
101 | "@com_google_absl//absl/synchronization",
102 | "@com_google_absl//absl/time",
103 | "@com_google_asylo//asylo:enclave_runtime",
104 | "@com_google_asylo//asylo/util:status",
105 | ],
106 | )
107 |
108 | debug_sign_enclave(
109 | name = "grpc_server_enclave.so",
110 | backends = sgx.backend_labels,
111 | config = "@com_google_asylo//asylo/grpc/util:grpc_enclave_config",
112 | unsigned = "grpc_server_enclave_unsigned.so",
113 | )
114 |
115 | # The driver for the gRPC server enclave.
116 | enclave_loader(
117 | name = "grpc_server",
118 | srcs = ["grpc_server_driver.cc"],
119 | enclaves = {"enclave": ":grpc_server_enclave.so"},
120 | loader_args = ["--enclave_path='{enclave}'"],
121 | deps = [
122 | ":grpc_server_util",
123 | "@com_google_absl//absl/flags:flag",
124 | "@com_google_absl//absl/flags:parse",
125 | "@com_google_absl//absl/time",
126 | "@com_google_asylo//asylo:enclave_client",
127 | "@com_google_asylo//asylo/util:logging",
128 | "@com_google_asylo//asylo/util:status",
129 | ],
130 | )
131 |
132 | cc_library(
133 | name = "grpc_server_util",
134 | srcs = ["grpc_server_util.cc"],
135 | hdrs = ["grpc_server_util.h"],
136 | deps = [
137 | ":grpc_server_config_cc_proto",
138 | "@com_google_absl//absl/strings",
139 | "@com_google_asylo//asylo:enclave_cc_proto",
140 | "@com_google_asylo//asylo:enclave_client",
141 | "@com_google_asylo//asylo/platform/primitives/sgx:loader_cc_proto",
142 | "@com_google_asylo//asylo/util:status",
143 | "@com_google_protobuf//:protobuf",
144 | ],
145 | )
146 |
147 | # A test of the example using the server enclave.
148 | enclave_test(
149 | name = "grpc_server_test",
150 | srcs = ["grpc_server_test.cc"],
151 | backend_dependent_data = [":grpc_server_host_loader"],
152 | backends = sgx.backend_labels,
153 | enclaves = {"server_enclave": ":grpc_server_enclave.so"},
154 | test_args = [
155 | "--server_enclave_path='{server_enclave}'",
156 | ],
157 | deps = [
158 | ":grpc_server_util",
159 | ":translator_client",
160 | ":translator_server_impl",
161 | "@com_github_grpc_grpc//:grpc++",
162 | "@com_google_absl//absl/base:core_headers",
163 | "@com_google_absl//absl/flags:flag",
164 | "@com_google_absl//absl/memory",
165 | "@com_google_absl//absl/strings",
166 | "@com_google_asylo//asylo:enclave_client",
167 | "@com_google_asylo//asylo/test/util:status_matchers",
168 | "@com_google_asylo//asylo/test/util:test_main",
169 | "@com_google_asylo//asylo/util:path",
170 | "@com_google_asylo//asylo/util:status",
171 | "@com_google_googletest//:gtest",
172 | ],
173 | )
174 |
175 | cc_library(
176 | name = "translator_client",
177 | testonly = 1,
178 | srcs = ["translator_client.cc"],
179 | hdrs = ["translator_client.h"],
180 | deps = [
181 | ":translator_server",
182 | ":translator_server_cc_proto",
183 | "@com_github_grpc_grpc//:grpc",
184 | "@com_github_grpc_grpc//:grpc++",
185 | "@com_google_absl//absl/memory",
186 | "@com_google_absl//absl/status",
187 | "@com_google_absl//absl/strings",
188 | "@com_google_absl//absl/time",
189 | "@com_google_asylo//asylo/util:status",
190 | "@com_google_asylo//asylo/util:status_helpers",
191 | ],
192 | )
193 |
--------------------------------------------------------------------------------
/grpc_server/grpc_server_config.proto:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2018 Asylo authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | syntax = "proto2";
18 |
19 | package examples.grpc_server;
20 |
21 | import "asylo/enclave.proto";
22 |
23 | extend asylo.EnclaveConfig {
24 | // The address that the gRPC server inside the enclave will be hosted on.
25 | // Required.
26 | optional string server_address = 205739939;
27 |
28 | // The port that the gRPC server should listen to. May be 0 to request that
29 | // the server let the operating system choose an unused port.
30 | optional int32 port = 253106740;
31 | }
32 |
33 | extend asylo.EnclaveOutput {
34 | // The Translator server's port.
35 | optional int32 actual_server_port = 285084421;
36 | }
37 |
--------------------------------------------------------------------------------
/grpc_server/grpc_server_driver.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include "absl/flags/flag.h"
23 | #include "absl/flags/parse.h"
24 | #include "absl/time/clock.h"
25 | #include "asylo/enclave_manager.h"
26 | #include "asylo/util/logging.h"
27 | #include "asylo/util/status.h"
28 | #include "asylo/util/statusor.h"
29 | #include "grpc_server/grpc_server_util.h"
30 |
31 | ABSL_FLAG(std::string, enclave_path, "", "Path to enclave to load");
32 |
33 | // By default, let the server run for five minutes.
34 | ABSL_FLAG(int32_t, server_max_lifetime, 300,
35 | "The longest amount of time (in seconds) that the server should be "
36 | "allowed to run");
37 |
38 | // Default value 0 is used to indicate that the system should choose an
39 | // available port.
40 | ABSL_FLAG(int32_t, port, 0, "Port that the server listens to");
41 | ABSL_FLAG(bool, debug, true, "Whether to use a debug enclave");
42 |
43 | int main(int argc, char *argv[]) {
44 | // Parse command-line arguments.
45 | absl::ParseCommandLine(argc, argv);
46 |
47 | std::string enclave_path = absl::GetFlag(FLAGS_enclave_path);
48 | LOG_IF(QFATAL, enclave_path.empty()) << "--enclave_path cannot be empty";
49 |
50 | asylo::Status status =
51 | asylo::EnclaveManager::Configure(asylo::EnclaveManagerOptions());
52 | LOG_IF(QFATAL, !status.ok())
53 | << "Failed to configure EnclaveManager: " << status;
54 |
55 | status = examples::grpc_server::LoadGrpcServerEnclave(
56 | enclave_path, absl::GetFlag(FLAGS_port), absl::GetFlag(FLAGS_debug));
57 | LOG_IF(QFATAL, !status.ok())
58 | << "Loading " << enclave_path << " failed: " << status;
59 |
60 | asylo::StatusOr port_result =
61 | examples::grpc_server::GrpcServerEnclaveGetPort();
62 | LOG_IF(QFATAL, !port_result.ok())
63 | << "Retrieving port failed: " << port_result.status();
64 |
65 | std::cout << "Server started on port " << port_result.value() << std::endl;
66 |
67 | absl::SleepFor(absl::Seconds(absl::GetFlag(FLAGS_server_max_lifetime)));
68 |
69 | status = examples::grpc_server::DestroyGrpcServerEnclave();
70 | LOG_IF(QFATAL, !status.ok())
71 | << "Destroy " << enclave_path << " failed: " << status;
72 |
73 | return 0;
74 | }
75 |
--------------------------------------------------------------------------------
/grpc_server/grpc_server_enclave.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include "absl/base/thread_annotations.h"
23 | #include "absl/status/status.h"
24 | #include "absl/strings/str_cat.h"
25 | #include "absl/synchronization/mutex.h"
26 | #include "absl/synchronization/notification.h"
27 | #include "absl/time/time.h"
28 | #include "asylo/trusted_application.h"
29 | #include "asylo/util/status.h"
30 | #include "asylo/util/status_macros.h"
31 | #include "grpc_server/grpc_server_config.pb.h"
32 | #include "grpc_server/translator_server_impl.h"
33 | #include "include/grpcpp/grpcpp.h"
34 | #include "include/grpcpp/security/server_credentials.h"
35 | #include "include/grpcpp/server.h"
36 | #include "include/grpcpp/server_builder.h"
37 |
38 | namespace examples {
39 | namespace grpc_server {
40 |
41 | // An enclave that runs a TranslatorServerImpl. We override the methods of
42 | // TrustedApplication as follows:
43 | //
44 | // * Initialize starts the gRPC server.
45 | // * Run retrieves the server port.
46 | // * Finalize shuts down the server.
47 | class GrpcServerEnclave final : public asylo::TrustedApplication {
48 | public:
49 | asylo::Status Initialize(const asylo::EnclaveConfig &enclave_config)
50 | ABSL_LOCKS_EXCLUDED(server_mutex_) override;
51 |
52 | asylo::Status Run(const asylo::EnclaveInput &enclave_input,
53 | asylo::EnclaveOutput *enclave_output) override;
54 |
55 | asylo::Status Finalize(const asylo::EnclaveFinal &enclave_final)
56 | ABSL_LOCKS_EXCLUDED(server_mutex_) override;
57 |
58 | private:
59 | // Guards the |server_| member.
60 | absl::Mutex server_mutex_;
61 |
62 | // A gRPC server hosting |service_|.
63 | std::unique_ptr<::grpc::Server> server_ ABSL_GUARDED_BY(server_mutex_);
64 |
65 | // The translation service.
66 | std::unique_ptr service_;
67 |
68 | // The server's selected port.
69 | int selected_port_;
70 | };
71 |
72 | asylo::Status GrpcServerEnclave::Initialize(
73 | const asylo::EnclaveConfig &enclave_config)
74 | ABSL_LOCKS_EXCLUDED(server_mutex_) {
75 | // Fail if there is no server_address available.
76 | if (!enclave_config.HasExtension(server_address)) {
77 | return absl::InvalidArgumentError(
78 | "Expected a server_address extension on config.");
79 | }
80 |
81 | if (!enclave_config.HasExtension(port)) {
82 | return absl::InvalidArgumentError("Expected a port extension on config.");
83 | }
84 |
85 | // Lock |server_mutex_| so that we can start setting up the server.
86 | absl::MutexLock lock(&server_mutex_);
87 |
88 | // Check that the server is not already running.
89 | if (server_) {
90 | return absl::AlreadyExistsError("Server is already started");
91 | }
92 |
93 | // Create a ServerBuilder object to set up the server.
94 | ::grpc::ServerBuilder builder;
95 |
96 | std::shared_ptr<::grpc::ServerCredentials> server_credentials =
97 | ::grpc::InsecureServerCredentials();
98 |
99 | // Add a listening port to the server.
100 | builder.AddListeningPort(
101 | absl::StrCat(enclave_config.GetExtension(server_address), ":",
102 | enclave_config.GetExtension(port)),
103 | server_credentials, &selected_port_);
104 |
105 | // Instantiate the translator service.
106 | service_ = absl::make_unique();
107 |
108 | // Add the translator service to the server.
109 | builder.RegisterService(service_.get());
110 |
111 | // Start the server.
112 | server_ = builder.BuildAndStart();
113 | if (!server_) {
114 | return absl::InternalError("Failed to start server");
115 | }
116 |
117 | return absl::OkStatus();
118 | }
119 |
120 | asylo::Status GrpcServerEnclave::Run(const asylo::EnclaveInput &enclave_input,
121 | asylo::EnclaveOutput *enclave_output) {
122 | enclave_output->SetExtension(actual_server_port, selected_port_);
123 | return absl::OkStatus();
124 | }
125 |
126 | asylo::Status GrpcServerEnclave::Finalize(
127 | const asylo::EnclaveFinal &enclave_final)
128 | ABSL_LOCKS_EXCLUDED(server_mutex_) {
129 | // Lock |server_mutex_| so that we can start shutting down the server.
130 | absl::MutexLock lock(&server_mutex_);
131 |
132 | // If the server exists, then shut it down. Also delete the Server object to
133 | // indicate that it is no longer valid.
134 | if (server_) {
135 | LOG(INFO) << "Server shutting down";
136 |
137 | // Give all outstanding RPC calls 500 milliseconds to complete.
138 | server_->Shutdown(std::chrono::system_clock::now() +
139 | std::chrono::milliseconds(500));
140 | server_.reset(nullptr);
141 | }
142 |
143 | return absl::OkStatus();
144 | }
145 |
146 | } // namespace grpc_server
147 | } // namespace examples
148 |
149 | namespace asylo {
150 |
151 | // Registers an instance of GrpcServerEnclave as the TrustedApplication. See
152 | // trusted_application.h for more information.
153 | TrustedApplication *BuildTrustedApplication() {
154 | return new examples::grpc_server::GrpcServerEnclave;
155 | }
156 |
157 | } // namespace asylo
158 |
--------------------------------------------------------------------------------
/grpc_server/grpc_server_test.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include
23 |
24 | #include "absl/flags/flag.h"
25 | #include "absl/memory/memory.h"
26 | #include "absl/strings/str_cat.h"
27 | #include "absl/strings/string_view.h"
28 | #include "asylo/enclave_manager.h"
29 | #include "asylo/test/util/status_matchers.h"
30 | #include "asylo/util/path.h"
31 | #include "asylo/util/status.h"
32 | #include "asylo/util/status_macros.h"
33 | #include "grpc_server/grpc_server_util.h"
34 | #include "grpc_server/translator_client.h"
35 |
36 | ABSL_FLAG(std::string, server_enclave_path, "",
37 | "The path to the server enclave to pass to the enclave loader");
38 |
39 | ABSL_FLAG(bool, debug_enclave, true,
40 | "Whether to load the server as a debug enclave");
41 |
42 | namespace examples {
43 | namespace grpc_server {
44 | namespace {
45 |
46 | using asylo::IsOkAndHolds;
47 | using asylo::StatusIs;
48 |
49 | class GrpcServerTest : public ::testing::Test {
50 | public:
51 | static void SetUpTestSuite() {
52 | ASYLO_ASSERT_OK(
53 | asylo::EnclaveManager::Configure(asylo::EnclaveManagerOptions()));
54 | }
55 |
56 | void SetUp() override {
57 | ASSERT_NE(absl::GetFlag(FLAGS_server_enclave_path), "");
58 | server_port_ = 0;
59 | }
60 |
61 | void StartServer() {
62 | ASYLO_ASSERT_OK(LoadGrpcServerEnclave(
63 | absl::GetFlag(FLAGS_server_enclave_path), server_port_,
64 | absl::GetFlag(FLAGS_debug_enclave)));
65 |
66 | // Retrieve the server's port.
67 | ASYLO_ASSERT_OK_AND_ASSIGN(server_port_, GrpcServerEnclaveGetPort());
68 | ASSERT_NE(server_port_, 0);
69 | }
70 |
71 | void TearDown() override { ASYLO_ASSERT_OK(DestroyGrpcServerEnclave()); }
72 |
73 | // Sends a GetTranslation RPC to the server via the client. Returns
74 | // the same grpc::Status as the stub function call. If the RPC is successful,
75 | // returns the translated word, else returns a non-OK status.
76 | asylo::StatusOr MakeRpc(const std::string &input_word) {
77 | std::unique_ptr client;
78 | ASYLO_ASSIGN_OR_RETURN(client, TranslatorClient::Create(absl::StrCat(
79 | "localhost:", server_port_)));
80 | return client->GrpcGetTranslation(input_word);
81 | }
82 |
83 | private:
84 | int server_port_;
85 | };
86 |
87 | TEST_F(GrpcServerTest, KnownTranslations) {
88 | ASSERT_NO_FATAL_FAILURE(StartServer());
89 |
90 | EXPECT_THAT(MakeRpc("asylo"), IsOkAndHolds("sanctuary"));
91 | EXPECT_THAT(MakeRpc("istio"), IsOkAndHolds("sail"));
92 | EXPECT_THAT(MakeRpc("kubernetes"), IsOkAndHolds("helmsman"));
93 | }
94 |
95 | TEST_F(GrpcServerTest, UnknownTranslation) {
96 | ASSERT_NO_FATAL_FAILURE(StartServer());
97 |
98 | EXPECT_THAT(MakeRpc("orkut"), StatusIs(asylo::error::INVALID_ARGUMENT,
99 | "No known translation for \"orkut\""));
100 | }
101 |
102 | } // namespace
103 | } // namespace grpc_server
104 | } // namespace examples
105 |
--------------------------------------------------------------------------------
/grpc_server/grpc_server_util.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include "absl/strings/str_cat.h"
23 | #include "asylo/client.h"
24 | #include "asylo/enclave.pb.h"
25 | #include "asylo/platform/primitives/sgx/loader.pb.h"
26 | #include "asylo/util/status.h"
27 | #include "asylo/util/status_macros.h"
28 | #include "grpc_server/grpc_server_config.pb.h"
29 |
30 | namespace examples {
31 | namespace grpc_server {
32 | namespace {
33 |
34 | constexpr char kServerAddress[] = "localhost";
35 | constexpr char kEnclaveName[] = "grpc_server";
36 |
37 | } // namespace
38 |
39 | asylo::Status LoadGrpcServerEnclave(const std::string &enclave_path,
40 | int server_port, bool debug_enclave) {
41 | // The EnclaveLoadConfig contains all configurations passed to the enclave for
42 | // initialization.
43 | asylo::EnclaveLoadConfig load_config;
44 | load_config.set_name(kEnclaveName);
45 |
46 | // The EnclaveConfig contains the address that the gRPC server will run on.
47 | asylo::EnclaveConfig *config = load_config.mutable_config();
48 | config->SetExtension(server_address, kServerAddress);
49 | config->SetExtension(port, server_port);
50 |
51 | // The SgxLoadConfig sets up configuration specific to an SGX enclave,
52 | // including the location of the enclave binary and whether to run in debug
53 | // mode.
54 | asylo::SgxLoadConfig *sgx_config =
55 | load_config.MutableExtension(asylo::sgx_load_config);
56 | sgx_config->mutable_file_enclave_config()->set_enclave_path(enclave_path);
57 | sgx_config->set_debug(debug_enclave);
58 |
59 | asylo::EnclaveManager *manager = nullptr;
60 | ASYLO_ASSIGN_OR_RETURN(manager, asylo::EnclaveManager::Instance());
61 |
62 | // Load the enclave. Calling LoadEnclave() triggers a call to the Initialize()
63 | // method of the TrustedApplication.
64 | return manager->LoadEnclave(load_config);
65 | }
66 |
67 | asylo::StatusOr GrpcServerEnclaveGetPort() {
68 | asylo::EnclaveManager *manager = nullptr;
69 | ASYLO_ASSIGN_OR_RETURN(manager, asylo::EnclaveManager::Instance());
70 |
71 | asylo::EnclaveClient *client = manager->GetClient(kEnclaveName);
72 | if (!client) {
73 | return asylo::Status(asylo::error::FAILED_PRECONDITION,
74 | absl::StrCat(kEnclaveName, " not running"));
75 | }
76 |
77 | asylo::EnclaveInput enclave_input;
78 | asylo::EnclaveOutput enclave_output;
79 | ASYLO_RETURN_IF_ERROR(client->EnterAndRun(enclave_input, &enclave_output));
80 | if (!enclave_output.HasExtension(actual_server_port)) {
81 | return asylo::Status(asylo::error::INTERNAL,
82 | "Server output missing server_port extension");
83 | }
84 | return enclave_output.GetExtension(actual_server_port);
85 | }
86 |
87 | asylo::Status DestroyGrpcServerEnclave() {
88 | asylo::EnclaveManager *manager = nullptr;
89 | ASYLO_ASSIGN_OR_RETURN(manager, asylo::EnclaveManager::Instance());
90 |
91 | asylo::EnclaveClient *client = manager->GetClient(kEnclaveName);
92 | if (!client) {
93 | return asylo::Status(asylo::error::FAILED_PRECONDITION,
94 | absl::StrCat(kEnclaveName, " not running"));
95 | }
96 |
97 | asylo::EnclaveFinal final_input;
98 | return manager->DestroyEnclave(client, final_input);
99 | }
100 |
101 | } // namespace grpc_server
102 | } // namespace examples
103 |
--------------------------------------------------------------------------------
/grpc_server/grpc_server_util.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #ifndef ASYLO_EXAMPLES_GRPC_SERVER_GRPC_SERVER_UTIL_H_
20 | #define ASYLO_EXAMPLES_GRPC_SERVER_GRPC_SERVER_UTIL_H_
21 |
22 | #include
23 |
24 | #include "asylo/util/status.h"
25 | #include "asylo/util/statusor.h"
26 |
27 | namespace examples {
28 | namespace grpc_server {
29 |
30 | // Each of the following functions assume that the asylo::EnclaveManager
31 | // instance has been configured using asylo::EnclaveManager::Configure().
32 |
33 | // Loads the GrpcServerEnclave from |enclave_path|. If |debug_enclave| is true,
34 | // then the enclave is started in debug mode. Starts the enclave's server on
35 | // |server_port| and configures the server to refer requests to the
36 | // GetTranslation RPC.
37 | asylo::Status LoadGrpcServerEnclave(const std::string &enclave_path,
38 | int server_port, bool debug_enclave);
39 |
40 | // Retrieves the port of the server inside the GrpcServerEnclave. Returns a
41 | // non-OK Status if the GrpcServerEnclave is not running.
42 | asylo::StatusOr GrpcServerEnclaveGetPort();
43 |
44 | // Destroys the GrpcServerEnclave and returns its finalization Status. Returns a
45 | // non-OK Status if the GrpcServerEnclave is not running.
46 | asylo::Status DestroyGrpcServerEnclave();
47 |
48 | } // namespace grpc_server
49 | } // namespace examples
50 |
51 | #endif // ASYLO_EXAMPLES_GRPC_SERVER_GRPC_SERVER_UTIL_H_
52 |
--------------------------------------------------------------------------------
/grpc_server/translator_client.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include "grpc_server/translator_client.h"
20 |
21 | #include
22 | #include
23 |
24 | #include "absl/memory/memory.h"
25 | #include "absl/status/status.h"
26 | #include "absl/strings/string_view.h"
27 | #include "absl/time/time.h"
28 | #include "asylo/util/status.h"
29 | #include "asylo/util/status_helpers.h"
30 | #include "asylo/util/status_macros.h"
31 | #include "asylo/util/statusor.h"
32 | #include "grpc_server/translator_server.grpc.pb.h"
33 | #include "grpc_server/translator_server.pb.h"
34 | #include "include/grpc/impl/codegen/gpr_types.h"
35 | #include "include/grpc/support/time.h"
36 | #include "include/grpcpp/create_channel.h"
37 | #include "include/grpcpp/grpcpp.h"
38 | #include "include/grpcpp/security/credentials.h"
39 |
40 | namespace examples {
41 | namespace grpc_server {
42 | namespace {
43 |
44 | const absl::Duration kChannelDeadline = absl::Seconds(5);
45 |
46 | // Makes a GetTranslation RPC with |request| to the server backed by *|stub|.
47 | asylo::StatusOr GetTranslation(
48 | const GetTranslationRequest &request, Translator::Stub *stub) {
49 | GetTranslationResponse response;
50 |
51 | ::grpc::ClientContext context;
52 | ASYLO_RETURN_IF_ERROR(asylo::ConvertStatus(
53 | stub->GetTranslation(&context, request, &response)));
54 | return response;
55 | }
56 |
57 | } // namespace
58 |
59 | asylo::StatusOr> TranslatorClient::Create(
60 | absl::string_view address) {
61 | if (address.empty()) {
62 | return asylo::Status(absl::StatusCode::kInvalidArgument,
63 | "Must provide a non-empty server address");
64 | }
65 | std::shared_ptr<::grpc::ChannelCredentials> channel_credentials =
66 | ::grpc::InsecureChannelCredentials();
67 |
68 | // Connect a gRPC channel to the server.
69 | std::shared_ptr<::grpc::Channel> channel =
70 | ::grpc::CreateChannel(std::string(address), channel_credentials);
71 |
72 | gpr_timespec absolute_deadline = gpr_time_add(
73 | gpr_now(GPR_CLOCK_REALTIME),
74 | gpr_time_from_micros(absl::ToInt64Microseconds(kChannelDeadline),
75 | GPR_TIMESPAN));
76 | if (!channel->WaitForConnected(absolute_deadline)) {
77 | return asylo::Status(absl::StatusCode::kInternal,
78 | "Failed to connect to server");
79 | }
80 |
81 | return absl::WrapUnique(new TranslatorClient(Translator::NewStub(channel)));
82 | }
83 |
84 | asylo::StatusOr TranslatorClient::GrpcGetTranslation(
85 | absl::string_view word_to_translate) {
86 | if (word_to_translate.empty()) {
87 | return asylo::Status(absl::StatusCode::kInvalidArgument,
88 | "Must provide a non-empty RPC input");
89 | }
90 |
91 | GetTranslationRequest request;
92 | request.set_input_word(std::string(word_to_translate));
93 | GetTranslationResponse response;
94 | ASYLO_ASSIGN_OR_RETURN(response, GetTranslation(request, stub_.get()));
95 |
96 | return response.translated_word();
97 | }
98 |
99 | } // namespace grpc_server
100 | } // namespace examples
101 |
--------------------------------------------------------------------------------
/grpc_server/translator_client.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #ifndef ASYLO_EXAMPLES_GRPC_SERVER_TRANSLATOR_CLIENT_H_
20 | #define ASYLO_EXAMPLES_GRPC_SERVER_TRANSLATOR_CLIENT_H_
21 |
22 | #include
23 | #include
24 |
25 | #include "absl/strings/string_view.h"
26 | #include "asylo/util/status.h"
27 | #include "asylo/util/statusor.h"
28 | #include "grpc_server/translator_server.grpc.pb.h"
29 | #include "grpc_server/translator_server.pb.h"
30 | #include "include/grpcpp/grpcpp.h"
31 |
32 | namespace examples {
33 | namespace grpc_server {
34 |
35 | // A gRPC client connected to a TranslationServer. Can only be instantiated
36 | // by the factory method TranslatorClient::Create.
37 | class TranslatorClient {
38 | public:
39 | // Factory method that returns a client connected to a TranslatorServer
40 | // at |address|. In case of error, returns a non-OK status.
41 | static asylo::StatusOr> Create(
42 | absl::string_view address);
43 |
44 | // Non-copyable, non-movable.
45 | TranslatorClient(const TranslatorClient &other) = delete;
46 | TranslatorClient &operator=(const TranslatorClient &other) = delete;
47 | TranslatorClient(TranslatorClient &&other) = delete;
48 | TranslatorClient &operator=(TranslatorClient &&other) = delete;
49 |
50 | // Makes a GetTranslation RPC for |word_to_translate| to the server and
51 | // returns the translated word on success, or a non-OK Status if the RPC
52 | // fails.
53 | asylo::StatusOr GrpcGetTranslation(
54 | absl::string_view word_to_translate);
55 |
56 | private:
57 | explicit TranslatorClient(std::unique_ptr stub)
58 | : stub_(std::move(stub)) {}
59 |
60 | std::unique_ptr stub_;
61 | };
62 |
63 | } // namespace grpc_server
64 | } // namespace examples
65 |
66 | #endif // ASYLO_EXAMPLES_GRPC_SERVER_TRANSLATOR_CLIENT_H_
67 |
--------------------------------------------------------------------------------
/grpc_server/translator_server.proto:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2018 Asylo authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | syntax = "proto2";
18 |
19 | package examples.grpc_server;
20 |
21 | // A request message containing a word to be translated.
22 | message GetTranslationRequest {
23 | optional string input_word = 1;
24 | }
25 |
26 | // A response message containing the translation of a GetTranslationRequest's
27 | // input_word.
28 | message GetTranslationResponse {
29 | optional string translated_word = 1;
30 | }
31 |
32 | service Translator {
33 | // Translates the given word.
34 | rpc GetTranslation(GetTranslationRequest) returns (GetTranslationResponse) {
35 | // errors: no input word, no translation available
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/grpc_server/translator_server_impl.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include "grpc_server/translator_server_impl.h"
20 |
21 | #include "absl/strings/ascii.h"
22 | #include "absl/strings/str_cat.h"
23 | #include "include/grpcpp/grpcpp.h"
24 |
25 | namespace examples {
26 | namespace grpc_server {
27 |
28 | TranslatorServerImpl::TranslatorServerImpl()
29 | : Service(),
30 | // Initialize the translation map with a few known translations.
31 | translation_map_({{"asylo", "sanctuary"},
32 | {"istio", "sail"},
33 | {"kubernetes", "helmsman"}}) {}
34 |
35 | ::grpc::Status TranslatorServerImpl::GetTranslation(
36 | ::grpc::ServerContext *context, const GetTranslationRequest *request,
37 | GetTranslationResponse *response) {
38 | // Confirm that |*request| has an |input_word| field.
39 | if (!request->has_input_word()) {
40 | return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT,
41 | "No input word given");
42 | }
43 |
44 | // Confirm that the translation map has a translation for the input word.
45 | auto response_iterator =
46 | translation_map_.find(absl::AsciiStrToLower(request->input_word()));
47 | if (response_iterator == translation_map_.end()) {
48 | return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT,
49 | absl::StrCat("No known translation for \"",
50 | request->input_word(), "\""));
51 | }
52 |
53 | // Return the translation.
54 | response->set_translated_word(response_iterator->second);
55 | return ::grpc::Status::OK;
56 | }
57 |
58 | } // namespace grpc_server
59 | } // namespace examples
60 |
--------------------------------------------------------------------------------
/grpc_server/translator_server_impl.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #ifndef ASYLO_EXAMPLES_GRPC_SERVER_TRANSLATOR_SERVER_IMPL_H_
20 | #define ASYLO_EXAMPLES_GRPC_SERVER_TRANSLATOR_SERVER_IMPL_H_
21 |
22 | #include
23 |
24 | #include "absl/base/thread_annotations.h"
25 | #include "absl/container/flat_hash_map.h"
26 | #include "absl/synchronization/mutex.h"
27 | #include "absl/synchronization/notification.h"
28 | #include "grpc_server/translator_server.grpc.pb.h"
29 | #include "include/grpcpp/grpcpp.h"
30 | #include "include/grpcpp/server.h"
31 |
32 | namespace examples {
33 | namespace grpc_server {
34 |
35 | class TranslatorServerImpl final : public Translator::Service {
36 | public:
37 | // Configure the server.
38 | explicit TranslatorServerImpl();
39 |
40 | private:
41 | ::grpc::Status GetTranslation(::grpc::ServerContext *context,
42 | const GetTranslationRequest *request,
43 | GetTranslationResponse *response) override;
44 |
45 | // A map from words to their translations.
46 | absl::flat_hash_map translation_map_;
47 | };
48 |
49 | } // namespace grpc_server
50 | } // namespace examples
51 |
52 | #endif // ASYLO_EXAMPLES_GRPC_SERVER_TRANSLATOR_SERVER_IMPL_H_
53 |
--------------------------------------------------------------------------------
/hello_world/BUILD:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2018 Asylo authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | # Hello World project for Asylo.
18 |
19 | load("@linux_sgx//:sgx_sdk.bzl", "sgx")
20 | load("@rules_cc//cc:defs.bzl", "cc_proto_library")
21 | load("@rules_proto//proto:defs.bzl", "proto_library")
22 | load("@com_google_asylo//asylo/bazel:asylo.bzl", "cc_unsigned_enclave", "debug_sign_enclave", "enclave_loader")
23 |
24 | licenses(["notice"])
25 |
26 | package(
27 | default_visibility = ["//visibility:public"],
28 | )
29 |
30 | # Example for using the Asylo framework.
31 |
32 | proto_library(
33 | name = "hello_proto",
34 | srcs = ["hello.proto"],
35 | deps = ["@com_google_asylo//asylo:enclave_proto"],
36 | )
37 |
38 | cc_proto_library(
39 | name = "hello_cc_proto",
40 | deps = [":hello_proto"],
41 | )
42 |
43 | cc_unsigned_enclave(
44 | name = "hello_enclave_unsigned.so",
45 | srcs = ["hello_enclave.cc"],
46 | deps = [
47 | ":hello_cc_proto",
48 | "@com_google_absl//absl/strings",
49 | "@com_google_asylo//asylo:enclave_runtime",
50 | "@com_google_asylo//asylo/util:logging",
51 | "@com_google_asylo//asylo/util:status",
52 | ],
53 | )
54 |
55 | debug_sign_enclave(
56 | name = "hello_enclave.so",
57 | unsigned = "hello_enclave_unsigned.so",
58 | )
59 |
60 | enclave_loader(
61 | name = "hello_world",
62 | srcs = ["hello_driver.cc"],
63 | backends = sgx.backend_labels, # Has SGX loader dependencies
64 | enclaves = {"enclave": ":hello_enclave.so"},
65 | loader_args = ["--enclave_path='{enclave}'"],
66 | deps = [
67 | ":hello_cc_proto",
68 | "@com_google_absl//absl/flags:flag",
69 | "@com_google_absl//absl/flags:parse",
70 | "@com_google_absl//absl/strings",
71 | "@com_google_asylo//asylo:enclave_cc_proto",
72 | "@com_google_asylo//asylo:enclave_client",
73 | "@com_google_asylo//asylo/platform/primitives/sgx:loader_cc_proto",
74 | "@com_google_asylo//asylo/util:logging",
75 | ],
76 | )
77 |
--------------------------------------------------------------------------------
/hello_world/hello.proto:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2018 Asylo authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | syntax = "proto2";
18 |
19 | package hello_world;
20 |
21 | import "asylo/enclave.proto";
22 |
23 | // Extension to EnclaveInput for use with HelloWorld enclave.
24 | message HelloInput {
25 | optional string to_greet = 1;
26 | }
27 |
28 | message HelloOutput {
29 | optional string greeting_message = 1;
30 | }
31 |
32 | extend asylo.EnclaveInput {
33 | optional HelloInput enclave_input_hello = 8086;
34 | }
35 |
36 | extend asylo.EnclaveOutput {
37 | optional HelloOutput enclave_output_hello = 8087;
38 | }
39 |
--------------------------------------------------------------------------------
/hello_world/hello_driver.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 | #include
22 |
23 | #include "absl/flags/flag.h"
24 | #include "absl/flags/parse.h"
25 | #include "absl/strings/str_split.h"
26 | #include "asylo/client.h"
27 | #include "asylo/enclave.pb.h"
28 | #include "asylo/platform/primitives/sgx/loader.pb.h"
29 | #include "asylo/util/logging.h"
30 | #include "hello_world/hello.pb.h"
31 |
32 | ABSL_FLAG(std::string, enclave_path, "", "Path to enclave to load");
33 | ABSL_FLAG(std::string, names, "",
34 | "A comma-separated list of names to pass to the enclave");
35 |
36 | int main(int argc, char *argv[]) {
37 | // Part 0: Setup
38 | absl::ParseCommandLine(argc, argv);
39 |
40 | if (absl::GetFlag(FLAGS_names).empty()) {
41 | LOG(QFATAL) << "Must supply a non-empty list of names with --names";
42 | }
43 |
44 | std::vector names =
45 | absl::StrSplit(absl::GetFlag(FLAGS_names), ',');
46 |
47 | // Part 1: Initialization
48 | asylo::EnclaveManager::Configure(asylo::EnclaveManagerOptions());
49 | auto manager_result = asylo::EnclaveManager::Instance();
50 | if (!manager_result.ok()) {
51 | LOG(QFATAL) << "EnclaveManager unavailable: " << manager_result.status();
52 | }
53 | asylo::EnclaveManager *manager = manager_result.value();
54 | std::cout << "Loading " << absl::GetFlag(FLAGS_enclave_path) << std::endl;
55 |
56 | // Create an EnclaveLoadConfig object.
57 | asylo::EnclaveLoadConfig load_config;
58 | load_config.set_name("hello_enclave");
59 |
60 | // Create an SgxLoadConfig object.
61 | asylo::SgxLoadConfig sgx_config;
62 | asylo::SgxLoadConfig::FileEnclaveConfig file_enclave_config;
63 | file_enclave_config.set_enclave_path(absl::GetFlag(FLAGS_enclave_path));
64 | *sgx_config.mutable_file_enclave_config() = file_enclave_config;
65 | sgx_config.set_debug(true);
66 |
67 | // Set an SGX message extension to load_config.
68 | *load_config.MutableExtension(asylo::sgx_load_config) = sgx_config;
69 | asylo::Status status = manager->LoadEnclave(load_config);
70 | if (!status.ok()) {
71 | LOG(QFATAL) << "Load " << absl::GetFlag(FLAGS_enclave_path)
72 | << " failed: " << status;
73 | }
74 |
75 | // Part 2: Secure execution
76 |
77 | asylo::EnclaveClient *client = manager->GetClient("hello_enclave");
78 |
79 | for (const auto &name : names) {
80 | asylo::EnclaveInput input;
81 | input.MutableExtension(hello_world::enclave_input_hello)
82 | ->set_to_greet(name);
83 |
84 | asylo::EnclaveOutput output;
85 | status = client->EnterAndRun(input, &output);
86 | if (!status.ok()) {
87 | LOG(QFATAL) << "EnterAndRun failed: " << status;
88 | }
89 |
90 | if (!output.HasExtension(hello_world::enclave_output_hello)) {
91 | LOG(QFATAL) << "Enclave did not assign an ID for " << name;
92 | }
93 |
94 | std::cout << "Message from enclave: "
95 | << output.GetExtension(hello_world::enclave_output_hello)
96 | .greeting_message()
97 | << std::endl;
98 | }
99 |
100 | // Part 3: Finalization
101 |
102 | asylo::EnclaveFinal final_input;
103 | status = manager->DestroyEnclave(client, final_input);
104 | if (!status.ok()) {
105 | LOG(QFATAL) << "Destroy " << absl::GetFlag(FLAGS_enclave_path)
106 | << " failed: " << status;
107 | }
108 |
109 | return 0;
110 | }
111 |
--------------------------------------------------------------------------------
/hello_world/hello_enclave.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 |
21 | #include "absl/status/status.h"
22 | #include "absl/strings/str_cat.h"
23 | #include "asylo/trusted_application.h"
24 | #include "asylo/util/logging.h"
25 | #include "asylo/util/status.h"
26 | #include "hello_world/hello.pb.h"
27 |
28 | class HelloApplication : public asylo::TrustedApplication {
29 | public:
30 | HelloApplication() : visitor_count_(0) {}
31 |
32 | asylo::Status Run(const asylo::EnclaveInput &input,
33 | asylo::EnclaveOutput *output) override {
34 | if (!input.HasExtension(hello_world::enclave_input_hello)) {
35 | return absl::InvalidArgumentError(
36 | "Expected a HelloInput extension on input.");
37 | }
38 | std::string visitor =
39 | input.GetExtension(hello_world::enclave_input_hello).to_greet();
40 |
41 | LOG(INFO) << "Hello " << visitor;
42 | if (output) {
43 | LOG(INFO) << "Incrementing visitor count...";
44 | output->MutableExtension(hello_world::enclave_output_hello)
45 | ->set_greeting_message(
46 | absl::StrCat("Hello ", visitor, "! You are visitor #",
47 | ++visitor_count_, " to this enclave."));
48 | }
49 | return absl::OkStatus();
50 | }
51 |
52 | private:
53 | uint64_t visitor_count_;
54 | };
55 |
56 | namespace asylo {
57 |
58 | TrustedApplication *BuildTrustedApplication() { return new HelloApplication; }
59 |
60 | } // namespace asylo
61 |
--------------------------------------------------------------------------------
/java/quickstart_client/BUILD:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2019 Asylo authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | load("@rules_java//java:defs.bzl", "java_binary", "java_proto_library")
18 |
19 | licenses(["notice"])
20 |
21 | java_binary(
22 | name = "quickstart",
23 | srcs = [
24 | "src/main/java/com/example/DemoDriver.java",
25 | ],
26 | main_class = "com.example.DemoDriver",
27 | deps = [
28 | ":demo_java_proto",
29 | "@com_google_asylo//asylo:enclave_client_java",
30 | "@com_google_protobuf//:protobuf_java",
31 | ],
32 | )
33 |
34 | java_proto_library(
35 | name = "demo_java_proto",
36 | deps = [
37 | "//quickstart/solution:demo_proto",
38 | ],
39 | )
40 |
--------------------------------------------------------------------------------
/java/quickstart_client/README.md:
--------------------------------------------------------------------------------
1 |
21 |
22 | This guide describes how to use Java to run an Asylo enclave that was written in
23 | C++. This guide assumes that the reader is familiar with
24 | [Asylo quickstart guide](https://asylo.dev/docs/guides/quickstart.html).
25 |
26 | ## Introduction
27 |
28 | There are two parts in an enclave application written using Asylo framework,
29 | _untrusted application_ and _trusted application (enclave)_. Asylo release 0.5.2
30 | and older required both trusted and untrusted components to be written in C++.
31 |
32 | With the introduction of Asylo Java client, untrusted application can now be
33 | written in Java as well. An Asylo Java client can load and run an enclave
34 | written in C++. This model enables users to write their enclave once and then
35 | reuse it in an untrusted application written in C++ or Java.
36 |
37 | ## Using a Java client
38 |
39 | An enclave can be loaded using an
40 | [`EnclaveManager`](https://github.com/google/asylo/blob/master/asylo/binding/java/src/main/java/com/asylo/client/EnclaveManager.java).
41 | It is a singleton class which can load an enclave from the file system by
42 | providing the path to the enclave binary using the
43 | [`EnclaveLoadConfig`](https://github.com/google/asylo/blob/master/asylo/enclave.proto) proto.
44 |
45 | Users may interact with a loaded enclave through an
46 | [`EnclaveClient`](https://github.com/google/asylo/blob/master/asylo/binding/java/src/main/java/com/asylo/client/EnclaveClient.java).
47 | The `EnclaveManager` returns a loaded and named `EnclaveClient` with the method
48 | `getEnclaveClient`.
49 |
50 | Most of the configurations, inputs, and outputs in a Java client are passed
51 | using
52 | [protocol-buffer messages](https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.message#Message).
53 |
54 | One major difference between the Java and C++ APIs is that in Java, errors are
55 | thrown as exceptions derived from
56 | [`EnclaveException`](https://github.com/google/asylo/blob/master/asylo/binding/java/src/main/java/com/asylo/client/EnclaveException.java),
57 | rather returned through a `StatusOr` type.
58 |
59 | The following snippet is a small example of a Java client that interacts with an
60 | enclave written in C++.
61 |
62 | ```java
63 | public static void main(String[] args) {
64 |
65 | if (args.length != 1) {
66 | System.err.println("Expecting a single argument which is the filepath of an enclave.");
67 | System.exit(1);
68 | }
69 |
70 | String enclavePath = args[0];
71 | String enclaveName = "demo_enclave";
72 |
73 | // Part 1: Initialization
74 | // Specify the enclave file.
75 | FileEnclaveConfig fileEnclaveConfig =
76 | FileEnclaveConfig.newBuilder().setEnclavePath(enclavePath).build();
77 |
78 | // Specify that the enclave uses SGX, and configure the SGX loader with the
79 | // path to the enclave binary.
80 | SgxLoadConfig sgxLoadConfig =
81 | SgxLoadConfig.newBuilder().setDebug(true).setFileEnclaveConfig(fileEnclaveConfig).build();
82 |
83 | // Specify the enclave name and inject the SGX configuration.
84 | EnclaveLoadConfig enclaveLoadConfig =
85 | EnclaveLoadConfig.newBuilder()
86 | .setName(enclaveName)
87 | .setExtension(EnclaveLoadConfigSgxExtension.sgxLoadConfig, sgxLoadConfig)
88 | .build();
89 |
90 | EnclaveManager.getInstance().loadEnclave(enclaveLoadConfig);
91 |
92 | // Part 2: Secure execution
93 | // Get user input.
94 | String plainText = getMessage();
95 |
96 | // Prepare input for enclave.
97 | Demo demoInput = Demo.newBuilder().setValue(plainText).setAction(Demo.Action.ENCRYPT).build();
98 | EnclaveInput enclaveInput =
99 | EnclaveInput.newBuilder()
100 | .setExtension(EnclaveDemoExtension.quickstartInput, demoInput)
101 | .build();
102 |
103 | // Register protobuf extension for output.
104 | ExtensionRegistry registry = ExtensionRegistry.newInstance();
105 | registry.add(EnclaveDemoExtension.quickstartOutput);
106 |
107 | EnclaveClient client = EnclaveManager.getInstance().getEnclaveClient(enclaveName);
108 | EnclaveOutput output = client.enterAndRun(enclaveInput, registry);
109 | Demo encryptedText = output.getExtension(EnclaveDemoExtension.quickstartOutput);
110 |
111 | System.out.println("Encrypted message:" + encryptedText.getValue());
112 |
113 | // Part 3: Finalization
114 | EnclaveFinal finalInput = EnclaveFinal.getDefaultInstance();
115 | EnclaveManager.getInstance().destroyEnclaveClient(client, finalInput);
116 | }
117 | ```
118 |
119 | The above snippet is conceptually the same as the one mentioned in
120 | [enclave lifecycle](https://asylo.dev/docs/guides/quickstart.html#enclave-lifecycle)
121 |
122 | ## Building and running an enclave Java application
123 |
124 | The Java library `//asylo:enclave_client_java` provides the API to load C++
125 | enclaves in Java.
126 |
127 | ```python
128 | java_binary(
129 | name = "quickstart",
130 | srcs = [
131 | "src/main/java/com/example/DemoDriver.java",
132 | ],
133 | main_class = "com.example.DemoDriver",
134 | deps = [
135 | ":demo_java_proto",
136 | "//java/com/google/protobuf",
137 | "@com_google_asylo//asylo:enclave_client_java",
138 | ],
139 | )
140 |
141 | java_proto_library(
142 | name = "demo_java_proto",
143 | deps = [
144 | "//quickstart:demo_proto",
145 | ],
146 | )
147 | ```
148 |
149 | The [Bazel](https://bazel.build) BUILD file shown above has untrusted java code
150 | in the target `:quickstart`, which contains the code to handle logic of
151 | initializing, running, and finalizing the enclave.
152 |
153 | To run this example first we need an enclave. The following workflow uses the
154 | enclave from
155 | [Asylo quickstart guide](https://asylo.dev/docs/guides/quickstart.html#building-and-running-an-enclave-application)
156 | by running:
157 |
158 | ```bash
159 | bazel build //quickstart:demo_enclave_sgx_sim.so
160 | ```
161 |
162 | Copy the generated file to some location:
163 |
164 | ```bash
165 | cp $(bazel info bazel-bin)/quickstart/demo_enclave_sgx_sim.so /tmp/demo_enclave_sgx_sim.so
166 | ```
167 |
168 | Now, untrusted Java client can be run as:
169 |
170 | ```bash
171 | bazel run //java/quickstart_client:quickstart /tmp/demo_enclave_sgx_sim.so
172 | ```
173 |
174 | You should then see a prompt for a message to encrypt, similar to the quickstart
175 | guide.
176 |
--------------------------------------------------------------------------------
/java/quickstart_client/src/main/java/com/example/DemoDriver.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | package com.example;
20 |
21 | import static java.nio.charset.StandardCharsets.UTF_8;
22 |
23 | import com.asylo.EnclaveFinal;
24 | import com.asylo.EnclaveInput;
25 | import com.asylo.EnclaveLoadConfig;
26 | import com.asylo.EnclaveLoadConfigSgxExtension;
27 | import com.asylo.EnclaveOutput;
28 | import com.asylo.SgxLoadConfig;
29 | import com.asylo.SgxLoadConfig.FileEnclaveConfig;
30 | import com.asylo.client.EnclaveClient;
31 | import com.asylo.client.EnclaveManager;
32 | import com.google.protobuf.ExtensionRegistry;
33 | import java.util.Scanner;
34 |
35 | /**
36 | * Class to demonstrate usage of Asylo Java client. This class uses the enclave created by the C++
37 | * quickstart example, which can be found in asylo/examples/quickstart.
38 | */
39 | public class DemoDriver {
40 | public static void main(String[] args) {
41 |
42 | if (args.length != 1) {
43 | System.err.println("Expecting a single argument which is the filepath of an enclave.");
44 | System.exit(1);
45 | }
46 |
47 | String enclavePath = args[0];
48 | String enclaveName = "demo_enclave";
49 |
50 | // Part 1: Initialization
51 | // Specify enclave file.
52 | FileEnclaveConfig fileEnclaveConfig =
53 | FileEnclaveConfig.newBuilder().setEnclavePath(enclavePath).build();
54 |
55 | // Specify that the enclave uses SGX, and configure the SGX loader with the
56 | // path to the enclave binary.
57 | SgxLoadConfig sgxLoadConfig =
58 | SgxLoadConfig.newBuilder().setDebug(true).setFileEnclaveConfig(fileEnclaveConfig).build();
59 |
60 | // Specify enclave load config.
61 | EnclaveLoadConfig enclaveLoadConfig =
62 | EnclaveLoadConfig.newBuilder()
63 | .setName(enclaveName)
64 | .setExtension(EnclaveLoadConfigSgxExtension.sgxLoadConfig, sgxLoadConfig)
65 | .build();
66 |
67 | EnclaveManager.getInstance().loadEnclave(enclaveLoadConfig);
68 |
69 | // Part 2: Secure execution
70 | // Get user input.
71 | String plainText = getMessage();
72 |
73 | // Prepare input for enclave.
74 | Demo demoInput = Demo.newBuilder().setValue(plainText).setAction(Demo.Action.ENCRYPT).build();
75 | EnclaveInput enclaveInput =
76 | EnclaveInput.newBuilder()
77 | .setExtension(EnclaveDemoExtension.quickstartInput, demoInput)
78 | .build();
79 |
80 | // Register protobuf extension for output.
81 | ExtensionRegistry registry = ExtensionRegistry.newInstance();
82 | registry.add(EnclaveDemoExtension.quickstartOutput);
83 |
84 | EnclaveClient client = EnclaveManager.getInstance().getEnclaveClient(enclaveName);
85 | EnclaveOutput output = client.enterAndRun(enclaveInput, registry);
86 | Demo encryptedText = output.getExtension(EnclaveDemoExtension.quickstartOutput);
87 |
88 | System.out.println("Encrypted message:" + encryptedText.getValue());
89 |
90 | // Part 3: Finalization
91 | EnclaveFinal finalInput = EnclaveFinal.getDefaultInstance();
92 | EnclaveManager.getInstance().destroyEnclaveClient(client, finalInput);
93 | }
94 |
95 | public static String getMessage() {
96 | String plainText = null;
97 | try (Scanner scanner = new Scanner(System.in, UTF_8.name())) {
98 | System.out.println("Please enter a message to encrypt: ");
99 | plainText = scanner.nextLine();
100 | }
101 |
102 | if (plainText == null || plainText.length() == 0) {
103 | System.out.println("No input provided.");
104 | System.exit(1);
105 | }
106 |
107 | return plainText;
108 | }
109 |
110 | private DemoDriver() {}
111 | }
112 |
--------------------------------------------------------------------------------
/quickstart/BUILD:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2018 Asylo authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | load("@linux_sgx//:sgx_sdk.bzl", "sgx")
18 | load("@rules_cc//cc:defs.bzl", "cc_proto_library")
19 | load("@rules_proto//proto:defs.bzl", "proto_library")
20 | load("@com_google_asylo//asylo/bazel:asylo.bzl", "cc_unsigned_enclave", "debug_sign_enclave", "enclave_loader")
21 |
22 | licenses(["notice"])
23 |
24 | package(
25 | default_visibility = [
26 | "@com_google_asylo//asylo:implementation",
27 | ],
28 | )
29 |
30 | # Example and exercise for using Asylo toolkits.
31 | proto_library(
32 | name = "demo_proto",
33 | srcs = ["demo.proto"],
34 | deps = ["@com_google_asylo//asylo:enclave_proto"],
35 | )
36 |
37 | cc_proto_library(
38 | name = "demo_cc_proto",
39 | deps = [":demo_proto"],
40 | )
41 |
42 | cc_unsigned_enclave(
43 | name = "demo_enclave_unsigned.so",
44 | srcs = ["demo_enclave.cc"],
45 | deps = [
46 | ":demo_cc_proto",
47 | "@com_google_absl//absl/base:core_headers",
48 | "@com_google_absl//absl/strings",
49 | "@com_google_asylo//asylo:enclave_runtime",
50 | "@com_google_asylo//asylo/crypto:aead_cryptor",
51 | "@com_google_asylo//asylo/util:cleansing_types",
52 | "@com_google_asylo//asylo/util:status",
53 | ],
54 | )
55 |
56 | debug_sign_enclave(
57 | name = "demo_enclave.so",
58 | unsigned = "demo_enclave_unsigned.so",
59 | )
60 |
61 | enclave_loader(
62 | name = "quickstart",
63 | srcs = ["demo_driver.cc"],
64 | backends = sgx.backend_labels, # Has SGX loader dependencies
65 | enclaves = {"enclave": ":demo_enclave.so"},
66 | loader_args = ["--enclave_path='{enclave}'"],
67 | deps = [
68 | ":demo_cc_proto",
69 | "@com_google_absl//absl/flags:flag",
70 | "@com_google_absl//absl/flags:parse",
71 | "@com_google_asylo//asylo:enclave_cc_proto",
72 | "@com_google_asylo//asylo:enclave_client",
73 | "@com_google_asylo//asylo/util:logging",
74 | ] + select(
75 | {
76 | "@linux_sgx//:sgx_hw": ["@com_google_asylo//asylo/platform/primitives/sgx:loader_cc_proto"],
77 | "@linux_sgx//:sgx_sim": ["@com_google_asylo//asylo/platform/primitives/sgx:loader_cc_proto"],
78 | },
79 | no_match_error = "quickstart is only configured to use the SGX backends",
80 | ),
81 | )
82 |
--------------------------------------------------------------------------------
/quickstart/demo.proto:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2018 Asylo authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | syntax = "proto2";
18 |
19 | package guide.asylo;
20 |
21 | import "asylo/enclave.proto";
22 |
23 | // A custom message to pass in and out of our enclave.
24 | message Demo {
25 | // This string value is used for both user input and enclave output.
26 | optional string value = 1;
27 | }
28 |
29 | // The EnclaveInput message that is passed to the enclave can be extended with
30 | // a Demo message to communicate a value our enclave knows to expect.
31 | extend .asylo.EnclaveInput {
32 | optional Demo quickstart_input = 9001;
33 | }
34 |
35 | // The EnclaveOutput message that is passed out of the enclave can be extended
36 | // with a Demo message to communicate a value our driver knows to expect.
37 | extend .asylo.EnclaveOutput {
38 | optional Demo quickstart_output = 9001;
39 | }
40 |
--------------------------------------------------------------------------------
/quickstart/demo_driver.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include "absl/flags/flag.h"
23 | #include "absl/flags/parse.h"
24 | #include "asylo/client.h"
25 | #include "asylo/platform/primitives/sgx/loader.pb.h"
26 | #include "asylo/util/logging.h"
27 | #include "quickstart/demo.pb.h"
28 |
29 | ABSL_FLAG(std::string, enclave_path, "",
30 | "Path to enclave binary image to load");
31 | ABSL_FLAG(std::string, message, "", "Message to encrypt");
32 |
33 | // Populates |enclave_input|->value() with |user_message|.
34 | void SetEnclaveUserMessage(asylo::EnclaveInput *enclave_input,
35 | const std::string &user_message) {
36 | guide::asylo::Demo *user_input =
37 | enclave_input->MutableExtension(guide::asylo::quickstart_input);
38 | user_input->set_value(user_message);
39 | }
40 |
41 | // Retrieves encrypted message from |output|. Intended to be used by the reader
42 | // for completing the exercise.
43 | const std::string GetEnclaveOutputMessage(const asylo::EnclaveOutput &output) {
44 | return output.GetExtension(guide::asylo::quickstart_output).value();
45 | }
46 |
47 | int main(int argc, char *argv[]) {
48 | absl::ParseCommandLine(argc, argv);
49 |
50 | constexpr char kEnclaveName[] = "demo_enclave";
51 |
52 | const std::string message = absl::GetFlag(FLAGS_message);
53 | LOG_IF(QFATAL, message.empty()) << "Empty --message flag.";
54 |
55 | const std::string enclave_path = absl::GetFlag(FLAGS_enclave_path);
56 | LOG_IF(QFATAL, enclave_path.empty()) << "Empty --enclave_path flag.";
57 |
58 | // Part 1: Initialization
59 |
60 | // Prepare |EnclaveManager| with default |EnclaveManagerOptions|
61 | asylo::EnclaveManager::Configure(asylo::EnclaveManagerOptions());
62 | auto manager_result = asylo::EnclaveManager::Instance();
63 | LOG_IF(QFATAL, !manager_result.ok()) << "Could not obtain EnclaveManager";
64 |
65 | // Prepare |load_config| message.
66 | asylo::EnclaveLoadConfig load_config;
67 | load_config.set_name(kEnclaveName);
68 |
69 | // Prepare |sgx_config| message.
70 | auto sgx_config = load_config.MutableExtension(asylo::sgx_load_config);
71 | sgx_config->set_debug(true);
72 | auto file_enclave_config = sgx_config->mutable_file_enclave_config();
73 | file_enclave_config->set_enclave_path(enclave_path);
74 |
75 | // Load Enclave with prepared |EnclaveManager| and |load_config| message.
76 | asylo::EnclaveManager *manager = manager_result.value();
77 | auto status = manager->LoadEnclave(load_config);
78 | LOG_IF(QFATAL, !status.ok()) << "LoadEnclave failed with: " << status;
79 |
80 | // Part 2: Secure execution
81 |
82 | // Prepare |input| with |message| and create |output| to retrieve response
83 | // from enclave.
84 | asylo::EnclaveInput input;
85 | SetEnclaveUserMessage(&input, message);
86 | asylo::EnclaveOutput output;
87 |
88 | // Get |EnclaveClient| for loaded enclave and execute |EnterAndRun|.
89 | asylo::EnclaveClient *const client = manager->GetClient(kEnclaveName);
90 | status = client->EnterAndRun(input, &output);
91 | LOG_IF(QFATAL, !status.ok()) << "EnterAndRun failed with: " << status;
92 |
93 | // Part 3: Finalization
94 |
95 | // |DestroyEnclave| before exiting program.
96 | asylo::EnclaveFinal empty_final_input;
97 | status = manager->DestroyEnclave(client, empty_final_input);
98 | LOG_IF(QFATAL, !status.ok()) << "DestroyEnclave failed with: " << status;
99 |
100 | return 0;
101 | }
102 |
--------------------------------------------------------------------------------
/quickstart/demo_enclave.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include "absl/base/macros.h"
23 | #include "absl/status/status.h"
24 | #include "absl/strings/escaping.h"
25 | #include "absl/strings/str_cat.h"
26 | #include "asylo/crypto/aead_cryptor.h"
27 | #include "asylo/crypto/util/byte_container_view.h"
28 | #include "asylo/trusted_application.h"
29 | #include "asylo/util/cleansing_types.h"
30 | #include "asylo/util/status_macros.h"
31 | #include "asylo/util/statusor.h"
32 | #include "quickstart/demo.pb.h"
33 |
34 | namespace asylo {
35 | namespace {
36 |
37 | // Example 128-bit AES key.
38 | constexpr uint8_t kAesKey128[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
39 | 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
40 | 0x12, 0x13, 0x14, 0x15};
41 |
42 | // Helper function that adapts absl::BytesToHexString, allowing it to be used
43 | // with ByteContainerView.
44 | std::string BytesToHexString(ByteContainerView bytes) {
45 | return absl::BytesToHexString(absl::string_view(
46 | reinterpret_cast(bytes.data()), bytes.size()));
47 | }
48 |
49 | // Encrypts a message against `kAesKey128` and returns a 12-byte nonce followed
50 | // by authenticated ciphertext, encoded as a hex string.
51 | const StatusOr EncryptMessage(const std::string &message) {
52 | std::unique_ptr cryptor;
53 | ASYLO_ASSIGN_OR_RETURN(cryptor,
54 | AeadCryptor::CreateAesGcmSivCryptor(kAesKey128));
55 |
56 | std::vector additional_authenticated_data;
57 | std::vector nonce(cryptor->NonceSize());
58 | std::vector ciphertext(message.size() + cryptor->MaxSealOverhead());
59 | size_t ciphertext_size;
60 |
61 | ASYLO_RETURN_IF_ERROR(cryptor->Seal(
62 | message, additional_authenticated_data, absl::MakeSpan(nonce),
63 | absl::MakeSpan(ciphertext), &ciphertext_size));
64 |
65 | return absl::StrCat(BytesToHexString(nonce), BytesToHexString(ciphertext));
66 | }
67 |
68 | // Decrypts a message using `kAesKey128`. Expects `nonce_and_ciphertext` to be
69 | // encoded as a hex string, and lead with a 12-byte nonce. Intended to be
70 | // used by the reader for completing the exercise.
71 | const StatusOr DecryptMessage(
72 | const std::string &nonce_and_ciphertext) {
73 | std::string input_bytes = absl::HexStringToBytes(nonce_and_ciphertext);
74 |
75 | std::unique_ptr cryptor;
76 | ASYLO_ASSIGN_OR_RETURN(cryptor,
77 | AeadCryptor::CreateAesGcmSivCryptor(kAesKey128));
78 |
79 | if (input_bytes.size() < cryptor->NonceSize()) {
80 | return Status(
81 | absl::StatusCode::kInvalidArgument,
82 | absl::StrCat("Input too short: expected at least ",
83 | cryptor->NonceSize(), " bytes, got ", input_bytes.size()));
84 | }
85 |
86 | std::vector additional_authenticated_data;
87 | std::vector nonce = {input_bytes.begin(),
88 | input_bytes.begin() + cryptor->NonceSize()};
89 | std::vector ciphertext = {input_bytes.begin() + cryptor->NonceSize(),
90 | input_bytes.end()};
91 |
92 | // The plaintext is always smaller than the ciphertext, so use
93 | // `ciphertext.size()` as an upper bound on the plaintext buffer size.
94 | CleansingVector plaintext(ciphertext.size());
95 | size_t plaintext_size;
96 |
97 | ASYLO_RETURN_IF_ERROR(cryptor->Open(ciphertext, additional_authenticated_data,
98 | nonce, absl::MakeSpan(plaintext),
99 | &plaintext_size));
100 |
101 | return CleansingString(plaintext.begin(), plaintext.end());
102 | }
103 |
104 | } // namespace
105 |
106 | class EnclaveDemo : public TrustedApplication {
107 | public:
108 | EnclaveDemo() = default;
109 |
110 | Status Run(const EnclaveInput &input, EnclaveOutput *output) {
111 | std::string user_message = GetEnclaveUserMessage(input);
112 |
113 | std::string result;
114 | ASYLO_ASSIGN_OR_RETURN(result, EncryptMessage(user_message));
115 |
116 | std::cout << "Encrypted message:" << std::endl << result << std::endl;
117 |
118 | return absl::OkStatus();
119 | }
120 |
121 | // Retrieves user message from |input|.
122 | const std::string GetEnclaveUserMessage(const EnclaveInput &input) {
123 | return input.GetExtension(guide::asylo::quickstart_input).value();
124 | }
125 |
126 | // Populates |enclave_output|->value() with |output_message|. Intended to be
127 | // used by the reader for completing the exercise.
128 | void SetEnclaveOutputMessage(EnclaveOutput *enclave_output,
129 | const std::string &output_message) {
130 | guide::asylo::Demo *output =
131 | enclave_output->MutableExtension(guide::asylo::quickstart_output);
132 | output->set_value(output_message);
133 | }
134 | };
135 |
136 | TrustedApplication *BuildTrustedApplication() { return new EnclaveDemo; }
137 |
138 | } // namespace asylo
139 |
--------------------------------------------------------------------------------
/quickstart/solution/BUILD:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2018 Asylo authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | load("@linux_sgx//:sgx_sdk.bzl", "sgx")
18 | load("@rules_cc//cc:defs.bzl", "cc_proto_library")
19 | load("@rules_proto//proto:defs.bzl", "proto_library")
20 | load("@com_google_asylo//asylo/bazel:asylo.bzl", "cc_unsigned_enclave", "debug_sign_enclave", "enclave_loader")
21 |
22 | licenses(["notice"])
23 |
24 | package(
25 | default_visibility = ["//visibility:public"],
26 | )
27 |
28 | # Example and exercise for using Asylo toolkits.
29 | proto_library(
30 | name = "demo_proto",
31 | srcs = ["demo.proto"],
32 | deps = ["@com_google_asylo//asylo:enclave_proto"],
33 | )
34 |
35 | cc_proto_library(
36 | name = "demo_cc_proto",
37 | deps = [":demo_proto"],
38 | )
39 |
40 | cc_unsigned_enclave(
41 | name = "demo_enclave_unsigned.so",
42 | srcs = ["demo_enclave.cc"],
43 | deps = [
44 | ":demo_cc_proto",
45 | "@com_google_absl//absl/base:core_headers",
46 | "@com_google_absl//absl/strings",
47 | "@com_google_asylo//asylo:enclave_runtime",
48 | "@com_google_asylo//asylo/crypto:aead_cryptor",
49 | "@com_google_asylo//asylo/util:cleansing_types",
50 | "@com_google_asylo//asylo/util:status",
51 | ],
52 | )
53 |
54 | debug_sign_enclave(
55 | name = "demo_enclave.so",
56 | unsigned = "demo_enclave_unsigned.so",
57 | )
58 |
59 | enclave_loader(
60 | name = "quickstart",
61 | srcs = ["demo_driver.cc"],
62 | backends = sgx.backend_labels, # Has SGX loader dependencies
63 | enclaves = {"enclave": ":demo_enclave.so"},
64 | loader_args = ["--enclave_path='{enclave}'"],
65 | deps = [
66 | ":demo_cc_proto",
67 | "@com_google_absl//absl/flags:flag",
68 | "@com_google_absl//absl/flags:parse",
69 | "@com_google_asylo//asylo:enclave_cc_proto",
70 | "@com_google_asylo//asylo:enclave_client",
71 | "@com_google_asylo//asylo/util:logging",
72 | ] + select(
73 | {
74 | "@linux_sgx//:sgx_hw": ["@com_google_asylo//asylo/platform/primitives/sgx:loader_cc_proto"],
75 | "@linux_sgx//:sgx_sim": ["@com_google_asylo//asylo/platform/primitives/sgx:loader_cc_proto"],
76 | },
77 | no_match_error = "quickstart is only configured to use the SGX backends",
78 | ),
79 | )
80 |
--------------------------------------------------------------------------------
/quickstart/solution/demo.proto:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2018 Asylo authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | syntax = "proto2";
18 |
19 | package guide.asylo;
20 |
21 | import "asylo/enclave.proto";
22 |
23 | option java_package = "com.example";
24 | option java_multiple_files = true;
25 | option java_outer_classname = "EnclaveDemoExtension";
26 |
27 | // A custom message to pass in and out of our enclave.
28 | message Demo {
29 | // This string value is used for both user input and enclave output.
30 | optional string value = 1;
31 | enum Action {
32 | UNKNOWN = 0;
33 | ENCRYPT = 1;
34 | DECRYPT = 2;
35 | }
36 | optional Action action = 2;
37 | }
38 |
39 | // The EnclaveInput message that is passed to the enclave can be extended with
40 | // a Demo message to communicate a value our enclave knows to expect.
41 | extend .asylo.EnclaveInput {
42 | optional Demo quickstart_input = 9001;
43 | }
44 |
45 | // The EnclaveOutput message that is passed out of the enclave can be extended
46 | // with a Demo message to communicate a value our driver knows to expect.
47 | extend .asylo.EnclaveOutput {
48 | optional Demo quickstart_output = 9001;
49 | }
50 |
--------------------------------------------------------------------------------
/quickstart/solution/demo_driver.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 | #include
21 |
22 | #include "absl/flags/flag.h"
23 | #include "absl/flags/parse.h"
24 | #include "asylo/client.h"
25 | #include "asylo/enclave.pb.h"
26 | #include "asylo/platform/primitives/sgx/loader.pb.h"
27 | #include "asylo/util/logging.h"
28 | #include "quickstart/solution/demo.pb.h"
29 |
30 | ABSL_FLAG(std::string, enclave_path, "", "Path to enclave to load");
31 | ABSL_FLAG(std::string, message1, "", "The first message to encrypt");
32 | ABSL_FLAG(std::string, message2, "", "The second message to encrypt");
33 | ABSL_FLAG(std::string, ciphertext, "", "The ciphertext message to decrypt");
34 |
35 | // Populates |enclave_input|->value() with |user_message|.
36 | void SetEnclaveUserMessage(asylo::EnclaveInput *enclave_input,
37 | const std::string &user_message,
38 | guide::asylo::Demo::Action action) {
39 | guide::asylo::Demo *user_input =
40 | enclave_input->MutableExtension(guide::asylo::quickstart_input);
41 | user_input->set_value(user_message);
42 | user_input->set_action(action);
43 | }
44 |
45 | // Retrieves encrypted message from |output|. Intended to be used by the reader
46 | // for completing the exercise.
47 | const std::string GetEnclaveOutputMessage(const asylo::EnclaveOutput &output) {
48 | return output.GetExtension(guide::asylo::quickstart_output).value();
49 | }
50 |
51 | int main(int argc, char *argv[]) {
52 | absl::ParseCommandLine(argc, argv);
53 |
54 | LOG_IF(QFATAL, absl::GetFlag(FLAGS_message1).empty() &&
55 | absl::GetFlag(FLAGS_message2).empty() &&
56 | absl::GetFlag(FLAGS_ciphertext).empty())
57 | << "Must specify at least one of --message1, --message2, or --ciphertext "
58 | "flag values";
59 |
60 | // Part 1: Initialization
61 |
62 | asylo::EnclaveManager::Configure(asylo::EnclaveManagerOptions());
63 | auto manager_result = asylo::EnclaveManager::Instance();
64 | LOG_IF(QFATAL, !manager_result.ok()) << "Could not obtain EnclaveManager";
65 |
66 | // Create an EnclaveLoadConfig object.
67 | asylo::EnclaveLoadConfig load_config;
68 | load_config.set_name("demo_enclave");
69 |
70 | // Create an SgxLoadConfig object.
71 | asylo::SgxLoadConfig sgx_config;
72 | asylo::SgxLoadConfig::FileEnclaveConfig file_enclave_config;
73 | file_enclave_config.set_enclave_path(absl::GetFlag(FLAGS_enclave_path));
74 | *sgx_config.mutable_file_enclave_config() = file_enclave_config;
75 | sgx_config.set_debug(true);
76 |
77 | // Set an SGX message extension to load_config.
78 | *load_config.MutableExtension(asylo::sgx_load_config) = sgx_config;
79 |
80 | asylo::EnclaveManager *manager = manager_result.value();
81 | asylo::Status status = manager->LoadEnclave(load_config);
82 | LOG_IF(QFATAL, !status.ok()) << "LoadEnclave failed with: " << status;
83 |
84 | // Part 2: Secure execution
85 |
86 | asylo::EnclaveClient *client = manager->GetClient("demo_enclave");
87 | asylo::EnclaveInput input;
88 | asylo::EnclaveOutput output;
89 |
90 | if (!absl::GetFlag(FLAGS_message1).empty()) {
91 | SetEnclaveUserMessage(&input, absl::GetFlag(FLAGS_message1),
92 | guide::asylo::Demo::ENCRYPT);
93 | status = client->EnterAndRun(input, &output);
94 | LOG_IF(QFATAL, !status.ok()) << "EnterAndRun failed with: " << status;
95 | std::cout << "Encrypted message1 from driver:" << std::endl
96 | << GetEnclaveOutputMessage(output) << std::endl;
97 | }
98 |
99 | if (!absl::GetFlag(FLAGS_message2).empty()) {
100 | SetEnclaveUserMessage(&input, absl::GetFlag(FLAGS_message2),
101 | guide::asylo::Demo::ENCRYPT);
102 | status = client->EnterAndRun(input, &output);
103 | LOG_IF(QFATAL, !status.ok()) << "EnterAndRun failed with: " << status;
104 | std::cout << "Encrypted message2 from driver:" << std::endl
105 | << GetEnclaveOutputMessage(output) << std::endl;
106 | }
107 |
108 | if (!absl::GetFlag(FLAGS_ciphertext).empty()) {
109 | SetEnclaveUserMessage(&input, absl::GetFlag(FLAGS_ciphertext),
110 | guide::asylo::Demo::DECRYPT);
111 | status = client->EnterAndRun(input, &output);
112 | LOG_IF(QFATAL, !status.ok()) << "EnterAndRun failed with: " << status;
113 | std::cout << "Decrypted ciphertext from driver:" << std::endl
114 | << GetEnclaveOutputMessage(output) << std::endl;
115 | }
116 |
117 | // Part 3: Finalization
118 |
119 | asylo::EnclaveFinal empty_final_input;
120 | status = manager->DestroyEnclave(client, empty_final_input);
121 | LOG_IF(QFATAL, !status.ok()) << "DestroyEnclave failed with: " << status;
122 |
123 | return 0;
124 | }
125 |
--------------------------------------------------------------------------------
/quickstart/solution/demo_enclave.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2018 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 |
21 | #include "absl/base/macros.h"
22 | #include "absl/status/status.h"
23 | #include "absl/strings/escaping.h"
24 | #include "absl/strings/str_cat.h"
25 | #include "asylo/crypto/aead_cryptor.h"
26 | #include "asylo/crypto/util/byte_container_view.h"
27 | #include "asylo/trusted_application.h"
28 | #include "asylo/util/cleansing_types.h"
29 | #include "asylo/util/status_macros.h"
30 | #include "asylo/util/statusor.h"
31 | #include "quickstart/solution/demo.pb.h"
32 |
33 | namespace asylo {
34 | namespace {
35 |
36 | // Example 128-bit AES key.
37 | constexpr uint8_t kAesKey128[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
38 | 0x06, 0x07, 0x08, 0x09, 0x10, 0x11,
39 | 0x12, 0x13, 0x14, 0x15};
40 |
41 | // Helper function that adapts absl::BytesToHexString, allowing it to be used
42 | // with ByteContainerView.
43 | std::string BytesToHexString(ByteContainerView bytes) {
44 | return absl::BytesToHexString(absl::string_view(
45 | reinterpret_cast(bytes.data()), bytes.size()));
46 | }
47 |
48 | // Encrypts a message against `kAesKey128` and returns a 12-byte nonce followed
49 | // by authenticated ciphertext, encoded as a hex string.
50 | const StatusOr EncryptMessage(const std::string &message) {
51 | std::unique_ptr cryptor;
52 | ASYLO_ASSIGN_OR_RETURN(cryptor,
53 | AeadCryptor::CreateAesGcmSivCryptor(kAesKey128));
54 |
55 | std::vector additional_authenticated_data;
56 | std::vector nonce(cryptor->NonceSize());
57 | std::vector ciphertext(message.size() + cryptor->MaxSealOverhead());
58 | size_t ciphertext_size;
59 |
60 | ASYLO_RETURN_IF_ERROR(cryptor->Seal(
61 | message, additional_authenticated_data, absl::MakeSpan(nonce),
62 | absl::MakeSpan(ciphertext), &ciphertext_size));
63 |
64 | return absl::StrCat(BytesToHexString(nonce), BytesToHexString(ciphertext));
65 | }
66 |
67 | // Decrypts a message using `kAesKey128`. Expects `nonce_and_ciphertext` to be
68 | // encoded as a hex string, and lead with a 12-byte nonce. Intended to be
69 | // used by the reader for completing the exercise.
70 | const StatusOr DecryptMessage(
71 | const std::string &nonce_and_ciphertext) {
72 | std::string input_bytes = absl::HexStringToBytes(nonce_and_ciphertext);
73 |
74 | std::unique_ptr cryptor;
75 | ASYLO_ASSIGN_OR_RETURN(cryptor,
76 | AeadCryptor::CreateAesGcmSivCryptor(kAesKey128));
77 |
78 | if (input_bytes.size() < cryptor->NonceSize()) {
79 | return Status(
80 | absl::StatusCode::kInvalidArgument,
81 | absl::StrCat("Input too short: expected at least ",
82 | cryptor->NonceSize(), " bytes, got ", input_bytes.size()));
83 | }
84 |
85 | std::vector additional_authenticated_data;
86 | std::vector nonce = {input_bytes.begin(),
87 | input_bytes.begin() + cryptor->NonceSize()};
88 | std::vector ciphertext = {input_bytes.begin() + cryptor->NonceSize(),
89 | input_bytes.end()};
90 |
91 | // The plaintext is always smaller than the ciphertext, so use
92 | // `ciphertext.size()` as an upper bound on the plaintext buffer size.
93 | CleansingVector plaintext(ciphertext.size());
94 | size_t plaintext_size;
95 |
96 | ASYLO_RETURN_IF_ERROR(cryptor->Open(ciphertext, additional_authenticated_data,
97 | nonce, absl::MakeSpan(plaintext),
98 | &plaintext_size));
99 |
100 | return CleansingString(plaintext.begin(), plaintext.end());
101 | }
102 |
103 | } // namespace
104 |
105 | class EnclaveDemo : public TrustedApplication {
106 | public:
107 | EnclaveDemo() = default;
108 |
109 | Status Run(const EnclaveInput &input, EnclaveOutput *output) {
110 | std::string user_message = GetEnclaveUserMessage(input);
111 |
112 | switch (GetEnclaveUserAction(input)) {
113 | case guide::asylo::Demo::ENCRYPT: {
114 | std::string result;
115 | ASYLO_ASSIGN_OR_RETURN(result, EncryptMessage(user_message));
116 | SetEnclaveOutputMessage(output, result);
117 | break;
118 | }
119 | case guide::asylo::Demo::DECRYPT: {
120 | CleansingString result;
121 | ASYLO_ASSIGN_OR_RETURN(result, DecryptMessage(user_message));
122 | SetEnclaveOutputMessage(output, result);
123 | break;
124 | }
125 | default:
126 | return absl::InvalidArgumentError("Action unspecified");
127 | }
128 |
129 | return absl::OkStatus();
130 | }
131 |
132 | // Retrieves user message from |input|.
133 | const std::string GetEnclaveUserMessage(const EnclaveInput &input) {
134 | return input.GetExtension(guide::asylo::quickstart_input).value();
135 | }
136 |
137 | // Retrieves user action from |input|.
138 | guide::asylo::Demo::Action GetEnclaveUserAction(const EnclaveInput &input) {
139 | return input.GetExtension(guide::asylo::quickstart_input).action();
140 | }
141 |
142 | // Populates |enclave_output|->value() with |output_message|. Intended to be
143 | // used by the reader for completing the exercise.
144 | void SetEnclaveOutputMessage(EnclaveOutput *enclave_output,
145 | absl::string_view output_message) {
146 | guide::asylo::Demo *output =
147 | enclave_output->MutableExtension(guide::asylo::quickstart_output);
148 | output->set_value(std::string(output_message));
149 | }
150 | };
151 |
152 | TrustedApplication *BuildTrustedApplication() { return new EnclaveDemo; }
153 |
154 | } // namespace asylo
155 |
--------------------------------------------------------------------------------
/redis/BUILD:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright 2019 Asylo authors
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 | #
16 |
17 | load("@linux_sgx//:sgx_sdk.bzl", "sgx", "sgx_enclave_configuration")
18 | load("@rules_cc//cc:defs.bzl", "cc_library")
19 | load(
20 | "@com_google_asylo//asylo/bazel:asylo.bzl",
21 | "cc_enclave_binary",
22 | "enclave_test",
23 | )
24 | load("@com_google_asylo//asylo/bazel:copts.bzl", "ASYLO_DEFAULT_COPTS")
25 |
26 | licenses(["notice"])
27 |
28 | # An implementation of ApplicationConfig() that returns an EnclaveConfig with
29 | # an SGX local assertion authority config.
30 | cc_library(
31 | name = "redis_enclave_config",
32 | srcs = ["redis_enclave_config.cc"],
33 | visibility = ["//visibility:public"],
34 | deps = [
35 | "@com_google_asylo//asylo:enclave_cc_proto",
36 | "@com_google_asylo//asylo/identity:descriptions",
37 | "@com_google_asylo//asylo/identity:enclave_assertion_authority_config_cc_proto",
38 | "@com_google_asylo//asylo/identity/attestation/sgx:sgx_local_assertion_authority_config_cc_proto",
39 | "@com_google_asylo//asylo/util:logging",
40 | ],
41 | )
42 |
43 | # The SGX configuration to run Redis Server inside an enclave.
44 | sgx_enclave_configuration(
45 | name = "redis_enclave_configuration",
46 | heap_max_size = "0x1000000",
47 | stack_max_size = "0x400000",
48 | )
49 |
50 | # The whole application wrapper target that runs Redis server inside an enclave.
51 | cc_enclave_binary(
52 | name = "asylo_redis",
53 | application_enclave_config = ":redis_enclave_config",
54 | enclave_build_config = ":redis_enclave_configuration",
55 | deps = ["@com_github_antirez_redis//:redis_main"],
56 | )
57 |
58 | enclave_test(
59 | name = "redis_test",
60 | srcs = ["redis_test.cc"],
61 | backend_dependent_data = [
62 | ":asylo_redis_host_loader",
63 | ],
64 | backends = sgx.backend_labels,
65 | data = ["@com_github_antirez_redis//:redis_cli_bin"],
66 | tags = ["exclusive"],
67 | test_args = [
68 | "--server_path=$(rootpath :asylo_redis_host_loader)",
69 | "--client_path=$(rootpath @com_github_antirez_redis//:redis_cli_bin)",
70 | ],
71 | deps = [
72 | "@bazel_tools//tools/cpp/runfiles",
73 | "@com_google_absl//absl/base:core_headers",
74 | "@com_google_absl//absl/flags:flag",
75 | "@com_google_absl//absl/memory",
76 | "@com_google_absl//absl/strings",
77 | "@com_google_absl//absl/synchronization",
78 | "@com_google_asylo//asylo/test/util:exec_tester",
79 | "@com_google_asylo//asylo/test/util:status_matchers",
80 | "@com_google_asylo//asylo/test/util:test_flags",
81 | "@com_google_asylo//asylo/test/util:test_main",
82 | "@com_google_asylo//asylo/util:status",
83 | "@com_google_googletest//:gtest",
84 | ],
85 | )
86 |
--------------------------------------------------------------------------------
/redis/redis_enclave_config.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include "asylo/enclave.pb.h"
20 | #include "asylo/identity/attestation/sgx/sgx_local_assertion_authority_config.pb.h"
21 | #include "asylo/identity/descriptions.h"
22 | #include "asylo/identity/enclave_assertion_authority_config.pb.h"
23 | #include "asylo/util/logging.h"
24 |
25 | // The attestation domain is expected to be a 16-byte unique identifier.
26 | constexpr char kAttestationDomain[] = "A 16-byte string";
27 |
28 | extern "C" asylo::EnclaveConfig GetApplicationConfig() {
29 | asylo::EnclaveAssertionAuthorityConfig assertion_authority_config;
30 | asylo::SetSgxLocalAssertionDescription(
31 | assertion_authority_config.mutable_description());
32 |
33 | asylo::SgxLocalAssertionAuthorityConfig sgx_local_assertion_authority_config;
34 | sgx_local_assertion_authority_config.set_attestation_domain(
35 | kAttestationDomain);
36 | CHECK(sgx_local_assertion_authority_config.SerializeToString(
37 | assertion_authority_config.mutable_config()));
38 |
39 | asylo::EnclaveConfig enclave_config;
40 | *enclave_config.add_enclave_assertion_authority_configs() =
41 | std::move(assertion_authority_config);
42 |
43 | return enclave_config;
44 | }
45 |
--------------------------------------------------------------------------------
/remote/bouncing_circles/README.md:
--------------------------------------------------------------------------------
1 |
21 |
22 | ## Introduction
23 |
24 | This guide demonstrates more elaborate usage of Asylo with a Remote Backend. It
25 | assumes the reader has knowledge introduced in the
26 | [Remote Quickstart Guide](https://asylo.dev/docs/guides/remote_quickstart.html).
27 |
28 | The bouncing circles web application uses four separate enclaves to track four
29 | circles. A simple web server accesses each enclave via the remote enclave
30 | backend. Each enclave, once initialized, holds color, location, radius and speed
31 | of the circle it owns, rendering them isolated from the outer world. The web
32 | application makes an EnterAndRun call to each of the 4 enclaves, gets back
33 | color, location and radius and draws the circle.
34 |
35 | This example provides two frameworks that are accessed identically by the remote
36 | backend: local and remote. Both of them provision RemoteEnclaveProxyServer, but
37 | do it differently:
38 |
39 | - local version runs the enclaves on the same machine as the application
40 |
41 | - remote version runs the enclaves on an SGX-enabled machine while the Web
42 | Application can be run on a non-SGX machine.
43 |
44 | ## Local version - still remote backend, but both running on the same machine
45 |
46 | ### Building
47 |
48 | To build the application and the enclaves:
49 |
50 | ```bash
51 | export CONFIG_TYPE=sgx # Or sgx-sim if not running on SGX-enabled hardware.
52 | bazel build :web_application --config=${CONFIG_TYPE} --define=ASYLO_REMOTE=1
53 | ```
54 |
55 | Note: The `CONFIG_TYPE=sgx` flag selects our enclave cross compiler toolchain,
56 | which builds code to run inside enclaves. To run on non-SGX hardware, specify
57 | simulated SGX flag `CONFIG_TYPE=sgx-sim`.
58 |
59 | ### Running
60 |
61 | To run the program, invoke the application binary (from bazel-bin):
62 |
63 | ```bash
64 | $(bazel info bazel-bin)/remote/bouncing_circles/web_application \
65 | --remote_proxy="$(bazel info bazel-bin)/remote/bouncing_circles/web_application"
66 | ```
67 |
68 | and then open a browser window at `http://:8888/` and follow the
69 | link named "circles".
70 |
71 | ## Remote backend running enclaves on another machine than the application
72 |
73 | The previous demo launched the application with local provisioning.
74 |
75 | To make it truly remote, we will now now utilize remote provisioning with our
76 | example remote
77 | [provision server](/remote/provision_server)
78 | and run the same application with enclaves deployed on another docker image.
79 |
80 | First, if you haven't already done so, download the Asylo SDK and Examples
81 | repos:
82 |
83 | ```bash
84 | export ASYLO_SDK=~/asylo-sdk
85 | git clone https://github.com/google/asylo.git "${ASYLO_SDK}"
86 | export MY_PROJECT=~/asylo-examples
87 | mkdir -p "${MY_PROJECT}"
88 | wget -q -O - https://github.com/google/asylo-examples/archive/master.tar.gz | \
89 | tar -zxv --strip 1 --directory "${MY_PROJECT}"
90 | ```
91 |
92 | Next, run the provision server:
93 |
94 | ```bash
95 | docker run -it --net=host \
96 | -v ${ASYLO_SDK}:/opt/asylo/sdk \
97 | -v ${MY_PROJECT}:/opt/asylo/examples \
98 | -w /opt/asylo/examples/remote/provision_server \
99 | gcr.io/asylo-framework/asylo:latest \
100 | ./build.sh
101 | ```
102 |
103 | Once the provisioning server reports that it is listening to port `4321`
104 | (configurable), run the container with the following command:
105 |
106 | ```bash
107 | export CONFIG_TYPE=sgx # Or sgx-sim if Remote Provision server isn't running on SGX-enabled hardware.
108 | docker run -it --net=host \
109 | -v ${ASYLO_SDK}:/opt/asylo/sdk \
110 | -v ${MY_PROJECT}:/opt/asylo/examples \
111 | -w /opt/asylo/examples/remote/bouncing_circles \
112 | gcr.io/asylo-framework/asylo:latest \
113 | ./build.sh ${CONFIG_TYPE}
114 | ```
115 |
116 | After the application started, open a browser window at `http://:8888/` and follow the link named "circles".
118 |
--------------------------------------------------------------------------------
/remote/bouncing_circles/build.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Script for building the bouncing circles example.
4 | #
5 | # Asylo toolchain has difficulties building with two --config types. This script
6 | # allows users to build the example enclaves with --config=sgx or sgx-sim, and
7 | # the rest of the application without the --config= designation.
8 | #
9 | # Instructions for use:
10 | # Set environment variables ASYLO_SDK, MY_PROJECT, and CONFIG_TYPE.
11 | # -- ASYLO_SDK: Path to the Asylo sdk.
12 | # -- MY_PROJECT: Path to the Examples repo.
13 | # -- CONFIG_TYPE: One of {sgx, sgx-sim}
14 | # Start the provision server with the directions given at asylo/examples/remote/provision_server.
15 | # ```bash
16 | # docker run --it --net=host \
17 | # -v ${ASYLO_SDK}:/opt/asylo/sdk \
18 | # -v ${MY_PROJECT}:/opt/asylo/examples \
19 | # -w /opt/asylo/examples/remote/bouncing_circles \
20 | # gcr.io/asylo-framework/asylo:latest \
21 | # ./build.sh ${CONFIG_TYPE}
22 | # ```
23 | #
24 | # then open a browser window at
25 | # http://:8888/
26 | # and follow the link
27 |
28 | # If any command fails exit.
29 | set -e
30 |
31 | # Export all variables as environment variables.
32 | set -a
33 |
34 |
35 | # Default configuration for CONFIG_TYPE.
36 | CONFIG_TYPE_DEFAULT=sgx
37 |
38 | # Command line argument: Allows selection of local backend, if one is not
39 | # selected it defaults to $CONFIG_DEFAULT
40 | CONFIG_TYPE=${1:-$CONFIG_TYPE_DEFAULT}
41 |
42 | # Set the ENCLAVE_TAG based on the CONFIG_TYPE. ENCLAVE_TAG is used as part of
43 | # the ENCLAVE_TARGET.
44 | if [ "$CONFIG_TYPE" == "sgx" ]; then
45 | ENCLAVE_TAG="sgx_hw";
46 | elif [ "$CONFIG_TYPE" == "sgx-sim" ]; then
47 | ENCLAVE_TAG="sgx_sim";
48 | fi
49 |
50 | if [ -z "$ENCLAVE_TAG" ]; then
51 | echo "CONFIG_TYPE must be one of sgx or sgx-sim";
52 | exit;
53 | fi
54 | bazel clean
55 |
56 | # Build the circle enclaves.
57 | for ENCLAVE_NUM in {0..3}
58 | do
59 | bazel build --config=${CONFIG_TYPE} \
60 | //remote/bouncing_circles:circle_enclave_${ENCLAVE_NUM}_debug.so
61 | done
62 |
63 | BAZEL_BIN_PATH=$(bazel info bazel-bin)
64 | CIRCLES_PATH=${BAZEL_BIN_PATH}/remote/bouncing_circles
65 |
66 | # Path where bazel puts generated files - can be but not always the same as
67 | # bazel-bin.
68 | BAZEL_GEN_PATH=$(bazel info bazel-genfiles)
69 | PROVISION_PATH=${BAZEL_GEN_PATH}/remote/provision_server
70 | bazel run //remote/bouncing_circles:web_application_remote -- \
71 | --port=8888 \
72 | --security_type=ssl \
73 | --ssl_key=${PROVISION_PATH}/server.key \
74 | --ssl_cert=${PROVISION_PATH}/server.crt \
75 | --enclave_binary_paths=${CIRCLES_PATH}/circle_enclave_0_debug_${CONFIG_TYPE}.so,${CIRCLES_PATH}/circle_enclave_1_debug_${CONFIG_TYPE}.so,${CIRCLES_PATH}/circle_enclave_2_debug_${CONFIG_TYPE}.so,${CIRCLES_PATH}/circle_enclave_3_debug_${CONFIG_TYPE}.so \
76 | --remote_provision_server=[::1]:4321 \
77 | --local_client_name=[::1]
78 |
--------------------------------------------------------------------------------
/remote/bouncing_circles/circle_client.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #ifndef ASYLO_EXAMPLES_REMOTE_BOUNCING_CIRCLES_CIRCLE_CLIENT_H_
20 | #define ASYLO_EXAMPLES_REMOTE_BOUNCING_CIRCLES_CIRCLE_CLIENT_H_
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 | #include "absl/strings/string_view.h"
29 |
30 | namespace asylo {
31 |
32 | class CircleStatus {
33 | public:
34 | CircleStatus() = default;
35 | virtual ~CircleStatus() = default;
36 |
37 | virtual std::tuple Update() = 0;
38 |
39 | static void InitializeGlobal(size_t n, absl::string_view enclave_prefix,
40 | int32_t width, int32_t height);
41 | static std::vector> *circles();
42 | };
43 |
44 | } // namespace asylo
45 |
46 | #endif // ASYLO_EXAMPLES_REMOTE_BOUNCING_CIRCLES_CIRCLE_CLIENT_H_
47 |
--------------------------------------------------------------------------------
/remote/bouncing_circles/circle_enclave.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include
20 |
21 | #include "absl/memory/memory.h"
22 | #include "absl/status/status.h"
23 | #include "absl/strings/str_cat.h"
24 | #include "absl/strings/string_view.h"
25 | #include "asylo/trusted_application.h"
26 | #include "asylo/util/logging.h"
27 | #include "asylo/util/status.h"
28 | #include "remote/bouncing_circles/circles.pb.h"
29 |
30 | namespace asylo {
31 | namespace {
32 |
33 | class CircleStatus {
34 | public:
35 | CircleStatus(int32_t width, int32_t height)
36 | : width_(width),
37 | height_(height),
38 | x_(std::min((CENTER_X) < 0 ? width + (CENTER_X) : (CENTER_X), width)),
39 | y_(std::min((CENTER_Y) < 0 ? height + (CENTER_Y) : (CENTER_Y), height)),
40 | radius_(std::max(2, (CIRCLE_RADIUS))),
41 | color_(CIRCLE_COLOR) {}
42 |
43 | void Update() {
44 | if (x_ <= width_ / 10) {
45 | step_x_ = +(SPEED_X);
46 | } else if (x_ >= width_ * 9 / 10) {
47 | step_x_ = -(SPEED_X);
48 | }
49 | if (y_ <= height_ / 10) {
50 | step_y_ = +(SPEED_Y);
51 | } else if (y_ >= height_ * 9 / 10) {
52 | step_y_ = -(SPEED_Y);
53 | }
54 | x_ += step_x_;
55 | y_ += step_y_;
56 | if (radius_ <= 10) {
57 | step_radius_ = +2;
58 | } else if (radius_ >= 50) {
59 | step_radius_ = -2;
60 | }
61 | radius_ += step_radius_;
62 | }
63 |
64 | int32_t width() const { return width_; }
65 | int32_t height() const { return height_; }
66 | int32_t x() const { return x_; }
67 | int32_t y() const { return y_; }
68 | int32_t radius() const { return radius_; }
69 | std::string color() const { return color_; }
70 |
71 | private:
72 | const int32_t width_;
73 | const int32_t height_;
74 |
75 | int32_t x_;
76 | int32_t y_;
77 | int32_t radius_;
78 | std::string color_;
79 |
80 | int32_t step_x_ = (SPEED_X);
81 | int32_t step_y_ = (SPEED_Y);
82 | int32_t step_radius_ = 10;
83 | };
84 |
85 | class CirclesEnclave : public TrustedApplication {
86 | public:
87 | CirclesEnclave() = default;
88 |
89 | asylo::Status Run(const asylo::EnclaveInput &input,
90 | asylo::EnclaveOutput *output) override {
91 | if (input.HasExtension(bouncing_circles::enclave_setup_input)) {
92 | // Output attached and left empty.
93 | output->MutableExtension(bouncing_circles::enclave_setup_output);
94 | return HandleSetup(
95 | input.GetExtension(bouncing_circles::enclave_setup_input));
96 | }
97 |
98 | if (input.HasExtension(bouncing_circles::enclave_update_position_input)) {
99 | // Input unused.
100 | return HandleUpdate(output->MutableExtension(
101 | bouncing_circles::enclave_update_position_output));
102 | }
103 |
104 | return absl::InvalidArgumentError("Missing extension on EnclaveInput.");
105 | }
106 |
107 | private:
108 | Status HandleSetup(const bouncing_circles::CirclesSetupInput &input) {
109 | if (input.height() >= input.width()) {
110 | return absl::FailedPreconditionError(
111 | absl::StrCat("Height=", input.height(), " weight=", input.width()));
112 | }
113 | if (managed_circle_) {
114 | return absl::AlreadyExistsError("Circle already created");
115 | }
116 | managed_circle_ =
117 | absl::make_unique(input.width(), input.height());
118 | return absl::OkStatus();
119 | }
120 |
121 | Status HandleUpdate(bouncing_circles::CirclesUpdatePositionOutput *output) {
122 | if (!managed_circle_) {
123 | return absl::NotFoundError("Calling Update before Setup");
124 | }
125 | managed_circle_->Update();
126 | output->set_x(managed_circle_->x());
127 | output->set_y(managed_circle_->y());
128 | output->set_radius(managed_circle_->radius());
129 | output->set_color(managed_circle_->color());
130 | return absl::OkStatus();
131 | }
132 |
133 | std::unique_ptr managed_circle_;
134 | };
135 |
136 | } // namespace
137 |
138 | TrustedApplication *BuildTrustedApplication() { return new CirclesEnclave(); }
139 |
140 | } // namespace asylo
141 |
--------------------------------------------------------------------------------
/remote/bouncing_circles/circles.proto:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright 2019 Asylo authors
3 | //
4 | // Licensed under the Apache License, Version 2.0 (the "License");
5 | // you may not use this file except in compliance with the License.
6 | // You may obtain a copy of the License at
7 | //
8 | // http://www.apache.org/licenses/LICENSE-2.0
9 | //
10 | // Unless required by applicable law or agreed to in writing, software
11 | // distributed under the License is distributed on an "AS IS" BASIS,
12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | // See the License for the specific language governing permissions and
14 | // limitations under the License.
15 | //
16 |
17 | syntax = "proto2";
18 |
19 | package bouncing_circles;
20 |
21 | import "asylo/enclave.proto";
22 |
23 | // Extensions to EnclaveInput for use with Circles enclave.
24 |
25 | message CirclesSetupInput {
26 | optional int32 width = 1;
27 | optional int32 height = 2;
28 | }
29 |
30 | message CirclesSetupOutput {}
31 |
32 | message CirclesUpdatePositionInput {}
33 |
34 | message CirclesUpdatePositionOutput {
35 | optional int32 x = 1;
36 | optional int32 y = 2;
37 | optional int32 radius = 3;
38 | optional string color = 4;
39 | }
40 |
41 | extend asylo.EnclaveInput {
42 | optional CirclesSetupInput enclave_setup_input = 9080;
43 | optional CirclesUpdatePositionInput enclave_update_position_input = 9090;
44 | }
45 |
46 | extend asylo.EnclaveOutput {
47 | optional CirclesSetupOutput enclave_setup_output = 9081;
48 | optional CirclesUpdatePositionOutput enclave_update_position_output = 9091;
49 | }
50 |
--------------------------------------------------------------------------------
/remote/bouncing_circles/web_server.h:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #ifndef ASYLO_EXAMPLES_REMOTE_BOUNCING_CIRCLES_WEB_SERVER_H_
20 | #define ASYLO_EXAMPLES_REMOTE_BOUNCING_CIRCLES_WEB_SERVER_H_
21 |
22 | // Based on NWEB.C (see https://github.com/ankushagarwal/nweb)
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #include "absl/container/flat_hash_map.h"
31 | #include "asylo/util/mutex_guarded.h"
32 |
33 | namespace asylo {
34 |
35 | // Test web server that can only be used in tests.
36 | // It only serves requests that are registered; does not serve any files.
37 | class WebServer {
38 | public:
39 | // In a request '/uri?p1=v1&p2=v2&...' uri determines the handler and
40 | // everything after '?' is parsed into WebRequest as parms['p1'] = 'v1' etc.
41 | // If there is no '?', parms is empty.
42 | struct WebRequest {
43 | absl::flat_hash_map parms;
44 | };
45 |
46 | // Response and its type
47 | struct WebResponse {
48 | std::string contents;
49 | std::string type = "text/html";
50 | };
51 |
52 | // Type used for handler callbacks.
53 | typedef std::function UriHandler;
54 |
55 | // Factory method; the only one allowed to create the server.
56 | static std::unique_ptr Create(int port, size_t max_worker_threads);
57 |
58 | ~WebServer() = default;
59 |
60 | WebServer(const WebServer &other) = delete;
61 | WebServer &operator=(const WebServer &other) = delete;
62 |
63 | // Blocks until server stops, returns immediately if server is not running.
64 | void Wait();
65 |
66 | void StartServer();
67 | void StopServer();
68 |
69 | void RegisterHandler(absl::string_view uri_pattern, UriHandler handler);
70 | void UnregisterHandler(absl::string_view uri_pattern);
71 |
72 | // Returns the handler for the given uri. Requires a handler is registered.
73 | const UriHandler GetHandler(absl::string_view uri_pattern) const;
74 |
75 | // Assign request to an available worker (block if none is available).
76 | void AssignRequest(int socket_fd);
77 |
78 | // Actually assigned port. Valid only after call to StartServer().
79 | int port() const { return port_; }
80 |
81 | private:
82 | // Worker thread.
83 | struct WorkerThread {
84 | WorkerThread() : state(State()) {}
85 | struct State {
86 | bool must_exit = false;
87 | int socket_fd = -1; // Negative if no request is assigned.
88 | };
89 | void WorkerThreadRunner(WebServer *server);
90 | MutexGuarded state;
91 | std::unique_ptr thread; // Assigned once, under workers lock.
92 | };
93 |
94 | // Constructor is private, so that only factory method can create the server.
95 | WebServer(int port, size_t max_worker_threads);
96 |
97 | // Server status.
98 | int port_;
99 | const size_t max_worker_threads_;
100 | const absl::Time start_time_;
101 |
102 | // Registered request handlers.
103 | MutexGuarded> handlers_;
104 |
105 | // Worker threads (no more than max_worker_threads_ at any time).
106 | MutexGuarded> workers_;
107 | };
108 |
109 | } // namespace asylo
110 |
111 | #endif // ASYLO_EXAMPLES_REMOTE_BOUNCING_CIRCLES_WEB_SERVER_H_
112 |
--------------------------------------------------------------------------------
/remote/bouncing_circles/web_server_test.cc:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2019 Asylo authors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | #include "remote/bouncing_circles/web_server.h"
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 |
27 | #include