@@ -0,0 +1,95 @@
/* ====================================================================
* Copyright (c) 2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/


#include <openssl/e_os2.h>
#include <evp.h>
#include "ui_locl.h"
#include "cryptlib.h"

#ifdef OPENSSL_NO_TTY

static int dummy_read_write_string(UI *ui, UI_STRING *uis);
static int dummy_open_close(UI *ui);

static UI_METHOD ui_dummy =
{
"Dummy user interface",
dummy_open_close,
dummy_read_write_string,
NULL,
dummy_read_write_string,
dummy_open_close,
NULL
};

UI_METHOD *UI_OpenSSL(void)
{
return &ui_dummy;
}

static int dummy_open_close(UI *ui)
{
/* Pretend that opening and closing the dummy UI succeeds. */
return 1;
}

static int dummy_read_write_string(UI *ui, UI_STRING *uis)
{
/* Writing to and reading from the dummy UI is not possible. */
return 0;
}


#endif
@@ -114,6 +114,7 @@
* [including the GNU Public Licence.]
*/

#ifndef OPENSSL_NO_TTY

#include <openssl/e_os2.h>

@@ -184,7 +185,7 @@
# undef SGTTY
#endif

#if defined(linux) && !defined(TERMIO)
#if defined(linux) && !defined(TERMIO) && !defined(__ANDROID__)
# undef TERMIOS
# define TERMIO
# undef SGTTY
@@ -710,3 +711,5 @@ static int noecho_fgets(char *buf, int size, FILE *tty)
return(strlen(buf));
}
#endif

#endif
@@ -287,6 +287,8 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
int ok=0;
int i,j,k;
unsigned long h;
unsigned long hash_array[2];
int hash_index;
BUF_MEM *b=NULL;
X509_OBJECT stmp,*tmp;
const char *postfix="";
@@ -323,6 +325,11 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
ctx=(BY_DIR *)xl->method_data;

h=X509_NAME_hash(name);
hash_array[0]=h;
hash_array[1]=X509_NAME_hash_old(name);
for (hash_index=0; hash_index < 2; hash_index++)
{
h=hash_array[hash_index];
for (i=0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++)
{
BY_DIR_ENTRY *ent;
@@ -476,6 +483,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
goto finish;
}
}
}
finish:
if (b != NULL) BUF_MEM_free(b);
return(ok);
@@ -789,6 +789,12 @@ int dtls1_client_hello(SSL *s)
#endif
(s->session->not_resumable))
{
if (!s->session_creation_enabled)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
goto err;
}
if (!ssl_get_new_session(s,0))
goto err;
}
@@ -614,6 +614,24 @@ int dtls1_get_record(SSL *s)
goto again;
}

/* If we receive a valid record larger than the current buffer size,
* allocate some memory for it.
*/
if (rr->length > s->s3->rbuf.len - DTLS1_RT_HEADER_LENGTH)
{
unsigned char *pp;
unsigned int newlen = rr->length + DTLS1_RT_HEADER_LENGTH;
if ((pp=OPENSSL_realloc(s->s3->rbuf.buf, newlen))==NULL)
{
SSLerr(SSL_F_DTLS1_GET_RECORD,ERR_R_MALLOC_FAILURE);
return(-1);
}
p = pp + (p - s->s3->rbuf.buf);
s->s3->rbuf.buf=pp;
s->s3->rbuf.len=newlen;
s->packet= &(s->s3->rbuf.buf[0]);
}

/* now s->rstate == SSL_ST_READ_BODY */
}

@@ -1452,6 +1470,7 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
SSL3_BUFFER *wb;
SSL_SESSION *sess;
int bs;
unsigned int len_with_overhead = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;

/* first check if there is a SSL3_BUFFER still being written
* out. This will happen with non blocking IO */
@@ -1461,6 +1480,16 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len,
return(ssl3_write_pending(s,type,buf,len));
}

if (s->s3->wbuf.len < len_with_overhead)
{
if ((p=OPENSSL_realloc(s->s3->wbuf.buf, len_with_overhead)) == NULL) {
SSLerr(SSL_F_DO_DTLS1_WRITE,ERR_R_MALLOC_FAILURE);
goto err;
}
s->s3->wbuf.buf = p;
s->s3->wbuf.len = len_with_overhead;
}

/* If we have an alert to send, lets send it */
if (s->s3->alert_dispatch)
{
@@ -770,6 +770,13 @@ static int ssl23_get_server_hello(SSL *s)

/* Since, if we are sending a ssl23 client hello, we are not
* reusing a session-id */
if (!s->session_creation_enabled)
{
if (!(s->client_version == SSL2_VERSION))
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
goto err;
}
if (!ssl_get_new_session(s,0))
goto err;

@@ -444,8 +444,13 @@ int ssl23_get_client_hello(SSL *s)
v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
v[1] = p[4];

/* The SSL2 protocol allows n to be larger, just pick
* a reasonable buffer size. */
#if SSL3_RT_DEFAULT_PACKET_SIZE < 1024*4 - SSL3_RT_DEFAULT_WRITE_OVERHEAD
#error "SSL3_RT_DEFAULT_PACKET_SIZE is too small."
#endif
n=((p[0]&0x7f)<<8)|p[1];
if (n > (1024*4))
if (n > SSL3_RT_DEFAULT_PACKET_SIZE - 2)
{
SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
goto err;
@@ -233,6 +233,7 @@ int ssl3_get_finished(SSL *s, int a, int b)
#ifdef OPENSSL_NO_NEXTPROTONEG
/* the mac has already been generated when we received the change
* cipher spec message and is in s->s3->tmp.peer_finish_md. */
#endif
#endif

n=s->method->ssl_get_message(s,
@@ -345,8 +346,11 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
unsigned long l=7;
BUF_MEM *buf;
int no_chain;
STACK_OF(X509) *cert_chain;

cert_chain = SSL_get_certificate_chain(s, x);

if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain)
no_chain = 1;
else
no_chain = 0;
@@ -398,6 +402,10 @@ unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
return(0);
}

for (i=0; i<sk_X509_num(cert_chain); i++)
if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i)))
return(0);

l-=7;
p=(unsigned char *)&(buf->data[4]);
l2n3(l,p);
@@ -745,6 +753,12 @@ int ssl3_setup_read_buffer(SSL *s)

if (s->s3->rbuf.buf == NULL)
{
if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
{
len = SSL3_RT_DEFAULT_PACKET_SIZE;
}
else
{
len = SSL3_RT_MAX_PLAIN_LENGTH
+ SSL3_RT_MAX_ENCRYPTED_OVERHEAD
+ headerlen + align;
@@ -753,6 +767,7 @@ int ssl3_setup_read_buffer(SSL *s)
s->s3->init_extra = 1;
len += SSL3_RT_MAX_EXTRA;
}
}
#ifndef OPENSSL_NO_COMP
if (!(s->options & SSL_OP_NO_COMPRESSION))
len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
@@ -787,7 +802,15 @@ int ssl3_setup_write_buffer(SSL *s)

if (s->s3->wbuf.buf == NULL)
{
len = s->max_send_fragment
if (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS)
{
len = SSL3_RT_DEFAULT_PACKET_SIZE;
}
else
{
len = s->max_send_fragment;
}
len += 0
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD
+ headerlen + align;
#ifndef OPENSSL_NO_COMP
@@ -797,7 +820,6 @@ int ssl3_setup_write_buffer(SSL *s)
if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
len += headerlen + align
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;

if ((p=freelist_extract(s->ctx, 0, len)) == NULL)
goto err;
s->s3->wbuf.buf = p;
@@ -840,4 +862,3 @@ int ssl3_release_read_buffer(SSL *s)
}
return 1;
}

@@ -202,6 +202,18 @@ int ssl3_connect(SSL *s)

s->in_handshake++;
if (!SSL_in_init(s) || SSL_in_before(s)) SSL_clear(s);
#if 0 /* Send app data in separate packet, otherwise, some particular site
* (only one site so far) closes the socket.
* Note: there is a very small chance that two TCP packets
* could be arriving at server combined into a single TCP packet,
* then trigger that site to break. We haven't encounter that though.
*/
if (SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH)
{
/* Send app data along with CCS/Finished */
s->s3->flags |= SSL3_FLAGS_DELAY_CLIENT_FINISHED;
}
#endif

#ifndef OPENSSL_NO_HEARTBEATS
/* If we're awaiting a HeartbeatResponse, pretend we
@@ -527,15 +539,32 @@ int ssl3_connect(SSL *s)
}
else
{
if ((SSL_get_mode(s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && SSL_get_cipher_bits(s, NULL) >= 128
&& s->s3->previous_server_finished_len == 0 /* no cutthrough on renegotiation (would complicate the state machine) */
)
{
if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED)
{
s->state=SSL3_ST_CUTTHROUGH_COMPLETE;
s->s3->flags|=SSL3_FLAGS_POP_BUFFER;
s->s3->delay_buf_pop_ret=0;
}
else
{
s->s3->tmp.next_state=SSL3_ST_CUTTHROUGH_COMPLETE;
}
}
else
{
#ifndef OPENSSL_NO_TLSEXT
/* Allow NewSessionTicket if ticket expected */
if (s->tlsext_ticket_expected)
s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
else
#endif

s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
}
}
s->init_num=0;
break;

@@ -582,6 +611,24 @@ int ssl3_connect(SSL *s)
s->state=s->s3->tmp.next_state;
break;

case SSL3_ST_CUTTHROUGH_COMPLETE:
#ifndef OPENSSL_NO_TLSEXT
/* Allow NewSessionTicket if ticket expected */
if (s->tlsext_ticket_expected)
s->state=SSL3_ST_CR_SESSION_TICKET_A;
else
#endif
s->state=SSL3_ST_CR_FINISHED_A;

/* SSL_write() will take care of flushing buffered data if
* DELAY_CLIENT_FINISHED is set.
*/
if (!(s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED))
ssl_free_wbio_buffer(s);
ret = 1;
goto end;
/* break; */

case SSL_ST_OK:
/* clean a few things up */
ssl3_cleanup_key_block(s);
@@ -675,6 +722,12 @@ int ssl3_client_hello(SSL *s)
#endif
(sess->not_resumable))
{
if (!s->session_creation_enabled)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
goto err;
}
if (!ssl_get_new_session(s,0))
goto err;
}
@@ -926,6 +979,12 @@ int ssl3_get_server_hello(SSL *s)
s->hit=0;
if (s->session->session_id_length > 0)
{
if (!s->session_creation_enabled)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
goto err;
}
if (!ssl_get_new_session(s,0))
{
al=SSL_AD_INTERNAL_ERROR;
@@ -3327,6 +3386,32 @@ int ssl3_send_next_proto(SSL *s)
*/

#ifndef OPENSSL_NO_TLSEXT
# ifndef OPENSSL_NO_NEXTPROTONEG
int ssl3_send_next_proto(SSL *s)
{
unsigned int len, padding_len;
unsigned char *d;

if (s->state == SSL3_ST_CW_NEXT_PROTO_A)
{
len = s->next_proto_negotiated_len;
padding_len = 32 - ((len + 2) % 32);
d = (unsigned char *)s->init_buf->data;
d[4] = len;
memcpy(d + 5, s->next_proto_negotiated, len);
d[5 + len] = padding_len;
memset(d + 6 + len, 0, padding_len);
*(d++)=SSL3_MT_NEXT_PROTO;
l2n3(2 + len + padding_len, d);
s->state = SSL3_ST_CW_NEXT_PROTO_B;
s->init_num = 4 + 2 + len + padding_len;
s->init_off = 0;
}

return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
}
# endif

int ssl3_check_finished(SSL *s)
{
int ok;
@@ -4199,9 +4199,22 @@ int ssl3_write(SSL *s, const void *buf, int len)

static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
{
int ret;
int n,ret;

clear_sys_error();
if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio))
{
/* Deal with an application that calls SSL_read() when handshake data
* is yet to be written.
*/
if (BIO_wpending(s->wbio) > 0)
{
s->rwstate=SSL_WRITING;
n=BIO_flush(s->wbio);
if (n <= 0) return(n);
s->rwstate=SSL_NOTHING;
}
}
if (s->s3->renegotiate) ssl3_renegotiate_check(s);
s->s3->in_read_app_data=1;
ret=s->method->ssl_read_bytes(s,SSL3_RT_APPLICATION_DATA,buf,len,peek);
@@ -295,6 +295,11 @@ static int ssl3_get_record(SSL *s)
size_t extra;
int decryption_failed_or_bad_record_mac = 0;
unsigned char *mac = NULL;
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
long align=SSL3_ALIGN_PAYLOAD;
#else
long align=0;
#endif

rr= &(s->s3->rrec);
sess=s->session;
@@ -303,7 +308,8 @@ static int ssl3_get_record(SSL *s)
extra=SSL3_RT_MAX_EXTRA;
else
extra=0;
if (extra && !s->s3->init_extra)
if (!(SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS) &&
extra && !s->s3->init_extra)
{
/* An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER
* set after ssl3_setup_buffers() was done */
@@ -352,6 +358,21 @@ fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length);
goto err;
}

/* If we receive a valid record larger than the current buffer size,
* allocate some memory for it.
*/
if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH - align)
{
if ((p=OPENSSL_realloc(s->s3->rbuf.buf, rr->length + SSL3_RT_HEADER_LENGTH + align))==NULL)
{
SSLerr(SSL_F_SSL3_GET_RECORD,ERR_R_MALLOC_FAILURE);
goto err;
}
s->s3->rbuf.buf=p;
s->s3->rbuf.len=rr->length + SSL3_RT_HEADER_LENGTH + align;
s->packet= &(s->s3->rbuf.buf[0]);
}

if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH)
{
al=SSL_AD_RECORD_OVERFLOW;
@@ -578,6 +599,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
const unsigned char *buf=buf_;
unsigned int tot,n,nw;
int i;
unsigned int max_plain_length;

s->rwstate=SSL_NOTHING;
tot=s->s3->wnum;
@@ -597,8 +619,13 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
n=(len-tot);
for (;;)
{
if (n > s->max_send_fragment)
nw=s->max_send_fragment;
if (type == SSL3_RT_APPLICATION_DATA && (SSL_get_mode(s) & SSL_MODE_SMALL_BUFFERS))
max_plain_length = SSL3_RT_DEFAULT_PLAIN_LENGTH;
else
max_plain_length = s->max_send_fragment;

if (n > max_plain_length)
nw = max_plain_length;
else
nw=n;

@@ -707,6 +734,18 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
s->s3->empty_fragment_done = 1;
}

/* resize if necessary to hold the data. */
if (len + SSL3_RT_DEFAULT_WRITE_OVERHEAD > wb->len)
{
if ((p=OPENSSL_realloc(wb->buf, len + SSL3_RT_DEFAULT_WRITE_OVERHEAD))==NULL)
{
SSLerr(SSL_F_DO_SSL3_WRITE,ERR_R_MALLOC_FAILURE);
goto err;
}
wb->buf = p;
wb->len = len + SSL3_RT_DEFAULT_WRITE_OVERHEAD;
}

if (create_empty_fragment)
{
#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
@@ -1416,8 +1455,10 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
int ssl3_do_change_cipher_spec(SSL *s)
{
int i;
#ifdef OPENSSL_NO_NEXTPROTONEG
const char *sender;
int slen;
#endif

if (s->state & SSL_ST_ACCEPT)
i=SSL3_CHANGE_CIPHER_SERVER_READ;
@@ -1440,6 +1481,7 @@ int ssl3_do_change_cipher_spec(SSL *s)
if (!s->method->ssl3_enc->change_cipher_state(s,i))
return(0);

#ifdef OPENSSL_NO_NEXTPROTONEG
/* we have to record the message digest at
* this point so we can get it before we read
* the finished message */
@@ -1456,6 +1498,7 @@ int ssl3_do_change_cipher_spec(SSL *s)

s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
sender,slen,s->s3->tmp.peer_finish_md);
#endif

return(1);
}
@@ -1001,6 +1001,12 @@ int ssl3_get_client_hello(SSL *s)
*/
if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION)))
{
if (!s->session_creation_enabled)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
goto err;
}
if (!ssl_get_new_session(s,1))
goto err;
}
@@ -1015,6 +1021,12 @@ int ssl3_get_client_hello(SSL *s)
goto err;
else /* i == 0 */
{
if (!s->session_creation_enabled)
{
ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED);
goto err;
}
if (!ssl_get_new_session(s,1))
goto err;
}
@@ -638,6 +638,13 @@ struct ssl_session_st
* TLS only.) "Released" buffers are put onto a free-list in the context
* or just freed (depending on the context's setting for freelist_max_len). */
#define SSL_MODE_RELEASE_BUFFERS 0x00000010L
/* Use small read and write buffers: (a) lazy allocate read buffers for
* large incoming records, and (b) limit the size of outgoing records. */
#define SSL_MODE_SMALL_BUFFERS 0x00000020L
/* When set, clients may send application data before receipt of CCS
* and Finished. This mode enables full-handshakes to 'complete' in
* one RTT. */
#define SSL_MODE_HANDSHAKE_CUTTHROUGH 0x00000040L

/* Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value,
* they cannot be used to clear bits. */
@@ -930,6 +937,25 @@ struct ssl_ctx_st
/* draft-rescorla-tls-opaque-prf-input-00.txt information */
int (*tlsext_opaque_prf_input_callback)(SSL *, void *peerinput, size_t len, void *arg);
void *tlsext_opaque_prf_input_callback_arg;

# ifndef OPENSSL_NO_NEXTPROTONEG
/* Next protocol negotiation information */
/* (for experimental NPN extension). */

/* For a server, this contains a callback function by which the set of
* advertised protocols can be provided. */
int (*next_protos_advertised_cb)(SSL *s, const unsigned char **buf,
unsigned int *len, void *arg);
void *next_protos_advertised_cb_arg;
/* For a client, this contains a callback function that selects the
* next protocol from the list provided by the server. */
int (*next_proto_select_cb)(SSL *s, unsigned char **out,
unsigned char *outlen,
const unsigned char *in,
unsigned int inlen,
void *arg);
void *next_proto_select_cb_arg;
#endif
#endif

#ifndef OPENSSL_NO_PSK
@@ -1217,6 +1243,9 @@ struct ssl_st
/* This can also be in the session once a session is established */
SSL_SESSION *session;

/* This can be disabled to prevent the use of uncached sessions */
int session_creation_enabled;

/* Default generate session ID callback. */
GEN_SESSION_CB generate_session_id;

@@ -1406,10 +1435,12 @@ extern "C" {
/* Is the SSL_connection established? */
#define SSL_get_state(a) SSL_state(a)
#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
#define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT)
#define SSL_in_init(a) ((SSL_state(a)&SSL_ST_INIT) && \
!SSL_cutthrough_complete(a))
#define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE)
#define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT)
#define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT)
int SSL_cutthrough_complete(const SSL *s);

/* The following 2 states are kept in ssl->rstate when reads fail,
* you should not need these */
@@ -1680,6 +1711,7 @@ const char * SSL_get_cipher_list(const SSL *s,int n);
char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
int SSL_get_read_ahead(const SSL * s);
int SSL_pending(const SSL *s);
const char * SSL_authentication_method(const SSL *c);
#ifndef OPENSSL_NO_SOCK
int SSL_set_fd(SSL *s, int fd);
int SSL_set_rfd(SSL *s, int fd);
@@ -1691,6 +1723,7 @@ BIO * SSL_get_rbio(const SSL *s);
BIO * SSL_get_wbio(const SSL *s);
#endif
int SSL_set_cipher_list(SSL *s, const char *str);
int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk);
void SSL_set_read_ahead(SSL *s, int yes);
int SSL_get_verify_mode(const SSL *s);
int SSL_get_verify_depth(const SSL *s);
@@ -1706,6 +1739,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len);
int SSL_use_certificate(SSL *ssl, X509 *x);
int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x);

#ifndef OPENSSL_NO_STDIO
int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
@@ -1754,6 +1789,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_SESSION *ses);
void SSL_SESSION_free(SSL_SESSION *ses);
int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp);
int SSL_set_session(SSL *to, SSL_SESSION *session);
void SSL_set_session_creation_enabled(SSL *, int);
int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c);
int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
@@ -2217,6 +2253,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303
#define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311
#define SSL_F_SSL_PEEK 270
#define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 312
#define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281
#define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282
#define SSL_F_SSL_READ 223
@@ -2244,6 +2281,7 @@ void ERR_load_SSL_strings(void);
#define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244
#define SSL_F_SSL_USE_CERTIFICATE 198
#define SSL_F_SSL_USE_CERTIFICATE_ASN1 199
#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000
#define SSL_F_SSL_USE_CERTIFICATE_FILE 200
#define SSL_F_SSL_USE_PRIVATEKEY 201
#define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202
@@ -2464,6 +2502,7 @@ void ERR_load_SSL_strings(void);
#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345
#define SSL_R_SERVERHELLO_TLSEXT 275
#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277
#define SSL_R_SESSION_MAY_NOT_BE_CREATED 2000
#define SSL_R_SHORT_READ 219
#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360
#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220
@@ -280,7 +280,7 @@ extern "C" {

#define SSL3_RT_MAX_EXTRA (16384)

/* Maximum plaintext length: defined by SSL/TLS standards */
/* Default buffer length used for writen records. Thus a generated record * will contain plaintext no larger than this value. */#define SSL3_RT_DEFAULT_PLAIN_LENGTH 2048/* Maximum plaintext length: defined by SSL/TLS standards */
#define SSL3_RT_MAX_PLAIN_LENGTH 16384
/* Maximum compression overhead: defined by SSL/TLS standards */
#define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024
@@ -311,7 +311,7 @@ extern "C" {
#define SSL3_RT_MAX_PACKET_SIZE \
(SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH)

#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
/* Extra space for empty fragment, headers, MAC, and padding. */#define SSL3_RT_DEFAULT_WRITE_OVERHEAD 256#define SSL3_RT_DEFAULT_PACKET_SIZE 4096 - SSL3_RT_DEFAULT_WRITE_OVERHEAD#if SSL3_RT_DEFAULT_PLAIN_LENGTH + SSL3_RT_DEFAULT_WRITE_OVERHEAD > SSL3_RT_DEFAULT_PACKET_SIZE#error "Insufficient space allocated for write buffers."#endif#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"

#define SSL3_VERSION 0x0300
@@ -477,7 +477,7 @@ typedef struct ssl3_state_st
void *server_opaque_prf_input;
size_t server_opaque_prf_input_len;

struct {
#ifndef OPENSSL_NO_NEXTPROTONEG /* Set if we saw the Next Protocol Negotiation extension from our peer. */ int next_proto_neg_seen;#endif struct {
/* actually only needs to be 16+20 */
unsigned char cert_verify_md[EVP_MAX_MD_SIZE*2];

@@ -547,7 +547,7 @@ typedef struct ssl3_state_st
/*client */
/* extra state */
#define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT)
#ifndef OPENSSL_NO_SCTP
#define SSL3_ST_CUTTHROUGH_COMPLETE (0x101|SSL_ST_CONNECT)#ifndef OPENSSL_NO_SCTP
#define DTLS1_SCTP_ST_CW_WRITE_SOCK (0x310|SSL_ST_CONNECT)
#define DTLS1_SCTP_ST_CR_READ_SOCK (0x320|SSL_ST_CONNECT)
#endif
@@ -675,4 +675,3 @@ typedef struct ssl3_state_st
}
#endif
#endif

@@ -1753,11 +1753,60 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits)
return(ret);
}


/* return string version of key exchange algorithm */
const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher)
{
switch (cipher->algorithm_mkey)
{
case SSL_kRSA:
return SSL_TXT_RSA;
case SSL_kDHr:
return SSL_TXT_DH "_" SSL_TXT_RSA;
case SSL_kDHd:
return SSL_TXT_DH "_" SSL_TXT_DSS;
case SSL_kEDH:
switch (cipher->algorithm_auth)
{
case SSL_aDSS:
return "DHE_" SSL_TXT_DSS;
case SSL_aRSA:
return "DHE_" SSL_TXT_RSA;
case SSL_aNULL:
return SSL_TXT_DH "_anon";
default:
return "UNKNOWN";
}
case SSL_kKRB5:
return SSL_TXT_KRB5;
case SSL_kECDHr:
return SSL_TXT_ECDH "_" SSL_TXT_RSA;
case SSL_kECDHe:
return SSL_TXT_ECDH "_" SSL_TXT_ECDSA;
case SSL_kEECDH:
switch (cipher->algorithm_auth)
{
case SSL_aECDSA:
return "ECDHE_" SSL_TXT_ECDSA;
case SSL_aRSA:
return "ECDHE_" SSL_TXT_RSA;
case SSL_aNULL:
return SSL_TXT_ECDH "_anon";
default:
return "UNKNOWN";
}
default:
return "UNKNOWN";
}
}


unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c)
{
return c->id;
}


SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
{
SSL_COMP *ctmp;
@@ -489,6 +489,7 @@ static ERR_STRING_DATA SSL_str_reasons[]=
{ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"},
{ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"},
{ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"},
{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"},
{ERR_REASON(SSL_R_SHORT_READ) ,"short read"},
{ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR),"signature algorithms error"},
{ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"},
@@ -329,6 +329,7 @@ SSL *SSL_new(SSL_CTX *ctx)
OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx));
s->verify_callback=ctx->default_verify_callback;
s->session_creation_enabled=1;
s->generate_session_id=ctx->generate_session_id;

s->param = X509_VERIFY_PARAM_new();
@@ -1333,6 +1334,32 @@ int SSL_set_cipher_list(SSL *s,const char *str)
return 1;
}

/** specify the ciphers to be used by the SSL */
int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk)
{
STACK_OF(SSL_CIPHER) *tmp_cipher_list;

if (sk == NULL)
return 0;

/* Based on end of ssl_create_cipher_list */
tmp_cipher_list = sk_SSL_CIPHER_dup(sk);
if (tmp_cipher_list == NULL)
{
return 0;
}
if (s->cipher_list != NULL)
sk_SSL_CIPHER_free(s->cipher_list);
s->cipher_list = sk;
if (s->cipher_list_by_id != NULL)
sk_SSL_CIPHER_free(s->cipher_list_by_id);
s->cipher_list_by_id = tmp_cipher_list;
(void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp);

sk_SSL_CIPHER_sort(s->cipher_list_by_id);
return 1;
}

/* works well for SSLv2, not so good for SSLv3 */
char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len)
{
@@ -2602,22 +2629,49 @@ SSL_METHOD *ssl_bad_method(int ver)
return(NULL);
}

const char *SSL_get_version(const SSL *s)
static const char *ssl_get_version(int version)
{
if (s->version == TLS1_2_VERSION)
return("TLSv1.2");
else if (s->version == TLS1_1_VERSION)
return("TLSv1.1");
if (s->version == TLS1_VERSION)
return("TLSv1");
else if (s->version == SSL3_VERSION)
else if (version == SSL3_VERSION)
return("SSLv3");
else if (s->version == SSL2_VERSION)
else if (version == SSL2_VERSION)
return("SSLv2");
else
return("unknown");
}

const char *SSL_get_version(const SSL *s)
{
return ssl_get_version(s->version);
}

const char *SSL_SESSION_get_version(const SSL_SESSION *s)
{
return ssl_get_version(s->ssl_version);
}

const char* SSL_authentication_method(const SSL* ssl)
{
if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL)
return SSL_TXT_RSA "_" SSL_TXT_EXPORT;
switch (ssl->version)
{
case SSL2_VERSION:
return SSL_TXT_RSA;
case SSL3_VERSION:
case TLS1_VERSION:
case DTLS1_VERSION:
return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher);
default:
return "UNKNOWN";
}
}

SSL *SSL_dup(SSL *s)
{
STACK_OF(X509_NAME) *sk;
@@ -3211,6 +3265,31 @@ void SSL_set_msg_callback(SSL *ssl, void (*cb)(int write_p, int version, int con
SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
}

int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const char *label, size_t llen, const unsigned char *p, size_t plen,
int use_context)
{
if (s->version < TLS1_VERSION)
return -1;

return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
llen, p, plen,
use_context);
}

int SSL_cutthrough_complete(const SSL *s)
{
return (!s->server && /* cutthrough only applies to clients */
!s->hit && /* full-handshake */
s->version >= SSL3_VERSION &&
s->s3->in_read_app_data == 0 && /* cutthrough only applies to write() */
(SSL_get_mode((SSL*)s) & SSL_MODE_HANDSHAKE_CUTTHROUGH) && /* cutthrough enabled */
SSL_get_cipher_bits(s, NULL) >= 128 && /* strong cipher choosen */
s->s3->previous_server_finished_len == 0 && /* not a renegotiation handshake */
(s->state == SSL3_ST_CR_SESSION_TICKET_A || /* ready to write app-data*/
s->state == SSL3_ST_CR_FINISHED_A));
}

/* Allocates new EVP_MD_CTX and sets pointer to it into given pointer
* vairable, freeing EVP_MD_CTX previously stored in that variable, if
* any. If EVP_MD pointer is passed, initializes ctx with this md
@@ -471,6 +471,7 @@
typedef struct cert_pkey_st
{
X509 *x509;
STACK_OF(X509) *cert_chain;
EVP_PKEY *privatekey;
/* Digest to use when signing */
const EVP_MD *digest;
@@ -697,6 +697,42 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const unsigned char *d,
}


int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain)
{
if (ssl == NULL)
{
SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER);
return(0);
}
if (ssl->cert == NULL)
{
SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
return(0);
}
if (ssl->cert->key == NULL)
{
SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED);
return(0);
}
ssl->cert->key->cert_chain = cert_chain;
return(1);
}

STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x)
{
int i;
if (x == NULL)
return NULL;
if (ssl == NULL)
return NULL;
if (ssl->cert == NULL)
return NULL;
for (i = 0; i < SSL_PKEY_NUM; i++)
if (ssl->cert->pkeys[i].x509 == x)
return ssl->cert->pkeys[i].cert_chain;
return NULL;
}

#ifndef OPENSSL_NO_STDIO
/* Read a file that contains our certificate in "PEM" format,
* possibly followed by a sequence of CA certificates that should be
@@ -269,6 +269,11 @@ static int def_generate_session_id(const SSL *ssl, unsigned char *id,
return 0;
}

void SSL_set_session_creation_enabled (SSL *s, int creation_enabled)
{
s->session_creation_enabled = creation_enabled;
}

int ssl_get_new_session(SSL *s, int session)
{
/* This gets used by clients and servers. */
@@ -277,6 +282,8 @@ int ssl_get_new_session(SSL *s, int session)
SSL_SESSION *ss=NULL;
GEN_SESSION_CB cb = def_generate_session_id;

/* caller should check this if they can do better error handling */
if (!s->session_creation_enabled) return(0);
if ((ss=SSL_SESSION_new()) == NULL) return(0);

/* If the context has a default timeout, use it */
@@ -369,6 +369,9 @@ static void sv_usage(void)
" (default is sect163r2).\n");
#endif
fprintf(stderr," -test_cipherlist - verifies the order of the ssl cipher lists\n");
fprintf(stderr," -c_small_records - enable client side use of small SSL record buffers\n");
fprintf(stderr," -s_small_records - enable server side use of small SSL record buffers\n");
fprintf(stderr," -cutthrough - enable 1-RTT full-handshake for strong ciphers\n");
}

static void print_details(SSL *c_ssl, const char *prefix)
@@ -497,6 +500,10 @@ int opaque_prf_input_cb(SSL *ssl, void *peerinput, size_t len, void *arg_)
return arg->ret;
}
#endif
int ssl_mode = 0;
int c_small_records=0;
int s_small_records=0;
int cutthrough = 0;

int main(int argc, char *argv[])
{
@@ -765,6 +772,18 @@ int main(int argc, char *argv[])
{
test_cipherlist = 1;
}
else if (strcmp(*argv, "-c_small_records") == 0)
{
c_small_records = 1;
}
else if (strcmp(*argv, "-s_small_records") == 0)
{
s_small_records = 1;
}
else if (strcmp(*argv, "-cutthrough") == 0)
{
cutthrough = 1;
}
else
{
fprintf(stderr,"unknown option %s\n",*argv);
@@ -901,6 +920,28 @@ int main(int argc, char *argv[])
SSL_CTX_set_cipher_list(s_ctx,cipher);
}

ssl_mode = 0;
if (c_small_records)
{
ssl_mode = SSL_CTX_get_mode(c_ctx);
ssl_mode |= SSL_MODE_SMALL_BUFFERS;
SSL_CTX_set_mode(c_ctx, ssl_mode);
}
ssl_mode = 0;
if (s_small_records)
{
ssl_mode = SSL_CTX_get_mode(s_ctx);
ssl_mode |= SSL_MODE_SMALL_BUFFERS;
SSL_CTX_set_mode(s_ctx, ssl_mode);
}
ssl_mode = 0;
if (cutthrough)
{
ssl_mode = SSL_CTX_get_mode(c_ctx);
ssl_mode = SSL_MODE_HANDSHAKE_CUTTHROUGH;
SSL_CTX_set_mode(c_ctx, ssl_mode);
}

#ifndef OPENSSL_NO_DH
if (!no_dhe)
{