os/ossrv/ssl/libssl/src/d1_both.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
/* ssl/d1_both.c */
sl@0
     2
/* 
sl@0
     3
 * DTLS implementation written by Nagendra Modadugu
sl@0
     4
 * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.  
sl@0
     5
 */
sl@0
     6
/* ====================================================================
sl@0
     7
 * Copyright (c) 1998-2005 The OpenSSL Project.  All rights reserved.
sl@0
     8
 *
sl@0
     9
 * Redistribution and use in source and binary forms, with or without
sl@0
    10
 * modification, are permitted provided that the following conditions
sl@0
    11
 * are met:
sl@0
    12
 *
sl@0
    13
 * 1. Redistributions of source code must retain the above copyright
sl@0
    14
 *    notice, this list of conditions and the following disclaimer. 
sl@0
    15
 *
sl@0
    16
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    17
 *    notice, this list of conditions and the following disclaimer in
sl@0
    18
 *    the documentation and/or other materials provided with the
sl@0
    19
 *    distribution.
sl@0
    20
 *
sl@0
    21
 * 3. All advertising materials mentioning features or use of this
sl@0
    22
 *    software must display the following acknowledgment:
sl@0
    23
 *    "This product includes software developed by the OpenSSL Project
sl@0
    24
 *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
sl@0
    25
 *
sl@0
    26
 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
sl@0
    27
 *    endorse or promote products derived from this software without
sl@0
    28
 *    prior written permission. For written permission, please contact
sl@0
    29
 *    openssl-core@openssl.org.
sl@0
    30
 *
sl@0
    31
 * 5. Products derived from this software may not be called "OpenSSL"
sl@0
    32
 *    nor may "OpenSSL" appear in their names without prior written
sl@0
    33
 *    permission of the OpenSSL Project.
sl@0
    34
 *
sl@0
    35
 * 6. Redistributions of any form whatsoever must retain the following
sl@0
    36
 *    acknowledgment:
sl@0
    37
 *    "This product includes software developed by the OpenSSL Project
sl@0
    38
 *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
sl@0
    39
 *
sl@0
    40
 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
sl@0
    41
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
    42
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
sl@0
    43
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
sl@0
    44
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
sl@0
    45
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
sl@0
    46
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
sl@0
    47
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
    48
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
sl@0
    49
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
sl@0
    50
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
sl@0
    51
 * OF THE POSSIBILITY OF SUCH DAMAGE.
sl@0
    52
 * ====================================================================
sl@0
    53
 *
sl@0
    54
 * This product includes cryptographic software written by Eric Young
sl@0
    55
 * (eay@cryptsoft.com).  This product includes software written by Tim
sl@0
    56
 * Hudson (tjh@cryptsoft.com).
sl@0
    57
 *
sl@0
    58
 */
sl@0
    59
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
sl@0
    60
 * All rights reserved.
sl@0
    61
 *
sl@0
    62
 * This package is an SSL implementation written
sl@0
    63
 * by Eric Young (eay@cryptsoft.com).
sl@0
    64
 * The implementation was written so as to conform with Netscapes SSL.
sl@0
    65
 * 
sl@0
    66
 * This library is free for commercial and non-commercial use as long as
sl@0
    67
 * the following conditions are aheared to.  The following conditions
sl@0
    68
 * apply to all code found in this distribution, be it the RC4, RSA,
sl@0
    69
 * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
sl@0
    70
 * included with this distribution is covered by the same copyright terms
sl@0
    71
 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
sl@0
    72
 * 
sl@0
    73
 * Copyright remains Eric Young's, and as such any Copyright notices in
sl@0
    74
 * the code are not to be removed.
sl@0
    75
 * If this package is used in a product, Eric Young should be given attribution
sl@0
    76
 * as the author of the parts of the library used.
sl@0
    77
 * This can be in the form of a textual message at program startup or
sl@0
    78
 * in documentation (online or textual) provided with the package.
sl@0
    79
 * 
sl@0
    80
 * Redistribution and use in source and binary forms, with or without
sl@0
    81
 * modification, are permitted provided that the following conditions
sl@0
    82
 * are met:
sl@0
    83
 * 1. Redistributions of source code must retain the copyright
sl@0
    84
 *    notice, this list of conditions and the following disclaimer.
sl@0
    85
 * 2. Redistributions in binary form must reproduce the above copyright
sl@0
    86
 *    notice, this list of conditions and the following disclaimer in the
sl@0
    87
 *    documentation and/or other materials provided with the distribution.
sl@0
    88
 * 3. All advertising materials mentioning features or use of this software
sl@0
    89
 *    must display the following acknowledgement:
sl@0
    90
 *    "This product includes cryptographic software written by
sl@0
    91
 *     Eric Young (eay@cryptsoft.com)"
sl@0
    92
 *    The word 'cryptographic' can be left out if the rouines from the library
sl@0
    93
 *    being used are not cryptographic related :-).
sl@0
    94
 * 4. If you include any Windows specific code (or a derivative thereof) from 
sl@0
    95
 *    the apps directory (application code) you must include an acknowledgement:
sl@0
    96
 *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
sl@0
    97
 * 
sl@0
    98
 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
sl@0
    99
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
sl@0
   100
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
sl@0
   101
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
sl@0
   102
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
sl@0
   103
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
sl@0
   104
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
sl@0
   105
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
sl@0
   106
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
sl@0
   107
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
sl@0
   108
 * SUCH DAMAGE.
sl@0
   109
 * 
sl@0
   110
 * The licence and distribution terms for any publically available version or
sl@0
   111
 * derivative of this code cannot be changed.  i.e. this code cannot simply be
sl@0
   112
 * copied and put under another distribution licence
sl@0
   113
 * [including the GNU Public Licence.]
sl@0
   114
 */
sl@0
   115
/*
sl@0
   116
 © Portions copyright (c) 2006 Nokia Corporation.  All rights reserved.
sl@0
   117
 */
sl@0
   118
 
sl@0
   119
#include <limits.h>
sl@0
   120
#include <string.h>
sl@0
   121
#include <stdio.h>
sl@0
   122
#include "ssl_locl.h"
sl@0
   123
#include <openssl/buffer.h>
sl@0
   124
#include <openssl/rand.h>
sl@0
   125
#include <openssl/objects.h>
sl@0
   126
#include <openssl/evp.h>
sl@0
   127
#include <openssl/x509.h>
sl@0
   128
sl@0
   129
sl@0
   130
/* XDTLS:  figure out the right values */
sl@0
   131
#ifdef EMULATOR
sl@0
   132
static const unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
sl@0
   133
#else
sl@0
   134
static unsigned int g_probable_mtu[] = {1500 - 28, 512 - 28, 256 - 28};
sl@0
   135
#endif
sl@0
   136
sl@0
   137
static unsigned int dtls1_min_mtu(void);
sl@0
   138
static unsigned int dtls1_guess_mtu(unsigned int curr_mtu);
sl@0
   139
static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, 
sl@0
   140
	unsigned long frag_len);
sl@0
   141
static unsigned char *dtls1_write_message_header(SSL *s,
sl@0
   142
	unsigned char *p);
sl@0
   143
static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
sl@0
   144
	unsigned long len, unsigned short seq_num, unsigned long frag_off, 
sl@0
   145
	unsigned long frag_len);
sl@0
   146
static int dtls1_retransmit_buffered_messages(SSL *s);
sl@0
   147
static long dtls1_get_message_fragment(SSL *s, int st1, int stn, 
sl@0
   148
    long max, int *ok);
sl@0
   149
sl@0
   150
static hm_fragment *
sl@0
   151
dtls1_hm_fragment_new(unsigned long frag_len)
sl@0
   152
    {
sl@0
   153
    hm_fragment *frag = NULL;
sl@0
   154
    unsigned char *buf = NULL;
sl@0
   155
sl@0
   156
    frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
sl@0
   157
    if ( frag == NULL)
sl@0
   158
        return NULL;
sl@0
   159
sl@0
   160
	if (frag_len)
sl@0
   161
		{
sl@0
   162
		buf = (unsigned char *)OPENSSL_malloc(frag_len);
sl@0
   163
    if ( buf == NULL)
sl@0
   164
        {
sl@0
   165
        OPENSSL_free(frag);
sl@0
   166
        return NULL;
sl@0
   167
        }
sl@0
   168
		}
sl@0
   169
    
sl@0
   170
	/* zero length fragment gets zero frag->fragment */
sl@0
   171
    frag->fragment = buf;
sl@0
   172
sl@0
   173
    return frag;
sl@0
   174
    }
sl@0
   175
sl@0
   176
static void
sl@0
   177
dtls1_hm_fragment_free(hm_fragment *frag)
sl@0
   178
    {
sl@0
   179
	if (frag->fragment) OPENSSL_free(frag->fragment);
sl@0
   180
    OPENSSL_free(frag);
sl@0
   181
    }
sl@0
   182
sl@0
   183
/* send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or SSL3_RT_CHANGE_CIPHER_SPEC) */
sl@0
   184
int dtls1_do_write(SSL *s, int type)
sl@0
   185
	{
sl@0
   186
	int ret;
sl@0
   187
	int curr_mtu;
sl@0
   188
	unsigned int len, frag_off;
sl@0
   189
sl@0
   190
	/* AHA!  Figure out the MTU, and stick to the right size */
sl@0
   191
	if ( ! (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU))
sl@0
   192
        {
sl@0
   193
		s->d1->mtu = 
sl@0
   194
			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
sl@0
   195
sl@0
   196
		/* I've seen the kernel return bogus numbers when it doesn't know
sl@0
   197
		 * (initial write), so just make sure we have a reasonable number */
sl@0
   198
		if ( s->d1->mtu < dtls1_min_mtu())
sl@0
   199
			{
sl@0
   200
			s->d1->mtu = 0;
sl@0
   201
			s->d1->mtu = dtls1_guess_mtu(s->d1->mtu);
sl@0
   202
			BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, 
sl@0
   203
				s->d1->mtu, NULL);
sl@0
   204
			}
sl@0
   205
		}
sl@0
   206
#if 0 
sl@0
   207
	mtu = s->d1->mtu;
sl@0
   208
sl@0
   209
	fprintf(stderr, "using MTU = %d\n", mtu);
sl@0
   210
sl@0
   211
	mtu -= (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
sl@0
   212
sl@0
   213
	curr_mtu = mtu - BIO_wpending(SSL_get_wbio(s));
sl@0
   214
sl@0
   215
	if ( curr_mtu > 0)
sl@0
   216
		mtu = curr_mtu;
sl@0
   217
	else if ( ( ret = BIO_flush(SSL_get_wbio(s))) <= 0)
sl@0
   218
		return ret;
sl@0
   219
		
sl@0
   220
	if ( BIO_wpending(SSL_get_wbio(s)) + s->init_num >= mtu)
sl@0
   221
		{
sl@0
   222
		ret = BIO_flush(SSL_get_wbio(s));
sl@0
   223
		if ( ret <= 0)
sl@0
   224
			return ret;
sl@0
   225
		mtu = s->d1->mtu - (DTLS1_HM_HEADER_LENGTH + DTLS1_RT_HEADER_LENGTH);
sl@0
   226
		}
sl@0
   227
sl@0
   228
	OPENSSL_assert(mtu > 0);  /* should have something reasonable now */
sl@0
   229
sl@0
   230
#endif
sl@0
   231
sl@0
   232
	if ( s->init_off == 0  && type == SSL3_RT_HANDSHAKE)
sl@0
   233
		OPENSSL_assert(s->init_num == 
sl@0
   234
			(int)s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH);
sl@0
   235
sl@0
   236
	frag_off = 0;
sl@0
   237
	while( s->init_num)
sl@0
   238
		{
sl@0
   239
		curr_mtu = s->d1->mtu - BIO_wpending(SSL_get_wbio(s)) - 
sl@0
   240
			DTLS1_RT_HEADER_LENGTH;
sl@0
   241
sl@0
   242
		if ( curr_mtu <= DTLS1_HM_HEADER_LENGTH)
sl@0
   243
			{
sl@0
   244
			/* grr.. we could get an error if MTU picked was wrong */
sl@0
   245
			ret = BIO_flush(SSL_get_wbio(s));
sl@0
   246
			if ( ret <= 0)
sl@0
   247
				return ret;
sl@0
   248
			curr_mtu = s->d1->mtu - DTLS1_RT_HEADER_LENGTH;
sl@0
   249
			}
sl@0
   250
sl@0
   251
		if ( s->init_num > curr_mtu)
sl@0
   252
			len = curr_mtu;
sl@0
   253
		else
sl@0
   254
			len = s->init_num;
sl@0
   255
sl@0
   256
sl@0
   257
		/* XDTLS: this function is too long.  split out the CCS part */
sl@0
   258
		if ( type == SSL3_RT_HANDSHAKE)
sl@0
   259
			{
sl@0
   260
			if ( s->init_off != 0)
sl@0
   261
				{
sl@0
   262
				OPENSSL_assert(s->init_off > DTLS1_HM_HEADER_LENGTH);
sl@0
   263
				s->init_off -= DTLS1_HM_HEADER_LENGTH;
sl@0
   264
				s->init_num += DTLS1_HM_HEADER_LENGTH;
sl@0
   265
sl@0
   266
                /* write atleast DTLS1_HM_HEADER_LENGTH bytes */
sl@0
   267
				if ( len <= DTLS1_HM_HEADER_LENGTH)  
sl@0
   268
					len += DTLS1_HM_HEADER_LENGTH;
sl@0
   269
				}
sl@0
   270
			
sl@0
   271
			dtls1_fix_message_header(s, frag_off, 
sl@0
   272
				len - DTLS1_HM_HEADER_LENGTH);
sl@0
   273
sl@0
   274
			dtls1_write_message_header(s, (unsigned char *)&s->init_buf->data[s->init_off]);
sl@0
   275
sl@0
   276
			OPENSSL_assert(len >= DTLS1_HM_HEADER_LENGTH);
sl@0
   277
			}
sl@0
   278
sl@0
   279
		ret=dtls1_write_bytes(s,type,&s->init_buf->data[s->init_off],
sl@0
   280
			len);
sl@0
   281
		if (ret < 0)
sl@0
   282
			{
sl@0
   283
			/* might need to update MTU here, but we don't know
sl@0
   284
			 * which previous packet caused the failure -- so can't
sl@0
   285
			 * really retransmit anything.  continue as if everything
sl@0
   286
			 * is fine and wait for an alert to handle the
sl@0
   287
			 * retransmit 
sl@0
   288
			 */
sl@0
   289
			if ( BIO_ctrl(SSL_get_wbio(s),
sl@0
   290
				BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL))
sl@0
   291
				s->d1->mtu = BIO_ctrl(SSL_get_wbio(s),
sl@0
   292
					BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
sl@0
   293
			else
sl@0
   294
				return(-1);
sl@0
   295
			}
sl@0
   296
		else
sl@0
   297
			{
sl@0
   298
			
sl@0
   299
			/* bad if this assert fails, only part of the handshake
sl@0
   300
			 * message got sent.  but why would this happen? */
sl@0
   301
			OPENSSL_assert(len == (unsigned int)ret); 
sl@0
   302
			
sl@0
   303
			if (type == SSL3_RT_HANDSHAKE && ! s->d1->retransmitting)
sl@0
   304
				{
sl@0
   305
				/* should not be done for 'Hello Request's, but in that case
sl@0
   306
				 * we'll ignore the result anyway */
sl@0
   307
				unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off];
sl@0
   308
				const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
sl@0
   309
				int xlen;
sl@0
   310
sl@0
   311
				if (frag_off == 0 && s->client_version != DTLS1_BAD_VER)
sl@0
   312
					{
sl@0
   313
					/* reconstruct message header is if it
sl@0
   314
					 * is being sent in single fragment */
sl@0
   315
					*p++ = msg_hdr->type;
sl@0
   316
					l2n3(msg_hdr->msg_len,p);
sl@0
   317
					s2n (msg_hdr->seq,p);
sl@0
   318
					l2n3(0,p);
sl@0
   319
					l2n3(msg_hdr->msg_len,p);
sl@0
   320
					p  -= DTLS1_HM_HEADER_LENGTH;
sl@0
   321
					xlen = ret;
sl@0
   322
					}
sl@0
   323
				else
sl@0
   324
					{
sl@0
   325
					p  += DTLS1_HM_HEADER_LENGTH;
sl@0
   326
					xlen = ret - DTLS1_HM_HEADER_LENGTH;
sl@0
   327
					}
sl@0
   328
sl@0
   329
				ssl3_finish_mac(s, p, xlen);
sl@0
   330
				}
sl@0
   331
			
sl@0
   332
			if (ret == s->init_num)
sl@0
   333
				{
sl@0
   334
				if (s->msg_callback)
sl@0
   335
					s->msg_callback(1, s->version, type, s->init_buf->data, 
sl@0
   336
						(size_t)(s->init_off + s->init_num), s, 
sl@0
   337
						s->msg_callback_arg);
sl@0
   338
sl@0
   339
				s->init_off = 0;  /* done writing this message */
sl@0
   340
				s->init_num = 0;
sl@0
   341
				
sl@0
   342
				return(1);
sl@0
   343
				}
sl@0
   344
			s->init_off+=ret;
sl@0
   345
			s->init_num-=ret;
sl@0
   346
			frag_off += (ret -= DTLS1_HM_HEADER_LENGTH);
sl@0
   347
			}
sl@0
   348
		}
sl@0
   349
	return(0);
sl@0
   350
	}
sl@0
   351
sl@0
   352
sl@0
   353
/* Obtain handshake message of message type 'mt' (any if mt == -1),
sl@0
   354
 * maximum acceptable body length 'max'.
sl@0
   355
 * Read an entire handshake message.  Handshake messages arrive in
sl@0
   356
 * fragments.
sl@0
   357
 */
sl@0
   358
long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
sl@0
   359
	{
sl@0
   360
	int i, al;
sl@0
   361
	struct hm_header_st *msg_hdr;
sl@0
   362
sl@0
   363
	/* s3->tmp is used to store messages that are unexpected, caused
sl@0
   364
	 * by the absence of an optional handshake message */
sl@0
   365
	if (s->s3->tmp.reuse_message)
sl@0
   366
		{
sl@0
   367
		s->s3->tmp.reuse_message=0;
sl@0
   368
		if ((mt >= 0) && (s->s3->tmp.message_type != mt))
sl@0
   369
			{
sl@0
   370
			al=SSL_AD_UNEXPECTED_MESSAGE;
sl@0
   371
			SSLerr(SSL_F_DTLS1_GET_MESSAGE,SSL_R_UNEXPECTED_MESSAGE);
sl@0
   372
			goto f_err;
sl@0
   373
			}
sl@0
   374
		*ok=1;
sl@0
   375
		s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
sl@0
   376
		s->init_num = (int)s->s3->tmp.message_size;
sl@0
   377
		return s->init_num;
sl@0
   378
		}
sl@0
   379
	
sl@0
   380
	msg_hdr = &s->d1->r_msg_hdr;
sl@0
   381
	do
sl@0
   382
		{
sl@0
   383
		if ( msg_hdr->frag_off == 0)
sl@0
   384
			{
sl@0
   385
			/* s->d1->r_message_header.msg_len = 0; */
sl@0
   386
			memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
sl@0
   387
			}
sl@0
   388
sl@0
   389
		i = dtls1_get_message_fragment(s, st1, stn, max, ok);
sl@0
   390
		if ( i == DTLS1_HM_BAD_FRAGMENT ||
sl@0
   391
            i == DTLS1_HM_FRAGMENT_RETRY)  /* bad fragment received */
sl@0
   392
			continue;
sl@0
   393
		else if ( i <= 0 && !*ok)
sl@0
   394
			return i;
sl@0
   395
sl@0
   396
		/* Note that s->init_sum is used as a counter summing
sl@0
   397
		 * up fragments' lengths: as soon as they sum up to
sl@0
   398
		 * handshake packet length, we assume we have got all
sl@0
   399
		 * the fragments. Overlapping fragments would cause
sl@0
   400
		 * premature termination, so we don't expect overlaps.
sl@0
   401
		 * Well, handling overlaps would require something more
sl@0
   402
		 * drastic. Indeed, as it is now there is no way to
sl@0
   403
		 * tell if out-of-order fragment from the middle was
sl@0
   404
		 * the last. '>=' is the best/least we can do to control
sl@0
   405
		 * the potential damage caused by malformed overlaps. */
sl@0
   406
		if ((unsigned int)s->init_num >= msg_hdr->msg_len)
sl@0
   407
			{
sl@0
   408
			unsigned char *p = (unsigned char *)s->init_buf->data;
sl@0
   409
			unsigned long msg_len = msg_hdr->msg_len;
sl@0
   410
sl@0
   411
			/* reconstruct message header as if it was
sl@0
   412
			 * sent in single fragment */
sl@0
   413
			*(p++) = msg_hdr->type;
sl@0
   414
			l2n3(msg_len,p);
sl@0
   415
			s2n (msg_hdr->seq,p);
sl@0
   416
			l2n3(0,p);
sl@0
   417
			l2n3(msg_len,p);
sl@0
   418
			if (s->client_version != DTLS1_BAD_VER)
sl@0
   419
				p       -= DTLS1_HM_HEADER_LENGTH,
sl@0
   420
				msg_len += DTLS1_HM_HEADER_LENGTH;
sl@0
   421
sl@0
   422
			ssl3_finish_mac(s, p, msg_len);
sl@0
   423
			if (s->msg_callback)
sl@0
   424
				s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
sl@0
   425
					p, msg_len,
sl@0
   426
					s, s->msg_callback_arg);
sl@0
   427
sl@0
   428
			memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
sl@0
   429
sl@0
   430
			s->d1->handshake_read_seq++;
sl@0
   431
			/* we just read a handshake message from the other side:
sl@0
   432
			 * this means that we don't need to retransmit of the
sl@0
   433
			 * buffered messages.  
sl@0
   434
			 * XDTLS: may be able clear out this
sl@0
   435
			 * buffer a little sooner (i.e if an out-of-order
sl@0
   436
			 * handshake message/record is received at the record
sl@0
   437
			 * layer.  
sl@0
   438
			 * XDTLS: exception is that the server needs to
sl@0
   439
			 * know that change cipher spec and finished messages
sl@0
   440
			 * have been received by the client before clearing this
sl@0
   441
			 * buffer.  this can simply be done by waiting for the
sl@0
   442
			 * first data  segment, but is there a better way?  */
sl@0
   443
			dtls1_clear_record_buffer(s);
sl@0
   444
sl@0
   445
			s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
sl@0
   446
			return s->init_num;
sl@0
   447
			}
sl@0
   448
		else
sl@0
   449
			msg_hdr->frag_off = i;
sl@0
   450
		} while(1) ;
sl@0
   451
sl@0
   452
f_err:
sl@0
   453
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
sl@0
   454
	*ok = 0;
sl@0
   455
	return -1;
sl@0
   456
	}
sl@0
   457
sl@0
   458
sl@0
   459
static int dtls1_preprocess_fragment(SSL *s,struct hm_header_st *msg_hdr,int max)
sl@0
   460
	{
sl@0
   461
	size_t frag_off,frag_len,msg_len;
sl@0
   462
sl@0
   463
	msg_len  = msg_hdr->msg_len;
sl@0
   464
	frag_off = msg_hdr->frag_off;
sl@0
   465
	frag_len = msg_hdr->frag_len;
sl@0
   466
sl@0
   467
	/* sanity checking */
sl@0
   468
	if ( (frag_off+frag_len) > msg_len)
sl@0
   469
		{
sl@0
   470
		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
sl@0
   471
		return SSL_AD_ILLEGAL_PARAMETER;
sl@0
   472
		}
sl@0
   473
sl@0
   474
	if ( (frag_off+frag_len) > (unsigned long)max)
sl@0
   475
		{
sl@0
   476
		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
sl@0
   477
		return SSL_AD_ILLEGAL_PARAMETER;
sl@0
   478
		}
sl@0
   479
sl@0
   480
	if ( s->d1->r_msg_hdr.frag_off == 0) /* first fragment */
sl@0
   481
		{
sl@0
   482
		/* msg_len is limited to 2^24, but is effectively checked
sl@0
   483
		 * against max above */
sl@0
   484
		if (!BUF_MEM_grow_clean(s->init_buf,(int)msg_len+DTLS1_HM_HEADER_LENGTH))
sl@0
   485
			{
sl@0
   486
			SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,ERR_R_BUF_LIB);
sl@0
   487
			return SSL_AD_INTERNAL_ERROR;
sl@0
   488
			}
sl@0
   489
sl@0
   490
		s->s3->tmp.message_size  = msg_len;
sl@0
   491
		s->d1->r_msg_hdr.msg_len = msg_len;
sl@0
   492
		s->s3->tmp.message_type  = msg_hdr->type;
sl@0
   493
		s->d1->r_msg_hdr.type    = msg_hdr->type;
sl@0
   494
		s->d1->r_msg_hdr.seq     = msg_hdr->seq;
sl@0
   495
		}
sl@0
   496
	else if (msg_len != s->d1->r_msg_hdr.msg_len)
sl@0
   497
		{
sl@0
   498
		/* They must be playing with us! BTW, failure to enforce
sl@0
   499
		 * upper limit would open possibility for buffer overrun. */
sl@0
   500
		SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT,SSL_R_EXCESSIVE_MESSAGE_SIZE);
sl@0
   501
		return SSL_AD_ILLEGAL_PARAMETER;
sl@0
   502
		}
sl@0
   503
sl@0
   504
	return 0; /* no error */
sl@0
   505
	}
sl@0
   506
sl@0
   507
sl@0
   508
static int
sl@0
   509
dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
sl@0
   510
    {
sl@0
   511
    /* (0) check whether the desired fragment is available
sl@0
   512
     * if so:
sl@0
   513
     * (1) copy over the fragment to s->init_buf->data[]
sl@0
   514
     * (2) update s->init_num
sl@0
   515
     */
sl@0
   516
    pitem *item;
sl@0
   517
    hm_fragment *frag;
sl@0
   518
	int al;
sl@0
   519
sl@0
   520
	*ok = 0;
sl@0
   521
    item = pqueue_peek(s->d1->buffered_messages);
sl@0
   522
    if ( item == NULL)
sl@0
   523
        return 0;
sl@0
   524
sl@0
   525
    frag = (hm_fragment *)item->data;
sl@0
   526
    
sl@0
   527
	if ( s->d1->handshake_read_seq == frag->msg_header.seq)
sl@0
   528
        {
sl@0
   529
        pqueue_pop(s->d1->buffered_messages);
sl@0
   530
sl@0
   531
		al=dtls1_preprocess_fragment(s,&frag->msg_header,max);
sl@0
   532
sl@0
   533
		if (al==0) /* no alert */
sl@0
   534
			{
sl@0
   535
			unsigned char *p = (unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
sl@0
   536
			memcpy(&p[frag->msg_header.frag_off],
sl@0
   537
				frag->fragment,frag->msg_header.frag_len);
sl@0
   538
			}
sl@0
   539
sl@0
   540
		dtls1_hm_fragment_free(frag);
sl@0
   541
        pitem_free(item);
sl@0
   542
sl@0
   543
		if (al==0)
sl@0
   544
			{
sl@0
   545
			*ok = 1;
sl@0
   546
			return frag->msg_header.frag_len;
sl@0
   547
			}
sl@0
   548
sl@0
   549
		ssl3_send_alert(s,SSL3_AL_FATAL,al);
sl@0
   550
		s->init_num = 0;
sl@0
   551
		*ok = 0;
sl@0
   552
		return -1;
sl@0
   553
        }
sl@0
   554
    else
sl@0
   555
        return 0;
sl@0
   556
    }
sl@0
   557
sl@0
   558
sl@0
   559
static int
sl@0
   560
dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
sl@0
   561
{
sl@0
   562
	int i=-1;
sl@0
   563
    hm_fragment *frag = NULL;
sl@0
   564
    pitem *item = NULL;
sl@0
   565
	PQ_64BIT seq64;
sl@0
   566
	unsigned long frag_len = msg_hdr->frag_len;
sl@0
   567
sl@0
   568
	if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
sl@0
   569
		goto err;
sl@0
   570
sl@0
   571
	if (msg_hdr->seq <= s->d1->handshake_read_seq)
sl@0
   572
		{
sl@0
   573
		unsigned char devnull [256];
sl@0
   574
sl@0
   575
		while (frag_len)
sl@0
   576
			{
sl@0
   577
			i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
sl@0
   578
				devnull,
sl@0
   579
				frag_len>sizeof(devnull)?sizeof(devnull):frag_len,0);
sl@0
   580
			if (i<=0) goto err;
sl@0
   581
			frag_len -= i;
sl@0
   582
			}
sl@0
   583
		}
sl@0
   584
	frag = dtls1_hm_fragment_new(frag_len);
sl@0
   585
    if ( frag == NULL)
sl@0
   586
        goto err;
sl@0
   587
sl@0
   588
sl@0
   589
    memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
sl@0
   590
sl@0
   591
	if (frag_len)
sl@0
   592
		{
sl@0
   593
		/* read the body of the fragment (header has already been read */
sl@0
   594
		i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
sl@0
   595
			frag->fragment,frag_len,0);
sl@0
   596
		if (i<=0 || (unsigned long)i!=frag_len)
sl@0
   597
			goto err;
sl@0
   598
		}
sl@0
   599
    pq_64bit_init(&seq64);
sl@0
   600
    pq_64bit_assign_word(&seq64, msg_hdr->seq);
sl@0
   601
sl@0
   602
    item = pitem_new(seq64, frag);
sl@0
   603
	pq_64bit_free(&seq64);
sl@0
   604
    if ( item == NULL)
sl@0
   605
        goto err;
sl@0
   606
sl@0
   607
    pqueue_insert(s->d1->buffered_messages, item);
sl@0
   608
	return DTLS1_HM_FRAGMENT_RETRY;
sl@0
   609
sl@0
   610
err:
sl@0
   611
    if ( frag != NULL) dtls1_hm_fragment_free(frag);
sl@0
   612
    if ( item != NULL) OPENSSL_free(item);
sl@0
   613
	*ok = 0;
sl@0
   614
	return i;
sl@0
   615
	}
sl@0
   616
sl@0
   617
sl@0
   618
static long
sl@0
   619
dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
sl@0
   620
	{
sl@0
   621
	unsigned char wire[DTLS1_HM_HEADER_LENGTH];
sl@0
   622
	unsigned long l, frag_off, frag_len;
sl@0
   623
	int i,al;
sl@0
   624
	struct hm_header_st msg_hdr;
sl@0
   625
    
sl@0
   626
    /* see if we have the required fragment already */
sl@0
   627
	if ((frag_len = dtls1_retrieve_buffered_fragment(s,max,ok)) || *ok)
sl@0
   628
    {
sl@0
   629
		if (*ok)	s->init_num += frag_len;
sl@0
   630
		return frag_len;
sl@0
   631
    }
sl@0
   632
sl@0
   633
    /* read handshake message header */
sl@0
   634
	i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,wire,
sl@0
   635
		DTLS1_HM_HEADER_LENGTH, 0);
sl@0
   636
	if (i <= 0) 	/* nbio, or an error */
sl@0
   637
		{
sl@0
   638
		s->rwstate=SSL_READING;
sl@0
   639
		*ok = 0;
sl@0
   640
		return i;
sl@0
   641
		}
sl@0
   642
sl@0
   643
	OPENSSL_assert(i == DTLS1_HM_HEADER_LENGTH);
sl@0
   644
sl@0
   645
    /* parse the message fragment header */
sl@0
   646
    
sl@0
   647
	dtls1_get_message_header(wire, &msg_hdr);
sl@0
   648
sl@0
   649
    /* 
sl@0
   650
     * if this is a future (or stale) message it gets buffered
sl@0
   651
     * (or dropped)--no further processing at this time 
sl@0
   652
     */
sl@0
   653
    if ( msg_hdr.seq != s->d1->handshake_read_seq)
sl@0
   654
        return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
sl@0
   655
sl@0
   656
    l = msg_hdr.msg_len;
sl@0
   657
    frag_off = msg_hdr.frag_off;
sl@0
   658
	frag_len = msg_hdr.frag_len;
sl@0
   659
sl@0
   660
	if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
sl@0
   661
		wire[0] == SSL3_MT_HELLO_REQUEST)
sl@0
   662
        {
sl@0
   663
        /* The server may always send 'Hello Request' messages --
sl@0
   664
         * we are doing a handshake anyway now, so ignore them
sl@0
   665
         * if their format is correct. Does not count for
sl@0
   666
         * 'Finished' MAC. */
sl@0
   667
		if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0)
sl@0
   668
            {
sl@0
   669
            if (s->msg_callback)
sl@0
   670
                s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, 
sl@0
   671
					wire, DTLS1_HM_HEADER_LENGTH, s, 
sl@0
   672
                    s->msg_callback_arg);
sl@0
   673
            
sl@0
   674
            s->init_num = 0;
sl@0
   675
            return dtls1_get_message_fragment(s, st1, stn,
sl@0
   676
                max, ok);
sl@0
   677
            }
sl@0
   678
        else /* Incorrectly formated Hello request */
sl@0
   679
            {
sl@0
   680
            al=SSL_AD_UNEXPECTED_MESSAGE;
sl@0
   681
            SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,SSL_R_UNEXPECTED_MESSAGE);
sl@0
   682
            goto f_err;
sl@0
   683
            }
sl@0
   684
        }
sl@0
   685
sl@0
   686
	if ((al=dtls1_preprocess_fragment(s,&msg_hdr,max)))
sl@0
   687
		goto f_err;
sl@0
   688
sl@0
   689
	/* XDTLS:  ressurect this when restart is in place */
sl@0
   690
	s->state=stn;
sl@0
   691
sl@0
   692
	if ( frag_len > 0)
sl@0
   693
		{
sl@0
   694
		unsigned char *p=(unsigned char *)s->init_buf->data+DTLS1_HM_HEADER_LENGTH;
sl@0
   695
sl@0
   696
		i=s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
sl@0
   697
			&p[frag_off],frag_len,0);
sl@0
   698
        /* XDTLS:  fix this--message fragments cannot span multiple packets */
sl@0
   699
		if (i <= 0)
sl@0
   700
			{
sl@0
   701
			s->rwstate=SSL_READING;
sl@0
   702
			*ok = 0;
sl@0
   703
			return i;
sl@0
   704
			}
sl@0
   705
		}
sl@0
   706
	else
sl@0
   707
		i = 0;
sl@0
   708
sl@0
   709
    /* XDTLS:  an incorrectly formatted fragment should cause the 
sl@0
   710
     * handshake to fail */
sl@0
   711
	OPENSSL_assert(i == (int)frag_len);
sl@0
   712
sl@0
   713
	*ok = 1;
sl@0
   714
sl@0
   715
	/* Note that s->init_num is *not* used as current offset in
sl@0
   716
	 * s->init_buf->data, but as a counter summing up fragments'
sl@0
   717
	 * lengths: as soon as they sum up to handshake packet
sl@0
   718
	 * length, we assume we have got all the fragments. */
sl@0
   719
	s->init_num += frag_len;
sl@0
   720
	return frag_len;
sl@0
   721
sl@0
   722
f_err:
sl@0
   723
	ssl3_send_alert(s,SSL3_AL_FATAL,al);
sl@0
   724
    s->init_num = 0;
sl@0
   725
sl@0
   726
	*ok=0;
sl@0
   727
	return(-1);
sl@0
   728
	}
sl@0
   729
sl@0
   730
int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
sl@0
   731
	{
sl@0
   732
	unsigned char *p,*d;
sl@0
   733
	int i;
sl@0
   734
	unsigned long l;
sl@0
   735
sl@0
   736
	if (s->state == a)
sl@0
   737
		{
sl@0
   738
		d=(unsigned char *)s->init_buf->data;
sl@0
   739
		p= &(d[DTLS1_HM_HEADER_LENGTH]);
sl@0
   740
sl@0
   741
		i=s->method->ssl3_enc->final_finish_mac(s,
sl@0
   742
			&(s->s3->finish_dgst1),
sl@0
   743
			&(s->s3->finish_dgst2),
sl@0
   744
			sender,slen,s->s3->tmp.finish_md);
sl@0
   745
		s->s3->tmp.finish_md_len = i;
sl@0
   746
		memcpy(p, s->s3->tmp.finish_md, i);
sl@0
   747
		p+=i;
sl@0
   748
		l=i;
sl@0
   749
sl@0
   750
#ifdef OPENSSL_SYS_WIN16
sl@0
   751
		/* MSVC 1.5 does not clear the top bytes of the word unless
sl@0
   752
		 * I do this.
sl@0
   753
		 */
sl@0
   754
		l&=0xffff;
sl@0
   755
#endif
sl@0
   756
sl@0
   757
		d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
sl@0
   758
		s->init_num=(int)l+DTLS1_HM_HEADER_LENGTH;
sl@0
   759
		s->init_off=0;
sl@0
   760
sl@0
   761
		/* buffer the message to handle re-xmits */
sl@0
   762
		dtls1_buffer_message(s, 0);
sl@0
   763
		
sl@0
   764
		s->state=b;
sl@0
   765
		}
sl@0
   766
sl@0
   767
	/* SSL3_ST_SEND_xxxxxx_HELLO_B */
sl@0
   768
	return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
sl@0
   769
	}
sl@0
   770
sl@0
   771
/* for these 2 messages, we need to
sl@0
   772
 * ssl->enc_read_ctx			re-init
sl@0
   773
 * ssl->s3->read_sequence		zero
sl@0
   774
 * ssl->s3->read_mac_secret		re-init
sl@0
   775
 * ssl->session->read_sym_enc		assign
sl@0
   776
 * ssl->session->read_compression	assign
sl@0
   777
 * ssl->session->read_hash		assign
sl@0
   778
 */
sl@0
   779
int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
sl@0
   780
	{ 
sl@0
   781
	unsigned char *p;
sl@0
   782
sl@0
   783
	if (s->state == a)
sl@0
   784
		{
sl@0
   785
		p=(unsigned char *)s->init_buf->data;
sl@0
   786
		*p++=SSL3_MT_CCS;
sl@0
   787
		s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
sl@0
   788
		s->init_num=DTLS1_CCS_HEADER_LENGTH;
sl@0
   789
sl@0
   790
		if (s->client_version == DTLS1_BAD_VER)
sl@0
   791
			{
sl@0
   792
			s->d1->next_handshake_write_seq++;
sl@0
   793
			s2n(s->d1->handshake_write_seq,p);
sl@0
   794
			s->init_num+=2;
sl@0
   795
			}
sl@0
   796
sl@0
   797
		s->init_off=0;
sl@0
   798
sl@0
   799
		dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, 
sl@0
   800
			s->d1->handshake_write_seq, 0, 0);
sl@0
   801
sl@0
   802
		/* buffer the message to handle re-xmits */
sl@0
   803
		dtls1_buffer_message(s, 1);
sl@0
   804
sl@0
   805
		s->state=b;
sl@0
   806
		}
sl@0
   807
sl@0
   808
	/* SSL3_ST_CW_CHANGE_B */
sl@0
   809
	return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
sl@0
   810
	}
sl@0
   811
sl@0
   812
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
sl@0
   813
	{
sl@0
   814
	unsigned char *p;
sl@0
   815
	int n,i;
sl@0
   816
	unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
sl@0
   817
	BUF_MEM *buf;
sl@0
   818
	X509_STORE_CTX xs_ctx;
sl@0
   819
	X509_OBJECT obj;
sl@0
   820
sl@0
   821
	/* TLSv1 sends a chain with nothing in it, instead of an alert */
sl@0
   822
	buf=s->init_buf;
sl@0
   823
	if (!BUF_MEM_grow_clean(buf,10))
sl@0
   824
		{
sl@0
   825
		SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
sl@0
   826
		return(0);
sl@0
   827
		}
sl@0
   828
	if (x != NULL)
sl@0
   829
		{
sl@0
   830
		if(!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,NULL,NULL))
sl@0
   831
			{
sl@0
   832
			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
sl@0
   833
			return(0);
sl@0
   834
			}
sl@0
   835
sl@0
   836
		for (;;)
sl@0
   837
			{
sl@0
   838
			n=i2d_X509(x,NULL);
sl@0
   839
			if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
sl@0
   840
				{
sl@0
   841
				SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
sl@0
   842
				return(0);
sl@0
   843
				}
sl@0
   844
			p=(unsigned char *)&(buf->data[l]);
sl@0
   845
			l2n3(n,p);
sl@0
   846
			i2d_X509(x,&p);
sl@0
   847
			l+=n+3;
sl@0
   848
			if (X509_NAME_cmp(X509_get_subject_name(x),
sl@0
   849
				X509_get_issuer_name(x)) == 0) break;
sl@0
   850
sl@0
   851
			i=X509_STORE_get_by_subject(&xs_ctx,X509_LU_X509,
sl@0
   852
				X509_get_issuer_name(x),&obj);
sl@0
   853
			if (i <= 0) break;
sl@0
   854
			x=obj.data.x509;
sl@0
   855
			/* Count is one too high since the X509_STORE_get uped the
sl@0
   856
			 * ref count */
sl@0
   857
			X509_free(x);
sl@0
   858
			}
sl@0
   859
sl@0
   860
		X509_STORE_CTX_cleanup(&xs_ctx);
sl@0
   861
		}
sl@0
   862
sl@0
   863
	/* Thawte special :-) */
sl@0
   864
	if (s->ctx->extra_certs != NULL)
sl@0
   865
	for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
sl@0
   866
		{
sl@0
   867
		x=sk_X509_value(s->ctx->extra_certs,i);
sl@0
   868
		n=i2d_X509(x,NULL);
sl@0
   869
		if (!BUF_MEM_grow_clean(buf,(int)(n+l+3)))
sl@0
   870
			{
sl@0
   871
			SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
sl@0
   872
			return(0);
sl@0
   873
			}
sl@0
   874
		p=(unsigned char *)&(buf->data[l]);
sl@0
   875
		l2n3(n,p);
sl@0
   876
		i2d_X509(x,&p);
sl@0
   877
		l+=n+3;
sl@0
   878
		}
sl@0
   879
sl@0
   880
	l-= (3 + DTLS1_HM_HEADER_LENGTH);
sl@0
   881
sl@0
   882
	p=(unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
sl@0
   883
	l2n3(l,p);
sl@0
   884
	l+=3;
sl@0
   885
	p=(unsigned char *)&(buf->data[0]);
sl@0
   886
	p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);
sl@0
   887
sl@0
   888
	l+=DTLS1_HM_HEADER_LENGTH;
sl@0
   889
	return(l);
sl@0
   890
	}
sl@0
   891
sl@0
   892
int dtls1_read_failed(SSL *s, int code)
sl@0
   893
    {
sl@0
   894
    DTLS1_STATE *state;
sl@0
   895
    BIO *bio;
sl@0
   896
    int send_alert = 0;
sl@0
   897
sl@0
   898
    if ( code > 0)
sl@0
   899
        {
sl@0
   900
        fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
sl@0
   901
        return 1;
sl@0
   902
        }
sl@0
   903
sl@0
   904
    bio = SSL_get_rbio(s);
sl@0
   905
    if ( ! BIO_dgram_recv_timedout(bio))
sl@0
   906
        {
sl@0
   907
        /* not a timeout, none of our business, 
sl@0
   908
           let higher layers handle this.  in fact it's probably an error */
sl@0
   909
        return code;
sl@0
   910
        }
sl@0
   911
sl@0
   912
    if ( ! SSL_in_init(s))  /* done, no need to send a retransmit */
sl@0
   913
        {
sl@0
   914
        BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
sl@0
   915
        return code;
sl@0
   916
        }
sl@0
   917
sl@0
   918
    state = s->d1;
sl@0
   919
    state->timeout.num_alerts++;
sl@0
   920
    if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
sl@0
   921
        {
sl@0
   922
        /* fail the connection, enough alerts have been sent */
sl@0
   923
        SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED);
sl@0
   924
        return 0;
sl@0
   925
        }
sl@0
   926
	
sl@0
   927
    state->timeout.read_timeouts++;
sl@0
   928
    if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
sl@0
   929
        {
sl@0
   930
        send_alert = 1;
sl@0
   931
        state->timeout.read_timeouts = 1;
sl@0
   932
        }
sl@0
   933
sl@0
   934
	
sl@0
   935
#if 0 /* for now, each alert contains only one record number */
sl@0
   936
    item = pqueue_peek(state->rcvd_records);
sl@0
   937
    if ( item )
sl@0
   938
        {
sl@0
   939
        /* send an alert immediately for all the missing records */
sl@0
   940
        }
sl@0
   941
    else
sl@0
   942
#endif
sl@0
   943
sl@0
   944
#if 0  /* no more alert sending, just retransmit the last set of messages */
sl@0
   945
        if ( send_alert)
sl@0
   946
            ssl3_send_alert(s,SSL3_AL_WARNING,
sl@0
   947
                DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
sl@0
   948
#endif
sl@0
   949
sl@0
   950
    return dtls1_retransmit_buffered_messages(s) ;
sl@0
   951
    }
sl@0
   952
sl@0
   953
sl@0
   954
static int
sl@0
   955
dtls1_retransmit_buffered_messages(SSL *s)
sl@0
   956
    {
sl@0
   957
    pqueue sent = s->d1->sent_messages;
sl@0
   958
    piterator iter;
sl@0
   959
    pitem *item;
sl@0
   960
    hm_fragment *frag;
sl@0
   961
    int found = 0;
sl@0
   962
sl@0
   963
    iter = pqueue_iterator(sent);
sl@0
   964
sl@0
   965
    for ( item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter))
sl@0
   966
        {
sl@0
   967
        frag = (hm_fragment *)item->data;
sl@0
   968
        if ( dtls1_retransmit_message(s, frag->msg_header.seq, 0, &found) <= 0 &&
sl@0
   969
            found)
sl@0
   970
            {
sl@0
   971
            fprintf(stderr, "dtls1_retransmit_message() failed\n");
sl@0
   972
            return -1;
sl@0
   973
            }
sl@0
   974
        }
sl@0
   975
sl@0
   976
    return 1;
sl@0
   977
    }
sl@0
   978
sl@0
   979
sl@0
   980
int
sl@0
   981
dtls1_buffer_message(SSL *s, int is_ccs)
sl@0
   982
    {
sl@0
   983
    pitem *item;
sl@0
   984
    hm_fragment *frag;
sl@0
   985
	PQ_64BIT seq64;
sl@0
   986
	unsigned int epoch = s->d1->w_epoch;
sl@0
   987
sl@0
   988
    /* this function is called immediately after a message has 
sl@0
   989
     * been serialized */
sl@0
   990
    OPENSSL_assert(s->init_off == 0);
sl@0
   991
sl@0
   992
    frag = dtls1_hm_fragment_new(s->init_num);
sl@0
   993
sl@0
   994
    memcpy(frag->fragment, s->init_buf->data, s->init_num);
sl@0
   995
sl@0
   996
    if ( is_ccs)
sl@0
   997
        {
sl@0
   998
        OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
sl@0
   999
			DTLS1_CCS_HEADER_LENGTH <= (unsigned int)s->init_num);
sl@0
  1000
		epoch++;
sl@0
  1001
        }
sl@0
  1002
    else
sl@0
  1003
        {
sl@0
  1004
        OPENSSL_assert(s->d1->w_msg_hdr.msg_len + 
sl@0
  1005
            DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
sl@0
  1006
        }
sl@0
  1007
sl@0
  1008
    frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
sl@0
  1009
    frag->msg_header.seq = s->d1->w_msg_hdr.seq;
sl@0
  1010
    frag->msg_header.type = s->d1->w_msg_hdr.type;
sl@0
  1011
    frag->msg_header.frag_off = 0;
sl@0
  1012
    frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
sl@0
  1013
    frag->msg_header.is_ccs = is_ccs;
sl@0
  1014
sl@0
  1015
    pq_64bit_init(&seq64);
sl@0
  1016
	pq_64bit_assign_word(&seq64, epoch<<16 | frag->msg_header.seq);
sl@0
  1017
sl@0
  1018
    item = pitem_new(seq64, frag);
sl@0
  1019
    pq_64bit_free(&seq64);
sl@0
  1020
    if ( item == NULL)
sl@0
  1021
        {
sl@0
  1022
        dtls1_hm_fragment_free(frag);
sl@0
  1023
        return 0;
sl@0
  1024
        }
sl@0
  1025
sl@0
  1026
#if 0
sl@0
  1027
    fprintf( stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
sl@0
  1028
    fprintf( stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
sl@0
  1029
    fprintf( stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
sl@0
  1030
#endif
sl@0
  1031
sl@0
  1032
    pqueue_insert(s->d1->sent_messages, item);
sl@0
  1033
    return 1;
sl@0
  1034
    }
sl@0
  1035
sl@0
  1036
int
sl@0
  1037
dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
sl@0
  1038
    int *found)
sl@0
  1039
    {
sl@0
  1040
    int ret;
sl@0
  1041
    /* XDTLS: for now assuming that read/writes are blocking */
sl@0
  1042
    pitem *item;
sl@0
  1043
    hm_fragment *frag ;
sl@0
  1044
    unsigned long header_length;
sl@0
  1045
	PQ_64BIT seq64;
sl@0
  1046
sl@0
  1047
    /*
sl@0
  1048
      OPENSSL_assert(s->init_num == 0);
sl@0
  1049
      OPENSSL_assert(s->init_off == 0);
sl@0
  1050
     */
sl@0
  1051
sl@0
  1052
    /* XDTLS:  the requested message ought to be found, otherwise error */
sl@0
  1053
    pq_64bit_init(&seq64);
sl@0
  1054
    pq_64bit_assign_word(&seq64, seq);
sl@0
  1055
sl@0
  1056
    item = pqueue_find(s->d1->sent_messages, seq64);
sl@0
  1057
    pq_64bit_free(&seq64);
sl@0
  1058
    if ( item == NULL)
sl@0
  1059
        {
sl@0
  1060
        fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
sl@0
  1061
        *found = 0;
sl@0
  1062
        return 0;
sl@0
  1063
        }
sl@0
  1064
sl@0
  1065
    *found = 1;
sl@0
  1066
    frag = (hm_fragment *)item->data;
sl@0
  1067
sl@0
  1068
    if ( frag->msg_header.is_ccs)
sl@0
  1069
        header_length = DTLS1_CCS_HEADER_LENGTH;
sl@0
  1070
    else
sl@0
  1071
        header_length = DTLS1_HM_HEADER_LENGTH;
sl@0
  1072
sl@0
  1073
    memcpy(s->init_buf->data, frag->fragment, 
sl@0
  1074
        frag->msg_header.msg_len + header_length);
sl@0
  1075
        s->init_num = frag->msg_header.msg_len + header_length;
sl@0
  1076
    
sl@0
  1077
    dtls1_set_message_header_int(s, frag->msg_header.type, 
sl@0
  1078
        frag->msg_header.msg_len, frag->msg_header.seq, 0, 
sl@0
  1079
        frag->msg_header.frag_len);
sl@0
  1080
sl@0
  1081
    s->d1->retransmitting = 1;
sl@0
  1082
    ret = dtls1_do_write(s, frag->msg_header.is_ccs ? 
sl@0
  1083
        SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
sl@0
  1084
    s->d1->retransmitting = 0;
sl@0
  1085
sl@0
  1086
	(void)BIO_flush(SSL_get_wbio(s));
sl@0
  1087
    return ret;
sl@0
  1088
    }
sl@0
  1089
sl@0
  1090
/* call this function when the buffered messages are no longer needed */
sl@0
  1091
void
sl@0
  1092
dtls1_clear_record_buffer(SSL *s)
sl@0
  1093
    {
sl@0
  1094
    pitem *item;
sl@0
  1095
    
sl@0
  1096
    for(item = pqueue_pop(s->d1->sent_messages);
sl@0
  1097
        item != NULL; item = pqueue_pop(s->d1->sent_messages))
sl@0
  1098
        {
sl@0
  1099
        dtls1_hm_fragment_free((hm_fragment *)item->data);
sl@0
  1100
        pitem_free(item);
sl@0
  1101
        }
sl@0
  1102
    }
sl@0
  1103
sl@0
  1104
sl@0
  1105
unsigned char *
sl@0
  1106
dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt,
sl@0
  1107
    unsigned long len, unsigned long frag_off, unsigned long frag_len)
sl@0
  1108
    {
sl@0
  1109
    if ( frag_off == 0)
sl@0
  1110
        {
sl@0
  1111
        s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
sl@0
  1112
        s->d1->next_handshake_write_seq++;
sl@0
  1113
        }
sl@0
  1114
    
sl@0
  1115
    dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
sl@0
  1116
        frag_off, frag_len);
sl@0
  1117
    
sl@0
  1118
    return p += DTLS1_HM_HEADER_LENGTH;
sl@0
  1119
    }
sl@0
  1120
sl@0
  1121
sl@0
  1122
/* don't actually do the writing, wait till the MTU has been retrieved */
sl@0
  1123
static void
sl@0
  1124
dtls1_set_message_header_int(SSL *s, unsigned char mt,
sl@0
  1125
    unsigned long len, unsigned short seq_num, unsigned long frag_off, 
sl@0
  1126
    unsigned long frag_len)
sl@0
  1127
    {
sl@0
  1128
    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
sl@0
  1129
    
sl@0
  1130
    msg_hdr->type = mt;
sl@0
  1131
    msg_hdr->msg_len = len;
sl@0
  1132
    msg_hdr->seq = seq_num;
sl@0
  1133
    msg_hdr->frag_off = frag_off;
sl@0
  1134
    msg_hdr->frag_len = frag_len;
sl@0
  1135
}
sl@0
  1136
sl@0
  1137
static void
sl@0
  1138
dtls1_fix_message_header(SSL *s, unsigned long frag_off,
sl@0
  1139
	unsigned long frag_len)
sl@0
  1140
    {
sl@0
  1141
    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
sl@0
  1142
    
sl@0
  1143
    msg_hdr->frag_off = frag_off;
sl@0
  1144
    msg_hdr->frag_len = frag_len;
sl@0
  1145
    }
sl@0
  1146
sl@0
  1147
static unsigned char *
sl@0
  1148
dtls1_write_message_header(SSL *s, unsigned char *p)
sl@0
  1149
    {
sl@0
  1150
    struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
sl@0
  1151
    
sl@0
  1152
    *p++ = msg_hdr->type;
sl@0
  1153
    l2n3(msg_hdr->msg_len, p);
sl@0
  1154
    
sl@0
  1155
    s2n(msg_hdr->seq, p);
sl@0
  1156
    l2n3(msg_hdr->frag_off, p);
sl@0
  1157
    l2n3(msg_hdr->frag_len, p);
sl@0
  1158
    
sl@0
  1159
    return p;
sl@0
  1160
    }
sl@0
  1161
sl@0
  1162
static unsigned int 
sl@0
  1163
dtls1_min_mtu(void)
sl@0
  1164
    {
sl@0
  1165
	return (g_probable_mtu[(sizeof(g_probable_mtu) / 
sl@0
  1166
		sizeof(g_probable_mtu[0])) - 1]);
sl@0
  1167
    }
sl@0
  1168
sl@0
  1169
static unsigned int 
sl@0
  1170
dtls1_guess_mtu(unsigned int curr_mtu)
sl@0
  1171
	{
sl@0
  1172
	size_t i;
sl@0
  1173
sl@0
  1174
	if ( curr_mtu == 0 )
sl@0
  1175
		return g_probable_mtu[0] ;
sl@0
  1176
sl@0
  1177
	for ( i = 0; i < sizeof(g_probable_mtu)/sizeof(g_probable_mtu[0]); i++)
sl@0
  1178
		if ( curr_mtu > g_probable_mtu[i])
sl@0
  1179
			return g_probable_mtu[i];
sl@0
  1180
	
sl@0
  1181
	return curr_mtu;
sl@0
  1182
	}
sl@0
  1183
sl@0
  1184
void
sl@0
  1185
dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
sl@0
  1186
    {
sl@0
  1187
    memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
sl@0
  1188
    msg_hdr->type = *(data++);
sl@0
  1189
    n2l3(data, msg_hdr->msg_len);
sl@0
  1190
    
sl@0
  1191
    n2s(data, msg_hdr->seq);
sl@0
  1192
    n2l3(data, msg_hdr->frag_off);
sl@0
  1193
    n2l3(data, msg_hdr->frag_len);
sl@0
  1194
    }
sl@0
  1195
sl@0
  1196
void
sl@0
  1197
dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
sl@0
  1198
    {
sl@0
  1199
    memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));
sl@0
  1200
    
sl@0
  1201
    ccs_hdr->type = *(data++);
sl@0
  1202
}