aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2012-12-10 21:59:19 +0000
committerVincent Richard <[email protected]>2012-12-10 21:59:19 +0000
commit87259631e4f9baf4cafb55a75db16ca9cc20d40e (patch)
tree0a423447f8f028d9b215641d4047666cd2860d48
parentFixed doc for classes in "net" package not being generated. (diff)
downloadvmime-87259631e4f9baf4cafb55a75db16ca9cc20d40e.tar.gz
vmime-87259631e4f9baf4cafb55a75db16ca9cc20d40e.zip
SSL server identity check.
-rw-r--r--CMakeLists.txt1
-rw-r--r--SConstruct1
-rw-r--r--examples/example6.cpp5
-rw-r--r--src/net/tls/gnutls/TLSSocket_GnuTLS.cpp14
-rwxr-xr-xsrc/net/tls/openssl/TLSSocket_OpenSSL.cpp14
-rw-r--r--src/platforms/posix/posixSocket.cpp95
-rw-r--r--src/platforms/windows/windowsSocket.cpp67
-rw-r--r--src/security/cert/defaultCertificateVerifier.cpp15
-rw-r--r--src/security/cert/gnutls/X509Certificate_GnuTLS.cpp6
-rwxr-xr-xsrc/security/cert/openssl/X509Certificate_OpenSSL.cpp68
-rw-r--r--src/security/sasl/SASLSocket.cpp12
-rw-r--r--vmime/net/socket.hpp12
-rw-r--r--vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp3
-rwxr-xr-xvmime/net/tls/openssl/TLSSocket_OpenSSL.hpp3
-rw-r--r--vmime/platforms/posix/posixSocket.hpp5
-rw-r--r--vmime/platforms/windows/windowsSocket.hpp5
-rw-r--r--vmime/security/cert/X509Certificate.hpp7
-rw-r--r--vmime/security/cert/certificateVerifier.hpp6
-rw-r--r--vmime/security/cert/defaultCertificateVerifier.hpp4
-rw-r--r--vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp2
-rw-r--r--vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp2
-rw-r--r--vmime/security/sasl/SASLSocket.hpp3
22 files changed, 340 insertions, 10 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5be9ca32..79a8ee03 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -561,6 +561,7 @@ INCLUDE(CheckFunctionExists)
INCLUDE(CheckSymbolExists)
CHECK_FUNCTION_EXISTS(getaddrinfo VMIME_HAVE_GETADDRINFO)
+CHECK_FUNCTION_EXISTS(getnameinfo VMIME_HAVE_GETNAMEINFO)
CHECK_FUNCTION_EXISTS(gettid VMIME_HAVE_GETTID)
CHECK_FUNCTION_EXISTS(syscall VMIME_HAVE_SYSCALL)
diff --git a/SConstruct b/SConstruct
index d1bb23c5..3fe9588d 100644
--- a/SConstruct
+++ b/SConstruct
@@ -860,6 +860,7 @@ for platform in libvmime_platforms_sources:
config_hpp.write("""
#define VMIME_HAVE_GETADDRINFO 1
+#define VMIME_HAVE_GETNAMEINFO 1
#define VMIME_HAVE_PTHREAD 1
#define VMIME_HAVE_GETTID 0
#define VMIME_HAVE_SYSCALL 1
diff --git a/examples/example6.cpp b/examples/example6.cpp
index bcb2df9a..53ff978a 100644
--- a/examples/example6.cpp
+++ b/examples/example6.cpp
@@ -147,7 +147,7 @@ class interactiveCertificateVerifier : public vmime::security::cert::defaultCert
{
public:
- void verify(vmime::ref <vmime::security::cert::certificateChain> chain)
+ void verify(vmime::ref <vmime::security::cert::certificateChain> chain, const vmime::string& hostname)
{
try
{
@@ -176,6 +176,9 @@ public:
{
m_trustedCerts.push_back(cert.dynamicCast
<vmime::security::cert::X509Certificate>());
+
+ setX509TrustedCerts(m_trustedCerts);
+ defaultCertificateVerifier::verify(chain, hostname);
}
return;
diff --git a/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp b/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp
index 477f655b..37381881 100644
--- a/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp
+++ b/src/net/tls/gnutls/TLSSocket_GnuTLS.cpp
@@ -116,6 +116,18 @@ TLSSocket::size_type TLSSocket_GnuTLS::getBlockSize() const
}
+const string TLSSocket_GnuTLS::getPeerName() const
+{
+ return m_wrapped->getPeerName();
+}
+
+
+const string TLSSocket_OpenSSL::getPeerAddress() const
+{
+ return m_wrapped->getPeerAddress();
+}
+
+
void TLSSocket_GnuTLS::receive(string& buffer)
{
const int size = receiveRaw(m_buffer, sizeof(m_buffer));
@@ -262,7 +274,7 @@ void TLSSocket_GnuTLS::handshake(ref <timeoutHandler> toHandler)
if (certs == NULL)
throw exceptions::tls_exception("No peer certificate.");
- m_session->getCertificateVerifier()->verify(certs);
+ m_session->getCertificateVerifier()->verify(certs, getPeerName());
m_connected = true;
}
diff --git a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp b/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
index 25937e32..f37d9a33 100755
--- a/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
+++ b/src/net/tls/openssl/TLSSocket_OpenSSL.cpp
@@ -160,6 +160,18 @@ TLSSocket::size_type TLSSocket_OpenSSL::getBlockSize() const
}
+const string TLSSocket_OpenSSL::getPeerName() const
+{
+ return m_wrapped->getPeerName();
+}
+
+
+const string TLSSocket_OpenSSL::getPeerAddress() const
+{
+ return m_wrapped->getPeerAddress();
+}
+
+
void TLSSocket_OpenSSL::receive(string& buffer)
{
const size_type size = receiveRaw(m_buffer, sizeof(m_buffer));
@@ -239,7 +251,7 @@ void TLSSocket_OpenSSL::handshake(ref <timeoutHandler> toHandler)
if (certs == NULL)
throw exceptions::tls_exception("No peer certificate.");
- m_session->getCertificateVerifier()->verify(certs);
+ m_session->getCertificateVerifier()->verify(certs, getPeerName());
m_connected = true;
}
diff --git a/src/platforms/posix/posixSocket.cpp b/src/platforms/posix/posixSocket.cpp
index b3e33f49..1a7fb7a3 100644
--- a/src/platforms/posix/posixSocket.cpp
+++ b/src/platforms/posix/posixSocket.cpp
@@ -104,6 +104,8 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
throw vmime::exceptions::connection_error("Cannot resolve address.");
}
+ m_serverAddress = address;
+
// Connect to host
int sock = -1;
struct ::addrinfo* res = res0;
@@ -268,6 +270,8 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
::memcpy(reinterpret_cast <char*>(&addr.sin_addr), hostInfo->h_addr, hostInfo->h_length);
}
+ m_serverAddress = address;
+
// Get a new socket
m_desc = ::socket(AF_INET, SOCK_STREAM, 0);
@@ -331,6 +335,97 @@ void posixSocket::disconnect()
}
+static bool isNumericAddress(const char* address)
+{
+
+#if VMIME_HAVE_GETADDRINFO
+
+ struct addrinfo hint, *info = NULL;
+ memset(&hint, 0, sizeof(hint));
+
+ hint.ai_family = AF_UNSPEC;
+ hint.ai_flags = AI_NUMERICHOST;
+
+ if (getaddrinfo(address, 0, &hint, &info) == 0)
+ {
+ freeaddrinfo(info);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+#else
+
+ return inet_addr(address) != INADDR_NONE;
+
+#endif
+
+}
+
+
+const string posixSocket::getPeerAddress() const
+{
+ // Get address of connected peer
+ sockaddr peer;
+ socklen_t peerLen = sizeof(peer);
+
+ getpeername(m_desc, reinterpret_cast <sockaddr*>(&peer), &peerLen);
+
+ // Convert to numerical presentation format
+ char numericAddress[1024];
+
+ if (inet_ntop(peer.sa_family, &peer, numericAddress, sizeof(numericAddress)) != NULL)
+ return string(numericAddress);
+
+ return ""; // should not happen
+}
+
+
+const string posixSocket::getPeerName() const
+{
+ // Get address of connected peer
+ sockaddr peer;
+ socklen_t peerLen = sizeof(peer);
+
+ getpeername(m_desc, reinterpret_cast <sockaddr*>(&peer), &peerLen);
+
+ // If server address as specified when connecting is a numeric
+ // address, try to get a host name for it
+ if (isNumericAddress(m_serverAddress.c_str()))
+ {
+
+#if VMIME_HAVE_GETNAMEINFO
+
+ char host[NI_MAXHOST + 1];
+ char service[NI_MAXSERV + 1];
+
+ if (getnameinfo(reinterpret_cast <sockaddr *>(&peer), peerLen,
+ host, sizeof(host), service, sizeof(service),
+ /* flags */ NI_NAMEREQD) == 0)
+ {
+ return string(host);
+ }
+
+#else
+
+ struct hostent *hp;
+
+ if ((hp = gethostbyaddr(reinterpret_cast <const void *>(&peer),
+ sizeof(peer), peer.sa_family)) != NULL)
+ {
+ return string(hp->h_name);
+ }
+
+#endif
+
+ }
+
+ return m_serverAddress;
+}
+
+
posixSocket::size_type posixSocket::getBlockSize() const
{
return 16384; // 16 KB
diff --git a/src/platforms/windows/windowsSocket.cpp b/src/platforms/windows/windowsSocket.cpp
index dc6f1b47..abc16d70 100644
--- a/src/platforms/windows/windowsSocket.cpp
+++ b/src/platforms/windows/windowsSocket.cpp
@@ -91,6 +91,8 @@ void windowsSocket::connect(const vmime::string& address, const vmime::port_t po
memcpy(reinterpret_cast <char*>(&addr.sin_addr), hostInfo->h_addr, hostInfo->h_length);
}
+ m_serverAddress = address;
+
// Get a new socket
m_desc = ::socket(AF_INET, SOCK_STREAM, 0);
@@ -156,6 +158,71 @@ void windowsSocket::disconnect()
}
+static bool isNumericAddress(const char* address)
+{
+ struct addrinfo hint, *info = NULL;
+ memset(&hint, 0, sizeof(hint));
+
+ hint.ai_family = AF_UNSPEC;
+ hint.ai_flags = AI_NUMERICHOST;
+
+ if (getaddrinfo(address, 0, &hint, &info) == 0)
+ {
+ freeaddrinfo(info);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+const string windowsSocket::getPeerAddress() const
+{
+ // Get address of connected peer
+ sockaddr peer;
+ socklen_t peerLen = sizeof(peer);
+
+ getpeername(m_desc, reinterpret_cast <sockaddr*>(&peer), &peerLen);
+
+ // Convert to numerical presentation format
+ char numericAddress[1024];
+
+ if (inet_ntop(peer.sa_family, &peer, numericAddress, sizeof(numericAddress)) != NULL)
+ return string(numericAddress);
+
+ return ""; // should not happen
+}
+
+
+const string windowsSocket::getPeerName() const
+{
+ // Get address of connected peer
+ sockaddr peer;
+ socklen_t peerLen = sizeof(peer);
+
+ getpeername(m_desc, reinterpret_cast <sockaddr*>(&peer), &peerLen);
+
+ // If server address as specified when connecting is a numeric
+ // address, try to get a host name for it
+ if (isNumericAddress(m_serverAddress.c_str()))
+ {
+ char host[NI_MAXHOST + 1];
+ char service[NI_MAXSERV + 1];
+
+ if (getnameinfo(reinterpret_cast <sockaddr *>(&peer), peerLen,
+ host, sizeof(host), service, sizeof(service),
+ /* flags */ NI_NAMEREQD) == 0)
+ {
+ return string(host);
+ }
+ }
+
+ return m_serverAddress;
+}
+
+
windowsSocket::size_type windowsSocket::getBlockSize() const
{
return 16384; // 16 KB
diff --git a/src/security/cert/defaultCertificateVerifier.cpp b/src/security/cert/defaultCertificateVerifier.cpp
index 6fde5519..65f5f476 100644
--- a/src/security/cert/defaultCertificateVerifier.cpp
+++ b/src/security/cert/defaultCertificateVerifier.cpp
@@ -50,7 +50,8 @@ defaultCertificateVerifier::defaultCertificateVerifier(const defaultCertificateV
}
-void defaultCertificateVerifier::verify(ref <certificateChain> chain)
+void defaultCertificateVerifier::verify
+ (ref <certificateChain> chain, const string& hostname)
{
if (chain->getCount() == 0)
return;
@@ -58,13 +59,14 @@ void defaultCertificateVerifier::verify(ref <certificateChain> chain)
const string type = chain->getAt(0)->getType();
if (type == "X.509")
- verifyX509(chain);
+ verifyX509(chain, hostname);
else
throw exceptions::unsupported_certificate_type(type);
}
-void defaultCertificateVerifier::verifyX509(ref <certificateChain> chain)
+void defaultCertificateVerifier::verifyX509
+ (ref <certificateChain> chain, const string& hostname)
{
// For every certificate in the chain, verify that the certificate
// has been issued by the next certificate in the chain
@@ -141,6 +143,13 @@ void defaultCertificateVerifier::verifyX509(ref <certificateChain> chain)
throw exceptions::certificate_verification_exception
("Cannot verify certificate against trusted certificates.");
}
+
+ // Ensure the first certificate's subject name matches server hostname
+ if (!firstCert->verifyHostName(hostname))
+ {
+ throw exceptions::certificate_verification_exception
+ ("Server identity cannot be verified.");
+ }
}
diff --git a/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp
index 633004ff..b3f939ec 100644
--- a/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp
+++ b/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp
@@ -181,6 +181,12 @@ bool X509Certificate_GnuTLS::verify(ref <const X509Certificate> caCert_) const
}
+bool X509Certificate_GnuTLS::verifyHostName(const string& hostname) const
+{
+ return gnutls_x509_crt_check_hostname(m_data->cert, hostname.c_str()) != 0;
+}
+
+
const datetime X509Certificate_GnuTLS::getActivationDate() const
{
const time_t t = gnutls_x509_crt_get_activation_time(m_data->cert);
diff --git a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
index e47a19a4..3f171a4f 100755
--- a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
+++ b/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
@@ -41,6 +41,8 @@
#include "vmime/exception.hpp"
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/conf.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/err.h>
@@ -330,6 +332,72 @@ bool X509Certificate_OpenSSL::verify(ref <const X509Certificate> caCert_) const
}
+bool X509Certificate_OpenSSL::verifyHostName(const string& hostname) const
+{
+ // First, check subject common name against hostname
+ char CNBuffer[1024];
+ CNBuffer[sizeof(CNBuffer - 1)] = '\0';
+
+ X509_NAME* xname = X509_get_subject_name(m_data->cert);
+
+ if (X509_NAME_get_text_by_NID(xname, NID_commonName, CNBuffer, sizeof(CNBuffer)) != -1)
+ {
+ if (strcasecmp(CNBuffer, hostname.c_str()) == 0)
+ return true;
+ }
+
+ // Now, look in subject alternative names
+ for (int i = 0, extCount = X509_get_ext_count(m_data->cert) ; i < extCount ; ++i)
+ {
+ X509_EXTENSION* ext = X509_get_ext(m_data->cert, i);
+ const char* extStr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
+
+ if (strcmp(extStr, "subjectAltName") == 0)
+ {
+ const X509V3_EXT_METHOD* method;
+
+ if ((method = X509V3_EXT_get(ext)) != NULL)
+ {
+ const unsigned char* extVal = ext->value->data;
+ void *extValStr;
+
+ if (method->it)
+ {
+ extValStr = ASN1_item_d2i
+ (NULL, &extVal, ext->value->length, ASN1_ITEM_ptr(method->it));
+ }
+ else
+ {
+ extValStr = method->d2i
+ (NULL, &extVal, ext->value->length);
+ }
+
+ if (extValStr && method->i2v)
+ {
+ STACK_OF(CONF_VALUE)* val = method->i2v(method, extValStr, NULL);
+
+ for (int j = 0 ; j < sk_CONF_VALUE_num(val) ; ++j)
+ {
+ CONF_VALUE* cnf = sk_CONF_VALUE_value(val, j);
+
+ if ((strcasecmp(cnf->name, "DNS") == 0 &&
+ strcasecmp(cnf->value, hostname.c_str()) == 0)
+ ||
+ (strncasecmp(cnf->name, "IP", 2) == 0 &&
+ strcasecmp(cnf->value, hostname.c_str()) == 0))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+
const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const
{
char* buffer;
diff --git a/src/security/sasl/SASLSocket.cpp b/src/security/sasl/SASLSocket.cpp
index c3498d22..a4b0ea56 100644
--- a/src/security/sasl/SASLSocket.cpp
+++ b/src/security/sasl/SASLSocket.cpp
@@ -81,6 +81,18 @@ SASLSocket::size_type SASLSocket::getBlockSize() const
}
+const string SASLSocket::getPeerName() const
+{
+ return m_wrapped->getPeerName();
+}
+
+
+const string SASLSocket::getPeerAddress() const
+{
+ return m_wrapped->getPeerAddress();
+}
+
+
void SASLSocket::receive(string& buffer)
{
const size_type n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer));
diff --git a/vmime/net/socket.hpp b/vmime/net/socket.hpp
index 4551e3e2..7a14b3d8 100644
--- a/vmime/net/socket.hpp
+++ b/vmime/net/socket.hpp
@@ -127,6 +127,18 @@ public:
*/
virtual unsigned int getStatus() const = 0;
+ /** Return the hostname of peer this socket is connected to.
+ *
+ * @return name of the peer, or numeric address if it cannot be found
+ */
+ virtual const string getPeerName() const = 0;
+
+ /** Return the address of peer this socket is connected to.
+ *
+ * @return numeric address of the peer
+ */
+ virtual const string getPeerAddress() const = 0;
+
protected:
socket() { }
diff --git a/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp b/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp
index ca113f17..ba7456d5 100644
--- a/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp
+++ b/vmime/net/tls/gnutls/TLSSocket_GnuTLS.hpp
@@ -76,6 +76,9 @@ public:
unsigned int getStatus() const;
+ const string getPeerName() const;
+ const string getPeerAddress() const;
+
private:
void internalThrow();
diff --git a/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp b/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp
index ab4093f7..6f7bc3d1 100755
--- a/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp
+++ b/vmime/net/tls/openssl/TLSSocket_OpenSSL.hpp
@@ -80,6 +80,9 @@ public:
unsigned int getStatus() const;
+ const string getPeerName() const;
+ const string getPeerAddress() const;
+
private:
static int bio_write(BIO* bio, const char* buf, int len);
diff --git a/vmime/platforms/posix/posixSocket.hpp b/vmime/platforms/posix/posixSocket.hpp
index 78b1c0aa..4c5bc9b0 100644
--- a/vmime/platforms/posix/posixSocket.hpp
+++ b/vmime/platforms/posix/posixSocket.hpp
@@ -61,6 +61,9 @@ public:
unsigned int getStatus() const;
+ const string getPeerName() const;
+ const string getPeerAddress() const;
+
protected:
static void throwSocketError(const int err);
@@ -73,6 +76,8 @@ private:
int m_desc;
unsigned int m_status;
+
+ string m_serverAddress;
};
diff --git a/vmime/platforms/windows/windowsSocket.hpp b/vmime/platforms/windows/windowsSocket.hpp
index ca007a06..8fe65133 100644
--- a/vmime/platforms/windows/windowsSocket.hpp
+++ b/vmime/platforms/windows/windowsSocket.hpp
@@ -65,6 +65,9 @@ public:
unsigned int getStatus() const;
+ const string getPeerName() const;
+ const string getPeerAddress() const;
+
protected:
void throwSocketError(const int err);
@@ -86,6 +89,8 @@ private:
SOCKET m_desc;
unsigned int m_status;
+
+ string m_serverAddress;
};
diff --git a/vmime/security/cert/X509Certificate.hpp b/vmime/security/cert/X509Certificate.hpp
index b7f0b946..a993a91c 100644
--- a/vmime/security/cert/X509Certificate.hpp
+++ b/vmime/security/cert/X509Certificate.hpp
@@ -115,6 +115,13 @@ public:
*/
virtual bool verify(ref <const X509Certificate> caCert) const = 0;
+ /** Verify certificate's subject name against the given hostname.
+ *
+ * @param hostname DNS name of the server
+ * @return true if the match is successful, false otherwise
+ */
+ virtual bool verifyHostName(const string& hostname) const = 0;
+
/** Gets the expiration date of this certificate. This is the date
* at which this certificate will not be valid anymore.
*
diff --git a/vmime/security/cert/certificateVerifier.hpp b/vmime/security/cert/certificateVerifier.hpp
index cf038262..05a66154 100644
--- a/vmime/security/cert/certificateVerifier.hpp
+++ b/vmime/security/cert/certificateVerifier.hpp
@@ -44,10 +44,12 @@ public:
/** Verify that the specified certificate chain is trusted.
*
* @param chain certificate chain
+ * @param server hostname
* @throw exceptions::certificate_verification_exception if one
- * or more certificates can not be trusted
+ * or more certificates can not be trusted, or the server identity
+ * cannot be verified
*/
- virtual void verify(ref <certificateChain> chain) = 0;
+ virtual void verify(ref <certificateChain> chain, const string& hostname) = 0;
};
diff --git a/vmime/security/cert/defaultCertificateVerifier.hpp b/vmime/security/cert/defaultCertificateVerifier.hpp
index 6f650f39..81262b8b 100644
--- a/vmime/security/cert/defaultCertificateVerifier.hpp
+++ b/vmime/security/cert/defaultCertificateVerifier.hpp
@@ -63,7 +63,7 @@ public:
// Implementation of 'certificateVerifier'
- void verify(ref <certificateChain> chain);
+ void verify(ref <certificateChain> chain, const string& hostname);
private:
@@ -71,7 +71,7 @@ private:
*
* @param chain list of X.509 certificates
*/
- void verifyX509(ref <certificateChain> chain);
+ void verifyX509(ref <certificateChain> chain, const string& hostname);
std::vector <ref <X509Certificate> > m_x509RootCAs;
diff --git a/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp b/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp
index c720c1fb..b06b712f 100644
--- a/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp
+++ b/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp
@@ -62,6 +62,8 @@ public:
bool verify(ref <const X509Certificate> caCert) const;
+ bool verifyHostName(const string& hostname) const;
+
const datetime getExpirationDate() const;
const datetime getActivationDate() const;
diff --git a/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp b/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp
index d9083b06..ef92b35f 100644
--- a/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp
+++ b/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp
@@ -65,6 +65,8 @@ public:
bool verify(ref <const X509Certificate> caCert) const;
+ bool verifyHostName(const string& hostname) const;
+
const datetime getExpirationDate() const;
const datetime getActivationDate() const;
diff --git a/vmime/security/sasl/SASLSocket.hpp b/vmime/security/sasl/SASLSocket.hpp
index 0e7d209f..c450b998 100644
--- a/vmime/security/sasl/SASLSocket.hpp
+++ b/vmime/security/sasl/SASLSocket.hpp
@@ -69,6 +69,9 @@ public:
unsigned int getStatus() const;
+ const string getPeerName() const;
+ const string getPeerAddress() const;
+
private:
ref <SASLSession> m_session;