summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/TLS/OpenSSL')
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp140
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificate.h108
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h12
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp496
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h50
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp18
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContextFactory.h16
7 files changed, 420 insertions, 420 deletions
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp
index fc8dce5..3110813 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp
@@ -20,91 +20,91 @@
namespace Swift {
OpenSSLCertificate::OpenSSLCertificate(boost::shared_ptr<X509> cert) : cert(cert) {
- parse();
+ parse();
}
OpenSSLCertificate::OpenSSLCertificate(const ByteArray& der) {
#if OPENSSL_VERSION_NUMBER <= 0x009070cfL
- unsigned char* p = const_cast<unsigned char*>(vecptr(der));
+ unsigned char* p = const_cast<unsigned char*>(vecptr(der));
#else
- const unsigned char* p = vecptr(der);
+ const unsigned char* p = vecptr(der);
#endif
- cert = boost::shared_ptr<X509>(d2i_X509(NULL, &p, der.size()), X509_free);
- if (!cert) {
- SWIFT_LOG(warning) << "Error creating certificate from DER data" << std::endl;
- }
- parse();
+ cert = boost::shared_ptr<X509>(d2i_X509(NULL, &p, der.size()), X509_free);
+ if (!cert) {
+ SWIFT_LOG(warning) << "Error creating certificate from DER data" << std::endl;
+ }
+ parse();
}
ByteArray OpenSSLCertificate::toDER() const {
- ByteArray result;
- if (!cert) {
- return result;
- }
- result.resize(i2d_X509(cert.get(), NULL));
- unsigned char* p = vecptr(result);
- i2d_X509(cert.get(), &p);
- return result;
+ ByteArray result;
+ if (!cert) {
+ return result;
+ }
+ result.resize(i2d_X509(cert.get(), NULL));
+ unsigned char* p = vecptr(result);
+ i2d_X509(cert.get(), &p);
+ return result;
}
void OpenSSLCertificate::parse() {
- if (!cert) {
- return;
- }
- // Subject name
- X509_NAME* subjectName = X509_get_subject_name(cert.get());
- if (subjectName) {
- // Subject name
- ByteArray subjectNameData;
- subjectNameData.resize(256);
- X509_NAME_oneline(X509_get_subject_name(cert.get()), reinterpret_cast<char*>(vecptr(subjectNameData)), static_cast<unsigned int>(subjectNameData.size()));
- this->subjectName = byteArrayToString(subjectNameData);
+ if (!cert) {
+ return;
+ }
+ // Subject name
+ X509_NAME* subjectName = X509_get_subject_name(cert.get());
+ if (subjectName) {
+ // Subject name
+ ByteArray subjectNameData;
+ subjectNameData.resize(256);
+ X509_NAME_oneline(X509_get_subject_name(cert.get()), reinterpret_cast<char*>(vecptr(subjectNameData)), static_cast<unsigned int>(subjectNameData.size()));
+ this->subjectName = byteArrayToString(subjectNameData);
- // Common name
- int cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1);
- while (cnLoc != -1) {
- X509_NAME_ENTRY* cnEntry = X509_NAME_get_entry(subjectName, cnLoc);
- ASN1_STRING* cnData = X509_NAME_ENTRY_get_data(cnEntry);
- commonNames.push_back(byteArrayToString(createByteArray(reinterpret_cast<const char*>(cnData->data), cnData->length)));
- cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, cnLoc);
- }
- }
+ // Common name
+ int cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1);
+ while (cnLoc != -1) {
+ X509_NAME_ENTRY* cnEntry = X509_NAME_get_entry(subjectName, cnLoc);
+ ASN1_STRING* cnData = X509_NAME_ENTRY_get_data(cnEntry);
+ commonNames.push_back(byteArrayToString(createByteArray(reinterpret_cast<const char*>(cnData->data), cnData->length)));
+ cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, cnLoc);
+ }
+ }
- // subjectAltNames
- int subjectAltNameLoc = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
- if(subjectAltNameLoc != -1) {
- X509_EXTENSION* extension = X509_get_ext(cert.get(), subjectAltNameLoc);
- boost::shared_ptr<GENERAL_NAMES> generalNames(reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(extension)), GENERAL_NAMES_free);
- boost::shared_ptr<ASN1_OBJECT> xmppAddrObject(OBJ_txt2obj(ID_ON_XMPPADDR_OID, 1), ASN1_OBJECT_free);
- boost::shared_ptr<ASN1_OBJECT> dnsSRVObject(OBJ_txt2obj(ID_ON_DNSSRV_OID, 1), ASN1_OBJECT_free);
- for (int i = 0; i < sk_GENERAL_NAME_num(generalNames.get()); ++i) {
- GENERAL_NAME* generalName = sk_GENERAL_NAME_value(generalNames.get(), i);
- if (generalName->type == GEN_OTHERNAME) {
- OTHERNAME* otherName = generalName->d.otherName;
- if (OBJ_cmp(otherName->type_id, xmppAddrObject.get()) == 0) {
- // XmppAddr
- if (otherName->value->type != V_ASN1_UTF8STRING) {
- continue;
- }
- ASN1_UTF8STRING* xmppAddrValue = otherName->value->value.utf8string;
- addXMPPAddress(byteArrayToString(createByteArray(reinterpret_cast<const char*>(ASN1_STRING_data(xmppAddrValue)), ASN1_STRING_length(xmppAddrValue))));
- }
- else if (OBJ_cmp(otherName->type_id, dnsSRVObject.get()) == 0) {
- // SRVName
- if (otherName->value->type != V_ASN1_IA5STRING) {
- continue;
- }
- ASN1_IA5STRING* srvNameValue = otherName->value->value.ia5string;
- addSRVName(byteArrayToString(createByteArray(reinterpret_cast<const char*>(ASN1_STRING_data(srvNameValue)), ASN1_STRING_length(srvNameValue))));
- }
- }
- else if (generalName->type == GEN_DNS) {
- // DNSName
- addDNSName(byteArrayToString(createByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName))));
- }
- }
- }
+ // subjectAltNames
+ int subjectAltNameLoc = X509_get_ext_by_NID(cert.get(), NID_subject_alt_name, -1);
+ if(subjectAltNameLoc != -1) {
+ X509_EXTENSION* extension = X509_get_ext(cert.get(), subjectAltNameLoc);
+ boost::shared_ptr<GENERAL_NAMES> generalNames(reinterpret_cast<GENERAL_NAMES*>(X509V3_EXT_d2i(extension)), GENERAL_NAMES_free);
+ boost::shared_ptr<ASN1_OBJECT> xmppAddrObject(OBJ_txt2obj(ID_ON_XMPPADDR_OID, 1), ASN1_OBJECT_free);
+ boost::shared_ptr<ASN1_OBJECT> dnsSRVObject(OBJ_txt2obj(ID_ON_DNSSRV_OID, 1), ASN1_OBJECT_free);
+ for (int i = 0; i < sk_GENERAL_NAME_num(generalNames.get()); ++i) {
+ GENERAL_NAME* generalName = sk_GENERAL_NAME_value(generalNames.get(), i);
+ if (generalName->type == GEN_OTHERNAME) {
+ OTHERNAME* otherName = generalName->d.otherName;
+ if (OBJ_cmp(otherName->type_id, xmppAddrObject.get()) == 0) {
+ // XmppAddr
+ if (otherName->value->type != V_ASN1_UTF8STRING) {
+ continue;
+ }
+ ASN1_UTF8STRING* xmppAddrValue = otherName->value->value.utf8string;
+ addXMPPAddress(byteArrayToString(createByteArray(reinterpret_cast<const char*>(ASN1_STRING_data(xmppAddrValue)), ASN1_STRING_length(xmppAddrValue))));
+ }
+ else if (OBJ_cmp(otherName->type_id, dnsSRVObject.get()) == 0) {
+ // SRVName
+ if (otherName->value->type != V_ASN1_IA5STRING) {
+ continue;
+ }
+ ASN1_IA5STRING* srvNameValue = otherName->value->value.ia5string;
+ addSRVName(byteArrayToString(createByteArray(reinterpret_cast<const char*>(ASN1_STRING_data(srvNameValue)), ASN1_STRING_length(srvNameValue))));
+ }
+ }
+ else if (generalName->type == GEN_DNS) {
+ // DNSName
+ addDNSName(byteArrayToString(createByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName))));
+ }
+ }
+ }
}
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificate.h b/Swiften/TLS/OpenSSL/OpenSSLCertificate.h
index 7419849..4b8b32c 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLCertificate.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLCertificate.h
@@ -15,58 +15,58 @@
#include <Swiften/TLS/Certificate.h>
namespace Swift {
- class OpenSSLCertificate : public Certificate {
- public:
- OpenSSLCertificate(boost::shared_ptr<X509>);
- OpenSSLCertificate(const ByteArray& der);
-
- std::string getSubjectName() const {
- return subjectName;
- }
-
- std::vector<std::string> getCommonNames() const {
- return commonNames;
- }
-
- std::vector<std::string> getSRVNames() const {
- return srvNames;
- }
-
- std::vector<std::string> getDNSNames() const {
- return dnsNames;
- }
-
- std::vector<std::string> getXMPPAddresses() const {
- return xmppAddresses;
- }
-
- ByteArray toDER() const;
-
- boost::shared_ptr<X509> getInternalX509() const {
- return cert;
- }
-
- private:
- void parse();
-
- void addSRVName(const std::string& name) {
- srvNames.push_back(name);
- }
-
- void addDNSName(const std::string& name) {
- dnsNames.push_back(name);
- }
-
- void addXMPPAddress(const std::string& addr) {
- xmppAddresses.push_back(addr);
- }
-
- private:
- boost::shared_ptr<X509> cert;
- std::string subjectName;
- std::vector<std::string> commonNames;
- std::vector<std::string> dnsNames;
- std::vector<std::string> xmppAddresses;
- std::vector<std::string> srvNames;
- };
+ class OpenSSLCertificate : public Certificate {
+ public:
+ OpenSSLCertificate(boost::shared_ptr<X509>);
+ OpenSSLCertificate(const ByteArray& der);
+
+ std::string getSubjectName() const {
+ return subjectName;
+ }
+
+ std::vector<std::string> getCommonNames() const {
+ return commonNames;
+ }
+
+ std::vector<std::string> getSRVNames() const {
+ return srvNames;
+ }
+
+ std::vector<std::string> getDNSNames() const {
+ return dnsNames;
+ }
+
+ std::vector<std::string> getXMPPAddresses() const {
+ return xmppAddresses;
+ }
+
+ ByteArray toDER() const;
+
+ boost::shared_ptr<X509> getInternalX509() const {
+ return cert;
+ }
+
+ private:
+ void parse();
+
+ void addSRVName(const std::string& name) {
+ srvNames.push_back(name);
+ }
+
+ void addDNSName(const std::string& name) {
+ dnsNames.push_back(name);
+ }
+
+ void addXMPPAddress(const std::string& addr) {
+ xmppAddresses.push_back(addr);
+ }
+
+ private:
+ boost::shared_ptr<X509> cert;
+ std::string subjectName;
+ std::vector<std::string> commonNames;
+ std::vector<std::string> dnsNames;
+ std::vector<std::string> xmppAddresses;
+ std::vector<std::string> srvNames;
+ };
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
index bb8780e..c996cd5 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLCertificateFactory.h
@@ -10,10 +10,10 @@
#include <Swiften/TLS/OpenSSL/OpenSSLCertificate.h>
namespace Swift {
- class OpenSSLCertificateFactory : public CertificateFactory {
- public:
- virtual Certificate* createCertificateFromDER(const ByteArray& der) {
- return new OpenSSLCertificate(der);
- }
- };
+ class OpenSSLCertificateFactory : public CertificateFactory {
+ public:
+ virtual Certificate* createCertificateFromDER(const ByteArray& der) {
+ return new OpenSSLCertificate(der);
+ }
+ };
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index a3e0e1d..cc420e6 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -36,302 +36,302 @@ static const int MAX_FINISHED_SIZE = 4096;
static const int SSL_READ_BUFFERSIZE = 8192;
static void freeX509Stack(STACK_OF(X509)* stack) {
- sk_X509_free(stack);
+ sk_X509_free(stack);
}
OpenSSLContext::OpenSSLContext() : state_(Start), context_(0), handle_(0), readBIO_(0), writeBIO_(0) {
- ensureLibraryInitialized();
- context_ = SSL_CTX_new(SSLv23_client_method());
- SSL_CTX_set_options(context_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
+ ensureLibraryInitialized();
+ context_ = SSL_CTX_new(SSLv23_client_method());
+ SSL_CTX_set_options(context_, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
- // TODO: implement CRL checking
- // TODO: download CRL (HTTP transport)
- // TODO: cache CRL downloads for configurable time period
+ // TODO: implement CRL checking
+ // TODO: download CRL (HTTP transport)
+ // TODO: cache CRL downloads for configurable time period
- // TODO: implement OCSP support
- // TODO: handle OCSP stapling see https://www.rfc-editor.org/rfc/rfc4366.txt
- // Load system certs
+ // TODO: implement OCSP support
+ // TODO: handle OCSP stapling see https://www.rfc-editor.org/rfc/rfc4366.txt
+ // Load system certs
#if defined(SWIFTEN_PLATFORM_WINDOWS)
- X509_STORE* store = SSL_CTX_get_cert_store(context_);
- HCERTSTORE systemStore = CertOpenSystemStore(0, "ROOT");
- if (systemStore) {
- PCCERT_CONTEXT certContext = NULL;
- while (true) {
- certContext = CertFindCertificateInStore(systemStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext);
- if (!certContext) {
- break;
- }
- OpenSSLCertificate cert(createByteArray(certContext->pbCertEncoded, certContext->cbCertEncoded));
- if (store && cert.getInternalX509()) {
- X509_STORE_add_cert(store, cert.getInternalX509().get());
- }
- }
- }
+ X509_STORE* store = SSL_CTX_get_cert_store(context_);
+ HCERTSTORE systemStore = CertOpenSystemStore(0, "ROOT");
+ if (systemStore) {
+ PCCERT_CONTEXT certContext = NULL;
+ while (true) {
+ certContext = CertFindCertificateInStore(systemStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_ANY, NULL, certContext);
+ if (!certContext) {
+ break;
+ }
+ OpenSSLCertificate cert(createByteArray(certContext->pbCertEncoded, certContext->cbCertEncoded));
+ if (store && cert.getInternalX509()) {
+ X509_STORE_add_cert(store, cert.getInternalX509().get());
+ }
+ }
+ }
#elif !defined(SWIFTEN_PLATFORM_MACOSX)
- SSL_CTX_load_verify_locations(context_, NULL, "/etc/ssl/certs");
+ SSL_CTX_load_verify_locations(context_, NULL, "/etc/ssl/certs");
#elif defined(SWIFTEN_PLATFORM_MACOSX) && !defined(SWIFTEN_PLATFORM_IPHONE)
- // On Mac OS X 10.5 (OpenSSL < 0.9.8), OpenSSL does not automatically look in the system store.
- // On Mac OS X 10.6 (OpenSSL >= 0.9.8), OpenSSL *does* look in the system store to determine trust.
- // However, if there is a certificate error, it will always emit the "Invalid CA" error if we didn't add
- // the certificates first. See
- // http://opensource.apple.com/source/OpenSSL098/OpenSSL098-27/src/crypto/x509/x509_vfy_apple.c
- // to understand why. We therefore add all certs from the system store ourselves.
- X509_STORE* store = SSL_CTX_get_cert_store(context_);
- CFArrayRef anchorCertificates;
- if (SecTrustCopyAnchorCertificates(&anchorCertificates) == 0) {
- for (int i = 0; i < CFArrayGetCount(anchorCertificates); ++i) {
- SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(const_cast<void*>(CFArrayGetValueAtIndex(anchorCertificates, i)));
- CSSM_DATA certCSSMData;
- if (SecCertificateGetData(cert, &certCSSMData) != 0 || certCSSMData.Length == 0) {
- continue;
- }
- std::vector<unsigned char> certData;
- certData.resize(certCSSMData.Length);
- memcpy(&certData[0], certCSSMData.Data, certCSSMData.Length);
- OpenSSLCertificate certificate(certData);
- if (store && certificate.getInternalX509()) {
- X509_STORE_add_cert(store, certificate.getInternalX509().get());
- }
- }
- CFRelease(anchorCertificates);
- }
+ // On Mac OS X 10.5 (OpenSSL < 0.9.8), OpenSSL does not automatically look in the system store.
+ // On Mac OS X 10.6 (OpenSSL >= 0.9.8), OpenSSL *does* look in the system store to determine trust.
+ // However, if there is a certificate error, it will always emit the "Invalid CA" error if we didn't add
+ // the certificates first. See
+ // http://opensource.apple.com/source/OpenSSL098/OpenSSL098-27/src/crypto/x509/x509_vfy_apple.c
+ // to understand why. We therefore add all certs from the system store ourselves.
+ X509_STORE* store = SSL_CTX_get_cert_store(context_);
+ CFArrayRef anchorCertificates;
+ if (SecTrustCopyAnchorCertificates(&anchorCertificates) == 0) {
+ for (int i = 0; i < CFArrayGetCount(anchorCertificates); ++i) {
+ SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(const_cast<void*>(CFArrayGetValueAtIndex(anchorCertificates, i)));
+ CSSM_DATA certCSSMData;
+ if (SecCertificateGetData(cert, &certCSSMData) != 0 || certCSSMData.Length == 0) {
+ continue;
+ }
+ std::vector<unsigned char> certData;
+ certData.resize(certCSSMData.Length);
+ memcpy(&certData[0], certCSSMData.Data, certCSSMData.Length);
+ OpenSSLCertificate certificate(certData);
+ if (store && certificate.getInternalX509()) {
+ X509_STORE_add_cert(store, certificate.getInternalX509().get());
+ }
+ }
+ CFRelease(anchorCertificates);
+ }
#endif
}
OpenSSLContext::~OpenSSLContext() {
- SSL_free(handle_);
- SSL_CTX_free(context_);
+ SSL_free(handle_);
+ SSL_CTX_free(context_);
}
void OpenSSLContext::ensureLibraryInitialized() {
- static bool isLibraryInitialized = false;
- if (!isLibraryInitialized) {
- SSL_load_error_strings();
- SSL_library_init();
- OpenSSL_add_all_algorithms();
-
- // Disable compression
- /*
- STACK_OF(SSL_COMP)* compressionMethods = SSL_COMP_get_compression_methods();
- sk_SSL_COMP_zero(compressionMethods);*/
-
- isLibraryInitialized = true;
- }
+ static bool isLibraryInitialized = false;
+ if (!isLibraryInitialized) {
+ SSL_load_error_strings();
+ SSL_library_init();
+ OpenSSL_add_all_algorithms();
+
+ // Disable compression
+ /*
+ STACK_OF(SSL_COMP)* compressionMethods = SSL_COMP_get_compression_methods();
+ sk_SSL_COMP_zero(compressionMethods);*/
+
+ isLibraryInitialized = true;
+ }
}
void OpenSSLContext::connect() {
- handle_ = SSL_new(context_);
- // Ownership of BIOs is ransferred
- readBIO_ = BIO_new(BIO_s_mem());
- writeBIO_ = BIO_new(BIO_s_mem());
- SSL_set_bio(handle_, readBIO_, writeBIO_);
-
- state_ = Connecting;
- doConnect();
+ handle_ = SSL_new(context_);
+ // Ownership of BIOs is ransferred
+ readBIO_ = BIO_new(BIO_s_mem());
+ writeBIO_ = BIO_new(BIO_s_mem());
+ SSL_set_bio(handle_, readBIO_, writeBIO_);
+
+ state_ = Connecting;
+ doConnect();
}
void OpenSSLContext::doConnect() {
- int connectResult = SSL_connect(handle_);
- int error = SSL_get_error(handle_, connectResult);
- switch (error) {
- case SSL_ERROR_NONE: {
- state_ = Connected;
- //std::cout << x->name << std::endl;
- //const char* comp = SSL_get_current_compression(handle_);
- //std::cout << "Compression: " << SSL_COMP_get_name(comp) << std::endl;
- onConnected();
- break;
- }
- case SSL_ERROR_WANT_READ:
- sendPendingDataToNetwork();
- break;
- default:
- state_ = Error;
- onError(boost::make_shared<TLSError>());
- }
+ int connectResult = SSL_connect(handle_);
+ int error = SSL_get_error(handle_, connectResult);
+ switch (error) {
+ case SSL_ERROR_NONE: {
+ state_ = Connected;
+ //std::cout << x->name << std::endl;
+ //const char* comp = SSL_get_current_compression(handle_);
+ //std::cout << "Compression: " << SSL_COMP_get_name(comp) << std::endl;
+ onConnected();
+ break;
+ }
+ case SSL_ERROR_WANT_READ:
+ sendPendingDataToNetwork();
+ break;
+ default:
+ state_ = Error;
+ onError(boost::make_shared<TLSError>());
+ }
}
void OpenSSLContext::sendPendingDataToNetwork() {
- int size = BIO_pending(writeBIO_);
- if (size > 0) {
- SafeByteArray data;
- data.resize(size);
- BIO_read(writeBIO_, vecptr(data), size);
- onDataForNetwork(data);
- }
+ int size = BIO_pending(writeBIO_);
+ if (size > 0) {
+ SafeByteArray data;
+ data.resize(size);
+ BIO_read(writeBIO_, vecptr(data), size);
+ onDataForNetwork(data);
+ }
}
void OpenSSLContext::handleDataFromNetwork(const SafeByteArray& data) {
- BIO_write(readBIO_, vecptr(data), data.size());
- switch (state_) {
- case Connecting:
- doConnect();
- break;
- case Connected:
- sendPendingDataToApplication();
- break;
- case Start: assert(false); break;
- case Error: /*assert(false);*/ break;
- }
+ BIO_write(readBIO_, vecptr(data), data.size());
+ switch (state_) {
+ case Connecting:
+ doConnect();
+ break;
+ 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(boost::make_shared<TLSError>());
- }
+ if (SSL_write(handle_, vecptr(data), data.size()) >= 0) {
+ sendPendingDataToNetwork();
+ }
+ else {
+ state_ = Error;
+ onError(boost::make_shared<TLSError>());
+ }
}
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>());
- }
+ 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;
- 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;
+ 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;
+ 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;
+ 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) {
- return boost::make_shared<CertificateVerificationError>(getVerificationErrorTypeForResult(verifyResult));
- }
- else {
- return boost::shared_ptr<CertificateVerificationError>();
- }
+ int verifyResult = SSL_get_verify_result(handle_);
+ if (verifyResult != X509_V_OK) {
+ return boost::make_shared<CertificateVerificationError>(getVerificationErrorTypeForResult(verifyResult));
+ }
+ else {
+ return boost::shared_ptr<CertificateVerificationError>();
+ }
}
ByteArray OpenSSLContext::getFinishMessage() const {
- ByteArray data;
- data.resize(MAX_FINISHED_SIZE);
- size_t size = SSL_get_finished(handle_, vecptr(data), data.size());
- data.resize(size);
- return data;
+ ByteArray data;
+ data.resize(MAX_FINISHED_SIZE);
+ size_t size = SSL_get_finished(handle_, vecptr(data), data.size());
+ data.resize(size);
+ return data;
}
CertificateVerificationError::Type OpenSSLContext::getVerificationErrorTypeForResult(int result) {
- assert(result != 0);
- switch (result) {
- case X509_V_ERR_CERT_NOT_YET_VALID:
- case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
- return CertificateVerificationError::NotYetValid;
-
- case X509_V_ERR_CERT_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
- return CertificateVerificationError::Expired;
-
- case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
- case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
- return CertificateVerificationError::SelfSigned;
-
- case X509_V_ERR_CERT_UNTRUSTED:
- return CertificateVerificationError::Untrusted;
-
- case X509_V_ERR_CERT_REJECTED:
- return CertificateVerificationError::Rejected;
-
- case X509_V_ERR_INVALID_PURPOSE:
- return CertificateVerificationError::InvalidPurpose;
-
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
- return CertificateVerificationError::PathLengthExceeded;
-
- case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
- case X509_V_ERR_CERT_SIGNATURE_FAILURE:
- case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
- return CertificateVerificationError::InvalidSignature;
-
- case X509_V_ERR_INVALID_CA:
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
- case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
- return CertificateVerificationError::InvalidCA;
-
- case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
- case X509_V_ERR_AKID_SKID_MISMATCH:
- case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
- case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
- return CertificateVerificationError::UnknownError;
-
- // Unused / should not happen
- case X509_V_ERR_CERT_REVOKED:
- case X509_V_ERR_OUT_OF_MEM:
- case X509_V_ERR_UNABLE_TO_GET_CRL:
- case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
- case X509_V_ERR_CRL_SIGNATURE_FAILURE:
- case X509_V_ERR_CRL_NOT_YET_VALID:
- case X509_V_ERR_CRL_HAS_EXPIRED:
- case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
- case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
- case X509_V_ERR_CERT_CHAIN_TOO_LONG:
- case X509_V_ERR_APPLICATION_VERIFICATION:
- default:
- return CertificateVerificationError::UnknownError;
- }
+ assert(result != 0);
+ switch (result) {
+ case X509_V_ERR_CERT_NOT_YET_VALID:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
+ return CertificateVerificationError::NotYetValid;
+
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
+ return CertificateVerificationError::Expired;
+
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
+ return CertificateVerificationError::SelfSigned;
+
+ case X509_V_ERR_CERT_UNTRUSTED:
+ return CertificateVerificationError::Untrusted;
+
+ case X509_V_ERR_CERT_REJECTED:
+ return CertificateVerificationError::Rejected;
+
+ case X509_V_ERR_INVALID_PURPOSE:
+ return CertificateVerificationError::InvalidPurpose;
+
+ case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+ return CertificateVerificationError::PathLengthExceeded;
+
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
+ case X509_V_ERR_CERT_SIGNATURE_FAILURE:
+ case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
+ return CertificateVerificationError::InvalidSignature;
+
+ case X509_V_ERR_INVALID_CA:
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
+ case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
+ case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
+ return CertificateVerificationError::InvalidCA;
+
+ case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
+ case X509_V_ERR_AKID_SKID_MISMATCH:
+ case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
+ case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
+ return CertificateVerificationError::UnknownError;
+
+ // Unused / should not happen
+ case X509_V_ERR_CERT_REVOKED:
+ case X509_V_ERR_OUT_OF_MEM:
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
+ case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
+ case X509_V_ERR_CRL_SIGNATURE_FAILURE:
+ case X509_V_ERR_CRL_NOT_YET_VALID:
+ case X509_V_ERR_CRL_HAS_EXPIRED:
+ case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
+ case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
+ case X509_V_ERR_CERT_CHAIN_TOO_LONG:
+ case X509_V_ERR_APPLICATION_VERIFICATION:
+ default:
+ return CertificateVerificationError::UnknownError;
+ }
}
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index 73fe75c..7fd5af7 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -17,38 +17,38 @@
namespace Swift {
- class OpenSSLContext : public TLSContext, boost::noncopyable {
- public:
- OpenSSLContext();
- virtual ~OpenSSLContext();
+ class OpenSSLContext : public TLSContext, boost::noncopyable {
+ public:
+ OpenSSLContext();
+ virtual ~OpenSSLContext();
- void connect();
- bool setClientCertificate(CertificateWithKey::ref cert);
+ void connect();
+ bool setClientCertificate(CertificateWithKey::ref cert);
- void handleDataFromNetwork(const SafeByteArray&);
- void handleDataFromApplication(const SafeByteArray&);
+ void handleDataFromNetwork(const SafeByteArray&);
+ void handleDataFromApplication(const SafeByteArray&);
- std::vector<Certificate::ref> getPeerCertificateChain() const;
- boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
+ std::vector<Certificate::ref> getPeerCertificateChain() const;
+ boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const;
- virtual ByteArray getFinishMessage() const;
+ virtual ByteArray getFinishMessage() const;
- private:
- static void ensureLibraryInitialized();
+ private:
+ static void ensureLibraryInitialized();
- static CertificateVerificationError::Type getVerificationErrorTypeForResult(int);
+ static CertificateVerificationError::Type getVerificationErrorTypeForResult(int);
- void doConnect();
- void sendPendingDataToNetwork();
- void sendPendingDataToApplication();
+ void doConnect();
+ void sendPendingDataToNetwork();
+ void sendPendingDataToApplication();
- private:
- enum State { Start, Connecting, Connected, Error };
+ private:
+ enum State { Start, Connecting, Connected, Error };
- State state_;
- SSL_CTX* context_;
- SSL* handle_;
- BIO* readBIO_;
- BIO* writeBIO_;
- };
+ State state_;
+ SSL_CTX* context_;
+ SSL* handle_;
+ BIO* readBIO_;
+ BIO* writeBIO_;
+ };
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
index ff27b49..9f7b2aa 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.cpp
@@ -12,24 +12,24 @@
namespace Swift {
bool OpenSSLContextFactory::canCreate() const {
- return true;
+ return true;
}
TLSContext* OpenSSLContextFactory::createTLSContext(const TLSOptions&) {
- return new OpenSSLContext();
+ return new OpenSSLContext();
}
void OpenSSLContextFactory::setCheckCertificateRevocation(bool check) {
- if (check) {
- SWIFT_LOG(warning) << "CRL Checking not supported for OpenSSL" << std::endl;
- assert(false);
- }
+ if (check) {
+ SWIFT_LOG(warning) << "CRL Checking not supported for OpenSSL" << std::endl;
+ assert(false);
+ }
}
void OpenSSLContextFactory::setDisconnectOnCardRemoval(bool check) {
- if (check) {
- SWIFT_LOG(warning) << "Smart cards not supported for OpenSSL" << std::endl;
- }
+ if (check) {
+ SWIFT_LOG(warning) << "Smart cards not supported for OpenSSL" << std::endl;
+ }
}
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h
index 21f05a4..e121a1a 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContextFactory.h
@@ -11,13 +11,13 @@
#include <Swiften/TLS/TLSContextFactory.h>
namespace Swift {
- class OpenSSLContextFactory : public TLSContextFactory {
- public:
- bool canCreate() const;
- virtual TLSContext* createTLSContext(const TLSOptions& tlsOptions);
+ class OpenSSLContextFactory : public TLSContextFactory {
+ public:
+ bool canCreate() const;
+ virtual TLSContext* createTLSContext(const TLSOptions& tlsOptions);
- // Not supported
- virtual void setCheckCertificateRevocation(bool b);
- virtual void setDisconnectOnCardRemoval(bool b);
- };
+ // Not supported
+ virtual void setCheckCertificateRevocation(bool b);
+ virtual void setDisconnectOnCardRemoval(bool b);
+ };
}