aboutsummaryrefslogtreecommitdiff
path: root/mysql/extra/yassl/include/yassl_int.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'mysql/extra/yassl/include/yassl_int.hpp')
-rw-r--r--mysql/extra/yassl/include/yassl_int.hpp725
1 files changed, 725 insertions, 0 deletions
diff --git a/mysql/extra/yassl/include/yassl_int.hpp b/mysql/extra/yassl/include/yassl_int.hpp
new file mode 100644
index 0000000..240cf94
--- /dev/null
+++ b/mysql/extra/yassl/include/yassl_int.hpp
@@ -0,0 +1,725 @@
+/*
+ Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ MA 02110-1301 USA.
+*/
+
+
+/* yaSSL internal header defines SSL supporting types not specified in the
+ * draft along with type conversion functions and openssl compatibility
+ */
+
+
+#ifndef yaSSL_INT_HPP
+#define yaSSL_INT_HPP
+
+#include "yassl_imp.hpp"
+#include "yassl_error.hpp"
+#include "crypto_wrapper.hpp"
+#include "cert_wrapper.hpp"
+#include "log.hpp"
+#include "lock.hpp"
+#include "openssl/ssl.h" // ASN1_STRING and DH
+
+// Check if _POSIX_THREADS should be forced
+#if !defined(_POSIX_THREADS) && defined(__hpux)
+// HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
+#define _POSIX_THREADS
+#endif
+
+#ifdef _POSIX_THREADS
+ #include <pthread.h>
+#endif
+
+
+namespace STL = STL_NAMESPACE;
+
+
+namespace yaSSL {
+
+
+// State Machine for Record Layer Protocol
+enum RecordLayerState {
+ recordNotReady = 0, // fatal error, no more processing
+ recordReady
+};
+
+
+// State Machine for HandShake Protocol
+enum HandShakeState {
+ handShakeNotReady = 0, // fatal error, no more processing
+ preHandshake, // initial state
+ inHandshake, // handshake started
+ handShakeReady // handshake done
+};
+
+
+// client input HandShake state, use if HandShakeState == inHandShake
+enum ClientState {
+ serverNull = 0,
+ serverHelloComplete,
+ serverCertComplete,
+ serverKeyExchangeComplete,
+ serverHelloDoneComplete,
+ serverFinishedComplete
+};
+
+
+// server input HandShake state, use if HandShakeState == inHandShake
+enum ServerState {
+ clientNull = 0,
+ clientHelloComplete,
+ clientKeyExchangeComplete,
+ clientFinishedComplete
+};
+
+
+// client connect state for nonblocking restart
+enum ConnectState {
+ CONNECT_BEGIN = 0,
+ CLIENT_HELLO_SENT,
+ FIRST_REPLY_DONE,
+ FINISHED_DONE,
+ SECOND_REPLY_DONE
+};
+
+
+// server accpet state for nonblocking restart
+enum AcceptState {
+ ACCEPT_BEGIN = 0,
+ ACCEPT_FIRST_REPLY_DONE,
+ SERVER_HELLO_DONE,
+ ACCEPT_SECOND_REPLY_DONE,
+ ACCEPT_FINISHED_DONE,
+ ACCEPT_THIRD_REPLY_DONE
+};
+
+
+// track received messages to explicitly disallow duplicate messages
+struct RecvdMessages {
+ uint8 gotClientHello_;
+ uint8 gotServerHello_;
+ uint8 gotCert_;
+ uint8 gotServerKeyExchange_;
+ uint8 gotCertRequest_;
+ uint8 gotServerHelloDone_;
+ uint8 gotCertVerify_;
+ uint8 gotClientKeyExchange_;
+ uint8 gotFinished_;
+ RecvdMessages() : gotClientHello_(0), gotServerHello_(0), gotCert_(0),
+ gotServerKeyExchange_(0), gotCertRequest_(0),
+ gotServerHelloDone_(0), gotCertVerify_(0),
+ gotClientKeyExchange_(0), gotFinished_(0)
+ {}
+};
+
+
+// combines all states
+class States {
+ RecordLayerState recordLayer_;
+ HandShakeState handshakeLayer_;
+ ClientState clientState_;
+ ServerState serverState_;
+ ConnectState connectState_;
+ AcceptState acceptState_;
+ RecvdMessages recvdMessages_;
+ char errorString_[MAX_ERROR_SZ];
+ YasslError what_;
+public:
+ States();
+
+ const RecordLayerState& getRecord() const;
+ const HandShakeState& getHandShake() const;
+ const ClientState& getClient() const;
+ const ServerState& getServer() const;
+ const ConnectState& GetConnect() const;
+ const AcceptState& GetAccept() const;
+ const char* getString() const;
+ YasslError What() const;
+
+ RecordLayerState& useRecord();
+ HandShakeState& useHandShake();
+ ClientState& useClient();
+ ServerState& useServer();
+ ConnectState& UseConnect();
+ AcceptState& UseAccept();
+ char* useString();
+ void SetError(YasslError);
+ int SetMessageRecvd(HandShakeType);
+private:
+ States(const States&); // hide copy
+ States& operator=(const States&); // and assign
+};
+
+
+// holds all factories
+class sslFactory {
+ MessageFactory messageFactory_; // creates new messages by type
+ HandShakeFactory handShakeFactory_; // creates new handshake types
+ ServerKeyFactory serverKeyFactory_; // creates new server key types
+ ClientKeyFactory clientKeyFactory_; // creates new client key types
+
+ sslFactory(); // only GetSSL_Factory creates
+public:
+ const MessageFactory& getMessage() const;
+ const HandShakeFactory& getHandShake() const;
+ const ServerKeyFactory& getServerKey() const;
+ const ClientKeyFactory& getClientKey() const;
+
+ friend sslFactory& GetSSL_Factory(); // singleton creator
+private:
+ sslFactory(const sslFactory&); // hide copy
+ sslFactory& operator=(const sslFactory&); // and assign
+};
+
+
+#undef X509_NAME // wincrypt.h clash
+
+// openSSL X509 names
+class X509_NAME {
+ char* name_;
+ size_t sz_;
+ int cnPosition_; // start of common name, -1 is none
+ int cnLen_; // length of above
+ ASN1_STRING entry_;
+public:
+ X509_NAME(const char*, size_t sz, int pos, int len);
+ ~X509_NAME();
+
+ const char* GetName() const;
+ ASN1_STRING* GetEntry(int i);
+ size_t GetLength() const;
+ int GetCnPosition() const { return cnPosition_; }
+ int GetCnLength() const { return cnLen_; }
+
+private:
+ X509_NAME(const X509_NAME&); // hide copy
+ X509_NAME& operator=(const X509_NAME&); // and assign
+};
+
+
+class StringHolder {
+ ASN1_STRING asnString_;
+public:
+ StringHolder(const char* str, int sz, byte type= 0);
+ ~StringHolder();
+
+ ASN1_STRING* GetString();
+private:
+ StringHolder(const StringHolder&); // hide copy
+ StringHolder& operator=(const StringHolder&); // and assign
+};
+
+
+// openSSL X509
+class X509 {
+ X509_NAME issuer_;
+ X509_NAME subject_;
+ StringHolder beforeDate_; // not valid before
+ StringHolder afterDate_; // not valid after
+public:
+ X509(const char* i, size_t, const char* s, size_t,
+ ASN1_STRING *b, ASN1_STRING *a, int, int, int, int);
+ ~X509() {}
+
+ X509_NAME* GetIssuer();
+ X509_NAME* GetSubject();
+
+ ASN1_STRING* GetBefore();
+ ASN1_STRING* GetAfter();
+
+private:
+ X509(const X509&); // hide copy
+ X509& operator=(const X509&); // and assign
+};
+
+
+// openSSL bignum
+struct BIGNUM {
+ /*
+ gcc 2.96 fix: because of two Integer classes (yaSSL::Integer and
+ TaoCrypt::Integer), we need to explicitly state the namespace
+ here to let gcc 2.96 deduce the correct type.
+ */
+ yaSSL::Integer int_;
+ void assign(const byte* b, uint s) { int_.assign(b,s); }
+};
+
+
+// openSSL session
+class SSL_SESSION {
+ opaque sessionID_[ID_LEN];
+ opaque master_secret_[SECRET_LEN];
+ Cipher suite_[SUITE_LEN];
+ uint bornOn_; // create time in seconds
+ uint timeout_; // timeout in seconds
+ RandomPool& random_; // will clean master secret
+ X509* peerX509_;
+public:
+ explicit SSL_SESSION(RandomPool&);
+ SSL_SESSION(const SSL&, RandomPool&);
+ ~SSL_SESSION();
+
+ const opaque* GetID() const;
+ const opaque* GetSecret() const;
+ const Cipher* GetSuite() const;
+ uint GetBornOn() const;
+ uint GetTimeOut() const;
+ X509* GetPeerX509() const;
+ void SetTimeOut(uint);
+
+ SSL_SESSION& operator=(const SSL_SESSION&); // allow assign for resumption
+private:
+ SSL_SESSION(const SSL_SESSION&); // hide copy
+
+ void CopyX509(X509*);
+};
+
+
+// holds all sessions
+class Sessions {
+ STL::list<SSL_SESSION*> list_;
+ RandomPool random_; // for session cleaning
+ Mutex mutex_; // no-op for single threaded
+ int count_; // flush counter
+
+ Sessions() : count_(0) {} // only GetSessions can create
+public:
+ SSL_SESSION* lookup(const opaque*, SSL_SESSION* copy = 0);
+ void add(const SSL&);
+ void remove(const opaque*);
+ void Flush();
+
+ ~Sessions();
+
+ friend void Session_initialize();
+ friend Sessions& GetSessions(); // singleton creator
+private:
+ Sessions(const Sessions&); // hide copy
+ Sessions& operator=(const Sessions&); // and assign
+};
+
+
+#ifdef _POSIX_THREADS
+ typedef pthread_t THREAD_ID_T;
+#else
+ typedef DWORD THREAD_ID_T;
+#endif
+
+// thread error data
+struct ThreadError {
+ THREAD_ID_T threadID_;
+ int errorID_;
+};
+
+
+// holds all errors
+class Errors {
+ STL::list<ThreadError> list_;
+ Mutex mutex_;
+
+ Errors() {} // only GetErrors can create
+public:
+ int Lookup(bool peek); // self lookup
+ void Add(int);
+ void Remove(); // remove self
+
+ ~Errors() {}
+
+ friend Errors& GetErrors(); // singleton creator
+private:
+ Errors(const Errors&); // hide copy
+ Errors& operator=(const Errors); // and assign
+};
+
+
+Sessions& GetSessions(); // forward singletons
+sslFactory& GetSSL_Factory();
+Errors& GetErrors();
+
+
+// openSSL method and context types
+class SSL_METHOD {
+ ProtocolVersion version_;
+ ConnectionEnd side_;
+ bool verifyPeer_; // request or send certificate
+ bool verifyNone_; // whether to verify certificate
+ bool failNoCert_;
+ bool multipleProtocol_; // for SSLv23 compatibility
+public:
+ SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv,
+ bool multipleProtocol = false);
+
+ ProtocolVersion getVersion() const;
+ ConnectionEnd getSide() const;
+
+ void setVerifyPeer();
+ void setVerifyNone();
+ void setFailNoCert();
+
+ bool verifyPeer() const;
+ bool verifyNone() const;
+ bool failNoCert() const;
+ bool multipleProtocol() const;
+private:
+ SSL_METHOD(const SSL_METHOD&); // hide copy
+ SSL_METHOD& operator=(const SSL_METHOD&); // and assign
+};
+
+
+struct Ciphers {
+ bool setSuites_; // user set suites from default
+ byte suites_[MAX_SUITE_SZ]; // new suites
+ int suiteSz_; // suite length in bytes
+
+ Ciphers() : setSuites_(false), suiteSz_(0) {}
+};
+
+
+struct DH; // forward
+
+
+// save for SSL construction
+struct DH_Parms {
+ Integer p_;
+ Integer g_;
+ bool set_; // if set by user
+
+ DH_Parms() : set_(false) {}
+};
+
+
+enum StatsField {
+ Accept, Connect, AcceptGood, ConnectGood, AcceptRenegotiate,
+ ConnectRenegotiate, Hits, CbHits, CacheFull, Misses, Timeouts, Number,
+ GetCacheSize, VerifyMode, VerifyDepth
+};
+
+
+// SSL stats
+struct Stats {
+ long accept_;
+ long connect_;
+ long acceptGood_;
+ long connectGood_;
+ long acceptRenegotiate_;
+ long connectRenegotiate_;
+
+ long hits_;
+ long cbHits_;
+ long cacheFull_;
+ long misses_;
+ long timeouts_;
+ long number_;
+ long getCacheSize_;
+
+ int verifyMode_;
+ int verifyDepth_;
+public:
+ Stats() : accept_(0), connect_(0), acceptGood_(0), connectGood_(0),
+ acceptRenegotiate_(0), connectRenegotiate_(0), hits_(0), cbHits_(0),
+ cacheFull_(0), misses_(0), timeouts_(0), number_(0), getCacheSize_(0),
+ verifyMode_(0), verifyDepth_(0)
+ {}
+private:
+ Stats(const Stats&); // hide copy
+ Stats& operator=(const Stats&); // and assign
+};
+
+
+// the SSL context
+class SSL_CTX {
+public:
+ typedef STL::list<x509*> CertList;
+private:
+ SSL_METHOD* method_;
+ x509* certificate_;
+ x509* privateKey_;
+ CertList caList_;
+ Ciphers ciphers_;
+ DH_Parms dhParms_;
+ pem_password_cb passwordCb_;
+ void* userData_;
+ bool sessionCacheOff_;
+ bool sessionCacheFlushOff_;
+ Stats stats_;
+ Mutex mutex_; // for Stats
+ VerifyCallback verifyCallback_;
+public:
+ explicit SSL_CTX(SSL_METHOD* meth);
+ ~SSL_CTX();
+
+ const x509* getCert() const;
+ const x509* getKey() const;
+ const SSL_METHOD* getMethod() const;
+ const Ciphers& GetCiphers() const;
+ const DH_Parms& GetDH_Parms() const;
+ const Stats& GetStats() const;
+ VerifyCallback getVerifyCallback() const;
+ pem_password_cb GetPasswordCb() const;
+ void* GetUserData() const;
+ bool GetSessionCacheOff() const;
+ bool GetSessionCacheFlushOff() const;
+
+ void setVerifyPeer();
+ void setVerifyNone();
+ void setFailNoCert();
+ void setVerifyCallback(VerifyCallback);
+ bool SetCipherList(const char*);
+ bool SetDH(const DH&);
+ void SetPasswordCb(pem_password_cb cb);
+ void SetUserData(void*);
+ void SetSessionCacheOff();
+ void SetSessionCacheFlushOff();
+ void SetMethod(SSL_METHOD* meth);
+ void IncrementStats(StatsField);
+ void AddCA(x509* ca);
+ const CertList& GetCA_List() const;
+
+ friend int read_file(SSL_CTX*, const char*, int, CertType);
+private:
+ SSL_CTX(const SSL_CTX&); // hide copy
+ SSL_CTX& operator=(const SSL_CTX&); // and assign
+};
+
+
+// holds all cryptographic types
+class Crypto {
+ Digest* digest_; // agreed upon digest
+ BulkCipher* cipher_; // agreed upon cipher
+ DiffieHellman* dh_; // dh parms
+ RandomPool random_; // random number generator
+ CertManager cert_; // manages certificates
+public:
+ explicit Crypto();
+ ~Crypto();
+
+ const Digest& get_digest() const;
+ const BulkCipher& get_cipher() const;
+ const DiffieHellman& get_dh() const;
+ const RandomPool& get_random() const;
+ const CertManager& get_certManager() const;
+
+ Digest& use_digest();
+ BulkCipher& use_cipher();
+ DiffieHellman& use_dh();
+ RandomPool& use_random();
+ CertManager& use_certManager();
+
+ void SetDH(DiffieHellman*);
+ void SetDH(const DH_Parms&);
+ void setDigest(Digest*);
+ void setCipher(BulkCipher*);
+
+ bool DhSet();
+private:
+ Crypto(const Crypto&); // hide copy
+ Crypto& operator=(const Crypto&); // and assign
+};
+
+
+// holds all handshake and verify hashes
+class sslHashes {
+ MD5 md5HandShake_; // md5 handshake hash
+ SHA shaHandShake_; // sha handshake hash
+ Finished verify_; // peer's verify hash
+ Hashes certVerify_; // peer's cert verify hash
+public:
+ sslHashes() {}
+
+ const MD5& get_MD5() const;
+ const SHA& get_SHA() const;
+ const Finished& get_verify() const;
+ const Hashes& get_certVerify() const;
+
+ MD5& use_MD5();
+ SHA& use_SHA();
+ Finished& use_verify();
+ Hashes& use_certVerify();
+private:
+ sslHashes(const sslHashes&); // hide copy
+ sslHashes& operator=(const sslHashes&); // and assign
+};
+
+
+// holds input and output buffers
+class Buffers {
+public:
+ typedef STL::list<input_buffer*> inputList;
+ typedef STL::list<output_buffer*> outputList;
+ int prevSent; // previous plain text bytes sent when got WANT_WRITE
+ int plainSz; // plain text bytes in buffer to send when got WANT_WRITE
+private:
+ inputList dataList_; // list of users app data / handshake
+ outputList handShakeList_; // buffered handshake msgs
+ input_buffer* rawInput_; // buffered raw input yet to process
+ output_buffer* output_; // WANT_WRITE buffered output
+public:
+ Buffers();
+ ~Buffers();
+
+ const inputList& getData() const;
+ const outputList& getHandShake() const;
+
+ inputList& useData();
+ outputList& useHandShake();
+
+ void SetRawInput(input_buffer*); // takes ownership
+ input_buffer* TakeRawInput(); // takes ownership
+ void SetOutput(output_buffer*); // takes ownership
+ output_buffer* TakeOutput(); // takes ownership
+private:
+ Buffers(const Buffers&); // hide copy
+ Buffers& operator=(const Buffers&); // and assign
+};
+
+
+// wraps security parameters
+class Security {
+ Connection conn_; // connection information
+ Parameters parms_; // may be pending
+ SSL_SESSION resumeSession_; // if resuming
+ SSL_CTX* ctx_; // context used to init
+ bool resuming_; // trying to resume
+public:
+ Security(ProtocolVersion, RandomPool&, ConnectionEnd, const Ciphers&,
+ SSL_CTX*, bool);
+
+ const SSL_CTX* GetContext() const;
+ const Connection& get_connection() const;
+ const Parameters& get_parms() const;
+ const SSL_SESSION& get_resume() const;
+ bool get_resuming() const;
+
+ Connection& use_connection();
+ Parameters& use_parms();
+ SSL_SESSION& use_resume();
+
+ void set_resuming(bool b);
+private:
+ Security(const Security&); // hide copy
+ Security& operator=(const Security&); // and assign
+};
+
+
+// THE SSL type
+class SSL {
+ Crypto crypto_; // agreed crypto agents
+ Security secure_; // Connection and Session parms
+ States states_; // Record and HandShake states
+ sslHashes hashes_; // handshake, finished hashes
+ Socket socket_; // socket wrapper
+ Buffers buffers_; // buffered handshakes and data
+ Log log_; // logger
+ bool quietShutdown_;
+
+ // optimization variables
+ bool has_data_; // buffered data ready?
+public:
+ SSL(SSL_CTX* ctx);
+
+ // gets and uses
+ const Crypto& getCrypto() const;
+ const Security& getSecurity() const;
+ const States& getStates() const;
+ const sslHashes& getHashes() const;
+ const sslFactory& getFactory() const;
+ const Socket& getSocket() const;
+ YasslError GetError() const;
+ bool GetMultiProtocol() const;
+ bool CompressionOn() const;
+
+ Crypto& useCrypto();
+ Security& useSecurity();
+ States& useStates();
+ sslHashes& useHashes();
+ Socket& useSocket();
+ Log& useLog();
+ Buffers& useBuffers();
+
+ bool HasData() const;
+ bool GetQuietShutdown() const;
+
+ // sets
+ void set_pending(Cipher suite);
+ void set_random(const opaque*, ConnectionEnd);
+ void set_sessionID(const opaque*);
+ void set_session(SSL_SESSION*);
+ void set_preMaster(const opaque*, uint);
+ void set_masterSecret(const opaque*);
+ void SetError(YasslError);
+ int SetCompression();
+ void UnSetCompression();
+ void SetQuietShutdown(bool mode);
+
+ // helpers
+ bool isTLS() const;
+ bool isTLSv1_1() const;
+ void order_error();
+ void makeMasterSecret();
+ void makeTLSMasterSecret();
+ void addData(input_buffer* data);
+ void fillData(Data&);
+ void PeekData(Data&);
+ void addBuffer(output_buffer* b);
+ void flushBuffer();
+ void verifyState(const RecordLayerHeader&);
+ void verifyState(const HandShakeHeader&);
+ void verifyState(ClientState);
+ void verifyState(ServerState);
+ void verfiyHandShakeComplete();
+ void matchSuite(const opaque*, uint length);
+ void deriveKeys();
+ void deriveTLSKeys();
+ void Send(const byte*, uint);
+ void SendWriteBuffered();
+
+ uint bufferedData();
+ uint get_SEQIncrement(bool);
+
+ const byte* get_macSecret(bool);
+private:
+ void storeKeys(const opaque*);
+ void setKeys();
+ void verifyClientState(HandShakeType);
+ void verifyServerState(HandShakeType);
+
+ SSL(const SSL&); // hide copy
+ const SSL& operator=(const SSL&); // and assign
+};
+
+
+// compression
+int Compress(const byte*, int, input_buffer&);
+int DeCompress(input_buffer&, int, input_buffer&);
+
+
+// conversion functions
+void c32to24(uint32, uint24&);
+void c24to32(const uint24, uint32&);
+
+uint32 c24to32(const uint24);
+
+void ato16(const opaque*, uint16&);
+void ato24(const opaque*, uint24&);
+
+void c16toa(uint16, opaque*);
+void c24toa(const uint24, opaque*);
+void c32toa(uint32 u32, opaque*);
+
+
+} // naemspace
+
+#endif // yaSSL_INT_HPP