static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
unsigned int len, int create_empty_fragment);
-static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
- unsigned int len);
static int ssl3_get_record(SSL *s);
-static int do_compress(SSL *ssl);
-static int do_uncompress(SSL *ssl);
-static int do_change_cipher_spec(SSL *ssl);
-/* used only by ssl3_get_record */
-static int ssl3_read_n(SSL *s, int n, int max, int extend)
+int ssl3_read_n(SSL *s, int n, int max, int extend)
{
/* If extend == 0, obtain new n-byte packet; if extend == 1, increase
* packet by another n bytes.
/* ... now we can act as if 'extend' was set */
}
+ /* extend reads should not span multiple packets for DTLS */
+ if ( SSL_version(s) == DTLS1_VERSION &&
+ extend)
+ {
+ if ( s->s3->rbuf.left > 0 && n > s->s3->rbuf.left)
+ n = s->s3->rbuf.left;
+ }
+
/* if there is enough in the buffer from a previous read, take some */
if (s->s3->rbuf.left >= (int)n)
{
extra=SSL3_RT_MAX_EXTRA;
else
extra=0;
- if (extra != s->s3->rbuf.len - SSL3_RT_MAX_PACKET_SIZE)
+ if (extra && !s->s3->init_extra)
{
- /* actually likely an application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
+ /* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
* set after ssl3_setup_buffers() was done */
SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR);
return -1;
ssl_minor= *(p++);
version=(ssl_major<<8)|ssl_minor;
n2s(p,rr->length);
+#if 0
+fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
+#endif
/* Lets check version */
if (s->first_packet)
goto err;
}
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH+extra)
+ if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG);
SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_COMPRESSED_LENGTH_TOO_LONG);
goto f_err;
}
- if (!do_uncompress(s))
+ if (!ssl3_do_uncompress(s))
{
al=SSL_AD_DECOMPRESSION_FAILURE;
SSLerr(SSL_F_SSL3_GET_RECORD,SSL_R_BAD_DECOMPRESSION);
/* just read a 0 length packet */
if (rr->length == 0) goto again;
+#if 0
+fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, rr->length);
+#endif
+
return(1);
f_err:
return(ret);
}
-static int do_uncompress(SSL *ssl)
+int ssl3_do_uncompress(SSL *ssl)
{
+#ifndef OPENSSL_NO_COMP
int i;
SSL3_RECORD *rr;
else
rr->length=i;
rr->data=rr->comp;
-
+#endif
return(1);
}
-static int do_compress(SSL *ssl)
+int ssl3_do_compress(SSL *ssl)
{
+#ifndef OPENSSL_NO_COMP
int i;
SSL3_RECORD *wr;
wr->length=i;
wr->input=wr->data;
+#endif
return(1);
}
n=(len-tot);
for (;;)
{
- if (n > SSL3_RT_MAX_PLAIN_LENGTH)
- nw=SSL3_RT_MAX_PLAIN_LENGTH;
+ if (n > s->max_send_fragment)
+ nw=s->max_send_fragment;
else
nw=n;
/* If we have an alert to send, lets send it */
if (s->s3->alert_dispatch)
{
- i=ssl3_dispatch_alert(s);
+ i=s->method->ssl_dispatch_alert(s);
if (i <= 0)
return(i);
/* if it went, fall through and send more stuff */
if (prefix_len <= 0)
goto err;
- if (s->s3->wbuf.len < (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE)
+ if (prefix_len >
+ (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD))
{
/* insufficient space */
SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
/* first we compress */
if (s->compress != NULL)
{
- if (!do_compress(s))
+ if (!ssl3_do_compress(s))
{
SSLerr(SSL_F_DO_SSL3_WRITE,SSL_R_COMPRESSION_FAILURE);
goto err;
}
/* if s->s3->wbuf.left != 0, we need to call this */
-static int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
- unsigned int len)
+int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
+ unsigned int len)
{
int i;
goto f_err;
}
+ /* Check we have a cipher to change to */
+ if (s->s3->tmp.new_cipher == NULL)
+ {
+ al=SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES,SSL_R_CCS_RECEIVED_EARLY);
+ goto f_err;
+ }
+
rr->length=0;
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data, 1, s, s->msg_callback_arg);
s->s3->change_cipher_spec=1;
- if (!do_change_cipher_spec(s))
+ if (!ssl3_do_change_cipher_spec(s))
goto err;
else
goto start;
return(-1);
}
-static int do_change_cipher_spec(SSL *s)
+int ssl3_do_change_cipher_spec(SSL *s)
{
int i;
const char *sender;
s->s3->send_alert[0]=level;
s->s3->send_alert[1]=desc;
if (s->s3->wbuf.left == 0) /* data still being written out? */
- ssl3_dispatch_alert(s);
+ s->method->ssl_dispatch_alert(s);
/* else data is still being written out, we will get written
* some time in the future */
}