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

Annotation 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 - (hide annotations) (download)
Tue Feb 18 03:03:09 2014 UTC (10 years, 3 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 wellsi 1.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