1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-08-01 21:51:48 +02:00

Major plugin refactor and cleanup.

Switched to POCO library for unified platform/library interface.
Deprecated the external module API. It was creating more problems than solving.
Removed most built-in libraries in favor of system libraries for easier maintenance.
Cleaned and secured code with help from static analyzers.
This commit is contained in:
Sandu Liviu Catalin
2021-01-30 08:51:39 +02:00
parent e0e34b4030
commit 4a6bfc086c
6219 changed files with 1209835 additions and 454916 deletions

View File

@@ -0,0 +1,52 @@
//
// AcceptCertificateHandler.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: AcceptCertificateHandler
//
// Definition of the AcceptCertificateHandler class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_AcceptCertificateHandler_INCLUDED
#define NetSSL_AcceptCertificateHandler_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/InvalidCertificateHandler.h"
namespace Poco {
namespace Net {
class NetSSL_API AcceptCertificateHandler: public InvalidCertificateHandler
/// A AcceptCertificateHandler is invoked whenever an error
/// occurs verifying the certificate. It always accepts
/// the certificate.
///
/// Should be using for testing purposes only.
{
public:
AcceptCertificateHandler(bool handleErrorsOnServerSide);
/// Creates the AcceptCertificateHandler
virtual ~AcceptCertificateHandler();
/// Destroys the AcceptCertificateHandler.
void onInvalidCertificate(const void* pSender, VerificationErrorArgs& errorCert);
/// Receives the questionable certificate in parameter errorCert. If one wants to accept the
/// certificate, call errorCert.setIgnoreError(true).
};
} } // namespace Poco::Net
#endif // NetSSL_AcceptCertificateHandler_INCLUDED

View File

@@ -0,0 +1,93 @@
//
// CertificateHandlerFactory.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: CertificateHandlerFactory
//
// Definition of the CertificateHandlerFactory class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_CertificateHandlerFactory_INCLUDED
#define NetSSL_CertificateHandlerFactory_INCLUDED
#include "Poco/Net/NetSSL.h"
namespace Poco {
namespace Net {
class InvalidCertificateHandler;
class NetSSL_API CertificateHandlerFactory
/// A CertificateHandlerFactory is responsible for creating InvalidCertificateHandlers.
///
/// You don't need to access this class directly. Use the macro
/// POCO_REGISTER_CHFACTORY(namespace, InvalidCertificateHandlerName)
/// instead (see the documentation of InvalidCertificateHandler for an example).
{
public:
CertificateHandlerFactory();
/// Creates the CertificateHandlerFactory.
virtual ~CertificateHandlerFactory();
/// Destroys the CertificateHandlerFactory.
virtual InvalidCertificateHandler* create(bool server) const = 0;
/// Creates a new InvalidCertificateHandler. Set server to true if the certificate handler is used on the server side.
};
class NetSSL_API CertificateHandlerFactoryRegistrar
/// Registrar class which automatically registers CertificateHandlerFactory at the CertificateHandlerFactoryMgr.
/// You don't need to access this class directly. Use the macro
/// POCO_REGISTER_CHFACTORY(namespace, InvalidCertificateHandlerName)
/// instead (see the documentation of InvalidCertificateHandler for an example).
{
public:
CertificateHandlerFactoryRegistrar(const std::string& name, CertificateHandlerFactory* pFactory);
/// Registers the CertificateHandlerFactory with the given name at the factory manager.
virtual ~CertificateHandlerFactoryRegistrar();
/// Destroys the CertificateHandlerFactoryRegistrar.
};
template <typename T>
class CertificateHandlerFactoryImpl: public Poco::Net::CertificateHandlerFactory
{
public:
CertificateHandlerFactoryImpl()
{
}
~CertificateHandlerFactoryImpl()
{
}
InvalidCertificateHandler* create(bool server) const
{
return new T(server);
}
};
} } // namespace Poco::Net
// DEPRECATED: register the factory directly at the FactoryMgr:
// Poco::Net::SSLManager::instance().certificateHandlerFactoryMgr().setFactory(name, new Poco::Net::CertificateHandlerFactoryImpl<MyConsoleHandler>());
#define POCO_REGISTER_CHFACTORY(API, PKCLS) \
static Poco::Net::CertificateHandlerFactoryRegistrar aRegistrar(std::string(#PKCLS), new Poco::Net::CertificateHandlerFactoryImpl<PKCLS>());
#endif // NetSSL_CertificateHandlerFactory_INCLUDED

View File

@@ -0,0 +1,64 @@
//
// CertificateHandlerFactoryMgr.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: CertificateHandlerFactoryMgr
//
// Definition of the CertificateHandlerFactoryMgr class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_CertificateHandlerFactoryMgr_INCLUDED
#define NetSSL_CertificateHandlerFactoryMgr_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/CertificateHandlerFactory.h"
#include "Poco/SharedPtr.h"
#include <map>
namespace Poco {
namespace Net {
class NetSSL_API CertificateHandlerFactoryMgr
/// A CertificateHandlerFactoryMgr manages all existing CertificateHandlerFactories.
{
public:
using FactoriesMap = std::map<std::string, Poco::SharedPtr<CertificateHandlerFactory>>;
CertificateHandlerFactoryMgr();
/// Creates the CertificateHandlerFactoryMgr.
~CertificateHandlerFactoryMgr();
/// Destroys the CertificateHandlerFactoryMgr.
void setFactory(const std::string& name, CertificateHandlerFactory* pFactory);
/// Registers the factory. Class takes ownership of the pointer.
/// If a factory with the same name already exists, an exception is thrown.
bool hasFactory(const std::string& name) const;
/// Returns true if for the given name a factory is already registered
const CertificateHandlerFactory* getFactory(const std::string& name) const;
/// Returns NULL if for the given name a factory does not exist, otherwise the factory is returned
void removeFactory(const std::string& name);
/// Removes the factory from the manager.
private:
FactoriesMap _factories;
};
} } // namespace Poco::Net
#endif // NetSSL_CertificateHandlerFactoryMgr_INCLUDED

View File

@@ -0,0 +1,50 @@
//
// ConsoleCertificateHandler.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: ConsoleCertificateHandler
//
// Definition of the ConsoleCertificateHandler class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_ConsoleCertificateHandler_INCLUDED
#define NetSSL_ConsoleCertificateHandler_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/InvalidCertificateHandler.h"
namespace Poco {
namespace Net {
class NetSSL_API ConsoleCertificateHandler: public InvalidCertificateHandler
/// A ConsoleCertificateHandler is invoked whenever an error occurs verifying the certificate.
///
/// The certificate is printed to stdout and the user is asked via console if he wants to accept it.
{
public:
ConsoleCertificateHandler(bool handleErrorsOnServerSide);
/// Creates the ConsoleCertificateHandler.
virtual ~ConsoleCertificateHandler();
/// Destroys the ConsoleCertificateHandler.
void onInvalidCertificate(const void* pSender, VerificationErrorArgs& errorCert);
/// Prints the certificate to stdout and waits for user input on the console
/// to decide if a certificate should be accepted/rejected.
};
} } // namespace Poco::Net
#endif // NetSSL_ConsoleCertificateHandler_INCLUDED

View File

@@ -0,0 +1,462 @@
//
// Context.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: Context
//
// Definition of the Context class.
//
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_Context_INCLUDED
#define NetSSL_Context_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/SocketDefs.h"
#include "Poco/Crypto/X509Certificate.h"
#include "Poco/Crypto/EVPPKey.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/RefCountedObject.h"
#include "Poco/AutoPtr.h"
#include <openssl/ssl.h>
#include <cstdlib>
namespace Poco {
namespace Net {
class NetSSL_API Context: public Poco::RefCountedObject
/// This class encapsulates context information for
/// an SSL server or client, such as the certificate
/// verification mode and the location of certificates
/// and private key files, as well as the list of
/// supported ciphers.
///
/// The Context class is also used to control
/// SSL session caching on the server and client side.
///
/// A Note Regarding TLSv1.3 Support:
///
/// TLSv1.3 support requires at least OpenSSL version 1.1.1.
/// Make sure that the TLSv1.3 cipher suites are enabled:
///
/// - TLS_AES_256_GCM_SHA384
/// - TLS_CHACHA20_POLY1305_SHA256
/// - TLS_AES_128_GCM_SHA256
/// - TLS_AES_128_CCM_8_SHA256
/// - TLS_AES_128_CCM_SHA256
///
/// The first three of the above cipher suites should be enabled
/// by default in OpenSSL if you do not provide an explicit
/// cipher configuration (cipherList).
{
public:
using Ptr = Poco::AutoPtr<Context>;
enum Usage
{
TLS_CLIENT_USE, /// Context is used by a client for TLSv1 or higher. Use requireMinimumProtocol() or disableProtocols() to disable undesired older versions.
TLS_SERVER_USE, /// Context is used by a client for TLSv1 or higher. Use requireMinimumProtocol() or disableProtocols() to disable undesired older versions.
CLIENT_USE, /// DEPRECATED. Context is used by a client.
SERVER_USE, /// DEPRECATED. Context is used by a server.
TLSV1_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.
TLSV1_SERVER_USE, /// DEPRECATED. Context is used by a server requiring TLSv1.
TLSV1_1_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.1 (OpenSSL 1.0.0 or newer).
TLSV1_1_SERVER_USE, /// DEPRECATED. Context is used by a server requiring TLSv1.1 (OpenSSL 1.0.0 or newer).
TLSV1_2_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.2 (OpenSSL 1.0.1 or newer).
TLSV1_2_SERVER_USE, /// DEPRECATED. Context is used by a server requiring TLSv1.2 (OpenSSL 1.0.1 or newer).
TLSV1_3_CLIENT_USE, /// DEPRECATED. Context is used by a client requiring TLSv1.3 (OpenSSL 1.1.1 or newer).
TLSV1_3_SERVER_USE /// DEPRECATED. Context is used by a server requiring TLSv1.3 (OpenSSL 1.1.1 or newer).
};
enum VerificationMode
{
VERIFY_NONE = SSL_VERIFY_NONE,
/// Server: The server will not send a client certificate
/// request to the client, so the client will not send a certificate.
///
/// Client: If not using an anonymous cipher (by default disabled),
/// the server will send a certificate which will be checked, but
/// the result of the check will be ignored.
VERIFY_RELAXED = SSL_VERIFY_PEER,
/// Server: The server sends a client certificate request to the
/// client. The certificate returned (if any) is checked.
/// If the verification process fails, the TLS/SSL handshake is
/// immediately terminated with an alert message containing the
/// reason for the verification failure.
///
/// Client: The server certificate is verified, if one is provided.
/// If the verification process fails, the TLS/SSL handshake is
/// immediately terminated with an alert message containing the
/// reason for the verification failure.
VERIFY_STRICT = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
/// Server: If the client did not return a certificate, the TLS/SSL
/// handshake is immediately terminated with a handshake failure
/// alert.
///
/// Client: Same as VERIFY_RELAXED.
VERIFY_ONCE = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE
/// Server: Only request a client certificate on the initial
/// TLS/SSL handshake. Do not ask for a client certificate
/// again in case of a renegotiation.
///
/// Client: Same as VERIFY_RELAXED.
};
enum Protocols
{
PROTO_SSLV2 = 0x01,
PROTO_SSLV3 = 0x02,
PROTO_TLSV1 = 0x04,
PROTO_TLSV1_1 = 0x08,
PROTO_TLSV1_2 = 0x10,
PROTO_TLSV1_3 = 0x20
};
struct NetSSL_API Params
{
Params();
/// Initializes the struct with default values.
std::string privateKeyFile;
/// Path to the private key file used for encryption.
/// Can be empty if no private key file is used.
std::string certificateFile;
/// Path to the certificate file (in PEM format).
/// If the private key and the certificate are stored in the same file, this
/// can be empty if privateKeyFile is given.
std::string caLocation;
/// Path to the file or directory containing the CA/root certificates.
/// Can be empty if the OpenSSL builtin CA certificates
/// are used (see loadDefaultCAs).
VerificationMode verificationMode;
/// Specifies whether and how peer certificates are validated.
/// Defaults to VERIFY_RELAXED.
int verificationDepth;
/// Sets the upper limit for verification chain sizes. Verification
/// will fail if a certificate chain larger than this is encountered.
/// Defaults to 9.
bool loadDefaultCAs;
/// Specifies whether the builtin CA certificates from OpenSSL are used.
/// Defaults to false.
std::string cipherList;
/// Specifies the supported ciphers in OpenSSL notation.
/// Defaults to "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH".
std::string dhParamsFile;
/// Specifies a file containing Diffie-Hellman parameters.
/// If empty, the default parameters are used.
bool dhUse2048Bits;
/// If set to true, will use 2048-bit MODP Group with 256-bit
/// prime order subgroup (RFC5114) instead of 1024-bit for DH.
std::string ecdhCurve;
/// OpenSSL 1.0.1 and earlier:
/// Specifies the name of the curve to use for ECDH, based
/// on the curve names specified in RFC 4492.
/// Defaults to "prime256v1".
/// OpenSSL 1.0.2 to 1.1.0:
/// Specifies the colon-separated list of curves
/// to be used for ECDH, based on the curve names
/// defined by OpenSSL, such as
/// "X448:X25519:P-521:P-384:P-256"
/// Defaults to the subset supported by the OpenSSL version
/// among the above.
/// OpenSSL 1.1.1 and above:
/// Specifies the colon-separated list of groups
/// (some of which can be curves) to be used for ECDH
/// and other TLSv1.3 ephemeral key negotiation, based
/// on the group names defined by OpenSSL. Defaults to
/// "X448:X25519:ffdhe4096:ffdhe3072:ffdhe2048:ffdhe6144:ffdhe8192:P-521:P-384:P-256"
};
Context(Usage usage, const Params& params);
/// Creates a Context using the given parameters.
///
/// * usage specifies whether the context is used by a client or server.
/// * params specifies the context parameters.
Context(
Usage usage,
const std::string& privateKeyFile,
const std::string& certificateFile,
const std::string& caLocation,
VerificationMode verificationMode = VERIFY_RELAXED,
int verificationDepth = 9,
bool loadDefaultCAs = false,
const std::string& cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
/// Creates a Context.
///
/// * usage specifies whether the context is used by a client or server.
/// * privateKeyFile contains the path to the private key file used for encryption.
/// Can be empty if no private key file is used.
/// * certificateFile contains the path to the certificate file (in PEM format).
/// If the private key and the certificate are stored in the same file, this
/// can be empty if privateKeyFile is given.
/// * caLocation contains the path to the file or directory containing the
/// CA/root certificates. Can be empty if the OpenSSL builtin CA certificates
/// are used (see loadDefaultCAs).
/// * verificationMode specifies whether and how peer certificates are validated.
/// * verificationDepth sets the upper limit for verification chain sizes. Verification
/// will fail if a certificate chain larger than this is encountered.
/// * loadDefaultCAs specifies whether the builtin CA certificates from OpenSSL are used.
/// * cipherList specifies the supported ciphers in OpenSSL notation.
///
/// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
/// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
/// event must be handled.
Context(
Usage usage,
const std::string& caLocation,
VerificationMode verificationMode = VERIFY_RELAXED,
int verificationDepth = 9,
bool loadDefaultCAs = false,
const std::string& cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
/// Creates a Context.
///
/// * usage specifies whether the context is used by a client or server.
/// * caLocation contains the path to the file or directory containing the
/// CA/root certificates. Can be empty if the OpenSSL builtin CA certificates
/// are used (see loadDefaultCAs).
/// * verificationMode specifies whether and how peer certificates are validated.
/// * verificationDepth sets the upper limit for verification chain sizes. Verification
/// will fail if a certificate chain larger than this is encountered.
/// * loadDefaultCAs specifies whether the builtin CA certificates from OpenSSL are used.
/// * cipherList specifies the supported ciphers in OpenSSL notation.
///
/// Note that a private key and/or certificate must be specified with
/// usePrivateKey()/useCertificate() before the Context can be used.
~Context();
/// Destroys the Context.
void useCertificate(const Poco::Crypto::X509Certificate& certificate);
/// Sets the certificate to be used by the Context.
///
/// To set-up a complete certificate chain, it might be
/// necessary to call addChainCertificate() to specify
/// additional certificates.
///
/// Note that useCertificate() must always be called before
/// usePrivateKey().
void addChainCertificate(const Poco::Crypto::X509Certificate& certificate);
/// Adds a certificate for certificate chain validation.
void addCertificateAuthority(const Poco::Crypto::X509Certificate& certificate);
/// Add one trusted certification authority to be used by the Context.
void usePrivateKey(const Poco::Crypto::RSAKey& key);
/// Sets the private key to be used by the Context.
///
/// Note that useCertificate() must always be called before
/// usePrivateKey().
///
/// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
/// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
/// event must be handled.
void usePrivateKey(const Poco::Crypto::EVPPKey &pkey);
/// Sets the private key to be used by the Context.
///
/// Note that useCertificate() must always be called before
/// usePrivateKey().
///
/// Note: If the private key is protected by a passphrase, a PrivateKeyPassphraseHandler
/// must have been setup with the SSLManager, or the SSLManager's PrivateKeyPassphraseRequired
/// event must be handled.
SSL_CTX* sslContext() const;
/// Returns the underlying OpenSSL SSL Context object.
Usage usage() const;
/// Returns whether the context is for use by a client or by a server
/// and whether TLSv1 is required.
bool isForServerUse() const;
/// Returns true iff the context is for use by a server.
Context::VerificationMode verificationMode() const;
/// Returns the verification mode.
void enableSessionCache(bool flag = true);
/// Enable or disable SSL/TLS session caching.
/// For session caching to work, it must be enabled
/// on the server, as well as on the client side.
///
/// The default is disabled session caching.
///
/// To enable session caching on the server side, use the
/// two-argument version of this method to specify
/// a session ID context.
void enableSessionCache(bool flag, const std::string& sessionIdContext);
/// Enables or disables SSL/TLS session caching on the server.
/// For session caching to work, it must be enabled
/// on the server, as well as on the client side.
///
/// SessionIdContext contains the application's unique
/// session ID context, which becomes part of each
/// session identifier generated by the server within this
/// context. SessionIdContext can be an arbitrary sequence
/// of bytes with a maximum length of SSL_MAX_SSL_SESSION_ID_LENGTH.
///
/// A non-empty sessionIdContext should be specified even if
/// session caching is disabled to avoid problems with clients
/// requesting to reuse a session (e.g. Firefox 3.6).
///
/// This method may only be called on SERVER_USE Context objects.
bool sessionCacheEnabled() const;
/// Returns true iff the session cache is enabled.
void setSessionCacheSize(std::size_t size);
/// Sets the maximum size of the server session cache, in number of
/// sessions. The default size (according to OpenSSL documentation)
/// is 1024*20, which may be too large for many applications,
/// especially on embedded platforms with limited memory.
///
/// Specifying a size of 0 will set an unlimited cache size.
///
/// This method may only be called on SERVER_USE Context objects.
std::size_t getSessionCacheSize() const;
/// Returns the current maximum size of the server session cache.
///
/// This method may only be called on SERVER_USE Context objects.
void setSessionTimeout(long seconds);
/// Sets the timeout (in seconds) of cached sessions on the server.
/// A cached session will be removed from the cache if it has
/// not been used for the given number of seconds.
///
/// This method may only be called on SERVER_USE Context objects.
long getSessionTimeout() const;
/// Returns the timeout (in seconds) of cached sessions on the server.
///
/// This method may only be called on SERVER_USE Context objects.
void flushSessionCache();
/// Flushes the SSL session cache on the server.
///
/// This method may only be called on SERVER_USE Context objects.
void enableExtendedCertificateVerification(bool flag = true);
/// Enable or disable the automatic post-connection
/// extended certificate verification.
///
/// See X509Certificate::verify() for more information.
bool extendedCertificateVerificationEnabled() const;
/// Returns true iff automatic extended certificate
/// verification is enabled.
void disableStatelessSessionResumption();
/// Newer versions of OpenSSL support RFC 4507 tickets for stateless
/// session resumption.
///
/// The feature can be disabled by calling this method.
void disableProtocols(int protocols);
/// Disables the given protocols.
///
/// The protocols to be disabled are specified by OR-ing
/// values from the Protocols enumeration, e.g.:
///
/// context.disableProtocols(PROTO_SSLV2 | PROTO_SSLV3);
void requireMinimumProtocol(Protocols protocol);
/// Disables all protocol version lower than the given one.
/// To require at least TLS 1.2 or later:
///
/// context.requireMinimumProtocol(PROTO_TLSV1_2);
void preferServerCiphers();
/// When choosing a cipher, use the server's preferences instead of the client
/// preferences. When not called, the SSL server will always follow the clients
/// preferences. When called, the SSL/TLS server will choose following its own
/// preferences.
private:
void init(const Params& params);
/// Initializes the Context with the given parameters.
void initDH(bool use2048Bits, const std::string& dhFile);
/// Initializes the Context with Diffie-Hellman parameters.
void initECDH(const std::string& curve);
/// Initializes the Context with Elliptic-Curve Diffie-Hellman key
/// exchange curve parameters.
void createSSLContext();
/// Create a SSL_CTX object according to Context configuration.
Usage _usage;
VerificationMode _mode;
SSL_CTX* _pSSLContext;
bool _extendedCertificateVerification;
};
//
// inlines
//
inline Context::Usage Context::usage() const
{
return _usage;
}
inline bool Context::isForServerUse() const
{
return _usage == SERVER_USE
|| _usage == TLS_SERVER_USE
|| _usage == TLSV1_SERVER_USE
|| _usage == TLSV1_1_SERVER_USE
|| _usage == TLSV1_2_SERVER_USE
|| _usage == TLSV1_3_SERVER_USE;
}
inline Context::VerificationMode Context::verificationMode() const
{
return _mode;
}
inline SSL_CTX* Context::sslContext() const
{
return _pSSLContext;
}
inline bool Context::extendedCertificateVerificationEnabled() const
{
return _extendedCertificateVerification;
}
} } // namespace Poco::Net
#endif // NetSSL_Context_INCLUDED

View File

@@ -0,0 +1,101 @@
//
// FTPSClientSession.h
//
// Library: NetSSL_OpenSSL
// Package: FTPS
// Module: FTPSClientSession
//
// Definition of the FTPSClientSession class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_FTPSClientSession_INCLUDED
#define NetSSL_FTPSClientSession_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/FTPClientSession.h"
namespace Poco {
namespace Net {
class NetSSL_API FTPSClientSession: public Poco::Net::FTPClientSession
/// This is an extension of FTPClientSession that supports
/// FTP over SSL/TLS using the AUTH SSL/AUTH TLS and PBSZ/PROT
/// commands according to RFC 4217.
{
public:
FTPSClientSession();
/// Creates an FTPSClientSession.
///
/// Passive mode will be used for data transfers.
explicit FTPSClientSession(Context::Ptr pContext);
/// Creates an FTPSClientSession using the given Context.
///
/// Passive mode will be used for data transfers.
FTPSClientSession(const StreamSocket& socket, bool readWelcomeMessage = true, bool enableFTPS = true, Context::Ptr pContext = nullptr);
/// Creates an FTPSClientSession using the given
/// connected socket for the control connection.
///
/// Passive mode will be used for data transfers.
FTPSClientSession(const std::string& host, Poco::UInt16 port = FTP_PORT, const std::string& username = "", const std::string& password = "", Context::Ptr pContext = nullptr);
/// Creates an FTPSClientSession using a socket connected
/// to the given host and port. If username is supplied,
/// login is attempted.
///
/// Passive mode will be used for data transfers.
virtual ~FTPSClientSession();
void enableFTPS(bool enable = true);
/// Enable or disable FTPS (FTP over SSL/TLS).
bool isSecure() const;
/// Returns true if the session is FTPS.
protected:
virtual StreamSocket establishDataConnection(const std::string& command, const std::string& arg);
/// Create secure data connection
virtual void receiveServerReadyReply();
/// Function that read server welcome message after connetion and set and make secure socket
private:
void beforeCreateDataSocket();
///Send commands to check if we can encrypt data socket
void afterCreateControlSocket();
///Send commands to make SSL negotiating of control channel
bool _enableFTPS = true;
bool _secureDataConnection = false;
Context::Ptr _pContext;
};
//
// inlines
//
inline bool FTPSClientSession::isSecure() const
{
if (_pControlSocket != nullptr)
return _pControlSocket->secure();
return false;
}
} } // namespace Poco::Net
#endif // #define NetSSL_FTPSClientSession_INCLUDED

View File

@@ -0,0 +1,74 @@
//
// FTPSStreamFactory.h
//
// Library: NetSSL_OpenSSL
// Package: FTPS
// Module: FTPSStreamFactory
//
// Definition of the FTPSStreamFactory class.
//
// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Net_FTPSStreamFactory_INCLUDED
#define Net_FTPSStreamFactory_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/HTTPSession.h"
#include "Poco/Net/FTPStreamFactory.h"
namespace Poco {
namespace Net {
class NetSSL_API FTPSStreamFactory: public Poco::Net::FTPStreamFactory
/// An implementation of the URIStreamFactory interface
/// that handles secure File Transfer Protocol (ftps) URIs
/// according to RFC 4217, based on the FTPSClientSession class.
///
/// The URI's path may end with an optional type specification
/// in the form (;type=<typecode>), where <typecode> is
/// one of a, i or d. If type=a, the file identified by the path
/// is transferred in ASCII (text) mode. If type=i, the file
/// is transferred in Image (binary) mode. If type=d, a directory
/// listing (in NLST format) is returned. This corresponds with
/// the FTP URL format specified in RFC 1738.
///
/// If the URI does not contain a username and password, the
/// username "anonymous" and the password "poco@localhost".
///
/// Note that ftps is a non-standard URI scheme.
{
public:
FTPSStreamFactory();
/// Creates the FTPSStreamFactory.
~FTPSStreamFactory();
/// Destroys the FTPSStreamFactory.
std::istream* open(const Poco::URI& uri);
/// Creates and opens a HTTP stream for the given URI.
/// The URI must be a ftps://... URI.
///
/// Throws a NetException if anything goes wrong.
static void registerFactory();
/// Registers the FTPSStreamFactory with the
/// default URIStreamOpener instance.
static void unregisterFactory();
/// Unregisters the FTPSStreamFactory with the
/// default URIStreamOpener instance.
};
} } // namespace Poco::Net
#endif // Net_FTPSStreamFactory_INCLUDED

View File

@@ -0,0 +1,165 @@
//
// HTTPSClientSession.h
//
// Library: NetSSL_OpenSSL
// Package: HTTPSClient
// Module: HTTPSClientSession
//
// Definition of the HTTPSClientSession class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_HTTPSClientSession_INCLUDED
#define NetSSL_HTTPSClientSession_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/Utility.h"
#include "Poco/Net/HTTPClientSession.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/Session.h"
#include "Poco/Net/X509Certificate.h"
namespace Poco {
namespace Net {
class SecureStreamSocket;
class HTTPRequest;
class HTTPResponse;
class NetSSL_API HTTPSClientSession: public HTTPClientSession
/// This class implements the client-side of
/// a HTTPS session.
///
/// To send a HTTPS request to a HTTPS server, first
/// instantiate a HTTPSClientSession object and
/// specify the server's host name and port number.
///
/// Then create a HTTPRequest object, fill it accordingly,
/// and pass it as argument to the sendRequest() method.
///
/// sendRequest() will return an output stream that can
/// be used to send the request body, if there is any.
///
/// After you are done sending the request body, create
/// a HTTPResponse object and pass it to receiveResponse().
///
/// This will return an input stream that can be used to
/// read the response body.
///
/// See RFC 2616 <http://www.faqs.org/rfcs/rfc2616.html> for more
/// information about the HTTP protocol.
///
/// Note that sending requests that neither contain a content length
/// field in the header nor are using chunked transfer encoding will
/// result in a SSL protocol violation, as the framework shuts down
/// the socket after sending the message body. No orderly SSL shutdown
/// will be performed in this case.
///
/// If session caching has been enabled for the Context object passed
/// to the HTTPSClientSession, the HTTPSClientSession class will
/// attempt to reuse a previously obtained Session object in
/// case of a reconnect.
{
public:
enum
{
HTTPS_PORT = 443
};
HTTPSClientSession();
/// Creates an unconnected HTTPSClientSession.
explicit HTTPSClientSession(const SecureStreamSocket& socket);
/// Creates a HTTPSClientSession using the given socket.
/// The socket must not be connected. The session
/// takes ownership of the socket.
HTTPSClientSession(const SecureStreamSocket& socket, Session::Ptr pSession);
/// Creates a HTTPSClientSession using the given socket.
/// The socket must not be connected. The session
/// takes ownership of the socket.
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
HTTPSClientSession(const std::string& host, Poco::UInt16 port = HTTPS_PORT);
/// Creates a HTTPSClientSession using the given host and port.
explicit HTTPSClientSession(Context::Ptr pContext);
/// Creates an unconnected HTTPSClientSession, using the
/// give SSL context.
HTTPSClientSession(Context::Ptr pContext, Session::Ptr pSession);
/// Creates an unconnected HTTPSClientSession, using the
/// give SSL context.
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
HTTPSClientSession(const std::string& host, Poco::UInt16 port, Context::Ptr pContext);
/// Creates a HTTPSClientSession using the given host and port,
/// using the given SSL context.
HTTPSClientSession(const std::string& host, Poco::UInt16 port, Context::Ptr pContext, Session::Ptr pSession);
/// Creates a HTTPSClientSession using the given host and port,
/// using the given SSL context.
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
~HTTPSClientSession();
/// Destroys the HTTPSClientSession and closes
/// the underlying socket.
bool secure() const;
/// Return true iff the session uses SSL or TLS,
/// or false otherwise.
X509Certificate serverCertificate();
/// Returns the server's certificate.
///
/// The certificate is available after the first request has been sent.
Session::Ptr sslSession();
/// Returns the SSL Session object for the current
/// connection, if session caching has been enabled for
/// the HTTPSClientSession's Context. A null pointer is
/// returned otherwise.
///
/// The Session object can be obtained after the first request has
/// been sent.
// HTTPSession
void abort();
protected:
void connect(const SocketAddress& address);
std::string proxyRequestPrefix() const;
void proxyAuthenticate(HTTPRequest& request);
int read(char* buffer, std::streamsize length);
private:
HTTPSClientSession(const HTTPSClientSession&);
HTTPSClientSession& operator = (const HTTPSClientSession&);
Context::Ptr _pContext;
Session::Ptr _pSession;
};
} } // namespace Poco::Net
#endif // Net_HTTPSClientSession_INCLUDED

View File

@@ -0,0 +1,65 @@
//
// HTTPSSessionInstantiator.h
//
// Library: NetSSL_OpenSSL
// Package: HTTPSClient
// Module: HTTPSSessionInstantiator
//
// Definition of the HTTPSSessionInstantiator class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Net_HTTPSSessionInstantiator_INCLUDED
#define Net_HTTPSSessionInstantiator_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/Utility.h"
#include "Poco/Net/HTTPSessionInstantiator.h"
#include "Poco/URI.h"
namespace Poco {
namespace Net {
class NetSSL_API HTTPSSessionInstantiator: public HTTPSessionInstantiator
/// The HTTPSessionInstantiator for HTTPSClientSession.
{
public:
HTTPSSessionInstantiator();
/// Creates the HTTPSSessionInstantiator.
HTTPSSessionInstantiator(Context::Ptr pContext);
/// Creates the HTTPSSessionInstantiator using the given SSL context.
~HTTPSSessionInstantiator();
/// Destroys the HTTPSSessionInstantiator.
HTTPClientSession* createClientSession(const Poco::URI& uri);
/// Creates a HTTPSClientSession for the given URI.
static void registerInstantiator();
/// Registers the instantiator with the global HTTPSessionFactory.
static void registerInstantiator(Context::Ptr pContext);
/// Registers the instantiator with the global HTTPSessionFactory using the given SSL context.
static void unregisterInstantiator();
/// Unregisters the factory with the global HTTPSessionFactory.
private:
Context::Ptr _pContext;
};
} } // namespace Poco::Net
#endif // Net_HTTPSSessionInstantiator_INCLUDED

View File

@@ -0,0 +1,83 @@
//
// HTTPSStreamFactory.h
//
// Library: NetSSL_OpenSSL
// Package: HTTPSClient
// Module: HTTPSStreamFactory
//
// Definition of the HTTPSStreamFactory class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_HTTPSStreamFactory_INCLUDED
#define NetSSL_HTTPSStreamFactory_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/HTTPSession.h"
#include "Poco/URIStreamFactory.h"
namespace Poco {
namespace Net {
class NetSSL_API HTTPSStreamFactory: public Poco::URIStreamFactory
/// An implementation of the URIStreamFactory interface
/// that handles secure Hyper-Text Transfer Protocol (https) URIs.
{
public:
HTTPSStreamFactory();
/// Creates the HTTPSStreamFactory.
HTTPSStreamFactory(const std::string& proxyHost, Poco::UInt16 proxyPort = HTTPSession::HTTP_PORT);
/// Creates the HTTPSStreamFactory.
///
/// HTTPS connections will use the given proxy.
HTTPSStreamFactory(const std::string& proxyHost, Poco::UInt16 proxyPort, const std::string& proxyUsername, const std::string& proxyPassword);
/// Creates the HTTPSStreamFactory.
///
/// HTTPS connections will use the given proxy and
/// will be authorized against the proxy using Basic authentication
/// with the given proxyUsername and proxyPassword.
~HTTPSStreamFactory();
/// Destroys the HTTPSStreamFactory.
std::istream* open(const Poco::URI& uri);
/// Creates and opens a HTTPS stream for the given URI.
/// The URI must be a https://... URI.
///
/// Throws a NetException if anything goes wrong.
static void registerFactory();
/// Registers the HTTPSStreamFactory with the
/// default URIStreamOpener instance.
static void unregisterFactory();
/// Unregisters the HTTPSStreamFactory with the
/// default URIStreamOpener instance.
private:
enum
{
MAX_REDIRECTS = 10
};
std::string _proxyHost;
Poco::UInt16 _proxyPort;
std::string _proxyUsername;
std::string _proxyPassword;
};
} } // namespace Poco::Net
#endif // Net_HTTPSStreamFactory_INCLUDED

View File

@@ -0,0 +1,80 @@
//
// InvalidCertificateHandler.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: InvalidCertificateHandler
//
// Definition of the InvalidCertificateHandler class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_InvalidCertificateHandler_INCLUDED
#define NetSSL_InvalidCertificateHandler_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/VerificationErrorArgs.h"
namespace Poco {
namespace Net {
class NetSSL_API InvalidCertificateHandler
/// A InvalidCertificateHandler is invoked whenever an error occurs verifying the certificate. It allows the user
/// to inspect and accept/reject the certificate.
/// One can install one's own InvalidCertificateHandler by implementing this interface. Note that
/// in the implementation file of the subclass the following code must be present (assuming you use the namespace My_API
/// and the name of your handler class is MyGuiHandler):
///
/// #include "Poco/Net/CertificateHandlerFactory.h"
/// ...
/// POCO_REGISTER_CHFACTORY(My_API, MyGuiHandler)
///
/// One can either set the handler directly in the startup code of the main method of ones application by calling
///
/// SSLManager::instance().initialize(mypassphraseHandler, myguiHandler, mySSLContext)
///
/// or in case one uses Poco::Util::Application one can rely on an XML configuration and put the following entry
/// under the path openSSL.invalidCertificateHandler:
///
/// <invalidCertificateHandler>
/// <name>MyGuiHandler<name>
/// <options>
/// [...] // Put optional config params for the handler here
/// </options>
/// </invalidCertificateHandler>
///
/// Note that the name of the InvalidCertificateHandler must be same as the one provided to the POCO_REGISTER_CHFACTORY macro.
{
public:
InvalidCertificateHandler(bool handleErrorsOnServerSide);
/// Creates the InvalidCertificateHandler.
///
/// Set handleErrorsOnServerSide to true if the certificate handler is used on the server side.
/// Automatically registers at one of the SSLManager::VerificationError events.
virtual ~InvalidCertificateHandler();
/// Destroys the InvalidCertificateHandler.
virtual void onInvalidCertificate(const void* pSender, VerificationErrorArgs& errorCert) = 0;
/// Receives the questionable certificate in parameter errorCert. If one wants to accept the
/// certificate, call errorCert.setIgnoreError(true).
protected:
bool _handleErrorsOnServerSide;
/// Stores if the certificate handler gets invoked by the server (i.e. a client certificate is wrong)
/// or the client (a server certificate is wrong)
};
} } // namespace Poco::Net
#endif // NetSSL_InvalidCertificateHandler_INCLUDED

View File

@@ -0,0 +1,47 @@
//
// KeyConsoleHandler.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: KeyConsoleHandler
//
// Definition of the KeyConsoleHandler class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_KeyConsoleHandler_INCLUDED
#define NetSSL_KeyConsoleHandler_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
namespace Poco {
namespace Net {
class NetSSL_API KeyConsoleHandler: public PrivateKeyPassphraseHandler
/// An implementation of PrivateKeyPassphraseHandler that
/// reads the key for a certificate from the console.
{
public:
KeyConsoleHandler(bool server);
/// Creates the KeyConsoleHandler.
~KeyConsoleHandler();
/// Destroys the KeyConsoleHandler.
void onPrivateKeyRequested(const void* pSender, std::string& privateKey);
};
} } // namespace Poco::Net
#endif // NetSSL_KeyConsoleHandler_INCLUDED

View File

@@ -0,0 +1,51 @@
//
// KeyFileHandler.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: KeyFileHandler
//
// Definition of the KeyFileHandler class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_KeyFileHandler_INCLUDED
#define NetSSL_KeyFileHandler_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
namespace Poco {
namespace Net {
class NetSSL_API KeyFileHandler: public PrivateKeyPassphraseHandler
/// An implementation of PrivateKeyPassphraseHandler that
/// reads the key for a certificate from a configuration file
/// under the path "openSSL.privateKeyPassphraseHandler.options.password".
{
public:
KeyFileHandler(bool server);
/// Creates the KeyFileHandler.
virtual ~KeyFileHandler();
/// Destroys the KeyFileHandler.
void onPrivateKeyRequested(const void* pSender, std::string& privateKey);
private:
static const std::string CFG_PRIV_KEY_FILE;
};
} } // namespace Poco::Net
#endif // NetSSL_KeyFileHandler_INCLUDED

View File

@@ -0,0 +1,94 @@
//
// NetSSL.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: OpenSSL
//
// Basic definitions for the Poco OpenSSL library.
// This file must be the first file included by every other OpenSSL
// header file.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_NetSSL_INCLUDED
#define NetSSL_NetSSL_INCLUDED
#include "Poco/Net/Net.h"
#include "Poco/Crypto/Crypto.h"
//
// The following block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the NetSSL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// NetSSL_API functions as being imported from a DLL, wheras this DLL sees symbols
// defined with this macro as being exported.
//
#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(POCO_DLL)
#if defined(NetSSL_EXPORTS)
#define NetSSL_API __declspec(dllexport)
#else
#define NetSSL_API __declspec(dllimport)
#endif
#endif
#if !defined(NetSSL_API)
#if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4)
#define NetSSL_API __attribute__ ((visibility ("default")))
#else
#define NetSSL_API
#endif
#endif
//
// Automatically link NetSSL and OpenSSL libraries.
//
#if defined(_MSC_VER)
#if !defined(POCO_NO_AUTOMATIC_LIBS)
#if !defined(NetSSL_EXPORTS)
#pragma comment(lib, "PocoNetSSL" POCO_LIB_SUFFIX)
#endif
#endif // POCO_NO_AUTOMATIC_LIBS
#endif
namespace Poco {
namespace Net {
void NetSSL_API initializeSSL();
/// Initialize the NetSSL library, as well as the underlying OpenSSL
/// libraries, by calling Poco::Crypto::OpenSSLInitializer::initialize().
///
/// Should be called before using any class from the NetSSL library.
/// The NetSSL will be initialized automatically, through
/// Poco::Crypto::OpenSSLInitializer instances or similar mechanisms
/// when creating Context or SSLManager instances.
/// However, it is recommended to call initializeSSL()
/// in any case at application startup.
///
/// Can be called multiple times; however, for every call to
/// initializeSSL(), a matching call to uninitializeSSL()
/// must be performed.
void NetSSL_API uninitializeSSL();
/// Uninitializes the NetSSL library by calling
/// Poco::Crypto::OpenSSLInitializer::uninitialize() and
/// shutting down the SSLManager.
} } // namespace Poco::Net
#endif // NetSSL_NetSSL_INCLUDED

View File

@@ -0,0 +1,95 @@
//
// PrivateKeyFactory.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: PrivateKeyFactory
//
// Definition of the PrivateKeyFactory class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_PrivateKeyFactory_INCLUDED
#define NetSSL_PrivateKeyFactory_INCLUDED
#include "Poco/Net/NetSSL.h"
namespace Poco {
namespace Net {
class PrivateKeyPassphraseHandler;
class NetSSL_API PrivateKeyFactory
/// A PrivateKeyFactory is responsible for creating PrivateKeyPassphraseHandlers.
///
/// You don't need to access this class directly. Use the macro
/// POCO_REGISTER_KEYFACTORY(namespace, PrivateKeyPassphraseHandlerName)
/// instead (see the documentation of PrivateKeyPassphraseHandler for an example).
{
public:
PrivateKeyFactory();
/// Creates the PrivateKeyFactory.
virtual ~PrivateKeyFactory();
/// Destroys the PrivateKeyFactory.
virtual PrivateKeyPassphraseHandler* create(bool onServer) const = 0;
/// Creates a new PrivateKeyPassphraseHandler
};
class NetSSL_API PrivateKeyFactoryRegistrar
/// Registrar class which automatically registers PrivateKeyFactories at the PrivateKeyFactoryMgr.
///
/// You don't need to access this class directly. Use the macro
/// POCO_REGISTER_KEYFACTORY(namespace, PrivateKeyPassphraseHandlerName)
/// instead (see the documentation of PrivateKeyPassphraseHandler for an example).
{
public:
PrivateKeyFactoryRegistrar(const std::string& name, PrivateKeyFactory* pFactory);
/// Registers the PrivateKeyFactory with the given name at the factory manager.
virtual ~PrivateKeyFactoryRegistrar();
/// Destroys the PrivateKeyFactoryRegistrar.
};
template<typename T>
class PrivateKeyFactoryImpl: public Poco::Net::PrivateKeyFactory
{
public:
PrivateKeyFactoryImpl()
{
}
~PrivateKeyFactoryImpl()
{
}
PrivateKeyPassphraseHandler* create(bool server) const
{
return new T(server);
}
};
} } // namespace Poco::Net
// DEPRECATED: register the factory directly at the FactoryMgr:
// Poco::Net::SSLManager::instance().privateKeyFactoryMgr().setFactory(name, new Poco::Net::PrivateKeyFactoryImpl<MyKeyHandler>());
#define POCO_REGISTER_KEYFACTORY(API, PKCLS) \
static Poco::Net::PrivateKeyFactoryRegistrar aRegistrar(std::string(#PKCLS), new Poco::Net::PrivateKeyFactoryImpl<PKCLS>());
#endif // NetSSL_PrivateKeyFactory_INCLUDED

View File

@@ -0,0 +1,64 @@
//
// PrivateKeyFactoryMgr.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: PrivateKeyFactoryMgr
//
// Definition of the PrivateKeyFactoryMgr class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_PrivateKeyFactoryMgr_INCLUDED
#define NetSSL_PrivateKeyFactoryMgr_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/PrivateKeyFactory.h"
#include "Poco/SharedPtr.h"
#include <map>
namespace Poco {
namespace Net {
class NetSSL_API PrivateKeyFactoryMgr
/// A PrivateKeyFactoryMgr manages all existing PrivateKeyFactories.
{
public:
using FactoriesMap = std::map<std::string, Poco::SharedPtr<PrivateKeyFactory>>;
PrivateKeyFactoryMgr();
/// Creates the PrivateKeyFactoryMgr.
~PrivateKeyFactoryMgr();
/// Destroys the PrivateKeyFactoryMgr.
void setFactory(const std::string& name, PrivateKeyFactory* pFactory);
/// Registers the factory. Class takes ownership of the pointer.
/// If a factory with the same name already exists, an exception is thrown.
bool hasFactory(const std::string& name) const;
/// Returns true if for the given name a factory is already registered
const PrivateKeyFactory* getFactory(const std::string& name) const;
/// Returns NULL if for the given name a factory does not exist, otherwise the factory is returned
void removeFactory(const std::string& name);
/// Removes the factory from the manager.
private:
FactoriesMap _factories;
};
} } // namespace Poco::Net
#endif // NetSSL_PrivateKeyFactoryMgr_INCLUDED

View File

@@ -0,0 +1,84 @@
//
// PrivateKeyPassphraseHandler.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: PrivateKeyPassphraseHandler
//
// Definition of the PrivateKeyPassphraseHandler class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_PrivateKeyPassphraseHandler_INCLUDED
#define NetSSL_PrivateKeyPassphraseHandler_INCLUDED
#include "Poco/Net/NetSSL.h"
namespace Poco {
namespace Net {
class NetSSL_API PrivateKeyPassphraseHandler
/// A passphrase handler is needed whenever the private key of a certificate is loaded and the certificate is protected
/// by a passphrase. The PrivateKeyPassphraseHandler's task is to provide that passphrase.
/// One can install one's own PrivateKeyPassphraseHandler by implementing this interface. Note that
/// in the implementation file of the subclass the following code must be present (assuming you use the namespace My_API
/// and the name of your handler class is MyGuiHandler):
///
/// #include "Poco/Net/PrivateKeyFactory.h"
/// ...
/// POCO_REGISTER_KEYFACTORY(My_API, MyGuiHandler)
///
/// One can either set the handler directly in the startup code of the main method of ones application by calling
///
/// SSLManager::instance().initialize(myguiHandler, myInvalidCertificateHandler, mySSLContext)
///
/// or in case one's application extends Poco::Util::Application one can use an XML configuration and put the following entry
/// under the path openSSL.privateKeyPassphraseHandler:
///
/// <privateKeyPassphraseHandler>
/// <name>MyGuiHandler</name>
/// <options>
/// [...] // Put optional config params for the handler here
/// </options>
/// </privateKeyPassphraseHandler>
///
/// Note that the name of the passphrase handler must be same as the one provided to the POCO_REGISTER_KEYFACTORY macro.
{
public:
PrivateKeyPassphraseHandler(bool onServerSide);
/// Creates the PrivateKeyPassphraseHandler. Automatically registers at the SSLManager::PrivateKeyPassword event.
virtual ~PrivateKeyPassphraseHandler();
/// Destroys the PrivateKeyPassphraseHandler.
virtual void onPrivateKeyRequested(const void* pSender, std::string& privateKey) = 0;
/// Returns the requested private key in the parameter privateKey.
bool serverSide() const;
private:
bool _serverSide;
};
//
// inlines
//
inline bool PrivateKeyPassphraseHandler::serverSide() const
{
return _serverSide;
}
} } // namespace Poco::Net
#endif // NetSSL_PrivateKeyPassphraseHandler_INCLUDED

View File

@@ -0,0 +1,48 @@
//
// RejectCertificateHandler.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: RejectCertificateHandler
//
// Definition of the RejectCertificateHandler class.
//
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_RejectCertificateHandler_INCLUDED
#define NetSSL_RejectCertificateHandler_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/InvalidCertificateHandler.h"
namespace Poco {
namespace Net {
class NetSSL_API RejectCertificateHandler: public InvalidCertificateHandler
/// A RejectCertificateHandler is invoked whenever an error
/// occurs verifying the certificate. It always rejects
/// the certificate.
{
public:
RejectCertificateHandler(bool handleErrorsOnServerSide);
/// Creates the RejectCertificateHandler
virtual ~RejectCertificateHandler();
/// Destroys the RejectCertificateHandler.
void onInvalidCertificate(const void* pSender, VerificationErrorArgs& errorCert);
};
} } // namespace Poco::Net
#endif // NetSSL_RejectCertificateHandler_INCLUDED

View File

@@ -0,0 +1,39 @@
//
// SSLException.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: SSLException
//
// Definition of the SSLException class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_SSLException_INCLUDED
#define NetSSL_SSLException_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/NetException.h"
namespace Poco {
namespace Net {
POCO_DECLARE_EXCEPTION(NetSSL_API, SSLException, NetException)
POCO_DECLARE_EXCEPTION(NetSSL_API, SSLContextException, SSLException)
POCO_DECLARE_EXCEPTION(NetSSL_API, InvalidCertificateException, SSLException)
POCO_DECLARE_EXCEPTION(NetSSL_API, CertificateValidationException, SSLException)
POCO_DECLARE_EXCEPTION(NetSSL_API, SSLConnectionUnexpectedlyClosedException, SSLException)
} } // namespace Poco::Net
#endif // NetSSL_SSLException_INCLUDED

View File

@@ -0,0 +1,395 @@
//
// SSLManager.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: SSLManager
//
// Definition of the SSLManager class.
//
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_SSLManager_INCLUDED
#define NetSSL_SSLManager_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/VerificationErrorArgs.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/PrivateKeyFactoryMgr.h"
#include "Poco/Net/CertificateHandlerFactoryMgr.h"
#include "Poco/Net/InvalidCertificateHandler.h"
#include "Poco/Util/AbstractConfiguration.h"
#include "Poco/BasicEvent.h"
#include "Poco/SharedPtr.h"
#include "Poco/Mutex.h"
#include <openssl/ssl.h>
#if defined(OPENSSL_FIPS) && OPENSSL_VERSION_NUMBER < 0x010001000L
#include <openssl/fips.h>
#endif
namespace Poco {
namespace Net {
class Context;
class NetSSL_API SSLManager
/// SSLManager is a singleton for holding the default server/client
/// Context and handling callbacks for certificate verification errors
/// and private key passphrases.
///
/// Proper initialization of SSLManager is critical.
///
/// SSLManager can be initialized manually, by calling initializeServer()
/// and/or initializeClient(), or initialization can be automatic. In the latter
/// case, a Poco::Util::Application instance must be available and the required
/// configuration properties must be set (see below).
///
/// Note that manual initialization must happen very early in the application,
/// before defaultClientContext() or defaultServerContext() are called.
///
/// If defaultClientContext() and defaultServerContext() are never called
/// in an application, initialization of SSLManager can be omitted.
/// However, in this case, delegates for the ServerVerificationError,
/// ClientVerificationError and PrivateKeyPassphraseRequired events
/// must be registered.
///
/// An exemplary documentation which sets either the server or client default context and creates
/// a PrivateKeyPassphraseHandler that reads the password from the XML file looks like this:
///
/// <AppConfig>
/// <openSSL>
/// <server|client>
/// <privateKeyFile>mycert.key</privateKeyFile>
/// <certificateFile>mycert.crt</certificateFile>
/// <caConfig>rootcert.pem</caConfig>
/// <verificationMode>none|relaxed|strict|once</verificationMode>
/// <verificationDepth>1..9</verificationDepth>
/// <loadDefaultCAFile>true|false</loadDefaultCAFile>
/// <cipherList>ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH</cipherList>
/// <preferServerCiphers>true|false</preferServerCiphers>
/// <privateKeyPassphraseHandler>
/// <name>KeyFileHandler</name>
/// <options>
/// <password>test</password>
/// </options>
/// </privateKeyPassphraseHandler>
/// <invalidCertificateHandler>
/// <name>ConsoleCertificateHandler</name>
/// </invalidCertificateHandler>
/// <cacheSessions>true|false</cacheSessions>
/// <sessionIdContext>someString</sessionIdContext> <!-- server only -->
/// <sessionCacheSize>0..n</sessionCacheSize> <!-- server only -->
/// <sessionTimeout>0..n</sessionTimeout> <!-- server only -->
/// <extendedVerification>true|false</extendedVerification>
/// <requireTLSv1>true|false</requireTLSv1>
/// <requireTLSv1_1>true|false</requireTLSv1_1>
/// <requireTLSv1_2>true|false</requireTLSv1_2>
/// <requireTLSv1_3>true|false</requireTLSv1_3>
/// <disableProtocols>sslv2,sslv3,tlsv1,tlsv1_1,tlsv1_2,tlsv1_3</disableProtocols>
/// <dhParamsFile>dh.pem</dhParamsFile>
/// <ecdhCurve>prime256v1</ecdhCurve>
/// </server|client>
/// <fips>false</fips>
/// </openSSL>
/// </AppConfig>
///
/// Following is a list of supported configuration properties. Property names must always
/// be prefixed with openSSL.server or openSSL.client. Some properties are only supported
/// for servers.
///
/// - privateKeyFile (string): The path to the file containing the private key for the certificate
/// in PEM format (or containing both the private key and the certificate).
/// - certificateFile (string): The Path to the file containing the server's or client's certificate
/// in PEM format. Can be omitted if the the file given in privateKeyFile contains the certificate as well.
/// - caConfig (string): The path to the file or directory containing the trusted root certificates.
/// - verificationMode (string): Specifies whether and how peer certificates are validated (see
/// the Context class for details). Valid values are none, relaxed, strict, once.
/// - verificationDepth (integer, 1-9): Sets the upper limit for verification chain sizes. Verification
/// will fail if a certificate chain larger than this is encountered.
/// - loadDefaultCAFile (boolean): Specifies whether the builtin CA certificates from OpenSSL are used.
/// - cipherList (string): Specifies the supported ciphers in OpenSSL notation
/// (e.g. "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH").
/// - preferServerCiphers (bool): When choosing a cipher, use the server's preferences instead of the
/// client preferences. When not called, the SSL server will always follow the clients
/// preferences. When called, the SSL/TLS server will choose following its own
/// preferences.
/// - privateKeyPassphraseHandler.name (string): The name of the class (subclass of PrivateKeyPassphraseHandler)
/// used for obtaining the passphrase for accessing the private key.
/// - privateKeyPassphraseHandler.options.password (string): The password to be used by KeyFileHandler.
/// - invalidCertificateHandler.name: The name of the class (subclass of CertificateHandler)
/// used for confirming invalid certificates.
/// - cacheSessions (boolean): Enables or disables session caching.
/// - sessionIdContext (string): contains the application's unique session ID context, which becomes
/// part of each session identifier generated by the server. Can be an arbitrary sequence
/// of bytes with a maximum length of SSL_MAX_SSL_SESSION_ID_LENGTH. Should be specified
/// for a server to enable session caching. Should be specified even if session caching
/// is disabled to avoid problems with clients that request session caching (e.g. Firefox 3.6).
/// If not specified, defaults to ${application.name}.
/// - sessionCacheSize (integer): Sets the maximum size of the server session cache, in number of
/// sessions. The default size (according to OpenSSL documentation) is 1024*20, which may be too
/// large for many applications, especially on embedded platforms with limited memory.
/// Specifying a size of 0 will set an unlimited cache size.
/// - sessionTimeout (integer): Sets the timeout (in seconds) of cached sessions on the server.
/// - extendedVerification (boolean): Enable or disable the automatic post-connection
/// extended certificate verification.
/// - requireTLSv1 (boolean): Require a TLSv1 connection.
/// - requireTLSv1_1 (boolean): Require a TLSv1.1 connection.
/// - requireTLSv1_2 (boolean): Require a TLSv1.2 connection.
/// - requireTLSv1_3 (boolean): Require a TLSv1.3 connection
/// - disableProtocols (string): A comma-separated list of protocols that should be
/// disabled. Valid protocol names are sslv2, sslv3, tlsv1, tlsv1_1, tlsv1_2, tlsv1_3.
/// - dhParamsFile (string): Specifies a file containing Diffie-Hellman parameters.
/// If not specified or empty, the default parameters are used.
/// - ecdhCurve (string): Specifies the name of the curve to use for ECDH, based
/// on the curve names specified in RFC 4492. Defaults to "prime256v1".
/// - fips: Enable or disable OpenSSL FIPS mode. Only supported if the OpenSSL version
/// that this library is built against supports FIPS mode.
///
/// Please see the Context class documentation regarding TLSv1.3 support.
{
public:
using PrivateKeyPassphraseHandlerPtr = Poco::SharedPtr<PrivateKeyPassphraseHandler>;
using InvalidCertificateHandlerPtr = Poco::SharedPtr<InvalidCertificateHandler>;
Poco::BasicEvent<VerificationErrorArgs> ServerVerificationError;
/// Fired whenever a certificate verification error is detected by the server during a handshake.
Poco::BasicEvent<VerificationErrorArgs> ClientVerificationError;
/// Fired whenever a certificate verification error is detected by the client during a handshake.
Poco::BasicEvent<std::string> PrivateKeyPassphraseRequired;
/// Fired when a encrypted certificate is loaded. Not setting the password
/// in the event parameter will result in a failure to load the certificate.
static SSLManager& instance();
/// Returns the instance of the SSLManager singleton.
void initializeServer(PrivateKeyPassphraseHandlerPtr ptrPassphraseHandler, InvalidCertificateHandlerPtr ptrCertificateHandler, Context::Ptr ptrContext);
/// Initializes the server side of the SSLManager with a default passphrase handler, a default invalid certificate handler and a default context. If this method
/// is never called the SSLmanager will try to initialize its members from an application configuration.
///
/// PtrPassphraseHandler and ptrCertificateHandler can be 0. However, in this case, event delegates
/// must be registered with the ServerVerificationError and PrivateKeyPassphraseRequired events.
///
/// Note: Always create the handlers (or register the corresponding event delegates) before creating
/// the Context, as during creation of the Context the passphrase for the private key might be needed.
///
/// Valid initialization code would be:
/// SharedPtr<PrivateKeyPassphraseHandler> pConsoleHandler = new KeyConsoleHandler;
/// SharedPtr<InvalidCertificateHandler> pInvalidCertHandler = new ConsoleCertificateHandler;
/// Context::Ptr pContext = new Context(Context::SERVER_USE, "any.pem", "any.pem", "rootcert.pem", Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
/// SSLManager::instance().initializeServer(pConsoleHandler, pInvalidCertHandler, pContext);
void initializeClient(PrivateKeyPassphraseHandlerPtr ptrPassphraseHandler, InvalidCertificateHandlerPtr ptrHandler, Context::Ptr ptrContext);
/// Initializes the client side of the SSLManager with a default passphrase handler, a default invalid certificate handler and a default context. If this method
/// is never called the SSLmanager will try to initialize its members from an application configuration.
///
/// PtrPassphraseHandler and ptrCertificateHandler can be 0. However, in this case, event delegates
/// must be registered with the ClientVerificationError and PrivateKeyPassphraseRequired events.
///
/// Note: Always create the handlers (or register the corresponding event delegates) before creating
/// the Context, as during creation of the Context the passphrase for the private key might be needed.
///
/// Valid initialization code would be:
/// SharedPtr<PrivateKeyPassphraseHandler> pConsoleHandler = new KeyConsoleHandler;
/// SharedPtr<InvalidCertificateHandler> pInvalidCertHandler = new ConsoleCertificateHandler;
/// Context::Ptr pContext = new Context(Context::CLIENT_USE, "", "", "rootcert.pem", Context::VERIFY_RELAXED, 9, false, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
/// SSLManager::instance().initializeClient(pConsoleHandler, pInvalidCertHandler, pContext);
Context::Ptr defaultServerContext();
/// Returns the default Context used by the server.
///
/// Unless initializeServer() has been called, the first call to this method initializes the default Context
/// from the application configuration.
Context::Ptr defaultClientContext();
/// Returns the default Context used by the client.
///
/// Unless initializeClient() has been called, the first call to this method initializes the default Context
/// from the application configuration.
PrivateKeyPassphraseHandlerPtr serverPassphraseHandler();
/// Returns the configured passphrase handler of the server. If none is set, the method will create a default one
/// from an application configuration.
InvalidCertificateHandlerPtr serverCertificateHandler();
/// Returns an initialized certificate handler (used by the server to verify client cert) which determines how invalid certificates are treated.
/// If none is set, it will try to auto-initialize one from an application configuration.
PrivateKeyPassphraseHandlerPtr clientPassphraseHandler();
/// Returns the configured passphrase handler of the client. If none is set, the method will create a default one
/// from an application configuration.
InvalidCertificateHandlerPtr clientCertificateHandler();
/// Returns an initialized certificate handler (used by the client to verify server cert) which determines how invalid certificates are treated.
/// If none is set, it will try to auto-initialize one from an application configuration.
PrivateKeyFactoryMgr& privateKeyFactoryMgr();
/// Returns the private key factory manager which stores the
/// factories for the different registered passphrase handlers for private keys.
CertificateHandlerFactoryMgr& certificateHandlerFactoryMgr();
/// Returns the CertificateHandlerFactoryMgr which stores the
/// factories for the different registered certificate handlers.
static bool isFIPSEnabled();
// Returns true if FIPS mode is enabled, false otherwise.
void shutdown();
/// Shuts down the SSLManager and releases the default Context
/// objects. After a call to shutdown(), the SSLManager can no
/// longer be used.
///
/// Normally, it's not necessary to call this method directly, as this
/// will be called either by uninitializeSSL(), or when
/// the SSLManager instance is destroyed.
static const std::string CFG_SERVER_PREFIX;
static const std::string CFG_CLIENT_PREFIX;
protected:
static int verifyClientCallback(int ok, X509_STORE_CTX* pStore);
/// The return value of this method defines how errors in
/// verification are handled. Return 0 to terminate the handshake,
/// or 1 to continue despite the error.
static int verifyServerCallback(int ok, X509_STORE_CTX* pStore);
/// The return value of this method defines how errors in
/// verification are handled. Return 0 to terminate the handshake,
/// or 1 to continue despite the error.
static int privateKeyPassphraseCallback(char* pBuf, int size, int flag, void* userData);
/// Method is invoked by OpenSSL to retrieve a passwd for an encrypted certificate.
/// The request is delegated to the PrivatekeyPassword event. This method returns the
/// length of the password.
static Poco::Util::AbstractConfiguration& appConfig();
/// Returns the application configuration.
///
/// Throws a InvalidStateException if not application instance
/// is available.
private:
SSLManager();
/// Creates the SSLManager.
~SSLManager();
/// Destroys the SSLManager.
void initDefaultContext(bool server);
/// Inits the default context, the first time it is accessed.
void initEvents(bool server);
/// Registers delegates at the events according to the configuration.
void initPassphraseHandler(bool server);
/// Inits the passphrase handler.
void initCertificateHandler(bool server);
/// Inits the certificate handler.
static int verifyCallback(bool server, int ok, X509_STORE_CTX* pStore);
/// The return value of this method defines how errors in
/// verification are handled. Return 0 to terminate the handshake,
/// or 1 to continue despite the error.
PrivateKeyFactoryMgr _factoryMgr;
CertificateHandlerFactoryMgr _certHandlerFactoryMgr;
Context::Ptr _ptrDefaultServerContext;
PrivateKeyPassphraseHandlerPtr _ptrServerPassphraseHandler;
InvalidCertificateHandlerPtr _ptrServerCertificateHandler;
Context::Ptr _ptrDefaultClientContext;
PrivateKeyPassphraseHandlerPtr _ptrClientPassphraseHandler;
InvalidCertificateHandlerPtr _ptrClientCertificateHandler;
Poco::FastMutex _mutex;
static const std::string CFG_PRIV_KEY_FILE;
static const std::string CFG_CERTIFICATE_FILE;
static const std::string CFG_CA_LOCATION;
static const std::string CFG_VER_MODE;
static const Context::VerificationMode VAL_VER_MODE;
static const std::string CFG_VER_DEPTH;
static const int VAL_VER_DEPTH;
static const std::string CFG_ENABLE_DEFAULT_CA;
static const bool VAL_ENABLE_DEFAULT_CA;
static const std::string CFG_CIPHER_LIST;
static const std::string CFG_CYPHER_LIST; // for backwards compatibility
static const std::string VAL_CIPHER_LIST;
static const std::string CFG_PREFER_SERVER_CIPHERS;
static const std::string CFG_DELEGATE_HANDLER;
static const std::string VAL_DELEGATE_HANDLER;
static const std::string CFG_CERTIFICATE_HANDLER;
static const std::string VAL_CERTIFICATE_HANDLER;
static const std::string CFG_CACHE_SESSIONS;
static const std::string CFG_SESSION_ID_CONTEXT;
static const std::string CFG_SESSION_CACHE_SIZE;
static const std::string CFG_SESSION_TIMEOUT;
static const std::string CFG_EXTENDED_VERIFICATION;
static const std::string CFG_REQUIRE_TLSV1;
static const std::string CFG_REQUIRE_TLSV1_1;
static const std::string CFG_REQUIRE_TLSV1_2;
static const std::string CFG_REQUIRE_TLSV1_3;
static const std::string CFG_DISABLE_PROTOCOLS;
static const std::string CFG_DH_PARAMS_FILE;
static const std::string CFG_ECDH_CURVE;
#ifdef OPENSSL_FIPS
static const std::string CFG_FIPS_MODE;
static const bool VAL_FIPS_MODE;
#endif
friend class Poco::SingletonHolder<SSLManager>;
friend class Context;
};
//
// inlines
//
inline PrivateKeyFactoryMgr& SSLManager::privateKeyFactoryMgr()
{
return _factoryMgr;
}
inline CertificateHandlerFactoryMgr& SSLManager::certificateHandlerFactoryMgr()
{
return _certHandlerFactoryMgr;
}
inline bool SSLManager::isFIPSEnabled()
{
#ifdef OPENSSL_FIPS
return FIPS_mode() ? true : false;
#else
return false;
#endif
}
inline int SSLManager::verifyServerCallback(int ok, X509_STORE_CTX* pStore)
{
return SSLManager::verifyCallback(true, ok, pStore);
}
inline int SSLManager::verifyClientCallback(int ok, X509_STORE_CTX* pStore)
{
return SSLManager::verifyCallback(false, ok, pStore);
}
} } // namespace Poco::Net
#endif // NetSSL_SSLManager_INCLUDED

View File

@@ -0,0 +1,93 @@
//
// SecureSMTPClientSession.h
//
// Library: NetSSL_OpenSSL
// Package: Mail
// Module: SecureSMTPClientSession
//
// Definition of the SecureSMTPClientSession class.
//
// Copyright (c) 2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef Net_SecureSMTPClientSession_INCLUDED
#define Net_SecureSMTPClientSession_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/SMTPClientSession.h"
#include "Poco/Net/Context.h"
namespace Poco {
namespace Net {
class NetSSL_API SecureSMTPClientSession: public SMTPClientSession
/// This class implements an Simple Mail
/// Transfer Protocol (SMTP, RFC 2821)
/// client for sending e-mail messages that
/// supports the STARTTLS command for secure
/// connections.
///
/// Usage is as follows:
/// 1. Create a SecureSMTPClientSession object.
/// 2. Call login() or login(hostname).
/// 3. Call startTLS() to switch to a secure connection.
/// Check the return value to see if a secure connection
/// has actually been established (not all servers may
/// support STARTTLS).
/// 4. Call any of the login() methods to securely authenticate
/// with a username and password.
/// 5. Send the message(s).
{
public:
explicit SecureSMTPClientSession(const StreamSocket& socket);
/// Creates the SecureSMTPClientSession using
/// the given socket, which must be connected
/// to a SMTP server.
SecureSMTPClientSession(const std::string& host, Poco::UInt16 port = SMTP_PORT);
/// Creates the SecureSMTPClientSession using a socket connected
/// to the given host and port.
virtual ~SecureSMTPClientSession();
/// Destroys the SMTPClientSession.
bool startTLS();
/// Sends a STARTTLS command and, if successful,
/// creates a secure SSL/TLS connection over the
/// existing socket connection.
///
/// Must be called after login() or login(hostname).
/// If successful, login() can be called again
/// to authenticate the user.
///
/// Returns true if the STARTTLS command was successful,
/// false otherwise.
bool startTLS(Context::Ptr pContext);
/// Sends a STARTTLS command and, if successful,
/// creates a secure SSL/TLS connection over the
/// existing socket connection.
///
/// Uses the given Context object for creating
/// the SSL/TLS connection.
///
/// Must be called after login() or login(hostname).
/// If successful, login() can be called again
/// to authenticate the user.
///
/// Returns true if the STARTTLS command was successful,
/// false otherwise.
};
} } // namespace Poco::Net
#endif // Net_SecureSMTPClientSession_INCLUDED

View File

@@ -0,0 +1,136 @@
//
// SecureServerSocket.h
//
// Library: NetSSL_OpenSSL
// Package: SSLSockets
// Module: SecureServerSocket
//
// Definition of the SecureServerSocket class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_SecureServerSocket_INCLUDED
#define NetSSL_SecureServerSocket_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/ServerSocket.h"
#include "Poco/Net/Context.h"
namespace Poco {
namespace Net {
class NetSSL_API SecureServerSocket: public ServerSocket
/// A server socket for secure SSL connections.
{
public:
SecureServerSocket();
/// Creates a SSL server socket using the
/// default SSL server context.
///
/// The server socket must be bound to
/// an address and put into listening state.
explicit SecureServerSocket(Context::Ptr pContext);
/// Creates a SSL server socket, using the
/// given SSL context object.
///
/// The server socket must be bound to
/// an address and put into listening state.
SecureServerSocket(const Socket& socket);
/// Creates the SecureServerSocket with the SocketImpl
/// from another socket. The SocketImpl must be
/// a SecureServerSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
SecureServerSocket(const SocketAddress& address, int backlog = 64);
/// Creates a server socket using the default server SSL context,
/// binds it to the given address and puts it in listening
/// state.
///
/// After successful construction, the server socket
/// is ready to accept connections.
SecureServerSocket(const SocketAddress& address, int backlog, Context::Ptr pContext);
/// Creates a server socket using the given SSL context, binds it
/// to the given address and puts it in listening
/// state.
///
/// After successful construction, the server socket
/// is ready to accept connections.
SecureServerSocket(Poco::UInt16 port, int backlog = 64);
/// Creates a server socket using the default server SSL context,
/// binds it to the given port and puts it in listening
/// state.
///
/// After successful construction, the server socket
/// is ready to accept connections.
SecureServerSocket(Poco::UInt16 port, int backlog, Context::Ptr pContext);
/// Creates a server socket using the given SSL context, binds it
/// to the given port and puts it in listening
/// state.
///
/// After successful construction, the server socket
/// is ready to accept connections.
virtual ~SecureServerSocket();
/// Destroys the StreamSocket.
SecureServerSocket& operator = (const Socket& socket);
/// Assignment operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
StreamSocket acceptConnection(SocketAddress& clientAddr);
/// Get the next completed connection from the
/// socket's completed connection queue.
///
/// If the queue is empty, waits until a connection
/// request completes.
///
/// Returns a new SSL socket for the connection
/// with the client.
///
/// The client socket's address is returned in clientAddr.
///
/// No SSL handshake is performed on the new connection.
/// The SSL handshake will be performed the first time
/// sendBytes(), receiveBytes() or completeHandshake()
/// is called on the returned SecureStreamSocket.
StreamSocket acceptConnection();
/// Get the next completed connection from the
/// socket's completed connection queue.
///
/// If the queue is empty, waits until a connection
/// request completes.
///
/// Returns a new SSL socket for the connection
/// with the client.
///
/// No SSL handshake is performed on the new connection.
/// The SSL handshake will be performed the first time
/// sendBytes(), receiveBytes() or completeHandshake()
/// is called on the returned SecureStreamSocket.
Context::Ptr context() const;
/// Returns the SSL context used by this socket.
};
} } // namespace Poco::Net
#endif // NetSSL_SecureServerSocket_INCLUDED

View File

@@ -0,0 +1,150 @@
//
// SecureServerSocketImpl.h
//
// Library: NetSSL_OpenSSL
// Package: SSLSockets
// Module: SecureServerSocketImpl
//
// Definition of the SecureServerSocketImpl class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_SecureServerSocketImpl_INCLUDED
#define NetSSL_SecureServerSocketImpl_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/SecureSocketImpl.h"
#include "Poco/Net/ServerSocketImpl.h"
#include "Poco/Net/Context.h"
namespace Poco {
namespace Net {
class NetSSL_API SecureServerSocketImpl: public ServerSocketImpl
/// The SocketImpl class for SecureServerSocket.
{
public:
SecureServerSocketImpl(Context::Ptr pContext);
/// Creates the SecureServerSocketImpl using the
/// given SSL context object.
SocketImpl* acceptConnection(SocketAddress& clientAddr);
/// Get the next completed connection from the
/// socket's completed connection queue.
///
/// If the queue is empty, waits until a connection
/// request completes.
///
/// Returns a new TCP socket for the connection
/// with the client.
///
/// The client socket's address is returned in clientAddr.
void connect(const SocketAddress& address);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
void connect(const SocketAddress& address, const Poco::Timespan& timeout);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
void connectNB(const SocketAddress& address);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
void bind(const SocketAddress& address, bool reuseAddress = false, bool reusePort = false);
/// Bind a local address to the socket.
///
/// This is usually only done when establishing a server
/// socket. TCP clients should not bind a socket to a
/// specific address.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
///
/// If reusePort is true, sets the SO_REUSEPORT
/// socket option.
void listen(int backlog = 64);
/// Puts the socket into listening state.
///
/// The socket becomes a passive socket that
/// can accept incoming connection requests.
///
/// The backlog argument specifies the maximum
/// number of connections that can be queued
/// for this socket.
void close();
/// Close the socket.
int sendBytes(const void* buffer, int length, int flags = 0);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
int receiveBytes(void* buffer, int length, int flags = 0);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
void sendUrgent(unsigned char data);
/// Not supported by this kind of socket.
///
/// Throws a Poco::InvalidAccessException.
bool secure() const;
/// Returns true iff the socket's connection is secure
/// (using SSL or TLS).
Context::Ptr context() const;
/// Returns the SSL context used by this socket.
protected:
~SecureServerSocketImpl();
/// Destroys the SecureServerSocketImpl.
private:
SecureServerSocketImpl(const SecureServerSocketImpl&);
SecureServerSocketImpl& operator = (const SecureServerSocketImpl&);
private:
SecureSocketImpl _impl;
};
//
// inlines
//
inline Context::Ptr SecureServerSocketImpl::context() const
{
return _impl.context();
}
} } // namespace Poco::Net
#endif // NetSSL_SecureServerSocketImpl_INCLUDED

View File

@@ -0,0 +1,266 @@
//
// SecureSocketImpl.h
//
// Library: NetSSL_OpenSSL
// Package: SSLSockets
// Module: SecureSocketImpl
//
// Definition of the SecureSocketImpl class.
//
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_SecureSocketImpl_INCLUDED
#define NetSSL_SecureSocketImpl_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/SocketImpl.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/X509Certificate.h"
#include "Poco/Net/Session.h"
#include <openssl/bio.h>
#include <openssl/ssl.h>
namespace Poco {
namespace Net {
class HostEntry;
class NetSSL_API SecureSocketImpl
/// The SocketImpl for SecureStreamSocket.
{
public:
SecureSocketImpl(Poco::AutoPtr<SocketImpl> pSocketImpl, Context::Ptr pContext);
/// Creates the SecureSocketImpl using an already
/// connected stream socket.
virtual ~SecureSocketImpl();
/// Destroys the SecureSocketImpl.
SocketImpl* acceptConnection(SocketAddress& clientAddr);
/// Get the next completed connection from the
/// socket's completed connection queue.
///
/// If the queue is empty, waits until a connection
/// request completes.
///
/// Returns a new SSL socket for the connection
/// with the client.
///
/// The client socket's address is returned in clientAddr.
void connect(const SocketAddress& address, bool performHandshake);
/// Initializes the socket and establishes a secure connection to
/// the TCP server at the given address.
///
/// If performHandshake is true, the SSL handshake is performed immediately
/// after establishing the connection. Otherwise, the handshake is performed
/// the first time sendBytes(), receiveBytes() or completeHandshake() is called.
void connect(const SocketAddress& address, const Poco::Timespan& timeout, bool performHandshake);
/// Initializes the socket, sets the socket timeout and
/// establishes a secure connection to the TCP server at the given address.
///
/// If performHandshake is true, the SSL handshake is performed immediately
/// after establishing the connection. Otherwise, the handshake is performed
/// the first time sendBytes(), receiveBytes() or completeHandshake() is called.
void connectNB(const SocketAddress& address);
/// Initializes the socket and establishes a secure connection to
/// the TCP server at the given address. Prior to opening the
/// connection the socket is set to nonblocking mode.
void bind(const SocketAddress& address, bool reuseAddress = false, bool reusePort = false);
/// Bind a local address to the socket.
///
/// This is usually only done when establishing a server
/// socket. SSL clients should not bind a socket to a
/// specific address.
///
/// If reuseAddress is true, sets the SO_REUSEADDR
/// socket option.
///
/// If reusePort is true, sets the SO_REUSEPORT
/// socket option.
void listen(int backlog = 64);
/// Puts the socket into listening state.
///
/// The socket becomes a passive socket that
/// can accept incoming connection requests.
///
/// The backlog argument specifies the maximum
/// number of connections that can be queued
/// for this socket.
void shutdown();
/// Shuts down the connection by attempting
/// an orderly SSL shutdown, then actually
/// shutting down the TCP connection.
void close();
/// Close the socket.
void abort();
/// Aborts the connection by closing the
/// underlying TCP connection. No orderly SSL shutdown
/// is performed.
int sendBytes(const void* buffer, int length, int flags = 0);
/// Sends the contents of the given buffer through
/// the socket. Any specified flags are ignored.
///
/// Returns the number of bytes sent, which may be
/// less than the number of bytes specified.
int receiveBytes(void* buffer, int length, int flags = 0);
/// Receives data from the socket and stores it
/// in buffer. Up to length bytes are received.
///
/// Returns the number of bytes received.
int available() const;
/// Returns the number of bytes available from the
/// SSL buffer for immediate reading.
int completeHandshake();
/// Completes the SSL handshake.
///
/// If the SSL connection was the result of an accept(),
/// the server-side handshake is completed, otherwise
/// a client-side handshake is performed.
poco_socket_t sockfd();
/// Returns the underlying socket descriptor.
X509* peerCertificate() const;
/// Returns the peer's certificate.
Context::Ptr context() const;
/// Returns the SSL context used for this socket.
void verifyPeerCertificate();
/// Performs post-connect (or post-accept) peer certificate validation,
/// using the peer host name set with setPeerHostName(), or the peer's
/// IP address string if no peer host name has been set.
void verifyPeerCertificate(const std::string& hostName);
/// Performs post-connect (or post-accept) peer certificate validation
/// using the given peer host name.
void setPeerHostName(const std::string& hostName);
/// Sets the peer host name for certificate validation purposes.
const std::string& getPeerHostName() const;
/// Returns the peer host name.
Session::Ptr currentSession();
/// Returns the SSL session of the current connection,
/// for reuse in a future connection (if session caching
/// is enabled).
///
/// If no connection is established, returns null.
void useSession(Session::Ptr pSession);
/// Sets the SSL session to use for the next
/// connection. Setting a previously saved Session
/// object is necessary to enable session caching.
///
/// To remove the currently set session, a null pointer
/// can be given.
///
/// Must be called before connect() to be effective.
bool sessionWasReused();
/// Returns true iff a reused session was negotiated during
/// the handshake.
protected:
void acceptSSL();
/// Performs a server-side SSL handshake and certificate verification.
void connectSSL(bool performHandshake);
/// Performs a client-side SSL handshake and establishes a secure
/// connection over an already existing TCP connection.
long verifyPeerCertificateImpl(const std::string& hostName);
/// Performs post-connect (or post-accept) peer certificate validation.
static bool isLocalHost(const std::string& hostName);
/// Returns true iff the given host name is the local host
/// (either "localhost" or "127.0.0.1").
bool mustRetry(int rc);
/// Returns true if the last operation should be retried,
/// otherwise false.
///
/// In case of an SSL_ERROR_WANT_READ error, and if the socket is
/// blocking, waits for the underlying socket to become readable.
///
/// In case of an SSL_ERROR_WANT_WRITE error, and if the socket is
/// blocking, waits for the underlying socket to become writable.
///
/// Can also throw a Poco::TimeoutException if the socket does
/// not become readable or writable within the sockets
/// receive or send timeout.
int handleError(int rc);
/// Handles an SSL error by throwing an appropriate exception.
void reset();
/// Prepares the socket for re-use.
///
/// After closing and resetting a socket, the socket can
/// be used for a new connection.
///
/// Note that simply closing a socket is not sufficient
/// to be able to re-use it again.
private:
SecureSocketImpl(const SecureSocketImpl&);
SecureSocketImpl& operator = (const SecureSocketImpl&);
SSL* _pSSL;
Poco::AutoPtr<SocketImpl> _pSocket;
Context::Ptr _pContext;
bool _needHandshake;
std::string _peerHostName;
Session::Ptr _pSession;
friend class SecureStreamSocketImpl;
};
//
// inlines
//
inline poco_socket_t SecureSocketImpl::sockfd()
{
return _pSocket->sockfd();
}
inline Context::Ptr SecureSocketImpl::context() const
{
return _pContext;
}
inline const std::string& SecureSocketImpl::getPeerHostName() const
{
return _peerHostName;
}
} } // namespace Poco::Net
#endif // NetSSL_SecureSocketImpl_INCLUDED

View File

@@ -0,0 +1,272 @@
//
// SecureStreamSocket.h
//
// Library: NetSSL_OpenSSL
// Package: SSLSockets
// Module: SecureStreamSocket
//
// Definition of the SecureStreamSocket class.
//
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_SecureStreamSocket_INCLUDED
#define NetSSL_SecureStreamSocket_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/Session.h"
#include "Poco/Net/X509Certificate.h"
namespace Poco {
namespace Net {
class NetSSL_API SecureStreamSocket: public StreamSocket
/// A subclass of StreamSocket for secure SSL sockets.
///
/// A few notes about nonblocking IO:
/// sendBytes() and receiveBytes() can return a
/// negative value when using a nonblocking socket, which means
/// a SSL handshake is currently in progress and more data
/// needs to be read or written for the handshake to continue.
/// If sendBytes() or receiveBytes() return ERR_SSL_WANT_WRITE,
/// sendBytes() must be called as soon as possible (usually, after
/// select() indicates that data can be written). Likewise, if
/// ERR_SSL_WANT_READ is returned, receiveBytes() must be called
/// as soon as data is available for reading (indicated by select()).
///
/// The SSL handshake is delayed until the first sendBytes() or
/// receiveBytes() operation is performed on the socket. No automatic
/// post connection check (checking the peer certificate for a valid
/// hostname) is performed when using nonblocking I/O. To manually
/// perform peer certificate validation, call verifyPeerCertificate()
/// after the SSL handshake has been completed.
{
public:
enum
{
ERR_SSL_WANT_READ = -1,
ERR_SSL_WANT_WRITE = -2
};
SecureStreamSocket();
/// Creates an unconnected secure stream socket
/// using the default client SSL context.
///
/// Before sending or receiving data, the socket
/// must be connected with a call to connect().
explicit SecureStreamSocket(Context::Ptr pContext);
/// Creates an unconnected secure stream socket
/// using the given SSL context.
///
/// Before sending or receiving data, the socket
/// must be connected with a call to connect().
SecureStreamSocket(Context::Ptr pContext, Session::Ptr pSession);
/// Creates an unconnected secure stream socket
/// using the given SSL context.
///
/// Before sending or receiving data, the socket
/// must be connected with a call to connect().
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
explicit SecureStreamSocket(const SocketAddress& address);
/// Creates a secure stream socket using the default
/// client SSL context and connects it to
/// the socket specified by address.
SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext);
/// Creates a secure stream socket using the given
/// client SSL context and connects it to
/// the socket specified by address.
SecureStreamSocket(const SocketAddress& address, Context::Ptr pContext, Session::Ptr pSession);
/// Creates a secure stream socket using the given
/// client SSL context and connects it to
/// the socket specified by address.
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
SecureStreamSocket(const SocketAddress& address, const std::string& hostName);
/// Creates a secure stream socket using the default
/// client SSL context and connects it to
/// the socket specified by address.
///
/// The given host name is used for certificate verification.
SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext);
/// Creates a secure stream socket using the given
/// client SSL context and connects it to
/// the socket specified by address.
///
/// The given host name is used for certificate verification.
SecureStreamSocket(const SocketAddress& address, const std::string& hostName, Context::Ptr pContext, Session::Ptr pSession);
/// Creates a secure stream socket using the given
/// client SSL context and connects it to
/// the socket specified by address.
///
/// The given host name is used for certificate verification.
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
SecureStreamSocket(const Socket& socket);
/// Creates the SecureStreamSocket with the SocketImpl
/// from another socket. The SocketImpl must be
/// a SecureStreamSocketImpl, otherwise an InvalidArgumentException
/// will be thrown.
virtual ~SecureStreamSocket();
/// Destroys the StreamSocket.
SecureStreamSocket& operator = (const Socket& socket);
/// Assignment operator.
///
/// Releases the socket's SocketImpl and
/// attaches the SocketImpl from the other socket and
/// increments the reference count of the SocketImpl.
bool havePeerCertificate() const;
/// Returns true iff the peer has presented a
/// certificate.
X509Certificate peerCertificate() const;
/// Returns the peer's X509 certificate.
///
/// Throws a SSLException if the peer did not
/// present a certificate.
void setPeerHostName(const std::string& hostName);
/// Sets the peer's host name used for certificate validation.
const std::string& getPeerHostName() const;
/// Returns the peer's host name used for certificate validation.
static SecureStreamSocket attach(const StreamSocket& streamSocket);
/// Creates a SecureStreamSocket over an existing socket
/// connection. The given StreamSocket must be connected.
/// A SSL handshake will be performed.
static SecureStreamSocket attach(const StreamSocket& streamSocket, Context::Ptr pContext);
/// Creates a SecureStreamSocket over an existing socket
/// connection. The given StreamSocket must be connected.
/// A SSL handshake will be performed.
static SecureStreamSocket attach(const StreamSocket& streamSocket, Context::Ptr pContext, Session::Ptr pSession);
/// Creates a SecureStreamSocket over an existing socket
/// connection. The given StreamSocket must be connected.
/// A SSL handshake will be performed.
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
static SecureStreamSocket attach(const StreamSocket& streamSocket, const std::string& peerHostName);
/// Creates a SecureStreamSocket over an existing socket
/// connection. The given StreamSocket must be connected.
/// A SSL handshake will be performed.
static SecureStreamSocket attach(const StreamSocket& streamSocket, const std::string& peerHostName, Context::Ptr pContext);
/// Creates a SecureStreamSocket over an existing socket
/// connection. The given StreamSocket must be connected.
/// A SSL handshake will be performed.
static SecureStreamSocket attach(const StreamSocket& streamSocket, const std::string& peerHostName, Context::Ptr pContext, Session::Ptr pSession);
/// Creates a SecureStreamSocket over an existing socket
/// connection. The given StreamSocket must be connected.
/// A SSL handshake will be performed.
///
/// The given Session is reused, if possible (client session
/// caching is enabled for the given Context, and the server
/// agrees to reuse the session).
Context::Ptr context() const;
/// Returns the SSL context used by this socket.
void setLazyHandshake(bool flag = true);
/// Enable lazy SSL handshake. If enabled, the SSL handshake
/// will be performed the first time date is sent or
/// received over the connection.
bool getLazyHandshake() const;
/// Returns true if setLazyHandshake(true) has been called.
void verifyPeerCertificate();
/// Performs post-connect (or post-accept) peer certificate validation,
/// using the peer host name set with setPeerHostName(), or the peer's
/// IP address string if no peer host name has been set.
///
/// Should only be used for non-blocking connections, after the
/// initial SSL handshake has been performed (see completeHandshake()).
void verifyPeerCertificate(const std::string& hostName);
/// Performs post-connect (or post-accept) peer certificate validation
/// using the given host name.
///
/// Should only be used for non-blocking connections, after the
/// initial SSL handshake has been performed (see completeHandshake()).
int completeHandshake();
/// Completes the SSL handshake.
///
/// If the SSL connection was the result of an accept(),
/// the server-side handshake is completed, otherwise
/// a client-side handshake is performed.
///
/// Returns 1 if the handshake was successful, ERR_SSL_WANT_READ or
/// ERR_SSL_WANT_WRITE if more data is required to complete the
/// handshake. In this case, completeHandshake() should be called
/// again, after the necessary condition has been met.
Session::Ptr currentSession();
/// Returns the SSL session of the current connection,
/// for reuse in a future connection (if session caching
/// is enabled).
///
/// If no connection is established, returns null.
void useSession(Session::Ptr pSession);
/// Sets the SSL session to use for the next
/// connection. Setting a previously saved Session
/// object is necessary to enable session caching.
///
/// To remove the currently set session, a null pointer
/// can be given.
///
/// Must be called before connect() to be effective.
bool sessionWasReused();
/// Returns true iff a reused session was negotiated during
/// the handshake.
void abort();
/// Aborts the SSL connection by closing the underlying
/// TCP connection. No orderly SSL shutdown is performed.
protected:
SecureStreamSocket(SocketImpl* pImpl);
friend class SecureServerSocket;
};
} } // namespace Poco::Net
#endif // NetSSL_SecureStreamSocket_INCLUDED

View File

@@ -0,0 +1,299 @@
//
// SecureStreamSocketImpl.h
//
// Library: NetSSL_OpenSSL
// Package: SSLSockets
// Module: SecureStreamSocketImpl
//
// Definition of the SecureStreamSocketImpl class.
//
// Copyright (c) 2006-2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_SecureStreamSocketImpl_INCLUDED
#define NetSSL_SecureStreamSocketImpl_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/SecureSocketImpl.h"
#include "Poco/Net/StreamSocketImpl.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/X509Certificate.h"
namespace Poco {
namespace Net {
class NetSSL_API SecureStreamSocketImpl: public StreamSocketImpl
/// This class implements a SSL stream socket.
{
public:
SecureStreamSocketImpl(Context::Ptr pContext);
/// Creates the SecureStreamSocketImpl.
SecureStreamSocketImpl(StreamSocketImpl* pStreamSocket, Context::Ptr pContext);
/// Creates the SecureStreamSocketImpl.
SocketImpl* acceptConnection(SocketAddress& clientAddr);
/// Not supported by a SecureStreamSocket.
///
/// Throws a Poco::InvalidAccessException.
void connect(const SocketAddress& address);
/// Initializes the socket and establishes a connection to
/// the TCP server at the given address.
///
/// Can also be used for UDP sockets. In this case, no
/// connection is established. Instead, incoming and outgoing
/// packets are restricted to the specified address.
void connect(const SocketAddress& address, const Poco::Timespan& timeout);
/// Initializes the socket, sets the socket timeout and
/// establishes a connection to the TCP server at the given address.
void connectNB(const SocketAddress& address);
/// Initializes the socket and establishes a connection to
/// the TCP server at the given address. Prior to opening the
/// connection the socket is set to nonblocking mode.
void bind(const SocketAddress& address, bool reuseAddress = false);
/// Not supported by a SecureStreamSocket.
///
/// Throws a Poco::InvalidAccessException.
void listen(int backlog = 64);
/// Not supported by a SecureStreamSocket.
///
/// Throws a Poco::InvalidAccessException.
void close();
/// Close the socket.
int sendBytes(const void* buffer, int length, int flags = 0);
/// Sends the contents of the given buffer through
/// the socket. Any specified flags are ignored.
///
/// Returns the number of bytes sent, which may be
/// less than the number of bytes specified.
int receiveBytes(void* buffer, int length, int flags = 0);
/// Receives data from the socket and stores it
/// in buffer. Up to length bytes are received.
///
/// Returns the number of bytes received.
int sendTo(const void* buffer, int length, const SocketAddress& address, int flags = 0);
/// Not supported by a SecureStreamSocket.
///
/// Throws a Poco::InvalidAccessException.
int receiveFrom(void* buffer, int length, SocketAddress& address, int flags = 0);
/// Not supported by a SecureStreamSocket.
///
/// Throws a Poco::InvalidAccessException.
void sendUrgent(unsigned char data);
/// Not supported by a SecureStreamSocket.
///
/// Throws a Poco::InvalidAccessException.
int available();
/// Returns the number of bytes available that can be read
/// without causing the socket to block.
///
/// For an SSL connection, returns the number of bytes that
/// can be read from the currently buffered SSL record,
/// before a new record is read from the underlying socket.
void shutdownReceive();
/// Shuts down the receiving part of the socket connection.
///
/// Since SSL does not support a half shutdown, this does
/// nothing.
void shutdownSend();
/// Shuts down the receiving part of the socket connection.
///
/// Since SSL does not support a half shutdown, this does
/// nothing.
void shutdown();
/// Shuts down the SSL connection.
void abort();
/// Aborts the connection by closing the underlying
/// TCP connection. No orderly SSL shutdown is performed.
bool secure() const;
/// Returns true iff the socket's connection is secure
/// (using SSL or TLS).
void setPeerHostName(const std::string& hostName);
/// Sets the peer host name for certificate validation purposes.
const std::string& getPeerHostName() const;
/// Returns the peer host name.
bool havePeerCertificate() const;
/// Returns true iff the peer has presented a
/// certificate.
X509Certificate peerCertificate() const;
/// Returns the peer's X509 certificate.
///
/// Throws a SSLException if the peer did not
/// present a certificate.
Context::Ptr context() const;
/// Returns the SSL context used by this socket.
void setLazyHandshake(bool flag = true);
/// Enable lazy SSL handshake. If enabled, the SSL handshake
/// will be performed the first time date is sent or
/// received over the connection.
bool getLazyHandshake() const;
/// Returns true if setLazyHandshake(true) has been called.
void verifyPeerCertificate();
/// Performs post-connect (or post-accept) peer certificate validation,
/// using the peer's IP address as host name.
void verifyPeerCertificate(const std::string& hostName);
/// Performs post-connect (or post-accept) peer certificate validation
/// using the given host name.
int completeHandshake();
/// Completes the SSL handshake.
///
/// If the SSL connection was the result of an accept(),
/// the server-side handshake is completed, otherwise
/// a client-side handshake is performed.
Session::Ptr currentSession();
/// Returns the SSL session of the current connection,
/// for reuse in a future connection (if session caching
/// is enabled).
///
/// If no connection is established, returns null.
void useSession(Session::Ptr pSession);
/// Sets the SSL session to use for the next
/// connection. Setting a previously saved Session
/// object is necessary to enable session caching.
///
/// To remove the currently set session, a null pointer
/// can be given.
///
/// Must be called before connect() to be effective.
bool sessionWasReused();
/// Returns true iff a reused session was negotiated during
/// the handshake.
protected:
void acceptSSL();
/// Performs a SSL server-side handshake.
void connectSSL();
/// Performs a SSL client-side handshake on an already connected TCP socket.
~SecureStreamSocketImpl();
/// Destroys the SecureStreamSocketImpl.
static int lastError();
static void error();
static void error(const std::string& arg);
static void error(int code);
static void error(int code, const std::string& arg);
private:
SecureStreamSocketImpl(const SecureStreamSocketImpl&);
SecureStreamSocketImpl& operator = (const SecureStreamSocketImpl&);
SecureSocketImpl _impl;
bool _lazyHandshake;
friend class SecureSocketImpl;
friend class SecureStreamSocket;
};
//
// inlines
//
inline const std::string& SecureStreamSocketImpl::getPeerHostName() const
{
return _impl.getPeerHostName();
}
inline void SecureStreamSocketImpl::setPeerHostName(const std::string& peerHostName)
{
_impl.setPeerHostName(peerHostName);
}
inline Context::Ptr SecureStreamSocketImpl::context() const
{
return _impl.context();
}
inline Session::Ptr SecureStreamSocketImpl::currentSession()
{
return _impl.currentSession();
}
inline void SecureStreamSocketImpl::useSession(Session::Ptr pSession)
{
_impl.useSession(pSession);
}
inline bool SecureStreamSocketImpl::sessionWasReused()
{
return _impl.sessionWasReused();
}
inline int SecureStreamSocketImpl::lastError()
{
return SocketImpl::lastError();
}
inline void SecureStreamSocketImpl::error()
{
return SocketImpl::error();
}
inline void SecureStreamSocketImpl::error(const std::string& arg)
{
return SocketImpl::error(arg);
}
inline void SecureStreamSocketImpl::error(int code)
{
return SocketImpl::error(code);
}
inline void SecureStreamSocketImpl::error(int code, const std::string& arg)
{
return SocketImpl::error(code, arg);
}
} } // namespace Poco::Net
#endif // NetSSL_SecureStreamSocketImpl_INCLUDED

View File

@@ -0,0 +1,79 @@
//
// Session.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: Session
//
// Definition of the Session class.
//
// Copyright (c) 2010, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_Session_INCLUDED
#define NetSSL_Session_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/RefCountedObject.h"
#include "Poco/AutoPtr.h"
#include <openssl/ssl.h>
namespace Poco {
namespace Net {
class NetSSL_API Session: public Poco::RefCountedObject
/// This class encapsulates a SSL session object
/// used with session caching on the client side.
///
/// For session caching to work, a client must
/// save the session object from an existing connection,
/// if it wants to reuse it with a future connection.
{
public:
using Ptr = Poco::AutoPtr<Session>;
SSL_SESSION* sslSession() const;
/// Returns the stored OpenSSL SSL_SESSION object.
protected:
Session(SSL_SESSION* pSession);
/// Creates a new Session object, using the given
/// SSL_SESSION object.
///
/// The SSL_SESSION's reference count is not changed.
~Session();
/// Destroys the Session.
///
/// Calls SSL_SESSION_free() on the stored
/// SSL_SESSION object.
private:
Session();
SSL_SESSION* _pSession;
friend class SecureSocketImpl;
};
//
// inlines
//
inline SSL_SESSION* Session::sslSession() const
{
return _pSession;
}
} } // namespace Poco::Net
#endif // NetSSL_Session_INCLUDED

View File

@@ -0,0 +1,52 @@
//
// Utility.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: Utility
//
// Definition of the Utility class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_Utility_INCLUDED
#define NetSSL_Utility_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/Context.h"
namespace Poco {
namespace Net {
class NetSSL_API Utility
/// This class provides various helper functions for working
/// with the OpenSSL library.
{
public:
static Context::VerificationMode convertVerificationMode(const std::string& verMode);
/// Non-case sensitive conversion of a string to a VerificationMode enum.
/// If verMode is illegal an InvalidArgumentException is thrown.
static std::string convertCertificateError(long errCode);
/// Converts an SSL certificate handling error code into an error message.
static std::string getLastError();
/// Returns the last error from the error stack
static void clearErrorStack();
/// Clears the error stack
};
} } // namespace Poco::Net
#endif // NetSSL_Utility_INCLUDED

View File

@@ -0,0 +1,108 @@
//
// VerificationErrorArgs.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: VerificationErrorArgs
//
// Definition of the VerificationErrorArgs class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_VerificationErrorArgs_INCLUDED
#define NetSSL_VerificationErrorArgs_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/X509Certificate.h"
namespace Poco {
namespace Net {
class NetSSL_API VerificationErrorArgs
/// A utility class for certificate error handling.
{
public:
VerificationErrorArgs(const X509Certificate& cert, int errDepth, int errNum, const std::string& errMsg);
/// Creates the VerificationErrorArgs. _ignoreError is per default set to false.
~VerificationErrorArgs();
/// Destroys the VerificationErrorArgs.
const X509Certificate& certificate() const;
/// Returns the certificate that caused the error.
int errorDepth() const;
/// Returns the position of the certificate in the certificate chain.
int errorNumber() const;
/// Returns the id of the error
const std::string& errorMessage() const;
/// Returns the textual presentation of the errorNumber.
void setIgnoreError(bool ignoreError);
/// setIgnoreError to true, if a verification error is judged non-fatal by the user.
bool getIgnoreError() const;
/// returns the value of _ignoreError
private:
X509Certificate _cert;
int _errorDepth;
int _errorNumber;
std::string _errorMessage; /// Textual representation of the _errorNumber
bool _ignoreError;
};
//
// inlines
//
inline const X509Certificate& VerificationErrorArgs::certificate() const
{
return _cert;
}
inline int VerificationErrorArgs::errorDepth() const
{
return _errorDepth;
}
inline int VerificationErrorArgs::errorNumber() const
{
return _errorNumber;
}
inline const std::string& VerificationErrorArgs::errorMessage() const
{
return _errorMessage;
}
inline void VerificationErrorArgs::setIgnoreError(bool ignoreError)
{
_ignoreError = ignoreError;
}
inline bool VerificationErrorArgs::getIgnoreError() const
{
return _ignoreError;
}
} } // namespace Poco::Net
#endif // NetSSL_VerificationErrorArgs_INCLUDED

View File

@@ -0,0 +1,114 @@
//
// X509Certificate.h
//
// Library: NetSSL_OpenSSL
// Package: SSLCore
// Module: X509Certificate
//
// Definition of the X509Certificate class.
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NetSSL_X509Certificate_INCLUDED
#define NetSSL_X509Certificate_INCLUDED
#include "Poco/Net/NetSSL.h"
#include "Poco/Net/SocketDefs.h"
#include "Poco/Crypto/X509Certificate.h"
#include "Poco/DateTime.h"
#include "Poco/SharedPtr.h"
#include <set>
namespace Poco {
namespace Net {
class HostEntry;
class NetSSL_API X509Certificate: public Poco::Crypto::X509Certificate
/// This class extends Poco::Crypto::X509Certificate with the
/// feature to validate a certificate.
{
public:
explicit X509Certificate(std::istream& istr);
/// Creates the X509Certificate object by reading
/// a certificate in PEM format from a stream.
explicit X509Certificate(const std::string& path);
/// Creates the X509Certificate object by reading
/// a certificate in PEM format from a file.
explicit X509Certificate(X509* pCert);
/// Creates the X509Certificate from an existing
/// OpenSSL certificate. Ownership is taken of
/// the certificate.
X509Certificate(X509* pCert, bool shared);
/// Creates the X509Certificate from an existing
/// OpenSSL certificate. Ownership is taken of
/// the certificate. If shared is true, the
/// certificate's reference count is incremented.
X509Certificate(const Poco::Crypto::X509Certificate& cert);
/// Creates the certificate by copying another one.
X509Certificate(const X509Certificate& cert);
/// Creates the certificate by copying another one.
X509Certificate(X509Certificate&& cert) noexcept;
/// Creates the certificate by moving another one.
X509Certificate& operator = (const Poco::Crypto::X509Certificate& cert);
/// Assigns a certificate.
X509Certificate& operator = (const X509Certificate& cert);
/// Assigns a certificate.
X509Certificate& operator = (X509Certificate&& cert) noexcept;
/// Moves a certificate.
~X509Certificate();
/// Destroys the X509Certificate.
bool verify(const std::string& hostName) const;
/// Verifies the validity of the certificate against the host name.
///
/// For this check to be successful, the certificate must contain
/// a domain name that matches the domain name
/// of the host.
///
/// Returns true if verification succeeded, or false otherwise.
static bool verify(const Poco::Crypto::X509Certificate& cert, const std::string& hostName);
/// Verifies the validity of the certificate against the host name.
///
/// For this check to be successful, the certificate must contain
/// a domain name that matches the domain name
/// of the host.
///
/// Returns true if verification succeeded, or false otherwise.
protected:
static bool containsWildcards(const std::string& commonName);
static bool matchWildcard(const std::string& alias, const std::string& hostName);
private:
enum
{
NAME_BUFFER_SIZE = 256
};
};
} } // namespace Poco::Net
#endif // NetSSL_X509Certificate_INCLUDED