backport from HEAD
[freeradius.git] / src / modules / rlm_eap / types / rlm_eap_tls / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * Copyright 2001  hereUare Communications, Inc. <raghud@hereuare.com>
21  * Copyright 2003  Alan DeKok <aland@freeradius.org>
22  */
23 #ifndef _EAP_TLS_H
24 #define _EAP_TLS_H
25
26 #include "rlm_eap_tls.h"
27
28 #define BUFFER_SIZE 1024
29
30 #define EAP_TLS_START           1
31 #define EAP_TLS_ACK             2
32 #define EAP_TLS_SUCCESS         3
33 #define EAP_TLS_FAIL            4
34 #define EAP_TLS_ALERT           9
35
36 #define TLS_HEADER_LEN          4
37
38 /*
39  *      RFC 2716, Section 4.2:
40  *
41  *         Flags
42  *
43  *      0 1 2 3 4 5 6 7 8
44  *      +-+-+-+-+-+-+-+-+
45  *      |L M S R R R R R|
46  *      +-+-+-+-+-+-+-+-+
47  *
48  *      L = Length included
49  *      M = More fragments
50  *      S = EAP-TLS start
51  *      R = Reserved
52  */
53 #define TLS_START(x)            (((x) & 0x20) != 0)
54 #define TLS_MORE_FRAGMENTS(x)   (((x) & 0x40) != 0)
55 #define TLS_LENGTH_INCLUDED(x)  (((x) & 0x80) != 0)
56
57 #define TLS_CHANGE_CIPHER_SPEC(x)       (((x) & 0x0014) == 0x0014)
58 #define TLS_ALERT(x)                    (((x) & 0x0015) == 0x0015)
59 #define TLS_HANDSHAKE(x)                (((x) & 0x0016) == 0x0016)
60
61 #define SET_START(x)            ((x) | (0x20))
62 #define SET_MORE_FRAGMENTS(x)   ((x) | (0x40))
63 #define SET_LENGTH_INCLUDED(x)  ((x) | (0x80))
64
65
66 /*
67  *      Following enums from rfc2246
68  *
69  *      Hmm... since we dpeend on OpenSSL, it would be smarter to
70  *      use the OpenSSL names for these.
71  */
72 enum ContentType {
73         change_cipher_spec = 20,
74         alert = 21,
75         handshake = 22,
76         application_data = 23
77 };
78
79 enum AlertLevel {
80         warning = 1,
81         fatal = 2
82 };
83
84 enum AlertDescription {
85         close_notify = 0,
86         unexpected_message = 10,
87         bad_record_mac = 20,
88         decryption_failed = 21,
89         record_overflow = 22,
90         decompression_failure = 30,
91         handshake_failure = 40,
92         bad_certificate = 42,
93         unsupported_certificate = 43,
94         certificate_revoked = 44,
95         certificate_expired = 45,
96         certificate_unknown = 46,
97         illegal_parameter = 47,
98         unknown_ca = 48,
99         access_denied = 49,
100         decode_error = 50,
101         decrypt_error = 51,
102         export_restriction = 60,
103         protocol_version = 70,
104         insufficient_security = 71,
105         internal_error = 80,
106         user_canceled = 90,
107         no_renegotiation = 100
108 };
109
110 enum HandshakeType {
111         hello_request = 0,
112         client_hello = 1,
113         server_hello = 2,
114         certificate = 11,
115         server_key_exchange  = 12,
116         certificate_request = 13,
117         server_hello_done = 14,
118         certificate_verify = 15,
119         client_key_exchange = 16,
120         finished = 20
121 };
122
123
124 /*
125  * From rfc
126    Flags
127
128       0 1 2 3 4 5 6 7 8
129       +-+-+-+-+-+-+-+-+
130       |L M S R R R R R|
131       +-+-+-+-+-+-+-+-+
132
133       L = Length included
134       M = More fragments
135       S = EAP-TLS start
136       R = Reserved
137
138       The L bit (length included) is set to indicate the presence of the
139       four octet TLS Message Length field, and MUST be set for the first
140       fragment of a fragmented TLS message or set of messages. The M bit
141       (more fragments) is set on all but the last fragment. The S bit
142       (EAP-TLS start) is set in an EAP-TLS Start message.  This
143       differentiates the EAP-TLS Start message from a fragment
144       acknowledgement.
145
146    TLS Message Length
147
148       The TLS Message Length field is four octets, and is present only
149       if the L bit is set. This field provides the total length of the
150       TLS message or set of messages that is being fragmented.
151
152    TLS data
153
154       The TLS data consists of the encapsulated TLS packet in TLS record
155       format.
156  *
157  * The data structures present here
158  * maps only to the typedata in the EAP packet
159  *
160  * Based on the L bit flag, first 4 bytes of data indicate the length
161  */
162 typedef struct tls_packet_t {
163         uint8_t         flags;
164         uint8_t         data[1];
165 } eaptls_packet_t;
166
167 typedef struct tls_packet {
168         uint8_t         code;
169         uint8_t         id;
170         uint32_t        length;
171         uint8_t         flags;
172         uint8_t         *data;
173         uint32_t        dlen;
174
175         //uint8_t               *packet;  /* Wired EAP-TLS packet as found in typdedata of EAP_PACKET */
176 } EAPTLS_PACKET;
177
178
179 /* configured values goes right here */
180 typedef struct eap_tls_conf {
181         char            *private_key_password;
182         char            *private_key_file;
183         char            *certificate_file;
184         char            *random_file;
185         char            *ca_path;
186         char            *ca_file;
187         char            *dh_file;
188         char            *rsa_file;
189         int             rsa_key;
190         int             dh_key;
191         int             rsa_key_length;
192         int             dh_key_length;
193         int             verify_depth;
194         int             file_type;
195         int             include_length;
196
197         /*
198          *      Always < 4096 (due to radius limit), 0 by default = 2048
199          */
200         int             fragment_size;
201         int             check_crl;
202         char            *check_cert_cn;
203 } EAP_TLS_CONF;
204
205
206 /* This structure gets stored in arg */
207 typedef struct _eap_tls_t {
208         EAP_TLS_CONF    *conf;
209         SSL_CTX         *ctx;
210 } eap_tls_t;
211
212
213 /* EAP-TLS framework */
214 EAPTLS_PACKET   *eaptls_alloc(void);
215 void            eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr);
216 int             eaptls_start(EAP_DS *eap_ds, int peap);
217 int             eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply);
218
219 /* Callbacks */
220 int             cbtls_password(char *buf, int num, int rwflag, void *userdata);
221 void            cbtls_info(const SSL *s, int where, int ret);
222 int             cbtls_verify(int ok, X509_STORE_CTX *ctx);
223 void            cbtls_msg(int write_p, int msg_version, int content_type,
224                         const void *buf, size_t len, SSL *ssl, void *arg);
225 RSA             *cbtls_rsa(SSL *s, int is_export, int keylength);
226
227 /* TLS */
228 tls_session_t   *eaptls_new_session(SSL_CTX *ssl_ctx, int client_cert);
229 int             tls_handshake_recv(tls_session_t *ssn);
230 int             tls_handshake_send(tls_session_t *ssn);
231 void            tls_session_information(tls_session_t *tls_session);
232
233 /* Session */
234 void            session_free(void *ssn);
235 void            session_close(tls_session_t *ssn);
236 void            session_init(tls_session_t *ssn);
237
238 /* record */
239 void            record_init(record_t *buf);
240 void            record_close(record_t *buf);
241 unsigned int    record_plus(record_t *buf, const unsigned char *ptr,
242                             unsigned int size);
243 unsigned int    record_minus(record_t *buf, unsigned char *ptr,
244                              unsigned int size);
245 #endif /*_EAP_TLS_H*/