summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2010-11-07 20:07:06 (GMT)
committerRemko Tronçon <git@el-tramo.be>2010-11-07 21:27:17 (GMT)
commita594eb3fef7e047d1eca7959d7734d4d10fd1eb7 (patch)
treef0c75a890caf231e18c963e6485d8c3fcf418324 /Swiften/TLS/OpenSSL
parent8cfb6d8f3492dd4180429f37dfb463b2fa48b0b8 (diff)
downloadswift-a594eb3fef7e047d1eca7959d7734d4d10fd1eb7.zip
swift-a594eb3fef7e047d1eca7959d7734d4d10fd1eb7.tar.bz2
Refactoring certificates & certificate checking.
Diffstat (limited to 'Swiften/TLS/OpenSSL')
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificate.cpp65
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLCertificate.h60
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.cpp57
-rw-r--r--Swiften/TLS/OpenSSL/OpenSSLContext.h2
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();