Skip to content

Commit 16e2ea6

Browse files
committed
Refactor TLS trust anchors to use TrustAnchorProvider in Rust and C++
Replaces static trust anchor path/DER configuration fields with a dynamic TrustAnchorProvider interface across both Rust and C++ Oak Session TLS libraries. This allows dynamic and per-session trust anchor resolution. - Added TrustAnchorProvider interface. - Updated ServerContextConfig and ClientContextConfig to take a provider. - In C++, removed early SSL_CTX_load_verify_locations path loading, and instead fetched the trust anchor from the provider per session, adding it dynamically via SSL_set1_verify_cert_store. - Updated test suites to use static or file-based provider implementations. - Refactored example gRPC clients to match the new API. Change-Id: I3a96418d5da0a3c3e3feb1997e34afa56a6a6964
1 parent 5f82059 commit 16e2ea6

11 files changed

Lines changed: 302 additions & 110 deletions

File tree

oak_private_memory/test/tls_client_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ fn test_server_context() -> OakSessionTlsServerContext {
6868

6969
OakSessionTlsServerContext::create(ServerContextConfig {
7070
tls_identity_provider: utils::create_static_cert_identity_provider(server_key, server_cert),
71-
client_trust_anchor_der: Some(ca_cert),
71+
client_trust_anchor_provider: Some(utils::create_static_trust_anchor_provider(ca_cert)),
7272
custom_cert_verifier: None,
7373
})
7474
.expect("failed to create TLS server context")
@@ -80,7 +80,7 @@ fn test_client_context() -> OakSessionTlsClientContext {
8080
let client_key = load_test_key("oak_session/tls/testing/test_client.key");
8181

8282
OakSessionTlsClientContext::create(ClientContextConfig {
83-
server_trust_anchor_der: Some(ca_cert),
83+
server_trust_anchor_provider: Some(utils::create_static_trust_anchor_provider(ca_cert)),
8484
tls_identity_provider: Some(utils::create_static_cert_identity_provider(
8585
client_key,
8686
client_cert,

oak_session/tls/example/grpc/client_main.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,15 @@ void RunClient() {
6868
TlsIdentity current_identity_;
6969
};
7070

71+
auto trust_anchor =
72+
util::CreateTrustAnchorFromFile(absl::GetFlag(FLAGS_ca_cert));
73+
if (!trust_anchor.ok()) {
74+
LOG(FATAL) << "Failed to load trust anchor: " << trust_anchor.status();
75+
}
76+
7177
absl::StatusOr<std::unique_ptr<OakSessionTlsContext>> tls_context =
7278
OakSessionTlsContext::Create(ClientContextConfig{
73-
.server_trust_anchor_path = absl::GetFlag(FLAGS_ca_cert),
79+
.server_trust_anchor_provider = std::move(*trust_anchor),
7480
.tls_identity_provider = std::make_unique<StaticIdentityProvider>(
7581
*client_key_asn1, *client_cert_asn1),
7682
});

oak_session/tls/oak_session_tls.cc

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,28 +109,21 @@ OakSessionTlsContext::Create(ServerContextConfig config) {
109109
SSL_GROUP_X25519};
110110
SSL_CTX_set1_group_ids(ctx.get(), kGroups, std::size(kGroups));
111111

112-
if (config.client_trust_anchor_path.has_value() ||
112+
if (config.client_trust_anchor_provider != nullptr ||
113113
config.custom_cert_verifier.has_value()) {
114114
SSL_CTX_set_verify(
115115
ctx.get(), SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
116116

117117
if (config.custom_cert_verifier.has_value()) {
118118
SSL_CTX_set_cert_verify_callback(ctx.get(), VerifyCallback, nullptr);
119119
}
120-
121-
if (config.client_trust_anchor_path.has_value()) {
122-
if (SSL_CTX_load_verify_locations(
123-
ctx.get(), config.client_trust_anchor_path->c_str(), nullptr) !=
124-
1) {
125-
return absl::InternalError("Failed to load trust anchor for client");
126-
}
127-
}
128120
}
129121

130122
return std::make_unique<OakSessionTlsContext>(
131123
OakSessionTlsMode::kServer, std::move(ctx),
132124
std::move(config.tls_identity_provider),
133-
std::move(config.custom_cert_verifier));
125+
std::move(config.client_trust_anchor_provider),
126+
std::move(config.custom_cert_verifier), "");
134127
}
135128

136129
absl::StatusOr<std::unique_ptr<OakSessionTlsContext>>
@@ -149,17 +142,9 @@ OakSessionTlsContext::Create(ClientContextConfig config) {
149142
SSL_GROUP_X25519};
150143
SSL_CTX_set1_group_ids(ctx.get(), kGroups, std::size(kGroups));
151144

152-
if (config.server_trust_anchor_path.has_value()) {
153-
if (SSL_CTX_load_verify_locations(ctx.get(),
154-
config.server_trust_anchor_path->c_str(),
155-
nullptr) != 1) {
156-
return absl::InternalError("Failed to load trust anchor for server");
157-
}
158-
}
159-
160145
// Enable server certificate verification if either a trust anchor or custom
161146
// verifier is configured.
162-
if (config.server_trust_anchor_path.has_value() ||
147+
if (config.server_trust_anchor_provider != nullptr ||
163148
config.custom_cert_verifier.has_value()) {
164149
SSL_CTX_set_verify(ctx.get(), SSL_VERIFY_PEER, nullptr);
165150
}
@@ -174,6 +159,7 @@ OakSessionTlsContext::Create(ClientContextConfig config) {
174159
return std::make_unique<OakSessionTlsContext>(
175160
OakSessionTlsMode::kClient, std::move(ctx),
176161
std::move(config.tls_identity_provider),
162+
std::move(config.server_trust_anchor_provider),
177163
std::move(config.custom_cert_verifier), std::move(expected_server_name));
178164
}
179165

@@ -190,15 +176,26 @@ OakSessionTlsContext::NewSession() {
190176
identity_ptr = &*identity;
191177
}
192178

179+
std::optional<std::string> trust_anchor;
180+
const std::string* trust_anchor_ptr = nullptr;
181+
if (trust_anchor_provider_ != nullptr) {
182+
auto anchor_or = trust_anchor_provider_->GetTrustAnchor();
183+
if (!anchor_or.ok()) {
184+
return anchor_or.status();
185+
}
186+
trust_anchor = std::move(*anchor_or);
187+
trust_anchor_ptr = &*trust_anchor;
188+
}
189+
193190
switch (mode_) {
194191
case OakSessionTlsMode::kClient:
195192
return OakSessionTlsInitializer::CreateClient(
196-
ssl_ctx_.get(), expected_server_name_, identity_ptr,
193+
ssl_ctx_.get(), expected_server_name_, identity_ptr, trust_anchor_ptr,
197194
custom_cert_verifier_.has_value() ? &*custom_cert_verifier_
198195
: nullptr);
199196
case OakSessionTlsMode::kServer:
200197
return OakSessionTlsInitializer::CreateServer(
201-
ssl_ctx_.get(), identity_ptr,
198+
ssl_ctx_.get(), identity_ptr, trust_anchor_ptr,
202199
custom_cert_verifier_.has_value() ? &*custom_cert_verifier_
203200
: nullptr);
204201
}
@@ -265,6 +262,7 @@ absl::StatusOr<InitializedSession> OakSessionTlsContext::NewInitializedSession(
265262
absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>>
266263
OakSessionTlsInitializer::Create(
267264
SSL_CTX* ssl_ctx, const TlsIdentity* tls_identity,
265+
const std::string* trust_anchor,
268266
const CustomCertVerifier* custom_cert_verifier) {
269267
auto ssl = bssl::UniquePtr<SSL>(SSL_new(ssl_ctx));
270268
if (!ssl) {
@@ -279,6 +277,27 @@ OakSessionTlsInitializer::Create(
279277
}
280278
}
281279

280+
if (trust_anchor != nullptr) {
281+
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(trust_anchor->data());
282+
X509* cert = d2i_X509(nullptr, &ptr, trust_anchor->size());
283+
if (cert == nullptr) {
284+
return absl::InternalError("failed to parse trust anchor certificate");
285+
}
286+
X509_STORE* store = X509_STORE_new();
287+
if (store == nullptr) {
288+
X509_free(cert);
289+
return absl::InternalError("failed to create certificate store");
290+
}
291+
if (X509_STORE_add_cert(store, cert) != 1) {
292+
X509_free(cert);
293+
X509_STORE_free(store);
294+
return absl::InternalError("failed to add certificate to store");
295+
}
296+
X509_free(cert);
297+
SSL_set1_verify_cert_store(ssl.get(), store);
298+
X509_STORE_free(store);
299+
}
300+
282301
// Enable the BIO API for this SSL instance.
283302
BIO* rbio = BIO_new(BIO_s_mem());
284303
if (rbio == nullptr) {
@@ -314,10 +333,10 @@ OakSessionTlsInitializer::Create(
314333
absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>>
315334
OakSessionTlsInitializer::CreateClient(
316335
SSL_CTX* ssl_ctx, const std::string& expected_server_name,
317-
const TlsIdentity* tls_identity,
336+
const TlsIdentity* tls_identity, const std::string* trust_anchor,
318337
const CustomCertVerifier* custom_cert_verifier) {
319338
absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>> initializer =
320-
OakSessionTlsInitializer::Create(ssl_ctx, tls_identity,
339+
OakSessionTlsInitializer::Create(ssl_ctx, tls_identity, trust_anchor,
321340
custom_cert_verifier);
322341
if (!initializer.ok()) {
323342
return initializer.status();
@@ -358,9 +377,10 @@ OakSessionTlsInitializer::CreateClient(
358377
absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>>
359378
OakSessionTlsInitializer::CreateServer(
360379
SSL_CTX* ssl_ctx, const TlsIdentity* tls_identity,
380+
const std::string* trust_anchor,
361381
const CustomCertVerifier* custom_cert_verifier) {
362382
absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>> initializer =
363-
OakSessionTlsInitializer::Create(ssl_ctx, tls_identity,
383+
OakSessionTlsInitializer::Create(ssl_ctx, tls_identity, trust_anchor,
364384
custom_cert_verifier);
365385
if (!initializer.ok()) {
366386
return initializer.status();

oak_session/tls/oak_session_tls.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,25 @@ class TlsIdentityProvider {
9292
virtual absl::StatusOr<TlsIdentity> GetIdentity() = 0;
9393
};
9494

95+
// Provider interface that returns a trust anchor certificate (DER-encoded).
96+
// Called each time a new session is created on the context.
97+
class TrustAnchorProvider {
98+
public:
99+
virtual ~TrustAnchorProvider() = default;
100+
virtual absl::StatusOr<std::string> GetTrustAnchor() = 0;
101+
};
102+
103+
95104
// Parameters to configure OakSessionTlsContext for server behavior.
96105
struct ServerContextConfig {
97106
// Provider that returns the key and certificate for this server.
98107
// Called each time a new session is created.
99108
std::unique_ptr<TlsIdentityProvider> tls_identity_provider;
100109

101-
// Optional trust anchor path for the client.
110+
// Optional trust anchor provider for the client.
102111
// If set, client verification mode will be enabled, and client verification
103112
// will be required.
104-
std::optional<std::string> client_trust_anchor_path;
113+
std::unique_ptr<TrustAnchorProvider> client_trust_anchor_provider;
105114

106115
// Optional custom certificate verifier. If provided, it will be called with
107116
// the result of standard verification, allowing it to override failures or
@@ -111,10 +120,10 @@ struct ServerContextConfig {
111120

112121
// Parameters to configure OakSessionTlsContext for client behavior.
113122
struct ClientContextConfig {
114-
// Optional path to a trust anchor that can verify the server.
123+
// Optional provider for a trust anchor that can verify the server.
115124
// If not set, standard PKI verification will not be configured and a
116125
// custom_cert_verifier must be provided to handle certificate validation.
117-
std::optional<std::string> server_trust_anchor_path;
126+
std::unique_ptr<TrustAnchorProvider> server_trust_anchor_provider;
118127

119128
// If provided, called each time a new session is created to get the
120129
// client's TLS identity. Enables mTLS mode, allowing the server to
@@ -182,18 +191,21 @@ class OakSessionTlsContext {
182191
OakSessionTlsContext(
183192
OakSessionTlsMode mode, bssl::UniquePtr<SSL_CTX> ssl_ctx,
184193
std::unique_ptr<TlsIdentityProvider> tls_identity_provider,
194+
std::unique_ptr<TrustAnchorProvider> trust_anchor_provider,
185195
std::optional<CustomCertVerifier> custom_cert_verifier,
186-
std::string expected_server_name = std::string(kDefaultServerName))
196+
std::string expected_server_name = "")
187197
: mode_(mode),
188198
ssl_ctx_(std::move(ssl_ctx)),
189199
tls_identity_provider_(std::move(tls_identity_provider)),
200+
trust_anchor_provider_(std::move(trust_anchor_provider)),
190201
custom_cert_verifier_(std::move(custom_cert_verifier)),
191202
expected_server_name_(std::move(expected_server_name)) {}
192203

193204
private:
194205
OakSessionTlsMode mode_;
195206
bssl::UniquePtr<SSL_CTX> ssl_ctx_;
196207
std::unique_ptr<TlsIdentityProvider> tls_identity_provider_;
208+
std::unique_ptr<TrustAnchorProvider> trust_anchor_provider_;
197209
std::optional<CustomCertVerifier> custom_cert_verifier_;
198210
std::string expected_server_name_;
199211
};
@@ -215,11 +227,13 @@ class OakSessionTlsInitializer {
215227
public:
216228
static absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>> CreateServer(
217229
SSL_CTX* ssl_ctx, const TlsIdentity* tls_identity = nullptr,
230+
const std::string* trust_anchor = nullptr,
218231
const CustomCertVerifier* custom_cert_verifier = nullptr);
219232

220233
static absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>> CreateClient(
221234
SSL_CTX* ssl_ctx, const std::string& expected_server_name,
222235
const TlsIdentity* tls_identity = nullptr,
236+
const std::string* trust_anchor = nullptr,
223237
const CustomCertVerifier* custom_cert_verifier = nullptr);
224238

225239
// Returns true if the handshake is complete.
@@ -247,6 +261,7 @@ class OakSessionTlsInitializer {
247261
private:
248262
static absl::StatusOr<std::unique_ptr<OakSessionTlsInitializer>> Create(
249263
SSL_CTX* ssl_ctx, const TlsIdentity* tls_identity = nullptr,
264+
const std::string* trust_anchor = nullptr,
250265
const CustomCertVerifier* custom_cert_verifier = nullptr);
251266
OakSessionTlsInitializer(bssl::UniquePtr<SSL> ssl, BIO* bio_read,
252267
BIO* bio_write,

0 commit comments

Comments
 (0)