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
|
/*
* Copyright (C) 2010 Martin Willi
* Copyright (C) 2010 revosec AG
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*/
/**
* @defgroup libtls libtls
*
* @addtogroup libtls
* TLS implementation on top of libstrongswan
*
* @defgroup tls tls
* @{ @ingroup libtls
*/
#ifndef TLS_H_
#define TLS_H_
/**
* Maximum size of a TLS fragment
* as defined by section 6.2.1. "Fragmentation" of RFC 5246 TLS 1.2
*/
#define TLS_MAX_FRAGMENT_LEN 16384
typedef enum tls_version_t tls_version_t;
typedef enum tls_content_type_t tls_content_type_t;
typedef enum tls_handshake_type_t tls_handshake_type_t;
typedef enum tls_purpose_t tls_purpose_t;
typedef struct tls_t tls_t;
#include <library.h>
#include "tls_application.h"
#include "tls_cache.h"
/**
* TLS/SSL version numbers
*/
enum tls_version_t {
SSL_2_0 = 0x0200,
SSL_3_0 = 0x0300,
TLS_1_0 = 0x0301,
TLS_1_1 = 0x0302,
TLS_1_2 = 0x0303,
};
/**
* Enum names for tls_version_t
*/
extern enum_name_t *tls_version_names;
/**
* TLS higher level content type
*/
enum tls_content_type_t {
TLS_CHANGE_CIPHER_SPEC = 20,
TLS_ALERT = 21,
TLS_HANDSHAKE = 22,
TLS_APPLICATION_DATA = 23,
};
/**
* Enum names for tls_content_type_t
*/
extern enum_name_t *tls_content_type_names;
/**
* TLS handshake subtype
*/
enum tls_handshake_type_t {
TLS_HELLO_REQUEST = 0,
TLS_CLIENT_HELLO = 1,
TLS_SERVER_HELLO = 2,
TLS_CERTIFICATE = 11,
TLS_SERVER_KEY_EXCHANGE = 12,
TLS_CERTIFICATE_REQUEST = 13,
TLS_SERVER_HELLO_DONE = 14,
TLS_CERTIFICATE_VERIFY = 15,
TLS_CLIENT_KEY_EXCHANGE = 16,
TLS_FINISHED = 20,
};
/**
* Enum names for tls_handshake_type_t
*/
extern enum_name_t *tls_handshake_type_names;
/**
* Purpose the TLS stack is initiated for.
*/
enum tls_purpose_t {
/** authentication in EAP-TLS */
TLS_PURPOSE_EAP_TLS,
/** outer authentication and protection in EAP-TTLS */
TLS_PURPOSE_EAP_TTLS,
/** outer authentication and protection in EAP-PEAP */
TLS_PURPOSE_EAP_PEAP,
/** non-EAP TLS */
TLS_PURPOSE_GENERIC,
/** non-EAP TLS accepting NULL encryption */
TLS_PURPOSE_GENERIC_NULLOK,
/** EAP binding for TNC */
TLS_PURPOSE_EAP_TNC
};
/**
* TLS Hello extension types.
*/
enum tls_extension_t {
/** Server name the client wants to talk to */
TLS_EXT_SERVER_NAME = 0,
/** request a maximum fragment size */
TLS_EXT_MAX_FRAGMENT_LENGTH = 1,
/** indicate client certificate URL support */
TLS_EXT_CLIENT_CERTIFICATE_URL = 2,
/** list of CA the client trusts */
TLS_EXT_TRUSTED_CA_KEYS = 3,
/** request MAC truncation to 80-bit */
TLS_EXT_TRUNCATED_HMAC = 4,
/** list of OCSP responders the client trusts */
TLS_EXT_STATUS_REQUEST = 5,
/** list of supported elliptic curves */
TLS_EXT_ELLIPTIC_CURVES = 10,
/** supported point formats */
TLS_EXT_EC_POINT_FORMATS = 11,
/** list supported signature algorithms */
TLS_EXT_SIGNATURE_ALGORITHMS = 13,
/** cryptographic binding for RFC 5746 renegotiation indication */
TLS_EXT_RENEGOTIATION_INFO = 65281,
};
enum tls_name_type_t {
TLS_NAME_TYPE_HOST_NAME = 0,
};
/**
* Enum names for tls_extension_t
*/
extern enum_name_t *tls_extension_names;
/**
* A bottom-up driven TLS stack, suitable for EAP implementations.
*/
struct tls_t {
/**
* Process one or more TLS records, pass it to upper layers.
*
* @param buf TLS record data, including headers
* @param buflen number of bytes in buf to process
* @return
* - SUCCESS if TLS negotiation complete
* - FAILED if TLS handshake failed
* - NEED_MORE if more invocations to process/build needed
*/
status_t (*process)(tls_t *this, void *buf, size_t buflen);
/**
* Query upper layer for one or more TLS records, build fragments.
*
* The TLS stack automatically fragments the records to the given buffer
* size. Fragmentation is indicated by the reclen ouput parameter and
* the return value. For the first fragment of a TLS record, a non-zero
* record length is returned in reclen. If more fragments follow, NEED_MORE
* is returned. A return value of ALREADY_DONE indicates that the final
* fragment has been returned.
*
* @param buf buffer to write TLS record fragments to
* @param buflen size of buffer, receives bytes written
* @param msglen receives size of all TLS fragments
* @return
* - SUCCESS if TLS negotiation complete
* - FAILED if TLS handshake failed
* - INVALID_STATE if more input data required
* - NEED_MORE if more fragments available
* - ALREADY_DONE if the last available fragment returned
*/
status_t (*build)(tls_t *this, void *buf, size_t *buflen, size_t *msglen);
/**
* Check if TLS stack is acting as a server.
*
* @return TRUE if server, FALSE if peer
*/
bool (*is_server)(tls_t *this);
/**
* Return the server identity.
*
* @return server identity
*/
identification_t* (*get_server_id)(tls_t *this);
/**
* Set the peer identity.
*
* @param id peer identity
*/
void (*set_peer_id)(tls_t *this, identification_t *id);
/**
* Return the peer identity.
*
* @return peer identity
*/
identification_t* (*get_peer_id)(tls_t *this);
/**
* Get the negotiated TLS/SSL version.
*
* @return negotiated TLS version
*/
tls_version_t (*get_version)(tls_t *this);
/**
* Set the negotiated TLS/SSL version.
*
* @param version negotiated TLS version
* @return TRUE if version acceptable
*/
bool (*set_version)(tls_t *this, tls_version_t version);
/**
* Get the purpose of this TLS stack instance.
*
* @return purpose given during construction
*/
tls_purpose_t (*get_purpose)(tls_t *this);
/**
* Check if TLS negotiation completed successfully.
*
* @return TRUE if TLS negotiation and authentication complete
*/
bool (*is_complete)(tls_t *this);
/**
* Get the MSK for EAP-TLS.
*
* @return MSK, internal data
*/
chunk_t (*get_eap_msk)(tls_t *this);
/**
* Get the authentication details after completing the handshake.
*
* @return authentication details, internal data
*/
auth_cfg_t* (*get_auth)(tls_t *this);
/**
* Destroy a tls_t.
*/
void (*destroy)(tls_t *this);
};
/**
* Dummy libtls initialization function needed for integrity test
*/
void libtls_init(void);
/**
* Create a tls instance.
*
* @param is_server TRUE to act as server, FALSE for client
* @param server server identity
* @param peer peer identity, NULL for no client authentication
* @param purpose purpose this TLS stack instance is used for
* @param application higher layer application or NULL if none
* @param cache session cache to use, or NULL
* @return TLS stack
*/
tls_t *tls_create(bool is_server, identification_t *server,
identification_t *peer, tls_purpose_t purpose,
tls_application_t *application, tls_cache_t *cache);
#endif /** TLS_H_ @}*/
|