mirror of
https://github.com/MariaDB/server.git
synced 2025-02-01 03:21:53 +01:00
540 lines
15 KiB
C++
540 lines
15 KiB
C++
/* yassl_int.hpp
|
|
*
|
|
* Copyright (C) 2003 Sawtooth Consulting Ltd.
|
|
*
|
|
* This file is part of yaSSL.
|
|
*
|
|
* yaSSL is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* yaSSL is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 "crypto_wrapper.hpp"
|
|
#include "cert_wrapper.hpp"
|
|
#include "log.hpp"
|
|
#include "lock.hpp"
|
|
|
|
|
|
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
|
|
};
|
|
|
|
|
|
// combines all states
|
|
class States {
|
|
enum {MAX_ERROR_SZ = 80 };
|
|
|
|
RecordLayerState recordLayer_;
|
|
HandShakeState handshakeLayer_;
|
|
ClientState clientState_;
|
|
ServerState serverState_;
|
|
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 char* getString() const;
|
|
YasslError What() const;
|
|
|
|
RecordLayerState& useRecord();
|
|
HandShakeState& useHandShake();
|
|
ClientState& useClient();
|
|
ServerState& useServer();
|
|
char* useString();
|
|
void SetError(YasslError);
|
|
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:
|
|
static sslFactory instance;
|
|
sslFactory(const sslFactory&); // hide copy
|
|
sslFactory& operator=(const sslFactory&); // and assign
|
|
};
|
|
|
|
|
|
// openSSL X509 names
|
|
class X509_NAME {
|
|
char* name_;
|
|
public:
|
|
X509_NAME(const char*, size_t sz);
|
|
~X509_NAME();
|
|
|
|
char* GetName();
|
|
private:
|
|
X509_NAME(const X509_NAME&); // hide copy
|
|
X509_NAME& operator=(const X509_NAME&); // and assign
|
|
};
|
|
|
|
|
|
// openSSL X509
|
|
class X509 {
|
|
X509_NAME issuer_;
|
|
X509_NAME subject_;
|
|
public:
|
|
X509(const char* i, size_t, const char* s, size_t);
|
|
~X509() {}
|
|
|
|
X509_NAME* GetIssuer();
|
|
X509_NAME* GetSubject();
|
|
private:
|
|
X509(const X509&); // hide copy
|
|
X509& operator=(const X509&); // and assign
|
|
};
|
|
|
|
|
|
// openSSL bignum
|
|
struct BIGNUM {
|
|
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
|
|
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;
|
|
void SetTimeOut(uint);
|
|
|
|
SSL_SESSION& operator=(const SSL_SESSION&); // allow assign for resumption
|
|
private:
|
|
SSL_SESSION(const SSL_SESSION&); // hide copy
|
|
};
|
|
|
|
|
|
// holds all sessions
|
|
class Sessions {
|
|
mySTL::list<SSL_SESSION*> list_;
|
|
RandomPool random_; // for session cleaning
|
|
Mutex mutex_; // no-op for single threaded
|
|
|
|
Sessions() {} // only GetSessions can create
|
|
public:
|
|
SSL_SESSION* lookup(const opaque*, SSL_SESSION* copy = 0);
|
|
void add(const SSL&);
|
|
void remove(const opaque*);
|
|
|
|
~Sessions();
|
|
|
|
friend Sessions& GetSessions(); // singleton creator
|
|
private:
|
|
Sessions(const Sessions&); // hide copy
|
|
Sessions& operator=(const Sessions&); // and assign
|
|
static Sessions instance;
|
|
};
|
|
|
|
|
|
Sessions& GetSessions(); // forward singletons
|
|
sslFactory& GetSSL_Factory();
|
|
|
|
|
|
// openSSL method and context types
|
|
class SSL_METHOD {
|
|
ProtocolVersion version_;
|
|
ConnectionEnd side_;
|
|
bool verifyPeer_;
|
|
bool failNoCert_;
|
|
public:
|
|
explicit SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv);
|
|
|
|
ProtocolVersion getVersion() const;
|
|
ConnectionEnd getSide() const;
|
|
|
|
void setVerifyPeer();
|
|
void setFailNoCert();
|
|
|
|
bool verifyPeer() const;
|
|
bool failNoCert() 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 mySTL::list<x509*> CertList;
|
|
private:
|
|
SSL_METHOD* method_;
|
|
x509* certificate_;
|
|
x509* privateKey_;
|
|
CertList caList_;
|
|
Ciphers ciphers_;
|
|
DH_Parms dhParms_;
|
|
Stats stats_;
|
|
Mutex mutex_; // for Stats
|
|
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;
|
|
|
|
void setVerifyPeer();
|
|
void setFailNoCert();
|
|
bool SetCipherList(const char*);
|
|
bool SetDH(const DH&);
|
|
|
|
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 {
|
|
typedef mySTL::list<input_buffer*> inputList;
|
|
typedef mySTL::list<output_buffer*> outputList;
|
|
|
|
inputList dataList_; // list of users app data / handshake
|
|
outputList handShakeList_; // buffered handshake msgs
|
|
public:
|
|
Buffers() {}
|
|
~Buffers();
|
|
|
|
const inputList& getData() const;
|
|
const outputList& getHandShake() const;
|
|
|
|
inputList& useData();
|
|
outputList& useHandShake();
|
|
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*);
|
|
|
|
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
|
|
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;
|
|
|
|
Crypto& useCrypto();
|
|
Security& useSecurity();
|
|
States& useStates();
|
|
sslHashes& useHashes();
|
|
Socket& useSocket();
|
|
Log& useLog();
|
|
|
|
// 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);
|
|
|
|
// helpers
|
|
bool isTLS() const;
|
|
void order_error();
|
|
void makeMasterSecret();
|
|
void makeTLSMasterSecret();
|
|
void addData(input_buffer* data);
|
|
void fillData(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);
|
|
|
|
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
|
|
};
|
|
|
|
|
|
|
|
// 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
|