Certificate exception differentiation for easier error handling.

This commit is contained in:
Vincent Richard 2014-07-24 20:59:52 +02:00
parent 937d9c01cc
commit 00e07962e7
24 changed files with 991 additions and 125 deletions

View File

@ -874,7 +874,7 @@ default behaviour is to fallback on a normal connection. To make
\subsubsection{How it works} % ...............................................
If you tried the previous examples, a
{\vcode certificate\_verification\_exception} might have been thrown.
{\vcode certificateException} might have been thrown.
This is because the default certificate verifier in VMime did not manage to
verify the certificate, and so could not trust it.
@ -905,6 +905,8 @@ used is quite simple:
issued by the next certificate in the chain;
\item for every certificate in the chain, verify that the certificate is valid
at the current time;
\item ensure that the first certificate's subject name matches the hostname
of the server;
\item decide whether the subject's certificate can be trusted:
\begin{itemize}
\item first, verify that the the last certificate in the chain was
@ -981,7 +983,7 @@ write your own verifier. Your verifier should inherit from the
{\vcode vmime::security::cert::certificateVerifier} class and implement the
method {\vcode verify()}. Then, if the specified certificate chain is trusted,
simply return from the function, or else throw a
{\vcode certificate\_verification\_exception}.
{\vcode certificateException}.
The following example shows how to implement an interactive certificate
verifier which relies on the user's decision, and nothing else (you SHOULD NOT
@ -1011,7 +1013,7 @@ public:
return; // OK, we trust the certificate
// Don't trust this certificate
throw exceptions::certificate_verification_exception();
throw vmime::security::cert::certificateException();
}
};
\end{lstlisting}

View File

@ -15,7 +15,7 @@ public:
defaultCertificateVerifier::verify(chain, hostname);
}
catch (vmime::exceptions::certificate_verification_exception&)
catch (vmime::security::cert::certificateException&)
{
// Obtain subject's certificate
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
@ -44,7 +44,7 @@ public:
return;
}
throw vmime::exceptions::certificate_verification_exception
throw vmime::security::cert::certificateException
("User did not accept the certificate.");
}
}

View File

@ -35,19 +35,19 @@ const exception exception::NO_EXCEPTION;
exception::exception()
: m_what(""), m_other(NULL)
: std::runtime_error(""), m_other(NULL)
{
}
exception::exception(const string& what, const exception& other)
: m_what(what), m_other(&other != &NO_EXCEPTION ? other.clone() : NULL)
: std::runtime_error(what), m_other(&other != &NO_EXCEPTION ? other.clone() : NULL)
{
}
exception::exception(const exception& e)
: std::exception(), m_what(e.what()), m_other(e.m_other == NULL ? NULL : e.m_other->clone())
: std::runtime_error(e.what()), m_other(e.m_other == NULL ? NULL : e.m_other->clone())
{
}
@ -58,15 +58,12 @@ exception::~exception() throw()
}
const char* exception::what() const throw()
void exception::chainException(const exception& other)
{
return (m_what.c_str());
}
exception* e = other.clone();
const char* exception::what() throw()
{
return (m_what.c_str());
delete m_other;
m_other = e;
}
@ -715,42 +712,6 @@ exception* tls_exception::clone() const { return new tls_exception(*this); }
const char* tls_exception::name() const throw() { return "tls_exception"; }
//
// certificate_exception
//
certificate_exception::~certificate_exception() throw() {}
certificate_exception::certificate_exception(const string& what, const exception& other)
: tls_exception(what, other) {}
exception* certificate_exception::clone() const { return new certificate_exception(*this); }
const char* certificate_exception::name() const throw() { return "certificate_exception"; }
//
// certificate_verification_exception
//
certificate_verification_exception::~certificate_verification_exception() throw() {}
certificate_verification_exception::certificate_verification_exception(const string& what, const exception& other)
: certificate_exception(what, other) {}
exception* certificate_verification_exception::clone() const { return new certificate_verification_exception(*this); }
const char* certificate_verification_exception::name() const throw() { return "certificate_verification_exception"; }
//
// unsupported_certificate_type
//
unsupported_certificate_type::~unsupported_certificate_type() throw() {}
unsupported_certificate_type::unsupported_certificate_type(const string& type, const exception& other)
: certificate_exception("Unsupported certificate type: '" + type + "'", other) {}
exception* unsupported_certificate_type::clone() const { return new unsupported_certificate_type(*this); }
const char* unsupported_certificate_type::name() const throw() { return "unsupported_certificate_type"; }
#endif // VMIME_HAVE_TLS_SUPPORT

View File

@ -39,11 +39,10 @@ namespace vmime
/** Base class for VMime exceptions.
*/
class VMIME_EXPORT exception : public std::exception
class VMIME_EXPORT exception : public std::runtime_error
{
private:
string m_what;
exception* m_other;
exception();
@ -55,19 +54,14 @@ public:
virtual ~exception() throw();
/** Return a description of the error.
/** Chain the specified exception with this exception.
*
* @return error message
* @param other next exception in the chain
*/
const char* what() const throw();
void chainException(const exception& other);
/** Return a description of the error.
*
* @return error message
*/
const char* what() throw();
/** Return the next exception in the chain (encapsulated exception).
/** Return the next exception in the chain, that is the exception
* that caused this exception. This permits nesting exceptions.
*
* @return next exception in the chain
*/
@ -874,42 +868,6 @@ public:
};
class VMIME_EXPORT certificate_exception : public tls_exception
{
public:
certificate_exception(const string& what, const exception& other = NO_EXCEPTION);
~certificate_exception() throw();
exception* clone() const;
const char* name() const throw();
};
class VMIME_EXPORT certificate_verification_exception : public certificate_exception
{
public:
certificate_verification_exception(const string& what, const exception& other = NO_EXCEPTION);
~certificate_verification_exception() throw ();
exception* clone() const;
const char* name() const throw ();
};
class VMIME_EXPORT unsupported_certificate_type : public certificate_exception
{
public:
unsupported_certificate_type(const string& type, const exception& other = NO_EXCEPTION);
~unsupported_certificate_type() throw ();
exception* clone() const;
const char* name() const throw ();
};
#endif // VMIME_HAVE_TLS_SUPPORT

View File

@ -31,7 +31,7 @@
#include "vmime/net/tls/openssl/TLSProperties_OpenSSL.hpp"
#include "vmime/net/tls/openssl/OpenSSLInitializer.hpp"
#include "vmime/exception.hpp"
#include "vmime/security/cert/certificateException.hpp"
#include <openssl/ssl.h>
#include <openssl/err.h>
@ -99,7 +99,7 @@ void TLSSession_OpenSSL::usePrivateKeyFile(const vmime::string& keyfile)
std::ostringstream oss;
oss << "Error loading private key from file " << keyfile;
oss << " - msg: " << sslErr;
throw exceptions::certificate_exception(oss.str());
throw security::cert::certificateException(oss.str());
}
}
@ -115,7 +115,7 @@ void TLSSession_OpenSSL::useCertificateChainFile(const vmime::string& chainFile)
std::ostringstream oss;
oss << "Error loading certificate from file " << chainFile;
oss << " - msg: " << sslErr;
throw exceptions::certificate_exception(oss.str());
throw security::cert::certificateException(oss.str());
}
}

View File

@ -29,6 +29,9 @@
#include "vmime/security/cert/X509Certificate.hpp"
#include "vmime/security/cert/certificateNotYetValidException.hpp"
#include "vmime/security/cert/certificateExpiredException.hpp"
namespace vmime {
namespace security {
@ -40,6 +43,27 @@ X509Certificate::~X509Certificate()
}
void X509Certificate::checkValidity()
{
const datetime now = datetime::now();
if (now < getActivationDate())
{
certificateNotYetValidException ex;
ex.setCertificate(dynamicCast <certificate>(shared_from_this()));
throw ex;
}
else if (now > getExpirationDate())
{
certificateExpiredException ex;
ex.setCertificate(dynamicCast <certificate>(shared_from_this()));
throw ex;
}
}
} // cert
} // security
} // vmime

View File

@ -153,6 +153,15 @@ public:
* @return the fingerprint of this certificate
*/
virtual const byteArray getFingerprint(const DigestAlgorithm algo) const = 0;
/** Checks that the certificate is currently valid. For the certificate
* to be valid, the current date and time must be in the validity period
* specified in the certificate.
*
* @throw certificateExpiredException if the certificate has expired
* @throw certificateNotYetValidException if the certificate is not yet valid
*/
virtual void checkValidity();
};

View File

@ -0,0 +1,78 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificateException.hpp"
namespace vmime {
namespace security {
namespace cert {
certificateException::certificateException()
: exception("A problem occured with a certificate.")
{
}
certificateException::certificateException(const std::string& what)
: exception(what)
{
}
certificateException::~certificateException() throw()
{
}
exception* certificateException::clone() const
{
return new certificateException(what());
}
void certificateException::setCertificate(shared_ptr <certificate> cert)
{
m_cert = cert;
}
shared_ptr <certificate> certificateException::getCertificate()
{
return m_cert;
}
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT

View File

@ -0,0 +1,89 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_SECURITY_CERT_CERTIFICATEEXCEPTION_HPP_INCLUDED
#define VMIME_SECURITY_CERT_CERTIFICATEEXCEPTION_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificate.hpp"
#include "vmime/exception.hpp"
namespace vmime {
namespace security {
namespace cert {
/** Thrown to indicate a problem with a certificate or certificate verification.
*/
class VMIME_EXPORT certificateException : public exception
{
public:
/** Constructs a certificateException with no detail message.
*/
certificateException();
/** Constructs a certificateException with a detail message.
*
* @param what a message that describes this exception
*/
certificateException(const std::string& what);
~certificateException() throw();
exception* clone() const;
/** Sets the certificate on which the problem occured.
*
* @param cert certificate
*/
void setCertificate(shared_ptr <certificate> cert);
/** Returns the certificate on which the problem occured.
*
* @return certificate
*/
shared_ptr <certificate> getCertificate();
private:
shared_ptr <certificate> m_cert;
};
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#endif // VMIME_SECURITY_CERT_CERTIFICATEEXCEPTION_HPP_INCLUDED

View File

@ -0,0 +1,55 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificateExpiredException.hpp"
namespace vmime {
namespace security {
namespace cert {
certificateExpiredException::certificateExpiredException()
: certificateException("The certificate has expired.")
{
}
exception* certificateExpiredException::clone() const
{
return new certificateExpiredException();
}
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT

View File

@ -0,0 +1,65 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_SECURITY_CERT_CERTIFICATEEXPIREDEXCEPTION_HPP_INCLUDED
#define VMIME_SECURITY_CERT_CERTIFICATEEXPIREDEXCEPTION_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificate.hpp"
#include "vmime/security/cert/certificateException.hpp"
namespace vmime {
namespace security {
namespace cert {
/** Thrown when the current date and time is after the validity period
* specified in the certificate.
*/
class VMIME_EXPORT certificateExpiredException : public certificateException
{
public:
/** Constructs a certificateExpiredException with no detail message.
*/
certificateExpiredException();
exception* clone() const;
};
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#endif // VMIME_SECURITY_CERT_CERTIFICATEEXPIREDEXCEPTION_HPP_INCLUDED

View File

@ -0,0 +1,55 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificateIssuerVerificationException.hpp"
namespace vmime {
namespace security {
namespace cert {
certificateIssuerVerificationException::certificateIssuerVerificationException()
: certificateException("Certificate subject/issuer verification failed.")
{
}
exception* certificateIssuerVerificationException::clone() const
{
return new certificateIssuerVerificationException();
}
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT

View File

@ -0,0 +1,65 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_SECURITY_CERT_CERTIFICATEISSUERVERIFICATIONEXCEPTION_HPP_INCLUDED
#define VMIME_SECURITY_CERT_CERTIFICATEISSUERVERIFICATIONEXCEPTION_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificate.hpp"
#include "vmime/security/cert/certificateException.hpp"
namespace vmime {
namespace security {
namespace cert {
/** Thrown when a certificate in a certificate chain cannot be verified
* against the next certificate in the chain (the issuer).
*/
class VMIME_EXPORT certificateIssuerVerificationException : public certificateException
{
public:
/** Constructs a certificateIssuerVerificationException with no detail message.
*/
certificateIssuerVerificationException();
exception* clone() const;
};
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#endif // VMIME_SECURITY_CERT_CERTIFICATEISSUERVERIFICATIONEXCEPTION_HPP_INCLUDED

View File

@ -0,0 +1,55 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificateNotTrustedException.hpp"
namespace vmime {
namespace security {
namespace cert {
certificateNotTrustedException::certificateNotTrustedException()
: certificateException("Cannot verify certificate against trusted certificates.")
{
}
exception* certificateNotTrustedException::clone() const
{
return new certificateNotTrustedException();
}
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT

View File

@ -0,0 +1,65 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_SECURITY_CERT_CERTIFICATENOTTRUSTEDEXCEPTION_HPP_INCLUDED
#define VMIME_SECURITY_CERT_CERTIFICATENOTTRUSTEDEXCEPTION_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificate.hpp"
#include "vmime/security/cert/certificateException.hpp"
namespace vmime {
namespace security {
namespace cert {
/** Thrown when a certificate cannot be verified against root and/or
* trusted certificates.
*/
class VMIME_EXPORT certificateNotTrustedException : public certificateException
{
public:
/** Constructs a certificateNotTrustedException with no detail message.
*/
certificateNotTrustedException();
exception* clone() const;
};
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#endif // VMIME_SECURITY_CERT_CERTIFICATENOTTRUSTEDEXCEPTION_HPP_INCLUDED

View File

@ -0,0 +1,55 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificateNotYetValidException.hpp"
namespace vmime {
namespace security {
namespace cert {
certificateNotYetValidException::certificateNotYetValidException()
: certificateException("The certificate is not yet valid.")
{
}
exception* certificateNotYetValidException::clone() const
{
return new certificateNotYetValidException();
}
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT

View File

@ -0,0 +1,65 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_SECURITY_CERT_CERTIFICATENOTYETVALIDEXCEPTION_HPP_INCLUDED
#define VMIME_SECURITY_CERT_CERTIFICATENOTYETVALIDEXCEPTION_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificate.hpp"
#include "vmime/security/cert/certificateException.hpp"
namespace vmime {
namespace security {
namespace cert {
/** Thrown when the current date and time is before the validity period
* specified in the certificate.
*/
class VMIME_EXPORT certificateNotYetValidException : public certificateException
{
public:
/** Constructs a certificateNotYetValidException with no detail message.
*/
certificateNotYetValidException();
exception* clone() const;
};
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#endif // VMIME_SECURITY_CERT_CERTIFICATENOTYETVALIDEXCEPTION_HPP_INCLUDED

View File

@ -29,6 +29,11 @@
#include "vmime/security/cert/certificateChain.hpp"
#include "vmime/security/cert/unsupportedCertificateTypeException.hpp"
#include "vmime/security/cert/certificateIssuerVerificationException.hpp"
#include "vmime/security/cert/certificateNotTrustedException.hpp"
#include "vmime/security/cert/serverIdentityException.hpp"
namespace vmime {
namespace security {
@ -45,9 +50,18 @@ public:
*
* @param chain certificate chain
* @param hostname server hostname
* @throw exceptions::certificate_verification_exception if one
* or more certificates can not be trusted, or the server identity
* cannot be verified
* @throw unsupportedCertificateTypeException if a certificate in the
* chain is of unsupported format
* @throw certificateExpiredException if a certificate in the chain
* has expired
* @throw certificateNotYetValidException if a certificate in the chain
* is not yet valid
* @throw certificateNotTrustedException if a certificate in the chain
* cannot be verified against root and/or trusted certificates
* @throw certificateIssuerVerificationException if a certificate in the
* chain cannot be verified against the next certificate (issuer)
* @throw serverIdentityException if the subject name of the certificate
* does not match the hostname of the server
*/
virtual void verify(shared_ptr <certificateChain> chain, const string& hostname) = 0;
};

View File

@ -65,7 +65,7 @@ void defaultCertificateVerifier::verify
if (type == "X.509")
verifyX509(chain, hostname);
else
throw exceptions::unsupported_certificate_type(type);
throw unsupportedCertificateTypeException(type);
}
@ -86,29 +86,22 @@ void defaultCertificateVerifier::verifyX509
if (!cert->checkIssuer(next))
{
throw exceptions::certificate_verification_exception
("Subject/issuer verification failed.");
certificateIssuerVerificationException ex;
ex.setCertificate(cert);
throw ex;
}
}
}
// For every certificate in the chain, verify that the certificate
// is valid at the current time
const datetime now = datetime::now();
for (unsigned int i = 0 ; i < chain->getCount() ; ++i)
{
shared_ptr <X509Certificate> cert =
dynamicCast <X509Certificate>(chain->getAt(i));
const datetime begin = cert->getActivationDate();
const datetime end = cert->getExpirationDate();
if (now < begin || now > end)
{
throw exceptions::certificate_verification_exception
("Validity date check failed.");
}
cert->checkValidity();
}
// Check whether the certificate can be trusted
@ -144,15 +137,19 @@ void defaultCertificateVerifier::verifyX509
if (!trusted)
{
throw exceptions::certificate_verification_exception
("Cannot verify certificate against trusted certificates.");
certificateNotTrustedException ex;
ex.setCertificate(firstCert);
throw ex;
}
// Ensure the first certificate's subject name matches server hostname
if (!firstCert->verifyHostName(hostname))
{
throw exceptions::certificate_verification_exception
("Server identity cannot be verified.");
serverIdentityException ex;
ex.setCertificate(firstCert);
throw ex;
}
}

View File

@ -38,7 +38,8 @@
#include "vmime/utility/outputStreamByteArrayAdapter.hpp"
#include "vmime/exception.hpp"
#include "vmime/security/cert/certificateException.hpp"
#include "vmime/security/cert/unsupportedCertificateTypeException.hpp"
#include <openssl/x509.h>
#include <openssl/x509v3.h>
@ -234,7 +235,7 @@ void X509Certificate_OpenSSL::write
}
else
{
throw vmime::exceptions::unsupported_certificate_type("Unknown cert type");
throw unsupportedCertificateTypeException("Unknown format");
}
return; // #### Early Return ####
@ -250,7 +251,7 @@ err:
char errstr[256];
long ec = ERR_get_error();
ERR_error_string(ec, errstr);
throw vmime::exceptions::certificate_exception(
throw certificateException(
"OpenSSLX509Certificate_OpenSSL::write exception - " + string(errstr));
}
}

View File

@ -0,0 +1,55 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/serverIdentityException.hpp"
namespace vmime {
namespace security {
namespace cert {
serverIdentityException::serverIdentityException()
: certificateException("Server identity cannot be verified.")
{
}
exception* serverIdentityException::clone() const
{
return new serverIdentityException();
}
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT

View File

@ -0,0 +1,65 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_SECURITY_CERT_SERVERIDENTITYEXCEPTION_HPP_INCLUDED
#define VMIME_SECURITY_CERT_SERVERIDENTITYEXCEPTION_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificate.hpp"
#include "vmime/security/cert/certificateException.hpp"
namespace vmime {
namespace security {
namespace cert {
/** Thrown when the subject name of a certificate does not match
* the hostname of the server.
*/
class VMIME_EXPORT serverIdentityException : public certificateException
{
public:
/** Constructs a serverIdentityException with no detail message.
*/
serverIdentityException();
exception* clone() const;
};
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#endif // VMIME_SECURITY_CERT_SERVERIDENTITYEXCEPTION_HPP_INCLUDED

View File

@ -0,0 +1,61 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/unsupportedCertificateTypeException.hpp"
namespace vmime {
namespace security {
namespace cert {
unsupportedCertificateTypeException::unsupportedCertificateTypeException(const string& type)
: certificateException(string("Unsupported certificate type: '") + type + "'."),
m_type(type)
{
}
unsupportedCertificateTypeException::~unsupportedCertificateTypeException() throw()
{
}
exception* unsupportedCertificateTypeException::clone() const
{
return new unsupportedCertificateTypeException(m_type);
}
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT

View File

@ -0,0 +1,72 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_SECURITY_CERT_UNSUPPORTEDCERTIFICATETYPEEXCEPTION_HPP_INCLUDED
#define VMIME_SECURITY_CERT_UNSUPPORTEDCERTIFICATETYPEEXCEPTION_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#include "vmime/security/cert/certificate.hpp"
#include "vmime/security/cert/certificateException.hpp"
namespace vmime {
namespace security {
namespace cert {
/** Thrown when a certificate is of unsupported format.
*/
class VMIME_EXPORT unsupportedCertificateTypeException : public certificateException
{
public:
/** Constructs a unsupportedCertificateTypeException.
*
* @param type certificate type
*/
unsupportedCertificateTypeException(const string& type);
~unsupportedCertificateTypeException() throw();
exception* clone() const;
private:
string m_type;
};
} // cert
} // security
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
#endif // VMIME_SECURITY_CERT_UNSUPPORTEDCERTIFICATETYPEEXCEPTION_HPP_INCLUDED