Put SSL errors into Module-Failure-Message
[freeradius.git] / src / modules / rlm_eap / libeap / eap_tls.h
1 /*
2  * eap_tls.h
3  *
4  * Version:     $Id$
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
21  * Copyright 2003  Alan DeKok <aland@freeradius.org>
22  * Copyright 2006  The FreeRADIUS server project
23  */
24 #ifndef _EAP_TLS_H
25 #define _EAP_TLS_H
26
27 #include <freeradius-devel/ident.h>
28 RCSIDH(eap_tls_h, "$Id$")
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <netinet/tcp.h>
38 #include <netdb.h>
39 #include <fcntl.h>
40 #include <signal.h>
41
42 #include <ctype.h>
43 #include <sys/time.h>
44 #include <arpa/inet.h>
45
46 #ifdef HAVE_LIMITS_H
47 #include <limits.h>
48 #endif
49
50 #ifdef HAVE_UNISTD_H
51 #include <unistd.h>
52 #endif
53
54 #ifndef NO_OPENSSL
55 /*
56  *      For RH 9, which apparently needs this.
57  */
58 #ifndef OPENSSL_NO_KRB5
59 #define OPENSSL_NO_KRB5
60 #endif
61 #include <openssl/err.h>
62 #ifdef HAVE_OPENSSL_ENGINE_H
63 #include <openssl/engine.h>
64 #endif
65 #include <openssl/ssl.h>
66 #endif /* !defined(NO_OPENSSL) */
67
68 #include "eap.h"
69
70 typedef enum {
71         EAPTLS_INVALID = 0,             /* invalid, don't reply */
72         EAPTLS_REQUEST,                 /* request, ok to send, invalid to receive */
73         EAPTLS_RESPONSE,                /* response, ok to receive, invalid to send */
74         EAPTLS_SUCCESS,                 /* success, send success */
75         EAPTLS_FAIL,                    /* fail, send fail */
76         EAPTLS_NOOP,                    /* noop, continue */
77
78         EAPTLS_START,                   /* start, ok to send, invalid to receive */
79         EAPTLS_OK,                      /* ok, continue */
80         EAPTLS_ACK,                     /* acknowledge, continue */
81         EAPTLS_FIRST_FRAGMENT,          /* first fragment */
82         EAPTLS_MORE_FRAGMENTS,          /* more fragments, to send/receive */
83         EAPTLS_LENGTH_INCLUDED,                 /* length included */
84         EAPTLS_MORE_FRAGMENTS_WITH_LENGTH,   /* more fragments with length */
85         EAPTLS_HANDLED                  /* tls code has handled it */
86 } eaptls_status_t;
87
88 #define MAX_RECORD_SIZE 16384
89
90 /*
91  *      A single TLS record may be up to 16384 octets in length, but a
92  *      TLS message may span multiple TLS records, and a TLS
93  *      certificate message may in principle be as long as 16MB.
94  *
95  *      However, note that in order to protect against reassembly
96  *      lockup and denial of service attacks, it may be desirable for
97  *      an implementation to set a maximum size for one such group of
98  *      TLS messages.
99  *
100  *      The TLS Message Length field is four octets, and provides the
101  *      total length of the TLS message or set of messages that is
102  *      being fragmented; this simplifies buffer allocation.
103  */
104
105 /*
106  * FIXME: Dynamic allocation of buffer to overcome MAX_RECORD_SIZE overflows.
107  *      or configure TLS not to exceed MAX_RECORD_SIZE.
108  */
109 typedef struct _record_t {
110         unsigned char data[MAX_RECORD_SIZE];
111         unsigned int  used;
112 } record_t;
113
114 typedef struct _tls_info_t {
115         unsigned char   origin;
116         unsigned char   content_type;
117         unsigned char   handshake_type;
118         unsigned char   alert_level;
119         unsigned char   alert_description;
120         char            info_description[256];
121         size_t          record_len;
122         int             version;
123         char            initialized;
124 } tls_info_t;
125
126 /*
127  * tls_session_t Structure gets stored as opaque in EAP_HANDLER
128  * This contains EAP-REQUEST specific data
129  * (ie EAPTLS_DATA(fragment), EAPTLS-ALERT, EAPTLS-REQUEST ...)
130  *
131  * clean_in  - data that needs to be sent but only after it is soiled.
132  * dirty_in  - data EAP server receives.
133  * clean_out - data that is cleaned after receiving.
134  * dirty_out - data EAP server sends.
135  * offset    - current fragment size transmitted
136  * fragment  - Flag, In fragment mode or not.
137  * tls_msg_len - Actual/Total TLS message length.
138  * length_flag - A flag to include length in every TLS Data/Alert packet
139  *                                      if set to no then only the first fragment contains length
140  */
141 typedef struct _tls_session_t {
142         SSL_CTX         *ctx;
143         SSL             *ssl;
144         tls_info_t      info;
145
146         BIO             *into_ssl;
147         BIO             *from_ssl;
148         record_t        clean_in;
149         record_t        clean_out;
150         record_t        dirty_in;
151         record_t        dirty_out;
152
153         void            (*record_init)(record_t *buf);
154         void            (*record_close)(record_t *buf);
155         unsigned int    (*record_plus)(record_t *buf, const void *ptr,
156                                        unsigned int size);
157         unsigned int    (*record_minus)(record_t *buf, void *ptr,
158                                         unsigned int size);
159
160
161         /*
162          * Framed-MTU attribute in RADIUS,
163          * if present, can also be used to set this
164          */
165         unsigned int    offset;
166         unsigned int    tls_msg_len;
167         int             fragment;
168         int             length_flag;
169         int             peap_flag;
170
171         /*
172          *      Used by TTLS & PEAP to keep track of other per-session
173          *      data.
174          */
175         void            *opaque;
176         void            (*free_opaque)(void *opaque);
177
178         const char      *prf_label;
179         int             allow_session_resumption;
180 } tls_session_t;
181
182
183 /*
184  *      Externally exported TLS functions.
185  */
186 eaptls_status_t eaptls_process(EAP_HANDLER *handler);
187
188 int             eaptls_success(EAP_HANDLER *handler, int peap_flag);
189 int             eaptls_fail(EAP_HANDLER *handler, int peap_flag);
190 int             eaptls_request(EAP_DS *eap_ds, tls_session_t *ssn);
191
192
193 /* MPPE key generation */
194 void            eaptls_gen_mppe_keys(VALUE_PAIR **reply_vps, SSL *s,
195                                      const char *prf_label);
196 void            eapttls_gen_challenge(SSL *s, uint8_t *buffer, size_t size);
197
198 #define BUFFER_SIZE 1024
199
200 #define EAP_TLS_START           1
201 #define EAP_TLS_ACK             2
202 #define EAP_TLS_SUCCESS         3
203 #define EAP_TLS_FAIL            4
204 #define EAP_TLS_ALERT           9
205
206 #define TLS_HEADER_LEN          4
207
208 /*
209  *      RFC 2716, Section 4.2:
210  *
211  *         Flags
212  *
213  *      0 1 2 3 4 5 6 7 8
214  *      +-+-+-+-+-+-+-+-+
215  *      |L M S R R R R R|
216  *      +-+-+-+-+-+-+-+-+
217  *
218  *      L = Length included
219  *      M = More fragments
220  *      S = EAP-TLS start
221  *      R = Reserved
222  */
223 #define TLS_START(x)            (((x) & 0x20) != 0)
224 #define TLS_MORE_FRAGMENTS(x)   (((x) & 0x40) != 0)
225 #define TLS_LENGTH_INCLUDED(x)  (((x) & 0x80) != 0)
226
227 #define TLS_CHANGE_CIPHER_SPEC(x)       (((x) & 0x0014) == 0x0014)
228 #define TLS_ALERT(x)                    (((x) & 0x0015) == 0x0015)
229 #define TLS_HANDSHAKE(x)                (((x) & 0x0016) == 0x0016)
230
231 #define SET_START(x)            ((x) | (0x20))
232 #define SET_MORE_FRAGMENTS(x)   ((x) | (0x40))
233 #define SET_LENGTH_INCLUDED(x)  ((x) | (0x80))
234
235 /*
236  *      Following enums from rfc2246
237  *
238  *      Hmm... since we dpeend on OpenSSL, it would be smarter to
239  *      use the OpenSSL names for these.
240  */
241 enum ContentType {
242         change_cipher_spec = 20,
243         alert = 21,
244         handshake = 22,
245         application_data = 23
246 };
247
248 enum AlertLevel {
249         warning = 1,
250         fatal = 2
251 };
252
253 enum AlertDescription {
254         close_notify = 0,
255         unexpected_message = 10,
256         bad_record_mac = 20,
257         decryption_failed = 21,
258         record_overflow = 22,
259         decompression_failure = 30,
260         handshake_failure = 40,
261         bad_certificate = 42,
262         unsupported_certificate = 43,
263         certificate_revoked = 44,
264         certificate_expired = 45,
265         certificate_unknown = 46,
266         illegal_parameter = 47,
267         unknown_ca = 48,
268         access_denied = 49,
269         decode_error = 50,
270         decrypt_error = 51,
271         export_restriction = 60,
272         protocol_version = 70,
273         insufficient_security = 71,
274         internal_error = 80,
275         user_canceled = 90,
276         no_renegotiation = 100
277 };
278
279 enum HandshakeType {
280         hello_request = 0,
281         client_hello = 1,
282         server_hello = 2,
283         certificate = 11,
284         server_key_exchange  = 12,
285         certificate_request = 13,
286         server_hello_done = 14,
287         certificate_verify = 15,
288         client_key_exchange = 16,
289         finished = 20
290 };
291
292
293 /*
294  * From rfc
295    Flags
296
297       0 1 2 3 4 5 6 7 8
298       +-+-+-+-+-+-+-+-+
299       |L M S R R R R R|
300       +-+-+-+-+-+-+-+-+
301
302       L = Length included
303       M = More fragments
304       S = EAP-TLS start
305       R = Reserved
306
307       The L bit (length included) is set to indicate the presence of the
308       four octet TLS Message Length field, and MUST be set for the first
309       fragment of a fragmented TLS message or set of messages. The M bit
310       (more fragments) is set on all but the last fragment. The S bit
311       (EAP-TLS start) is set in an EAP-TLS Start message.  This
312       differentiates the EAP-TLS Start message from a fragment
313       acknowledgement.
314
315    TLS Message Length
316
317       The TLS Message Length field is four octets, and is present only
318       if the L bit is set. This field provides the total length of the
319       TLS message or set of messages that is being fragmented.
320
321    TLS data
322
323       The TLS data consists of the encapsulated TLS packet in TLS record
324       format.
325  *
326  * The data structures present here
327  * maps only to the typedata in the EAP packet
328  *
329  * Based on the L bit flag, first 4 bytes of data indicate the length
330  */
331 typedef struct tls_packet_t {
332         uint8_t         flags;
333         uint8_t         data[1];
334 } eaptls_packet_t;
335
336 typedef struct tls_packet {
337         uint8_t         code;
338         uint8_t         id;
339         uint32_t        length;
340         uint8_t         flags;
341         uint8_t         *data;
342         uint32_t        dlen;
343
344         //uint8_t               *packet;  /* Wired EAP-TLS packet as found in typdedata of EAP_PACKET */
345 } EAPTLS_PACKET;
346
347
348 /* EAP-TLS framework */
349 EAPTLS_PACKET   *eaptls_alloc(void);
350 void            eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr);
351 int             eaptls_start(EAP_DS *eap_ds, int peap);
352 int             eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply);
353
354 /* Callbacks */
355 int             cbtls_password(char *buf, int num, int rwflag, void *userdata);
356 void            cbtls_info(const SSL *s, int where, int ret);
357 void            cbtls_msg(int write_p, int msg_version, int content_type,
358                         const void *buf, size_t len, SSL *ssl, void *arg);
359
360 /* TLS */
361 tls_session_t   *eaptls_new_session(SSL_CTX *ssl_ctx, int client_cert);
362 int             tls_handshake_recv(REQUEST *, tls_session_t *ssn);
363 int             tls_handshake_send(REQUEST *,tls_session_t *ssn);
364 void            tls_session_information(tls_session_t *tls_session);
365
366 /* Session */
367 void            session_free(void *ssn);
368 void            session_close(tls_session_t *ssn);
369 void            session_init(tls_session_t *ssn);
370
371 /* SSL Indicies for ex data */
372 extern int      eaptls_handle_idx;
373 extern int      eaptls_conf_idx;
374 extern int      eaptls_session_idx;
375
376 #endif /*_EAP_TLS_H*/