Skip to content

Commit 00e7c65

Browse files
ripplehangpitrou
andauthored
GH-43535: [C++] Support the AWS S3 SSE-C encryption (#43601)
### Rationale for this change [server-side encryption with customer-provided keys](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html) is an important security feature for aws s3, it's useful when user want to manager the encryption key themselves, say, they don't want the data to be exposed to the aws system admin, and ensure the object is safe even the ACCESS_KEY and SECRET_KEY is somehow leaked. Some comparison of S3 encryption options : https://www.linkedin.com/pulse/delusion-s3-encryption-benefits-ravi-ivaturi/ ### What changes are included in this PR? 1. Add the **sse_customer_key** member for S3Options to support [server-side encryption with customer-provided keys](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html) (SSE-C keys). - The sse_customer_key was expected to be 256 bits (32 bytes) according to [aws doc](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html#specifying-s3-c-encryption) - The sse_customer_key was expected to be the raw key rather than base64 encoded value, arrow would calculate the base64 and MD5 on the fly. - By default the sse_customer_key is empty, and when the sse_customer_key is empty, there is no impact on the existing workflow. When the sse_customer_key is configured, it would require the aws sdk version to newer than 1.9.201. 2. Add the **tls_ca_file_path**, **tls_ca_dir_path** and **tls_verify_certificates** members for S3Options. - the tls_ca_file_path, tls_ca_dir_path member for S3Options would override the value configured by arrow::fs::FileSystemGlobalOptions. - for s3, according to [aws sdk doc](https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/client-config.html), the tls_ca_file_path and tls_ca_dir_path only take effect in Linux, in order to support connect to the the storage server like minio with self-signed certificates on non-linux platform, we expose the tls_verify_certificates. 3. Refine the unit test to start the minio server with self-signed certificate on linux platform, so the unit test could cover the https case on linux, and http case on non-linux platform. ### Are these changes tested? Yes ### Are there any user-facing changes? Only additional members to S3Options. * GitHub Issue: #43535 Lead-authored-by: Hang Zheng <[email protected]> Co-authored-by: Antoine Pitrou <[email protected]> Signed-off-by: Antoine Pitrou <[email protected]>
1 parent a08037f commit 00e7c65

File tree

10 files changed

+486
-37
lines changed

10 files changed

+486
-37
lines changed

cpp/src/arrow/filesystem/s3_internal.h

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,38 @@
2929
#include <aws/core/client/RetryStrategy.h>
3030
#include <aws/core/http/HttpTypes.h>
3131
#include <aws/core/utils/DateTime.h>
32+
#include <aws/core/utils/HashingUtils.h>
3233
#include <aws/core/utils/StringUtils.h>
3334

3435
#include "arrow/filesystem/filesystem.h"
3536
#include "arrow/filesystem/s3fs.h"
3637
#include "arrow/status.h"
38+
#include "arrow/util/base64.h"
3739
#include "arrow/util/logging.h"
3840
#include "arrow/util/print.h"
3941
#include "arrow/util/string.h"
4042

43+
#ifndef ARROW_AWS_SDK_VERSION_CHECK
44+
// AWS_SDK_VERSION_{MAJOR,MINOR,PATCH} are available since 1.9.7.
45+
# if defined(AWS_SDK_VERSION_MAJOR) && defined(AWS_SDK_VERSION_MINOR) && \
46+
defined(AWS_SDK_VERSION_PATCH)
47+
// Redundant "(...)" are for suppressing "Weird number of spaces at
48+
// line-start. Are you using a 2-space indent? [whitespace/indent]
49+
// [3]" errors...
50+
# define ARROW_AWS_SDK_VERSION_CHECK(major, minor, patch) \
51+
((AWS_SDK_VERSION_MAJOR > (major) || \
52+
(AWS_SDK_VERSION_MAJOR == (major) && AWS_SDK_VERSION_MINOR > (minor)) || \
53+
((AWS_SDK_VERSION_MAJOR == (major) && AWS_SDK_VERSION_MINOR == (minor) && \
54+
AWS_SDK_VERSION_PATCH >= (patch)))))
55+
# else
56+
# define ARROW_AWS_SDK_VERSION_CHECK(major, minor, patch) 0
57+
# endif
58+
#endif // !ARROW_AWS_SDK_VERSION_CHECK
59+
60+
#if ARROW_AWS_SDK_VERSION_CHECK(1, 9, 201)
61+
# define ARROW_S3_HAS_SSE_CUSTOMER_KEY
62+
#endif
63+
4164
namespace arrow {
4265
namespace fs {
4366
namespace internal {
@@ -291,6 +314,70 @@ class ConnectRetryStrategy : public Aws::Client::RetryStrategy {
291314
int32_t max_retry_duration_;
292315
};
293316

317+
/// \brief calculate the MD5 of the input SSE-C key (raw key, not base64 encoded)
318+
/// \param sse_customer_key is the input SSE-C key
319+
/// \return the base64 encoded MD5 for the input key
320+
inline Result<std::string> CalculateSSECustomerKeyMD5(
321+
const std::string& sse_customer_key) {
322+
// The key needs to be 256 bits (32 bytes) according to
323+
// https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerSideEncryptionCustomerKeys.html#specifying-s3-c-encryption
324+
if (sse_customer_key.length() != 32) {
325+
return Status::Invalid("32 bytes SSE-C key is expected");
326+
}
327+
328+
// Convert the raw binary key to an Aws::String
329+
Aws::String sse_customer_key_aws_string(sse_customer_key.data(),
330+
sse_customer_key.length());
331+
332+
// Compute the MD5 hash of the raw binary key
333+
Aws::Utils::ByteBuffer sse_customer_key_md5 =
334+
Aws::Utils::HashingUtils::CalculateMD5(sse_customer_key_aws_string);
335+
336+
// Base64-encode the MD5 hash
337+
return arrow::util::base64_encode(std::string_view(
338+
reinterpret_cast<const char*>(sse_customer_key_md5.GetUnderlyingData()),
339+
sse_customer_key_md5.GetLength()));
340+
}
341+
342+
struct SSECustomerKeyHeaders {
343+
std::string sse_customer_key;
344+
std::string sse_customer_key_md5;
345+
std::string sse_customer_algorithm;
346+
};
347+
348+
inline Result<std::optional<SSECustomerKeyHeaders>> GetSSECustomerKeyHeaders(
349+
const std::string& sse_customer_key) {
350+
if (sse_customer_key.empty()) {
351+
return std::nullopt;
352+
}
353+
#ifdef ARROW_S3_HAS_SSE_CUSTOMER_KEY
354+
ARROW_ASSIGN_OR_RAISE(auto md5, internal::CalculateSSECustomerKeyMD5(sse_customer_key));
355+
return SSECustomerKeyHeaders{arrow::util::base64_encode(sse_customer_key), md5,
356+
"AES256"};
357+
#else
358+
return Status::NotImplemented(
359+
"SSE customer key not supported by this version of the AWS SDK");
360+
#endif
361+
}
362+
363+
template <typename S3RequestType>
364+
Status SetSSECustomerKey(S3RequestType* request, const std::string& sse_customer_key) {
365+
ARROW_ASSIGN_OR_RAISE(auto maybe_headers, GetSSECustomerKeyHeaders(sse_customer_key));
366+
if (!maybe_headers.has_value()) {
367+
return Status::OK();
368+
}
369+
#ifdef ARROW_S3_HAS_SSE_CUSTOMER_KEY
370+
auto headers = std::move(maybe_headers).value();
371+
request->SetSSECustomerKey(headers.sse_customer_key);
372+
request->SetSSECustomerKeyMD5(headers.sse_customer_key_md5);
373+
request->SetSSECustomerAlgorithm(headers.sse_customer_algorithm);
374+
return Status::OK();
375+
#else
376+
return Status::NotImplemented(
377+
"SSE customer key not supported by this version of the AWS SDK");
378+
#endif
379+
}
380+
294381
} // namespace internal
295382
} // namespace fs
296383
} // namespace arrow
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. 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,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
#pragma once
19+
20+
namespace arrow::fs {
21+
// The below two static strings are generated according to
22+
// https://github.com/minio/minio/tree/RELEASE.2024-09-22T00-33-43Z/docs/tls#323-generate-a-self-signed-certificate
23+
// `openssl req -new -x509 -nodes -days 36500 -keyout private.key -out public.crt -config
24+
// openssl.conf`
25+
static constexpr const char* kMinioPrivateKey = R"(-----BEGIN PRIVATE KEY-----
26+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCqwKYHsTSciGqP
27+
uU3qkTWpnXIi3iC0eeW7JSzJHGFs880WdR5JdK4WufPK+1xzgiYjMEPfAcuSWz3b
28+
qYyCI61q+a9Iu2nj7cFTW9bfZrmWlnI0YOLJc+q0AAdAjF1lvRKenH8tbjz/2jyl
29+
i/cYQ+I5Tg4nngrX8OmOfluNzwD/nwGLq6/DVbzDUdPI9q1XtVT/0Vf7qwbDG1HD
30+
NkIzKT5B+YdSLaOCRYNK3x7RPsfazKIBrTmRy1v454wKe8TjTmTB7+m5wKqfCJcq
31+
lI253WHcK0lsw6zCNtX/kahPAvm/8mniPolW4qxoD6xwebgMVkrNTs3ztcPIG9O4
32+
pmCbATijAgMBAAECggEACL5swiAU7Z8etdVrZAOjl9f0LEzrp9JGLVst++50Hrwt
33+
WGUO8/wBnjBPh6lvhoq3oT2rfBP/dLMva7w28cMZ8kxu6W6PcZiPOdGOI0qDXm69
34+
0mjTtDU3Y5hMxsVpUvhnp6+j45Otk/x89o1ATgHL59tTZjv1mjFABIf78DsVdgF9
35+
CMi2q6Lv7NLftieyWmz1K3p109z9+xkDNSOkVrv1JFChviKqWgIS0rdFjySvTgoy
36+
rHYT+TweDliKJrZCeoUJmNB0uVW/dM9lXhcvkvkJZKPPurylx1oH5a7K/sWFPf7A
37+
Ed1vjvZQFlaXu/bOUUSOZtkErAir/oCxrUDsHxGsAQKBgQDZghyy7jNGNdjZe1Xs
38+
On1ZVgIS3Nt+OLGCVH7tTsfZsCOb+SkrhB1RQva3YzPMfgoZScI9+bN/pRVf49Pj
39+
qGEHkW/wozutUve7UMzeTOm1aWxUuaKSrmYST7muvAnlYEtO7agd0wrcusYXlMoG
40+
KQwghkufO9I7wXcrudMKXZalIwKBgQDI+FaUwhgfThkgq6bRbdMEeosgohrCM9Wm
41+
E5JMePQq4VaGcgGveWUoNOgT8kvJa0qQwQOqLZj7kUIdj+SCRt0u+Wu3p5IMqdOq
42+
6tMnLNQ3wzUC2KGFLSfISR3L/bo5Bo6Jqz4hVtjMk3PV9bu50MNTNaofYb2xlf/f
43+
/WgiEG0WgQKBgAr8RVLMMQ7EvXUOg6Jwuc//Rg+J1BQl7OE2P0rhBbr66HGCPhAS
44+
liB6j1dnzT/wxbXNQeA7clNqFRBIw3TmFjB5qfuvYt44KIbvZ8l6fPtKncwRrCJY
45+
aJNYL3qhyKYrHOKZojoPZKcNT9/1BdcVz6T842jhbpbSCKDOu9f0Lh2dAoGATZeM
46+
Hh0eISAPFY0QeDV1znnds3jC6g4HQ/q0dnAQnWmo9XmY6v3sr2xV2jWnSxnwjRjo
47+
aFD4itBXfYBr0ly30wYbr6mz+s2q2oeVhL+LJAhrNDEdk4SOooaQSY0p1BCTAdYq
48+
w8Z7J+kaRRZ+J0zRzROgHkOncKQgSYPWK6i55YECgYAC+ECrHhUlPsfusjKpFsEe
49+
stW1HCt3wXtKQn6SJ6IAesbxwALZS6Da/ZC2x1mdBHS3GwWvtGLc0BPnPVfJjr9V
50+
m82qkgJ+p5d7qp7pRA7SFD+5809yVqRnEF3rSLafgGet9ah0ZjZvQ3fwnYZNnNH9
51+
t9pJcv2E5xY7/nFNIorpKg==
52+
-----END PRIVATE KEY-----
53+
)";
54+
55+
static constexpr const char* kMinioCert = R"(-----BEGIN CERTIFICATE-----
56+
MIIDiTCCAnGgAwIBAgIUXbHZ6FAhKSXg4WSGUQySlSyE4U0wDQYJKoZIhvcNAQEL
57+
BQAwXzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMQ4wDAYDVQQHDAVBcnJvdzEO
58+
MAwGA1UECgwFQXJyb3cxDjAMBgNVBAsMBUFycm93MRMwEQYDVQQDDApBcnJyb3dU
59+
ZXN0MB4XDTI0MDkyNDA5MzUxNloXDTM0MDkyMjA5MzUxNlowXzELMAkGA1UEBhMC
60+
VVMxCzAJBgNVBAgMAlZBMQ4wDAYDVQQHDAVBcnJvdzEOMAwGA1UECgwFQXJyb3cx
61+
DjAMBgNVBAsMBUFycm93MRMwEQYDVQQDDApBcnJyb3dUZXN0MIIBIjANBgkqhkiG
62+
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqsCmB7E0nIhqj7lN6pE1qZ1yIt4gtHnluyUs
63+
yRxhbPPNFnUeSXSuFrnzyvtcc4ImIzBD3wHLkls926mMgiOtavmvSLtp4+3BU1vW
64+
32a5lpZyNGDiyXPqtAAHQIxdZb0Snpx/LW48/9o8pYv3GEPiOU4OJ54K1/Dpjn5b
65+
jc8A/58Bi6uvw1W8w1HTyPatV7VU/9FX+6sGwxtRwzZCMyk+QfmHUi2jgkWDSt8e
66+
0T7H2syiAa05kctb+OeMCnvE405kwe/pucCqnwiXKpSNud1h3CtJbMOswjbV/5Go
67+
TwL5v/Jp4j6JVuKsaA+scHm4DFZKzU7N87XDyBvTuKZgmwE4owIDAQABoz0wOzAa
68+
BgNVHREEEzARhwR/AAABgglsb2NhbGhvc3QwHQYDVR0OBBYEFOUNqUSfROf1dz3o
69+
hAVBhgd3UIvKMA0GCSqGSIb3DQEBCwUAA4IBAQBSwWJ2dSw3jlHU0l2V3ozqthTt
70+
XFo07AyWGw8AWNCM6mQ+GKBf0JJ1d7e4lyTf2lCobknS94EgGPORWeiucKYAoCjS
71+
dh1eKGsSevz1rNbp7wsO7DoiRPciK+S95DbsPowloGI6fvOeE12Cf1udeNIpEYWs
72+
OBFwN0HxfYqdPALCtw7l0icpTrJ2Us06UfL9kbkdZwQhXvOscG7JDRtNjBxl9XNm
73+
TFeMNKROmrEPCWaYr6MJ+ItHtb5Cawapea4THz9GCjR9eLq2CbMqLezZ8xBHPzc4
74+
ixI2l0uCfg7ZUSA+90yaScc7bhEQ8CMiPtJgNKaKIqB58DpY7028xJpW7Ma2
75+
-----END CERTIFICATE-----
76+
)";
77+
} // namespace arrow::fs

cpp/src/arrow/filesystem/s3_test_util.cc

Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
# include <sys/wait.h>
2020
#endif
2121

22+
#include "arrow/filesystem/s3_test_cert_internal.h"
2223
#include "arrow/filesystem/s3_test_util.h"
2324
#include "arrow/filesystem/s3fs.h"
2425
#include "arrow/testing/process.h"
@@ -31,6 +32,11 @@
3132
namespace arrow {
3233
namespace fs {
3334

35+
using ::arrow::internal::FileClose;
36+
using ::arrow::internal::FileDescriptor;
37+
using ::arrow::internal::FileOpenWritable;
38+
using ::arrow::internal::FileWrite;
39+
using ::arrow::internal::PlatformFilename;
3440
using ::arrow::internal::TemporaryDir;
3541

3642
namespace {
@@ -44,16 +50,16 @@ const char* kEnvConnectString = "ARROW_TEST_S3_CONNECT_STRING";
4450
const char* kEnvAccessKey = "ARROW_TEST_S3_ACCESS_KEY";
4551
const char* kEnvSecretKey = "ARROW_TEST_S3_SECRET_KEY";
4652

47-
std::string GenerateConnectString() { return GetListenAddress(); }
48-
4953
} // namespace
5054

5155
struct MinioTestServer::Impl {
5256
std::unique_ptr<TemporaryDir> temp_dir_;
57+
std::unique_ptr<TemporaryDir> temp_dir_ca_;
5358
std::string connect_string_;
5459
std::string access_key_ = kMinioAccessKey;
5560
std::string secret_key_ = kMinioSecretKey;
5661
std::unique_ptr<util::Process> server_process_;
62+
std::string scheme_ = "http";
5763
};
5864

5965
MinioTestServer::MinioTestServer() : impl_(new Impl) {}
@@ -69,7 +75,41 @@ std::string MinioTestServer::access_key() const { return impl_->access_key_; }
6975

7076
std::string MinioTestServer::secret_key() const { return impl_->secret_key_; }
7177

72-
Status MinioTestServer::Start() {
78+
std::string MinioTestServer::ca_dir_path() const {
79+
return impl_->temp_dir_ca_->path().ToString();
80+
}
81+
82+
std::string MinioTestServer::ca_file_path() const {
83+
return impl_->temp_dir_ca_->path().ToString() + "/public.crt";
84+
}
85+
86+
std::string MinioTestServer::scheme() const { return impl_->scheme_; }
87+
88+
Status MinioTestServer::GenerateCertificateFile() {
89+
// create the dedicated folder for certificate file, rather than reuse the data
90+
// folder, since there is test case to check whether the folder is empty.
91+
ARROW_ASSIGN_OR_RAISE(impl_->temp_dir_ca_, TemporaryDir::Make("s3fs-test-ca-"));
92+
93+
ARROW_ASSIGN_OR_RAISE(auto public_crt_file,
94+
PlatformFilename::FromString(ca_dir_path() + "/public.crt"));
95+
ARROW_ASSIGN_OR_RAISE(auto public_cert_fd, FileOpenWritable(public_crt_file));
96+
ARROW_RETURN_NOT_OK(FileWrite(public_cert_fd.fd(),
97+
reinterpret_cast<const uint8_t*>(kMinioCert),
98+
strlen(kMinioCert)));
99+
ARROW_RETURN_NOT_OK(public_cert_fd.Close());
100+
101+
ARROW_ASSIGN_OR_RAISE(auto private_key_file,
102+
PlatformFilename::FromString(ca_dir_path() + "/private.key"));
103+
ARROW_ASSIGN_OR_RAISE(auto private_key_fd, FileOpenWritable(private_key_file));
104+
ARROW_RETURN_NOT_OK(FileWrite(private_key_fd.fd(),
105+
reinterpret_cast<const uint8_t*>(kMinioPrivateKey),
106+
strlen(kMinioPrivateKey)));
107+
ARROW_RETURN_NOT_OK(private_key_fd.Close());
108+
109+
return Status::OK();
110+
}
111+
112+
Status MinioTestServer::Start(bool enable_tls) {
73113
const char* connect_str = std::getenv(kEnvConnectString);
74114
const char* access_key = std::getenv(kEnvAccessKey);
75115
const char* secret_key = std::getenv(kEnvSecretKey);
@@ -88,12 +128,27 @@ Status MinioTestServer::Start() {
88128
impl_->server_process_->SetEnv("MINIO_SECRET_KEY", kMinioSecretKey);
89129
// Disable the embedded console (one less listening address to care about)
90130
impl_->server_process_->SetEnv("MINIO_BROWSER", "off");
91-
impl_->connect_string_ = GenerateConnectString();
92-
ARROW_RETURN_NOT_OK(impl_->server_process_->SetExecutable(kMinioExecutableName));
93131
// NOTE: --quiet makes startup faster by suppressing remote version check
94-
impl_->server_process_->SetArgs({"server", "--quiet", "--compat", "--address",
95-
impl_->connect_string_,
96-
impl_->temp_dir_->path().ToString()});
132+
std::vector<std::string> minio_args({"server", "--quiet", "--compat"});
133+
if (enable_tls) {
134+
ARROW_RETURN_NOT_OK(GenerateCertificateFile());
135+
minio_args.emplace_back("--certs-dir");
136+
minio_args.emplace_back(ca_dir_path());
137+
impl_->scheme_ = "https";
138+
// With TLS enabled, we need the connection hostname to match the certificate's
139+
// subject name. This also constrains the actual listening IP address.
140+
impl_->connect_string_ = GetListenAddress("localhost");
141+
} else {
142+
// Without TLS enabled, we want to minimize the likelihood of address collisions
143+
// by varying the listening IP address (note that most tests don't enable TLS).
144+
impl_->connect_string_ = GetListenAddress();
145+
}
146+
minio_args.emplace_back("--address");
147+
minio_args.emplace_back(impl_->connect_string_);
148+
minio_args.emplace_back(impl_->temp_dir_->path().ToString());
149+
150+
ARROW_RETURN_NOT_OK(impl_->server_process_->SetExecutable(kMinioExecutableName));
151+
impl_->server_process_->SetArgs(minio_args);
97152
ARROW_RETURN_NOT_OK(impl_->server_process_->Execute());
98153
return Status::OK();
99154
}
@@ -105,24 +160,29 @@ Status MinioTestServer::Stop() {
105160

106161
struct MinioTestEnvironment::Impl {
107162
std::function<Future<std::shared_ptr<MinioTestServer>>()> server_generator_;
163+
bool enable_tls_;
164+
165+
explicit Impl(bool enable_tls) : enable_tls_(enable_tls) {}
108166

109167
Result<std::shared_ptr<MinioTestServer>> LaunchOneServer() {
110168
auto server = std::make_shared<MinioTestServer>();
111-
RETURN_NOT_OK(server->Start());
169+
RETURN_NOT_OK(server->Start(enable_tls_));
112170
return server;
113171
}
114172
};
115173

116-
MinioTestEnvironment::MinioTestEnvironment() : impl_(new Impl) {}
174+
MinioTestEnvironment::MinioTestEnvironment(bool enable_tls)
175+
: impl_(new Impl(enable_tls)) {}
117176

118177
MinioTestEnvironment::~MinioTestEnvironment() = default;
119178

120179
void MinioTestEnvironment::SetUp() {
121180
auto pool = ::arrow::internal::GetCpuThreadPool();
122181

123-
auto launch_one_server = []() -> Result<std::shared_ptr<MinioTestServer>> {
182+
auto launch_one_server =
183+
[enable_tls = impl_->enable_tls_]() -> Result<std::shared_ptr<MinioTestServer>> {
124184
auto server = std::make_shared<MinioTestServer>();
125-
RETURN_NOT_OK(server->Start());
185+
RETURN_NOT_OK(server->Start(enable_tls));
126186
return server;
127187
};
128188
impl_->server_generator_ = [pool, launch_one_server]() {

cpp/src/arrow/filesystem/s3_test_util.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class MinioTestServer {
4040
MinioTestServer();
4141
~MinioTestServer();
4242

43-
Status Start();
43+
Status Start(bool enable_tls = false);
4444

4545
Status Stop();
4646

@@ -50,7 +50,14 @@ class MinioTestServer {
5050

5151
std::string secret_key() const;
5252

53+
std::string ca_dir_path() const;
54+
55+
std::string ca_file_path() const;
56+
57+
std::string scheme() const;
58+
5359
private:
60+
Status GenerateCertificateFile();
5461
struct Impl;
5562
std::unique_ptr<Impl> impl_;
5663
};
@@ -60,7 +67,7 @@ class MinioTestServer {
6067

6168
class MinioTestEnvironment : public ::testing::Environment {
6269
public:
63-
MinioTestEnvironment();
70+
explicit MinioTestEnvironment(bool enable_tls = false);
6471
~MinioTestEnvironment();
6572

6673
void SetUp() override;

0 commit comments

Comments
 (0)