summaryrefslogtreecommitdiffstats
path: root/src/PolarSSL++/SslContext.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/PolarSSL++/SslContext.h')
-rw-r--r--src/PolarSSL++/SslContext.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/PolarSSL++/SslContext.h b/src/PolarSSL++/SslContext.h
new file mode 100644
index 000000000..6b4f2c1e7
--- /dev/null
+++ b/src/PolarSSL++/SslContext.h
@@ -0,0 +1,156 @@
+
+// SslContext.h
+
+// Declares the cSslContext class that holds everything a single SSL context needs to function
+
+
+
+
+
+#pragma once
+
+#include "polarssl/ssl.h"
+#include "../ByteBuffer.h"
+#include "CryptoKey.h"
+#include "RsaPrivateKey.h"
+#include "X509Cert.h"
+
+
+
+
+
+// fwd:
+class cCtrDrbgContext;
+
+
+
+
+
+/**
+Acts as a generic SSL encryptor / decryptor between the two endpoints. The "owner" of this class is expected
+to create it, initialize it and then provide the means of reading and writing data through the SSL link.
+This is an abstract base class, there are descendants that handle the specific aspects of how the SSL peer
+data comes into the system:
+ - cBufferedSslContext uses a cByteBuffer to read and write the data
+ - cCallbackSslContext uses callbacks to provide the data
+*/
+class cSslContext abstract
+{
+public:
+ /** Creates a new uninitialized context */
+ cSslContext(void);
+
+ virtual ~cSslContext();
+
+ /** Initializes the context for use as a server or client.
+ Returns 0 on success, PolarSSL error on failure. */
+ int Initialize(bool a_IsClient, const SharedPtr<cCtrDrbgContext> & a_CtrDrbg = SharedPtr<cCtrDrbgContext>());
+
+ /** Returns true if the object has been initialized properly. */
+ bool IsValid(void) const { return m_IsValid; }
+
+ /** Sets the certificate to use as our own. Must be used when representing a server, optional when client.
+ Must be called after Initialize(). */
+ void SetOwnCert(const cX509CertPtr & a_OwnCert, const cRsaPrivateKeyPtr & a_OwnCertPrivKey);
+
+ /** Sets the certificate to use as our own. Must be used when representing a server, optional when client.
+ Must be called after Initialize(). */
+ void SetOwnCert(const cX509CertPtr & a_OwnCert, const cCryptoKeyPtr & a_OwnCertPrivKey);
+
+ /** Sets a cert chain as the trusted cert store for this context. Must be called after Initialize().
+ Calling this will switch the context into strict cert verification mode.
+ a_ExpectedPeerName is the CommonName that we expect the SSL peer to have in its cert,
+ if it is different, the verification will fail. An empty string will disable the CN check. */
+ void SetCACerts(const cX509CertPtr & a_CACert, const AString & a_ExpectedPeerName);
+
+ /** Writes data to be encrypted and sent to the SSL peer. Will perform SSL handshake, if needed.
+ Returns the number of bytes actually written, or PolarSSL error code.
+ If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any
+ cached outgoing data to the SSL peer and write any incoming data received from the SSL peer and then call
+ this function again with the same parameters. Note that this may repeat a few times before the data is
+ actually written, mainly due to initial handshake. */
+ int WritePlain(const void * a_Data, size_t a_NumBytes);
+
+ /** Reads data decrypted from the SSL stream. Will perform SSL handshake, if needed.
+ Returns the number of bytes actually read, or PolarSSL error code.
+ If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any
+ cached outgoing data to the SSL peer and write any incoming data received from the SSL peer and then call
+ this function again with the same parameters. Note that this may repeat a few times before the data is
+ actually read, mainly due to initial handshake. */
+ int ReadPlain(void * a_Data, size_t a_MaxBytes);
+
+ /** Performs the SSL handshake.
+ Returns zero on success, PoladSSL error code on failure.
+ If the return value is POLARSSL_ERR_NET_WANT_READ or POLARSSL_ERR_NET_WANT_WRITE, the owner should send any
+ cached outgoing data to the SSL peer and write any incoming data received from the SSL peer and then call
+ this function again. Note that this may repeat a few times before the handshake is completed. */
+ int Handshake(void);
+
+ /** Returns true if the SSL handshake has been completed. */
+ bool HasHandshaken(void) const { return m_HasHandshaken; }
+
+ /** Notifies the SSL peer that the connection is being closed.
+ Returns 0 on success, PolarSSL error code on failure. */
+ int NotifyClose(void);
+
+protected:
+ /** True if the object has been initialized properly. */
+ bool m_IsValid;
+
+ /** The random generator to use */
+ SharedPtr<cCtrDrbgContext> m_CtrDrbg;
+
+ /** The SSL context that PolarSSL uses. */
+ ssl_context m_Ssl;
+
+ /** The certificate that we present to the peer. */
+ cX509CertPtr m_OwnCert;
+
+ /** Private key for m_OwnCert, if initialized from a cRsaPrivateKey. */
+ cRsaPrivateKeyPtr m_OwnCertPrivKey;
+
+ /** Private key for m_OwnCert, if initialized from a cCryptoKey. */
+ cCryptoKeyPtr m_OwnCertPrivKey2;
+
+ /** True if the SSL handshake has been completed. */
+ bool m_HasHandshaken;
+
+ /** A copy of the trusted CA root cert store that is passed to us in SetCACerts(), so that the pointer
+ stays valid even after the call, when PolarSSL finally uses it. */
+ cX509CertPtr m_CACerts;
+
+ /** Buffer for the expected peer name. We need to buffer it because the caller may free the string they
+ give us before PolarSSL consumes the raw pointer it gets to the CN. */
+ AString m_ExpectedPeerName;
+
+
+ /** The callback used by PolarSSL when it wants to read encrypted data. */
+ static int ReceiveEncrypted(void * a_This, unsigned char * a_Buffer, size_t a_NumBytes)
+ {
+ return ((cSslContext *)a_This)->ReceiveEncrypted(a_Buffer, a_NumBytes);
+ }
+
+ /** The callback used by PolarSSL when it wants to write encrypted data. */
+ static int SendEncrypted(void * a_This, const unsigned char * a_Buffer, size_t a_NumBytes)
+ {
+ return ((cSslContext *)a_This)->SendEncrypted(a_Buffer, a_NumBytes);
+ }
+
+ #ifdef _DEBUG
+ /** The callback used by PolarSSL to output debug messages */
+ static void SSLDebugMessage(void * a_UserParam, int a_Level, const char * a_Text);
+
+ /** The callback used by PolarSSL to log information on the cert chain */
+ static int SSLVerifyCert(void * a_This, x509_crt * a_Crt, int a_Depth, int * a_Flags);
+ #endif // _DEBUG
+
+ /** Called when PolarSSL wants to read encrypted data. */
+ virtual int ReceiveEncrypted(unsigned char * a_Buffer, size_t a_NumBytes) = 0;
+
+ /** Called when PolarSSL wants to write encrypted data. */
+ virtual int SendEncrypted(const unsigned char * a_Buffer, size_t a_NumBytes) = 0;
+} ;
+
+
+
+