summaryrefslogtreecommitdiff
path: root/src/components/security_manager/src/ssl_context_impl.cc
diff options
context:
space:
mode:
authorAleksandr Galiuzov <AGaliuzov@luxoft.com>2015-09-25 01:18:22 +0300
committerAleksandr Galiuzov <AGaliuzov@luxoft.com>2015-10-04 21:03:54 +0300
commit16a6b3e7b686382370d8d9ddd6d4e8519aea94be (patch)
tree162ed6360d3ef4fadfffb05933a3042b4e5aadc9 /src/components/security_manager/src/ssl_context_impl.cc
parentd656eb202c2c1060adf2e700bc2719f131d9f8bb (diff)
downloadsdl_core-16a6b3e7b686382370d8d9ddd6d4e8519aea94be.tar.gz
Refactor security things and add additional logging
Add logging for certificates dates as well as current host time. Refactor cryptomanger and modify tests. Closes-bug: APPLINK-16448
Diffstat (limited to 'src/components/security_manager/src/ssl_context_impl.cc')
-rw-r--r--src/components/security_manager/src/ssl_context_impl.cc198
1 files changed, 143 insertions, 55 deletions
diff --git a/src/components/security_manager/src/ssl_context_impl.cc b/src/components/security_manager/src/ssl_context_impl.cc
index 3361711b13..e49d631092 100644
--- a/src/components/security_manager/src/ssl_context_impl.cc
+++ b/src/components/security_manager/src/ssl_context_impl.cc
@@ -134,69 +134,131 @@ std::map<std::string, CryptoManagerImpl::SSLContextImpl::BlockSizeGetter>
CryptoManagerImpl::SSLContextImpl::max_block_sizes =
CryptoManagerImpl::SSLContextImpl::create_max_block_sizes();
-SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::
-DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
- const uint8_t** const out_data, size_t* out_data_size) {
- 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_)) {
- is_handshake_pending_ = false;
- return Handshake_Result_Success;
- }
-
- if (in_data && in_data_size) {
- const int ret = BIO_write(bioIn_, in_data, in_data_size);
- if (ret <= 0) {
- is_handshake_pending_ = false;
- ResetConnection();
- return Handshake_Result_AbnormalFail;
- }
- }
-
- bool cn_found;
- bool sn_found;
- STACK_OF(X509 ) *peer_certs = SSL_get_peer_cert_chain(connection_);
- while (sk_X509_num(peer_certs) > 0) {
- X509* cert = sk_X509_pop(peer_certs);
- const bool last_step = (sk_X509_num(peer_certs) == 0);
+void CryptoManagerImpl::SSLContextImpl::PrintCertData(X509* cert,
+ const std::string& cert_owner) {
+ if (cert) {
X509_NAME* subj_name = X509_get_subject_name(cert);
char *subj = X509_NAME_oneline(subj_name, NULL, 0);
if (subj) {
std::replace(subj, subj + strlen(subj), '/', ' ');
- LOG4CXX_DEBUG(logger_, "Mobile cert subject:" << subj);
+ LOG4CXX_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_, "Mobile cert issuer:" << issuer);
+ LOG4CXX_DEBUG(logger_, cert_owner << " issuer:" << issuer);
OPENSSL_free(issuer);
}
const std::string& cn = GetTextBy(subj_name, NID_commonName);
const std::string& sn = GetTextBy(subj_name, NID_serialNumber);
- cn_found = cn_found || (hsh_context_.expected_cn == cn);
- sn_found = sn_found || (hsh_context_.expected_sn == sn);
+ LOG4CXX_DEBUG(logger_, "CN: " << cn << ". SERIALNUMBER: " << sn);
+
+ ASN1_TIME* notBefore = X509_get_notBefore(cert);
+ ASN1_TIME* notAfter = X509_get_notAfter(cert);
- if (!cn_found && last_step) {
- LOG4CXX_ERROR(logger_,"Trying to run handshake with wrong app name");
- return Handshake_Result_AppNameMismatch;
+ if (notBefore) {
+ LOG4CXX_DEBUG(logger_, " Start date: " << (char*)notBefore->data);
}
+ if (notAfter) {
+ LOG4CXX_DEBUG(logger_, " End date: " << (char*)notAfter->data);
+ }
+ }
+}
- if (!sn_found && last_step) {
- LOG4CXX_ERROR(logger_,"Trying to run handshake with wrong app id");
- return Handshake_Result_AppIDMismatch;
+void CryptoManagerImpl::SSLContextImpl::PrintCertInfo() {
+ PrintCertData(SSL_get_certificate(connection_), "HU's");
+
+ STACK_OF(X509 ) *peer_certs = SSL_get_peer_cert_chain(connection_);
+ while (sk_X509_num(peer_certs) > 0) {
+ X509* cert = sk_X509_pop(peer_certs);
+ PrintCertData(cert, "SERVERS");
+ }
+}
+
+SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::
+CheckCertContext() {
+ X509* cert = SSL_get_peer_certificate(connection_);
+ if (!cert) {
+ // According to the openssl documentation the peer certificate
+ // might be ommitted for the SERVER but required for the cient.
+ return CLIENT == mode_ ? Handshake_Result_Fail : Handshake_Result_Success;
+ }
+
+ X509_NAME* subj_name =
+ X509_get_subject_name(cert);
+
+ const std::string& cn = GetTextBy(subj_name, NID_commonName);
+ const std::string& sn = GetTextBy(subj_name, NID_serialNumber);
+
+ if (hsh_context_.expected_cn.compare(cn) != 0) {
+ LOG4CXX_ERROR(logger_,"Trying to run handshake with wrong app name: " << cn
+ << ". Expected app name: " << hsh_context_.expected_cn);
+ return Handshake_Result_AppNameMismatch;
+ }
+
+ if (hsh_context_.expected_sn.compare(sn) != 0) {
+ LOG4CXX_ERROR(logger_,"Trying to run handshake with wrong app id: " << sn
+ << ". Expected app id: " << hsh_context_.expected_sn);
+ return Handshake_Result_AppIDMismatch;
+ }
+ return Handshake_Result_Success;
+}
+
+bool CryptoManagerImpl::SSLContextImpl::ReadHandshakeData(
+ const uint8_t** const out_data, size_t* out_data_size) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ const size_t pend = BIO_ctrl_pending(bioOut_);
+ LOG4CXX_DEBUG(logger_, "Available " << pend << " bytes for handshake");
+
+ if (pend > 0) {
+ LOG4CXX_DEBUG(logger_, "Reading handshake data");
+ EnsureBufferSizeEnough(pend);
+
+ const int read_count = BIO_read(bioOut_, buffer_, pend);
+ if (read_count == static_cast<int>(pend)) {
+ *out_data_size = read_count;
+ *out_data = buffer_;
+ } else {
+ LOG4CXX_WARN(logger_, "BIO read fail");
+ is_handshake_pending_ = false;
+ ResetConnection();
+ return false;
}
}
+ return true;
+}
+
+bool CryptoManagerImpl::SSLContextImpl::
+WriteHandshakeData(const uint8_t* const in_data, size_t in_data_size) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (in_data && in_data_size) {
+ const int ret = BIO_write(bioIn_, in_data, in_data_size);
+ if (ret <= 0) {
+ is_handshake_pending_ = false;
+ ResetConnection();
+ return Handshake_Result_AbnormalFail;
+ }
+ }
+ return true;
+}
+
+
+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);
@@ -204,6 +266,7 @@ DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
const SSL_CIPHER *cipher = SSL_get_current_cipher(connection_);
max_block_size_ = max_block_sizes[SSL_CIPHER_get_name(cipher)];
is_handshake_pending_ = false;
+
} else if (handshake_result == 0) {
SSL_clear(connection_);
is_handshake_pending_ = false;
@@ -217,6 +280,7 @@ DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
<< " \"" << LastError() << '"');
ResetConnection();
is_handshake_pending_ = false;
+
// In case error happened but ssl verification shows OK
// method will return AbnormalFail.
if (X509_V_OK == error) {
@@ -225,24 +289,43 @@ DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
return openssl_error_convert_to_internal(error);
}
}
+ return Handshake_Result_Success;
+}
- const size_t pend = BIO_ctrl_pending(bioOut_);
- if (pend) {
- EnsureBufferSizeEnough(pend);
+SSLContext::HandshakeResult CryptoManagerImpl::SSLContextImpl::
+DoHandshakeStep(const uint8_t* const in_data, size_t in_data_size,
+ const uint8_t** const out_data, size_t* out_data_size) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ DCHECK(out_data);
+ DCHECK(out_data_size);
+ *out_data = NULL;
+ *out_data_size = 0;
- const int read_count = BIO_read(bioOut_, buffer_, pend);
- if (read_count == static_cast<int>(pend)) {
- *out_data_size = read_count;
- *out_data = buffer_;
- } else {
- is_handshake_pending_ = false;
- ResetConnection();
- return Handshake_Result_AbnormalFail;
- }
+ // 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;
}
- return Handshake_Result_Success;
+ if (!WriteHandshakeData(in_data, in_data_size)) {
+ return Handshake_Result_AbnormalFail;
+ }
+
+ PrintCertInfo();
+
+ const HandshakeResult res = PerformHandshake();
+ if (res != Handshake_Result_Success) {
+ return res;
+ }
+
+ if (!ReadHandshakeData(out_data, out_data_size)) {
+ return Handshake_Result_AbnormalFail;
+ }
+
+ return res;
}
bool CryptoManagerImpl::SSLContextImpl::Encrypt(
@@ -399,6 +482,8 @@ std::string CryptoManagerImpl::SSLContextImpl::GetTextBy(
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");
return std::string();
}
@@ -406,8 +491,11 @@ std::string CryptoManagerImpl::SSLContextImpl::GetTextBy(
data.resize(req_len + 1);
X509_NAME_get_text_by_NID(name, object, &data.front(), data.size());
- return std::string(data.begin(), data.end() - 1);
-}
+ std::string str (data.begin(), data.end() - 1);
+ std::transform(str.begin(), str.end(),
+ str.begin(), ::tolower);
+ return str;
+}
} // namespace security_manager