MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
yassl_int.hpp
1 /*
2  Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
3 
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.
7 
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.
12 
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.
17 */
18 
19 
20 /* yaSSL internal header defines SSL supporting types not specified in the
21  * draft along with type conversion functions and openssl compatibility
22  */
23 
24 
25 #ifndef yaSSL_INT_HPP
26 #define yaSSL_INT_HPP
27 
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
35 
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
41 
42 #ifdef _POSIX_THREADS
43  #include <pthread.h>
44 #endif
45 
46 
47 namespace STL = STL_NAMESPACE;
48 
49 
50 namespace yaSSL {
51 
52 
53 // State Machine for Record Layer Protocol
54 enum RecordLayerState {
55  recordNotReady = 0, // fatal error, no more processing
56  recordReady
57 };
58 
59 
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
66 };
67 
68 
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
77 };
78 
79 
80 // server input HandShake state, use if HandShakeState == inHandShake
81 enum ServerState {
82  clientNull = 0,
83  clientHelloComplete,
84  clientKeyExchangeComplete,
85  clientFinishedComplete
86 };
87 
88 
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
96 };
97 
98 
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
107 };
108 
109 
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();
122 
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;
131 
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
143 };
144 
145 
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
152 
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;
159 
160  friend sslFactory& GetSSL_Factory(); // singleton creator
161 private:
162  sslFactory(const sslFactory&); // hide copy
163  sslFactory& operator=(const sslFactory&); // and assign
164 };
165 
166 
167 #undef X509_NAME // wincrypt.h clash
168 
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();
177 
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
184 };
185 
186 
188  ASN1_STRING asnString_;
189 public:
190  StringHolder(const char* str, int sz, byte type= 0);
191  ~StringHolder();
192 
193  ASN1_STRING* GetString();
194 private:
195  StringHolder(const StringHolder&); // hide copy
196  StringHolder& operator=(const StringHolder&); // and assign
197 };
198 
199 
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  ASN1_STRING *b, ASN1_STRING *a);
209  ~X509() {}
210 
211  X509_NAME* GetIssuer();
212  X509_NAME* GetSubject();
213 
214  ASN1_STRING* GetBefore();
215  ASN1_STRING* GetAfter();
216 
217 private:
218  X509(const X509&); // hide copy
219  X509& operator=(const X509&); // and assign
220 };
221 
222 
223 // openSSL bignum
224 struct BIGNUM {
225  /*
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.
229  */
230  yaSSL::Integer int_;
231  void assign(const byte* b, uint s) { int_.assign(b,s); }
232 };
233 
234 
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();
248 
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);
256 
257  SSL_SESSION& operator=(const SSL_SESSION&); // allow assign for resumption
258 private:
259  SSL_SESSION(const SSL_SESSION&); // hide copy
260 
261  void CopyX509(X509*);
262 };
263 
264 
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
271 
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();
278 
279  ~Sessions();
280 
281  friend void Session_initialize();
282  friend Sessions& GetSessions(); // singleton creator
283 private:
284  Sessions(const Sessions&); // hide copy
285  Sessions& operator=(const Sessions&); // and assign
286 };
287 
288 
289 #ifdef _POSIX_THREADS
290  typedef pthread_t THREAD_ID_T;
291 #else
292  typedef DWORD THREAD_ID_T;
293 #endif
294 
295 // thread error data
296 struct ThreadError {
297  THREAD_ID_T threadID_;
298  int errorID_;
299 };
300 
301 
302 // holds all errors
303 class Errors {
304  STL::list<ThreadError> list_;
305  Mutex mutex_;
306 
307  Errors() {} // only GetErrors can create
308 public:
309  int Lookup(bool peek); // self lookup
310  void Add(int);
311  void Remove(); // remove self
312 
313  ~Errors() {}
314 
315  friend Errors& GetErrors(); // singleton creator
316 private:
317  Errors(const Errors&); // hide copy
318  Errors& operator=(const Errors); // and assign
319 };
320 
321 
322 Sessions& GetSessions(); // forward singletons
323 sslFactory& GetSSL_Factory();
324 Errors& GetErrors();
325 
326 
327 // openSSL method and context types
328 class SSL_METHOD {
329  ProtocolVersion version_;
330  ConnectionEnd side_;
331  bool verifyPeer_; // request or send certificate
332  bool verifyNone_; // whether to verify certificate
333  bool failNoCert_;
334  bool multipleProtocol_; // for SSLv23 compatibility
335 public:
336  SSL_METHOD(ConnectionEnd ce, ProtocolVersion pv,
337  bool multipleProtocol = false);
338 
339  ProtocolVersion getVersion() const;
340  ConnectionEnd getSide() const;
341 
342  void setVerifyPeer();
343  void setVerifyNone();
344  void setFailNoCert();
345 
346  bool verifyPeer() const;
347  bool verifyNone() const;
348  bool failNoCert() const;
349  bool multipleProtocol() const;
350 private:
351  SSL_METHOD(const SSL_METHOD&); // hide copy
352  SSL_METHOD& operator=(const SSL_METHOD&); // and assign
353 };
354 
355 
356 struct Ciphers {
357  bool setSuites_; // user set suites from default
358  byte suites_[MAX_SUITE_SZ]; // new suites
359  int suiteSz_; // suite length in bytes
360 
361  Ciphers() : setSuites_(false), suiteSz_(0) {}
362 };
363 
364 
365 struct DH; // forward
366 
367 
368 // save for SSL construction
369 struct DH_Parms {
370  Integer p_;
371  Integer g_;
372  bool set_; // if set by user
373 
374  DH_Parms() : set_(false) {}
375 };
376 
377 
378 enum StatsField {
379  Accept, Connect, AcceptGood, ConnectGood, AcceptRenegotiate,
380  ConnectRenegotiate, Hits, CbHits, CacheFull, Misses, Timeouts, Number,
381  GetCacheSize, VerifyMode, VerifyDepth
382 };
383 
384 
385 // SSL stats
386 struct Stats {
387  long accept_;
388  long connect_;
389  long acceptGood_;
390  long connectGood_;
391  long acceptRenegotiate_;
392  long connectRenegotiate_;
393 
394  long hits_;
395  long cbHits_;
396  long cacheFull_;
397  long misses_;
398  long timeouts_;
399  long number_;
400  long getCacheSize_;
401 
402  int verifyMode_;
403  int verifyDepth_;
404 public:
405  Stats() : accept_(0), connect_(0), acceptGood_(0), connectGood_(0),
406  acceptRenegotiate_(0), connectRenegotiate_(0), hits_(0), cbHits_(0),
407  cacheFull_(0), misses_(0), timeouts_(0), number_(0), getCacheSize_(0),
408  verifyMode_(0), verifyDepth_(0)
409  {}
410 private:
411  Stats(const Stats&); // hide copy
412  Stats& operator=(const Stats&); // and assign
413 };
414 
415 
416 // the SSL context
417 class SSL_CTX {
418 public:
419  typedef STL::list<x509*> CertList;
420 private:
421  SSL_METHOD* method_;
422  x509* certificate_;
423  x509* privateKey_;
424  CertList caList_;
425  Ciphers ciphers_;
426  DH_Parms dhParms_;
427  pem_password_cb passwordCb_;
428  void* userData_;
429  bool sessionCacheOff_;
430  bool sessionCacheFlushOff_;
431  Stats stats_;
432  Mutex mutex_; // for Stats
433  VerifyCallback verifyCallback_;
434 public:
435  explicit SSL_CTX(SSL_METHOD* meth);
436  ~SSL_CTX();
437 
438  const x509* getCert() const;
439  const x509* getKey() const;
440  const SSL_METHOD* getMethod() const;
441  const Ciphers& GetCiphers() const;
442  const DH_Parms& GetDH_Parms() const;
443  const Stats& GetStats() const;
444  const VerifyCallback getVerifyCallback() const;
445  pem_password_cb GetPasswordCb() const;
446  void* GetUserData() const;
447  bool GetSessionCacheOff() const;
448  bool GetSessionCacheFlushOff() const;
449 
450  void setVerifyPeer();
451  void setVerifyNone();
452  void setFailNoCert();
453  void setVerifyCallback(VerifyCallback);
454  bool SetCipherList(const char*);
455  bool SetDH(const DH&);
456  void SetPasswordCb(pem_password_cb cb);
457  void SetUserData(void*);
458  void SetSessionCacheOff();
459  void SetSessionCacheFlushOff();
460 
461  void IncrementStats(StatsField);
462  void AddCA(x509* ca);
463  const CertList& GetCA_List() const;
464 
465  friend int read_file(SSL_CTX*, const char*, int, CertType);
466 private:
467  SSL_CTX(const SSL_CTX&); // hide copy
468  SSL_CTX& operator=(const SSL_CTX&); // and assign
469 };
470 
471 
472 // holds all cryptographic types
473 class Crypto {
474  Digest* digest_; // agreed upon digest
475  BulkCipher* cipher_; // agreed upon cipher
476  DiffieHellman* dh_; // dh parms
477  RandomPool random_; // random number generator
478  CertManager cert_; // manages certificates
479 public:
480  explicit Crypto();
481  ~Crypto();
482 
483  const Digest& get_digest() const;
484  const BulkCipher& get_cipher() const;
485  const DiffieHellman& get_dh() const;
486  const RandomPool& get_random() const;
487  const CertManager& get_certManager() const;
488 
489  Digest& use_digest();
490  BulkCipher& use_cipher();
491  DiffieHellman& use_dh();
492  RandomPool& use_random();
493  CertManager& use_certManager();
494 
495  void SetDH(DiffieHellman*);
496  void SetDH(const DH_Parms&);
497  void setDigest(Digest*);
498  void setCipher(BulkCipher*);
499 
500  bool DhSet();
501 private:
502  Crypto(const Crypto&); // hide copy
503  Crypto& operator=(const Crypto&); // and assign
504 };
505 
506 
507 // holds all handshake and verify hashes
508 class sslHashes {
509  MD5 md5HandShake_; // md5 handshake hash
510  SHA shaHandShake_; // sha handshake hash
511  Finished verify_; // peer's verify hash
512  Hashes certVerify_; // peer's cert verify hash
513 public:
514  sslHashes() {}
515 
516  const MD5& get_MD5() const;
517  const SHA& get_SHA() const;
518  const Finished& get_verify() const;
519  const Hashes& get_certVerify() const;
520 
521  MD5& use_MD5();
522  SHA& use_SHA();
523  Finished& use_verify();
524  Hashes& use_certVerify();
525 private:
526  sslHashes(const sslHashes&); // hide copy
527  sslHashes& operator=(const sslHashes&); // and assign
528 };
529 
530 
531 // holds input and output buffers
532 class Buffers {
533 public:
534  typedef STL::list<input_buffer*> inputList;
535  typedef STL::list<output_buffer*> outputList;
536  int prevSent; // previous plain text bytes sent when got WANT_WRITE
537  int plainSz; // plain text bytes in buffer to send when got WANT_WRITE
538 private:
539  inputList dataList_; // list of users app data / handshake
540  outputList handShakeList_; // buffered handshake msgs
541  input_buffer* rawInput_; // buffered raw input yet to process
542  output_buffer* output_; // WANT_WRITE buffered output
543 public:
544  Buffers();
545  ~Buffers();
546 
547  const inputList& getData() const;
548  const outputList& getHandShake() const;
549 
550  inputList& useData();
551  outputList& useHandShake();
552 
553  void SetRawInput(input_buffer*); // takes ownership
554  input_buffer* TakeRawInput(); // takes ownership
555  void SetOutput(output_buffer*); // takes ownership
556  output_buffer* TakeOutput(); // takes ownership
557 private:
558  Buffers(const Buffers&); // hide copy
559  Buffers& operator=(const Buffers&); // and assign
560 };
561 
562 
563 // wraps security parameters
564 class Security {
565  Connection conn_; // connection information
566  Parameters parms_; // may be pending
567  SSL_SESSION resumeSession_; // if resuming
568  SSL_CTX* ctx_; // context used to init
569  bool resuming_; // trying to resume
570 public:
571  Security(ProtocolVersion, RandomPool&, ConnectionEnd, const Ciphers&,
572  SSL_CTX*, bool);
573 
574  const SSL_CTX* GetContext() const;
575  const Connection& get_connection() const;
576  const Parameters& get_parms() const;
577  const SSL_SESSION& get_resume() const;
578  bool get_resuming() const;
579 
580  Connection& use_connection();
581  Parameters& use_parms();
582  SSL_SESSION& use_resume();
583 
584  void set_resuming(bool b);
585 private:
586  Security(const Security&); // hide copy
587  Security& operator=(const Security&); // and assign
588 };
589 
590 
591 // THE SSL type
592 class SSL {
593  Crypto crypto_; // agreed crypto agents
594  Security secure_; // Connection and Session parms
595  States states_; // Record and HandShake states
596  sslHashes hashes_; // handshake, finished hashes
597  Socket socket_; // socket wrapper
598  Buffers buffers_; // buffered handshakes and data
599  Log log_; // logger
600  bool quietShutdown_;
601 
602  // optimization variables
603  bool has_data_; // buffered data ready?
604 public:
605  SSL(SSL_CTX* ctx);
606 
607  // gets and uses
608  const Crypto& getCrypto() const;
609  const Security& getSecurity() const;
610  const States& getStates() const;
611  const sslHashes& getHashes() const;
612  const sslFactory& getFactory() const;
613  const Socket& getSocket() const;
614  YasslError GetError() const;
615  bool GetMultiProtocol() const;
616  bool CompressionOn() const;
617 
618  Crypto& useCrypto();
619  Security& useSecurity();
620  States& useStates();
621  sslHashes& useHashes();
622  Socket& useSocket();
623  Log& useLog();
624  Buffers& useBuffers();
625 
626  bool HasData() const;
627  bool GetQuietShutdown() const;
628 
629  // sets
630  void set_pending(Cipher suite);
631  void set_random(const opaque*, ConnectionEnd);
632  void set_sessionID(const opaque*);
633  void set_session(SSL_SESSION*);
634  void set_preMaster(const opaque*, uint);
635  void set_masterSecret(const opaque*);
636  void SetError(YasslError);
637  int SetCompression();
638  void UnSetCompression();
639  void SetQuietShutdown(bool mode);
640 
641  // helpers
642  bool isTLS() const;
643  bool isTLSv1_1() const;
644  void order_error();
645  void makeMasterSecret();
646  void makeTLSMasterSecret();
647  void addData(input_buffer* data);
648  void fillData(Data&);
649  void PeekData(Data&);
650  void addBuffer(output_buffer* b);
651  void flushBuffer();
652  void verifyState(const RecordLayerHeader&);
653  void verifyState(const HandShakeHeader&);
654  void verifyState(ClientState);
655  void verifyState(ServerState);
656  void verfiyHandShakeComplete();
657  void matchSuite(const opaque*, uint length);
658  void deriveKeys();
659  void deriveTLSKeys();
660  void Send(const byte*, uint);
661  void SendWriteBuffered();
662 
663  uint bufferedData();
664  uint get_SEQIncrement(bool);
665 
666  const byte* get_macSecret(bool);
667 private:
668  void storeKeys(const opaque*);
669  void setKeys();
670  void verifyClientState(HandShakeType);
671  void verifyServerState(HandShakeType);
672 
673  SSL(const SSL&); // hide copy
674  const SSL& operator=(const SSL&); // and assign
675 };
676 
677 
678 // compression
679 int Compress(const byte*, int, input_buffer&);
680 int DeCompress(input_buffer&, int, input_buffer&);
681 
682 
683 // conversion functions
684 void c32to24(uint32, uint24&);
685 void c24to32(const uint24, uint32&);
686 
687 uint32 c24to32(const uint24);
688 
689 void ato16(const opaque*, uint16&);
690 void ato24(const opaque*, uint24&);
691 
692 void c16toa(uint16, opaque*);
693 void c24toa(const uint24, opaque*);
694 void c32toa(uint32 u32, opaque*);
695 
696 
697 } // naemspace
698 
699 #endif // yaSSL_INT_HPP