|
@@ -0,0 +1,314 @@
|
|
1
|
+// Note: This file still needs some work.
|
|
2
|
+
|
|
3
|
+// Typedefs
|
|
4
|
+// (As defined by the SSL v3.0 RFC Draft)
|
|
5
|
+// URL: http://wp.netscape.com/eng/ssl3/draft302.txt
|
|
6
|
+typedef unsigned char uint8;
|
|
7
|
+typedef uint8 uint16[2];
|
|
8
|
+typedef uint8 uint24[3];
|
|
9
|
+typedef uint8 uint32[4];
|
|
10
|
+typedef uint8 uint64[8];
|
|
11
|
+
|
|
12
|
+// Record layers
|
|
13
|
+typedef struct _ProtocolVersion{
|
|
14
|
+ uint8 major, minor;
|
|
15
|
+} ProtocolVersion;
|
|
16
|
+
|
|
17
|
+ProtocolVersion version = { 3, 0 };
|
|
18
|
+
|
|
19
|
+typedef enum _ContentType{
|
|
20
|
+ content_type_change_cipher_spec_type=20,
|
|
21
|
+ content_type_alert=21,
|
|
22
|
+ content_type_handshake=22,
|
|
23
|
+ content_type_application_data=23,
|
|
24
|
+ content_type_size=255 // to force size
|
|
25
|
+} ContentType;
|
|
26
|
+
|
|
27
|
+typedef struct _SSLPlaintext{
|
|
28
|
+ ContentType type;
|
|
29
|
+ ProtocolVersion version;
|
|
30
|
+ uint16 length; // can not exceed 2^14 bytes
|
|
31
|
+ uint8 fragment[16384]; // 2^14 = 16,384 bytes
|
|
32
|
+} SSLPlaintext;
|
|
33
|
+
|
|
34
|
+typedef struct _SSLCompressed{
|
|
35
|
+ ContentType type;
|
|
36
|
+ ProtocolVersion version;
|
|
37
|
+ uint16 length; // can not exceed 2^14 + 1024
|
|
38
|
+ uint8 fragment[17408]; // SSLCompressed.length
|
|
39
|
+} SSLCompressed;
|
|
40
|
+
|
|
41
|
+typedef struct _GenericStreamCipher{
|
|
42
|
+ uint8 content[17408]; // SSLCompressed.length
|
|
43
|
+ uint8 MAC[]; // CipherSpec.hash_size
|
|
44
|
+} GenericStreamCipher;
|
|
45
|
+
|
|
46
|
+typedef struct _SSLStreamCiphertext{
|
|
47
|
+ ContentType type;
|
|
48
|
+ ProtocolVersion version;
|
|
49
|
+ uint16 length; // can not exceed 2^14 + 2048 = 18,456
|
|
50
|
+ GenericStreamCipher fragment;
|
|
51
|
+} SSLStreamCiphertext;
|
|
52
|
+
|
|
53
|
+typedef struct _GenericBlockCipher{
|
|
54
|
+ uint8 content[17408]; // SSLConpressed.length
|
|
55
|
+ uint8 MAC[0]; // CipherSpec.hash_size
|
|
56
|
+ // padding is used to bring the plaintext to
|
|
57
|
+ // a multiple of the block cipher's block length.
|
|
58
|
+ uint8 padding[0]; // GenericBlockCipher.padding_length
|
|
59
|
+ uint8 padding_length;
|
|
60
|
+} GenericBlockCipher;
|
|
61
|
+
|
|
62
|
+typedef struct _SSLBlockCiphertext{
|
|
63
|
+ ContentType type;
|
|
64
|
+ ProtocolVersion version;
|
|
65
|
+ uint16 length; // can not exceed 2^14 + 2048 = 18,456
|
|
66
|
+ GenericBlockCipher fragment;
|
|
67
|
+} SSLBlockCiphertext;
|
|
68
|
+
|
|
69
|
+// Change cipher specs message
|
|
70
|
+typedef struct _ChangeCipherSpec{
|
|
71
|
+ enum { type_change_cipher_spec=1, type_size=255 } type;
|
|
72
|
+} ChangeCipherSpec;
|
|
73
|
+
|
|
74
|
+// Alert messages
|
|
75
|
+typedef enum _AlertLevel{
|
|
76
|
+ alert_level_warning=1,
|
|
77
|
+ alert_level_fatal=2,
|
|
78
|
+ alert_level_size=255
|
|
79
|
+} AlertLevel;
|
|
80
|
+
|
|
81
|
+typedef enum _AlertDescription{
|
|
82
|
+ alert_description_close_notify=0,
|
|
83
|
+ alert_description_unexpected_message=10,
|
|
84
|
+ alert_description_bad_record_mac=20,
|
|
85
|
+ alert_description_decompression_failure=30,
|
|
86
|
+ alert_description_handshake_failure=40,
|
|
87
|
+ alert_description_no_certificate=41,
|
|
88
|
+ alert_description_bad_certificate=42,
|
|
89
|
+ alert_description_unsupported_certificate=43,
|
|
90
|
+ alert_description_certificate_revoked=44,
|
|
91
|
+ alert_description_certificate_expired=45,
|
|
92
|
+ alert_description_certificate_unknown=46,
|
|
93
|
+ alert_description_illegal_parameter=47,
|
|
94
|
+ alert_description_size=255
|
|
95
|
+} AlertDescription;
|
|
96
|
+
|
|
97
|
+typedef struct _Alert{
|
|
98
|
+ AlertLevel level;
|
|
99
|
+ AlertDescription description;
|
|
100
|
+} Alert;
|
|
101
|
+
|
|
102
|
+// Handshake protocol
|
|
103
|
+// What is the best way to have a generic pointer to the body struct??
|
|
104
|
+typedef enum _HandshakeType{
|
|
105
|
+ handshake_type_hello_request=0,
|
|
106
|
+ handshake_type_client_hello=1,
|
|
107
|
+ handshake_type_server_hello=2,
|
|
108
|
+ handshake_type_certificate=11,
|
|
109
|
+ handshake_type_server_key_exchange=12,
|
|
110
|
+ handshake_type_certificate_request=13,
|
|
111
|
+ handshake_type_server_done=14,
|
|
112
|
+ handshake_type_certificate_verify=15,
|
|
113
|
+ handshake_type_client_key_exchange=16,
|
|
114
|
+ handshake_type_finished=20,
|
|
115
|
+ handshake_type_size=255
|
|
116
|
+} HandshakeType;
|
|
117
|
+
|
|
118
|
+typedef struct _Handshake{
|
|
119
|
+ HandshakeType msg_type;
|
|
120
|
+ uint24 length;
|
|
121
|
+} Handshake; // generic Handshake, need to recast to get body
|
|
122
|
+
|
|
123
|
+// Hello messages
|
|
124
|
+typedef struct _HelloRequest{} HelloRequest;
|
|
125
|
+
|
|
126
|
+typedef struct _HelloRequestHandshake{
|
|
127
|
+ HandshakeType msg_type;
|
|
128
|
+ uint24 length;
|
|
129
|
+ HelloRequest body;
|
|
130
|
+} HelloRequestHandshake;
|
|
131
|
+
|
|
132
|
+typedef struct _Random{
|
|
133
|
+ uint32 gmt_unix_time;
|
|
134
|
+ uint8 random_bytes[28];
|
|
135
|
+} Random;
|
|
136
|
+
|
|
137
|
+typedef uint8 SessionID[32]; // <0..32>
|
|
138
|
+typedef uint8 CipherSuite[2];
|
|
139
|
+
|
|
140
|
+typedef enum _CompressionMethod{ compression_method_null=0, compression_method_size=255 } CompressionMethod;
|
|
141
|
+
|
|
142
|
+typedef struct _ClientHello{
|
|
143
|
+ ProtocolVersion client_version;
|
|
144
|
+ Random random;
|
|
145
|
+ SessionID session_id;
|
|
146
|
+ CipherSuite cipher_suites[32768]; // <2..2^16-1> = 65,536 bytes and CipherSuite is 2 bytes
|
|
147
|
+ CompressionMethod compression_methods[256]; // <0..2^8-1> = 256 bytes and CompressionMethod is 1 byte
|
|
148
|
+} ClientHello;
|
|
149
|
+
|
|
150
|
+typedef struct _ClientHelloHandshake{
|
|
151
|
+ HandshakeType msg_type;
|
|
152
|
+ uint24 length;
|
|
153
|
+ ClientHello body;
|
|
154
|
+} ClientHelloHandshake;
|
|
155
|
+
|
|
156
|
+typedef struct _ServerHello{
|
|
157
|
+ ProtocolVersion server_version;
|
|
158
|
+ Random random;
|
|
159
|
+ SessionID session_id;
|
|
160
|
+ CipherSuite cipher_suite;
|
|
161
|
+ CompressionMethod compression_method;
|
|
162
|
+} ServerHello;
|
|
163
|
+
|
|
164
|
+typedef struct _ServerHelloHandshake{
|
|
165
|
+ HandshakeType msg_type;
|
|
166
|
+ uint24 length;
|
|
167
|
+ ServerHello body;
|
|
168
|
+} ServerHelloHandshake;
|
|
169
|
+
|
|
170
|
+// Server authentication and key exchange messages
|
|
171
|
+typedef uint8 ASN1Cert[16777216]; // <1..2^24-1> = 16,777,216 bytes
|
|
172
|
+
|
|
173
|
+typedef struct _Certificate{
|
|
174
|
+ ASN1Cert certificate_list[1]; // <1..2^24-1> / ANS1Cert = 1
|
|
175
|
+ // for some reason the size of certificate_list and ASN1Cert is the same, so only one certificate in the list
|
|
176
|
+} Certificate;
|
|
177
|
+
|
|
178
|
+typedef enum _KeyExchangeAlgorithm{
|
|
179
|
+ key_exchange_algorithm_rsa,
|
|
180
|
+ key_exchange_algorithm_diffie_hellman,
|
|
181
|
+ key_exchange_algorithm_fortezza_kea
|
|
182
|
+} KeyExchangeAlgorithm;
|
|
183
|
+
|
|
184
|
+typedef struct _AnonSignature{
|
|
185
|
+ struct {};
|
|
186
|
+} AnonSignature;
|
|
187
|
+
|
|
188
|
+typedef struct _RSASignature{
|
|
189
|
+ uint8 md5_hash[16];
|
|
190
|
+ uint8 sha_hash[20];
|
|
191
|
+} RSASignature;
|
|
192
|
+
|
|
193
|
+typedef struct _DSASignature{
|
|
194
|
+ uint8 sha_hash[20];
|
|
195
|
+} DSASignature;
|
|
196
|
+
|
|
197
|
+// use union??, make a mess to reference, but easy to make Signature type.
|
|
198
|
+typedef union _Signature{ AnonSignature anon; RSASignature rsa; DSASignature dsa; } Signature;
|
|
199
|
+
|
|
200
|
+typedef struct _ServerRSAParams{
|
|
201
|
+ uint8 RSA_modulus[65536]; // <1..2^16-1> = 65,536
|
|
202
|
+ uint8 RSA_exponent[65536]; // <1..2^16-1> = 65,536
|
|
203
|
+} ServerRSAParams;
|
|
204
|
+
|
|
205
|
+typedef struct _ServerDHParams{
|
|
206
|
+ uint8 DH_p[65536]; // <1..2^16-1>
|
|
207
|
+ uint8 DH_g[65536]; // <1..2^16-1>
|
|
208
|
+ uint8 DH_Ys[65536]; // <1..2^16-1>
|
|
209
|
+} ServerDHParams;
|
|
210
|
+
|
|
211
|
+typedef struct _ServerDHKeyExchange{
|
|
212
|
+ ServerDHParams params;
|
|
213
|
+ Signature signed_params;
|
|
214
|
+} ServerDHKeyExchange;
|
|
215
|
+
|
|
216
|
+typedef struct _ServerRSAKeyExchange{
|
|
217
|
+ ServerRSAParams params;
|
|
218
|
+ Signature signed_params;
|
|
219
|
+} ServerRSAKeyExchange;
|
|
220
|
+
|
|
221
|
+typedef enum _SignatureAlgorithm{
|
|
222
|
+ signature_algorithm_anonymous,
|
|
223
|
+ signature_algorithm_rsa,
|
|
224
|
+ signature_algorithm_dsa
|
|
225
|
+} SignatureAlgorithm;
|
|
226
|
+
|
|
227
|
+typedef enum _CertificateType{
|
|
228
|
+ certificate_type_RSA_sign=1,
|
|
229
|
+ certificate_type_DSS_sign=2,
|
|
230
|
+ certificate_type_RSA_fixed_DH=3,
|
|
231
|
+ certificate_type_DSS_fixed_DH=4,
|
|
232
|
+ certificate_type_RSA_ephemeral_DH=5,
|
|
233
|
+ certificate_type_DSS_ephemeral_DH=6,
|
|
234
|
+ certificate_type_FORTEZZA_MISSI=20,
|
|
235
|
+ certificate_type_size=255
|
|
236
|
+} CertificateType;
|
|
237
|
+
|
|
238
|
+typedef uint8 DistinguishedName[65536]; // <1..2^16-1> = 65,536
|
|
239
|
+
|
|
240
|
+typedef struct _CertificateRequest{
|
|
241
|
+ CertificateType certificate_types[256]; // <1..2^8-1>
|
|
242
|
+ DistinguishedName certificate_authorities[1]; // <3...2^16-1> / DistinguishedName
|
|
243
|
+ // this is another one that is odd with a list size of 1
|
|
244
|
+} CertificateRequest;
|
|
245
|
+
|
|
246
|
+typedef struct _ServerHelloDone{} ServerHelloDone;
|
|
247
|
+
|
|
248
|
+// Client authentication and key exchange messages
|
|
249
|
+typedef struct _PreMasterSecret{
|
|
250
|
+ ProtocolVersion client_version;
|
|
251
|
+ uint8 random[46];
|
|
252
|
+} PreMasterSecret;
|
|
253
|
+
|
|
254
|
+typedef struct _EncryptedPreMasterSecret{
|
|
255
|
+ PreMasterSecret pre_master_secret;
|
|
256
|
+} EncryptedPreMasterSecret;
|
|
257
|
+
|
|
258
|
+typedef struct _RSAClientKeyExchange{
|
|
259
|
+ EncryptedPreMasterSecret exchange_keys;
|
|
260
|
+} RSAClientKeyExchange;
|
|
261
|
+
|
|
262
|
+typedef enum _PublicValueEncoding{ public_value_encoding_implicit, public_value_encoding_explicit } PublicValueEncoding;
|
|
263
|
+
|
|
264
|
+typedef struct _ClientDiffieHellmanPublic{
|
|
265
|
+ // This is a select on PublicValueEncoding, and I chose the larger size
|
|
266
|
+ uint8 dh_public[65536]; // DH_Yc<1..2^16-1>, the dh public value
|
|
267
|
+} ClientDiffieHellmanPublic;
|
|
268
|
+
|
|
269
|
+typedef struct _DHClientKeyExhange{
|
|
270
|
+ ClientDiffieHellmanPublic exchange_keys;
|
|
271
|
+} DHClientKeyExchange;
|
|
272
|
+
|
|
273
|
+typedef struct _CertificateVerify{
|
|
274
|
+ Signature signature;
|
|
275
|
+} CertificateVerify;
|
|
276
|
+
|
|
277
|
+// Handshake finalization message
|
|
278
|
+typedef struct _Finished{
|
|
279
|
+ uint8 md5_hash[16];
|
|
280
|
+ uint8 sha_hash[20];
|
|
281
|
+} Finished;
|
|
282
|
+
|
|
283
|
+// The CipherSuite
|
|
284
|
+CipherSuite SSL_NULL_WITH_NULL_NULL = { 0x00, 0x00 };
|
|
285
|
+CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00, 0x0B };
|
|
286
|
+CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA = { 0x00, 0x0C };
|
|
287
|
+CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00, 0x17 };
|
|
288
|
+CipherSuite SSL_DH_anon_WITH_RC4_128_MD5 = { 0x00, 0x18 };
|
|
289
|
+
|
|
290
|
+// The CipherSpec
|
|
291
|
+typedef enum _CipherType{ cipher_type_stream, cipher_type_block } CipherType;
|
|
292
|
+typedef enum _IsExportable{ is_exportable_true, is_exportable_false } IsExportable;
|
|
293
|
+typedef enum _BulkCipherAlgorithm{
|
|
294
|
+ bulk_cipher_algorithm_null,
|
|
295
|
+ bulk_cipher_algorithm_rc4,
|
|
296
|
+ bulk_cipher_algorithm_rc2,
|
|
297
|
+ bulk_cipher_algorithm_des,
|
|
298
|
+ bulk_cipher_algorithm_3des,
|
|
299
|
+ bulk_cipher_algorithm_des40,
|
|
300
|
+ bulk_cipher_algorithm_fortezza
|
|
301
|
+} BulkCipherAlgorithm;
|
|
302
|
+typedef enum _MACAlgorithm{ mac_algorithm_null, mac_algorithm_md5, mac_algorithm_sha } MACAlgorithm;
|
|
303
|
+
|
|
304
|
+typedef struct _CipherSpec{
|
|
305
|
+ BulkCipherAlgorithm bulk_cipher_algorithm;
|
|
306
|
+ MACAlgorithm mac_algorithm;
|
|
307
|
+ CipherType cipher_type;
|
|
308
|
+ IsExportable is_exportable;
|
|
309
|
+ uint8 hash_size;
|
|
310
|
+ uint8 key_material;
|
|
311
|
+ uint8 IV_size;
|
|
312
|
+} CipherSpec;
|
|
313
|
+
|
|
314
|
+
|