Skip to content

Commit 8c28ccc

Browse files
committed
Merge pull request #361 from redboltz/support_client_certificate
Added a client certificate support.
2 parents 326648e + b649d05 commit 8c28ccc

File tree

15 files changed

+167
-36
lines changed

15 files changed

+167
-36
lines changed

boost/network/protocol/http/client/async_impl.hpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ struct async_client
4040
bool always_verify_peer,
4141
boost::shared_ptr<boost::asio::io_service> service,
4242
optional<string_type> const& certificate_filename,
43-
optional<string_type> const& verify_path)
43+
optional<string_type> const& verify_path,
44+
optional<string_type> const& certificate_file,
45+
optional<string_type> const& private_key_file)
4446
: connection_base(cache_resolved, follow_redirect),
4547
service_ptr(service.get()
4648
? service
@@ -50,6 +52,8 @@ struct async_client
5052
sentinel_(new boost::asio::io_service::work(service_)),
5153
certificate_filename_(certificate_filename),
5254
verify_path_(verify_path),
55+
certificate_file_(certificate_file),
56+
private_key_file_(private_key_file),
5357
always_verify_peer_(always_verify_peer) {
5458
connection_base::resolver_strand_.reset(
5559
new boost::asio::io_service::strand(service_));
@@ -71,8 +75,9 @@ struct async_client
7175
body_generator_function_type generator) {
7276
typename connection_base::connection_ptr connection_;
7377
connection_ = connection_base::get_connection(
74-
resolver_, request_, always_verify_peer_, certificate_filename_,
75-
verify_path_);
78+
resolver_, request_, always_verify_peer_,
79+
certificate_filename_, verify_path_,
80+
certificate_file_, private_key_file_);
7681
return connection_->send_request(method, request_, get_body, callback,
7782
generator);
7883
}
@@ -82,7 +87,10 @@ struct async_client
8287
resolver_type resolver_;
8388
boost::shared_ptr<boost::asio::io_service::work> sentinel_;
8489
boost::shared_ptr<boost::thread> lifetime_thread_;
85-
optional<string_type> certificate_filename_, verify_path_;
90+
optional<string_type> certificate_filename_;
91+
optional<string_type> verify_path_;
92+
optional<string_type> certificate_file_;
93+
optional<string_type> private_key_file_;
8694
bool always_verify_peer_;
8795
};
8896
} // namespace impl

boost/network/protocol/http/client/connection/async_base.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ namespace boost { namespace network { namespace http { namespace impl {
4040
bool always_verify_peer,
4141
bool https,
4242
optional<string_type> certificate_filename=optional<string_type>(),
43-
optional<string_type> const & verify_path=optional<string_type>()) {
43+
optional<string_type> const & verify_path=optional<string_type>(),
44+
optional<string_type> certificate_file=optional<string_type>(),
45+
optional<string_type> private_key_file=optional<string_type>()) {
4446
typedef http_async_connection<Tag,version_major,version_minor>
4547
async_connection;
4648
typedef typename delegate_factory<Tag>::type delegate_factory_type;
@@ -55,7 +57,9 @@ namespace boost { namespace network { namespace http { namespace impl {
5557
https,
5658
always_verify_peer,
5759
certificate_filename,
58-
verify_path)));
60+
verify_path,
61+
certificate_file,
62+
private_key_file)));
5963
BOOST_ASSERT(temp.get() != 0);
6064
return temp;
6165
}

boost/network/protocol/http/client/connection/connection_delegate_factory.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,18 @@ struct connection_delegate_factory {
3232
bool https,
3333
bool always_verify_peer,
3434
optional<string_type> certificate_filename,
35-
optional<string_type> verify_path) {
35+
optional<string_type> verify_path,
36+
optional<string_type> certificate_file,
37+
optional<string_type> private_key_file) {
3638
connection_delegate_ptr delegate;
3739
if (https) {
3840
#ifdef BOOST_NETWORK_ENABLE_HTTPS
3941
delegate.reset(new ssl_delegate(service,
4042
always_verify_peer,
4143
certificate_filename,
42-
verify_path));
44+
verify_path,
45+
certificate_file,
46+
private_key_file));
4347
#else
4448
BOOST_THROW_EXCEPTION(std::runtime_error("HTTPS not supported."));
4549
#endif /* BOOST_NETWORK_ENABLE_HTTPS */

boost/network/protocol/http/client/connection/ssl_delegate.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ struct ssl_delegate : connection_delegate,
2424
enable_shared_from_this<ssl_delegate> {
2525
ssl_delegate(asio::io_service &service, bool always_verify_peer,
2626
optional<std::string> certificate_filename,
27-
optional<std::string> verify_path);
27+
optional<std::string> verify_path,
28+
optional<std::string> certificate_file,
29+
optional<std::string> private_key_file);
2830

2931
virtual void connect(asio::ip::tcp::endpoint &endpoint,
3032
function<void(system::error_code const &)> handler);
@@ -38,7 +40,10 @@ struct ssl_delegate : connection_delegate,
3840

3941
private:
4042
asio::io_service &service_;
41-
optional<std::string> certificate_filename_, verify_path_;
43+
optional<std::string> certificate_filename_;
44+
optional<std::string> verify_path_;
45+
optional<std::string> certificate_file_;
46+
optional<std::string> private_key_file_;
4247
scoped_ptr<asio::ssl::context> context_;
4348
scoped_ptr<asio::ssl::stream<asio::ip::tcp::socket> > socket_;
4449
bool always_verify_peer_;

boost/network/protocol/http/client/connection/ssl_delegate.ipp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,14 @@
1414
boost::network::http::impl::ssl_delegate::ssl_delegate(
1515
asio::io_service &service, bool always_verify_peer,
1616
optional<std::string> certificate_filename,
17-
optional<std::string> verify_path)
17+
optional<std::string> verify_path,
18+
optional<std::string> certificate_file,
19+
optional<std::string> private_key_file)
1820
: service_(service),
1921
certificate_filename_(certificate_filename),
2022
verify_path_(verify_path),
23+
certificate_file_(certificate_file),
24+
private_key_file_(private_key_file),
2125
always_verify_peer_(always_verify_peer) {}
2226

2327
void boost::network::http::impl::ssl_delegate::connect(
@@ -36,6 +40,12 @@ void boost::network::http::impl::ssl_delegate::connect(
3640
else
3741
context_->set_verify_mode(asio::ssl::context::verify_none);
3842
}
43+
if (certificate_file_)
44+
context_->use_certificate_file(
45+
*certificate_file_, boost::asio::ssl::context::pem);
46+
if (private_key_file_)
47+
context_->use_private_key_file(
48+
*private_key_file_, boost::asio::ssl::context::pem);
3949
socket_.reset(
4050
new asio::ssl::stream<asio::ip::tcp::socket>(service_, *context_));
4151
socket_->lowest_layer().async_connect(

boost/network/protocol/http/client/connection/sync_base.hpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,16 +240,22 @@ struct sync_connection_base {
240240
static sync_connection_base<Tag, version_major, version_minor>*
241241
new_connection(resolver_type& resolver, resolver_function_type resolve,
242242
bool https, bool always_verify_peer,
243-
optional<string_type> const& cert_filename =
243+
optional<string_type> const& certificate_filename =
244244
optional<string_type>(),
245245
optional<string_type> const& verify_path =
246+
optional<string_type>(),
247+
optional<string_type> const& certificate_file =
248+
optional<string_type>(),
249+
optional<string_type> const& private_key_file =
246250
optional<string_type>()) {
247251
if (https) {
248252
#ifdef BOOST_NETWORK_ENABLE_HTTPS
249253
return dynamic_cast<
250254
sync_connection_base<Tag, version_major, version_minor>*>(
251255
new https_sync_connection<Tag, version_major, version_minor>(
252-
resolver, resolve, cert_filename, verify_path));
256+
resolver, resolve,
257+
certificate_filename, verify_path,
258+
certificate_file, private_key_file));
253259
#else
254260
throw std::runtime_error("HTTPS not supported.");
255261
#endif

boost/network/protocol/http/client/connection/sync_ssl.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ struct https_sync_connection
5151
optional<string_type> const& certificate_filename =
5252
optional<string_type>(),
5353
optional<string_type> const& verify_path =
54+
optional<string_type>(),
55+
optional<string_type> const& certificate_file =
56+
optional<string_type>(),
57+
optional<string_type> const& private_key_file =
5458
optional<string_type>())
5559
: connection_base(),
5660
resolver_(resolver),
@@ -71,6 +75,12 @@ struct https_sync_connection
7175
else
7276
context_.set_verify_mode(boost::asio::ssl::context_base::verify_none);
7377
}
78+
if (certificate_file)
79+
context_.use_certificate_file(
80+
*certificate_file, boost::asio::ssl::context::pem);
81+
if (private_key_file)
82+
context_.use_private_key_file(
83+
*private_key_file, boost::asio::ssl::context::pem);
7484
}
7585

7686
void init_socket(string_type const& hostname, string_type const& port) {

boost/network/protocol/http/client/facade.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,8 @@ struct basic_client_facade {
170170
options.always_verify_peer(),
171171
options.openssl_certificate(),
172172
options.openssl_verify_path(),
173+
options.openssl_certificate_file(),
174+
options.openssl_private_key_file(),
173175
options.io_service()));
174176
}
175177
};

boost/network/protocol/http/client/options.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ struct client_options {
2525
follow_redirects_(false),
2626
openssl_certificate_(),
2727
openssl_verify_path_(),
28+
openssl_certificate_file_(),
29+
openssl_private_key_file_(),
2830
io_service_(),
2931
always_verify_peer_(false) {}
3032

@@ -33,6 +35,8 @@ struct client_options {
3335
follow_redirects_(other.follow_redirects_),
3436
openssl_certificate_(other.openssl_certificate_),
3537
openssl_verify_path_(other.openssl_verify_path_),
38+
openssl_certificate_file_(other.openssl_certificate_file_),
39+
openssl_private_key_file_(other.openssl_private_key_file_),
3640
io_service_(other.io_service_),
3741
always_verify_peer_(other.always_verify_peer_) {}
3842

@@ -47,6 +51,8 @@ struct client_options {
4751
swap(follow_redirects_, other.follow_redirects_);
4852
swap(openssl_certificate_, other.openssl_certificate_);
4953
swap(openssl_verify_path_, other.openssl_verify_path_);
54+
swap(openssl_certificate_file_, other.openssl_certificate_file_);
55+
swap(openssl_private_key_file_, other.openssl_private_key_file_);
5056
swap(io_service_, other.io_service_);
5157
swap(always_verify_peer_, other.always_verify_peer_);
5258
}
@@ -71,6 +77,16 @@ struct client_options {
7177
return *this;
7278
}
7379

80+
client_options& openssl_certificate_file(string_type const& v) {
81+
openssl_certificate_file_ = v;
82+
return *this;
83+
}
84+
85+
client_options& openssl_private_key_file(string_type const& v) {
86+
openssl_private_key_file_ = v;
87+
return *this;
88+
}
89+
7490
client_options& io_service(boost::shared_ptr<boost::asio::io_service> v) {
7591
io_service_ = v;
7692
return *this;
@@ -88,6 +104,14 @@ struct client_options {
88104
return openssl_verify_path_;
89105
}
90106

107+
boost::optional<string_type> openssl_certificate_file() const {
108+
return openssl_certificate_file_;
109+
}
110+
111+
boost::optional<string_type> openssl_private_key_file() const {
112+
return openssl_private_key_file_;
113+
}
114+
91115
boost::shared_ptr<boost::asio::io_service> io_service() const {
92116
return io_service_;
93117
}
@@ -99,6 +123,8 @@ struct client_options {
99123
bool follow_redirects_;
100124
boost::optional<string_type> openssl_certificate_;
101125
boost::optional<string_type> openssl_verify_path_;
126+
boost::optional<string_type> openssl_certificate_file_;
127+
boost::optional<string_type> openssl_private_key_file_;
102128
boost::shared_ptr<boost::asio::io_service> io_service_;
103129
bool always_verify_peer_;
104130
};

boost/network/protocol/http/client/pimpl.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,12 @@ struct basic_client_impl
6969
bool always_verify_peer,
7070
optional<string_type> const& certificate_filename,
7171
optional<string_type> const& verify_path,
72+
optional<string_type> const& certificate_file,
73+
optional<string_type> const& private_key_file,
7274
boost::shared_ptr<boost::asio::io_service> service)
7375
: base_type(cache_resolved, follow_redirect, always_verify_peer, service,
74-
certificate_filename, verify_path) {}
76+
certificate_filename, verify_path,
77+
certificate_file, private_key_file) {}
7578

7679
~basic_client_impl() {}
7780
};

0 commit comments

Comments
 (0)