diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-11-07 20:07:06 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-11-07 21:27:17 (GMT) |
commit | a594eb3fef7e047d1eca7959d7734d4d10fd1eb7 (patch) | |
tree | f0c75a890caf231e18c963e6485d8c3fcf418324 /Swiften/TLS/OpenSSL | |
parent | 8cfb6d8f3492dd4180429f37dfb463b2fa48b0b8 (diff) | |
download | swift-contrib-a594eb3fef7e047d1eca7959d7734d4d10fd1eb7.zip swift-contrib-a594eb3fef7e047d1eca7959d7734d4d10fd1eb7.tar.bz2 |
Refactoring certificates & certificate checking.
Diffstat (limited to 'Swiften/TLS/OpenSSL')
-rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp | 65 | ||||
-rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLCertificate.h | 60 | ||||
-rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLContext.cpp | 57 | ||||
-rw-r--r-- | Swiften/TLS/OpenSSL/OpenSSLContext.h | 2 |
4 files changed, 131 insertions, 53 deletions
diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp new file mode 100644 index 0000000..5d9aac2 --- /dev/null +++ b/Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/TLS/OpenSSL/OpenSSLCertificate.h" + +#include <openssl/x509v3.h> + +#include "Swiften/Base/ByteArray.h" + +#pragma GCC diagnostic ignored "-Wold-style-cast" + +namespace Swift { + +OpenSSLCertificate::OpenSSLCertificate(boost::shared_ptr<X509> cert) : cert(cert) { + // Common name + X509_NAME* subjectName = X509_get_subject_name(cert.get()); + if (subjectName) { + int cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1); + if (cnLoc != -1) { + X509_NAME_ENTRY* cnEntry = X509_NAME_get_entry(subjectName, cnLoc); + ASN1_STRING* cnData = X509_NAME_ENTRY_get_data(cnEntry); + setCommonName(ByteArray(cnData->data, cnData->length).toString()); + } + } + + // 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(ByteArray(ASN1_STRING_data(xmppAddrValue), ASN1_STRING_length(xmppAddrValue)).toString()); + } + 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(ByteArray(ASN1_STRING_data(srvNameValue), ASN1_STRING_length(srvNameValue)).toString()); + } + } + else if (generalName->type == GEN_DNS) { + // DNSName + addDNSName(ByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName)).toString()); + } + } + } +} + +} diff --git a/Swiften/TLS/OpenSSL/OpenSSLCertificate.h b/Swiften/TLS/OpenSSL/OpenSSLCertificate.h new file mode 100644 index 0000000..4708120 --- /dev/null +++ b/Swiften/TLS/OpenSSL/OpenSSLCertificate.h @@ -0,0 +1,60 @@ +/* + * 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 <boost/shared_ptr.hpp> +#include <openssl/ssl.h> + +#include "Swiften/Base/String.h" +#include "Swiften/TLS/Certificate.h" + +namespace Swift { + class OpenSSLCertificate : public Certificate { + public: + OpenSSLCertificate(boost::shared_ptr<X509>); + + String getCommonName() const { + return commonName; + } + + std::vector<String> getSRVNames() const { + return srvNames; + } + + std::vector<String> getDNSNames() const { + return dnsNames; + } + + std::vector<String> getXMPPAddresses() const { + return xmppAddresses; + } + + private: + void addSRVName(const String& name) { + srvNames.push_back(name); + } + + void addDNSName(const String& name) { + dnsNames.push_back(name); + } + + void addXMPPAddress(const String& addr) { + xmppAddresses.push_back(addr); + } + + void setCommonName(const String& commonName) { + this->commonName = commonName; + } + + private: + boost::shared_ptr<X509> cert; + String commonName; + std::vector<String> dnsNames; + std::vector<String> xmppAddresses; + std::vector<String> srvNames; + }; +} diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp index c78d5a1..41c98c1 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContext.cpp +++ b/Swiften/TLS/OpenSSL/OpenSSLContext.cpp @@ -7,9 +7,9 @@ #include <vector> #include <openssl/err.h> #include <openssl/pkcs12.h> -#include <openssl/x509v3.h> #include "Swiften/TLS/OpenSSL/OpenSSLContext.h" +#include "Swiften/TLS/OpenSSL/OpenSSLCertificate.h" #include "Swiften/TLS/PKCS12Certificate.h" #pragma GCC diagnostic ignored "-Wold-style-cast" @@ -166,67 +166,20 @@ bool OpenSSLContext::setClientCertificate(const PKCS12Certificate& certificate) Certificate::ref OpenSSLContext::getPeerCertificate() const { boost::shared_ptr<X509> x509Cert(SSL_get_peer_certificate(handle_), X509_free); if (x509Cert) { - Certificate::ref certificate(new Certificate()); - - // Common name - X509_NAME* subjectName = X509_get_subject_name(x509Cert.get()); - if (subjectName) { - int cnLoc = X509_NAME_get_index_by_NID(subjectName, NID_commonName, -1); - if (cnLoc != -1) { - X509_NAME_ENTRY* cnEntry = X509_NAME_get_entry(subjectName, cnLoc); - ASN1_STRING* cnData = X509_NAME_ENTRY_get_data(cnEntry); - certificate->setCommonName(ByteArray(cnData->data, cnData->length).toString()); - } - } - - // subjectAltNames - int subjectAltNameLoc = X509_get_ext_by_NID(x509Cert.get(), NID_subject_alt_name, -1); - if(subjectAltNameLoc != -1) { - X509_EXTENSION* extension = X509_get_ext(x509Cert.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; - certificate->addXMPPAddress(ByteArray(ASN1_STRING_data(xmppAddrValue), ASN1_STRING_length(xmppAddrValue)).toString()); - } - 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; - certificate->addSRVName(ByteArray(ASN1_STRING_data(srvNameValue), ASN1_STRING_length(srvNameValue)).toString()); - } - } - else if (generalName->type == GEN_DNS) { - // DNSName - certificate->addDNSName(ByteArray(ASN1_STRING_data(generalName->d.dNSName), ASN1_STRING_length(generalName->d.dNSName)).toString()); - } - } - } - return certificate; + return Certificate::ref(new OpenSSLCertificate(x509Cert)); } else { return Certificate::ref(); } } -boost::optional<CertificateVerificationError> OpenSSLContext::getPeerCertificateVerificationError() const { +boost::shared_ptr<CertificateVerificationError> OpenSSLContext::getPeerCertificateVerificationError() const { int verifyResult = SSL_get_verify_result(handle_); if (verifyResult != X509_V_OK) { - return CertificateVerificationError(getVerificationErrorTypeForResult(verifyResult)); + return boost::shared_ptr<CertificateVerificationError>(new CertificateVerificationError(getVerificationErrorTypeForResult(verifyResult))); } else { - return boost::optional<CertificateVerificationError>(); + return boost::shared_ptr<CertificateVerificationError>(); } } diff --git a/Swiften/TLS/OpenSSL/OpenSSLContext.h b/Swiften/TLS/OpenSSL/OpenSSLContext.h index 31141a5..9cb287d 100644 --- a/Swiften/TLS/OpenSSL/OpenSSLContext.h +++ b/Swiften/TLS/OpenSSL/OpenSSLContext.h @@ -28,7 +28,7 @@ namespace Swift { void handleDataFromApplication(const ByteArray&); Certificate::ref getPeerCertificate() const; - boost::optional<CertificateVerificationError> getPeerCertificateVerificationError() const; + boost::shared_ptr<CertificateVerificationError> getPeerCertificateVerificationError() const; private: static void ensureLibraryInitialized(); |