summaryrefslogtreecommitdiffstats
path: root/src/crypto/ssl_constructs.h
blob: 43c585518b6eaea5c80b01b2b821cdd6f0cf4e39 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
// Note: This file still needs some work.

// Typedefs
// (As defined by the SSL v3.0 RFC Draft)
// URL: http://wp.netscape.com/eng/ssl3/draft302.txt
typedef unsigned char uint8;
typedef uint8 uint16[2];
typedef uint8 uint24[3];
typedef uint8 uint32[4];
typedef uint8 uint64[8];

// Record layers
typedef struct _ProtocolVersion{
  uint8 major, minor;
} ProtocolVersion;

ProtocolVersion version = { 3, 0 };

typedef enum _ContentType{
  content_type_change_cipher_spec_type=20,
  content_type_alert=21,
  content_type_handshake=22,
  content_type_application_data=23,
  content_type_size=255 // to force size
} ContentType;

typedef struct _SSLPlaintext{
  ContentType type;
  ProtocolVersion version;
  uint16 length; // can not exceed 2^14 bytes
  uint8 fragment[16384]; // 2^14 = 16,384 bytes
} SSLPlaintext;

typedef struct _SSLCompressed{
  ContentType type;
  ProtocolVersion version;
  uint16 length; // can not exceed 2^14 + 1024
  uint8 fragment[17408]; // SSLCompressed.length
} SSLCompressed;

typedef struct _GenericStreamCipher{
  uint8 content[17408]; // SSLCompressed.length
  uint8 MAC[]; // CipherSpec.hash_size
} GenericStreamCipher;

typedef struct _SSLStreamCiphertext{
  ContentType type;
  ProtocolVersion version;
  uint16 length; // can not exceed 2^14 + 2048 = 18,456
  GenericStreamCipher fragment;
} SSLStreamCiphertext;

typedef struct _GenericBlockCipher{
  uint8 content[17408]; // SSLConpressed.length
  uint8 MAC[0]; // CipherSpec.hash_size
  // padding is used to bring the plaintext to
  // a multiple of the block cipher's block length.
  uint8 padding[0]; // GenericBlockCipher.padding_length
  uint8 padding_length;
} GenericBlockCipher;

typedef struct _SSLBlockCiphertext{
  ContentType type;
  ProtocolVersion version;
  uint16 length; // can not exceed 2^14 + 2048 = 18,456
  GenericBlockCipher fragment;
} SSLBlockCiphertext;

// Change cipher specs message
typedef struct _ChangeCipherSpec{
  enum { type_change_cipher_spec=1, type_size=255 } type;
} ChangeCipherSpec;

// Alert messages
typedef enum _AlertLevel{
  alert_level_warning=1,
  alert_level_fatal=2,
  alert_level_size=255 
} AlertLevel;

typedef enum _AlertDescription{
  alert_description_close_notify=0,
  alert_description_unexpected_message=10,
  alert_description_bad_record_mac=20,
  alert_description_decompression_failure=30,
  alert_description_handshake_failure=40,
  alert_description_no_certificate=41,
  alert_description_bad_certificate=42,
  alert_description_unsupported_certificate=43,
  alert_description_certificate_revoked=44,
  alert_description_certificate_expired=45,
  alert_description_certificate_unknown=46,
  alert_description_illegal_parameter=47,
  alert_description_size=255
} AlertDescription;

typedef struct _Alert{
  AlertLevel level;
  AlertDescription description;
} Alert;

// Handshake protocol
// What is the best way to have a generic pointer to the body struct??
typedef enum _HandshakeType{
  handshake_type_hello_request=0,
  handshake_type_client_hello=1,
  handshake_type_server_hello=2,
  handshake_type_certificate=11,
  handshake_type_server_key_exchange=12,
  handshake_type_certificate_request=13,
  handshake_type_server_done=14,
  handshake_type_certificate_verify=15,
  handshake_type_client_key_exchange=16,
  handshake_type_finished=20,
  handshake_type_size=255
} HandshakeType;

typedef struct _Handshake{
  HandshakeType msg_type;
  uint24 length;
} Handshake; // generic Handshake, need to recast to get body

// Hello messages
typedef struct _HelloRequest{} HelloRequest;

typedef struct _HelloRequestHandshake{
  HandshakeType msg_type;
  uint24 length;
  HelloRequest body;
} HelloRequestHandshake;

typedef struct _Random{
  uint32 gmt_unix_time;
  uint8 random_bytes[28];
} Random;

typedef uint8 SessionID[32]; // <0..32>
typedef uint8 CipherSuite[2];

typedef enum _CompressionMethod{ compression_method_null=0, compression_method_size=255 } CompressionMethod;

typedef struct _ClientHello{
  ProtocolVersion client_version;
  Random random;
  SessionID session_id;
  CipherSuite cipher_suites[32768]; // <2..2^16-1> = 65,536 bytes and CipherSuite is 2 bytes
  CompressionMethod compression_methods[256]; // <0..2^8-1> = 256 bytes and CompressionMethod is 1 byte
} ClientHello;

typedef struct _ClientHelloHandshake{
  HandshakeType msg_type;
  uint24 length;
  ClientHello body;
} ClientHelloHandshake;

typedef struct _ServerHello{
  ProtocolVersion server_version;
  Random random;
  SessionID session_id;
  CipherSuite cipher_suite;
  CompressionMethod compression_method;
} ServerHello;

typedef struct _ServerHelloHandshake{
  HandshakeType msg_type;
  uint24 length;
  ServerHello body;
} ServerHelloHandshake;

// Server authentication and key exchange messages
typedef uint8 ASN1Cert[16777216]; // <1..2^24-1> = 16,777,216 bytes

typedef struct _Certificate{
  ASN1Cert certificate_list[1]; // <1..2^24-1> / ANS1Cert = 1
  // for some reason the size of certificate_list and ASN1Cert is the same, so only one certificate in the list
} Certificate;

typedef enum _KeyExchangeAlgorithm{
  key_exchange_algorithm_rsa,
  key_exchange_algorithm_diffie_hellman,
  key_exchange_algorithm_fortezza_kea 
} KeyExchangeAlgorithm;

typedef struct _AnonSignature{
  struct {};
} AnonSignature;

typedef struct _RSASignature{
  uint8 md5_hash[16];
  uint8 sha_hash[20];
} RSASignature;

typedef struct _DSASignature{
  uint8 sha_hash[20];
} DSASignature;

// use union??,  make a mess to reference, but easy to make Signature type.
typedef union _Signature{ AnonSignature anon; RSASignature rsa; DSASignature dsa; } Signature;

typedef struct _ServerRSAParams{
  uint8 RSA_modulus[65536]; // <1..2^16-1> = 65,536
  uint8 RSA_exponent[65536]; // <1..2^16-1> = 65,536
} ServerRSAParams;

typedef struct _ServerDHParams{
  uint8 DH_p[65536]; // <1..2^16-1>
  uint8 DH_g[65536]; // <1..2^16-1>
  uint8 DH_Ys[65536]; // <1..2^16-1>
} ServerDHParams;

typedef struct _ServerDHKeyExchange{
  ServerDHParams params;
  Signature signed_params;
} ServerDHKeyExchange;

typedef struct _ServerRSAKeyExchange{
  ServerRSAParams params;
  Signature signed_params;
} ServerRSAKeyExchange;

typedef enum _SignatureAlgorithm{
  signature_algorithm_anonymous,
  signature_algorithm_rsa,
  signature_algorithm_dsa 
} SignatureAlgorithm;

typedef enum _CertificateType{
  certificate_type_RSA_sign=1,
  certificate_type_DSS_sign=2,
  certificate_type_RSA_fixed_DH=3,
  certificate_type_DSS_fixed_DH=4,
  certificate_type_RSA_ephemeral_DH=5,
  certificate_type_DSS_ephemeral_DH=6,
  certificate_type_FORTEZZA_MISSI=20,
  certificate_type_size=255
} CertificateType;

typedef uint8 DistinguishedName[65536]; // <1..2^16-1> = 65,536

typedef struct _CertificateRequest{
  CertificateType certificate_types[256]; // <1..2^8-1>
  DistinguishedName certificate_authorities[1]; // <3...2^16-1> / DistinguishedName
  // this is another one that is odd with a list size of 1
} CertificateRequest;

typedef struct _ServerHelloDone{} ServerHelloDone;

// Client authentication and key exchange messages
typedef struct _PreMasterSecret{
  ProtocolVersion client_version;
  uint8 random[46];
} PreMasterSecret;

typedef struct _EncryptedPreMasterSecret{
  PreMasterSecret pre_master_secret;
} EncryptedPreMasterSecret;

typedef struct _RSAClientKeyExchange{
  EncryptedPreMasterSecret exchange_keys;
} RSAClientKeyExchange;

typedef enum _PublicValueEncoding{ public_value_encoding_implicit, public_value_encoding_explicit } PublicValueEncoding;

typedef struct _ClientDiffieHellmanPublic{
  // This is a select on PublicValueEncoding,  and I chose the larger size
  uint8 dh_public[65536]; // DH_Yc<1..2^16-1>, the dh public value
} ClientDiffieHellmanPublic;

typedef struct _DHClientKeyExhange{
  ClientDiffieHellmanPublic exchange_keys;
} DHClientKeyExchange;

typedef struct _CertificateVerify{
  Signature signature;
} CertificateVerify;

// Handshake finalization message
typedef struct _Finished{
  uint8 md5_hash[16];
  uint8 sha_hash[20];
} Finished;

// The CipherSuite
CipherSuite SSL_NULL_WITH_NULL_NULL                     = { 0x00, 0x00 };
CipherSuite SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA        = { 0x00, 0x0B };
CipherSuite SSL_DH_DSS_WITH_DES_CBC_SHA                 = { 0x00, 0x0C };
CipherSuite SSL_DH_anon_EXPORT_WITH_RC4_40_MD5          = { 0x00, 0x17 };
CipherSuite SSL_DH_anon_WITH_RC4_128_MD5                = { 0x00, 0x18 };

// The CipherSpec
typedef enum _CipherType{ cipher_type_stream, cipher_type_block } CipherType;
typedef enum _IsExportable{ is_exportable_true, is_exportable_false } IsExportable;
typedef enum _BulkCipherAlgorithm{
  bulk_cipher_algorithm_null,
  bulk_cipher_algorithm_rc4,
  bulk_cipher_algorithm_rc2,
  bulk_cipher_algorithm_des,
  bulk_cipher_algorithm_3des,
  bulk_cipher_algorithm_des40,
  bulk_cipher_algorithm_fortezza 
} BulkCipherAlgorithm;
typedef enum _MACAlgorithm{ mac_algorithm_null, mac_algorithm_md5, mac_algorithm_sha } MACAlgorithm;

typedef struct _CipherSpec{
  BulkCipherAlgorithm bulk_cipher_algorithm;
  MACAlgorithm mac_algorithm;
  CipherType cipher_type;
  IsExportable is_exportable;
  uint8 hash_size;
  uint8 key_material;
  uint8 IV_size;
} CipherSpec;