75c53ba3b77719f75aaa89c208826661a50537cc
[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 } EAP_TLS_CONF;
203
204
205 /* This structure gets stored in arg */
206 typedef struct _eap_tls_t {
207         EAP_TLS_CONF    *conf;
208         SSL_CTX         *ctx;
209 } eap_tls_t;
210
211
212 /* EAP-TLS framework */
213 EAPTLS_PACKET   *eaptls_alloc(void);
214 void            eaptls_free(EAPTLS_PACKET **eaptls_packet_ptr);
215 int             eaptls_start(EAP_DS *eap_ds, int peap);
216 int             eaptls_compose(EAP_DS *eap_ds, EAPTLS_PACKET *reply);
217
218 /* Callbacks */
219 int             cbtls_password(char *buf, int num, int rwflag, void *userdata);
220 void            cbtls_info(const SSL *s, int where, int ret);
221 int             cbtls_verify(int ok, X509_STORE_CTX *ctx);
222 void            cbtls_msg(int write_p, int msg_version, int content_type,
223                         const void *buf, size_t len, SSL *ssl, void *arg);
224 RSA             *cbtls_rsa(SSL *s, int is_export, int keylength);
225
226 /* TLS */
227 tls_session_t   *eaptls_new_session(SSL_CTX *ssl_ctx, int client_cert);
228 int             tls_handshake_recv(tls_session_t *ssn);
229 int             tls_handshake_send(tls_session_t *ssn);
230 void            tls_session_information(tls_session_t *tls_session);
231
232 /* Session */
233 void            session_free(void *ssn);
234 void            session_close(tls_session_t *ssn);
235 void            session_init(tls_session_t *ssn);
236
237 /* record */
238 void            record_init(record_t *buf);
239 void            record_close(record_t *buf);
240 unsigned int    record_plus(record_t *buf, const unsigned char *ptr, 
241                             unsigned int size);
242 unsigned int    record_minus(record_t *buf, unsigned char *ptr, 
243                              unsigned int size);
244 #endif /*_EAP_TLS_H*/