diff options
Diffstat (limited to 'thirdparty/openssl/ssl')
31 files changed, 964 insertions, 1822 deletions
diff --git a/thirdparty/openssl/ssl/d1_both.c b/thirdparty/openssl/ssl/d1_both.c index 5d26c94926..e6bc761e8b 100644 --- a/thirdparty/openssl/ssl/d1_both.c +++ b/thirdparty/openssl/ssl/d1_both.c @@ -517,6 +517,17 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) return i; } + /* + * Don't change the *message* read sequence number while listening. For + * the *record* write sequence we reflect the ClientHello sequence number + * when listening. + */ + if (s->d1->listen) + memcpy(s->s3->write_sequence, s->s3->read_sequence, + sizeof(s->s3->write_sequence)); + else + s->d1->handshake_read_seq++; + if (mt >= 0 && s->s3->tmp.message_type != mt) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); @@ -544,10 +555,6 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - /* Don't change sequence numbers while listening */ - if (!s->d1->listen) - s->d1->handshake_read_seq++; - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; return s->init_num; @@ -581,9 +588,12 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, /* * msg_len is limited to 2^24, but is effectively checked against max * above + * + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 */ if (!BUF_MEM_grow_clean - (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { + (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) { SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); return SSL_AD_INTERNAL_ERROR; } @@ -618,11 +628,23 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) int al; *ok = 0; - item = pqueue_peek(s->d1->buffered_messages); - if (item == NULL) - return 0; + do { + item = pqueue_peek(s->d1->buffered_messages); + if (item == NULL) + return 0; + + frag = (hm_fragment *)item->data; + + if (frag->msg_header.seq < s->d1->handshake_read_seq) { + /* This is a stale message that has been buffered so clear it */ + pqueue_pop(s->d1->buffered_messages); + dtls1_hm_fragment_free(frag); + pitem_free(item); + item = NULL; + frag = NULL; + } + } while (item == NULL); - frag = (hm_fragment *)item->data; /* Don't return if reassembly still in progress */ if (frag->reassembly != NULL) @@ -1053,7 +1075,9 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) int dtls1_read_failed(SSL *s, int code) { if (code > 0) { +#ifdef TLS_DEBUG fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); +#endif return 1; } @@ -1125,7 +1149,9 @@ int dtls1_retransmit_buffered_messages(SSL *s) (frag->msg_header.seq, frag->msg_header.is_ccs), 0, &found) <= 0 && found) { +#ifdef TLS_DEBUG fprintf(stderr, "dtls1_retransmit_message() failed\n"); +#endif return -1; } } @@ -1211,7 +1237,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, unsigned long header_length; unsigned char seq64be[8]; struct dtls1_retransmit_state saved_state; - unsigned char save_write_sequence[8]; + unsigned char save_write_sequence[8] = {0, 0, 0, 0, 0, 0, 0, 0}; /*- OPENSSL_assert(s->init_num == 0); @@ -1225,7 +1251,9 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, item = pqueue_find(s->d1->sent_messages, seq64be); if (item == NULL) { +#ifdef TLS_DEBUG fprintf(stderr, "retransmit: message %d non-existant\n", seq); +#endif *found = 0; return 0; } @@ -1296,18 +1324,6 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, return ret; } -/* call this function when the buffered messages are no longer needed */ -void dtls1_clear_record_buffer(SSL *s) -{ - pitem *item; - - for (item = pqueue_pop(s->d1->sent_messages); - item != NULL; item = pqueue_pop(s->d1->sent_messages)) { - dtls1_hm_fragment_free((hm_fragment *)item->data); - pitem_free(item); - } -} - unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, unsigned char mt, unsigned long len, unsigned long frag_off, @@ -1469,7 +1485,7 @@ int dtls1_process_heartbeat(SSL *s) memcpy(bp, pl, payload); bp += payload; /* Random padding */ - if (RAND_pseudo_bytes(bp, padding) < 0) { + if (RAND_bytes(bp, padding) <= 0) { OPENSSL_free(buffer); return -1; } @@ -1546,6 +1562,8 @@ int dtls1_heartbeat(SSL *s) * - Padding */ buf = OPENSSL_malloc(1 + 2 + payload + padding); + if (buf == NULL) + goto err; p = buf; /* Message Type */ *p++ = TLS1_HB_REQUEST; @@ -1554,11 +1572,11 @@ int dtls1_heartbeat(SSL *s) /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ - if (RAND_pseudo_bytes(p, 16) < 0) + if (RAND_bytes(p, 16) <= 0) goto err; p += 16; /* Random padding */ - if (RAND_pseudo_bytes(p, padding) < 0) + if (RAND_bytes(p, padding) <= 0) goto err; ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); diff --git a/thirdparty/openssl/ssl/d1_clnt.c b/thirdparty/openssl/ssl/d1_clnt.c index 3ddfa7bca4..76451a346d 100644 --- a/thirdparty/openssl/ssl/d1_clnt.c +++ b/thirdparty/openssl/ssl/d1_clnt.c @@ -320,8 +320,13 @@ int dtls1_connect(SSL *s) s->shutdown = 0; /* every DTLS ClientHello resets Finished MAC */ - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + /* fall thru */ case SSL3_ST_CW_CLNT_HELLO_B: dtls1_start_timer(s); ret = ssl3_client_hello(s); @@ -769,6 +774,7 @@ int dtls1_connect(SSL *s) /* done with handshaking */ s->d1->handshake_read_seq = 0; s->d1->next_handshake_write_seq = 0; + dtls1_clear_received_buffer(s); goto end; /* break; */ diff --git a/thirdparty/openssl/ssl/d1_lib.c b/thirdparty/openssl/ssl/d1_lib.c index ee78921ba8..debd4fd5dc 100644 --- a/thirdparty/openssl/ssl/d1_lib.c +++ b/thirdparty/openssl/ssl/d1_lib.c @@ -170,7 +170,6 @@ int dtls1_new(SSL *s) static void dtls1_clear_queues(SSL *s) { pitem *item = NULL; - hm_fragment *frag = NULL; DTLS1_RECORD_DATA *rdata; while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { @@ -191,28 +190,44 @@ static void dtls1_clear_queues(SSL *s) pitem_free(item); } + while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } + + dtls1_clear_received_buffer(s); + dtls1_clear_sent_buffer(s); +} + +void dtls1_clear_received_buffer(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { frag = (hm_fragment *)item->data; dtls1_hm_fragment_free(frag); pitem_free(item); } +} + +void dtls1_clear_sent_buffer(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { frag = (hm_fragment *)item->data; dtls1_hm_fragment_free(frag); pitem_free(item); } - - while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { - rdata = (DTLS1_RECORD_DATA *)item->data; - if (rdata->rbuf.buf) { - OPENSSL_free(rdata->rbuf.buf); - } - OPENSSL_free(item->data); - pitem_free(item); - } } + void dtls1_free(SSL *s) { ssl3_free(s); @@ -456,7 +471,7 @@ void dtls1_stop_timer(SSL *s) BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); /* Clear retransmission buffer */ - dtls1_clear_record_buffer(s); + dtls1_clear_sent_buffer(s); } int dtls1_check_timeout_num(SSL *s) diff --git a/thirdparty/openssl/ssl/d1_pkt.c b/thirdparty/openssl/ssl/d1_pkt.c index fe30ec7d00..10586fee54 100644 --- a/thirdparty/openssl/ssl/d1_pkt.c +++ b/thirdparty/openssl/ssl/d1_pkt.c @@ -125,7 +125,7 @@ /* mod 128 saturating subtract of two 64-bit values in big-endian order */ static int satsub64be(const unsigned char *v1, const unsigned char *v2) { - int ret, sat, brw, i; + int ret, i; if (sizeof(long) == 8) do { @@ -157,28 +157,51 @@ static int satsub64be(const unsigned char *v1, const unsigned char *v2) return (int)l; } while (0); - ret = (int)v1[7] - (int)v2[7]; - sat = 0; - brw = ret >> 8; /* brw is either 0 or -1 */ - if (ret & 0x80) { - for (i = 6; i >= 0; i--) { - brw += (int)v1[i] - (int)v2[i]; - sat |= ~brw; - brw >>= 8; - } - } else { - for (i = 6; i >= 0; i--) { - brw += (int)v1[i] - (int)v2[i]; - sat |= brw; - brw >>= 8; + ret = 0; + for (i=0; i<7; i++) { + if (v1[i] > v2[i]) { + /* v1 is larger... but by how much? */ + if (v1[i] != v2[i] + 1) + return 128; + while (++i <= 6) { + if (v1[i] != 0x00 || v2[i] != 0xff) + return 128; /* too much */ + } + /* We checked all the way to the penultimate byte, + * so despite higher bytes changing we actually + * know that it only changed from (e.g.) + * ... (xx) ff ff ff ?? + * to ... (xx+1) 00 00 00 ?? + * so we add a 'bias' of 256 for the carry that + * happened, and will eventually return + * 256 + v1[7] - v2[7]. */ + ret = 256; + break; + } else if (v2[i] > v1[i]) { + /* v2 is larger... but by how much? */ + if (v2[i] != v1[i] + 1) + return -128; + while (++i <= 6) { + if (v2[i] != 0x00 || v1[i] != 0xff) + return -128; /* too much */ + } + /* Similar to the case above, we know it changed + * from ... (xx) 00 00 00 ?? + * to ... (xx-1) ff ff ff ?? + * so we add a 'bias' of -256 for the borrow, + * to return -256 + v1[7] - v2[7]. */ + ret = -256; } } - brw <<= 8; /* brw is either 0 or -256 */ - if (sat & 0xff) - return brw | 0x80; + ret += (int)v1[7] - (int)v2[7]; + + if (ret > 128) + return 128; + else if (ret < -128) + return -128; else - return brw + (ret & 0xFF); + return ret; } static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, @@ -194,7 +217,7 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, #endif static int dtls1_buffer_record(SSL *s, record_pqueue *q, unsigned char *priority); -static int dtls1_process_record(SSL *s); +static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap); /* copy buffered record into SSL structure */ static int dtls1_copy_record(SSL *s, pitem *item) @@ -319,21 +342,70 @@ static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) static int dtls1_process_buffered_records(SSL *s) { pitem *item; + SSL3_BUFFER *rb; + SSL3_RECORD *rr; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + int replayok = 1; item = pqueue_peek(s->d1->unprocessed_rcds.q); if (item) { /* Check if epoch is current. */ if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) - return (1); /* Nothing to do. */ + return 1; /* Nothing to do. */ + + rr = &s->s3->rrec; + rb = &s->s3->rbuf; + + if (rb->left > 0) { + /* + * We've still got data from the current packet to read. There could + * be a record from the new epoch in it - so don't overwrite it + * with the unprocessed records yet (we'll do it when we've + * finished reading the current packet). + */ + return 1; + } + /* Process all the records. */ while (pqueue_peek(s->d1->unprocessed_rcds.q)) { dtls1_get_unprocessed_record(s); - if (!dtls1_process_record(s)) - return (0); + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if (bitmap == NULL) { + /* + * Should not happen. This will only ever be NULL when the + * current record is from a different epoch. But that cannot + * be the case because we already checked the epoch above + */ + SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS, + ERR_R_INTERNAL_ERROR); + return 0; + } +#ifndef OPENSSL_NO_SCTP + /* Only do replay check if no SCTP bio */ + if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) +#endif + { + /* + * Check whether this is a repeat, or aged record. We did this + * check once already when we first received the record - but + * we might have updated the window since then due to + * records we subsequently processed. + */ + replayok = dtls1_record_replay_check(s, bitmap); + } + + if (!replayok || !dtls1_process_record(s, bitmap)) { + /* dump this record */ + rr->length = 0; + s->packet_length = 0; + continue; + } + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), s->s3->rrec.seq_num) < 0) - return -1; + return 0; } } @@ -344,7 +416,7 @@ static int dtls1_process_buffered_records(SSL *s) s->d1->processed_rcds.epoch = s->d1->r_epoch; s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; - return (1); + return 1; } #if 0 @@ -391,7 +463,7 @@ static int dtls1_get_buffered_record(SSL *s) #endif -static int dtls1_process_record(SSL *s) +static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap) { int i, al; int enc_err; @@ -551,6 +623,10 @@ static int dtls1_process_record(SSL *s) /* we have pulled in a full packet so zero things */ s->packet_length = 0; + + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap); + return (1); f_err: @@ -581,11 +657,12 @@ int dtls1_get_record(SSL *s) rr = &(s->s3->rrec); + again: /* * The epoch may have changed. If so, process all the pending records. * This is a non-blocking operation. */ - if (dtls1_process_buffered_records(s) < 0) + if (!dtls1_process_buffered_records(s)) return -1; /* if we're renegotiating, then there may be buffered records */ @@ -593,7 +670,6 @@ int dtls1_get_record(SSL *s) return 1; /* get something from the wire */ - again: /* check if we have the header */ if ((s->rstate != SSL_ST_READ_BODY) || (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { @@ -721,20 +797,17 @@ int dtls1_get_record(SSL *s) if (dtls1_buffer_record (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) return -1; - /* Mark receipt of record. */ - dtls1_record_bitmap_update(s, bitmap); } rr->length = 0; s->packet_length = 0; goto again; } - if (!dtls1_process_record(s)) { + if (!dtls1_process_record(s, bitmap)) { rr->length = 0; s->packet_length = 0; /* dump this record */ goto again; /* get another record */ } - dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ return (1); @@ -878,6 +951,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) goto start; } + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->cert->alert_count = 0; + /* we now have a packet which can be read and processed */ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, @@ -1144,6 +1224,14 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; + + s->cert->alert_count++; + if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { #ifndef OPENSSL_NO_SCTP /* @@ -1201,7 +1289,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); return (0); } else { al = SSL_AD_ILLEGAL_PARAMETER; @@ -1235,9 +1323,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) /* XDTLS: check that epoch is consistent */ if ((rr->length != ccs_hdr_len) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - i = SSL_AD_ILLEGAL_PARAMETER; + al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto err; + goto f_err; } rr->length = 0; @@ -1830,8 +1918,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, if (rr->epoch == s->d1->r_epoch) return &s->d1->bitmap; - /* Only HM and ALERT messages can be from the next epoch */ + /* + * Only HM and ALERT messages can be from the next epoch and only if we + * have already processed all of the unprocessed records from the last + * epoch + */ else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && + s->d1->unprocessed_rcds.epoch != s->d1->r_epoch && (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { *is_next_epoch = 1; return &s->d1->next_bitmap; @@ -1910,6 +2003,12 @@ void dtls1_reset_seq_numbers(SSL *s, int rw) s->d1->r_epoch++; memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); + + /* + * We must not use any buffered messages received from the previous + * epoch + */ + dtls1_clear_received_buffer(s); } else { seq = s->s3->write_sequence; memcpy(s->d1->last_write_sequence, seq, diff --git a/thirdparty/openssl/ssl/d1_srvr.c b/thirdparty/openssl/ssl/d1_srvr.c index e677d880f0..8502b242e5 100644 --- a/thirdparty/openssl/ssl/d1_srvr.c +++ b/thirdparty/openssl/ssl/d1_srvr.c @@ -282,7 +282,12 @@ int dtls1_accept(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->state = SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else if (!s->s3->send_connection_binding && @@ -313,7 +318,7 @@ int dtls1_accept(SSL *s) case SSL3_ST_SW_HELLO_REQ_B: s->shutdown = 0; - dtls1_clear_record_buffer(s); + dtls1_clear_sent_buffer(s); dtls1_start_timer(s); ret = ssl3_send_hello_request(s); if (ret <= 0) @@ -322,7 +327,11 @@ int dtls1_accept(SSL *s) s->state = SSL3_ST_SW_FLUSH; s->init_num = 0; - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; case SSL3_ST_SW_HELLO_REQ_C: @@ -346,15 +355,6 @@ int dtls1_accept(SSL *s) s->init_num = 0; - /* - * Reflect ClientHello sequence to remain stateless while - * listening - */ - if (listen) { - memcpy(s->s3->write_sequence, s->s3->read_sequence, - sizeof(s->s3->write_sequence)); - } - /* If we're just listening, stop here */ if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { ret = 2; @@ -381,7 +381,11 @@ int dtls1_accept(SSL *s) /* HelloVerifyRequest resets Finished MAC */ if (s->version != DTLS1_BAD_VER) - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; #ifndef OPENSSL_NO_SCTP @@ -894,6 +898,7 @@ int dtls1_accept(SSL *s) /* next message is server hello */ s->d1->handshake_write_seq = 0; s->d1->next_handshake_write_seq = 0; + dtls1_clear_received_buffer(s); goto end; /* break; */ diff --git a/thirdparty/openssl/ssl/install-ssl.com b/thirdparty/openssl/ssl/install-ssl.com deleted file mode 100755 index afe6967f85..0000000000 --- a/thirdparty/openssl/ssl/install-ssl.com +++ /dev/null @@ -1,136 +0,0 @@ -$! INSTALL-SSL.COM -- Installs the files in a given directory tree -$! -$! Author: Richard Levitte <richard@levitte.org> -$! Time of creation: 22-MAY-1998 10:13 -$! -$! P1 root of the directory tree -$! P2 "64" for 64-bit pointers. -$! -$! -$! Announce/identify. -$! -$ proc = f$environment( "procedure") -$ write sys$output "@@@ "+ - - f$parse( proc, , , "name")+ f$parse( proc, , , "type") -$! -$ on error then goto tidy -$ on control_c then goto tidy -$! -$ if p1 .eqs. "" -$ then -$ write sys$output "First argument missing." -$ write sys$output - - "It should be the directory where you want things installed." -$ exit -$ endif -$! -$ if (f$getsyi( "cpu") .lt. 128) -$ then -$ arch = "VAX" -$ else -$ arch = f$edit( f$getsyi( "arch_name"), "upcase") -$ if (arch .eqs. "") then arch = "UNK" -$ endif -$! -$ archd = arch -$ lib32 = "32" -$ shr = "_SHR32" -$! -$ if (p2 .nes. "") -$ then -$ if (p2 .eqs. "64") -$ then -$ archd = arch+ "_64" -$ lib32 = "" -$ shr = "_SHR" -$ else -$ if (p2 .nes. "32") -$ then -$ write sys$output "Second argument invalid." -$ write sys$output "It should be "32", "64", or nothing." -$ exit -$ endif -$ endif -$ endif -$! -$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0" -$ root_dev = f$parse(root,,,"device","syntax_only") -$ root_dir = f$parse(root,,,"directory","syntax_only") - - - "[000000." - "][" - "[" - "]" -$ root = root_dev + "[" + root_dir -$! -$ define /nolog wrk_sslroot 'root'.] /trans=conc -$ define /nolog wrk_sslinclude wrk_sslroot:[include] -$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe] -$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib] -$! -$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then - - create /directory /log wrk_sslroot:[000000] -$ if f$parse("wrk_sslinclude:") .eqs. "" then - - create /directory /log wrk_sslinclude: -$ if f$parse("wrk_sslxexe:") .eqs. "" then - - create /directory /log wrk_sslxexe: -$ if f$parse("wrk_sslxlib:") .eqs. "" then - - create /directory /log wrk_sslxlib: -$! -$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h, srtp.h -$ e_exe := ssl_task -$ libs := ssl_libssl -$! -$ xexe_dir := [-.'archd'.exe.ssl] -$! -$ copy /protection = w:re 'exheader' wrk_sslinclude: /log -$! -$ i = 0 -$ loop_exe: -$ e = f$edit( f$element( i, ",", e_exe), "trim") -$ i = i + 1 -$ if e .eqs. "," then goto loop_exe_end -$ set noon -$ file = xexe_dir+ e+ ".exe" -$ if f$search( file) .nes. "" -$ then -$ copy /protection = w:re 'file' wrk_sslxexe: /log -$ endif -$ set on -$ goto loop_exe -$ loop_exe_end: -$! -$ i = 0 -$ loop_lib: -$ e = f$edit(f$element(i, ",", libs),"trim") -$ i = i + 1 -$ if e .eqs. "," then goto loop_lib_end -$ set noon -$! Object library. -$ file = xexe_dir+ e+ lib32+ ".olb" -$ if f$search( file) .nes. "" -$ then -$ copy /protection = w:re 'file' wrk_sslxlib: /log -$ endif -$! Shareable image. -$ file = xexe_dir+ e+ shr+ ".exe" -$ if f$search( file) .nes. "" -$ then -$ copy /protection = w:re 'file' wrk_sslxlib: /log -$ endif -$ set on -$ goto loop_lib -$ loop_lib_end: -$! -$ tidy: -$! -$ call deass wrk_sslroot -$ call deass wrk_sslinclude -$ call deass wrk_sslxexe -$ call deass wrk_sslxlib -$! -$ exit -$! -$ deass: subroutine -$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "") -$ then -$ deassign /process 'p1' -$ endif -$ endsubroutine -$! diff --git a/thirdparty/openssl/ssl/s23_clnt.c b/thirdparty/openssl/ssl/s23_clnt.c index f782010c47..b80d1fd8ce 100644 --- a/thirdparty/openssl/ssl/s23_clnt.c +++ b/thirdparty/openssl/ssl/s23_clnt.c @@ -204,7 +204,10 @@ int ssl23_connect(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } s->state = SSL23_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; @@ -289,9 +292,9 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) unsigned long Time = (unsigned long)time(NULL); unsigned char *p = result; l2n(Time, p); - return RAND_pseudo_bytes(p, len - 4); + return RAND_bytes(p, len - 4); } else - return RAND_pseudo_bytes(result, len); + return RAND_bytes(result, len); } static int ssl23_client_hello(SSL *s) @@ -466,8 +469,8 @@ static int ssl23_client_hello(SSL *s) i = ch_len; s2n(i, d); memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE); - if (RAND_pseudo_bytes - (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) <= 0) + if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) + <= 0) return -1; memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); diff --git a/thirdparty/openssl/ssl/s23_pkt.c b/thirdparty/openssl/ssl/s23_pkt.c index efc8647841..6544180efe 100644 --- a/thirdparty/openssl/ssl/s23_pkt.c +++ b/thirdparty/openssl/ssl/s23_pkt.c @@ -63,6 +63,9 @@ #include <openssl/evp.h> #include <openssl/buffer.h> +/* + * Return values are as per SSL_write() + */ int ssl23_write_bytes(SSL *s) { int i, num, tot; @@ -77,7 +80,7 @@ int ssl23_write_bytes(SSL *s) if (i <= 0) { s->init_off = tot; s->init_num = num; - return (i); + return i; } s->rwstate = SSL_NOTHING; if (i == num) @@ -88,7 +91,10 @@ int ssl23_write_bytes(SSL *s) } } -/* return regularly only when we have read (at least) 'n' bytes */ +/* return regularly only when we have read (at least) 'n' bytes + * + * Return values are as per SSL_read() + */ int ssl23_read_bytes(SSL *s, int n) { unsigned char *p; @@ -102,7 +108,7 @@ int ssl23_read_bytes(SSL *s, int n) j = BIO_read(s->rbio, (char *)&(p[s->packet_length]), n - s->packet_length); if (j <= 0) - return (j); + return j; s->rwstate = SSL_NOTHING; s->packet_length += j; if (s->packet_length >= (unsigned int)n) diff --git a/thirdparty/openssl/ssl/s23_srvr.c b/thirdparty/openssl/ssl/s23_srvr.c index 470bd3d94f..d3f6db15cc 100644 --- a/thirdparty/openssl/ssl/s23_srvr.c +++ b/thirdparty/openssl/ssl/s23_srvr.c @@ -195,7 +195,10 @@ int ssl23_accept(SSL *s) s->init_buf = buf; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } s->state = SSL23_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; diff --git a/thirdparty/openssl/ssl/s2_clnt.c b/thirdparty/openssl/ssl/s2_clnt.c index 69da6b1421..20de1a8217 100644 --- a/thirdparty/openssl/ssl/s2_clnt.c +++ b/thirdparty/openssl/ssl/s2_clnt.c @@ -581,7 +581,7 @@ static int client_hello(SSL *s) /* * challenge id data */ - if (RAND_pseudo_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) + if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) return -1; memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH); d += SSL2_CHALLENGE_LENGTH; @@ -629,7 +629,7 @@ static int client_master_key(SSL *s) return -1; } if (i > 0) - if (RAND_pseudo_bytes(sess->key_arg, i) <= 0) + if (RAND_bytes(sess->key_arg, i) <= 0) return -1; /* make a master key */ diff --git a/thirdparty/openssl/ssl/s2_lib.c b/thirdparty/openssl/ssl/s2_lib.c index 88e67f083a..cc1360307b 100644 --- a/thirdparty/openssl/ssl/s2_lib.c +++ b/thirdparty/openssl/ssl/s2_lib.c @@ -254,7 +254,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = { SSL_3DES, SSL_MD5, SSL_SSLV2, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, 0, 112, 168, diff --git a/thirdparty/openssl/ssl/s2_pkt.c b/thirdparty/openssl/ssl/s2_pkt.c index 7a61888134..e44bc0335a 100644 --- a/thirdparty/openssl/ssl/s2_pkt.c +++ b/thirdparty/openssl/ssl/s2_pkt.c @@ -307,6 +307,9 @@ int ssl2_peek(SSL *s, void *buf, int len) return ssl2_read_internal(s, buf, len, 1); } +/* + * Return values are as per SSL_read() + */ static int read_n(SSL *s, unsigned int n, unsigned int max, unsigned int extend) { @@ -374,7 +377,7 @@ static int read_n(SSL *s, unsigned int n, unsigned int max, # endif if (i <= 0) { s->s2->rbuf_left += newb; - return (i); + return i; } newb += i; } @@ -441,6 +444,9 @@ int ssl2_write(SSL *s, const void *_buf, int len) } } +/* + * Return values are as per SSL_write() + */ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) { int i; @@ -477,7 +483,7 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) s->rwstate = SSL_NOTHING; return (s->s2->wpend_ret); } else if (i <= 0) - return (i); + return i; s->s2->wpend_off += i; s->s2->wpend_len -= i; } diff --git a/thirdparty/openssl/ssl/s2_srvr.c b/thirdparty/openssl/ssl/s2_srvr.c index 07e9df8282..d3b243c27e 100644 --- a/thirdparty/openssl/ssl/s2_srvr.c +++ b/thirdparty/openssl/ssl/s2_srvr.c @@ -526,11 +526,8 @@ static int get_client_master_key(SSL *s) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* - * should be RAND_bytes, but we cannot work around a failure. - */ - if (RAND_pseudo_bytes(rand_premaster_secret, - (int)num_encrypted_key_bytes) <= 0) + if (RAND_bytes(rand_premaster_secret, + (int)num_encrypted_key_bytes) <= 0) return 0; i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, @@ -822,8 +819,7 @@ static int server_hello(SSL *s) /* make and send conn_id */ s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */ s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH; - if (RAND_pseudo_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= - 0) + if (RAND_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= 0) return -1; memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH); d += SSL2_CONNECTION_ID_LENGTH; @@ -962,7 +958,7 @@ static int request_certificate(SSL *s) p = (unsigned char *)s->init_buf->data; *(p++) = SSL2_MT_REQUEST_CERTIFICATE; *(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION; - if (RAND_pseudo_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) + if (RAND_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) return -1; memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH); diff --git a/thirdparty/openssl/ssl/s3_both.c b/thirdparty/openssl/ssl/s3_both.c index 09d0661e81..054ded1c99 100644 --- a/thirdparty/openssl/ssl/s3_both.c +++ b/thirdparty/openssl/ssl/s3_both.c @@ -356,21 +356,22 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) } *ok = 1; s->state = stn; - s->init_msg = s->init_buf->data + 4; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; s->init_num = (int)s->s3->tmp.message_size; return s->init_num; } p = (unsigned char *)s->init_buf->data; - if (s->state == st1) { /* s->init_num < 4 */ + if (s->state == st1) { /* s->init_num < SSL3_HM_HEADER_LENGTH */ int skip_message; do { - while (s->init_num < 4) { + while (s->init_num < SSL3_HM_HEADER_LENGTH) { i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], - 4 - s->init_num, 0); + SSL3_HM_HEADER_LENGTH - + s->init_num, 0); if (i <= 0) { s->rwstate = SSL_READING; *ok = 0; @@ -394,12 +395,13 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - p, 4, s, s->msg_callback_arg); + p, SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); } } while (skip_message); - /* s->init_num == 4 */ + /* s->init_num == SSL3_HM_HEADER_LENGTH */ if ((mt >= 0) && (*p != mt)) { al = SSL_AD_UNEXPECTED_MESSAGE; @@ -415,19 +417,20 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } - if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */ - al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); - goto f_err; - } - if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) { + /* + * Make buffer slightly larger than message length as a precaution + * against small OOB reads e.g. CVE-2016-6306 + */ + if (l + && !BUF_MEM_grow_clean(s->init_buf, + (int)l + SSL3_HM_HEADER_LENGTH + 16)) { SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); goto err; } s->s3->tmp.message_size = l; s->state = stn; - s->init_msg = s->init_buf->data + 4; + s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH; s->init_num = 0; } @@ -456,10 +459,12 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) #endif /* Feed this message into MAC computation. */ - ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); + ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, + s->init_num + SSL3_HM_HEADER_LENGTH); if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, - (size_t)s->init_num + 4, s, s->msg_callback_arg); + (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s, + s->msg_callback_arg); *ok = 1; return s->init_num; f_err: @@ -535,6 +540,9 @@ int ssl_verify_alarm_type(long type) case X509_V_ERR_CRL_NOT_YET_VALID: case X509_V_ERR_CERT_UNTRUSTED: case X509_V_ERR_CERT_REJECTED: + case X509_V_ERR_HOSTNAME_MISMATCH: + case X509_V_ERR_EMAIL_MISMATCH: + case X509_V_ERR_IP_ADDRESS_MISMATCH: al = SSL_AD_BAD_CERTIFICATE; break; case X509_V_ERR_CERT_SIGNATURE_FAILURE: @@ -548,7 +556,10 @@ int ssl_verify_alarm_type(long type) case X509_V_ERR_CERT_REVOKED: al = SSL_AD_CERTIFICATE_REVOKED; break; + case X509_V_ERR_UNSPECIFIED: case X509_V_ERR_OUT_OF_MEM: + case X509_V_ERR_INVALID_CALL: + case X509_V_ERR_STORE_LOOKUP: al = SSL_AD_INTERNAL_ERROR; break; case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: diff --git a/thirdparty/openssl/ssl/s3_clnt.c b/thirdparty/openssl/ssl/s3_clnt.c index 19dc8648b9..5b8b2da59f 100644 --- a/thirdparty/openssl/ssl/s3_clnt.c +++ b/thirdparty/openssl/ssl/s3_clnt.c @@ -263,6 +263,7 @@ int ssl3_connect(SSL *s) if (!ssl3_setup_buffers(s)) { ret = -1; + s->state = SSL_ST_ERR; goto end; } @@ -275,7 +276,11 @@ int ssl3_connect(SSL *s) /* don't push the buffering BIO quite yet */ - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } s->state = SSL3_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; @@ -1216,6 +1221,12 @@ int ssl3_get_server_certificate(SSL *s) goto f_err; } for (nc = 0; nc < llen;) { + if (nc + 3 > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } n2l3(p, l); if ((l + nc + 3) > llen) { al = SSL_AD_DECODE_ERROR; @@ -1704,12 +1715,6 @@ int ssl3_get_key_exchange(SSL *s) } p += i; - if (BN_is_zero(dh->p)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE); - goto f_err; - } - - if (2 > n - param_len) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1730,11 +1735,6 @@ int ssl3_get_key_exchange(SSL *s) } p += i; - if (BN_is_zero(dh->g)) { - SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); - goto f_err; - } - if (2 > n - param_len) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1761,6 +1761,39 @@ int ssl3_get_key_exchange(SSL *s) goto f_err; } + /*- + * Check that p and g are suitable enough + * + * p is odd + * 1 < g < p - 1 + */ + { + BIGNUM *tmp = NULL; + + if (!BN_is_odd(dh->p)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE); + goto f_err; + } + if (BN_is_negative(dh->g) || BN_is_zero(dh->g) + || BN_is_one(dh->g)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); + goto f_err; + } + if ((tmp = BN_new()) == NULL + || BN_copy(tmp, dh->p) == NULL + || !BN_sub_word(tmp, 1)) { + BN_free(tmp); + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + if (BN_cmp(dh->g, tmp) >= 0) { + BN_free(tmp); + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); + goto f_err; + } + BN_free(tmp); + } + # ifndef OPENSSL_NO_RSA if (alg_a & SSL_aRSA) pkey = @@ -1836,6 +1869,7 @@ int ssl3_get_key_exchange(SSL *s) goto err; } if (EC_KEY_set_group(ecdh, ngroup) == 0) { + EC_GROUP_free(ngroup); SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } @@ -2111,6 +2145,10 @@ int ssl3_get_certificate_request(SSL *s) if (ctype_num > SSL3_CT_NUMBER) { /* If we exceed static buffer copy all to cert structure */ s->cert->ctypes = OPENSSL_malloc(ctype_num); + if (s->cert->ctypes == NULL) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } memcpy(s->cert->ctypes, p, ctype_num); s->cert->ctype_num = (size_t)ctype_num; ctype_num = SSL3_CT_NUMBER; @@ -2167,6 +2205,11 @@ int ssl3_get_certificate_request(SSL *s) } for (nc = 0; nc < llen;) { + if (nc + 2 > llen) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); + goto err; + } n2s(p, l); if ((l + nc + 2) > llen) { if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) @@ -2999,19 +3042,6 @@ int ssl3_send_client_key_exchange(SSL *s) goto err; } /* - * If we have client certificate, use its secret as peer key - */ - if (s->s3->tmp.cert_req && s->cert->key->privatekey) { - if (EVP_PKEY_derive_set_peer - (pkey_ctx, s->cert->key->privatekey) <= 0) { - /* - * If there was an error - just ignore it. Ephemeral key - * * would be used - */ - ERR_clear_error(); - } - } - /* * Compute shared IV and store it in algorithm-specific context * data */ @@ -3057,12 +3087,6 @@ int ssl3_send_client_key_exchange(SSL *s) n = msglen + 2; } memcpy(p, tmp, msglen); - /* Check if pubkey from client certificate was used */ - if (EVP_PKEY_CTX_ctrl - (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) { - /* Set flag "skip certificate verify" */ - s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; - } EVP_PKEY_CTX_free(pkey_ctx); s->session->master_key_length = s->method->ssl3_enc->generate_master_secret(s, diff --git a/thirdparty/openssl/ssl/s3_enc.c b/thirdparty/openssl/ssl/s3_enc.c index 47a0ec9fe0..1eee9d9b21 100644 --- a/thirdparty/openssl/ssl/s3_enc.c +++ b/thirdparty/openssl/ssl/s3_enc.c @@ -177,32 +177,34 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX_init(&s1); for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { k++; - if (k > sizeof buf) { + if (k > sizeof(buf)) /* bug: 'buf' is too small for this ciphersuite */ - SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); - return 0; - } + goto err; for (j = 0; j < k; j++) buf[j] = c; c++; - EVP_DigestInit_ex(&s1, EVP_sha1(), NULL); - EVP_DigestUpdate(&s1, buf, k); - EVP_DigestUpdate(&s1, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&s1, smd, NULL); - - EVP_DigestInit_ex(&m5, EVP_md5(), NULL); - EVP_DigestUpdate(&m5, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH); + if (!EVP_DigestInit_ex(&s1, EVP_sha1(), NULL) || + !EVP_DigestUpdate(&s1, buf, k) || + !EVP_DigestUpdate(&s1, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&s1, smd, NULL)) + goto err2; + + if (!EVP_DigestInit_ex(&m5, EVP_md5(), NULL) || + !EVP_DigestUpdate(&m5, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH)) + goto err2; if ((int)(i + MD5_DIGEST_LENGTH) > num) { - EVP_DigestFinal_ex(&m5, smd, NULL); + if (!EVP_DigestFinal_ex(&m5, smd, NULL)) + goto err2; memcpy(km, smd, (num - i)); } else - EVP_DigestFinal_ex(&m5, km, NULL); + if (!EVP_DigestFinal_ex(&m5, km, NULL)) + goto err2; km += MD5_DIGEST_LENGTH; } @@ -210,6 +212,12 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX_cleanup(&m5); EVP_MD_CTX_cleanup(&s1); return 1; + err: + SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + err2: + EVP_MD_CTX_cleanup(&m5); + EVP_MD_CTX_cleanup(&s1); + return 0; } int ssl3_change_cipher_state(SSL *s, int which) @@ -360,25 +368,33 @@ int ssl3_change_cipher_state(SSL *s, int which) * In here I set both the read and write key/iv to the same value * since only the correct one will be used :-). */ - EVP_DigestInit_ex(&md, EVP_md5(), NULL); - EVP_DigestUpdate(&md, key, j); - EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL); + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, key, j) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } key = &(exp_key[0]); if (k > 0) { - EVP_DigestInit_ex(&md, EVP_md5(), NULL); - EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL); + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } iv = &(exp_iv[0]); } } + EVP_MD_CTX_cleanup(&md); s->session->key_arg_length = 0; - EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)); + if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) + goto err2; #ifdef OPENSSL_SSL_TRACE_CRYPTO if (s->msg_callback) { @@ -399,7 +415,6 @@ int ssl3_change_cipher_state(SSL *s, int which) OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key)); OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv)); - EVP_MD_CTX_cleanup(&md); return (1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); @@ -555,17 +570,20 @@ int ssl3_enc(SSL *s, int send) if ((bs != 1) && !send) return ssl3_cbc_remove_padding(s, rec, bs, mac_size); } - return (1); + return 1; } -void ssl3_init_finished_mac(SSL *s) +int ssl3_init_finished_mac(SSL *s) { if (s->s3->handshake_buffer) BIO_free(s->s3->handshake_buffer); if (s->s3->handshake_dgst) ssl3_free_digest_list(s); s->s3->handshake_buffer = BIO_new(BIO_s_mem()); + if (s->s3->handshake_buffer == NULL) + return 0; (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); + return 1; } void ssl3_free_digest_list(SSL *s) @@ -607,6 +625,10 @@ int ssl3_digest_cached_records(SSL *s) ssl3_free_digest_list(s); s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); + if (s->s3->handshake_dgst == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); if (hdatalen <= 0) { @@ -618,14 +640,22 @@ int ssl3_digest_cached_records(SSL *s) for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { if ((mask & ssl_get_algorithm2(s)) && md) { s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); + if (s->s3->handshake_dgst[i] == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } #ifdef OPENSSL_FIPS if (EVP_MD_nid(md) == NID_md5) { EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); } #endif - EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL); - EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen); + if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL) + || !EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, + hdatalen)) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR); + return 0; + } } else { s->s3->handshake_dgst[i] = NULL; } @@ -895,7 +925,7 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, s, s->msg_callback_arg); } #endif - OPENSSL_cleanse(buf, sizeof buf); + OPENSSL_cleanse(buf, sizeof(buf)); return (ret); } diff --git a/thirdparty/openssl/ssl/s3_lib.c b/thirdparty/openssl/ssl/s3_lib.c index 872e636af9..1014a3fce1 100644 --- a/thirdparty/openssl/ssl/s3_lib.c +++ b/thirdparty/openssl/ssl/s3_lib.c @@ -329,7 +329,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -382,7 +382,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -434,7 +434,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -487,7 +487,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -539,7 +539,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -625,7 +625,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -712,7 +712,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -778,7 +778,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_MD5, SSL_SSLV3, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -1728,7 +1728,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2120,7 +2120,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2200,7 +2200,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2280,7 +2280,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2360,7 +2360,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2440,7 +2440,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2490,7 +2490,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2506,7 +2506,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -2522,7 +2522,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { SSL_3DES, SSL_SHA1, SSL_TLSV1, - SSL_NOT_EXP | SSL_HIGH, + SSL_NOT_EXP | SSL_MEDIUM, SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, 112, 168, @@ -4237,7 +4237,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) return (int)s->cert->ctype_num; } /* get configured sigalgs */ - siglen = tls12_get_psigalgs(s, &sig); + siglen = tls12_get_psigalgs(s, 1, &sig); if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) nostrict = 0; for (i = 0; i < siglen; i += 2, sig += 2) { @@ -4528,7 +4528,10 @@ int ssl3_renegotiate_check(SSL *s) */ long ssl_get_algorithm2(SSL *s) { - long alg2 = s->s3->tmp.new_cipher->algorithm2; + long alg2; + if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL) + return -1; + alg2 = s->s3->tmp.new_cipher->algorithm2; if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF && alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; diff --git a/thirdparty/openssl/ssl/s3_pkt.c b/thirdparty/openssl/ssl/s3_pkt.c index 379890237e..0290c991d8 100644 --- a/thirdparty/openssl/ssl/s3_pkt.c +++ b/thirdparty/openssl/ssl/s3_pkt.c @@ -136,6 +136,9 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, unsigned int len, int create_empty_fragment); static int ssl3_get_record(SSL *s); +/* + * Return values are as per SSL_read() + */ int ssl3_read_n(SSL *s, int n, int max, int extend) { /* @@ -667,7 +670,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) * promptly send beyond the end of the users buffer ... so we trap and * report the error in a way the user will notice */ - if (len < tot) { + if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) { SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); return (-1); } @@ -696,6 +699,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) len >= 4 * (int)(max_send_fragment = s->max_send_fragment) && s->compress == NULL && s->msg_callback == NULL && SSL_USE_EXPLICIT_IV(s) && + s->enc_write_ctx != NULL && EVP_CIPHER_flags(s->enc_write_ctx->cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) { unsigned char aad[13]; @@ -1082,7 +1086,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, return -1; } -/* if s->s3->wbuf.left != 0, we need to call this */ +/* if s->s3->wbuf.left != 0, we need to call this + * + * Return values are as per SSL_write(), i.e. + */ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, unsigned int len) { @@ -1122,7 +1129,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, */ wb->left = 0; } - return (i); + return i; } wb->offset += i; wb->left -= i; @@ -1229,6 +1236,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) return (ret); } + /* + * Reset the count of consecutive warning alerts if we've got a non-empty + * record that isn't an alert. + */ + if (rr->type != SSL3_RT_ALERT && rr->length != 0) + s->cert->alert_count = 0; + /* we now have a packet which can be read and processed */ if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, @@ -1443,6 +1457,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) if (alert_level == SSL3_AL_WARNING) { s->s3->warn_alert = alert_descr; + + s->cert->alert_count++; + if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS); + goto f_err; + } + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { s->shutdown |= SSL_RECEIVED_SHUTDOWN; return (0); @@ -1473,7 +1495,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); ERR_add_error_data(2, "SSL alert number ", tmp); s->shutdown |= SSL_RECEIVED_SHUTDOWN; - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); return (0); } else { al = SSL_AD_ILLEGAL_PARAMETER; @@ -1578,16 +1600,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) switch (rr->type) { default: -#ifndef OPENSSL_NO_TLS /* - * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give - * an unexpected message alert. + * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but + * TLS 1.2 says you MUST send an unexpected message alert. We use the + * TLS 1.2 behaviour for all protocol versions to prevent issues where + * no progress is being made and the peer continually sends unrecognised + * record types, using up resources processing them. */ - if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) { - rr->length = 0; - goto start; - } -#endif al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); goto f_err; @@ -1698,7 +1717,7 @@ int ssl3_send_alert(SSL *s, int level, int desc) return -1; /* If a fatal one, remove from cache */ if ((level == 2) && (s->session != NULL)) - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); s->s3->alert_dispatch = 1; s->s3->send_alert[0] = level; diff --git a/thirdparty/openssl/ssl/s3_srvr.c b/thirdparty/openssl/ssl/s3_srvr.c index ab28702ee9..ba17f1b562 100644 --- a/thirdparty/openssl/ssl/s3_srvr.c +++ b/thirdparty/openssl/ssl/s3_srvr.c @@ -311,7 +311,12 @@ int ssl3_accept(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->state = SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else if (!s->s3->send_connection_binding && @@ -348,7 +353,11 @@ int ssl3_accept(SSL *s) s->state = SSL3_ST_SW_FLUSH; s->init_num = 0; - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; case SSL3_ST_SW_HELLO_REQ_C: @@ -506,7 +515,7 @@ int ssl3_accept(SSL *s) * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert * during re-negotiation: */ - ((s->session->peer != NULL) && + (s->s3->tmp.finish_md_len != 0 && (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || /* * never request cert in anonymous ciphersuites (see @@ -980,7 +989,8 @@ int ssl3_get_client_hello(SSL *s) session_length = *(p + SSL3_RANDOM_SIZE); - if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) { + if (SSL3_RANDOM_SIZE + session_length + 1 + >= (unsigned int)((d + n) - p)) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -998,7 +1008,7 @@ int ssl3_get_client_hello(SSL *s) /* get the session-id */ j = *(p++); - if (p + j > d + n) { + if ((d + n) - p < j) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1054,14 +1064,14 @@ int ssl3_get_client_hello(SSL *s) if (SSL_IS_DTLS(s)) { /* cookie stuff */ - if (p + 1 > d + n) { + if ((d + n) - p < 1) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; } cookie_len = *(p++); - if (p + cookie_len > d + n) { + if ((unsigned int)((d + n ) - p) < cookie_len) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1131,7 +1141,7 @@ int ssl3_get_client_hello(SSL *s) } } - if (p + 2 > d + n) { + if ((d + n ) - p < 2) { al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); goto f_err; @@ -1145,7 +1155,7 @@ int ssl3_get_client_hello(SSL *s) } /* i bytes of cipher data + 1 byte for compression length later */ - if ((p + i + 1) > (d + n)) { + if ((d + n) - p < i + 1) { /* not enough data */ al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); @@ -1211,7 +1221,7 @@ int ssl3_get_client_hello(SSL *s) /* compression */ i = *(p++); - if ((p + i) > (d + n)) { + if ((d + n) - p < i) { /* not enough data */ al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); @@ -1464,9 +1474,9 @@ int ssl3_get_client_hello(SSL *s) /* Handles TLS extensions that we couldn't check earlier */ if (s->version >= SSL3_VERSION) { - if (ssl_check_clienthello_tlsext_late(s) <= 0) { + if (!ssl_check_clienthello_tlsext_late(s, &al)) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); - goto err; + goto f_err; } } @@ -1600,6 +1610,9 @@ int ssl3_send_server_key_exchange(SSL *s) unsigned int u; #endif #ifndef OPENSSL_NO_DH +# ifdef OPENSSL_NO_RSA + int j; +# endif DH *dh = NULL, *dhp; #endif #ifndef OPENSSL_NO_ECDH @@ -1700,6 +1713,12 @@ int ssl3_send_server_key_exchange(SSL *s) if (type & SSL_kEECDH) { const EC_GROUP *group; + if (s->s3->tmp.ecdh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + ecdhp = cert->ecdh_tmp; if (s->cert->ecdh_tmp_auto) { /* Get NID of appropriate shared curve */ @@ -1720,17 +1739,7 @@ int ssl3_send_server_key_exchange(SSL *s) goto f_err; } - if (s->s3->tmp.ecdh != NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - /* Duplicate the ECDH structure. */ - if (ecdhp == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } if (s->cert->ecdh_tmp_auto) ecdh = ecdhp; else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { @@ -1861,6 +1870,16 @@ int ssl3_send_server_key_exchange(SSL *s) n += 1 + nr[i]; else #endif +#ifndef OPENSSL_NO_DH + /* + * for interoperability with some versions of the Microsoft TLS + * stack, we need to zero pad the DHE pub key to the same length + * as the prime, so use the length of the prime here + */ + if ((i == 2) && (type & (SSL_kEDH))) + n += 2 + nr[0]; + else +#endif n += 2 + nr[i]; } @@ -1872,6 +1891,11 @@ int ssl3_send_server_key_exchange(SSL *s) goto f_err; } kn = EVP_PKEY_size(pkey); + /* Allow space for signature algorithm */ + if (SSL_USE_SIGALGS(s)) + kn += 2; + /* Allow space for signature length */ + kn += 2; } else { pkey = NULL; kn = 0; @@ -1890,6 +1914,20 @@ int ssl3_send_server_key_exchange(SSL *s) p++; } else #endif +#ifndef OPENSSL_NO_DH + /* + * for interoperability with some versions of the Microsoft TLS + * stack, we need to zero pad the DHE pub key to the same length + * as the prime + */ + if ((i == 2) && (type & (SSL_kEDH))) { + s2n(nr[0], p); + for (j = 0; j < (nr[0] - nr[2]); ++j) { + *p = 0; + ++p; + } + } else +#endif s2n(nr[i], p); BN_bn2bin(r[i], p); p += nr[i]; @@ -2051,7 +2089,7 @@ int ssl3_send_certificate_request(SSL *s) if (SSL_USE_SIGALGS(s)) { const unsigned char *psigs; - nl = tls12_get_psigalgs(s, &psigs); + nl = tls12_get_psigalgs(s, 1, &psigs); s2n(nl, p); memcpy(p, psigs, nl); p += nl; @@ -2229,11 +2267,8 @@ int ssl3_get_client_key_exchange(SSL *s) * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 */ - /* - * should be RAND_bytes, but we cannot work around a failure. - */ - if (RAND_pseudo_bytes(rand_premaster_secret, - sizeof(rand_premaster_secret)) <= 0) + if (RAND_bytes(rand_premaster_secret, + sizeof(rand_premaster_secret)) <= 0) goto err; decrypt_len = RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); @@ -2323,7 +2358,8 @@ int ssl3_get_client_key_exchange(SSL *s) if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); - goto err; + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; } else { p -= 2; i = (int)n; @@ -2376,9 +2412,10 @@ int ssl3_get_client_key_exchange(SSL *s) i = DH_compute_key(p, pub, dh_srvr); if (i <= 0) { + al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); BN_clear_free(pub); - goto err; + goto f_err; } DH_free(s->s3->tmp.dh); @@ -2676,12 +2713,14 @@ int ssl3_get_client_key_exchange(SSL *s) i = *p; p += 1; if (n != 1 + i) { - SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; } if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); - goto err; + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; } /* * p is pointing to somewhere in the buffer currently, so set it @@ -2984,6 +3023,11 @@ int ssl3_get_cert_verify(SSL *s) peer = s->session->peer; pkey = X509_get_pubkey(peer); + if (pkey == NULL) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + type = X509_certificate_type(peer, pkey); if (!(type & EVP_PKT_SIGN)) { @@ -3120,7 +3164,9 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } if (i != 64) { +#ifdef SSL_DEBUG fprintf(stderr, "GOST signature length is %d", i); +#endif } for (idx = 0; idx < 64; idx++) { signature[63 - idx] = p[idx]; @@ -3213,6 +3259,12 @@ int ssl3_get_client_certificate(SSL *s) goto f_err; } for (nc = 0; nc < llen;) { + if (nc + 3 > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } n2l3(p, l); if ((l + nc + 3) > llen) { al = SSL_AD_DECODE_ERROR; @@ -3423,8 +3475,22 @@ int ssl3_send_newsession_ticket(SSL *s) * all the work otherwise use generated values from parent ctx. */ if (tctx->tlsext_ticket_key_cb) { - if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, - &hctx, 1) < 0) + /* if 0 is returned, write en empty ticket */ + int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + &hctx, 1); + + if (ret == 0) { + l2n(0, p); /* timeout */ + s2n(0, p); /* length */ + ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, + p - ssl_handshake_start(s)); + s->state = SSL3_ST_SW_SESSION_TICKET_B; + OPENSSL_free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + return ssl_do_write(s); + } + if (ret < 0) goto err; } else { if (RAND_bytes(iv, 16) <= 0) @@ -3497,37 +3563,34 @@ int ssl3_send_cert_status(SSL *s) { if (s->state == SSL3_ST_SW_CERT_STATUS_A) { unsigned char *p; + size_t msglen; + /*- * Grow buffer if need be: the length calculation is as - * follows 1 (message type) + 3 (message length) + + * follows handshake_header_length + * 1 (ocsp response type) + 3 (ocsp response length) * + (ocsp response) */ - if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) { + msglen = 4 + s->tlsext_ocsp_resplen; + if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen)) { s->state = SSL_ST_ERR; return -1; } - p = (unsigned char *)s->init_buf->data; + p = ssl_handshake_start(s); - /* do the header */ - *(p++) = SSL3_MT_CERTIFICATE_STATUS; - /* message length */ - l2n3(s->tlsext_ocsp_resplen + 4, p); /* status type */ *(p++) = s->tlsext_status_type; /* length of OCSP response */ l2n3(s->tlsext_ocsp_resplen, p); /* actual response */ memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen); - /* number of bytes to write */ - s->init_num = 8 + s->tlsext_ocsp_resplen; - s->state = SSL3_ST_SW_CERT_STATUS_B; - s->init_off = 0; + + ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen); } /* SSL3_ST_SW_CERT_STATUS_B */ - return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + return (ssl_do_write(s)); } # ifndef OPENSSL_NO_NEXTPROTONEG diff --git a/thirdparty/openssl/ssl/ssl-lib.com b/thirdparty/openssl/ssl/ssl-lib.com deleted file mode 100644 index 43fea17541..0000000000 --- a/thirdparty/openssl/ssl/ssl-lib.com +++ /dev/null @@ -1,1229 +0,0 @@ -$! -$! SSL-LIB.COM -$! Written By: Robert Byer -$! Vice-President -$! A-Com Computing, Inc. -$! byer@mail.all-net.net -$! -$! Changes by Richard Levitte <richard@levitte.org> -$! -$! This command file compiles and creates the "[.xxx.EXE.SSL]LIBSSL.OLB" -$! library for OpenSSL. The "xxx" denotes the machine architecture of -$! ALPHA, IA64 or VAX. -$! -$! It is written to detect what type of machine you are compiling on -$! (i.e. ALPHA or VAX) and which "C" compiler you have (i.e. VAXC, DECC -$! or GNU C) or you can specify which compiler to use. -$! -$! Specify the following as P1 to build just that part or ALL to just -$! build everything. -$! -$! LIBRARY To just compile the [.xxx.EXE.SSL]LIBSSL.OLB Library. -$! SSL_TASK To just compile the [.xxx.EXE.SSL]SSL_TASK.EXE -$! -$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger -$! information. -$! -$! Specify which compiler at P3 to try to compile under. -$! -$! VAXC For VAX C. -$! DECC For DEC C. -$! GNUC For GNU C. -$! -$! If you don't specify a compiler, it will try to determine which -$! "C" compiler to use. -$! -$! P4, if defined, sets a TCP/IP library to use, through one of the following -$! keywords: -$! -$! UCX for UCX -$! TCPIP for TCPIP (post UCX) -$! SOCKETSHR for SOCKETSHR+NETLIB -$! -$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up) -$! -$! P6, if defined, specifies the C pointer size. Ignored on VAX. -$! ("64=ARGV" gives more efficient code with HP C V7.3 or newer.) -$! Supported values are: -$! -$! "" Compile with default (/NOPOINTER_SIZE) -$! 32 Compile with /POINTER_SIZE=32 (SHORT) -$! 64 Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]) -$! (Automatically select ARGV if compiler supports it.) -$! 64= Compile with /POINTER_SIZE=64 (LONG). -$! 64=ARGV Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV). -$! -$! P7, if defined, specifies a directory where ZLIB files (zlib.h, -$! libz.olb) may be found. Optionally, a non-default object library -$! name may be included ("dev:[dir]libz_64.olb", for example). -$! -$! -$! Announce/identify. -$! -$ proc = f$environment( "procedure") -$ write sys$output "@@@ "+ - - f$parse( proc, , , "name")+ f$parse( proc, , , "type") -$! -$! Define A TCP/IP Library That We Will Need To Link To. -$! (That Is, If We Need To Link To One.) -$! -$ TCPIP_LIB = "" -$ ZLIB_LIB = "" -$! -$! Check What Architecture We Are Using. -$! -$ IF (F$GETSYI("CPU").LT.128) -$ THEN -$! -$! The Architecture Is VAX. -$! -$ ARCH = "VAX" -$! -$! Else... -$! -$ ELSE -$! -$! The Architecture Is Alpha, IA64 or whatever comes in the future. -$! -$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE") -$ IF (ARCH .EQS. "") THEN ARCH = "UNK" -$! -$! End The Architecture Check. -$! -$ ENDIF -$! -$ ARCHD = ARCH -$ LIB32 = "32" -$ OPT_FILE = "" -$ POINTER_SIZE = "" -$! -$! Check To Make Sure We Have Valid Command Line Parameters. -$! -$ GOSUB CHECK_OPTIONS -$! -$! Define The OBJ and EXE Directories. -$! -$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.SSL] -$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.SSL] -$! -$! Specify the destination directory in any /MAP option. -$! -$ if (LINKMAP .eqs. "MAP") -$ then -$ LINKMAP = LINKMAP+ "=''EXE_DIR'" -$ endif -$! -$! Add the location prefix to the linker options file name. -$! -$ if (OPT_FILE .nes. "") -$ then -$ OPT_FILE = EXE_DIR+ OPT_FILE -$ endif -$! -$! Initialise logical names and such -$! -$ GOSUB INITIALISE -$! -$! Tell The User What Kind of Machine We Run On. -$! -$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'" -$! -$! Check To See If The Architecture Specific OBJ Directory Exists. -$! -$ IF (F$PARSE(OBJ_DIR).EQS."") -$ THEN -$! -$! It Dosen't Exist, So Create It. -$! -$ CREATE/DIR 'OBJ_DIR' -$! -$! End The Architecture Specific OBJ Directory Check. -$! -$ ENDIF -$! -$! Check To See If The Architecture Specific Directory Exists. -$! -$ IF (F$PARSE(EXE_DIR).EQS."") -$ THEN -$! -$! It Dosen't Exist, So Create It. -$! -$ CREATE/DIR 'EXE_DIR' -$! -$! End The Architecture Specific Directory Check. -$! -$ ENDIF -$! -$! Define The Library Name. -$! -$ SSL_LIB := 'EXE_DIR'SSL_LIBSSL'LIB32'.OLB -$! -$! Define The CRYPTO-LIB We Are To Use. -$! -$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB -$! -$! Set up exceptional compilations. -$! -$ CC5_SHOWN = 0 -$! -$! Check To See What We Are To Do. -$! -$ IF (BUILDALL.EQS."TRUE") -$ THEN -$! -$! Since Nothing Special Was Specified, Do Everything. -$! -$ GOSUB LIBRARY -$ GOSUB SSL_TASK -$! -$! Else... -$! -$ ELSE -$! -$! Build Just What The User Wants Us To Build. -$! -$ GOSUB 'BUILDALL' -$! -$! End The BUILDALL Check. -$! -$ ENDIF -$! -$! Time To EXIT. -$! -$ EXIT: -$ GOSUB CLEANUP -$ EXIT -$! -$! Compile The Library. -$! -$ LIBRARY: -$! -$! Check To See If We Already Have A "[.xxx.EXE.SSL]SSL_LIBSSL''LIB32'.OLB" Library... -$! -$ IF (F$SEARCH(SSL_LIB).EQS."") -$ THEN -$! -$! Guess Not, Create The Library. -$! -$ LIBRARY/CREATE/OBJECT 'SSL_LIB' -$! -$! End The Library Exist Check. -$! -$ ENDIF -$! -$! Define The Different SSL "library" Files. -$! -$ LIB_SSL = "s2_meth, s2_srvr, s2_clnt, s2_lib, s2_enc, s2_pkt,"+ - - "s3_meth, s3_srvr, s3_clnt, s3_lib, s3_enc, s3_pkt, s3_both, s3_cbc,"+ - - "s23_meth,s23_srvr,s23_clnt,s23_lib, s23_pkt,"+ - - "t1_meth, t1_srvr, t1_clnt, t1_lib, t1_enc, t1_ext,"+ - - "d1_meth, d1_srvr, d1_clnt, d1_lib, d1_pkt,"+ - - "d1_both,d1_srtp,"+ - - "ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ - - "ssl_ciph,ssl_stat,ssl_rsa,"+ - - "ssl_asn1,ssl_txt,ssl_algs,ssl_conf,"+ - - "bio_ssl,ssl_err,kssl,t1_reneg,tls_srp,t1_trce,ssl_utst" -$! -$ COMPILEWITH_CC5 = "" -$! -$! Tell The User That We Are Compiling The Library. -$! -$ WRITE SYS$OUTPUT "Building The ",SSL_LIB," Library." -$! -$! Define A File Counter And Set It To "0" -$! -$ FILE_COUNTER = 0 -$! -$! Top Of The File Loop. -$! -$ NEXT_FILE: -$! -$! O.K, Extract The File Name From The File List. -$! -$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",LIB_SSL),"COLLAPSE") -$! -$! Check To See If We Are At The End Of The File List. -$! -$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE -$! -$! Increment The Counter. -$! -$ FILE_COUNTER = FILE_COUNTER + 1 -$! -$! Create The Source File Name. -$! -$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C" -$! -$! Create The Object File Name. -$! -$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ" -$ ON WARNING THEN GOTO NEXT_FILE -$! -$! Check To See If The File We Want To Compile Is Actually There. -$! -$ IF (F$SEARCH(SOURCE_FILE).EQS."") -$ THEN -$! -$! Tell The User That The File Dosen't Exist. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist." -$ WRITE SYS$OUTPUT "" -$! -$! Exit The Build. -$! -$ EXIT -$! -$! End The File Exists Check. -$! -$ ENDIF -$! -$! Tell The User What File We Are Compiling. -$! -$ WRITE SYS$OUTPUT " ",FILE_NAME,".c" -$! -$! Compile The File. -$! -$ ON ERROR THEN GOTO NEXT_FILE -$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE' -$! -$! Add It To The Library. -$! -$ LIBRARY/REPLACE/OBJECT 'SSL_LIB' 'OBJECT_FILE' -$! -$! Time To Clean Up The Object File. -$! -$ DELETE 'OBJECT_FILE';* -$! -$! Go Back And Get The Next File Name. -$! -$ GOTO NEXT_FILE -$! -$! All Done With This Library. -$! -$ FILE_DONE: -$! -$! Tell The User That We Are All Done. -$! -$ WRITE SYS$OUTPUT "Library ",SSL_LIB," Compiled." -$! -$! Time To RETURN. -$! -$ RETURN -$ SSL_TASK: -$! -$! Check To See If We Have The Proper Libraries. -$! -$ GOSUB LIB_CHECK -$! -$! Check To See If We Have A Linker Option File. -$! -$ GOSUB CHECK_OPT_FILE -$! -$! Check To See If The File We Want To Compile Is Actually There. -$! -$ IF (F$SEARCH("SYS$DISK:[]SSL_TASK.C").EQS."") -$ THEN -$! -$! Tell The User That The File Dosen't Exist. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The File SSL_TASK.C Dosen't Exist." -$ WRITE SYS$OUTPUT "" -$! -$! Exit The Build. -$! -$ EXIT -$! -$! End The SSL_TASK.C File Check. -$! -$ ENDIF -$! -$ COMPILEWITH_CC5 = "" !!! ",ssl_task," -$! -$! Tell The User We Are Creating The SSL_TASK. -$! -$! Tell The User We Are Creating The SSL_TASK. -$! -$ WRITE SYS$OUTPUT "Creating SSL_TASK OSU HTTP SSL Engine." -$! -$! Tell The User What File We Are Compiling. -$! -$ FILE_NAME = "ssl_task" -$ WRITE SYS$OUTPUT " ",FILE_NAME,".c" -$! -$! Compile The File. -$! -$ ON ERROR THEN GOTO SSL_TASK_END -$! -$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ "," -$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5 -$ THEN -$ if (.not. CC5_SHOWN) -$ then -$ CC5_SHOWN = 1 -$ write sys$output " \Using special rule (5)" -$ x = " "+ CC5 -$ write /symbol sys$output x -$ endif -$ CC5 /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C -$ ELSE -$ CC /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C -$ ENDIF -$! -$! Link The Program. -$! -$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_DIR'SSL_TASK.EXE - - 'OBJ_DIR'SSL_TASK.OBJ, - - 'SSL_LIB'/LIBRARY, - - 'CRYPTO_LIB'/LIBRARY - - 'TCPIP_LIB' - - 'ZLIB_LIB' - - ,'OPT_FILE' /OPTIONS -$! -$! Time To Return. -$! -$SSL_TASK_END: -$ RETURN -$! -$! Check For The Link Option FIle. -$! -$ CHECK_OPT_FILE: -$! -$! Check To See If We Need To Make A VAX C Option File. -$! -$ IF (COMPILER.EQS."VAXC") -$ THEN -$! -$! Check To See If We Already Have A VAX C Linker Option File. -$! -$ IF (F$SEARCH(OPT_FILE).EQS."") -$ THEN -$! -$! We Need A VAX C Linker Option File. -$! -$ CREATE 'OPT_FILE' -$DECK -! -! Default System Options File To Link Against -! The Sharable VAX C Runtime Library. -! -SYS$SHARE:VAXCRTL.EXE/SHARE -$EOD -$! -$! End The Option File Check. -$! -$ ENDIF -$! -$! End The VAXC Check. -$! -$ ENDIF -$! -$! Check To See If We Need A GNU C Option File. -$! -$ IF (COMPILER.EQS."GNUC") -$ THEN -$! -$! Check To See If We Already Have A GNU C Linker Option File. -$! -$ IF (F$SEARCH(OPT_FILE).EQS."") -$ THEN -$! -$! We Need A GNU C Linker Option File. -$! -$ CREATE 'OPT_FILE' -$DECK -! -! Default System Options File To Link Against -! The Sharable C Runtime Library. -! -GNU_CC:[000000]GCCLIB/LIBRARY -SYS$SHARE:VAXCRTL/SHARE -$EOD -$! -$! End The Option File Check. -$! -$ ENDIF -$! -$! End The GNU C Check. -$! -$ ENDIF -$! -$! Check To See If We Need A DEC C Option File. -$! -$ IF (COMPILER.EQS."DECC") -$ THEN -$! -$! Check To See If We Already Have A DEC C Linker Option File. -$! -$ IF (F$SEARCH(OPT_FILE).EQS."") -$ THEN -$! -$! Figure Out If We Need A non-VAX Or A VAX Linker Option File. -$! -$ IF (ARCH.EQS."VAX") -$ THEN -$! -$! We Need A DEC C Linker Option File For VAX. -$! -$ CREATE 'OPT_FILE' -$DECK -! -! Default System Options File To Link Against -! The Sharable DEC C Runtime Library. -! -SYS$SHARE:DECC$SHR.EXE/SHARE -$EOD -$! -$! Else... -$! -$ ELSE -$! -$! Create The non-VAX Linker Option File. -$! -$ CREATE 'OPT_FILE' -$DECK -! -! Default System Options File For non-VAX To Link Against -! The Sharable C Runtime Library. -! -SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE -SYS$SHARE:CMA$OPEN_RTL/SHARE -$EOD -$! -$! End The DEC C Option File Check. -$! -$ ENDIF -$! -$! End The Option File Search. -$! -$ ENDIF -$! -$! End The DEC C Check. -$! -$ ENDIF -$! -$! Tell The User What Linker Option File We Are Using. -$! -$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"." -$! -$! Time To RETURN. -$! -$ RETURN -$ LIB_CHECK: -$! -$! Look For The VAX Library LIBSSL.OLB. -$! -$ IF (F$SEARCH(SSL_LIB).EQS."") -$ THEN -$! -$! Tell The User We Can't Find The LIBSSL.OLB Library. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"." -$ WRITE SYS$OUTPUT "We Can't Link Without It." -$ WRITE SYS$OUTPUT "" -$! -$! Since We Can't Link Without It, Exit. -$! -$ EXIT -$! -$! End The LIBSSL.OLB Library Check. -$! -$ ENDIF -$! -$! Look For The Library LIBCRYPTO.OLB. -$! -$ IF (F$SEARCH(CRYPTO_LIB).EQS."") -$ THEN -$! -$! Tell The User We Can't Find The LIBCRYPTO.OLB Library. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"." -$ WRITE SYS$OUTPUT "We Can't Link Without It." -$ WRITE SYS$OUTPUT "" -$! -$! Since We Can't Link Without It, Exit. -$! -$ EXIT -$! -$! End The LIBCRYPTO.OLB Library Check. -$! -$ ENDIF -$! -$! Time To Return. -$! -$ RETURN -$! -$! Check The User's Options. -$! -$ CHECK_OPTIONS: -$! -$! Check To See If P1 Is Blank. -$! -$ IF (P1.EQS."ALL") -$ THEN -$! -$! P1 Is Blank, So Build Everything. -$! -$ BUILDALL = "TRUE" -$! -$! Else... -$! -$ ELSE -$! -$! Else, Check To See If P1 Has A Valid Argument. -$! -$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."SSL_TASK") -$ THEN -$! -$! A Valid Argument. -$! -$ BUILDALL = P1 -$! -$! Else... -$! -$ ELSE -$! -$! Tell The User We Don't Know What They Want. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:" -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT " ALL : Just Build Everything." -$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.SSL]LIBSSL.OLB Library." -$ WRITE SYS$OUTPUT " SSL_TASK : To Compile Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program." -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:" -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT " ALPHA[64]: Alpha Architecture." -$ WRITE SYS$OUTPUT " IA64[64] : IA64 Architecture." -$ WRITE SYS$OUTPUT " VAX : VAX Architecture." -$ WRITE SYS$OUTPUT "" -$! -$! Time To EXIT. -$! -$ EXIT -$! -$! End The Valid Argument Check. -$! -$ ENDIF -$! -$! End The P1 Check. -$! -$ ENDIF -$! -$! Check To See If P2 Is Blank. -$! -$ IF (P2.EQS."NODEBUG") -$ THEN -$! -$! P2 Is NODEBUG, So Compile Without Debugger Information. -$! -$ DEBUGGER = "NODEBUG" -$ LINKMAP = "NOMAP" -$ TRACEBACK = "NOTRACEBACK" -$ GCC_OPTIMIZE = "OPTIMIZE" -$ CC_OPTIMIZE = "OPTIMIZE" -$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile." -$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization." -$! -$! Else... -$! -$ ELSE -$! -$! Check To See If We Are To Compile With Debugger Information. -$! -$ IF (P2.EQS."DEBUG") -$ THEN -$! -$! Compile With Debugger Information. -$! -$ DEBUGGER = "DEBUG" -$ LINKMAP = "MAP" -$ TRACEBACK = "TRACEBACK" -$ GCC_OPTIMIZE = "NOOPTIMIZE" -$ CC_OPTIMIZE = "NOOPTIMIZE" -$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile." -$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization." -$ ELSE -$! -$! Tell The User Entered An Invalid Option. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:" -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information." -$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information." -$ WRITE SYS$OUTPUT "" -$! -$! Time To EXIT. -$! -$ EXIT -$! -$! End The Valid Argument Check. -$! -$ ENDIF -$! -$! End The P2 Check. -$! -$ ENDIF -$! -$! Special Threads For OpenVMS v7.1 Or Later -$! -$! Written By: Richard Levitte -$! richard@levitte.org -$! -$! -$! Check To See If We Have A Option For P5. -$! -$ IF (P5.EQS."") -$ THEN -$! -$! Get The Version Of VMS We Are Using. -$! -$ ISSEVEN := -$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION"))) -$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP)) -$! -$! Check To See If The VMS Version Is v7.1 Or Later. -$! -$ IF (TMP.GE.71) -$ THEN -$! -$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads. -$! -$ ISSEVEN := ,PTHREAD_USE_D4 -$! -$! End The VMS Version Check. -$! -$ ENDIF -$! -$! End The P5 Check. -$! -$ ENDIF -$! -$! Check P6 (POINTER_SIZE). -$! -$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX") -$ THEN -$! -$ IF (P6 .EQS. "32") -$ THEN -$ POINTER_SIZE = " /POINTER_SIZE=32" -$ ELSE -$ POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE") -$ IF ((POINTER_SIZE .EQS. "64") .OR. - - (POINTER_SIZE .EQS. "64=") .OR. - - (POINTER_SIZE .EQS. "64=ARGV")) -$ THEN -$ ARCHD = ARCH+ "_64" -$ LIB32 = "" -$ POINTER_SIZE = " /POINTER_SIZE=64" -$ ELSE -$! -$! Tell The User Entered An Invalid Option. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The Option ", P6, - - " Is Invalid. The Valid Options Are:" -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT - - " """" : Compile with default (short) pointers." -$ WRITE SYS$OUTPUT - - " 32 : Compile with 32-bit (short) pointers." -$ WRITE SYS$OUTPUT - - " 64 : Compile with 64-bit (long) pointers (auto ARGV)." -$ WRITE SYS$OUTPUT - - " 64= : Compile with 64-bit (long) pointers (no ARGV)." -$ WRITE SYS$OUTPUT - - " 64=ARGV : Compile with 64-bit (long) pointers (ARGV)." -$ WRITE SYS$OUTPUT "" -$! -$! Time To EXIT. -$! -$ EXIT -$! -$ ENDIF -$! -$ ENDIF -$! -$! End The P6 (POINTER_SIZE) Check. -$! -$ ENDIF -$! -$! Set basic C compiler /INCLUDE directories. -$! -$ CC_INCLUDES = "SYS$DISK:[-.CRYPTO],SYS$DISK:[-]" -$! -$! Check To See If P3 Is Blank. -$! -$ IF (P3.EQS."") -$ THEN -$! -$! O.K., The User Didn't Specify A Compiler, Let's Try To -$! Find Out Which One To Use. -$! -$! Check To See If We Have GNU C. -$! -$ IF (F$TRNLNM("GNU_CC").NES."") -$ THEN -$! -$! Looks Like GNUC, Set To Use GNUC. -$! -$ P3 = "GNUC" -$! -$! End The GNU C Compiler Check. -$! -$ ELSE -$! -$! Check To See If We Have VAXC Or DECC. -$! -$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."") -$ THEN -$! -$! Looks Like DECC, Set To Use DECC. -$! -$ P3 = "DECC" -$! -$! Else... -$! -$ ELSE -$! -$! Looks Like VAXC, Set To Use VAXC. -$! -$ P3 = "VAXC" -$! -$! End The VAXC Compiler Check. -$! -$ ENDIF -$! -$! End The DECC & VAXC Compiler Check. -$! -$ ENDIF -$! -$! End The Compiler Check. -$! -$ ENDIF -$! -$! Check To See If We Have A Option For P4. -$! -$ IF (P4.EQS."") -$ THEN -$! -$! Find out what socket library we have available -$! -$ IF F$PARSE("SOCKETSHR:") .NES. "" -$ THEN -$! -$! We have SOCKETSHR, and it is my opinion that it's the best to use. -$! -$ P4 = "SOCKETSHR" -$! -$! Tell the user -$! -$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP" -$! -$! Else, let's look for something else -$! -$ ELSE -$! -$! Like UCX (the reason to do this before Multinet is that the UCX -$! emulation is easier to use...) -$! -$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" - - .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" - - .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. "" -$ THEN -$! -$! Last resort: a UCX or UCX-compatible library -$! -$ P4 = "UCX" -$! -$! Tell the user -$! -$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP" -$! -$! That was all... -$! -$ ENDIF -$ ENDIF -$ ENDIF -$! -$! Set Up Initial CC Definitions, Possibly With User Ones -$! -$ CCDEFS = "TCPIP_TYPE_''P4'" -$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS -$ CCEXTRAFLAGS = "" -$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS -$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR" -$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" -$ THEN -$ IF CCDISABLEWARNINGS .NES. THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," -$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS -$ ENDIF -$! -$! Check To See If We Have A ZLIB Option. -$! -$ ZLIB = P7 -$ IF (ZLIB .NES. "") -$ THEN -$! -$! Check for expected ZLIB files. -$! -$ err = 0 -$ file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY") -$ if (f$search( file1) .eqs. "") -$ then -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid." -$ WRITE SYS$OUTPUT " Can't find header: ''file1'" -$ err = 1 -$ endif -$ file1 = f$parse( "A.;", ZLIB)- "A.;" -$! -$ file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY") -$ if (f$search( file2) .eqs. "") -$ then -$ if (err .eq. 0) -$ then -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid." -$ endif -$ WRITE SYS$OUTPUT " Can't find library: ''file2'" -$ WRITE SYS$OUTPUT "" -$ err = err+ 2 -$ endif -$ if (err .eq. 1) -$ then -$ WRITE SYS$OUTPUT "" -$ endif -$! -$ if (err .ne. 0) -$ then -$ EXIT -$ endif -$! -$ CCDEFS = """ZLIB=1"", "+ CCDEFS -$ CC_INCLUDES = CC_INCLUDES+ ", "+ file1 -$ ZLIB_LIB = ", ''file2' /library" -$! -$! Print info -$! -$ WRITE SYS$OUTPUT "ZLIB library spec: ", file2 -$! -$! End The ZLIB Check. -$! -$ ENDIF -$! -$! Check To See If The User Entered A Valid Parameter. -$! -$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC") -$ THEN -$! -$! Check To See If The User Wanted DECC. -$! -$ IF (P3.EQS."DECC") -$ THEN -$! -$! Looks Like DECC, Set To Use DECC. -$! -$ COMPILER = "DECC" -$! -$! Tell The User We Are Using DECC. -$! -$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler." -$! -$! Use DECC... -$! -$ CC = "CC" -$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" - - THEN CC = "CC/DECC" -$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ - - "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + - - " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS -$! -$! Define The Linker Options File Name. -$! -$ OPT_FILE = "VAX_DECC_OPTIONS.OPT" -$! -$! End DECC Check. -$! -$ ENDIF -$! -$! Check To See If We Are To Use VAXC. -$! -$ IF (P3.EQS."VAXC") -$ THEN -$! -$! Looks Like VAXC, Set To Use VAXC. -$! -$ COMPILER = "VAXC" -$! -$! Tell The User We Are Using VAX C. -$! -$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler." -$! -$! Compile Using VAXC. -$! -$ CC = "CC" -$ IF ARCH.NES."VAX" -$ THEN -$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!" -$ EXIT -$ ENDIF -$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC" -$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - - "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS -$ CCDEFS = CCDEFS + ",""VAXC""" -$! -$! Define <sys> As SYS$COMMON:[SYSLIB] -$! -$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB] -$! -$! Define The Linker Options File Name. -$! -$ OPT_FILE = "VAX_VAXC_OPTIONS.OPT" -$! -$! End VAXC Check -$! -$ ENDIF -$! -$! Check To See If We Are To Use GNU C. -$! -$ IF (P3.EQS."GNUC") -$ THEN -$! -$! Looks Like GNUC, Set To Use GNUC. -$! -$ COMPILER = "GNUC" -$! -$! Tell The User We Are Using GNUC. -$! -$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler." -$! -$! Use GNU C... -$! -$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC -$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - - "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS -$! -$! Define The Linker Options File Name. -$! -$ OPT_FILE = "VAX_GNUC_OPTIONS.OPT" -$! -$! End The GNU C Check. -$! -$ ENDIF -$! -$! Set up default defines -$! -$ CCDEFS = """FLAT_INC=1""," + CCDEFS -$! -$! Finish up the definition of CC. -$! -$ IF COMPILER .EQS. "DECC" -$ THEN -$! Not all compiler versions support MAYLOSEDATA3. -$ OPT_TEST = "MAYLOSEDATA3" -$ DEFINE /USER_MODE SYS$ERROR NL: -$ DEFINE /USER_MODE SYS$OUTPUT NL: -$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT - - /WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL: -$ IF ($SEVERITY) -$ THEN -$ IF CCDISABLEWARNINGS .NES. "" THEN - - CCDISABLEWARNINGS = CCDISABLEWARNINGS+ "," -$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST -$ ENDIF -$ IF CCDISABLEWARNINGS .EQS. "" -$ THEN -$ CC4DISABLEWARNINGS = "DOLLARID" -$ ELSE -$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID" -$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))" -$ ENDIF -$ CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))" -$ ELSE -$ CCDISABLEWARNINGS = "" -$ CC4DISABLEWARNINGS = "" -$ ENDIF -$ CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS -$ CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS -$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS -$ IF COMPILER .EQS. "DECC" -$ THEN -$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS -$ CC5 = CC3 - CCDISABLEWARNINGS + CC4DISABLEWARNINGS -$ ELSE -$ CC4 = CC -$ CC5 = CC3 -$ ENDIF -$! -$! Show user the result -$! -$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC -$! -$! Else The User Entered An Invalid Argument. -$! -$ ELSE -$! -$! Tell The User We Don't Know What They Want. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:" -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C." -$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C." -$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C." -$ WRITE SYS$OUTPUT "" -$! -$! Time To EXIT. -$! -$ EXIT -$ ENDIF -$! -$! Time to check the contents, and to make sure we get the correct library. -$! -$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" - - .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE" -$ THEN -$! -$! Check to see if SOCKETSHR was chosen -$! -$ IF P4.EQS."SOCKETSHR" -$ THEN -$! -$! Set the library to use SOCKETSHR -$! -$ TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS" -$! -$! Done with SOCKETSHR -$! -$ ENDIF -$! -$! Check to see if MULTINET was chosen -$! -$ IF P4.EQS."MULTINET" -$ THEN -$! -$! Set the library to use UCX emulation. -$! -$ P4 = "UCX" -$! -$! Done with MULTINET -$! -$ ENDIF -$! -$! Check to see if UCX was chosen -$! -$ IF P4.EQS."UCX" -$ THEN -$! -$! Set the library to use UCX. -$! -$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS" -$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -$ THEN -$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS" -$ ELSE -$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN - - TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS" -$ ENDIF -$! -$! Done with UCX -$! -$ ENDIF -$! -$! Check to see if TCPIP was chosen -$! -$ IF P4.EQS."TCPIP" -$ THEN -$! -$! Set the library to use TCPIP (post UCX). -$! -$ TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS" -$! -$! Done with TCPIP -$! -$ ENDIF -$! -$! Check to see if NONE was chosen -$! -$ IF P4.EQS."NONE" -$ THEN -$! -$! Do not use a TCPIP library. -$! -$ TCPIP_LIB = "" -$! -$! Done with NONE -$! -$ ENDIF -$! -$! Print info -$! -$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- "," -$! -$! Else The User Entered An Invalid Argument. -$! -$ ELSE -$! -$! Tell The User We Don't Know What They Want. -$! -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:" -$ WRITE SYS$OUTPUT "" -$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library." -$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library." -$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library." -$ WRITE SYS$OUTPUT "" -$! -$! Time To EXIT. -$! -$ EXIT -$! -$! Done with TCP/IP libraries -$! -$ ENDIF -$! -$! Time To RETURN... -$! -$ RETURN -$! -$ INITIALISE: -$! -$! Save old value of the logical name OPENSSL -$! -$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE") -$! -$! Save directory information -$! -$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;" -$ __HERE = F$EDIT(__HERE,"UPCASE") -$ __TOP = __HERE - "SSL]" -$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]" -$! -$! Set up the logical name OPENSSL to point at the include directory -$! -$ DEFINE OPENSSL/NOLOG '__INCLUDE' -$! -$! Done -$! -$ RETURN -$! -$ CLEANUP: -$! -$! Restore the logical name OPENSSL if it had a value -$! -$ IF __SAVE_OPENSSL .EQS. "" -$ THEN -$ DEASSIGN OPENSSL -$ ELSE -$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL' -$ ENDIF -$! -$! Done -$! -$ RETURN diff --git a/thirdparty/openssl/ssl/ssl_asn1.c b/thirdparty/openssl/ssl/ssl_asn1.c index 35cc27c5e9..499f0e85ad 100644 --- a/thirdparty/openssl/ssl/ssl_asn1.c +++ b/thirdparty/openssl/ssl/ssl_asn1.c @@ -527,6 +527,9 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, if (os.length > SSL_MAX_SID_CTX_LENGTH) { c.error = SSL_R_BAD_LENGTH; c.line = __LINE__; + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; goto err; } else { ret->sid_ctx_length = os.length; diff --git a/thirdparty/openssl/ssl/ssl_cert.c b/thirdparty/openssl/ssl/ssl_cert.c index f48ebaecc0..155728d037 100644 --- a/thirdparty/openssl/ssl/ssl_cert.c +++ b/thirdparty/openssl/ssl/ssl_cert.c @@ -315,7 +315,7 @@ CERT *ssl_cert_dup(CERT *cert) OPENSSL_malloc(cert->pkeys[i].serverinfo_length); if (ret->pkeys[i].serverinfo == NULL) { SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); - return NULL; + goto err; } ret->pkeys[i].serverinfo_length = cert->pkeys[i].serverinfo_length; @@ -392,9 +392,7 @@ CERT *ssl_cert_dup(CERT *cert) return (ret); -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) err: -#endif #ifndef OPENSSL_NO_RSA if (ret->rsa_tmp != NULL) RSA_free(ret->rsa_tmp); @@ -414,6 +412,7 @@ CERT *ssl_cert_dup(CERT *cert) #endif ssl_cert_clear_certs(ret); + OPENSSL_free(ret); return NULL; } diff --git a/thirdparty/openssl/ssl/ssl_ciph.c b/thirdparty/openssl/ssl/ssl_ciph.c index 302464e643..40021329a9 100644 --- a/thirdparty/openssl/ssl/ssl_ciph.c +++ b/thirdparty/openssl/ssl/ssl_ciph.c @@ -1932,17 +1932,27 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) } #ifdef OPENSSL_NO_COMP -void *SSL_COMP_get_compression_methods(void) +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) +{ + return NULL; +} + +STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP) + *meths) { return NULL; } -int SSL_COMP_add_compression_method(int id, void *cm) +void SSL_COMP_free_compression_methods(void) +{ +} + +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; } -const char *SSL_COMP_get_name(const void *comp) +const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; } @@ -1991,13 +2001,19 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) if (id < 193 || id > 255) { SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); - return 0; + return 1; } MemCheck_off(); comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp == NULL) { + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); + return 1; + } comp->id = id; comp->method = cm; + comp->name = cm->name; load_builtin_compressions(); if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { OPENSSL_free(comp); diff --git a/thirdparty/openssl/ssl/ssl_err.c b/thirdparty/openssl/ssl/ssl_err.c index 704088dc46..a4c17a6bf3 100644 --- a/thirdparty/openssl/ssl/ssl_err.c +++ b/thirdparty/openssl/ssl/ssl_err.c @@ -1,6 +1,6 @@ /* ssl/ssl_err.c */ /* ==================================================================== - * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2016 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 @@ -93,6 +93,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"}, {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "dtls1_output_cert_chain"}, {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS), + "DTLS1_PROCESS_BUFFERED_RECORDS"}, {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, @@ -751,6 +753,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = { "tls illegal exporter label"}, {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), "tls invalid ecpointformat list"}, + {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"}, {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), "tls peer did not respond with certificate list"}, {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), diff --git a/thirdparty/openssl/ssl/ssl_lib.c b/thirdparty/openssl/ssl/ssl_lib.c index fd94325bb3..24be376c9f 100644 --- a/thirdparty/openssl/ssl/ssl_lib.c +++ b/thirdparty/openssl/ssl/ssl_lib.c @@ -1828,7 +1828,7 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, const unsigned char *p, size_t plen, int use_context) { - if (s->version < TLS1_VERSION) + if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER) return -1; return s->method->ssl3_enc->export_keying_material(s, out, olen, label, @@ -1838,13 +1838,21 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, static unsigned long ssl_session_hash(const SSL_SESSION *a) { + const unsigned char *session_id = a->session_id; unsigned long l; + unsigned char tmp_storage[4]; + + if (a->session_id_length < sizeof(tmp_storage)) { + memset(tmp_storage, 0, sizeof(tmp_storage)); + memcpy(tmp_storage, a->session_id, a->session_id_length); + session_id = tmp_storage; + } l = (unsigned long) - ((unsigned int)a->session_id[0]) | - ((unsigned int)a->session_id[1] << 8L) | - ((unsigned long)a->session_id[2] << 16L) | - ((unsigned long)a->session_id[3] << 24L); + ((unsigned long)session_id[0]) | + ((unsigned long)session_id[1] << 8L) | + ((unsigned long)session_id[2] << 16L) | + ((unsigned long)session_id[3] << 24L); return (l); } @@ -2000,7 +2008,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->tlsext_servername_callback = 0; ret->tlsext_servername_arg = NULL; /* Setup RFC4507 ticket keys */ - if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) + if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) ret->options |= SSL_OP_NO_TICKET; @@ -2030,10 +2038,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->rbuf_freelist->len = 0; ret->rbuf_freelist->head = NULL; ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); - if (!ret->wbuf_freelist) { - OPENSSL_free(ret->rbuf_freelist); + if (!ret->wbuf_freelist) goto err; - } ret->wbuf_freelist->chunklen = 0; ret->wbuf_freelist->len = 0; ret->wbuf_freelist->head = NULL; @@ -3050,12 +3056,12 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) } #ifdef OPENSSL_NO_COMP -const void *SSL_get_current_compression(SSL *s) +const COMP_METHOD *SSL_get_current_compression(SSL *s) { return NULL; } -const void *SSL_get_current_expansion(SSL *s) +const COMP_METHOD *SSL_get_current_expansion(SSL *s) { return NULL; } @@ -3188,6 +3194,9 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len; ocert->alpn_proposed = NULL; ssl->cert->alpn_sent = ocert->alpn_sent; + + if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext)) + return NULL; #endif ssl_cert_free(ocert); } diff --git a/thirdparty/openssl/ssl/ssl_locl.h b/thirdparty/openssl/ssl/ssl_locl.h index 747e718a52..aeffc00634 100644 --- a/thirdparty/openssl/ssl/ssl_locl.h +++ b/thirdparty/openssl/ssl/ssl_locl.h @@ -491,6 +491,12 @@ # define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \ ((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \ (!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION)) +/* + * Determine if a client should send signature algorithms extension: + * as with TLS1.2 cipher we can't rely on method flags. + */ +# define SSL_CLIENT_USE_SIGALGS(s) \ + SSL_CLIENT_USE_TLS1_2_CIPHERS(s) /* Mostly for SSLv3 */ # define SSL_PKEY_RSA_ENC 0 @@ -585,6 +591,8 @@ typedef struct { */ # define SSL_EXT_FLAG_SENT 0x2 +# define MAX_WARN_ALERT_COUNT 5 + typedef struct { custom_ext_method *meths; size_t meths_count; @@ -692,6 +700,8 @@ typedef struct cert_st { unsigned char *alpn_proposed; /* server */ unsigned int alpn_proposed_len; int alpn_sent; /* client */ + /* Count of the number of consecutive warning alerts received */ + unsigned int alert_count; } CERT; typedef struct sess_cert_st { @@ -1148,7 +1158,7 @@ long ssl2_default_timeout(void); const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -void ssl3_init_finished_mac(SSL *s); +int ssl3_init_finished_mac(SSL *s); int ssl3_send_server_certificate(SSL *s); int ssl3_send_newsession_ticket(SSL *s); int ssl3_send_cert_status(SSL *s); @@ -1242,7 +1252,8 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, int *found); int dtls1_get_queue_priority(unsigned short seq, int is_ccs); int dtls1_retransmit_buffered_messages(SSL *s); -void dtls1_clear_record_buffer(SSL *s); +void dtls1_clear_received_buffer(SSL *s); +void dtls1_clear_sent_buffer(SSL *s); void dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr); void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); @@ -1373,7 +1384,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, unsigned char *limit); int tls1_set_server_sigalgs(SSL *s); -int ssl_check_clienthello_tlsext_late(SSL *s); +int ssl_check_clienthello_tlsext_late(SSL *s, int *al); int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, unsigned char *d, int n); int ssl_prepare_clienthello_tlsext(SSL *s); @@ -1419,7 +1430,7 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, long ssl_get_algorithm2(SSL *s); int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize); int tls1_process_sigalgs(SSL *s); -size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs); +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs); int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, const unsigned char *sig, EVP_PKEY *pkey); void ssl_set_client_disabled(SSL *s); @@ -1471,6 +1482,8 @@ int custom_ext_add(SSL *s, int server, unsigned char **pret, unsigned char *limit, int *al); int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src); +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src); void custom_exts_free(custom_ext_methods *exts); # else diff --git a/thirdparty/openssl/ssl/ssl_rsa.c b/thirdparty/openssl/ssl/ssl_rsa.c index 82022470bf..af03d45c2e 100644 --- a/thirdparty/openssl/ssl/ssl_rsa.c +++ b/thirdparty/openssl/ssl/ssl_rsa.c @@ -912,6 +912,8 @@ static int serverinfo_process_buffer(const unsigned char *serverinfo, int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length) { + unsigned char *new_serverinfo; + if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER); return 0; @@ -928,12 +930,13 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR); return 0; } - ctx->cert->key->serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, - serverinfo_length); - if (ctx->cert->key->serverinfo == NULL) { + new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo, + serverinfo_length); + if (new_serverinfo == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE); return 0; } + ctx->cert->key->serverinfo = new_serverinfo; memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length); ctx->cert->key->serverinfo_length = serverinfo_length; @@ -961,6 +964,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) int ret = 0; BIO *bin = NULL; size_t num_extensions = 0; + unsigned char *new_serverinfo; if (ctx == NULL || file == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, @@ -1011,12 +1015,13 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) goto end; } /* Append the decoded extension to the serverinfo buffer */ - serverinfo = + new_serverinfo = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length); - if (serverinfo == NULL) { + if (new_serverinfo == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); goto end; } + serverinfo = new_serverinfo; memcpy(serverinfo + serverinfo_length, extension, extension_length); serverinfo_length += extension_length; diff --git a/thirdparty/openssl/ssl/ssl_sess.c b/thirdparty/openssl/ssl/ssl_sess.c index b182998343..f50f514212 100644 --- a/thirdparty/openssl/ssl/ssl_sess.c +++ b/thirdparty/openssl/ssl/ssl_sess.c @@ -382,7 +382,7 @@ static int def_generate_session_id(const SSL *ssl, unsigned char *id, { unsigned int retry = 0; do - if (RAND_pseudo_bytes(id, *id_len) <= 0) + if (RAND_bytes(id, *id_len) <= 0) return 0; while (SSL_has_matching_session_id(ssl, id, *id_len) && (++retry < MAX_SESS_ID_ATTEMPTS)) ; @@ -573,7 +573,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, int r; #endif - if (session_id + len > limit) { + if (limit - session_id < len) { fatal = 1; goto err; } @@ -769,6 +769,15 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) * obtain the same session from an external cache) */ s = NULL; + } else if (s == NULL && + lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) { + /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */ + + /* + * ... so take back the extra reference and also don't add + * the session to the SSL_SESSION_list at this time + */ + s = c; } /* Put at the head of the queue unless it is already in the cache */ @@ -919,6 +928,10 @@ int SSL_set_session(SSL *s, SSL_SESSION *session) session->krb5_client_princ_len > 0) { s->kssl_ctx->client_princ = (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); + if (s->kssl_ctx->client_princ == NULL) { + SSLerr(SSL_F_SSL_SET_SESSION, ERR_R_MALLOC_FAILURE); + return 0; + } memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, session->krb5_client_princ_len); s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; @@ -993,7 +1006,8 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, return 0; } s->sid_ctx_length = sid_ctx_len; - memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + if (s->sid_ctx != sid_ctx) + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); return 1; } @@ -1123,7 +1137,7 @@ int ssl_clear_bad_session(SSL *s) if ((s->session != NULL) && !(s->shutdown & SSL_SENT_SHUTDOWN) && !(SSL_in_init(s) || SSL_in_before(s))) { - SSL_CTX_remove_session(s->ctx, s->session); + SSL_CTX_remove_session(s->session_ctx, s->session); return (1); } else return (0); diff --git a/thirdparty/openssl/ssl/t1_enc.c b/thirdparty/openssl/ssl/t1_enc.c index 514fcb3e4e..b6d1ee95a5 100644 --- a/thirdparty/openssl/ssl/t1_enc.c +++ b/thirdparty/openssl/ssl/t1_enc.c @@ -673,7 +673,6 @@ int tls1_setup_key_block(SSL *s) if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); - OPENSSL_free(p1); goto err; } #ifdef TLS_DEBUG diff --git a/thirdparty/openssl/ssl/t1_ext.c b/thirdparty/openssl/ssl/t1_ext.c index 724ddf76ac..0f4aba0226 100644 --- a/thirdparty/openssl/ssl/t1_ext.c +++ b/thirdparty/openssl/ssl/t1_ext.c @@ -179,6 +179,25 @@ int custom_ext_add(SSL *s, int server, return 1; } +/* Copy the flags from src to dst for any extensions that exist in both */ +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src) +{ + size_t i; + custom_ext_method *methsrc = src->meths; + + for (i = 0; i < src->meths_count; i++, methsrc++) { + custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type); + + if (methdst == NULL) + continue; + + methdst->ext_flags = methsrc->ext_flags; + } + + return 1; +} + /* Copy table of custom extensions */ int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src) { @@ -223,16 +242,14 @@ static int custom_ext_meth_add(custom_ext_methods *exts, /* Search for duplicate */ if (custom_ext_find(exts, ext_type)) return 0; - exts->meths = OPENSSL_realloc(exts->meths, - (exts->meths_count + - 1) * sizeof(custom_ext_method)); - - if (!exts->meths) { - exts->meths_count = 0; + meth = OPENSSL_realloc(exts->meths, + (exts->meths_count + 1) + * sizeof(custom_ext_method)); + if (meth == NULL) return 0; - } - meth = exts->meths + exts->meths_count; + exts->meths = meth; + meth += exts->meths_count; memset(meth, 0, sizeof(custom_ext_method)); meth->parse_cb = parse_cb; meth->add_cb = add_cb; @@ -275,7 +292,9 @@ int SSL_extension_supported(unsigned int ext_type) case TLSEXT_TYPE_ec_point_formats: case TLSEXT_TYPE_elliptic_curves: case TLSEXT_TYPE_heartbeat: +# ifndef OPENSSL_NO_NEXTPROTONEG case TLSEXT_TYPE_next_proto_neg: +# endif case TLSEXT_TYPE_padding: case TLSEXT_TYPE_renegotiate: case TLSEXT_TYPE_server_name: diff --git a/thirdparty/openssl/ssl/t1_lib.c b/thirdparty/openssl/ssl/t1_lib.c index dd5bd0050d..6587e8bb68 100644 --- a/thirdparty/openssl/ssl/t1_lib.c +++ b/thirdparty/openssl/ssl/t1_lib.c @@ -132,6 +132,9 @@ static int ssl_check_clienthello_tlsext_early(SSL *s); int ssl_check_serverhello_tlsext(SSL *s); #endif +#define CHECKLEN(curr, val, limit) \ + (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val)) + SSL3_ENC_METHOD TLSv1_enc_data = { tls1_enc, tls1_mac, @@ -1032,7 +1035,7 @@ static unsigned char suiteb_sigalgs[] = { tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) }; # endif -size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs) { /* * If Suite B mode use Suite B sigalgs only, ignore any other @@ -1054,7 +1057,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) } # endif /* If server use client authentication sigalgs if not NULL */ - if (s->server && s->cert->client_sigalgs) { + if (s->server == sent && s->cert->client_sigalgs) { *psigs = s->cert->client_sigalgs; return s->cert->client_sigalgslen; } else if (s->cert->conf_sigalgs) { @@ -1118,7 +1121,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, # endif /* Check signature matches a type we sent */ - sent_sigslen = tls12_get_psigalgs(s, &sent_sigs); + sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1]) break; @@ -1166,7 +1169,7 @@ void ssl_set_client_disabled(SSL *s) * Now go through all signature algorithms seeing if we support any for * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. */ - sigalgslen = tls12_get_psigalgs(s, &sigalgs); + sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { switch (sigalgs[1]) { # ifndef OPENSSL_NO_RSA @@ -1263,8 +1266,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (s->tlsext_hostname != NULL) { /* Add TLS extension servername to the Client Hello message */ - unsigned long size_str; - long lenmax; + size_t size_str; /*- * check for enough space. @@ -1274,10 +1276,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, * 2 for hostname length * + hostname length */ - - if ((lenmax = limit - ret - 9) < 0 - || (size_str = - strlen(s->tlsext_hostname)) > (unsigned long)lenmax) + size_str = strlen(s->tlsext_hostname); + if (CHECKLEN(ret, 9 + size_str, limit)) return NULL; /* extension type and length */ @@ -1321,7 +1321,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the * Client Hello message */ - int login_len = strlen(s->srp_ctx.login); + size_t login_len = strlen(s->srp_ctx.login); if (login_len > 255 || login_len == 0) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return NULL; @@ -1333,7 +1333,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, * 1 for the srp user identity * + srp user identity length */ - if ((limit - ret - 5 - login_len) < 0) + if (CHECKLEN(ret, 5 + login_len, limit)) return NULL; /* fill in the extension */ @@ -1350,20 +1350,23 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, /* * Add TLS extension ECPointFormats to the ClientHello message */ - long lenmax; const unsigned char *pcurves, *pformats; size_t num_curves, num_formats, curves_list_len; tls1_get_formatlist(s, &pformats, &num_formats); - if ((lenmax = limit - ret - 5) < 0) - return NULL; - if (num_formats > (size_t)lenmax) - return NULL; if (num_formats > 255) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return NULL; } + /*- + * check for enough space. + * 4 bytes for the ec point formats type and extension length + * 1 byte for the length of the formats + * + formats length + */ + if (CHECKLEN(ret, 5 + num_formats, limit)) + return NULL; s2n(TLSEXT_TYPE_ec_point_formats, ret); /* The point format list has 1-byte length. */ @@ -1379,15 +1382,20 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves)) return NULL; - if ((lenmax = limit - ret - 6) < 0) - return NULL; - if (num_curves > (size_t)lenmax / 2) - return NULL; if (num_curves > 65532 / 2) { SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return NULL; } curves_list_len = 2 * num_curves; + /*- + * check for enough space. + * 4 bytes for the ec curves type and extension length + * 2 bytes for the curve list length + * + curve list length + */ + if (CHECKLEN(ret, 6 + curves_list_len, limit)) + return NULL; + s2n(TLSEXT_TYPE_elliptic_curves, ret); s2n(curves_list_len + 2, ret); s2n(curves_list_len, ret); @@ -1397,7 +1405,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, # endif /* OPENSSL_NO_EC */ if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { - int ticklen; + size_t ticklen; if (!s->new_session && s->session && s->session->tlsext_tick) ticklen = s->session->tlsext_ticklen; else if (s->session && s->tlsext_session_ticket && @@ -1418,22 +1426,29 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, * Check for enough room 2 for extension type, 2 for len rest for * ticket */ - if ((long)(limit - ret - 4 - ticklen) < 0) + if (CHECKLEN(ret, 4 + ticklen, limit)) return NULL; s2n(TLSEXT_TYPE_session_ticket, ret); s2n(ticklen, ret); - if (ticklen) { + if (ticklen > 0) { memcpy(ret, s->session->tlsext_tick, ticklen); ret += ticklen; } } skip_ext: - if (SSL_USE_SIGALGS(s)) { + if (SSL_CLIENT_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; - salglen = tls12_get_psigalgs(s, &salg); - if ((size_t)(limit - ret) < salglen + 6) + salglen = tls12_get_psigalgs(s, 1, &salg); + + /*- + * check for enough space. + * 4 bytes for the sigalgs type and extension length + * 2 bytes for the sigalg list length + * + sigalg list length + */ + if (CHECKLEN(ret, salglen + 6, limit)) return NULL; s2n(TLSEXT_TYPE_signature_algorithms, ret); s2n(salglen + 2, ret); @@ -1460,30 +1475,42 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { int i; - long extlen, idlen, itmp; + size_t extlen, idlen; + int lentmp; OCSP_RESPID *id; idlen = 0; for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); - itmp = i2d_OCSP_RESPID(id, NULL); - if (itmp <= 0) + lentmp = i2d_OCSP_RESPID(id, NULL); + if (lentmp <= 0) return NULL; - idlen += itmp + 2; + idlen += (size_t)lentmp + 2; } if (s->tlsext_ocsp_exts) { - extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); - if (extlen < 0) + lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); + if (lentmp < 0) return NULL; + extlen = (size_t)lentmp; } else extlen = 0; - if ((long)(limit - ret - 7 - extlen - idlen) < 0) - return NULL; - s2n(TLSEXT_TYPE_status_request, ret); if (extlen + idlen > 0xFFF0) return NULL; + /* + * 2 bytes for status request type + * 2 bytes for status request len + * 1 byte for OCSP request type + * 2 bytes for length of ids + * 2 bytes for length of extensions + * + length of ids + * + length of extensions + */ + if (CHECKLEN(ret, 9 + idlen + extlen, limit)) + return NULL; + + s2n(TLSEXT_TYPE_status_request, ret); s2n(extlen + idlen + 5, ret); *(ret++) = TLSEXT_STATUSTYPE_ocsp; s2n(idlen, ret); @@ -1493,9 +1520,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); /* skip over id len */ ret += 2; - itmp = i2d_OCSP_RESPID(id, &ret); + lentmp = i2d_OCSP_RESPID(id, &ret); /* write id len */ - s2n(itmp, q); + s2n(lentmp, q); } s2n(extlen, ret); if (extlen > 0) @@ -1503,8 +1530,15 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, } # ifndef OPENSSL_NO_HEARTBEATS /* Add Heartbeat extension */ - if ((limit - ret - 4 - 1) < 0) + + /*- + * check for enough space. + * 4 bytes for the heartbeat ext type and extension length + * 1 byte for the mode + */ + if (CHECKLEN(ret, 5, limit)) return NULL; + s2n(TLSEXT_TYPE_heartbeat, ret); s2n(1, ret); /*- @@ -1524,7 +1558,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, * The client advertises an emtpy extension to indicate its support * for Next Protocol Negotiation */ - if (limit - ret - 4 < 0) + + /*- + * check for enough space. + * 4 bytes for the NPN ext type and extension length + */ + if (CHECKLEN(ret, 4, limit)) return NULL; s2n(TLSEXT_TYPE_next_proto_neg, ret); s2n(0, ret); @@ -1532,7 +1571,13 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, # endif if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) { - if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) + /*- + * check for enough space. + * 4 bytes for the ALPN type and extension length + * 2 bytes for the ALPN protocol list length + * + ALPN protocol list length + */ + if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit)) return NULL; s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); s2n(2 + s->alpn_client_proto_list_len, ret); @@ -1547,7 +1592,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); - if ((limit - ret - 4 - el) < 0) + /*- + * check for enough space. + * 4 bytes for the SRTP type and extension length + * + SRTP profiles length + */ + if (CHECKLEN(ret, 4 + el, limit)) return NULL; s2n(TLSEXT_TYPE_use_srtp, ret); @@ -1587,6 +1637,17 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, else hlen = 0; + /*- + * check for enough space. Strictly speaking we know we've already + * got enough space because to get here the message size is < 0x200, + * but we know that we've allocated far more than that in the buffer + * - but for consistency and robustness we're going to check anyway. + * + * 4 bytes for the padding type and extension length + * + padding length + */ + if (CHECKLEN(ret, 4 + hlen, limit)) + return NULL; s2n(TLSEXT_TYPE_padding, ret); s2n(hlen, ret); memset(ret, 0, hlen); @@ -1644,7 +1705,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, return NULL; } - if ((limit - ret - 4 - el) < 0) + /*- + * check for enough space. + * 4 bytes for the reneg type and extension length + * + reneg data length + */ + if (CHECKLEN(ret, 4 + el, limit)) return NULL; s2n(TLSEXT_TYPE_renegotiate, ret); @@ -1664,19 +1730,23 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, /* * Add TLS extension ECPointFormats to the ServerHello message */ - long lenmax; tls1_get_formatlist(s, &plist, &plistlen); - if ((lenmax = limit - ret - 5) < 0) - return NULL; - if (plistlen > (size_t)lenmax) - return NULL; if (plistlen > 255) { SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); return NULL; } + /*- + * check for enough space. + * 4 bytes for the ec points format type and extension length + * 1 byte for the points format list length + * + length of points format list + */ + if (CHECKLEN(ret, 5 + plistlen, limit)) + return NULL; + s2n(TLSEXT_TYPE_ec_point_formats, ret); s2n(plistlen + 1, ret); *(ret++) = (unsigned char)plistlen; @@ -1691,14 +1761,25 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, # endif /* OPENSSL_NO_EC */ if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) { - if ((long)(limit - ret - 4) < 0) + /*- + * check for enough space. + * 4 bytes for the Ticket type and extension length + */ + if (CHECKLEN(ret, 4, limit)) return NULL; s2n(TLSEXT_TYPE_session_ticket, ret); s2n(0, ret); + } else { + /* if we don't add the above TLSEXT, we can't add a session ticket later */ + s->tlsext_ticket_expected = 0; } if (s->tlsext_status_expected) { - if ((long)(limit - ret - 4) < 0) + /*- + * check for enough space. + * 4 bytes for the Status request type and extension length + */ + if (CHECKLEN(ret, 4, limit)) return NULL; s2n(TLSEXT_TYPE_status_request, ret); s2n(0, ret); @@ -1726,7 +1807,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); - if ((limit - ret - 4 - el) < 0) + /*- + * check for enough space. + * 4 bytes for the SRTP profiles type and extension length + * + length of the SRTP profiles list + */ + if (CHECKLEN(ret, 4 + el, limit)) return NULL; s2n(TLSEXT_TYPE_use_srtp, ret); @@ -1751,16 +1837,23 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 }; - if (limit - ret < 36) + + /* check for enough space. */ + if (CHECKLEN(ret, sizeof(cryptopro_ext), limit)) return NULL; - memcpy(ret, cryptopro_ext, 36); - ret += 36; + memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext)); + ret += sizeof(cryptopro_ext); } # ifndef OPENSSL_NO_HEARTBEATS /* Add Heartbeat extension if we've received one */ if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) { - if ((limit - ret - 4 - 1) < 0) + /*- + * check for enough space. + * 4 bytes for the Heartbeat type and extension length + * 1 byte for the mode + */ + if (CHECKLEN(ret, 5, limit)) return NULL; s2n(TLSEXT_TYPE_heartbeat, ret); s2n(1, ret); @@ -1789,7 +1882,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, s-> ctx->next_protos_advertised_cb_arg); if (r == SSL_TLSEXT_ERR_OK) { - if ((long)(limit - ret - 4 - npalen) < 0) + /*- + * check for enough space. + * 4 bytes for the NPN type and extension length + * + length of protocols list + */ + if (CHECKLEN(ret, 4 + npalen, limit)) return NULL; s2n(TLSEXT_TYPE_next_proto_neg, ret); s2n(npalen, ret); @@ -1804,9 +1902,16 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, if (s->s3->alpn_selected) { const unsigned char *selected = s->s3->alpn_selected; - unsigned len = s->s3->alpn_selected_len; + size_t len = s->s3->alpn_selected_len; - if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) + /*- + * check for enough space. + * 4 bytes for the ALPN type and extension length + * 2 bytes for ALPN data length + * 1 byte for selected protocol length + * + length of the selected protocol + */ + if (CHECKLEN(ret, 7 + len, limit)) return NULL; s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret); s2n(3 + len, ret); @@ -1867,11 +1972,11 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, 0x02, 0x03, /* SHA-1/ECDSA */ }; - if (data >= (limit - 2)) + if (limit - data <= 2) return; data += 2; - if (data > (limit - 4)) + if (limit - data < 4) return; n2s(data, type); n2s(data, size); @@ -1879,7 +1984,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, if (type != TLSEXT_TYPE_server_name) return; - if (data + size > limit) + if (limit - data < size) return; data += size; @@ -1887,7 +1992,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, const size_t len1 = sizeof(kSafariExtensionsBlock); const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); - if (data + len1 + len2 != limit) + if (limit - data != (int)(len1 + len2)) return; if (memcmp(data, kSafariExtensionsBlock, len1) != 0) return; @@ -1896,7 +2001,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data, } else { const size_t len = sizeof(kSafariExtensionsBlock); - if (data + len != limit) + if (limit - data != (int)(len)) return; if (memcmp(data, kSafariExtensionsBlock, len) != 0) return; @@ -1966,11 +2071,10 @@ static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data, /* * Process the ALPN extension in a ClientHello. - * ret: a pointer to the TLSEXT return value: SSL_TLSEXT_ERR_* * al: a pointer to the alert value to send in the event of a failure. - * returns 1 on success, 0 on failure: al/ret set only on failure + * returns 1 on success, 0 on failure: al set only on failure */ -static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al) +static int tls1_alpn_handle_client_hello_late(SSL *s, int *al) { const unsigned char *selected = NULL; unsigned char selected_len = 0; @@ -1986,7 +2090,6 @@ static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al) s->s3->alpn_selected = OPENSSL_malloc(selected_len); if (s->s3->alpn_selected == NULL) { *al = SSL_AD_INTERNAL_ERROR; - *ret = SSL_TLSEXT_ERR_ALERT_FATAL; return 0; } memcpy(s->s3->alpn_selected, selected, selected_len); @@ -2053,19 +2156,19 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, if (data == limit) goto ri_check; - if (data > (limit - 2)) + if (limit - data < 2) goto err; n2s(data, len); - if (data + len != limit) + if (limit - data != len) goto err; - while (data <= (limit - 4)) { + while (limit - data >= 4) { n2s(data, type); n2s(data, size); - if (data + size > (limit)) + if (limit - data < size) goto err; # if 0 fprintf(stderr, "Received extension type %d size %d\n", type, size); @@ -2316,6 +2419,23 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, size -= 2; if (dsize > size) goto err; + + /* + * We remove any OCSP_RESPIDs from a previous handshake + * to prevent unbounded memory growth - CVE-2016-6304 + */ + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, + OCSP_RESPID_free); + if (dsize > 0) { + s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null(); + if (s->tlsext_ocsp_ids == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } else { + s->tlsext_ocsp_ids = NULL; + } + while (dsize > 0) { OCSP_RESPID *id; int idsize; @@ -2335,13 +2455,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, OCSP_RESPID_free(id); goto err; } - if (!s->tlsext_ocsp_ids - && !(s->tlsext_ocsp_ids = - sk_OCSP_RESPID_new_null())) { - OCSP_RESPID_free(id); - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { OCSP_RESPID_free(id); *al = SSL_AD_INTERNAL_ERROR; @@ -2472,18 +2585,18 @@ static int ssl_scan_clienthello_custom_tlsext(SSL *s, if (s->hit || s->cert->srv_ext.meths_count == 0) return 1; - if (data >= limit - 2) + if (limit - data <= 2) return 1; n2s(data, len); - if (data > limit - len) + if (limit - data < len) return 1; - while (data <= limit - 4) { + while (limit - data >= 4) { n2s(data, type); n2s(data, size); - if (data + size > limit) + if (limit - data < size) return 1; if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0) return 0; @@ -2569,20 +2682,20 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, SSL_TLSEXT_HB_DONT_SEND_REQUESTS); # endif - if (data >= (d + n - 2)) + if ((d + n) - data <= 2) goto ri_check; n2s(data, length); - if (data + length != d + n) { + if ((d + n) - data != length) { *al = SSL_AD_DECODE_ERROR; return 0; } - while (data <= (d + n - 4)) { + while ((d + n) - data >= 4) { n2s(data, type); n2s(data, size); - if (data + size > (d + n)) + if ((d + n) - data < size) goto ri_check; if (s->tlsext_debug_cb) @@ -2712,6 +2825,11 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, *al = TLS1_AD_INTERNAL_ERROR; return 0; } + /* + * Could be non-NULL if server has sent multiple NPN extensions in + * a single Serverhello + */ + OPENSSL_free(s->next_proto_negotiated); s->next_proto_negotiated = OPENSSL_malloc(selected_len); if (!s->next_proto_negotiated) { *al = TLS1_AD_INTERNAL_ERROR; @@ -3049,10 +3167,12 @@ int tls1_set_server_sigalgs(SSL *s) return 0; } -int ssl_check_clienthello_tlsext_late(SSL *s) +/* + * Upon success, returns 1. + * Upon failure, returns 0 and sets |al| to the appropriate fatal alert. + */ +int ssl_check_clienthello_tlsext_late(SSL *s, int *al) { - int ret = SSL_TLSEXT_ERR_OK; - int al; /* * If status request then ask callback what to do. Note: this must be @@ -3061,58 +3181,41 @@ int ssl_check_clienthello_tlsext_late(SSL *s) * influence which certificate is sent */ if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { - int r; + int ret; CERT_PKEY *certpkey; certpkey = ssl_get_server_send_pkey(s); /* If no certificate can't return certificate status */ - if (certpkey == NULL) { - s->tlsext_status_expected = 0; - return 1; - } - /* - * Set current certificate to one we will use so SSL_get_certificate - * et al can pick it up. - */ - s->cert->key = certpkey; - r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); - switch (r) { - /* We don't want to send a status request response */ - case SSL_TLSEXT_ERR_NOACK: - s->tlsext_status_expected = 0; - break; - /* status request response should be sent */ - case SSL_TLSEXT_ERR_OK: - if (s->tlsext_ocsp_resp) - s->tlsext_status_expected = 1; - else + if (certpkey != NULL) { + /* + * Set current certificate to one we will use so SSL_get_certificate + * et al can pick it up. + */ + s->cert->key = certpkey; + ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + switch (ret) { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: s->tlsext_status_expected = 0; - break; - /* something bad happened */ - case SSL_TLSEXT_ERR_ALERT_FATAL: - ret = SSL_TLSEXT_ERR_ALERT_FATAL; - al = SSL_AD_INTERNAL_ERROR; - goto err; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + default: + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } } - } else - s->tlsext_status_expected = 0; - - if (!tls1_alpn_handle_client_hello_late(s, &ret, &al)) { - goto err; } - err: - switch (ret) { - case SSL_TLSEXT_ERR_ALERT_FATAL: - ssl3_send_alert(s, SSL3_AL_FATAL, al); - return -1; - - case SSL_TLSEXT_ERR_ALERT_WARNING: - ssl3_send_alert(s, SSL3_AL_WARNING, al); - return 1; - - default: - return 1; + if (!tls1_alpn_handle_client_hello_late(s, al)) { + return 0; } + + return 1; } int ssl_check_serverhello_tlsext(SSL *s) @@ -3307,29 +3410,33 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, /* Skip past DTLS cookie */ if (SSL_IS_DTLS(s)) { i = *(p++); - p += i; - if (p >= limit) + + if (limit - p <= i) return -1; + + p += i; } /* Skip past cipher list */ n2s(p, i); - p += i; - if (p >= limit) + if (limit - p <= i) return -1; + p += i; + /* Skip past compression algorithm list */ i = *(p++); - p += i; - if (p > limit) + if (limit - p < i) return -1; + p += i; + /* Now at start of extensions */ - if ((p + 2) >= limit) + if (limit - p <= 2) return 0; n2s(p, i); - while ((p + 4) <= limit) { + while (limit - p >= 4) { unsigned short type, size; n2s(p, type); n2s(p, size); - if (p + size > limit) + if (limit - p < size) return 0; if (type == TLSEXT_TYPE_session_ticket) { int r; @@ -3397,9 +3504,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, HMAC_CTX hctx; EVP_CIPHER_CTX ctx; SSL_CTX *tctx = s->initial_ctx; - /* Need at least keyname + iv + some encrypted data */ - if (eticklen < 48) - return 2; + /* Initialize session ticket encryption and HMAC contexts */ HMAC_CTX_init(&hctx); EVP_CIPHER_CTX_init(&ctx); @@ -3433,6 +3538,13 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, if (mlen < 0) { goto err; } + /* Sanity check ticket length: must exceed keyname + IV + HMAC */ + if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) { + HMAC_CTX_cleanup(&hctx); + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + eticklen -= mlen; /* Check HMAC of encrypted ticket */ if (HMAC_Update(&hctx, etick, eticklen) <= 0 @@ -3465,8 +3577,14 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, p = sdec; sess = d2i_SSL_SESSION(NULL, &p, slen); + slen -= p - sdec; OPENSSL_free(sdec); if (sess) { + /* Some additional consistency checks */ + if (slen != 0 || sess->session_id_length != 0) { + SSL_SESSION_free(sess); + return 2; + } /* * The session ID, if non-empty, is used by some clients to detect * that the ticket has been accepted. So we copy it to the session @@ -3694,7 +3812,7 @@ static int tls1_set_shared_sigalgs(SSL *s) conf = c->conf_sigalgs; conflen = c->conf_sigalgslen; } else - conflen = tls12_get_psigalgs(s, &conf); + conflen = tls12_get_psigalgs(s, 0, &conf); if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { pref = conf; preflen = conflen; @@ -3902,7 +4020,7 @@ int tls1_process_heartbeat(SSL *s) memcpy(bp, pl, payload); bp += payload; /* Random padding */ - if (RAND_pseudo_bytes(bp, padding) < 0) { + if (RAND_bytes(bp, padding) <= 0) { OPENSSL_free(buffer); return -1; } @@ -3980,6 +4098,8 @@ int tls1_heartbeat(SSL *s) * - Padding */ buf = OPENSSL_malloc(1 + 2 + payload + padding); + if (buf == NULL) + return -1; p = buf; /* Message Type */ *p++ = TLS1_HB_REQUEST; @@ -3988,13 +4108,13 @@ int tls1_heartbeat(SSL *s) /* Sequence number */ s2n(s->tlsext_hb_seq, p); /* 16 random bytes */ - if (RAND_pseudo_bytes(p, 16) < 0) { + if (RAND_bytes(p, 16) <= 0) { SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } p += 16; /* Random padding */ - if (RAND_pseudo_bytes(p, padding) < 0) { + if (RAND_bytes(p, padding) <= 0) { SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); goto err; } |