Add set_verify_callback function to both ssl::context and ssl::stream.

Add set_verify_mode to ssl:stream.
This commit is contained in:
Christopher Kohlhoff 2011-03-21 16:46:09 +11:00
parent 13cc97283b
commit 42009c793e
17 changed files with 1175 additions and 250 deletions

View File

@ -304,6 +304,7 @@ nobase_include_HEADERS = \
asio/ssl/detail/read_op.hpp \
asio/ssl/detail/shutdown_op.hpp \
asio/ssl/detail/stream_core.hpp \
asio/ssl/detail/verify_callback.hpp \
asio/ssl/detail/write_op.hpp \
asio/ssl/error.hpp \
asio/ssl.hpp \
@ -321,6 +322,8 @@ nobase_include_HEADERS = \
asio/ssl/stream_base.hpp \
asio/ssl/stream.hpp \
asio/ssl/stream_service.hpp \
asio/ssl/verify_context.hpp \
asio/ssl/verify_mode.hpp \
asio/strand.hpp \
asio/streambuf.hpp \
asio/stream_socket_service.hpp \

View File

@ -23,5 +23,7 @@
#include "asio/ssl/stream.hpp"
#include "asio/ssl/stream_base.hpp"
#include "asio/ssl/stream_service.hpp"
#include "asio/ssl/verify_context.hpp"
#include "asio/ssl/verify_mode.hpp"
#endif // ASIO_SSL_HPP

View File

@ -27,6 +27,8 @@
# include "asio/ssl/detail/openssl_types.hpp"
# include "asio/ssl/detail/openssl_init.hpp"
# include "asio/ssl/detail/password_callback.hpp"
# include "asio/ssl/detail/verify_callback.hpp"
# include "asio/ssl/verify_mode.hpp"
#endif // defined(ASIO_ENABLE_OLD_SSL)
namespace asio {
@ -138,8 +140,8 @@ public:
* This function may be used to configure the peer verification mode used by
* the context.
*
* @param v A bitmask of peer verification modes. The available verify_mode
* values are defined in the context_base class.
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @throws asio::system_error Thrown on failure.
*
@ -152,8 +154,8 @@ public:
* This function may be used to configure the peer verification mode used by
* the context.
*
* @param v A bitmask of peer verification modes. The available verify_mode
* values are defined in the context_base class.
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @param ec Set to indicate what error occurred, if any.
*
@ -162,6 +164,49 @@ public:
ASIO_DECL asio::error_code set_verify_mode(
verify_mode v, asio::error_code& ec);
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @throws asio::system_error Thrown on failure.
*
* @note Calls @c SSL_CTX_set_verify.
*/
template <typename VerifyCallback>
void set_verify_callback(VerifyCallback callback);
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_CTX_set_verify.
*/
template <typename VerifyCallback>
asio::error_code set_verify_callback(VerifyCallback callback,
asio::error_code& ec);
/// Load a certification authority file for performing verification.
/**
* This function is used to load one or more trusted certification authorities
@ -446,6 +491,14 @@ public:
asio::error_code& ec);
private:
// Helper function used to set a peer certificate verification callback.
ASIO_DECL asio::error_code do_set_verify_callback(
detail::verify_callback_base* callback, asio::error_code& ec);
// Callback used when the SSL implementation wants to verify a certificate.
ASIO_DECL static int verify_callback_function(
int preverified, X509_STORE_CTX* ctx);
// Helper function used to set a password callback.
ASIO_DECL asio::error_code do_set_password_callback(
detail::password_callback_base* callback, asio::error_code& ec);

View File

@ -105,24 +105,11 @@ public:
pem
};
/// Bitmask type for peer verification.
#if !defined(GENERATING_DOCUMENTATION)
// The following types and constants are preserved for backward compatibility.
// New programs should use the equivalents of the same names that are defined
// in the asio::ssl namespace.
typedef int verify_mode;
#if defined(GENERATING_DOCUMENTATION)
/// No verification.
static const int verify_none = implementation_defined;
/// Verify the peer.
static const int verify_peer = implementation_defined;
/// Fail verification if the peer has no certificate. Ignored unless
/// verify_peer is set.
static const int verify_fail_if_no_peer_cert = implementation_defined;
/// Do not request client certificate on renegotiation. Ignored unless
/// verify_peer is set.
static const int verify_client_once = implementation_defined;
#else
BOOST_STATIC_CONSTANT(int, verify_none = SSL_VERIFY_NONE);
BOOST_STATIC_CONSTANT(int, verify_peer = SSL_VERIFY_PEER);
BOOST_STATIC_CONSTANT(int,

View File

@ -21,7 +21,9 @@
# include "asio/buffer.hpp"
# include "asio/detail/static_mutex.hpp"
# include "asio/ssl/detail/openssl_types.hpp"
# include "asio/ssl/detail/verify_callback.hpp"
# include "asio/ssl/stream_base.hpp"
# include "asio/ssl/verify_mode.hpp"
#endif // !defined(ASIO_ENABLE_OLD_SSL)
#include "asio/detail/push_options.hpp"
@ -66,6 +68,14 @@ public:
// Get the underlying implementation in the native type.
ASIO_DECL SSL* native_handle();
// Set the peer verification mode.
ASIO_DECL asio::error_code set_verify_mode(
verify_mode v, asio::error_code& ec);
// Set a peer certificate verification callback.
ASIO_DECL asio::error_code set_verify_callback(
verify_callback_base* callback, asio::error_code& ec);
// Perform an SSL handshake using either SSL_connect (client-side) or
// SSL_accept (server-side).
ASIO_DECL want handshake(
@ -101,6 +111,10 @@ private:
engine(const engine&);
engine& operator=(const engine&);
// Callback used when the SSL implementation wants to verify a certificate.
ASIO_DECL static int verify_callback_function(
int preverified, X509_STORE_CTX* ctx);
// The SSL_accept function may not be thread safe. This mutex is used to
// protect all calls to the SSL_accept function.
ASIO_DECL static asio::detail::static_mutex& accept_mutex();

View File

@ -19,6 +19,7 @@
#if !defined(ASIO_ENABLE_OLD_SSL)
# include "asio/ssl/detail/engine.hpp"
# include "asio/ssl/verify_context.hpp"
#endif // !defined(ASIO_ENABLE_OLD_SSL)
#include "asio/detail/push_options.hpp"
@ -43,6 +44,12 @@ engine::engine(SSL_CTX* context)
engine::~engine()
{
if (SSL_get_app_data(ssl_))
{
delete static_cast<verify_callback_base*>(SSL_get_app_data(ssl_));
SSL_set_app_data(ssl_, 0);
}
::BIO_free(ext_bio_);
::SSL_free(ssl_);
}
@ -52,6 +59,53 @@ SSL* engine::native_handle()
return ssl_;
}
asio::error_code engine::set_verify_mode(
verify_mode v, asio::error_code& ec)
{
::SSL_set_verify(ssl_, v, ::SSL_get_verify_callback(ssl_));
ec = asio::error_code();
return ec;
}
asio::error_code engine::set_verify_callback(
verify_callback_base* callback, asio::error_code& ec)
{
if (SSL_get_app_data(ssl_))
delete static_cast<verify_callback_base*>(SSL_get_app_data(ssl_));
SSL_set_app_data(ssl_, callback);
::SSL_set_verify(ssl_, ::SSL_get_verify_mode(ssl_),
&engine::verify_callback_function);
ec = asio::error_code();
return ec;
}
int engine::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
{
if (ctx)
{
if (SSL* ssl = static_cast<SSL*>(
::X509_STORE_CTX_get_ex_data(
ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx())))
{
if (SSL_get_app_data(ssl))
{
verify_callback_base* callback =
static_cast<verify_callback_base*>(
SSL_get_app_data(ssl));
verify_context verify_ctx(ctx);
return callback->call(preverified != 0, verify_ctx) ? 1 : 0;
}
}
}
return 0;
}
engine::want engine::handshake(
stream_base::handshake_type type, asio::error_code& ec)
{

View File

@ -0,0 +1,68 @@
//
// ssl/detail/verify_callback.hpp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP
#define ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#if !defined(ASIO_ENABLE_OLD_SSL)
# include "asio/ssl/verify_context.hpp"
#endif // !defined(ASIO_ENABLE_OLD_SSL)
#include "asio/detail/push_options.hpp"
namespace asio {
namespace ssl {
namespace detail {
#if !defined(ASIO_ENABLE_OLD_SSL)
class verify_callback_base
{
public:
virtual ~verify_callback_base()
{
}
virtual bool call(bool preverified, verify_context& ctx) = 0;
};
template <typename VerifyCallback>
class verify_callback : public verify_callback_base
{
public:
explicit verify_callback(VerifyCallback callback)
: callback_(callback)
{
}
virtual bool call(bool preverified, verify_context& ctx)
{
return callback_(preverified, ctx);
}
private:
VerifyCallback callback_;
};
#endif // !defined(ASIO_ENABLE_OLD_SSL)
} // namespace detail
} // namespace ssl
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_SSL_DETAIL_VERIFY_CALLBACK_HPP

View File

@ -29,6 +29,22 @@ namespace ssl {
#if !defined(ASIO_ENABLE_OLD_SSL)
template <typename VerifyCallback>
void context::set_verify_callback(VerifyCallback callback)
{
asio::error_code ec;
this->set_verify_callback(callback, ec);
asio::detail::throw_error(ec, "set_verify_callback");
}
template <typename VerifyCallback>
asio::error_code context::set_verify_callback(
VerifyCallback callback, asio::error_code& ec)
{
return do_set_verify_callback(
new detail::verify_callback<VerifyCallback>(callback), ec);
}
template <typename PasswordCallback>
void context::set_password_callback(PasswordCallback callback)
{

View File

@ -124,6 +124,15 @@ context::~context()
handle_->default_passwd_callback_userdata = 0;
}
if (SSL_CTX_get_app_data(handle_))
{
detail::verify_callback_base* callback =
static_cast<detail::verify_callback_base*>(
SSL_CTX_get_app_data(handle_));
delete callback;
SSL_CTX_set_app_data(handle_, 0);
}
::SSL_CTX_free(handle_);
}
}
@ -154,7 +163,7 @@ asio::error_code context::set_options(
return ec;
}
void context::set_verify_mode(context::verify_mode v)
void context::set_verify_mode(verify_mode v)
{
asio::error_code ec;
set_verify_mode(v, ec);
@ -162,9 +171,9 @@ void context::set_verify_mode(context::verify_mode v)
}
asio::error_code context::set_verify_mode(
context::verify_mode v, asio::error_code& ec)
verify_mode v, asio::error_code& ec)
{
::SSL_CTX_set_verify(handle_, v, 0);
::SSL_CTX_set_verify(handle_, v, ::SSL_CTX_get_verify_callback(handle_));
ec = asio::error_code();
return ec;
@ -411,6 +420,51 @@ asio::error_code context::use_tmp_dh_file(
return ec;
}
asio::error_code context::do_set_verify_callback(
detail::verify_callback_base* callback, asio::error_code& ec)
{
if (SSL_CTX_get_app_data(handle_))
{
delete static_cast<detail::verify_callback_base*>(
SSL_CTX_get_app_data(handle_));
}
SSL_CTX_set_app_data(handle_, callback);
::SSL_CTX_set_verify(handle_,
::SSL_CTX_get_verify_mode(handle_),
&context::verify_callback_function);
ec = asio::error_code();
return ec;
}
int context::verify_callback_function(int preverified, X509_STORE_CTX* ctx)
{
if (ctx)
{
if (SSL* ssl = static_cast<SSL*>(
::X509_STORE_CTX_get_ex_data(
ctx, ::SSL_get_ex_data_X509_STORE_CTX_idx())))
{
if (SSL_CTX* handle = ::SSL_get_SSL_CTX(ssl))
{
if (SSL_CTX_get_app_data(handle))
{
detail::verify_callback_base* callback =
static_cast<detail::verify_callback_base*>(
SSL_CTX_get_app_data(handle));
verify_context verify_ctx(ctx);
return callback->call(preverified != 0, verify_ctx) ? 1 : 0;
}
}
}
}
return 0;
}
asio::error_code context::do_set_password_callback(
detail::password_callback_base* callback, asio::error_code& ec)
{

View File

@ -219,6 +219,95 @@ public:
return next_layer_.lowest_layer();
}
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the stream. The new mode will override the mode inherited from the context.
*
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @throws asio::system_error Thrown on failure.
*
* @note Calls @c SSL_set_verify.
*/
void set_verify_mode(verify_mode v)
{
asio::error_code ec;
set_verify_mode(v, ec);
asio::detail::throw_error(ec, "set_verify_mode");
}
/// Set the peer verification mode.
/**
* This function may be used to configure the peer verification mode used by
* the stream. The new mode will override the mode inherited from the context.
*
* @param v A bitmask of peer verification modes. See @ref verify_mode for
* available values.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_set_verify.
*/
asio::error_code set_verify_mode(
verify_mode v, asio::error_code& ec)
{
return core_.engine_.set_verify_mode(v, ec);
}
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @throws asio::system_error Thrown on failure.
*
* @note Calls @c SSL_set_verify.
*/
template <typename VerifyCallback>
void set_verify_callback(VerifyCallback callback)
{
asio::error_code ec;
this->set_verify_callback(callback, ec);
asio::detail::throw_error(ec, "set_verify_callback");
}
/// Set the callback used to verify peer certificates.
/**
* This function is used to specify a callback function that will be called
* by the implementation when it needs to verify a peer certificate.
*
* @param callback The function object to be used for verifying a certificate.
* The function signature of the handler must be:
* @code bool verify_callback(
* bool preverified, // True if the certificate passed pre-verification.
* verify_context& ctx // The peer certificate and other context.
* ); @endcode
* The return value of the callback is true if the certificate has passed
* verification, false otherwise.
*
* @param ec Set to indicate what error occurred, if any.
*
* @note Calls @c SSL_set_verify.
*/
template <typename VerifyCallback>
asio::error_code set_verify_callback(VerifyCallback callback,
asio::error_code& ec)
{
return core_.engine_.set_verify_callback(
new detail::verify_callback<VerifyCallback>(callback), ec);
}
/// Perform SSL handshaking.
/**
* This function is used to perform SSL handshaking on the stream. The

View File

@ -0,0 +1,71 @@
//
// ssl/verify_context.hpp
// ~~~~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_SSL_VERIFY_CONTEXT_HPP
#define ASIO_SSL_VERIFY_CONTEXT_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#if !defined(ASIO_ENABLE_OLD_SSL)
# include "asio/detail/noncopyable.hpp"
# include "asio/ssl/detail/openssl_types.hpp"
#endif // !defined(ASIO_ENABLE_OLD_SSL)
namespace asio {
namespace ssl {
#if !defined(ASIO_ENABLE_OLD_SSL)
/// A simple wrapper around the X509_STORE_CTX type, used during verification of
/// a peer certificate.
/**
* @note The verify_context does not own the underlying X509_STORE_CTX object.
*/
class verify_context
: private noncopyable
{
public:
/// The native handle type of the verification context.
typedef X509_STORE_CTX* native_handle_type;
/// Constructor.
explicit verify_context(native_handle_type handle)
: handle_(handle)
{
}
/// Get the underlying implementation in the native type.
/**
* This function may be used to obtain the underlying implementation of the
* context. This is intended to allow access to context functionality that is
* not otherwise provided.
*/
native_handle_type native_handle()
{
return handle_;
}
private:
// The underlying native implementation.
native_handle_type handle_;
};
#endif // defined(ASIO_ENABLE_OLD_SSL)
} // namespace ssl
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_SSL_VERIFY_CONTEXT_HPP

View File

@ -0,0 +1,62 @@
//
// ssl/verify_mode.hpp
// ~~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#ifndef ASIO_SSL_VERIFY_MODE_HPP
#define ASIO_SSL_VERIFY_MODE_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/ssl/detail/openssl_types.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
namespace ssl {
/// Bitmask type for peer verification.
/**
* Possible values are:
* @li @ref verify_none
* @li @ref verify_peer
* @li @ref verify_fail_if_no_peer_cert
* @li @ref verify_client_once
*/
typedef int verify_mode;
#if defined(GENERATING_DOCUMENTATION)
/// No verification.
const int verify_none = implementation_defined;
/// Verify the peer.
const int verify_peer = implementation_defined;
/// Fail verification if the peer has no certificate. Ignored unless
/// @ref verify_peer is set.
const int verify_fail_if_no_peer_cert = implementation_defined;
/// Do not request client certificate on renegotiation. Ignored unless
/// @ref verify_peer is set.
const int verify_client_once = implementation_defined;
#else
const int verify_none = SSL_VERIFY_NONE;
const int verify_peer = SSL_VERIFY_PEER;
const int verify_fail_if_no_peer_cert = SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
const int verify_client_once = SSL_VERIFY_CLIENT_ONCE;
#endif
} // namespace ssl
} // namespace asio
#include "asio/detail/pop_options.hpp"
#endif // ASIO_SSL_VERIFY_MODE_HPP

View File

@ -308,6 +308,7 @@
<member><link linkend="asio.reference.ssl__context">ssl::context</link></member>
<member><link linkend="asio.reference.ssl__context_base">ssl::context_base</link></member>
<member><link linkend="asio.reference.ssl__stream_base">ssl::stream_base</link></member>
<member><link linkend="asio.reference.ssl__verify_context">ssl::verify_context</link></member>
</simplelist>
<bridgehead renderas="sect3">Class Templates</bridgehead>
<simplelist type="vert" columns="1">

View File

@ -8670,7 +8670,7 @@ The [link asio.reference.basic_deadline_timer `basic_deadline_timer`] class temp
A deadline timer is always in one of two states: "expired" or "not expired". If the `wait()` or `async_wait()` function is called on an expired timer, the wait operation will complete immediately.
Most applications will use the `asio::deadline_timer` typedef.
Most applications will use the [link asio.reference.deadline_timer `deadline_timer`] typedef.
[heading Thread Safety]
@ -23068,7 +23068,7 @@ Provides signal functionality.
The [link asio.reference.basic_signal_set `basic_signal_set`] class template provides the ability to perform an asynchronous wait for one or more signals to occur.
Most applications will use the `asio::signal_set` typedef.
Most applications will use the [link asio.reference.signal_set `signal_set`] typedef.
[heading Thread Safety]
@ -51254,7 +51254,7 @@ The [link asio.reference.basic_deadline_timer `basic_deadline_timer`] class temp
A deadline timer is always in one of two states: "expired" or "not expired". If the `wait()` or `async_wait()` function is called on an expired timer, the wait operation will complete immediately.
Most applications will use the `asio::deadline_timer` typedef.
Most applications will use the [link asio.reference.deadline_timer `deadline_timer`] typedef.
[heading Thread Safety]
@ -53155,7 +53155,7 @@ The [link asio.reference.io_service `io_service`] class provides the core I/O fu
* `asio::ip::udp::socket`
* `asio::deadline_timer`.
* [link asio.reference.deadline_timer `deadline_timer`].
The [link asio.reference.io_service `io_service`] class also includes facilities intended for developers of custom asynchronous services.
@ -78901,7 +78901,7 @@ Typedef for the typical usage of a signal set.
The [link asio.reference.basic_signal_set `basic_signal_set`] class template provides the ability to perform an asynchronous wait for one or more signals to occur.
Most applications will use the `asio::signal_set` typedef.
Most applications will use the [link asio.reference.signal_set `signal_set`] typedef.
[heading Thread Safety]
@ -81035,13 +81035,6 @@ Protected destructor to prevent deletion through this type.
]
[
[[link asio.reference.ssl__context.verify_mode [*verify_mode]]]
[Bitmask type for peer verification. ]
]
]
[heading Member Functions]
@ -81097,6 +81090,11 @@ Protected destructor to prevent deletion through this type.
[Set the password callback. ]
]
[
[[link asio.reference.ssl__context.set_verify_callback [*set_verify_callback]]]
[Set the callback used to verify peer certificates. ]
]
[
[[link asio.reference.ssl__context.set_verify_mode [*set_verify_mode]]]
[Set the peer verification mode. ]
@ -81163,26 +81161,6 @@ Protected destructor to prevent deletion through this type.
[Always create a new key when using tmp_dh parameters. ]
]
[
[[link asio.reference.ssl__context.verify_client_once [*verify_client_once]]]
[Do not request client certificate on renegotiation. Ignored unless verify_peer is set. ]
]
[
[[link asio.reference.ssl__context.verify_fail_if_no_peer_cert [*verify_fail_if_no_peer_cert]]]
[Fail verification if the peer has no certificate. Ignored unless verify_peer is set. ]
]
[
[[link asio.reference.ssl__context.verify_none [*verify_none]]]
[No verification. ]
]
[
[[link asio.reference.ssl__context.verify_peer [*verify_peer]]]
[Verify the peer. ]
]
]
[heading Requirements]
@ -82127,6 +82105,126 @@ Calls `SSL_CTX_set_default_passwd_cb`.
[endsect]
[endsect]
[section:set_verify_callback ssl::context::set_verify_callback]
[indexterm2 set_verify_callback..ssl::context]
Set the callback used to verify peer certificates.
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
void ``[link asio.reference.ssl__context.set_verify_callback.overload1 set_verify_callback]``(
VerifyCallback callback);
`` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_callback.overload1 more...]]``
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
asio::error_code ``[link asio.reference.ssl__context.set_verify_callback.overload2 set_verify_callback]``(
VerifyCallback callback,
asio::error_code & ec);
`` [''''&raquo;''' [link asio.reference.ssl__context.set_verify_callback.overload2 more...]]``
[section:overload1 ssl::context::set_verify_callback (1 of 2 overloads)]
Set the callback used to verify peer certificates.
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
void set_verify_callback(
VerifyCallback callback);
This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
[heading Parameters]
[variablelist
[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
``
bool verify_callback(
bool preverified, // True if the certificate passed pre-verification.
verify_context& ctx // The peer certificate and other context.
);
``
The return value of the callback is true if the certificate has passed verification, false otherwise.]]
]
[heading Exceptions]
[variablelist
[[asio::system_error][Thrown on failure.]]
]
[heading Remarks]
Calls `SSL_CTX_set_verify`.
[endsect]
[section:overload2 ssl::context::set_verify_callback (2 of 2 overloads)]
Set the callback used to verify peer certificates.
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
asio::error_code set_verify_callback(
VerifyCallback callback,
asio::error_code & ec);
This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
[heading Parameters]
[variablelist
[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
``
bool verify_callback(
bool preverified, // True if the certificate passed pre-verification.
verify_context& ctx // The peer certificate and other context.
);
``
The return value of the callback is true if the certificate has passed verification, false otherwise.]]
[[ec][Set to indicate what error occurred, if any.]]
]
[heading Remarks]
Calls `SSL_CTX_set_verify`.
[endsect]
@ -82166,7 +82264,7 @@ This function may be used to configure the peer verification mode used by the co
[variablelist
[[v][A bitmask of peer verification modes. The available verify\_mode values are defined in the [link asio.reference.ssl__context_base `ssl::context_base`] class.]]
[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
]
@ -82211,7 +82309,7 @@ This function may be used to configure the peer verification mode used by the co
[variablelist
[[v][A bitmask of peer verification modes. The available verify\_mode values are defined in the [link asio.reference.ssl__context_base `ssl::context_base`] class.]]
[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
[[ec][Set to indicate what error occurred, if any.]]
@ -82759,83 +82857,6 @@ Calls `SSL_CTX_set_tmp_dh`.
[endsect]
[section:verify_client_once ssl::context::verify_client_once]
[indexterm2 verify_client_once..ssl::context]
Do not request client certificate on renegotiation. Ignored unless verify\_peer is set.
static const int verify_client_once = implementation_defined;
[endsect]
[section:verify_fail_if_no_peer_cert ssl::context::verify_fail_if_no_peer_cert]
[indexterm2 verify_fail_if_no_peer_cert..ssl::context]
Fail verification if the peer has no certificate. Ignored unless verify\_peer is set.
static const int verify_fail_if_no_peer_cert = implementation_defined;
[endsect]
[section:verify_mode ssl::context::verify_mode]
[indexterm2 verify_mode..ssl::context]
Bitmask type for peer verification.
typedef int verify_mode;
[heading Requirements]
[*Header: ][^asio/ssl/context.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:verify_none ssl::context::verify_none]
[indexterm2 verify_none..ssl::context]
No verification.
static const int verify_none = implementation_defined;
[endsect]
[section:verify_peer ssl::context::verify_peer]
[indexterm2 verify_peer..ssl::context]
Verify the peer.
static const int verify_peer = implementation_defined;
[endsect]
[section:_context ssl::context::~context]
[indexterm2 ~context..ssl::context]
@ -82893,13 +82914,6 @@ The [link asio.reference.ssl__context_base `ssl::context_base`] class is used as
]
[
[[link asio.reference.ssl__context_base.verify_mode [*verify_mode]]]
[Bitmask type for peer verification. ]
]
]
[heading Protected Member Functions]
@ -82942,26 +82956,6 @@ The [link asio.reference.ssl__context_base `ssl::context_base`] class is used as
[Always create a new key when using tmp_dh parameters. ]
]
[
[[link asio.reference.ssl__context_base.verify_client_once [*verify_client_once]]]
[Do not request client certificate on renegotiation. Ignored unless verify_peer is set. ]
]
[
[[link asio.reference.ssl__context_base.verify_fail_if_no_peer_cert [*verify_fail_if_no_peer_cert]]]
[Fail verification if the peer has no certificate. Ignored unless verify_peer is set. ]
]
[
[[link asio.reference.ssl__context_base.verify_none [*verify_none]]]
[No verification. ]
]
[
[[link asio.reference.ssl__context_base.verify_peer [*verify_peer]]]
[Verify the peer. ]
]
]
[heading Requirements]
@ -83218,83 +83212,6 @@ Always create a new key when using tmp\_dh parameters.
[section:verify_client_once ssl::context_base::verify_client_once]
[indexterm2 verify_client_once..ssl::context_base]
Do not request client certificate on renegotiation. Ignored unless verify\_peer is set.
static const int verify_client_once = implementation_defined;
[endsect]
[section:verify_fail_if_no_peer_cert ssl::context_base::verify_fail_if_no_peer_cert]
[indexterm2 verify_fail_if_no_peer_cert..ssl::context_base]
Fail verification if the peer has no certificate. Ignored unless verify\_peer is set.
static const int verify_fail_if_no_peer_cert = implementation_defined;
[endsect]
[section:verify_mode ssl::context_base::verify_mode]
[indexterm2 verify_mode..ssl::context_base]
Bitmask type for peer verification.
typedef int verify_mode;
[heading Requirements]
[*Header: ][^asio/ssl/context_base.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:verify_none ssl::context_base::verify_none]
[indexterm2 verify_none..ssl::context_base]
No verification.
static const int verify_none = implementation_defined;
[endsect]
[section:verify_peer ssl::context_base::verify_peer]
[indexterm2 verify_peer..ssl::context_base]
Verify the peer.
static const int verify_peer = implementation_defined;
[endsect]
[section:_context_base ssl::context_base::~context_base]
[indexterm2 ~context_base..ssl::context_base]
@ -83431,6 +83348,16 @@ Provides stream-oriented functionality using SSL.
[Read some data from the stream. ]
]
[
[[link asio.reference.ssl__stream.set_verify_callback [*set_verify_callback]]]
[Set the callback used to verify peer certificates. ]
]
[
[[link asio.reference.ssl__stream.set_verify_mode [*set_verify_mode]]]
[Set the peer verification mode. ]
]
[
[[link asio.reference.ssl__stream.shutdown [*shutdown]]]
[Shut down SSL on the stream. ]
@ -84166,6 +84093,224 @@ The read\_some operation may not read all of the requested number of bytes. Cons
[endsect]
[endsect]
[section:set_verify_callback ssl::stream::set_verify_callback]
[indexterm2 set_verify_callback..ssl::stream]
Set the callback used to verify peer certificates.
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
void ``[link asio.reference.ssl__stream.set_verify_callback.overload1 set_verify_callback]``(
VerifyCallback callback);
`` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_callback.overload1 more...]]``
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
asio::error_code ``[link asio.reference.ssl__stream.set_verify_callback.overload2 set_verify_callback]``(
VerifyCallback callback,
asio::error_code & ec);
`` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_callback.overload2 more...]]``
[section:overload1 ssl::stream::set_verify_callback (1 of 2 overloads)]
Set the callback used to verify peer certificates.
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
void set_verify_callback(
VerifyCallback callback);
This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
[heading Parameters]
[variablelist
[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
``
bool verify_callback(
bool preverified, // True if the certificate passed pre-verification.
verify_context& ctx // The peer certificate and other context.
);
``
The return value of the callback is true if the certificate has passed verification, false otherwise.]]
]
[heading Exceptions]
[variablelist
[[asio::system_error][Thrown on failure.]]
]
[heading Remarks]
Calls `SSL_set_verify`.
[endsect]
[section:overload2 ssl::stream::set_verify_callback (2 of 2 overloads)]
Set the callback used to verify peer certificates.
template<
typename ``[link asio.reference.VerifyCallback VerifyCallback]``>
asio::error_code set_verify_callback(
VerifyCallback callback,
asio::error_code & ec);
This function is used to specify a callback function that will be called by the implementation when it needs to verify a peer certificate.
[heading Parameters]
[variablelist
[[callback][The function object to be used for verifying a certificate. The function signature of the handler must be:
``
bool verify_callback(
bool preverified, // True if the certificate passed pre-verification.
verify_context& ctx // The peer certificate and other context.
);
``
The return value of the callback is true if the certificate has passed verification, false otherwise.]]
[[ec][Set to indicate what error occurred, if any.]]
]
[heading Remarks]
Calls `SSL_set_verify`.
[endsect]
[endsect]
[section:set_verify_mode ssl::stream::set_verify_mode]
[indexterm2 set_verify_mode..ssl::stream]
Set the peer verification mode.
void ``[link asio.reference.ssl__stream.set_verify_mode.overload1 set_verify_mode]``(
verify_mode v);
`` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_mode.overload1 more...]]``
asio::error_code ``[link asio.reference.ssl__stream.set_verify_mode.overload2 set_verify_mode]``(
verify_mode v,
asio::error_code & ec);
`` [''''&raquo;''' [link asio.reference.ssl__stream.set_verify_mode.overload2 more...]]``
[section:overload1 ssl::stream::set_verify_mode (1 of 2 overloads)]
Set the peer verification mode.
void set_verify_mode(
verify_mode v);
This function may be used to configure the peer verification mode used by the stream. The new mode will override the mode inherited from the context.
[heading Parameters]
[variablelist
[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
]
[heading Exceptions]
[variablelist
[[asio::system_error][Thrown on failure.]]
]
[heading Remarks]
Calls `SSL_set_verify`.
[endsect]
[section:overload2 ssl::stream::set_verify_mode (2 of 2 overloads)]
Set the peer verification mode.
asio::error_code set_verify_mode(
verify_mode v,
asio::error_code & ec);
This function may be used to configure the peer verification mode used by the stream. The new mode will override the mode inherited from the context.
[heading Parameters]
[variablelist
[[v][A bitmask of peer verification modes. See [link asio.reference.ssl__verify_mode `ssl::verify_mode`] for available values.]]
[[ec][Set to indicate what error occurred, if any.]]
]
[heading Remarks]
Calls `SSL_set_verify`.
[endsect]
@ -84540,6 +84685,225 @@ Protected destructor to prevent deletion through this type.
[endsect]
[section:ssl__verify_client_once ssl::verify_client_once]
[indexterm1 ssl::verify_client_once]
Do not request client certificate on renegotiation. Ignored unless [link asio.reference.ssl__verify_peer `ssl::verify_peer`] is set.
const int verify_client_once = implementation_defined;
[heading Requirements]
[*Header: ][^asio/ssl/verify_mode.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:ssl__verify_context ssl::verify_context]
A simple wrapper around the X509\_STORE\_CTX type, used during verification of a peer certificate.
class verify_context :
noncopyable
[heading Types]
[table
[[Name][Description]]
[
[[link asio.reference.ssl__verify_context.native_handle_type [*native_handle_type]]]
[The native handle type of the verification context. ]
]
]
[heading Member Functions]
[table
[[Name][Description]]
[
[[link asio.reference.ssl__verify_context.native_handle [*native_handle]]]
[Get the underlying implementation in the native type. ]
]
[
[[link asio.reference.ssl__verify_context.verify_context [*verify_context]]]
[Constructor. ]
]
]
[heading Remarks]
The [link asio.reference.ssl__verify_context `ssl::verify_context`] does not own the underlying X509\_STORE\_CTX object.
[heading Requirements]
[*Header: ][^asio/ssl/verify_context.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[section:native_handle ssl::verify_context::native_handle]
[indexterm2 native_handle..ssl::verify_context]
Get the underlying implementation in the native type.
native_handle_type native_handle();
This function may be used to obtain the underlying implementation of the context. This is intended to allow access to context functionality that is not otherwise provided.
[endsect]
[section:native_handle_type ssl::verify_context::native_handle_type]
[indexterm2 native_handle_type..ssl::verify_context]
The native handle type of the verification context.
typedef X509_STORE_CTX * native_handle_type;
[heading Requirements]
[*Header: ][^asio/ssl/verify_context.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:verify_context ssl::verify_context::verify_context]
[indexterm2 verify_context..ssl::verify_context]
Constructor.
verify_context(
native_handle_type handle);
[endsect]
[endsect]
[section:ssl__verify_fail_if_no_peer_cert ssl::verify_fail_if_no_peer_cert]
[indexterm1 ssl::verify_fail_if_no_peer_cert]
Fail verification if the peer has no certificate. Ignored unless [link asio.reference.ssl__verify_peer `ssl::verify_peer`] is set.
const int verify_fail_if_no_peer_cert = implementation_defined;
[heading Requirements]
[*Header: ][^asio/ssl/verify_mode.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:ssl__verify_mode ssl::verify_mode]
[indexterm1 ssl::verify_mode]
Bitmask type for peer verification.
typedef int verify_mode;
Possible values are:
* [link asio.reference.ssl__verify_none `ssl::verify_none`]
* [link asio.reference.ssl__verify_peer `ssl::verify_peer`]
* [link asio.reference.ssl__verify_fail_if_no_peer_cert `ssl::verify_fail_if_no_peer_cert`]
* [link asio.reference.ssl__verify_client_once `ssl::verify_client_once`]
[heading Requirements]
[*Header: ][^asio/ssl/verify_mode.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:ssl__verify_none ssl::verify_none]
[indexterm1 ssl::verify_none]
No verification.
const int verify_none = implementation_defined;
[heading Requirements]
[*Header: ][^asio/ssl/verify_mode.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:ssl__verify_peer ssl::verify_peer]
[indexterm1 ssl::verify_peer]
Verify the peer.
const int verify_peer = implementation_defined;
[heading Requirements]
[*Header: ][^asio/ssl/verify_mode.hpp]
[*Convenience header: ][^asio/ssl.hpp]
[endsect]
[section:strand strand]
[indexterm1 strand]

View File

@ -639,16 +639,66 @@
<xsl:template match="ref[@kindref='member']" mode="markup">
<xsl:text>`</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
<xsl:variable name="dox-ref-id" select="@refid"/>
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
<xsl:choose>
<xsl:when test="contains(@refid, 'namespaceasio') and count($memberdefs) &gt; 0">
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
<xsl:variable name="ref-name">
<xsl:call-template name="strip-asio-ns">
<xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ref-id">
<xsl:call-template name="make-id">
<xsl:with-param name="name" select="$ref-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>[link asio.reference.</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$ref-name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>`</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="ref[@kindref='member']" mode="markup-nested">
<xsl:text>`</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
<xsl:variable name="dox-ref-id" select="@refid"/>
<xsl:variable name="memberdefs" select="/doxygen//compounddef/sectiondef/memberdef[@id=$dox-ref-id]"/>
<xsl:choose>
<xsl:when test="contains(@refid, 'namespaceasio') and count($memberdefs) &gt; 0">
<xsl:variable name="dox-compound-name" select="($memberdefs)[1]/../../compoundname"/>
<xsl:variable name="dox-name" select="($memberdefs)[1]/name"/>
<xsl:variable name="ref-name">
<xsl:call-template name="strip-asio-ns">
<xsl:with-param name="name" select="concat($dox-compound-name,'::',$dox-name)"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="ref-id">
<xsl:call-template name="make-id">
<xsl:with-param name="name" select="$ref-name"/>
</xsl:call-template>
</xsl:variable>
<xsl:text>[link asio.reference.</xsl:text>
<xsl:value-of select="$ref-id"/>
<xsl:text> `</xsl:text>
<xsl:value-of name="text" select="$ref-name"/>
<xsl:text>`]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>`</xsl:text>
<xsl:value-of select="."/>
<xsl:text>`</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

View File

@ -24,11 +24,34 @@ public:
asio::ip::tcp::resolver::iterator endpoint_iterator)
: socket_(io_service, context)
{
socket_.set_verify_mode(asio::ssl::verify_peer);
socket_.set_verify_callback(
boost::bind(&client::verify_certificate, this, _1, _2));
asio::async_connect(socket_.lowest_layer(), endpoint_iterator,
boost::bind(&client::handle_connect, this,
asio::placeholders::error));
}
bool verify_certificate(bool preverified,
asio::ssl::verify_context& ctx)
{
// The verify callback can be used to check whether the certificate that is
// being presented is valid for the peer. For example, RFC 2818 describes the
// steps involved in doing this for HTTPS. Consult the OpenSSL documentation
// for more details. Note that the callback is called once for each
// certificate in the certificate chain, starting from the root certificate
// authority.
// In this example we will simply print the certificate's subject name.
char subject_name[256];
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
std::cout << "Verifying " << subject_name << "\n";
return preverified;
}
void handle_connect(const asio::error_code& error)
{
if (!error)
@ -39,7 +62,7 @@ public:
}
else
{
std::cout << "Connect failed: " << error << "\n";
std::cout << "Connect failed: " << error.message() << "\n";
}
}
@ -59,7 +82,7 @@ public:
}
else
{
std::cout << "Handshake failed: " << error << "\n";
std::cout << "Handshake failed: " << error.message() << "\n";
}
}
@ -76,7 +99,7 @@ public:
}
else
{
std::cout << "Write failed: " << error << "\n";
std::cout << "Write failed: " << error.message() << "\n";
}
}
@ -91,7 +114,7 @@ public:
}
else
{
std::cout << "Read failed: " << error << "\n";
std::cout << "Read failed: " << error.message() << "\n";
}
}
@ -118,7 +141,6 @@ int main(int argc, char* argv[])
asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
asio::ssl::context ctx(asio::ssl::context::sslv23);
ctx.set_verify_mode(asio::ssl::context::verify_peer);
ctx.load_verify_file("ca.pem");
client c(io_service, ctx, iterator);

View File

@ -29,6 +29,13 @@
namespace ssl_stream_compile {
#if !defined(ASIO_ENABLE_OLD_SSL)
bool verify_callback(bool, asio::ssl::verify_context&)
{
return false;
}
#endif // !defined(ASIO_ENABLE_OLD_SSL)
void handshake_handler(const asio::error_code&)
{
}
@ -88,6 +95,14 @@ void test()
= stream3.lowest_layer();
(void)lowest_layer2;
#if !defined(ASIO_ENABLE_OLD_SSL)
stream1.set_verify_mode(ssl::verify_none);
stream1.set_verify_mode(ssl::verify_none, ec);
stream1.set_verify_callback(verify_callback);
stream1.set_verify_callback(verify_callback, ec);
#endif // !defined(ASIO_ENABLE_OLD_SSL)
stream1.handshake(ssl::stream_base::client);
stream1.handshake(ssl::stream_base::server);
stream1.handshake(ssl::stream_base::client, ec);