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,
19 /* yaSSL implementation header defines all strucutres from the SSL.v3
20 * specification "draft-freier-ssl-version3-02.txt"
21 * all page citations refer to this document unless otherwise noted.
29 // disable truncated debug symbols
30 #pragma warning(disable:4786)
33 #include "yassl_types.hpp"
34 #include "factory.hpp"
35 #include STL_LIST_FILE
38 namespace STL
= STL_NAMESPACE
;
44 class SSL
; // forward decls
49 struct ProtocolVersion
{
51 uint8 minor_
; // major and minor SSL/TLS version numbers
53 ProtocolVersion(uint8 maj
= 3, uint8 min
= 0);
57 // Record Layer Header for PlainText, Compressed, and CipherText
58 struct RecordLayerHeader
{
60 ProtocolVersion version_
;
61 uint16 length_
; // should not exceed 2^14
65 // base for all messages
66 struct Message
: public virtual_base
{
67 virtual input_buffer
& set(input_buffer
&) =0;
68 virtual output_buffer
& get(output_buffer
&) const =0;
70 virtual void Process(input_buffer
&, SSL
&) =0;
71 virtual ContentType
get_type() const =0;
72 virtual uint16
get_length() const =0;
78 class ChangeCipherSpec
: public Message
{
83 friend input_buffer
& operator>>(input_buffer
&, ChangeCipherSpec
&);
84 friend output_buffer
& operator<<(output_buffer
&, const ChangeCipherSpec
&);
86 input_buffer
& set(input_buffer
& in
);
87 output_buffer
& get(output_buffer
& out
) const;
89 ContentType
get_type() const;
90 uint16
get_length() const;
91 void Process(input_buffer
&, SSL
&);
93 ChangeCipherSpec(const ChangeCipherSpec
&); // hide copy
94 ChangeCipherSpec
& operator=(const ChangeCipherSpec
&); // and assign
99 class Alert
: public Message
{
101 AlertDescription description_
;
104 Alert(AlertLevel al
, AlertDescription ad
);
106 ContentType
get_type() const;
107 uint16
get_length() const;
108 void Process(input_buffer
&, SSL
&);
110 friend input_buffer
& operator>>(input_buffer
&, Alert
&);
111 friend output_buffer
& operator<<(output_buffer
&, const Alert
&);
113 input_buffer
& set(input_buffer
& in
);
114 output_buffer
& get(output_buffer
& out
) const;
116 Alert(const Alert
&); // hide copy
117 Alert
& operator=(const Alert
&); // and assign
121 class Data
: public Message
{
123 opaque
* buffer_
; // read buffer used by fillData input
124 const opaque
* write_buffer_
; // write buffer used by output operator
127 Data(uint16 len
, opaque
* b
);
129 friend output_buffer
& operator<<(output_buffer
&, const Data
&);
131 input_buffer
& set(input_buffer
& in
);
132 output_buffer
& get(output_buffer
& out
) const;
134 ContentType
get_type() const;
135 uint16
get_length() const;
136 void set_length(uint16 l
);
137 opaque
* set_buffer();
138 void SetData(uint16
, const opaque
*);
139 void Process(input_buffer
&, SSL
&);
141 Data(const Data
&); // hide copy
142 Data
& operator=(const Data
&); // and assign
146 uint32
c24to32(const uint24
); // forward form internal header
147 void c32to24(uint32
, uint24
&);
150 // HandShake header, same for each message type from page 20/21
151 class HandShakeHeader
: public Message
{
153 uint24 length_
; // length of message
157 ContentType
get_type() const;
158 uint16
get_length() const;
159 HandShakeType
get_handshakeType() const;
160 void Process(input_buffer
&, SSL
&);
162 void set_type(HandShakeType hst
);
163 void set_length(uint32 u32
);
165 friend input_buffer
& operator>>(input_buffer
&, HandShakeHeader
&);
166 friend output_buffer
& operator<<(output_buffer
&, const HandShakeHeader
&);
168 input_buffer
& set(input_buffer
& in
);
169 output_buffer
& get(output_buffer
& out
) const;
171 HandShakeHeader(const HandShakeHeader
&); // hide copy
172 HandShakeHeader
& operator=(const HandShakeHeader
&); // and assign
176 // Base Class for all handshake messages
177 class HandShakeBase
: public virtual_base
{
180 int get_length() const;
181 void set_length(int);
183 // for building buffer's type field
184 virtual HandShakeType
get_type() const =0;
186 // handles dispactch of proper >>
187 virtual input_buffer
& set(input_buffer
& in
) =0;
188 virtual output_buffer
& get(output_buffer
& out
) const =0;
190 virtual void Process(input_buffer
&, SSL
&) =0;
192 virtual ~HandShakeBase() {}
196 struct HelloRequest
: public HandShakeBase
{
197 input_buffer
& set(input_buffer
& in
);
198 output_buffer
& get(output_buffer
& out
) const;
200 void Process(input_buffer
&, SSL
&);
202 HandShakeType
get_type() const;
206 // The Client's Hello Message from page 23
207 class ClientHello
: public HandShakeBase
{
208 ProtocolVersion client_version_
;
210 uint8 id_len_
; // session id length
211 opaque session_id_
[ID_LEN
];
212 uint16 suite_len_
; // cipher suite length
213 opaque cipher_suites_
[MAX_SUITE_SZ
];
214 uint8 comp_len_
; // compression length
215 CompressionMethod compression_methods_
;
217 friend input_buffer
& operator>>(input_buffer
&, ClientHello
&);
218 friend output_buffer
& operator<<(output_buffer
&, const ClientHello
&);
220 input_buffer
& set(input_buffer
& in
);
221 output_buffer
& get(output_buffer
& out
) const;
223 HandShakeType
get_type() const;
224 void Process(input_buffer
&, SSL
&);
226 const opaque
* get_random() const;
227 friend void buildClientHello(SSL
&, ClientHello
&);
228 friend void ProcessOldClientHello(input_buffer
& input
, SSL
& ssl
);
231 ClientHello(ProtocolVersion pv
, bool useCompression
);
233 ClientHello(const ClientHello
&); // hide copy
234 ClientHello
& operator=(const ClientHello
&); // and assign
239 // The Server's Hello Message from page 24
240 class ServerHello
: public HandShakeBase
{
241 ProtocolVersion server_version_
;
243 uint8 id_len_
; // session id length
244 opaque session_id_
[ID_LEN
];
245 opaque cipher_suite_
[SUITE_LEN
];
246 CompressionMethod compression_method_
;
248 ServerHello(ProtocolVersion pv
, bool useCompression
);
251 friend input_buffer
& operator>>(input_buffer
&, ServerHello
&);
252 friend output_buffer
& operator<<(output_buffer
&, const ServerHello
&);
254 input_buffer
& set(input_buffer
& in
);
255 output_buffer
& get(output_buffer
& out
) const;
257 HandShakeType
get_type() const;
258 void Process(input_buffer
&, SSL
&);
260 const opaque
* get_random() const;
261 friend void buildServerHello(SSL
&, ServerHello
&);
263 ServerHello(const ServerHello
&); // hide copy
264 ServerHello
& operator=(const ServerHello
&); // and assign
270 // Certificate could be a chain
271 class Certificate
: public HandShakeBase
{
275 explicit Certificate(const x509
* cert
);
276 friend output_buffer
& operator<<(output_buffer
&, const Certificate
&);
278 const opaque
* get_buffer() const;
280 // Process handles input, needs SSL
281 input_buffer
& set(input_buffer
& in
);
282 output_buffer
& get(output_buffer
& out
) const;
284 HandShakeType
get_type() const;
285 void Process(input_buffer
&, SSL
&);
287 Certificate(const Certificate
&); // hide copy
288 Certificate
& operator=(const Certificate
&); // and assign
294 struct ServerRSAParams
{
295 opaque
* rsa_modulus_
;
296 opaque
* rsa_exponent_
;
300 // Ephemeral Diffie-Hellman Parameters
301 class ServerDHParams
{
312 int get_pSize() const;
313 int get_gSize() const;
314 int get_pubSize() const;
316 const opaque
* get_p() const;
317 const opaque
* get_g() const;
318 const opaque
* get_pub() const;
320 opaque
* alloc_p(int sz
);
321 opaque
* alloc_g(int sz
);
322 opaque
* alloc_pub(int sz
);
324 ServerDHParams(const ServerDHParams
&); // hide copy
325 ServerDHParams
& operator=(const ServerDHParams
&); // and assign
329 struct ServerKeyBase
: public virtual_base
{
330 virtual ~ServerKeyBase() {}
331 virtual void build(SSL
&) {}
332 virtual void read(SSL
&, input_buffer
&) {}
333 virtual int get_length() const;
334 virtual opaque
* get_serverKey() const;
338 // Server random number for FORTEZZA KEA
339 struct Fortezza_Server
: public ServerKeyBase
{
340 opaque r_s_
[FORTEZZA_MAX
];
344 struct SignatureBase
: public virtual_base
{
345 virtual ~SignatureBase() {}
348 struct anonymous_sa
: public SignatureBase
{};
357 struct rsa_sa
: public SignatureBase
{
362 struct dsa_sa
: public SignatureBase
{
367 // Server's Diffie-Hellman exchange
368 class DH_Server
: public ServerKeyBase
{
369 ServerDHParams parms_
;
372 int length_
; // total length of message
373 opaque
* keyMessage_
; // total exchange message
379 void read(SSL
&, input_buffer
&);
380 int get_length() const;
381 opaque
* get_serverKey() const;
383 DH_Server(const DH_Server
&); // hide copy
384 DH_Server
& operator=(const DH_Server
&); // and assign
388 // Server's RSA exchange
389 struct RSA_Server
: public ServerKeyBase
{
390 ServerRSAParams params_
;
391 opaque
* signature_
; // signed rsa_sa hashes
395 class ServerKeyExchange
: public HandShakeBase
{
396 ServerKeyBase
* server_key_
;
398 explicit ServerKeyExchange(SSL
&);
400 ~ServerKeyExchange();
402 void createKey(SSL
&);
403 void build(SSL
& ssl
);
405 const opaque
* getKey() const;
406 int getKeyLength() const;
408 input_buffer
& set(input_buffer
& in
);
409 output_buffer
& get(output_buffer
& out
) const;
411 friend output_buffer
& operator<<(output_buffer
&, const ServerKeyExchange
&);
413 void Process(input_buffer
&, SSL
&);
414 HandShakeType
get_type() const;
416 ServerKeyExchange(const ServerKeyExchange
&); // hide copy
417 ServerKeyExchange
& operator=(const ServerKeyExchange
&); // and assign
422 class CertificateRequest
: public HandShakeBase
{
423 ClientCertificateType certificate_types_
[CERT_TYPES
];
425 STL::list
<DistinguishedName
> certificate_authorities_
;
427 CertificateRequest();
428 ~CertificateRequest();
430 input_buffer
& set(input_buffer
& in
);
431 output_buffer
& get(output_buffer
& out
) const;
433 friend input_buffer
& operator>>(input_buffer
&, CertificateRequest
&);
434 friend output_buffer
& operator<<(output_buffer
&,
435 const CertificateRequest
&);
437 void Process(input_buffer
&, SSL
&);
438 HandShakeType
get_type() const;
442 CertificateRequest(const CertificateRequest
&); // hide copy
443 CertificateRequest
& operator=(const CertificateRequest
&); // and assign
447 struct ServerHelloDone
: public HandShakeBase
{
449 input_buffer
& set(input_buffer
& in
);
450 output_buffer
& get(output_buffer
& out
) const;
452 void Process(input_buffer
& input
, SSL
& ssl
);
454 HandShakeType
get_type() const;
458 struct PreMasterSecret
{
459 opaque random_
[SECRET_LEN
]; // first two bytes Protocol Version
463 struct ClientKeyBase
: public virtual_base
{
464 virtual ~ClientKeyBase() {}
465 virtual void build(SSL
&) {}
466 virtual void read(SSL
&, input_buffer
&) {}
467 virtual int get_length() const;
468 virtual opaque
* get_clientKey() const;
472 class EncryptedPreMasterSecret
: public ClientKeyBase
{
476 EncryptedPreMasterSecret();
477 ~EncryptedPreMasterSecret();
480 void read(SSL
&, input_buffer
&);
481 int get_length() const;
482 opaque
* get_clientKey() const;
485 // hide copy and assign
486 EncryptedPreMasterSecret(const EncryptedPreMasterSecret
&);
487 EncryptedPreMasterSecret
& operator=(const EncryptedPreMasterSecret
&);
491 // Fortezza Key Parameters from page 29
492 // hard code lengths cause only used here
493 struct FortezzaKeys
: public ClientKeyBase
{
494 opaque y_c_
[128]; // client's Yc, public value
495 opaque r_c_
[128]; // client's Rc
496 opaque y_signature_
[40]; // DSS signed public key
497 opaque wrapped_client_write_key_
[12]; // wrapped by the TEK
498 opaque wrapped_server_write_key_
[12]; // wrapped by the TEK
499 opaque client_write_iv_
[24];
500 opaque server_write_iv_
[24];
501 opaque master_secret_iv_
[24]; // IV used to encrypt preMaster
502 opaque encrypted_preMasterSecret_
[48]; // random & crypted by the TEK
507 // Diffie-Hellman public key from page 40/41
508 class ClientDiffieHellmanPublic
: public ClientKeyBase
{
509 PublicValueEncoding public_value_encoding_
;
510 int length_
; // includes two byte length for message
511 opaque
* Yc_
; // length + Yc_
512 // dh_Yc only if explicit, otherwise sent in certificate
513 enum { KEY_OFFSET
= 2 };
515 ClientDiffieHellmanPublic();
516 ~ClientDiffieHellmanPublic();
519 void read(SSL
&, input_buffer
&);
520 int get_length() const;
521 opaque
* get_clientKey() const;
522 void alloc(int sz
, bool offset
= false);
524 // hide copy and assign
525 ClientDiffieHellmanPublic(const ClientDiffieHellmanPublic
&);
526 ClientDiffieHellmanPublic
& operator=(const ClientDiffieHellmanPublic
&);
530 class ClientKeyExchange
: public HandShakeBase
{
531 ClientKeyBase
* client_key_
;
533 explicit ClientKeyExchange(SSL
& ssl
);
535 ~ClientKeyExchange();
537 void createKey(SSL
&);
538 void build(SSL
& ssl
);
540 const opaque
* getKey() const;
541 int getKeyLength() const;
543 friend output_buffer
& operator<<(output_buffer
&, const ClientKeyExchange
&);
545 input_buffer
& set(input_buffer
& in
);
546 output_buffer
& get(output_buffer
& out
) const;
548 HandShakeType
get_type() const;
549 void Process(input_buffer
&, SSL
&);
551 ClientKeyExchange(const ClientKeyExchange
&); // hide copy
552 ClientKeyExchange
& operator=(const ClientKeyExchange
&); // and assign
556 class CertificateVerify
: public HandShakeBase
{
558 byte
* signature_
; // owns
561 ~CertificateVerify();
563 input_buffer
& set(input_buffer
& in
);
564 output_buffer
& get(output_buffer
& out
) const;
566 friend input_buffer
& operator>>(input_buffer
&, CertificateVerify
&);
567 friend output_buffer
& operator<<(output_buffer
&, const CertificateVerify
&);
569 void Process(input_buffer
&, SSL
&);
570 HandShakeType
get_type() const;
574 CertificateVerify(const CertificateVerify
&); // hide copy
575 CertificateVerify
& operator=(const CertificateVerify
&); // and assign
579 class Finished
: public HandShakeBase
{
587 friend input_buffer
& operator>>(input_buffer
&, Finished
&);
588 friend output_buffer
& operator<<(output_buffer
&, const Finished
&);
590 input_buffer
& set(input_buffer
& in
);
591 output_buffer
& get(output_buffer
& out
) const;
593 void Process(input_buffer
&, SSL
&);
595 HandShakeType
get_type() const;
597 Finished(const Finished
&); // hide copy
598 Finished
& operator=(const Finished
&); // and assign
602 class RandomPool
; // forward for connection
605 // SSL Connection defined on page 11
607 opaque
*pre_master_secret_
;
608 opaque master_secret_
[SECRET_LEN
];
609 opaque client_random_
[RAN_LEN
];
610 opaque server_random_
[RAN_LEN
];
611 opaque sessionID_
[ID_LEN
];
612 opaque client_write_MAC_secret_
[SHA_LEN
]; // sha is max size
613 opaque server_write_MAC_secret_
[SHA_LEN
];
614 opaque client_write_key_
[AES_256_KEY_SZ
]; // aes 256bit is max sz
615 opaque server_write_key_
[AES_256_KEY_SZ
];
616 opaque client_write_IV_
[AES_IV_SZ
]; // aes is max size
617 opaque server_write_IV_
[AES_IV_SZ
];
618 uint32 sequence_number_
;
619 uint32 peer_sequence_number_
;
620 uint32 pre_secret_len_
; // pre master length
621 bool send_server_key_
; // server key exchange?
622 bool master_clean_
; // master secret clean?
623 bool TLS_
; // TLSv1 or greater
624 bool TLSv1_1_
; // TLSv1.1 or greater
625 bool sessionID_Set_
; // do we have a session
626 bool compression_
; // zlib compression?
627 ProtocolVersion version_
; // negotiated version
628 ProtocolVersion chVersion_
; // client hello version
631 Connection(ProtocolVersion v
, RandomPool
& ran
);
634 void AllocPreSecret(uint sz
);
635 void CleanPreMaster();
638 void TurnOffTLS1_1();
640 Connection(const Connection
&); // hide copy
641 Connection
& operator=(const Connection
&); // and assign
645 struct Ciphers
; // forward
648 // TLSv1 Security Spec, defined on page 56 of RFC 2246
650 ConnectionEnd entity_
;
651 BulkCipherAlgorithm bulk_cipher_algorithm_
;
652 CipherType cipher_type_
;
655 IsExportable is_exportable_
;
656 MACAlgorithm mac_algorithm_
;
658 CompressionMethod compression_algorithm_
;
659 KeyExchangeAlgorithm kea_
; // yassl additions
660 SignatureAlgorithm sig_algo_
; // signature auth type
661 SignatureAlgorithm verify_algo_
; // cert verify auth type
663 bool resumable_
; // new conns by session
664 uint16 encrypt_size_
; // current msg encrypt sz
665 Cipher suite_
[SUITE_LEN
]; // choosen suite
667 Cipher suites_
[MAX_SUITE_SZ
];
668 char cipher_name_
[MAX_SUITE_NAME
];
669 char cipher_list_
[MAX_CIPHERS
][MAX_SUITE_NAME
];
670 bool removeDH_
; // for server's later use
672 Parameters(ConnectionEnd
, const Ciphers
&, ProtocolVersion
, bool haveDH
);
674 void SetSuites(ProtocolVersion pv
, bool removeDH
= false,
675 bool removeRSA
= false, bool removeDSA
= false);
676 void SetCipherNames();
678 Parameters(const Parameters
&); // hide copy
679 Parameters
& operator=(const Parameters
&); // and assing
683 input_buffer
& operator>>(input_buffer
&, RecordLayerHeader
&);
684 output_buffer
& operator<<(output_buffer
&, const RecordLayerHeader
&);
686 input_buffer
& operator>>(input_buffer
&, Message
&);
687 output_buffer
& operator<<(output_buffer
&, const Message
&);
689 input_buffer
& operator>>(input_buffer
&, HandShakeBase
&);
690 output_buffer
& operator<<(output_buffer
&, const HandShakeBase
&);
693 // Message Factory definition
694 // uses the ContentType enumeration for unique id
695 typedef Factory
<Message
> MessageFactory
;
696 void InitMessageFactory(MessageFactory
&); // registers derived classes
698 // HandShake Factory definition
699 // uses the HandShakeType enumeration for unique id
700 typedef Factory
<HandShakeBase
> HandShakeFactory
;
701 void InitHandShakeFactory(HandShakeFactory
&); // registers derived classes
703 // ServerKey Factory definition
704 // uses KeyExchangeAlgorithm enumeration for unique id
705 typedef Factory
<ServerKeyBase
> ServerKeyFactory
;
706 void InitServerKeyFactory(ServerKeyFactory
&);
708 // ClientKey Factory definition
709 // uses KeyExchangeAlgorithm enumeration for unique id
710 typedef Factory
<ClientKeyBase
> ClientKeyFactory
;
711 void InitClientKeyFactory(ClientKeyFactory
&);
715 Message
* CreateHandShake();
716 Message
* CreateCipherSpec();
717 Message
* CreateAlert();
718 Message
* CreateData();
721 // HandShake Creators
722 HandShakeBase
* CreateCertificate();
723 HandShakeBase
* CreateHelloRequest();
724 HandShakeBase
* CreateClientHello();
725 HandShakeBase
* CreateServerHello();
726 HandShakeBase
* CreateServerKeyExchange();
727 HandShakeBase
* CreateCertificateRequest();
728 HandShakeBase
* CreateServerHelloDone();
729 HandShakeBase
* CreateClientKeyExchange();
730 HandShakeBase
* CreateCertificateVerify();
731 HandShakeBase
* CreateFinished();
734 // ServerKey Exchange Creators
735 ServerKeyBase
* CreateRSAServerKEA();
736 ServerKeyBase
* CreateDHServerKEA();
737 ServerKeyBase
* CreateFortezzaServerKEA();
739 // ClientKey Exchange Creators
740 ClientKeyBase
* CreateRSAClient();
741 ClientKeyBase
* CreateDHClient();
742 ClientKeyBase
* CreateFortezzaClient();
748 #endif // yaSSL_IMP_HPP