added some support for session resuming (in client)
[gnutls:gnutls.git] / lib / gnutls_int.h
1 #ifndef GNUTLS_INT_H
2
3 #define GNUTLS_INT_H
4
5 #define HANDSHAKE_DEBUG
6 //#define HARD_DEBUG
7 //#define READ_DEBUG
8 //#define WRITE_DEBUG
9 #define DEBUG
10
11 #define MAX32 4294967295
12 #define MAX24 16777215
13 #define MAX16 65535
14
15 /* for big numbers support */ /* FIXME */
16 #include <gcrypt.h>
17
18 #define GNUTLS_MPI MPI
19 #define gnutls_mpi_release mpi_release
20
21 #define svoid void /* for functions that allocate using secure_free */
22 #define secure_free free
23 #define secure_malloc malloc
24 #define secure_realloc realloc
25 #define secure_calloc calloc
26 #define gnutls_malloc malloc
27 #define gnutls_realloc realloc
28 #define gnutls_calloc calloc
29 #define gnutls_free free
30
31 typedef struct {
32         uint8   pint[3];
33 } uint24;
34
35 #define rotl64(x,n)   (((x) << ((uint16)(n))) | ((x) >> (64 - (uint16)(n))))
36 #define rotr64(x,n)   (((x) >> ((uint16)(n))) | ((x) << (64 - (uint16)(n))))
37 #define rotl32(x,n)   (((x) << ((uint16)(n))) | ((x) >> (32 - (uint16)(n))))
38 #define rotr32(x,n)   (((x) >> ((uint16)(n))) | ((x) << (32 - (uint16)(n))))
39 #define rotl16(x,n)   (((x) << ((uint16)(n))) | ((x) >> (16 - (uint16)(n))))
40 #define rotr16(x,n)   (((x) >> ((uint16)(n))) | ((x) << (16 - (uint16)(n))))
41
42 #define byteswap16(x)  ((rotl16(x, 8) & 0x00ff) | (rotr16(x, 8) & 0xff00))
43 #define byteswap32(x)  ((rotl32(x, 8) & 0x00ff00ff) | (rotr32(x, 8) & 0xff00ff00))
44 #define byteswap64(x)  ((rotl64(x, 8) & 0x00ff00ff00ff00ffLL) | (rotr64(x, 8) & 0xff00ff00ff00ff00LL))
45
46 typedef unsigned char opaque;
47
48
49 enum ChangeCipherSpecType { GNUTLS_TYPE_CHANGE_CIPHER_SPEC=1 };
50 enum AlertLevel { GNUTLS_WARNING=1, GNUTLS_FATAL };
51 enum AlertDescription { GNUTLS_CLOSE_NOTIFY, GNUTLS_UNEXPECTED_MESSAGE=10, GNUTLS_BAD_RECORD_MAC=20,
52                         GNUTLS_DECRYPTION_FAILED, GNUTLS_RECORD_OVERFLOW,  GNUTLS_DECOMPRESSION_FAILURE=30,
53                         GNUTLS_HANDSHAKE_FAILURE=40, GNUTLS_BAD_CERTIFICATE=42, GNUTLS_UNSUPPORTED_CERTIFICATE,
54                         GNUTLS_CERTIFICATE_REVOKED, GNUTLS_CERTIFICATE_EXPIRED, GNUTLS_CERTIFICATE_UNKNOWN,
55                         GNUTLS_ILLEGAL_PARAMETER, GNUTLS_UNKNOWN_CA, GNUTLS_ACCESS_DENIED, GNUTLS_DECODE_ERROR=50,
56                         GNUTLS_DECRYPT_ERROR, GNUTLS_EXPORT_RESTRICTION=60, GNUTLS_PROTOCOL_VERSION=70,
57                         GNUTLS_INSUFFICIENT_SECURITY, GNUTLS_INTERNAL_ERROR=80, GNUTLS_USER_CANCELED=90,
58                         GNUTLS_NO_RENEGOTIATION=100
59                         };
60                         
61 typedef enum AlertDescription AlertDescription;
62 typedef enum AlertLevel AlertLevel;
63 typedef enum ChangeCipherSpecType ChangeCipherSpecType;
64
65 enum HandshakeType { GNUTLS_HELLO_REQUEST, GNUTLS_CLIENT_HELLO, GNUTLS_SERVER_HELLO,
66                      GNUTLS_CERTIFICATE=11, GNUTLS_SERVER_KEY_EXCHANGE,
67                      GNUTLS_CERTIFICATE_REQUEST, GNUTLS_SERVER_HELLO_DONE,
68                      GNUTLS_CERTIFICATE_VERIFY, GNUTLS_CLIENT_KEY_EXCHANGE,
69                      GNUTLS_FINISHED=20 };
70                         
71 typedef enum HandshakeType HandshakeType;
72
73
74 typedef struct {
75         ChangeCipherSpecType type;
76 } ChangeCipherSpec;
77
78 typedef struct {
79         AlertLevel level;
80         AlertDescription description;
81 } Alert;
82
83
84 /* STATE */
85 enum ConnectionEnd { GNUTLS_SERVER, GNUTLS_CLIENT };
86 enum BulkCipherAlgorithm { GNUTLS_NULL, GNUTLS_ARCFOUR=1, GNUTLS_3DES = 4, GNUTLS_RIJNDAEL };
87 enum KXAlgorithm { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DH_DSS, GNUTLS_KX_DH_RSA, GNUTLS_KX_ANON_DH };
88 enum KeyExchangeAlgorithm { GNUTLS_RSA, GNUTLS_DIFFIE_HELLMAN };
89 enum CipherType { CIPHER_STREAM, CIPHER_BLOCK };
90 enum MACAlgorithm { GNUTLS_MAC_NULL, GNUTLS_MAC_MD5, GNUTLS_MAC_SHA };
91 enum CompressionMethod { GNUTLS_COMPRESSION_NULL, GNUTLS_ZLIB=224 };
92
93 enum ValidSession { VALID_TRUE, VALID_FALSE };
94 enum ResumableSession { RESUME_TRUE, RESUME_FALSE };
95
96 typedef enum KeyExchangeAlgorithm KeyExchangeAlgorithm;
97 typedef enum KXAlgorithm KXAlgorithm;
98 typedef enum ValidSession ValidSession;
99 typedef enum ResumableSession ResumableSession;
100 typedef enum ConnectionEnd ConnectionEnd;
101 typedef enum BulkCipherAlgorithm BulkCipherAlgorithm;
102 typedef enum CipherType CipherType;
103 typedef enum MACAlgorithm MACAlgorithm;
104 typedef enum CompressionMethod CompressionMethod;
105
106 #include <gnutls_hash_int.h>
107 #include <gnutls_cipher_int.h>
108
109 typedef struct {
110         ConnectionEnd entity;
111         BulkCipherAlgorithm bulk_cipher_algorithm;
112         CipherType cipher_type;
113         MACAlgorithm mac_algorithm;
114         CompressionMethod compression_algorithm;
115         uint8 IV_size;
116         uint8 key_size;
117         uint8 key_material_length;
118         uint8 hash_size;
119         opaque master_secret[48];
120         opaque client_random[32];
121         opaque server_random[32];
122         opaque session_id[32];
123         uint8 session_id_size;
124 } SecurityParameters;
125
126 typedef struct {
127         opaque* server_write_mac_secret;
128         opaque* client_write_mac_secret;
129         opaque* server_write_IV;
130         opaque* client_write_IV;
131         opaque* server_write_key;
132         opaque* client_write_key;
133 } CipherSpecs;
134
135
136 typedef struct {
137         uint8 local;
138         uint8 major;
139         uint8 minor;
140 } GNUTLS_Version;
141
142 extern GNUTLS_Version GNUTLS_TLS1;
143 extern GNUTLS_Version GNUTLS_SSL3;
144
145 typedef struct {
146         GNUTLS_Version version;
147         opaque*         read_compression_state;
148         opaque*         write_compression_state;
149         GNUTLS_CIPHER_HANDLE write_cipher_state;
150         GNUTLS_CIPHER_HANDLE read_cipher_state;
151         opaque*         read_mac_secret;
152         opaque*         write_mac_secret;
153         uint8           mac_secret_size;
154         uint64  read_sequence_number;
155         uint64  write_sequence_number;
156 } ConnectionState;
157
158 typedef struct {
159         uint8 CipherSuite[2];
160 } GNUTLS_CipherSuite;
161
162 typedef struct {
163         int* algorithm_priority;
164         int algorithms;
165 } GNUTLS_Priority;
166
167 #define BulkCipherAlgorithm_Priority GNUTLS_Priority
168 #define MACAlgorithm_Priority GNUTLS_Priority
169 #define KXAlgorithm_Priority GNUTLS_Priority
170 #define CompressionMethod_Priority GNUTLS_Priority
171
172 typedef struct {
173         char*                   buffer;
174         uint32                  bufferSize;
175         char*                   hash_buffer; /* used to keep all handshake messages */
176         uint32                  hash_bufferSize;
177         char*                   buffer_handshake; /* this is a buffer that holds the current handshake message */
178         uint32                  bufferSize_handshake;
179         ResumableSession        resumable; /* TRUE or FALSE - if we can resume that session */
180         ValidSession            valid_connection; /* true or FALSE - if this session is valid */
181         AlertDescription        last_alert; /* last alert received */
182         /* this is the ciphersuite we are going to use */
183         GNUTLS_CipherSuite      current_cipher_suite;
184         /* this is the compression method we are going to use */
185         CompressionMethod       compression_method;
186         /* priorities */
187         BulkCipherAlgorithm_Priority    BulkCipherAlgorithmPriority;
188         MACAlgorithm_Priority           MACAlgorithmPriority;
189         KXAlgorithm_Priority            KXAlgorithmPriority;
190         CompressionMethod_Priority      CompressionMethodPriority;
191         /* resumed session */
192         ResumableSession        resumed; /* TRUE or FALSE - if we are resuming a session */
193         SecurityParameters  resumed_security_parameters;
194         /* For DH KX */
195         MPI                             KEY;
196         MPI                             client_Y;
197         MPI                             client_g;
198         MPI                             client_p;
199         MPI                             dh_secret;
200         int                             certificate_requested; /* non zero if client certificate was requested */
201         int                             certificate_verify_needed; /* non zero if we should expect for certificate verify */
202 } GNUTLS_INTERNALS;
203
204 typedef struct {
205         SecurityParameters security_parameters;
206         CipherSpecs cipher_specs;
207         ConnectionState connection_state;
208         GNUTLS_INTERNALS gnutls_internals;
209 } GNUTLS_STATE_INT;
210
211 typedef GNUTLS_STATE_INT *GNUTLS_STATE;
212
213
214 /* Record Protocol */
215 enum ContentType { GNUTLS_CHANGE_CIPHER_SPEC=20, GNUTLS_ALERT, GNUTLS_HANDSHAKE,
216                 GNUTLS_APPLICATION_DATA };
217 typedef enum ContentType ContentType;
218
219 typedef struct {
220         uint8 major;
221         uint8 minor;
222 } ProtocolVersion;
223
224 typedef struct {
225         uint8   type;
226         ProtocolVersion version;
227         uint16          length;
228         opaque*         fragment;
229 } GNUTLSPlaintext;
230
231 typedef struct {
232         uint8   type;
233         ProtocolVersion version;
234         uint16          length;
235         opaque*         fragment;
236 } GNUTLSCompressed;
237
238 /* This is used for both block ciphers and stream ciphers. In stream ciphers
239  * the padding is just ignored.
240  */
241 typedef struct {
242         opaque*         content;
243         opaque*         MAC;
244         uint8*          padding;
245         uint8           padding_length;
246 } GNUTLS_GenericBlockCipher;
247
248 typedef struct {
249         opaque*         content;
250         opaque*         MAC;
251 } GNUTLS_GenericStreamCipher;
252
253 typedef struct {
254         uint8           type;
255         ProtocolVersion         version;
256         uint16                  length;
257         void*                   fragment; /* points GenericStreamCipher
258                                            * or GenericBlockCipher
259                                            */
260 } GNUTLSCiphertext;
261
262
263 /* Handshake protocol */
264
265
266 typedef struct {
267         HandshakeType   msg_type;
268         uint24          length;
269         void*           body;
270 } GNUTLS_Handshake;
271
272 typedef struct {
273         uint32  gmt_unix_time;
274         opaque  random_bytes[28];
275 } GNUTLS_random;
276
277
278 typedef struct {
279         ProtocolVersion client_version;
280         GNUTLS_random           random;
281         opaque*                 session_id;
282         GNUTLS_CipherSuite*     cipher_suites;
283         CompressionMethod*      compression_methods;
284 } GNUTLS_ClientHello;
285
286 typedef struct {
287         ProtocolVersion server_version;
288         GNUTLS_random           random;
289         opaque*                 session_id;
290         GNUTLS_CipherSuite      cipher_suite;
291         CompressionMethod       compression_method;
292 } GNUTLS_ServerHello;
293
294 /* functions */
295 int _gnutls_send_alert( int cd, GNUTLS_STATE state, AlertLevel level, AlertDescription desc);
296 int gnutls_close(int cd, GNUTLS_STATE state);
297 svoid *gnutls_PRF( opaque * secret, int secret_size, uint8 * label,
298                   int label_size, opaque * seed, int seed_size,
299                   int total_bytes);
300 void gnutls_set_current_version(GNUTLS_STATE state, GNUTLS_Version version);
301 GNUTLS_Version gnutls_get_current_version(GNUTLS_STATE state);
302 int _gnutls_set_keys(GNUTLS_STATE state);
303 ssize_t gnutls_send_int(int cd, GNUTLS_STATE state, ContentType type, void* data, size_t sizeofdata);
304 ssize_t gnutls_recv_int(int cd, GNUTLS_STATE state, ContentType type, char* data, size_t sizeofdata);
305 int _gnutls_send_change_cipher_spec(int cd, GNUTLS_STATE state);
306 int _gnutls_version_cmp(GNUTLS_Version ver1, GNUTLS_Version ver2);
307 #define _gnutls_version_ssl3(x) _gnutls_version_cmp(x, GNUTLS_SSL3)
308
309 #endif /* GNUTLS_INT_H */