| 71 | } |
| 72 | |
| 73 | void UnbufferedAsioTlsStream::BeforeHandshake(handshake_type type) |
| 74 | { |
| 75 | namespace ssl = boost::asio::ssl; |
| 76 | |
| 77 | if (!m_Hostname.IsEmpty()) { |
| 78 | X509_VERIFY_PARAM_set1_host(SSL_get0_param(native_handle()), m_Hostname.CStr(), m_Hostname.GetLength()); |
| 79 | } |
| 80 | |
| 81 | set_verify_mode(ssl::verify_peer | ssl::verify_client_once); |
| 82 | |
| 83 | set_verify_callback([](bool preverified, ssl::verify_context& ctx) { |
| 84 | (void) preverified; |
| 85 | (void) ctx; |
| 86 | |
| 87 | /* Continue the handshake even if an invalid peer certificate was presented. The verification result has to be |
| 88 | * checked using the IsVerifyOK() method. |
| 89 | * |
| 90 | * Such connections are used for the initial enrollment of nodes where they use a self-signed certificate to |
| 91 | * send a certificate request and receive their valid certificate after approval (manually by the administrator |
| 92 | * or using a certificate ticket). |
| 93 | */ |
| 94 | return true; |
| 95 | }); |
| 96 | |
| 97 | #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME |
| 98 | if (type == client && !m_Hostname.IsEmpty()) { |
| 99 | String environmentName = Application::GetAppEnvironment(); |
| 100 | String serverName = m_Hostname; |
| 101 | |
| 102 | if (!environmentName.IsEmpty()) |
| 103 | serverName += ":" + environmentName; |
| 104 | |
| 105 | SSL_set_tlsext_host_name(native_handle(), serverName.CStr()); |
| 106 | } |
| 107 | #endif /* SSL_CTRL_SET_TLSEXT_HOSTNAME */ |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Forcefully close the connection, typically (details are up to the operating system) using a TCP RST. |