mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / extra / yassl / include / yassl_int.hpp
blob6f3ea1c6ad3c379dcaf8c2310e2a4e7dcd719ab8
1 /*
2 Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; see the file COPYING. If not, write to the
15 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
16 MA 02110-1301 USA.
20 /* yaSSL internal header defines SSL supporting types not specified in the
21 * draft along with type conversion functions and openssl compatibility
25 #ifndef yaSSL_INT_HPP
26 #define yaSSL_INT_HPP
28 #include "yassl_imp.hpp"
29 #include "yassl_error.hpp"
30 #include "crypto_wrapper.hpp"
31 #include "cert_wrapper.hpp"
32 #include "log.hpp"
33 #include "lock.hpp"
34 #include "openssl/ssl.h" // ASN1_STRING and DH
36 // Check if _POSIX_THREADS should be forced
37 #if !defined(_POSIX_THREADS) && defined(__hpux)
38 // HPUX does not define _POSIX_THREADS as it's not _fully_ implemented
39 #define _POSIX_THREADS
40 #endif
42 #ifdef _POSIX_THREADS
43 #include <pthread.h>
44 #endif
47 namespace STL = STL_NAMESPACE;
50 namespace yaSSL {
53 // State Machine for Record Layer Protocol
54 enum RecordLayerState {
55 recordNotReady = 0, // fatal error, no more processing
56 recordReady
60 // State Machine for HandShake Protocol
61 enum HandShakeState {
62 handShakeNotReady = 0, // fatal error, no more processing
63 preHandshake, // initial state
64 inHandshake, // handshake started
65 handShakeReady // handshake done
69 // client input HandShake state, use if HandShakeState == inHandShake
70 enum ClientState {
71 serverNull = 0,
72 serverHelloComplete,
73 serverCertComplete,
74 serverKeyExchangeComplete,
75 serverHelloDoneComplete,
76 serverFinishedComplete
80 // server input HandShake state, use if HandShakeState == inHandShake
81 enum ServerState {
82 clientNull = 0,
83 clientHelloComplete,
84 clientKeyExchangeComplete,
85 clientFinishedComplete
89 // client connect state for nonblocking restart
90 enum ConnectState {
91 CONNECT_BEGIN = 0,
92 CLIENT_HELLO_SENT,
93 FIRST_REPLY_DONE,
94 FINISHED_DONE,
95 SECOND_REPLY_DONE
99 // server accpet state for nonblocking restart
100 enum AcceptState {
101 ACCEPT_BEGIN = 0,
102 ACCEPT_FIRST_REPLY_DONE,
103 SERVER_HELLO_DONE,
104 ACCEPT_SECOND_REPLY_DONE,
105 ACCEPT_FINISHED_DONE,
106 ACCEPT_THIRD_REPLY_DONE
110 // combines all states
111 class States {
112 RecordLayerState recordLayer_;
113 HandShakeState handshakeLayer_;
114 ClientState clientState_;
115 ServerState serverState_;
116 ConnectState connectState_;
117 AcceptState acceptState_;
118 char errorString_[MAX_ERROR_SZ];
119 YasslError what_;
120 public:
121 States();
123 const RecordLayerState& getRecord() const;
124 const HandShakeState& getHandShake() const;
125 const ClientState& getClient() const;
126 const ServerState& getServer() const;
127 const ConnectState& GetConnect() const;
128 const AcceptState& GetAccept() const;
129 const char* getString() const;
130 YasslError What() const;
132 RecordLayerState& useRecord();
133 HandShakeState& useHandShake();
134 ClientState& useClient();
135 ServerState& useServer();
136 ConnectState& UseConnect();
137 AcceptState& UseAccept();
138 char* useString();
139 void SetError(YasslError);
140 private:
141 States(const States&); // hide copy
142 States& operator=(const States&); // and assign
146 // holds all factories
147 class sslFactory {
148 MessageFactory messageFactory_; // creates new messages by type
149 HandShakeFactory handShakeFactory_; // creates new handshake types
150 ServerKeyFactory serverKeyFactory_; // creates new server key types
151 ClientKeyFactory clientKeyFactory_; // creates new client key types
153 sslFactory(); // only GetSSL_Factory creates
154 public:
155 const MessageFactory& getMessage() const;
156 const HandShakeFactory& getHandShake() const;
157 const ServerKeyFactory& getServerKey() const;
158 const ClientKeyFactory& getClientKey() const;
160 friend sslFactory& GetSSL_Factory(); // singleton creator
161 private:
162 sslFactory(const sslFactory&); // hide copy
163 sslFactory& operator=(const sslFactory&); // and assign
167 #undef X509_NAME // wincrypt.h clash
169 // openSSL X509 names
170 class X509_NAME {
171 char* name_;
172 size_t sz_;
173 ASN1_STRING entry_;
174 public:
175 X509_NAME(const char*, size_t sz);
176 ~X509_NAME();
178 const char* GetName() const;
179 ASN1_STRING* GetEntry(int i);
180 size_t GetLength() const;
181 private:
182 X509_NAME(const X509_NAME&); // hide copy
183 X509_NAME& operator=(const X509_NAME&); // and assign
187 class StringHolder {
188 ASN1_STRING asnString_;
189 public:
190 StringHolder(const char* str, int sz);
191 ~StringHolder();
193 ASN1_STRING* GetString();
194 private:
195 StringHolder(const StringHolder&); // hide copy
196 StringHolder& operator=(const StringHolder&); // and assign
200 // openSSL X509
201 class X509 {
202 X509_NAME issuer_;
203 X509_NAME subject_;
204 StringHolder beforeDate_; // not valid before
205 StringHolder afterDate_; // not valid after
206 public:
207 X509(const char* i, size_t, const char* s, size_t,
208 const char* b, int, const char* a, int);
209 ~X509() {}
211 X509_NAME* GetIssuer();
212 X509_NAME* GetSubject();
214 ASN1_STRING* GetBefore();
215 ASN1_STRING* GetAfter();
217 private:
218 X509(const X509&); // hide copy
219 X509& operator=(const X509&); // and assign
223 // openSSL bignum
224 struct BIGNUM {
226 gcc 2.96 fix: because of two Integer classes (yaSSL::Integer and
227 TaoCrypt::Integer), we need to explicitly state the namespace
228 here to let gcc 2.96 deduce the correct type.
230 yaSSL::Integer int_;
231 void assign(const byte* b, uint s) { int_.assign(b,s); }
235 // openSSL session
236 class SSL_SESSION {
237 opaque sessionID_[ID_LEN];
238 opaque master_secret_[SECRET_LEN];
239 Cipher suite_[SUITE_LEN];
240 uint bornOn_; // create time in seconds
241 uint timeout_; // timeout in seconds
242 RandomPool& random_; // will clean master secret
243 X509* peerX509_;
244 public:
245 explicit SSL_SESSION(RandomPool&);
246 SSL_SESSION(const SSL&, RandomPool&);
247 ~SSL_SESSION();
249 const opaque* GetID() const;
250 const opaque* GetSecret() const;
251 const Cipher* GetSuite() const;
252 uint GetBornOn() const;
253 uint GetTimeOut() const;
254 X509* GetPeerX509() const;
255 void SetTimeOut(uint);
257 SSL_SESSION& operator=(const SSL_SESSION&); // allow assign for resumption
258 private:
259 SSL_SESSION(const SSL_SESSION&); // hide copy
261 void CopyX509(X509*);
265 // holds all sessions
266 class Sessions {
267 STL::list<SSL_SESSION*> list_;
268 RandomPool random_; // for session cleaning
269 Mutex mutex_; // no-op for single threaded
270 int count_; // flush counter
272 Sessions() : count_(0) {} // only GetSessions can create
273 public:
274 SSL_SESSION* lookup(const opaque*, SSL_SESSION* copy = 0);
275 void add(const SSL&);
276 void remove(const opaque*);
277 void Flush();
279 ~Sessions();
281 friend Sessions& GetSessions(); // singleton creator
282 private:
283 Sessions(const Sessions&); // hide copy
284 Sessions& operator=(const Sessions&); // and assign
288 #ifdef _POSIX_THREADS
289 typedef pthread_t THREAD_ID_T;
290 #else
291 typedef DWORD THREAD_ID_T;
292 #endif
294 // thread error data
295 struct ThreadError {
296 THREAD_ID_T threadID_;
297 int errorID_;
301 // holds all errors
302 class Errors {
303 STL::list<ThreadError> list_;
304 Mutex mutex_;
306 Errors() {} // only GetErrors can create
307 public:
308 int Lookup(bool peek); // self lookup
309 void Add(int);
310 void Remove(); // remove self
312 ~Errors() {}
314 friend Errors& GetErrors(); // singleton creator
315 private:
316 Errors(const Errors&); // hide copy
317 Errors& operator=(const Errors); // and assign
321 Sessions& GetSessions(); // forward singletons
322 sslFactory& GetSSL_Factory();
323 Errors& GetErrors();
326 // openSSL method and context types
327 class SSL_METHOD {
328 ProtocolVersion version_;
329 ConnectionEnd side_;
330 bool verifyPeer_; // request or send certificate
331 bool verifyNone_; // whether to verify certificate
332 bool failNoCert_;
333 bool multipleProtocol_; // for SSLv23 compatibility
334 public:
335 SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv,
336 bool multipleProtocol = false);
338 ProtocolVersion getVersion() const;
339 ConnectionEnd getSide() const;
341 void setVerifyPeer();
342 void setVerifyNone();
343 void setFailNoCert();
345 bool verifyPeer() const;
346 bool verifyNone() const;
347 bool failNoCert() const;
348 bool multipleProtocol() const;
349 private:
350 SSL_METHOD(const SSL_METHOD&); // hide copy
351 SSL_METHOD& operator=(const SSL_METHOD&); // and assign
355 struct Ciphers {
356 bool setSuites_; // user set suites from default
357 byte suites_[MAX_SUITE_SZ]; // new suites
358 int suiteSz_; // suite length in bytes
360 Ciphers() : setSuites_(false), suiteSz_(0) {}
364 struct DH; // forward
367 // save for SSL construction
368 struct DH_Parms {
369 Integer p_;
370 Integer g_;
371 bool set_; // if set by user
373 DH_Parms() : set_(false) {}
377 enum StatsField {
378 Accept, Connect, AcceptGood, ConnectGood, AcceptRenegotiate,
379 ConnectRenegotiate, Hits, CbHits, CacheFull, Misses, Timeouts, Number,
380 GetCacheSize, VerifyMode, VerifyDepth
384 // SSL stats
385 struct Stats {
386 long accept_;
387 long connect_;
388 long acceptGood_;
389 long connectGood_;
390 long acceptRenegotiate_;
391 long connectRenegotiate_;
393 long hits_;
394 long cbHits_;
395 long cacheFull_;
396 long misses_;
397 long timeouts_;
398 long number_;
399 long getCacheSize_;
401 int verifyMode_;
402 int verifyDepth_;
403 public:
404 Stats() : accept_(0), connect_(0), acceptGood_(0), connectGood_(0),
405 acceptRenegotiate_(0), connectRenegotiate_(0), hits_(0), cbHits_(0),
406 cacheFull_(0), misses_(0), timeouts_(0), number_(0), getCacheSize_(0),
407 verifyMode_(0), verifyDepth_(0)
409 private:
410 Stats(const Stats&); // hide copy
411 Stats& operator=(const Stats&); // and assign
415 // the SSL context
416 class SSL_CTX {
417 public:
418 typedef STL::list<x509*> CertList;
419 private:
420 SSL_METHOD* method_;
421 x509* certificate_;
422 x509* privateKey_;
423 CertList caList_;
424 Ciphers ciphers_;
425 DH_Parms dhParms_;
426 pem_password_cb passwordCb_;
427 void* userData_;
428 bool sessionCacheOff_;
429 bool sessionCacheFlushOff_;
430 Stats stats_;
431 Mutex mutex_; // for Stats
432 VerifyCallback verifyCallback_;
433 public:
434 explicit SSL_CTX(SSL_METHOD* meth);
435 ~SSL_CTX();
437 const x509* getCert() const;
438 const x509* getKey() const;
439 const SSL_METHOD* getMethod() const;
440 const Ciphers& GetCiphers() const;
441 const DH_Parms& GetDH_Parms() const;
442 const Stats& GetStats() const;
443 const VerifyCallback getVerifyCallback() const;
444 pem_password_cb GetPasswordCb() const;
445 void* GetUserData() const;
446 bool GetSessionCacheOff() const;
447 bool GetSessionCacheFlushOff() const;
449 void setVerifyPeer();
450 void setVerifyNone();
451 void setFailNoCert();
452 void setVerifyCallback(VerifyCallback);
453 bool SetCipherList(const char*);
454 bool SetDH(const DH&);
455 void SetPasswordCb(pem_password_cb cb);
456 void SetUserData(void*);
457 void SetSessionCacheOff();
458 void SetSessionCacheFlushOff();
460 void IncrementStats(StatsField);
461 void AddCA(x509* ca);
462 const CertList& GetCA_List() const;
464 friend int read_file(SSL_CTX*, const char*, int, CertType);
465 private:
466 SSL_CTX(const SSL_CTX&); // hide copy
467 SSL_CTX& operator=(const SSL_CTX&); // and assign
471 // holds all cryptographic types
472 class Crypto {
473 Digest* digest_; // agreed upon digest
474 BulkCipher* cipher_; // agreed upon cipher
475 DiffieHellman* dh_; // dh parms
476 RandomPool random_; // random number generator
477 CertManager cert_; // manages certificates
478 public:
479 explicit Crypto();
480 ~Crypto();
482 const Digest& get_digest() const;
483 const BulkCipher& get_cipher() const;
484 const DiffieHellman& get_dh() const;
485 const RandomPool& get_random() const;
486 const CertManager& get_certManager() const;
488 Digest& use_digest();
489 BulkCipher& use_cipher();
490 DiffieHellman& use_dh();
491 RandomPool& use_random();
492 CertManager& use_certManager();
494 void SetDH(DiffieHellman*);
495 void SetDH(const DH_Parms&);
496 void setDigest(Digest*);
497 void setCipher(BulkCipher*);
499 bool DhSet();
500 private:
501 Crypto(const Crypto&); // hide copy
502 Crypto& operator=(const Crypto&); // and assign
506 // holds all handshake and verify hashes
507 class sslHashes {
508 MD5 md5HandShake_; // md5 handshake hash
509 SHA shaHandShake_; // sha handshake hash
510 Finished verify_; // peer's verify hash
511 Hashes certVerify_; // peer's cert verify hash
512 public:
513 sslHashes() {}
515 const MD5& get_MD5() const;
516 const SHA& get_SHA() const;
517 const Finished& get_verify() const;
518 const Hashes& get_certVerify() const;
520 MD5& use_MD5();
521 SHA& use_SHA();
522 Finished& use_verify();
523 Hashes& use_certVerify();
524 private:
525 sslHashes(const sslHashes&); // hide copy
526 sslHashes& operator=(const sslHashes&); // and assign
530 // holds input and output buffers
531 class Buffers {
532 public:
533 typedef STL::list<input_buffer*> inputList;
534 typedef STL::list<output_buffer*> outputList;
535 int prevSent; // previous plain text bytes sent when got WANT_WRITE
536 int plainSz; // plain text bytes in buffer to send when got WANT_WRITE
537 private:
538 inputList dataList_; // list of users app data / handshake
539 outputList handShakeList_; // buffered handshake msgs
540 input_buffer* rawInput_; // buffered raw input yet to process
541 output_buffer* output_; // WANT_WRITE buffered output
542 public:
543 Buffers();
544 ~Buffers();
546 const inputList& getData() const;
547 const outputList& getHandShake() const;
549 inputList& useData();
550 outputList& useHandShake();
552 void SetRawInput(input_buffer*); // takes ownership
553 input_buffer* TakeRawInput(); // takes ownership
554 void SetOutput(output_buffer*); // takes ownership
555 output_buffer* TakeOutput(); // takes ownership
556 private:
557 Buffers(const Buffers&); // hide copy
558 Buffers& operator=(const Buffers&); // and assign
562 // wraps security parameters
563 class Security {
564 Connection conn_; // connection information
565 Parameters parms_; // may be pending
566 SSL_SESSION resumeSession_; // if resuming
567 SSL_CTX* ctx_; // context used to init
568 bool resuming_; // trying to resume
569 public:
570 Security(ProtocolVersion, RandomPool&, ConnectionEnd, const Ciphers&,
571 SSL_CTX*, bool);
573 const SSL_CTX* GetContext() const;
574 const Connection& get_connection() const;
575 const Parameters& get_parms() const;
576 const SSL_SESSION& get_resume() const;
577 bool get_resuming() const;
579 Connection& use_connection();
580 Parameters& use_parms();
581 SSL_SESSION& use_resume();
583 void set_resuming(bool b);
584 private:
585 Security(const Security&); // hide copy
586 Security& operator=(const Security&); // and assign
590 // THE SSL type
591 class SSL {
592 Crypto crypto_; // agreed crypto agents
593 Security secure_; // Connection and Session parms
594 States states_; // Record and HandShake states
595 sslHashes hashes_; // handshake, finished hashes
596 Socket socket_; // socket wrapper
597 Buffers buffers_; // buffered handshakes and data
598 Log log_; // logger
599 bool quietShutdown_;
601 // optimization variables
602 bool has_data_; // buffered data ready?
603 public:
604 SSL(SSL_CTX* ctx);
606 // gets and uses
607 const Crypto& getCrypto() const;
608 const Security& getSecurity() const;
609 const States& getStates() const;
610 const sslHashes& getHashes() const;
611 const sslFactory& getFactory() const;
612 const Socket& getSocket() const;
613 YasslError GetError() const;
614 bool GetMultiProtocol() const;
615 bool CompressionOn() const;
617 Crypto& useCrypto();
618 Security& useSecurity();
619 States& useStates();
620 sslHashes& useHashes();
621 Socket& useSocket();
622 Log& useLog();
623 Buffers& useBuffers();
625 bool HasData() const;
626 bool GetQuietShutdown() const;
628 // sets
629 void set_pending(Cipher suite);
630 void set_random(const opaque*, ConnectionEnd);
631 void set_sessionID(const opaque*);
632 void set_session(SSL_SESSION*);
633 void set_preMaster(const opaque*, uint);
634 void set_masterSecret(const opaque*);
635 void SetError(YasslError);
636 int SetCompression();
637 void UnSetCompression();
638 void SetQuietShutdown(bool mode);
640 // helpers
641 bool isTLS() const;
642 bool isTLSv1_1() const;
643 void order_error();
644 void makeMasterSecret();
645 void makeTLSMasterSecret();
646 void addData(input_buffer* data);
647 void fillData(Data&);
648 void PeekData(Data&);
649 void addBuffer(output_buffer* b);
650 void flushBuffer();
651 void verifyState(const RecordLayerHeader&);
652 void verifyState(const HandShakeHeader&);
653 void verifyState(ClientState);
654 void verifyState(ServerState);
655 void verfiyHandShakeComplete();
656 void matchSuite(const opaque*, uint length);
657 void deriveKeys();
658 void deriveTLSKeys();
659 void Send(const byte*, uint);
660 void SendWriteBuffered();
662 uint bufferedData();
663 uint get_SEQIncrement(bool);
665 const byte* get_macSecret(bool);
666 private:
667 void storeKeys(const opaque*);
668 void setKeys();
669 void verifyClientState(HandShakeType);
670 void verifyServerState(HandShakeType);
672 SSL(const SSL&); // hide copy
673 const SSL& operator=(const SSL&); // and assign
677 // compression
678 int Compress(const byte*, int, input_buffer&);
679 int DeCompress(input_buffer&, int, input_buffer&);
682 // conversion functions
683 void c32to24(uint32, uint24&);
684 void c24to32(const uint24, uint32&);
686 uint32 c24to32(const uint24);
688 void ato16(const opaque*, uint16&);
689 void ato24(const opaque*, uint24&);
691 void c16toa(uint16, opaque*);
692 void c24toa(const uint24, opaque*);
693 void c32toa(uint32 u32, opaque*);
696 } // naemspace
698 #endif // yaSSL_INT_HPP