summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2012-02-22 13:31:39 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-02-22 14:16:18 (GMT)
commitfa705718be1f98185557a09cf155ed66cbc740e2 (patch)
treeb73c65981c6e879df40c40c4b5436a4d4386e5a4 /Swiften/TLS/OpenSSL
parent110eb87e848b85dd74a6f19413c775520a75ea35 (diff)
downloadswift-contrib-fa705718be1f98185557a09cf155ed66cbc740e2.zip
swift-contrib-fa705718be1f98185557a09cf155ed66cbc740e2.tar.bz2
Fix up for previous CAPI patch
Now connects successfully with or without TLS(with cert)
Diffstat (limited to 'Swiften/TLS/OpenSSL')
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp11
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h2
2 files changed, 5 insertions, 8 deletions
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index dd3462f..8076967 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -154,92 +154,89 @@ void OpenSSLContext::handleDataFromNetwork(const SafeByteArray& data) {
case Connected:
sendPendingDataToApplication();
break;
case Start: assert(false); break;
case Error: /*assert(false);*/ break;
}
}
void OpenSSLContext::handleDataFromApplication(const SafeByteArray& data) {
if (SSL_write(handle_, vecptr(data), data.size()) >= 0) {
sendPendingDataToNetwork();
}
else {
state_ = Error;
onError();
}
}
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();
}
}
bool OpenSSLContext::setClientCertificate(CertificateWithKey * certificate) {
- if (!certificate || certificate->isNull()) {
- return false;
- }
-
- if (!certificate->isPrivateKeyExportable()) {
+ 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(certificate->getData()), certificate->getData().size());
+ BIO_write(bio, vecptr(certificate->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(certificate->getPassword())), &privateKeyPtr, &certPtr, &caCertsPtr);
+ int result = PKCS12_parse(pkcs12.get(), reinterpret_cast<const char*>(vecptr(pkcs12Certificate->getPassword())), &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;
}
Certificate::ref OpenSSLContext::getPeerCertificate() const {
boost::shared_ptr<X509> x509Cert(SSL_get_peer_certificate(handle_), X509_free);
if (x509Cert) {
return boost::make_shared<OpenSSLCertificate>(x509Cert);
}
else {
return Certificate::ref();
}
}
boost::shared_ptr<CertificateVerificationError> OpenSSLContext::getPeerCertificateVerificationError() const {
int verifyResult = SSL_get_verify_result(handle_);
if (verifyResult != X509_V_OK) {
return boost::make_shared<CertificateVerificationError>(getVerificationErrorTypeForResult(verifyResult));
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index b53e715..e98fb49 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -1,53 +1,53 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <openssl/ssl.h>
#include <Swiften/Base/boost_bsignals.h>
#include <boost/noncopyable.hpp>
#include <Swiften/TLS/TLSContext.h>
#include <Swiften/Base/ByteArray.h>
namespace Swift {
class CertificateWithKey;
class OpenSSLContext : public TLSContext, boost::noncopyable {
public:
OpenSSLContext();
~OpenSSLContext();
void connect();
- bool setClientCertificate(CertificateWithKey * cert);
+ bool setClientCertificate(CertificateWithKey::ref cert);
void handleDataFromNetwork(const SafeByteArray&);
void handleDataFromApplication(const SafeByteArray&);
Certificate::ref getPeerCertificate() const;
boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
virtual ByteArray getFinishMessage() const;
private:
static void ensureLibraryInitialized();
static CertificateVerificationError::Type getVerificationErrorTypeForResult(int);
void doConnect();
void sendPendingDataToNetwork();
void sendPendingDataToApplication();
private:
enum State { Start, Connecting, Connected, Error };
State state_;
SSL_CTX* context_;
SSL* handle_;
BIO* readBIO_;
BIO* writeBIO_;
};
}