diff options
| author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-06-25 22:59:01 +0000 |
|---|---|---|
| committer | <> | 2013-09-27 11:49:28 +0000 |
| commit | 8c4528713d907ee2cfd3bfcbbad272c749867f84 (patch) | |
| tree | c09e2ce80f47b90c85cc720f5139089ad9c8cfff /libs/asio/example/cpp03/ssl | |
| download | boost-tarball-baserock/morph.tar.gz | |
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_54_0.tar.bz2.boost_1_54_0baserock/morph
Diffstat (limited to 'libs/asio/example/cpp03/ssl')
| -rw-r--r-- | libs/asio/example/cpp03/ssl/Jamfile | 49 | ||||
| -rw-r--r-- | libs/asio/example/cpp03/ssl/Jamfile.v2 | 54 | ||||
| -rw-r--r-- | libs/asio/example/cpp03/ssl/README | 8 | ||||
| -rw-r--r-- | libs/asio/example/cpp03/ssl/ca.pem | 31 | ||||
| -rw-r--r-- | libs/asio/example/cpp03/ssl/client.cpp | 156 | ||||
| -rw-r--r-- | libs/asio/example/cpp03/ssl/dh512.pem | 12 | ||||
| -rw-r--r-- | libs/asio/example/cpp03/ssl/server.cpp | 170 | ||||
| -rw-r--r-- | libs/asio/example/cpp03/ssl/server.pem | 44 |
8 files changed, 524 insertions, 0 deletions
diff --git a/libs/asio/example/cpp03/ssl/Jamfile b/libs/asio/example/cpp03/ssl/Jamfile new file mode 100644 index 000000000..5456e93fa --- /dev/null +++ b/libs/asio/example/cpp03/ssl/Jamfile @@ -0,0 +1,49 @@ +# +# Copyright (c) 2003-2013 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) +# + +subproject libs/asio/example/ssl ; + +project boost : $(BOOST_ROOT) ; + +if $(UNIX) +{ + switch $(JAMUNAME) + { + case SunOS* : + { + SOCKET_LIBS = <find-library>socket <find-library>nsl ; + } + } +} + +exe client + : <lib>@boost/libs/system/build/boost_system + client.cpp + : <include>$(BOOST_ROOT) + <include>../../../.. + <define>BOOST_ALL_NO_LIB=1 + <threading>multi + <find-library>ssl + <find-library>crypto + <mingw><*><find-library>ws2_32 + <mingw><*><find-library>mswsock + $(SOCKET_LIBS) + ; + +exe server + : <lib>@boost/libs/system/build/boost_system + server.cpp + : <include>$(BOOST_ROOT) + <include>../../../.. + <define>BOOST_ALL_NO_LIB=1 + <threading>multi + <find-library>ssl + <find-library>crypto + <mingw><*><find-library>ws2_32 + <mingw><*><find-library>mswsock + $(SOCKET_LIBS) + ; diff --git a/libs/asio/example/cpp03/ssl/Jamfile.v2 b/libs/asio/example/cpp03/ssl/Jamfile.v2 new file mode 100644 index 000000000..5a2416f62 --- /dev/null +++ b/libs/asio/example/cpp03/ssl/Jamfile.v2 @@ -0,0 +1,54 @@ +# +# Copyright (c) 2003-2013 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) +# + +import os ; + +if [ os.name ] = SOLARIS +{ + lib socket ; + lib nsl ; +} +else if [ os.name ] = NT +{ + lib ws2_32 ; + lib mswsock ; +} +else if [ os.name ] = HPUX +{ + lib ipv6 ; +} + +if [ os.name ] = NT +{ + lib ssl : : <name>ssleay32 ; + lib crypto : : <name>libeay32 ; +} +else +{ + lib ssl ; + lib crypto ; +} + +project + : requirements + <library>/boost/system//boost_system + <define>BOOST_ALL_NO_LIB=1 + <threading>multi + <os>SOLARIS:<library>socket + <os>SOLARIS:<library>nsl + <os>NT:<define>_WIN32_WINNT=0x0501 + <os>NT,<toolset>gcc:<library>ws2_32 + <os>NT,<toolset>gcc:<library>mswsock + <os>NT,<toolset>gcc-cygwin:<define>__USE_W32_SOCKETS + <os>HPUX,<toolset>gcc:<define>_XOPEN_SOURCE_EXTENDED + <os>HPUX:<library>ipv6 + <library>ssl + <library>crypto + ; + +exe client : client.cpp ; +exe server : server.cpp ; diff --git a/libs/asio/example/cpp03/ssl/README b/libs/asio/example/cpp03/ssl/README new file mode 100644 index 000000000..911f0a4dc --- /dev/null +++ b/libs/asio/example/cpp03/ssl/README @@ -0,0 +1,8 @@ +The passphrase for both the CA and server private keys is "test". + + +------------------------------------------------------------------------------- +Copyright (c) 2003-2013 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) diff --git a/libs/asio/example/cpp03/ssl/ca.pem b/libs/asio/example/cpp03/ssl/ca.pem new file mode 100644 index 000000000..45de7742b --- /dev/null +++ b/libs/asio/example/cpp03/ssl/ca.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIB7TCCAVYCCQCxKhAUH1ygCDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJB +VTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8w +HhcNMDUxMTAyMTk0ODU1WhcNMTUxMTAyMTk0ODU1WjA7MQswCQYDVQQGEwJBVTEM +MAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMkNbM2RjFdm48Wy1nBA3+exfJL5fR6H +guRFu/7MKf6pQZGRqhzxIWYRoYQDx16BggHwqFVVls5hgoQF0fUqoHfE8MLGwr6m +T6rIYBrIAGnH8eMhfwMNy4I0emkoWI+grEXlw54IUSijh8LokLWorElyGuPmxhn3 +IgZkgGe8dCQTAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAdpHw+r3X4NwzKn9nQs3h +mQK2WeH6DVQ1r7fWqEq1Lq10qBdobbjDRE9jpezWdGMThbYtle6/8wHUJeq189PR +XwZWyRvnfcI+pqX832yNRh24Ujwuv3wlx3JOVByybCoJc05N1THaHo0Q7j//8HsX +VS/RFHuq3muy47cV9gbsCIw= +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,EC6C715D9BC7AFF2 + +bBOh4F/Ouq2cpaWYUqCvpVVTAkptsHCkUFZpjqruGMw1pQ6BY2eBzuHHNgOV+8BI +4Md8LcvD9oRmkigXp10I6ELkPpvTqK5S/9iJBlR/XgYjuj2PkdLiT2t4dWrJP9Rq +NdjybhKV0qqB/WiBKoSI/n0mYDxmrrHjmPAXi3BnivyQiUry42hs+Izxlkyt///D +bDzkW/LqiMDwxOu9mCsxdN/iiFgKsPQBxvLbdG3p1GyERrnB85DeewYGF9fzp1Nz +CXWQiPqEkf3arqgKBIjK+TDfmDluL7+nOyhSp0j9Rh1zba8ffmYZNXXLt0ludVdm +8zbwqjbX6u4BZ+pSpnURFBp9um0TlxhpJ5F3q5ZyUa7l4tTlw37V8UkFP8KmBbuc +PDnjbdlD5BtAbR/b/dDSAhU2y7aftcTsZCu22UOLQqWOm6jMk943ZfmG93rCeKNL +qa4OPXsICSNqKivF0Ovyw5U7ODsFj0UTD8/VY+JWLz/bmJdpsBCNlkfQHGtTahfq +QY4mG0K+cWmUiGvcWcU1pjI4e551dR05wNDmyfJMHHVzn2VnCrxKSKGEtJOMcyzi +E42zQkGlYWVJyqDFHfxCe+1GJLJvW2oYGUUY/++XDzvxITT6Lq3wb1MGisoaC1Q7 +523SXpzVIU+FLlWxewrSnZOyTe13lgNK4OVnuRqz/LQExjfwUXtgqQkRp6A8jTmC +6LWEaXQ6kC7QmwX0VQgtNi74ZMMrBsaxywaE+3oEibeJiXbVJCHDo3RufA9AJnpF +HUmTFTnoBr4f8AUxN0Eyb5Yg16pzOBI5o4EzjKzJ4D0= +-----END RSA PRIVATE KEY----- diff --git a/libs/asio/example/cpp03/ssl/client.cpp b/libs/asio/example/cpp03/ssl/client.cpp new file mode 100644 index 000000000..7beb595b1 --- /dev/null +++ b/libs/asio/example/cpp03/ssl/client.cpp @@ -0,0 +1,156 @@ +// +// client.cpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2013 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) +// + +#include <cstdlib> +#include <iostream> +#include <boost/bind.hpp> +#include <boost/asio.hpp> +#include <boost/asio/ssl.hpp> + +enum { max_length = 1024 }; + +class client +{ +public: + client(boost::asio::io_service& io_service, + boost::asio::ssl::context& context, + boost::asio::ip::tcp::resolver::iterator endpoint_iterator) + : socket_(io_service, context) + { + socket_.set_verify_mode(boost::asio::ssl::verify_peer); + socket_.set_verify_callback( + boost::bind(&client::verify_certificate, this, _1, _2)); + + boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator, + boost::bind(&client::handle_connect, this, + boost::asio::placeholders::error)); + } + + bool verify_certificate(bool preverified, + boost::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 boost::system::error_code& error) + { + if (!error) + { + socket_.async_handshake(boost::asio::ssl::stream_base::client, + boost::bind(&client::handle_handshake, this, + boost::asio::placeholders::error)); + } + else + { + std::cout << "Connect failed: " << error.message() << "\n"; + } + } + + void handle_handshake(const boost::system::error_code& error) + { + if (!error) + { + std::cout << "Enter message: "; + std::cin.getline(request_, max_length); + size_t request_length = strlen(request_); + + boost::asio::async_write(socket_, + boost::asio::buffer(request_, request_length), + boost::bind(&client::handle_write, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + } + else + { + std::cout << "Handshake failed: " << error.message() << "\n"; + } + } + + void handle_write(const boost::system::error_code& error, + size_t bytes_transferred) + { + if (!error) + { + boost::asio::async_read(socket_, + boost::asio::buffer(reply_, bytes_transferred), + boost::bind(&client::handle_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + } + else + { + std::cout << "Write failed: " << error.message() << "\n"; + } + } + + void handle_read(const boost::system::error_code& error, + size_t bytes_transferred) + { + if (!error) + { + std::cout << "Reply: "; + std::cout.write(reply_, bytes_transferred); + std::cout << "\n"; + } + else + { + std::cout << "Read failed: " << error.message() << "\n"; + } + } + +private: + boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_; + char request_[max_length]; + char reply_[max_length]; +}; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 3) + { + std::cerr << "Usage: client <host> <port>\n"; + return 1; + } + + boost::asio::io_service io_service; + + boost::asio::ip::tcp::resolver resolver(io_service); + boost::asio::ip::tcp::resolver::query query(argv[1], argv[2]); + boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query); + + boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23); + ctx.load_verify_file("ca.pem"); + + client c(io_service, ctx, iterator); + + io_service.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} diff --git a/libs/asio/example/cpp03/ssl/dh512.pem b/libs/asio/example/cpp03/ssl/dh512.pem new file mode 100644 index 000000000..14c53b2a2 --- /dev/null +++ b/libs/asio/example/cpp03/ssl/dh512.pem @@ -0,0 +1,12 @@ +Diffie-Hellman-Parameters: (512 bit) + prime: + 00:a0:bc:d0:c2:c3:a8:c7:a5:62:13:cd:f0:63:39: + ea:85:e0:f7:ca:00:8a:57:ec:12:dd:92:2b:20:70: + 38:6c:03:60:b1:19:e3:0b:e9:d3:05:f1:1b:cc:8c: + 9c:1a:30:3e:91:de:db:17:a7:19:cf:da:a0:2d:ee: + ef:35:95:8b:4b + generator: 5 (0x5) +-----BEGIN DH PARAMETERS----- +MEYCQQCgvNDCw6jHpWITzfBjOeqF4PfKAIpX7BLdkisgcDhsA2CxGeML6dMF8RvM +jJwaMD6R3tsXpxnP2qAt7u81lYtLAgEF +-----END DH PARAMETERS----- diff --git a/libs/asio/example/cpp03/ssl/server.cpp b/libs/asio/example/cpp03/ssl/server.cpp new file mode 100644 index 000000000..eabcfb33b --- /dev/null +++ b/libs/asio/example/cpp03/ssl/server.cpp @@ -0,0 +1,170 @@ +// +// server.cpp +// ~~~~~~~~~~ +// +// Copyright (c) 2003-2013 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) +// + +#include <cstdlib> +#include <iostream> +#include <boost/bind.hpp> +#include <boost/asio.hpp> +#include <boost/asio/ssl.hpp> + +typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> ssl_socket; + +class session +{ +public: + session(boost::asio::io_service& io_service, + boost::asio::ssl::context& context) + : socket_(io_service, context) + { + } + + ssl_socket::lowest_layer_type& socket() + { + return socket_.lowest_layer(); + } + + void start() + { + socket_.async_handshake(boost::asio::ssl::stream_base::server, + boost::bind(&session::handle_handshake, this, + boost::asio::placeholders::error)); + } + + void handle_handshake(const boost::system::error_code& error) + { + if (!error) + { + socket_.async_read_some(boost::asio::buffer(data_, max_length), + boost::bind(&session::handle_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + } + else + { + delete this; + } + } + + void handle_read(const boost::system::error_code& error, + size_t bytes_transferred) + { + if (!error) + { + boost::asio::async_write(socket_, + boost::asio::buffer(data_, bytes_transferred), + boost::bind(&session::handle_write, this, + boost::asio::placeholders::error)); + } + else + { + delete this; + } + } + + void handle_write(const boost::system::error_code& error) + { + if (!error) + { + socket_.async_read_some(boost::asio::buffer(data_, max_length), + boost::bind(&session::handle_read, this, + boost::asio::placeholders::error, + boost::asio::placeholders::bytes_transferred)); + } + else + { + delete this; + } + } + +private: + ssl_socket socket_; + enum { max_length = 1024 }; + char data_[max_length]; +}; + +class server +{ +public: + server(boost::asio::io_service& io_service, unsigned short port) + : io_service_(io_service), + acceptor_(io_service, + boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)), + context_(boost::asio::ssl::context::sslv23) + { + context_.set_options( + boost::asio::ssl::context::default_workarounds + | boost::asio::ssl::context::no_sslv2 + | boost::asio::ssl::context::single_dh_use); + context_.set_password_callback(boost::bind(&server::get_password, this)); + context_.use_certificate_chain_file("server.pem"); + context_.use_private_key_file("server.pem", boost::asio::ssl::context::pem); + context_.use_tmp_dh_file("dh512.pem"); + + start_accept(); + } + + std::string get_password() const + { + return "test"; + } + + void start_accept() + { + session* new_session = new session(io_service_, context_); + acceptor_.async_accept(new_session->socket(), + boost::bind(&server::handle_accept, this, new_session, + boost::asio::placeholders::error)); + } + + void handle_accept(session* new_session, + const boost::system::error_code& error) + { + if (!error) + { + new_session->start(); + } + else + { + delete new_session; + } + + start_accept(); + } + +private: + boost::asio::io_service& io_service_; + boost::asio::ip::tcp::acceptor acceptor_; + boost::asio::ssl::context context_; +}; + +int main(int argc, char* argv[]) +{ + try + { + if (argc != 2) + { + std::cerr << "Usage: server <port>\n"; + return 1; + } + + boost::asio::io_service io_service; + + using namespace std; // For atoi. + server s(io_service, atoi(argv[1])); + + io_service.run(); + } + catch (std::exception& e) + { + std::cerr << "Exception: " << e.what() << "\n"; + } + + return 0; +} diff --git a/libs/asio/example/cpp03/ssl/server.pem b/libs/asio/example/cpp03/ssl/server.pem new file mode 100644 index 000000000..5b2052d9e --- /dev/null +++ b/libs/asio/example/cpp03/ssl/server.pem @@ -0,0 +1,44 @@ +-----BEGIN CERTIFICATE----- +MIIB/jCCAWcCCQDlADUqOr8YCTANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJB +VTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8w +HhcNMDUxMTAyMTk1MjMzWhcNMTUxMTAyMTk1MjMzWjBMMQswCQYDVQQGEwJBVTEM +MAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8xDzAN +BgNVBAsTBnNlcnZlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxAkg4iw5 +X8pXhJ8GfjGRKVOClt/EI9ypQMqWQSRH0pGDFlIOQzsfhqsCyp/xcfCwPBvfMIeE +IzYiZ5kH6YD9EfHmIA6hsd1i3layCpeiA2VXrUXsvL8Y3fUt1/3IAR+pmVI4XGas +lCb0zs1n0K08v9AWBkVE5rirA5an263Sd+kCAwEAATANBgkqhkiG9w0BAQUFAAOB +gQBzFX/efrhGVzfK4Ue+/7Og44r7OLzQepSyQavFhp+t3PX1hy4ifneTnqMyME8w +WuB94G/gtST9ECVHRKUuBn4xT1rz5DO20h3VSAzTirkSFQPdWunyBbIva0Hsf6pF +287CA1cM106X0Vs4dv2F2u0zSszYfOysAM1pIPcxdyboXA== +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,9A7CF9C13224C492 + +w00sJ2/d79LRI+9LRsnQkBZwIo/NbprFtN3SVqcUAtncqowl9BnKZnQ2csnj8KZA +STAL+PZAyJQTiJfJxecCkB8Tu4/apFe2V9/PxUirJzGtJ9FHBAjLgmpK4yWwSCMq +txyy8hjm8ggR8SQNJ1Jf+O6uGotillq02TJ0RluRrhukkfevClXTfCl3ngGI3D1q +v5dFZrU2r2pGpkxCxI8SoQCCaH6l/plR9IhKl1/cz9chiXUFmAb4kMazneZaFmiu +B8AJMQcFDfKttdKmkxY1qdQI9bOKw2YSZT6aASZTHD84hDloQRdgok8VO1YBKfzj +0jEYnaYuXZGD+h38giABPV0iTY7aC0RdcyP63ZQH95KXtSLGBfUHEOvR4jR4uLu9 +3Qfw4j1/HzmCrXVZNyGswwagVuVcvmBuHwGmnxMaWCGIC1CODf8X5BG4V932Akpl +mCeQyLdkXHehZvSV1OCwxGko0FjVwnKIOplyMqCVpeDNwuddH02zo5h+kBSrTg0m +XEMlVMAadS9vgwLCLL1GKeVpYT3jNbgDfUrXC6udycgGdYA6QtmeuiZ3Lv37TQ8K +LD7ono+XsT38XvlKRqbPrlHNae+PRLudKWHsgrZg2MckyEpG/x9dygru561p1Dns +Bm17CVkQUIZyAPXQB6/UmxPbJYsChiQXxy3/4U2eZLVVkHRP7gPWBnFjNoyd5OBw +G+psOVLNgCnFh+z4NO5CB4mVNtrR1NAH6IFhnlrip4YFRk3XPHVlkrxn6fHeEDGE +eVB3XJcgsGnVQCvF5vsymZWZ722xgLPkK8iG3QLayoM4c9RlrKMwwA== +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIB7TCCAVYCCQCxKhAUH1ygCDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJB +VTEMMAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8w +HhcNMDUxMTAyMTk0ODU1WhcNMTUxMTAyMTk0ODU1WjA7MQswCQYDVQQGEwJBVTEM +MAoGA1UECBMDTlNXMQ8wDQYDVQQHEwZTeWRuZXkxDTALBgNVBAoTBGFzaW8wgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMkNbM2RjFdm48Wy1nBA3+exfJL5fR6H +guRFu/7MKf6pQZGRqhzxIWYRoYQDx16BggHwqFVVls5hgoQF0fUqoHfE8MLGwr6m +T6rIYBrIAGnH8eMhfwMNy4I0emkoWI+grEXlw54IUSijh8LokLWorElyGuPmxhn3 +IgZkgGe8dCQTAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAdpHw+r3X4NwzKn9nQs3h +mQK2WeH6DVQ1r7fWqEq1Lq10qBdobbjDRE9jpezWdGMThbYtle6/8wHUJeq189PR +XwZWyRvnfcI+pqX832yNRh24Ujwuv3wlx3JOVByybCoJc05N1THaHo0Q7j//8HsX +VS/RFHuq3muy47cV9gbsCIw= +-----END CERTIFICATE----- |
