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,
20 /* yaSSL internal header defines SSL supporting types not specified in the
21 * draft along with type conversion functions and openssl compatibility
28 #include "yassl_imp.hpp"
29 #include "yassl_error.hpp"
30 #include "crypto_wrapper.hpp"
31 #include "cert_wrapper.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
47 namespace STL
= STL_NAMESPACE
;
53 // State Machine for Record Layer Protocol
54 enum RecordLayerState
{
55 recordNotReady
= 0, // fatal error, no more processing
60 // State Machine for HandShake Protocol
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
74 serverKeyExchangeComplete
,
75 serverHelloDoneComplete
,
76 serverFinishedComplete
80 // server input HandShake state, use if HandShakeState == inHandShake
84 clientKeyExchangeComplete
,
85 clientFinishedComplete
89 // client connect state for nonblocking restart
99 // server accpet state for nonblocking restart
102 ACCEPT_FIRST_REPLY_DONE
,
104 ACCEPT_SECOND_REPLY_DONE
,
105 ACCEPT_FINISHED_DONE
,
106 ACCEPT_THIRD_REPLY_DONE
110 // combines all 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
];
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();
139 void SetError(YasslError
);
141 States(const States
&); // hide copy
142 States
& operator=(const States
&); // and assign
146 // holds all factories
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
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
162 sslFactory(const sslFactory
&); // hide copy
163 sslFactory
& operator=(const sslFactory
&); // and assign
167 #undef X509_NAME // wincrypt.h clash
169 // openSSL X509 names
175 X509_NAME(const char*, size_t sz
);
178 const char* GetName() const;
179 ASN1_STRING
* GetEntry(int i
);
180 size_t GetLength() const;
182 X509_NAME(const X509_NAME
&); // hide copy
183 X509_NAME
& operator=(const X509_NAME
&); // and assign
188 ASN1_STRING asnString_
;
190 StringHolder(const char* str
, int sz
);
193 ASN1_STRING
* GetString();
195 StringHolder(const StringHolder
&); // hide copy
196 StringHolder
& operator=(const StringHolder
&); // and assign
204 StringHolder beforeDate_
; // not valid before
205 StringHolder afterDate_
; // not valid after
207 X509(const char* i
, size_t, const char* s
, size_t,
208 const char* b
, int, const char* a
, int);
211 X509_NAME
* GetIssuer();
212 X509_NAME
* GetSubject();
214 ASN1_STRING
* GetBefore();
215 ASN1_STRING
* GetAfter();
218 X509(const X509
&); // hide copy
219 X509
& operator=(const X509
&); // and assign
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.
231 void assign(const byte
* b
, uint s
) { int_
.assign(b
,s
); }
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
245 explicit SSL_SESSION(RandomPool
&);
246 SSL_SESSION(const SSL
&, RandomPool
&);
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
259 SSL_SESSION(const SSL_SESSION
&); // hide copy
261 void CopyX509(X509
*);
265 // holds all 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
274 SSL_SESSION
* lookup(const opaque
*, SSL_SESSION
* copy
= 0);
275 void add(const SSL
&);
276 void remove(const opaque
*);
281 friend Sessions
& GetSessions(); // singleton creator
283 Sessions(const Sessions
&); // hide copy
284 Sessions
& operator=(const Sessions
&); // and assign
288 #ifdef _POSIX_THREADS
289 typedef pthread_t THREAD_ID_T
;
291 typedef DWORD THREAD_ID_T
;
296 THREAD_ID_T threadID_
;
303 STL::list
<ThreadError
> list_
;
306 Errors() {} // only GetErrors can create
308 int Lookup(bool peek
); // self lookup
310 void Remove(); // remove self
314 friend Errors
& GetErrors(); // singleton creator
316 Errors(const Errors
&); // hide copy
317 Errors
& operator=(const Errors
); // and assign
321 Sessions
& GetSessions(); // forward singletons
322 sslFactory
& GetSSL_Factory();
326 // openSSL method and context types
328 ProtocolVersion version_
;
330 bool verifyPeer_
; // request or send certificate
331 bool verifyNone_
; // whether to verify certificate
333 bool multipleProtocol_
; // for SSLv23 compatibility
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;
350 SSL_METHOD(const SSL_METHOD
&); // hide copy
351 SSL_METHOD
& operator=(const SSL_METHOD
&); // and assign
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
371 bool set_
; // if set by user
373 DH_Parms() : set_(false) {}
378 Accept
, Connect
, AcceptGood
, ConnectGood
, AcceptRenegotiate
,
379 ConnectRenegotiate
, Hits
, CbHits
, CacheFull
, Misses
, Timeouts
, Number
,
380 GetCacheSize
, VerifyMode
, VerifyDepth
390 long acceptRenegotiate_
;
391 long connectRenegotiate_
;
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)
410 Stats(const Stats
&); // hide copy
411 Stats
& operator=(const Stats
&); // and assign
418 typedef STL::list
<x509
*> CertList
;
426 pem_password_cb passwordCb_
;
428 bool sessionCacheOff_
;
429 bool sessionCacheFlushOff_
;
431 Mutex mutex_
; // for Stats
432 VerifyCallback verifyCallback_
;
434 explicit SSL_CTX(SSL_METHOD
* meth
);
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
);
466 SSL_CTX(const SSL_CTX
&); // hide copy
467 SSL_CTX
& operator=(const SSL_CTX
&); // and assign
471 // holds all cryptographic types
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
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
*);
501 Crypto(const Crypto
&); // hide copy
502 Crypto
& operator=(const Crypto
&); // and assign
506 // holds all handshake and verify hashes
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
515 const MD5
& get_MD5() const;
516 const SHA
& get_SHA() const;
517 const Finished
& get_verify() const;
518 const Hashes
& get_certVerify() const;
522 Finished
& use_verify();
523 Hashes
& use_certVerify();
525 sslHashes(const sslHashes
&); // hide copy
526 sslHashes
& operator=(const sslHashes
&); // and assign
530 // holds input and output buffers
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
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
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
557 Buffers(const Buffers
&); // hide copy
558 Buffers
& operator=(const Buffers
&); // and assign
562 // wraps security parameters
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
570 Security(ProtocolVersion
, RandomPool
&, ConnectionEnd
, const Ciphers
&,
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
);
585 Security(const Security
&); // hide copy
586 Security
& operator=(const Security
&); // and assign
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
601 // optimization variables
602 bool has_data_
; // buffered data ready?
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;
618 Security
& useSecurity();
620 sslHashes
& useHashes();
623 Buffers
& useBuffers();
625 bool HasData() const;
626 bool GetQuietShutdown() const;
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
);
642 bool isTLSv1_1() const;
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
);
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
);
658 void deriveTLSKeys();
659 void Send(const byte
*, uint
);
660 void SendWriteBuffered();
663 uint
get_SEQIncrement(bool);
665 const byte
* get_macSecret(bool);
667 void storeKeys(const opaque
*);
669 void verifyClientState(HandShakeType
);
670 void verifyServerState(HandShakeType
);
672 SSL(const SSL
&); // hide copy
673 const SSL
& operator=(const SSL
&); // and assign
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
*);
698 #endif // yaSSL_INT_HPP