~ubuntu-branches/ubuntu/utopic/freeradius/utopic

« back to all changes in this revision

Viewing changes to src/modules/rlm_eap/libeap/eap_tls.h

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2006-12-16 20:45:11 UTC
  • mfrom: (3.1.10 feisty)
  • Revision ID: james.westby@ubuntu.com-20061216204511-3pbbsu4s8jtehsor
Tags: 1.1.3-3
Fix POSIX compliance problem in init script.  Closes: #403384. 

Show diffs side-by-side

added added

removed removed

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