From 544be0dcf730994909c1fd5e0e665a6b0dd03fee Mon Sep 17 00:00:00 2001 From: dmatetelki Date: Wed, 11 May 2016 10:45:47 +0200 Subject: [PATCH] SSL connection close fix and some cert and pey to start a server --- lib/cpp_utils/SslConnection.cpp | 70 ++++++++++++++++++++++----------- lib/cpp_utils/SslConnection.hpp | 12 ++++-- other/cert.pem | 21 ++++++++++ other/key.pem | 28 +++++++++++++ other/sslserver_main.cpp | 4 +- 5 files changed, 106 insertions(+), 29 deletions(-) create mode 100644 other/cert.pem create mode 100644 other/key.pem diff --git a/lib/cpp_utils/SslConnection.cpp b/lib/cpp_utils/SslConnection.cpp index 260ca18..71761a0 100644 --- a/lib/cpp_utils/SslConnection.cpp +++ b/lib/cpp_utils/SslConnection.cpp @@ -29,7 +29,9 @@ void SslConnection::destroy() SslConnection::SslConnection ( const std::string host, const std::string port, Message *message, - const size_t bufferLength ) + const size_t bufferLength, + bool bidirectional_shutdown + ) : StreamConnection(host, port) , m_timedTcpConnection(new TimedTcpConnection(host, port, message, 0)) , m_message(message) @@ -37,6 +39,7 @@ SslConnection::SslConnection ( const std::string host, , m_bufferLength(bufferLength) , m_sslHandle(0) , m_sslContext(0) + , m_bidirectional_shutdown(bidirectional_shutdown) { TRACE; m_buffer = new unsigned char[m_bufferLength]; @@ -131,25 +134,33 @@ bool SslConnection::disconnect() { TRACE; - /// @note do I have to call this? - if ( m_timedTcpConnection->getSocket() != -1 ) - m_timedTcpConnection->disconnect(); - if ( m_sslHandle == 0 || m_sslContext == 0 ) return false; int ret = SSL_shutdown(m_sslHandle); if ( ret == 0 ) { - LOG( Logger::INFO, "\"close notify\" alert was sent and the peer's " - "\"close notify\" alert was received."); + LOG( Logger::INFO, "\"close notify\" alert was sent, " + "shutdown is not yet finished"); + if (m_bidirectional_shutdown) { + int ret2 = SSL_shutdown(m_sslHandle); + if ( ret2 == 0 ) { + LOG( Logger::ERR, "Shutdown is not finished, giving up."); + } else if ( ret2 == 1 ) { + LOG( Logger::INFO, "Peer's \"close notify\" alert reply was received."); + } else if ( ret2 < 0 ) { + LOG (Logger::INFO, "No reply, the peer probably closed the underlying connection." ); + } + } } else if (ret == 1 ) { - LOG( Logger::WARNING, "The shutdown is not yet finished. " - "Calling SSL_shutdown() for a second time..."); - SSL_shutdown(m_sslHandle); + LOG( Logger::INFO, "\"close notify\" alert was sent" + " and the peer's \"close notify\" alert was received."); } - else if ( ret == 2 ) { - LOG (Logger::ERR, getSslError("The shutdown was not successful. ").c_str() ); + else if ( ret < 0 ) { + LOG (Logger::ERR, (getSslError("The shutdown was not successful. ") + + "system error: " + std::string(strerror(errno))).c_str() + + ); } /// @note I have to check the ref count?! This stinks @@ -162,6 +173,10 @@ bool SslConnection::disconnect() m_sslHandle = 0; m_sslContext = 0; + /// @note do I have to call this? + if ( m_timedTcpConnection->getSocket() != -1 ) + m_timedTcpConnection->disconnect(); + return true; } @@ -207,10 +222,10 @@ bool SslConnection::send( const void* message, const size_t length ) if ( ret > 0 ) return true; - unsigned long sslErrNo = ERR_peek_error(); + unsigned long sslErrNo = ERR_get_error(); if ( ret == 0 && sslErrNo == SSL_ERROR_ZERO_RETURN ) { - LOG( Logger::INFO, "Underlying connection has been closed."); - return true; + LOG( Logger::INFO, "SSL connection has been closed, cannot write."); + return false; } LOG (Logger::ERR, getSslError("SSL write failed. ").c_str() ); @@ -222,17 +237,21 @@ bool SslConnection::receive() { TRACE; - int length = SSL_read(m_sslHandle, m_buffer, m_bufferLength); + int ret = SSL_read(m_sslHandle, m_buffer, m_bufferLength); - if ( length > 0 ) - return m_message->buildMessage( (void*)m_buffer, (size_t)length); + if ( ret > 0 ) + return m_message->buildMessage( (void*)m_buffer, (size_t)ret); - if ( length == 0 ) { - LOG( Logger::INFO, "SSL connection has been closed."); + unsigned long sslErrNo = ERR_get_error(); + if ( ret == 0 && (sslErrNo == SSL_ERROR_ZERO_RETURN || + sslErrNo == SSL_ERROR_NONE) ) { + LOG( Logger::INFO, "SSL connection has been closed, cannot read."); return false; } - LOG (Logger::ERR, getSslError("SSL read failed. ").c_str() ); + LOG (Logger::ERR, (getSslError("The shutdown was not successful. ") + + "system error: " + std::string(strerror(errno))).c_str() ); + return false; } @@ -251,9 +270,11 @@ int SslConnection::getSocket() const } -SslConnection::SslConnection(TimedTcpConnection *timedTcpConnection, - Message *message, - const size_t bufferLength) +SslConnection::SslConnection(TimedTcpConnection* timedTcpConnection, + Message* message, + const size_t bufferLength, + bool bidirectional_shutdown + ) : StreamConnection("invalid", "invalid") , m_timedTcpConnection(timedTcpConnection) , m_message(message) @@ -261,6 +282,7 @@ SslConnection::SslConnection(TimedTcpConnection *timedTcpConnection, , m_bufferLength(bufferLength) , m_sslHandle(0) , m_sslContext(0) + , m_bidirectional_shutdown(bidirectional_shutdown) { TRACE; diff --git a/lib/cpp_utils/SslConnection.hpp b/lib/cpp_utils/SslConnection.hpp index ebed1fc..920c0ac 100644 --- a/lib/cpp_utils/SslConnection.hpp +++ b/lib/cpp_utils/SslConnection.hpp @@ -21,7 +21,8 @@ public: SslConnection ( const std::string host, const std::string port, Message *message, - const size_t bufferLength = 1024 ); + const size_t bufferLength = 1024, + bool bidirectional_shutdown = true ); virtual ~SslConnection(); @@ -46,9 +47,11 @@ public: private: - SslConnection ( TimedTcpConnection *timedTcpConnection, - Message *message, - const size_t bufferLength = 1024 ); + SslConnection ( TimedTcpConnection* timedTcpConnection, + Message* message, + const size_t bufferLength = 1024, + bool bidirectional_shutdown = true + ); SslConnection(const SslConnection&); SslConnection& operator=(const SslConnection&); @@ -67,6 +70,7 @@ private: size_t m_bufferLength; SSL *m_sslHandle; SSL_CTX *m_sslContext; + bool m_bidirectional_shutdown; }; diff --git a/other/cert.pem b/other/cert.pem new file mode 100644 index 0000000..bb987e4 --- /dev/null +++ b/other/cert.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIJAIj9maLye2npMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAm5vMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTYwNTEwMTQyODE4WhcNMTYwNjA5MTQyODE4WjBF +MQswCQYDVQQGEwJubzETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuvX93o9UXiWOOB/AhlHk1U1aP8EQujfT6vlG//fzde8RIxotvkW8VhEd +Ef59jwEjsMBkqiaroOOTGFtG9iLXFnQJ6nOFW5jZaYQ2CeGsT4I9PvieO2n3/p9W +w/CwsgwdwqgdXRWHKhyPu3pVUaurrPY++uH2twFYEVptaAczwBzeXpL1oWCYLidS +TLymmmEyB4ZM+CAX3SmUeeFX9zFyI6scwksT17kbRdQAnKI3ua7wPGwKjSD9jgoX +3XadI9ffsEA3NIPcJZRX9NsOR/x+eLJrJuvQn7WGI+xP9xZ87xiLbJdax1XmtNG5 +bKezQ14DcrDXQExQITZ4t4yl+P6b2QIDAQABo1AwTjAdBgNVHQ4EFgQU69mZpq4Z +HEyqWDDc+DLgLqUW7p8wHwYDVR0jBBgwFoAU69mZpq4ZHEyqWDDc+DLgLqUW7p8w +DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANFEMrB1dsMlSiglAT25L +U3/8SiCpp0AKMeFqzPEP24AiQAQe2qCobJ5uUPiB6w3zb3EUGSeOv5RuKT6Pvq+0 +u+MHmltJ8h8AnY0x+SvCY3Lnjircono9A/sZNEq+URTzXgFK6d8CgcJWZc2sPvat +/ZosVC4gQjyXRmnsAoKq19aUfHeA+sippoGMRmex0VHfolweacWPTdrez716yGHy +9aqo7hA5QzKz5l5/LGd/zdAyxm9qrlkFPpDq7Vmy0iumIM7WsFVePDx4WIRaWOct +V93hC+O1eT0+oiKddZLOnbikROhS6R5tS7mxppwClInMOT8iLBXNRht0xS0cf0fT +3w== +-----END CERTIFICATE----- diff --git a/other/key.pem b/other/key.pem new file mode 100644 index 0000000..02a2d04 --- /dev/null +++ b/other/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC69f3ej1ReJY44 +H8CGUeTVTVo/wRC6N9Pq+Ub/9/N17xEjGi2+RbxWER0R/n2PASOwwGSqJqug45MY +W0b2ItcWdAnqc4VbmNlphDYJ4axPgj0++J47aff+n1bD8LCyDB3CqB1dFYcqHI+7 +elVRq6us9j764fa3AVgRWm1oBzPAHN5ekvWhYJguJ1JMvKaaYTIHhkz4IBfdKZR5 +4Vf3MXIjqxzCSxPXuRtF1ACcoje5rvA8bAqNIP2OChfddp0j19+wQDc0g9wllFf0 +2w5H/H54smsm69CftYYj7E/3FnzvGItsl1rHVea00blsp7NDXgNysNdATFAhNni3 +jKX4/pvZAgMBAAECggEAYOzWyGMWIhjmOkJ71Sbvs4V+nD7DJUd8Hf1NybYKCcH+ +6GvR+yq8EQKeR43gGhtFHYUgqvWRVL+mqqHnkANP7twJp/pr0KjVTda1DTpp0m56 +wgKyRasSXnbMzJgjgqq1Yw006+UVRce43ED3qneNcQXYcMhk10tjFNwEjEHvmlB5 +vC43lz5tvKQkbP+MH1D3Hm2r0jkGKmOb8v1e8gqVnqdpGv8ns6JCVySwJBLTqJW+ +rh5/S/CKiJcoEmTvAR4pc2rlBQJ4b1kd62O9o0Ldd+4ZnmIJgZ62tq1jxhRxklKl +2/1Eaoq0v9Tp8TSVYjKa4+PCrKN/qiT9ZXPC3CN9YQKBgQDqGW7qqliR7gtZXzqh +UO0NPC0oVUaoljckT/g9hJwA+U+nFzjBKj2mhWu3+iqNLqKuVudfAonnSZDkvYE7 +NniAkZDw3Tx0i1UYJnshuecRNtEd/XwBxDMNley3NNWLsZEzRHElRyiDY4SgPv8l +b9yb4jnGMZw7arjIIUWNxDJFbwKBgQDMc52I2B+tE4y+gouJPmJvD6rNeaSg3C58 +xbgFxtc1Lf8ONpzhorzu3SrOQ88SMgHGTEDBpR0YnBrMs3sg5vG08ZBowqM6I6s6 +OgS3RuRLew6O85TCWjZG9zZuW3pzNWtvMXgAwk8HQRLqt+L5T46wB5WT+lPiN8B7 +KZaJ1KrfNwKBgQCBvFab9ovfU+02OnBjtlWpYBAmqhvekmE83pTUgwlyALkEAPqT +ErXX81kfPKUYWSAPPlo7bUy/wSVrnxpflnBx0DpjQjie3hjqqWjT6BMGlzqNRE3V +LMaeYNgvMDiokl/F6chKwITTS/PUWxVLyhKY0WbzT8slop+FSesiBflWQQKBgGZE +ltJyuTWMB+Try/x0tiwzvA5YAJ9uQ9qp1Ckfk1rIjUKA0uySyMr62oSeqp/BX93f +Gq1CeFFtFIK8bKTCoLkP9FpSse9NFENl7iH3Vg7jmR6sfQbStT++PP3qyE+Esx7F +se8/QuSwClRaczCeOROYV5vTpc4McT2qSeDb/jT1AoGBAIPzDSDyjxfh4DpSmFQA +gECwAcu9S4fhJp39xvUxyz055iwnxhhqXHbJPwhe+d2DLbdgDEQPBYpNCis5Fx/d +8utQLfwv5Uqk0rxbfBGuCVbS8kpxY9+yHRljfc8AP23g0/Whu6WjjiFqyGQ/1RPD +aajcoSVKH5jKFjxdCmzfHUOJ +-----END PRIVATE KEY----- diff --git a/other/sslserver_main.cpp b/other/sslserver_main.cpp index 5a7ed9a..8e517bf 100644 --- a/other/sslserver_main.cpp +++ b/other/sslserver_main.cpp @@ -1,4 +1,6 @@ -// gpp sslserver_main.cpp -o sslserver -I../include ../src/Logger.cpp ../src/Socket.cpp -ggdb ../src/SocketServer.cpp ../src/Connection.cpp ../src/Poll.cpp ../src/TcpConnection.cpp ../src/SslConnection.cpp -lssl -lcrypto ../src/Addrinfo.cpp +// run with +// ./sslserver 127.0.0.1 9001 ./cert.pem ./key.pem + #include #include