SSL server identity check.
This commit is contained in:
parent
589f2f3545
commit
87259631e4
@ -561,6 +561,7 @@ INCLUDE(CheckFunctionExists)
|
|||||||
INCLUDE(CheckSymbolExists)
|
INCLUDE(CheckSymbolExists)
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS(getaddrinfo VMIME_HAVE_GETADDRINFO)
|
CHECK_FUNCTION_EXISTS(getaddrinfo VMIME_HAVE_GETADDRINFO)
|
||||||
|
CHECK_FUNCTION_EXISTS(getnameinfo VMIME_HAVE_GETNAMEINFO)
|
||||||
|
|
||||||
CHECK_FUNCTION_EXISTS(gettid VMIME_HAVE_GETTID)
|
CHECK_FUNCTION_EXISTS(gettid VMIME_HAVE_GETTID)
|
||||||
CHECK_FUNCTION_EXISTS(syscall VMIME_HAVE_SYSCALL)
|
CHECK_FUNCTION_EXISTS(syscall VMIME_HAVE_SYSCALL)
|
||||||
|
@ -860,6 +860,7 @@ for platform in libvmime_platforms_sources:
|
|||||||
|
|
||||||
config_hpp.write("""
|
config_hpp.write("""
|
||||||
#define VMIME_HAVE_GETADDRINFO 1
|
#define VMIME_HAVE_GETADDRINFO 1
|
||||||
|
#define VMIME_HAVE_GETNAMEINFO 1
|
||||||
#define VMIME_HAVE_PTHREAD 1
|
#define VMIME_HAVE_PTHREAD 1
|
||||||
#define VMIME_HAVE_GETTID 0
|
#define VMIME_HAVE_GETTID 0
|
||||||
#define VMIME_HAVE_SYSCALL 1
|
#define VMIME_HAVE_SYSCALL 1
|
||||||
|
@ -147,7 +147,7 @@ class interactiveCertificateVerifier : public vmime::security::cert::defaultCert
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void verify(vmime::ref <vmime::security::cert::certificateChain> chain)
|
void verify(vmime::ref <vmime::security::cert::certificateChain> chain, const vmime::string& hostname)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -176,6 +176,9 @@ public:
|
|||||||
{
|
{
|
||||||
m_trustedCerts.push_back(cert.dynamicCast
|
m_trustedCerts.push_back(cert.dynamicCast
|
||||||
<vmime::security::cert::X509Certificate>());
|
<vmime::security::cert::X509Certificate>());
|
||||||
|
|
||||||
|
setX509TrustedCerts(m_trustedCerts);
|
||||||
|
defaultCertificateVerifier::verify(chain, hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -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)
|
void TLSSocket_GnuTLS::receive(string& buffer)
|
||||||
{
|
{
|
||||||
const int size = receiveRaw(m_buffer, sizeof(m_buffer));
|
const int size = receiveRaw(m_buffer, sizeof(m_buffer));
|
||||||
@ -262,7 +274,7 @@ void TLSSocket_GnuTLS::handshake(ref <timeoutHandler> toHandler)
|
|||||||
if (certs == NULL)
|
if (certs == NULL)
|
||||||
throw exceptions::tls_exception("No peer certificate.");
|
throw exceptions::tls_exception("No peer certificate.");
|
||||||
|
|
||||||
m_session->getCertificateVerifier()->verify(certs);
|
m_session->getCertificateVerifier()->verify(certs, getPeerName());
|
||||||
|
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
void TLSSocket_OpenSSL::receive(string& buffer)
|
||||||
{
|
{
|
||||||
const size_type size = receiveRaw(m_buffer, sizeof(m_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)
|
if (certs == NULL)
|
||||||
throw exceptions::tls_exception("No peer certificate.");
|
throw exceptions::tls_exception("No peer certificate.");
|
||||||
|
|
||||||
m_session->getCertificateVerifier()->verify(certs);
|
m_session->getCertificateVerifier()->verify(certs, getPeerName());
|
||||||
|
|
||||||
m_connected = true;
|
m_connected = true;
|
||||||
}
|
}
|
||||||
|
@ -104,6 +104,8 @@ void posixSocket::connect(const vmime::string& address, const vmime::port_t port
|
|||||||
throw vmime::exceptions::connection_error("Cannot resolve address.");
|
throw vmime::exceptions::connection_error("Cannot resolve address.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_serverAddress = address;
|
||||||
|
|
||||||
// Connect to host
|
// Connect to host
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
struct ::addrinfo* res = res0;
|
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);
|
::memcpy(reinterpret_cast <char*>(&addr.sin_addr), hostInfo->h_addr, hostInfo->h_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_serverAddress = address;
|
||||||
|
|
||||||
// Get a new socket
|
// Get a new socket
|
||||||
m_desc = ::socket(AF_INET, SOCK_STREAM, 0);
|
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
|
posixSocket::size_type posixSocket::getBlockSize() const
|
||||||
{
|
{
|
||||||
return 16384; // 16 KB
|
return 16384; // 16 KB
|
||||||
|
@ -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);
|
memcpy(reinterpret_cast <char*>(&addr.sin_addr), hostInfo->h_addr, hostInfo->h_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_serverAddress = address;
|
||||||
|
|
||||||
// Get a new socket
|
// Get a new socket
|
||||||
m_desc = ::socket(AF_INET, SOCK_STREAM, 0);
|
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
|
windowsSocket::size_type windowsSocket::getBlockSize() const
|
||||||
{
|
{
|
||||||
return 16384; // 16 KB
|
return 16384; // 16 KB
|
||||||
|
@ -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)
|
if (chain->getCount() == 0)
|
||||||
return;
|
return;
|
||||||
@ -58,13 +59,14 @@ void defaultCertificateVerifier::verify(ref <certificateChain> chain)
|
|||||||
const string type = chain->getAt(0)->getType();
|
const string type = chain->getAt(0)->getType();
|
||||||
|
|
||||||
if (type == "X.509")
|
if (type == "X.509")
|
||||||
verifyX509(chain);
|
verifyX509(chain, hostname);
|
||||||
else
|
else
|
||||||
throw exceptions::unsupported_certificate_type(type);
|
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
|
// For every certificate in the chain, verify that the certificate
|
||||||
// has been issued by the next certificate in the chain
|
// 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
|
throw exceptions::certificate_verification_exception
|
||||||
("Cannot verify certificate against trusted certificates.");
|
("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.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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 datetime X509Certificate_GnuTLS::getActivationDate() const
|
||||||
{
|
{
|
||||||
const time_t t = gnutls_x509_crt_get_activation_time(m_data->cert);
|
const time_t t = gnutls_x509_crt_get_activation_time(m_data->cert);
|
||||||
|
@ -41,6 +41,8 @@
|
|||||||
#include "vmime/exception.hpp"
|
#include "vmime/exception.hpp"
|
||||||
|
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
|
#include <openssl/x509v3.h>
|
||||||
|
#include <openssl/conf.h>
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/err.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
|
const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const
|
||||||
{
|
{
|
||||||
char* buffer;
|
char* buffer;
|
||||||
|
@ -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)
|
void SASLSocket::receive(string& buffer)
|
||||||
{
|
{
|
||||||
const size_type n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer));
|
const size_type n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer));
|
||||||
|
@ -127,6 +127,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual unsigned int getStatus() const = 0;
|
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:
|
protected:
|
||||||
|
|
||||||
socket() { }
|
socket() { }
|
||||||
|
@ -76,6 +76,9 @@ public:
|
|||||||
|
|
||||||
unsigned int getStatus() const;
|
unsigned int getStatus() const;
|
||||||
|
|
||||||
|
const string getPeerName() const;
|
||||||
|
const string getPeerAddress() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void internalThrow();
|
void internalThrow();
|
||||||
|
@ -80,6 +80,9 @@ public:
|
|||||||
|
|
||||||
unsigned int getStatus() const;
|
unsigned int getStatus() const;
|
||||||
|
|
||||||
|
const string getPeerName() const;
|
||||||
|
const string getPeerAddress() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static int bio_write(BIO* bio, const char* buf, int len);
|
static int bio_write(BIO* bio, const char* buf, int len);
|
||||||
|
@ -61,6 +61,9 @@ public:
|
|||||||
|
|
||||||
unsigned int getStatus() const;
|
unsigned int getStatus() const;
|
||||||
|
|
||||||
|
const string getPeerName() const;
|
||||||
|
const string getPeerAddress() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static void throwSocketError(const int err);
|
static void throwSocketError(const int err);
|
||||||
@ -73,6 +76,8 @@ private:
|
|||||||
int m_desc;
|
int m_desc;
|
||||||
|
|
||||||
unsigned int m_status;
|
unsigned int m_status;
|
||||||
|
|
||||||
|
string m_serverAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ public:
|
|||||||
|
|
||||||
unsigned int getStatus() const;
|
unsigned int getStatus() const;
|
||||||
|
|
||||||
|
const string getPeerName() const;
|
||||||
|
const string getPeerAddress() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void throwSocketError(const int err);
|
void throwSocketError(const int err);
|
||||||
@ -86,6 +89,8 @@ private:
|
|||||||
SOCKET m_desc;
|
SOCKET m_desc;
|
||||||
|
|
||||||
unsigned int m_status;
|
unsigned int m_status;
|
||||||
|
|
||||||
|
string m_serverAddress;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,6 +115,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool verify(ref <const X509Certificate> caCert) const = 0;
|
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
|
/** Gets the expiration date of this certificate. This is the date
|
||||||
* at which this certificate will not be valid anymore.
|
* at which this certificate will not be valid anymore.
|
||||||
*
|
*
|
||||||
|
@ -44,10 +44,12 @@ public:
|
|||||||
/** Verify that the specified certificate chain is trusted.
|
/** Verify that the specified certificate chain is trusted.
|
||||||
*
|
*
|
||||||
* @param chain certificate chain
|
* @param chain certificate chain
|
||||||
|
* @param server hostname
|
||||||
* @throw exceptions::certificate_verification_exception if one
|
* @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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
// Implementation of 'certificateVerifier'
|
// Implementation of 'certificateVerifier'
|
||||||
void verify(ref <certificateChain> chain);
|
void verify(ref <certificateChain> chain, const string& hostname);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ private:
|
|||||||
*
|
*
|
||||||
* @param chain list of X.509 certificates
|
* @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;
|
std::vector <ref <X509Certificate> > m_x509RootCAs;
|
||||||
|
@ -62,6 +62,8 @@ public:
|
|||||||
|
|
||||||
bool verify(ref <const X509Certificate> caCert) const;
|
bool verify(ref <const X509Certificate> caCert) const;
|
||||||
|
|
||||||
|
bool verifyHostName(const string& hostname) const;
|
||||||
|
|
||||||
const datetime getExpirationDate() const;
|
const datetime getExpirationDate() const;
|
||||||
const datetime getActivationDate() const;
|
const datetime getActivationDate() const;
|
||||||
|
|
||||||
|
@ -65,6 +65,8 @@ public:
|
|||||||
|
|
||||||
bool verify(ref <const X509Certificate> caCert) const;
|
bool verify(ref <const X509Certificate> caCert) const;
|
||||||
|
|
||||||
|
bool verifyHostName(const string& hostname) const;
|
||||||
|
|
||||||
const datetime getExpirationDate() const;
|
const datetime getExpirationDate() const;
|
||||||
const datetime getActivationDate() const;
|
const datetime getActivationDate() const;
|
||||||
|
|
||||||
|
@ -69,6 +69,9 @@ public:
|
|||||||
|
|
||||||
unsigned int getStatus() const;
|
unsigned int getStatus() const;
|
||||||
|
|
||||||
|
const string getPeerName() const;
|
||||||
|
const string getPeerAddress() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
ref <SASLSession> m_session;
|
ref <SASLSession> m_session;
|
||||||
|
Loading…
Reference in New Issue
Block a user