1 // Note: This file still needs some work.
2 // Note: I had to redefine the enums to a set of const values,
3 // so that the size of the variable would be correct.
6 // (As defined by the SSL v3.0 RFC Draft)
7 // URL: http://wp.netscape.com/eng/ssl3/draft302.txt
8 typedef unsigned char uint8
;
9 typedef uint8 uint16
[2];
10 typedef uint8 uint24
[3];
11 typedef uint8 uint32
[4];
12 typedef uint8 uint64
[8];
15 typedef struct _ProtocolVersion
{
19 const ProtocolVersion version
= { 3, 0 };
21 typedef uint8 ContentType
;
22 const ContentType content_type_change_cipher_spec_type
= 20;
23 const ContentType content_type_alert
= 21;
24 const ContentType content_type_handshake
= 22;
25 const ContentType content_type_application_data
= 23;
27 typedef struct _SSLPlaintext
{
29 ProtocolVersion version
;
30 uint16 length
; // can not exceed 2^14 bytes
31 uint8 fragment
[16384]; // 2^14 = 16,384 bytes
34 typedef struct _SSLCompressed
{
36 ProtocolVersion version
;
37 uint16 length
; // can not exceed 2^14 + 1024
38 uint8 fragment
[17408]; // SSLCompressed.length
41 typedef struct _SSLCiphertext
{
43 ProtocolVersion version
;
45 uint8 fragment
; // so we have a pointer to the data, and don't have to do math
46 // fragment; type GenericStreamCipher or GenericBlockCipher
47 } SSLCiphertext
; // recast to get fragment
49 typedef struct _GenericStreamCipher
{
50 uint8 content
[17408]; // SSLCompressed.length
51 uint8 MAC
[]; // CipherSpec.hash_size
52 } GenericStreamCipher
;
54 typedef struct _SSLStreamCiphertext
{
56 ProtocolVersion version
;
57 uint16 length
; // can not exceed 2^14 + 2048 = 18,456
58 GenericStreamCipher fragment
;
59 } SSLStreamCiphertext
;
61 typedef struct _GenericBlockCipher
{
62 uint8 content
[17408]; // SSLConpressed.length
63 uint8 MAC
[0]; // CipherSpec.hash_size
64 // padding is used to bring the plaintext to
65 // a multiple of the block cipher's block length.
66 uint8 padding
[0]; // GenericBlockCipher.padding_length
70 typedef struct _SSLBlockCiphertext
{
72 ProtocolVersion version
;
73 uint16 length
; // can not exceed 2^14 + 2048 = 18,456
74 GenericBlockCipher fragment
;
77 // Change cipher specs message
78 typedef struct _ChangeCipherSpec
{
79 enum { type_change_cipher_spec
=1, type_size
=255 } type
;
83 typedef uint8 AlertLevel
;
84 const AlertLevel alert_level_warning
= 1;
85 const AlertLevel alert_level_fatal
=2;
87 typedef uint8 AlertDescription
;
88 const AlertDescription alert_description_close_notify
= 0;
89 const AlertDescription alert_description_unexpected_message
= 10;
90 const AlertDescription alert_description_bad_record_mac
= 20;
91 const AlertDescription alert_description_decompression_failure
= 30;
92 const AlertDescription alert_description_handshake_failure
= 40;
93 const AlertDescription alert_description_no_certificate
= 41;
94 const AlertDescription alert_description_bad_certificate
= 42;
95 const AlertDescription alert_description_unsupported_certificate
= 43;
96 const AlertDescription alert_description_certificate_revoked
= 44;
97 const AlertDescription alert_description_certificate_expired
= 45;
98 const AlertDescription alert_description_certificate_unknown
= 46;
99 const AlertDescription alert_description_illegal_parameter
= 47;
101 typedef struct _Alert
{
103 AlertDescription description
;
106 // Handshake protocol
107 // What is the best way to have a generic pointer to the body struct??
108 typedef uint8 HandshakeType
;
109 const HandshakeType handshake_type_hello_request
= 0;
110 const HandshakeType handshake_type_client_hello
= 1;
111 const HandshakeType handshake_type_server_hello
= 2;
112 const HandshakeType handshake_type_certificate
= 11;
113 const HandshakeType handshake_type_server_key_exchange
= 12;
114 const HandshakeType handshake_type_certificate_request
= 13;
115 const HandshakeType handshake_type_server_done
= 14;
116 const HandshakeType handshake_type_certificate_verify
= 15;
117 const HandshakeType handshake_type_client_key_exchange
= 16;
118 const HandshakeType handshake_type_finished
= 20;
120 typedef struct _Handshake
{
121 HandshakeType msg_type
;
123 // body; // one of HandshakeType structs
124 } Handshake
; // generic Handshake, need to recast to get body
127 typedef struct _HelloRequest
{} HelloRequest
;
129 typedef struct _HelloRequestHandshake
{
130 HandshakeType msg_type
;
133 } HelloRequestHandshake
;
135 typedef struct _Random
{
136 uint32 gmt_unix_time
;
137 uint8 random_bytes
[28];
140 //typedef uint8 SessionID[32]; // <0..32>
141 typedef uint8 SessionIDLength
;
142 typedef uint8 SessionID
;
144 typedef uint16 CipherSuiteLength
;
145 typedef uint8 CipherSuite
[2];
147 typedef uint8 CompressionMethodLength
;
148 typedef uint8 CompressionMethod
;
149 const CompressionMethod compression_method_null
= 0;
152 typedef struct _ClientHello
{
153 ProtocolVersion client_version
;
155 SessionIDLength session_id_length
;
156 SessionID
*session_id
;
157 SessionID
*session_id_end
;
158 CipherSuiteLength
*cipher_suites_length
;
159 CipherSuite
*cipher_suites
; // min size is one entry
160 CipherSuite
*cipher_suites_end
;
161 //CipherSuite cipher_suites[32768]; // <2..2^16-1> = 65,536 bytes and CipherSuite is 2 bytes
162 CompressionMethodLength
*compression_methods_length
;
163 CompressionMethod
*compression_methods
;
164 CompressionMethod
*compression_methods_end
;
165 //CompressionMethod *compression_methods; // min size is zero
166 //CompressionMethod compression_methods[256]; // <0..2^8-1> = 256 bytes and CompressionMethod is 1 byte
169 typedef struct _ClientHelloHandshake
{
170 //HandshakeType msg_type;
174 } ClientHelloHandshake
;
176 typedef struct _ServerHello
{
177 ProtocolVersion server_version
;
179 SessionID session_id
;
180 CipherSuite cipher_suite
;
181 CompressionMethod compression_method
;
184 typedef struct _ServerHelloHandshake
{
185 HandshakeType msg_type
;
188 } ServerHelloHandshake
;
190 // Server authentication and key exchange messages
191 typedef uint8 ASN1Cert
[16777216]; // <1..2^24-1> = 16,777,216 bytes
193 typedef struct _Certificate
{
194 ASN1Cert certificate_list
[1]; // <1..2^24-1> / ANS1Cert = 1
195 // for some reason the size of certificate_list and ASN1Cert is the same, so only one certificate in the list
198 typedef uint8 KeyExchangeAlgorithm
;
199 const KeyExchangeAlgorithm key_exchange_algorithm_rsa
= 0;
200 const KeyExchangeAlgorithm key_exchange_algorithm_diffie_hellman
= 1;
201 const KeyExchangeAlgorithm key_exchange_algorithm_fortezza_kea
= 2;
203 typedef struct _AnonSignature
{
207 typedef struct _RSASignature
{
212 typedef struct _DSASignature
{
216 // use union??, make a mess to reference, but easy to make Signature type.
217 typedef union _Signature
{ AnonSignature anon
; RSASignature rsa
; DSASignature dsa
; } Signature
;
219 typedef struct _ServerRSAParams
{
220 uint8 RSA_modulus
[65536]; // <1..2^16-1> = 65,536
221 uint8 RSA_exponent
[65536]; // <1..2^16-1> = 65,536
224 typedef struct _ServerDHParams
{
225 uint8 DH_p
[65536]; // <1..2^16-1>
226 uint8 DH_g
[65536]; // <1..2^16-1>
227 uint8 DH_Ys
[65536]; // <1..2^16-1>
230 typedef struct _ServerDHKeyExchange
{
231 ServerDHParams params
;
232 Signature signed_params
;
233 } ServerDHKeyExchange
;
235 typedef struct _ServerRSAKeyExchange
{
236 ServerRSAParams params
;
237 Signature signed_params
;
238 } ServerRSAKeyExchange
;
240 typedef uint8 SignatureAlgorithm
;
241 const SignatureAlgorithm signature_algorithm_anonymous
= 0;
242 const SignatureAlgorithm signature_algorithm_rsa
= 1;
243 const SignatureAlgorithm signature_algorithm_dsa
= 2;
245 typedef uint8 CertificateType
;
246 const CertificateType certificate_type_RSA_sign
= 1;
247 const CertificateType certificate_type_DSS_sign
= 2;
248 const CertificateType certificate_type_RSA_fixed_DH
= 3;
249 const CertificateType certificate_type_DSS_fixed_DH
= 4;
250 const CertificateType certificate_type_RSA_ephemeral_DH
= 5;
251 const CertificateType certificate_type_DSS_ephemeral_DH
= 6;
252 const CertificateType certificate_type_FORTEZZA_MISSI
= 20;
254 typedef uint8 DistinguishedName
[65536]; // <1..2^16-1> = 65,536
256 typedef struct _CertificateRequest
{
257 CertificateType certificate_types
[256]; // <1..2^8-1>
258 DistinguishedName certificate_authorities
[1]; // <3...2^16-1> / DistinguishedName
259 // this is another one that is odd with a list size of 1
260 } CertificateRequest
;
262 typedef struct _ServerHelloDone
{} ServerHelloDone
;
264 // Client authentication and key exchange messages
265 typedef struct _PreMasterSecret
{
266 ProtocolVersion client_version
;
270 typedef struct _EncryptedPreMasterSecret
{
271 PreMasterSecret pre_master_secret
;
272 } EncryptedPreMasterSecret
;
274 typedef struct _RSAClientKeyExchange
{
275 EncryptedPreMasterSecret exchange_keys
;
276 } RSAClientKeyExchange
;
278 typedef uint8 PublicValueEncoding
;
279 const PublicValueEncoding public_value_encoding_implicit
= 0;
280 const PublicValueEncoding public_value_encoding_explicit
= 1;
282 typedef struct _ClientDiffieHellmanPublic
{
283 // This is a select on PublicValueEncoding, and I chose the larger size
284 uint8 dh_public
[65536]; // DH_Yc<1..2^16-1>, the dh public value
285 } ClientDiffieHellmanPublic
;
287 typedef struct _DHClientKeyExhange
{
288 ClientDiffieHellmanPublic exchange_keys
;
289 } DHClientKeyExchange
;
291 typedef struct _CertificateVerify
{
295 // Handshake finalization message
296 typedef struct _Finished
{
302 CipherSuite SSL_NULL_WITH_NULL_NULL
= { 0x00, 0x13 };
303 CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
= { 0x00, 0x0B };
304 CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA
= { 0x00, 0x0C };
305 CipherSuite SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
= { 0x00, 0x11 };
306 CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
= { 0x00, 0x17 };
307 CipherSuite SSL_DH_anon_WITH_RC4_128_MD5
= { 0x00, 0x18 };
310 typedef uint8 CipherType
;
311 const CipherType cipher_type_stream
= 0;
312 const CipherType cipher_type_block
= 1;
314 typedef uint8 IsExportable
;
315 const IsExportable is_exportable_true
= 0;
316 const IsExportable is_exportable_false
= 1;
318 typedef uint8 BulkCipherAlgorithm
;
319 const BulkCipherAlgorithm bulk_cipher_algorithm_null
= 0;
320 const BulkCipherAlgorithm bulk_cipher_algorithm_rc4
= 1;
321 const BulkCipherAlgorithm bulk_cipher_algorithm_rc2
= 2;
322 const BulkCipherAlgorithm bulk_cipher_algorithm_des
= 3;
323 const BulkCipherAlgorithm bulk_cipher_algorithm_3des
= 4;
324 const BulkCipherAlgorithm bulk_cipher_algorithm_des40
= 5;
325 const BulkCipherAlgorithm bulk_cipher_algorithm_fortezza
= 6;
327 typedef uint8 MACAlgorithm
;
328 const MACAlgorithm mac_algorithm_null
= 0;
329 const MACAlgorithm mac_algorithm_md5
= 1;
330 const MACAlgorithm mac_algorithm_sha
= 2;
332 typedef struct _CipherSpec
{
333 BulkCipherAlgorithm bulk_cipher_algorithm
;
334 MACAlgorithm mac_algorithm
;
335 CipherType cipher_type
;
336 IsExportable is_exportable
;