mirror of
https://github.com/boostorg/beast.git
synced 2025-07-30 12:57:31 +02:00
Verify certificates in SSL clients
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
Version 73:
|
Version 73:
|
||||||
|
|
||||||
* Jamroot tweak
|
* Jamroot tweak
|
||||||
|
* Verify certificates in SSL clients
|
||||||
|
|
||||||
HTTP:
|
HTTP:
|
||||||
|
|
||||||
|
117
example/common/root_certificates.hpp
Normal file
117
example/common/root_certificates.hpp
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail 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 BEAST_EXAMPLE_COMMON_ROOT_CERTIFICATES_HPP
|
||||||
|
#define BEAST_EXAMPLE_COMMON_ROOT_CERTIFICATES_HPP
|
||||||
|
|
||||||
|
#include <boost/asio/ssl.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
// The template argument is gratuituous, to
|
||||||
|
// allow the implementation to be header-only.
|
||||||
|
//
|
||||||
|
template<class = void>
|
||||||
|
void
|
||||||
|
load_root_certificates(ssl::context& ctx, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
std::string const cert =
|
||||||
|
/* This is the DigiCert root certificate.
|
||||||
|
|
||||||
|
CN = DigiCert High Assurance EV Root CA
|
||||||
|
OU = www.digicert.com
|
||||||
|
O = DigiCert Inc
|
||||||
|
C = US
|
||||||
|
|
||||||
|
Valid to: Sunday, ?November ?9, ?2031 5:00:00 PM
|
||||||
|
|
||||||
|
Thumbprint(sha1):
|
||||||
|
5f b7 ee 06 33 e2 59 db ad 0c 4c 9a e6 d3 8f 1a 61 c7 dc 25
|
||||||
|
*/
|
||||||
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
|
"MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\n"
|
||||||
|
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
|
||||||
|
"d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n"
|
||||||
|
"ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\n"
|
||||||
|
"MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n"
|
||||||
|
"LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\n"
|
||||||
|
"RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n"
|
||||||
|
"+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\n"
|
||||||
|
"PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\n"
|
||||||
|
"xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\n"
|
||||||
|
"Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\n"
|
||||||
|
"hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\n"
|
||||||
|
"EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\n"
|
||||||
|
"MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\n"
|
||||||
|
"FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\n"
|
||||||
|
"nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\n"
|
||||||
|
"eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\n"
|
||||||
|
"hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\n"
|
||||||
|
"Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\n"
|
||||||
|
"vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n"
|
||||||
|
"+OkuE6N36B9K\n"
|
||||||
|
"-----END CERTIFICATE-----\n";
|
||||||
|
/* This is the GeoTrust root certificate.
|
||||||
|
|
||||||
|
CN = GeoTrust Global CA
|
||||||
|
O = GeoTrust Inc.
|
||||||
|
C = US
|
||||||
|
Valid to: Friday, May 20, 2022 9:00:00 PM
|
||||||
|
|
||||||
|
Thumbprint(sha1):
|
||||||
|
de 28 f4 a4 ff e5 b9 2f a3 c5 03 d1 a3 49 a7 f9 96 2a 82 12
|
||||||
|
*/
|
||||||
|
"-----BEGIN CERTIFICATE-----\n"
|
||||||
|
"MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\n"
|
||||||
|
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
|
||||||
|
"d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n"
|
||||||
|
"ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\n"
|
||||||
|
"MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n"
|
||||||
|
"LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\n"
|
||||||
|
"RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n"
|
||||||
|
"+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\n"
|
||||||
|
"PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\n"
|
||||||
|
"xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\n"
|
||||||
|
"Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\n"
|
||||||
|
"hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\n"
|
||||||
|
"EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\n"
|
||||||
|
"MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\n"
|
||||||
|
"FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\n"
|
||||||
|
"nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\n"
|
||||||
|
"eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\n"
|
||||||
|
"hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\n"
|
||||||
|
"Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\n"
|
||||||
|
"vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n"
|
||||||
|
"+OkuE6N36B9K\n"
|
||||||
|
"-----END CERTIFICATE-----\n";
|
||||||
|
|
||||||
|
ctx.add_certificate_authority(
|
||||||
|
boost::asio::buffer(cert.data(), cert.size()), ec);
|
||||||
|
if(ec)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // detail
|
||||||
|
|
||||||
|
// Load the root certificates into an ssl::context
|
||||||
|
//
|
||||||
|
// This function is inline so that its easy to take
|
||||||
|
// the address and there's nothing weird like a
|
||||||
|
// gratuituous template argument; thus it appears
|
||||||
|
// like a "normal" function.
|
||||||
|
//
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
load_root_certificates(ssl::context& ctx, boost::system::error_code& ec)
|
||||||
|
{
|
||||||
|
detail::load_root_certificates(ctx, ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,11 +1,12 @@
|
|||||||
# Part of Beast
|
# Part of Beast
|
||||||
|
|
||||||
GroupSources(include/beast beast)
|
GroupSources(include/beast beast)
|
||||||
|
GroupSources(example/common common)
|
||||||
GroupSources(example/http-client-ssl "/")
|
GroupSources(example/http-client-ssl "/")
|
||||||
|
|
||||||
add_executable (http-client-ssl
|
add_executable (http-client-ssl
|
||||||
${BEAST_INCLUDES}
|
${BEAST_INCLUDES}
|
||||||
|
${COMMON_INCLUDES}
|
||||||
http_client_ssl.cpp
|
http_client_ssl.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "../common/root_certificates.hpp"
|
||||||
|
|
||||||
#include <beast/core.hpp>
|
#include <beast/core.hpp>
|
||||||
#include <beast/http.hpp>
|
#include <beast/http.hpp>
|
||||||
#include <beast/version.hpp>
|
#include <beast/version.hpp>
|
||||||
@ -46,10 +48,17 @@ int main()
|
|||||||
if(ec)
|
if(ec)
|
||||||
return fail("connect", ec);
|
return fail("connect", ec);
|
||||||
|
|
||||||
|
// Create the required ssl context
|
||||||
|
ssl::context ctx{ssl::context::sslv23_client};
|
||||||
|
|
||||||
|
// This holds the root certificate used for verification
|
||||||
|
load_root_certificates(ctx, ec);
|
||||||
|
if(ec)
|
||||||
|
return fail("certificate", ec);
|
||||||
|
|
||||||
// Wrap the now-connected socket in an SSL stream
|
// Wrap the now-connected socket in an SSL stream
|
||||||
ssl::context ctx{ssl::context::sslv23};
|
|
||||||
ssl::stream<tcp::socket&> stream{sock, ctx};
|
ssl::stream<tcp::socket&> stream{sock, ctx};
|
||||||
stream.set_verify_mode(ssl::verify_none);
|
stream.set_verify_mode(ssl::verify_peer | ssl::verify_fail_if_no_peer_cert);
|
||||||
|
|
||||||
// Perform SSL handshaking
|
// Perform SSL handshaking
|
||||||
stream.handshake(ssl::stream_base::client, ec);
|
stream.handshake(ssl::stream_base::client, ec);
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "../common/root_certificates.hpp"
|
||||||
|
|
||||||
#include <beast/core.hpp>
|
#include <beast/core.hpp>
|
||||||
#include <beast/websocket.hpp>
|
#include <beast/websocket.hpp>
|
||||||
#include <beast/websocket/ssl.hpp>
|
#include <beast/websocket/ssl.hpp>
|
||||||
@ -47,9 +49,16 @@ int main()
|
|||||||
if(ec)
|
if(ec)
|
||||||
return fail("connect", ec);
|
return fail("connect", ec);
|
||||||
|
|
||||||
|
// Create the required ssl context
|
||||||
|
ssl::context ctx{ssl::context::sslv23_client};
|
||||||
|
|
||||||
|
// This holds the root certificate used for verification
|
||||||
|
load_root_certificates(ctx, ec);
|
||||||
|
if(ec)
|
||||||
|
return fail("certificate", ec);
|
||||||
|
|
||||||
// Wrap the now-connected socket in an SSL stream
|
// Wrap the now-connected socket in an SSL stream
|
||||||
using stream_type = ssl::stream<tcp::socket&>;
|
using stream_type = ssl::stream<tcp::socket&>;
|
||||||
ssl::context ctx{ssl::context::sslv23};
|
|
||||||
stream_type stream{sock, ctx};
|
stream_type stream{sock, ctx};
|
||||||
stream.set_verify_mode(ssl::verify_none);
|
stream.set_verify_mode(ssl::verify_none);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user