external/boringssl: Sync to 392cedd0a28f15b693c81c8b877ee3d74c122d42.
am: ae1abf960b
Change-Id: Ia4835872c131299a4a5cb70c9b1dcb045bfa577a
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index 7112211..0bc058b 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-575334657fcb66a4861c9d125430b2aef60476a6
+392cedd0a28f15b693c81c8b877ee3d74c122d42
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0b95a81..43277f9 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -85,8 +85,6 @@
# possible loss of data
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
# possible loss of data
- "C4245" # 'initializing' : conversion from 'long' to
- # 'unsigned long', signed/unsigned mismatch
"C4267" # conversion from 'size_t' to 'int', possible loss of data
"C4371" # layout of class may have changed from a previous version of the
# compiler due to better packing of member '...'
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 8541bbb..1cd8458 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -40,7 +40,7 @@
# CMake does not add -isysroot and -arch flags to assembly.
if (APPLE)
if (CMAKE_OSX_SYSROOT)
- set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot ${CMAKE_OSX_SYSROOT}")
+ set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -isysroot \"${CMAKE_OSX_SYSROOT}\"")
endif()
foreach(arch ${CMAKE_OSX_ARCHITECTURES})
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch ${arch}")
diff --git a/src/crypto/bio/bio_test.cc b/src/crypto/bio/bio_test.cc
index 3d78635..eb54f7e 100644
--- a/src/crypto/bio/bio_test.cc
+++ b/src/crypto/bio/bio_test.cc
@@ -12,10 +12,6 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 201410L
-#endif
-
#include <algorithm>
#include <string>
diff --git a/src/crypto/bio/printf.c b/src/crypto/bio/printf.c
index 28162e6..4f9d8a1 100644
--- a/src/crypto/bio/printf.c
+++ b/src/crypto/bio/printf.c
@@ -54,10 +54,6 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 201410L // for snprintf, vprintf etc
-#endif
-
#include <openssl/bio.h>
#include <assert.h>
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index 04e245e..7b7b833 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -167,7 +167,7 @@
dh->q = q;
}
- if (g == NULL) {
+ if (g != NULL) {
BN_free(dh->g);
dh->g = g;
}
diff --git a/src/crypto/err/err.c b/src/crypto/err/err.c
index 2c567ce..a620fc7 100644
--- a/src/crypto/err/err.c
+++ b/src/crypto/err/err.c
@@ -129,18 +129,9 @@
extern const size_t kOpenSSLReasonValuesLen;
extern const char kOpenSSLReasonStringData[];
-// err_clear_data frees the optional |data| member of the given error.
-static void err_clear_data(struct err_error_st *error) {
- if ((error->flags & ERR_FLAG_MALLOCED) != 0) {
- OPENSSL_free(error->data);
- }
- error->data = NULL;
- error->flags &= ~ERR_FLAG_MALLOCED;
-}
-
// err_clear clears the given queued error.
static void err_clear(struct err_error_st *error) {
- err_clear_data(error);
+ OPENSSL_free(error->data);
OPENSSL_memset(error, 0, sizeof(struct err_error_st));
}
@@ -227,7 +218,7 @@
} else {
*data = error->data;
if (flags != NULL) {
- *flags = error->flags & ERR_FLAG_PUBLIC_MASK;
+ *flags = ERR_FLAG_STRING;
}
// If this error is being removed, take ownership of data from
// the error. The semantics are such that the caller doesn't
@@ -235,12 +226,11 @@
// ownership and retains it until the next call that affects the
// error queue.
if (inc) {
- if (error->flags & ERR_FLAG_MALLOCED) {
+ if (error->data != NULL) {
OPENSSL_free(state->to_free);
state->to_free = error->data;
}
error->data = NULL;
- error->flags = 0;
}
}
}
@@ -585,24 +575,20 @@
ERR_print_errors_cb(print_errors_to_file, file);
}
-// err_set_error_data sets the data on the most recent error. The |flags|
-// argument is a combination of the |ERR_FLAG_*| values.
-static void err_set_error_data(char *data, int flags) {
+// err_set_error_data sets the data on the most recent error.
+static void err_set_error_data(char *data) {
ERR_STATE *const state = err_get_state();
struct err_error_st *error;
if (state == NULL || state->top == state->bottom) {
- if (flags & ERR_FLAG_MALLOCED) {
- OPENSSL_free(data);
- }
+ OPENSSL_free(data);
return;
}
error = &state->errors[state->top];
- err_clear_data(error);
+ OPENSSL_free(error->data);
error->data = data;
- error->flags = flags;
}
void ERR_put_error(int library, int unused, int reason, const char *file,
@@ -680,7 +666,7 @@
}
buf[len] = 0;
- err_set_error_data(buf, ERR_FLAG_MALLOCED | ERR_FLAG_STRING);
+ err_set_error_data(buf);
}
void ERR_add_error_data(unsigned count, ...) {
@@ -708,7 +694,7 @@
buf[buf_len] = 0;
va_end(ap);
- err_set_error_data(buf, ERR_FLAG_MALLOCED | ERR_FLAG_STRING);
+ err_set_error_data(buf);
}
int ERR_set_mark(void) {
@@ -717,7 +703,7 @@
if (state == NULL || state->bottom == state->top) {
return 0;
}
- state->errors[state->top].flags |= ERR_FLAG_MARK;
+ state->errors[state->top].mark = 1;
return 1;
}
@@ -731,8 +717,8 @@
while (state->bottom != state->top) {
struct err_error_st *error = &state->errors[state->top];
- if ((error->flags & ERR_FLAG_MARK) != 0) {
- error->flags &= ~ERR_FLAG_MARK;
+ if (error->mark) {
+ error->mark = 0;
return 1;
}
diff --git a/src/crypto/fipsmodule/sha/sha1.c b/src/crypto/fipsmodule/sha/sha1.c
index 7ce0193..e5b4ba6 100644
--- a/src/crypto/fipsmodule/sha/sha1.c
+++ b/src/crypto/fipsmodule/sha/sha1.c
@@ -63,10 +63,10 @@
#include "../../internal.h"
-#if !defined(OPENSSL_NO_ASM) && \
- (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
- defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \
- defined(OPENSSL_PPC64LE))
+#if (!defined(OPENSSL_NO_ASM) && \
+ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \
+ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))) || \
+ defined(OPENSSL_PPC64LE)
#define SHA1_ASM
#endif
diff --git a/src/crypto/lhash/lhash_test.cc b/src/crypto/lhash/lhash_test.cc
index cc146e8..0859eeb 100644
--- a/src/crypto/lhash/lhash_test.cc
+++ b/src/crypto/lhash/lhash_test.cc
@@ -12,10 +12,6 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 201410L
-#endif
-
#include <openssl/lhash.h>
#include <stdio.h>
diff --git a/src/crypto/mem.c b/src/crypto/mem.c
index 09f3159..67f74b7 100644
--- a/src/crypto/mem.c
+++ b/src/crypto/mem.c
@@ -54,10 +54,6 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#if !defined(_POSIX_C_SOURCE)
-#define _POSIX_C_SOURCE 201410L // needed for strdup, snprintf, vprintf etc
-#endif
-
#include <openssl/mem.h>
#include <assert.h>
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index 0980463..f132e6b 100644
--- a/src/crypto/x509/x_name.c
+++ b/src/crypto/x509/x_name.c
@@ -244,7 +244,7 @@
entry->set = i;
if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
goto err;
- sk_X509_NAME_ENTRY_set(entries, j, NULL);
+ (void)sk_X509_NAME_ENTRY_set(entries, j, NULL);
}
}
ret = x509_name_canon(nm.x);
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index 0a64925..5de3cbd 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -158,6 +158,15 @@
// Reading and formatting errors.
+// ERR_GET_LIB returns the library code for the error. This is one of
+// the |ERR_LIB_*| values.
+#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff))
+
+// ERR_GET_REASON returns the reason code for the error. This is one of
+// library-specific |LIB_R_*| values where |LIB| is the library (see
+// |ERR_GET_LIB|). Note that reason codes are specific to the library.
+#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff))
+
// ERR_get_error gets the packed error code for the least recent error and
// removes that error from the queue. If there are no errors in the queue then
// it returns zero.
@@ -167,6 +176,10 @@
// number of the call that added the error are also returned.
OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line);
+// ERR_FLAG_STRING means that the |data| member is a NUL-terminated string that
+// can be printed. This is always set if |data| is non-NULL.
+#define ERR_FLAG_STRING 1
+
// ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the
// error-specific data pointer and flags. The flags are a bitwise-OR of
// |ERR_FLAG_*| values. The error-specific data is owned by the error queue
@@ -257,67 +270,6 @@
// need to call this function. Use |ERR_clear_error|.
OPENSSL_EXPORT void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
-
-// Custom errors.
-
-// ERR_get_next_error_library returns a value suitable for passing as the
-// |library| argument to |ERR_put_error|. This is intended for code that wishes
-// to push its own, non-standard errors to the error queue.
-OPENSSL_EXPORT int ERR_get_next_error_library(void);
-
-
-// Deprecated functions.
-
-// ERR_remove_state calls |ERR_clear_error|.
-OPENSSL_EXPORT void ERR_remove_state(unsigned long pid);
-
-// ERR_func_error_string returns the string "OPENSSL_internal".
-OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error);
-
-// ERR_error_string behaves like |ERR_error_string_n| but |len| is implicitly
-// |ERR_ERROR_STRING_BUF_LEN| and it returns |buf|. If |buf| is NULL, the error
-// string is placed in a static buffer which is returned. (The static buffer may
-// be overridden by concurrent calls in other threads so this form should not be
-// used.)
-//
-// Use |ERR_error_string_n| instead.
-//
-// TODO(fork): remove this function.
-OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf);
-#define ERR_ERROR_STRING_BUF_LEN 256
-
-
-// Private functions.
-
-// ERR_clear_system_error clears the system's error value (i.e. errno).
-OPENSSL_EXPORT void ERR_clear_system_error(void);
-
-// OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error
-// queue.
-#define OPENSSL_PUT_ERROR(library, reason) \
- ERR_put_error(ERR_LIB_##library, 0, reason, __FILE__, __LINE__)
-
-// OPENSSL_PUT_SYSTEM_ERROR is used by OpenSSL code to add an error from the
-// operating system to the error queue.
-// TODO(fork): include errno.
-#define OPENSSL_PUT_SYSTEM_ERROR() \
- ERR_put_error(ERR_LIB_SYS, 0, 0, __FILE__, __LINE__);
-
-// ERR_put_error adds an error to the error queue, dropping the least recent
-// error if necessary for space reasons.
-OPENSSL_EXPORT void ERR_put_error(int library, int unused, int reason,
- const char *file, unsigned line);
-
-// ERR_add_error_data takes a variable number (|count|) of const char*
-// pointers, concatenates them and sets the result as the data on the most
-// recent error.
-OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...);
-
-// ERR_add_error_dataf takes a printf-style format and arguments, and sets the
-// result as the data on the most recent error.
-OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...)
- OPENSSL_PRINTF_FORMAT_FUNC(1, 2);
-
// ERR_set_mark "marks" the most recent error for use with |ERR_pop_to_mark|.
// It returns one if an error was marked and zero if there are no errors.
OPENSSL_EXPORT int ERR_set_mark(void);
@@ -328,60 +280,18 @@
// are marked using |ERR_set_mark|.
OPENSSL_EXPORT int ERR_pop_to_mark(void);
-struct err_error_st {
- // file contains the filename where the error occurred.
- const char *file;
- // data contains optional data. It must be freed with |OPENSSL_free| if
- // |flags&ERR_FLAG_MALLOCED|.
- char *data;
- // packed contains the error library and reason, as packed by ERR_PACK.
- uint32_t packed;
- // line contains the line number where the error occurred.
- uint16_t line;
- // flags contains a bitwise-OR of ERR_FLAG_* values.
- uint8_t flags;
-};
-// ERR_FLAG_STRING means that the |data| member is a NUL-terminated string that
-// can be printed.
-#define ERR_FLAG_STRING 1
-// ERR_TXT_STRING is provided for compatibility with code that assumes that
-// it's using OpenSSL.
-#define ERR_TXT_STRING ERR_FLAG_STRING
+// Custom errors.
-// ERR_FLAG_PUBLIC_MASK is applied to the flags field before it is returned
-// from functions like |ERR_get_error_line_data|.
-#define ERR_FLAG_PUBLIC_MASK 0xf
+// ERR_get_next_error_library returns a value suitable for passing as the
+// |library| argument to |ERR_put_error|. This is intended for code that wishes
+// to push its own, non-standard errors to the error queue.
+OPENSSL_EXPORT int ERR_get_next_error_library(void);
-// The following flag values are internal and are masked when flags are
-// returned from functions like |ERR_get_error_line_data|.
-// ERR_FLAG_MALLOCED means the the |data| member must be freed when no longer
-// needed.
-#define ERR_FLAG_MALLOCED 16
-// ERR_FLAG_MARK is used to indicate a reversion point in the queue. See
-// |ERR_pop_to_mark|.
-#define ERR_FLAG_MARK 32
+// Built-in library and reason codes.
-// ERR_NUM_ERRORS is the limit of the number of errors in the queue.
-#define ERR_NUM_ERRORS 16
-
-// err_state_st (aka |ERR_STATE|) contains the per-thread, error queue.
-typedef struct err_state_st {
- // errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring
- // buffer.
- struct err_error_st errors[ERR_NUM_ERRORS];
- // top contains the index one past the most recent error. If |top| equals
- // |bottom| then the queue is empty.
- unsigned top;
- // bottom contains the index of the last error in the queue.
- unsigned bottom;
-
- // to_free, if not NULL, contains a pointer owned by this structure that was
- // previously a |data| pointer of one of the elements of |errors|.
- void *to_free;
-} ERR_STATE;
-
+// The following values are built-in library codes.
enum {
ERR_LIB_NONE = 1,
ERR_LIB_SYS,
@@ -418,6 +328,8 @@
ERR_NUM_LIBS
};
+// The following reason codes used to denote an error occuring in another
+// library. They are sometimes used for a stack trace.
#define ERR_R_SYS_LIB ERR_LIB_SYS
#define ERR_R_BN_LIB ERR_LIB_BN
#define ERR_R_RSA_LIB ERR_LIB_RSA
@@ -456,7 +368,7 @@
#define ERR_R_CIPHER_LIB ERR_LIB_CIPHER
#define ERR_R_HKDF_LIB ERR_LIB_HKDF
-// Global reasons.
+// The following values are global reason codes. They may occur in any library.
#define ERR_R_FATAL 64
#define ERR_R_MALLOC_FAILURE (1 | ERR_R_FATAL)
#define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2 | ERR_R_FATAL)
@@ -464,13 +376,102 @@
#define ERR_R_INTERNAL_ERROR (4 | ERR_R_FATAL)
#define ERR_R_OVERFLOW (5 | ERR_R_FATAL)
+
+// Deprecated functions.
+
+// ERR_remove_state calls |ERR_clear_error|.
+OPENSSL_EXPORT void ERR_remove_state(unsigned long pid);
+
+// ERR_func_error_string returns the string "OPENSSL_internal".
+OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error);
+
+// ERR_error_string behaves like |ERR_error_string_n| but |len| is implicitly
+// |ERR_ERROR_STRING_BUF_LEN| and it returns |buf|. If |buf| is NULL, the error
+// string is placed in a static buffer which is returned. (The static buffer may
+// be overridden by concurrent calls in other threads so this form should not be
+// used.)
+//
+// Use |ERR_error_string_n| instead.
+//
+// TODO(fork): remove this function.
+OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf);
+#define ERR_ERROR_STRING_BUF_LEN 256
+
+// ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code.
+#define ERR_GET_FUNC(packed_error) 0
+
+// ERR_TXT_STRING is provided for compatibility with code that assumes that
+// it's using OpenSSL.
+#define ERR_TXT_STRING ERR_FLAG_STRING
+
+
+// Private functions.
+
+// ERR_clear_system_error clears the system's error value (i.e. errno).
+OPENSSL_EXPORT void ERR_clear_system_error(void);
+
+// OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error
+// queue.
+#define OPENSSL_PUT_ERROR(library, reason) \
+ ERR_put_error(ERR_LIB_##library, 0, reason, __FILE__, __LINE__)
+
+// OPENSSL_PUT_SYSTEM_ERROR is used by OpenSSL code to add an error from the
+// operating system to the error queue.
+// TODO(fork): include errno.
+#define OPENSSL_PUT_SYSTEM_ERROR() \
+ ERR_put_error(ERR_LIB_SYS, 0, 0, __FILE__, __LINE__);
+
+// ERR_put_error adds an error to the error queue, dropping the least recent
+// error if necessary for space reasons.
+OPENSSL_EXPORT void ERR_put_error(int library, int unused, int reason,
+ const char *file, unsigned line);
+
+// ERR_add_error_data takes a variable number (|count|) of const char*
+// pointers, concatenates them and sets the result as the data on the most
+// recent error.
+OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...);
+
+// ERR_add_error_dataf takes a printf-style format and arguments, and sets the
+// result as the data on the most recent error.
+OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...)
+ OPENSSL_PRINTF_FORMAT_FUNC(1, 2);
+
+struct err_error_st {
+ // file contains the filename where the error occurred.
+ const char *file;
+ // data contains a NUL-terminated string with optional data. It must be freed
+ // with |OPENSSL_free|.
+ char *data;
+ // packed contains the error library and reason, as packed by ERR_PACK.
+ uint32_t packed;
+ // line contains the line number where the error occurred.
+ uint16_t line;
+ // mark indicates a reversion point in the queue. See |ERR_pop_to_mark|.
+ unsigned mark : 1;
+};
+
+// ERR_NUM_ERRORS is the limit of the number of errors in the queue.
+#define ERR_NUM_ERRORS 16
+
+// err_state_st (aka |ERR_STATE|) contains the per-thread, error queue.
+typedef struct err_state_st {
+ // errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring
+ // buffer.
+ struct err_error_st errors[ERR_NUM_ERRORS];
+ // top contains the index one past the most recent error. If |top| equals
+ // |bottom| then the queue is empty.
+ unsigned top;
+ // bottom contains the index of the last error in the queue.
+ unsigned bottom;
+
+ // to_free, if not NULL, contains a pointer owned by this structure that was
+ // previously a |data| pointer of one of the elements of |errors|.
+ void *to_free;
+} ERR_STATE;
+
#define ERR_PACK(lib, reason) \
(((((uint32_t)(lib)) & 0xff) << 24) | ((((uint32_t)(reason)) & 0xfff)))
-#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff))
-#define ERR_GET_FUNC(packed_error) 0
-#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff))
-
// OPENSSL_DECLARE_ERROR_REASON is used by util/make_errors.h (which generates
// the error defines) to recognise that an additional reason value is needed.
// This is needed when the reason value is used outside of an
diff --git a/src/include/openssl/span.h b/src/include/openssl/span.h
index d447314..3109036 100644
--- a/src/include/openssl/span.h
+++ b/src/include/openssl/span.h
@@ -22,6 +22,7 @@
extern "C++" {
#include <algorithm>
+#include <cstdlib>
#include <type_traits>
namespace bssl {
@@ -104,6 +105,8 @@
std::is_convertible<decltype(std::declval<C>().data()), T *>::value &&
std::is_integral<decltype(std::declval<C>().size())>::value>;
+ static const size_t npos = static_cast<size_t>(-1);
+
public:
constexpr Span() : Span(nullptr, 0) {}
constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {}
@@ -124,6 +127,7 @@
T *data() const { return data_; }
size_t size() const { return size_; }
+ bool empty() const { return size_ == 0; }
T *begin() const { return data_; }
const T *cbegin() const { return data_; }
@@ -133,12 +137,22 @@
T &operator[](size_t i) const { return data_[i]; }
T &at(size_t i) const { return data_[i]; }
+ Span subspan(size_t pos = 0, size_t len = npos) const {
+ if (pos > size_) {
+ abort(); // absl::Span throws an exception here.
+ }
+ return Span(data_ + pos, std::min(size_ - pos, len));
+ }
+
private:
T *data_;
size_t size_;
};
template <typename T>
+const size_t Span<T>::npos;
+
+template <typename T>
Span<T> MakeSpan(T *ptr, size_t size) {
return Span<T>(ptr, size);
}
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index a85fc9c..6b4bf81 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -591,7 +591,6 @@
#define TLS1_3_EXPERIMENT_VERSION 0x7e01
#define TLS1_3_EXPERIMENT2_VERSION 0x7e02
#define TLS1_3_EXPERIMENT3_VERSION 0x7e03
-#define TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION 0x7a12
// SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to
// |version|. If |version| is zero, the default minimum version is used. It
@@ -1670,10 +1669,21 @@
OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes(
const uint8_t *in, size_t in_len, const SSL_CTX *ctx);
-// SSL_SESSION_get_version returns a string describing the TLS version |session|
-// was established at. For example, "TLSv1.2" or "SSLv3".
+// SSL_SESSION_get_version returns a string describing the TLS or DTLS version
+// |session| was established at. For example, "TLSv1.2" or "SSLv3".
OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *session);
+// SSL_SESSION_get_protocol_version returns the TLS or DTLS version |session|
+// was established at.
+OPENSSL_EXPORT uint16_t
+SSL_SESSION_get_protocol_version(const SSL_SESSION *session);
+
+// SSL_SESSION_set_protocol_version sets |session|'s TLS or DTLS version to
+// |version|. This may be useful when writing tests but should otherwise not be
+// used. It returns one on success and zero on error.
+OPENSSL_EXPORT int SSL_SESSION_set_protocol_version(SSL_SESSION *session,
+ uint16_t version);
+
// SSL_SESSION_get_id returns a pointer to a buffer containing |session|'s
// session ID and sets |*out_len| to its length.
OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session,
@@ -3219,10 +3229,8 @@
enum tls13_variant_t {
tls13_default = 0,
tls13_experiment = 1,
- tls13_record_type_experiment = 2,
- tls13_no_session_id_experiment = 3,
- tls13_experiment2 = 4,
- tls13_experiment3 = 5,
+ tls13_experiment2 = 2,
+ tls13_experiment3 = 3,
};
// SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the
@@ -4047,7 +4055,7 @@
struct ssl_session_st {
CRYPTO_refcount_t references;
- int ssl_version; // what ssl version session info is being kept in here?
+ uint16_t ssl_version; // what ssl version session info is being kept in here?
// group_id is the ID of the ECDH group used to establish this session or zero
// if not applicable or unknown.
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index 719a52d..6754cec 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -272,7 +272,6 @@
#define SSL3_RT_ALERT 21
#define SSL3_RT_HANDSHAKE 22
#define SSL3_RT_APPLICATION_DATA 23
-#define SSL3_RT_PLAINTEXT_HANDSHAKE 24
// Pseudo content type for SSL/TLS header info
#define SSL3_RT_HEADER 0x100
diff --git a/src/ssl/handshake.cc b/src/ssl/handshake.cc
index c10c40f..a03b140 100644
--- a/src/ssl/handshake.cc
+++ b/src/ssl/handshake.cc
@@ -147,7 +147,6 @@
SSL_HANDSHAKE::~SSL_HANDSHAKE() {
ssl->ctx->x509_method->hs_flush_cached_ca_names(this);
- OPENSSL_free(key_block);
}
SSL_HANDSHAKE *ssl_handshake_new(SSL *ssl) {
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 13e6655..4247425 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -258,6 +258,7 @@
const T *data() const { return data_; }
T *data() { return data_; }
size_t size() const { return size_; }
+ bool empty() const { return size_ == 0; }
const T &operator[](size_t i) const { return data_[i]; }
T &operator[](size_t i) { return data_[i]; }
@@ -352,32 +353,31 @@
// compared numerically.
// ssl_protocol_version_from_wire sets |*out| to the protocol version
-// corresponding to wire version |version| and returns one. If |version| is not
-// a valid TLS or DTLS version, it returns zero.
+// corresponding to wire version |version| and returns true. If |version| is not
+// a valid TLS or DTLS version, it returns false.
//
// Note this simultaneously handles both DTLS and TLS. Use one of the
// higher-level functions below for most operations.
-int ssl_protocol_version_from_wire(uint16_t *out, uint16_t version);
+bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version);
// ssl_get_version_range sets |*out_min_version| and |*out_max_version| to the
// minimum and maximum enabled protocol versions, respectively.
-int ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version,
- uint16_t *out_max_version);
+bool ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version,
+ uint16_t *out_max_version);
-// ssl_supports_version returns one if |hs| supports |version| and zero
-// otherwise.
-int ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version);
+// ssl_supports_version returns whether |hs| supports |version|.
+bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version);
// ssl_add_supported_versions writes the supported versions of |hs| to |cbb|, in
// decreasing preference order.
-int ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb);
+bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb);
// ssl_negotiate_version negotiates a common version based on |hs|'s preferences
-// and the peer preference list in |peer_versions|. On success, it returns one
-// and sets |*out_version| to the selected version. Otherwise, it returns zero
+// and the peer preference list in |peer_versions|. On success, it returns true
+// and sets |*out_version| to the selected version. Otherwise, it returns false
// and sets |*out_alert| to an alert to send.
-int ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- uint16_t *out_version, const CBS *peer_versions);
+bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ uint16_t *out_version, const CBS *peer_versions);
// ssl3_protocol_version returns |ssl|'s protocol version. It is an error to
// call this function before the version is determined.
@@ -470,11 +470,11 @@
// object for |cipher| protocol version |version|. It sets |*out_mac_secret_len|
// and |*out_fixed_iv_len| to the MAC key length and fixed IV length,
// respectively. The MAC key length is zero except for legacy block and stream
-// ciphers. It returns 1 on success and 0 on error.
-int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
- size_t *out_mac_secret_len,
- size_t *out_fixed_iv_len, const SSL_CIPHER *cipher,
- uint16_t version, int is_dtls);
+// ciphers. It returns true on success and false on error.
+bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
+ size_t *out_mac_secret_len,
+ size_t *out_fixed_iv_len, const SSL_CIPHER *cipher,
+ uint16_t version, int is_dtls);
// ssl_get_handshake_digest returns the |EVP_MD| corresponding to |version| and
// |cipher|.
@@ -483,14 +483,14 @@
// ssl_create_cipher_list evaluates |rule_str| according to the ciphers in
// |ssl_method|. It sets |*out_cipher_list| to a newly-allocated
-// |ssl_cipher_preference_list_st| containing the result. It returns 1 on
-// success and 0 on failure. If |strict| is true, nonsense will be rejected. If
-// false, nonsense will be silently ignored. An empty result is considered an
-// error regardless of |strict|.
-int ssl_create_cipher_list(
+// |ssl_cipher_preference_list_st| containing the result. It returns true on
+// success and false on failure. If |strict| is true, nonsense will be
+// rejected. If false, nonsense will be silently ignored. An empty result is
+// considered an error regardless of |strict|.
+bool ssl_create_cipher_list(
const SSL_PROTOCOL_METHOD *ssl_method,
struct ssl_cipher_preference_list_st **out_cipher_list,
- const char *rule_str, int strict);
+ const char *rule_str, bool strict);
// ssl_cipher_get_value returns the cipher suite id of |cipher|.
uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher);
@@ -499,17 +499,16 @@
// values suitable for use with |key| in TLS 1.2 and below.
uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key);
-// ssl_cipher_uses_certificate_auth returns one if |cipher| authenticates the
-// server and, optionally, the client with a certificate. Otherwise it returns
-// zero.
-int ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher);
+// ssl_cipher_uses_certificate_auth returns whether |cipher| authenticates the
+// server and, optionally, the client with a certificate.
+bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher);
-// ssl_cipher_requires_server_key_exchange returns 1 if |cipher| requires a
-// ServerKeyExchange message. Otherwise it returns 0.
+// ssl_cipher_requires_server_key_exchange returns whether |cipher| requires a
+// ServerKeyExchange message.
//
-// This function may return zero while still allowing |cipher| an optional
+// This function may return false while still allowing |cipher| an optional
// ServerKeyExchange. This is the case for plain PSK ciphers.
-int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);
+bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);
// ssl_cipher_get_record_split_len, for TLS 1.0 CBC mode ciphers, returns the
// length of an encrypted 1-byte record, for use in record-splitting. Otherwise
@@ -618,11 +617,12 @@
// returns nullptr on error. Only one of |Open| or |Seal| may be used with the
// resulting object, depending on |direction|. |version| is the normalized
// protocol version, so DTLS 1.0 is represented as 0x0301, not 0xffef.
- static UniquePtr<SSLAEADContext> Create(
- enum evp_aead_direction_t direction, uint16_t version, int is_dtls,
- const SSL_CIPHER *cipher, const uint8_t *enc_key, size_t enc_key_len,
- const uint8_t *mac_key, size_t mac_key_len, const uint8_t *fixed_iv,
- size_t fixed_iv_len);
+ static UniquePtr<SSLAEADContext> Create(enum evp_aead_direction_t direction,
+ uint16_t version, int is_dtls,
+ const SSL_CIPHER *cipher,
+ Span<const uint8_t> enc_key,
+ Span<const uint8_t> mac_key,
+ Span<const uint8_t> fixed_iv);
// SetVersionIfNullCipher sets the version the SSLAEADContext for the null
// cipher, to make version-specific determinations in the record layer prior
@@ -1335,8 +1335,9 @@
// CertificateRequest message.
UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names;
- // cached_x509_ca_names contains a cache of parsed versions of the elements
- // of |ca_names|.
+ // cached_x509_ca_names contains a cache of parsed versions of the elements of
+ // |ca_names|. This pointer is left non-owning so only
+ // |ssl_crypto_x509_method| needs to link against crypto/x509.
STACK_OF(X509_NAME) *cached_x509_ca_names = nullptr;
// certificate_types, on the client, contains the set of certificate types
@@ -1361,8 +1362,7 @@
const SSL_CIPHER *new_cipher = nullptr;
// key_block is the record-layer key block for TLS 1.2 and earlier.
- uint8_t *key_block = nullptr;
- uint8_t key_block_len = 0;
+ Array<uint8_t> key_block;
// scts_requested is true if the SCT extension is in the ClientHello.
bool scts_requested:1;
@@ -2229,12 +2229,13 @@
int ssl_session_is_resumable(const SSL_HANDSHAKE *hs,
const SSL_SESSION *session);
-// SSL_SESSION_protocol_version returns the protocol version associated with
-// |session|.
-uint16_t SSL_SESSION_protocol_version(const SSL_SESSION *session);
+// ssl_session_protocol_version returns the protocol version associated with
+// |session|. Note that despite the name, this is not the same as
+// |SSL_SESSION_get_protocol_version|. The latter is based on upstream's name.
+uint16_t ssl_session_protocol_version(const SSL_SESSION *session);
-// SSL_SESSION_get_digest returns the digest used in |session|.
-const EVP_MD *SSL_SESSION_get_digest(const SSL_SESSION *session);
+// ssl_session_get_digest returns the digest used in |session|.
+const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session);
void ssl_set_session(SSL *ssl, SSL_SESSION *session);
diff --git a/src/ssl/s3_both.cc b/src/ssl/s3_both.cc
index f63ed26..65e2089 100644
--- a/src/ssl/s3_both.cc
+++ b/src/ssl/s3_both.cc
@@ -132,8 +132,8 @@
namespace bssl {
-static int add_record_to_flight(SSL *ssl, uint8_t type, const uint8_t *in,
- size_t in_len) {
+static int add_record_to_flight(SSL *ssl, uint8_t type,
+ Span<const uint8_t> in) {
// We'll never add a flight while in the process of writing it out.
assert(ssl->s3->pending_flight_offset == 0);
@@ -144,18 +144,19 @@
}
}
- size_t max_out = in_len + SSL_max_seal_overhead(ssl);
+ size_t max_out = in.size() + SSL_max_seal_overhead(ssl);
size_t new_cap = ssl->s3->pending_flight->length + max_out;
- if (max_out < in_len || new_cap < max_out) {
+ if (max_out < in.size() || new_cap < max_out) {
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return 0;
}
size_t len;
if (!BUF_MEM_reserve(ssl->s3->pending_flight, new_cap) ||
- !tls_seal_record(ssl, (uint8_t *)ssl->s3->pending_flight->data +
- ssl->s3->pending_flight->length,
- &len, max_out, type, in, in_len)) {
+ !tls_seal_record(ssl,
+ (uint8_t *)ssl->s3->pending_flight->data +
+ ssl->s3->pending_flight->length,
+ &len, max_out, type, in.data(), in.size())) {
return 0;
}
@@ -183,26 +184,15 @@
int ssl3_add_message(SSL *ssl, Array<uint8_t> msg) {
// Add the message to the current flight, splitting into several records if
// needed.
- size_t added = 0;
+ Span<const uint8_t> rest = msg;
do {
- size_t todo = msg.size() - added;
- if (todo > ssl->max_send_fragment) {
- todo = ssl->max_send_fragment;
- }
+ Span<const uint8_t> chunk = rest.subspan(0, ssl->max_send_fragment);
+ rest = rest.subspan(chunk.size());
- uint8_t type = SSL3_RT_HANDSHAKE;
- if (ssl->server &&
- ssl->s3->have_version &&
- ssl->version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION &&
- ssl->s3->aead_write_ctx->is_null_cipher()) {
- type = SSL3_RT_PLAINTEXT_HANDSHAKE;
- }
-
- if (!add_record_to_flight(ssl, type, msg.data() + added, todo)) {
+ if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) {
return 0;
}
- added += todo;
- } while (added < msg.size());
+ } while (!rest.empty());
ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg.data(),
msg.size());
@@ -218,8 +208,8 @@
int ssl3_add_change_cipher_spec(SSL *ssl) {
static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
- if (!add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec,
- sizeof(kChangeCipherSpec))) {
+ if (!add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC,
+ kChangeCipherSpec)) {
return 0;
}
@@ -230,7 +220,7 @@
int ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc) {
uint8_t alert[2] = {level, desc};
- if (!add_record_to_flight(ssl, SSL3_RT_ALERT, alert, sizeof(alert))) {
+ if (!add_record_to_flight(ssl, SSL3_RT_ALERT, alert)) {
return 0;
}
diff --git a/src/ssl/s3_pkt.cc b/src/ssl/s3_pkt.cc
index b9eebf3..f7470ae 100644
--- a/src/ssl/s3_pkt.cc
+++ b/src/ssl/s3_pkt.cc
@@ -522,13 +522,7 @@
return -1;
}
- // Accept server_plaintext_handshake records when the content type TLS 1.3
- // variant is enabled.
- if (rr->type != SSL3_RT_HANDSHAKE &&
- !(!ssl->server &&
- ssl->tls13_variant == tls13_record_type_experiment &&
- ssl->s3->aead_read_ctx->is_null_cipher() &&
- rr->type == SSL3_RT_PLAINTEXT_HANDSHAKE)) {
+ if (rr->type != SSL3_RT_HANDSHAKE) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
diff --git a/src/ssl/ssl_aead_ctx.cc b/src/ssl/ssl_aead_ctx.cc
index d03a4a0..8856f74 100644
--- a/src/ssl/ssl_aead_ctx.cc
+++ b/src/ssl/ssl_aead_ctx.cc
@@ -56,10 +56,8 @@
UniquePtr<SSLAEADContext> SSLAEADContext::Create(
enum evp_aead_direction_t direction, uint16_t version, int is_dtls,
- const SSL_CIPHER *cipher, const uint8_t *enc_key, size_t enc_key_len,
- const uint8_t *mac_key, size_t mac_key_len, const uint8_t *fixed_iv,
- size_t fixed_iv_len) {
-
+ const SSL_CIPHER *cipher, Span<const uint8_t> enc_key,
+ Span<const uint8_t> mac_key, Span<const uint8_t> fixed_iv) {
const EVP_AEAD *aead;
uint16_t protocol_version;
size_t expected_mac_key_len, expected_fixed_iv_len;
@@ -68,27 +66,27 @@
&expected_fixed_iv_len, cipher, protocol_version,
is_dtls) ||
// Ensure the caller returned correct key sizes.
- expected_fixed_iv_len != fixed_iv_len ||
- expected_mac_key_len != mac_key_len) {
+ expected_fixed_iv_len != fixed_iv.size() ||
+ expected_mac_key_len != mac_key.size()) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return nullptr;
}
uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
- if (mac_key_len > 0) {
+ if (!mac_key.empty()) {
// This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
// suites).
- if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
+ if (mac_key.size() + enc_key.size() + fixed_iv.size() >
+ sizeof(merged_key)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return nullptr;
}
- OPENSSL_memcpy(merged_key, mac_key, mac_key_len);
- OPENSSL_memcpy(merged_key + mac_key_len, enc_key, enc_key_len);
- OPENSSL_memcpy(merged_key + mac_key_len + enc_key_len, fixed_iv,
- fixed_iv_len);
- enc_key = merged_key;
- enc_key_len += mac_key_len;
- enc_key_len += fixed_iv_len;
+ OPENSSL_memcpy(merged_key, mac_key.data(), mac_key.size());
+ OPENSSL_memcpy(merged_key + mac_key.size(), enc_key.data(), enc_key.size());
+ OPENSSL_memcpy(merged_key + mac_key.size() + enc_key.size(),
+ fixed_iv.data(), fixed_iv.size());
+ enc_key = MakeConstSpan(merged_key,
+ enc_key.size() + mac_key.size() + fixed_iv.size());
}
UniquePtr<SSLAEADContext> aead_ctx =
@@ -101,7 +99,7 @@
assert(aead_ctx->ProtocolVersion() == protocol_version);
if (!EVP_AEAD_CTX_init_with_direction(
- aead_ctx->ctx_.get(), aead, enc_key, enc_key_len,
+ aead_ctx->ctx_.get(), aead, enc_key.data(), enc_key.size(),
EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) {
return nullptr;
}
@@ -110,10 +108,10 @@
static_assert(EVP_AEAD_MAX_NONCE_LENGTH < 256,
"variable_nonce_len doesn't fit in uint8_t");
aead_ctx->variable_nonce_len_ = (uint8_t)EVP_AEAD_nonce_length(aead);
- if (mac_key_len == 0) {
- assert(fixed_iv_len <= sizeof(aead_ctx->fixed_nonce_));
- OPENSSL_memcpy(aead_ctx->fixed_nonce_, fixed_iv, fixed_iv_len);
- aead_ctx->fixed_nonce_len_ = fixed_iv_len;
+ if (mac_key.empty()) {
+ assert(fixed_iv.size() <= sizeof(aead_ctx->fixed_nonce_));
+ OPENSSL_memcpy(aead_ctx->fixed_nonce_, fixed_iv.data(), fixed_iv.size());
+ aead_ctx->fixed_nonce_len_ = fixed_iv.size();
if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) {
// The fixed nonce into the actual nonce (the sequence number).
@@ -121,8 +119,8 @@
aead_ctx->variable_nonce_len_ = 8;
} else {
// The fixed IV is prepended to the nonce.
- assert(fixed_iv_len <= aead_ctx->variable_nonce_len_);
- aead_ctx->variable_nonce_len_ -= fixed_iv_len;
+ assert(fixed_iv.size() <= aead_ctx->variable_nonce_len_);
+ aead_ctx->variable_nonce_len_ -= fixed_iv.size();
}
// AES-GCM uses an explicit nonce.
@@ -137,7 +135,7 @@
aead_ctx->variable_nonce_len_ = 8;
aead_ctx->variable_nonce_included_in_record_ = false;
aead_ctx->omit_ad_ = true;
- assert(fixed_iv_len >= aead_ctx->variable_nonce_len_);
+ assert(fixed_iv.size() >= aead_ctx->variable_nonce_len_);
}
} else {
assert(protocol_version < TLS1_3_VERSION);
diff --git a/src/ssl/ssl_cipher.cc b/src/ssl/ssl_cipher.cc
index 435441d..0c02389 100644
--- a/src/ssl/ssl_cipher.cc
+++ b/src/ssl/ssl_cipher.cc
@@ -553,8 +553,8 @@
typedef struct cipher_order_st {
const SSL_CIPHER *cipher;
- int active;
- int in_group;
+ bool active;
+ bool in_group;
struct cipher_order_st *next, *prev;
} CIPHER_ORDER;
@@ -645,10 +645,10 @@
}
}
-int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
- size_t *out_mac_secret_len,
- size_t *out_fixed_iv_len,
- const SSL_CIPHER *cipher, uint16_t version, int is_dtls) {
+bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
+ size_t *out_mac_secret_len,
+ size_t *out_fixed_iv_len, const SSL_CIPHER *cipher,
+ uint16_t version, int is_dtls) {
*out_aead = NULL;
*out_mac_secret_len = 0;
*out_fixed_iv_len = 0;
@@ -668,7 +668,7 @@
*out_aead = EVP_aead_chacha20_poly1305();
*out_fixed_iv_len = 12;
} else {
- return 0;
+ return false;
}
// In TLS 1.3, the iv_len is equal to the AEAD nonce length whereas the code
@@ -714,7 +714,7 @@
*out_aead = EVP_aead_aes_256_cbc_sha1_tls();
}
} else {
- return 0;
+ return false;
}
*out_mac_secret_len = SHA_DIGEST_LENGTH;
@@ -724,22 +724,22 @@
} else if (cipher->algorithm_enc == SSL_AES256) {
*out_aead = EVP_aead_aes_256_cbc_sha256_tls();
} else {
- return 0;
+ return false;
}
*out_mac_secret_len = SHA256_DIGEST_LENGTH;
} else if (cipher->algorithm_mac == SSL_SHA384) {
if (cipher->algorithm_enc != SSL_AES256) {
- return 0;
+ return false;
}
*out_aead = EVP_aead_aes_256_cbc_sha384_tls();
*out_mac_secret_len = SHA384_DIGEST_LENGTH;
} else {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
const EVP_MD *ssl_get_handshake_digest(uint16_t version,
@@ -764,9 +764,9 @@
return !is_strict && (c == ' ' || c == ';' || c == ',');
}
-// rule_equals returns one iff the NUL-terminated string |rule| is equal to the
+// rule_equals returns whether the NUL-terminated string |rule| is equal to the
// |buf_len| bytes at |buf|.
-static int rule_equals(const char *rule, const char *buf, size_t buf_len) {
+static bool rule_equals(const char *rule, const char *buf, size_t buf_len) {
// |strncmp| alone only checks that |buf| is a prefix of |rule|.
return strncmp(rule, buf, buf_len) == 0 && rule[buf_len] == '\0';
}
@@ -826,8 +826,8 @@
co_list[co_list_num].cipher = cipher;
co_list[co_list_num].next = NULL;
co_list[co_list_num].prev = NULL;
- co_list[co_list_num].active = 0;
- co_list[co_list_num].in_group = 0;
+ co_list[co_list_num].active = false;
+ co_list[co_list_num].in_group = false;
co_list_num++;
}
}
@@ -866,11 +866,11 @@
static void ssl_cipher_apply_rule(
uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth,
uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule,
- int strength_bits, int in_group, CIPHER_ORDER **head_p,
+ int strength_bits, bool in_group, CIPHER_ORDER **head_p,
CIPHER_ORDER **tail_p) {
CIPHER_ORDER *head, *tail, *curr, *next, *last;
const SSL_CIPHER *cp;
- int reverse = 0;
+ bool reverse = false;
if (cipher_id == 0 && strength_bits == -1 && min_version == 0 &&
(alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) {
@@ -880,7 +880,7 @@
if (rule == CIPHER_DEL) {
// needed to maintain sorting between currently deleted ciphers
- reverse = 1;
+ reverse = true;
}
head = *head_p;
@@ -930,33 +930,33 @@
// add the cipher if it has not been added yet.
if (rule == CIPHER_ADD) {
- // reverse == 0
+ // reverse == false
if (!curr->active) {
ll_append_tail(&head, curr, &tail);
- curr->active = 1;
+ curr->active = true;
curr->in_group = in_group;
}
}
// Move the added cipher to this location
else if (rule == CIPHER_ORD) {
- // reverse == 0
+ // reverse == false
if (curr->active) {
ll_append_tail(&head, curr, &tail);
- curr->in_group = 0;
+ curr->in_group = false;
}
} else if (rule == CIPHER_DEL) {
- // reverse == 1
+ // reverse == true
if (curr->active) {
// most recently deleted ciphersuites get best positions
// for any future CIPHER_ADD (note that the CIPHER_DEL loop
// works in reverse to maintain the order)
ll_append_head(&head, curr, &tail);
- curr->active = 0;
- curr->in_group = 0;
+ curr->active = false;
+ curr->in_group = false;
}
} else if (rule == CIPHER_KILL) {
- // reverse == 0
+ // reverse == false
if (head == curr) {
head = curr->next;
} else {
@@ -966,7 +966,7 @@
if (tail == curr) {
tail = curr->prev;
}
- curr->active = 0;
+ curr->active = false;
if (curr->next != NULL) {
curr->next->prev = curr->prev;
}
@@ -982,16 +982,13 @@
*tail_p = tail;
}
-static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
- CIPHER_ORDER **tail_p) {
- int max_strength_bits, i, *number_uses;
- CIPHER_ORDER *curr;
-
+static bool ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
+ CIPHER_ORDER **tail_p) {
// This routine sorts the ciphers with descending strength. The sorting must
// keep the pre-sorted sequence, so we apply the normal sorting routine as
// '+' movement to the end of the list.
- max_strength_bits = 0;
- curr = *head_p;
+ int max_strength_bits = 0;
+ CIPHER_ORDER *curr = *head_p;
while (curr != NULL) {
if (curr->active &&
SSL_CIPHER_get_bits(curr->cipher, NULL) > max_strength_bits) {
@@ -1000,12 +997,11 @@
curr = curr->next;
}
- number_uses = (int *)OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
- if (!number_uses) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
+ Array<int> number_uses;
+ if (!number_uses.Init(max_strength_bits + 1)) {
+ return false;
}
- OPENSSL_memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
+ OPENSSL_memset(number_uses.data(), 0, (max_strength_bits + 1) * sizeof(int));
// Now find the strength_bits values actually used.
curr = *head_p;
@@ -1017,24 +1013,25 @@
}
// Go through the list of used strength_bits values in descending order.
- for (i = max_strength_bits; i >= 0; i--) {
+ for (int i = max_strength_bits; i >= 0; i--) {
if (number_uses[i] > 0) {
- ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, 0, head_p, tail_p);
+ ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, false, head_p,
+ tail_p);
}
}
- OPENSSL_free(number_uses);
- return 1;
+ return true;
}
-static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
- const char *rule_str,
- CIPHER_ORDER **head_p,
- CIPHER_ORDER **tail_p, int strict) {
+static bool ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
+ const char *rule_str,
+ CIPHER_ORDER **head_p,
+ CIPHER_ORDER **tail_p, bool strict) {
uint32_t alg_mkey, alg_auth, alg_enc, alg_mac;
uint16_t min_version;
const char *l, *buf;
- int multi, skip_rule, rule, in_group = 0, has_group = 0;
+ int rule;
+ bool multi, skip_rule, in_group = false, has_group = false;
size_t j, buf_len;
uint32_t cipher_id;
char ch;
@@ -1050,9 +1047,9 @@
if (in_group) {
if (ch == ']') {
if (*tail_p) {
- (*tail_p)->in_group = 0;
+ (*tail_p)->in_group = false;
}
- in_group = 0;
+ in_group = false;
l++;
continue;
}
@@ -1064,7 +1061,7 @@
} else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') &&
!(ch >= '0' && ch <= '9')) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
- return 0;
+ return false;
} else {
rule = CIPHER_ADD;
}
@@ -1082,8 +1079,8 @@
l++;
} else if (ch == '[') {
assert(!in_group);
- in_group = 1;
- has_group = 1;
+ in_group = true;
+ has_group = true;
l++;
continue;
} else {
@@ -1094,7 +1091,7 @@
// Otherwise the in_group bits will get mixed up.
if (has_group && rule != CIPHER_ADD) {
OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
- return 0;
+ return false;
}
if (is_cipher_list_separator(ch, strict)) {
@@ -1102,14 +1099,14 @@
continue;
}
- multi = 0;
+ multi = false;
cipher_id = 0;
alg_mkey = ~0u;
alg_auth = ~0u;
alg_enc = ~0u;
alg_mac = ~0u;
min_version = 0;
- skip_rule = 0;
+ skip_rule = false;
for (;;) {
ch = *l;
@@ -1125,7 +1122,7 @@
// We hit something we cannot deal with, it is no command or separator
// nor alphanumeric, so we call this an error.
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
- return 0;
+ return false;
}
if (rule == CIPHER_SPECIAL) {
@@ -1155,7 +1152,7 @@
if (min_version != 0 &&
min_version != kCipherAliases[j].min_version) {
- skip_rule = 1;
+ skip_rule = true;
} else {
min_version = kCipherAliases[j].min_version;
}
@@ -1163,10 +1160,10 @@
}
}
if (j == kCipherAliasesLen) {
- skip_rule = 1;
+ skip_rule = true;
if (strict) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
- return 0;
+ return false;
}
}
}
@@ -1176,17 +1173,17 @@
break;
}
l++;
- multi = 1;
+ multi = true;
}
// Ok, we have the rule, now apply it.
if (rule == CIPHER_SPECIAL) {
if (buf_len != 8 || strncmp(buf, "STRENGTH", 8) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
- return 0;
+ return false;
}
if (!ssl_cipher_strength_sort(head_p, tail_p)) {
- return 0;
+ return false;
}
// We do not support any "multi" options together with "@", so throw away
@@ -1202,16 +1199,16 @@
if (in_group) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-int ssl_create_cipher_list(
+bool ssl_create_cipher_list(
const SSL_PROTOCOL_METHOD *ssl_method,
struct ssl_cipher_preference_list_st **out_cipher_list,
- const char *rule_str, int strict) {
+ const char *rule_str, bool strict) {
STACK_OF(SSL_CIPHER) *cipherstack = NULL;
CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
uint8_t *in_group_flags = NULL;
@@ -1220,7 +1217,7 @@
// Return with error if nothing to do.
if (rule_str == NULL || out_cipher_list == NULL) {
- return 0;
+ return false;
}
// Now we have to collect the available ciphers from the compiled in ciphers.
@@ -1229,7 +1226,7 @@
co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
if (co_list == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
+ return false;
}
ssl_cipher_collect_ciphers(ssl_method, co_list, &head, &tail);
@@ -1240,10 +1237,10 @@
// Everything else being equal, prefer ECDHE_ECDSA and ECDHE_RSA over other
// key exchange mechanisms
ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1,
- 0, &head, &tail);
- ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0,
+ false, &head, &tail);
+ ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false,
&head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0, &head,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head,
&tail);
// Order the bulk ciphers. First the preferred AEAD ciphers. We prefer
@@ -1251,40 +1248,40 @@
// AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the
// old one.
if (EVP_has_aes_hardware()) {
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
- &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
- &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1,
+ false, &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1,
+ false, &head, &tail);
ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
- -1, 0, &head, &tail);
+ -1, false, &head, &tail);
} else {
ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD,
- -1, 0, &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, 0,
- &head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, 0,
- &head, &tail);
+ -1, false, &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1,
+ false, &head, &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1,
+ false, &head, &tail);
}
// Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC,
// 3DES_EDE_CBC_SHA.
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, 0,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, false,
&head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, 0,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, false,
&head, &tail);
- ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, 0, &head,
- &tail);
+ ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, false,
+ &head, &tail);
// Temporarily enable everything else for sorting
- ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, 0, &head,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, &head,
&tail);
// Move ciphers without forward secrecy to the end.
- ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0,
- CIPHER_ORD, -1, 0, &head, &tail);
+ ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0, CIPHER_ORD,
+ -1, false, &head, &tail);
// Now disable everything (maintaining the ordering!)
- ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, 0, &head,
+ ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head,
&tail);
// If the rule_string begins with DEFAULT, apply the default rule before
@@ -1358,10 +1355,10 @@
// output.
if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
- return 0;
+ return false;
}
- return 1;
+ return true;
err:
OPENSSL_free(co_list);
@@ -1371,7 +1368,7 @@
OPENSSL_free(pref_list->in_group_flags);
}
OPENSSL_free(pref_list);
- return 0;
+ return false;
}
uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) {
@@ -1394,18 +1391,14 @@
}
}
-int ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) {
+bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) {
return (cipher->algorithm_auth & SSL_aCERT) != 0;
}
-int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
- // Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange.
- if (cipher->algorithm_mkey & SSL_kECDHE) {
- return 1;
- }
-
- // It is optional in all others.
- return 0;
+bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
+ // Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. It is
+ // optional or omitted in all others.
+ return (cipher->algorithm_mkey & SSL_kECDHE) != 0;
}
size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) {
diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc
index b864f8d..f62d155 100644
--- a/src/ssl/ssl_lib.cc
+++ b/src/ssl/ssl_lib.cc
@@ -1741,22 +1741,22 @@
int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
return ssl_create_cipher_list(ctx->method, &ctx->cipher_list, str,
- 0 /* not strict */);
+ false /* not strict */);
}
int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) {
return ssl_create_cipher_list(ctx->method, &ctx->cipher_list, str,
- 1 /* strict */);
+ true /* strict */);
}
int SSL_set_cipher_list(SSL *ssl, const char *str) {
return ssl_create_cipher_list(ssl->ctx->method, &ssl->cipher_list, str,
- 0 /* not strict */);
+ false /* not strict */);
}
int SSL_set_strict_cipher_list(SSL *ssl, const char *str) {
return ssl_create_cipher_list(ssl->ctx->method, &ssl->cipher_list, str,
- 1 /* strict */);
+ true /* strict */);
}
const char *SSL_get_servername(const SSL *ssl, const int type) {
diff --git a/src/ssl/ssl_session.cc b/src/ssl/ssl_session.cc
index ed4c779..aff9c0f 100644
--- a/src/ssl/ssl_session.cc
+++ b/src/ssl/ssl_session.cc
@@ -340,7 +340,7 @@
}
}
-uint16_t SSL_SESSION_protocol_version(const SSL_SESSION *session) {
+uint16_t ssl_session_protocol_version(const SSL_SESSION *session) {
uint16_t ret;
if (!ssl_protocol_version_from_wire(&ret, session->ssl_version)) {
// An |SSL_SESSION| will never have an invalid version. This is enforced by
@@ -352,8 +352,8 @@
return ret;
}
-const EVP_MD *SSL_SESSION_get_digest(const SSL_SESSION *session) {
- return ssl_get_handshake_digest(SSL_SESSION_protocol_version(session),
+const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session) {
+ return ssl_get_handshake_digest(ssl_session_protocol_version(session),
session->cipher);
}
@@ -967,7 +967,7 @@
}
int SSL_SESSION_should_be_single_use(const SSL_SESSION *session) {
- return SSL_SESSION_protocol_version(session) >= TLS1_3_VERSION;
+ return ssl_session_protocol_version(session) >= TLS1_3_VERSION;
}
int SSL_SESSION_is_resumable(const SSL_SESSION *session) {
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 4653f73..f9cf83c 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -3740,6 +3740,26 @@
EXPECT_EQ(SSL_R_NO_CIPHERS_AVAILABLE, ERR_GET_REASON(err));
}
+TEST_P(SSLVersionTest, SessionVersion) {
+ SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
+ SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
+
+ bssl::UniquePtr<SSL_SESSION> session =
+ CreateClientSession(client_ctx_.get(), server_ctx_.get());
+ ASSERT_TRUE(session);
+ EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
+
+ // Sessions in TLS 1.3 and later should be single-use.
+ EXPECT_EQ(version() == TLS1_3_VERSION,
+ !!SSL_SESSION_should_be_single_use(session.get()));
+
+ // Making fake sessions for testing works.
+ session.reset(SSL_SESSION_new(client_ctx_.get()));
+ ASSERT_TRUE(session);
+ ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
+ EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
+}
+
// TODO(davidben): Convert this file to GTest properly.
TEST(SSLTest, AllTests) {
if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
diff --git a/src/ssl/ssl_versions.cc b/src/ssl/ssl_versions.cc
index 560d0cf..56653b1 100644
--- a/src/ssl/ssl_versions.cc
+++ b/src/ssl/ssl_versions.cc
@@ -25,34 +25,33 @@
namespace bssl {
-int ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) {
+bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) {
switch (version) {
case SSL3_VERSION:
case TLS1_VERSION:
case TLS1_1_VERSION:
case TLS1_2_VERSION:
*out = version;
- return 1;
+ return true;
case TLS1_3_DRAFT_VERSION:
case TLS1_3_EXPERIMENT_VERSION:
case TLS1_3_EXPERIMENT2_VERSION:
case TLS1_3_EXPERIMENT3_VERSION:
- case TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION:
*out = TLS1_3_VERSION;
- return 1;
+ return true;
case DTLS1_VERSION:
// DTLS 1.0 is analogous to TLS 1.1, not TLS 1.0.
*out = TLS1_1_VERSION;
- return 1;
+ return true;
case DTLS1_2_VERSION:
*out = TLS1_2_VERSION;
- return 1;
+ return true;
default:
- return 0;
+ return false;
}
}
@@ -63,7 +62,6 @@
TLS1_3_EXPERIMENT3_VERSION,
TLS1_3_EXPERIMENT2_VERSION,
TLS1_3_EXPERIMENT_VERSION,
- TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION,
TLS1_3_DRAFT_VERSION,
TLS1_2_VERSION,
TLS1_1_VERSION,
@@ -87,157 +85,30 @@
}
}
-static int method_supports_version(const SSL_PROTOCOL_METHOD *method,
- uint16_t version) {
+static bool method_supports_version(const SSL_PROTOCOL_METHOD *method,
+ uint16_t version) {
const uint16_t *versions;
size_t num_versions;
get_method_versions(method, &versions, &num_versions);
for (size_t i = 0; i < num_versions; i++) {
if (versions[i] == version) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-static int set_version_bound(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
- uint16_t version) {
- // The public API uses wire versions, except we use |TLS1_3_VERSION|
- // everywhere to refer to any draft TLS 1.3 versions. In this direction, we
- // map it to some representative TLS 1.3 draft version.
- if (version == TLS1_3_DRAFT_VERSION ||
- version == TLS1_3_EXPERIMENT_VERSION ||
- version == TLS1_3_EXPERIMENT2_VERSION ||
- version == TLS1_3_EXPERIMENT3_VERSION ||
- version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
- return 0;
- }
- if (version == TLS1_3_VERSION) {
- version = TLS1_3_DRAFT_VERSION;
- }
-
- if (!method_supports_version(method, version) ||
- !ssl_protocol_version_from_wire(out, version)) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
- return 0;
- }
-
- return 1;
-}
-
-static int set_min_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
- uint16_t version) {
- // Zero is interpreted as the default minimum version.
- if (version == 0) {
- // SSL 3.0 is disabled by default and TLS 1.0 does not exist in DTLS.
- *out = method->is_dtls ? TLS1_1_VERSION : TLS1_VERSION;
- return 1;
- }
-
- return set_version_bound(method, out, version);
-}
-
-static int set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
- uint16_t version) {
- // Zero is interpreted as the default maximum version.
- if (version == 0) {
- *out = TLS1_2_VERSION;
- return 1;
- }
-
- return set_version_bound(method, out, version);
-}
-
-const struct {
- uint16_t version;
- uint32_t flag;
-} kProtocolVersions[] = {
- {SSL3_VERSION, SSL_OP_NO_SSLv3},
- {TLS1_VERSION, SSL_OP_NO_TLSv1},
- {TLS1_1_VERSION, SSL_OP_NO_TLSv1_1},
- {TLS1_2_VERSION, SSL_OP_NO_TLSv1_2},
- {TLS1_3_VERSION, SSL_OP_NO_TLSv1_3},
-};
-
-int ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version,
- uint16_t *out_max_version) {
- // For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but
- // DTLS 1.0 should be mapped to TLS 1.1.
- uint32_t options = ssl->options;
- if (SSL_is_dtls(ssl)) {
- options &= ~SSL_OP_NO_TLSv1_1;
- if (options & SSL_OP_NO_DTLSv1) {
- options |= SSL_OP_NO_TLSv1_1;
- }
- }
-
- uint16_t min_version = ssl->conf_min_version;
- uint16_t max_version = ssl->conf_max_version;
-
- // OpenSSL's API for controlling versions entails blacklisting individual
- // protocols. This has two problems. First, on the client, the protocol can
- // only express a contiguous range of versions. Second, a library consumer
- // trying to set a maximum version cannot disable protocol versions that get
- // added in a future version of the library.
- //
- // To account for both of these, OpenSSL interprets the client-side bitmask
- // as a min/max range by picking the lowest contiguous non-empty range of
- // enabled protocols. Note that this means it is impossible to set a maximum
- // version of the higest supported TLS version in a future-proof way.
- int any_enabled = 0;
- for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kProtocolVersions); i++) {
- // Only look at the versions already enabled.
- if (min_version > kProtocolVersions[i].version) {
- continue;
- }
- if (max_version < kProtocolVersions[i].version) {
- break;
- }
-
- if (!(options & kProtocolVersions[i].flag)) {
- // The minimum version is the first enabled version.
- if (!any_enabled) {
- any_enabled = 1;
- min_version = kProtocolVersions[i].version;
- }
- continue;
- }
-
- // If there is a disabled version after the first enabled one, all versions
- // after it are implicitly disabled.
- if (any_enabled) {
- max_version = kProtocolVersions[i-1].version;
- break;
- }
- }
-
- if (!any_enabled) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SUPPORTED_VERSIONS_ENABLED);
- return 0;
- }
-
- *out_min_version = min_version;
- *out_max_version = max_version;
- return 1;
-}
-
-static uint16_t ssl_version(const SSL *ssl) {
- // In early data, we report the predicted version.
- if (SSL_in_early_data(ssl) && !ssl->server) {
- return ssl->s3->hs->early_session->ssl_version;
- }
- return ssl->version;
-}
+// The following functions map between API versions and wire versions. The
+// public API works on wire versions, except that TLS 1.3 draft versions all
+// appear as TLS 1.3. This will get collapsed back down when TLS 1.3 is
+// finalized.
static const char *ssl_version_to_string(uint16_t version) {
switch (version) {
- // Report TLS 1.3 draft version as TLS 1.3 in the public API.
case TLS1_3_DRAFT_VERSION:
case TLS1_3_EXPERIMENT_VERSION:
case TLS1_3_EXPERIMENT2_VERSION:
case TLS1_3_EXPERIMENT3_VERSION:
- case TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION:
return "TLSv1.3";
case TLS1_2_VERSION:
@@ -263,6 +134,159 @@
}
}
+static uint16_t wire_version_to_api(uint16_t version) {
+ switch (version) {
+ // Report TLS 1.3 draft versions as TLS 1.3 in the public API.
+ case TLS1_3_DRAFT_VERSION:
+ case TLS1_3_EXPERIMENT_VERSION:
+ case TLS1_3_EXPERIMENT2_VERSION:
+ case TLS1_3_EXPERIMENT3_VERSION:
+ return TLS1_3_VERSION;
+ default:
+ return version;
+ }
+}
+
+// api_version_to_wire maps |version| to some representative wire version. In
+// particular, it picks an arbitrary TLS 1.3 representative. This should only be
+// used in context where that does not matter.
+static bool api_version_to_wire(uint16_t *out, uint16_t version) {
+ if (version == TLS1_3_DRAFT_VERSION ||
+ version == TLS1_3_EXPERIMENT_VERSION ||
+ version == TLS1_3_EXPERIMENT2_VERSION ||
+ version == TLS1_3_EXPERIMENT3_VERSION) {
+ return false;
+ }
+ if (version == TLS1_3_VERSION) {
+ version = TLS1_3_DRAFT_VERSION;
+ }
+
+ // Check it is a real protocol version.
+ uint16_t unused;
+ if (!ssl_protocol_version_from_wire(&unused, version)) {
+ return false;
+ }
+
+ *out = version;
+ return true;
+}
+
+static bool set_version_bound(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
+ uint16_t version) {
+ if (!api_version_to_wire(&version, version) ||
+ !method_supports_version(method, version) ||
+ !ssl_protocol_version_from_wire(out, version)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
+ return false;
+ }
+
+ return true;
+}
+
+static bool set_min_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
+ uint16_t version) {
+ // Zero is interpreted as the default minimum version.
+ if (version == 0) {
+ // SSL 3.0 is disabled by default and TLS 1.0 does not exist in DTLS.
+ *out = method->is_dtls ? TLS1_1_VERSION : TLS1_VERSION;
+ return true;
+ }
+
+ return set_version_bound(method, out, version);
+}
+
+static bool set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out,
+ uint16_t version) {
+ // Zero is interpreted as the default maximum version.
+ if (version == 0) {
+ *out = TLS1_2_VERSION;
+ return true;
+ }
+
+ return set_version_bound(method, out, version);
+}
+
+const struct {
+ uint16_t version;
+ uint32_t flag;
+} kProtocolVersions[] = {
+ {SSL3_VERSION, SSL_OP_NO_SSLv3},
+ {TLS1_VERSION, SSL_OP_NO_TLSv1},
+ {TLS1_1_VERSION, SSL_OP_NO_TLSv1_1},
+ {TLS1_2_VERSION, SSL_OP_NO_TLSv1_2},
+ {TLS1_3_VERSION, SSL_OP_NO_TLSv1_3},
+};
+
+bool ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version,
+ uint16_t *out_max_version) {
+ // For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but
+ // DTLS 1.0 should be mapped to TLS 1.1.
+ uint32_t options = ssl->options;
+ if (SSL_is_dtls(ssl)) {
+ options &= ~SSL_OP_NO_TLSv1_1;
+ if (options & SSL_OP_NO_DTLSv1) {
+ options |= SSL_OP_NO_TLSv1_1;
+ }
+ }
+
+ uint16_t min_version = ssl->conf_min_version;
+ uint16_t max_version = ssl->conf_max_version;
+
+ // OpenSSL's API for controlling versions entails blacklisting individual
+ // protocols. This has two problems. First, on the client, the protocol can
+ // only express a contiguous range of versions. Second, a library consumer
+ // trying to set a maximum version cannot disable protocol versions that get
+ // added in a future version of the library.
+ //
+ // To account for both of these, OpenSSL interprets the client-side bitmask
+ // as a min/max range by picking the lowest contiguous non-empty range of
+ // enabled protocols. Note that this means it is impossible to set a maximum
+ // version of the higest supported TLS version in a future-proof way.
+ bool any_enabled = false;
+ for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kProtocolVersions); i++) {
+ // Only look at the versions already enabled.
+ if (min_version > kProtocolVersions[i].version) {
+ continue;
+ }
+ if (max_version < kProtocolVersions[i].version) {
+ break;
+ }
+
+ if (!(options & kProtocolVersions[i].flag)) {
+ // The minimum version is the first enabled version.
+ if (!any_enabled) {
+ any_enabled = true;
+ min_version = kProtocolVersions[i].version;
+ }
+ continue;
+ }
+
+ // If there is a disabled version after the first enabled one, all versions
+ // after it are implicitly disabled.
+ if (any_enabled) {
+ max_version = kProtocolVersions[i-1].version;
+ break;
+ }
+ }
+
+ if (!any_enabled) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SUPPORTED_VERSIONS_ENABLED);
+ return false;
+ }
+
+ *out_min_version = min_version;
+ *out_max_version = max_version;
+ return true;
+}
+
+static uint16_t ssl_version(const SSL *ssl) {
+ // In early data, we report the predicted version.
+ if (SSL_in_early_data(ssl) && !ssl->server) {
+ return ssl->s3->hs->early_session->ssl_version;
+ }
+ return ssl->version;
+}
+
uint16_t ssl3_protocol_version(const SSL *ssl) {
assert(ssl->s3->have_version);
uint16_t version;
@@ -275,7 +299,7 @@
return version;
}
-int ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) {
+bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) {
SSL *const ssl = hs->ssl;
// As a client, only allow the configured TLS 1.3 variant. As a server,
// support all TLS 1.3 variants as long as tls13_variant is set to a
@@ -284,23 +308,19 @@
if (ssl->tls13_variant == tls13_default &&
(version == TLS1_3_EXPERIMENT_VERSION ||
version == TLS1_3_EXPERIMENT2_VERSION ||
- version == TLS1_3_EXPERIMENT3_VERSION ||
- version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION)) {
- return 0;
+ version == TLS1_3_EXPERIMENT3_VERSION)) {
+ return false;
}
} else {
if ((ssl->tls13_variant != tls13_experiment &&
- ssl->tls13_variant != tls13_no_session_id_experiment &&
version == TLS1_3_EXPERIMENT_VERSION) ||
(ssl->tls13_variant != tls13_experiment2 &&
version == TLS1_3_EXPERIMENT2_VERSION) ||
(ssl->tls13_variant != tls13_experiment3 &&
version == TLS1_3_EXPERIMENT3_VERSION) ||
- (ssl->tls13_variant != tls13_record_type_experiment &&
- version == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) ||
(ssl->tls13_variant != tls13_default &&
version == TLS1_3_DRAFT_VERSION)) {
- return 0;
+ return false;
}
}
@@ -311,21 +331,21 @@
protocol_version <= hs->max_version;
}
-int ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb) {
+bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb) {
const uint16_t *versions;
size_t num_versions;
get_method_versions(hs->ssl->method, &versions, &num_versions);
for (size_t i = 0; i < num_versions; i++) {
if (ssl_supports_version(hs, versions[i]) &&
!CBB_add_u16(cbb, versions[i])) {
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
-int ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- uint16_t *out_version, const CBS *peer_versions) {
+bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ uint16_t *out_version, const CBS *peer_versions) {
const uint16_t *versions;
size_t num_versions;
get_method_versions(hs->ssl->method, &versions, &num_versions);
@@ -340,19 +360,19 @@
if (!CBS_get_u16(©, &version)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
if (version == versions[i]) {
*out_version = version;
- return 1;
+ return true;
}
}
}
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
*out_alert = SSL_AD_PROTOCOL_VERSION;
- return 0;
+ return false;
}
bool ssl_is_resumption_experiment(uint16_t version) {
@@ -397,16 +417,7 @@
}
int SSL_version(const SSL *ssl) {
- uint16_t ret = ssl_version(ssl);
- // Report TLS 1.3 draft version as TLS 1.3 in the public API.
- if (ret == TLS1_3_DRAFT_VERSION ||
- ret == TLS1_3_EXPERIMENT_VERSION ||
- ret == TLS1_3_EXPERIMENT2_VERSION ||
- ret == TLS1_3_EXPERIMENT3_VERSION ||
- ret == TLS1_3_RECORD_TYPE_EXPERIMENT_VERSION) {
- return TLS1_3_VERSION;
- }
- return ret;
+ return wire_version_to_api(ssl_version(ssl));
}
const char *SSL_get_version(const SSL *ssl) {
@@ -416,3 +427,13 @@
const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
return ssl_version_to_string(session->ssl_version);
}
+
+uint16_t SSL_SESSION_get_protocol_version(const SSL_SESSION *session) {
+ return wire_version_to_api(session->ssl_version);
+}
+
+int SSL_SESSION_set_protocol_version(SSL_SESSION *session, uint16_t version) {
+ // This picks a representative TLS 1.3 version, but this API should only be
+ // used on unit test sessions anyway.
+ return api_version_to_wire(&session->ssl_version, version);
+}
diff --git a/src/ssl/t1_enc.cc b/src/ssl/t1_enc.cc
index d693007..85c368c 100644
--- a/src/ssl/t1_enc.cc
+++ b/src/ssl/t1_enc.cc
@@ -318,7 +318,7 @@
static int tls1_setup_key_block(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- if (hs->key_block_len != 0) {
+ if (!hs->key_block.empty()) {
return 1;
}
@@ -356,22 +356,13 @@
ssl->s3->tmp.new_key_len = (uint8_t)key_len;
ssl->s3->tmp.new_fixed_iv_len = (uint8_t)fixed_iv_len;
- size_t key_block_len = SSL_get_key_block_len(ssl);
-
- uint8_t *keyblock = (uint8_t *)OPENSSL_malloc(key_block_len);
- if (keyblock == NULL) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ Array<uint8_t> key_block;
+ if (!key_block.Init(SSL_get_key_block_len(ssl)) ||
+ !SSL_generate_key_block(ssl, key_block.data(), key_block.size())) {
return 0;
}
- if (!SSL_generate_key_block(ssl, keyblock, key_block_len)) {
- OPENSSL_free(keyblock);
- return 0;
- }
-
- assert(key_block_len < 256);
- hs->key_block_len = (uint8_t)key_block_len;
- hs->key_block = keyblock;
+ hs->key_block = std::move(key_block);
return 1;
}
@@ -383,45 +374,28 @@
return 0;
}
- // use_client_keys is true if we wish to use the keys for the "client write"
- // direction. This is the case if we're a client sending a ChangeCipherSpec,
- // or a server reading a client's ChangeCipherSpec.
- const bool use_client_keys =
- direction == (ssl->server ? evp_aead_open : evp_aead_seal);
-
size_t mac_secret_len = ssl->s3->tmp.new_mac_secret_len;
size_t key_len = ssl->s3->tmp.new_key_len;
size_t iv_len = ssl->s3->tmp.new_fixed_iv_len;
- assert((mac_secret_len + key_len + iv_len) * 2 == hs->key_block_len);
+ assert((mac_secret_len + key_len + iv_len) * 2 == hs->key_block.size());
- const uint8_t *key_data = hs->key_block;
- const uint8_t *client_write_mac_secret = key_data;
- key_data += mac_secret_len;
- const uint8_t *server_write_mac_secret = key_data;
- key_data += mac_secret_len;
- const uint8_t *client_write_key = key_data;
- key_data += key_len;
- const uint8_t *server_write_key = key_data;
- key_data += key_len;
- const uint8_t *client_write_iv = key_data;
- key_data += iv_len;
- const uint8_t *server_write_iv = key_data;
- key_data += iv_len;
-
- const uint8_t *mac_secret, *key, *iv;
- if (use_client_keys) {
- mac_secret = client_write_mac_secret;
- key = client_write_key;
- iv = client_write_iv;
+ Span<const uint8_t> key_block = hs->key_block;
+ Span<const uint8_t> mac_secret, key, iv;
+ if (direction == (ssl->server ? evp_aead_open : evp_aead_seal)) {
+ // Use the client write (server read) keys.
+ mac_secret = key_block.subspan(0, mac_secret_len);
+ key = key_block.subspan(2 * mac_secret_len, key_len);
+ iv = key_block.subspan(2 * mac_secret_len + 2 * key_len, iv_len);
} else {
- mac_secret = server_write_mac_secret;
- key = server_write_key;
- iv = server_write_iv;
+ // Use the server write (client read) keys.
+ mac_secret = key_block.subspan(mac_secret_len, mac_secret_len);
+ key = key_block.subspan(2 * mac_secret_len + key_len, key_len);
+ iv = key_block.subspan(2 * mac_secret_len + 2 * key_len + iv_len, iv_len);
}
- UniquePtr<SSLAEADContext> aead_ctx = SSLAEADContext::Create(
- direction, ssl->version, SSL_is_dtls(ssl), hs->new_cipher, key, key_len,
- mac_secret, mac_secret_len, iv, iv_len);
+ UniquePtr<SSLAEADContext> aead_ctx =
+ SSLAEADContext::Create(direction, ssl->version, SSL_is_dtls(ssl),
+ hs->new_cipher, key, mac_secret, iv);
if (!aead_ctx) {
return 0;
}
@@ -488,7 +462,7 @@
SSL3_RANDOM_SIZE, ssl->s3->client_random, SSL3_RANDOM_SIZE);
}
- const EVP_MD *digest = SSL_SESSION_get_digest(session);
+ const EVP_MD *digest = ssl_session_get_digest(session);
return tls1_prf(digest, out, out_len, session->master_key,
session->master_key_length, TLS_MD_KEY_EXPANSION_CONST,
TLS_MD_KEY_EXPANSION_CONST_SIZE, ssl->s3->server_random,
@@ -537,7 +511,7 @@
}
const SSL_SESSION *session = SSL_get_session(ssl);
- const EVP_MD *digest = SSL_SESSION_get_digest(session);
+ const EVP_MD *digest = ssl_session_get_digest(session);
int ret = tls1_prf(digest, out, out_len, session->master_key,
session->master_key_length, label, label_len, seed,
seed_len, NULL, 0);
diff --git a/src/ssl/t1_lib.cc b/src/ssl/t1_lib.cc
index 1fe360b..9c4231d 100644
--- a/src/ssl/t1_lib.cc
+++ b/src/ssl/t1_lib.cc
@@ -930,7 +930,7 @@
ssl->session != NULL &&
ssl->session->tlsext_tick != NULL &&
// Don't send TLS 1.3 session tickets in the ticket extension.
- SSL_SESSION_protocol_version(ssl->session) < TLS1_3_VERSION) {
+ ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) {
ticket_data = ssl->session->tlsext_tick;
ticket_len = ssl->session->tlsext_ticklen;
}
@@ -1808,18 +1808,18 @@
static size_t ext_pre_shared_key_clienthello_length(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
if (hs->max_version < TLS1_3_VERSION || ssl->session == NULL ||
- SSL_SESSION_protocol_version(ssl->session) < TLS1_3_VERSION) {
+ ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) {
return 0;
}
- size_t binder_len = EVP_MD_size(SSL_SESSION_get_digest(ssl->session));
+ size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session));
return 15 + ssl->session->tlsext_ticklen + binder_len;
}
static int ext_pre_shared_key_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (hs->max_version < TLS1_3_VERSION || ssl->session == NULL ||
- SSL_SESSION_protocol_version(ssl->session) < TLS1_3_VERSION) {
+ ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) {
return 1;
}
@@ -1831,7 +1831,7 @@
// Fill in a placeholder zero binder of the appropriate length. It will be
// computed and filled in later after length prefixes are computed.
uint8_t zero_binder[EVP_MAX_MD_SIZE] = {0};
- size_t binder_len = EVP_MD_size(SSL_SESSION_get_digest(ssl->session));
+ size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session));
CBB contents, identity, ticket, binders, binder;
if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) ||
@@ -1997,7 +1997,7 @@
static int ext_early_data_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (ssl->session == NULL ||
- SSL_SESSION_protocol_version(ssl->session) < TLS1_3_VERSION ||
+ ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION ||
ssl->session->ticket_max_early_data == 0 ||
hs->received_hello_retry_request ||
!ssl->cert->enable_early_data) {
@@ -2111,7 +2111,7 @@
// Predict the most preferred group.
Span<const uint16_t> groups = tls1_get_grouplist(ssl);
- if (groups.size() == 0) {
+ if (groups.empty()) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED);
return 0;
}
@@ -2290,7 +2290,7 @@
// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.2
static int ext_cookie_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
- if (hs->cookie.size() == 0) {
+ if (hs->cookie.empty()) {
return 1;
}
@@ -3184,7 +3184,7 @@
}
Span<const uint16_t> peer_sigalgs = hs->peer_sigalgs;
- if (peer_sigalgs.size() == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
+ if (peer_sigalgs.empty() && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
// If the client didn't specify any signature_algorithms extension then
// we can assume that it supports SHA1. See
// http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 8404d52..3991870 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -33,20 +33,17 @@
// A draft version of TLS 1.3 that is sent over the wire for the current draft.
const (
- tls13DraftVersion = 0x7f12
- tls13ExperimentVersion = 0x7e01
- tls13Experiment2Version = 0x7e02
- tls13Experiment3Version = 0x7e03
- tls13RecordTypeExperimentVersion = 0x7a12
+ tls13DraftVersion = 0x7f12
+ tls13ExperimentVersion = 0x7e01
+ tls13Experiment2Version = 0x7e02
+ tls13Experiment3Version = 0x7e03
)
const (
- TLS13Default = 0
- TLS13Experiment = 1
- TLS13RecordTypeExperiment = 2
- TLS13NoSessionIDExperiment = 3
- TLS13Experiment2 = 4
- TLS13Experiment3 = 5
+ TLS13Default = 0
+ TLS13Experiment = 1
+ TLS13Experiment2 = 2
+ TLS13Experiment3 = 3
)
var allTLSWireVersions = []uint16{
@@ -54,7 +51,6 @@
tls13Experiment3Version,
tls13Experiment2Version,
tls13ExperimentVersion,
- tls13RecordTypeExperimentVersion,
VersionTLS12,
VersionTLS11,
VersionTLS10,
@@ -743,10 +739,6 @@
// connection if there is not a SessionID in the ClientHello.
ExpectClientHelloSessionID bool
- // ExpectEmptyClientHelloSessionID, if true, causes the server to fail the
- // connection if there is a SessionID in the ClientHello.
- ExpectEmptyClientHelloSessionID bool
-
// ExpectNoTLS12Session, if true, causes the server to fail the
// connection if either a session ID or TLS 1.2 ticket is offered.
ExpectNoTLS12Session bool
@@ -1394,6 +1386,12 @@
// empty slice, no extension will be sent.
SendSupportedPointFormats []byte
+ // SendServerSupportedCurves, if true, causes the server to send its
+ // supported curves list in the ServerHello (TLS 1.2) or
+ // EncryptedExtensions (TLS 1.3) message. This is invalid in TLS 1.2 and
+ // valid in TLS 1.3.
+ SendServerSupportedCurves bool
+
// MaxReceivePlaintext, if non-zero, is the maximum plaintext record
// length accepted from the peer.
MaxReceivePlaintext int
@@ -1558,7 +1556,7 @@
switch vers {
case VersionSSL30, VersionTLS10, VersionTLS11, VersionTLS12:
return vers, true
- case tls13DraftVersion, tls13ExperimentVersion, tls13Experiment2Version, tls13Experiment3Version, tls13RecordTypeExperimentVersion:
+ case tls13DraftVersion, tls13ExperimentVersion, tls13Experiment2Version, tls13Experiment3Version:
return VersionTLS13, true
}
}
@@ -1582,10 +1580,9 @@
// it returns true and the corresponding protocol version. Otherwise, it returns
// false.
func (c *Config) isSupportedVersion(wireVers uint16, isDTLS bool) (uint16, bool) {
- if (c.TLS13Variant != TLS13Experiment && c.TLS13Variant != TLS13NoSessionIDExperiment && wireVers == tls13ExperimentVersion) ||
+ if (c.TLS13Variant != TLS13Experiment && wireVers == tls13ExperimentVersion) ||
(c.TLS13Variant != TLS13Experiment2 && wireVers == tls13Experiment2Version) ||
(c.TLS13Variant != TLS13Experiment3 && wireVers == tls13Experiment3Version) ||
- (c.TLS13Variant != TLS13RecordTypeExperiment && wireVers == tls13RecordTypeExperimentVersion) ||
(c.TLS13Variant != TLS13Default && wireVers == tls13DraftVersion) {
return 0, false
}
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index 25123b1..a80e3c8 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -774,11 +774,6 @@
return 0, nil, c.in.setErrorLocked(errors.New("tls: unsupported SSLv2 handshake received"))
}
- // Accept server_plaintext_handshake records when the content type TLS 1.3 variant is enabled.
- if c.isClient && c.in.cipher == nil && c.config.TLS13Variant == TLS13RecordTypeExperiment && want == recordTypeHandshake && typ == recordTypePlaintextHandshake {
- typ = recordTypeHandshake
- }
-
vers := uint16(b.data[1])<<8 | uint16(b.data[2])
n := int(b.data[3])<<8 | int(b.data[4])
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index 5dbcab9..bf9cb7f 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -1149,6 +1149,7 @@
keyShare keyShareEntry
supportedVersion uint16
supportedPoints []uint8
+ supportedCurves []CurveID
serverNameAck bool
}
@@ -1256,6 +1257,15 @@
supportedPoints := supportedPointsList.addU8LengthPrefixed()
supportedPoints.addBytes(m.supportedPoints)
}
+ if len(m.supportedCurves) > 0 {
+ // https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.4
+ extensions.addU16(extensionSupportedCurves)
+ supportedCurvesList := extensions.addU16LengthPrefixed()
+ supportedCurves := supportedCurvesList.addU16LengthPrefixed()
+ for _, curve := range m.supportedCurves {
+ supportedCurves.addU16(uint16(curve))
+ }
+ }
if m.hasEarlyData {
extensions.addU16(extensionEarlyData)
extensions.addBytes([]byte{0, 0})
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 0a67a80..f67cc94 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -573,11 +573,7 @@
if sendHelloRetryRequest {
oldClientHelloBytes := hs.clientHello.marshal()
hs.writeServerHash(helloRetryRequest.marshal())
- if c.vers == tls13RecordTypeExperimentVersion {
- c.writeRecord(recordTypePlaintextHandshake, helloRetryRequest.marshal())
- } else {
- c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
- }
+ c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
c.flushHandshake()
if hs.clientHello.hasEarlyData {
@@ -755,11 +751,7 @@
toWrite = append(toWrite, typeEncryptedExtensions)
c.writeRecord(recordTypeHandshake, toWrite)
} else {
- if c.vers == tls13RecordTypeExperimentVersion {
- c.writeRecord(recordTypePlaintextHandshake, hs.hello.marshal())
- } else {
- c.writeRecord(recordTypeHandshake, hs.hello.marshal())
- }
+ c.writeRecord(recordTypeHandshake, hs.hello.marshal())
}
c.flushHandshake()
@@ -1089,9 +1081,6 @@
copy(hs.hello.random[len(hs.hello.random)-8:], downgradeTLS12)
}
- if len(hs.clientHello.sessionId) > 0 && c.config.Bugs.ExpectEmptyClientHelloSessionID {
- return false, errors.New("tls: expected empty session ID from client")
- }
if len(hs.clientHello.sessionId) == 0 && c.config.Bugs.ExpectClientHelloSessionID {
return false, errors.New("tls: expected non-empty session ID from client")
}
@@ -1308,6 +1297,10 @@
serverExtensions.supportedPoints = c.config.Bugs.SendSupportedPointFormats
}
+ if c.config.Bugs.SendServerSupportedCurves {
+ serverExtensions.supportedCurves = c.config.curvePreferences()
+ }
+
if !hs.clientHello.hasGREASEExtension && config.Bugs.ExpectGREASE {
return errors.New("tls: no GREASE extension found")
}
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 5415aa5..39a3765 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -1316,13 +1316,6 @@
versionWire: tls13Experiment3Version,
tls13Variant: TLS13Experiment3,
},
- {
- name: "TLS13RecordTypeExperiment",
- version: VersionTLS13,
- excludeFlag: "-no-tls13",
- versionWire: tls13RecordTypeExperimentVersion,
- tls13Variant: TLS13RecordTypeExperiment,
- },
}
func allVersions(protocol protocol) []tlsVersion {
@@ -9619,6 +9612,28 @@
expectedError: ":ERROR_PARSING_EXTENSION:",
})
+ // Server-sent supported groups/curves are legal in TLS 1.3. They are
+ // illegal in TLS 1.2, but some servers send them anyway, so we must
+ // tolerate them.
+ testCases = append(testCases, testCase{
+ name: "SupportedCurves-ServerHello-TLS12",
+ config: Config{
+ MaxVersion: VersionTLS12,
+ Bugs: ProtocolBugs{
+ SendServerSupportedCurves: true,
+ },
+ },
+ })
+ testCases = append(testCases, testCase{
+ name: "SupportedCurves-EncryptedExtensions-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendServerSupportedCurves: true,
+ },
+ },
+ })
+
// Test that we tolerate unknown point formats, as long as
// pointFormatUncompressed is present. Limit ciphers to ECDHE ciphers to
// check they are still functional.
@@ -10762,10 +10777,7 @@
})
hasSessionID := false
- hasEmptySessionID := false
- if variant == TLS13NoSessionIDExperiment {
- hasEmptySessionID = true
- } else if variant != TLS13Default && variant != TLS13RecordTypeExperiment {
+ if variant != TLS13Default {
hasSessionID = true
}
@@ -10776,8 +10788,7 @@
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
- ExpectClientHelloSessionID: hasSessionID,
- ExpectEmptyClientHelloSessionID: hasEmptySessionID,
+ ExpectClientHelloSessionID: hasSessionID,
},
},
tls13Variant: variant,
diff --git a/src/ssl/tls13_enc.cc b/src/ssl/tls13_enc.cc
index 6ff9972..0a36aab 100644
--- a/src/ssl/tls13_enc.cc
+++ b/src/ssl/tls13_enc.cc
@@ -57,7 +57,7 @@
int tls13_init_early_key_schedule(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
- return init_key_schedule(hs, SSL_SESSION_protocol_version(ssl->session),
+ return init_key_schedule(hs, ssl_session_protocol_version(ssl->session),
ssl->session->cipher);
}
@@ -116,7 +116,7 @@
const uint8_t *traffic_secret,
size_t traffic_secret_len) {
const SSL_SESSION *session = SSL_get_session(ssl);
- uint16_t version = SSL_SESSION_protocol_version(session);
+ uint16_t version = ssl_session_protocol_version(session);
if (traffic_secret_len > 0xff) {
OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
@@ -131,7 +131,7 @@
return 0;
}
- const EVP_MD *digest = SSL_SESSION_get_digest(session);
+ const EVP_MD *digest = ssl_session_get_digest(session);
// Derive the key.
size_t key_len = EVP_AEAD_key_length(aead);
@@ -149,9 +149,10 @@
return 0;
}
- UniquePtr<SSLAEADContext> traffic_aead = SSLAEADContext::Create(
- direction, session->ssl_version, SSL_is_dtls(ssl), session->cipher, key,
- key_len, NULL, 0, iv, iv_len);
+ UniquePtr<SSLAEADContext> traffic_aead =
+ SSLAEADContext::Create(direction, session->ssl_version, SSL_is_dtls(ssl),
+ session->cipher, MakeConstSpan(key, key_len),
+ Span<const uint8_t>(), MakeConstSpan(iv, iv_len));
if (!traffic_aead) {
return 0;
}
@@ -235,7 +236,9 @@
hs->server_traffic_secret_0, hs->hash_len) &&
derive_secret(hs, ssl->s3->exporter_secret, hs->hash_len,
(const uint8_t *)kTLS13LabelExporter,
- strlen(kTLS13LabelExporter));
+ strlen(kTLS13LabelExporter)) &&
+ ssl_log_secret(ssl, "EXPORTER_SECRET", ssl->s3->exporter_secret,
+ hs->hash_len);
}
static const char kTLS13LabelApplicationTraffic[] =
@@ -252,7 +255,7 @@
secret_len = ssl->s3->write_traffic_secret_len;
}
- const EVP_MD *digest = SSL_SESSION_get_digest(SSL_get_session(ssl));
+ const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));
if (!hkdf_expand_label(secret, digest, secret, secret_len,
(const uint8_t *)kTLS13LabelApplicationTraffic,
strlen(kTLS13LabelApplicationTraffic), NULL, 0,
@@ -327,7 +330,7 @@
hash_len = context_len;
}
- const EVP_MD *digest = SSL_SESSION_get_digest(SSL_get_session(ssl));
+ const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));
return hkdf_expand_label(out, digest, ssl->s3->exporter_secret,
ssl->s3->exporter_secret_len, (const uint8_t *)label,
label_len, hash, hash_len, out_len);
@@ -367,7 +370,7 @@
int tls13_write_psk_binder(SSL_HANDSHAKE *hs, uint8_t *msg, size_t len) {
SSL *const ssl = hs->ssl;
- const EVP_MD *digest = SSL_SESSION_get_digest(ssl->session);
+ const EVP_MD *digest = ssl_session_get_digest(ssl->session);
size_t hash_len = EVP_MD_size(digest);
if (len < hash_len + 3) {
diff --git a/src/tool/client.cc b/src/tool/client.cc
index e1d9a26..d439860 100644
--- a/src/tool/client.cc
+++ b/src/tool/client.cc
@@ -327,14 +327,6 @@
*out = tls13_experiment3;
return true;
}
- if (in == "record-type") {
- *out = tls13_record_type_experiment;
- return true;
- }
- if (in == "no-session-id") {
- *out = tls13_no_session_id_experiment;
- return true;
- }
return false;
}