summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2014-06-22 11:15:29 (GMT)
committerRemko Tronçon <git@el-tramo.be>2014-06-22 11:31:31 (GMT)
commit1eb14b6bde145ca54ac9b981df339fb8c56d3930 (patch)
tree402da86d2807365179dea0789b08fd70556c65d3
parentf91647cf9a0df0366342fae2cbcfe9df376379ba (diff)
downloadswift-contrib-1eb14b6bde145ca54ac9b981df339fb8c56d3930.zip
swift-contrib-1eb14b6bde145ca54ac9b981df339fb8c56d3930.tar.bz2
NULL-terminate PKCS12 password buffer
This fixes a bug with PCKS12 cert auth that only manifested itself on specific platforms (e.g. ARM) Test-Information: Patch was tested by reporter on a failing platform Change-Id: I4663363aadaf5f00c2092e2f58d45f5ba1b4229a
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index 4e8654f..54fb7bd 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -188,71 +188,73 @@ void OpenSSLContext::handleDataFromApplication(const SafeByteArray& data) {
void OpenSSLContext::sendPendingDataToApplication() {
SafeByteArray data;
data.resize(SSL_READ_BUFFERSIZE);
int ret = SSL_read(handle_, vecptr(data), data.size());
while (ret > 0) {
data.resize(ret);
onDataForApplication(data);
data.resize(SSL_READ_BUFFERSIZE);
ret = SSL_read(handle_, vecptr(data), data.size());
}
if (ret < 0 && SSL_get_error(handle_, ret) != SSL_ERROR_WANT_READ) {
state_ = Error;
onError(boost::make_shared<TLSError>());
}
}
bool OpenSSLContext::setClientCertificate(CertificateWithKey::ref certificate) {
boost::shared_ptr<PKCS12Certificate> pkcs12Certificate = boost::dynamic_pointer_cast<PKCS12Certificate>(certificate);
if (!pkcs12Certificate || pkcs12Certificate->isNull()) {
return false;
}
// Create a PKCS12 structure
BIO* bio = BIO_new(BIO_s_mem());
BIO_write(bio, vecptr(pkcs12Certificate->getData()), pkcs12Certificate->getData().size());
boost::shared_ptr<PKCS12> pkcs12(d2i_PKCS12_bio(bio, NULL), PKCS12_free);
BIO_free(bio);
if (!pkcs12) {
return false;
}
// Parse PKCS12
X509 *certPtr = 0;
EVP_PKEY* privateKeyPtr = 0;
STACK_OF(X509)* caCertsPtr = 0;
- int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(pkcs12Certificate->getPassword())), &privateKeyPtr, &certPtr, &caCertsPtr);
+ SafeByteArray password(pkcs12Certificate->getPassword());
+ password.push_back(0);
+ int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(password)), &privateKeyPtr, &certPtr, &caCertsPtr);
if (result != 1) {
return false;
}
boost::shared_ptr<X509> cert(certPtr, X509_free);
boost::shared_ptr<EVP_PKEY> privateKey(privateKeyPtr, EVP_PKEY_free);
boost::shared_ptr<STACK_OF(X509)> caCerts(caCertsPtr, freeX509Stack);
// Use the key & certificates
if (SSL_CTX_use_certificate(context_, cert.get()) != 1) {
return false;
}
if (SSL_CTX_use_PrivateKey(context_, privateKey.get()) != 1) {
return false;
}
for (int i = 0; i < sk_X509_num(caCerts.get()); ++i) {
SSL_CTX_add_extra_chain_cert(context_, sk_X509_value(caCerts.get(), i));
}
return true;
}
std::vector<Certificate::ref> OpenSSLContext::getPeerCertificateChain() const {
std::vector<Certificate::ref> result;
STACK_OF(X509)* chain = SSL_get_peer_cert_chain(handle_);
for (int i = 0; i < sk_X509_num(chain); ++i) {
boost::shared_ptr<X509> x509Cert(X509_dup(sk_X509_value(chain, i)), X509_free);
Certificate::ref cert = boost::make_shared<OpenSSLCertificate>(x509Cert);
result.push_back(cert);
}
return result;
}
boost::shared_ptr<CertificateVerificationError> OpenSSLContext::getPeerCertificateVerificationError() const {
int verifyResult = SSL_get_verify_result(handle_);
if (verifyResult != X509_V_OK) {