aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/kde.scm
diff options
context:
space:
mode:
authorSharlatan Hellseher <sharlatanus@gmail.com>2024-09-09 20:17:20 +0100
committerSharlatan Hellseher <sharlatanus@gmail.com>2024-09-09 21:05:20 +0100
commit6da76f1f04782f87c9f637b84f48e06e42d71624 (patch)
treee1f66beb55ccbafd39dcec9f6bc48152ac8eb79c /gnu/packages/kde.scm
parentf415ce5a9678e5475ccabfdfe16019d0b563b8b1 (diff)
downloadguix-6da76f1f04782f87c9f637b84f48e06e42d71624.tar.gz
guix-6da76f1f04782f87c9f637b84f48e06e42d71624.zip
gnu: Add go-github-com-libp2p-go-libp2p.
* gnu/packages/ipfs.scm (go-github-com-libp2p-go-libp2p): New variable. Change-Id: I28d21513a07a4e11e7411390c692472473bf1844
Diffstat (limited to 'gnu/packages/kde.scm')
0 files changed, 0 insertions, 0 deletions
l/d1_lib.c1087
-rw-r--r--openssl-1.1.0h/ssl/d1_msg.c84
-rw-r--r--openssl-1.1.0h/ssl/d1_srtp.c329
-rw-r--r--openssl-1.1.0h/ssl/methods.c266
-rw-r--r--openssl-1.1.0h/ssl/packet_locl.h555
-rw-r--r--openssl-1.1.0h/ssl/pqueue.c154
-rw-r--r--openssl-1.1.0h/ssl/record/README74
-rw-r--r--openssl-1.1.0h/ssl/record/dtls1_bitmap.c78
-rw-r--r--openssl-1.1.0h/ssl/record/rec_layer_d1.c1229
-rw-r--r--openssl-1.1.0h/ssl/record/rec_layer_s3.c1549
-rw-r--r--openssl-1.1.0h/ssl/record/record.h243
-rw-r--r--openssl-1.1.0h/ssl/record/record_locl.h116
-rw-r--r--openssl-1.1.0h/ssl/record/ssl3_buffer.c163
-rw-r--r--openssl-1.1.0h/ssl/record/ssl3_record.c1641
-rw-r--r--openssl-1.1.0h/ssl/s3_cbc.c529
-rw-r--r--openssl-1.1.0h/ssl/s3_enc.c550
-rw-r--r--openssl-1.1.0h/ssl/s3_lib.c4140
-rw-r--r--openssl-1.1.0h/ssl/s3_msg.c102
-rw-r--r--openssl-1.1.0h/ssl/ssl_asn1.c367
-rw-r--r--openssl-1.1.0h/ssl/ssl_cert.c1087
-rw-r--r--openssl-1.1.0h/ssl/ssl_ciph.c1962
-rw-r--r--openssl-1.1.0h/ssl/ssl_conf.c893
-rw-r--r--openssl-1.1.0h/ssl/ssl_err.c689
-rw-r--r--openssl-1.1.0h/ssl/ssl_init.c210
-rw-r--r--openssl-1.1.0h/ssl/ssl_lib.c4476
-rw-r--r--openssl-1.1.0h/ssl/ssl_locl.h2133
-rw-r--r--openssl-1.1.0h/ssl/ssl_mcnf.c199
-rw-r--r--openssl-1.1.0h/ssl/ssl_rsa.c964
-rw-r--r--openssl-1.1.0h/ssl/ssl_sess.c1179
-rw-r--r--openssl-1.1.0h/ssl/ssl_stat.c362
-rw-r--r--openssl-1.1.0h/ssl/ssl_txt.c217
-rw-r--r--openssl-1.1.0h/ssl/ssl_utst.c28
-rw-r--r--openssl-1.1.0h/ssl/statem/README63
-rw-r--r--openssl-1.1.0h/ssl/statem/statem.c860
-rw-r--r--openssl-1.1.0h/ssl/statem/statem.h116
-rw-r--r--openssl-1.1.0h/ssl/statem/statem_clnt.c2946
-rw-r--r--openssl-1.1.0h/ssl/statem/statem_dtls.c1220
-rw-r--r--openssl-1.1.0h/ssl/statem/statem_lib.c1083
-rw-r--r--openssl-1.1.0h/ssl/statem/statem_locl.h125
-rw-r--r--openssl-1.1.0h/ssl/statem/statem_srvr.c3341
-rw-r--r--openssl-1.1.0h/ssl/t1_enc.c668
-rw-r--r--openssl-1.1.0h/ssl/t1_ext.c283
-rw-r--r--openssl-1.1.0h/ssl/t1_lib.c4228
-rw-r--r--openssl-1.1.0h/ssl/t1_reneg.c165
-rw-r--r--openssl-1.1.0h/ssl/t1_trce.c1322
-rw-r--r--openssl-1.1.0h/ssl/tls_srp.c430
48 files changed, 45035 insertions, 0 deletions
diff --git a/openssl-1.1.0h/ssl/bio_ssl.c b/openssl-1.1.0h/ssl/bio_ssl.c
new file mode 100644
index 0000000..97540e6
--- /dev/null
+++ b/openssl-1.1.0h/ssl/bio_ssl.c
@@ -0,0 +1,516 @@
+/*
+ * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/crypto.h>
+#include "internal/bio.h"
+#include <openssl/err.h>
+#include "ssl_locl.h"
+
+static int ssl_write(BIO *h, const char *buf, int num);
+static int ssl_read(BIO *h, char *buf, int size);
+static int ssl_puts(BIO *h, const char *str);
+static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int ssl_new(BIO *h);
+static int ssl_free(BIO *data);
+static long ssl_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
+typedef struct bio_ssl_st {
+ SSL *ssl; /* The ssl handle :-) */
+ /* re-negotiate every time the total number of bytes is this size */
+ int num_renegotiates;
+ unsigned long renegotiate_count;
+ unsigned long byte_count;
+ unsigned long renegotiate_timeout;
+ unsigned long last_time;
+} BIO_SSL;
+
+static const BIO_METHOD methods_sslp = {
+ BIO_TYPE_SSL,
+ "ssl",
+ ssl_write,
+ ssl_read,
+ ssl_puts,
+ NULL, /* ssl_gets, */
+ ssl_ctrl,
+ ssl_new,
+ ssl_free,
+ ssl_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_ssl(void)
+{
+ return (&methods_sslp);
+}
+
+static int ssl_new(BIO *bi)
+{
+ BIO_SSL *bs = OPENSSL_zalloc(sizeof(*bs));
+
+ if (bs == NULL) {
+ BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
+ return (0);
+ }
+ BIO_set_init(bi, 0);
+ BIO_set_data(bi, bs);
+ /* Clear all flags */
+ BIO_clear_flags(bi, ~0);
+
+ return 1;
+}
+
+static int ssl_free(BIO *a)
+{
+ BIO_SSL *bs;
+
+ if (a == NULL)
+ return (0);
+ bs = BIO_get_data(a);
+ if (bs->ssl != NULL)
+ SSL_shutdown(bs->ssl);
+ if (BIO_get_shutdown(a)) {
+ if (BIO_get_init(a))
+ SSL_free(bs->ssl);
+ /* Clear all flags */
+ BIO_clear_flags(a, ~0);
+ BIO_set_init(a, 0);
+ }
+ OPENSSL_free(bs);
+ return 1;
+}
+
+static int ssl_read(BIO *b, char *out, int outl)
+{
+ int ret = 1;
+ BIO_SSL *sb;
+ SSL *ssl;
+ int retry_reason = 0;
+ int r = 0;
+
+ if (out == NULL)
+ return (0);
+ sb = BIO_get_data(b);
+ ssl = sb->ssl;
+
+ BIO_clear_retry_flags(b);
+
+ ret = SSL_read(ssl, out, outl);
+
+ switch (SSL_get_error(ssl, ret)) {
+ case SSL_ERROR_NONE:
+ if (ret <= 0)
+ break;
+ if (sb->renegotiate_count > 0) {
+ sb->byte_count += ret;
+ if (sb->byte_count > sb->renegotiate_count) {
+ sb->byte_count = 0;
+ sb->num_renegotiates++;
+ SSL_renegotiate(ssl);
+ r = 1;
+ }
+ }
+ if ((sb->renegotiate_timeout > 0) && (!r)) {
+ unsigned long tm;
+
+ tm = (unsigned long)time(NULL);
+ if (tm > sb->last_time + sb->renegotiate_timeout) {
+ sb->last_time = tm;
+ sb->num_renegotiates++;
+ SSL_renegotiate(ssl);
+ }
+ }
+
+ break;
+ case SSL_ERROR_WANT_READ:
+ BIO_set_retry_read(b);
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ BIO_set_retry_write(b);
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ BIO_set_retry_special(b);
+ retry_reason = BIO_RR_SSL_X509_LOOKUP;
+ break;
+ case SSL_ERROR_WANT_ACCEPT:
+ BIO_set_retry_special(b);
+ retry_reason = BIO_RR_ACCEPT;
+ break;
+ case SSL_ERROR_WANT_CONNECT:
+ BIO_set_retry_special(b);
+ retry_reason = BIO_RR_CONNECT;
+ break;
+ case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SSL:
+ case SSL_ERROR_ZERO_RETURN:
+ default:
+ break;
+ }
+
+ BIO_set_retry_reason(b, retry_reason);
+ return (ret);
+}
+
+static int ssl_write(BIO *b, const char *out, int outl)
+{
+ int ret, r = 0;
+ int retry_reason = 0;
+ SSL *ssl;
+ BIO_SSL *bs;
+
+ if (out == NULL)
+ return (0);
+ bs = BIO_get_data(b);
+ ssl = bs->ssl;
+
+ BIO_clear_retry_flags(b);
+
+ /*
+ * ret=SSL_do_handshake(ssl); if (ret > 0)
+ */
+ ret = SSL_write(ssl, out, outl);
+
+ switch (SSL_get_error(ssl, ret)) {
+ case SSL_ERROR_NONE:
+ if (ret <= 0)
+ break;
+ if (bs->renegotiate_count > 0) {
+ bs->byte_count += ret;
+ if (bs->byte_count > bs->renegotiate_count) {
+ bs->byte_count = 0;
+ bs->num_renegotiates++;
+ SSL_renegotiate(ssl);
+ r = 1;
+ }
+ }
+ if ((bs->renegotiate_timeout > 0) && (!r)) {
+ unsigned long tm;
+
+ tm = (unsigned long)time(NULL);
+ if (tm > bs->last_time + bs->renegotiate_timeout) {
+ bs->last_time = tm;
+ bs->num_renegotiates++;
+ SSL_renegotiate(ssl);
+ }
+ }
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ BIO_set_retry_write(b);
+ break;
+ case SSL_ERROR_WANT_READ:
+ BIO_set_retry_read(b);
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ BIO_set_retry_special(b);
+ retry_reason = BIO_RR_SSL_X509_LOOKUP;
+ break;
+ case SSL_ERROR_WANT_CONNECT:
+ BIO_set_retry_special(b);
+ retry_reason = BIO_RR_CONNECT;
+ case SSL_ERROR_SYSCALL:
+ case SSL_ERROR_SSL:
+ default:
+ break;
+ }
+
+ BIO_set_retry_reason(b, retry_reason);
+ return ret;
+}
+
+static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+ SSL **sslp, *ssl;
+ BIO_SSL *bs, *dbs;
+ BIO *dbio, *bio;
+ long ret = 1;
+ BIO *next;
+
+ bs = BIO_get_data(b);
+ next = BIO_next(b);
+ ssl = bs->ssl;
+ if ((ssl == NULL) && (cmd != BIO_C_SET_SSL))
+ return (0);
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ SSL_shutdown(ssl);
+
+ if (ssl->handshake_func == ssl->method->ssl_connect)
+ SSL_set_connect_state(ssl);
+ else if (ssl->handshake_func == ssl->method->ssl_accept)
+ SSL_set_accept_state(ssl);
+
+ if (!SSL_clear(ssl)) {
+ ret = 0;
+ break;
+ }
+
+ if (next != NULL)
+ ret = BIO_ctrl(next, cmd, num, ptr);
+ else if (ssl->rbio != NULL)
+ ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
+ else
+ ret = 1;
+ break;
+ case BIO_CTRL_INFO:
+ ret = 0;
+ break;
+ case BIO_C_SSL_MODE:
+ if (num) /* client mode */
+ SSL_set_connect_state(ssl);
+ else
+ SSL_set_accept_state(ssl);
+ break;
+ case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT:
+ ret = bs->renegotiate_timeout;
+ if (num < 60)
+ num = 5;
+ bs->renegotiate_timeout = (unsigned long)num;
+ bs->last_time = (unsigned long)time(NULL);
+ break;
+ case BIO_C_SET_SSL_RENEGOTIATE_BYTES:
+ ret = bs->renegotiate_count;
+ if ((long)num >= 512)
+ bs->renegotiate_count = (unsigned long)num;
+ break;
+ case BIO_C_GET_SSL_NUM_RENEGOTIATES:
+ ret = bs->num_renegotiates;
+ break;
+ case BIO_C_SET_SSL:
+ if (ssl != NULL) {
+ ssl_free(b);
+ if (!ssl_new(b))
+ return 0;
+ }
+ BIO_set_shutdown(b, num);
+ ssl = (SSL *)ptr;
+ bs->ssl = ssl;
+ bio = SSL_get_rbio(ssl);
+ if (bio != NULL) {
+ if (next != NULL)
+ BIO_push(bio, next);
+ BIO_set_next(b, bio);
+ BIO_up_ref(bio);
+ }
+ BIO_set_init(b, 1);
+ break;
+ case BIO_C_GET_SSL:
+ if (ptr != NULL) {
+ sslp = (SSL **)ptr;
+ *sslp = ssl;
+ } else
+ ret = 0;
+ break;
+ case BIO_CTRL_GET_CLOSE:
+ ret = BIO_get_shutdown(b);
+ break;
+ case BIO_CTRL_SET_CLOSE:
+ BIO_set_shutdown(b, (int)num);
+ break;
+ case BIO_CTRL_WPENDING:
+ ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_PENDING:
+ ret = SSL_pending(ssl);
+ if (ret == 0)
+ ret = BIO_pending(ssl->rbio);
+ break;
+ case BIO_CTRL_FLUSH:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(ssl->wbio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+ case BIO_CTRL_PUSH:
+ if ((next != NULL) && (next != ssl->rbio)) {
+ /*
+ * We are going to pass ownership of next to the SSL object...but
+ * we don't own a reference to pass yet - so up ref
+ */
+ BIO_up_ref(next);
+ SSL_set_bio(ssl, next, next);
+ }
+ break;
+ case BIO_CTRL_POP:
+ /* Only detach if we are the BIO explicitly being popped */
+ if (b == ptr) {
+ /* This will clear the reference we obtained during push */
+ SSL_set_bio(ssl, NULL, NULL);
+ }
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+
+ BIO_set_retry_reason(b, 0);
+ ret = (int)SSL_do_handshake(ssl);
+
+ switch (SSL_get_error(ssl, (int)ret)) {
+ case SSL_ERROR_WANT_READ:
+ BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
+ break;
+ case SSL_ERROR_WANT_WRITE:
+ BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY);
+ break;
+ case SSL_ERROR_WANT_CONNECT:
+ BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY);
+ BIO_set_retry_reason(b, BIO_get_retry_reason(next));
+ break;
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ BIO_set_retry_special(b);
+ BIO_set_retry_reason(b, BIO_RR_SSL_X509_LOOKUP);
+ break;
+ default:
+ break;
+ }
+ break;
+ case BIO_CTRL_DUP:
+ dbio = (BIO *)ptr;
+ dbs = BIO_get_data(dbio);
+ SSL_free(dbs->ssl);
+ dbs->ssl = SSL_dup(ssl);
+ dbs->num_renegotiates = bs->num_renegotiates;
+ dbs->renegotiate_count = bs->renegotiate_count;
+ dbs->byte_count = bs->byte_count;
+ dbs->renegotiate_timeout = bs->renegotiate_timeout;
+ dbs->last_time = bs->last_time;
+ ret = (dbs->ssl != NULL);
+ break;
+ case BIO_C_GET_FD:
+ ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
+ break;
+ case BIO_CTRL_SET_CALLBACK:
+ {
+#if 0 /* FIXME: Should this be used? -- Richard
+ * Levitte */
+ SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ret = -1;
+#else
+ ret = 0;
+#endif
+ }
+ break;
+ default:
+ ret = BIO_ctrl(ssl->rbio, cmd, num, ptr);
+ break;
+ }
+ return (ret);
+}
+
+static long ssl_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
+{
+ SSL *ssl;
+ BIO_SSL *bs;
+ long ret = 1;
+
+ bs = BIO_get_data(b);
+ ssl = bs->ssl;
+ switch (cmd) {
+ case BIO_CTRL_SET_CALLBACK:
+ ret = BIO_callback_ctrl(ssl->rbio, cmd, fp);
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return (ret);
+}
+
+static int ssl_puts(BIO *bp, const char *str)
+{
+ int n, ret;
+
+ n = strlen(str);
+ ret = BIO_write(bp, str, n);
+ return (ret);
+}
+
+BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx)
+{
+#ifndef OPENSSL_NO_SOCK
+ BIO *ret = NULL, *buf = NULL, *ssl = NULL;
+
+ if ((buf = BIO_new(BIO_f_buffer())) == NULL)
+ return (NULL);
+ if ((ssl = BIO_new_ssl_connect(ctx)) == NULL)
+ goto err;
+ if ((ret = BIO_push(buf, ssl)) == NULL)
+ goto err;
+ return (ret);
+ err:
+ BIO_free(buf);
+ BIO_free(ssl);
+#endif
+ return (NULL);
+}
+
+BIO *BIO_new_ssl_connect(SSL_CTX *ctx)
+{
+#ifndef OPENSSL_NO_SOCK
+ BIO *ret = NULL, *con = NULL, *ssl = NULL;
+
+ if ((con = BIO_new(BIO_s_connect())) == NULL)
+ return (NULL);
+ if ((ssl = BIO_new_ssl(ctx, 1)) == NULL)
+ goto err;
+ if ((ret = BIO_push(ssl, con)) == NULL)
+ goto err;
+ return (ret);
+ err:
+ BIO_free(con);
+#endif
+ return (NULL);
+}
+
+BIO *BIO_new_ssl(SSL_CTX *ctx, int client)
+{
+ BIO *ret;
+ SSL *ssl;
+
+ if ((ret = BIO_new(BIO_f_ssl())) == NULL)
+ return (NULL);
+ if ((ssl = SSL_new(ctx)) == NULL) {
+ BIO_free(ret);
+ return (NULL);
+ }
+ if (client)
+ SSL_set_connect_state(ssl);
+ else
+ SSL_set_accept_state(ssl);
+
+ BIO_set_ssl(ret, ssl, BIO_CLOSE);
+ return (ret);
+}
+
+int BIO_ssl_copy_session_id(BIO *t, BIO *f)
+{
+ BIO_SSL *tdata, *fdata;
+ t = BIO_find_type(t, BIO_TYPE_SSL);
+ f = BIO_find_type(f, BIO_TYPE_SSL);
+ if ((t == NULL) || (f == NULL))
+ return 0;
+ tdata = BIO_get_data(t);
+ fdata = BIO_get_data(f);
+ if ((tdata->ssl == NULL) || (fdata->ssl == NULL))
+ return (0);
+ if (!SSL_copy_session_id(tdata->ssl, (fdata->ssl)))
+ return 0;
+ return (1);
+}
+
+void BIO_ssl_shutdown(BIO *b)
+{
+ BIO_SSL *bdata;
+
+ for (; b != NULL; b = BIO_next(b)) {
+ if (BIO_method_type(b) != BIO_TYPE_SSL)
+ continue;
+ bdata = BIO_get_data(b);
+ if (bdata != NULL && bdata->ssl != NULL)
+ SSL_shutdown(bdata->ssl);
+ }
+}
diff --git a/openssl-1.1.0h/ssl/build.info b/openssl-1.1.0h/ssl/build.info
new file mode 100644
index 0000000..6977246
--- /dev/null
+++ b/openssl-1.1.0h/ssl/build.info
@@ -0,0 +1,14 @@
+LIBS=../libssl
+SOURCE[../libssl]=\
+ pqueue.c \
+ statem/statem_srvr.c statem/statem_clnt.c s3_lib.c s3_enc.c record/rec_layer_s3.c \
+ statem/statem_lib.c s3_cbc.c s3_msg.c \
+ methods.c t1_lib.c t1_enc.c t1_ext.c \
+ d1_lib.c record/rec_layer_d1.c d1_msg.c \
+ statem/statem_dtls.c d1_srtp.c \
+ ssl_lib.c ssl_cert.c ssl_sess.c \
+ ssl_ciph.c ssl_stat.c ssl_rsa.c \
+ ssl_asn1.c ssl_txt.c ssl_init.c ssl_conf.c ssl_mcnf.c \
+ bio_ssl.c ssl_err.c t1_reneg.c tls_srp.c t1_trce.c ssl_utst.c \
+ record/ssl3_buffer.c record/ssl3_record.c record/dtls1_bitmap.c \
+ statem/statem.c
diff --git a/openssl-1.1.0h/ssl/d1_lib.c b/openssl-1.1.0h/ssl/d1_lib.c
new file mode 100644
index 0000000..55a81c3
--- /dev/null
+++ b/openssl-1.1.0h/ssl/d1_lib.c
@@ -0,0 +1,1087 @@
+/*
+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#define USE_SOCKETS
+#include <openssl/objects.h>
+#include <openssl/rand.h>
+#include "ssl_locl.h"
+
+#if defined(OPENSSL_SYS_VMS)
+# include <sys/timeb.h>
+#elif defined(OPENSSL_SYS_VXWORKS)
+# include <sys/times.h>
+#elif !defined(OPENSSL_SYS_WIN32)
+# include <sys/time.h>
+#endif
+
+static void get_current_time(struct timeval *t);
+static int dtls1_set_handshake_header(SSL *s, int type, unsigned long len);
+static int dtls1_handshake_write(SSL *s);
+static unsigned int dtls1_link_min_mtu(void);
+
+/* XDTLS: figure out the right values */
+static const unsigned int g_probable_mtu[] = { 1500, 512, 256 };
+
+const SSL3_ENC_METHOD DTLSv1_enc_data = {
+ tls1_enc,
+ tls1_mac,
+ tls1_setup_key_block,
+ tls1_generate_master_secret,
+ tls1_change_cipher_state,
+ tls1_final_finish_mac,
+ TLS1_FINISH_MAC_LENGTH,
+ TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
+ TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
+ tls1_alert_code,
+ tls1_export_keying_material,
+ SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV,
+ DTLS1_HM_HEADER_LENGTH,
+ dtls1_set_handshake_header,
+ dtls1_handshake_write
+};
+
+const SSL3_ENC_METHOD DTLSv1_2_enc_data = {
+ tls1_enc,
+ tls1_mac,
+ tls1_setup_key_block,
+ tls1_generate_master_secret,
+ tls1_change_cipher_state,
+ tls1_final_finish_mac,
+ TLS1_FINISH_MAC_LENGTH,
+ TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE,
+ TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE,
+ tls1_alert_code,
+ tls1_export_keying_material,
+ SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_EXPLICIT_IV | SSL_ENC_FLAG_SIGALGS
+ | SSL_ENC_FLAG_SHA256_PRF | SSL_ENC_FLAG_TLS1_2_CIPHERS,
+ DTLS1_HM_HEADER_LENGTH,
+ dtls1_set_handshake_header,
+ dtls1_handshake_write
+};
+
+long dtls1_default_timeout(void)
+{
+ /*
+ * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for
+ * http, the cache would over fill
+ */
+ return (60 * 60 * 2);
+}
+
+int dtls1_new(SSL *s)
+{
+ DTLS1_STATE *d1;
+
+ if (!DTLS_RECORD_LAYER_new(&s->rlayer)) {
+ return 0;
+ }
+
+ if (!ssl3_new(s))
+ return (0);
+ if ((d1 = OPENSSL_zalloc(sizeof(*d1))) == NULL) {
+ ssl3_free(s);
+ return (0);
+ }
+
+ d1->buffered_messages = pqueue_new();
+ d1->sent_messages = pqueue_new();
+
+ if (s->server) {
+ d1->cookie_len = sizeof(s->d1->cookie);
+ }
+
+ d1->link_mtu = 0;
+ d1->mtu = 0;
+
+ if (d1->buffered_messages == NULL || d1->sent_messages == NULL) {
+ pqueue_free(d1->buffered_messages);
+ pqueue_free(d1->sent_messages);
+ OPENSSL_free(d1);
+ ssl3_free(s);
+ return (0);
+ }
+
+ s->d1 = d1;
+ s->method->ssl_clear(s);
+ return (1);
+}
+
+static void dtls1_clear_queues(SSL *s)
+{
+ 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);
+ }
+}
+
+
+void dtls1_free(SSL *s)
+{
+ DTLS_RECORD_LAYER_free(&s->rlayer);
+
+ ssl3_free(s);
+
+ dtls1_clear_queues(s);
+
+ pqueue_free(s->d1->buffered_messages);
+ pqueue_free(s->d1->sent_messages);
+
+ OPENSSL_free(s->d1);
+ s->d1 = NULL;
+}
+
+void dtls1_clear(SSL *s)
+{
+ pqueue *buffered_messages;
+ pqueue *sent_messages;
+ unsigned int mtu;
+ unsigned int link_mtu;
+
+ DTLS_RECORD_LAYER_clear(&s->rlayer);
+
+ if (s->d1) {
+ buffered_messages = s->d1->buffered_messages;
+ sent_messages = s->d1->sent_messages;
+ mtu = s->d1->mtu;
+ link_mtu = s->d1->link_mtu;
+
+ dtls1_clear_queues(s);
+
+ memset(s->d1, 0, sizeof(*s->d1));
+
+ if (s->server) {
+ s->d1->cookie_len = sizeof(s->d1->cookie);
+ }
+
+ if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
+ s->d1->mtu = mtu;
+ s->d1->link_mtu = link_mtu;
+ }
+
+ s->d1->buffered_messages = buffered_messages;
+ s->d1->sent_messages = sent_messages;
+ }
+
+ ssl3_clear(s);
+
+ if (s->method->version == DTLS_ANY_VERSION)
+ s->version = DTLS_MAX_VERSION;
+#ifndef OPENSSL_NO_DTLS1_METHOD
+ else if (s->options & SSL_OP_CISCO_ANYCONNECT)
+ s->client_version = s->version = DTLS1_BAD_VER;
+#endif
+ else
+ s->version = s->method->version;
+}
+
+long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
+{
+ int ret = 0;
+
+ switch (cmd) {
+ case DTLS_CTRL_GET_TIMEOUT:
+ if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) {
+ ret = 1;
+ }
+ break;
+ case DTLS_CTRL_HANDLE_TIMEOUT:
+ ret = dtls1_handle_timeout(s);
+ break;
+ case DTLS_CTRL_SET_LINK_MTU:
+ if (larg < (long)dtls1_link_min_mtu())
+ return 0;
+ s->d1->link_mtu = larg;
+ return 1;
+ case DTLS_CTRL_GET_LINK_MIN_MTU:
+ return (long)dtls1_link_min_mtu();
+ case SSL_CTRL_SET_MTU:
+ /*
+ * We may not have a BIO set yet so can't call dtls1_min_mtu()
+ * We'll have to make do with dtls1_link_min_mtu() and max overhead
+ */
+ if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
+ return 0;
+ s->d1->mtu = larg;
+ return larg;
+ default:
+ ret = ssl3_ctrl(s, cmd, larg, parg);
+ break;
+ }
+ return (ret);
+}
+
+void dtls1_start_timer(SSL *s)
+{
+#ifndef OPENSSL_NO_SCTP
+ /* Disable timer for SCTP */
+ if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
+ memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout));
+ return;
+ }
+#endif
+
+ /* If timer is not set, initialize duration with 1 second */
+ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
+ s->d1->timeout_duration = 1;
+ }
+
+ /* Set timeout to current time */
+ get_current_time(&(s->d1->next_timeout));
+
+ /* Add duration to current time */
+ s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
+ &(s->d1->next_timeout));
+}
+
+struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft)
+{
+ struct timeval timenow;
+
+ /* If no timeout is set, just return NULL */
+ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
+ return NULL;
+ }
+
+ /* Get current time */
+ get_current_time(&timenow);
+
+ /* If timer already expired, set remaining time to 0 */
+ if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
+ (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
+ s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
+ memset(timeleft, 0, sizeof(*timeleft));
+ return timeleft;
+ }
+
+ /* Calculate time left until timer expires */
+ memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval));
+ timeleft->tv_sec -= timenow.tv_sec;
+ timeleft->tv_usec -= timenow.tv_usec;
+ if (timeleft->tv_usec < 0) {
+ timeleft->tv_sec--;
+ timeleft->tv_usec += 1000000;
+ }
+
+ /*
+ * If remaining time is less than 15 ms, set it to 0 to prevent issues
+ * because of small divergences with socket timeouts.
+ */
+ if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
+ memset(timeleft, 0, sizeof(*timeleft));
+ }
+
+ return timeleft;
+}
+
+int dtls1_is_timer_expired(SSL *s)
+{
+ struct timeval timeleft;
+
+ /* Get time left until timeout, return false if no timer running */
+ if (dtls1_get_timeout(s, &timeleft) == NULL) {
+ return 0;
+ }
+
+ /* Return false if timer is not expired yet */
+ if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
+ return 0;
+ }
+
+ /* Timer expired, so return true */
+ return 1;
+}
+
+void dtls1_double_timeout(SSL *s)
+{
+ s->d1->timeout_duration *= 2;
+ if (s->d1->timeout_duration > 60)
+ s->d1->timeout_duration = 60;
+ dtls1_start_timer(s);
+}
+
+void dtls1_stop_timer(SSL *s)
+{
+ /* Reset everything */
+ memset(&s->d1->timeout, 0, sizeof(s->d1->timeout));
+ memset(&s->d1->next_timeout, 0, sizeof(s->d1->next_timeout));
+ s->d1->timeout_duration = 1;
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
+ &(s->d1->next_timeout));
+ /* Clear retransmission buffer */
+ dtls1_clear_sent_buffer(s);
+}
+
+int dtls1_check_timeout_num(SSL *s)
+{
+ unsigned int mtu;
+
+ s->d1->timeout.num_alerts++;
+
+ /* Reduce MTU after 2 unsuccessful retransmissions */
+ if (s->d1->timeout.num_alerts > 2
+ && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
+ mtu =
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
+ if (mtu < s->d1->mtu)
+ s->d1->mtu = mtu;
+ }
+
+ if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
+ /* fail the connection, enough alerts have been sent */
+ SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED);
+ return -1;
+ }
+
+ return 0;
+}
+
+int dtls1_handle_timeout(SSL *s)
+{
+ /* if no timer is expired, don't do anything */
+ if (!dtls1_is_timer_expired(s)) {
+ return 0;
+ }
+
+ dtls1_double_timeout(s);
+
+ if (dtls1_check_timeout_num(s) < 0)
+ return -1;
+
+ s->d1->timeout.read_timeouts++;
+ if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
+ s->d1->timeout.read_timeouts = 1;
+ }
+#ifndef OPENSSL_NO_HEARTBEATS
+ if (s->tlsext_hb_pending) {
+ s->tlsext_hb_pending = 0;
+ return dtls1_heartbeat(s);
+ }
+#endif
+
+ dtls1_start_timer(s);
+ return dtls1_retransmit_buffered_messages(s);
+}
+
+static void get_current_time(struct timeval *t)
+{
+#if defined(_WIN32)
+ SYSTEMTIME st;
+ union {
+ unsigned __int64 ul;
+ FILETIME ft;
+ } now;
+
+ GetSystemTime(&st);
+ SystemTimeToFileTime(&st, &now.ft);
+ /* re-bias to 1/1/1970 */
+# ifdef __MINGW32__
+ now.ul -= 116444736000000000ULL;
+# else
+ /* *INDENT-OFF* */
+ now.ul -= 116444736000000000UI64;
+ /* *INDENT-ON* */
+# endif
+ t->tv_sec = (long)(now.ul / 10000000);
+ t->tv_usec = ((int)(now.ul % 10000000)) / 10;
+#elif defined(OPENSSL_SYS_VMS)
+ struct timeb tb;
+ ftime(&tb);
+ t->tv_sec = (long)tb.time;
+ t->tv_usec = (long)tb.millitm * 1000;
+#else
+ gettimeofday(t, NULL);
+#endif
+}
+
+#define LISTEN_SUCCESS 2
+#define LISTEN_SEND_VERIFY_REQUEST 1
+
+#ifndef OPENSSL_NO_SOCK
+int DTLSv1_listen(SSL *s, BIO_ADDR *client)
+{
+ int next, n, ret = 0, clearpkt = 0;
+ unsigned char cookie[DTLS1_COOKIE_LENGTH];
+ unsigned char seq[SEQ_NUM_SIZE];
+ const unsigned char *data;
+ unsigned char *p, *buf;
+ unsigned long reclen, fragoff, fraglen, msglen;
+ unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen;
+ BIO *rbio, *wbio;
+ BUF_MEM *bufm;
+ BIO_ADDR *tmpclient = NULL;
+ PACKET pkt, msgpkt, msgpayload, session, cookiepkt;
+
+ if (s->handshake_func == NULL) {
+ /* Not properly initialized yet */
+ SSL_set_accept_state(s);
+ }
+
+ /* Ensure there is no state left over from a previous invocation */
+ if (!SSL_clear(s))
+ return -1;
+
+ ERR_clear_error();
+
+ rbio = SSL_get_rbio(s);
+ wbio = SSL_get_wbio(s);
+
+ if (!rbio || !wbio) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BIO_NOT_SET);
+ return -1;
+ }
+
+ /*
+ * We only peek at incoming ClientHello's until we're sure we are going to
+ * to respond with a HelloVerifyRequest. If its a ClientHello with a valid
+ * cookie then we leave it in the BIO for accept to handle.
+ */
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
+
+ /*
+ * Note: This check deliberately excludes DTLS1_BAD_VER because that version
+ * requires the MAC to be calculated *including* the first ClientHello
+ * (without the cookie). Since DTLSv1_listen is stateless that cannot be
+ * supported. DTLS1_BAD_VER must use cookies in a stateful manner (e.g. via
+ * SSL_accept)
+ */
+ if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNSUPPORTED_SSL_VERSION);
+ return -1;
+ }
+
+ if (s->init_buf == NULL) {
+ if ((bufm = BUF_MEM_new()) == NULL) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+
+ if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) {
+ BUF_MEM_free(bufm);
+ SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ s->init_buf = bufm;
+ }
+ buf = (unsigned char *)s->init_buf->data;
+
+ do {
+ /* Get a packet */
+
+ clear_sys_error();
+ /*
+ * Technically a ClientHello could be SSL3_RT_MAX_PLAIN_LENGTH
+ * + DTLS1_RT_HEADER_LENGTH bytes long. Normally init_buf does not store
+ * the record header as well, but we do here. We've set up init_buf to
+ * be the standard size for simplicity. In practice we shouldn't ever
+ * receive a ClientHello as long as this. If we do it will get dropped
+ * in the record length check below.
+ */
+ n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
+
+ if (n <= 0) {
+ if (BIO_should_retry(rbio)) {
+ /* Non-blocking IO */
+ goto end;
+ }
+ return -1;
+ }
+
+ /* If we hit any problems we need to clear this packet from the BIO */
+ clearpkt = 1;
+
+ if (!PACKET_buf_init(&pkt, buf, n)) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ /*
+ * Parse the received record. If there are any problems with it we just
+ * dump it - with no alert. RFC6347 says this "Unlike TLS, DTLS is
+ * resilient in the face of invalid records (e.g., invalid formatting,
+ * length, MAC, etc.). In general, invalid records SHOULD be silently
+ * discarded, thus preserving the association; however, an error MAY be
+ * logged for diagnostic purposes."
+ */
+
+ /* this packet contained a partial record, dump it */
+ if (n < DTLS1_RT_HEADER_LENGTH) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_RECORD_TOO_SMALL);
+ goto end;
+ }
+
+ if (s->msg_callback)
+ s->msg_callback(0, 0, SSL3_RT_HEADER, buf,
+ DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
+
+ /* Get the record header */
+ if (!PACKET_get_1(&pkt, &rectype)
+ || !PACKET_get_1(&pkt, &versmajor)) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+ goto end;
+ }
+
+ if (rectype != SSL3_RT_HANDSHAKE) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
+ goto end;
+ }
+
+ /*
+ * Check record version number. We only check that the major version is
+ * the same.
+ */
+ if (versmajor != DTLS1_VERSION_MAJOR) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
+ goto end;
+ }
+
+ if (!PACKET_forward(&pkt, 1)
+ /* Save the sequence number: 64 bits, with top 2 bytes = epoch */
+ || !PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE)
+ || !PACKET_get_length_prefixed_2(&pkt, &msgpkt)) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+ goto end;
+ }
+ /*
+ * We allow data remaining at the end of the packet because there could
+ * be a second record (but we ignore it)
+ */
+
+ /* This is an initial ClientHello so the epoch has to be 0 */
+ if (seq[0] != 0 || seq[1] != 0) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
+ goto end;
+ }
+
+ /* Get a pointer to the raw message for the later callback */
+ data = PACKET_data(&msgpkt);
+
+ /* Finished processing the record header, now process the message */
+ if (!PACKET_get_1(&msgpkt, &msgtype)
+ || !PACKET_get_net_3(&msgpkt, &msglen)
+ || !PACKET_get_net_2(&msgpkt, &msgseq)
+ || !PACKET_get_net_3(&msgpkt, &fragoff)
+ || !PACKET_get_net_3(&msgpkt, &fraglen)
+ || !PACKET_get_sub_packet(&msgpkt, &msgpayload, fraglen)
+ || PACKET_remaining(&msgpkt) != 0) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+ goto end;
+ }
+
+ if (msgtype != SSL3_MT_CLIENT_HELLO) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
+ goto end;
+ }
+
+ /* Message sequence number can only be 0 or 1 */
+ if (msgseq > 2) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_INVALID_SEQUENCE_NUMBER);
+ goto end;
+ }
+
+ /*
+ * We don't support fragment reassembly for ClientHellos whilst
+ * listening because that would require server side state (which is
+ * against the whole point of the ClientHello/HelloVerifyRequest
+ * mechanism). Instead we only look at the first ClientHello fragment
+ * and require that the cookie must be contained within it.
+ */
+ if (fragoff != 0 || fraglen > msglen) {
+ /* Non initial ClientHello fragment (or bad fragment) */
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_FRAGMENTED_CLIENT_HELLO);
+ goto end;
+ }
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, data,
+ fraglen + DTLS1_HM_HEADER_LENGTH, s,
+ s->msg_callback_arg);
+
+ if (!PACKET_get_net_2(&msgpayload, &clientvers)) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+ goto end;
+ }
+
+ /*
+ * Verify client version is supported
+ */
+ if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) &&
+ s->method->version != DTLS_ANY_VERSION) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_WRONG_VERSION_NUMBER);
+ goto end;
+ }
+
+ if (!PACKET_forward(&msgpayload, SSL3_RANDOM_SIZE)
+ || !PACKET_get_length_prefixed_1(&msgpayload, &session)
+ || !PACKET_get_length_prefixed_1(&msgpayload, &cookiepkt)) {
+ /*
+ * Could be malformed or the cookie does not fit within the initial
+ * ClientHello fragment. Either way we can't handle it.
+ */
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
+ goto end;
+ }
+
+ /*
+ * Check if we have a cookie or not. If not we need to send a
+ * HelloVerifyRequest.
+ */
+ if (PACKET_remaining(&cookiepkt) == 0) {
+ next = LISTEN_SEND_VERIFY_REQUEST;
+ } else {
+ /*
+ * We have a cookie, so lets check it.
+ */
+ if (s->ctx->app_verify_cookie_cb == NULL) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_NO_VERIFY_COOKIE_CALLBACK);
+ /* This is fatal */
+ return -1;
+ }
+ if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookiepkt),
+ PACKET_remaining(&cookiepkt)) ==
+ 0) {
+ /*
+ * We treat invalid cookies in the same was as no cookie as
+ * per RFC6347
+ */
+ next = LISTEN_SEND_VERIFY_REQUEST;
+ } else {
+ /* Cookie verification succeeded */
+ next = LISTEN_SUCCESS;
+ }
+ }
+
+ if (next == LISTEN_SEND_VERIFY_REQUEST) {
+ /*
+ * There was no cookie in the ClientHello so we need to send a
+ * HelloVerifyRequest. If this fails we do not worry about trying
+ * to resend, we just drop it.
+ */
+
+ /*
+ * Dump the read packet, we don't need it any more. Ignore return
+ * value
+ */
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
+ BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);
+
+ /* Generate the cookie */
+ if (s->ctx->app_gen_cookie_cb == NULL ||
+ s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 ||
+ cookielen > 255) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_COOKIE_GEN_CALLBACK_FAILURE);
+ /* This is fatal */
+ return -1;
+ }
+
+ p = &buf[DTLS1_RT_HEADER_LENGTH];
+ msglen = dtls_raw_hello_verify_request(p + DTLS1_HM_HEADER_LENGTH,
+ cookie, cookielen);
+
+ *p++ = DTLS1_MT_HELLO_VERIFY_REQUEST;
+
+ /* Message length */
+ l2n3(msglen, p);
+
+ /* Message sequence number is always 0 for a HelloVerifyRequest */
+ s2n(0, p);
+
+ /*
+ * We never fragment a HelloVerifyRequest, so fragment offset is 0
+ * and fragment length is message length
+ */
+ l2n3(0, p);
+ l2n3(msglen, p);
+
+ /* Set reclen equal to length of whole handshake message */
+ reclen = msglen + DTLS1_HM_HEADER_LENGTH;
+
+ /* Add the record header */
+ p = buf;
+
+ *(p++) = SSL3_RT_HANDSHAKE;
+ /*
+ * Special case: for hello verify request, client version 1.0 and we
+ * haven't decided which version to use yet send back using version
+ * 1.0 header: otherwise some clients will ignore it.
+ */
+ if (s->method->version == DTLS_ANY_VERSION) {
+ *(p++) = DTLS1_VERSION >> 8;
+ *(p++) = DTLS1_VERSION & 0xff;
+ } else {
+ *(p++) = s->version >> 8;
+ *(p++) = s->version & 0xff;
+ }
+
+ /*
+ * Record sequence number is always the same as in the received
+ * ClientHello
+ */
+ memcpy(p, seq, SEQ_NUM_SIZE);
+ p += SEQ_NUM_SIZE;
+
+ /* Length */
+ s2n(reclen, p);
+
+ /*
+ * Set reclen equal to length of whole record including record
+ * header
+ */
+ reclen += DTLS1_RT_HEADER_LENGTH;
+
+ if (s->msg_callback)
+ s->msg_callback(1, 0, SSL3_RT_HEADER, buf,
+ DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
+
+ if ((tmpclient = BIO_ADDR_new()) == NULL) {
+ SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
+ goto end;
+ }
+
+ /*
+ * This is unnecessary if rbio and wbio are one and the same - but
+ * maybe they're not. We ignore errors here - some BIOs do not
+ * support this.
+ */
+ if (BIO_dgram_get_peer(rbio, tmpclient) > 0) {
+ (void)BIO_dgram_set_peer(wbio, tmpclient);
+ }
+ BIO_ADDR_free(tmpclient);
+ tmpclient = NULL;
+
+ if (BIO_write(wbio, buf, reclen) < (int)reclen) {
+ if (BIO_should_retry(wbio)) {
+ /*
+ * Non-blocking IO...but we're stateless, so we're just
+ * going to drop this packet.
+ */
+ goto end;
+ }
+ return -1;
+ }
+
+ if (BIO_flush(wbio) <= 0) {
+ if (BIO_should_retry(wbio)) {
+ /*
+ * Non-blocking IO...but we're stateless, so we're just
+ * going to drop this packet.
+ */
+ goto end;
+ }
+ return -1;
+ }
+ }
+ } while (next != LISTEN_SUCCESS);
+
+ /*
+ * Set expected sequence numbers to continue the handshake.
+ */
+ s->d1->handshake_read_seq = 1;
+ s->d1->handshake_write_seq = 1;
+ s->d1->next_handshake_write_seq = 1;
+ DTLS_RECORD_LAYER_set_write_sequence(&s->rlayer, seq);
+
+ /*
+ * We are doing cookie exchange, so make sure we set that option in the
+ * SSL object
+ */
+ SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
+
+ /*
+ * Tell the state machine that we've done the initial hello verify
+ * exchange
+ */
+ ossl_statem_set_hello_verify_done(s);
+
+ /*
+ * Some BIOs may not support this. If we fail we clear the client address
+ */
+ if (BIO_dgram_get_peer(rbio, client) <= 0)
+ BIO_ADDR_clear(client);
+
+ ret = 1;
+ clearpkt = 0;
+ end:
+ BIO_ADDR_free(tmpclient);
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
+ if (clearpkt) {
+ /* Dump this packet. Ignore return value */
+ BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
+ }
+ return ret;
+}
+#endif
+
+static int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len)
+{
+ dtls1_set_message_header(s, htype, len, 0, len);
+ s->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
+ s->init_off = 0;
+ /* Buffer the message to handle re-xmits */
+
+ if (!dtls1_buffer_message(s, 0))
+ return 0;
+
+ return 1;
+}
+
+static int dtls1_handshake_write(SSL *s)
+{
+ return dtls1_do_write(s, SSL3_RT_HANDSHAKE);
+}
+
+#ifndef OPENSSL_NO_HEARTBEATS
+
+# define HEARTBEAT_SIZE(payload, padding) ( \
+ 1 /* heartbeat type */ + \
+ 2 /* heartbeat length */ + \
+ (payload) + (padding))
+
+# define HEARTBEAT_SIZE_STD(payload) HEARTBEAT_SIZE(payload, 16)
+
+int dtls1_process_heartbeat(SSL *s, unsigned char *p, unsigned int length)
+{
+ unsigned char *pl;
+ unsigned short hbtype;
+ unsigned int payload;
+ unsigned int padding = 16; /* Use minimum padding */
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, DTLS1_RT_HEARTBEAT,
+ p, length, s, s->msg_callback_arg);
+
+ /* Read type and payload length */
+ if (HEARTBEAT_SIZE_STD(0) > length)
+ return 0; /* silently discard */
+ if (length > SSL3_RT_MAX_PLAIN_LENGTH)
+ return 0; /* silently discard per RFC 6520 sec. 4 */
+
+ hbtype = *p++;
+ n2s(p, payload);
+ if (HEARTBEAT_SIZE_STD(payload) > length)
+ return 0; /* silently discard per RFC 6520 sec. 4 */
+ pl = p;
+
+ if (hbtype == TLS1_HB_REQUEST) {
+ unsigned char *buffer, *bp;
+ unsigned int write_length = HEARTBEAT_SIZE(payload, padding);
+ int r;
+
+ if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
+ return 0;
+
+ /* Allocate memory for the response. */
+ buffer = OPENSSL_malloc(write_length);
+ if (buffer == NULL)
+ return -1;
+ bp = buffer;
+
+ /* Enter response type, length and copy payload */
+ *bp++ = TLS1_HB_RESPONSE;
+ s2n(payload, bp);
+ memcpy(bp, pl, payload);
+ bp += payload;
+ /* Random padding */
+ if (RAND_bytes(bp, padding) <= 0) {
+ OPENSSL_free(buffer);
+ return -1;
+ }
+
+ r = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buffer, write_length);
+
+ if (r >= 0 && s->msg_callback)
+ s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT,
+ buffer, write_length, s, s->msg_callback_arg);
+
+ OPENSSL_free(buffer);
+
+ if (r < 0)
+ return r;
+ } else if (hbtype == TLS1_HB_RESPONSE) {
+ unsigned int seq;
+
+ /*
+ * We only send sequence numbers (2 bytes unsigned int), and 16
+ * random bytes, so we just try to read the sequence number
+ */
+ n2s(pl, seq);
+
+ if (payload == 18 && seq == s->tlsext_hb_seq) {
+ dtls1_stop_timer(s);
+ s->tlsext_hb_seq++;
+ s->tlsext_hb_pending = 0;
+ }
+ }
+
+ return 0;
+}
+
+int dtls1_heartbeat(SSL *s)
+{
+ unsigned char *buf, *p;
+ int ret = -1;
+ unsigned int payload = 18; /* Sequence number + random bytes */
+ unsigned int padding = 16; /* Use minimum padding */
+ unsigned int size;
+
+ /* Only send if peer supports and accepts HB requests... */
+ if (!(s->tlsext_heartbeat & SSL_DTLSEXT_HB_ENABLED) ||
+ s->tlsext_heartbeat & SSL_DTLSEXT_HB_DONT_SEND_REQUESTS) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
+ return -1;
+ }
+
+ /* ...and there is none in flight yet... */
+ if (s->tlsext_hb_pending) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
+ return -1;
+ }
+
+ /* ...and no handshake in progress. */
+ if (SSL_in_init(s) || ossl_statem_get_in_handshake(s)) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
+ return -1;
+ }
+
+ /*-
+ * Create HeartBeat message, we just use a sequence number
+ * as payload to distinguish different messages and add
+ * some random stuff.
+ */
+ size = HEARTBEAT_SIZE(payload, padding);
+ buf = OPENSSL_malloc(size);
+ if (buf == NULL) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ p = buf;
+ /* Message Type */
+ *p++ = TLS1_HB_REQUEST;
+ /* Payload length (18 bytes here) */
+ s2n(payload, p);
+ /* Sequence number */
+ s2n(s->tlsext_hb_seq, p);
+ /* 16 random bytes */
+ if (RAND_bytes(p, 16) <= 0) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ p += 16;
+ /* Random padding */
+ if (RAND_bytes(p, padding) <= 0) {
+ SSLerr(SSL_F_DTLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ ret = dtls1_write_bytes(s, DTLS1_RT_HEARTBEAT, buf, size);
+ if (ret >= 0) {
+ if (s->msg_callback)
+ s->msg_callback(1, s->version, DTLS1_RT_HEARTBEAT,
+ buf, size, s, s->msg_callback_arg);
+
+ dtls1_start_timer(s);
+ s->tlsext_hb_pending = 1;
+ }
+
+ err:
+ OPENSSL_free(buf);
+
+ return ret;
+}
+#endif
+
+int dtls1_shutdown(SSL *s)
+{
+ int ret;
+#ifndef OPENSSL_NO_SCTP
+ BIO *wbio;
+
+ wbio = SSL_get_wbio(s);
+ if (wbio != NULL && BIO_dgram_is_sctp(wbio) &&
+ !(s->shutdown & SSL_SENT_SHUTDOWN)) {
+ ret = BIO_dgram_sctp_wait_for_dry(wbio);
+ if (ret < 0)
+ return -1;
+
+ if (ret == 0)
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1,
+ NULL);
+ }
+#endif
+ ret = ssl3_shutdown(s);
+#ifndef OPENSSL_NO_SCTP
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL);
+#endif
+ return ret;
+}
+
+int dtls1_query_mtu(SSL *s)
+{
+ if (s->d1->link_mtu) {
+ s->d1->mtu =
+ s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
+ s->d1->link_mtu = 0;
+ }
+
+ /* AHA! Figure out the MTU, and stick to the right size */
+ if (s->d1->mtu < dtls1_min_mtu(s)) {
+ if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
+ s->d1->mtu =
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
+
+ /*
+ * I've seen the kernel return bogus numbers when it doesn't know
+ * (initial write), so just make sure we have a reasonable number
+ */
+ if (s->d1->mtu < dtls1_min_mtu(s)) {
+ /* Set to min mtu */
+ s->d1->mtu = dtls1_min_mtu(s);
+ BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
+ s->d1->mtu, NULL);
+ }
+ } else
+ return 0;
+ }
+ return 1;
+}
+
+static unsigned int dtls1_link_min_mtu(void)
+{
+ return (g_probable_mtu[(sizeof(g_probable_mtu) /
+ sizeof(g_probable_mtu[0])) - 1]);
+}
+
+unsigned int dtls1_min_mtu(SSL *s)
+{
+ return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
+}
diff --git a/openssl-1.1.0h/ssl/d1_msg.c b/openssl-1.1.0h/ssl/d1_msg.c
new file mode 100644
index 0000000..7471fd3
--- /dev/null
+++ b/openssl-1.1.0h/ssl/d1_msg.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#define USE_SOCKETS
+#include "ssl_locl.h"
+
+int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len)
+{
+ int i;
+
+ if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) {
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES,
+ SSL_R_SSL_HANDSHAKE_FAILURE);
+ return -1;
+ }
+ }
+
+ if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
+ SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG);
+ return -1;
+ }
+
+ i = dtls1_write_bytes(s, type, buf_, len);
+ return i;
+}
+
+int dtls1_dispatch_alert(SSL *s)
+{
+ int i, j;
+ void (*cb) (const SSL *ssl, int type, int val) = NULL;
+ unsigned char buf[DTLS1_AL_HEADER_LENGTH];
+ unsigned char *ptr = &buf[0];
+
+ s->s3->alert_dispatch = 0;
+
+ memset(buf, 0, sizeof(buf));
+ *ptr++ = s->s3->send_alert[0];
+ *ptr++ = s->s3->send_alert[1];
+
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+ if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) {
+ s2n(s->d1->handshake_read_seq, ptr);
+ l2n3(s->d1->r_msg_hdr.frag_off, ptr);
+ }
+#endif
+
+ i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0);
+ if (i <= 0) {
+ s->s3->alert_dispatch = 1;
+ /* fprintf( stderr, "not done with alert\n" ); */
+ } else {
+ if (s->s3->send_alert[0] == SSL3_AL_FATAL
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+ || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+#endif
+ )
+ (void)BIO_flush(s->wbio);
+
+ if (s->msg_callback)
+ s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert,
+ 2, s, s->msg_callback_arg);
+
+ if (s->info_callback != NULL)
+ cb = s->info_callback;
+ else if (s->ctx->info_callback != NULL)
+ cb = s->ctx->info_callback;
+
+ if (cb != NULL) {
+ j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1];
+ cb(s, SSL_CB_WRITE_ALERT, j);
+ }
+ }
+ return (i);
+}
diff --git a/openssl-1.1.0h/ssl/d1_srtp.c b/openssl-1.1.0h/ssl/d1_srtp.c
new file mode 100644
index 0000000..7e88f17
--- /dev/null
+++ b/openssl-1.1.0h/ssl/d1_srtp.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*
+ * DTLS code by Eric Rescorla <ekr@rtfm.com>
+ *
+ * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc.
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+#ifndef OPENSSL_NO_SRTP
+
+static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
+ {
+ "SRTP_AES128_CM_SHA1_80",
+ SRTP_AES128_CM_SHA1_80,
+ },
+ {
+ "SRTP_AES128_CM_SHA1_32",
+ SRTP_AES128_CM_SHA1_32,
+ },
+ {
+ "SRTP_AEAD_AES_128_GCM",
+ SRTP_AEAD_AES_128_GCM,
+ },
+ {
+ "SRTP_AEAD_AES_256_GCM",
+ SRTP_AEAD_AES_256_GCM,
+ },
+ {0}
+};
+
+static int find_profile_by_name(char *profile_name,
+ SRTP_PROTECTION_PROFILE **pptr, unsigned len)
+{
+ SRTP_PROTECTION_PROFILE *p;
+
+ p = srtp_known_profiles;
+ while (p->name) {
+ if ((len == strlen(p->name))
+ && strncmp(p->name, profile_name, len) == 0) {
+ *pptr = p;
+ return 0;
+ }
+
+ p++;
+ }
+
+ return 1;
+}
+
+static int ssl_ctx_make_profiles(const char *profiles_string,
+ STACK_OF(SRTP_PROTECTION_PROFILE) **out)
+{
+ STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
+
+ char *col;
+ char *ptr = (char *)profiles_string;
+ SRTP_PROTECTION_PROFILE *p;
+
+ if ((profiles = sk_SRTP_PROTECTION_PROFILE_new_null()) == NULL) {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+ SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+ return 1;
+ }
+
+ do {
+ col = strchr(ptr, ':');
+
+ if (!find_profile_by_name(ptr, &p, col ? col - ptr : (int)strlen(ptr))) {
+ if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+ SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ goto err;
+ }
+
+ if (!sk_SRTP_PROTECTION_PROFILE_push(profiles, p)) {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+ SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+ goto err;
+ }
+ } else {
+ SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES,
+ SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+ goto err;
+ }
+
+ if (col)
+ ptr = col + 1;
+ } while (col);
+
+ sk_SRTP_PROTECTION_PROFILE_free(*out);
+
+ *out = profiles;
+
+ return 0;
+ err:
+ sk_SRTP_PROTECTION_PROFILE_free(profiles);
+ return 1;
+}
+
+int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles)
+{
+ return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
+}
+
+int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles)
+{
+ return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
+}
+
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s)
+{
+ if (s != NULL) {
+ if (s->srtp_profiles != NULL) {
+ return s->srtp_profiles;
+ } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) {
+ return s->ctx->srtp_profiles;
+ }
+ }
+
+ return NULL;
+}
+
+SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s)
+{
+ return s->srtp_profile;
+}
+
+/*
+ * Note: this function returns 0 length if there are no profiles specified
+ */
+int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
+ int maxlen)
+{
+ int ct = 0;
+ int i;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
+ SRTP_PROTECTION_PROFILE *prof;
+
+ clnt = SSL_get_srtp_profiles(s);
+ ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
+
+ if (p) {
+ if (ct == 0) {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
+ SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
+ return 1;
+ }
+
+ if ((2 + ct * 2 + 1) > maxlen) {
+ SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT,
+ SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+ return 1;
+ }
+
+ /* Add the length */
+ s2n(ct * 2, p);
+ for (i = 0; i < ct; i++) {
+ prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
+ s2n(prof->id, p);
+ }
+
+ /* Add an empty use_mki value */
+ *p++ = 0;
+ }
+
+ *len = 2 + ct * 2 + 1;
+
+ return 0;
+}
+
+int ssl_parse_clienthello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
+{
+ SRTP_PROTECTION_PROFILE *sprof;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
+ unsigned int ct, mki_len, id;
+ int i, srtp_pref;
+ PACKET subpkt;
+
+ /* Pull off the length of the cipher suite list and check it is even */
+ if (!PACKET_get_net_2(pkt, &ct)
+ || (ct & 1) != 0 || !PACKET_get_sub_packet(pkt, &subpkt, ct)) {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+ SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al = SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ srvr = SSL_get_srtp_profiles(s);
+ s->srtp_profile = NULL;
+ /* Search all profiles for a match initially */
+ srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);
+
+ while (PACKET_remaining(&subpkt)) {
+ if (!PACKET_get_net_2(&subpkt, &id)) {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+ SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al = SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /*
+ * Only look for match in profiles of higher preference than
+ * current match.
+ * If no profiles have been have been configured then this
+ * does nothing.
+ */
+ for (i = 0; i < srtp_pref; i++) {
+ sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i);
+ if (sprof->id == id) {
+ s->srtp_profile = sprof;
+ srtp_pref = i;
+ break;
+ }
+ }
+ }
+
+ /*
+ * Now extract the MKI value as a sanity check, but discard it for now
+ */
+ if (!PACKET_get_1(pkt, &mki_len)) {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+ SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al = SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ if (!PACKET_forward(pkt, mki_len)
+ || PACKET_remaining(pkt)) {
+ SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT,
+ SSL_R_BAD_SRTP_MKI_VALUE);
+ *al = SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ return 0;
+}
+
+int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
+ int maxlen)
+{
+ if (p) {
+ if (maxlen < 5) {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
+ SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
+ return 1;
+ }
+
+ if (s->srtp_profile == 0) {
+ SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT,
+ SSL_R_USE_SRTP_NOT_NEGOTIATED);
+ return 1;
+ }
+ s2n(2, p);
+ s2n(s->srtp_profile->id, p);
+ *p++ = 0;
+ }
+ *len = 5;
+
+ return 0;
+}
+
+int ssl_parse_serverhello_use_srtp_ext(SSL *s, PACKET *pkt, int *al)
+{
+ unsigned int id, ct, mki;
+ int i;
+
+ STACK_OF(SRTP_PROTECTION_PROFILE) *clnt;
+ SRTP_PROTECTION_PROFILE *prof;
+
+ if (!PACKET_get_net_2(pkt, &ct)
+ || ct != 2 || !PACKET_get_net_2(pkt, &id)
+ || !PACKET_get_1(pkt, &mki)
+ || PACKET_remaining(pkt) != 0) {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+ SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al = SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ if (mki != 0) {
+ /* Must be no MKI, since we never offer one */
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+ SSL_R_BAD_SRTP_MKI_VALUE);
+ *al = SSL_AD_ILLEGAL_PARAMETER;
+ return 1;
+ }
+
+ clnt = SSL_get_srtp_profiles(s);
+
+ /* Throw an error if the server gave us an unsolicited extension */
+ if (clnt == NULL) {
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+ SSL_R_NO_SRTP_PROFILES);
+ *al = SSL_AD_DECODE_ERROR;
+ return 1;
+ }
+
+ /*
+ * Check to see if the server gave us something we support (and
+ * presumably offered)
+ */
+ for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) {
+ prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
+
+ if (prof->id == id) {
+ s->srtp_profile = prof;
+ *al = 0;
+ return 0;
+ }
+ }
+
+ SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT,
+ SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *al = SSL_AD_DECODE_ERROR;
+ return 1;
+}
+
+#endif
diff --git a/openssl-1.1.0h/ssl/methods.c b/openssl-1.1.0h/ssl/methods.c
new file mode 100644
index 0000000..c846143
--- /dev/null
+++ b/openssl-1.1.0h/ssl/methods.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <openssl/objects.h>
+#include "ssl_locl.h"
+
+/*-
+ * TLS/SSLv3 methods
+ */
+
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0,
+ TLS_method,
+ ossl_statem_accept,
+ ossl_statem_connect, TLSv1_2_enc_data)
+#ifndef OPENSSL_NO_TLS1_2_METHOD
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2,
+ tlsv1_2_method,
+ ossl_statem_accept,
+ ossl_statem_connect, TLSv1_2_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1,
+ tlsv1_1_method,
+ ossl_statem_accept,
+ ossl_statem_connect, TLSv1_1_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1,
+ tlsv1_method,
+ ossl_statem_accept, ossl_statem_connect, TLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
+IMPLEMENT_ssl3_meth_func(sslv3_method, ossl_statem_accept, ossl_statem_connect)
+#endif
+/*-
+ * TLS/SSLv3 server methods
+ */
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0,
+ TLS_server_method,
+ ossl_statem_accept,
+ ssl_undefined_function, TLSv1_2_enc_data)
+#ifndef OPENSSL_NO_TLS1_2_METHOD
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2,
+ tlsv1_2_server_method,
+ ossl_statem_accept,
+ ssl_undefined_function, TLSv1_2_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1,
+ tlsv1_1_server_method,
+ ossl_statem_accept,
+ ssl_undefined_function, TLSv1_1_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1,
+ tlsv1_server_method,
+ ossl_statem_accept,
+ ssl_undefined_function, TLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
+IMPLEMENT_ssl3_meth_func(sslv3_server_method,
+ ossl_statem_accept, ssl_undefined_function)
+#endif
+/*-
+ * TLS/SSLv3 client methods
+ */
+IMPLEMENT_tls_meth_func(TLS_ANY_VERSION, 0, 0,
+ TLS_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, TLSv1_2_enc_data)
+#ifndef OPENSSL_NO_TLS1_2_METHOD
+IMPLEMENT_tls_meth_func(TLS1_2_VERSION, 0, SSL_OP_NO_TLSv1_2,
+ tlsv1_2_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, TLSv1_2_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1_1,
+ tlsv1_1_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, TLSv1_1_enc_data)
+#endif
+#ifndef OPENSSL_NO_TLS1_METHOD
+IMPLEMENT_tls_meth_func(TLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_TLSv1,
+ tlsv1_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, TLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_SSL3_METHOD
+IMPLEMENT_ssl3_meth_func(sslv3_client_method,
+ ssl_undefined_function, ossl_statem_connect)
+#endif
+/*-
+ * DTLS methods
+ */
+#ifndef OPENSSL_NO_DTLS1_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+ dtlsv1_method,
+ ossl_statem_accept,
+ ossl_statem_connect, DTLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_DTLS1_2_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
+ dtlsv1_2_method,
+ ossl_statem_accept,
+ ossl_statem_connect, DTLSv1_2_enc_data)
+#endif
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
+ DTLS_method,
+ ossl_statem_accept,
+ ossl_statem_connect, DTLSv1_2_enc_data)
+
+/*-
+ * DTLS server methods
+ */
+#ifndef OPENSSL_NO_DTLS1_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+ dtlsv1_server_method,
+ ossl_statem_accept,
+ ssl_undefined_function, DTLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_DTLS1_2_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
+ dtlsv1_2_server_method,
+ ossl_statem_accept,
+ ssl_undefined_function, DTLSv1_2_enc_data)
+#endif
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
+ DTLS_server_method,
+ ossl_statem_accept,
+ ssl_undefined_function, DTLSv1_2_enc_data)
+
+/*-
+ * DTLS client methods
+ */
+#ifndef OPENSSL_NO_DTLS1_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_VERSION, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+ dtlsv1_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, DTLSv1_enc_data)
+IMPLEMENT_dtls1_meth_func(DTLS1_BAD_VER, SSL_METHOD_NO_SUITEB, SSL_OP_NO_DTLSv1,
+ dtls_bad_ver_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, DTLSv1_enc_data)
+#endif
+#ifndef OPENSSL_NO_DTLS1_2_METHOD
+IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2,
+ dtlsv1_2_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, DTLSv1_2_enc_data)
+#endif
+IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0,
+ DTLS_client_method,
+ ssl_undefined_function,
+ ossl_statem_connect, DTLSv1_2_enc_data)
+#if OPENSSL_API_COMPAT < 0x10100000L
+# ifndef OPENSSL_NO_TLS1_2_METHOD
+const SSL_METHOD *TLSv1_2_method(void)
+{
+ return tlsv1_2_method();
+}
+
+const SSL_METHOD *TLSv1_2_server_method(void)
+{
+ return tlsv1_2_server_method();
+}
+
+const SSL_METHOD *TLSv1_2_client_method(void)
+{
+ return tlsv1_2_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_TLS1_1_METHOD
+const SSL_METHOD *TLSv1_1_method(void)
+{
+ return tlsv1_1_method();
+}
+
+const SSL_METHOD *TLSv1_1_server_method(void)
+{
+ return tlsv1_1_server_method();
+}
+
+const SSL_METHOD *TLSv1_1_client_method(void)
+{
+ return tlsv1_1_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_TLS1_METHOD
+const SSL_METHOD *TLSv1_method(void)
+{
+ return tlsv1_method();
+}
+
+const SSL_METHOD *TLSv1_server_method(void)
+{
+ return tlsv1_server_method();
+}
+
+const SSL_METHOD *TLSv1_client_method(void)
+{
+ return tlsv1_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_SSL3_METHOD
+const SSL_METHOD *SSLv3_method(void)
+{
+ return sslv3_method();
+}
+
+const SSL_METHOD *SSLv3_server_method(void)
+{
+ return sslv3_server_method();
+}
+
+const SSL_METHOD *SSLv3_client_method(void)
+{
+ return sslv3_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_DTLS1_2_METHOD
+const SSL_METHOD *DTLSv1_2_method(void)
+{
+ return dtlsv1_2_method();
+}
+
+const SSL_METHOD *DTLSv1_2_server_method(void)
+{
+ return dtlsv1_2_server_method();
+}
+
+const SSL_METHOD *DTLSv1_2_client_method(void)
+{
+ return dtlsv1_2_client_method();
+}
+# endif
+
+# ifndef OPENSSL_NO_DTLS1_METHOD
+const SSL_METHOD *DTLSv1_method(void)
+{
+ return dtlsv1_method();
+}
+
+const SSL_METHOD *DTLSv1_server_method(void)
+{
+ return dtlsv1_server_method();
+}
+
+const SSL_METHOD *DTLSv1_client_method(void)
+{
+ return dtlsv1_client_method();
+}
+# endif
+
+#endif
diff --git a/openssl-1.1.0h/ssl/packet_locl.h b/openssl-1.1.0h/ssl/packet_locl.h
new file mode 100644
index 0000000..d34034d
--- /dev/null
+++ b/openssl-1.1.0h/ssl/packet_locl.h
@@ -0,0 +1,555 @@
+/*
+ * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_PACKET_LOCL_H
+# define HEADER_PACKET_LOCL_H
+
+# include <string.h>
+# include <openssl/bn.h>
+# include <openssl/buffer.h>
+# include <openssl/crypto.h>
+# include <openssl/e_os2.h>
+
+# include "internal/numbers.h"
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+typedef struct {
+ /* Pointer to where we are currently reading from */
+ const unsigned char *curr;
+ /* Number of bytes remaining */
+ size_t remaining;
+} PACKET;
+
+/* Internal unchecked shorthand; don't use outside this file. */
+static ossl_inline void packet_forward(PACKET *pkt, size_t len)
+{
+ pkt->curr += len;
+ pkt->remaining -= len;
+}
+
+/*
+ * Returns the number of bytes remaining to be read in the PACKET
+ */
+static ossl_inline size_t PACKET_remaining(const PACKET *pkt)
+{
+ return pkt->remaining;
+}
+
+/*
+ * Returns a pointer to the first byte after the packet data.
+ * Useful for integrating with non-PACKET parsing code.
+ * Specifically, we use PACKET_end() to verify that a d2i_... call
+ * has consumed the entire packet contents.
+ */
+static ossl_inline const unsigned char *PACKET_end(const PACKET *pkt)
+{
+ return pkt->curr + pkt->remaining;
+}
+
+/*
+ * Returns a pointer to the PACKET's current position.
+ * For use in non-PACKETized APIs.
+ */
+static ossl_inline const unsigned char *PACKET_data(const PACKET *pkt)
+{
+ return pkt->curr;
+}
+
+/*
+ * Initialise a PACKET with |len| bytes held in |buf|. This does not make a
+ * copy of the data so |buf| must be present for the whole time that the PACKET
+ * is being used.
+ */
+__owur static ossl_inline int PACKET_buf_init(PACKET *pkt,
+ const unsigned char *buf,
+ size_t len)
+{
+ /* Sanity check for negative values. */
+ if (len > (size_t)(SIZE_MAX / 2))
+ return 0;
+
+ pkt->curr = buf;
+ pkt->remaining = len;
+ return 1;
+}
+
+/* Initialize a PACKET to hold zero bytes. */
+static ossl_inline void PACKET_null_init(PACKET *pkt)
+{
+ pkt->curr = NULL;
+ pkt->remaining = 0;
+}
+
+/*
+ * Returns 1 if the packet has length |num| and its contents equal the |num|
+ * bytes read from |ptr|. Returns 0 otherwise (lengths or contents not equal).
+ * If lengths are equal, performs the comparison in constant time.
+ */
+__owur static ossl_inline int PACKET_equal(const PACKET *pkt, const void *ptr,
+ size_t num)
+{
+ if (PACKET_remaining(pkt) != num)
+ return 0;
+ return CRYPTO_memcmp(pkt->curr, ptr, num) == 0;
+}
+
+/*
+ * Peek ahead and initialize |subpkt| with the next |len| bytes read from |pkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ */
+__owur static ossl_inline int PACKET_peek_sub_packet(const PACKET *pkt,
+ PACKET *subpkt, size_t len)
+{
+ if (PACKET_remaining(pkt) < len)
+ return 0;
+
+ return PACKET_buf_init(subpkt, pkt->curr, len);
+}
+
+/*
+ * Initialize |subpkt| with the next |len| bytes read from |pkt|. Data is not
+ * copied: the |subpkt| packet will share its underlying buffer with the
+ * original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ */
+__owur static ossl_inline int PACKET_get_sub_packet(PACKET *pkt,
+ PACKET *subpkt, size_t len)
+{
+ if (!PACKET_peek_sub_packet(pkt, subpkt, len))
+ return 0;
+
+ packet_forward(pkt, len);
+
+ return 1;
+}
+
+/*
+ * Peek ahead at 2 bytes in network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_peek_net_2(const PACKET *pkt,
+ unsigned int *data)
+{
+ if (PACKET_remaining(pkt) < 2)
+ return 0;
+
+ *data = ((unsigned int)(*pkt->curr)) << 8;
+ *data |= *(pkt->curr + 1);
+
+ return 1;
+}
+
+/* Equivalent of n2s */
+/* Get 2 bytes in network order from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_net_2(PACKET *pkt, unsigned int *data)
+{
+ if (!PACKET_peek_net_2(pkt, data))
+ return 0;
+
+ packet_forward(pkt, 2);
+
+ return 1;
+}
+
+/*
+ * Peek ahead at 3 bytes in network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_peek_net_3(const PACKET *pkt,
+ unsigned long *data)
+{
+ if (PACKET_remaining(pkt) < 3)
+ return 0;
+
+ *data = ((unsigned long)(*pkt->curr)) << 16;
+ *data |= ((unsigned long)(*(pkt->curr + 1))) << 8;
+ *data |= *(pkt->curr + 2);
+
+ return 1;
+}
+
+/* Equivalent of n2l3 */
+/* Get 3 bytes in network order from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_net_3(PACKET *pkt, unsigned long *data)
+{
+ if (!PACKET_peek_net_3(pkt, data))
+ return 0;
+
+ packet_forward(pkt, 3);
+
+ return 1;
+}
+
+/*
+ * Peek ahead at 4 bytes in network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt,
+ unsigned long *data)
+{
+ if (PACKET_remaining(pkt) < 4)
+ return 0;
+
+ *data = ((unsigned long)(*pkt->curr)) << 24;
+ *data |= ((unsigned long)(*(pkt->curr + 1))) << 16;
+ *data |= ((unsigned long)(*(pkt->curr + 2))) << 8;
+ *data |= *(pkt->curr + 3);
+
+ return 1;
+}
+
+/* Equivalent of n2l */
+/* Get 4 bytes in network order from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_net_4(PACKET *pkt, unsigned long *data)
+{
+ if (!PACKET_peek_net_4(pkt, data))
+ return 0;
+
+ packet_forward(pkt, 4);
+
+ return 1;
+}
+
+/* Peek ahead at 1 byte from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_peek_1(const PACKET *pkt,
+ unsigned int *data)
+{
+ if (!PACKET_remaining(pkt))
+ return 0;
+
+ *data = *pkt->curr;
+
+ return 1;
+}
+
+/* Get 1 byte from |pkt| and store the value in |*data| */
+__owur static ossl_inline int PACKET_get_1(PACKET *pkt, unsigned int *data)
+{
+ if (!PACKET_peek_1(pkt, data))
+ return 0;
+
+ packet_forward(pkt, 1);
+
+ return 1;
+}
+
+/*
+ * Peek ahead at 4 bytes in reverse network order from |pkt| and store the value
+ * in |*data|
+ */
+__owur static ossl_inline int PACKET_peek_4(const PACKET *pkt,
+ unsigned long *data)
+{
+ if (PACKET_remaining(pkt) < 4)
+ return 0;
+
+ *data = *pkt->curr;
+ *data |= ((unsigned long)(*(pkt->curr + 1))) << 8;
+ *data |= ((unsigned long)(*(pkt->curr + 2))) << 16;
+ *data |= ((unsigned long)(*(pkt->curr + 3))) << 24;
+
+ return 1;
+}
+
+/* Equivalent of c2l */
+/*
+ * Get 4 bytes in reverse network order from |pkt| and store the value in
+ * |*data|
+ */
+__owur static ossl_inline int PACKET_get_4(PACKET *pkt, unsigned long *data)
+{
+ if (!PACKET_peek_4(pkt, data))
+ return 0;
+
+ packet_forward(pkt, 4);
+
+ return 1;
+}
+
+/*
+ * Peek ahead at |len| bytes from the |pkt| and store a pointer to them in
+ * |*data|. This just points at the underlying buffer that |pkt| is using. The
+ * caller should not free this data directly (it will be freed when the
+ * underlying buffer gets freed
+ */
+__owur static ossl_inline int PACKET_peek_bytes(const PACKET *pkt,
+ const unsigned char **data,
+ size_t len)
+{
+ if (PACKET_remaining(pkt) < len)
+ return 0;
+
+ *data = pkt->curr;
+
+ return 1;
+}
+
+/*
+ * Read |len| bytes from the |pkt| and store a pointer to them in |*data|. This
+ * just points at the underlying buffer that |pkt| is using. The caller should
+ * not free this data directly (it will be freed when the underlying buffer gets
+ * freed
+ */
+__owur static ossl_inline int PACKET_get_bytes(PACKET *pkt,
+ const unsigned char **data,
+ size_t len)
+{
+ if (!PACKET_peek_bytes(pkt, data, len))
+ return 0;
+
+ packet_forward(pkt, len);
+
+ return 1;
+}
+
+/* Peek ahead at |len| bytes from |pkt| and copy them to |data| */
+__owur static ossl_inline int PACKET_peek_copy_bytes(const PACKET *pkt,
+ unsigned char *data,
+ size_t len)
+{
+ if (PACKET_remaining(pkt) < len)
+ return 0;
+
+ memcpy(data, pkt->curr, len);
+
+ return 1;
+}
+
+/*
+ * Read |len| bytes from |pkt| and copy them to |data|.
+ * The caller is responsible for ensuring that |data| can hold |len| bytes.
+ */
+__owur static ossl_inline int PACKET_copy_bytes(PACKET *pkt,
+ unsigned char *data, size_t len)
+{
+ if (!PACKET_peek_copy_bytes(pkt, data, len))
+ return 0;
+
+ packet_forward(pkt, len);
+
+ return 1;
+}
+
+/*
+ * Copy packet data to |dest|, and set |len| to the number of copied bytes.
+ * If the packet has more than |dest_len| bytes, nothing is copied.
+ * Returns 1 if the packet data fits in |dest_len| bytes, 0 otherwise.
+ * Does not forward PACKET position (because it is typically the last thing
+ * done with a given PACKET).
+ */
+__owur static ossl_inline int PACKET_copy_all(const PACKET *pkt,
+ unsigned char *dest,
+ size_t dest_len, size_t *len)
+{
+ if (PACKET_remaining(pkt) > dest_len) {
+ *len = 0;
+ return 0;
+ }
+ *len = pkt->remaining;
+ memcpy(dest, pkt->curr, pkt->remaining);
+ return 1;
+}
+
+/*
+ * Copy |pkt| bytes to a newly allocated buffer and store a pointer to the
+ * result in |*data|, and the length in |len|.
+ * If |*data| is not NULL, the old data is OPENSSL_free'd.
+ * If the packet is empty, or malloc fails, |*data| will be set to NULL.
+ * Returns 1 if the malloc succeeds and 0 otherwise.
+ * Does not forward PACKET position (because it is typically the last thing
+ * done with a given PACKET).
+ */
+__owur static ossl_inline int PACKET_memdup(const PACKET *pkt,
+ unsigned char **data, size_t *len)
+{
+ size_t length;
+
+ OPENSSL_free(*data);
+ *data = NULL;
+ *len = 0;
+
+ length = PACKET_remaining(pkt);
+
+ if (length == 0)
+ return 1;
+
+ *data = OPENSSL_memdup(pkt->curr, length);
+ if (*data == NULL)
+ return 0;
+
+ *len = length;
+ return 1;
+}
+
+/*
+ * Read a C string from |pkt| and copy to a newly allocated, NUL-terminated
+ * buffer. Store a pointer to the result in |*data|.
+ * If |*data| is not NULL, the old data is OPENSSL_free'd.
+ * If the data in |pkt| does not contain a NUL-byte, the entire data is
+ * copied and NUL-terminated.
+ * Returns 1 if the malloc succeeds and 0 otherwise.
+ * Does not forward PACKET position (because it is typically the last thing done
+ * with a given PACKET).
+ */
+__owur static ossl_inline int PACKET_strndup(const PACKET *pkt, char **data)
+{
+ OPENSSL_free(*data);
+
+ /* This will succeed on an empty packet, unless pkt->curr == NULL. */
+ *data = OPENSSL_strndup((const char *)pkt->curr, PACKET_remaining(pkt));
+ return (*data != NULL);
+}
+
+/* Returns 1 if |pkt| contains at least one 0-byte, 0 otherwise. */
+static ossl_inline int PACKET_contains_zero_byte(const PACKET *pkt)
+{
+ return memchr(pkt->curr, 0, pkt->remaining) != NULL;
+}
+
+/* Move the current reading position forward |len| bytes */
+__owur static ossl_inline int PACKET_forward(PACKET *pkt, size_t len)
+{
+ if (PACKET_remaining(pkt) < len)
+ return 0;
+
+ packet_forward(pkt, len);
+
+ return 1;
+}
+
+/*
+ * Reads a variable-length vector prefixed with a one-byte length, and stores
+ * the contents in |subpkt|. |pkt| can equal |subpkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ * Upon failure, the original |pkt| and |subpkt| are not modified.
+ */
+__owur static ossl_inline int PACKET_get_length_prefixed_1(PACKET *pkt,
+ PACKET *subpkt)
+{
+ unsigned int length;
+ const unsigned char *data;
+ PACKET tmp = *pkt;
+ if (!PACKET_get_1(&tmp, &length) ||
+ !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
+ return 0;
+ }
+
+ *pkt = tmp;
+ subpkt->curr = data;
+ subpkt->remaining = length;
+
+ return 1;
+}
+
+/*
+ * Like PACKET_get_length_prefixed_1, but additionally, fails when there are
+ * leftover bytes in |pkt|.
+ */
+__owur static ossl_inline int PACKET_as_length_prefixed_1(PACKET *pkt,
+ PACKET *subpkt)
+{
+ unsigned int length;
+ const unsigned char *data;
+ PACKET tmp = *pkt;
+ if (!PACKET_get_1(&tmp, &length) ||
+ !PACKET_get_bytes(&tmp, &data, (size_t)length) ||
+ PACKET_remaining(&tmp) != 0) {
+ return 0;
+ }
+
+ *pkt = tmp;
+ subpkt->curr = data;
+ subpkt->remaining = length;
+
+ return 1;
+}
+
+/*
+ * Reads a variable-length vector prefixed with a two-byte length, and stores
+ * the contents in |subpkt|. |pkt| can equal |subpkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ * Upon failure, the original |pkt| and |subpkt| are not modified.
+ */
+__owur static ossl_inline int PACKET_get_length_prefixed_2(PACKET *pkt,
+ PACKET *subpkt)
+{
+ unsigned int length;
+ const unsigned char *data;
+ PACKET tmp = *pkt;
+
+ if (!PACKET_get_net_2(&tmp, &length) ||
+ !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
+ return 0;
+ }
+
+ *pkt = tmp;
+ subpkt->curr = data;
+ subpkt->remaining = length;
+
+ return 1;
+}
+
+/*
+ * Like PACKET_get_length_prefixed_2, but additionally, fails when there are
+ * leftover bytes in |pkt|.
+ */
+__owur static ossl_inline int PACKET_as_length_prefixed_2(PACKET *pkt,
+ PACKET *subpkt)
+{
+ unsigned int length;
+ const unsigned char *data;
+ PACKET tmp = *pkt;
+
+ if (!PACKET_get_net_2(&tmp, &length) ||
+ !PACKET_get_bytes(&tmp, &data, (size_t)length) ||
+ PACKET_remaining(&tmp) != 0) {
+ return 0;
+ }
+
+ *pkt = tmp;
+ subpkt->curr = data;
+ subpkt->remaining = length;
+
+ return 1;
+}
+
+/*
+ * Reads a variable-length vector prefixed with a three-byte length, and stores
+ * the contents in |subpkt|. |pkt| can equal |subpkt|.
+ * Data is not copied: the |subpkt| packet will share its underlying buffer with
+ * the original |pkt|, so data wrapped by |pkt| must outlive the |subpkt|.
+ * Upon failure, the original |pkt| and |subpkt| are not modified.
+ */
+__owur static ossl_inline int PACKET_get_length_prefixed_3(PACKET *pkt,
+ PACKET *subpkt)
+{
+ unsigned long length;
+ const unsigned char *data;
+ PACKET tmp = *pkt;
+ if (!PACKET_get_net_3(&tmp, &length) ||
+ !PACKET_get_bytes(&tmp, &data, (size_t)length)) {
+ return 0;
+ }
+
+ *pkt = tmp;
+ subpkt->curr = data;
+ subpkt->remaining = length;
+
+ return 1;
+}
+# ifdef __cplusplus
+}
+# endif
+
+#endif /* HEADER_PACKET_LOCL_H */
diff --git a/openssl-1.1.0h/ssl/pqueue.c b/openssl-1.1.0h/ssl/pqueue.c
new file mode 100644
index 0000000..b447e1d
--- /dev/null
+++ b/openssl-1.1.0h/ssl/pqueue.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "ssl_locl.h"
+#include <openssl/bn.h>
+
+struct pqueue_st {
+ pitem *items;
+ int count;
+};
+
+pitem *pitem_new(unsigned char *prio64be, void *data)
+{
+ pitem *item = OPENSSL_malloc(sizeof(*item));
+ if (item == NULL)
+ return NULL;
+
+ memcpy(item->priority, prio64be, sizeof(item->priority));
+
+ item->data = data;
+ item->next = NULL;
+
+ return item;
+}
+
+void pitem_free(pitem *item)
+{
+ OPENSSL_free(item);
+}
+
+pqueue *pqueue_new()
+{
+ pqueue *pq = OPENSSL_zalloc(sizeof(*pq));
+
+ return pq;
+}
+
+void pqueue_free(pqueue *pq)
+{
+ OPENSSL_free(pq);
+}
+
+pitem *pqueue_insert(pqueue *pq, pitem *item)
+{
+ pitem *curr, *next;
+
+ if (pq->items == NULL) {
+ pq->items = item;
+ return item;
+ }
+
+ for (curr = NULL, next = pq->items;
+ next != NULL; curr = next, next = next->next) {
+ /*
+ * we can compare 64-bit value in big-endian encoding with memcmp:-)
+ */
+ int cmp = memcmp(next->priority, item->priority, 8);
+ if (cmp > 0) { /* next > item */
+ item->next = next;
+
+ if (curr == NULL)
+ pq->items = item;
+ else
+ curr->next = item;
+
+ return item;
+ }
+
+ else if (cmp == 0) /* duplicates not allowed */
+ return NULL;
+ }
+
+ item->next = NULL;
+ curr->next = item;
+
+ return item;
+}
+
+pitem *pqueue_peek(pqueue *pq)
+{
+ return pq->items;
+}
+
+pitem *pqueue_pop(pqueue *pq)
+{
+ pitem *item = pq->items;
+
+ if (pq->items != NULL)
+ pq->items = pq->items->next;
+
+ return item;
+}
+
+pitem *pqueue_find(pqueue *pq, unsigned char *prio64be)
+{
+ pitem *next;
+ pitem *found = NULL;
+
+ if (pq->items == NULL)
+ return NULL;
+
+ for (next = pq->items; next->next != NULL; next = next->next) {
+ if (memcmp(next->priority, prio64be, 8) == 0) {
+ found = next;
+ break;
+ }
+ }
+
+ /* check the one last node */
+ if (memcmp(next->priority, prio64be, 8) == 0)
+ found = next;
+
+ if (!found)
+ return NULL;
+
+ return found;
+}
+
+pitem *pqueue_iterator(pqueue *pq)
+{
+ return pqueue_peek(pq);
+}
+
+pitem *pqueue_next(pitem **item)
+{
+ pitem *ret;
+
+ if (item == NULL || *item == NULL)
+ return NULL;
+
+ /* *item != NULL */
+ ret = *item;
+ *item = (*item)->next;
+
+ return ret;
+}
+
+int pqueue_size(pqueue *pq)
+{
+ pitem *item = pq->items;
+ int count = 0;
+
+ while (item != NULL) {
+ count++;
+ item = item->next;
+ }
+ return count;
+}
diff --git a/openssl-1.1.0h/ssl/record/README b/openssl-1.1.0h/ssl/record/README
new file mode 100644
index 0000000..987e9fd
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/README
@@ -0,0 +1,74 @@
+Record Layer Design
+===================
+
+This file provides some guidance on the thinking behind the design of the
+record layer code to aid future maintenance.
+
+The record layer is divided into a number of components. At the time of writing
+there are four: SSL3_RECORD, SSL3_BUFFER, DLTS1_BITMAP and RECORD_LAYER. Each
+of these components is defined by:
+1) A struct definition of the same name as the component
+2) A set of source files that define the functions for that component
+3) A set of accessor macros
+
+All struct definitions are in record.h. The functions and macros are either
+defined in record.h or record_locl.h dependent on whether they are intended to
+be private to the record layer, or whether they form part of the API to the rest
+of libssl.
+
+The source files map to components as follows:
+
+dtls1_bitmap.c -> DTLS1_BITMAP component
+ssl3_buffer.c -> SSL3_BUFFER component
+ssl3_record.c -> SSL3_RECORD component
+rec_layer_s3.c, rec_layer_d1.c -> RECORD_LAYER component
+
+The RECORD_LAYER component is a facade pattern, i.e. it provides a simplified
+interface to the record layer for the rest of libssl. The other 3 components are
+entirely private to the record layer and therefore should never be accessed
+directly by libssl.
+
+Any component can directly access its own members - they are private to that
+component, e.g. ssl3_buffer.c can access members of the SSL3_BUFFER struct
+without using a macro. No component can directly access the members of another
+component, e.g. ssl3_buffer cannot reach inside the RECORD_LAYER component to
+directly access its members. Instead components use accessor macros, so if code
+in ssl3_buffer.c wants to access the members of the RECORD_LAYER it uses the
+RECORD_LAYER_* macros.
+
+Conceptually it looks like this:
+
+ libssl
+ |
+---------------------------|-----record.h--------------------------------------
+ |
+ _______V______________
+ | |
+ | RECORD_LAYER |
+ | |
+ | rec_layer_s3.c |
+ | ^ |
+ | _________|__________ |
+ || ||
+ || DTLS1_RECORD_LAYER ||
+ || ||
+ || rec_layer_d1.c ||
+ ||____________________||
+ |______________________|
+ record_locl.h ^ ^ ^
+ _________________| | |_________________
+ | | |
+ _____V_________ ______V________ _______V________
+ | | | | | |
+ | SSL3_BUFFER | | SSL3_RECORD | | DTLS1_BITMAP |
+ | |--->| | | |
+ | ssl3_buffer.c | | ssl3_record.c | | dtls1_bitmap.c |
+ |_______________| |_______________| |________________|
+
+
+The two RECORD_LAYER source files build on each other, i.e.
+the main one is rec_layer_s3.c which provides the core SSL/TLS layer. The second
+one is rec_layer_d1.c which builds off of the SSL/TLS code to provide DTLS
+specific capabilities. It uses some DTLS specific RECORD_LAYER component members
+which should only be accessed from rec_layer_d1.c. These are held in the
+DTLS1_RECORD_LAYER struct.
diff --git a/openssl-1.1.0h/ssl/record/dtls1_bitmap.c b/openssl-1.1.0h/ssl/record/dtls1_bitmap.c
new file mode 100644
index 0000000..5923c53
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/dtls1_bitmap.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "../ssl_locl.h"
+#include "record_locl.h"
+
+/* mod 128 saturating subtract of two 64-bit values in big-endian order */
+static int satsub64be(const unsigned char *v1, const unsigned char *v2)
+{
+ int64_t ret;
+ uint64_t l1, l2;
+
+ n2l8(v1, l1);
+ n2l8(v2, l2);
+
+ ret = l1 - l2;
+
+ /* We do not permit wrap-around */
+ if (l1 > l2 && ret < 0)
+ return 128;
+ else if (l2 > l1 && ret > 0)
+ return -128;
+
+ if (ret > 128)
+ return 128;
+ else if (ret < -128)
+ return -128;
+ else
+ return (int)ret;
+}
+
+int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap)
+{
+ int cmp;
+ unsigned int shift;
+ const unsigned char *seq = s->rlayer.read_sequence;
+
+ cmp = satsub64be(seq, bitmap->max_seq_num);
+ if (cmp > 0) {
+ SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
+ return 1; /* this record in new */
+ }
+ shift = -cmp;
+ if (shift >= sizeof(bitmap->map) * 8)
+ return 0; /* stale, outside the window */
+ else if (bitmap->map & (1UL << shift))
+ return 0; /* record previously received */
+
+ SSL3_RECORD_set_seq_num(RECORD_LAYER_get_rrec(&s->rlayer), seq);
+ return 1;
+}
+
+void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap)
+{
+ int cmp;
+ unsigned int shift;
+ const unsigned char *seq = RECORD_LAYER_get_read_sequence(&s->rlayer);
+
+ cmp = satsub64be(seq, bitmap->max_seq_num);
+ if (cmp > 0) {
+ shift = cmp;
+ if (shift < sizeof(bitmap->map) * 8)
+ bitmap->map <<= shift, bitmap->map |= 1UL;
+ else
+ bitmap->map = 1UL;
+ memcpy(bitmap->max_seq_num, seq, SEQ_NUM_SIZE);
+ } else {
+ shift = -cmp;
+ if (shift < sizeof(bitmap->map) * 8)
+ bitmap->map |= 1UL << shift;
+ }
+}
diff --git a/openssl-1.1.0h/ssl/record/rec_layer_d1.c b/openssl-1.1.0h/ssl/record/rec_layer_d1.c
new file mode 100644
index 0000000..b3ff5f1
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/rec_layer_d1.c
@@ -0,0 +1,1229 @@
+/*
+ * Copyright 2005-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "../ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include "record_locl.h"
+
+int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl)
+{
+ DTLS_RECORD_LAYER *d;
+
+ if ((d = OPENSSL_malloc(sizeof(*d))) == NULL)
+ return (0);
+
+ rl->d = d;
+
+ d->unprocessed_rcds.q = pqueue_new();
+ d->processed_rcds.q = pqueue_new();
+ d->buffered_app_data.q = pqueue_new();
+
+ if (d->unprocessed_rcds.q == NULL || d->processed_rcds.q == NULL
+ || d->buffered_app_data.q == NULL) {
+ pqueue_free(d->unprocessed_rcds.q);
+ pqueue_free(d->processed_rcds.q);
+ pqueue_free(d->buffered_app_data.q);
+ OPENSSL_free(d);
+ rl->d = NULL;
+ return (0);
+ }
+
+ return 1;
+}
+
+void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl)
+{
+ DTLS_RECORD_LAYER_clear(rl);
+ pqueue_free(rl->d->unprocessed_rcds.q);
+ pqueue_free(rl->d->processed_rcds.q);
+ pqueue_free(rl->d->buffered_app_data.q);
+ OPENSSL_free(rl->d);
+ rl->d = NULL;
+}
+
+void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl)
+{
+ DTLS_RECORD_LAYER *d;
+ pitem *item = NULL;
+ DTLS1_RECORD_DATA *rdata;
+ pqueue *unprocessed_rcds;
+ pqueue *processed_rcds;
+ pqueue *buffered_app_data;
+
+ d = rl->d;
+
+ while ((item = pqueue_pop(d->unprocessed_rcds.q)) != NULL) {
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+
+ while ((item = pqueue_pop(d->processed_rcds.q)) != NULL) {
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+
+ while ((item = pqueue_pop(d->buffered_app_data.q)) != NULL) {
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+
+ unprocessed_rcds = d->unprocessed_rcds.q;
+ processed_rcds = d->processed_rcds.q;
+ buffered_app_data = d->buffered_app_data.q;
+ memset(d, 0, sizeof(*d));
+ d->unprocessed_rcds.q = unprocessed_rcds;
+ d->processed_rcds.q = processed_rcds;
+ d->buffered_app_data.q = buffered_app_data;
+}
+
+void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e)
+{
+ if (e == rl->d->w_epoch - 1) {
+ memcpy(rl->d->curr_write_sequence,
+ rl->write_sequence, sizeof(rl->write_sequence));
+ memcpy(rl->write_sequence,
+ rl->d->last_write_sequence, sizeof(rl->write_sequence));
+ } else if (e == rl->d->w_epoch + 1) {
+ memcpy(rl->d->last_write_sequence,
+ rl->write_sequence, sizeof(unsigned char[8]));
+ memcpy(rl->write_sequence,
+ rl->d->curr_write_sequence, sizeof(rl->write_sequence));
+ }
+ rl->d->w_epoch = e;
+}
+
+void DTLS_RECORD_LAYER_resync_write(RECORD_LAYER *rl)
+{
+ memcpy(rl->write_sequence, rl->read_sequence, sizeof(rl->write_sequence));
+}
+
+void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq)
+{
+ memcpy(rl->write_sequence, seq, SEQ_NUM_SIZE);
+}
+
+static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
+ int len);
+
+/* copy buffered record into SSL structure */
+static int dtls1_copy_record(SSL *s, pitem *item)
+{
+ DTLS1_RECORD_DATA *rdata;
+
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+
+ SSL3_BUFFER_release(&s->rlayer.rbuf);
+
+ s->rlayer.packet = rdata->packet;
+ s->rlayer.packet_length = rdata->packet_length;
+ memcpy(&s->rlayer.rbuf, &(rdata->rbuf), sizeof(SSL3_BUFFER));
+ memcpy(&s->rlayer.rrec, &(rdata->rrec), sizeof(SSL3_RECORD));
+
+ /* Set proper sequence number for mac calculation */
+ memcpy(&(s->rlayer.read_sequence[2]), &(rdata->packet[5]), 6);
+
+ return (1);
+}
+
+int dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority)
+{
+ DTLS1_RECORD_DATA *rdata;
+ pitem *item;
+
+ /* Limit the size of the queue to prevent DOS attacks */
+ if (pqueue_size(queue->q) >= 100)
+ return 0;
+
+ rdata = OPENSSL_malloc(sizeof(*rdata));
+ item = pitem_new(priority, rdata);
+ if (rdata == NULL || item == NULL) {
+ OPENSSL_free(rdata);
+ pitem_free(item);
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ rdata->packet = s->rlayer.packet;
+ rdata->packet_length = s->rlayer.packet_length;
+ memcpy(&(rdata->rbuf), &s->rlayer.rbuf, sizeof(SSL3_BUFFER));
+ memcpy(&(rdata->rrec), &s->rlayer.rrec, sizeof(SSL3_RECORD));
+
+ item->data = rdata;
+
+#ifndef OPENSSL_NO_SCTP
+ /* Store bio_dgram_sctp_rcvinfo struct */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ (SSL_get_state(s) == TLS_ST_SR_FINISHED
+ || SSL_get_state(s) == TLS_ST_CR_FINISHED)) {
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO,
+ sizeof(rdata->recordinfo), &rdata->recordinfo);
+ }
+#endif
+
+ s->rlayer.packet = NULL;
+ s->rlayer.packet_length = 0;
+ memset(&s->rlayer.rbuf, 0, sizeof(s->rlayer.rbuf));
+ memset(&s->rlayer.rrec, 0, sizeof(s->rlayer.rrec));
+
+ if (!ssl3_setup_buffers(s)) {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+ return (-1);
+ }
+
+ /* insert should not fail, since duplicates are dropped */
+ if (pqueue_insert(queue->q, item) == NULL) {
+ SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(rdata->rbuf.buf);
+ OPENSSL_free(rdata);
+ pitem_free(item);
+ return (-1);
+ }
+
+ return (1);
+}
+
+int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
+{
+ pitem *item;
+
+ item = pqueue_pop(queue->q);
+ if (item) {
+ dtls1_copy_record(s, item);
+
+ OPENSSL_free(item->data);
+ pitem_free(item);
+
+ return (1);
+ }
+
+ return (0);
+}
+
+/*
+ * retrieve a buffered record that belongs to the new epoch, i.e., not
+ * processed yet
+ */
+#define dtls1_get_unprocessed_record(s) \
+ dtls1_retrieve_buffered_record((s), \
+ &((s)->rlayer.d->unprocessed_rcds))
+
+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->rlayer.d->unprocessed_rcds.q);
+ if (item) {
+ /* Check if epoch is current. */
+ if (s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch)
+ return 1; /* Nothing to do. */
+
+ rr = RECORD_LAYER_get_rrec(&s->rlayer);
+
+ rb = RECORD_LAYER_get_rbuf(&s->rlayer);
+
+ if (SSL3_BUFFER_get_left(rb) > 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->rlayer.d->unprocessed_rcds.q)) {
+ dtls1_get_unprocessed_record(s);
+ 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;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ continue;
+ }
+
+ if (dtls1_buffer_record(s, &(s->rlayer.d->processed_rcds),
+ SSL3_RECORD_get_seq_num(s->rlayer.rrec)) < 0)
+ return 0;
+ }
+ }
+
+ /*
+ * sync epoch numbers once all the unprocessed records have been
+ * processed
+ */
+ s->rlayer.d->processed_rcds.epoch = s->rlayer.d->r_epoch;
+ s->rlayer.d->unprocessed_rcds.epoch = s->rlayer.d->r_epoch + 1;
+
+ return 1;
+}
+
+/*-
+ * Return up to 'len' payload bytes received in 'type' records.
+ * 'type' is one of the following:
+ *
+ * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
+ * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ * - 0 (during a shutdown, no data has to be returned)
+ *
+ * If we don't have stored data to work from, read a SSL/TLS record first
+ * (possibly multiple records if we still don't have anything to return).
+ *
+ * This function must handle any surprises the peer may have for us, such as
+ * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec
+ * messages are treated as if they were handshake messages *if* the |recd_type|
+ * argument is non NULL.
+ * Also if record payloads contain fragments too small to process, we store
+ * them until there is enough for the respective protocol (the record protocol
+ * may use arbitrary fragmentation and even interleaving):
+ * Change cipher spec protocol
+ * just 1 byte needed, no need for keeping anything stored
+ * Alert protocol
+ * 2 bytes needed (AlertLevel, AlertDescription)
+ * Handshake protocol
+ * 4 bytes needed (HandshakeType, uint24 length) -- we just have
+ * to detect unexpected Client Hello and Hello Request messages
+ * here, anything else is handled by higher layers
+ * Application data protocol
+ * none of our business
+ */
+int dtls1_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
+ int len, int peek)
+{
+ int al, i, j, ret;
+ unsigned int n;
+ SSL3_RECORD *rr;
+ void (*cb) (const SSL *ssl, int type2, int val) = NULL;
+
+ if (!SSL3_BUFFER_is_initialised(&s->rlayer.rbuf)) {
+ /* Not initialized yet */
+ if (!ssl3_setup_buffers(s))
+ return (-1);
+ }
+
+ if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
+ (type != SSL3_RT_HANDSHAKE)) ||
+ (peek && (type != SSL3_RT_APPLICATION_DATA))) {
+ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ /*
+ * check whether there's a handshake message (client hello?) waiting
+ */
+ if ((ret = have_handshake_fragment(s, type, buf, len))) {
+ *recvd_type = SSL3_RT_HANDSHAKE;
+ return ret;
+ }
+
+ /*
+ * Now s->rlayer.d->handshake_fragment_len == 0 if
+ * type == SSL3_RT_HANDSHAKE.
+ */
+
+ if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s))
+ {
+ /* type == SSL3_RT_APPLICATION_DATA */
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return (-1);
+ }
+ }
+
+ start:
+ s->rwstate = SSL_NOTHING;
+
+ /*-
+ * s->s3->rrec.type - is the type of record
+ * s->s3->rrec.data, - data
+ * s->s3->rrec.off, - offset into 'data' for next read
+ * s->s3->rrec.length, - number of bytes.
+ */
+ rr = s->rlayer.rrec;
+
+ /*
+ * We are not handshaking and have no data yet, so process data buffered
+ * during the last handshake in advance, if any.
+ */
+ if (SSL_is_init_finished(s) && SSL3_RECORD_get_length(rr) == 0) {
+ pitem *item;
+ item = pqueue_pop(s->rlayer.d->buffered_app_data.q);
+ if (item) {
+#ifndef OPENSSL_NO_SCTP
+ /* Restore bio_dgram_sctp_rcvinfo struct */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s))) {
+ DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data;
+ BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO,
+ sizeof(rdata->recordinfo), &rdata->recordinfo);
+ }
+#endif
+
+ dtls1_copy_record(s, item);
+
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+ }
+
+ /* Check for timeout */
+ if (dtls1_handle_timeout(s) > 0)
+ goto start;
+
+ /* get new packet if necessary */
+ if ((SSL3_RECORD_get_length(rr) == 0)
+ || (s->rlayer.rstate == SSL_ST_READ_BODY)) {
+ ret = dtls1_get_record(s);
+ if (ret <= 0) {
+ ret = dtls1_read_failed(s, ret);
+ /* anything other than a timeout is an error */
+ if (ret <= 0)
+ return (ret);
+ else
+ goto start;
+ }
+ }
+
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
+ && SSL3_RECORD_get_length(rr) != 0)
+ s->rlayer.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,
+ * reset by ssl3_get_finished */
+ && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
+ /*
+ * We now have application data between CCS and Finished. Most likely
+ * the packets were reordered on their way, so buffer the application
+ * data for later processing rather than dropping the connection.
+ */
+ if (dtls1_buffer_record(s, &(s->rlayer.d->buffered_app_data),
+ SSL3_RECORD_get_seq_num(rr)) < 0) {
+ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ SSL3_RECORD_set_length(rr, 0);
+ goto start;
+ }
+
+ /*
+ * If the other end has shut down, throw anything we read away (even in
+ * 'peek' mode)
+ */
+ if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ SSL3_RECORD_set_length(rr, 0);
+ s->rwstate = SSL_NOTHING;
+ return (0);
+ }
+
+ if (type == SSL3_RECORD_get_type(rr)
+ || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+ && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
+ /*
+ * SSL3_RT_APPLICATION_DATA or
+ * SSL3_RT_HANDSHAKE or
+ * SSL3_RT_CHANGE_CIPHER_SPEC
+ */
+ /*
+ * make sure that we are not getting application data when we are
+ * doing a handshake for the first time
+ */
+ if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
+ (s->enc_read_ctx == NULL)) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE);
+ goto f_err;
+ }
+
+ if (recvd_type != NULL)
+ *recvd_type = SSL3_RECORD_get_type(rr);
+
+ if (len <= 0)
+ return (len);
+
+ if ((unsigned int)len > SSL3_RECORD_get_length(rr))
+ n = SSL3_RECORD_get_length(rr);
+ else
+ n = (unsigned int)len;
+
+ memcpy(buf, &(SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)]), n);
+ if (!peek) {
+ SSL3_RECORD_sub_length(rr, n);
+ SSL3_RECORD_add_off(rr, n);
+ if (SSL3_RECORD_get_length(rr) == 0) {
+ s->rlayer.rstate = SSL_ST_READ_HEADER;
+ SSL3_RECORD_set_off(rr, 0);
+ }
+ }
+#ifndef OPENSSL_NO_SCTP
+ /*
+ * We might had to delay a close_notify alert because of reordered
+ * app data. If there was an alert and there is no message to read
+ * anymore, finally set shutdown.
+ */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ s->d1->shutdown_received
+ && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+ s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ return (0);
+ }
+#endif
+ return (n);
+ }
+
+ /*
+ * If we get here, then type != rr->type; if we have a handshake message,
+ * then it was unexpected (Hello Request or Client Hello).
+ */
+
+ /*
+ * In case of record types for which we have 'fragment' storage, fill
+ * that so that we can process the data at a fixed place.
+ */
+ {
+ unsigned int k, dest_maxlen = 0;
+ unsigned char *dest = NULL;
+ unsigned int *dest_len = NULL;
+
+ if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
+ dest_maxlen = sizeof(s->rlayer.d->handshake_fragment);
+ dest = s->rlayer.d->handshake_fragment;
+ dest_len = &s->rlayer.d->handshake_fragment_len;
+ } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
+ dest_maxlen = sizeof(s->rlayer.d->alert_fragment);
+ dest = s->rlayer.d->alert_fragment;
+ dest_len = &s->rlayer.d->alert_fragment_len;
+ }
+#ifndef OPENSSL_NO_HEARTBEATS
+ else if (SSL3_RECORD_get_type(rr) == DTLS1_RT_HEARTBEAT) {
+ /* We allow a 0 return */
+ if (dtls1_process_heartbeat(s, SSL3_RECORD_get_data(rr),
+ SSL3_RECORD_get_length(rr)) < 0) {
+ return -1;
+ }
+ /* Exit and notify application to read again */
+ SSL3_RECORD_set_length(rr, 0);
+ s->rwstate = SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ return (-1);
+ }
+#endif
+ /* else it's a CCS message, or application data or wrong */
+ else if (SSL3_RECORD_get_type(rr) != SSL3_RT_CHANGE_CIPHER_SPEC) {
+ /*
+ * Application data while renegotiating is allowed. Try again
+ * reading.
+ */
+ if (SSL3_RECORD_get_type(rr) == SSL3_RT_APPLICATION_DATA) {
+ BIO *bio;
+ s->s3->in_read_app_data = 2;
+ bio = SSL_get_rbio(s);
+ s->rwstate = SSL_READING;
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return (-1);
+ }
+
+ /* Not certain if this is the right error handling */
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ }
+
+ if (dest_maxlen > 0) {
+ /*
+ * XDTLS: In a pathological case, the Client Hello may be
+ * fragmented--don't always expect dest_maxlen bytes
+ */
+ if (SSL3_RECORD_get_length(rr) < dest_maxlen) {
+#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE
+ /*
+ * for normal alerts rr->length is 2, while
+ * dest_maxlen is 7 if we were to handle this
+ * non-existing alert...
+ */
+ FIX ME;
+#endif
+ s->rlayer.rstate = SSL_ST_READ_HEADER;
+ SSL3_RECORD_set_length(rr, 0);
+ goto start;
+ }
+
+ /* now move 'n' bytes: */
+ for (k = 0; k < dest_maxlen; k++) {
+ dest[k] = SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
+ SSL3_RECORD_add_off(rr, 1);
+ SSL3_RECORD_add_length(rr, -1);
+ }
+ *dest_len = dest_maxlen;
+ }
+ }
+
+ /*-
+ * s->rlayer.d->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE;
+ * s->rlayer.d->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT.
+ * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
+ */
+
+ /* If we are a client, check for an incoming 'Hello Request': */
+ if ((!s->server) &&
+ (s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
+ (s->rlayer.d->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+ (s->session != NULL) && (s->session->cipher != NULL)) {
+ s->rlayer.d->handshake_fragment_len = 0;
+
+ if ((s->rlayer.d->handshake_fragment[1] != 0) ||
+ (s->rlayer.d->handshake_fragment[2] != 0) ||
+ (s->rlayer.d->handshake_fragment[3] != 0)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
+ goto f_err;
+ }
+
+ /*
+ * no need to check sequence number on HELLO REQUEST messages
+ */
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+ s->rlayer.d->handshake_fragment, 4, s,
+ s->msg_callback_arg);
+
+ if (SSL_is_init_finished(s) &&
+ (s->options & SSL_OP_NO_RENEGOTIATION) == 0 &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+ !s->s3->renegotiate) {
+ s->d1->handshake_read_seq++;
+ s->new_session = 1;
+ ssl3_renegotiate(s);
+ if (ssl3_renegotiate_check(s)) {
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return (-1);
+ }
+
+ if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+ if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
+ /* no read-ahead left? */
+ BIO *bio;
+ /*
+ * In the case where we try to read application data,
+ * but we trigger an SSL handshake, we return -1 with
+ * the retry option set. Otherwise renegotiation may
+ * cause nasty problems in the blocking world
+ */
+ s->rwstate = SSL_READING;
+ bio = SSL_get_rbio(s);
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return (-1);
+ }
+ }
+ }
+ } else {
+ SSL3_RECORD_set_length(rr, 0);
+ ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ }
+ /*
+ * we either finished a handshake or ignored the request, now try
+ * again to obtain the (application) data we were asked for
+ */
+ goto start;
+ }
+
+ /*
+ * If we are a server and get a client hello when renegotiation isn't
+ * allowed send back a no renegotiation alert and carry on.
+ */
+ if (s->server
+ && SSL_is_init_finished(s)
+ && s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH
+ && s->rlayer.d->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO
+ && s->s3->previous_client_finished_len != 0
+ && ((!s->s3->send_connection_binding
+ && (s->options
+ & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0)
+ || (s->options & SSL_OP_NO_RENEGOTIATION) != 0)) {
+ s->rlayer.d->handshake_fragment_len = 0;
+ SSL3_RECORD_set_length(rr, 0);
+ ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ goto start;
+ }
+
+ if (s->rlayer.d->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) {
+ int alert_level = s->rlayer.d->alert_fragment[0];
+ int alert_descr = s->rlayer.d->alert_fragment[1];
+
+ s->rlayer.d->alert_fragment_len = 0;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_ALERT,
+ s->rlayer.d->alert_fragment, 2, s,
+ s->msg_callback_arg);
+
+ if (s->info_callback != NULL)
+ cb = s->info_callback;
+ else if (s->ctx->info_callback != NULL)
+ cb = s->ctx->info_callback;
+
+ if (cb != NULL) {
+ j = (alert_level << 8) | alert_descr;
+ cb(s, SSL_CB_READ_ALERT, j);
+ }
+
+ if (alert_level == SSL3_AL_WARNING) {
+ s->s3->warn_alert = alert_descr;
+
+ s->rlayer.alert_count++;
+ if (s->rlayer.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
+ /*
+ * With SCTP and streams the socket may deliver app data
+ * after a close_notify alert. We have to check this first so
+ * that nothing gets discarded.
+ */
+ if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
+ BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
+ s->d1->shutdown_received = 1;
+ s->rwstate = SSL_READING;
+ BIO_clear_retry_flags(SSL_get_rbio(s));
+ BIO_set_retry_read(SSL_get_rbio(s));
+ return -1;
+ }
+#endif
+ s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ return (0);
+ }
+#if 0
+ /* XXX: this is a possible improvement in the future */
+ /* now check if it's a missing record */
+ if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) {
+ unsigned short seq;
+ unsigned int frag_off;
+ unsigned char *p = &(s->rlayer.d->alert_fragment[2]);
+
+ n2s(p, seq);
+ n2l3(p, frag_off);
+
+ dtls1_retransmit_message(s,
+ dtls1_get_queue_priority
+ (frag->msg_header.seq, 0), frag_off,
+ &found);
+ if (!found && SSL_in_init(s)) {
+ /*
+ * fprintf( stderr,"in init = %d\n", SSL_in_init(s));
+ */
+ /*
+ * requested a message not yet sent, send an alert
+ * ourselves
+ */
+ ssl3_send_alert(s, SSL3_AL_WARNING,
+ DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+ }
+ }
+#endif
+ } else if (alert_level == SSL3_AL_FATAL) {
+ char tmp[16];
+
+ s->rwstate = SSL_NOTHING;
+ s->s3->fatal_alert = alert_descr;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+ 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->session_ctx, s->session);
+ return (0);
+ } else {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE);
+ goto f_err;
+ }
+
+ goto start;
+ }
+
+ if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
+ * shutdown */
+ s->rwstate = SSL_NOTHING;
+ SSL3_RECORD_set_length(rr, 0);
+ return (0);
+ }
+
+ if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
+ /*
+ * We can't process a CCS now, because previous handshake messages
+ * are still missing, so just drop it.
+ */
+ SSL3_RECORD_set_length(rr, 0);
+ goto start;
+ }
+
+ /*
+ * Unexpected handshake message (Client Hello, or protocol violation)
+ */
+ if ((s->rlayer.d->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) &&
+ !ossl_statem_get_in_handshake(s)) {
+ struct hm_header_st msg_hdr;
+
+ /* this may just be a stale retransmit */
+ dtls1_get_message_header(rr->data, &msg_hdr);
+ if (SSL3_RECORD_get_epoch(rr) != s->rlayer.d->r_epoch) {
+ SSL3_RECORD_set_length(rr, 0);
+ goto start;
+ }
+
+ /*
+ * If we are server, we may have a repeated FINISHED of the client
+ * here, then retransmit our CCS and FINISHED.
+ */
+ if (msg_hdr.type == SSL3_MT_FINISHED) {
+ if (dtls1_check_timeout_num(s) < 0)
+ return -1;
+
+ dtls1_retransmit_buffered_messages(s);
+ SSL3_RECORD_set_length(rr, 0);
+ goto start;
+ }
+
+ if (SSL_is_init_finished(s) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
+ ossl_statem_set_in_init(s, 1);
+ s->renegotiate = 1;
+ s->new_session = 1;
+ }
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return (-1);
+ }
+
+ if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+ if (SSL3_BUFFER_get_left(&s->rlayer.rbuf) == 0) {
+ /* no read-ahead left? */
+ BIO *bio;
+ /*
+ * In the case where we try to read application data, but we
+ * trigger an SSL handshake, we return -1 with the retry
+ * option set. Otherwise renegotiation may cause nasty
+ * problems in the blocking world
+ */
+ s->rwstate = SSL_READING;
+ bio = SSL_get_rbio(s);
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return (-1);
+ }
+ }
+ goto start;
+ }
+
+ switch (SSL3_RECORD_get_type(rr)) {
+ default:
+ /* TLS just ignores unknown message types */
+ if (s->version == TLS1_VERSION) {
+ SSL3_RECORD_set_length(rr, 0);
+ goto start;
+ }
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ case SSL3_RT_CHANGE_CIPHER_SPEC:
+ case SSL3_RT_ALERT:
+ case SSL3_RT_HANDSHAKE:
+ /*
+ * we already handled all of these, with the possible exception of
+ * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but
+ * that should not happen when type != rr->type
+ */
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ case SSL3_RT_APPLICATION_DATA:
+ /*
+ * At this point, we were expecting handshake data, but have
+ * application data. If the library was running inside ssl3_read()
+ * (i.e. in_read_app_data is set) and it makes sense to read
+ * application data at this point (session renegotiation not yet
+ * started), we will indulge it.
+ */
+ if (s->s3->in_read_app_data &&
+ (s->s3->total_renegotiations != 0) &&
+ ossl_statem_app_data_allowed(s)) {
+ s->s3->in_read_app_data = 2;
+ return (-1);
+ } else {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ }
+ }
+ /* not reached */
+
+ f_err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ return (-1);
+}
+
+ /*
+ * this only happens when a client hello is received and a handshake
+ * is started.
+ */
+static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
+ int len)
+{
+
+ if ((type == SSL3_RT_HANDSHAKE)
+ && (s->rlayer.d->handshake_fragment_len > 0))
+ /* (partially) satisfy request from storage */
+ {
+ unsigned char *src = s->rlayer.d->handshake_fragment;
+ unsigned char *dst = buf;
+ unsigned int k, n;
+
+ /* peek == 0 */
+ n = 0;
+ while ((len > 0) && (s->rlayer.d->handshake_fragment_len > 0)) {
+ *dst++ = *src++;
+ len--;
+ s->rlayer.d->handshake_fragment_len--;
+ n++;
+ }
+ /* move any remaining fragment bytes: */
+ for (k = 0; k < s->rlayer.d->handshake_fragment_len; k++)
+ s->rlayer.d->handshake_fragment[k] = *src++;
+ return n;
+ }
+
+ return 0;
+}
+
+/*
+ * Call this to write data in records of type 'type' It will return <= 0 if
+ * not all data has been sent or non-blocking IO.
+ */
+int dtls1_write_bytes(SSL *s, int type, const void *buf, int len)
+{
+ int i;
+
+ OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH);
+ s->rwstate = SSL_NOTHING;
+ i = do_dtls1_write(s, type, buf, len, 0);
+ return i;
+}
+
+int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+ unsigned int len, int create_empty_fragment)
+{
+ unsigned char *p, *pseq;
+ int i, mac_size, clear = 0;
+ int prefix_len = 0;
+ int eivlen;
+ SSL3_RECORD wr;
+ SSL3_BUFFER *wb;
+ SSL_SESSION *sess;
+
+ wb = &s->rlayer.wbuf[0];
+
+ /*
+ * first check if there is a SSL3_BUFFER still being written out. This
+ * will happen with non blocking IO
+ */
+ if (SSL3_BUFFER_get_left(wb) != 0) {
+ OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */
+ return (ssl3_write_pending(s, type, buf, len));
+ }
+
+ /* If we have an alert to send, lets send it */
+ if (s->s3->alert_dispatch) {
+ i = s->method->ssl_dispatch_alert(s);
+ if (i <= 0)
+ return (i);
+ /* if it went, fall through and send more stuff */
+ }
+
+ if (len == 0 && !create_empty_fragment)
+ return 0;
+
+ if (len > s->max_send_fragment) {
+ SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE);
+ return 0;
+ }
+
+ sess = s->session;
+
+ if ((sess == NULL) ||
+ (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL))
+ clear = 1;
+
+ if (clear)
+ mac_size = 0;
+ else {
+ mac_size = EVP_MD_CTX_size(s->write_hash);
+ if (mac_size < 0)
+ goto err;
+ }
+
+ p = SSL3_BUFFER_get_buf(wb) + prefix_len;
+
+ /* write the header */
+
+ *(p++) = type & 0xff;
+ SSL3_RECORD_set_type(&wr, type);
+ /*
+ * Special case: for hello verify request, client version 1.0 and we
+ * haven't decided which version to use yet send back using version 1.0
+ * header: otherwise some clients will ignore it.
+ */
+ if (s->method->version == DTLS_ANY_VERSION &&
+ s->max_proto_version != DTLS1_BAD_VER) {
+ *(p++) = DTLS1_VERSION >> 8;
+ *(p++) = DTLS1_VERSION & 0xff;
+ } else {
+ *(p++) = s->version >> 8;
+ *(p++) = s->version & 0xff;
+ }
+
+ /* field where we are to write out packet epoch, seq num and len */
+ pseq = p;
+ p += 10;
+
+ /* Explicit IV length, block ciphers appropriate version flag */
+ if (s->enc_write_ctx) {
+ int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+ if (mode == EVP_CIPH_CBC_MODE) {
+ eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+ if (eivlen <= 1)
+ eivlen = 0;
+ }
+ /* Need explicit part of IV for GCM mode */
+ else if (mode == EVP_CIPH_GCM_MODE)
+ eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ else if (mode == EVP_CIPH_CCM_MODE)
+ eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
+ else
+ eivlen = 0;
+ } else
+ eivlen = 0;
+
+ /* lets setup the record stuff. */
+ SSL3_RECORD_set_data(&wr, p + eivlen); /* make room for IV in case of CBC */
+ SSL3_RECORD_set_length(&wr, (int)len);
+ SSL3_RECORD_set_input(&wr, (unsigned char *)buf);
+
+ /*
+ * we now 'read' from wr.input, wr.length bytes into wr.data
+ */
+
+ /* first we compress */
+ if (s->compress != NULL) {
+ if (!ssl3_do_compress(s, &wr)) {
+ SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_COMPRESSION_FAILURE);
+ goto err;
+ }
+ } else {
+ memcpy(SSL3_RECORD_get_data(&wr), SSL3_RECORD_get_input(&wr),
+ SSL3_RECORD_get_length(&wr));
+ SSL3_RECORD_reset_input(&wr);
+ }
+
+ /*
+ * we should still have the output to wr.data and the input from
+ * wr.input. Length should be wr.length. wr.data still points in the
+ * wb->buf
+ */
+
+ if (mac_size != 0) {
+ if (s->method->ssl3_enc->mac(s, &wr,
+ &(p[SSL3_RECORD_get_length(&wr) + eivlen]),
+ 1) < 0)
+ goto err;
+ SSL3_RECORD_add_length(&wr, mac_size);
+ }
+
+ /* this is true regardless of mac size */
+ SSL3_RECORD_set_data(&wr, p);
+ SSL3_RECORD_reset_input(&wr);
+
+ if (eivlen)
+ SSL3_RECORD_add_length(&wr, eivlen);
+
+ if (s->method->ssl3_enc->enc(s, &wr, 1, 1) < 1)
+ goto err;
+
+ /* record length after mac and block padding */
+ /*
+ * if (type == SSL3_RT_APPLICATION_DATA || (type == SSL3_RT_ALERT && !
+ * SSL_in_init(s)))
+ */
+
+ /* there's only one epoch between handshake and app data */
+
+ s2n(s->rlayer.d->w_epoch, pseq);
+
+ /* XDTLS: ?? */
+ /*
+ * else s2n(s->d1->handshake_epoch, pseq);
+ */
+
+ memcpy(pseq, &(s->rlayer.write_sequence[2]), 6);
+ pseq += 6;
+ s2n(SSL3_RECORD_get_length(&wr), pseq);
+
+ if (s->msg_callback)
+ s->msg_callback(1, 0, SSL3_RT_HEADER, pseq - DTLS1_RT_HEADER_LENGTH,
+ DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
+
+ /*
+ * we should now have wr.data pointing to the encrypted data, which is
+ * wr->length long
+ */
+ SSL3_RECORD_set_type(&wr, type); /* not needed but helps for debugging */
+ SSL3_RECORD_add_length(&wr, DTLS1_RT_HEADER_LENGTH);
+
+ ssl3_record_sequence_update(&(s->rlayer.write_sequence[0]));
+
+ if (create_empty_fragment) {
+ /*
+ * we are in a recursive call; just return the length, don't write
+ * out anything here
+ */
+ return wr.length;
+ }
+
+ /* now let's set up wb */
+ SSL3_BUFFER_set_left(wb, prefix_len + SSL3_RECORD_get_length(&wr));
+ SSL3_BUFFER_set_offset(wb, 0);
+
+ /*
+ * memorize arguments so that ssl3_write_pending can detect bad write
+ * retries later
+ */
+ s->rlayer.wpend_tot = len;
+ s->rlayer.wpend_buf = buf;
+ s->rlayer.wpend_type = type;
+ s->rlayer.wpend_ret = len;
+
+ /* we now just need to write the buffer */
+ return ssl3_write_pending(s, type, buf, len);
+ err:
+ return -1;
+}
+
+DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
+ unsigned int *is_next_epoch)
+{
+
+ *is_next_epoch = 0;
+
+ /* In current epoch, accept HM, CCS, DATA, & ALERT */
+ if (rr->epoch == s->rlayer.d->r_epoch)
+ return &s->rlayer.d->bitmap;
+
+ /*
+ * 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->rlayer.d->r_epoch + 1) &&
+ s->rlayer.d->unprocessed_rcds.epoch != s->rlayer.d->r_epoch &&
+ (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) {
+ *is_next_epoch = 1;
+ return &s->rlayer.d->next_bitmap;
+ }
+
+ return NULL;
+}
+
+void dtls1_reset_seq_numbers(SSL *s, int rw)
+{
+ unsigned char *seq;
+ unsigned int seq_bytes = sizeof(s->rlayer.read_sequence);
+
+ if (rw & SSL3_CC_READ) {
+ seq = s->rlayer.read_sequence;
+ s->rlayer.d->r_epoch++;
+ memcpy(&s->rlayer.d->bitmap, &s->rlayer.d->next_bitmap,
+ sizeof(s->rlayer.d->bitmap));
+ memset(&s->rlayer.d->next_bitmap, 0, sizeof(s->rlayer.d->next_bitmap));
+
+ /*
+ * We must not use any buffered messages received from the previous
+ * epoch
+ */
+ dtls1_clear_received_buffer(s);
+ } else {
+ seq = s->rlayer.write_sequence;
+ memcpy(s->rlayer.d->last_write_sequence, seq,
+ sizeof(s->rlayer.write_sequence));
+ s->rlayer.d->w_epoch++;
+ }
+
+ memset(seq, 0, seq_bytes);
+}
diff --git a/openssl-1.1.0h/ssl/record/rec_layer_s3.c b/openssl-1.1.0h/ssl/record/rec_layer_s3.c
new file mode 100644
index 0000000..1ffc120
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/rec_layer_s3.c
@@ -0,0 +1,1549 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#define USE_SOCKETS
+#include "../ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/buffer.h>
+#include <openssl/rand.h>
+#include "record_locl.h"
+
+#if defined(OPENSSL_SMALL_FOOTPRINT) || \
+ !( defined(AES_ASM) && ( \
+ defined(__x86_64) || defined(__x86_64__) || \
+ defined(_M_AMD64) || defined(_M_X64) ) \
+ )
+# undef EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+# define EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK 0
+#endif
+
+void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s)
+{
+ rl->s = s;
+ RECORD_LAYER_set_first_record(&s->rlayer);
+ SSL3_RECORD_clear(rl->rrec, SSL_MAX_PIPELINES);
+}
+
+void RECORD_LAYER_clear(RECORD_LAYER *rl)
+{
+ rl->rstate = SSL_ST_READ_HEADER;
+
+ /*
+ * Do I need to clear read_ahead? As far as I can tell read_ahead did not
+ * previously get reset by SSL_clear...so I'll keep it that way..but is
+ * that right?
+ */
+
+ rl->packet = NULL;
+ rl->packet_length = 0;
+ rl->wnum = 0;
+ memset(rl->alert_fragment, 0, sizeof(rl->alert_fragment));
+ rl->alert_fragment_len = 0;
+ memset(rl->handshake_fragment, 0, sizeof(rl->handshake_fragment));
+ rl->handshake_fragment_len = 0;
+ rl->wpend_tot = 0;
+ rl->wpend_type = 0;
+ rl->wpend_ret = 0;
+ rl->wpend_buf = NULL;
+
+ SSL3_BUFFER_clear(&rl->rbuf);
+ ssl3_release_write_buffer(rl->s);
+ rl->numrpipes = 0;
+ SSL3_RECORD_clear(rl->rrec, SSL_MAX_PIPELINES);
+
+ RECORD_LAYER_reset_read_sequence(rl);
+ RECORD_LAYER_reset_write_sequence(rl);
+
+ if (rl->d)
+ DTLS_RECORD_LAYER_clear(rl);
+}
+
+void RECORD_LAYER_release(RECORD_LAYER *rl)
+{
+ if (SSL3_BUFFER_is_initialised(&rl->rbuf))
+ ssl3_release_read_buffer(rl->s);
+ if (rl->numwpipes > 0)
+ ssl3_release_write_buffer(rl->s);
+ SSL3_RECORD_release(rl->rrec, SSL_MAX_PIPELINES);
+}
+
+/* Checks if we have unprocessed read ahead data pending */
+int RECORD_LAYER_read_pending(const RECORD_LAYER *rl)
+{
+ return SSL3_BUFFER_get_left(&rl->rbuf) != 0;
+}
+
+/* Checks if we have decrypted unread record data pending */
+int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl)
+{
+ size_t curr_rec = 0, num_recs = RECORD_LAYER_get_numrpipes(rl);
+ const SSL3_RECORD *rr = rl->rrec;
+
+ while (curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]))
+ curr_rec++;
+
+ return curr_rec < num_recs;
+}
+
+int RECORD_LAYER_write_pending(const RECORD_LAYER *rl)
+{
+ return (rl->numwpipes > 0)
+ && SSL3_BUFFER_get_left(&rl->wbuf[rl->numwpipes - 1]) != 0;
+}
+
+int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len)
+{
+ rl->packet_length = len;
+ if (len != 0) {
+ rl->rstate = SSL_ST_READ_HEADER;
+ if (!SSL3_BUFFER_is_initialised(&rl->rbuf))
+ if (!ssl3_setup_read_buffer(rl->s))
+ return 0;
+ }
+
+ rl->packet = SSL3_BUFFER_get_buf(&rl->rbuf);
+ SSL3_BUFFER_set_data(&rl->rbuf, buf, len);
+
+ return 1;
+}
+
+void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl)
+{
+ memset(rl->read_sequence, 0, sizeof(rl->read_sequence));
+}
+
+void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl)
+{
+ memset(rl->write_sequence, 0, sizeof(rl->write_sequence));
+}
+
+int ssl3_pending(const SSL *s)
+{
+ unsigned int i;
+ int num = 0;
+
+ if (s->rlayer.rstate == SSL_ST_READ_BODY)
+ return 0;
+
+ for (i = 0; i < RECORD_LAYER_get_numrpipes(&s->rlayer); i++) {
+ if (SSL3_RECORD_get_type(&s->rlayer.rrec[i])
+ != SSL3_RT_APPLICATION_DATA)
+ return 0;
+ num += SSL3_RECORD_get_length(&s->rlayer.rrec[i]);
+ }
+
+ return num;
+}
+
+void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len)
+{
+ ctx->default_read_buf_len = len;
+}
+
+void SSL_set_default_read_buffer_len(SSL *s, size_t len)
+{
+ SSL3_BUFFER_set_default_len(RECORD_LAYER_get_rbuf(&s->rlayer), len);
+}
+
+const char *SSL_rstate_string_long(const SSL *s)
+{
+ switch (s->rlayer.rstate) {
+ case SSL_ST_READ_HEADER:
+ return "read header";
+ case SSL_ST_READ_BODY:
+ return "read body";
+ case SSL_ST_READ_DONE:
+ return "read done";
+ default:
+ return "unknown";
+ }
+}
+
+const char *SSL_rstate_string(const SSL *s)
+{
+ switch (s->rlayer.rstate) {
+ case SSL_ST_READ_HEADER:
+ return "RH";
+ case SSL_ST_READ_BODY:
+ return "RB";
+ case SSL_ST_READ_DONE:
+ return "RD";
+ default:
+ return "unknown";
+ }
+}
+
+/*
+ * Return values are as per SSL_read()
+ */
+int ssl3_read_n(SSL *s, int n, int max, int extend, int clearold)
+{
+ /*
+ * If extend == 0, obtain new n-byte packet; if extend == 1, increase
+ * packet by another n bytes. The packet will be in the sub-array of
+ * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If
+ * s->rlayer.read_ahead is set, 'max' bytes may be stored in rbuf [plus
+ * s->packet_length bytes if extend == 1].)
+ * if clearold == 1, move the packet to the start of the buffer; if
+ * clearold == 0 then leave any old packets where they were
+ */
+ int i, len, left;
+ size_t align = 0;
+ unsigned char *pkt;
+ SSL3_BUFFER *rb;
+
+ if (n <= 0)
+ return n;
+
+ rb = &s->rlayer.rbuf;
+ if (rb->buf == NULL)
+ if (!ssl3_setup_read_buffer(s))
+ return -1;
+
+ left = rb->left;
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+ align = (size_t)rb->buf + SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+
+ if (!extend) {
+ /* start with empty packet ... */
+ if (left == 0)
+ rb->offset = align;
+ else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) {
+ /*
+ * check if next packet length is large enough to justify payload
+ * alignment...
+ */
+ pkt = rb->buf + rb->offset;
+ if (pkt[0] == SSL3_RT_APPLICATION_DATA
+ && (pkt[3] << 8 | pkt[4]) >= 128) {
+ /*
+ * Note that even if packet is corrupted and its length field
+ * is insane, we can only be led to wrong decision about
+ * whether memmove will occur or not. Header values has no
+ * effect on memmove arguments and therefore no buffer
+ * overrun can be triggered.
+ */
+ memmove(rb->buf + align, pkt, left);
+ rb->offset = align;
+ }
+ }
+ s->rlayer.packet = rb->buf + rb->offset;
+ s->rlayer.packet_length = 0;
+ /* ... now we can act as if 'extend' was set */
+ }
+
+ len = s->rlayer.packet_length;
+ pkt = rb->buf + align;
+ /*
+ * Move any available bytes to front of buffer: 'len' bytes already
+ * pointed to by 'packet', 'left' extra ones at the end
+ */
+ if (s->rlayer.packet != pkt && clearold == 1) {
+ memmove(pkt, s->rlayer.packet, len + left);
+ s->rlayer.packet = pkt;
+ rb->offset = len + align;
+ }
+
+ /*
+ * For DTLS/UDP reads should not span multiple packets because the read
+ * operation returns the whole packet at once (as long as it fits into
+ * the buffer).
+ */
+ if (SSL_IS_DTLS(s)) {
+ if (left == 0 && extend)
+ return 0;
+ if (left > 0 && n > left)
+ n = left;
+ }
+
+ /* if there is enough in the buffer from a previous read, take some */
+ if (left >= n) {
+ s->rlayer.packet_length += n;
+ rb->left = left - n;
+ rb->offset += n;
+ return (n);
+ }
+
+ /* else we need to read more data */
+
+ if (n > (int)(rb->len - rb->offset)) { /* does not happen */
+ SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ /* We always act like read_ahead is set for DTLS */
+ if (!s->rlayer.read_ahead && !SSL_IS_DTLS(s))
+ /* ignore max parameter */
+ max = n;
+ else {
+ if (max < n)
+ max = n;
+ if (max > (int)(rb->len - rb->offset))
+ max = rb->len - rb->offset;
+ }
+
+ while (left < n) {
+ /*
+ * Now we have len+left bytes at the front of s->s3->rbuf.buf and
+ * need to read in more until we have len+n (up to len+max if
+ * possible)
+ */
+
+ clear_sys_error();
+ if (s->rbio != NULL) {
+ s->rwstate = SSL_READING;
+ i = BIO_read(s->rbio, pkt + len + left, max - left);
+ } else {
+ SSLerr(SSL_F_SSL3_READ_N, SSL_R_READ_BIO_NOT_SET);
+ i = -1;
+ }
+
+ if (i <= 0) {
+ rb->left = left;
+ if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
+ if (len + left == 0)
+ ssl3_release_read_buffer(s);
+ return i;
+ }
+ left += i;
+ /*
+ * reads should *never* span multiple packets for DTLS because the
+ * underlying transport protocol is message oriented as opposed to
+ * byte oriented as in the TLS case.
+ */
+ if (SSL_IS_DTLS(s)) {
+ if (n > left)
+ n = left; /* makes the while condition false */
+ }
+ }
+
+ /* done reading, now the book-keeping */
+ rb->offset += n;
+ rb->left = left - n;
+ s->rlayer.packet_length += n;
+ s->rwstate = SSL_NOTHING;
+ return (n);
+}
+
+/*
+ * Call this to write data in records of type 'type' It will return <= 0 if
+ * not all data has been sent or non-blocking IO.
+ */
+int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
+{
+ const unsigned char *buf = buf_;
+ int tot;
+ unsigned int n, split_send_fragment, maxpipes;
+#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+ unsigned int max_send_fragment, nw;
+ unsigned int u_len = (unsigned int)len;
+#endif
+ SSL3_BUFFER *wb = &s->rlayer.wbuf[0];
+ int i;
+
+ if (len < 0) {
+ SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_NEGATIVE_LENGTH);
+ return -1;
+ }
+
+ s->rwstate = SSL_NOTHING;
+ tot = s->rlayer.wnum;
+ /*
+ * ensure that if we end up with a smaller value of data to write out
+ * than the the original len from a write which didn't complete for
+ * non-blocking I/O and also somehow ended up avoiding the check for
+ * this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be
+ * possible to end up with (len-tot) as a large number that will then
+ * promptly send beyond the end of the users buffer ... so we trap and
+ * report the error in a way the user will notice
+ */
+ if (((unsigned int)len < s->rlayer.wnum)
+ || ((wb->left != 0) && ((unsigned int)len < (s->rlayer.wnum + s->rlayer.wpend_tot)))) {
+ SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH);
+ return -1;
+ }
+
+ s->rlayer.wnum = 0;
+
+ if (SSL_in_init(s) && !ossl_statem_get_in_handshake(s)) {
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return -1;
+ }
+ }
+
+ /*
+ * first check if there is a SSL3_BUFFER still being written out. This
+ * will happen with non blocking IO
+ */
+ if (wb->left != 0) {
+ i = ssl3_write_pending(s, type, &buf[tot], s->rlayer.wpend_tot);
+ if (i <= 0) {
+ /* XXX should we ssl3_release_write_buffer if i<0? */
+ s->rlayer.wnum = tot;
+ return i;
+ }
+ tot += i; /* this might be last fragment */
+ }
+#if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK
+ /*
+ * Depending on platform multi-block can deliver several *times*
+ * better performance. Downside is that it has to allocate
+ * jumbo buffer to accommodate up to 8 records, but the
+ * compromise is considered worthy.
+ */
+ if (type == SSL3_RT_APPLICATION_DATA &&
+ u_len >= 4 * (max_send_fragment = s->max_send_fragment) &&
+ s->compress == NULL && s->msg_callback == NULL &&
+ !SSL_WRITE_ETM(s) && SSL_USE_EXPLICIT_IV(s) &&
+ EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx)) &
+ EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) {
+ unsigned char aad[13];
+ EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
+ int packlen;
+
+ /* minimize address aliasing conflicts */
+ if ((max_send_fragment & 0xfff) == 0)
+ max_send_fragment -= 512;
+
+ if (tot == 0 || wb->buf == NULL) { /* allocate jumbo buffer */
+ ssl3_release_write_buffer(s);
+
+ packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+ EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE,
+ max_send_fragment, NULL);
+
+ if (u_len >= 8 * max_send_fragment)
+ packlen *= 8;
+ else
+ packlen *= 4;
+
+ if (!ssl3_setup_write_buffer(s, 1, packlen)) {
+ SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_MALLOC_FAILURE);
+ return -1;
+ }
+ } else if (tot == len) { /* done? */
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
+ return tot;
+ }
+
+ n = (len - tot);
+ for (;;) {
+ if (n < 4 * max_send_fragment) {
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
+ break;
+ }
+
+ if (s->s3->alert_dispatch) {
+ i = s->method->ssl_dispatch_alert(s);
+ if (i <= 0) {
+ s->rlayer.wnum = tot;
+ return i;
+ }
+ }
+
+ if (n >= 8 * max_send_fragment)
+ nw = max_send_fragment * (mb_param.interleave = 8);
+ else
+ nw = max_send_fragment * (mb_param.interleave = 4);
+
+ memcpy(aad, s->rlayer.write_sequence, 8);
+ aad[8] = type;
+ aad[9] = (unsigned char)(s->version >> 8);
+ aad[10] = (unsigned char)(s->version);
+ aad[11] = 0;
+ aad[12] = 0;
+ mb_param.out = NULL;
+ mb_param.inp = aad;
+ mb_param.len = nw;
+
+ packlen = EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+ EVP_CTRL_TLS1_1_MULTIBLOCK_AAD,
+ sizeof(mb_param), &mb_param);
+
+ if (packlen <= 0 || packlen > (int)wb->len) { /* never happens */
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
+ break;
+ }
+
+ mb_param.out = wb->buf;
+ mb_param.inp = &buf[tot];
+ mb_param.len = nw;
+
+ if (EVP_CIPHER_CTX_ctrl(s->enc_write_ctx,
+ EVP_CTRL_TLS1_1_MULTIBLOCK_ENCRYPT,
+ sizeof(mb_param), &mb_param) <= 0)
+ return -1;
+
+ s->rlayer.write_sequence[7] += mb_param.interleave;
+ if (s->rlayer.write_sequence[7] < mb_param.interleave) {
+ int j = 6;
+ while (j >= 0 && (++s->rlayer.write_sequence[j--]) == 0) ;
+ }
+
+ wb->offset = 0;
+ wb->left = packlen;
+
+ s->rlayer.wpend_tot = nw;
+ s->rlayer.wpend_buf = &buf[tot];
+ s->rlayer.wpend_type = type;
+ s->rlayer.wpend_ret = nw;
+
+ i = ssl3_write_pending(s, type, &buf[tot], nw);
+ if (i <= 0) {
+ if (i < 0 && (!s->wbio || !BIO_should_retry(s->wbio))) {
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
+ }
+ s->rlayer.wnum = tot;
+ return i;
+ }
+ if (i == (int)n) {
+ /* free jumbo buffer */
+ ssl3_release_write_buffer(s);
+ return tot + i;
+ }
+ n -= i;
+ tot += i;
+ }
+ } else
+#endif
+ if (tot == len) { /* done? */
+ if (s->mode & SSL_MODE_RELEASE_BUFFERS && !SSL_IS_DTLS(s))
+ ssl3_release_write_buffer(s);
+
+ return tot;
+ }
+
+ n = (len - tot);
+
+ split_send_fragment = s->split_send_fragment;
+ /*
+ * If max_pipelines is 0 then this means "undefined" and we default to
+ * 1 pipeline. Similarly if the cipher does not support pipelined
+ * processing then we also only use 1 pipeline, or if we're not using
+ * explicit IVs
+ */
+ maxpipes = s->max_pipelines;
+ if (maxpipes > SSL_MAX_PIPELINES) {
+ /*
+ * We should have prevented this when we set max_pipelines so we
+ * shouldn't get here
+ */
+ SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ if (maxpipes == 0
+ || s->enc_write_ctx == NULL
+ || !(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_write_ctx))
+ & EVP_CIPH_FLAG_PIPELINE)
+ || !SSL_USE_EXPLICIT_IV(s))
+ maxpipes = 1;
+ if (s->max_send_fragment == 0 || split_send_fragment > s->max_send_fragment
+ || split_send_fragment == 0) {
+ /*
+ * We should have prevented this when we set the split and max send
+ * fragments so we shouldn't get here
+ */
+ SSLerr(SSL_F_SSL3_WRITE_BYTES, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ for (;;) {
+ unsigned int pipelens[SSL_MAX_PIPELINES], tmppipelen, remain;
+ unsigned int numpipes, j;
+
+ if (n == 0)
+ numpipes = 1;
+ else
+ numpipes = ((n - 1) / split_send_fragment) + 1;
+ if (numpipes > maxpipes)
+ numpipes = maxpipes;
+
+ if (n / numpipes >= s->max_send_fragment) {
+ /*
+ * We have enough data to completely fill all available
+ * pipelines
+ */
+ for (j = 0; j < numpipes; j++) {
+ pipelens[j] = s->max_send_fragment;
+ }
+ } else {
+ /* We can partially fill all available pipelines */
+ tmppipelen = n / numpipes;
+ remain = n % numpipes;
+ for (j = 0; j < numpipes; j++) {
+ pipelens[j] = tmppipelen;
+ if (j < remain)
+ pipelens[j]++;
+ }
+ }
+
+ i = do_ssl3_write(s, type, &(buf[tot]), pipelens, numpipes, 0);
+ if (i <= 0) {
+ /* XXX should we ssl3_release_write_buffer if i<0? */
+ s->rlayer.wnum = tot;
+ return i;
+ }
+
+ if ((i == (int)n) ||
+ (type == SSL3_RT_APPLICATION_DATA &&
+ (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) {
+ /*
+ * next chunk of data should get another prepended empty fragment
+ * in ciphersuites with known-IV weakness:
+ */
+ s->s3->empty_fragment_done = 0;
+
+ if ((i == (int)n) && s->mode & SSL_MODE_RELEASE_BUFFERS &&
+ !SSL_IS_DTLS(s))
+ ssl3_release_write_buffer(s);
+
+ return tot + i;
+ }
+
+ n -= i;
+ tot += i;
+ }
+}
+
+int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ unsigned int *pipelens, unsigned int numpipes,
+ int create_empty_fragment)
+{
+ unsigned char *outbuf[SSL_MAX_PIPELINES], *plen[SSL_MAX_PIPELINES];
+ SSL3_RECORD wr[SSL_MAX_PIPELINES];
+ int i, mac_size, clear = 0;
+ int prefix_len = 0;
+ int eivlen;
+ size_t align = 0;
+ SSL3_BUFFER *wb;
+ SSL_SESSION *sess;
+ unsigned int totlen = 0;
+ unsigned int j;
+
+ for (j = 0; j < numpipes; j++)
+ totlen += pipelens[j];
+ /*
+ * first check if there is a SSL3_BUFFER still being written out. This
+ * will happen with non blocking IO
+ */
+ if (RECORD_LAYER_write_pending(&s->rlayer))
+ return (ssl3_write_pending(s, type, buf, totlen));
+
+ /* If we have an alert to send, lets send it */
+ if (s->s3->alert_dispatch) {
+ i = s->method->ssl_dispatch_alert(s);
+ if (i <= 0)
+ return (i);
+ /* if it went, fall through and send more stuff */
+ }
+
+ if (s->rlayer.numwpipes < numpipes)
+ if (!ssl3_setup_write_buffer(s, numpipes, 0))
+ return -1;
+
+ if (totlen == 0 && !create_empty_fragment)
+ return 0;
+
+ sess = s->session;
+
+ if ((sess == NULL) ||
+ (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) {
+ clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */
+ mac_size = 0;
+ } else {
+ mac_size = EVP_MD_CTX_size(s->write_hash);
+ if (mac_size < 0)
+ goto err;
+ }
+
+ /*
+ * 'create_empty_fragment' is true only when this function calls itself
+ */
+ if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) {
+ /*
+ * countermeasure against known-IV weakness in CBC ciphersuites (see
+ * http://www.openssl.org/~bodo/tls-cbc.txt)
+ */
+
+ if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) {
+ /*
+ * recursive function call with 'create_empty_fragment' set; this
+ * prepares and buffers the data for an empty fragment (these
+ * 'prefix_len' bytes are sent out later together with the actual
+ * payload)
+ */
+ unsigned int tmppipelen = 0;
+
+ prefix_len = do_ssl3_write(s, type, buf, &tmppipelen, 1, 1);
+ if (prefix_len <= 0)
+ goto err;
+
+ if (prefix_len >
+ (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) {
+ /* insufficient space */
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ }
+
+ s->s3->empty_fragment_done = 1;
+ }
+
+ if (create_empty_fragment) {
+ wb = &s->rlayer.wbuf[0];
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+ /*
+ * extra fragment would be couple of cipher blocks, which would be
+ * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real
+ * payload, then we can just pretend we simply have two headers.
+ */
+ align = (size_t)SSL3_BUFFER_get_buf(wb) + 2 * SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+ outbuf[0] = SSL3_BUFFER_get_buf(wb) + align;
+ SSL3_BUFFER_set_offset(wb, align);
+ } else if (prefix_len) {
+ wb = &s->rlayer.wbuf[0];
+ outbuf[0] = SSL3_BUFFER_get_buf(wb) + SSL3_BUFFER_get_offset(wb)
+ + prefix_len;
+ } else {
+ for (j = 0; j < numpipes; j++) {
+ wb = &s->rlayer.wbuf[j];
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+ align = (size_t)SSL3_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH;
+ align = SSL3_ALIGN_PAYLOAD - 1 - ((align - 1) % SSL3_ALIGN_PAYLOAD);
+#endif
+ outbuf[j] = SSL3_BUFFER_get_buf(wb) + align;
+ SSL3_BUFFER_set_offset(wb, align);
+ }
+ }
+
+ /* Explicit IV length, block ciphers appropriate version flag */
+ if (s->enc_write_ctx && SSL_USE_EXPLICIT_IV(s)) {
+ int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx);
+ if (mode == EVP_CIPH_CBC_MODE) {
+ eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx);
+ if (eivlen <= 1)
+ eivlen = 0;
+ }
+ /* Need explicit part of IV for GCM mode */
+ else if (mode == EVP_CIPH_GCM_MODE)
+ eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ else if (mode == EVP_CIPH_CCM_MODE)
+ eivlen = EVP_CCM_TLS_EXPLICIT_IV_LEN;
+ else
+ eivlen = 0;
+ } else
+ eivlen = 0;
+
+ totlen = 0;
+ /* Clear our SSL3_RECORD structures */
+ memset(wr, 0, sizeof(wr));
+ for (j = 0; j < numpipes; j++) {
+ /* write the header */
+ *(outbuf[j]++) = type & 0xff;
+ SSL3_RECORD_set_type(&wr[j], type);
+
+ *(outbuf[j]++) = (s->version >> 8);
+ /*
+ * Some servers hang if initial client hello is larger than 256 bytes
+ * and record version number > TLS 1.0
+ */
+ if (SSL_get_state(s) == TLS_ST_CW_CLNT_HELLO
+ && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION)
+ *(outbuf[j]++) = 0x1;
+ else
+ *(outbuf[j]++) = s->version & 0xff;
+
+ /* field where we are to write out packet length */
+ plen[j] = outbuf[j];
+ outbuf[j] += 2;
+
+ /* lets setup the record stuff. */
+ SSL3_RECORD_set_data(&wr[j], outbuf[j] + eivlen);
+ SSL3_RECORD_set_length(&wr[j], (int)pipelens[j]);
+ SSL3_RECORD_set_input(&wr[j], (unsigned char *)&buf[totlen]);
+ totlen += pipelens[j];
+
+ /*
+ * we now 'read' from wr->input, wr->length bytes into wr->data
+ */
+
+ /* first we compress */
+ if (s->compress != NULL) {
+ if (!ssl3_do_compress(s, &wr[j])) {
+ SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE);
+ goto err;
+ }
+ } else {
+ memcpy(wr[j].data, wr[j].input, wr[j].length);
+ SSL3_RECORD_reset_input(&wr[j]);
+ }
+
+ /*
+ * we should still have the output to wr->data and the input from
+ * wr->input. Length should be wr->length. wr->data still points in the
+ * wb->buf
+ */
+
+ if (!SSL_WRITE_ETM(s) && mac_size != 0) {
+ if (s->method->ssl3_enc->mac(s, &wr[j],
+ &(outbuf[j][wr[j].length + eivlen]),
+ 1) < 0)
+ goto err;
+ SSL3_RECORD_add_length(&wr[j], mac_size);
+ }
+
+ SSL3_RECORD_set_data(&wr[j], outbuf[j]);
+ SSL3_RECORD_reset_input(&wr[j]);
+
+ if (eivlen) {
+ /*
+ * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err;
+ */
+ SSL3_RECORD_add_length(&wr[j], eivlen);
+ }
+ }
+
+ if (s->method->ssl3_enc->enc(s, wr, numpipes, 1) < 1)
+ goto err;
+
+ for (j = 0; j < numpipes; j++) {
+ if (SSL_WRITE_ETM(s) && mac_size != 0) {
+ if (s->method->ssl3_enc->mac(s, &wr[j],
+ outbuf[j] + wr[j].length, 1) < 0)
+ goto err;
+ SSL3_RECORD_add_length(&wr[j], mac_size);
+ }
+
+ /* record length after mac and block padding */
+ s2n(SSL3_RECORD_get_length(&wr[j]), plen[j]);
+
+ if (s->msg_callback)
+ s->msg_callback(1, 0, SSL3_RT_HEADER, plen[j] - 5, 5, s,
+ s->msg_callback_arg);
+
+ /*
+ * we should now have wr->data pointing to the encrypted data, which is
+ * wr->length long
+ */
+ SSL3_RECORD_set_type(&wr[j], type); /* not needed but helps for
+ * debugging */
+ SSL3_RECORD_add_length(&wr[j], SSL3_RT_HEADER_LENGTH);
+
+ if (create_empty_fragment) {
+ /*
+ * we are in a recursive call; just return the length, don't write
+ * out anything here
+ */
+ if (j > 0) {
+ /* We should never be pipelining an empty fragment!! */
+ SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ return SSL3_RECORD_get_length(wr);
+ }
+
+ /* now let's set up wb */
+ SSL3_BUFFER_set_left(&s->rlayer.wbuf[j],
+ prefix_len + SSL3_RECORD_get_length(&wr[j]));
+ }
+
+ /*
+ * memorize arguments so that ssl3_write_pending can detect bad write
+ * retries later
+ */
+ s->rlayer.wpend_tot = totlen;
+ s->rlayer.wpend_buf = buf;
+ s->rlayer.wpend_type = type;
+ s->rlayer.wpend_ret = totlen;
+
+ /* we now just need to write the buffer */
+ return ssl3_write_pending(s, type, buf, totlen);
+ err:
+ return -1;
+}
+
+/* if s->s3->wbuf.left != 0, we need to call this
+ *
+ * Return values are as per SSL_write()
+ */
+int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
+ unsigned int len)
+{
+ int i;
+ SSL3_BUFFER *wb = s->rlayer.wbuf;
+ unsigned int currbuf = 0;
+
+ if ((s->rlayer.wpend_tot > (int)len)
+ || (!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)
+ && (s->rlayer.wpend_buf != buf))
+ || (s->rlayer.wpend_type != type)) {
+ SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY);
+ return (-1);
+ }
+
+ for (;;) {
+ /* Loop until we find a buffer we haven't written out yet */
+ if (SSL3_BUFFER_get_left(&wb[currbuf]) == 0
+ && currbuf < s->rlayer.numwpipes - 1) {
+ currbuf++;
+ continue;
+ }
+ clear_sys_error();
+ if (s->wbio != NULL) {
+ s->rwstate = SSL_WRITING;
+ i = BIO_write(s->wbio, (char *)
+ &(SSL3_BUFFER_get_buf(&wb[currbuf])
+ [SSL3_BUFFER_get_offset(&wb[currbuf])]),
+ (unsigned int)SSL3_BUFFER_get_left(&wb[currbuf]));
+ } else {
+ SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET);
+ i = -1;
+ }
+ if (i == SSL3_BUFFER_get_left(&wb[currbuf])) {
+ SSL3_BUFFER_set_left(&wb[currbuf], 0);
+ SSL3_BUFFER_add_offset(&wb[currbuf], i);
+ if (currbuf + 1 < s->rlayer.numwpipes)
+ continue;
+ s->rwstate = SSL_NOTHING;
+ return (s->rlayer.wpend_ret);
+ } else if (i <= 0) {
+ if (SSL_IS_DTLS(s)) {
+ /*
+ * For DTLS, just drop it. That's kind of the whole point in
+ * using a datagram service
+ */
+ SSL3_BUFFER_set_left(&wb[currbuf], 0);
+ }
+ return i;
+ }
+ SSL3_BUFFER_add_offset(&wb[currbuf], i);
+ SSL3_BUFFER_add_left(&wb[currbuf], -i);
+ }
+}
+
+/*-
+ * Return up to 'len' payload bytes received in 'type' records.
+ * 'type' is one of the following:
+ *
+ * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
+ * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
+ * - 0 (during a shutdown, no data has to be returned)
+ *
+ * If we don't have stored data to work from, read a SSL/TLS record first
+ * (possibly multiple records if we still don't have anything to return).
+ *
+ * This function must handle any surprises the peer may have for us, such as
+ * Alert records (e.g. close_notify) or renegotiation requests. ChangeCipherSpec
+ * messages are treated as if they were handshake messages *if* the |recd_type|
+ * argument is non NULL.
+ * Also if record payloads contain fragments too small to process, we store
+ * them until there is enough for the respective protocol (the record protocol
+ * may use arbitrary fragmentation and even interleaving):
+ * Change cipher spec protocol
+ * just 1 byte needed, no need for keeping anything stored
+ * Alert protocol
+ * 2 bytes needed (AlertLevel, AlertDescription)
+ * Handshake protocol
+ * 4 bytes needed (HandshakeType, uint24 length) -- we just have
+ * to detect unexpected Client Hello and Hello Request messages
+ * here, anything else is handled by higher layers
+ * Application data protocol
+ * none of our business
+ */
+int ssl3_read_bytes(SSL *s, int type, int *recvd_type, unsigned char *buf,
+ int len, int peek)
+{
+ int al, i, j, ret;
+ unsigned int n, curr_rec, num_recs, read_bytes;
+ SSL3_RECORD *rr;
+ SSL3_BUFFER *rbuf;
+ void (*cb) (const SSL *ssl, int type2, int val) = NULL;
+
+ rbuf = &s->rlayer.rbuf;
+
+ if (!SSL3_BUFFER_is_initialised(rbuf)) {
+ /* Not initialized yet */
+ if (!ssl3_setup_read_buffer(s))
+ return (-1);
+ }
+
+ if ((type && (type != SSL3_RT_APPLICATION_DATA)
+ && (type != SSL3_RT_HANDSHAKE)) || (peek
+ && (type !=
+ SSL3_RT_APPLICATION_DATA))) {
+ SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ if ((type == SSL3_RT_HANDSHAKE) && (s->rlayer.handshake_fragment_len > 0))
+ /* (partially) satisfy request from storage */
+ {
+ unsigned char *src = s->rlayer.handshake_fragment;
+ unsigned char *dst = buf;
+ unsigned int k;
+
+ /* peek == 0 */
+ n = 0;
+ while ((len > 0) && (s->rlayer.handshake_fragment_len > 0)) {
+ *dst++ = *src++;
+ len--;
+ s->rlayer.handshake_fragment_len--;
+ n++;
+ }
+ /* move any remaining fragment bytes: */
+ for (k = 0; k < s->rlayer.handshake_fragment_len; k++)
+ s->rlayer.handshake_fragment[k] = *src++;
+
+ if (recvd_type != NULL)
+ *recvd_type = SSL3_RT_HANDSHAKE;
+
+ return n;
+ }
+
+ /*
+ * Now s->rlayer.handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE.
+ */
+
+ if (!ossl_statem_get_in_handshake(s) && SSL_in_init(s)) {
+ /* type == SSL3_RT_APPLICATION_DATA */
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return (-1);
+ }
+ }
+ start:
+ s->rwstate = SSL_NOTHING;
+
+ /*-
+ * For each record 'i' up to |num_recs]
+ * rr[i].type - is the type of record
+ * rr[i].data, - data
+ * rr[i].off, - offset into 'data' for next read
+ * rr[i].length, - number of bytes.
+ */
+ rr = s->rlayer.rrec;
+ num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer);
+
+ do {
+ /* get new records if necessary */
+ if (num_recs == 0) {
+ ret = ssl3_get_record(s);
+ if (ret <= 0)
+ return (ret);
+ num_recs = RECORD_LAYER_get_numrpipes(&s->rlayer);
+ if (num_recs == 0) {
+ /* Shouldn't happen */
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ }
+ /* Skip over any records we have already read */
+ for (curr_rec = 0;
+ curr_rec < num_recs && SSL3_RECORD_is_read(&rr[curr_rec]);
+ curr_rec++) ;
+ if (curr_rec == num_recs) {
+ RECORD_LAYER_set_numrpipes(&s->rlayer, 0);
+ num_recs = 0;
+ curr_rec = 0;
+ }
+ } while (num_recs == 0);
+ rr = &rr[curr_rec];
+
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (SSL3_RECORD_get_type(rr) != SSL3_RT_ALERT
+ && SSL3_RECORD_get_length(rr) != 0)
+ s->rlayer.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,
+ * reset by ssl3_get_finished */
+ && (SSL3_RECORD_get_type(rr) != SSL3_RT_HANDSHAKE)) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
+ goto f_err;
+ }
+
+ /*
+ * If the other end has shut down, throw anything we read away (even in
+ * 'peek' mode)
+ */
+ if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ SSL3_RECORD_set_length(rr, 0);
+ s->rwstate = SSL_NOTHING;
+ return (0);
+ }
+
+ if (type == SSL3_RECORD_get_type(rr)
+ || (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+ && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) {
+ /*
+ * SSL3_RT_APPLICATION_DATA or
+ * SSL3_RT_HANDSHAKE or
+ * SSL3_RT_CHANGE_CIPHER_SPEC
+ */
+ /*
+ * make sure that we are not getting application data when we are
+ * doing a handshake for the first time
+ */
+ if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) &&
+ (s->enc_read_ctx == NULL)) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE);
+ goto f_err;
+ }
+
+ if (type == SSL3_RT_HANDSHAKE
+ && SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC
+ && s->rlayer.handshake_fragment_len > 0) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY);
+ goto f_err;
+ }
+
+ if (recvd_type != NULL)
+ *recvd_type = SSL3_RECORD_get_type(rr);
+
+ if (len <= 0) {
+ /*
+ * Mark a zero length record as read. This ensures multiple calls to
+ * SSL_read() with a zero length buffer will eventually cause
+ * SSL_pending() to report data as being available.
+ */
+ if (SSL3_RECORD_get_length(rr) == 0)
+ SSL3_RECORD_set_read(rr);
+ return len;
+ }
+
+ read_bytes = 0;
+ do {
+ if ((unsigned int)len - read_bytes > SSL3_RECORD_get_length(rr))
+ n = SSL3_RECORD_get_length(rr);
+ else
+ n = (unsigned int)len - read_bytes;
+
+ memcpy(buf, &(rr->data[rr->off]), n);
+ buf += n;
+ if (peek) {
+ /* Mark any zero length record as consumed CVE-2016-6305 */
+ if (SSL3_RECORD_get_length(rr) == 0)
+ SSL3_RECORD_set_read(rr);
+ } else {
+ SSL3_RECORD_sub_length(rr, n);
+ SSL3_RECORD_add_off(rr, n);
+ if (SSL3_RECORD_get_length(rr) == 0) {
+ s->rlayer.rstate = SSL_ST_READ_HEADER;
+ SSL3_RECORD_set_off(rr, 0);
+ SSL3_RECORD_set_read(rr);
+ }
+ }
+ if (SSL3_RECORD_get_length(rr) == 0
+ || (peek && n == SSL3_RECORD_get_length(rr))) {
+ curr_rec++;
+ rr++;
+ }
+ read_bytes += n;
+ } while (type == SSL3_RT_APPLICATION_DATA && curr_rec < num_recs
+ && read_bytes < (unsigned int)len);
+ if (read_bytes == 0) {
+ /* We must have read empty records. Get more data */
+ goto start;
+ }
+ if (!peek && curr_rec == num_recs
+ && (s->mode & SSL_MODE_RELEASE_BUFFERS)
+ && SSL3_BUFFER_get_left(rbuf) == 0)
+ ssl3_release_read_buffer(s);
+ return read_bytes;
+ }
+
+ /*
+ * If we get here, then type != rr->type; if we have a handshake message,
+ * then it was unexpected (Hello Request or Client Hello) or invalid (we
+ * were actually expecting a CCS).
+ */
+
+ /*
+ * Lets just double check that we've not got an SSLv2 record
+ */
+ if (rr->rec_version == SSL2_VERSION) {
+ /*
+ * Should never happen. ssl3_get_record() should only give us an SSLv2
+ * record back if this is the first packet and we are looking for an
+ * initial ClientHello. Therefore |type| should always be equal to
+ * |rr->type|. If not then something has gone horribly wrong
+ */
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+
+ if (s->method->version == TLS_ANY_VERSION
+ && (s->server || rr->type != SSL3_RT_ALERT)) {
+ /*
+ * If we've got this far and still haven't decided on what version
+ * we're using then this must be a client side alert we're dealing with
+ * (we don't allow heartbeats yet). We shouldn't be receiving anything
+ * other than a ClientHello if we are a server.
+ */
+ s->version = rr->rec_version;
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_MESSAGE);
+ goto f_err;
+ }
+
+ /*
+ * In case of record types for which we have 'fragment' storage, fill
+ * that so that we can process the data at a fixed place.
+ */
+ {
+ unsigned int dest_maxlen = 0;
+ unsigned char *dest = NULL;
+ unsigned int *dest_len = NULL;
+
+ if (SSL3_RECORD_get_type(rr) == SSL3_RT_HANDSHAKE) {
+ dest_maxlen = sizeof(s->rlayer.handshake_fragment);
+ dest = s->rlayer.handshake_fragment;
+ dest_len = &s->rlayer.handshake_fragment_len;
+ } else if (SSL3_RECORD_get_type(rr) == SSL3_RT_ALERT) {
+ dest_maxlen = sizeof(s->rlayer.alert_fragment);
+ dest = s->rlayer.alert_fragment;
+ dest_len = &s->rlayer.alert_fragment_len;
+ }
+
+ if (dest_maxlen > 0) {
+ n = dest_maxlen - *dest_len; /* available space in 'dest' */
+ if (SSL3_RECORD_get_length(rr) < n)
+ n = SSL3_RECORD_get_length(rr); /* available bytes */
+
+ /* now move 'n' bytes: */
+ while (n-- > 0) {
+ dest[(*dest_len)++] =
+ SSL3_RECORD_get_data(rr)[SSL3_RECORD_get_off(rr)];
+ SSL3_RECORD_add_off(rr, 1);
+ SSL3_RECORD_add_length(rr, -1);
+ }
+
+ if (*dest_len < dest_maxlen) {
+ SSL3_RECORD_set_read(rr);
+ goto start; /* fragment was too small */
+ }
+ }
+ }
+
+ /*-
+ * s->rlayer.handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE;
+ * s->rlayer.alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT.
+ * (Possibly rr is 'empty' now, i.e. rr->length may be 0.)
+ */
+
+ /* If we are a client, check for an incoming 'Hello Request': */
+ if ((!s->server) &&
+ (s->rlayer.handshake_fragment_len >= 4) &&
+ (s->rlayer.handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) &&
+ (s->session != NULL) && (s->session->cipher != NULL)) {
+ s->rlayer.handshake_fragment_len = 0;
+
+ if ((s->rlayer.handshake_fragment[1] != 0) ||
+ (s->rlayer.handshake_fragment[2] != 0) ||
+ (s->rlayer.handshake_fragment[3] != 0)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST);
+ goto f_err;
+ }
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
+ s->rlayer.handshake_fragment, 4, s,
+ s->msg_callback_arg);
+ if (SSL_is_init_finished(s) &&
+ (s->options & SSL_OP_NO_RENEGOTIATION) == 0 &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) &&
+ !s->s3->renegotiate) {
+ ssl3_renegotiate(s);
+ if (ssl3_renegotiate_check(s)) {
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return (-1);
+ }
+
+ if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+ if (SSL3_BUFFER_get_left(rbuf) == 0) {
+ /* no read-ahead left? */
+ BIO *bio;
+ /*
+ * In the case where we try to read application data,
+ * but we trigger an SSL handshake, we return -1 with
+ * the retry option set. Otherwise renegotiation may
+ * cause nasty problems in the blocking world
+ */
+ s->rwstate = SSL_READING;
+ bio = SSL_get_rbio(s);
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return (-1);
+ }
+ }
+ } else {
+ SSL3_RECORD_set_read(rr);
+ }
+ } else {
+ ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ SSL3_RECORD_set_read(rr);
+ }
+ /*
+ * we either finished a handshake or ignored the request, now try
+ * again to obtain the (application) data we were asked for
+ */
+ goto start;
+ }
+ /*
+ * If we are a server and get a client hello when renegotiation isn't
+ * allowed send back a no renegotiation alert and carry on.
+ */
+ if (s->server
+ && SSL_is_init_finished(s)
+ && s->version > SSL3_VERSION
+ && s->rlayer.handshake_fragment_len >= SSL3_HM_HEADER_LENGTH
+ && s->rlayer.handshake_fragment[0] == SSL3_MT_CLIENT_HELLO
+ && s->s3->previous_client_finished_len != 0
+ && ((!s->s3->send_connection_binding
+ && (s->options
+ & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION) == 0)
+ || (s->options & SSL_OP_NO_RENEGOTIATION) != 0)) {
+ SSL3_RECORD_set_length(rr, 0);
+ SSL3_RECORD_set_read(rr);
+ ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION);
+ goto start;
+ }
+ if (s->rlayer.alert_fragment_len >= 2) {
+ int alert_level = s->rlayer.alert_fragment[0];
+ int alert_descr = s->rlayer.alert_fragment[1];
+
+ s->rlayer.alert_fragment_len = 0;
+
+ if (s->msg_callback)
+ s->msg_callback(0, s->version, SSL3_RT_ALERT,
+ s->rlayer.alert_fragment, 2, s,
+ s->msg_callback_arg);
+
+ if (s->info_callback != NULL)
+ cb = s->info_callback;
+ else if (s->ctx->info_callback != NULL)
+ cb = s->ctx->info_callback;
+
+ if (cb != NULL) {
+ j = (alert_level << 8) | alert_descr;
+ cb(s, SSL_CB_READ_ALERT, j);
+ }
+
+ if (alert_level == SSL3_AL_WARNING) {
+ s->s3->warn_alert = alert_descr;
+ SSL3_RECORD_set_read(rr);
+
+ s->rlayer.alert_count++;
+ if (s->rlayer.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);
+ }
+ /*
+ * This is a warning but we receive it if we requested
+ * renegotiation and the peer denied it. Terminate with a fatal
+ * alert because if application tried to renegotiate it
+ * presumably had a good reason and expects it to succeed. In
+ * future we might have a renegotiation where we don't care if
+ * the peer refused it where we carry on.
+ */
+ else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION);
+ goto f_err;
+ }
+#ifdef SSL_AD_MISSING_SRP_USERNAME
+ else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME)
+ return (0);
+#endif
+ } else if (alert_level == SSL3_AL_FATAL) {
+ char tmp[16];
+
+ s->rwstate = SSL_NOTHING;
+ s->s3->fatal_alert = alert_descr;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr);
+ BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
+ ERR_add_error_data(2, "SSL alert number ", tmp);
+ s->shutdown |= SSL_RECEIVED_SHUTDOWN;
+ SSL3_RECORD_set_read(rr);
+ SSL_CTX_remove_session(s->session_ctx, s->session);
+ return (0);
+ } else {
+ al = SSL_AD_ILLEGAL_PARAMETER;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE);
+ goto f_err;
+ }
+
+ goto start;
+ }
+
+ if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a
+ * shutdown */
+ s->rwstate = SSL_NOTHING;
+ SSL3_RECORD_set_length(rr, 0);
+ SSL3_RECORD_set_read(rr);
+ return (0);
+ }
+
+ if (SSL3_RECORD_get_type(rr) == SSL3_RT_CHANGE_CIPHER_SPEC) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY);
+ goto f_err;
+ }
+
+ /*
+ * Unexpected handshake message (Client Hello, or protocol violation)
+ */
+ if ((s->rlayer.handshake_fragment_len >= 4)
+ && !ossl_statem_get_in_handshake(s)) {
+ if (SSL_is_init_finished(s) &&
+ !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) {
+ ossl_statem_set_in_init(s, 1);
+ s->renegotiate = 1;
+ s->new_session = 1;
+ }
+ i = s->handshake_func(s);
+ if (i < 0)
+ return (i);
+ if (i == 0) {
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE);
+ return (-1);
+ }
+
+ if (!(s->mode & SSL_MODE_AUTO_RETRY)) {
+ if (SSL3_BUFFER_get_left(rbuf) == 0) {
+ /* no read-ahead left? */
+ BIO *bio;
+ /*
+ * In the case where we try to read application data, but we
+ * trigger an SSL handshake, we return -1 with the retry
+ * option set. Otherwise renegotiation may cause nasty
+ * problems in the blocking world
+ */
+ s->rwstate = SSL_READING;
+ bio = SSL_get_rbio(s);
+ BIO_clear_retry_flags(bio);
+ BIO_set_retry_read(bio);
+ return (-1);
+ }
+ }
+ goto start;
+ }
+
+ switch (SSL3_RECORD_get_type(rr)) {
+ default:
+ /*
+ * 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.
+ */
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ case SSL3_RT_CHANGE_CIPHER_SPEC:
+ case SSL3_RT_ALERT:
+ case SSL3_RT_HANDSHAKE:
+ /*
+ * we already handled all of these, with the possible exception of
+ * SSL3_RT_HANDSHAKE when ossl_statem_get_in_handshake(s) is true, but
+ * that should not happen when type != rr->type
+ */
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ case SSL3_RT_APPLICATION_DATA:
+ /*
+ * At this point, we were expecting handshake data, but have
+ * application data. If the library was running inside ssl3_read()
+ * (i.e. in_read_app_data is set) and it makes sense to read
+ * application data at this point (session renegotiation not yet
+ * started), we will indulge it.
+ */
+ if (ossl_statem_app_data_allowed(s)) {
+ s->s3->in_read_app_data = 2;
+ return (-1);
+ } else {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
+ goto f_err;
+ }
+ }
+ /* not reached */
+
+ f_err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ return (-1);
+}
+
+void ssl3_record_sequence_update(unsigned char *seq)
+{
+ int i;
+
+ for (i = 7; i >= 0; i--) {
+ ++seq[i];
+ if (seq[i] != 0)
+ break;
+ }
+}
+
+/*
+ * Returns true if the current rrec was sent in SSLv2 backwards compatible
+ * format and false otherwise.
+ */
+int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl)
+{
+ return SSL3_RECORD_is_sslv2_record(&rl->rrec[0]);
+}
+
+/*
+ * Returns the length in bytes of the current rrec
+ */
+unsigned int RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl)
+{
+ return SSL3_RECORD_get_length(&rl->rrec[0]);
+}
diff --git a/openssl-1.1.0h/ssl/record/record.h b/openssl-1.1.0h/ssl/record/record.h
new file mode 100644
index 0000000..9bb2431
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/record.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*****************************************************************************
+ * *
+ * These structures should be considered PRIVATE to the record layer. No *
+ * non-record layer code should be using these structures in any way. *
+ * *
+ *****************************************************************************/
+
+typedef struct ssl3_buffer_st {
+ /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */
+ unsigned char *buf;
+ /* default buffer size (or 0 if no default set) */
+ size_t default_len;
+ /* buffer size */
+ size_t len;
+ /* where to 'copy from' */
+ int offset;
+ /* how many bytes left */
+ int left;
+} SSL3_BUFFER;
+
+#define SEQ_NUM_SIZE 8
+
+typedef struct ssl3_record_st {
+ /* Record layer version */
+ /* r */
+ int rec_version;
+ /* type of record */
+ /* r */
+ int type;
+ /* How many bytes available */
+ /* rw */
+ unsigned int length;
+ /*
+ * How many bytes were available before padding was removed? This is used
+ * to implement the MAC check in constant time for CBC records.
+ */
+ /* rw */
+ unsigned int orig_len;
+ /* read/write offset into 'buf' */
+ /* r */
+ unsigned int off;
+ /* pointer to the record data */
+ /* rw */
+ unsigned char *data;
+ /* where the decode bytes are */
+ /* rw */
+ unsigned char *input;
+ /* only used with decompression - malloc()ed */
+ /* r */
+ unsigned char *comp;
+ /* Whether the data from this record has already been read or not */
+ /* r */
+ unsigned int read;
+ /* epoch number, needed by DTLS1 */
+ /* r */
+ unsigned long epoch;
+ /* sequence number, needed by DTLS1 */
+ /* r */
+ unsigned char seq_num[SEQ_NUM_SIZE];
+} SSL3_RECORD;
+
+typedef struct dtls1_bitmap_st {
+ /* Track 32 packets on 32-bit systems and 64 - on 64-bit systems */
+ unsigned long map;
+ /* Max record number seen so far, 64-bit value in big-endian encoding */
+ unsigned char max_seq_num[SEQ_NUM_SIZE];
+} DTLS1_BITMAP;
+
+typedef struct record_pqueue_st {
+ unsigned short epoch;
+ struct pqueue_st *q;
+} record_pqueue;
+
+typedef struct dtls1_record_data_st {
+ unsigned char *packet;
+ unsigned int packet_length;
+ SSL3_BUFFER rbuf;
+ SSL3_RECORD rrec;
+#ifndef OPENSSL_NO_SCTP
+ struct bio_dgram_sctp_rcvinfo recordinfo;
+#endif
+} DTLS1_RECORD_DATA;
+
+typedef struct dtls_record_layer_st {
+ /*
+ * The current data and handshake epoch. This is initially
+ * undefined, and starts at zero once the initial handshake is
+ * completed
+ */
+ unsigned short r_epoch;
+ unsigned short w_epoch;
+ /* records being received in the current epoch */
+ DTLS1_BITMAP bitmap;
+ /* renegotiation starts a new set of sequence numbers */
+ DTLS1_BITMAP next_bitmap;
+ /* Received handshake records (processed and unprocessed) */
+ record_pqueue unprocessed_rcds;
+ record_pqueue processed_rcds;
+ /*
+ * Buffered application records. Only for records between CCS and
+ * Finished to prevent either protocol violation or unnecessary message
+ * loss.
+ */
+ record_pqueue buffered_app_data;
+ /*
+ * storage for Alert/Handshake protocol data received but not yet
+ * processed by ssl3_read_bytes:
+ */
+ unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH];
+ unsigned int alert_fragment_len;
+ unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH];
+ unsigned int handshake_fragment_len;
+ /* save last and current sequence numbers for retransmissions */
+ unsigned char last_write_sequence[8];
+ unsigned char curr_write_sequence[8];
+} DTLS_RECORD_LAYER;
+
+/*****************************************************************************
+ * *
+ * This structure should be considered "opaque" to anything outside of the *
+ * record layer. No non-record layer code should be accessing the members of *
+ * this structure. *
+ * *
+ *****************************************************************************/
+
+typedef struct record_layer_st {
+ /* The parent SSL structure */
+ SSL *s;
+ /*
+ * Read as many input bytes as possible (for
+ * non-blocking reads)
+ */
+ int read_ahead;
+ /* where we are when reading */
+ int rstate;
+ /* How many pipelines can be used to read data */
+ unsigned int numrpipes;
+ /* How many pipelines can be used to write data */
+ unsigned int numwpipes;
+ /* read IO goes into here */
+ SSL3_BUFFER rbuf;
+ /* write IO goes into here */
+ SSL3_BUFFER wbuf[SSL_MAX_PIPELINES];
+ /* each decoded record goes in here */
+ SSL3_RECORD rrec[SSL_MAX_PIPELINES];
+ /* used internally to point at a raw packet */
+ unsigned char *packet;
+ unsigned int packet_length;
+ /* number of bytes sent so far */
+ unsigned int wnum;
+ /*
+ * storage for Alert/Handshake protocol data received but not yet
+ * processed by ssl3_read_bytes:
+ */
+ unsigned char alert_fragment[2];
+ unsigned int alert_fragment_len;
+ unsigned char handshake_fragment[4];
+ unsigned int handshake_fragment_len;
+ /* The number of consecutive empty records we have received */
+ unsigned int empty_record_count;
+ /* partial write - check the numbers match */
+ /* number bytes written */
+ int wpend_tot;
+ int wpend_type;
+ /* number of bytes submitted */
+ int wpend_ret;
+ const unsigned char *wpend_buf;
+ unsigned char read_sequence[SEQ_NUM_SIZE];
+ unsigned char write_sequence[SEQ_NUM_SIZE];
+ /* Set to true if this is the first record in a connection */
+ unsigned int is_first_record;
+ /* Count of the number of consecutive warning alerts received */
+ unsigned int alert_count;
+ DTLS_RECORD_LAYER *d;
+} RECORD_LAYER;
+
+/*****************************************************************************
+ * *
+ * The following macros/functions represent the libssl internal API to the *
+ * record layer. Any libssl code may call these functions/macros *
+ * *
+ *****************************************************************************/
+
+#define MIN_SSL2_RECORD_LEN 9
+
+#define RECORD_LAYER_set_read_ahead(rl, ra) ((rl)->read_ahead = (ra))
+#define RECORD_LAYER_get_read_ahead(rl) ((rl)->read_ahead)
+#define RECORD_LAYER_get_packet(rl) ((rl)->packet)
+#define RECORD_LAYER_get_packet_length(rl) ((rl)->packet_length)
+#define RECORD_LAYER_add_packet_length(rl, inc) ((rl)->packet_length += (inc))
+#define DTLS_RECORD_LAYER_get_w_epoch(rl) ((rl)->d->w_epoch)
+#define DTLS_RECORD_LAYER_get_processed_rcds(rl) \
+ ((rl)->d->processed_rcds)
+#define DTLS_RECORD_LAYER_get_unprocessed_rcds(rl) \
+ ((rl)->d->unprocessed_rcds)
+
+void RECORD_LAYER_init(RECORD_LAYER *rl, SSL *s);
+void RECORD_LAYER_clear(RECORD_LAYER *rl);
+void RECORD_LAYER_release(RECORD_LAYER *rl);
+int RECORD_LAYER_read_pending(const RECORD_LAYER *rl);
+int RECORD_LAYER_processed_read_pending(const RECORD_LAYER *rl);
+int RECORD_LAYER_write_pending(const RECORD_LAYER *rl);
+int RECORD_LAYER_set_data(RECORD_LAYER *rl, const unsigned char *buf, int len);
+void RECORD_LAYER_reset_read_sequence(RECORD_LAYER *rl);
+void RECORD_LAYER_reset_write_sequence(RECORD_LAYER *rl);
+int RECORD_LAYER_is_sslv2_record(RECORD_LAYER *rl);
+unsigned int RECORD_LAYER_get_rrec_length(RECORD_LAYER *rl);
+__owur int ssl3_pending(const SSL *s);
+__owur int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
+__owur int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
+ unsigned int *pipelens, unsigned int numpipes,
+ int create_empty_fragment);
+__owur int ssl3_read_bytes(SSL *s, int type, int *recvd_type,
+ unsigned char *buf, int len, int peek);
+__owur int ssl3_setup_buffers(SSL *s);
+__owur int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, unsigned int n_recs, int send);
+__owur int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send);
+__owur int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
+ unsigned int len);
+__owur int tls1_enc(SSL *s, SSL3_RECORD *recs, unsigned int n_recs, int send);
+__owur int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int send);
+int DTLS_RECORD_LAYER_new(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_free(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_set_saved_w_epoch(RECORD_LAYER *rl, unsigned short e);
+void DTLS_RECORD_LAYER_clear(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_resync_write(RECORD_LAYER *rl);
+void DTLS_RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, unsigned char *seq);
+__owur int dtls1_read_bytes(SSL *s, int type, int *recvd_type,
+ unsigned char *buf, int len, int peek);
+__owur int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
+__owur int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
+ unsigned int len, int create_empty_fragement);
+void dtls1_reset_seq_numbers(SSL *s, int rw);
diff --git a/openssl-1.1.0h/ssl/record/record_locl.h b/openssl-1.1.0h/ssl/record/record_locl.h
new file mode 100644
index 0000000..b69afd8
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/record_locl.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/*****************************************************************************
+ * *
+ * The following macros/functions are PRIVATE to the record layer. They *
+ * should NOT be used outside of the record layer. *
+ * *
+ *****************************************************************************/
+
+#define MAX_WARN_ALERT_COUNT 5
+
+/* Functions/macros provided by the RECORD_LAYER component */
+
+#define RECORD_LAYER_get_rbuf(rl) (&(rl)->rbuf)
+#define RECORD_LAYER_get_wbuf(rl) ((rl)->wbuf)
+#define RECORD_LAYER_get_rrec(rl) ((rl)->rrec)
+#define RECORD_LAYER_set_packet(rl, p) ((rl)->packet = (p))
+#define RECORD_LAYER_reset_packet_length(rl) ((rl)->packet_length = 0)
+#define RECORD_LAYER_get_rstate(rl) ((rl)->rstate)
+#define RECORD_LAYER_set_rstate(rl, st) ((rl)->rstate = (st))
+#define RECORD_LAYER_get_read_sequence(rl) ((rl)->read_sequence)
+#define RECORD_LAYER_get_write_sequence(rl) ((rl)->write_sequence)
+#define RECORD_LAYER_get_numrpipes(rl) ((rl)->numrpipes)
+#define RECORD_LAYER_set_numrpipes(rl, n) ((rl)->numrpipes = (n))
+#define RECORD_LAYER_inc_empty_record_count(rl) ((rl)->empty_record_count++)
+#define RECORD_LAYER_reset_empty_record_count(rl) \
+ ((rl)->empty_record_count = 0)
+#define RECORD_LAYER_get_empty_record_count(rl) ((rl)->empty_record_count)
+#define RECORD_LAYER_is_first_record(rl) ((rl)->is_first_record)
+#define RECORD_LAYER_set_first_record(rl) ((rl)->is_first_record = 1)
+#define RECORD_LAYER_clear_first_record(rl) ((rl)->is_first_record = 0)
+#define DTLS_RECORD_LAYER_get_r_epoch(rl) ((rl)->d->r_epoch)
+
+__owur int ssl3_read_n(SSL *s, int n, int max, int extend, int clearold);
+
+void RECORD_LAYER_set_write_sequence(RECORD_LAYER *rl, const unsigned char *ws);
+DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
+ unsigned int *is_next_epoch);
+int dtls1_process_buffered_records(SSL *s);
+int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue);
+int dtls1_buffer_record(SSL *s, record_pqueue *q, unsigned char *priority);
+void ssl3_record_sequence_update(unsigned char *seq);
+
+/* Functions provided by the DTLS1_BITMAP component */
+
+int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
+void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
+
+/* Macros/functions provided by the SSL3_BUFFER component */
+
+#define SSL3_BUFFER_get_buf(b) ((b)->buf)
+#define SSL3_BUFFER_set_buf(b, n) ((b)->buf = (n))
+#define SSL3_BUFFER_get_len(b) ((b)->len)
+#define SSL3_BUFFER_set_len(b, l) ((b)->len = (l))
+#define SSL3_BUFFER_get_left(b) ((b)->left)
+#define SSL3_BUFFER_set_left(b, l) ((b)->left = (l))
+#define SSL3_BUFFER_add_left(b, l) ((b)->left += (l))
+#define SSL3_BUFFER_get_offset(b) ((b)->offset)
+#define SSL3_BUFFER_set_offset(b, o) ((b)->offset = (o))
+#define SSL3_BUFFER_add_offset(b, o) ((b)->offset += (o))
+#define SSL3_BUFFER_is_initialised(b) ((b)->buf != NULL)
+#define SSL3_BUFFER_set_default_len(b, l) ((b)->default_len = (l))
+
+void SSL3_BUFFER_clear(SSL3_BUFFER *b);
+void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n);
+void SSL3_BUFFER_release(SSL3_BUFFER *b);
+__owur int ssl3_setup_read_buffer(SSL *s);
+__owur int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len);
+int ssl3_release_read_buffer(SSL *s);
+int ssl3_release_write_buffer(SSL *s);
+
+/* Macros/functions provided by the SSL3_RECORD component */
+
+#define SSL3_RECORD_get_type(r) ((r)->type)
+#define SSL3_RECORD_set_type(r, t) ((r)->type = (t))
+#define SSL3_RECORD_get_length(r) ((r)->length)
+#define SSL3_RECORD_set_length(r, l) ((r)->length = (l))
+#define SSL3_RECORD_add_length(r, l) ((r)->length += (l))
+#define SSL3_RECORD_sub_length(r, l) ((r)->length -= (l))
+#define SSL3_RECORD_get_data(r) ((r)->data)
+#define SSL3_RECORD_set_data(r, d) ((r)->data = (d))
+#define SSL3_RECORD_get_input(r) ((r)->input)
+#define SSL3_RECORD_set_input(r, i) ((r)->input = (i))
+#define SSL3_RECORD_reset_input(r) ((r)->input = (r)->data)
+#define SSL3_RECORD_get_seq_num(r) ((r)->seq_num)
+#define SSL3_RECORD_get_off(r) ((r)->off)
+#define SSL3_RECORD_set_off(r, o) ((r)->off = (o))
+#define SSL3_RECORD_add_off(r, o) ((r)->off += (o))
+#define SSL3_RECORD_get_epoch(r) ((r)->epoch)
+#define SSL3_RECORD_is_sslv2_record(r) \
+ ((r)->rec_version == SSL2_VERSION)
+#define SSL3_RECORD_is_read(r) ((r)->read)
+#define SSL3_RECORD_set_read(r) ((r)->read = 1)
+
+void SSL3_RECORD_clear(SSL3_RECORD *r, unsigned int num_recs);
+void SSL3_RECORD_release(SSL3_RECORD *r, unsigned int num_recs);
+void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num);
+int ssl3_get_record(SSL *s);
+__owur int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr);
+__owur int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr);
+void ssl3_cbc_copy_mac(unsigned char *out,
+ const SSL3_RECORD *rec, unsigned md_size);
+__owur int ssl3_cbc_remove_padding(SSL3_RECORD *rec,
+ unsigned block_size, unsigned mac_size);
+__owur int tls1_cbc_remove_padding(const SSL *s,
+ SSL3_RECORD *rec,
+ unsigned block_size, unsigned mac_size);
+int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap);
+__owur int dtls1_get_record(SSL *s);
diff --git a/openssl-1.1.0h/ssl/record/ssl3_buffer.c b/openssl-1.1.0h/ssl/record/ssl3_buffer.c
new file mode 100644
index 0000000..b6ed771
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/ssl3_buffer.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "../ssl_locl.h"
+#include "record_locl.h"
+
+void SSL3_BUFFER_set_data(SSL3_BUFFER *b, const unsigned char *d, int n)
+{
+ if (d != NULL)
+ memcpy(b->buf, d, n);
+ b->left = n;
+ b->offset = 0;
+}
+
+/*
+ * Clear the contents of an SSL3_BUFFER but retain any memory allocated. Also
+ * retains the default_len setting
+ */
+void SSL3_BUFFER_clear(SSL3_BUFFER *b)
+{
+ b->offset = 0;
+ b->left = 0;
+}
+
+void SSL3_BUFFER_release(SSL3_BUFFER *b)
+{
+ OPENSSL_free(b->buf);
+ b->buf = NULL;
+}
+
+int ssl3_setup_read_buffer(SSL *s)
+{
+ unsigned char *p;
+ size_t len, align = 0, headerlen;
+ SSL3_BUFFER *b;
+
+ b = RECORD_LAYER_get_rbuf(&s->rlayer);
+
+ if (SSL_IS_DTLS(s))
+ headerlen = DTLS1_RT_HEADER_LENGTH;
+ else
+ headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+ align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
+#endif
+
+ if (b->buf == NULL) {
+ len = SSL3_RT_MAX_PLAIN_LENGTH
+ + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
+#ifndef OPENSSL_NO_COMP
+ if (ssl_allow_compression(s))
+ len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+ if (b->default_len > len)
+ len = b->default_len;
+ if ((p = OPENSSL_malloc(len)) == NULL)
+ goto err;
+ b->buf = p;
+ b->len = len;
+ }
+
+ RECORD_LAYER_set_packet(&s->rlayer, &(b->buf[0]));
+ return 1;
+
+ err:
+ SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+int ssl3_setup_write_buffer(SSL *s, unsigned int numwpipes, size_t len)
+{
+ unsigned char *p;
+ size_t align = 0, headerlen;
+ SSL3_BUFFER *wb;
+ unsigned int currpipe;
+
+ s->rlayer.numwpipes = numwpipes;
+
+ if (len == 0) {
+ if (SSL_IS_DTLS(s))
+ headerlen = DTLS1_RT_HEADER_LENGTH + 1;
+ else
+ headerlen = SSL3_RT_HEADER_LENGTH;
+
+#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
+ align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
+#endif
+
+ len = s->max_send_fragment
+ + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
+#ifndef OPENSSL_NO_COMP
+ if (ssl_allow_compression(s))
+ len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
+#endif
+ if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
+ len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+ }
+
+ wb = RECORD_LAYER_get_wbuf(&s->rlayer);
+ for (currpipe = 0; currpipe < numwpipes; currpipe++) {
+ SSL3_BUFFER *thiswb = &wb[currpipe];
+
+ if (thiswb->buf == NULL) {
+ p = OPENSSL_malloc(len);
+ if (p == NULL) {
+ s->rlayer.numwpipes = currpipe;
+ goto err;
+ }
+ memset(thiswb, 0, sizeof(SSL3_BUFFER));
+ thiswb->buf = p;
+ thiswb->len = len;
+ }
+ }
+
+ return 1;
+
+ err:
+ SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE);
+ return 0;
+}
+
+int ssl3_setup_buffers(SSL *s)
+{
+ if (!ssl3_setup_read_buffer(s))
+ return 0;
+ if (!ssl3_setup_write_buffer(s, 1, 0))
+ return 0;
+ return 1;
+}
+
+int ssl3_release_write_buffer(SSL *s)
+{
+ SSL3_BUFFER *wb;
+ unsigned int pipes;
+
+ pipes = s->rlayer.numwpipes;
+ while (pipes > 0) {
+ wb = &RECORD_LAYER_get_wbuf(&s->rlayer)[pipes - 1];
+
+ OPENSSL_free(wb->buf);
+ wb->buf = NULL;
+ pipes--;
+ }
+ s->rlayer.numwpipes = 0;
+ return 1;
+}
+
+int ssl3_release_read_buffer(SSL *s)
+{
+ SSL3_BUFFER *b;
+
+ b = RECORD_LAYER_get_rbuf(&s->rlayer);
+ OPENSSL_free(b->buf);
+ b->buf = NULL;
+ return 1;
+}
diff --git a/openssl-1.1.0h/ssl/record/ssl3_record.c b/openssl-1.1.0h/ssl/record/ssl3_record.c
new file mode 100644
index 0000000..c7a54fe
--- /dev/null
+++ b/openssl-1.1.0h/ssl/record/ssl3_record.c
@@ -0,0 +1,1641 @@
+/*
+ * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <assert.h>
+#include "../ssl_locl.h"
+#include "internal/constant_time_locl.h"
+#include <openssl/rand.h>
+#include "record_locl.h"
+
+static const unsigned char ssl3_pad_1[48] = {
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+ 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
+};
+
+static const unsigned char ssl3_pad_2[48] = {
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
+ 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
+};
+
+/*
+ * Clear the contents of an SSL3_RECORD but retain any memory allocated
+ */
+void SSL3_RECORD_clear(SSL3_RECORD *r, unsigned int num_recs)
+{
+ unsigned char *comp;
+ unsigned int i;
+
+ for (i = 0; i < num_recs; i++) {
+ comp = r[i].comp;
+
+ memset(&r[i], 0, sizeof(*r));
+ r[i].comp = comp;
+ }
+}
+
+void SSL3_RECORD_release(SSL3_RECORD *r, unsigned int num_recs)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_recs; i++) {
+ OPENSSL_free(r[i].comp);
+ r[i].comp = NULL;
+ }
+}
+
+void SSL3_RECORD_set_seq_num(SSL3_RECORD *r, const unsigned char *seq_num)
+{
+ memcpy(r->seq_num, seq_num, SEQ_NUM_SIZE);
+}
+
+/*
+ * Peeks ahead into "read_ahead" data to see if we have a whole record waiting
+ * for us in the buffer.
+ */
+static int ssl3_record_app_data_waiting(SSL *s)
+{
+ SSL3_BUFFER *rbuf;
+ int left, len;
+ unsigned char *p;
+
+ rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+
+ p = SSL3_BUFFER_get_buf(rbuf);
+ if (p == NULL)
+ return 0;
+
+ left = SSL3_BUFFER_get_left(rbuf);
+
+ if (left < SSL3_RT_HEADER_LENGTH)
+ return 0;
+
+ p += SSL3_BUFFER_get_offset(rbuf);
+
+ /*
+ * We only check the type and record length, we will sanity check version
+ * etc later
+ */
+ if (*p != SSL3_RT_APPLICATION_DATA)
+ return 0;
+
+ p += 3;
+ n2s(p, len);
+
+ if (left < SSL3_RT_HEADER_LENGTH + len)
+ return 0;
+
+ return 1;
+}
+
+/*
+ * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that
+ * will be processed per call to ssl3_get_record. Without this limit an
+ * attacker could send empty records at a faster rate than we can process and
+ * cause ssl3_get_record to loop forever.
+ */
+#define MAX_EMPTY_RECORDS 32
+
+#define SSL2_RT_HEADER_LENGTH 2
+/*-
+ * Call this to get new input records.
+ * It will return <= 0 if more data is needed, normally due to an error
+ * or non-blocking IO.
+ * When it finishes, |numrpipes| records have been decoded. For each record 'i':
+ * rr[i].type - is the type of record
+ * rr[i].data, - data
+ * rr[i].length, - number of bytes
+ * Multiple records will only be returned if the record types are all
+ * SSL3_RT_APPLICATION_DATA. The number of records returned will always be <=
+ * |max_pipelines|
+ */
+/* used only by ssl3_read_bytes */
+int ssl3_get_record(SSL *s)
+{
+ int ssl_major, ssl_minor, al;
+ int enc_err, n, i, ret = -1;
+ SSL3_RECORD *rr;
+ SSL3_BUFFER *rbuf;
+ SSL_SESSION *sess;
+ unsigned char *p;
+ unsigned char md[EVP_MAX_MD_SIZE];
+ short version;
+ unsigned mac_size;
+ int imac_size;
+ unsigned int num_recs = 0;
+ unsigned int max_recs;
+ unsigned int j;
+
+ rr = RECORD_LAYER_get_rrec(&s->rlayer);
+ rbuf = RECORD_LAYER_get_rbuf(&s->rlayer);
+ max_recs = s->max_pipelines;
+ if (max_recs == 0)
+ max_recs = 1;
+ sess = s->session;
+
+ do {
+ /* check if we have the header */
+ if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
+ (RECORD_LAYER_get_packet_length(&s->rlayer)
+ < SSL3_RT_HEADER_LENGTH)) {
+ n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH,
+ SSL3_BUFFER_get_len(rbuf), 0,
+ num_recs == 0 ? 1 : 0);
+ if (n <= 0)
+ return (n); /* error or non-blocking */
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
+
+ p = RECORD_LAYER_get_packet(&s->rlayer);
+
+ /*
+ * The first record received by the server may be a V2ClientHello.
+ */
+ if (s->server && RECORD_LAYER_is_first_record(&s->rlayer)
+ && (p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) {
+ /*
+ * SSLv2 style record
+ *
+ * |num_recs| here will actually always be 0 because
+ * |num_recs > 0| only ever occurs when we are processing
+ * multiple app data records - which we know isn't the case here
+ * because it is an SSLv2ClientHello. We keep it using
+ * |num_recs| for the sake of consistency
+ */
+ rr[num_recs].type = SSL3_RT_HANDSHAKE;
+ rr[num_recs].rec_version = SSL2_VERSION;
+
+ rr[num_recs].length = ((p[0] & 0x7f) << 8) | p[1];
+
+ if (rr[num_recs].length > SSL3_BUFFER_get_len(rbuf)
+ - SSL2_RT_HEADER_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+
+ if (rr[num_recs].length < MIN_SSL2_RECORD_LEN) {
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ } else {
+ /* SSLv3+ style record */
+ if (s->msg_callback)
+ s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s,
+ s->msg_callback_arg);
+
+ /* Pull apart the header into the SSL3_RECORD */
+ rr[num_recs].type = *(p++);
+ ssl_major = *(p++);
+ ssl_minor = *(p++);
+ version = (ssl_major << 8) | ssl_minor;
+ rr[num_recs].rec_version = version;
+ n2s(p, rr[num_recs].length);
+
+ /* Lets check version */
+ if (!s->first_packet && version != s->version) {
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER);
+ if ((s->version & 0xFF00) == (version & 0xFF00)
+ && !s->enc_write_ctx && !s->write_hash) {
+ if (rr->type == SSL3_RT_ALERT) {
+ /*
+ * The record is using an incorrect version number,
+ * but what we've got appears to be an alert. We
+ * haven't read the body yet to check whether its a
+ * fatal or not - but chances are it is. We probably
+ * shouldn't send a fatal alert back. We'll just
+ * end.
+ */
+ goto err;
+ }
+ /*
+ * Send back error using their minor version number :-)
+ */
+ s->version = (unsigned short)version;
+ }
+ al = SSL_AD_PROTOCOL_VERSION;
+ goto f_err;
+ }
+
+ if ((version >> 8) != SSL3_VERSION_MAJOR) {
+ if (RECORD_LAYER_is_first_record(&s->rlayer)) {
+ /* Go back to start of packet, look at the five bytes
+ * that we have. */
+ p = RECORD_LAYER_get_packet(&s->rlayer);
+ if (strncmp((char *)p, "GET ", 4) == 0 ||
+ strncmp((char *)p, "POST ", 5) == 0 ||
+ strncmp((char *)p, "HEAD ", 5) == 0 ||
+ strncmp((char *)p, "PUT ", 4) == 0) {
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_HTTP_REQUEST);
+ goto err;
+ } else if (strncmp((char *)p, "CONNE", 5) == 0) {
+ SSLerr(SSL_F_SSL3_GET_RECORD,
+ SSL_R_HTTPS_PROXY_REQUEST);
+ goto err;
+ }
+
+ /* Doesn't look like TLS - don't send an alert */
+ SSLerr(SSL_F_SSL3_GET_RECORD,
+ SSL_R_WRONG_VERSION_NUMBER);
+ goto err;
+ } else {
+ SSLerr(SSL_F_SSL3_GET_RECORD,
+ SSL_R_WRONG_VERSION_NUMBER);
+ al = SSL_AD_PROTOCOL_VERSION;
+ goto f_err;
+ }
+ }
+
+ if (rr[num_recs].length >
+ SSL3_BUFFER_get_len(rbuf) - SSL3_RT_HEADER_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ }
+
+ /* now s->rlayer.rstate == SSL_ST_READ_BODY */
+ }
+
+ /*
+ * s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data.
+ * Calculate how much more data we need to read for the rest of the
+ * record
+ */
+ if (rr[num_recs].rec_version == SSL2_VERSION) {
+ i = rr[num_recs].length + SSL2_RT_HEADER_LENGTH
+ - SSL3_RT_HEADER_LENGTH;
+ } else {
+ i = rr[num_recs].length;
+ }
+ if (i > 0) {
+ /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
+
+ n = ssl3_read_n(s, i, i, 1, 0);
+ if (n <= 0)
+ return (n); /* error or non-blocking io */
+ }
+
+ /* set state for later operations */
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
+
+ /*
+ * At this point, s->packet_length == SSL3_RT_HEADER_LENGTH + rr->length,
+ * or s->packet_length == SSL2_RT_HEADER_LENGTH + rr->length
+ * and we have that many bytes in s->packet
+ */
+ if (rr[num_recs].rec_version == SSL2_VERSION) {
+ rr[num_recs].input =
+ &(RECORD_LAYER_get_packet(&s->rlayer)[SSL2_RT_HEADER_LENGTH]);
+ } else {
+ rr[num_recs].input =
+ &(RECORD_LAYER_get_packet(&s->rlayer)[SSL3_RT_HEADER_LENGTH]);
+ }
+
+ /*
+ * ok, we can now read from 's->packet' data into 'rr' rr->input points
+ * at rr->length bytes, which need to be copied into rr->data by either
+ * the decryption or by the decompression When the data is 'copied' into
+ * the rr->data buffer, rr->input will be pointed at the new buffer
+ */
+
+ /*
+ * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length
+ * bytes of encrypted compressed stuff.
+ */
+
+ /* check is not needed I believe */
+ if (rr[num_recs].length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+
+ /* decrypt in place in 'rr->input' */
+ rr[num_recs].data = rr[num_recs].input;
+ rr[num_recs].orig_len = rr[num_recs].length;
+
+ /* Mark this record as not read by upper layers yet */
+ rr[num_recs].read = 0;
+
+ num_recs++;
+
+ /* we have pulled in a full packet so zero things */
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ RECORD_LAYER_clear_first_record(&s->rlayer);
+ } while (num_recs < max_recs
+ && rr[num_recs - 1].type == SSL3_RT_APPLICATION_DATA
+ && SSL_USE_EXPLICIT_IV(s)
+ && s->enc_read_ctx != NULL
+ && (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_read_ctx))
+ & EVP_CIPH_FLAG_PIPELINE)
+ && ssl3_record_app_data_waiting(s));
+
+ /*
+ * If in encrypt-then-mac mode calculate mac from encrypted record. All
+ * the details below are public so no timing details can leak.
+ */
+ if (SSL_READ_ETM(s) && s->read_hash) {
+ unsigned char *mac;
+
+ imac_size = EVP_MD_CTX_size(s->read_hash);
+ assert(imac_size >= 0 && imac_size <= EVP_MAX_MD_SIZE);
+ if (imac_size < 0 || imac_size > EVP_MAX_MD_SIZE) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_SSL3_GET_RECORD, ERR_LIB_EVP);
+ goto f_err;
+ }
+ mac_size = (unsigned)imac_size;
+
+ for (j = 0; j < num_recs; j++) {
+ if (rr[j].length < mac_size) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+ rr[j].length -= mac_size;
+ mac = rr[j].data + rr[j].length;
+ i = s->method->ssl3_enc->mac(s, &rr[j], md, 0 /* not send */ );
+ if (i < 0 || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) {
+ al = SSL_AD_BAD_RECORD_MAC;
+ SSLerr(SSL_F_SSL3_GET_RECORD,
+ SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+ goto f_err;
+ }
+ }
+ }
+
+ enc_err = s->method->ssl3_enc->enc(s, rr, num_recs, 0);
+ /*-
+ * enc_err is:
+ * 0: (in non-constant time) if the record is publically invalid.
+ * 1: if the padding is valid
+ * -1: if the padding is invalid
+ */
+ if (enc_err == 0) {
+ al = SSL_AD_DECRYPTION_FAILED;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG);
+ goto f_err;
+ }
+#ifdef SSL_DEBUG
+ printf("dec %d\n", rr->length);
+ {
+ unsigned int z;
+ for (z = 0; z < rr->length; z++)
+ printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n');
+ }
+ printf("\n");
+#endif
+
+ /* r->length is now the compressed data plus mac */
+ if ((sess != NULL) &&
+ (s->enc_read_ctx != NULL) &&
+ (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)) {
+ /* s->read_hash != NULL => mac_size != -1 */
+ unsigned char *mac = NULL;
+ unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+
+ mac_size = EVP_MD_CTX_size(s->read_hash);
+ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+ for (j = 0; j < num_recs; j++) {
+ /*
+ * orig_len is the length of the record before any padding was
+ * removed. This is public information, as is the MAC in use,
+ * therefore we can safely process the record in a different amount
+ * of time if it's too short to possibly contain a MAC.
+ */
+ if (rr[j].orig_len < mac_size ||
+ /* CBC records must have a padding length byte too. */
+ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ rr[j].orig_len < mac_size + 1)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+
+ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
+ /*
+ * We update the length so that the TLS header bytes can be
+ * constructed correctly but we need to extract the MAC in
+ * constant time from within the record, without leaking the
+ * contents of the padding bytes.
+ */
+ mac = mac_tmp;
+ ssl3_cbc_copy_mac(mac_tmp, &rr[j], mac_size);
+ rr[j].length -= mac_size;
+ } else {
+ /*
+ * In this case there's no padding, so |rec->orig_len| equals
+ * |rec->length| and we checked that there's enough bytes for
+ * |mac_size| above.
+ */
+ rr[j].length -= mac_size;
+ mac = &rr[j].data[rr[j].length];
+ }
+
+ i = s->method->ssl3_enc->mac(s, &rr[j], md, 0 /* not send */ );
+ if (i < 0 || mac == NULL
+ || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+ enc_err = -1;
+ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
+ enc_err = -1;
+ }
+ }
+
+ if (enc_err < 0) {
+ /*
+ * A separate 'decryption_failed' alert was introduced with TLS 1.0,
+ * SSL 3.0 only has 'bad_record_mac'. But unless a decryption
+ * failure is directly visible from the ciphertext anyway, we should
+ * not reveal which kind of error occurred -- this might become
+ * visible to an attacker (e.g. via a logfile)
+ */
+ al = SSL_AD_BAD_RECORD_MAC;
+ SSLerr(SSL_F_SSL3_GET_RECORD,
+ SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+ goto f_err;
+ }
+
+ for (j = 0; j < num_recs; j++) {
+ /* rr[j].length is now just compressed */
+ if (s->expand != NULL) {
+ if (rr[j].length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ if (!ssl3_do_uncompress(s, &rr[j])) {
+ al = SSL_AD_DECOMPRESSION_FAILURE;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_DECOMPRESSION);
+ goto f_err;
+ }
+ }
+
+ if (rr[j].length > SSL3_RT_MAX_PLAIN_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+
+ rr[j].off = 0;
+ /*-
+ * So at this point the following is true
+ * rr[j].type is the type of record
+ * rr[j].length == number of bytes in record
+ * rr[j].off == offset to first valid byte
+ * rr[j].data == where to take bytes from, increment after use :-).
+ */
+
+ /* just read a 0 length packet */
+ if (rr[j].length == 0) {
+ RECORD_LAYER_inc_empty_record_count(&s->rlayer);
+ if (RECORD_LAYER_get_empty_record_count(&s->rlayer)
+ > MAX_EMPTY_RECORDS) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_RECORD_TOO_SMALL);
+ goto f_err;
+ }
+ } else {
+ RECORD_LAYER_reset_empty_record_count(&s->rlayer);
+ }
+ }
+
+ RECORD_LAYER_set_numrpipes(&s->rlayer, num_recs);
+ return 1;
+
+ f_err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+ return ret;
+}
+
+int ssl3_do_uncompress(SSL *ssl, SSL3_RECORD *rr)
+{
+#ifndef OPENSSL_NO_COMP
+ int i;
+
+ if (rr->comp == NULL) {
+ rr->comp = (unsigned char *)
+ OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH);
+ }
+ if (rr->comp == NULL)
+ return 0;
+
+ i = COMP_expand_block(ssl->expand, rr->comp,
+ SSL3_RT_MAX_PLAIN_LENGTH, rr->data, (int)rr->length);
+ if (i < 0)
+ return 0;
+ else
+ rr->length = i;
+ rr->data = rr->comp;
+#endif
+ return 1;
+}
+
+int ssl3_do_compress(SSL *ssl, SSL3_RECORD *wr)
+{
+#ifndef OPENSSL_NO_COMP
+ int i;
+
+ i = COMP_compress_block(ssl->compress, wr->data,
+ SSL3_RT_MAX_COMPRESSED_LENGTH,
+ wr->input, (int)wr->length);
+ if (i < 0)
+ return (0);
+ else
+ wr->length = i;
+
+ wr->input = wr->data;
+#endif
+ return (1);
+}
+
+/*-
+ * ssl3_enc encrypts/decrypts |n_recs| records in |inrecs|
+ *
+ * Returns:
+ * 0: (in non-constant time) if the record is publically invalid (i.e. too
+ * short etc).
+ * 1: if the record's padding is valid / the encryption was successful.
+ * -1: if the record's padding is invalid or, if sending, an internal error
+ * occurred.
+ */
+int ssl3_enc(SSL *s, SSL3_RECORD *inrecs, unsigned int n_recs, int sending)
+{
+ SSL3_RECORD *rec;
+ EVP_CIPHER_CTX *ds;
+ unsigned long l;
+ int bs, i, mac_size = 0;
+ const EVP_CIPHER *enc;
+
+ rec = inrecs;
+ /*
+ * We shouldn't ever be called with more than one record in the SSLv3 case
+ */
+ if (n_recs != 1)
+ return 0;
+ if (sending) {
+ ds = s->enc_write_ctx;
+ if (s->enc_write_ctx == NULL)
+ enc = NULL;
+ else
+ enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+ } else {
+ ds = s->enc_read_ctx;
+ if (s->enc_read_ctx == NULL)
+ enc = NULL;
+ else
+ enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+ }
+
+ if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
+ memmove(rec->data, rec->input, rec->length);
+ rec->input = rec->data;
+ } else {
+ l = rec->length;
+ bs = EVP_CIPHER_CTX_block_size(ds);
+
+ /* COMPRESS */
+
+ if ((bs != 1) && sending) {
+ i = bs - ((int)l % bs);
+
+ /* we need to add 'i-1' padding bytes */
+ l += i;
+ /*
+ * the last of these zero bytes will be overwritten with the
+ * padding length.
+ */
+ memset(&rec->input[rec->length], 0, i);
+ rec->length += i;
+ rec->input[l - 1] = (i - 1);
+ }
+
+ if (!sending) {
+ if (l == 0 || l % bs != 0)
+ return 0;
+ /* otherwise, rec->length >= bs */
+ }
+
+ if (EVP_Cipher(ds, rec->data, rec->input, l) < 1)
+ return -1;
+
+ if (EVP_MD_CTX_md(s->read_hash) != NULL)
+ mac_size = EVP_MD_CTX_size(s->read_hash);
+ if ((bs != 1) && !sending)
+ return ssl3_cbc_remove_padding(rec, bs, mac_size);
+ }
+ return (1);
+}
+
+/*-
+ * tls1_enc encrypts/decrypts |n_recs| in |recs|.
+ *
+ * Returns:
+ * 0: (in non-constant time) if the record is publically invalid (i.e. too
+ * short etc).
+ * 1: if the record's padding is valid / the encryption was successful.
+ * -1: if the record's padding/AEAD-authenticator is invalid or, if sending,
+ * an internal error occurred.
+ */
+int tls1_enc(SSL *s, SSL3_RECORD *recs, unsigned int n_recs, int sending)
+{
+ EVP_CIPHER_CTX *ds;
+ size_t reclen[SSL_MAX_PIPELINES];
+ unsigned char buf[SSL_MAX_PIPELINES][EVP_AEAD_TLS1_AAD_LEN];
+ int bs, i, j, k, pad = 0, ret, mac_size = 0;
+ const EVP_CIPHER *enc;
+ unsigned int ctr;
+
+ if (n_recs == 0)
+ return 0;
+
+ if (sending) {
+ if (EVP_MD_CTX_md(s->write_hash)) {
+ int n = EVP_MD_CTX_size(s->write_hash);
+ OPENSSL_assert(n >= 0);
+ }
+ ds = s->enc_write_ctx;
+ if (s->enc_write_ctx == NULL)
+ enc = NULL;
+ else {
+ int ivlen;
+ enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx);
+ /* For TLSv1.1 and later explicit IV */
+ if (SSL_USE_EXPLICIT_IV(s)
+ && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE)
+ ivlen = EVP_CIPHER_iv_length(enc);
+ else
+ ivlen = 0;
+ if (ivlen > 1) {
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ if (recs[ctr].data != recs[ctr].input) {
+ /*
+ * we can't write into the input stream: Can this ever
+ * happen?? (steve)
+ */
+ SSLerr(SSL_F_TLS1_ENC, ERR_R_INTERNAL_ERROR);
+ return -1;
+ } else if (RAND_bytes(recs[ctr].input, ivlen) <= 0) {
+ SSLerr(SSL_F_TLS1_ENC, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ }
+ }
+ }
+ } else {
+ if (EVP_MD_CTX_md(s->read_hash)) {
+ int n = EVP_MD_CTX_size(s->read_hash);
+ OPENSSL_assert(n >= 0);
+ }
+ ds = s->enc_read_ctx;
+ if (s->enc_read_ctx == NULL)
+ enc = NULL;
+ else
+ enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx);
+ }
+
+ if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) {
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ memmove(recs[ctr].data, recs[ctr].input, recs[ctr].length);
+ recs[ctr].input = recs[ctr].data;
+ }
+ ret = 1;
+ } else {
+ bs = EVP_CIPHER_block_size(EVP_CIPHER_CTX_cipher(ds));
+
+ if (n_recs > 1) {
+ if (!(EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds))
+ & EVP_CIPH_FLAG_PIPELINE)) {
+ /*
+ * We shouldn't have been called with pipeline data if the
+ * cipher doesn't support pipelining
+ */
+ SSLerr(SSL_F_TLS1_ENC, SSL_R_PIPELINE_FAILURE);
+ return -1;
+ }
+ }
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ reclen[ctr] = recs[ctr].length;
+
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds))
+ & EVP_CIPH_FLAG_AEAD_CIPHER) {
+ unsigned char *seq;
+
+ seq = sending ? RECORD_LAYER_get_write_sequence(&s->rlayer)
+ : RECORD_LAYER_get_read_sequence(&s->rlayer);
+
+ if (SSL_IS_DTLS(s)) {
+ /* DTLS does not support pipelining */
+ unsigned char dtlsseq[9], *p = dtlsseq;
+
+ s2n(sending ? DTLS_RECORD_LAYER_get_w_epoch(&s->rlayer) :
+ DTLS_RECORD_LAYER_get_r_epoch(&s->rlayer), p);
+ memcpy(p, &seq[2], 6);
+ memcpy(buf[ctr], dtlsseq, 8);
+ } else {
+ memcpy(buf[ctr], seq, 8);
+ for (i = 7; i >= 0; i--) { /* increment */
+ ++seq[i];
+ if (seq[i] != 0)
+ break;
+ }
+ }
+
+ buf[ctr][8] = recs[ctr].type;
+ buf[ctr][9] = (unsigned char)(s->version >> 8);
+ buf[ctr][10] = (unsigned char)(s->version);
+ buf[ctr][11] = recs[ctr].length >> 8;
+ buf[ctr][12] = recs[ctr].length & 0xff;
+ pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD,
+ EVP_AEAD_TLS1_AAD_LEN, buf[ctr]);
+ if (pad <= 0)
+ return -1;
+
+ if (sending) {
+ reclen[ctr] += pad;
+ recs[ctr].length += pad;
+ }
+
+ } else if ((bs != 1) && sending) {
+ i = bs - ((int)reclen[ctr] % bs);
+
+ /* Add weird padding of upto 256 bytes */
+
+ /* we need to add 'i' padding bytes of value j */
+ j = i - 1;
+ for (k = (int)reclen[ctr]; k < (int)(reclen[ctr] + i); k++)
+ recs[ctr].input[k] = j;
+ reclen[ctr] += i;
+ recs[ctr].length += i;
+ }
+
+ if (!sending) {
+ if (reclen[ctr] == 0 || reclen[ctr] % bs != 0)
+ return 0;
+ }
+ }
+ if (n_recs > 1) {
+ unsigned char *data[SSL_MAX_PIPELINES];
+
+ /* Set the output buffers */
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ data[ctr] = recs[ctr].data;
+ }
+ if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_OUTPUT_BUFS,
+ n_recs, data) <= 0) {
+ SSLerr(SSL_F_TLS1_ENC, SSL_R_PIPELINE_FAILURE);
+ }
+ /* Set the input buffers */
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ data[ctr] = recs[ctr].input;
+ }
+ if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_BUFS,
+ n_recs, data) <= 0
+ || EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_SET_PIPELINE_INPUT_LENS,
+ n_recs, reclen) <= 0) {
+ SSLerr(SSL_F_TLS1_ENC, SSL_R_PIPELINE_FAILURE);
+ return -1;
+ }
+ }
+
+ i = EVP_Cipher(ds, recs[0].data, recs[0].input, reclen[0]);
+ if ((EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(ds))
+ & EVP_CIPH_FLAG_CUSTOM_CIPHER)
+ ? (i < 0)
+ : (i == 0))
+ return -1; /* AEAD can fail to verify MAC */
+ if (sending == 0) {
+ if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE) {
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ recs[ctr].data += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ recs[ctr].input += EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ recs[ctr].length -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
+ }
+ } else if (EVP_CIPHER_mode(enc) == EVP_CIPH_CCM_MODE) {
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ recs[ctr].data += EVP_CCM_TLS_EXPLICIT_IV_LEN;
+ recs[ctr].input += EVP_CCM_TLS_EXPLICIT_IV_LEN;
+ recs[ctr].length -= EVP_CCM_TLS_EXPLICIT_IV_LEN;
+ }
+ }
+ }
+
+ ret = 1;
+ if (!SSL_READ_ETM(s) && EVP_MD_CTX_md(s->read_hash) != NULL)
+ mac_size = EVP_MD_CTX_size(s->read_hash);
+ if ((bs != 1) && !sending) {
+ int tmpret;
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ tmpret = tls1_cbc_remove_padding(s, &recs[ctr], bs, mac_size);
+ /*
+ * If tmpret == 0 then this means publicly invalid so we can
+ * short circuit things here. Otherwise we must respect constant
+ * time behaviour.
+ */
+ if (tmpret == 0)
+ return 0;
+ ret = constant_time_select_int(constant_time_eq_int(tmpret, 1),
+ ret, -1);
+ }
+ }
+ if (pad && !sending) {
+ for (ctr = 0; ctr < n_recs; ctr++) {
+ recs[ctr].length -= pad;
+ }
+ }
+ }
+ return ret;
+}
+
+int n_ssl3_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
+{
+ unsigned char *mac_sec, *seq;
+ const EVP_MD_CTX *hash;
+ unsigned char *p, rec_char;
+ size_t md_size;
+ int npad;
+ int t;
+
+ if (sending) {
+ mac_sec = &(ssl->s3->write_mac_secret[0]);
+ seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
+ hash = ssl->write_hash;
+ } else {
+ mac_sec = &(ssl->s3->read_mac_secret[0]);
+ seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
+ hash = ssl->read_hash;
+ }
+
+ t = EVP_MD_CTX_size(hash);
+ if (t < 0)
+ return -1;
+ md_size = t;
+ npad = (48 / md_size) * md_size;
+
+ if (!sending &&
+ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ ssl3_cbc_record_digest_supported(hash)) {
+ /*
+ * This is a CBC-encrypted record. We must avoid leaking any
+ * timing-side channel information about how many blocks of data we
+ * are hashing because that gives an attacker a timing-oracle.
+ */
+
+ /*-
+ * npad is, at most, 48 bytes and that's with MD5:
+ * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
+ *
+ * With SHA-1 (the largest hash speced for SSLv3) the hash size
+ * goes up 4, but npad goes down by 8, resulting in a smaller
+ * total size.
+ */
+ unsigned char header[75];
+ unsigned j = 0;
+ memcpy(header + j, mac_sec, md_size);
+ j += md_size;
+ memcpy(header + j, ssl3_pad_1, npad);
+ j += npad;
+ memcpy(header + j, seq, 8);
+ j += 8;
+ header[j++] = rec->type;
+ header[j++] = rec->length >> 8;
+ header[j++] = rec->length & 0xff;
+
+ /* Final param == is SSLv3 */
+ if (ssl3_cbc_digest_record(hash,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, rec->orig_len,
+ mac_sec, md_size, 1) <= 0)
+ return -1;
+ } else {
+ unsigned int md_size_u;
+ /* Chop the digest off the end :-) */
+ EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
+
+ if (md_ctx == NULL)
+ return -1;
+
+ rec_char = rec->type;
+ p = md;
+ s2n(rec->length, p);
+ if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+ || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0
+ || EVP_DigestUpdate(md_ctx, seq, 8) <= 0
+ || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0
+ || EVP_DigestUpdate(md_ctx, md, 2) <= 0
+ || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0
+ || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0
+ || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
+ || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
+ || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
+ || EVP_DigestUpdate(md_ctx, md, md_size) <= 0
+ || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
+ EVP_MD_CTX_free(md_ctx);
+ return -1;
+ }
+ md_size = md_size_u;
+
+ EVP_MD_CTX_free(md_ctx);
+ }
+
+ ssl3_record_sequence_update(seq);
+ return (md_size);
+}
+
+int tls1_mac(SSL *ssl, SSL3_RECORD *rec, unsigned char *md, int sending)
+{
+ unsigned char *seq;
+ EVP_MD_CTX *hash;
+ size_t md_size;
+ int i;
+ EVP_MD_CTX *hmac = NULL, *mac_ctx;
+ unsigned char header[13];
+ int stream_mac = (sending ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM)
+ : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM));
+ int t;
+
+ if (sending) {
+ seq = RECORD_LAYER_get_write_sequence(&ssl->rlayer);
+ hash = ssl->write_hash;
+ } else {
+ seq = RECORD_LAYER_get_read_sequence(&ssl->rlayer);
+ hash = ssl->read_hash;
+ }
+
+ t = EVP_MD_CTX_size(hash);
+ OPENSSL_assert(t >= 0);
+ md_size = t;
+
+ /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */
+ if (stream_mac) {
+ mac_ctx = hash;
+ } else {
+ hmac = EVP_MD_CTX_new();
+ if (hmac == NULL || !EVP_MD_CTX_copy(hmac, hash)) {
+ EVP_MD_CTX_free(hmac);
+ return -1;
+ }
+ mac_ctx = hmac;
+ }
+
+ if (SSL_IS_DTLS(ssl)) {
+ unsigned char dtlsseq[8], *p = dtlsseq;
+
+ s2n(sending ? DTLS_RECORD_LAYER_get_w_epoch(&ssl->rlayer) :
+ DTLS_RECORD_LAYER_get_r_epoch(&ssl->rlayer), p);
+ memcpy(p, &seq[2], 6);
+
+ memcpy(header, dtlsseq, 8);
+ } else
+ memcpy(header, seq, 8);
+
+ header[8] = rec->type;
+ header[9] = (unsigned char)(ssl->version >> 8);
+ header[10] = (unsigned char)(ssl->version);
+ header[11] = (rec->length) >> 8;
+ header[12] = (rec->length) & 0xff;
+
+ if (!sending && !SSL_READ_ETM(ssl) &&
+ EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ ssl3_cbc_record_digest_supported(mac_ctx)) {
+ /*
+ * This is a CBC-encrypted record. We must avoid leaking any
+ * timing-side channel information about how many blocks of data we
+ * are hashing because that gives an attacker a timing-oracle.
+ */
+ /* Final param == not SSLv3 */
+ if (ssl3_cbc_digest_record(mac_ctx,
+ md, &md_size,
+ header, rec->input,
+ rec->length + md_size, rec->orig_len,
+ ssl->s3->read_mac_secret,
+ ssl->s3->read_mac_secret_size, 0) <= 0) {
+ EVP_MD_CTX_free(hmac);
+ return -1;
+ }
+ } else {
+ if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0
+ || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0
+ || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) {
+ EVP_MD_CTX_free(hmac);
+ return -1;
+ }
+ if (!sending && !SSL_READ_ETM(ssl) && FIPS_mode())
+ if (!tls_fips_digest_extra(ssl->enc_read_ctx,
+ mac_ctx, rec->input,
+ rec->length, rec->orig_len)) {
+ EVP_MD_CTX_free(hmac);
+ return -1;
+ }
+ }
+
+ EVP_MD_CTX_free(hmac);
+
+#ifdef SSL_DEBUG
+ fprintf(stderr, "seq=");
+ {
+ int z;
+ for (z = 0; z < 8; z++)
+ fprintf(stderr, "%02X ", seq[z]);
+ fprintf(stderr, "\n");
+ }
+ fprintf(stderr, "rec=");
+ {
+ unsigned int z;
+ for (z = 0; z < rec->length; z++)
+ fprintf(stderr, "%02X ", rec->data[z]);
+ fprintf(stderr, "\n");
+ }
+#endif
+
+ if (!SSL_IS_DTLS(ssl)) {
+ for (i = 7; i >= 0; i--) {
+ ++seq[i];
+ if (seq[i] != 0)
+ break;
+ }
+ }
+#ifdef SSL_DEBUG
+ {
+ unsigned int z;
+ for (z = 0; z < md_size; z++)
+ fprintf(stderr, "%02X ", md[z]);
+ fprintf(stderr, "\n");
+ }
+#endif
+ return (md_size);
+}
+
+/*-
+ * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC
+ * record in |rec| by updating |rec->length| in constant time.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ * 0: (in non-constant time) if the record is publicly invalid.
+ * 1: if the padding was valid
+ * -1: otherwise.
+ */
+int ssl3_cbc_remove_padding(SSL3_RECORD *rec,
+ unsigned block_size, unsigned mac_size)
+{
+ unsigned padding_length, good;
+ const unsigned overhead = 1 /* padding length byte */ + mac_size;
+
+ /*
+ * These lengths are all public so we can test them in non-constant time.
+ */
+ if (overhead > rec->length)
+ return 0;
+
+ padding_length = rec->data[rec->length - 1];
+ good = constant_time_ge(rec->length, padding_length + overhead);
+ /* SSLv3 requires that the padding is minimal. */
+ good &= constant_time_ge(block_size, padding_length + 1);
+ rec->length -= good & (padding_length + 1);
+ return constant_time_select_int(good, 1, -1);
+}
+
+/*-
+ * tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC
+ * record in |rec| in constant time and returns 1 if the padding is valid and
+ * -1 otherwise. It also removes any explicit IV from the start of the record
+ * without leaking any timing about whether there was enough space after the
+ * padding was removed.
+ *
+ * block_size: the block size of the cipher used to encrypt the record.
+ * returns:
+ * 0: (in non-constant time) if the record is publicly invalid.
+ * 1: if the padding was valid
+ * -1: otherwise.
+ */
+int tls1_cbc_remove_padding(const SSL *s,
+ SSL3_RECORD *rec,
+ unsigned block_size, unsigned mac_size)
+{
+ unsigned padding_length, good, to_check, i;
+ const unsigned overhead = 1 /* padding length byte */ + mac_size;
+ /* Check if version requires explicit IV */
+ if (SSL_USE_EXPLICIT_IV(s)) {
+ /*
+ * These lengths are all public so we can test them in non-constant
+ * time.
+ */
+ if (overhead + block_size > rec->length)
+ return 0;
+ /* We can now safely skip explicit IV */
+ rec->data += block_size;
+ rec->input += block_size;
+ rec->length -= block_size;
+ rec->orig_len -= block_size;
+ } else if (overhead > rec->length)
+ return 0;
+
+ padding_length = rec->data[rec->length - 1];
+
+ if (EVP_CIPHER_flags(EVP_CIPHER_CTX_cipher(s->enc_read_ctx)) &
+ EVP_CIPH_FLAG_AEAD_CIPHER) {
+ /* padding is already verified */
+ rec->length -= padding_length + 1;
+ return 1;
+ }
+
+ good = constant_time_ge(rec->length, overhead + padding_length);
+ /*
+ * The padding consists of a length byte at the end of the record and
+ * then that many bytes of padding, all with the same value as the length
+ * byte. Thus, with the length byte included, there are i+1 bytes of
+ * padding. We can't check just |padding_length+1| bytes because that
+ * leaks decrypted information. Therefore we always have to check the
+ * maximum amount of padding possible. (Again, the length of the record
+ * is public information so we can use it.)
+ */
+ to_check = 256; /* maximum amount of padding, inc length byte. */
+ if (to_check > rec->length)
+ to_check = rec->length;
+
+ for (i = 0; i < to_check; i++) {
+ unsigned char mask = constant_time_ge_8(padding_length, i);
+ unsigned char b = rec->data[rec->length - 1 - i];
+ /*
+ * The final |padding_length+1| bytes should all have the value
+ * |padding_length|. Therefore the XOR should be zero.
+ */
+ good &= ~(mask & (padding_length ^ b));
+ }
+
+ /*
+ * If any of the final |padding_length+1| bytes had the wrong value, one
+ * or more of the lower eight bits of |good| will be cleared.
+ */
+ good = constant_time_eq(0xff, good & 0xff);
+ rec->length -= good & (padding_length + 1);
+
+ return constant_time_select_int(good, 1, -1);
+}
+
+/*-
+ * ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in
+ * constant time (independent of the concrete value of rec->length, which may
+ * vary within a 256-byte window).
+ *
+ * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to
+ * this function.
+ *
+ * On entry:
+ * rec->orig_len >= md_size
+ * md_size <= EVP_MAX_MD_SIZE
+ *
+ * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with
+ * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into
+ * a single or pair of cache-lines, then the variable memory accesses don't
+ * actually affect the timing. CPUs with smaller cache-lines [if any] are
+ * not multi-core and are not considered vulnerable to cache-timing attacks.
+ */
+#define CBC_MAC_ROTATE_IN_PLACE
+
+void ssl3_cbc_copy_mac(unsigned char *out,
+ const SSL3_RECORD *rec, unsigned md_size)
+{
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+ unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE];
+ unsigned char *rotated_mac;
+#else
+ unsigned char rotated_mac[EVP_MAX_MD_SIZE];
+#endif
+
+ /*
+ * mac_end is the index of |rec->data| just after the end of the MAC.
+ */
+ unsigned mac_end = rec->length;
+ unsigned mac_start = mac_end - md_size;
+ unsigned in_mac;
+ /*
+ * scan_start contains the number of bytes that we can ignore because the
+ * MAC's position can only vary by 255 bytes.
+ */
+ unsigned scan_start = 0;
+ unsigned i, j;
+ unsigned rotate_offset;
+
+ OPENSSL_assert(rec->orig_len >= md_size);
+ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+ rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63);
+#endif
+
+ /* This information is public so it's safe to branch based on it. */
+ if (rec->orig_len > md_size + 255 + 1)
+ scan_start = rec->orig_len - (md_size + 255 + 1);
+
+ in_mac = 0;
+ rotate_offset = 0;
+ memset(rotated_mac, 0, md_size);
+ for (i = scan_start, j = 0; i < rec->orig_len; i++) {
+ unsigned mac_started = constant_time_eq(i, mac_start);
+ unsigned mac_ended = constant_time_lt(i, mac_end);
+ unsigned char b = rec->data[i];
+
+ in_mac |= mac_started;
+ in_mac &= mac_ended;
+ rotate_offset |= j & mac_started;
+ rotated_mac[j++] |= b & in_mac;
+ j &= constant_time_lt(j, md_size);
+ }
+
+ /* Now rotate the MAC */
+#if defined(CBC_MAC_ROTATE_IN_PLACE)
+ j = 0;
+ for (i = 0; i < md_size; i++) {
+ /* in case cache-line is 32 bytes, touch second line */
+ ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32];
+ out[j++] = rotated_mac[rotate_offset++];
+ rotate_offset &= constant_time_lt(rotate_offset, md_size);
+ }
+#else
+ memset(out, 0, md_size);
+ rotate_offset = md_size - rotate_offset;
+ rotate_offset &= constant_time_lt(rotate_offset, md_size);
+ for (i = 0; i < md_size; i++) {
+ for (j = 0; j < md_size; j++)
+ out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset);
+ rotate_offset++;
+ rotate_offset &= constant_time_lt(rotate_offset, md_size);
+ }
+#endif
+}
+
+int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
+{
+ int i, al;
+ int enc_err;
+ SSL_SESSION *sess;
+ SSL3_RECORD *rr;
+ unsigned int mac_size;
+ unsigned char md[EVP_MAX_MD_SIZE];
+
+ rr = RECORD_LAYER_get_rrec(&s->rlayer);
+ sess = s->session;
+
+ /*
+ * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length,
+ * and we have that many bytes in s->packet
+ */
+ rr->input = &(RECORD_LAYER_get_packet(&s->rlayer)[DTLS1_RT_HEADER_LENGTH]);
+
+ /*
+ * ok, we can now read from 's->packet' data into 'rr' rr->input points
+ * at rr->length bytes, which need to be copied into rr->data by either
+ * the decryption or by the decompression When the data is 'copied' into
+ * the rr->data buffer, rr->input will be pointed at the new buffer
+ */
+
+ /*
+ * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length
+ * bytes of encrypted compressed stuff.
+ */
+
+ /* check is not needed I believe */
+ if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+
+ /* decrypt in place in 'rr->input' */
+ rr->data = rr->input;
+ rr->orig_len = rr->length;
+
+ enc_err = s->method->ssl3_enc->enc(s, rr, 1, 0);
+ /*-
+ * enc_err is:
+ * 0: (in non-constant time) if the record is publically invalid.
+ * 1: if the padding is valid
+ * -1: if the padding is invalid
+ */
+ if (enc_err == 0) {
+ /* For DTLS we simply ignore bad packets. */
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto err;
+ }
+#ifdef SSL_DEBUG
+ printf("dec %d\n", rr->length);
+ {
+ unsigned int z;
+ for (z = 0; z < rr->length; z++)
+ printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n');
+ }
+ printf("\n");
+#endif
+
+ /* r->length is now the compressed data plus mac */
+ if ((sess != NULL) &&
+ (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) {
+ /* s->read_hash != NULL => mac_size != -1 */
+ unsigned char *mac = NULL;
+ unsigned char mac_tmp[EVP_MAX_MD_SIZE];
+ mac_size = EVP_MD_CTX_size(s->read_hash);
+ OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
+
+ /*
+ * orig_len is the length of the record before any padding was
+ * removed. This is public information, as is the MAC in use,
+ * therefore we can safely process the record in a different amount
+ * of time if it's too short to possibly contain a MAC.
+ */
+ if (rr->orig_len < mac_size ||
+ /* CBC records must have a padding length byte too. */
+ (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
+ rr->orig_len < mac_size + 1)) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT);
+ goto f_err;
+ }
+
+ if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
+ /*
+ * We update the length so that the TLS header bytes can be
+ * constructed correctly but we need to extract the MAC in
+ * constant time from within the record, without leaking the
+ * contents of the padding bytes.
+ */
+ mac = mac_tmp;
+ ssl3_cbc_copy_mac(mac_tmp, rr, mac_size);
+ rr->length -= mac_size;
+ } else {
+ /*
+ * In this case there's no padding, so |rec->orig_len| equals
+ * |rec->length| and we checked that there's enough bytes for
+ * |mac_size| above.
+ */
+ rr->length -= mac_size;
+ mac = &rr->data[rr->length];
+ }
+
+ i = s->method->ssl3_enc->mac(s, rr, md, 0 /* not send */ );
+ if (i < 0 || mac == NULL
+ || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
+ enc_err = -1;
+ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
+ enc_err = -1;
+ }
+
+ if (enc_err < 0) {
+ /* decryption failed, silently discard message */
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto err;
+ }
+
+ /* r->length is now just compressed */
+ if (s->expand != NULL) {
+ if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD,
+ SSL_R_COMPRESSED_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+ if (!ssl3_do_uncompress(s, rr)) {
+ al = SSL_AD_DECOMPRESSION_FAILURE;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION);
+ goto f_err;
+ }
+ }
+
+ if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) {
+ al = SSL_AD_RECORD_OVERFLOW;
+ SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG);
+ goto f_err;
+ }
+
+ rr->off = 0;
+ /*-
+ * So at this point the following is true
+ * ssl->s3->rrec.type is the type of record
+ * ssl->s3->rrec.length == number of bytes in record
+ * ssl->s3->rrec.off == offset to first valid byte
+ * ssl->s3->rrec.data == where to take bytes from, increment
+ * after use :-).
+ */
+
+ /* we have pulled in a full packet so zero things */
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+
+ /* Mark receipt of record. */
+ dtls1_record_bitmap_update(s, bitmap);
+
+ return (1);
+
+ f_err:
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ err:
+ return (0);
+}
+
+/*
+ * Retrieve a buffered record that belongs to the current epoch, i.e. processed
+ */
+#define dtls1_get_processed_record(s) \
+ dtls1_retrieve_buffered_record((s), \
+ &(DTLS_RECORD_LAYER_get_processed_rcds(&s->rlayer)))
+
+/*-
+ * Call this to get a new input record.
+ * It will return <= 0 if more data is needed, normally due to an error
+ * or non-blocking IO.
+ * When it finishes, one packet has been decoded and can be found in
+ * ssl->s3->rrec.type - is the type of record
+ * ssl->s3->rrec.data, - data
+ * ssl->s3->rrec.length, - number of bytes
+ */
+/* used only by dtls1_read_bytes */
+int dtls1_get_record(SSL *s)
+{
+ int ssl_major, ssl_minor;
+ int i, n;
+ SSL3_RECORD *rr;
+ unsigned char *p = NULL;
+ unsigned short version;
+ DTLS1_BITMAP *bitmap;
+ unsigned int is_next_epoch;
+
+ rr = RECORD_LAYER_get_rrec(&s->rlayer);
+
+ 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))
+ return -1;
+
+ /* if we're renegotiating, then there may be buffered records */
+ if (dtls1_get_processed_record(s))
+ return 1;
+
+ /* get something from the wire */
+
+ /* check if we have the header */
+ if ((RECORD_LAYER_get_rstate(&s->rlayer) != SSL_ST_READ_BODY) ||
+ (RECORD_LAYER_get_packet_length(&s->rlayer) < DTLS1_RT_HEADER_LENGTH)) {
+ n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH,
+ SSL3_BUFFER_get_len(&s->rlayer.rbuf), 0, 1);
+ /* read timeout is handled by dtls1_read_bytes */
+ if (n <= 0)
+ return (n); /* error or non-blocking */
+
+ /* this packet contained a partial record, dump it */
+ if (RECORD_LAYER_get_packet_length(&s->rlayer) !=
+ DTLS1_RT_HEADER_LENGTH) {
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto again;
+ }
+
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_BODY);
+
+ p = RECORD_LAYER_get_packet(&s->rlayer);
+
+ if (s->msg_callback)
+ s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH,
+ s, s->msg_callback_arg);
+
+ /* Pull apart the header into the DTLS1_RECORD */
+ rr->type = *(p++);
+ ssl_major = *(p++);
+ ssl_minor = *(p++);
+ version = (ssl_major << 8) | ssl_minor;
+
+ /* sequence number is 64 bits, with top 2 bytes = epoch */
+ n2s(p, rr->epoch);
+
+ memcpy(&(RECORD_LAYER_get_read_sequence(&s->rlayer)[2]), p, 6);
+ p += 6;
+
+ n2s(p, rr->length);
+
+ /*
+ * Lets check the version. We tolerate alerts that don't have the exact
+ * version number (e.g. because of protocol version errors)
+ */
+ if (!s->first_packet && rr->type != SSL3_RT_ALERT) {
+ if (version != s->version) {
+ /* unexpected version, silently discard */
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto again;
+ }
+ }
+
+ if ((version & 0xff00) != (s->version & 0xff00)) {
+ /* wrong version, silently discard record */
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto again;
+ }
+
+ if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+ /* record too long, silently discard it */
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto again;
+ }
+
+ /* now s->rlayer.rstate == SSL_ST_READ_BODY */
+ }
+
+ /* s->rlayer.rstate == SSL_ST_READ_BODY, get and decode the data */
+
+ if (rr->length >
+ RECORD_LAYER_get_packet_length(&s->rlayer) - DTLS1_RT_HEADER_LENGTH) {
+ /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
+ i = rr->length;
+ n = ssl3_read_n(s, i, i, 1, 1);
+ /* this packet contained a partial record, dump it */
+ if (n != i) {
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto again;
+ }
+
+ /*
+ * now n == rr->length, and s->packet_length ==
+ * DTLS1_RT_HEADER_LENGTH + rr->length
+ */
+ }
+ /* set state for later operations */
+ RECORD_LAYER_set_rstate(&s->rlayer, SSL_ST_READ_HEADER);
+
+ /* match epochs. NULL means the packet is dropped on the floor */
+ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+ if (bitmap == NULL) {
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+ goto again; /* get another record */
+ }
+#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. */
+ /*
+ * TODO: Does it make sense to have replay protection in epoch 0 where
+ * we have no integrity negotiated yet?
+ */
+ if (!dtls1_record_replay_check(s, bitmap)) {
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+ goto again; /* get another record */
+ }
+#ifndef OPENSSL_NO_SCTP
+ }
+#endif
+
+ /* just read a 0 length packet */
+ if (rr->length == 0)
+ goto again;
+
+ /*
+ * If this record is from the next epoch (either HM or ALERT), and a
+ * handshake is currently in progress, buffer it since it cannot be
+ * processed at this time.
+ */
+ if (is_next_epoch) {
+ if ((SSL_in_init(s) || ossl_statem_get_in_handshake(s))) {
+ if (dtls1_buffer_record
+ (s, &(DTLS_RECORD_LAYER_get_unprocessed_rcds(&s->rlayer)),
+ rr->seq_num) < 0)
+ return -1;
+ }
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer);
+ goto again;
+ }
+
+ if (!dtls1_process_record(s, bitmap)) {
+ rr->length = 0;
+ RECORD_LAYER_reset_packet_length(&s->rlayer); /* dump this record */
+ goto again; /* get another record */
+ }
+
+ return (1);
+
+}
diff --git a/openssl-1.1.0h/ssl/s3_cbc.c b/openssl-1.1.0h/ssl/s3_cbc.c
new file mode 100644
index 0000000..9a228f7
--- /dev/null
+++ b/openssl-1.1.0h/ssl/s3_cbc.c
@@ -0,0 +1,529 @@
+/*
+ * Copyright 2012-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/constant_time_locl.h"
+#include "ssl_locl.h"
+
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+
+/*
+ * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's
+ * length field. (SHA-384/512 have 128-bit length.)
+ */
+#define MAX_HASH_BIT_COUNT_BYTES 16
+
+/*
+ * MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support.
+ * Currently SHA-384/512 has a 128-byte block size and that's the largest
+ * supported by TLS.)
+ */
+#define MAX_HASH_BLOCK_SIZE 128
+
+/*
+ * u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
+ * little-endian order. The value of p is advanced by four.
+ */
+#define u32toLE(n, p) \
+ (*((p)++)=(unsigned char)(n), \
+ *((p)++)=(unsigned char)(n>>8), \
+ *((p)++)=(unsigned char)(n>>16), \
+ *((p)++)=(unsigned char)(n>>24))
+
+/*
+ * These functions serialize the state of a hash and thus perform the
+ * standard "final" operation without adding the padding and length that such
+ * a function typically does.
+ */
+static void tls1_md5_final_raw(void *ctx, unsigned char *md_out)
+{
+ MD5_CTX *md5 = ctx;
+ u32toLE(md5->A, md_out);
+ u32toLE(md5->B, md_out);
+ u32toLE(md5->C, md_out);
+ u32toLE(md5->D, md_out);
+}
+
+static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out)
+{
+ SHA_CTX *sha1 = ctx;
+ l2n(sha1->h0, md_out);
+ l2n(sha1->h1, md_out);
+ l2n(sha1->h2, md_out);
+ l2n(sha1->h3, md_out);
+ l2n(sha1->h4, md_out);
+}
+
+static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out)
+{
+ SHA256_CTX *sha256 = ctx;
+ unsigned i;
+
+ for (i = 0; i < 8; i++) {
+ l2n(sha256->h[i], md_out);
+ }
+}
+
+static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out)
+{
+ SHA512_CTX *sha512 = ctx;
+ unsigned i;
+
+ for (i = 0; i < 8; i++) {
+ l2n8(sha512->h[i], md_out);
+ }
+}
+
+#undef LARGEST_DIGEST_CTX
+#define LARGEST_DIGEST_CTX SHA512_CTX
+
+/*
+ * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function
+ * which ssl3_cbc_digest_record supports.
+ */
+char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx)
+{
+ if (FIPS_mode())
+ return 0;
+ switch (EVP_MD_CTX_type(ctx)) {
+ case NID_md5:
+ case NID_sha1:
+ case NID_sha224:
+ case NID_sha256:
+ case NID_sha384:
+ case NID_sha512:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/*-
+ * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS
+ * record.
+ *
+ * ctx: the EVP_MD_CTX from which we take the hash function.
+ * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX.
+ * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written.
+ * md_out_size: if non-NULL, the number of output bytes is written here.
+ * header: the 13-byte, TLS record header.
+ * data: the record data itself, less any preceding explicit IV.
+ * data_plus_mac_size: the secret, reported length of the data and MAC
+ * once the padding has been removed.
+ * data_plus_mac_plus_padding_size: the public length of the whole
+ * record, including padding.
+ * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS.
+ *
+ * On entry: by virtue of having been through one of the remove_padding
+ * functions, above, we know that data_plus_mac_size is large enough to contain
+ * a padding byte and MAC. (If the padding was invalid, it might contain the
+ * padding too. )
+ * Returns 1 on success or 0 on error
+ */
+int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
+ unsigned char *md_out,
+ size_t *md_out_size,
+ const unsigned char header[13],
+ const unsigned char *data,
+ size_t data_plus_mac_size,
+ size_t data_plus_mac_plus_padding_size,
+ const unsigned char *mac_secret,
+ unsigned mac_secret_length, char is_sslv3)
+{
+ union {
+ double align;
+ unsigned char c[sizeof(LARGEST_DIGEST_CTX)];
+ } md_state;
+ void (*md_final_raw) (void *ctx, unsigned char *md_out);
+ void (*md_transform) (void *ctx, const unsigned char *block);
+ unsigned md_size, md_block_size = 64;
+ unsigned sslv3_pad_length = 40, header_length, variance_blocks,
+ len, max_mac_bytes, num_blocks,
+ num_starting_blocks, k, mac_end_offset, c, index_a, index_b;
+ unsigned int bits; /* at most 18 bits */
+ unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES];
+ /* hmac_pad is the masked HMAC key. */
+ unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE];
+ unsigned char first_block[MAX_HASH_BLOCK_SIZE];
+ unsigned char mac_out[EVP_MAX_MD_SIZE];
+ unsigned i, j, md_out_size_u;
+ EVP_MD_CTX *md_ctx = NULL;
+ /*
+ * mdLengthSize is the number of bytes in the length field that
+ * terminates * the hash.
+ */
+ unsigned md_length_size = 8;
+ char length_is_big_endian = 1;
+ int ret;
+
+ /*
+ * This is a, hopefully redundant, check that allows us to forget about
+ * many possible overflows later in this function.
+ */
+ OPENSSL_assert(data_plus_mac_plus_padding_size < 1024 * 1024);
+
+ switch (EVP_MD_CTX_type(ctx)) {
+ case NID_md5:
+ if (MD5_Init((MD5_CTX *)md_state.c) <= 0)
+ return 0;
+ md_final_raw = tls1_md5_final_raw;
+ md_transform =
+ (void (*)(void *ctx, const unsigned char *block))MD5_Transform;
+ md_size = 16;
+ sslv3_pad_length = 48;
+ length_is_big_endian = 0;
+ break;
+ case NID_sha1:
+ if (SHA1_Init((SHA_CTX *)md_state.c) <= 0)
+ return 0;
+ md_final_raw = tls1_sha1_final_raw;
+ md_transform =
+ (void (*)(void *ctx, const unsigned char *block))SHA1_Transform;
+ md_size = 20;
+ break;
+ case NID_sha224:
+ if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0)
+ return 0;
+ md_final_raw = tls1_sha256_final_raw;
+ md_transform =
+ (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
+ md_size = 224 / 8;
+ break;
+ case NID_sha256:
+ if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0)
+ return 0;
+ md_final_raw = tls1_sha256_final_raw;
+ md_transform =
+ (void (*)(void *ctx, const unsigned char *block))SHA256_Transform;
+ md_size = 32;
+ break;
+ case NID_sha384:
+ if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0)
+ return 0;
+ md_final_raw = tls1_sha512_final_raw;
+ md_transform =
+ (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
+ md_size = 384 / 8;
+ md_block_size = 128;
+ md_length_size = 16;
+ break;
+ case NID_sha512:
+ if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0)
+ return 0;
+ md_final_raw = tls1_sha512_final_raw;
+ md_transform =
+ (void (*)(void *ctx, const unsigned char *block))SHA512_Transform;
+ md_size = 64;
+ md_block_size = 128;
+ md_length_size = 16;
+ break;
+ default:
+ /*
+ * ssl3_cbc_record_digest_supported should have been called first to
+ * check that the hash function is supported.
+ */
+ OPENSSL_assert(0);
+ if (md_out_size)
+ *md_out_size = 0;
+ return 0;
+ }
+
+ OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES);
+ OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE);
+ OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE);
+
+ header_length = 13;
+ if (is_sslv3) {
+ header_length = mac_secret_length + sslv3_pad_length + 8 /* sequence
+ * number */ +
+ 1 /* record type */ +
+ 2 /* record length */ ;
+ }
+
+ /*
+ * variance_blocks is the number of blocks of the hash that we have to
+ * calculate in constant time because they could be altered by the
+ * padding value. In SSLv3, the padding must be minimal so the end of
+ * the plaintext varies by, at most, 15+20 = 35 bytes. (We conservatively
+ * assume that the MAC size varies from 0..20 bytes.) In case the 9 bytes
+ * of hash termination (0x80 + 64-bit length) don't fit in the final
+ * block, we say that the final two blocks can vary based on the padding.
+ * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
+ * required to be minimal. Therefore we say that the final six blocks can
+ * vary based on the padding. Later in the function, if the message is
+ * short and there obviously cannot be this many blocks then
+ * variance_blocks can be reduced.
+ */
+ variance_blocks = is_sslv3 ? 2 : 6;
+ /*
+ * From now on we're dealing with the MAC, which conceptually has 13
+ * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+ * (SSLv3)
+ */
+ len = data_plus_mac_plus_padding_size + header_length;
+ /*
+ * max_mac_bytes contains the maximum bytes of bytes in the MAC,
+ * including * |header|, assuming that there's no padding.
+ */
+ max_mac_bytes = len - md_size - 1;
+ /* num_blocks is the maximum number of hash blocks. */
+ num_blocks =
+ (max_mac_bytes + 1 + md_length_size + md_block_size -
+ 1) / md_block_size;
+ /*
+ * In order to calculate the MAC in constant time we have to handle the
+ * final blocks specially because the padding value could cause the end
+ * to appear somewhere in the final |variance_blocks| blocks and we can't
+ * leak where. However, |num_starting_blocks| worth of data can be hashed
+ * right away because no padding value can affect whether they are
+ * plaintext.
+ */
+ num_starting_blocks = 0;
+ /*
+ * k is the starting byte offset into the conceptual header||data where
+ * we start processing.
+ */
+ k = 0;
+ /*
+ * mac_end_offset is the index just past the end of the data to be MACed.
+ */
+ mac_end_offset = data_plus_mac_size + header_length - md_size;
+ /*
+ * c is the index of the 0x80 byte in the final hash block that contains
+ * application data.
+ */
+ c = mac_end_offset % md_block_size;
+ /*
+ * index_a is the hash block number that contains the 0x80 terminating
+ * value.
+ */
+ index_a = mac_end_offset / md_block_size;
+ /*
+ * index_b is the hash block number that contains the 64-bit hash length,
+ * in bits.
+ */
+ index_b = (mac_end_offset + md_length_size) / md_block_size;
+ /*
+ * bits is the hash-length in bits. It includes the additional hash block
+ * for the masked HMAC key, or whole of |header| in the case of SSLv3.
+ */
+
+ /*
+ * For SSLv3, if we're going to have any starting blocks then we need at
+ * least two because the header is larger than a single block.
+ */
+ if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) {
+ num_starting_blocks = num_blocks - variance_blocks;
+ k = md_block_size * num_starting_blocks;
+ }
+
+ bits = 8 * mac_end_offset;
+ if (!is_sslv3) {
+ /*
+ * Compute the initial HMAC block. For SSLv3, the padding and secret
+ * bytes are included in |header| because they take more than a
+ * single block.
+ */
+ bits += 8 * md_block_size;
+ memset(hmac_pad, 0, md_block_size);
+ OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad));
+ memcpy(hmac_pad, mac_secret, mac_secret_length);
+ for (i = 0; i < md_block_size; i++)
+ hmac_pad[i] ^= 0x36;
+
+ md_transform(md_state.c, hmac_pad);
+ }
+
+ if (length_is_big_endian) {
+ memset(length_bytes, 0, md_length_size - 4);
+ length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24);
+ length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16);
+ length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8);
+ length_bytes[md_length_size - 1] = (unsigned char)bits;
+ } else {
+ memset(length_bytes, 0, md_length_size);
+ length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24);
+ length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16);
+ length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8);
+ length_bytes[md_length_size - 8] = (unsigned char)bits;
+ }
+
+ if (k > 0) {
+ if (is_sslv3) {
+ unsigned overhang;
+
+ /*
+ * The SSLv3 header is larger than a single block. overhang is
+ * the number of bytes beyond a single block that the header
+ * consumes: either 7 bytes (SHA1) or 11 bytes (MD5). There are no
+ * ciphersuites in SSLv3 that are not SHA1 or MD5 based and
+ * therefore we can be confident that the header_length will be
+ * greater than |md_block_size|. However we add a sanity check just
+ * in case
+ */
+ if (header_length <= md_block_size) {
+ /* Should never happen */
+ return 0;
+ }
+ overhang = header_length - md_block_size;
+ md_transform(md_state.c, header);
+ memcpy(first_block, header + md_block_size, overhang);
+ memcpy(first_block + overhang, data, md_block_size - overhang);
+ md_transform(md_state.c, first_block);
+ for (i = 1; i < k / md_block_size - 1; i++)
+ md_transform(md_state.c, data + md_block_size * i - overhang);
+ } else {
+ /* k is a multiple of md_block_size. */
+ memcpy(first_block, header, 13);
+ memcpy(first_block + 13, data, md_block_size - 13);
+ md_transform(md_state.c, first_block);
+ for (i = 1; i < k / md_block_size; i++)
+ md_transform(md_state.c, data + md_block_size * i - 13);
+ }
+ }
+
+ memset(mac_out, 0, sizeof(mac_out));
+
+ /*
+ * We now process the final hash blocks. For each block, we construct it
+ * in constant time. If the |i==index_a| then we'll include the 0x80
+ * bytes and zero pad etc. For each block we selectively copy it, in
+ * constant time, to |mac_out|.
+ */
+ for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks;
+ i++) {
+ unsigned char block[MAX_HASH_BLOCK_SIZE];
+ unsigned char is_block_a = constant_time_eq_8(i, index_a);
+ unsigned char is_block_b = constant_time_eq_8(i, index_b);
+ for (j = 0; j < md_block_size; j++) {
+ unsigned char b = 0, is_past_c, is_past_cp1;
+ if (k < header_length)
+ b = header[k];
+ else if (k < data_plus_mac_plus_padding_size + header_length)
+ b = data[k - header_length];
+ k++;
+
+ is_past_c = is_block_a & constant_time_ge_8(j, c);
+ is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1);
+ /*
+ * If this is the block containing the end of the application
+ * data, and we are at the offset for the 0x80 value, then
+ * overwrite b with 0x80.
+ */
+ b = constant_time_select_8(is_past_c, 0x80, b);
+ /*
+ * If this the the block containing the end of the application
+ * data and we're past the 0x80 value then just write zero.
+ */
+ b = b & ~is_past_cp1;
+ /*
+ * If this is index_b (the final block), but not index_a (the end
+ * of the data), then the 64-bit length didn't fit into index_a
+ * and we're having to add an extra block of zeros.
+ */
+ b &= ~is_block_b | is_block_a;
+
+ /*
+ * The final bytes of one of the blocks contains the length.
+ */
+ if (j >= md_block_size - md_length_size) {
+ /* If this is index_b, write a length byte. */
+ b = constant_time_select_8(is_block_b,
+ length_bytes[j -
+ (md_block_size -
+ md_length_size)], b);
+ }
+ block[j] = b;
+ }
+
+ md_transform(md_state.c, block);
+ md_final_raw(md_state.c, block);
+ /* If this is index_b, copy the hash value to |mac_out|. */
+ for (j = 0; j < md_size; j++)
+ mac_out[j] |= block[j] & is_block_b;
+ }
+
+ md_ctx = EVP_MD_CTX_new();
+ if (md_ctx == NULL)
+ goto err;
+ if (EVP_DigestInit_ex(md_ctx, EVP_MD_CTX_md(ctx), NULL /* engine */ ) <= 0)
+ goto err;
+ if (is_sslv3) {
+ /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */
+ memset(hmac_pad, 0x5c, sslv3_pad_length);
+
+ if (EVP_DigestUpdate(md_ctx, mac_secret, mac_secret_length) <= 0
+ || EVP_DigestUpdate(md_ctx, hmac_pad, sslv3_pad_length) <= 0
+ || EVP_DigestUpdate(md_ctx, mac_out, md_size) <= 0)
+ goto err;
+ } else {
+ /* Complete the HMAC in the standard manner. */
+ for (i = 0; i < md_block_size; i++)
+ hmac_pad[i] ^= 0x6a;
+
+ if (EVP_DigestUpdate(md_ctx, hmac_pad, md_block_size) <= 0
+ || EVP_DigestUpdate(md_ctx, mac_out, md_size) <= 0)
+ goto err;
+ }
+ ret = EVP_DigestFinal(md_ctx, md_out, &md_out_size_u);
+ if (ret && md_out_size)
+ *md_out_size = md_out_size_u;
+ EVP_MD_CTX_free(md_ctx);
+
+ return 1;
+ err:
+ EVP_MD_CTX_free(md_ctx);
+ return 0;
+}
+
+/*
+ * Due to the need to use EVP in FIPS mode we can't reimplement digests but
+ * we can ensure the number of blocks processed is equal for all cases by
+ * digesting additional data.
+ */
+
+int tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx,
+ EVP_MD_CTX *mac_ctx, const unsigned char *data,
+ size_t data_len, size_t orig_len)
+{
+ size_t block_size, digest_pad, blocks_data, blocks_orig;
+ if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE)
+ return 1;
+ block_size = EVP_MD_CTX_block_size(mac_ctx);
+ /*-
+ * We are in FIPS mode if we get this far so we know we have only SHA*
+ * digests and TLS to deal with.
+ * Minimum digest padding length is 17 for SHA384/SHA512 and 9
+ * otherwise.
+ * Additional header is 13 bytes. To get the number of digest blocks
+ * processed round up the amount of data plus padding to the nearest
+ * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise.
+ * So we have:
+ * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size
+ * equivalently:
+ * blocks = (payload_len + digest_pad + 12)/block_size + 1
+ * HMAC adds a constant overhead.
+ * We're ultimately only interested in differences so this becomes
+ * blocks = (payload_len + 29)/128
+ * for SHA384/SHA512 and
+ * blocks = (payload_len + 21)/64
+ * otherwise.
+ */
+ digest_pad = block_size == 64 ? 21 : 29;
+ blocks_orig = (orig_len + digest_pad) / block_size;
+ blocks_data = (data_len + digest_pad) / block_size;
+ /*
+ * MAC enough blocks to make up the difference between the original and
+ * actual lengths plus one extra block to ensure this is never a no op.
+ * The "data" pointer should always have enough space to perform this
+ * operation as it is large enough for a maximum length TLS buffer.
+ */
+ return EVP_DigestSignUpdate(mac_ctx, data,
+ (blocks_orig - blocks_data + 1) * block_size);
+}
diff --git a/openssl-1.1.0h/ssl/s3_enc.c b/openssl-1.1.0h/ssl/s3_enc.c
new file mode 100644
index 0000000..e08857d
--- /dev/null
+++ b/openssl-1.1.0h/ssl/s3_enc.c
@@ -0,0 +1,550 @@
+/*
+ * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+/* ====================================================================
+ * Copyright 2005 Nokia. All rights reserved.
+ *
+ * The portions of the attached software ("Contribution") is developed by
+ * Nokia Corporation and is licensed pursuant to the OpenSSL open source
+ * license.
+ *
+ * The Contribution, originally written by Mika Kousa and Pasi Eronen of
+ * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
+ * support (see RFC 4279) to OpenSSL.
+ *
+ * No patent licenses or other rights except those expressly stated in
+ * the OpenSSL open source license shall be deemed granted or received
+ * expressly, by implication, estoppel, or otherwise.
+ *
+ * No assurances are provided by Nokia that the Contribution does not
+ * infringe the patent or other intellectual property rights of any third
+ * party or that the license provides you with all the necessary rights
+ * to make use of the Contribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
+ * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
+ * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
+ * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
+ * OTHERWISE.
+ */
+
+#include <stdio.h>
+#include "ssl_locl.h"
+#include <openssl/evp.h>
+#include <openssl/md5.h>
+
+static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
+{
+ EVP_MD_CTX *m5;
+ EVP_MD_CTX *s1;
+ unsigned char buf[16], smd[SHA_DIGEST_LENGTH];
+ unsigned char c = 'A';
+ unsigned int i, j, k;
+ int ret = 0;
+
+#ifdef CHARSET_EBCDIC
+ c = os_toascii[c]; /* 'A' in ASCII */
+#endif
+ k = 0;
+ m5 = EVP_MD_CTX_new();
+ s1 = EVP_MD_CTX_new();
+ if (m5 == NULL || s1 == NULL) {
+ SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ EVP_MD_CTX_set_flags(m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+ for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
+ k++;
+ if (k > sizeof(buf)) {
+ /* bug: 'buf' is too small for this ciphersuite */
+ SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
+ for (j = 0; j < k; j++)
+ buf[j] = c;
+ c++;
+ 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)
+ || !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 err;
+ if ((int)(i + MD5_DIGEST_LENGTH) > num) {
+ if (!EVP_DigestFinal_ex(m5, smd, NULL))
+ goto err;
+ memcpy(km, smd, (num - i));
+ } else {
+ if (!EVP_DigestFinal_ex(m5, km, NULL))
+ goto err;
+ }
+
+ km += MD5_DIGEST_LENGTH;
+ }
+ OPENSSL_cleanse(smd, sizeof(smd));
+ ret = 1;
+ err:
+ EVP_MD_CTX_free(m5);
+ EVP_MD_CTX_free(s1);
+ return ret;
+}
+
+int ssl3_change_cipher_state(SSL *s, int which)
+{
+ unsigned char *p, *mac_secret;
+ unsigned char exp_key[EVP_MAX_KEY_LENGTH];
+ unsigned char exp_iv[EVP_MAX_IV_LENGTH];
+ unsigned char *ms, *key, *iv;
+ EVP_CIPHER_CTX *dd;
+ const EVP_CIPHER *c;
+#ifndef OPENSSL_NO_COMP
+ COMP_METHOD *comp;
+#endif
+ const EVP_MD *m;
+ int n, i, j, k, cl;
+ int reuse_dd = 0;
+
+ c = s->s3->tmp.new_sym_enc;
+ m = s->s3->tmp.new_hash;
+ /* m == NULL will lead to a crash later */
+ OPENSSL_assert(m);
+#ifndef OPENSSL_NO_COMP
+ if (s->s3->tmp.new_compression == NULL)
+ comp = NULL;
+ else
+ comp = s->s3->tmp.new_compression->method;
+#endif
+
+ if (which & SSL3_CC_READ) {
+ if (s->enc_read_ctx != NULL)
+ reuse_dd = 1;
+ else if ((s->enc_read_ctx = EVP_CIPHER_CTX_new()) == NULL)
+ goto err;
+ else
+ /*
+ * make sure it's initialised in case we exit later with an error
+ */
+ EVP_CIPHER_CTX_reset(s->enc_read_ctx);
+ dd = s->enc_read_ctx;
+
+ if (ssl_replace_hash(&s->read_hash, m) == NULL) {
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err2;
+ }
+#ifndef OPENSSL_NO_COMP
+ /* COMPRESS */
+ COMP_CTX_free(s->expand);
+ s->expand = NULL;
+ if (comp != NULL) {
+ s->expand = COMP_CTX_new(comp);
+ if (s->expand == NULL) {
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
+ SSL_R_COMPRESSION_LIBRARY_ERROR);
+ goto err2;
+ }
+ }
+#endif
+ RECORD_LAYER_reset_read_sequence(&s->rlayer);
+ mac_secret = &(s->s3->read_mac_secret[0]);
+ } else {
+ if (s->enc_write_ctx != NULL)
+ reuse_dd = 1;
+ else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL)
+ goto err;
+ else
+ /*
+ * make sure it's initialised in case we exit later with an error
+ */
+ EVP_CIPHER_CTX_reset(s->enc_write_ctx);
+ dd = s->enc_write_ctx;
+ if (ssl_replace_hash(&s->write_hash, m) == NULL) {
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err2;
+ }
+#ifndef OPENSSL_NO_COMP
+ /* COMPRESS */
+ COMP_CTX_free(s->compress);
+ s->compress = NULL;
+ if (comp != NULL) {
+ s->compress = COMP_CTX_new(comp);
+ if (s->compress == NULL) {
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE,
+ SSL_R_COMPRESSION_LIBRARY_ERROR);
+ goto err2;
+ }
+ }
+#endif
+ RECORD_LAYER_reset_write_sequence(&s->rlayer);
+ mac_secret = &(s->s3->write_mac_secret[0]);
+ }
+
+ if (reuse_dd)
+ EVP_CIPHER_CTX_reset(dd);
+
+ p = s->s3->tmp.key_block;
+ i = EVP_MD_size(m);
+ if (i < 0)
+ goto err2;
+ cl = EVP_CIPHER_key_length(c);
+ j = cl;
+ k = EVP_CIPHER_iv_length(c);
+ if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) ||
+ (which == SSL3_CHANGE_CIPHER_SERVER_READ)) {
+ ms = &(p[0]);
+ n = i + i;
+ key = &(p[n]);
+ n += j + j;
+ iv = &(p[n]);
+ n += k + k;
+ } else {
+ n = i;
+ ms = &(p[n]);
+ n += i + j;
+ key = &(p[n]);
+ n += j + k;
+ iv = &(p[n]);
+ n += k;
+ }
+
+ if (n > s->s3->tmp.key_block_length) {
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR);
+ goto err2;
+ }
+
+ memcpy(mac_secret, ms, i);
+
+ if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)))
+ goto err2;
+
+ OPENSSL_cleanse(exp_key, sizeof(exp_key));
+ OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
+ return (1);
+ err:
+ SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
+ err2:
+ OPENSSL_cleanse(exp_key, sizeof(exp_key));
+ OPENSSL_cleanse(exp_iv, sizeof(exp_iv));
+ return (0);
+}
+
+int ssl3_setup_key_block(SSL *s)
+{
+ unsigned char *p;
+ const EVP_CIPHER *c;
+ const EVP_MD *hash;
+ int num;
+ int ret = 0;
+ SSL_COMP *comp;
+
+ if (s->s3->tmp.key_block_length != 0)
+ return (1);
+
+ if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp, 0)) {
+ SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+ return (0);
+ }
+
+ s->s3->tmp.new_sym_enc = c;
+ s->s3->tmp.new_hash = hash;
+#ifdef OPENSSL_NO_COMP
+ s->s3->tmp.new_compression = NULL;
+#else
+ s->s3->tmp.new_compression = comp;
+#endif
+
+ num = EVP_MD_size(hash);
+ if (num < 0)
+ return 0;
+
+ num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c);
+ num *= 2;
+
+ ssl3_cleanup_key_block(s);
+
+ if ((p = OPENSSL_malloc(num)) == NULL)
+ goto err;
+
+ s->s3->tmp.key_block_length = num;
+ s->s3->tmp.key_block = p;
+
+ ret = ssl3_generate_key_block(s, p, num);
+
+ if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) {
+ /*
+ * enable vulnerability countermeasure for CBC ciphers with known-IV
+ * problem (http://www.openssl.org/~bodo/tls-cbc.txt)
+ */
+ s->s3->need_empty_fragments = 1;
+
+ if (s->session->cipher != NULL) {
+ if (s->session->cipher->algorithm_enc == SSL_eNULL)
+ s->s3->need_empty_fragments = 0;
+
+#ifndef OPENSSL_NO_RC4
+ if (s->session->cipher->algorithm_enc == SSL_RC4)
+ s->s3->need_empty_fragments = 0;
+#endif
+ }
+ }
+
+ return ret;
+
+ err:
+ SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
+ return (0);
+}
+
+void ssl3_cleanup_key_block(SSL *s)
+{
+ OPENSSL_clear_free(s->s3->tmp.key_block, s->s3->tmp.key_block_length);
+ s->s3->tmp.key_block = NULL;
+ s->s3->tmp.key_block_length = 0;
+}
+
+int ssl3_init_finished_mac(SSL *s)
+{
+ BIO *buf = BIO_new(BIO_s_mem());
+
+ if (buf == NULL) {
+ SSLerr(SSL_F_SSL3_INIT_FINISHED_MAC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ ssl3_free_digest_list(s);
+ s->s3->handshake_buffer = buf;
+ (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
+ return 1;
+}
+
+/*
+ * Free digest list. Also frees handshake buffer since they are always freed
+ * together.
+ */
+
+void ssl3_free_digest_list(SSL *s)
+{
+ BIO_free(s->s3->handshake_buffer);
+ s->s3->handshake_buffer = NULL;
+ EVP_MD_CTX_free(s->s3->handshake_dgst);
+ s->s3->handshake_dgst = NULL;
+}
+
+int ssl3_finish_mac(SSL *s, const unsigned char *buf, int len)
+{
+ if (s->s3->handshake_dgst == NULL)
+ /* Note: this writes to a memory BIO so a failure is a fatal error */
+ return BIO_write(s->s3->handshake_buffer, (void *)buf, len) == len;
+ else
+ return EVP_DigestUpdate(s->s3->handshake_dgst, buf, len);
+}
+
+int ssl3_digest_cached_records(SSL *s, int keep)
+{
+ const EVP_MD *md;
+ long hdatalen;
+ void *hdata;
+
+ if (s->s3->handshake_dgst == NULL) {
+ hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
+ if (hdatalen <= 0) {
+ SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS,
+ SSL_R_BAD_HANDSHAKE_LENGTH);
+ return 0;
+ }
+
+ s->s3->handshake_dgst = EVP_MD_CTX_new();
+ if (s->s3->handshake_dgst == NULL) {
+ SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ md = ssl_handshake_md(s);
+ if (md == NULL || !EVP_DigestInit_ex(s->s3->handshake_dgst, md, NULL)
+ || !EVP_DigestUpdate(s->s3->handshake_dgst, hdata, hdatalen)) {
+ SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ }
+ if (keep == 0) {
+ BIO_free(s->s3->handshake_buffer);
+ s->s3->handshake_buffer = NULL;
+ }
+
+ return 1;
+}
+
+int ssl3_final_finish_mac(SSL *s, const char *sender, int len, unsigned char *p)
+{
+ int ret;
+ EVP_MD_CTX *ctx = NULL;
+
+ if (!ssl3_digest_cached_records(s, 0))
+ return 0;
+
+ if (EVP_MD_CTX_type(s->s3->handshake_dgst) != NID_md5_sha1) {
+ SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, SSL_R_NO_REQUIRED_DIGEST);
+ return 0;
+ }
+
+ ctx = EVP_MD_CTX_new();
+ if (ctx == NULL) {
+ SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (!EVP_MD_CTX_copy_ex(ctx, s->s3->handshake_dgst)) {
+ SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ ret = EVP_MD_CTX_size(ctx);
+ if (ret < 0) {
+ EVP_MD_CTX_reset(ctx);
+ return 0;
+ }
+
+ if ((sender != NULL && EVP_DigestUpdate(ctx, sender, len) <= 0)
+ || EVP_MD_CTX_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET,
+ s->session->master_key_length,
+ s->session->master_key) <= 0
+ || EVP_DigestFinal_ex(ctx, p, NULL) <= 0) {
+ SSLerr(SSL_F_SSL3_FINAL_FINISH_MAC, ERR_R_INTERNAL_ERROR);
+ ret = 0;
+ }
+
+ EVP_MD_CTX_free(ctx);
+
+ return ret;
+}
+
+int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
+ int len)
+{
+ static const unsigned char *salt[3] = {
+#ifndef CHARSET_EBCDIC
+ (const unsigned char *)"A",
+ (const unsigned char *)"BB",
+ (const unsigned char *)"CCC",
+#else
+ (const unsigned char *)"\x41",
+ (const unsigned char *)"\x42\x42",
+ (const unsigned char *)"\x43\x43\x43",
+#endif
+ };
+ unsigned char buf[EVP_MAX_MD_SIZE];
+ EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+ int i, ret = 0;
+ unsigned int n;
+
+ if (ctx == NULL) {
+ SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ for (i = 0; i < 3; i++) {
+ if (EVP_DigestInit_ex(ctx, s->ctx->sha1, NULL) <= 0
+ || EVP_DigestUpdate(ctx, salt[i],
+ strlen((const char *)salt[i])) <= 0
+ || EVP_DigestUpdate(ctx, p, len) <= 0
+ || EVP_DigestUpdate(ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestFinal_ex(ctx, buf, &n) <= 0
+ || EVP_DigestInit_ex(ctx, s->ctx->md5, NULL) <= 0
+ || EVP_DigestUpdate(ctx, p, len) <= 0
+ || EVP_DigestUpdate(ctx, buf, n) <= 0
+ || EVP_DigestFinal_ex(ctx, out, &n) <= 0) {
+ SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR);
+ ret = 0;
+ break;
+ }
+ out += n;
+ ret += n;
+ }
+ EVP_MD_CTX_free(ctx);
+
+ OPENSSL_cleanse(buf, sizeof(buf));
+ return (ret);
+}
+
+int ssl3_alert_code(int code)
+{
+ switch (code) {
+ case SSL_AD_CLOSE_NOTIFY:
+ return (SSL3_AD_CLOSE_NOTIFY);
+ case SSL_AD_UNEXPECTED_MESSAGE:
+ return (SSL3_AD_UNEXPECTED_MESSAGE);
+ case SSL_AD_BAD_RECORD_MAC:
+ return (SSL3_AD_BAD_RECORD_MAC);
+ case SSL_AD_DECRYPTION_FAILED:
+ return (SSL3_AD_BAD_RECORD_MAC);
+ case SSL_AD_RECORD_OVERFLOW:
+ return (SSL3_AD_BAD_RECORD_MAC);
+ case SSL_AD_DECOMPRESSION_FAILURE:
+ return (SSL3_AD_DECOMPRESSION_FAILURE);
+ case SSL_AD_HANDSHAKE_FAILURE:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_NO_CERTIFICATE:
+ return (SSL3_AD_NO_CERTIFICATE);
+ case SSL_AD_BAD_CERTIFICATE:
+ return (SSL3_AD_BAD_CERTIFICATE);
+ case SSL_AD_UNSUPPORTED_CERTIFICATE:
+ return (SSL3_AD_UNSUPPORTED_CERTIFICATE);
+ case SSL_AD_CERTIFICATE_REVOKED:
+ return (SSL3_AD_CERTIFICATE_REVOKED);
+ case SSL_AD_CERTIFICATE_EXPIRED:
+ return (SSL3_AD_CERTIFICATE_EXPIRED);
+ case SSL_AD_CERTIFICATE_UNKNOWN:
+ return (SSL3_AD_CERTIFICATE_UNKNOWN);
+ case SSL_AD_ILLEGAL_PARAMETER:
+ return (SSL3_AD_ILLEGAL_PARAMETER);
+ case SSL_AD_UNKNOWN_CA:
+ return (SSL3_AD_BAD_CERTIFICATE);
+ case SSL_AD_ACCESS_DENIED:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_DECODE_ERROR:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_DECRYPT_ERROR:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_EXPORT_RESTRICTION:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_PROTOCOL_VERSION:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_INSUFFICIENT_SECURITY:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_INTERNAL_ERROR:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_USER_CANCELLED:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_NO_RENEGOTIATION:
+ return (-1); /* Don't send it :-) */
+ case SSL_AD_UNSUPPORTED_EXTENSION:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_CERTIFICATE_UNOBTAINABLE:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_UNRECOGNIZED_NAME:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_BAD_CERTIFICATE_HASH_VALUE:
+ return (SSL3_AD_HANDSHAKE_FAILURE);
+ case SSL_AD_UNKNOWN_PSK_IDENTITY:
+ return (TLS1_AD_UNKNOWN_PSK_IDENTITY);
+ case SSL_AD_INAPPROPRIATE_FALLBACK:
+ return (TLS1_AD_INAPPROPRIATE_FALLBACK);
+ case SSL_AD_NO_APPLICATION_PROTOCOL:
+ return (TLS1_AD_NO_APPLICATION_PROTOCOL);
+ default:
+ return (-1);
+ }
+}
diff --git a/openssl-1.1.0h/ssl/s3_lib.c b/openssl-1.1.0h/ssl/s3_lib.c
new file mode 100644
index 0000000..ad7532b
--- /dev/null
+++ b/openssl-1.1.0h/ssl/s3_lib.c