summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2012-02-23 15:06:11 (GMT)
committerKevin Smith <git@kismith.co.uk>2012-02-23 15:06:11 (GMT)
commiteca0f020873f7620c5125101113e2c1eb25b273e (patch)
treeceb9649fb2b183e6d0cad665d8ebb7214ef2c424
parentfa705718be1f98185557a09cf155ed66cbc740e2 (diff)
downloadswift-contrib-eca0f020873f7620c5125101113e2c1eb25b273e.zip
swift-contrib-eca0f020873f7620c5125101113e2c1eb25b273e.tar.bz2
Compile when non-SChannel
-rw-r--r--Swiften/SConscript2
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp5
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h2
3 files changed, 5 insertions, 4 deletions
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 9e61fc6..258b566 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -381,59 +381,59 @@ if env["SCONS_STAGE"] == "build" :
File("StringCodecs/UnitTest/MD5Test.cpp"),
File("StringCodecs/UnitTest/HexifyTest.cpp"),
File("StringCodecs/UnitTest/HMACTest.cpp"),
File("StringCodecs/UnitTest/PBKDF2Test.cpp"),
File("TLS/UnitTest/ServerIdentityVerifierTest.cpp"),
File("TLS/UnitTest/CertificateTest.cpp"),
File("VCards/UnitTest/VCardManagerTest.cpp"),
])
# Generate the Swiften header
def relpath(path, start) :
i = len(os.path.commonprefix([path, start]))
return path[i+1:]
swiften_header = "#pragma once\n"
swiften_includes = []
top_path = env.Dir("..").abspath
for root, dirs, files in os.walk(env.Dir(".").abspath) :
if root.endswith("UnitTest") :
continue
for file in files :
if not file.endswith(".h") :
continue
include = relpath(os.path.join(root, file), top_path)
if swiften_env["PLATFORM"] == "win32" :
include = include.replace("\\", "/")
swiften_includes.append(include)
# Private modules
if root.endswith("Config") or root.endswith("Compress") :
continue
# Library-specfifc private modules
if root.endswith("OpenSSL") or root.endswith("Cocoa") or root.endswith("Qt") or root.endswith("IDN") or root.endswith("Avahi") or root.endswith("Bonjour") :
continue
# Library-specific files
- if file.startswith("Schannel") or file.startswith("CAres") or file.startswith("LibXML") or file.startswith("Expat") or file.startswith("GConf") or file.startswith("MacOSX") or file.startswith("Windows") or file.startswith("SQLite") or file.startswith("NATPMP") or file.startswith("MiniUPnP") :
+ if file.startswith("Schannel") or file.startswith("CAPI") or file.startswith("CAres") or file.startswith("LibXML") or file.startswith("Expat") or file.startswith("GConf") or file.startswith("MacOSX") or file.startswith("Windows") or file.startswith("SQLite") or file.startswith("NATPMP") or file.startswith("MiniUPnP") :
continue
# Specific headers we don't want to globally include
if file == "Swiften.h" or file == "foreach.h" or file == "Log.h" or file == "format.h" or file == "CompressionLayer.h":
continue
swiften_header += "#include <" + include + ">\n"
swiften_includes.append(include)
swiften_env.WriteVal("Swiften.h", swiften_env.Value(swiften_header))
swiften_includes.append("Swiften/Swiften.h")
version_header = "#pragma once\n\n"
version_header += "#define SWIFTEN_VERSION 0x%02X%02X%02X\n" % (swiften_env["SWIFTEN_VERSION_MAJOR"], swiften_env["SWIFTEN_VERSION_MINOR"], swiften_env["SWIFTEN_VERSION_PATCH"])
version_header += "#define SWIFTEN_VERSION_STRING \"%s\"\n" % swiften_env["SWIFTEN_VERSION"]
swiften_env.WriteVal("Version.h", swiften_env.Value(version_header))
swiften_includes.append("Swiften/Version.h")
# Install swiften
if swiften_env.get("SWIFTEN_INSTALLDIR", "") :
swiften_env.Install(os.path.join(swiften_env["SWIFTEN_INSTALLDIR"], "lib"), swiften_lib)
for alias in myenv["SWIFTEN_LIBRARY_ALIASES"] :
myenv.Command(myenv.File(os.path.join(swiften_env["SWIFTEN_INSTALLDIR"], "lib", alias)), [env.Value(swiften_lib[0].name), swiften_lib[0]], symlink)
for include in swiften_includes :
swiften_env.Install(os.path.join(swiften_env["SWIFTEN_INSTALLDIR"], "include", os.path.dirname(include)), "#/" + include)
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
index 8076967..54addef 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp
@@ -1,59 +1,60 @@
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Base/Platform.h>
#ifdef SWIFTEN_PLATFORM_WINDOWS
#include <windows.h>
#include <wincrypt.h>
#endif
#include <vector>
#include <openssl/err.h>
#include <openssl/pkcs12.h>
#include <boost/smart_ptr/make_shared.hpp>
#if defined(SWIFTEN_PLATFORM_MACOSX) && OPENSSL_VERSION_NUMBER < 0x00908000
#include <Security/Security.h>
#endif
#include <Swiften/TLS/OpenSSL/OpenSSLContext.h>
#include <Swiften/TLS/OpenSSL/OpenSSLCertificate.h>
#include <Swiften/TLS/CertificateWithKey.h>
+#include <Swiften/TLS/PKCS12Certificate.h>
#pragma GCC diagnostic ignored "-Wold-style-cast"
namespace Swift {
static const int MAX_FINISHED_SIZE = 4096;
static const int SSL_READ_BUFFERSIZE = 8192;
void freeX509Stack(STACK_OF(X509)* stack) {
sk_X509_free(stack);
}
OpenSSLContext::OpenSSLContext() : state_(Start), context_(0), handle_(0), readBIO_(0), writeBIO_(0) {
ensureLibraryInitialized();
context_ = SSL_CTX_new(TLSv1_client_method());
// 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());
}
}
}
#elif !defined(SWIFTEN_PLATFORM_MACOSX)
SSL_CTX_load_verify_locations(context_, NULL, "/etc/ssl/certs");
@@ -153,79 +154,79 @@ void OpenSSLContext::handleDataFromNetwork(const SafeByteArray& data) {
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();
}
}
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) {
+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(certificate->getData()), pkcs12Certificate->getData().size());
+ 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);
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);
diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h
index e98fb49..d8d0d2f 100644
--- a/Swiften/TLS/OpenSSL/OpenSSLContext.h
+++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h
@@ -1,52 +1,52 @@
/*
* 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>
+#include <Swiften/TLS/CertificateWithKey.h>
namespace Swift {
- class CertificateWithKey;
class OpenSSLContext : public TLSContext, boost::noncopyable {
public:
OpenSSLContext();
~OpenSSLContext();
void connect();
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_;
};