Line data Source code
1 : #include "source/extensions/transport_sockets/tls/ssl_handshaker.h" 2 : 3 : #include "envoy/stats/scope.h" 4 : 5 : #include "source/common/common/assert.h" 6 : #include "source/common/common/empty_string.h" 7 : #include "source/common/http/headers.h" 8 : #include "source/common/runtime/runtime_features.h" 9 : #include "source/extensions/transport_sockets/tls/utility.h" 10 : 11 : using Envoy::Network::PostIoAction; 12 : 13 : namespace Envoy { 14 : namespace Extensions { 15 : namespace TransportSockets { 16 : namespace Tls { 17 : 18 0 : void ValidateResultCallbackImpl::onSslHandshakeCancelled() { extended_socket_info_.reset(); } 19 : 20 : void ValidateResultCallbackImpl::onCertValidationResult(bool succeeded, 21 : Ssl::ClientValidationStatus detailed_status, 22 : const std::string& /*error_details*/, 23 0 : uint8_t tls_alert) { 24 0 : if (!extended_socket_info_.has_value()) { 25 0 : return; 26 0 : } 27 0 : extended_socket_info_->setCertificateValidationStatus(detailed_status); 28 0 : extended_socket_info_->setCertificateValidationAlert(tls_alert); 29 0 : extended_socket_info_->onCertificateValidationCompleted(succeeded, true); 30 0 : } 31 : 32 0 : SslExtendedSocketInfoImpl::~SslExtendedSocketInfoImpl() { 33 0 : if (cert_validate_result_callback_.has_value()) { 34 0 : cert_validate_result_callback_->onSslHandshakeCancelled(); 35 0 : } 36 0 : } 37 : 38 : void SslExtendedSocketInfoImpl::setCertificateValidationStatus( 39 0 : Envoy::Ssl::ClientValidationStatus validated) { 40 0 : certificate_validation_status_ = validated; 41 0 : } 42 : 43 0 : Envoy::Ssl::ClientValidationStatus SslExtendedSocketInfoImpl::certificateValidationStatus() const { 44 0 : return certificate_validation_status_; 45 0 : } 46 : 47 0 : void SslExtendedSocketInfoImpl::onCertificateValidationCompleted(bool succeeded, bool async) { 48 0 : cert_validation_result_ = 49 0 : succeeded ? Ssl::ValidateStatus::Successful : Ssl::ValidateStatus::Failed; 50 0 : if (cert_validate_result_callback_.has_value()) { 51 0 : cert_validate_result_callback_.reset(); 52 : // Resume handshake. 53 0 : if (async) { 54 0 : ssl_handshaker_.handshakeCallbacks()->onAsynchronousCertValidationComplete(); 55 0 : } 56 0 : } 57 0 : } 58 : 59 0 : Ssl::ValidateResultCallbackPtr SslExtendedSocketInfoImpl::createValidateResultCallback() { 60 0 : auto callback = std::make_unique<ValidateResultCallbackImpl>( 61 0 : ssl_handshaker_.handshakeCallbacks()->connection().dispatcher(), *this); 62 0 : cert_validate_result_callback_ = *callback; 63 0 : cert_validation_result_ = Ssl::ValidateStatus::Pending; 64 0 : return callback; 65 0 : } 66 : 67 : SslHandshakerImpl::SslHandshakerImpl(bssl::UniquePtr<SSL> ssl, int ssl_extended_socket_info_index, 68 : Ssl::HandshakeCallbacks* handshake_callbacks) 69 : : ssl_(std::move(ssl)), handshake_callbacks_(handshake_callbacks), 70 0 : extended_socket_info_(*this) { 71 0 : SSL_set_ex_data(ssl_.get(), ssl_extended_socket_info_index, &(this->extended_socket_info_)); 72 0 : } 73 : 74 0 : bool SslHandshakerImpl::peerCertificateValidated() const { 75 0 : return extended_socket_info_.certificateValidationStatus() == 76 0 : Envoy::Ssl::ClientValidationStatus::Validated; 77 0 : } 78 : 79 0 : Network::PostIoAction SslHandshakerImpl::doHandshake() { 80 0 : ASSERT(state_ != Ssl::SocketState::HandshakeComplete && state_ != Ssl::SocketState::ShutdownSent); 81 0 : int rc = SSL_do_handshake(ssl()); 82 0 : if (rc == 1) { 83 0 : state_ = Ssl::SocketState::HandshakeComplete; 84 0 : handshake_callbacks_->onSuccess(ssl()); 85 : 86 : // It's possible that we closed during the handshake callback. 87 0 : return handshake_callbacks_->connection().state() == Network::Connection::State::Open 88 0 : ? PostIoAction::KeepOpen 89 0 : : PostIoAction::Close; 90 0 : } else { 91 0 : int err = SSL_get_error(ssl(), rc); 92 0 : ENVOY_CONN_LOG(trace, "ssl error occurred while read: {}", handshake_callbacks_->connection(), 93 0 : Utility::getErrorDescription(err)); 94 0 : switch (err) { 95 0 : case SSL_ERROR_WANT_READ: 96 0 : case SSL_ERROR_WANT_WRITE: 97 0 : return PostIoAction::KeepOpen; 98 0 : case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION: 99 0 : case SSL_ERROR_WANT_CERTIFICATE_VERIFY: 100 0 : state_ = Ssl::SocketState::HandshakeInProgress; 101 0 : return PostIoAction::KeepOpen; 102 0 : default: 103 0 : handshake_callbacks_->onFailure(); 104 0 : return PostIoAction::Close; 105 0 : } 106 0 : } 107 0 : } 108 : 109 : } // namespace Tls 110 : } // namespace TransportSockets 111 : } // namespace Extensions 112 : } // namespace Envoy