diff options
Diffstat (limited to 'vmime-master/src/vmime/security')
55 files changed, 7245 insertions, 0 deletions
| diff --git a/vmime-master/src/vmime/security/authenticator.hpp b/vmime-master/src/vmime/security/authenticator.hpp new file mode 100644 index 0000000..03bca73 --- /dev/null +++ b/vmime-master/src/vmime/security/authenticator.hpp @@ -0,0 +1,136 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_AUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_AUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/types.hpp" + + +// Forward declarations +namespace vmime { +namespace net { + +class service; + +} // net +} // vmime + + +namespace vmime { +namespace security { + + +/** Provides required information for user authentication. The same +  * information can be requested multiple time (eg. in IMAP, there is a +  * new connection started each time a folder is open), so the object is +  * responsible for caching the information to avoid useless interactions +  * with the user. +  * +  * Usually, you should not inherit from this class, but instead from the +  * more convenient defaultAuthenticator class. +  * +  * WARNING: an authenticator should be used with one and ONLY ONE messaging +  * service at a time. +  */ +class VMIME_EXPORT authenticator : public object { + +public: + +	/** Return the authentication identity (usually, this +	  * is the username). +	  * +	  * @return username +	  * @throw exceptions::no_auth_information if the information +	  * could not be provided +	  */ +	virtual const string getUsername() const = 0; + +	/** Return the password of the authentication identity. +	  * +	  * @return password +	  * @throw exceptions::no_auth_information if the information +	  * could not be provided +	  */ +	virtual const string getPassword() const = 0; + +	/** Return the optional access token for authentication. This is +	  * used for example with XOAuth2 SASL authentication. +	  * +	  * @return access token +	  * @throw exceptions::no_auth_information if the information +	  * could not be provided +	  */ +	virtual const string getAccessToken() const = 0; + +	/** Return the local host name of the machine. +	  * +	  * @return hostname +	  * @throw exceptions::no_auth_information if the information +	  * could not be provided +	  */ +	virtual const string getHostname() const = 0; + +	/** Return the anonymous token (usually, this is the user's +	  * email address). +	  * +	  * @return anonymous token +	  * @throw exceptions::no_auth_information if the information +	  * could not be provided +	  */ +	virtual const string getAnonymousToken() const = 0; + +	/** Return the registered service name of the application +	  * service (eg: "imap"). This can be used by GSSAPI or DIGEST-MD5 +	  * mechanisms with SASL. +	  * +	  * @return service name +	  * @throw exceptions::no_auth_information if the information +	  * could not be provided +	  */ +	virtual const string getServiceName() const = 0; + +	/** Called by the messaging service to allow this authenticator to +	  * know which service is currently using it. This is called just +	  * before the service starts the authentication process. +	  * +	  * @param serv messaging service instance +	  */ +	virtual void setService(const shared_ptr <net::service>& serv) = 0; +}; + + +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_SECURITY_AUTHENTICATOR_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/cert/X509Certificate.cpp b/vmime-master/src/vmime/security/cert/X509Certificate.cpp new file mode 100644 index 0000000..128fac1 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/X509Certificate.cpp @@ -0,0 +1,72 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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/X509Certificate.hpp" + +#include "vmime/security/cert/certificateNotYetValidException.hpp" +#include "vmime/security/cert/certificateExpiredException.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +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 + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT diff --git a/vmime-master/src/vmime/security/cert/X509Certificate.hpp b/vmime-master/src/vmime/security/cert/X509Certificate.hpp new file mode 100644 index 0000000..5434b45 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/X509Certificate.hpp @@ -0,0 +1,197 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_X509CERTIFICATE_HPP_INCLUDED +#define VMIME_SECURITY_CERT_X509CERTIFICATE_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#include "vmime/security/cert/certificate.hpp" + +#include "vmime/utility/stream.hpp" + +#include "vmime/base.hpp" +#include "vmime/types.hpp" +#include "vmime/dateTime.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +/** Identity certificate based on X.509 standard. +  */ +class VMIME_EXPORT X509Certificate : public certificate { + +public: + +	~X509Certificate(); + +	/** Supported encodings for X.509 certificates. */ +	enum Format { +		FORMAT_DER,   /**< DER encoding */ +		FORMAT_PEM    /**< PEM encoding */ +	}; + +	/** Supported digest algorithms (used for fingerprint). */ +	enum DigestAlgorithm { +		DIGEST_MD5,   /**< MD5 digest */ +		DIGEST_SHA1   /**< SHA1 digest */ +	}; + + +	/** Imports a DER or PEM encoded X.509 certificate. +	  * +	  * @param is input stream to read data from +	  * @return a X.509 certificate, or NULL if the given data does not +	  * represent a valid certificate +	  */ +	static shared_ptr <X509Certificate> import(utility::inputStream& is); + +	/** Imports a DER or PEM encoded X.509 certificate. +	  * +	  * @param data points to raw data +	  * @param length size of data +	  * @return a X.509 certificate, or NULL if the given data does not +	  * represent a valid certificate +	  */ +	static shared_ptr <X509Certificate> import(const byte_t* data, const size_t length); + +	/** Import sveral DER or PEM encoded X.509 certificates. +	  * +	  * @param is input stream to read data from +	  * @param certs the resulting list of certificates +	  */ +	static void import( +		utility::inputStream& is, +		std::vector <shared_ptr <X509Certificate> >& certs +	); + +	/** Import several DER or PEM encoded X.509 certificates. +	 * +	 * @param data points to raw data +	 * @param length size of data +	 * @param certs the resulting list of certificates +	 */ +	static void import( +		const byte_t* data, +		const size_t length, +		std::vector <shared_ptr <X509Certificate> >& certs +	); + +	/** Exports this X.509 certificate to the specified format. +	  * +	  * @param os output stream into which write data +	  * @param format output format +	  */ +	virtual void write(utility::outputStream& os, const Format format) const = 0; + +	/** Returns the X.509 certificate's serial number. This is obtained +	  * by the X.509 Certificate 'serialNumber' field. Serial is not +	  * always a 32 or 64bit number. Some CAs use large serial numbers, +	  * thus it may be wise to handle it as something opaque. +	  * +	  * @return serial number of this certificate +	  */ +	virtual const byteArray getSerialNumber() const = 0; + +	/** Returns the distinguished name of the issuer of this certificate. +	  * Eg. "C=US,O=VeriSign\, Inc.,OU=Class 1 Public Primary Certification Authority" +	  * +	  * @return distinguished name of the certificate issuer, as a string +	  */ +	virtual const string getIssuerString() const = 0; + +	/** Checks if this certificate has the given issuer. +	  * +	  * @param issuer certificate of a possible issuer +	  * @return true if this certificate was issued by the given issuer, +	  * false otherwise +	  */ +	virtual bool checkIssuer(const shared_ptr <const X509Certificate>& issuer) const = 0; + +	/** Verifies this certificate against a given trusted one. +	  * +	  * @param caCert a certificate that is considered to be trusted one +	  * @return true if the verification succeeded, false otherwise +	  */ +	virtual bool verify(const shared_ptr <const X509Certificate>& caCert) const = 0; + +	/** Verify certificate's subject name against the given hostname. +	  * +	  * @param hostname DNS name of the server +	  * @param nonMatchingNames if not NULL, will contain the names that do +	  * not match the identities in the certificate +	  * @return true if the match is successful, false otherwise +	  */ +	virtual bool verifyHostName( +		const string& hostname, +		std::vector <std::string>* nonMatchingNames = NULL +	) const = 0; + +	/** Gets the expiration date of this certificate. This is the date +	  * at which this certificate will not be valid anymore. +	  * +	  * @return expiration date of this certificate +	  */ +	virtual const datetime getExpirationDate() const = 0; + +	/** Gets the activation date of this certificate. This is the date +	  * at which this certificate will be valid. +	  * +	  * @return activation date of this certificate +	  */ +	virtual const datetime getActivationDate() const = 0; + +	/** Returns the fingerprint of this certificate. +	  * +	  * @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(); +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + +#endif // VMIME_SECURITY_CERT_X509CERTIFICATE_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/cert/certificate.hpp b/vmime-master/src/vmime/security/cert/certificate.hpp new file mode 100644 index 0000000..ed0f175 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificate.hpp @@ -0,0 +1,84 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_CERTIFICATE_HPP_INCLUDED +#define VMIME_SECURITY_CERT_CERTIFICATE_HPP_INCLUDED + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +/** Identity certificate for a peer. +  */ +class VMIME_EXPORT certificate : public object, public enable_shared_from_this <certificate> { + +public: + +	/** Returns the encoded form of this certificate (for example, +	  * X.509 certificates are encoded as ASN.1 DER). +	  * +	  * @return the encoded form of this certificate +	  */ +	virtual const byteArray getEncoded() const = 0; + +	/** Return the type of this certificate. +	  * +	  * @return the type of this certificate +	  */ +	virtual const string getType() const = 0; + +	/** Return the version of this certificate. +	  * +	  * @return the version of this certificate +	  */ +	virtual int getVersion() const = 0; + +	/** Checks if two certificates are the same. +	  * +	  * @param other certificate to compare with +	  * @return true if the two certificates are the same, +	  * false otherwise +	  */ +	virtual bool equals(const shared_ptr <const certificate>& other) const = 0; + +	/** Returns a pointer to internal binary data for this certificate. +	  * The actual type of data depends on the library used for TLS support. +	  * +	  * @return pointer to underlying data +	  */ +	virtual void* getInternalData() = 0; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_SECURITY_CERT_CERTIFICATE_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/cert/certificateChain.cpp b/vmime-master/src/vmime/security/cert/certificateChain.cpp new file mode 100644 index 0000000..c506913 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateChain.cpp @@ -0,0 +1,53 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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/security/cert/certificateChain.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +certificateChain::certificateChain(const std::vector <shared_ptr <certificate> >& certs) +	: m_certs(certs) { + +} + + +size_t certificateChain::getCount() const { + +	return m_certs.size(); +} + + +const shared_ptr <certificate>& certificateChain::getAt(const size_t index) { + +	return m_certs[index]; +} + + +} // cert +} // security +} // vmime + diff --git a/vmime-master/src/vmime/security/cert/certificateChain.hpp b/vmime-master/src/vmime/security/cert/certificateChain.hpp new file mode 100644 index 0000000..f8c363e --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateChain.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_CERTIFICATECHAIN_HPP_INCLUDED +#define VMIME_SECURITY_CERT_CERTIFICATECHAIN_HPP_INCLUDED + + +#include "vmime/types.hpp" + +#include "vmime/security/cert/certificate.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +/** An ordered list of certificates, from the subject certificate to +  * the issuer certificate. +  */ +class VMIME_EXPORT certificateChain : public object { + +public: + +	/** Construct a new certificateChain object given an ordered list +	  * of certificates. +	  * +	  * @param certs chain of certificates +	  */ +	certificateChain(const std::vector <shared_ptr <certificate> >& certs); + +	/** Return the number of certificates in the chain. +	  * +	  * @return number of certificates in the chain +	  */ +	size_t getCount() const; + +	/** Return the certificate at the specified position. 0 is the +	  * subject certificate, 1 is the issuer's certificate, 2 is +	  * the issuer's issuer, etc. +	  * +	  * @param index position at which to retrieve certificate +	  * @return certificate at the specified position +	  */ +	const shared_ptr <certificate>& getAt(const size_t index); + +protected: + +	std::vector <shared_ptr <certificate> > m_certs; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_SECURITY_CERT_CERTIFICATECHAIN_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/cert/certificateException.cpp b/vmime-master/src/vmime/security/cert/certificateException.cpp new file mode 100644 index 0000000..51a4f03 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateException.cpp @@ -0,0 +1,84 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 occurred 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(const shared_ptr <certificate>& cert) { + +	m_cert = cert; +} + + +shared_ptr <certificate> certificateException::getCertificate() { + +	return m_cert; +} + + +shared_ptr <const certificate> certificateException::getCertificate() const { + +	return m_cert; +} + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT diff --git a/vmime-master/src/vmime/security/cert/certificateException.hpp b/vmime-master/src/vmime/security/cert/certificateException.hpp new file mode 100644 index 0000000..9dd5443 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateException.hpp @@ -0,0 +1,95 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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(const shared_ptr <certificate>& cert); + +	/** Returns the certificate on which the problem occured. +	  * +	  * @return certificate +	  */ +	shared_ptr <certificate> getCertificate(); + +	/** Returns the certificate on which the problem occured. +	  * +	  * @return certificate +	  */ +	shared_ptr <const certificate> getCertificate() const; + +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 diff --git a/vmime-master/src/vmime/security/cert/certificateExpiredException.cpp b/vmime-master/src/vmime/security/cert/certificateExpiredException.cpp new file mode 100644 index 0000000..1aa248e --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateExpiredException.cpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateExpiredException.hpp b/vmime-master/src/vmime/security/cert/certificateExpiredException.hpp new file mode 100644 index 0000000..4db0a1e --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateExpiredException.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateIssuerVerificationException.cpp b/vmime-master/src/vmime/security/cert/certificateIssuerVerificationException.cpp new file mode 100644 index 0000000..adf5049 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateIssuerVerificationException.cpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateIssuerVerificationException.hpp b/vmime-master/src/vmime/security/cert/certificateIssuerVerificationException.hpp new file mode 100644 index 0000000..e22bd92 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateIssuerVerificationException.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateNotTrustedException.cpp b/vmime-master/src/vmime/security/cert/certificateNotTrustedException.cpp new file mode 100644 index 0000000..a5ebb99 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateNotTrustedException.cpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateNotTrustedException.hpp b/vmime-master/src/vmime/security/cert/certificateNotTrustedException.hpp new file mode 100644 index 0000000..8cdb2f0 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateNotTrustedException.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateNotYetValidException.cpp b/vmime-master/src/vmime/security/cert/certificateNotYetValidException.cpp new file mode 100644 index 0000000..ed8ca79 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateNotYetValidException.cpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateNotYetValidException.hpp b/vmime-master/src/vmime/security/cert/certificateNotYetValidException.hpp new file mode 100644 index 0000000..8f321eb --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateNotYetValidException.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/certificateVerifier.hpp b/vmime-master/src/vmime/security/cert/certificateVerifier.hpp new file mode 100644 index 0000000..7e2913a --- /dev/null +++ b/vmime-master/src/vmime/security/cert/certificateVerifier.hpp @@ -0,0 +1,76 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_CERTIFICATEVERIFIER_HPP_INCLUDED +#define VMIME_SECURITY_CERT_CERTIFICATEVERIFIER_HPP_INCLUDED + + +#include "vmime/types.hpp" + +#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 { +namespace cert { + + +/** Verify that a certificate path issued by a server can be trusted. +  */ +class VMIME_EXPORT certificateVerifier : public object { + +public: + +	/** Verify that the specified certificate chain is trusted. +	  * +	  * @param chain certificate chain +	  * @param hostname server hostname +	  * @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(const shared_ptr <certificateChain>& chain, const string& hostname) = 0; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_SECURITY_CERT_CERTIFICATEVERIFIER_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/cert/defaultCertificateVerifier.cpp b/vmime-master/src/vmime/security/cert/defaultCertificateVerifier.cpp new file mode 100644 index 0000000..a67052e --- /dev/null +++ b/vmime-master/src/vmime/security/cert/defaultCertificateVerifier.cpp @@ -0,0 +1,191 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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/defaultCertificateVerifier.hpp" + +#include "vmime/security/cert/X509Certificate.hpp" + +#include "vmime/exception.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +defaultCertificateVerifier::defaultCertificateVerifier() { + +} + + +defaultCertificateVerifier::~defaultCertificateVerifier() { + +} + + +defaultCertificateVerifier::defaultCertificateVerifier(const defaultCertificateVerifier&) +	: certificateVerifier() { + +	// Not used +} + + +void defaultCertificateVerifier::verify( +	const shared_ptr <certificateChain>& chain, +	const string& hostname +) { + +	if (chain->getCount() == 0) { +		return; +	} + +	const string type = chain->getAt(0)->getType(); + +	if (type == "X.509") { +		verifyX509(chain, hostname); +	} else { +		throw unsupportedCertificateTypeException(type); +	} +} + + +void defaultCertificateVerifier::verifyX509( +	const shared_ptr <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 +	if (chain->getCount() >= 2) { + +		for (size_t i = 0 ; i < chain->getCount() - 1 ; ++i) { + +			shared_ptr <X509Certificate> cert = +				dynamicCast <X509Certificate>(chain->getAt(i)); + +			shared_ptr <X509Certificate> next = +				dynamicCast <X509Certificate>(chain->getAt(i + 1)); + +			if (!cert->checkIssuer(next)) { + +				certificateIssuerVerificationException ex; +				ex.setCertificate(cert); + +				throw ex; +			} +		} +	} + +	// For every certificate in the chain, verify that the certificate +	// is valid at the current time +	for (size_t i = 0 ; i < chain->getCount() ; ++i) { + +		shared_ptr <X509Certificate> cert = +			dynamicCast <X509Certificate>(chain->getAt(i)); + +		cert->checkValidity(); +	} + +	// Check whether the certificate can be trusted + +	// -- First, verify that the the last certificate in the chain was +	// -- issued by a third-party that we trust +	shared_ptr <X509Certificate> lastCert = +		dynamicCast <X509Certificate>(chain->getAt(chain->getCount() - 1)); + +	bool trusted = false; + +	for (size_t i = 0 ; !trusted && i < m_x509RootCAs.size() ; ++i) { + +		shared_ptr <X509Certificate> rootCa = m_x509RootCAs[i]; + +		//		printf("rootCAs size is %d, i is %d\n", m_x509RootCAs.size(), i); +		//		printf("will cal verify with %p\n", rootCa.get()); +		if (lastCert->verify(rootCa)) { +			trusted = true; +		} +		//		printf("called verify");		 +	} + +	// -- Next, if the issuer certificate cannot be verified against +	// -- root CAs, compare the subject's certificate against the +	// -- trusted certificates +	shared_ptr <X509Certificate> firstCert = +		dynamicCast <X509Certificate>(chain->getAt(0)); + +	for (size_t i = 0 ; !trusted && i < m_x509TrustedCerts.size() ; ++i) { + +		shared_ptr <X509Certificate> cert = m_x509TrustedCerts[i]; + +		if (firstCert->equals(cert)) { +			trusted = true; +		} +	} + +	if (!trusted) { + +		certificateNotTrustedException ex; +		ex.setCertificate(firstCert); + +		throw ex; +	} + +	// Ensure the first certificate's subject name matches server hostname +	if (!firstCert->verifyHostName(hostname)) { + +		serverIdentityException ex; +		ex.setCertificate(firstCert); + +		throw ex; +	} +} + + +void defaultCertificateVerifier::setX509RootCAs( +	const std::vector <shared_ptr <X509Certificate> >& caCerts +) { + +	m_x509RootCAs = caCerts; +} + + +void defaultCertificateVerifier::setX509TrustedCerts( +	const std::vector <shared_ptr <X509Certificate> >& trustedCerts +) { + +	m_x509TrustedCerts = trustedCerts; +} + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT diff --git a/vmime-master/src/vmime/security/cert/defaultCertificateVerifier.hpp b/vmime-master/src/vmime/security/cert/defaultCertificateVerifier.hpp new file mode 100644 index 0000000..4aa4445 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/defaultCertificateVerifier.hpp @@ -0,0 +1,98 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED +#define VMIME_SECURITY_CERT_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#include "vmime/security/cert/certificateVerifier.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +class X509Certificate; + + +/** Default implementation for certificate verification. +  */ +class VMIME_EXPORT defaultCertificateVerifier : public certificateVerifier { + +private: + +	defaultCertificateVerifier(const defaultCertificateVerifier&); + +public: + +	defaultCertificateVerifier(); +	~defaultCertificateVerifier(); + +	/** Sets a list of X.509 certificates that are trusted. +	  * +	  * @param trustedCerts list of trusted certificates +	  */ +	void setX509TrustedCerts(const std::vector <shared_ptr <X509Certificate> >& trustedCerts); + +	/** Sets the X.509 root CAs used for certificate verification. +	  * +	  * @param caCerts list of root CAs +	  */ +	void setX509RootCAs(const std::vector <shared_ptr <X509Certificate> >& caCerts); + + +	// Implementation of 'certificateVerifier' +	void verify(const shared_ptr <certificateChain>& chain, const string& hostname); + +private: + +	/** Verify a chain of X.509 certificates. +	  * +	  * @param chain list of X.509 certificates +	  * @param hostname server hostname +	  */ +	void verifyX509(const shared_ptr <certificateChain>& chain, const string& hostname); + + +	std::vector <shared_ptr <X509Certificate> > m_x509RootCAs; +	std::vector <shared_ptr <X509Certificate> > m_x509TrustedCerts; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT + + +#endif // VMIME_SECURITY_CERT_DEFAULTCERTIFICATEVERIFIER_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/vmime-master/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp new file mode 100644 index 0000000..3dfa1c6 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp @@ -0,0 +1,395 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + + +#include <gnutls/gnutls.h> +#include <gnutls/x509.h> + +#include <ctime> + +#include "vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp" + +#include "vmime/utility/outputStreamByteArrayAdapter.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +#ifndef VMIME_BUILDING_DOC + +struct GnuTLSX509CertificateInternalData { + +	GnuTLSX509CertificateInternalData() { + +		gnutls_x509_crt_init(&cert); +	} + +	~GnuTLSX509CertificateInternalData() { + +		gnutls_x509_crt_deinit(cert); +	} + +	void swap(gnutls_x509_crt_t to) { +		gnutls_x509_crt_deinit(cert); +		cert = to; +	} + + +	gnutls_x509_crt_t cert; +}; + +#endif // VMIME_BUILDING_DOC + + +X509Certificate_GnuTLS::X509Certificate_GnuTLS() +	: m_data(new GnuTLSX509CertificateInternalData) { + +} + + +X509Certificate_GnuTLS::X509Certificate_GnuTLS(const X509Certificate&) +	: X509Certificate(), m_data(NULL) { + +	// Not used +} + + +X509Certificate_GnuTLS::~X509Certificate_GnuTLS() { + +	delete m_data; +} + + +void* X509Certificate_GnuTLS::getInternalData() { + +	return &m_data->cert; +} + + +// static +shared_ptr <X509Certificate> X509Certificate::import( +	utility::inputStream& is +) { + +	byteArray bytes; +	byte_t chunk[4096]; + +	while (!is.eof()) { +		const size_t len = is.read(chunk, sizeof(chunk)); +		bytes.insert(bytes.end(), chunk, chunk + len); +	} + +	return import(&bytes[0], bytes.size()); +} + + +// static +shared_ptr <X509Certificate> X509Certificate::import( +	const byte_t* data, +	const size_t length +) { + +	gnutls_datum_t buffer; +	buffer.data = const_cast <byte_t*>(data); +	buffer.size = static_cast <unsigned int>(length); + +	// Try DER format +	shared_ptr <X509Certificate_GnuTLS> derCert = make_shared <X509Certificate_GnuTLS>(); + +	if (gnutls_x509_crt_import(derCert->m_data->cert, &buffer, GNUTLS_X509_FMT_DER) >= 0) { +		return derCert; +	} + +	// Try PEM format +	shared_ptr <X509Certificate_GnuTLS> pemCert = make_shared <X509Certificate_GnuTLS>(); + +	if (gnutls_x509_crt_import(pemCert->m_data->cert, &buffer, GNUTLS_X509_FMT_PEM) >= 0) { +		return pemCert; +	} + +	return null; +} + + +// static +void X509Certificate::import( +	utility::inputStream& is, +	std::vector <shared_ptr <X509Certificate> >& certs +) { + +	byteArray bytes; +	byte_t chunk[4096]; + +	while (!is.eof()) { +		const size_t len = is.read(chunk, sizeof(chunk)); +		bytes.insert(bytes.end(), chunk, chunk + len); +	} + +	import(&bytes[0], bytes.size(), certs); +} + + +// static +void X509Certificate::import( +	const byte_t* data, +	const size_t length, +	std::vector <shared_ptr <X509Certificate> >& certs +) { + +	gnutls_datum_t buffer; +	buffer.data = const_cast <byte_t*>(data); +	buffer.size = static_cast <unsigned int>(length); + +	unsigned int size = 1024; +	gnutls_x509_crt_t x509[1024]; + +	// Try DER format +	if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_DER, 0) < 0) { + +		// Try PEM format +		if (gnutls_x509_crt_list_import(x509, &size, &buffer, GNUTLS_X509_FMT_PEM, 0) < 0) { +			return; +		} +	} + +	for (unsigned int i = 0 ; i < size ; i += 1) { + +		auto c = make_shared <X509Certificate_GnuTLS>(); +		c->m_data->swap(x509[i]); +		certs.push_back(c); +	} +} + + +void X509Certificate_GnuTLS::write( +	utility::outputStream& os, +	const Format format +) const { + +	size_t dataSize = 0; +	gnutls_x509_crt_fmt_t fmt = GNUTLS_X509_FMT_DER; + +	switch (format) { +		case FORMAT_DER: fmt = GNUTLS_X509_FMT_DER; break; +		case FORMAT_PEM: fmt = GNUTLS_X509_FMT_PEM; break; +	} + +	gnutls_x509_crt_export(m_data->cert, fmt, NULL, &dataSize); + +	std::vector <byte_t> data(dataSize); + +	gnutls_x509_crt_export(m_data->cert, fmt, &data[0], &dataSize); + +	os.write(reinterpret_cast <byte_t*>(&data[0]), dataSize); +} + + +const byteArray X509Certificate_GnuTLS::getSerialNumber() const { + +	char serial[64]; +	size_t serialSize = sizeof(serial); + +	gnutls_x509_crt_get_serial(m_data->cert, serial, &serialSize); + +	return byteArray(serial, serial + serialSize); +} + + +bool X509Certificate_GnuTLS::checkIssuer(const shared_ptr <const X509Certificate>& issuer_) const { + +	shared_ptr <const X509Certificate_GnuTLS> issuer = +		dynamicCast <const X509Certificate_GnuTLS>(issuer_); + +	return gnutls_x509_crt_check_issuer(m_data->cert, issuer->m_data->cert) >= 1; +} + + +bool X509Certificate_GnuTLS::verify(const shared_ptr <const X509Certificate>& caCert_) const { + +	shared_ptr <const X509Certificate_GnuTLS> caCert = +		dynamicCast <const X509Certificate_GnuTLS>(caCert_); + +	unsigned int verify = 0; + +	const int res = gnutls_x509_crt_verify( +		m_data->cert, &(caCert->m_data->cert), 1, +		GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT, +		&verify +	); + +	return res == 0 && verify == 0; +} + + +bool X509Certificate_GnuTLS::verifyHostName( +	const string& hostname, +	std::vector <std::string>* nonMatchingNames +) const { + +	if (gnutls_x509_crt_check_hostname(m_data->cert, hostname.c_str()) != 0) { +		return true; +	} + +	if (nonMatchingNames) { + +		const int MAX_CN = 256; +		const char* OID_X520_COMMON_NAME = "2.5.4.3"; + +		char dnsName[MAX_CN]; +		size_t dnsNameLength; + +		dnsNameLength = sizeof(dnsName); + +		if (gnutls_x509_crt_get_dn_by_oid(m_data->cert, OID_X520_COMMON_NAME, 0, 0, dnsName, &dnsNameLength) >= 0) { +			nonMatchingNames->push_back(dnsName); +		} + +		for (int i = 0, ret = 0 ; ret >= 0 ; ++i) { + +			dnsNameLength = sizeof(dnsName); +			ret = gnutls_x509_crt_get_subject_alt_name(m_data->cert, i, dnsName, &dnsNameLength, NULL); + +			if (ret == GNUTLS_SAN_DNSNAME) { +				nonMatchingNames->push_back(dnsName); +			} +		} +	} + +	return false; +} + + +const datetime X509Certificate_GnuTLS::getActivationDate() const { + +	const time_t t = gnutls_x509_crt_get_activation_time(m_data->cert); +	return datetime(t); +} + + +const datetime X509Certificate_GnuTLS::getExpirationDate() const { + +	const time_t t = gnutls_x509_crt_get_expiration_time(m_data->cert); +	return datetime(t); +} + + +const byteArray X509Certificate_GnuTLS::getFingerprint(const DigestAlgorithm algo) const { + +	gnutls_digest_algorithm_t galgo; + +	switch (algo) { + +		case DIGEST_MD5: + +			galgo = GNUTLS_DIG_MD5; +			break; + +		default: +		case DIGEST_SHA1: + +			galgo = GNUTLS_DIG_SHA; +			break; +	} + +	size_t bufferSize = 0; +	gnutls_x509_crt_get_fingerprint(m_data->cert, galgo, NULL, &bufferSize); + +	std::vector <byte_t> buffer(bufferSize); + +	if (gnutls_x509_crt_get_fingerprint(m_data->cert, galgo, &buffer[0], &bufferSize) == 0) { + +		byteArray res; +		res.insert(res.end(), &buffer[0], &buffer[0] + bufferSize); + +		return res; +	} + +	return byteArray(); +} + + +const byteArray X509Certificate_GnuTLS::getEncoded() const { + +	byteArray bytes; +	utility::outputStreamByteArrayAdapter os(bytes); + +	write(os, FORMAT_DER); + +	return bytes; +} + + +const string X509Certificate_GnuTLS::getIssuerString() const { + +	char buffer[4096]; +	size_t bufferSize = sizeof(buffer); + +	if (gnutls_x509_crt_get_issuer_dn(m_data->cert, buffer, &bufferSize) != GNUTLS_E_SUCCESS) { +		return ""; +	} + +	return buffer; +} + + +const string X509Certificate_GnuTLS::getType() const { + +	return "X.509"; +} + + +int X509Certificate_GnuTLS::getVersion() const { + +	return gnutls_x509_crt_get_version(m_data->cert); +} + + +bool X509Certificate_GnuTLS::equals(const shared_ptr <const certificate>& other) const { + +	shared_ptr <const X509Certificate_GnuTLS> otherX509 = +		dynamicCast <const X509Certificate_GnuTLS>(other); + +	if (!otherX509) { +		return false; +	} + +	const byteArray fp1 = getFingerprint(DIGEST_MD5); +	const byteArray fp2 = otherX509->getFingerprint(DIGEST_MD5); + +	return fp1 == fp2; +} + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS diff --git a/vmime-master/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp b/vmime-master/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp new file mode 100644 index 0000000..c7c6c48 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp @@ -0,0 +1,96 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_X509CERTIFICATE_GNUTLS_HPP_INCLUDED +#define VMIME_SECURITY_CERT_X509CERTIFICATE_GNUTLS_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + + +#include "vmime/security/cert/X509Certificate.hpp" + + +namespace vmime { +namespace security { +namespace cert { + + +class X509Certificate_GnuTLS : public X509Certificate { + +	friend class X509Certificate; + +	X509Certificate_GnuTLS(const X509Certificate&); + +public: + +	X509Certificate_GnuTLS(); + +	~X509Certificate_GnuTLS(); + + +	void write(utility::outputStream& os, const Format format) const; + +	const byteArray getSerialNumber() const; + +	const string getIssuerString() const; +	bool checkIssuer(const shared_ptr <const X509Certificate>& issuer) const; + +	bool verify(const shared_ptr <const X509Certificate>& caCert) const; + +	bool verifyHostName( +		const string& hostname, +		std::vector <std::string>* nonMatchingNames = NULL +	) const; + +	const datetime getExpirationDate() const; +	const datetime getActivationDate() const; + +	const byteArray getFingerprint(const DigestAlgorithm algo) const; + + +	// Implementation of 'certificate' +	const byteArray getEncoded() const; +	const string getType() const; +	int getVersion() const; +	bool equals(const shared_ptr <const certificate>& other) const; +	void* getInternalData(); + +private: + +	struct GnuTLSX509CertificateInternalData* m_data; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS + +#endif // VMIME_SECURITY_CERT_X509CERTIFICATE_GNUTLS_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp b/vmime-master/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp new file mode 100644 index 0000000..5488801 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp @@ -0,0 +1,655 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + + +#include <cstdio> +#include <ctime> +#include <map> +#include <algorithm> + +#include "vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp" + +#include "vmime/net/tls/openssl/OpenSSLInitializer.hpp" + +#include "vmime/utility/outputStreamByteArrayAdapter.hpp" + +#include "vmime/security/cert/certificateException.hpp" +#include "vmime/security/cert/unsupportedCertificateTypeException.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> + + +#ifdef _WIN32 +#	define strcasecmp _stricmp +#	define strncasecmp _strnicmp +#endif + + +namespace vmime { +namespace security { +namespace cert { + + +static net::tls::OpenSSLInitializer::autoInitializer openSSLInitializer; + + +#ifndef VMIME_BUILDING_DOC + +class monthMap { + +public: + +	monthMap() { + +		m_monthMap["jan"] = vmime::datetime::JAN; +		m_monthMap["feb"] = vmime::datetime::FEB; +		m_monthMap["mar"] = vmime::datetime::MAR; +		m_monthMap["apr"] = vmime::datetime::APR; +		m_monthMap["may"] = vmime::datetime::MAY; +		m_monthMap["jun"] = vmime::datetime::JUN; +		m_monthMap["jul"] = vmime::datetime::JUL; +		m_monthMap["aug"] = vmime::datetime::AUG; +		m_monthMap["sep"] = vmime::datetime::SEP; +		m_monthMap["oct"] = vmime::datetime::OCT; +		m_monthMap["nov"] = vmime::datetime::NOV; +		m_monthMap["dec"] = vmime::datetime::DEC; +	} + +	int getMonth(vmime::string mstr) { + +		std::transform(mstr.begin(), mstr.end(), mstr.begin(), ::tolower); + +		std::map <vmime::string, vmime::datetime::Months>::const_iterator +			c_it = m_monthMap.find(mstr); + +		if (c_it != m_monthMap.end()) { +			return c_it->second; +		} + +		return -1; +	} + +private: + +	std::map<vmime::string, vmime::datetime::Months> m_monthMap; +}; + +static monthMap sg_monthMap; + + + +struct OpenSSLX509CertificateInternalData { + +	OpenSSLX509CertificateInternalData() { + +		cert = 0; +	} + +	~OpenSSLX509CertificateInternalData() { + +		if (cert) { +			X509_free(cert); +		} +	} + +	X509* cert; +}; + + +// Workaround for i2v() taking either a const or a non-const 'method' on some platforms +STACK_OF(CONF_VALUE)* call_i2v(const X509V3_EXT_METHOD* m, void* p1, STACK_OF(CONF_VALUE)* p2) { + +	return m->i2v(m, p1, p2); +} + + +STACK_OF(CONF_VALUE)* call_i2v(X509V3_EXT_METHOD* m, void* p1, STACK_OF(CONF_VALUE)* p2) { + +	return m->i2v(m, p1, p2); +} + + +#endif // VMIME_BUILDING_DOC + + +X509Certificate_OpenSSL::X509Certificate_OpenSSL() +	: m_data(new OpenSSLX509CertificateInternalData) { + +} + + +X509Certificate_OpenSSL::X509Certificate_OpenSSL(X509* cert) +	: m_data(new OpenSSLX509CertificateInternalData) { + +	m_data->cert = X509_dup(cert); +} + + +X509Certificate_OpenSSL::X509Certificate_OpenSSL(const X509Certificate_OpenSSL&) +	: X509Certificate(), m_data(NULL) { + +	// Not used +} + + +X509Certificate_OpenSSL::~X509Certificate_OpenSSL() { + +	delete m_data; +} + + +void* X509Certificate_OpenSSL::getInternalData() { + +	return &m_data->cert; +} + + +// static +shared_ptr <X509Certificate> X509Certificate_OpenSSL::importInternal(X509* cert) { + +	if (cert) { +		return make_shared <X509Certificate_OpenSSL>(reinterpret_cast <X509 *>(cert)); +	} + +	return null; +} + + +// static +shared_ptr <X509Certificate> X509Certificate::import(utility::inputStream& is) { + +	byteArray bytes; +	byte_t chunk[4096]; + +	while (!is.eof()) { +		const size_t len = is.read(chunk, sizeof(chunk)); +		bytes.insert(bytes.end(), chunk, chunk + len); +	} + +	return import(&bytes[0], bytes.size()); +} + + +// static +shared_ptr <X509Certificate> X509Certificate::import( +	const byte_t* data, +	const size_t length +) { + +	shared_ptr <X509Certificate_OpenSSL> cert = make_shared <X509Certificate_OpenSSL>(); + +	BIO* membio = BIO_new_mem_buf(const_cast <byte_t*>(data), static_cast <int>(length)); + +	if (!(cert->m_data->cert = d2i_X509_bio(membio, NULL)) +	    /*!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)*/) { +		BIO_vfree(membio); +		return null; +	} + +	BIO_vfree(membio); + +	return cert; +} + + +// static +void X509Certificate::import( +	utility::inputStream& is, +	std::vector <shared_ptr <X509Certificate> >& certs +) { + +	byteArray bytes; +	byte_t chunk[4096]; + +	while (!is.eof()) { +		const size_t len = is.read(chunk, sizeof(chunk)); +		bytes.insert(bytes.end(), chunk, chunk + len); +	} + +	import(&bytes[0], bytes.size(), certs); +} + + +// static +void X509Certificate::import( +	const byte_t* data, +	const size_t length, +	std::vector <shared_ptr <X509Certificate> >& certs +) { + +	BIO* membio = BIO_new_mem_buf(const_cast <byte_t*>(data), static_cast <int>(length)); +	shared_ptr <X509Certificate_OpenSSL> cert = null; + +	while (true) { + +		cert = make_shared <X509Certificate_OpenSSL>(); + +		if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0)) { +			break; +		} + +		certs.push_back(cert); +	} + +	BIO_vfree(membio); +} + + +void X509Certificate_OpenSSL::write( +	utility::outputStream& os, +	const Format format +) const { + +	BIO* membio = 0; +	long dataSize = 0; +	unsigned char* out = 0; + +	if (format == FORMAT_DER) { + +		if ((dataSize = i2d_X509(m_data->cert, &out)) < 0) { +			goto err; +		} + +		os.write(reinterpret_cast <byte_t*>(out), dataSize); +		os.flush(); +		OPENSSL_free(out); + +	} else if (format == FORMAT_PEM) { + +		membio = BIO_new(BIO_s_mem()); +		BIO_set_close(membio, BIO_CLOSE); + +		if (!PEM_write_bio_X509(membio, m_data->cert)) { +			goto pem_err; +		} + +		dataSize = BIO_get_mem_data(membio, &out); +		os.write(reinterpret_cast <byte_t*>(out), dataSize); +		os.flush(); +		BIO_vfree(membio); + +	} else { + +		throw unsupportedCertificateTypeException("Unknown format"); +	} + +	return; // #### Early Return #### + +pem_err: +	{ +		if (membio) { +			BIO_vfree(membio); +		} +	} + +err: +	{ +		char errstr[256]; +		long ec = ERR_get_error(); +		ERR_error_string(ec, errstr); +		throw certificateException("OpenSSLX509Certificate_OpenSSL::write exception - " + string(errstr)); +	} +} + + +const byteArray X509Certificate_OpenSSL::getSerialNumber() const { + +	ASN1_INTEGER *serial = X509_get_serialNumber(m_data->cert); +	BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL); +	int n = BN_num_bytes(bnser); +	byte_t* outbuf = new byte_t[n]; +	BN_bn2bin(bnser, outbuf); +	byteArray ser(outbuf, outbuf + n); +	delete [] outbuf; +	BN_free(bnser); +	return ser; +} + + +bool X509Certificate_OpenSSL::checkIssuer(const shared_ptr <const X509Certificate>& cert_) const { + +	shared_ptr <const X509Certificate_OpenSSL> cert = +		dynamicCast <const X509Certificate_OpenSSL>(cert_); + +	// Get issuer for this cert +	BIO *out; +	unsigned char *issuer; + +	out = BIO_new(BIO_s_mem()); +	X509_NAME_print_ex(out, X509_get_issuer_name(m_data->cert), 0, XN_FLAG_RFC2253); +	long n = BIO_get_mem_data(out, &issuer); +	vmime::string thisIssuerName((char*)issuer, n); +	BIO_free(out); + +	// Get subject of issuer +	unsigned char *subject; +	out = BIO_new(BIO_s_mem()); +	X509_NAME_print_ex(out, X509_get_subject_name(cert->m_data->cert), 0, XN_FLAG_RFC2253); +	n = BIO_get_mem_data(out, &subject); +	vmime::string subjOfIssuer((char*)subject, n); +	BIO_free(out); + +	return subjOfIssuer == thisIssuerName; +} + + +bool X509Certificate_OpenSSL::verify(const shared_ptr <const X509Certificate>& caCert_) const { + +	shared_ptr <const X509Certificate_OpenSSL> caCert = +		dynamicCast <const X509Certificate_OpenSSL>(caCert_); + +//	printf("ptr before cast is %p\n", caCert_.get()); +//	printf("ptr is %p\n", caCert.get()); + +	bool verified = false; +	bool error = true; + +	X509_STORE *store = X509_STORE_new(); + +	if (store) { + +		X509_STORE_CTX *verifyCtx = X509_STORE_CTX_new(); + +		if (verifyCtx) { + +			if (X509_STORE_add_cert(store, caCert->m_data->cert)) { + +				X509_STORE_CTX_init(verifyCtx, store, m_data->cert, NULL); + +				int ret = X509_verify_cert(verifyCtx); + +				if (ret == 1) { + +					verified = true; +					error = false; + +				} else if (ret == 0) { + +					verified = false; +					error = false; +				} + +				//X509_verify_cert_error_string(vrfy_ctx->error) + +				X509_STORE_CTX_free(verifyCtx); +			} +		} + +		X509_STORE_free(store); +	} + +	return verified && !error; +} + + +// static +bool X509Certificate_OpenSSL::cnMatch(const char* cnBuf, const char* host) { + +	// Right-to-left match, looking for a '*' wildcard +	const bool hasWildcard = (strlen(cnBuf) > 1 && cnBuf[0] == '*' && cnBuf[1] == '.'); +	const char* cnBufReverseEndPtr = (cnBuf + (hasWildcard ? 2 : 0)); +	const char* hostPtr = host + strlen(host); +	const char* cnPtr = cnBuf + strlen(cnBuf); + +	bool matches = true; + +	while (matches && --hostPtr >= host && --cnPtr >= cnBufReverseEndPtr) { +		matches = (toupper(*hostPtr) == toupper(*cnPtr)); +	} + +	return matches; +} + + +bool X509Certificate_OpenSSL::verifyHostName( +	const string& hostname, +	std::vector <std::string>* nonMatchingNames +) 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 (cnMatch(CNBuffer, hostname.c_str())) { +			return true; +		} + +		if (nonMatchingNames) { +			nonMatchingNames->push_back(CNBuffer); +		} +	} + +	// Now, look in subject alternative names +	bool verify = false; + +	STACK_OF(GENERAL_NAME)* altNames = static_cast <GENERAL_NAMES*> +		(X509_get_ext_d2i(m_data->cert, NID_subject_alt_name, NULL, NULL)); + +	if (altNames == NULL) { +		return false; +	} + +	// Check each name within the extension +	for (int i = 0, n = sk_GENERAL_NAME_num(altNames) ; i < n ; ++i) { + +		const GENERAL_NAME* currentName = sk_GENERAL_NAME_value(altNames, i); + +		if (currentName->type == GEN_DNS) { + +			// Current name is a DNS name, let's check it +			char *DNSName = (char *) ASN1_STRING_data(currentName->d.dNSName); + +			// Make sure there isn't an embedded NUL character in the DNS name +			if (ASN1_STRING_length(currentName->d.dNSName) != strlen(DNSName)) { +				// Malformed certificate +				break; +			} + +			if (cnMatch(DNSName, hostname.c_str())) { +				verify = true; +				break; +			} + +			if (nonMatchingNames) { +				nonMatchingNames->push_back(DNSName); +			} +		} +	} + +	sk_GENERAL_NAME_pop_free(altNames, GENERAL_NAME_free); + +	return verify; +} + + +const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const { + +	char* buffer; +	BIO* out = BIO_new(BIO_s_mem()); +	BIO_set_close(out, BIO_CLOSE); + +	ASN1_TIME* asn1_time = reinterpret_cast<ASN1_TIME*>(time); +	ASN1_TIME_print(out, asn1_time); + +	const long sz = BIO_get_mem_data(out, &buffer); +	char* dest = new char[sz + 1]; +	dest[sz] = 0; +	memcpy(dest, buffer, sz); +	vmime::string t(dest); + +	BIO_free(out); +	delete [] dest; + +	if (t.size() > 0) { + +		char month[4] = {0}; +		char zone[4] = {0}; +		int day, hour, minute, second, year; +		int nrconv = sscanf(t.c_str(), "%s %2d %02d:%02d:%02d %d%s", month, &day, &hour, &minute, &second,&year,zone); + +		if (nrconv >= 6) { +			return datetime(year, sg_monthMap.getMonth(vmime::string(month)), day, hour, minute, second); +		} +	} + +	// let datetime try and parse it +	return datetime(t); +} + + +const datetime X509Certificate_OpenSSL::getActivationDate() const { + +	return convertX509Date(X509_get_notBefore(m_data->cert)); +} + + +const datetime X509Certificate_OpenSSL::getExpirationDate() const { + +	return convertX509Date(X509_get_notAfter(m_data->cert)); +} + + +const byteArray X509Certificate_OpenSSL::getFingerprint(const DigestAlgorithm algo) const { + +	BIO *out; +	int j; +	unsigned int n; +	const EVP_MD *digest; +	unsigned char * fingerprint; +	unsigned char md[EVP_MAX_MD_SIZE]; + +	switch (algo) { + +		case DIGEST_MD5: + +			digest = EVP_md5(); +			break; + +		default: +		case DIGEST_SHA1: + +			digest = EVP_sha1(); +			break; +	} + +	out = BIO_new(BIO_s_mem()); +	BIO_set_close(out, BIO_CLOSE); + +	if (X509_digest(m_data->cert, digest, md, &n)) { + +		for (j = 0 ; j < (int) n ; j++) { +			BIO_printf(out, "%02X", md[j]); +			if (j + 1 != (int) n) BIO_printf(out, ":"); +		} +	} + +	const long resultLen = BIO_get_mem_data(out, &fingerprint); +	unsigned char* result = new unsigned char[resultLen]; +	memcpy(result, fingerprint, resultLen); +	BIO_free(out); + +	byteArray res; +	res.insert(res.end(), &result[0], &result[0] + resultLen); + +	delete [] result; + +	return res; +} + + +const byteArray X509Certificate_OpenSSL::getEncoded() const { + +	byteArray bytes; +	utility::outputStreamByteArrayAdapter os(bytes); + +	write(os, FORMAT_DER); + +	return bytes; +} + + +const string X509Certificate_OpenSSL::getIssuerString() const { + +	// Get issuer for this cert +	BIO* out = BIO_new(BIO_s_mem()); +	X509_NAME_print_ex(out, X509_get_issuer_name(m_data->cert), 0, XN_FLAG_RFC2253); + +	unsigned char* issuer; +	const long n = BIO_get_mem_data(out, &issuer); + +	vmime::string name(reinterpret_cast <char*>(issuer), n); +	BIO_free(out); + +	return name; +} + + +const string X509Certificate_OpenSSL::getType() const { + +	return "X.509"; +} + + +int X509Certificate_OpenSSL::getVersion() const { + +	return (int) X509_get_version(m_data->cert); +} + + +bool X509Certificate_OpenSSL::equals(const shared_ptr <const certificate>& other) const { + +	shared_ptr <const X509Certificate_OpenSSL> otherX509 = +		dynamicCast <const X509Certificate_OpenSSL>(other); + +	if (!otherX509) { +		return false; +	} + +	const byteArray fp1 = getFingerprint(DIGEST_MD5); +	const byteArray fp2 = otherX509->getFingerprint(DIGEST_MD5); + +	return fp1 == fp2; +} + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + diff --git a/vmime-master/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp b/vmime-master/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp new file mode 100644 index 0000000..c0ebf3c --- /dev/null +++ b/vmime-master/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp @@ -0,0 +1,119 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_X509CERTIFICATE_OPENSSL_HPP_INCLUDED +#define VMIME_SECURITY_CERT_X509CERTIFICATE_OPENSSL_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + + +#include "vmime/security/cert/X509Certificate.hpp" + +#include <openssl/x509.h> + + +namespace vmime { +namespace security { +namespace cert { + + +class X509Certificate_OpenSSL : public X509Certificate { + +	friend class X509Certificate; + +	X509Certificate_OpenSSL(const X509Certificate_OpenSSL&); + +public: + +	X509Certificate_OpenSSL(); +	X509Certificate_OpenSSL(X509* cert); + +	~X509Certificate_OpenSSL(); + + +	void write(utility::outputStream& os, const Format format) const; + +	const byteArray getSerialNumber() const; + +	const string getIssuerString() const; +	bool checkIssuer(const shared_ptr <const X509Certificate>& issuer) const; + +	bool verify(const shared_ptr <const X509Certificate>& caCert) const; + +	bool verifyHostName( +		const string& hostname, +		std::vector <std::string>* nonMatchingNames = NULL +	) const; + +	const datetime getExpirationDate() const; +	const datetime getActivationDate() const; + +	const byteArray getFingerprint(const DigestAlgorithm algo) const; + + +	static shared_ptr <X509Certificate> importInternal(X509* cert); + + +	// Implementation of 'certificate' +	const byteArray getEncoded() const; +	const string getType() const; +	int getVersion() const; +	bool equals(const shared_ptr <const certificate>& other) const; +	void* getInternalData(); + +private: + +	/** Internal utility function to test whether a hostname matches +	  * the specified X509 Common Name (wildcard is supported). +	  * +	  * @param cnBuf pointer to buffer holding Common Name +	  * @param host pointer to buffer holding host name +	  * @return true if the hostname matches the Common Name, or +	  * false otherwise +	  */ +	static bool cnMatch(const char* cnBuf, const char* host); + +	/** Internal utility function to convert ASN1_TIME +	 *  structs to vmime::datetime +	 * +	 *  @param pointer to ASN1_TIME struct to convert +	 */ +	const datetime convertX509Date(void* time) const; + +	struct OpenSSLX509CertificateInternalData* m_data; +}; + + +} // cert +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL + +#endif // VMIME_SECURITY_CERT_X509CERTIFICATE_OPENSSL_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/cert/serverIdentityException.cpp b/vmime-master/src/vmime/security/cert/serverIdentityException.cpp new file mode 100644 index 0000000..fcbe571 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/serverIdentityException.cpp @@ -0,0 +1,55 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/serverIdentityException.hpp b/vmime-master/src/vmime/security/cert/serverIdentityException.hpp new file mode 100644 index 0000000..358553e --- /dev/null +++ b/vmime-master/src/vmime/security/cert/serverIdentityException.hpp @@ -0,0 +1,65 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/unsupportedCertificateTypeException.cpp b/vmime-master/src/vmime/security/cert/unsupportedCertificateTypeException.cpp new file mode 100644 index 0000000..5765651 --- /dev/null +++ b/vmime-master/src/vmime/security/cert/unsupportedCertificateTypeException.cpp @@ -0,0 +1,61 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/cert/unsupportedCertificateTypeException.hpp b/vmime-master/src/vmime/security/cert/unsupportedCertificateTypeException.hpp new file mode 100644 index 0000000..725035f --- /dev/null +++ b/vmime-master/src/vmime/security/cert/unsupportedCertificateTypeException.hpp @@ -0,0 +1,72 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 diff --git a/vmime-master/src/vmime/security/defaultAuthenticator.cpp b/vmime-master/src/vmime/security/defaultAuthenticator.cpp new file mode 100644 index 0000000..86c29d3 --- /dev/null +++ b/vmime-master/src/vmime/security/defaultAuthenticator.cpp @@ -0,0 +1,130 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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 + +#include "vmime/security/defaultAuthenticator.hpp" + +#include "vmime/net/service.hpp" + +#include "vmime/platform.hpp" + + +namespace vmime { +namespace security { + + +defaultAuthenticator::defaultAuthenticator() { + +} + + +defaultAuthenticator::~defaultAuthenticator() { + +} + + +const string defaultAuthenticator::getUsername() const { + +	shared_ptr <const net::service> service = m_service.lock(); + +	const string prefix = service->getInfos().getPropertyPrefix(); +	const propertySet& props = service->getSession()->getProperties(); + +	if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_USERNAME.getName())) { +		return props[prefix + net::serviceInfos::property::AUTH_USERNAME.getName()]; +	} + +	throw exceptions::no_auth_information(); +} + + +const string defaultAuthenticator::getPassword() const { + +	shared_ptr <const net::service> service = m_service.lock(); + +	const string prefix = service->getInfos().getPropertyPrefix(); +	const propertySet& props = service->getSession()->getProperties(); + +	if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_PASSWORD.getName())) { +		return props[prefix + net::serviceInfos::property::AUTH_PASSWORD.getName()]; +	} + +	throw exceptions::no_auth_information(); +} + + +const string defaultAuthenticator::getAccessToken() const { + +	shared_ptr <const net::service> service = m_service.lock(); + +	const string prefix = service->getInfos().getPropertyPrefix(); +	const propertySet& props = service->getSession()->getProperties(); + +	if (props.hasProperty(prefix + net::serviceInfos::property::AUTH_ACCESS_TOKEN.getName())) { +		return props[prefix + net::serviceInfos::property::AUTH_ACCESS_TOKEN.getName()]; +	} + +	throw exceptions::no_auth_information(); +} + + +const string defaultAuthenticator::getHostname() const { + +	return platform::getHandler()->getHostName(); +} + + +const string defaultAuthenticator::getAnonymousToken() const { + +	return "anonymous@" + platform::getHandler()->getHostName(); +} + + +const string defaultAuthenticator::getServiceName() const { + +	// Information cannot be provided +	throw exceptions::no_auth_information(); +} + + +void defaultAuthenticator::setService(const shared_ptr <net::service>& serv) { + +	m_service = serv; +} + + +weak_ptr <net::service> defaultAuthenticator::getService() const { + +	return m_service; +} + + +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES diff --git a/vmime-master/src/vmime/security/defaultAuthenticator.hpp b/vmime-master/src/vmime/security/defaultAuthenticator.hpp new file mode 100644 index 0000000..e053f9e --- /dev/null +++ b/vmime-master/src/vmime/security/defaultAuthenticator.hpp @@ -0,0 +1,73 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_DEFAULTAUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_DEFAULTAUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES + + +#include "vmime/security/authenticator.hpp" + + +namespace vmime { +namespace security { + + +/** An authenticator that can provide some basic information by +  * reading in the messaging session properties. +  */ +class VMIME_EXPORT defaultAuthenticator : public authenticator { + +public: + +	defaultAuthenticator(); +	~defaultAuthenticator(); + +	const string getUsername() const; +	const string getPassword() const; +	const string getHostname() const; +	const string getAnonymousToken() const; +	const string getServiceName() const; +	const string getAccessToken() const; + +	void setService(const shared_ptr <net::service>& serv); +	weak_ptr <net::service> getService() const; + +private: + +	weak_ptr <net::service> m_service; +}; + + +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES + +#endif // VMIME_SECURITY_DEFAULTAUTHENTICATOR_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/digest/md5/md5MessageDigest.cpp b/vmime-master/src/vmime/security/digest/md5/md5MessageDigest.cpp new file mode 100644 index 0000000..9a07b57 --- /dev/null +++ b/vmime-master/src/vmime/security/digest/md5/md5MessageDigest.cpp @@ -0,0 +1,349 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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. +// +// +// Derived from cryptoapi implementation, originally based on the +// public domain implementation written by Colin Plumb in 1993. +// +// Copyright (C) Cryptoapi developers. +// +// Algorithm Copyright: +// +//     Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +//     rights reserved. +// +//     License to copy and use this software is granted provided that it +//     is identified as the "RSA Data Security, Inc. MD5 Message-Digest +//     Algorithm" in all material mentioning or referencing this software +//     or this function. +// +//     License is also granted to make and use derivative works provided +//     that such works are identified as "derived from the RSA Data +//     Security, Inc. MD5 Message-Digest Algorithm" in all material +//     mentioning or referencing the derived work. +// +//     RSA Data Security, Inc. makes no representations concerning either +//     the merchantability of this software or the suitability of this +//     software forany particular purpose. It is provided "as is" +//     without express or implied warranty of any kind. +//     These notices must be retained in any copies of any part of this +//     documentation and/or software. + +#include "vmime/security/digest/md5/md5MessageDigest.hpp" + +#include <cstring> + + +namespace vmime { +namespace security { +namespace digest { +namespace md5 { + + +md5MessageDigest::md5MessageDigest() { + +	init(); +} + + +void md5MessageDigest::reset() { + +	init(); +} + + +void md5MessageDigest::init() { + +	m_hash[0] = 0x67452301; +	m_hash[1] = 0xefcdab89; +	m_hash[2] = 0x98badcfe; +	m_hash[3] = 0x10325476; + +	m_byteCount = 0; +	m_finalized = false; +} + + +static void copyUint8Array(vmime_uint8* dest, const vmime_uint8* src, size_t count) { + +	for ( ; count >= 4 ; count -= 4, dest += 4, src += 4) { +		dest[0] = src[0]; +		dest[1] = src[1]; +		dest[2] = src[2]; +		dest[3] = src[3]; +	} + +	for ( ; count ; --count, ++dest, ++src) { +		dest[0] = src[0]; +	} +} + + +static inline vmime_uint32 swapUint32(const vmime_uint32 D) { + +	return ((D << 24) | ((D << 8) & 0x00FF0000) | ((D >> 8) & 0x0000FF00) | (D >> 24)); +} + + +static inline void swapUint32Array(vmime_uint32* buf, size_t words) { + +	for ( ; words >= 4 ; words -= 4, buf += 4) { +		buf[0] = swapUint32(buf[0]); +		buf[1] = swapUint32(buf[1]); +		buf[2] = swapUint32(buf[2]); +		buf[3] = swapUint32(buf[3]); +	} + +	for ( ; words ; --words, ++buf) { +		buf[0] = swapUint32(buf[0]); +	} +} + + +void md5MessageDigest::update(const byte_t b) { + +	update(&b, 1); +} + + +void md5MessageDigest::update(const string& s) { + +	update(reinterpret_cast <const byte_t*>(s.data()), s.length()); +} + + +void md5MessageDigest::update(const byte_t* data, const size_t offset, const size_t len) { + +	update(data + offset, len); +} + + +void md5MessageDigest::update(const byte_t* data, const size_t length) { + +	const size_t avail = 64 - (m_byteCount & 0x3f); +	size_t len = length; + +	m_byteCount += len; + +	if (avail > len) { +		copyUint8Array(m_block.b8 + (64 - avail), data, len); +		return; +	} + +	copyUint8Array(m_block.b8 + (64 - avail), data, avail); +	transformHelper(); + +	data += avail; +	len -= avail; + +	while (len >= 64) { + +		copyUint8Array(m_block.b8, data, 64); +		transformHelper(); + +		data += 64; +		len -= 64; +	} + +	copyUint8Array(m_block.b8, data, len); +} + + +void md5MessageDigest::finalize(const string& s) { + +	update(s); +	finalize(); +} + + +void md5MessageDigest::finalize(const byte_t* buffer, const size_t len) { + +	update(buffer, len); +	finalize(); +} + + +void md5MessageDigest::finalize( +	const byte_t* buffer, +	const size_t offset, +	const size_t len +) { + +	update(buffer, offset, len); +	finalize(); +} + + +void md5MessageDigest::finalize() { + +	const long offset = m_byteCount & 0x3f; + +	vmime_uint8* p = m_block.b8 + offset; +	long padding = 56 - (offset + 1); + +	*p++ = 0x80; + +	if (padding < 0) { + +		memset(p, 0x00, padding + 8); +		transformHelper(); +		p = m_block.b8; +		padding = 56; +	} + +	memset(p, 0, padding); + +	m_block.b32[14] = static_cast <vmime_uint32>(m_byteCount << 3); +	m_block.b32[15] = static_cast <vmime_uint32>(m_byteCount >> 29); + +#if VMIME_BYTE_ORDER_BIG_ENDIAN +	swapUint32Array(m_block.b32, (64 - 8) / 4); +#endif + +	transform(); + +#if VMIME_BYTE_ORDER_BIG_ENDIAN +	swapUint32Array(m_hash, 4); +#endif + +	m_finalized = true; +} + + +void md5MessageDigest::transformHelper() { + +#if VMIME_BYTE_ORDER_BIG_ENDIAN +	swapUint32Array(m_block.b32, 64 / 4); +#endif +	transform(); +} + + +void md5MessageDigest::transform() { + +	const vmime_uint32* const in = m_block.b32; + +	vmime_uint32 a = m_hash[0]; +	vmime_uint32 b = m_hash[1]; +	vmime_uint32 c = m_hash[2]; +	vmime_uint32 d = m_hash[3]; + +#define F1(x, y, z)	(z ^ (x & (y ^ z))) +#define F2(x, y, z)	F1(z, x, y) +#define F3(x, y, z)	(x ^ y ^ z) +#define F4(x, y, z)	(y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, in, s) \ +	(w += f(x, y, z) + in, w = (w<<s | w>>(32-s)) + x) + +	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); +	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); +	MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); +	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); +	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); +	MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); +	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); +	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); +	MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); +	MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); +	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); +	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); +	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); +	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); +	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); +	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + +	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); +	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); +	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); +	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); +	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); +	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); +	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); +	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); +	MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); +	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); +	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); +	MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); +	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); +	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); +	MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); +	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + +	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); +	MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); +	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); +	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); +	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); +	MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); +	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); +	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); +	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); +	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); +	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); +	MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); +	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); +	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); +	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); +	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + +	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); +	MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); +	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); +	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); +	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); +	MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); +	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); +	MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); +	MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); +	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); +	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); +	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); +	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); +	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); +	MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); +	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + +	m_hash[0] += a; +	m_hash[1] += b; +	m_hash[2] += c; +	m_hash[3] += d; +} + + +size_t md5MessageDigest::getDigestLength() const { + +	return 16; +} + + +const byte_t* md5MessageDigest::getDigest() const { + +	return reinterpret_cast <const byte_t*>(m_hash); +} + + +} // md5 +} // digest +} // security +} // vmime + diff --git a/vmime-master/src/vmime/security/digest/md5/md5MessageDigest.hpp b/vmime-master/src/vmime/security/digest/md5/md5MessageDigest.hpp new file mode 100644 index 0000000..bdb730a --- /dev/null +++ b/vmime-master/src/vmime/security/digest/md5/md5MessageDigest.hpp @@ -0,0 +1,85 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_DIGEST_MD5_MD5MESSAGEDIGEST_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_MD5_MD5MESSAGEDIGEST_HPP_INCLUDED + + +#include "vmime/security/digest/messageDigest.hpp" + + +namespace vmime { +namespace security { +namespace digest { +namespace md5 { + + +class md5MessageDigest : public messageDigest { + +public: + +	md5MessageDigest(); + +	void update(const byte_t b); +	void update(const string& s); +	void update(const byte_t* buffer, const size_t len); +	void update(const byte_t* buffer, const size_t offset, const size_t len); + +	void finalize(); +	void finalize(const string& s); +	void finalize(const byte_t* buffer, const size_t len); +	void finalize(const byte_t* buffer, const size_t offset, const size_t len); + +	size_t getDigestLength() const; +	const byte_t* getDigest() const; + +	void reset(); + +protected: + +	void init(); +	void transformHelper(); +	void transform(); + +	vmime_uint32 m_hash[4]; + +	union BlockType { +		vmime_uint32 b32[16]; +		vmime_uint8 b8[64]; +	}; + +	size_t m_byteCount; +	BlockType m_block; + +	bool m_finalized; +}; + + +} // md5 +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_MD5_MD5MESSAGEDIGEST_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/digest/messageDigest.cpp b/vmime-master/src/vmime/security/digest/messageDigest.cpp new file mode 100644 index 0000000..d7e394f --- /dev/null +++ b/vmime-master/src/vmime/security/digest/messageDigest.cpp @@ -0,0 +1,56 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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/security/digest/messageDigest.hpp" + +#include <sstream> + + +namespace vmime { +namespace security { +namespace digest { + + +const string messageDigest::getHexDigest() const { + +	const byte_t* hash = getDigest(); +	const size_t len = getDigestLength(); + +	static const unsigned char hex[] = "0123456789abcdef"; + +	std::ostringstream oss; +	oss.imbue(std::locale::classic()); + +	for (size_t i = 0 ; i < len ; ++i) { +		oss << hex[(hash[i] & 0xf0) >> 4]; +		oss << hex[(hash[i] & 0x0f)]; +	} + +	return oss.str(); +} + + +} // digest +} // security +} // vmime + diff --git a/vmime-master/src/vmime/security/digest/messageDigest.hpp b/vmime-master/src/vmime/security/digest/messageDigest.hpp new file mode 100644 index 0000000..0413810 --- /dev/null +++ b/vmime-master/src/vmime/security/digest/messageDigest.hpp @@ -0,0 +1,142 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_DIGEST_MESSAGEDIGEST_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_MESSAGEDIGEST_HPP_INCLUDED + + +#include "vmime/object.hpp" +#include "vmime/types.hpp" + + +namespace vmime { +namespace security { +namespace digest { + + +/** Computes message digests using standard algorithms, +  * such as MD5 or SHA. +  */ +class VMIME_EXPORT messageDigest : public object { + +public: + +	/** Updates the digest using the specified string. +	  * +	  * @param s the string with which to update the digest. +	  */ +	virtual void update(const string& s) = 0; + +	/** Updates the digest using the specified byte. +	  * +	  * @param b the byte with which to update the digest. +	  */ +	virtual void update(const byte_t b) = 0; + +	/** Updates the digest using the specified array of bytes. +	  * +	  * @param buffer array of bytes +	  * @param len number of bytes to use in the buffer +	  */ +	virtual void update(const byte_t* buffer, const size_t len) = 0; + +	/** Updates the digest using the specified array of bytes, +	  * starting at the specified offset. +	  * +	  * @param buffer array of bytes +	  * @param offset offset to start from in the array of bytes +	  * @param len number of bytes to use, starting at offset +	  */ +	virtual void update( +		const byte_t* buffer, +		const size_t offset, +		const size_t len +	) = 0; + +	/** Completes the hash computation by performing final operations +	  * such as padding. +	  */ +	virtual void finalize() = 0; + +	/** Completes the hash computation by performing final operations +	  * such as padding. This is equivalent to calling update() and +	  * then finalize(). +	  */ +	virtual void finalize(const string& s) = 0; + +	/** Completes the hash computation by performing final operations +	  * such as padding. This is equivalent to calling update() and +	  * then finalize(). +	  */ +	virtual void finalize( +		const byte_t* buffer, +		const size_t len +	) = 0; + +	/** Completes the hash computation by performing final operations +	  * such as padding. This is equivalent to calling update() and +	  * then finalize(). +	  */ +	virtual void finalize( +		const byte_t* buffer, +		const size_t offset, +		const size_t len +	) = 0; + +	/** Returns the length of the hash. +	  * This is the length of the array returned by getDigest(). +	  * +	  * @return length of computed hash +	  */ +	virtual size_t getDigestLength() const = 0; + +	/** Returns the hash, as computed by the algorithm. +	  * You must call finalize() before using this function, or the +	  * hash will not be correct. +	  * To get the size of the returned array, call getDigestLength(). +	  * +	  * @return computed hash +	  */ +	virtual const byte_t* getDigest() const = 0; + +	/** Returns the hash as an hexadecimal string. +	  * You must call finalize() before using this function, or the +	  * hash will not be correct. +	  * +	  * @return computed hash, in hexadecimal format +	  */ +	virtual const string getHexDigest() const; + +	/** Resets the algorithm to its initial state, so that you can +	  * compute a new hash using the same object. +	  */ +	virtual void reset() = 0; +}; + + +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_MESSAGEDIGEST_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/digest/messageDigestFactory.cpp b/vmime-master/src/vmime/security/digest/messageDigestFactory.cpp new file mode 100644 index 0000000..2e49968 --- /dev/null +++ b/vmime-master/src/vmime/security/digest/messageDigestFactory.cpp @@ -0,0 +1,81 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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/security/digest/messageDigestFactory.hpp" +#include "vmime/exception.hpp" + +#include "vmime/security/digest/md5/md5MessageDigest.hpp" +#include "vmime/security/digest/sha1/sha1MessageDigest.hpp" + + +namespace vmime { +namespace security { +namespace digest { + + +messageDigestFactory::messageDigestFactory() { + +	registerAlgorithm <md5::md5MessageDigest>("md5"); +	registerAlgorithm <sha1::sha1MessageDigest>("sha1"); +} + + +messageDigestFactory::~messageDigestFactory() { + +} + + +messageDigestFactory* messageDigestFactory::getInstance() { + +	static messageDigestFactory instance; +	return &instance; +} + + +shared_ptr <messageDigest> messageDigestFactory::create(const string& name) { + +	const MapType::const_iterator it = m_algos.find(utility::stringUtils::toLower(name)); + +	if (it != m_algos.end()) { +		return (*it).second->create(); +	} + +	throw exceptions::no_digest_algorithm_available(name); +} + + +const std::vector <string> messageDigestFactory::getSupportedAlgorithms() const { + +	std::vector <string> res; + +	for (MapType::const_iterator it = m_algos.begin() ; it != m_algos.end() ; ++it) { +		res.push_back((*it).first); +	} + +	return res; +} + + +} // digest +} // security +} // vmime diff --git a/vmime-master/src/vmime/security/digest/messageDigestFactory.hpp b/vmime-master/src/vmime/security/digest/messageDigestFactory.hpp new file mode 100644 index 0000000..56a0cfe --- /dev/null +++ b/vmime-master/src/vmime/security/digest/messageDigestFactory.hpp @@ -0,0 +1,110 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_DIGEST_MESSAGEDIGESTFACTORY_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_MESSAGEDIGESTFACTORY_HPP_INCLUDED + + +#include "vmime/types.hpp" +#include "vmime/security/digest/messageDigest.hpp" +#include "vmime/utility/stringUtils.hpp" + + +namespace vmime { +namespace security { +namespace digest { + + +/** Creates instances of message digest algorithms. +  */ + +class VMIME_EXPORT messageDigestFactory { + +private: + +	messageDigestFactory(); +	~messageDigestFactory(); + +public: + +	static messageDigestFactory* getInstance(); + +private: + +	struct digestAlgorithmFactory : public object { + +		virtual shared_ptr <messageDigest> create() const = 0; +	}; + +	template <class E> +	struct digestAlgorithmFactoryImpl : public digestAlgorithmFactory { + +		shared_ptr <messageDigest> create() const { +			return vmime::make_shared <E>(); +		} +	}; + + +	typedef std::map <string, shared_ptr <digestAlgorithmFactory> > MapType; +	MapType m_algos; + +public: + +	/** Register a new digest algorithm by its name. +	  * +	  * @param name algorithm name +	  */ +	template <class E> +	void registerAlgorithm(const string& name) { + +		m_algos.insert( +			MapType::value_type( +				utility::stringUtils::toLower(name), +				vmime::make_shared <digestAlgorithmFactoryImpl <E> >() +			) +		); +	} + +	/** Create a new algorithm instance from its name. +	  * +	  * @param name algorithm name (eg. "md5") +	  * @return a new algorithm instance for the specified name +	  * @throw exceptions::no_digest_algorithm_available if no algorithm is +	  * registered with this name +	  */ +	shared_ptr <messageDigest> create(const string& name); + +	/** Return a list of supported digest algorithms. +	  * +	  * @return list of supported digest algorithms +	  */ +	const std::vector <string> getSupportedAlgorithms() const; +}; + + +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_MESSAGEDIGESTFACTORY_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/digest/sha1/sha1MessageDigest.cpp b/vmime-master/src/vmime/security/digest/sha1/sha1MessageDigest.cpp new file mode 100644 index 0000000..c098f14 --- /dev/null +++ b/vmime-master/src/vmime/security/digest/sha1/sha1MessageDigest.cpp @@ -0,0 +1,276 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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. +// +// +// This is an implementation by Steve Reid <steve@edmweb.com> +// 100% public domain. + +#include "vmime/security/digest/sha1/sha1MessageDigest.hpp" + +#include <cstring> +#include <cassert> + + +namespace vmime { +namespace security { +namespace digest { +namespace sha1 { + + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +// blk0() and blk() perform the initial expand. +// I got the idea of expanding during the round function from SSLeay +#if VMIME_BYTE_ORDER_LITTLE_ENDIAN +	#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) \ +	                             | (rol(block->l[i],  8) & 0x00FF00FF)) +#else +	#define blk0(i) block->l[i] +#endif + +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] \ +                ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) + +// (R0+R1), R2, R3, R4 are the different operations used in SHA1 +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +sha1MessageDigest::sha1MessageDigest() { + +	init(); +} + + +void sha1MessageDigest::reset() { + +	init(); +} + + +void sha1MessageDigest::init() { + +	m_state[0] = 0x67452301; +	m_state[1] = 0xefcdab89; +	m_state[2] = 0x98badcfe; +	m_state[3] = 0x10325476; +	m_state[4] = 0xc3d2e1f0; + +	m_count[0] = 0; +	m_count[1] = 0; +} + + +void sha1MessageDigest::update(const byte_t b) { + +	update(&b, 1); +} + + +void sha1MessageDigest::update(const string& s) { + +	update(reinterpret_cast <const byte_t*>(s.data()), s.length()); +} + + +void sha1MessageDigest::update(const byte_t* buffer, const size_t offset, const size_t len) { + +	update(buffer + offset, len); +} + + +void sha1MessageDigest::update(const byte_t* buffer, const size_t len) { + +	unsigned int i, j; + +	j = (m_count[0] >> 3) & 63; + +	if ((m_count[0] += static_cast <unsigned int>(len << 3)) < static_cast <unsigned int>(len << 3)) { +		m_count[1]++; +	} + +	m_count[1] += static_cast <unsigned int>(len >> 29); + +	if ((j + len) > 63) { + +		memcpy(&m_buffer[j], buffer, (i = 64 - j)); + +		transform(m_state, m_buffer); + +		for ( ; i + 63 < len ; i += 64) { +			transform(m_state, &buffer[i]); +		} + +		j = 0; + +	} else { + +		i = 0; +	} + +	std::memcpy(&m_buffer[j], &buffer[i], len - i); +} + + +void sha1MessageDigest::finalize() { + +	unsigned int i, j; +	unsigned char finalcount[8]; + +	for (i = 0 ; i < 8 ; i++) { + +		finalcount[i] = static_cast <unsigned char>( +			(m_count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255  // Endian independent +		); +	} + +	update(reinterpret_cast <const byte_t*>("\200"), 1); + +	while ((m_count[0] & 504) != 448) { +		update(reinterpret_cast <const byte_t*>("\0"), 1); +	} + +	update(finalcount, 8);  // Should cause a transform() + +	for (i = 0 ; i < 20 ; i++) { + +		m_digest[i] = static_cast <unsigned char>( +			(m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255 +		); +	} + +	// Wipe variables +	i = j = 0; + +	std::memset(m_buffer, 0, 64); +	std::memset(m_state, 0, 5 * sizeof(unsigned int)); +	std::memset(m_count, 0, 2 * sizeof(unsigned int)); +	std::memset(&finalcount, 0, 8); +} + + +void sha1MessageDigest::finalize(const string& s) { + +	finalize(reinterpret_cast <const byte_t*>(s.data()), s.length()); +} + + +void sha1MessageDigest::finalize(const byte_t* buffer, const size_t len) { + +	update(buffer, len); +	finalize(); +} + + +void sha1MessageDigest::finalize( +	const byte_t* buffer, +	const size_t offset, +	const size_t len +) { + +	finalize(buffer + offset, len); +} + + +/** Hash a single 512-bit block. +  * This is the core of the algorithm. +  */ +void sha1MessageDigest::transform( +	unsigned int state[5], +	const unsigned char buffer[64] +) { + +	unsigned int a, b, c, d, e; + +	typedef union { +		unsigned char c[64]; +		unsigned int l[16]; +	} CHAR64LONG16; + +	assert(sizeof(unsigned int) == 4); + +	CHAR64LONG16* block; +	static unsigned char workspace[64]; + +	block = reinterpret_cast <CHAR64LONG16*>(workspace); +	memcpy(block, buffer, 64); + +	// Copy context->state[] to working vars +	a = state[0]; +	b = state[1]; +	c = state[2]; +	d = state[3]; +	e = state[4]; + +	// 4 rounds of 20 operations each. Loop unrolled. +	R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); +	R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); +	R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); +	R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); +	R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); +	R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); +	R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); +	R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); +	R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); +	R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); +	R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); +	R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); +	R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); +	R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); +	R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); +	R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); +	R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); +	R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); +	R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); +	R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + +	// Add the working vars back into context.state[] +	state[0] += a; +	state[1] += b; +	state[2] += c; +	state[3] += d; +	state[4] += e; + +	// Wipe variables +	a = b = c = d = e = 0; +} + + +size_t sha1MessageDigest::getDigestLength() const { + +	return 20; +} + + +const byte_t* sha1MessageDigest::getDigest() const { + +	return m_digest; +} + + +} // sha1 +} // digest +} // security +} // vmime diff --git a/vmime-master/src/vmime/security/digest/sha1/sha1MessageDigest.hpp b/vmime-master/src/vmime/security/digest/sha1/sha1MessageDigest.hpp new file mode 100644 index 0000000..1906236 --- /dev/null +++ b/vmime-master/src/vmime/security/digest/sha1/sha1MessageDigest.hpp @@ -0,0 +1,79 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_DIGEST_SHA1_SHA1MESSAGEDIGEST_HPP_INCLUDED +#define VMIME_SECURITY_DIGEST_SHA1_SHA1MESSAGEDIGEST_HPP_INCLUDED + + +#include "vmime/security/digest/messageDigest.hpp" + + +namespace vmime { +namespace security { +namespace digest { +namespace sha1 { + + +class sha1MessageDigest : public messageDigest { + +public: + +	sha1MessageDigest(); + +	void update(const byte_t b); +	void update(const string& s); +	void update(const byte_t* buffer, const size_t len); +	void update(const byte_t* buffer, const size_t offset, const size_t len); + +	void finalize(); +	void finalize(const string& s); +	void finalize(const byte_t* buffer, const size_t len); +	void finalize(const byte_t* buffer, const size_t offset, const size_t len); + +	size_t getDigestLength() const; +	const byte_t* getDigest() const; + +	void reset(); + +protected: + +	void init(); + +	static void transform(unsigned int state[5], const byte_t buffer[64]); + +	unsigned int m_state[5]; +	unsigned int m_count[2]; +	byte_t m_buffer[64]; + +	byte_t m_digest[20]; +}; + + +} // sha1 +} // digest +} // security +} // vmime + + +#endif // VMIME_SECURITY_DIGEST_SHA1_SHA1MESSAGEDIGEST_HPP_INCLUDED + diff --git a/vmime-master/src/vmime/security/sasl/SASLAuthenticator.hpp b/vmime-master/src/vmime/security/sasl/SASLAuthenticator.hpp new file mode 100644 index 0000000..a75bfa0 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLAuthenticator.hpp @@ -0,0 +1,96 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SASLAUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/security/authenticator.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLMechanism; +class SASLSession; + + +/** SASL-aware authenticator. +  * +  * Usually, you should not inherit from this class, but instead from the +  * more convenient defaultSASLAuthenticator class. +  */ +class VMIME_EXPORT SASLAuthenticator : public authenticator { + +public: + +	/** This method is called to allow the client to choose the +	  * authentication mechanisms that will be used. By default, +	  * the most secure mechanisms are chosen. +	  * +	  * @param available available mechanisms +	  * @param suggested suggested mechanism (or NULL if the system +	  * could not suggest a mechanism) +	  * @return ordered list of mechanism to use among the available +	  * mechanisms (from the first to try to the last) +	  */ +	virtual const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms( +		const std::vector <shared_ptr <SASLMechanism> >& available, +		const shared_ptr <SASLMechanism>& suggested +	) const = 0; + +	/** Set the SASL session which is using this authenticator. +	  * +	  * @param sess SASL session +	  */ +	virtual void setSASLSession(const shared_ptr <SASLSession>& sess) = 0; + +	/** Set the SASL mechanism which has been selected for the +	  * SASL authentication process. This may be called several times +	  * if the multiple mechanisms are tried by the service which +	  * use this authentication. +	  * +	  * @param mech SASL mechanism +	  */ +	virtual void setSASLMechanism(const shared_ptr <SASLMechanism>& mech) = 0; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLAUTHENTICATOR_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/SASLContext.cpp b/vmime-master/src/vmime/security/sasl/SASLContext.cpp new file mode 100644 index 0000000..2174541 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLContext.cpp @@ -0,0 +1,221 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include <sstream> + +#include <gsasl.h> + +#include "vmime/security/sasl/SASLContext.hpp" +#include "vmime/security/sasl/SASLMechanism.hpp" + +#include "vmime/base.hpp" + +#include "vmime/utility/encoder/encoderFactory.hpp" + +#include "vmime/utility/stream.hpp" +#include "vmime/utility/outputStreamStringAdapter.hpp" +#include "vmime/utility/inputStreamStringAdapter.hpp" +#include "vmime/utility/inputStreamByteBufferAdapter.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +SASLContext::SASLContext() { + +	if (gsasl_init(&m_gsaslContext) != GSASL_OK) { +		throw std::bad_alloc(); +	} +} + + +SASLContext::~SASLContext() { + +	gsasl_done(m_gsaslContext); +} + + +// static +shared_ptr <SASLContext> SASLContext::create() { + +	return shared_ptr <SASLContext>(new SASLContext()); +} + + +shared_ptr <SASLSession> SASLContext::createSession( +	const string& serviceName, +	const shared_ptr <authenticator>& auth, +	const shared_ptr <SASLMechanism>& mech +) { + +	return SASLSession::create +		(serviceName, dynamicCast <SASLContext>(shared_from_this()), auth, mech); +} + + +shared_ptr <SASLMechanism> SASLContext::createMechanism(const string& name) { + +	return SASLMechanismFactory::getInstance()->create( +		dynamicCast <SASLContext>(shared_from_this()), name +	); +} + + +shared_ptr <SASLMechanism> SASLContext::suggestMechanism( +	const std::vector <shared_ptr <SASLMechanism> >& mechs +) { + +	if (mechs.empty()) { +		return null; +	} + +	std::ostringstream oss; + +	for (unsigned int i = 0 ; i < mechs.size() ; ++i) { +		oss << mechs[i]->getName() << " "; +	} + +	const string mechList = oss.str(); +	const char* suggested = gsasl_client_suggest_mechanism(m_gsaslContext, mechList.c_str()); + +	if (suggested) { + +		for (unsigned int i = 0 ; i < mechs.size() ; ++i) { + +			if (mechs[i]->getName() == suggested) { +				return mechs[i]; +			} +		} +	} + +	return null; +} + + +void SASLContext::decodeB64(const string& input, byte_t** output, size_t* outputLen) { + +	string res; + +	utility::inputStreamStringAdapter is(input); +	utility::outputStreamStringAdapter os(res); + +	shared_ptr <utility::encoder::encoder> dec = +		utility::encoder::encoderFactory::getInstance()->create("base64"); + +	dec->decode(is, os); + +	byte_t* out = new byte_t[res.length()]; + +	std::copy(res.begin(), res.end(), out); + +	*output = out; +	*outputLen = res.length(); +} + + +const string SASLContext::encodeB64(const byte_t* input, const size_t inputLen) { + +	string res; + +	utility::inputStreamByteBufferAdapter is(input, inputLen); +	utility::outputStreamStringAdapter os(res); + +	shared_ptr <utility::encoder::encoder> enc = +		utility::encoder::encoderFactory::getInstance()->create("base64"); + +	enc->encode(is, os); + +	return res; +} + + +const string SASLContext::getErrorMessage(const string& fname, const int code) { + +	string msg = fname + "() returned "; + +#define ERROR(x) \ +	case x: msg += #x; break; + +	switch (code) +	{ +		ERROR(GSASL_NEEDS_MORE) +		ERROR(GSASL_UNKNOWN_MECHANISM) +		ERROR(GSASL_MECHANISM_CALLED_TOO_MANY_TIMES) +		ERROR(GSASL_MALLOC_ERROR) +		ERROR(GSASL_BASE64_ERROR) +		ERROR(GSASL_CRYPTO_ERROR) +		ERROR(GSASL_SASLPREP_ERROR) +		ERROR(GSASL_MECHANISM_PARSE_ERROR) +		ERROR(GSASL_AUTHENTICATION_ERROR) +		ERROR(GSASL_INTEGRITY_ERROR) +		ERROR(GSASL_NO_CLIENT_CODE) +		ERROR(GSASL_NO_SERVER_CODE) +		ERROR(GSASL_NO_CALLBACK) +		ERROR(GSASL_NO_ANONYMOUS_TOKEN) +		ERROR(GSASL_NO_AUTHID) +		ERROR(GSASL_NO_AUTHZID) +		ERROR(GSASL_NO_PASSWORD) +		ERROR(GSASL_NO_PASSCODE) +		ERROR(GSASL_NO_PIN) +		ERROR(GSASL_NO_SERVICE) +		ERROR(GSASL_NO_HOSTNAME) +		ERROR(GSASL_GSSAPI_RELEASE_BUFFER_ERROR) +		ERROR(GSASL_GSSAPI_IMPORT_NAME_ERROR) +		ERROR(GSASL_GSSAPI_INIT_SEC_CONTEXT_ERROR) +		ERROR(GSASL_GSSAPI_ACCEPT_SEC_CONTEXT_ERROR) +		ERROR(GSASL_GSSAPI_UNWRAP_ERROR) +		ERROR(GSASL_GSSAPI_WRAP_ERROR) +		ERROR(GSASL_GSSAPI_ACQUIRE_CRED_ERROR) +		ERROR(GSASL_GSSAPI_DISPLAY_NAME_ERROR) +		ERROR(GSASL_GSSAPI_UNSUPPORTED_PROTECTION_ERROR) +		ERROR(GSASL_KERBEROS_V5_INIT_ERROR) +		ERROR(GSASL_KERBEROS_V5_INTERNAL_ERROR) +		ERROR(GSASL_SECURID_SERVER_NEED_ADDITIONAL_PASSCODE) +		ERROR(GSASL_SECURID_SERVER_NEED_NEW_PIN) + +		default: + +			msg += "unknown error"; +			break; +	} + +#undef ERROR + +	return msg; +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/SASLContext.hpp b/vmime-master/src/vmime/security/sasl/SASLContext.hpp new file mode 100644 index 0000000..93d80ff --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLContext.hpp @@ -0,0 +1,136 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SASLCONTEXT_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/security/sasl/SASLSession.hpp" +#include "vmime/security/sasl/SASLMechanismFactory.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +/** An SASL client context. +  */ +class VMIME_EXPORT SASLContext : public object, public enable_shared_from_this <SASLContext> { + +	friend class SASLSession; +	friend class builtinSASLMechanism; + +public: + +	~SASLContext(); + +	/** Construct and initialize a new SASL context. +	  * +	  * @return pointer to a new SASL context +	  */ +	static shared_ptr <SASLContext> create(); + +	/** Create and initialize a new SASL session. +	  * +	  * @param serviceName name of the service which will use the session +	  * @param auth authenticator object to use during the session +	  * @param mech SASL mechanism +	  * @return a new SASL session +	  */ +	shared_ptr <SASLSession> createSession( +		const string& serviceName, +		const shared_ptr <authenticator>& auth, +		const shared_ptr <SASLMechanism>& mech +	); + +	/** Create an instance of an SASL mechanism. +	  * +	  * @param name mechanism name +	  * @return a new instance of the specified SASL mechanism +	  * @throw exceptions::no_such_mechanism if no mechanism is +	  * registered for the specified name +	  */ +	shared_ptr <SASLMechanism> createMechanism(const string& name); + +	/** Suggests an SASL mechanism among a set of mechanisms +	  * supported by the server. +	  * +	  * @param mechs list of mechanisms +	  * @return suggested mechanism (usually the safest mechanism +	  * supported by both the client and the server) +	  */ +	shared_ptr <SASLMechanism> suggestMechanism( +		const std::vector <shared_ptr <SASLMechanism> >& mechs +	); + +	/** Helper function for decoding Base64-encoded challenge. +	  * +	  * @param input input buffer +	  * @param output output buffer +	  * @param outputLen length of output buffer +	  */ +	void decodeB64(const string& input, byte_t** output, size_t* outputLen); + +	/** Helper function for encoding challenge in Base64. +	  * +	  * @param input input buffer +	  * @param inputLen length of input buffer +	  * @return Base64-encoded challenge +	  */ +	const string encodeB64(const byte_t* input, const size_t inputLen); + +private: + +	SASLContext(); +	SASLContext(SASLContext&); + + +	static const string getErrorMessage(const string& fname, const int code); + + +#ifdef GSASL_VERSION +	Gsasl* m_gsaslContext; +#else +	void* m_gsaslContext; +#endif // GSASL_VERSION + +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLCONTEXT_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/SASLMechanism.hpp b/vmime-master/src/vmime/security/sasl/SASLMechanism.hpp new file mode 100644 index 0000000..a6e056d --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLMechanism.hpp @@ -0,0 +1,153 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SASLMECHANISM_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLSession; + + +/** An SASL mechanism. +  */ +class VMIME_EXPORT SASLMechanism : public object { + +public: + +	/** Return the name of this mechanism. +	  * +	  * @return mechanism name +	  */ +	virtual const string getName() const = 0; + +	/** Perform one step of SASL authentication. Accept data from the +	  * server (challenge), process it and return data to be returned +	  * in response to the server. +	  * +	  * If the challenge is empty (challengeLen == 0), the initial +	  * response is returned, if this mechanism has one. +	  * +	  * @param sess SASL session +	  * @param challenge challenge sent from the server +	  * @param challengeLen length of challenge +	  * @param response response to send to the server (allocated by +	  * this function, free with delete[]) +	  * @param responseLen length of response buffer +	  * @return true if authentication terminated successfully, or +	  * false if the authentication process should continue +	  * @throw exceptions::sasl_exception if an error occurred during +	  * authentication (in this case, the values in 'response' and +	  * 'responseLen' are undetermined) +	  */ +	virtual bool step( +		const shared_ptr <SASLSession>& sess, +		const byte_t* challenge, +		const size_t challengeLen, +		byte_t** response, +		size_t* responseLen +	) = 0; + +	/** Check whether authentication has completed. If false, more +	  * calls to evaluateChallenge() are needed to complete the +	  * authentication process). +	  * +	  * @return true if the authentication has finished, or false +	  * otherwise +	  */ +	virtual bool isComplete() const = 0; + +	/** Determine if this mechanism has an optional initial response. +	  * If true, caller should call step() with an empty challenge to +	  * get the initial response. +	  * +	  * @return true if this mechanism has an initial response, or +	  * false otherwise +	  */ +	virtual bool hasInitialResponse() const = 0; + +	/** Encode data according to negotiated SASL mechanism. This +	  * might mean that data is integrity or privacy protected. +	  * +	  * @param sess SASL session +	  * @param input input buffer +	  * @param inputLen length of input buffer +	  * @param output output buffer (allocated bu the function, +	  * free with delete[]) +	  * @param outputLen length of output buffer +	  * @throw exceptions::sasl_exception if an error occurred during +	  * the encoding of data (in this case, the values in 'output' and +	  * 'outputLen' are undetermined) +	  */ +	virtual void encode( +		const shared_ptr <SASLSession>& sess, +		const byte_t* input, +		const size_t inputLen, +		byte_t** output, +		size_t* outputLen +	) = 0; + +	/** Decode data according to negotiated SASL mechanism. This +	  * might mean that data is integrity or privacy protected. +	  * +	  * @param sess SASL session +	  * @param input input buffer +	  * @param inputLen length of input buffer +	  * @param output output buffer (allocated bu the function, +	  * free with delete[]) +	  * @param outputLen length of output buffer +	  * @throw exceptions::sasl_exception if an error occurred during +	  * the encoding of data (in this case, the values in 'output' and +	  * 'outputLen' are undetermined) +	  */ +	virtual void decode( +		const shared_ptr <SASLSession>& sess, +		const byte_t* input, +		const size_t inputLen, +		byte_t** output, +		size_t* outputLen +	) = 0; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLMECHANISM_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.cpp b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.cpp new file mode 100644 index 0000000..a2fbedb --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.cpp @@ -0,0 +1,149 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include <stdexcept> +#include <new> + +#include <gsasl.h> + +#include "vmime/security/sasl/SASLMechanismFactory.hpp" +#include "vmime/security/sasl/builtinSASLMechanism.hpp" +#include "vmime/security/sasl/SASLContext.hpp" + +#include "vmime/utility/stringUtils.hpp" + +#include "vmime/base.hpp" +#include "vmime/exception.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +SASLMechanismFactory::SASLMechanismFactory() { + +	if (gsasl_init(&m_gsaslContext) != GSASL_OK) { +		throw std::bad_alloc(); +	} +} + + +SASLMechanismFactory::~SASLMechanismFactory() { + +	gsasl_done(m_gsaslContext); +} + + +// static +SASLMechanismFactory* SASLMechanismFactory::getInstance() { + +	static SASLMechanismFactory instance; +	return &instance; +} + + +shared_ptr <SASLMechanism> SASLMechanismFactory::create( +	const shared_ptr <SASLContext>& ctx, +	const string& name_ +) { + +	const string name(utility::stringUtils::toUpper(name_)); + +	// Check for registered mechanisms +	MapType::iterator it = m_mechs.find(name); + +	if (it != m_mechs.end()) { +		return (*it).second->create(ctx, name); +	} + +	// Check for built-in mechanisms +	if (isBuiltinMechanism(name)) { +		return make_shared <builtinSASLMechanism>(ctx, name); +	} + +	throw exceptions::no_such_mechanism(name); +	return null; +} + + +const std::vector <string> SASLMechanismFactory::getSupportedMechanisms() const { + +	std::vector <string> list; + +	// Registered mechanisms +	for (MapType::const_iterator it = m_mechs.begin() ; +	     it != m_mechs.end() ; ++it) { + +		list.push_back((*it).first); +	} + +	// Built-in mechanisms +	char* out = 0; + +	if (gsasl_client_mechlist(m_gsaslContext, &out) == GSASL_OK) { + +		// 'out' contains SASL mechanism names, separated by spaces +		for (char *start = out, *p = out ; ; ++p) { + +			if (*p == ' ' || !*p) { + +				list.push_back(string(start, p)); +				start = p + 1; + +				// End of string +				if (!*p) break; +			} +		} + +		gsasl_free(out); +	} + +	return list; +} + + +bool SASLMechanismFactory::isMechanismSupported(const string& name) const { + +	return isBuiltinMechanism(name) || m_mechs.find(name) != m_mechs.end(); +} + + +bool SASLMechanismFactory::isBuiltinMechanism(const string& name) const { + +	return gsasl_client_support_p(m_gsaslContext, name.c_str()) != 0; +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.hpp b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.hpp new file mode 100644 index 0000000..af76c96 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLMechanismFactory.hpp @@ -0,0 +1,155 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" +#include "vmime/base.hpp" + +#include "vmime/security/sasl/SASLMechanism.hpp" + +#include <map> + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLContext; + + +/** Constructs SASL mechanism objects. +  */ +class VMIME_EXPORT SASLMechanismFactory : public object { + +private: + +	SASLMechanismFactory(); +	~SASLMechanismFactory(); + + +	struct registeredMechanism : public object { + +		virtual shared_ptr <SASLMechanism> create( +			const shared_ptr <SASLContext>& ctx, const string& name +		) = 0; +	}; + +	template <typename T> +	struct registeredMechanismImpl : public registeredMechanism { + +		shared_ptr <SASLMechanism> create( +			const shared_ptr <SASLContext>& ctx, +			const string& name +		) { + +			return vmime::make_shared <T>(ctx, name); +		} +	}; + +	typedef std::map <string, shared_ptr <registeredMechanism> > MapType; +	MapType m_mechs; + +public: + +	static SASLMechanismFactory* getInstance(); + +	/** Register a mechanism into this factory, so that subsequent +	  * calls to create return a valid object for this mechanism. +	  * +	  * @param name mechanism name +	  */ +	template <typename MECH_CLASS> +	void registerMechanism(const string& name) { + +		m_mechs.insert( +			MapType::value_type( +				name, +				vmime::make_shared <registeredMechanismImpl <MECH_CLASS> >() +			) +		); +	} + +	/** Create a mechanism object given its name. +	  * +	  * @param ctx SASL context +	  * @param name mechanism name +	  * @return a new mechanism object +	  * @throw exceptions::no_such_mechanism if no mechanism is +	  * registered for the specified name +	  */ +	shared_ptr <SASLMechanism> create(const shared_ptr <SASLContext>& ctx, const string& name); + +	/** Return a list of supported mechanisms. This includes mechanisms +	  * registered using registerMechanism() as well as the ones that +	  * are built-in. +	  * +	  * @return list of supported mechanisms +	  */ +	const std::vector <string> getSupportedMechanisms() const; + +	/** Test whether an authentication mechanism is supported. +	  * +	  * @param name mechanism name +	  * @return true if the specified mechanism is supported, +	  * false otherwise +	  */ +	bool isMechanismSupported(const string& name) const; + +	/** Test whether an authentication mechanism is directly supported +	  * by the underlying SASL library. +	  * +	  * @param name mechanism name +	  * @return true if the specified mechanism is built-in, +	  * or false otherwise +	  */ +	bool isBuiltinMechanism(const string& name) const; + +private: + +#ifdef GSASL_VERSION +	Gsasl* m_gsaslContext; +#else +	void* m_gsaslContext; +#endif // GSASL_VERSION + +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLMECHANISMFACTORY_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/SASLSession.cpp b/vmime-master/src/vmime/security/sasl/SASLSession.cpp new file mode 100644 index 0000000..7498b46 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLSession.cpp @@ -0,0 +1,221 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include <sstream> + +#include <gsasl.h> + +#include "vmime/security/sasl/SASLSession.hpp" + +#include "vmime/security/sasl/SASLContext.hpp" +#include "vmime/security/sasl/SASLSocket.hpp" +#include "vmime/security/sasl/SASLAuthenticator.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +SASLSession::SASLSession( +	const string& serviceName, +	const shared_ptr <SASLContext>& ctx, +	const shared_ptr <authenticator>& auth, +	const shared_ptr <SASLMechanism>& mech +) +	: m_serviceName(serviceName), +	  m_context(ctx), +	  m_auth(auth), +	  m_mech(mech), +	  m_gsaslContext(0), +	  m_gsaslSession(0) { + +	if (gsasl_init(&m_gsaslContext) != GSASL_OK) { +		throw std::bad_alloc(); +	} + +	gsasl_client_start(m_gsaslContext, mech->getName().c_str(), &m_gsaslSession); + +	gsasl_callback_set(m_gsaslContext, gsaslCallback); +	gsasl_callback_hook_set(m_gsaslContext, this); +} + + +SASLSession::~SASLSession() { + +	gsasl_finish(m_gsaslSession); +	m_gsaslSession = NULL; + +	gsasl_done(m_gsaslContext); +	m_gsaslContext = NULL; +} + + +// static +shared_ptr <SASLSession> SASLSession::create( +	const string& serviceName, +	const shared_ptr <SASLContext>& ctx, +	const shared_ptr <authenticator>& auth, +	const shared_ptr <SASLMechanism>& mech +) { + +	return shared_ptr <SASLSession>(new SASLSession(serviceName, ctx, auth, mech)); +} + + +void SASLSession::init() { + +	shared_ptr <SASLAuthenticator> saslAuth = dynamicCast <SASLAuthenticator>(m_auth); + +	if (saslAuth) { +		saslAuth->setSASLMechanism(m_mech); +		saslAuth->setSASLSession(dynamicCast <SASLSession>(shared_from_this())); +	} +} + + +shared_ptr <authenticator> SASLSession::getAuthenticator() { + +	return m_auth; +} + + +shared_ptr <SASLMechanism> SASLSession::getMechanism() { + +	return m_mech; +} + + +shared_ptr <SASLContext> SASLSession::getContext() { + +	return m_context; +} + + +bool SASLSession::evaluateChallenge( +	const byte_t* challenge, +	const size_t challengeLen, +	byte_t** response, +	size_t* responseLen +) { + +	return m_mech->step( +		dynamicCast <SASLSession>(shared_from_this()), +		challenge, challengeLen, response, responseLen +	); +} + + +shared_ptr <net::socket> SASLSession::getSecuredSocket(const shared_ptr <net::socket>& sok) { + +	return make_shared <SASLSocket>(dynamicCast <SASLSession>(shared_from_this()), sok); +} + + +const string SASLSession::getServiceName() const { + +	return m_serviceName; +} + + +// static +int SASLSession::gsaslCallback( +	Gsasl* ctx, +	Gsasl_session* sctx, +	Gsasl_property prop +) { + +	SASLSession* sess = reinterpret_cast <SASLSession*>(gsasl_callback_hook_get(ctx)); + +	if (!sess) { +		return GSASL_AUTHENTICATION_ERROR; +	} + +	shared_ptr <authenticator> auth = sess->getAuthenticator(); + +	try { + +		string res; + +		switch (prop) { + +			case GSASL_AUTHID: + +				res = auth->getUsername(); +				break; + +			case GSASL_PASSWORD: + +				res = auth->getPassword(); +				break; + +			case GSASL_ANONYMOUS_TOKEN: + +				res = auth->getAnonymousToken(); +				break; + +			case GSASL_HOSTNAME: + +				res = auth->getHostname(); +				break; + +			case GSASL_SERVICE: + +				res = auth->getServiceName(); +				break; + +			case GSASL_AUTHZID: +			case GSASL_GSSAPI_DISPLAY_NAME: +			case GSASL_PASSCODE: +			case GSASL_SUGGESTED_PIN: +			case GSASL_PIN: +			case GSASL_REALM: + +			default: + +				return GSASL_NO_CALLBACK; +		} + +		gsasl_property_set(sctx, prop, res.c_str()); + +		return GSASL_OK; + +	} catch (...) { + +		return GSASL_NO_CALLBACK; +	} +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/SASLSession.hpp b/vmime-master/src/vmime/security/sasl/SASLSession.hpp new file mode 100644 index 0000000..7fc7225 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLSession.hpp @@ -0,0 +1,180 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SASLSESSION_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/net/socket.hpp" + +#include "vmime/security/sasl/SASLAuthenticator.hpp" +#include "vmime/security/sasl/SASLMechanism.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLContext; + + +/** An SASL client session. +  */ +class VMIME_EXPORT SASLSession : public object, public enable_shared_from_this <SASLSession> { + +	friend class builtinSASLMechanism; +	friend class SASLSocket; + +public: + +	~SASLSession(); + +	/** Construct a new SASL session. +	  * +	  * @param serviceName name of the service using this session +	  * @param ctx SASL context +	  * @param auth authenticator to use for this session +	  * @param mech SASL mechanism +	  */ +	static shared_ptr <SASLSession> create( +		const string& serviceName, +		const shared_ptr <SASLContext>& ctx, +		const shared_ptr <authenticator>& auth, +		const shared_ptr <SASLMechanism>& mech +	); + +	/** Initialize this SASL session. This must be called before +	  * calling any other method on this object (except accessors). +	  */ +	void init(); + +	/** Return the authenticator used for this session. This is the +	  * authenticator which has been previously set with a call to +	  * setAuthenticator(). +	  * +	  * @return authenticator object +	  */ +	shared_ptr <authenticator> getAuthenticator(); + +	/** Return the mechanism used for this session. +	  * +	  * @return SASL mechanism +	  */ +	shared_ptr <SASLMechanism> getMechanism(); + +	/** Return the SASL context. +	  * +	  * @return SASL context +	  */ +	shared_ptr <SASLContext> getContext(); + +	/** Perform one step of SASL authentication. Accept data from the +	  * server (challenge), process it and return data to be returned +	  * in response to the server. +	  * +	  * If the challenge is empty (challengeLen == 0), the initial +	  * response is returned, if the mechanism has one. +	  * +	  * @param challenge challenge sent from the server +	  * @param challengeLen length of challenge +	  * @param response response to send to the server (allocated by +	  * this function, free with delete[]) +	  * @param responseLen length of response buffer +	  * @return true if authentication terminated successfully, or +	  * false if the authentication process should continue +	  * @throw exceptions::sasl_exception if an error occurred during +	  * authentication (in this case, the values in 'response' and +	  * 'responseLen' are undetermined) +	  */ +	bool evaluateChallenge( +		const byte_t* challenge, +		const size_t challengeLen, +		byte_t** response, +		size_t* responseLen +	); + +	/** Return a socket in which transmitted data is integrity +	  * and/or privacy protected, depending on the QOP (Quality of +	  * Protection) negotiated during the SASL authentication. +	  * +	  * @param sok socket to wrap +	  * @return secured socket +	  */ +	shared_ptr <net::socket> getSecuredSocket(const shared_ptr <net::socket>& sok); + +	/** Return the name of the service which is using this +	  * SASL session (eg. "imap"). This value should be returned +	  * by the authenticator when INFO_SERVICE is requested. +	  * +	  * @return service name +	  */ +	const string getServiceName() const; + +private: + +	SASLSession( +		const string& serviceName, +		const shared_ptr <SASLContext>& ctx, +		const shared_ptr <authenticator>& auth, +		const shared_ptr <SASLMechanism>& mech +	); + + +	const string m_serviceName; + +	shared_ptr <SASLContext> m_context; +	shared_ptr <authenticator> m_auth; +	shared_ptr <SASLMechanism> m_mech; + +#ifdef GSASL_VERSION +	Gsasl* m_gsaslContext; +	Gsasl_session* m_gsaslSession; + +	static int gsaslCallback(Gsasl* ctx, Gsasl_session* sctx, Gsasl_property prop); +#else +	void* m_gsaslContext; +	void* m_gsaslSession; + +	static int gsaslCallback(void* ctx, void* sctx, int prop); +#endif // GSASL_VERSION + +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLSESSION_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/SASLSocket.cpp b/vmime-master/src/vmime/security/sasl/SASLSocket.cpp new file mode 100644 index 0000000..0dbafd8 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLSocket.cpp @@ -0,0 +1,273 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include "vmime/security/sasl/SASLSocket.hpp" +#include "vmime/security/sasl/SASLSession.hpp" + +#include "vmime/utility/stringUtils.hpp" + +#include "vmime/exception.hpp" + +#include <algorithm> +#include <cstring> + +#include <gsasl.h> + + +namespace vmime { +namespace security { +namespace sasl { + + + +SASLSocket::SASLSocket( +	const shared_ptr <SASLSession>& sess, +	const shared_ptr <net::socket>& wrapped +) +	: m_session(sess), +	  m_wrapped(wrapped), +	  m_pendingBuffer(0), +	  m_pendingPos(0), +	  m_pendingLen(0) { + +} + + +SASLSocket::~SASLSocket() { + +	if (m_pendingBuffer) { +		delete [] m_pendingBuffer; +	} +} + + +void SASLSocket::connect(const string& address, const port_t port) { + +	m_wrapped->connect(address, port); +} + + +void SASLSocket::disconnect() { + +	m_wrapped->disconnect(); +} + + +bool SASLSocket::isConnected() const { + +	return m_wrapped->isConnected(); +} + + +size_t SASLSocket::getBlockSize() const { + +	return m_wrapped->getBlockSize(); +} + + +const string SASLSocket::getPeerName() const { + +	return m_wrapped->getPeerName(); +} + + +const string SASLSocket::getPeerAddress() const { + +	return m_wrapped->getPeerAddress(); +} + + +shared_ptr <net::timeoutHandler> SASLSocket::getTimeoutHandler() { + +	return m_wrapped->getTimeoutHandler(); +} + + +void SASLSocket::setTracer(const shared_ptr <net::tracer>& tracer) { + +	m_wrapped->setTracer(tracer); +} + + +shared_ptr <net::tracer> SASLSocket::getTracer() { + +	return m_wrapped->getTracer(); +} + + +bool SASLSocket::waitForRead(const int msecs) { + +	return m_wrapped->waitForRead(msecs); +} + + +bool SASLSocket::waitForWrite(const int msecs) { + +	return m_wrapped->waitForWrite(msecs); +} + + +void SASLSocket::receive(string& buffer) { + +	const size_t n = receiveRaw(m_recvBuffer, sizeof(m_recvBuffer)); + +	buffer = utility::stringUtils::makeStringFromBytes(m_recvBuffer, n); +} + + +size_t SASLSocket::receiveRaw(byte_t* buffer, const size_t count) { + +	if (m_pendingLen != 0) { + +		const size_t copyLen = +			(count >= m_pendingLen ? m_pendingLen : count); + +		std::copy( +			m_pendingBuffer + m_pendingPos, +			m_pendingBuffer + m_pendingPos + copyLen, +			buffer +		); + +		m_pendingLen -= copyLen; +		m_pendingPos += copyLen; + +		if (m_pendingLen == 0) { + +			delete [] m_pendingBuffer; + +			m_pendingBuffer = 0; +			m_pendingPos = 0; +			m_pendingLen = 0; +		} + +		return copyLen; +	} + +	const size_t n = m_wrapped->receiveRaw(buffer, count); + +	byte_t* output = 0; +	size_t outputLen = 0; + +	m_session->getMechanism()->decode(m_session, buffer, n, &output, &outputLen); + +	// If we can not copy all decoded data into the output buffer, put +	// remaining data into a pending buffer for next calls to receive() +	if (outputLen > count) { + +		std::copy(output, output + count, buffer); + +		m_pendingBuffer = output; +		m_pendingLen = outputLen; +		m_pendingPos = count; + +		return count; + +	} else { + +		std::copy(output, output + outputLen, buffer); + +		delete [] output; + +		return outputLen; +	} +} + + +void SASLSocket::send(const string& buffer) { + +	sendRaw(reinterpret_cast <const byte_t*>(buffer.data()), buffer.length()); +} + + +void SASLSocket::send(const char* str) { + +	sendRaw(reinterpret_cast <const byte_t*>(str), strlen(str)); +} + + +void SASLSocket::sendRaw(const byte_t* buffer, const size_t count) { + +	byte_t* output = 0; +	size_t outputLen = 0; + +	m_session->getMechanism()->encode( +		m_session, buffer, count, &output, &outputLen +	); + +	try { + +		m_wrapped->sendRaw(output, outputLen); + +	} catch (...) { + +		delete [] output; +		throw; +	} + +	delete [] output; +} + + +size_t SASLSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) { + +	byte_t* output = 0; +	size_t outputLen = 0; + +	m_session->getMechanism()->encode(m_session, buffer, count, &output, &outputLen); + +	size_t bytesSent = 0; + +	try { + +		bytesSent = m_wrapped->sendRawNonBlocking(output, outputLen); + +	} catch (...) { + +		delete [] output; +		throw; +	} + +	delete [] output; + +	return bytesSent; +} + + +unsigned int SASLSocket::getStatus() const { + +	return m_wrapped->getStatus(); +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/SASLSocket.hpp b/vmime-master/src/vmime/security/sasl/SASLSocket.hpp new file mode 100644 index 0000000..ac0e89e --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/SASLSocket.hpp @@ -0,0 +1,108 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SASLSOCKET_HPP_INCLUDED +#define VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/types.hpp" + +#include "vmime/net/socket.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLSession; + + +/** A socket which provides data integrity and/or privacy protection. +  */ +class VMIME_EXPORT SASLSocket : public net::socket { + +public: + +	SASLSocket( +		const shared_ptr <SASLSession>& sess, +		const shared_ptr <net::socket>& wrapped +	); + +	~SASLSocket(); + +	void connect(const string& address, const port_t port); +	void disconnect(); + +	bool isConnected() const; + +	bool waitForRead(const int msecs = 30000); +	bool waitForWrite(const int msecs = 30000); + +	void receive(string& buffer); +	size_t receiveRaw(byte_t* buffer, const size_t count); + +	void send(const string& buffer); +	void send(const char* str); +	void sendRaw(const byte_t* buffer, const size_t count); +	size_t sendRawNonBlocking(const byte_t* buffer, const size_t count); + +	size_t getBlockSize() const; + +	unsigned int getStatus() const; + +	const string getPeerName() const; +	const string getPeerAddress() const; + +	shared_ptr <net::timeoutHandler> getTimeoutHandler(); + +	void setTracer(const shared_ptr <net::tracer>& tracer); +	shared_ptr <net::tracer> getTracer(); + +private: + +	shared_ptr <SASLSession> m_session; +	shared_ptr <net::socket> m_wrapped; + +	byte_t* m_pendingBuffer; +	size_t m_pendingPos; +	size_t m_pendingLen; + +	byte_t m_recvBuffer[65536]; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_SASLSOCKET_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp new file mode 100644 index 0000000..ecc715a --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.cpp @@ -0,0 +1,99 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include "vmime/security/sasl/XOAuth2SASLAuthenticator.hpp" + +#include "vmime/security/sasl/SASLMechanism.hpp" +#include "vmime/security/sasl/SASLSession.hpp" +#include "vmime/security/sasl/SASLContext.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +XOAuth2SASLAuthenticator::XOAuth2SASLAuthenticator(const Mode mode) +	: m_mode(mode) { + +} + + +XOAuth2SASLAuthenticator::~XOAuth2SASLAuthenticator() { + +} + + +const std::vector <shared_ptr <SASLMechanism> > +	XOAuth2SASLAuthenticator::getAcceptableMechanisms( +		const std::vector <shared_ptr <SASLMechanism> >& available, +		const shared_ptr <SASLMechanism>& suggested +	) const { + +	if (m_mode == MODE_EXCLUSIVE) { + +		std::vector <shared_ptr <SASLMechanism> > mechs; + +		for (size_t i = available.size() ; i != 0 ; --i) { + +			shared_ptr <SASLMechanism> mech = available[i - 1]; + +			if ("XOAUTH2" == mech->getName()) { +				// Only allow XOAuth2 +				mechs.push_back(mech); +			} +		} + +		return mechs; + +	} else { + +		shared_ptr <SASLMechanism> newSuggested(suggested); + +		for (size_t i = available.size() ; i != 0 ; --i) { + +			shared_ptr <SASLMechanism> mech = available[i - 1]; + +			if ("XOAUTH2" == mech->getName()) { +				// Suggest using XOAuth2 +				newSuggested = mech; +			} +		} + +		return defaultSASLAuthenticator::getAcceptableMechanisms(available, newSuggested); +	} +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp new file mode 100644 index 0000000..e4d3d83 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLAuthenticator.hpp @@ -0,0 +1,77 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_XOAUTH2SASLAUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_SASL_XOAUTH2SASLAUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/security/sasl/defaultSASLAuthenticator.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +/** An authenticator that is capable of providing information +  * for XOAuth2 authentication mechanisms (username and access token). +  * This authenticator force using the XOAUTH2 mechanism. +  */ +class VMIME_EXPORT XOAuth2SASLAuthenticator : public defaultSASLAuthenticator { + +public: + +	enum Mode { +		MODE_SUGGEST,    /**< Try XOAUTH2 before other mechanisms. */ +		MODE_EXCLUSIVE   /**< Use XOAUTH2 and nothing else. */ +	}; + + +	XOAuth2SASLAuthenticator(const Mode mode); +	~XOAuth2SASLAuthenticator(); + +	const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms( +		const std::vector <shared_ptr <SASLMechanism> >& available, +		const shared_ptr <SASLMechanism>& suggested +	) const; + +private: + +	Mode m_mode; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_XOAUTH2SASLAUTHENTICATOR_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp new file mode 100644 index 0000000..e5ecd4b --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.cpp @@ -0,0 +1,155 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include "vmime/security/sasl/XOAuth2SASLMechanism.hpp" + +#include "vmime/security/sasl/SASLContext.hpp" +#include "vmime/security/sasl/SASLSession.hpp" + +#include "vmime/exception.hpp" + +#include <sstream> + + +namespace vmime { +namespace security { +namespace sasl { + + +XOAuth2SASLMechanism::XOAuth2SASLMechanism( +	const shared_ptr <SASLContext>& ctx, +	const string& /* name */ +) +	: m_context(ctx), +	  m_complete(false) { + +} + + +XOAuth2SASLMechanism::~XOAuth2SASLMechanism() { + +} + + +const string XOAuth2SASLMechanism::getName() const { + +	return "XOAUTH2"; +} + + +bool XOAuth2SASLMechanism::step( +	const shared_ptr <SASLSession>& sess, +	const byte_t* /* challenge */, +	const size_t /* challengeLen */, +	byte_t** response, +	size_t* responseLen +) { + +	// Build initial response +	// +	// The SASL XOAUTH2 initial client response has the following format: +	//    base64("user=" {User} "^Aauth=Bearer " {Access Token} "^A^A") + +	const std::string user(sess->getAuthenticator()->getUsername()); +	const std::string accessToken(sess->getAuthenticator()->getAccessToken()); + +	std::ostringstream initRespBytes; +	initRespBytes.write("user=", 5); +	initRespBytes.write(user.c_str(), user.length()); +	initRespBytes.write("\x01", 1); +	initRespBytes.write("auth=Bearer ", 12); +	initRespBytes.write(accessToken.c_str(), accessToken.length()); +	initRespBytes.write("\x01\x01", 2); + +	const std::string initResp = initRespBytes.str(); + +	// Set initial response +	byte_t* res = new byte_t[initResp.length()]; +	std::copy(initResp.c_str(), initResp.c_str() + initResp.length(), res); + +	*response = res; +	*responseLen = initResp.length(); +	m_complete = true; + +	return true; +} + + +bool XOAuth2SASLMechanism::isComplete() const { + +	return m_complete; +} + + +bool XOAuth2SASLMechanism::hasInitialResponse() const { + +	return true; +} + + +void XOAuth2SASLMechanism::encode( +	const shared_ptr <SASLSession>& /* sess */, +	const byte_t* input, +	const size_t inputLen, +	byte_t** output, +	size_t* outputLen +) { + +	// No encoding performed, just copy input bytes +	byte_t* res = new byte_t[inputLen]; +	std::copy(input, input + inputLen, res); + +	*outputLen = inputLen; +	*output = res; +} + + +void XOAuth2SASLMechanism::decode( +	const shared_ptr <SASLSession>& /* sess */, +	const byte_t* input, +	const size_t inputLen, +	byte_t** output, +	size_t* outputLen +) { + +	// No decoding performed, just copy input bytes +	byte_t* res = new byte_t[inputLen]; +	std::copy(input, input + inputLen, res); + +	*outputLen = inputLen; +	*output = res; +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp new file mode 100644 index 0000000..eacbb0a --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/XOAuth2SASLMechanism.hpp @@ -0,0 +1,102 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_XOAUTH2SASLMECHANISM_HPP_INCLUDED +#define VMIME_SECURITY_SASL_XOAUTH2SASLMECHANISM_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/security/sasl/SASLMechanism.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLContext; + + +/** SASL XOAUTH2 mechanism, used by GMail. +  */ +class VMIME_EXPORT XOAuth2SASLMechanism : public SASLMechanism { + +public: + +	XOAuth2SASLMechanism(const shared_ptr <SASLContext>& ctx, const string& name); +	~XOAuth2SASLMechanism(); + + +	const string getName() const; + +	bool step( +		const shared_ptr <SASLSession>& sess, +		const byte_t* challenge, +		const size_t challengeLen, +		byte_t** response, +		size_t* responseLen +	); + +	bool isComplete() const; + +	bool hasInitialResponse() const; + +	void encode( +		const shared_ptr <SASLSession>& sess, +		const byte_t* input, +		const size_t inputLen, +		byte_t** output, +		size_t* outputLen +	); + +	void decode( +		const shared_ptr <SASLSession>& sess, +		const byte_t* input, +		const size_t inputLen, +		byte_t** output, +		size_t* outputLen +	); + +private: + +	/** SASL context */ +	shared_ptr <SASLContext> m_context; + +	/** Authentication process status. */ +	bool m_complete; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_XOAUTH2SASLMECHANISM_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.cpp b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.cpp new file mode 100644 index 0000000..846e2cc --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.cpp @@ -0,0 +1,221 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include <gsasl.h> + +#include "vmime/security/sasl/builtinSASLMechanism.hpp" + +#include "vmime/security/sasl/SASLContext.hpp" +#include "vmime/security/sasl/SASLSession.hpp" + +#include "vmime/exception.hpp" + +#include <stdexcept> +#include <new> + + +namespace vmime { +namespace security { +namespace sasl { + + +builtinSASLMechanism::builtinSASLMechanism( +	const shared_ptr <SASLContext>& ctx, +	const string& name +) +	: m_context(ctx), +	  m_name(name), +	  m_complete(false) { + +} + + +builtinSASLMechanism::~builtinSASLMechanism() { + +} + + +const string builtinSASLMechanism::getName() const { + +	return m_name; +} + + +bool builtinSASLMechanism::step( +	const shared_ptr <SASLSession>& sess, +	const byte_t* challenge, +	const size_t challengeLen, +	byte_t** response, +	size_t* responseLen +) { + +	char* output = 0; +	size_t outputLen = 0; + +	const int result = gsasl_step( +		sess->m_gsaslSession, +		reinterpret_cast <const char*>(challenge), challengeLen, +		&output, &outputLen +	); + +	if (result == GSASL_OK || result == GSASL_NEEDS_MORE) { + +		byte_t* res = new byte_t[outputLen]; + +		for (size_t i = 0 ; i < outputLen ; ++i) { +			res[i] = output[i]; +		} + +		*response = res; +		*responseLen = outputLen; + +		gsasl_free(output); + +	} else { + +		*response = 0; +		*responseLen = 0; +	} + +	if (result == GSASL_OK) { + +		// Authentication process completed +		m_complete = true; +		return true; + +	} else if (result == GSASL_NEEDS_MORE) { + +		// Continue authentication process +		return false; + +	} else if (result == GSASL_MALLOC_ERROR) { + +		throw std::bad_alloc(); + +	} else { + +		throw exceptions::sasl_exception( +			"Error when processing challenge: " +			+ SASLContext::getErrorMessage("gsasl_step", result) +		); +	} +} + + +bool builtinSASLMechanism::isComplete() const { + +	return m_complete; +} + + +bool builtinSASLMechanism::hasInitialResponse() const { + +	// It seems GNU SASL does not support initial response +	return false; +} + + +void builtinSASLMechanism::encode( +	const shared_ptr <SASLSession>& sess, +	const byte_t* input, +	const size_t inputLen, +	byte_t** output, +	size_t* outputLen +) { + +	char* coutput = 0; +	size_t coutputLen = 0; + +	if (gsasl_encode(sess->m_gsaslSession, reinterpret_cast <const char*>(input), inputLen, +			&coutput, &coutputLen) != GSASL_OK) { + +		throw exceptions::sasl_exception("Encoding error."); +	} + +	try { + +		byte_t* res = new byte_t[coutputLen]; + +		std::copy(coutput, coutput + coutputLen, res); + +		*output = res; +		*outputLen = static_cast <int>(coutputLen); + +	} catch (...) { + +		gsasl_free(coutput); +		throw; +	} + +	gsasl_free(coutput); +} + + +void builtinSASLMechanism::decode( +	const shared_ptr <SASLSession>& sess, +	const byte_t* input, +	const size_t inputLen, +	byte_t** output, +	size_t* outputLen +) { + +	char* coutput = 0; +	size_t coutputLen = 0; + +	try { + +		if (gsasl_decode(sess->m_gsaslSession, reinterpret_cast <const char*>(input), inputLen, +				&coutput, &coutputLen) != GSASL_OK) { + +			throw exceptions::sasl_exception("Decoding error."); +		} + +		byte_t* res = new byte_t[coutputLen]; + +		std::copy(coutput, coutput + coutputLen, res); + +		*output = res; +		*outputLen = static_cast <int>(coutputLen); + +	} catch (...) { + +		gsasl_free(coutput); +		throw; +	} + +	gsasl_free(coutput); +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.hpp b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.hpp new file mode 100644 index 0000000..2e412d6 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/builtinSASLMechanism.hpp @@ -0,0 +1,105 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED +#define VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/security/sasl/SASLMechanism.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +class SASLContext; + + +/** A built-in authentication mechanism that relies on +  * the GNU SASL library. +  */ +class VMIME_EXPORT builtinSASLMechanism : public SASLMechanism { + +public: + +	builtinSASLMechanism(const shared_ptr <SASLContext>& ctx, const string& name); +	~builtinSASLMechanism(); + + +	const string getName() const; + +	bool step( +		const shared_ptr <SASLSession>& sess, +		const byte_t* challenge, +		const size_t challengeLen, +		byte_t** response, size_t* responseLen +	); + +	bool isComplete() const; + +	bool hasInitialResponse() const; + +	void encode( +		const shared_ptr <SASLSession>& sess, +		const byte_t* input, +		const size_t inputLen, +		byte_t** output, +		size_t* outputLen +	); + +	void decode( +		const shared_ptr <SASLSession>& sess, +		const byte_t* input, +		const size_t inputLen, +		byte_t** output, +		size_t* outputLen +	); + +private: + +	/** SASL context */ +	shared_ptr <SASLContext> m_context; + +	/** Mechanism name */ +	const string m_name; + +	/** Authentication process status. */ +	bool m_complete; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_BUILTINSASLMECHANISM_HPP_INCLUDED diff --git a/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.cpp b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.cpp new file mode 100644 index 0000000..ebd7e68 --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.cpp @@ -0,0 +1,159 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_SUPPORT + + +#include "vmime/security/sasl/defaultSASLAuthenticator.hpp" + +#include "vmime/security/sasl/SASLMechanism.hpp" +#include "vmime/security/sasl/SASLSession.hpp" +#include "vmime/security/sasl/SASLContext.hpp" + +#include "vmime/net/service.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +defaultSASLAuthenticator::defaultSASLAuthenticator() { + +} + + +defaultSASLAuthenticator::~defaultSASLAuthenticator() { + +} + + +const std::vector <shared_ptr <SASLMechanism> > defaultSASLAuthenticator::getAcceptableMechanisms( +	const std::vector <shared_ptr <SASLMechanism> >& available, +	const shared_ptr <SASLMechanism>& suggested +) const { + +	if (suggested) { + +		std::vector <shared_ptr <SASLMechanism> > res; + +		res.push_back(suggested); + +		for (unsigned int i = 0 ; i < available.size() ; ++i) { + +			if (available[i]->getName() != suggested->getName()) { +				res.push_back(available[i]); +			} +		} + +		return res; + +	} else { + +		return available; +	} +} + + +const string defaultSASLAuthenticator::getUsername() const { + +	return m_default.getUsername(); +} + + +const string defaultSASLAuthenticator::getPassword() const { + +	return m_default.getPassword(); +} + + +const string defaultSASLAuthenticator::getAccessToken() const { + +	return m_default.getAccessToken(); +} + + +const string defaultSASLAuthenticator::getHostname() const { + +	return m_default.getHostname(); +} + + +const string defaultSASLAuthenticator::getAnonymousToken() const { + +	return m_default.getAnonymousToken(); +} + + +const string defaultSASLAuthenticator::getServiceName() const { + +	return m_saslSession.lock()->getServiceName(); +} + + +void defaultSASLAuthenticator::setService(const shared_ptr <net::service>& serv) { + +	m_service = serv; +	m_default.setService(serv); +} + + +weak_ptr <net::service> defaultSASLAuthenticator::getService() const { + +	return m_service; +} + + +void defaultSASLAuthenticator::setSASLSession(const shared_ptr <SASLSession>& sess) { + +	m_saslSession = sess; +} + + +shared_ptr <SASLSession> defaultSASLAuthenticator::getSASLSession() const { + +	return m_saslSession.lock(); +} + + +void defaultSASLAuthenticator::setSASLMechanism(const shared_ptr <SASLMechanism>& mech) { + +	m_saslMech = mech; +} + + +shared_ptr <SASLMechanism> defaultSASLAuthenticator::getSASLMechanism() const { + +	return m_saslMech; +} + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT diff --git a/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.hpp b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.hpp new file mode 100644 index 0000000..368e9ef --- /dev/null +++ b/vmime-master/src/vmime/security/sasl/defaultSASLAuthenticator.hpp @@ -0,0 +1,91 @@ +// +// VMime library (http://www.vmime.org) +// Copyright (C) 2002 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_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED +#define VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED + + +#include "vmime/config.hpp" + + +#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + + +#include "vmime/security/sasl/SASLAuthenticator.hpp" +#include "vmime/security/defaultAuthenticator.hpp" + + +namespace vmime { +namespace security { +namespace sasl { + + +/** An authenticator that is capable of providing information +  * for simple authentication mechanisms (username and password). +  */ +class VMIME_EXPORT defaultSASLAuthenticator : public SASLAuthenticator { + +public: + +	defaultSASLAuthenticator(); +	~defaultSASLAuthenticator(); + +	const std::vector <shared_ptr <SASLMechanism> > getAcceptableMechanisms( +		const std::vector <shared_ptr <SASLMechanism> >& available, +		const shared_ptr <SASLMechanism>& suggested +	) const; + +	const string getUsername() const; +	const string getPassword() const; +	const string getHostname() const; +	const string getAnonymousToken() const; +	const string getServiceName() const; +	const string getAccessToken() const; + +	void setService(const shared_ptr <net::service>& serv); +	weak_ptr <net::service> getService() const; + +	void setSASLSession(const shared_ptr <SASLSession>& sess); +	shared_ptr <SASLSession> getSASLSession() const; + +	void setSASLMechanism(const shared_ptr <SASLMechanism>& mech); +	shared_ptr <SASLMechanism> getSASLMechanism() const; + +private: + +	defaultAuthenticator m_default; + +	weak_ptr <net::service> m_service; +	weak_ptr <SASLSession> m_saslSession; +	shared_ptr <SASLMechanism> m_saslMech; +}; + + +} // sasl +} // security +} // vmime + + +#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_SASL_SUPPORT + +#endif // VMIME_SECURITY_SASL_DEFAULTSASLAUTHENTICATOR_HPP_INCLUDED | 
