summaryrefslogtreecommitdiff
path: root/src/components/security_manager/src/ssl_context_impl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/security_manager/src/ssl_context_impl.cc')
-rw-r--r--src/components/security_manager/src/ssl_context_impl.cc197
1 files changed, 116 insertions, 81 deletions
diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc
index 6f53234867..fb049aa497 100644
--- a/src/components/security_manager/src/ssl_context_impl.cc
+++ b/src/components/security_manager/src/ssl_context_impl.cc
@@ -68,7 +68,7 @@ std::string CryptoManagerImpl::SSLContextImpl::LastError() const {
}
bool CryptoManagerImpl::SSLContextImpl::IsInitCompleted() const {
- sync_primitives::AutoLock locker(bio_locker);
+ sync_primitives::AutoLock locker(ssl_locker_);
return SSL_is_init_finished(connection_);
}
@@ -114,21 +114,27 @@ size_t des_cbc3_sha_max_block_size(size_t mtu) {
std::map<std::string, CryptoManagerImpl::SSLContextImpl::BlockSizeGetter>
CryptoManagerImpl::SSLContextImpl::create_max_block_sizes() {
std::map<std::string, CryptoManagerImpl::SSLContextImpl::BlockSizeGetter> rc;
+ rc.insert(std::make_pair(std::string("AES128-GCM-SHA256"),
+ aes128_gcm_sha256_max_block_size));
+ rc.insert(std::make_pair(std::string("AES128-SHA256"),
+ aes128_sha256_max_block_size));
+ rc.insert(std::make_pair(std::string("AES128-SHA"), seed_sha_max_block_size));
+ rc.insert(std::make_pair(std::string("AES256-GCM-SHA384"),
+ aes128_gcm_sha256_max_block_size));
+ rc.insert(std::make_pair(std::string("AES256-SHA256"),
+ aes128_sha256_max_block_size));
+ rc.insert(std::make_pair(std::string("AES256-SHA"), seed_sha_max_block_size));
rc.insert(
- std::make_pair("AES128-GCM-SHA256", aes128_gcm_sha256_max_block_size));
- rc.insert(std::make_pair("AES128-SHA256", aes128_sha256_max_block_size));
- rc.insert(std::make_pair("AES128-SHA", seed_sha_max_block_size));
+ std::make_pair(std::string("CAMELLIA128-SHA"), seed_sha_max_block_size));
rc.insert(
- std::make_pair("AES256-GCM-SHA384", aes128_gcm_sha256_max_block_size));
- rc.insert(std::make_pair("AES256-SHA256", aes128_sha256_max_block_size));
- rc.insert(std::make_pair("AES256-SHA", seed_sha_max_block_size));
- rc.insert(std::make_pair("CAMELLIA128-SHA", seed_sha_max_block_size));
- rc.insert(std::make_pair("CAMELLIA256-SHA", seed_sha_max_block_size));
- rc.insert(std::make_pair("DES-CBC3-SHA", des_cbc3_sha_max_block_size));
- rc.insert(std::make_pair("DES-CBC-SHA", des_cbc3_sha_max_block_size));
- rc.insert(std::make_pair("RC4-MD5", rc4_md5_max_block_size));
- rc.insert(std::make_pair("RC4-SHA", rc4_sha_max_block_size));
- rc.insert(std::make_pair("SEED-SHA", seed_sha_max_block_size));
+ std::make_pair(std::string("CAMELLIA256-SHA"), seed_sha_max_block_size));
+ rc.insert(
+ std::make_pair(std::string("DES-CBC3-SHA"), des_cbc3_sha_max_block_size));
+ rc.insert(
+ std::make_pair(std::string("DES-CBC-SHA"), des_cbc3_sha_max_block_size));
+ rc.insert(std::make_pair(std::string("RC4-MD5"), rc4_md5_max_block_size));
+ rc.insert(std::make_pair(std::string("RC4-SHA"), rc4_sha_max_block_size));
+ rc.insert(std::make_pair(std::string("SEED-SHA"), seed_sha_max_block_size));
return rc;
}
@@ -143,13 +149,13 @@ void CryptoManagerImpl::SSLContextImpl::PrintCertData(
char* subj = X509_NAME_oneline(subj_name, NULL, 0);
if (subj) {
std::replace(subj, subj + strlen(subj), '/', ' ');
- LOG4CXX_DEBUG(logger_, cert_owner << " subject:" << subj);
+ LOGGER_DEBUG(logger_, cert_owner << " subject:" << subj);
OPENSSL_free(subj);
}
char* issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
if (issuer) {
std::replace(issuer, issuer + strlen(issuer), '/', ' ');
- LOG4CXX_DEBUG(logger_, cert_owner << " issuer:" << issuer);
+ LOGGER_DEBUG(logger_, cert_owner << " issuer:" << issuer);
OPENSSL_free(issuer);
}
@@ -157,15 +163,16 @@ void CryptoManagerImpl::SSLContextImpl::PrintCertData(
ASN1_TIME* notAfter = X509_get_notAfter(cert);
if (notBefore) {
- LOG4CXX_DEBUG(logger_, " Start date: " << (char*)notBefore->data);
+ LOGGER_DEBUG(logger_, " Start date: " << (char*)notBefore->data);
}
if (notAfter) {
- LOG4CXX_DEBUG(logger_, " End date: " << (char*)notAfter->data);
+ LOGGER_DEBUG(logger_, " End date: " << (char*)notAfter->data);
}
}
}
void CryptoManagerImpl::SSLContextImpl::PrintCertInfo() {
+ sync_primitives::AutoLock locker(ssl_locker_);
PrintCertData(SSL_get_certificate(connection_), "HU's");
STACK_OF(X509)* peer_certs = SSL_get_peer_cert_chain(connection_);
@@ -190,18 +197,18 @@ CryptoManagerImpl::SSLContextImpl::CheckCertContext() {
const std::string& sn = GetTextBy(subj_name, NID_serialNumber);
if (!(hsh_context_.expected_cn.CompareIgnoreCase(cn.c_str()))) {
- LOG4CXX_ERROR(logger_,
- "Trying to run handshake with wrong app name: "
- << cn << ". Expected app name: "
- << hsh_context_.expected_cn.AsMBString());
+ LOGGER_ERROR(logger_,
+ "Trying to run handshake with wrong app name: "
+ << cn << ". Expected app name: "
+ << hsh_context_.expected_cn.AsMBString());
return Handshake_Result_AppNameMismatch;
}
if (!(hsh_context_.expected_sn.CompareIgnoreCase(sn.c_str()))) {
- LOG4CXX_ERROR(logger_,
- "Trying to run handshake with wrong app id: "
- << sn << ". Expected app id: "
- << hsh_context_.expected_sn.AsMBString());
+ LOGGER_ERROR(logger_,
+ "Trying to run handshake with wrong app id: "
+ << sn << ". Expected app id: "
+ << hsh_context_.expected_sn.AsMBString());
return Handshake_Result_AppIDMismatch;
}
return Handshake_Result_Success;
@@ -209,12 +216,13 @@ CryptoManagerImpl::SSLContextImpl::CheckCertContext() {
bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData(
const uint8_t** const out_data, size_t* out_data_size) {
- LOG4CXX_AUTO_TRACE(logger_);
+ LOGGER_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock locker(ssl_locker_);
const size_t pend = BIO_ctrl_pending(bioOut_);
- LOG4CXX_DEBUG(logger_, "Available " << pend << " bytes for handshake");
+ LOGGER_DEBUG(logger_, "Available " << pend << " bytes for handshake");
if (pend > 0) {
- LOG4CXX_DEBUG(logger_, "Reading handshake data");
+ LOGGER_DEBUG(logger_, "Reading handshake data");
EnsureBufferSizeEnough(pend);
const int read_count = BIO_read(bioOut_, buffer_, pend);
@@ -222,7 +230,7 @@ bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData(
*out_data_size = read_count;
*out_data = buffer_;
} else {
- LOG4CXX_WARN(logger_, "BIO read fail");
+ LOGGER_WARN(logger_, "BIO read fail");
is_handshake_pending_ = false;
ResetConnection();
return false;
@@ -234,7 +242,8 @@ bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData(
bool CryptoManagerImpl::SSLContextImpl::WriteHandshakeData(
const uint8_t* const in_data, size_t in_data_size) {
- LOG4CXX_AUTO_TRACE(logger_);
+ LOGGER_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock locker(ssl_locker_);
if (in_data && in_data_size) {
const int ret = BIO_write(bioIn_, in_data, in_data_size);
if (ret <= 0) {
@@ -250,46 +259,68 @@ SSLContext::HandshakeResult
CryptoManagerImpl::SSLContextImpl::PerformHandshake() {
const int handshake_result = SSL_do_handshake(connection_);
if (handshake_result == 1) {
- const HandshakeResult result = CheckCertContext();
- if (result != Handshake_Result_Success) {
- ResetConnection();
- is_handshake_pending_ = false;
- return result;
- }
-
- LOG4CXX_DEBUG(logger_, "SSL handshake successfully finished");
- // Handshake is successful
- bioFilter_ = BIO_new(BIO_f_ssl());
- BIO_set_ssl(bioFilter_, connection_, BIO_NOCLOSE);
-
- const SSL_CIPHER* cipher = SSL_get_current_cipher(connection_);
- max_block_size_ = max_block_sizes[SSL_CIPHER_get_name(cipher)];
- is_handshake_pending_ = false;
-
+ return ProcessSuccessHandshake();
} else if (handshake_result == 0) {
+ sync_primitives::AutoLock locker(ssl_locker_);
SSL_clear(connection_);
is_handshake_pending_ = false;
return Handshake_Result_Fail;
} else {
- const int error = SSL_get_error(connection_, handshake_result);
- if (error != SSL_ERROR_WANT_READ) {
- const long error = SSL_get_verify_result(connection_);
- SetHandshakeError(error);
- LOG4CXX_WARN(logger_,
- "Handshake failed with error "
- << " -> " << SSL_get_error(connection_, error) << " \""
- << LastError() << '"');
- ResetConnection();
- is_handshake_pending_ = false;
+ return ProcessHandshakeError(handshake_result);
+ }
+ return Handshake_Result_Success;
+}
+
+SSLContext::HandshakeResult
+CryptoManagerImpl::SSLContextImpl::ProcessSuccessHandshake() {
+ sync_primitives::AutoLock locker(ssl_locker_);
+ const HandshakeResult result = CheckCertContext();
+ if (result != Handshake_Result_Success) {
+ ResetConnection();
+ is_handshake_pending_ = false;
+ return result;
+ }
- // In case error happened but ssl verification shows OK
- // method will return AbnormalFail.
- if (X509_V_OK == error) {
- return Handshake_Result_AbnormalFail;
- }
- return openssl_error_convert_to_internal(error);
+ LOGGER_DEBUG(logger_, "SSL handshake successfully finished");
+ // Handshake is successful
+ bioFilter_ = BIO_new(BIO_f_ssl());
+ BIO_set_ssl(bioFilter_, connection_, BIO_NOCLOSE);
+
+ const SSL_CIPHER* cipher = SSL_get_current_cipher(connection_);
+ max_block_size_ = max_block_sizes[SSL_CIPHER_get_name(cipher)];
+ is_handshake_pending_ = false;
+
+ return result;
+}
+
+SSLContext::HandshakeResult
+CryptoManagerImpl::SSLContextImpl::ProcessHandshakeError(
+ const int handshake_error) {
+ // Since the LastError function uses lock and this one is public
+ // we need to cache its value before execute code below
+ // in order to prevent dead lock, since our mutex is not recursive one.
+ const std::string& last_error = LastError();
+
+ sync_primitives::AutoLock locker(ssl_locker_);
+ const int error = SSL_get_error(connection_, handshake_error);
+ if (error != SSL_ERROR_WANT_READ) {
+ const long error = SSL_get_verify_result(connection_);
+ SetHandshakeError(error);
+ LOGGER_WARN(logger_,
+ "Handshake failed with error "
+ << " -> " << SSL_get_error(connection_, error) << " \""
+ << last_error << '"');
+ ResetConnection();
+ is_handshake_pending_ = false;
+
+ // In case error happened but ssl verification shows OK
+ // method will return AbnormalFail.
+ if (X509_V_OK == error) {
+ return Handshake_Result_AbnormalFail;
}
+ return openssl_error_convert_to_internal(error);
}
+
return Handshake_Result_Success;
}
@@ -298,21 +329,14 @@ SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::DoHandshakeStep(
size_t in_data_size,
const uint8_t** const out_data,
size_t* out_data_size) {
- LOG4CXX_AUTO_TRACE(logger_);
+ LOGGER_AUTO_TRACE(logger_);
DCHECK(out_data);
DCHECK(out_data_size);
*out_data = NULL;
*out_data_size = 0;
- // TODO(Ezamakhov): add test - hanshake fail -> restart StartHandshake
- {
- sync_primitives::AutoLock locker(bio_locker);
-
- if (SSL_is_init_finished(connection_)) {
- LOG4CXX_DEBUG(logger_, "SSL initilization is finished");
- is_handshake_pending_ = false;
- return Handshake_Result_Success;
- }
+ if (CheckInitFinished()) {
+ return Handshake_Result_Success;
}
if (!WriteHandshakeData(in_data, in_data_size)) {
@@ -333,11 +357,22 @@ SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::DoHandshakeStep(
return res;
}
+bool CryptoManagerImpl::SSLContextImpl::CheckInitFinished() {
+ // TODO(Ezamakhov): add test - hanshake fail -> restart StartHandshake
+ sync_primitives::AutoLock locker(ssl_locker_);
+ if (SSL_is_init_finished(connection_)) {
+ LOGGER_DEBUG(logger_, "SSL initilization is finished");
+ is_handshake_pending_ = false;
+ return true;
+ }
+ return false;
+}
+
bool CryptoManagerImpl::SSLContextImpl::Encrypt(const uint8_t* const in_data,
size_t in_data_size,
const uint8_t** const out_data,
size_t* out_data_size) {
- sync_primitives::AutoLock locker(bio_locker);
+ sync_primitives::AutoLock locker(ssl_locker_);
if (!SSL_is_init_finished(connection_) || !in_data || !in_data_size) {
return false;
}
@@ -363,7 +398,7 @@ bool CryptoManagerImpl::SSLContextImpl::Decrypt(const uint8_t* const in_data,
size_t in_data_size,
const uint8_t** const out_data,
size_t* out_data_size) {
- sync_primitives::AutoLock locker(bio_locker);
+ sync_primitives::AutoLock locker(ssl_locker_);
if (!SSL_is_init_finished(connection_)) {
return false;
}
@@ -424,19 +459,19 @@ void CryptoManagerImpl::SSLContextImpl::SetHandshakeError(const int error) {
}
void CryptoManagerImpl::SSLContextImpl::ResetConnection() {
- LOG4CXX_AUTO_TRACE(logger_);
+ LOGGER_AUTO_TRACE(logger_);
const int shutdown_result = SSL_shutdown(connection_);
if (shutdown_result != 1) {
const size_t pend = BIO_ctrl_pending(bioOut_);
- LOG4CXX_DEBUG(logger_, "Available " << pend << " bytes for shutdown");
+ LOGGER_DEBUG(logger_, "Available " << pend << " bytes for shutdown");
if (pend > 0) {
- LOG4CXX_DEBUG(logger_, "Reading shutdown data");
+ LOGGER_DEBUG(logger_, "Reading shutdown data");
EnsureBufferSizeEnough(pend);
BIO_read(bioOut_, buffer_, pend);
}
SSL_shutdown(connection_);
}
- LOG4CXX_DEBUG(logger_, "SSL connection recreation");
+ LOGGER_DEBUG(logger_, "SSL connection recreation");
SSL_CTX* ssl_context = connection_->ctx;
SSL_free(connection_);
connection_ = SSL_new(ssl_context);
@@ -488,8 +523,8 @@ std::string CryptoManagerImpl::SSLContextImpl::GetTextBy(X509_NAME* name,
const int req_len = X509_NAME_get_text_by_NID(name, object, NULL, 0);
if (-1 == req_len) {
- LOG4CXX_WARN(logger_,
- "Unable to obtain object: " << object << " from certificate");
+ LOGGER_WARN(logger_,
+ "Unable to obtain object: " << object << " from certificate");
return std::string();
}