/[smeserver]/rpms/openssl/sme8/openssl-fips-0.9.8e-dtls-fixes.patch
ViewVC logotype

Contents of /rpms/openssl/sme8/openssl-fips-0.9.8e-dtls-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Tue Feb 18 03:03:09 2014 UTC (10 years, 8 months ago) by wellsi
Branch: MAIN
CVS Tags: openssl-0_9_8e-28_el5_sme, openssl-0_9_8e-33_1_el5_sme, openssl-0_9_8e-32_1_el5_sme, openssl-0_9_8e-27_1_el5_sme, openssl-0_9_8e-27_el5_10_1, openssl-0_9_8e-31_1_el5_sme, HEAD
Branch point for: upstream
Initial import

1 diff -up openssl-fips-0.9.8f-dev/ssl/dtls1.h.dtls-fixes openssl-fips-0.9.8f-dev/ssl/dtls1.h
2 --- openssl-fips-0.9.8f-dev/ssl/dtls1.h.dtls-fixes 2008-07-15 21:01:29.000000000 +0200
3 +++ openssl-fips-0.9.8f-dev/ssl/dtls1.h 2008-07-15 21:01:29.000000000 +0200
4 @@ -67,9 +67,8 @@
5 extern "C" {
6 #endif
7
8 -#define DTLS1_VERSION 0x0100
9 -#define DTLS1_VERSION_MAJOR 0x01
10 -#define DTLS1_VERSION_MINOR 0x00
11 +#define DTLS1_VERSION 0xFEFF
12 +#define DTLS1_BAD_VER 0x0100
13
14 #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110
15
16 @@ -83,7 +82,7 @@ extern "C" {
17 #define DTLS1_HM_BAD_FRAGMENT -2
18 #define DTLS1_HM_FRAGMENT_RETRY -3
19
20 -#define DTLS1_CCS_HEADER_LENGTH 3
21 +#define DTLS1_CCS_HEADER_LENGTH 1
22
23 #define DTLS1_AL_HEADER_LENGTH 7
24
25 diff -up openssl-fips-0.9.8f-dev/ssl/d1_lib.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_lib.c
26 --- openssl-fips-0.9.8f-dev/ssl/d1_lib.c.dtls-fixes 2007-01-21 17:07:25.000000000 +0100
27 +++ openssl-fips-0.9.8f-dev/ssl/d1_lib.c 2008-07-15 21:01:29.000000000 +0200
28 @@ -188,3 +188,23 @@ void dtls1_clear(SSL *s)
29 ssl3_clear(s);
30 s->version=DTLS1_VERSION;
31 }
32 +
33 +/*
34 + * As it's impossible to use stream ciphers in "datagram" mode, this
35 + * simple filter is designed to disengage them in DTLS. Unfortunately
36 + * there is no universal way to identify stream SSL_CIPHER, so we have
37 + * to explicitly list their SSL_* codes. Currently RC4 is the only one
38 + * available, but if new ones emerge, they will have to be added...
39 + */
40 +SSL_CIPHER *dtls1_get_cipher(unsigned int u)
41 + {
42 + SSL_CIPHER *ciph = ssl3_get_cipher(u);
43 +
44 + if (ciph != NULL)
45 + {
46 + if ((ciph->algorithms&SSL_ENC_MASK) == SSL_RC4)
47 + return NULL;
48 + }
49 +
50 + return ciph;
51 + }
52 diff -up openssl-fips-0.9.8f-dev/ssl/d1_srvr.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_srvr.c
53 --- openssl-fips-0.9.8f-dev/ssl/d1_srvr.c.dtls-fixes 2007-09-19 02:02:49.000000000 +0200
54 +++ openssl-fips-0.9.8f-dev/ssl/d1_srvr.c 2008-07-15 21:01:29.000000000 +0200
55 @@ -285,6 +285,10 @@ int dtls1_accept(SSL *s)
56 s->d1->send_cookie = 0;
57 s->state=SSL3_ST_SW_FLUSH;
58 s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A;
59 +
60 + /* HelloVerifyRequests resets Finished MAC */
61 + if (s->client_version != DTLS1_BAD_VER)
62 + ssl3_init_finished_mac(s);
63 break;
64
65 case SSL3_ST_SW_SRVR_HELLO_A:
66 @@ -620,10 +624,13 @@ int dtls1_send_hello_verify_request(SSL
67 buf = (unsigned char *)s->init_buf->data;
68
69 msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
70 - *(p++) = s->version >> 8;
71 - *(p++) = s->version & 0xFF;
72 + if (s->client_version == DTLS1_BAD_VER)
73 + *(p++) = DTLS1_BAD_VER>>8,
74 + *(p++) = DTLS1_BAD_VER&0xff;
75 + else
76 + *(p++) = s->version >> 8,
77 + *(p++) = s->version & 0xFF;
78
79 - *(p++) = (unsigned char) s->d1->cookie_len;
80 if ( s->ctx->app_gen_cookie_cb != NULL &&
81 s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
82 &(s->d1->cookie_len)) == 0)
83 @@ -634,6 +641,7 @@ int dtls1_send_hello_verify_request(SSL
84 /* else the cookie is assumed to have
85 * been initialized by the application */
86
87 + *(p++) = (unsigned char) s->d1->cookie_len;
88 memcpy(p, s->d1->cookie, s->d1->cookie_len);
89 p += s->d1->cookie_len;
90 msg_len = p - msg;
91 @@ -672,8 +680,12 @@ int dtls1_send_server_hello(SSL *s)
92 /* Do the message type and length last */
93 d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);
94
95 - *(p++)=s->version>>8;
96 - *(p++)=s->version&0xff;
97 + if (s->client_version == DTLS1_BAD_VER)
98 + *(p++)=DTLS1_BAD_VER>>8,
99 + *(p++)=DTLS1_BAD_VER&0xff;
100 + else
101 + *(p++)=s->version>>8,
102 + *(p++)=s->version&0xff;
103
104 /* Random stuff */
105 memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
106 diff -up openssl-fips-0.9.8f-dev/ssl/s3_srvr.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/s3_srvr.c
107 --- openssl-fips-0.9.8f-dev/ssl/s3_srvr.c.dtls-fixes 2007-03-22 01:39:14.000000000 +0100
108 +++ openssl-fips-0.9.8f-dev/ssl/s3_srvr.c 2008-07-15 21:01:29.000000000 +0200
109 @@ -699,7 +699,8 @@ int ssl3_get_client_hello(SSL *s)
110 s->client_version=(((int)p[0])<<8)|(int)p[1];
111 p+=2;
112
113 - if (s->client_version < s->version)
114 + if ((s->version == DTLS1_VERSION && s->client_version > s->version) ||
115 + (s->version != DTLS1_VERSION && s->client_version < s->version))
116 {
117 SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
118 if ((s->client_version>>8) == SSL3_VERSION_MAJOR)
119 @@ -750,7 +751,7 @@ int ssl3_get_client_hello(SSL *s)
120
121 p+=j;
122
123 - if (SSL_version(s) == DTLS1_VERSION)
124 + if (s->version == DTLS1_VERSION)
125 {
126 /* cookie stuff */
127 cookie_len = *(p++);
128 @@ -1713,8 +1714,9 @@ int ssl3_get_client_key_exchange(SSL *s)
129 rsa=pkey->pkey.rsa;
130 }
131
132 - /* TLS */
133 - if (s->version > SSL3_VERSION)
134 + /* TLS and [incidentally] DTLS, including pre-0.9.8f */
135 + if (s->version > SSL3_VERSION &&
136 + s->client_version != DTLS1_BAD_VER)
137 {
138 n2s(p,i);
139 if (n != i+2)
140 diff -up openssl-fips-0.9.8f-dev/ssl/ssl_locl.h.dtls-fixes openssl-fips-0.9.8f-dev/ssl/ssl_locl.h
141 --- openssl-fips-0.9.8f-dev/ssl/ssl_locl.h.dtls-fixes 2008-07-15 21:01:29.000000000 +0200
142 +++ openssl-fips-0.9.8f-dev/ssl/ssl_locl.h 2008-07-15 21:01:29.000000000 +0200
143 @@ -680,7 +680,7 @@ SSL_METHOD *func_name(void) \
144 ssl3_put_cipher_by_char, \
145 ssl3_pending, \
146 ssl3_num_ciphers, \
147 - ssl3_get_cipher, \
148 + dtls1_get_cipher, \
149 s_get_meth, \
150 dtls1_default_timeout, \
151 &DTLSv1_enc_data, \
152 @@ -845,6 +845,8 @@ void dtls1_get_message_header(unsigned c
153 void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
154 void dtls1_reset_seq_numbers(SSL *s, int rw);
155 long dtls1_default_timeout(void);
156 +SSL_CIPHER *dtls1_get_cipher(unsigned int u);
157 +
158
159
160 /* some client-only functions */
161 diff -up openssl-fips-0.9.8f-dev/ssl/t1_enc.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/t1_enc.c
162 --- openssl-fips-0.9.8f-dev/ssl/t1_enc.c.dtls-fixes 2007-03-22 01:39:15.000000000 +0100
163 +++ openssl-fips-0.9.8f-dev/ssl/t1_enc.c 2008-07-15 21:01:29.000000000 +0200
164 @@ -740,15 +740,35 @@ int tls1_mac(SSL *ssl, unsigned char *md
165 md_size=EVP_MD_size(hash);
166
167 buf[0]=rec->type;
168 - buf[1]=TLS1_VERSION_MAJOR;
169 - buf[2]=TLS1_VERSION_MINOR;
170 + if (ssl->version == DTLS1_VERSION && ssl->client_version == DTLS1_BAD_VER)
171 + {
172 + buf[1]=TLS1_VERSION_MAJOR;
173 + buf[2]=TLS1_VERSION_MINOR;
174 + }
175 + else {
176 + buf[1]=(unsigned char)(ssl->version>>8);
177 + buf[2]=(unsigned char)(ssl->version);
178 + }
179 +
180 buf[3]=rec->length>>8;
181 buf[4]=rec->length&0xff;
182
183 /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
184 HMAC_CTX_init(&hmac);
185 HMAC_Init_ex(&hmac,mac_sec,EVP_MD_size(hash),hash,NULL);
186 - HMAC_Update(&hmac,seq,8);
187 +
188 + if (ssl->version == DTLS1_VERSION && ssl->client_version != DTLS1_BAD_VER)
189 + {
190 + unsigned char dtlsseq[8],*p=dtlsseq;
191 +
192 + s2n(send?ssl->d1->w_epoch:ssl->d1->r_epoch, p);
193 + memcpy (p,&seq[2],6);
194 +
195 + HMAC_Update(&hmac,dtlsseq,8);
196 + }
197 + else
198 + HMAC_Update(&hmac,seq,8);
199 +
200 HMAC_Update(&hmac,buf,5);
201 HMAC_Update(&hmac,rec->input,rec->length);
202 HMAC_Final(&hmac,md,&md_size);
203 @@ -765,8 +785,8 @@ printf("rec=");
204 {unsigned int z; for (z=0; z<rec->length; z++) printf("%02X ",buf[z]); printf("\n"); }
205 #endif
206
207 - if ( SSL_version(ssl) != DTLS1_VERSION)
208 - {
209 + if ( SSL_version(ssl) != DTLS1_VERSION)
210 + {
211 for (i=7; i>=0; i--)
212 {
213 ++seq[i];
214 diff -up openssl-fips-0.9.8f-dev/ssl/ssl.h.dtls-fixes openssl-fips-0.9.8f-dev/ssl/ssl.h
215 --- openssl-fips-0.9.8f-dev/ssl/ssl.h.dtls-fixes 2008-07-15 21:01:29.000000000 +0200
216 +++ openssl-fips-0.9.8f-dev/ssl/ssl.h 2008-07-15 21:01:29.000000000 +0200
217 @@ -1554,6 +1554,7 @@ void ERR_load_SSL_strings(void);
218 #define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253
219 #define SSL_F_DTLS1_GET_RECORD 254
220 #define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255
221 +#define SSL_F_DTLS1_PREPROCESS_FRAGMENT 277
222 #define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256
223 #define SSL_F_DTLS1_PROCESS_RECORD 257
224 #define SSL_F_DTLS1_READ_BYTES 258
225 diff -up openssl-fips-0.9.8f-dev/ssl/d1_pkt.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_pkt.c
226 --- openssl-fips-0.9.8f-dev/ssl/d1_pkt.c.dtls-fixes 2006-11-29 15:45:13.000000000 +0100
227 +++ openssl-fips-0.9.8f-dev/ssl/d1_pkt.c 2008-07-15 21:01:29.000000000 +0200
228 @@ -120,6 +120,7 @@
229 #include <openssl/evp.h>
230 #include <openssl/buffer.h>
231 #include <openssl/pqueue.h>
232 +#include <openssl/rand.h>
233
234 static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
235 int len, int peek);
236 @@ -486,9 +487,9 @@ int dtls1_get_record(SSL *s)
237 SSL3_RECORD *rr;
238 SSL_SESSION *sess;
239 unsigned char *p;
240 - short version;
241 + unsigned short version;
242 DTLS1_BITMAP *bitmap;
243 - unsigned int is_next_epoch;
244 + unsigned int is_next_epoch;
245
246 rr= &(s->s3->rrec);
247 sess=s->session;
248 @@ -524,7 +525,7 @@ again:
249 ssl_minor= *(p++);
250 version=(ssl_major<<8)|ssl_minor;
251
252 - /* sequence number is 64 bits, with top 2 bytes = epoch */
253 + /* sequence number is 64 bits, with top 2 bytes = epoch */
254 n2s(p,rr->epoch);
255
256 memcpy(&(s->s3->read_sequence[2]), p, 6);
257 @@ -535,7 +536,7 @@ again:
258 /* Lets check version */
259 if (!s->first_packet)
260 {
261 - if (version != s->version)
262 + if (version != s->version && version != DTLS1_BAD_VER)
263 {
264 SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
265 /* Send back error using their
266 @@ -546,7 +547,8 @@ again:
267 }
268 }
269
270 - if ((version & 0xff00) != (DTLS1_VERSION & 0xff00))
271 + if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
272 + (version & 0xff00) != (DTLS1_BAD_VER & 0xff00))
273 {
274 SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER);
275 goto err;
276 @@ -559,6 +561,7 @@ again:
277 goto f_err;
278 }
279
280 + s->client_version = version;
281 /* now s->rstate == SSL_ST_READ_BODY */
282 }
283
284 @@ -973,47 +976,40 @@ start:
285 }
286
287 if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC)
288 - {
289 - struct ccs_header_st ccs_hdr;
290 + {
291 + struct ccs_header_st ccs_hdr;
292
293 dtls1_get_ccs_header(rr->data, &ccs_hdr);
294
295 - if ( ccs_hdr.seq == s->d1->handshake_read_seq)
296 + /* 'Change Cipher Spec' is just a single byte, so we know
297 + * exactly what the record payload has to look like */
298 + /* XDTLS: check that epoch is consistent */
299 + if ( (s->client_version == DTLS1_BAD_VER && rr->length != 3) ||
300 + (s->client_version != DTLS1_BAD_VER && rr->length != DTLS1_CCS_HEADER_LENGTH) ||
301 + (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
302 {
303 - /* 'Change Cipher Spec' is just a single byte, so we know
304 - * exactly what the record payload has to look like */
305 - /* XDTLS: check that epoch is consistent */
306 - if ( (rr->length != DTLS1_CCS_HEADER_LENGTH) ||
307 - (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS))
308 - {
309 - i=SSL_AD_ILLEGAL_PARAMETER;
310 - SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
311 - goto err;
312 - }
313 -
314 - rr->length=0;
315 -
316 - if (s->msg_callback)
317 - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
318 - rr->data, 1, s, s->msg_callback_arg);
319 -
320 - s->s3->change_cipher_spec=1;
321 - if (!ssl3_do_change_cipher_spec(s))
322 - goto err;
323 -
324 - /* do this whenever CCS is processed */
325 - dtls1_reset_seq_numbers(s, SSL3_CC_READ);
326 -
327 - /* handshake read seq is reset upon handshake completion */
328 - s->d1->handshake_read_seq++;
329 -
330 - goto start;
331 - }
332 - else
333 - {
334 - rr->length = 0;
335 - goto start;
336 + i=SSL_AD_ILLEGAL_PARAMETER;
337 + SSLerr(SSL_F_DTLS1_READ_BYTES,SSL_R_BAD_CHANGE_CIPHER_SPEC);
338 + goto err;
339 }
340 +
341 + rr->length=0;
342 +
343 + if (s->msg_callback)
344 + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC,
345 + rr->data, 1, s, s->msg_callback_arg);
346 +
347 + s->s3->change_cipher_spec=1;
348 + if (!ssl3_do_change_cipher_spec(s))
349 + goto err;
350 +
351 + /* do this whenever CCS is processed */
352 + dtls1_reset_seq_numbers(s, SSL3_CC_READ);
353 +
354 + if (s->client_version == DTLS1_BAD_VER)
355 + s->d1->handshake_read_seq++;
356 +
357 + goto start;
358 }
359
360 /* Unexpected handshake message (Client Hello, or protocol violation) */
361 @@ -1341,8 +1337,12 @@ int do_dtls1_write(SSL *s, int type, con
362 *(p++)=type&0xff;
363 wr->type=type;
364
365 - *(p++)=(s->version>>8);
366 - *(p++)=s->version&0xff;
367 + if (s->client_version == DTLS1_BAD_VER)
368 + *(p++) = DTLS1_BAD_VER>>8,
369 + *(p++) = DTLS1_BAD_VER&0xff;
370 + else
371 + *(p++)=(s->version>>8),
372 + *(p++)=s->version&0xff;
373
374 /* field where we are to write out packet epoch, seq num and len */
375 pseq=p;
376 @@ -1397,8 +1397,14 @@ int do_dtls1_write(SSL *s, int type, con
377
378
379 /* ssl3_enc can only have an error on read */
380 - wr->length += bs; /* bs != 0 in case of CBC. The enc fn provides
381 - * the randomness */
382 + if (bs) /* bs != 0 in case of CBC */
383 + {
384 + RAND_pseudo_bytes(p,bs);
385 + /* master IV and last CBC residue stand for
386 + * the rest of randomness */
387 + wr->length += bs;
388 + }
389 +
390 s->method->ssl3_enc->enc(s,1);
391
392 /* record length after mac and block padding */
393 diff -up openssl-fips-0.9.8f-dev/ssl/ssl_err.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/ssl_err.c
394 --- openssl-fips-0.9.8f-dev/ssl/ssl_err.c.dtls-fixes 2006-11-21 21:14:46.000000000 +0100
395 +++ openssl-fips-0.9.8f-dev/ssl/ssl_err.c 2008-07-15 21:01:29.000000000 +0200
396 @@ -87,6 +87,7 @@ static ERR_STRING_DATA SSL_str_functs[]=
397 {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), "DTLS1_GET_MESSAGE_FRAGMENT"},
398 {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"},
399 {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"},
400 +{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"},
401 {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
402 {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"},
403 {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "DTLS1_READ_BYTES"},
404 diff -up openssl-fips-0.9.8f-dev/ssl/s3_clnt.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/s3_clnt.c
405 --- openssl-fips-0.9.8f-dev/ssl/s3_clnt.c.dtls-fixes 2007-03-22 01:39:14.000000000 +0100
406 +++ openssl-fips-0.9.8f-dev/ssl/s3_clnt.c 2008-07-15 21:08:43.000000000 +0200
407 @@ -1847,6 +1847,13 @@ int ssl3_send_client_key_exchange(SSL *s
408 {
409 DH *dh_srvr,*dh_clnt;
410
411 + if (s->session->sess_cert == NULL)
412 + {
413 + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
414 + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
415 + goto err;
416 + }
417 +
418 if (s->session->sess_cert->peer_dh_tmp != NULL)
419 dh_srvr=s->session->sess_cert->peer_dh_tmp;
420 else
421 diff -up openssl-fips-0.9.8f-dev/ssl/d1_both.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_both.c
422 --- openssl-fips-0.9.8f-dev/ssl/d1_both.c.dtls-fixes 2007-06-22 14:17:52.000000000 +0200
423 +++ openssl-fips-0.9.8f-dev/ssl/d1_both.c 2008-07-15 21:01:29.000000000 +0200
424 @@ -138,38 +138,40 @@ static void dtls1_set_message_header_int
425 unsigned long frag_len);
426 static int dtls1_retransmit_buffered_messages(SSL *s);
427 static long dtls1_get_message_fragment(SSL *s, int st1, int stn,
428 - long max, int *ok);
429 -static void dtls1_process_handshake_fragment(SSL *s, int frag_len);
430 + long max, int *ok);
431
432 static hm_fragment *
433 dtls1_hm_fragment_new(unsigned long frag_len)
434 - {
435 - hm_fragment *frag = NULL;
436 - unsigned char *buf = NULL;
437 + {
438 + hm_fragment *frag = NULL;
439 + unsigned char *buf = NULL;
440
441 - frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
442 - if ( frag == NULL)
443 - return NULL;
444 + frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
445 + if ( frag == NULL)
446 + return NULL;
447
448 - buf = (unsigned char *)OPENSSL_malloc(frag_len
449 - + DTLS1_HM_HEADER_LENGTH);
450 - if ( buf == NULL)
451 - {
452 - OPENSSL_free(frag);
453 - return NULL;
454 - }
455 -
456 - frag->fragment = buf;
457 + if (frag_len)
458 + {
459 + buf = (unsigned char *)OPENSSL_malloc(frag_len);
460 + if ( buf == NULL)
461 + {
462 + OPENSSL_free(frag);
463 + return NULL;
464 + }
465 + }
466
467 - return frag;
468 - }
469 + /* zero length fragment gets zero frag->fragment */
470 + frag->fragment = buf;
471 +
472 + return frag;
473 + }
474
475 static void
476 dtls1_hm_fragment_free(hm_fragment *frag)
477 - {
478 - OPENSSL_free(frag->fragment);
479 - OPENSSL_free(frag);
480 - }
481 + {
482 + if (frag->fragment) OPENSSL_free(frag->fragment);
483 + OPENSSL_free(frag);
484 + }
485
486 /* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
487 int dtls1_do_write(SSL *s, int type)
488 @@ -180,7 +182,7 @@ int dtls1_do_write(SSL *s, int type)
489
490 /* AHA! Figure out the MTU, and stick to the right size */
491 if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
492 - {
493 + {
494 s->d1->mtu =
495 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
496
497 @@ -207,7 +209,7 @@ int dtls1_do_write(SSL *s, int type)
498 mtu = curr_mtu;
499 else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
500 return ret;
501 -
502 +
503 if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
504 {
505 ret = BIO_flush(SSL_get_wbio(s));
506 @@ -254,11 +256,11 @@ int dtls1_do_write(SSL *s, int type)
507 s->init_off -= DTLS1_HM_HEADER_LENGTH;
508 s->init_num += DTLS1_HM_HEADER_LENGTH;
509
510 - /* write atleast DTLS1_HM_HEADER_LENGTH bytes */
511 + /* write atleast DTLS1_HM_HEADER_LENGTH bytes */
512 if ( len <= DTLS1_HM_HEADER_LENGTH)
513 len += DTLS1_HM_HEADER_LENGTH;
514 }
515 -
516 +
517 dtls1_fix_message_header(s, frag_off,
518 len - DTLS1_HM_HEADER_LENGTH);
519
520 @@ -286,18 +288,40 @@ int dtls1_do_write(SSL *s, int type)
521 }
522 else
523 {
524 -
525 +
526 /* bad if this assert fails, only part of the handshake
527 * message got sent. but why would this happen? */
528 - OPENSSL_assert(len == (unsigned int)ret);
529 -
530 + OPENSSL_assert(len == (unsigned int)ret);
531 +
532 if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting)
533 + {
534 /* should not be done for 'Hello Request's, but in that case
535 * we'll ignore the result anyway */
536 - ssl3_finish_mac(s,
537 - (unsigned char *)&s->init_buf->data[s->init_off +
538 - DTLS1_HM_HEADER_LENGTH], ret - DTLS1_HM_HEADER_LENGTH);
539 -
540 + unsigned char *p = &s->init_buf->data[s->init_off];
541 + const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
542 + int len;
543 +
544 + if (frag_off == 0 && s->client_version != DTLS1_BAD_VER)
545 + {
546 + /* reconstruct message header is if it
547 + * is being sent in single fragment */
548 + *p++ = msg_hdr->type;
549 + l2n3(msg_hdr->msg_len,p);
550 + s2n (msg_hdr->seq,p);
551 + l2n3(0,p);
552 + l2n3(msg_hdr->msg_len,p);
553 + p -= DTLS1_HM_HEADER_LENGTH;
554 + len = ret;
555 + }
556 + else
557 + {
558 + p += DTLS1_HM_HEADER_LENGTH;
559 + len = ret - DTLS1_HM_HEADER_LENGTH;
560 + }
561 +
562 + ssl3_finish_mac(s, p, len);
563 + }
564 +
565 if (ret == s->init_num)
566 {
567 if (s->msg_callback)
568 @@ -307,7 +331,7 @@ int dtls1_do_write(SSL *s, int type)
569
570 s->init_off = 0; /* done writing this message */
571 s->init_num = 0;
572 -
573 +
574 return(1);
575 }
576 s->init_off+=ret;
577 @@ -327,6 +351,7 @@ int dtls1_do_write(SSL *s, int type)
578 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
579 {
580 int i, al;
581 + struct hm_header_st *msg_hdr;
582
583 /* s3->tmp is used to store messages that are unexpected, caused
584 * by the absence of an optional handshake message */
585 @@ -344,25 +369,56 @@ long dtls1_get_message(SSL *s, int st1,
586 s->init_num = (int)s->s3->tmp.message_size;
587 return s->init_num;
588 }
589 -
590 +
591 + msg_hdr = &s->d1->r_msg_hdr;
592 do
593 {
594 - if ( s->d1->r_msg_hdr.frag_off == 0)
595 + if ( msg_hdr->frag_off == 0)
596 {
597 /* s->d1->r_message_header.msg_len = 0; */
598 - memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st));
599 + memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
600 }
601
602 i = dtls1_get_message_fragment(s, st1, stn, max, ok);
603 if ( i == DTLS1_HM_BAD_FRAGMENT ||
604 - i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */
605 + i == DTLS1_HM_FRAGMENT_RETRY) /* bad fragment received */
606 continue;
607 else if ( i <= 0 && !*ok)
608 return i;
609
610 - if (s->d1->r_msg_hdr.msg_len == (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH)
611 + /* Note that s->init_sum is used as a counter summing
612 + * up fragments' lengths: as soon as they sum up to
613 + * handshake packet length, we assume we have got all
614 + * the fragments. Overlapping fragments would cause
615 + * premature termination, so we don't expect overlaps.
616 + * Well, handling overlaps would require something more
617 + * drastic. Indeed, as it is now there is no way to
618 + * tell if out-of-order fragment from the middle was
619 + * the last. '>=' is the best/least we can do to control
620 + * the potential damage caused by malformed overlaps. */
621 + if ((unsigned int)s->init_num >= msg_hdr->msg_len)
622 {
623 - memset(&(s->d1->r_msg_hdr), 0x00, sizeof(struct hm_header_st));
624 + unsigned char *p = s->init_buf->data;
625 + unsigned long msg_len = msg_hdr->msg_len;
626 +
627 + /* reconstruct message header as if it was
628 + * sent in single fragment */
629 + *(p++) = msg_hdr->type;
630 + l2n3(msg_len,p);
631 + s2n (msg_hdr->seq,p);
632 + l2n3(0,p);
633 + l2n3(msg_len,p);
634 + if (s->client_version != DTLS1_BAD_VER)
635 + p -= DTLS1_HM_HEADER_LENGTH,
636 + msg_len += DTLS1_HM_HEADER_LENGTH;
637 +
638 + ssl3_finish_mac(s, p, msg_len);
639 + if (s->msg_callback)
640 + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
641 + p, msg_len,
642 + s, s->msg_callback_arg);
643 +
644 + memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
645
646 s->d1->handshake_read_seq++;
647 /* we just read a handshake message from the other side:
648 @@ -379,11 +435,11 @@ long dtls1_get_message(SSL *s, int st1,
649 * first data segment, but is there a better way? */
650 dtls1_clear_record_buffer(s);
651
652 - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
653 - return s->init_num - DTLS1_HM_HEADER_LENGTH;
654 + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
655 + return s->init_num;
656 }
657 else
658 - s->d1->r_msg_hdr.frag_off = i;
659 + msg_hdr->frag_off = i;
660 } while(1) ;
661
662 f_err:
663 @@ -393,161 +449,183 @@ f_err:
664 }
665
666
667 -static int
668 -dtls1_retrieve_buffered_fragment(SSL *s, unsigned long *copied)
669 - {
670 - /* (0) check whether the desired fragment is available
671 - * if so:
672 - * (1) copy over the fragment to s->init_buf->data[]
673 - * (2) update s->init_num
674 - */
675 - pitem *item;
676 - hm_fragment *frag;
677 - unsigned long overlap;
678 - unsigned char *p;
679 -
680 - item = pqueue_peek(s->d1->buffered_messages);
681 - if ( item == NULL)
682 - return 0;
683 +static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max)
684 + {
685 + size_t frag_off,frag_len,msg_len;
686
687 - frag = (hm_fragment *)item->data;
688 -
689 - if ( s->d1->handshake_read_seq == frag->msg_header.seq &&
690 - frag->msg_header.frag_off <= (unsigned int)s->init_num - DTLS1_HM_HEADER_LENGTH)
691 - {
692 - pqueue_pop(s->d1->buffered_messages);
693 - overlap = s->init_num - DTLS1_HM_HEADER_LENGTH
694 - - frag->msg_header.frag_off;
695 -
696 - p = frag->fragment;
697 -
698 - memcpy(&s->init_buf->data[s->init_num],
699 - p + DTLS1_HM_HEADER_LENGTH + overlap,
700 - frag->msg_header.frag_len - overlap);
701 -
702 - OPENSSL_free(frag->fragment);
703 - OPENSSL_free(frag);
704 - pitem_free(item);
705 + msg_len = msg_hdr->msg_len;
706 + frag_off = msg_hdr->frag_off;
707 + frag_len = msg_hdr->frag_len;
708
709 - *copied = frag->msg_header.frag_len - overlap;
710 - return *copied;
711 - }
712 - else
713 - return 0;
714 - }
715 + /* sanity checking */
716 + if ( (frag_off+frag_len) > msg_len)
717 + {
718 + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
719 + return SSL_AD_ILLEGAL_PARAMETER;
720 + }
721
722 + if ( (frag_off+frag_len) > (unsigned long)max)
723 + {
724 + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
725 + return SSL_AD_ILLEGAL_PARAMETER;
726 + }
727
728 -static int
729 -dtls1_buffer_handshake_fragment(SSL *s, struct hm_header_st* msg_hdr)
730 -{
731 - hm_fragment *frag = NULL;
732 - pitem *item = NULL;
733 - PQ_64BIT seq64;
734 + if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
735 + {
736 + /* msg_len is limited to 2^24, but is effectively checked
737 + * against max above */
738 + if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH))
739 + {
740 + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
741 + return SSL_AD_INTERNAL_ERROR;
742 + }
743
744 - frag = dtls1_hm_fragment_new(msg_hdr->frag_len);
745 - if ( frag == NULL)
746 - goto err;
747 + s->s3->tmp.message_size = msg_len;
748 + s->d1->r_msg_hdr.msg_len = msg_len;
749 + s->s3->tmp.message_type = msg_hdr->type;
750 + s->d1->r_msg_hdr.type = msg_hdr->type;
751 + s->d1->r_msg_hdr.seq = msg_hdr->seq;
752 + }
753 + else if (msg_len != s->d1->r_msg_hdr.msg_len)
754 + {
755 + /* They must be playing with us! BTW, failure to enforce
756 + * upper limit would open possibility for buffer overrun. */
757 + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
758 + return SSL_AD_ILLEGAL_PARAMETER;
759 + }
760
761 - memcpy(frag->fragment, &(s->init_buf->data[s->init_num]),
762 - msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH);
763 + return 0; /* no error */
764 + }
765
766 - memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
767
768 - pq_64bit_init(&seq64);
769 - pq_64bit_assign_word(&seq64, msg_hdr->seq);
770 +static int
771 +dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
772 + {
773 + /* (0) check whether the desired fragment is available
774 + * if so:
775 + * (1) copy over the fragment to s->init_buf->data[]
776 + * (2) update s->init_num
777 + */
778 + pitem *item;
779 + hm_fragment *frag;
780 + int al;
781
782 - item = pitem_new(seq64, frag);
783 - if ( item == NULL)
784 - goto err;
785 + *ok = 0;
786 + item = pqueue_peek(s->d1->buffered_messages);
787 + if ( item == NULL)
788 + return 0;
789
790 - pq_64bit_free(&seq64);
791 + frag = (hm_fragment *)item->data;
792
793 - pqueue_insert(s->d1->buffered_messages, item);
794 - return 1;
795 + if ( s->d1->handshake_read_seq == frag->msg_header.seq)
796 + {
797 + pqueue_pop(s->d1->buffered_messages);
798
799 -err:
800 - if ( frag != NULL) dtls1_hm_fragment_free(frag);
801 - if ( item != NULL) OPENSSL_free(item);
802 - return 0;
803 -}
804 + al=dtls1_preprocess_fragment(s,&frag->msg_header,max);
805
806 + if (al==0) /* no alert */
807 + {
808 + unsigned char *p = s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
809 + memcpy(&p[frag->msg_header.frag_off],
810 + frag->fragment,frag->msg_header.frag_len);
811 + }
812
813 -static void
814 -dtls1_process_handshake_fragment(SSL *s, int frag_len)
815 - {
816 - unsigned char *p;
817 + dtls1_hm_fragment_free(frag);
818 + pitem_free(item);
819
820 - p = (unsigned char *)s->init_buf->data;
821 + if (al==0)
822 + {
823 + *ok = 1;
824 + return frag->msg_header.frag_len;
825 + }
826
827 - ssl3_finish_mac(s, &p[s->init_num - frag_len], frag_len);
828 - }
829 + ssl3_send_alert(s,SSL3_AL_FATAL,al);
830 + s->init_num = 0;
831 + *ok = 0;
832 + return -1;
833 + }
834 + else
835 + return 0;
836 + }
837
838
839 static int
840 -dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st *msg_hdr, int *ok)
841 - {
842 - int i;
843 - unsigned char *p;
844 -
845 - /* make sure there's enough room to read this fragment */
846 - if ( (int)msg_hdr->frag_len && !BUF_MEM_grow_clean(s->init_buf,
847 - (int)msg_hdr->frag_len + DTLS1_HM_HEADER_LENGTH + s->init_num))
848 - {
849 - SSLerr(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE,ERR_R_BUF_LIB);
850 - goto err;
851 - }
852 +dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
853 +{
854 + int i=-1;
855 + hm_fragment *frag = NULL;
856 + pitem *item = NULL;
857 + PQ_64BIT seq64;
858 + unsigned long frag_len = msg_hdr->frag_len;
859
860 - p = (unsigned char *)s->init_buf->data;
861 + if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
862 + goto err;
863
864 - /* read the body of the fragment (header has already been read */
865 - if ( msg_hdr->frag_len > 0)
866 + if (msg_hdr->seq <= s->d1->handshake_read_seq)
867 {
868 - i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
869 - &p[s->init_num],
870 - msg_hdr->frag_len,0);
871 - if (i <= 0)
872 + unsigned char devnull [256];
873 +
874 + while (frag_len)
875 {
876 - *ok = 0;
877 - return i;
878 + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
879 + devnull,
880 + frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
881 + if (i<=0) goto err;
882 + frag_len -= i;
883 }
884 }
885
886 - if ( msg_hdr->seq > s->d1->handshake_read_seq)
887 - dtls1_buffer_handshake_fragment(s, msg_hdr);
888 - else
889 - OPENSSL_assert(msg_hdr->seq < s->d1->handshake_read_seq);
890 + frag = dtls1_hm_fragment_new(frag_len);
891 + if ( frag == NULL)
892 + goto err;
893 +
894 + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
895 +
896 + if (frag_len)
897 + {
898 + /* read the body of the fragment (header has already been read */
899 + i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
900 + frag->fragment,frag_len,0);
901 + if (i<=0 || i!=frag_len)
902 + goto err;
903 + }
904 +
905 + pq_64bit_init(&seq64);
906 + pq_64bit_assign_word(&seq64, msg_hdr->seq);
907 +
908 + item = pitem_new(seq64, frag);
909 + pq_64bit_free(&seq64);
910 + if ( item == NULL)
911 + goto err;
912 +
913 + pqueue_insert(s->d1->buffered_messages, item);
914 + return DTLS1_HM_FRAGMENT_RETRY;
915
916 - return DTLS1_HM_FRAGMENT_RETRY;
917 err:
918 - *ok = 0;
919 - return -1;
920 - }
921 + if ( frag != NULL) dtls1_hm_fragment_free(frag);
922 + if ( item != NULL) OPENSSL_free(item);
923 + *ok = 0;
924 + return i;
925 + }
926
927
928 static long
929 dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
930 {
931 - unsigned char *p;
932 + unsigned char wire[DTLS1_HM_HEADER_LENGTH];
933 unsigned long l, frag_off, frag_len;
934 int i,al;
935 struct hm_header_st msg_hdr;
936 - unsigned long overlap;
937 -
938 - /* see if we have the required fragment already */
939 - if (dtls1_retrieve_buffered_fragment(s, &l))
940 - {
941 - /* compute MAC, remove fragment headers */
942 - dtls1_process_handshake_fragment(s, l);
943 - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
944 - s->state = stn;
945 - return 1;
946 - }
947
948 - /* get a handshake fragment from the record layer */
949 - p = (unsigned char *)s->init_buf->data;
950 + /* see if we have the required fragment already */
951 + if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
952 + {
953 + if (*ok) s->init_num += frag_len;
954 + return frag_len;
955 + }
956
957 - /* read handshake message header */
958 - i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,&p[s->init_num],
959 + /* read handshake message header */
960 + i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire,
961 DTLS1_HM_HEADER_LENGTH, 0);
962 if (i <= 0) /* nbio, or an error */
963 {
964 @@ -555,130 +633,61 @@ dtls1_get_message_fragment(SSL *s, int s
965 *ok = 0;
966 return i;
967 }
968 -
969 OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH);
970
971 - p += s->init_num;
972 - /* parse the message fragment header */
973 -
974 - dtls1_get_message_header(p, &msg_hdr);
975 + /* parse the message fragment header */
976 + dtls1_get_message_header(wire, &msg_hdr);
977
978 - /*
979 - * if this is a future (or stale) message it gets buffered
980 - * (or dropped)--no further processing at this time
981 - */
982 - if ( msg_hdr.seq != s->d1->handshake_read_seq)
983 - return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
984 + /*
985 + * if this is a future (or stale) message it gets buffered
986 + * (or dropped)--no further processing at this time
987 + */
988 + if ( msg_hdr.seq != s->d1->handshake_read_seq)
989 + return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
990
991 - l = msg_hdr.msg_len;
992 - frag_off = msg_hdr.frag_off;
993 + l = msg_hdr.msg_len;
994 + frag_off = msg_hdr.frag_off;
995 frag_len = msg_hdr.frag_len;
996
997 - /* sanity checking */
998 - if ( frag_off + frag_len > l)
999 - {
1000 - al=SSL_AD_ILLEGAL_PARAMETER;
1001 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
1002 - goto f_err;
1003 - }
1004 -
1005 if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
1006 - p[0] == SSL3_MT_HELLO_REQUEST)
1007 - {
1008 - /* The server may always send 'Hello Request' messages --
1009 - * we are doing a handshake anyway now, so ignore them
1010 - * if their format is correct. Does not count for
1011 - * 'Finished' MAC. */
1012 - if (p[1] == 0 && p[2] == 0 &&p[3] == 0)
1013 - {
1014 - if (s->msg_callback)
1015 - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
1016 - p, DTLS1_HM_HEADER_LENGTH, s,
1017 - s->msg_callback_arg);
1018 -
1019 - s->init_num = 0;
1020 - return dtls1_get_message_fragment(s, st1, stn,
1021 - max, ok);
1022 - }
1023 - else /* Incorrectly formated Hello request */
1024 - {
1025 - al=SSL_AD_UNEXPECTED_MESSAGE;
1026 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
1027 - goto f_err;
1028 - }
1029 - }
1030 -
1031 - /* XDTLS: do a sanity check on the fragment */
1032 -
1033 - s->init_num += i;
1034 -
1035 - if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
1036 + wire[0] == SSL3_MT_HELLO_REQUEST)
1037 {
1038 - /* BUF_MEM_grow takes an 'int' parameter */
1039 - if (l > (INT_MAX-DTLS1_HM_HEADER_LENGTH))
1040 + /* The server may always send 'Hello Request' messages --
1041 + * we are doing a handshake anyway now, so ignore them
1042 + * if their format is correct. Does not count for
1043 + * 'Finished' MAC. */
1044 + if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0)
1045 {
1046 - al=SSL_AD_ILLEGAL_PARAMETER;
1047 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
1048 - goto f_err;
1049 - }
1050 - if (l && !BUF_MEM_grow_clean(s->init_buf,(int)l
1051 - + DTLS1_HM_HEADER_LENGTH))
1052 - {
1053 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB);
1054 - goto err;
1055 + if (s->msg_callback)
1056 + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
1057 + wire, DTLS1_HM_HEADER_LENGTH, s,
1058 + s->msg_callback_arg);
1059 +
1060 + s->init_num = 0;
1061 + return dtls1_get_message_fragment(s, st1, stn,
1062 + max, ok);
1063 }
1064 - /* Only do this test when we're reading the expected message.
1065 - * Stale messages will be dropped and future messages will be buffered */
1066 - if ( l > (unsigned long)max)
1067 + else /* Incorrectly formated Hello request */
1068 {
1069 - al=SSL_AD_ILLEGAL_PARAMETER;
1070 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
1071 + al=SSL_AD_UNEXPECTED_MESSAGE;
1072 + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
1073 goto f_err;
1074 }
1075 -
1076 - s->s3->tmp.message_size=l;
1077 }
1078
1079 - if ( frag_len > (unsigned long)max)
1080 - {
1081 - al=SSL_AD_ILLEGAL_PARAMETER;
1082 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
1083 - goto f_err;
1084 - }
1085 - if ( frag_len + s->init_num > (INT_MAX - DTLS1_HM_HEADER_LENGTH))
1086 - {
1087 - al=SSL_AD_ILLEGAL_PARAMETER;
1088 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
1089 - goto f_err;
1090 - }
1091 -
1092 - if ( frag_len & !BUF_MEM_grow_clean(s->init_buf, (int)frag_len
1093 - + DTLS1_HM_HEADER_LENGTH + s->init_num))
1094 - {
1095 - SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,ERR_R_BUF_LIB);
1096 - goto err;
1097 - }
1098 -
1099 - if ( s->d1->r_msg_hdr.frag_off == 0)
1100 - {
1101 - s->s3->tmp.message_type = msg_hdr.type;
1102 - s->d1->r_msg_hdr.type = msg_hdr.type;
1103 - s->d1->r_msg_hdr.msg_len = l;
1104 - /* s->d1->r_msg_hdr.seq = seq_num; */
1105 - }
1106 + if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max)))
1107 + goto f_err;
1108
1109 /* XDTLS: ressurect this when restart is in place */
1110 s->state=stn;
1111 -
1112 - /* next state (stn) */
1113 - p = (unsigned char *)s->init_buf->data;
1114
1115 if ( frag_len > 0)
1116 {
1117 + unsigned char *p=s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
1118 +
1119 i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
1120 - &p[s->init_num],
1121 - frag_len,0);
1122 - /* XDTLS: fix this--message fragments cannot span multiple packets */
1123 + &p[frag_off],frag_len,0);
1124 + /* XDTLS: fix this--message fragments cannot span multiple packets */
1125 if (i <= 0)
1126 {
1127 s->rwstate=SSL_READING;
1128 @@ -689,70 +698,23 @@ dtls1_get_message_fragment(SSL *s, int s
1129 else
1130 i = 0;
1131
1132 - /* XDTLS: an incorrectly formatted fragment should cause the
1133 - * handshake to fail */
1134 + /* XDTLS: an incorrectly formatted fragment should cause the
1135 + * handshake to fail */
1136 OPENSSL_assert(i == (int)frag_len);
1137
1138 -#if 0
1139 - /* Successfully read a fragment.
1140 - * It may be (1) out of order, or
1141 - * (2) it's a repeat, in which case we dump it
1142 - * (3) the one we are expecting next (maybe with overlap)
1143 - * If it is next one, it may overlap with previously read bytes
1144 - */
1145 + *ok = 1;
1146
1147 - /* case (1): buffer the future fragment
1148 - * (we can treat fragments from a future message the same
1149 - * as future fragments from the message being currently read, since
1150 - * they are sematically simply out of order.
1151 - */
1152 - if ( msg_hdr.seq > s->d1->handshake_read_seq ||
1153 - frag_off > s->init_num - DTLS1_HM_HEADER_LENGTH)
1154 - {
1155 - dtls1_buffer_handshake_fragment(s, &msg_hdr);
1156 - return DTLS1_HM_FRAGMENT_RETRY;
1157 - }
1158 -
1159 - /* case (2): drop the entire fragment, and try again */
1160 - if ( msg_hdr.seq < s->d1->handshake_read_seq ||
1161 - frag_off + frag_len < s->init_num - DTLS1_HM_HEADER_LENGTH)
1162 - {
1163 - s->init_num -= DTLS1_HM_HEADER_LENGTH;
1164 - return DTLS1_HM_FRAGMENT_RETRY;
1165 - }
1166 -#endif
1167 -
1168 - /* case (3): received a immediately useful fragment. Determine the
1169 - * possible overlap and copy the fragment.
1170 - */
1171 - overlap = (s->init_num - DTLS1_HM_HEADER_LENGTH) - frag_off;
1172 -
1173 - /* retain the header for the first fragment */
1174 - if ( s->init_num > DTLS1_HM_HEADER_LENGTH)
1175 - {
1176 - memmove(&(s->init_buf->data[s->init_num]),
1177 - &(s->init_buf->data[s->init_num + DTLS1_HM_HEADER_LENGTH + overlap]),
1178 - frag_len - overlap);
1179 -
1180 - s->init_num += frag_len - overlap;
1181 - }
1182 - else
1183 - s->init_num += frag_len;
1184 -
1185 - dtls1_process_handshake_fragment(s, frag_len - overlap);
1186 -
1187 - if (s->msg_callback)
1188 - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
1189 - (size_t)s->init_num, s,
1190 - s->msg_callback_arg);
1191 - *ok=1;
1192 -
1193 - return s->init_num;
1194 + /* Note that s->init_num is *not* used as current offset in
1195 + * s->init_buf->data, but as a counter summing up fragments'
1196 + * lengths: as soon as they sum up to handshake packet
1197 + * length, we assume we have got all the fragments. */
1198 + s->init_num += frag_len;
1199 + return frag_len;
1200
1201 f_err:
1202 ssl3_send_alert(s,SSL3_AL_FATAL,al);
1203 - s->init_num = 0;
1204 -err:
1205 + s->init_num = 0;
1206 +
1207 *ok=0;
1208 return(-1);
1209 }
1210 @@ -790,7 +752,7 @@ int dtls1_send_finished(SSL *s, int a, i
1211
1212 /* buffer the message to handle re-xmits */
1213 dtls1_buffer_message(s, 0);
1214 -
1215 +
1216 s->state=b;
1217 }
1218
1219 @@ -815,10 +777,15 @@ int dtls1_send_change_cipher_spec(SSL *s
1220 p=(unsigned char *)s->init_buf->data;
1221 *p++=SSL3_MT_CCS;
1222 s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
1223 - s->d1->next_handshake_write_seq++;
1224 - s2n(s->d1->handshake_write_seq,p);
1225 -
1226 s->init_num=DTLS1_CCS_HEADER_LENGTH;
1227 +
1228 + if (s->client_version == DTLS1_BAD_VER)
1229 + {
1230 + s->d1->next_handshake_write_seq++;
1231 + s2n(s->d1->handshake_write_seq,p);
1232 + s->init_num+=2;
1233 + }
1234 +
1235 s->init_off=0;
1236
1237 dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
1238 @@ -1044,6 +1011,7 @@ dtls1_buffer_message(SSL *s, int is_ccs)
1239 pitem *item;
1240 hm_fragment *frag;
1241 PQ_64BIT seq64;
1242 + unsigned int epoch = s->d1->w_epoch;
1243
1244 /* this function is called immediately after a message has
1245 * been serialized */
1246 @@ -1056,7 +1024,8 @@ dtls1_buffer_message(SSL *s, int is_ccs)
1247 if ( is_ccs)
1248 {
1249 OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
1250 - DTLS1_CCS_HEADER_LENGTH == (unsigned int)s->init_num);
1251 + DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num);
1252 + epoch++;
1253 }
1254 else
1255 {
1256 @@ -1072,7 +1041,7 @@ dtls1_buffer_message(SSL *s, int is_ccs)
1257 frag->msg_header.is_ccs = is_ccs;
1258
1259 pq_64bit_init(&seq64);
1260 - pq_64bit_assign_word(&seq64, frag->msg_header.seq);
1261 + pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq);
1262
1263 item = pitem_new(seq64, frag);
1264 pq_64bit_free(&seq64);
1265 @@ -1259,5 +1228,4 @@ dtls1_get_ccs_header(unsigned char *data
1266 memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));
1267
1268 ccs_hdr->type = *(data++);
1269 - n2s(data, ccs_hdr->seq);
1270 }
1271 diff -up openssl-fips-0.9.8f-dev/ssl/d1_clnt.c.dtls-fixes openssl-fips-0.9.8f-dev/ssl/d1_clnt.c
1272 --- openssl-fips-0.9.8f-dev/ssl/d1_clnt.c.dtls-fixes 2005-12-05 18:32:19.000000000 +0100
1273 +++ openssl-fips-0.9.8f-dev/ssl/d1_clnt.c 2008-07-15 21:01:29.000000000 +0200
1274 @@ -214,17 +214,21 @@ int dtls1_connect(SSL *s)
1275
1276 /* don't push the buffering BIO quite yet */
1277
1278 - ssl3_init_finished_mac(s);
1279 -
1280 s->state=SSL3_ST_CW_CLNT_HELLO_A;
1281 s->ctx->stats.sess_connect++;
1282 s->init_num=0;
1283 + /* mark client_random uninitialized */
1284 + memset(s->s3->client_random,0,sizeof(s->s3->client_random));
1285 break;
1286
1287 case SSL3_ST_CW_CLNT_HELLO_A:
1288 case SSL3_ST_CW_CLNT_HELLO_B:
1289
1290 s->shutdown=0;
1291 +
1292 + /* every DTLS ClientHello resets Finished MAC */
1293 + ssl3_init_finished_mac(s);
1294 +
1295 ret=dtls1_client_hello(s);
1296 if (ret <= 0) goto end;
1297
1298 @@ -422,6 +426,9 @@ int dtls1_connect(SSL *s)
1299 s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
1300 }
1301 s->init_num=0;
1302 + /* mark client_random uninitialized */
1303 + memset (s->s3->client_random,0,sizeof(s->s3->client_random));
1304 +
1305 break;
1306
1307 case SSL3_ST_CR_FINISHED_A:
1308 @@ -544,9 +551,15 @@ int dtls1_client_hello(SSL *s)
1309 /* else use the pre-loaded session */
1310
1311 p=s->s3->client_random;
1312 - Time=(unsigned long)time(NULL); /* Time */
1313 - l2n(Time,p);
1314 - RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time));
1315 + /* if client_random is initialized, reuse it, we are
1316 + * required to use same upon reply to HelloVerify */
1317 + for (i=0;p[i]=='\0' && i<sizeof(s->s3->client_random);i++) ;
1318 + if (i==sizeof(s->s3->client_random))
1319 + {
1320 + Time=(unsigned long)time(NULL); /* Time */
1321 + l2n(Time,p);
1322 + RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4);
1323 + }
1324
1325 /* Do the message type and length last */
1326 d=p= &(buf[DTLS1_HM_HEADER_LENGTH]);

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed