external/boringssl: Sync to f8de2af7e319f83ba88579fbf127ba5fafc26c71.
This includes the following changes:
https://boringssl.googlesource.com/boringssl/+log/73ffb74b9e36a93a3e593010a367a610105da9a1..f8de2af7e319f83ba88579fbf127ba5fafc26c71
Change-Id: Iab4fb4fde30c1f26ad2b98160abca366bdea1da4
Test: BoringSSL CTS Presubmits.
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 3266ea2..ae5d0b6 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -220,6 +220,7 @@
asn1/asn1_test.cc
base64/base64_test.cc
+ buf/buf_test.cc
bio/bio_test.cc
bytestring/bytestring_test.cc
chacha/chacha_test.cc
diff --git a/src/crypto/buf/buf.c b/src/crypto/buf/buf.c
index 5addc79..146b1e0 100644
--- a/src/crypto/buf/buf.c
+++ b/src/crypto/buf/buf.c
@@ -86,7 +86,7 @@
OPENSSL_free(buf);
}
-static int buf_mem_reserve(BUF_MEM *buf, size_t cap, int clean) {
+int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) {
if (buf->max >= cap) {
return 1;
}
@@ -116,12 +116,8 @@
return 1;
}
-int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) {
- return buf_mem_reserve(buf, cap, 0 /* don't clear old buffer contents. */);
-}
-
-static size_t buf_mem_grow(BUF_MEM *buf, size_t len, int clean) {
- if (!buf_mem_reserve(buf, len, clean)) {
+size_t BUF_MEM_grow(BUF_MEM *buf, size_t len) {
+ if (!BUF_MEM_reserve(buf, len)) {
return 0;
}
if (buf->length < len) {
@@ -131,12 +127,22 @@
return len;
}
-size_t BUF_MEM_grow(BUF_MEM *buf, size_t len) {
- return buf_mem_grow(buf, len, 0 /* don't clear old buffer contents. */);
+size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) {
+ return BUF_MEM_grow(buf, len);
}
-size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) {
- return buf_mem_grow(buf, len, 1 /* clear old buffer contents. */);
+int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) {
+ size_t new_len = buf->length + len;
+ if (new_len < len) {
+ OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW);
+ return 0;
+ }
+ if (!BUF_MEM_reserve(buf, new_len)) {
+ return 0;
+ }
+ OPENSSL_memcpy(buf->data + buf->length, in, len);
+ buf->length = new_len;
+ return 1;
}
char *BUF_strdup(const char *str) {
diff --git a/src/crypto/buf/buf_test.cc b/src/crypto/buf/buf_test.cc
new file mode 100644
index 0000000..4be0394
--- /dev/null
+++ b/src/crypto/buf/buf_test.cc
@@ -0,0 +1,97 @@
+/* Copyright (c) 2017, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/buf.h>
+
+#include <string.h>
+
+#include <string>
+
+#include <gtest/gtest.h>
+
+
+TEST(BufTest, Basic) {
+ bssl::UniquePtr<BUF_MEM> buf(BUF_MEM_new());
+ ASSERT_TRUE(buf);
+ EXPECT_EQ(0u, buf->length);
+
+ // Use BUF_MEM_reserve to increase buf->max.
+ ASSERT_TRUE(BUF_MEM_reserve(buf.get(), 200));
+ EXPECT_GE(buf->max, 200u);
+ EXPECT_EQ(0u, buf->length);
+
+ // BUF_MEM_reserve with a smaller cap is a no-op.
+ size_t old_max = buf->max;
+ ASSERT_TRUE(BUF_MEM_reserve(buf.get(), 100));
+ EXPECT_EQ(old_max, buf->max);
+ EXPECT_EQ(0u, buf->length);
+
+ // BUF_MEM_grow can increase the length without reallocating.
+ ASSERT_EQ(100u, BUF_MEM_grow(buf.get(), 100));
+ EXPECT_EQ(100u, buf->length);
+ EXPECT_EQ(old_max, buf->max);
+ memset(buf->data, 'A', buf->length);
+
+ // If BUF_MEM_reserve reallocates, it preserves the contents.
+ ASSERT_TRUE(BUF_MEM_reserve(buf.get(), old_max + 1));
+ ASSERT_GE(buf->max, old_max + 1);
+ EXPECT_EQ(100u, buf->length);
+ for (size_t i = 0; i < 100; i++) {
+ EXPECT_EQ('A', buf->data[i]);
+ }
+
+ // BUF_MEM_grow should zero everything beyond buf->length.
+ memset(buf->data, 'B', buf->max);
+ ASSERT_EQ(150u, BUF_MEM_grow(buf.get(), 150));
+ EXPECT_EQ(150u, buf->length);
+ for (size_t i = 0; i < 100; i++) {
+ EXPECT_EQ('B', buf->data[i]);
+ }
+ for (size_t i = 100; i < 150; i++) {
+ EXPECT_EQ(0, buf->data[i]);
+ }
+
+ // BUF_MEM_grow can rellocate if necessary.
+ size_t new_len = buf->max + 1;
+ ASSERT_EQ(new_len, BUF_MEM_grow(buf.get(), new_len));
+ EXPECT_GE(buf->max, new_len);
+ EXPECT_EQ(new_len, buf->length);
+ for (size_t i = 0; i < 100; i++) {
+ EXPECT_EQ('B', buf->data[i]);
+ }
+ for (size_t i = 100; i < new_len; i++) {
+ EXPECT_EQ(0, buf->data[i]);
+ }
+
+ // BUF_MEM_grow can shink.
+ ASSERT_EQ(50u, BUF_MEM_grow(buf.get(), 50));
+ EXPECT_EQ(50u, buf->length);
+ for (size_t i = 0; i < 50; i++) {
+ EXPECT_EQ('B', buf->data[i]);
+ }
+}
+
+TEST(BufTest, Append) {
+ bssl::UniquePtr<BUF_MEM> buf(BUF_MEM_new());
+ ASSERT_TRUE(buf);
+
+ ASSERT_TRUE(BUF_MEM_append(buf.get(), nullptr, 0));
+ ASSERT_TRUE(BUF_MEM_append(buf.get(), "hello ", 6));
+ ASSERT_TRUE(BUF_MEM_append(buf.get(), nullptr, 0));
+ ASSERT_TRUE(BUF_MEM_append(buf.get(), "world", 5));
+ std::string str(128, 'A');
+ ASSERT_TRUE(BUF_MEM_append(buf.get(), str.data(), str.size()));
+
+ EXPECT_EQ("hello world" + str, std::string(buf->data, buf->length));
+}
diff --git a/src/crypto/err/err.c b/src/crypto/err/err.c
index a620fc7..c7bff16 100644
--- a/src/crypto/err/err.c
+++ b/src/crypto/err/err.c
@@ -123,8 +123,39 @@
#include <openssl/thread.h>
#include "../internal.h"
+#include "./internal.h"
+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_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;
+
extern const uint32_t kOpenSSLReasonValues[];
extern const size_t kOpenSSLReasonValuesLen;
extern const char kOpenSSLReasonStringData[];
@@ -135,6 +166,16 @@
OPENSSL_memset(error, 0, sizeof(struct err_error_st));
}
+static void err_copy(struct err_error_st *dst, const struct err_error_st *src) {
+ err_clear(dst);
+ dst->file = src->file;
+ if (src->data != NULL) {
+ dst->data = OPENSSL_strdup(src->data);
+ }
+ dst->packed = src->packed;
+ dst->line = src->line;
+}
+
// global_next_library contains the next custom library value to return.
static int global_next_library = ERR_NUM_LIBS;
@@ -150,8 +191,7 @@
return;
}
- unsigned i;
- for (i = 0; i < ERR_NUM_ERRORS; i++) {
+ for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) {
err_clear(&state->errors[i]);
}
OPENSSL_free(state->to_free);
@@ -740,3 +780,68 @@
void ERR_load_BIO_strings(void) {}
void ERR_load_ERR_strings(void) {}
+
+struct err_save_state_st {
+ struct err_error_st *errors;
+ size_t num_errors;
+};
+
+void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) {
+ if (state == NULL) {
+ return;
+ }
+ for (size_t i = 0; i < state->num_errors; i++) {
+ err_clear(&state->errors[i]);
+ }
+ OPENSSL_free(state->errors);
+ OPENSSL_free(state);
+}
+
+ERR_SAVE_STATE *ERR_save_state(void) {
+ ERR_STATE *const state = err_get_state();
+ if (state == NULL || state->top == state->bottom) {
+ return NULL;
+ }
+
+ ERR_SAVE_STATE *ret = OPENSSL_malloc(sizeof(ERR_SAVE_STATE));
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ // Errors are stored in the range (bottom, top].
+ size_t num_errors = state->top >= state->bottom
+ ? state->top - state->bottom
+ : ERR_NUM_ERRORS + state->top - state->bottom;
+ assert(num_errors < ERR_NUM_ERRORS);
+ ret->errors = OPENSSL_malloc(num_errors * sizeof(struct err_error_st));
+ if (ret->errors == NULL) {
+ OPENSSL_free(ret);
+ return NULL;
+ }
+ OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st));
+ ret->num_errors = num_errors;
+
+ for (size_t i = 0; i < num_errors; i++) {
+ size_t j = (state->bottom + i + 1) % ERR_NUM_ERRORS;
+ err_copy(&ret->errors[i], &state->errors[j]);
+ }
+ return ret;
+}
+
+void ERR_restore_state(const ERR_SAVE_STATE *state) {
+ if (state == NULL || state->num_errors == 0) {
+ ERR_clear_error();
+ return;
+ }
+
+ ERR_STATE *const dst = err_get_state();
+ if (dst == NULL) {
+ return;
+ }
+
+ for (size_t i = 0; i < state->num_errors; i++) {
+ err_copy(&dst->errors[i], &state->errors[i]);
+ }
+ dst->top = state->num_errors - 1;
+ dst->bottom = ERR_NUM_ERRORS - 1;
+}
diff --git a/src/crypto/err/err_test.cc b/src/crypto/err/err_test.cc
index 5d04ae2..489d248 100644
--- a/src/crypto/err/err_test.cc
+++ b/src/crypto/err/err_test.cc
@@ -21,6 +21,8 @@
#include <openssl/err.h>
#include <openssl/mem.h>
+#include "./internal.h"
+
TEST(ErrTest, Overflow) {
for (unsigned i = 0; i < ERR_NUM_ERRORS*2; i++) {
@@ -119,3 +121,94 @@
EXPECT_EQ(ERR_LIB_USER, ERR_GET_LIB(error));
EXPECT_EQ(ERR_R_INTERNAL_ERROR, ERR_GET_REASON(error));
}
+
+TEST(ErrTest, SaveAndRestore) {
+ // Restoring no state clears the error queue, including error data.
+ ERR_put_error(1, 0 /* unused */, 1, "test1.c", 1);
+ ERR_put_error(2, 0 /* unused */, 2, "test2.c", 2);
+ ERR_add_error_data(1, "data1");
+ ERR_restore_state(nullptr);
+ EXPECT_EQ(0u, ERR_get_error());
+
+ // Add some entries to the error queue and save it.
+ ERR_put_error(1, 0 /* unused */, 1, "test1.c", 1);
+ ERR_add_error_data(1, "data1");
+ ERR_put_error(2, 0 /* unused */, 2, "test2.c", 2);
+ ERR_put_error(3, 0 /* unused */, 3, "test3.c", 3);
+ ERR_add_error_data(1, "data3");
+ bssl::UniquePtr<ERR_SAVE_STATE> saved(ERR_save_state());
+ ASSERT_TRUE(saved);
+
+ // The existing error queue entries still exist.
+ int line, flags;
+ const char *file, *data;
+ uint32_t packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
+ EXPECT_EQ(ERR_GET_LIB(packed_error), 1);
+ EXPECT_EQ(ERR_GET_REASON(packed_error), 1);
+ EXPECT_STREQ("test1.c", file);
+ EXPECT_EQ(line, 1);
+ EXPECT_STREQ(data, "data1");
+ EXPECT_EQ(flags, ERR_FLAG_STRING);
+
+ // The state may be restored, both over an empty and non-empty state.
+ for (unsigned i = 0; i < 2; i++) {
+ SCOPED_TRACE(i);
+ ERR_restore_state(saved.get());
+
+ packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
+ EXPECT_EQ(ERR_GET_LIB(packed_error), 1);
+ EXPECT_EQ(ERR_GET_REASON(packed_error), 1);
+ EXPECT_STREQ("test1.c", file);
+ EXPECT_EQ(line, 1);
+ EXPECT_STREQ(data, "data1");
+ EXPECT_EQ(flags, ERR_FLAG_STRING);
+
+ packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
+ EXPECT_EQ(ERR_GET_LIB(packed_error), 2);
+ EXPECT_EQ(ERR_GET_REASON(packed_error), 2);
+ EXPECT_STREQ("test2.c", file);
+ EXPECT_EQ(line, 2);
+ EXPECT_STREQ(data, ""); // No error data is reported as the empty string.
+ EXPECT_EQ(flags, 0);
+
+ packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
+ EXPECT_EQ(ERR_GET_LIB(packed_error), 3);
+ EXPECT_EQ(ERR_GET_REASON(packed_error), 3);
+ EXPECT_STREQ("test3.c", file);
+ EXPECT_EQ(line, 3);
+ EXPECT_STREQ(data, "data3");
+ EXPECT_EQ(flags, ERR_FLAG_STRING);
+
+ // The error queue is now empty for the next iteration.
+ EXPECT_EQ(0u, ERR_get_error());
+ }
+
+ // Test a case where the error queue wraps around. The first set of errors
+ // will all be discarded, but result in wrapping the list around.
+ ERR_clear_error();
+ for (unsigned i = 0; i < ERR_NUM_ERRORS / 2; i++) {
+ ERR_put_error(0, 0 /* unused */, 0, "invalid", 0);
+ }
+ for (unsigned i = 1; i < ERR_NUM_ERRORS; i++) {
+ ERR_put_error(i, 0 /* unused */, i, "test", i);
+ }
+ saved.reset(ERR_save_state());
+
+ // The state may be restored, both over an empty and non-empty state. Pop one
+ // error off so the first iteration is tested to not be a no-op.
+ ERR_get_error();
+ for (int i = 0; i < 2; i++) {
+ SCOPED_TRACE(i);
+ ERR_restore_state(saved.get());
+ for (int j = 1; j < ERR_NUM_ERRORS; j++) {
+ SCOPED_TRACE(j);
+ packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
+ EXPECT_EQ(ERR_GET_LIB(packed_error), j);
+ EXPECT_EQ(ERR_GET_REASON(packed_error), j);
+ EXPECT_STREQ("test", file);
+ EXPECT_EQ(line, j);
+ }
+ // The error queue is now empty for the next iteration.
+ EXPECT_EQ(0u, ERR_get_error());
+ }
+}
diff --git a/src/crypto/err/internal.h b/src/crypto/err/internal.h
new file mode 100644
index 0000000..3f2397c
--- /dev/null
+++ b/src/crypto/err/internal.h
@@ -0,0 +1,58 @@
+/* Copyright (c) 2017, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H
+#define OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H
+
+#include <openssl/err.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+// Private error queue functions.
+
+// ERR_SAVE_STATE contains a saved representation of the error queue. It is
+// slightly more compact than |ERR_STATE| as the error queue will typically not
+// contain |ERR_NUM_ERRORS| entries.
+typedef struct err_save_state_st ERR_SAVE_STATE;
+
+// ERR_SAVE_STATE_free releases all memory associated with |state|.
+OPENSSL_EXPORT void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state);
+
+// ERR_save_state returns a newly-allocated |ERR_SAVE_STATE| structure
+// containing the current state of the error queue or NULL on allocation
+// error. It should be released with |ERR_SAVE_STATE_free|.
+OPENSSL_EXPORT ERR_SAVE_STATE *ERR_save_state(void);
+
+// ERR_restore_state clears the error queue and replaces it with |state|.
+OPENSSL_EXPORT void ERR_restore_state(const ERR_SAVE_STATE *state);
+
+
+#if defined(__cplusplus)
+} // extern C
+
+extern "C++" {
+
+namespace bssl {
+
+BORINGSSL_MAKE_DELETER(ERR_SAVE_STATE, ERR_SAVE_STATE_free)
+
+} // namespace bssl
+
+} // extern C++
+#endif
+
+#endif // OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H
diff --git a/src/include/openssl/buf.h b/src/include/openssl/buf.h
index d4c3e22..3f961b8 100644
--- a/src/include/openssl/buf.h
+++ b/src/include/openssl/buf.h
@@ -89,10 +89,14 @@
// zeros. It returns the length of |buf|, or zero if there's an error.
OPENSSL_EXPORT size_t BUF_MEM_grow(BUF_MEM *buf, size_t len);
-// BUF_MEM_grow_clean acts the same as |BUF_MEM_grow|, but clears the previous
-// contents of memory if reallocing.
+// BUF_MEM_grow_clean calls |BUF_MEM_grow|. BoringSSL always zeros memory
+// allocated memory on free.
OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len);
+// BUF_MEM_append appends |in| to |buf|. It returns one on success and zero on
+// error.
+OPENSSL_EXPORT int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len);
+
// BUF_strdup returns an allocated, duplicate of |str|.
OPENSSL_EXPORT char *BUF_strdup(const char *str);
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 66f6204..6d355b5 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -41,10 +41,16 @@
size_t len;
#if !defined(BORINGSSL_NO_CXX)
- // Allow implicit conversions to bssl::Span<const uint8_t>.
+ // Allow implicit conversions to and from bssl::Span<const uint8_t>.
+ cbs_st(bssl::Span<const uint8_t> span)
+ : data(span.data()), len(span.size()) {}
operator bssl::Span<const uint8_t>() const {
return bssl::MakeConstSpan(data, len);
}
+
+ // Defining any constructors requires we explicitly default the others.
+ cbs_st() = default;
+ cbs_st(const cbs_st &) = default;
#endif
};
diff --git a/src/include/openssl/chacha.h b/src/include/openssl/chacha.h
index 61deb8e..684fc5b 100644
--- a/src/include/openssl/chacha.h
+++ b/src/include/openssl/chacha.h
@@ -17,10 +17,14 @@
#include <openssl/base.h>
-#ifdef __cplusplus
+#if defined(__cplusplus)
extern "C" {
#endif
+// ChaCha20.
+//
+// ChaCha20 is a stream cipher. See https://tools.ietf.org/html/rfc7539.
+
// CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and
// nonce and writes the result to |out|. If |in| and |out| alias, they must be
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index 5de3cbd..9a65ffb 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -436,39 +436,10 @@
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.
+// ERR_NUM_ERRORS is one more than 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)))
diff --git a/src/include/openssl/span.h b/src/include/openssl/span.h
index 3109036..3a629f7 100644
--- a/src/include/openssl/span.h
+++ b/src/include/openssl/span.h
@@ -22,6 +22,7 @@
extern "C++" {
#include <algorithm>
+#include <cassert>
#include <cstdlib>
#include <type_traits>
@@ -134,6 +135,15 @@
T *end() const { return data_ + size_; };
const T *cend() const { return end(); };
+ T &front() const {
+ assert(size_ != 0);
+ return data_[0];
+ }
+ T &back() const {
+ assert(size_ != 0);
+ return data_[size_ - 1];
+ }
+
T &operator[](size_t i) const { return data_[i]; }
T &at(size_t i) const { return data_[i]; }
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 6b4bf81..a2d3ce7 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -146,7 +146,6 @@
#include <openssl/bio.h>
#include <openssl/buf.h>
-#include <openssl/lhash.h>
#include <openssl/pem.h>
#include <openssl/span.h>
#include <openssl/ssl3.h>
@@ -158,6 +157,11 @@
#include <sys/time.h>
#endif
+// NGINX needs this #include. Consider revisiting this after NGINX 1.14.0 has
+// been out for a year or so (assuming that they fix it in that release.) See
+// https://boringssl-review.googlesource.com/c/boringssl/+/21664.
+#include <openssl/hmac.h>
+
// Forward-declare struct timeval. On Windows, it is defined in winsock2.h and
// Windows headers define too many macros to be included in public headers.
// However, only a forward declaration is needed.
@@ -1042,8 +1046,8 @@
// |type| parameter is one of the |SSL_FILETYPE_*| values and determines whether
// the file's contents are read as PEM or DER.
-#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
-#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
+#define SSL_FILETYPE_PEM 1
+#define SSL_FILETYPE_ASN1 2
OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx,
const char *file,
@@ -1635,7 +1639,6 @@
// established, an |SSL_SESSION| may be shared by multiple |SSL| objects on
// different threads and must not be modified.
-DECLARE_LHASH_OF(SSL_SESSION)
DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
// SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on
@@ -2023,7 +2026,7 @@
// 1) One can simply set the keys with |SSL_CTX_set_tlsext_ticket_keys|.
// 2) One can configure an |EVP_CIPHER_CTX| and |HMAC_CTX| directly for
// encryption and authentication.
-// 3) One can configure an |SSL_TICKET_ENCRYPTION_METHOD| to have more control
+// 3) One can configure an |SSL_TICKET_AEAD_METHOD| to have more control
// and the option of asynchronous decryption.
//
// An attacker that compromises a server's session ticket key can impersonate
@@ -2100,8 +2103,8 @@
ssl_ticket_aead_error,
};
-// ssl_ticket_aead_method_st (aka |SSL_TICKET_ENCRYPTION_METHOD|) contains
-// methods for encrypting and decrypting session tickets.
+// ssl_ticket_aead_method_st (aka |SSL_TICKET_AEAD_METHOD|) contains methods
+// for encrypting and decrypting session tickets.
struct ssl_ticket_aead_method_st {
// max_overhead returns the maximum number of bytes of overhead that |seal|
// may add.
@@ -4042,13 +4045,9 @@
// This structures are exposed for historical reasons, but access to them is
// deprecated.
-// TODO(davidben): Opaquify most or all of |SSL_CTX| and |SSL_SESSION| so these
-// forward declarations are not needed.
-typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
+// TODO(davidben): Remove this forward declaration when |SSL_SESSION| is opaque.
typedef struct ssl_x509_method_st SSL_X509_METHOD;
-DECLARE_STACK_OF(SSL_CUSTOM_EXTENSION)
-
#define SSL_MAX_SSL_SESSION_ID_LENGTH 32
#define SSL_MAX_SID_CTX_LENGTH 32
#define SSL_MAX_MASTER_KEY_LENGTH 48
@@ -4177,319 +4176,6 @@
unsigned is_server:1;
};
-// ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with
-// equal-preference groups. For TLS clients, the groups are moot because the
-// server picks the cipher and groups cannot be expressed on the wire. However,
-// for servers, the equal-preference groups allow the client's preferences to
-// be partially respected. (This only has an effect with
-// SSL_OP_CIPHER_SERVER_PREFERENCE).
-//
-// The equal-preference groups are expressed by grouping SSL_CIPHERs together.
-// All elements of a group have the same priority: no ordering is expressed
-// within a group.
-//
-// The values in |ciphers| are in one-to-one correspondence with
-// |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of
-// bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to
-// indicate that the corresponding SSL_CIPHER is not the last element of a
-// group, or 0 to indicate that it is.
-//
-// For example, if |in_group_flags| contains all zeros then that indicates a
-// traditional, fully-ordered preference. Every SSL_CIPHER is the last element
-// of the group (i.e. they are all in a one-element group).
-//
-// For a more complex example, consider:
-// ciphers: A B C D E F
-// in_group_flags: 1 1 0 0 1 0
-//
-// That would express the following, order:
-//
-// A E
-// B -> D -> F
-// C
-struct ssl_cipher_preference_list_st {
- STACK_OF(SSL_CIPHER) *ciphers;
- uint8_t *in_group_flags;
-};
-
-struct tlsext_ticket_key {
- uint8_t name[SSL_TICKET_KEY_NAME_LEN];
- uint8_t hmac_key[16];
- uint8_t aes_key[16];
- // next_rotation_tv_sec is the time (in seconds from the epoch) when the
- // current key should be superseded by a new key, or the time when a previous
- // key should be dropped. If zero, then the key should not be automatically
- // rotated.
- uint64_t next_rotation_tv_sec;
-};
-
-// ssl_ctx_st (aka |SSL_CTX|) contains configuration common to several SSL
-// connections.
-struct ssl_ctx_st {
- const SSL_PROTOCOL_METHOD *method;
- const SSL_X509_METHOD *x509_method;
-
- // lock is used to protect various operations on this object.
- CRYPTO_MUTEX lock;
-
- // conf_max_version is the maximum acceptable protocol version configured by
- // |SSL_CTX_set_max_proto_version|. Note this version is normalized in DTLS
- // and is further constrainted by |SSL_OP_NO_*|.
- uint16_t conf_max_version;
-
- // conf_min_version is the minimum acceptable protocol version configured by
- // |SSL_CTX_set_min_proto_version|. Note this version is normalized in DTLS
- // and is further constrainted by |SSL_OP_NO_*|.
- uint16_t conf_min_version;
-
- // tls13_variant is the variant of TLS 1.3 we are using for this
- // configuration.
- enum tls13_variant_t tls13_variant;
-
- struct ssl_cipher_preference_list_st *cipher_list;
-
- X509_STORE *cert_store;
- LHASH_OF(SSL_SESSION) *sessions;
- // Most session-ids that will be cached, default is
- // SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
- unsigned long session_cache_size;
- SSL_SESSION *session_cache_head;
- SSL_SESSION *session_cache_tail;
-
- // handshakes_since_cache_flush is the number of successful handshakes since
- // the last cache flush.
- int handshakes_since_cache_flush;
-
- // This can have one of 2 values, ored together,
- // SSL_SESS_CACHE_CLIENT,
- // SSL_SESS_CACHE_SERVER,
- // Default is SSL_SESSION_CACHE_SERVER, which means only
- // SSL_accept which cache SSL_SESSIONS.
- int session_cache_mode;
-
- // session_timeout is the default lifetime for new sessions in TLS 1.2 and
- // earlier, in seconds.
- uint32_t session_timeout;
-
- // session_psk_dhe_timeout is the default lifetime for new sessions in TLS
- // 1.3, in seconds.
- uint32_t session_psk_dhe_timeout;
-
- // If this callback is not null, it will be called each time a session id is
- // added to the cache. If this function returns 1, it means that the
- // callback will do a SSL_SESSION_free() when it has finished using it.
- // Otherwise, on 0, it means the callback has finished with it. If
- // remove_session_cb is not null, it will be called when a session-id is
- // removed from the cache. After the call, OpenSSL will SSL_SESSION_free()
- // it.
- int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess);
- void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess);
- SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *data, int len,
- int *copy);
- SSL_SESSION *(*get_session_cb_legacy)(SSL *ssl, uint8_t *data, int len,
- int *copy);
-
- CRYPTO_refcount_t references;
-
- // if defined, these override the X509_verify_cert() calls
- int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg);
- void *app_verify_arg;
-
- enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl,
- uint8_t *out_alert);
-
- // Default password callback.
- pem_password_cb *default_passwd_callback;
-
- // Default password callback user data.
- void *default_passwd_callback_userdata;
-
- // get client cert callback
- int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey);
-
- // get channel id callback
- void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey);
-
- CRYPTO_EX_DATA ex_data;
-
- // custom_*_extensions stores any callback sets for custom extensions. Note
- // that these pointers will be NULL if the stack would otherwise be empty.
- STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions;
- STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions;
-
- // Default values used when no per-SSL value is defined follow
-
- void (*info_callback)(const SSL *ssl, int type, int value);
-
- // what we put in client cert requests
- STACK_OF(CRYPTO_BUFFER) *client_CA;
-
- // cached_x509_client_CA is a cache of parsed versions of the elements of
- // |client_CA|.
- STACK_OF(X509_NAME) *cached_x509_client_CA;
-
-
- // Default values to use in SSL structures follow (these are copied by
- // SSL_new)
-
- uint32_t options;
- uint32_t mode;
- uint32_t max_cert_list;
-
- struct cert_st *cert;
-
- // callback that allows applications to peek at protocol messages
- void (*msg_callback)(int write_p, int version, int content_type,
- const void *buf, size_t len, SSL *ssl, void *arg);
- void *msg_callback_arg;
-
- int verify_mode;
- int (*default_verify_callback)(
- int ok, X509_STORE_CTX *ctx); // called 'verify_callback' in the SSL
-
- X509_VERIFY_PARAM *param;
-
- // select_certificate_cb is called before most ClientHello processing and
- // before the decision whether to resume a session is made. See
- // |ssl_select_cert_result_t| for details of the return values.
- enum ssl_select_cert_result_t (*select_certificate_cb)(
- const SSL_CLIENT_HELLO *);
-
- // dos_protection_cb is called once the resumption decision for a ClientHello
- // has been made. It returns one to continue the handshake or zero to
- // abort.
- int (*dos_protection_cb) (const SSL_CLIENT_HELLO *);
-
- // Maximum amount of data to send in one fragment. actual record size can be
- // more than this due to padding and MAC overheads.
- uint16_t max_send_fragment;
-
- // TLS extensions servername callback
- int (*tlsext_servername_callback)(SSL *, int *, void *);
- void *tlsext_servername_arg;
-
- // RFC 4507 session ticket keys. |tlsext_ticket_key_current| may be NULL
- // before the first handshake and |tlsext_ticket_key_prev| may be NULL at any
- // time. Automatically generated ticket keys are rotated as needed at
- // handshake time. Hence, all access must be synchronized through |lock|.
- struct tlsext_ticket_key *tlsext_ticket_key_current;
- struct tlsext_ticket_key *tlsext_ticket_key_prev;
-
- // Callback to support customisation of ticket key setting
- int (*tlsext_ticket_key_cb)(SSL *ssl, uint8_t *name, uint8_t *iv,
- EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc);
-
- // Server-only: psk_identity_hint is the default identity hint to send in
- // PSK-based key exchanges.
- char *psk_identity_hint;
-
- unsigned int (*psk_client_callback)(SSL *ssl, const char *hint,
- char *identity,
- unsigned int max_identity_len,
- uint8_t *psk, unsigned int max_psk_len);
- unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
- uint8_t *psk, unsigned int max_psk_len);
-
-
- // retain_only_sha256_of_client_certs is true if we should compute the SHA256
- // hash of the peer's certificate and then discard it to save memory and
- // session space. Only effective on the server side.
- char retain_only_sha256_of_client_certs;
-
- // Next protocol negotiation information
- // (for experimental NPN extension).
-
- // For a server, this contains a callback function by which the set of
- // advertised protocols can be provided.
- int (*next_protos_advertised_cb)(SSL *ssl, const uint8_t **out,
- unsigned *out_len, void *arg);
- void *next_protos_advertised_cb_arg;
- // For a client, this contains a callback function that selects the
- // next protocol from the list provided by the server.
- int (*next_proto_select_cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
- const uint8_t *in, unsigned in_len, void *arg);
- void *next_proto_select_cb_arg;
-
- // ALPN information
- // (we are in the process of transitioning from NPN to ALPN.)
-
- // For a server, this contains a callback function that allows the
- // server to select the protocol for the connection.
- // out: on successful return, this must point to the raw protocol
- // name (without the length prefix).
- // outlen: on successful return, this contains the length of |*out|.
- // in: points to the client's list of supported protocols in
- // wire-format.
- // inlen: the length of |in|.
- int (*alpn_select_cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len,
- const uint8_t *in, unsigned in_len, void *arg);
- void *alpn_select_cb_arg;
-
- // For a client, this contains the list of supported protocols in wire
- // format.
- uint8_t *alpn_client_proto_list;
- unsigned alpn_client_proto_list_len;
-
- // SRTP profiles we are willing to do from RFC 5764
- STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
-
- // Supported group values inherited by SSL structure
- size_t supported_group_list_len;
- uint16_t *supported_group_list;
-
- // The client's Channel ID private key.
- EVP_PKEY *tlsext_channel_id_private;
-
- // keylog_callback, if not NULL, is the key logging callback. See
- // |SSL_CTX_set_keylog_callback|.
- void (*keylog_callback)(const SSL *ssl, const char *line);
-
- // current_time_cb, if not NULL, is the function to use to get the current
- // time. It sets |*out_clock| to the current time. The |ssl| argument is
- // always NULL. See |SSL_CTX_set_current_time_cb|.
- void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock);
-
- // pool is used for all |CRYPTO_BUFFER|s in case we wish to share certificate
- // memory.
- CRYPTO_BUFFER_POOL *pool;
-
- // ticket_aead_method contains function pointers for opening and sealing
- // session tickets.
- const SSL_TICKET_AEAD_METHOD *ticket_aead_method;
-
- // verify_sigalgs, if not empty, is the set of signature algorithms
- // accepted from the peer in decreasing order of preference.
- uint16_t *verify_sigalgs;
- size_t num_verify_sigalgs;
-
- // quiet_shutdown is true if the connection should not send a close_notify on
- // shutdown.
- unsigned quiet_shutdown:1;
-
- // ocsp_stapling_enabled is only used by client connections and indicates
- // whether OCSP stapling will be requested.
- unsigned ocsp_stapling_enabled:1;
-
- // If true, a client will request certificate timestamps.
- unsigned signed_cert_timestamps_enabled:1;
-
- // tlsext_channel_id_enabled is one if Channel ID is enabled and zero
- // otherwise. For a server, means that we'll accept Channel IDs from clients.
- // For a client, means that we'll advertise support.
- unsigned tlsext_channel_id_enabled:1;
-
- // grease_enabled is one if draft-davidben-tls-grease-01 is enabled and zero
- // otherwise.
- unsigned grease_enabled:1;
-
- // allow_unknown_alpn_protos is one if the client allows unsolicited ALPN
- // protocols from the peer.
- unsigned allow_unknown_alpn_protos:1;
-
- // ed25519_enabled is one if Ed25519 is advertised in the handshake.
- unsigned ed25519_enabled:1;
-};
-
// Nodejs compatibility section (hidden).
//
@@ -4644,14 +4330,12 @@
BORINGSSL_MAKE_DELETER(SSL, SSL_free)
BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free)
BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free)
-BORINGSSL_MAKE_DELETER(tlsext_ticket_key, OPENSSL_free);
enum class OpenRecordResult {
kOK,
kDiscard,
kIncompleteRecord,
kAlertCloseNotify,
- kAlertFatal,
kError,
};
@@ -4665,9 +4349,8 @@
// - kIncompleteRecord if |in| did not contain a complete record.
// - kAlertCloseNotify if a record was successfully processed but is a
// close_notify alert.
-// - kAlertFatal if a record was successfully processed but is a fatal alert.
// - kError if an error occurred or the record is invalid. |*out_alert| will be
-// set to an alert to emit.
+// set to an alert to emit, or zero if no alert should be emitted.
OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span<uint8_t> *out,
size_t *out_record_len,
uint8_t *out_alert,
diff --git a/src/infra/config/cq.cfg b/src/infra/config/cq.cfg
index e63026c..c657250 100644
--- a/src/infra/config/cq.cfg
+++ b/src/infra/config/cq.cfg
@@ -53,10 +53,7 @@
builders { name: "win64" }
builders { name: "win64_rel" }
builders { name: "win64_small" }
- builders { name: "win32_vs2017_compile" }
- builders { name: "win64_vs2017_compile" }
- builders { name: "win32_clang_vs2017_compile" }
- builders { name: "win64_clang_vs2017_compile" }
+
builders { name: "linux_fips" }
builders { name: "linux_fips_rel" }
diff --git a/src/ssl/custom_extensions.cc b/src/ssl/custom_extensions.cc
index c22f4fe..85b8a33 100644
--- a/src/ssl/custom_extensions.cc
+++ b/src/ssl/custom_extensions.cc
@@ -114,7 +114,7 @@
break;
default:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
ERR_add_error_dataf("extension %u", (unsigned) ext->value);
return 0;
diff --git a/src/ssl/d1_both.cc b/src/ssl/d1_both.cc
index c2f6479..3a31a02 100644
--- a/src/ssl/d1_both.cc
+++ b/src/ssl/d1_both.cc
@@ -287,7 +287,7 @@
if (frag->type != msg_hdr->type ||
frag->msg_len != msg_hdr->msg_len) {
OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return NULL;
}
return frag;
@@ -315,7 +315,7 @@
case SSL3_RT_APPLICATION_DATA:
// Unencrypted application data records are always illegal.
if (ssl->s3->aead_read_ctx->is_null_cipher()) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
return -1;
}
@@ -330,21 +330,21 @@
// We do not support renegotiation, so encrypted ChangeCipherSpec records
// are illegal.
if (!ssl->s3->aead_read_ctx->is_null_cipher()) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
return -1;
}
if (rr->length != 1 || rr->data[0] != SSL3_MT_CCS) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return -1;
}
// Flag the ChangeCipherSpec for later.
ssl->d1->has_change_cipher_spec = true;
ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC,
- rr->data, rr->length);
+ MakeSpan(rr->data, rr->length));
rr->length = 0;
ssl_read_buffer_discard(ssl);
@@ -355,7 +355,7 @@
break;
default:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
return -1;
}
@@ -369,7 +369,7 @@
CBS body;
if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return -1;
}
@@ -380,14 +380,14 @@
frag_off + frag_len > msg_len ||
msg_len > ssl_max_handshake_message_len(ssl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return -1;
}
// The encrypted epoch in DTLS has only one handshake message.
if (ssl->d1->r_epoch == 1 && msg_hdr.seq != ssl->d1->handshake_read_seq) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
@@ -433,8 +433,7 @@
CBS_init(&out->raw, frag->data, DTLS1_HM_HEADER_LENGTH + frag->msg_len);
out->is_v2_hello = false;
if (!ssl->s3->has_message) {
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, frag->data,
- frag->msg_len + DTLS1_HM_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw);
ssl->s3->has_message = true;
}
return true;
@@ -462,7 +461,11 @@
}
}
-int dtls_has_incoming_messages(const SSL *ssl) {
+bool dtls_has_unprocessed_handshake_data(const SSL *ssl) {
+ if (ssl->d1->has_change_cipher_spec) {
+ return true;
+ }
+
size_t current = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT;
for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) {
// Skip the current message.
@@ -471,10 +474,10 @@
continue;
}
if (ssl->d1->incoming_messages[i] != NULL) {
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
int dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr,
@@ -575,7 +578,7 @@
// TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript
// on hs.
if (ssl->s3->hs != NULL &&
- !ssl->s3->hs->transcript.Update(data.data(), data.size())) {
+ !ssl->s3->hs->transcript.Update(data)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -673,7 +676,7 @@
}
ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC,
- kChangeCipherSpec, sizeof(kChangeCipherSpec));
+ kChangeCipherSpec);
return seal_success;
}
@@ -716,7 +719,8 @@
return seal_error;
}
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, frag, frag_len);
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE,
+ MakeSpan(frag, frag_len));
if (!dtls_seal_record(ssl, out, out_len, max_out, SSL3_RT_HANDSHAKE,
out + prefix, frag_len, use_epoch)) {
diff --git a/src/ssl/d1_pkt.cc b/src/ssl/d1_pkt.cc
index a3095e1..5b1cce5 100644
--- a/src/ssl/d1_pkt.cc
+++ b/src/ssl/d1_pkt.cc
@@ -129,80 +129,55 @@
namespace bssl {
int dtls1_get_record(SSL *ssl) {
-again:
- switch (ssl->s3->recv_shutdown) {
- case ssl_shutdown_none:
- break;
- case ssl_shutdown_fatal_alert:
- OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
- return -1;
- case ssl_shutdown_close_notify:
- return 0;
- }
-
- // Read a new packet if there is no unconsumed one.
- if (ssl_read_buffer_len(ssl) == 0) {
- int read_ret = ssl_read_buffer_extend_to(ssl, 0 /* unused */);
- if (read_ret < 0 && dtls1_is_timer_expired(ssl)) {
- // Historically, timeouts were handled implicitly if the caller did not
- // handle them.
- //
- // TODO(davidben): This was to support blocking sockets but affected
- // non-blocking sockets. Can it be removed?
- int timeout_ret = DTLSv1_handle_timeout(ssl);
- if (timeout_ret <= 0) {
- return timeout_ret;
+ for (;;) {
+ Span<uint8_t> body;
+ uint8_t type, alert;
+ size_t consumed;
+ enum ssl_open_record_t open_ret = dtls_open_record(
+ ssl, &type, &body, &consumed, &alert, ssl_read_buffer(ssl));
+ if (open_ret != ssl_open_record_partial) {
+ ssl_read_buffer_consume(ssl, consumed);
+ }
+ switch (open_ret) {
+ case ssl_open_record_partial: {
+ assert(ssl_read_buffer(ssl).empty());
+ int read_ret = ssl_read_buffer_extend_to(ssl, 0 /* unused */);
+ if (read_ret <= 0) {
+ return read_ret;
+ }
+ continue;
}
- goto again;
- }
- if (read_ret <= 0) {
- return read_ret;
- }
- }
- assert(ssl_read_buffer_len(ssl) > 0);
- CBS body;
- uint8_t type, alert;
- size_t consumed;
- enum ssl_open_record_t open_ret =
- dtls_open_record(ssl, &type, &body, &consumed, &alert,
- ssl_read_buffer(ssl), ssl_read_buffer_len(ssl));
- ssl_read_buffer_consume(ssl, consumed);
- switch (open_ret) {
- case ssl_open_record_partial:
- // Impossible in DTLS.
- break;
+ case ssl_open_record_success: {
+ if (body.size() > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
+ }
- case ssl_open_record_success: {
- if (CBS_len(&body) > 0xffff) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ SSL3_RECORD *rr = &ssl->s3->rrec;
+ rr->type = type;
+ rr->length = static_cast<uint16_t>(body.size());
+ rr->data = body.data();
+ return 1;
+ }
+
+ case ssl_open_record_discard:
+ continue;
+
+ case ssl_open_record_close_notify:
+ return 0;
+
+ case ssl_open_record_error:
+ if (alert != 0) {
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
+ }
return -1;
- }
-
- SSL3_RECORD *rr = &ssl->s3->rrec;
- rr->type = type;
- rr->length = (uint16_t)CBS_len(&body);
- rr->data = (uint8_t *)CBS_data(&body);
- return 1;
}
- case ssl_open_record_discard:
- goto again;
-
- case ssl_open_record_close_notify:
- return 0;
-
- case ssl_open_record_fatal_alert:
- return -1;
-
- case ssl_open_record_error:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
- return -1;
+ assert(0);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
-
- assert(0);
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
}
int dtls1_read_app_data(SSL *ssl, bool *out_got_handshake, uint8_t *buf,
@@ -228,7 +203,7 @@
struct hm_header_st msg_hdr;
CBS_init(&cbs, rr->data, rr->length);
if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
return -1;
}
@@ -255,7 +230,7 @@
}
if (rr->type != SSL3_RT_APPLICATION_DATA) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
return -1;
}
@@ -293,8 +268,8 @@
// alerts also aren't delivered reliably, so we may even time out because the
// peer never received our close_notify. Report to the caller that the channel
// has fully shut down.
- if (ssl->s3->recv_shutdown == ssl_shutdown_none) {
- ssl->s3->recv_shutdown = ssl_shutdown_close_notify;
+ if (ssl->s3->read_shutdown == ssl_shutdown_none) {
+ ssl->s3->read_shutdown = ssl_shutdown_close_notify;
}
}
@@ -369,8 +344,7 @@
BIO_flush(ssl->wbio);
}
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert,
- 2);
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert);
int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert);
diff --git a/src/ssl/dtls_method.cc b/src/ssl/dtls_method.cc
index 050246d..daaec2d 100644
--- a/src/ssl/dtls_method.cc
+++ b/src/ssl/dtls_method.cc
@@ -83,10 +83,10 @@
}
static int dtls1_set_read_state(SSL *ssl, UniquePtr<SSLAEADContext> aead_ctx) {
- // Cipher changes are illegal when there are buffered incoming messages.
- if (dtls_has_incoming_messages(ssl) || ssl->d1->has_change_cipher_spec) {
+ // Cipher changes are forbidden if the current epoch has leftover data.
+ if (dtls_has_unprocessed_handshake_data(ssl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return 0;
}
diff --git a/src/ssl/dtls_record.cc b/src/ssl/dtls_record.cc
index 5009f04..2bf1d42 100644
--- a/src/ssl/dtls_record.cc
+++ b/src/ssl/dtls_record.cc
@@ -174,14 +174,27 @@
}
}
-enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, CBS *out,
+enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type,
+ Span<uint8_t> *out,
size_t *out_consumed,
- uint8_t *out_alert, uint8_t *in,
- size_t in_len) {
+ uint8_t *out_alert, Span<uint8_t> in) {
*out_consumed = 0;
+ switch (ssl->s3->read_shutdown) {
+ case ssl_shutdown_none:
+ break;
+ case ssl_shutdown_fatal_alert:
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ *out_alert = 0;
+ return ssl_open_record_error;
+ case ssl_shutdown_close_notify:
+ return ssl_open_record_close_notify;
+ }
- CBS cbs;
- CBS_init(&cbs, in, in_len);
+ if (in.empty()) {
+ return ssl_open_record_partial;
+ }
+
+ CBS cbs = CBS(in);
// Decode the record.
uint8_t type;
@@ -194,7 +207,7 @@
!CBS_get_u16_length_prefixed(&cbs, &body) ||
CBS_len(&body) > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
// The record header was incomplete or malformed. Drop the entire packet.
- *out_consumed = in_len;
+ *out_consumed = in.size();
return ssl_open_record_discard;
}
@@ -209,12 +222,12 @@
if (!version_ok) {
// The record header was incomplete or malformed. Drop the entire packet.
- *out_consumed = in_len;
+ *out_consumed = in.size();
return ssl_open_record_discard;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, in,
- DTLS1_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER,
+ in.subspan(0, DTLS1_RT_HEADER_LENGTH));
uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1];
if (epoch != ssl->d1->r_epoch ||
@@ -223,14 +236,14 @@
// |epoch| is the next epoch, the record could be buffered for later. For
// simplicity, drop it and expect retransmit to handle it later; DTLS must
// handle packet loss anyway.
- *out_consumed = in_len - CBS_len(&cbs);
+ *out_consumed = in.size() - CBS_len(&cbs);
return ssl_open_record_discard;
}
- // Decrypt the body in-place.
- if (!ssl->s3->aead_read_ctx->Open(out, type, version, sequence,
- (uint8_t *)CBS_data(&body),
- CBS_len(&body))) {
+ // discard the body in-place.
+ if (!ssl->s3->aead_read_ctx->Open(
+ out, type, version, sequence,
+ MakeSpan(const_cast<uint8_t *>(CBS_data(&body)), CBS_len(&body)))) {
// Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347.
// Clear the error queue of any errors decryption may have added. Drop the
// entire packet as it must not have come from the peer.
@@ -238,13 +251,13 @@
// TODO(davidben): This doesn't distinguish malloc failures from encryption
// failures.
ERR_clear_error();
- *out_consumed = in_len - CBS_len(&cbs);
+ *out_consumed = in.size() - CBS_len(&cbs);
return ssl_open_record_discard;
}
- *out_consumed = in_len - CBS_len(&cbs);
+ *out_consumed = in.size() - CBS_len(&cbs);
// Check the plaintext length.
- if (CBS_len(out) > SSL3_RT_MAX_PLAIN_LENGTH) {
+ if (out->size() > SSL3_RT_MAX_PLAIN_LENGTH) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
*out_alert = SSL_AD_RECORD_OVERFLOW;
return ssl_open_record_error;
@@ -256,7 +269,7 @@
// useful if we also limit discarded packets.
if (type == SSL3_RT_ALERT) {
- return ssl_process_alert(ssl, out_alert, CBS_data(out), CBS_len(out));
+ return ssl_process_alert(ssl, out_alert, *out);
}
ssl->s3->warning_alert_count = 0;
@@ -338,8 +351,8 @@
*out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out,
- DTLS1_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER,
+ MakeSpan(out, DTLS1_RT_HEADER_LENGTH));
return 1;
}
diff --git a/src/ssl/handshake.cc b/src/ssl/handshake.cc
index a03b140..80b64f3 100644
--- a/src/ssl/handshake.cc
+++ b/src/ssl/handshake.cc
@@ -162,7 +162,7 @@
int ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) {
if (msg.type != type) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
ERR_add_error_dataf("got type %d, wanted type %d", msg.type, type);
return 0;
@@ -194,7 +194,7 @@
return kMaxMessageLen;
}
- if (ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) < TLS1_3_VERSION) {
// In TLS 1.2 and below, the largest acceptable post-handshake message is
// a HelloRequest.
return 0;
@@ -206,8 +206,7 @@
return 1;
}
- // Clients must accept NewSessionTicket and CertificateRequest, so allow the
- // default size.
+ // Clients must accept NewSessionTicket, so allow the default size.
return kMaxMessageLen;
}
@@ -217,7 +216,7 @@
return true;
}
- return hs->transcript.Update(CBS_data(&msg.raw), CBS_len(&msg.raw));
+ return hs->transcript.Update(msg.raw);
}
int ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert,
@@ -293,7 +292,7 @@
if (sk_CRYPTO_BUFFER_num(prev_session->certs) !=
sk_CRYPTO_BUFFER_num(hs->new_session->certs)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_verify_invalid;
}
@@ -307,7 +306,7 @@
CRYPTO_BUFFER_data(new_cert),
CRYPTO_BUFFER_len(old_cert)) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_verify_invalid;
}
}
@@ -347,7 +346,7 @@
if (ret == ssl_verify_invalid) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
}
return ret;
@@ -363,7 +362,7 @@
: ssl->s3->client_random[index];
// The first four bytes of server_random are a timestamp prior to TLS 1.3, but
// servers have no fields to GREASE until TLS 1.3.
- assert(!ssl->server || ssl3_protocol_version(ssl) >= TLS1_3_VERSION);
+ assert(!ssl->server || ssl_protocol_version(ssl) >= TLS1_3_VERSION);
// This generates a random value of the form 0xωaωa, for all 0 ≤ ω < 16.
ret = (ret & 0xf0) | 0x0a;
ret |= ret << 8;
@@ -395,7 +394,7 @@
finished_ok = 1;
#endif
if (!finished_ok) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
return ssl_hs_error;
}
@@ -421,13 +420,73 @@
return ssl_hs_ok;
}
+bool ssl_send_finished(SSL_HANDSHAKE *hs) {
+ SSL *const ssl = hs->ssl;
+ const SSL_SESSION *session = SSL_get_session(ssl);
+
+ uint8_t finished[EVP_MAX_MD_SIZE];
+ size_t finished_len;
+ if (!hs->transcript.GetFinishedMAC(finished, &finished_len, session,
+ ssl->server)) {
+ return 0;
+ }
+
+ // Log the master secret, if logging is enabled.
+ if (!ssl_log_secret(ssl, "CLIENT_RANDOM",
+ session->master_key,
+ session->master_key_length)) {
+ return 0;
+ }
+
+ // Copy the Finished so we can use it for renegotiation checks.
+ if (ssl->version != SSL3_VERSION) {
+ if (finished_len > sizeof(ssl->s3->previous_client_finished) ||
+ finished_len > sizeof(ssl->s3->previous_server_finished)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ if (ssl->server) {
+ OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len);
+ ssl->s3->previous_server_finished_len = finished_len;
+ } else {
+ OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len);
+ ssl->s3->previous_client_finished_len = finished_len;
+ }
+ }
+
+ ScopedCBB cbb;
+ CBB body;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) ||
+ !CBB_add_bytes(&body, finished, finished_len) ||
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ return 1;
+}
+
+bool ssl_output_cert_chain(SSL *ssl) {
+ ScopedCBB cbb;
+ CBB body;
+ if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) ||
+ !ssl_add_cert_chain(ssl, &body) ||
+ !ssl_add_message_cbb(ssl, cbb.get())) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return false;
+ }
+
+ return true;
+}
+
int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) {
SSL *const ssl = hs->ssl;
for (;;) {
// Resolve the operation the handshake was waiting on.
switch (hs->wait) {
case ssl_hs_error:
- OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
+ ERR_restore_state(hs->error.get());
return -1;
case ssl_hs_flush: {
@@ -531,8 +590,7 @@
// Run the state machine again.
hs->wait = ssl->do_handshake(hs);
if (hs->wait == ssl_hs_error) {
- // Don't loop around to avoid a stray |SSL_R_SSL_HANDSHAKE_FAILURE| the
- // first time around.
+ hs->error.reset(ERR_save_state());
return -1;
}
if (hs->wait == ssl_hs_ok) {
diff --git a/src/ssl/handshake_client.cc b/src/ssl/handshake_client.cc
index b2d5384..5466b56 100644
--- a/src/ssl/handshake_client.cc
+++ b/src/ssl/handshake_client.cc
@@ -358,7 +358,7 @@
SSL *const ssl = hs->ssl;
if (msg.type != SSL3_MT_SERVER_HELLO &&
msg.type != SSL3_MT_HELLO_RETRY_REQUEST) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
return 0;
}
@@ -366,7 +366,7 @@
CBS server_hello = msg.body;
if (!CBS_get_u16(&server_hello, out)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -382,7 +382,7 @@
!CBS_skip(&server_hello, sid_length + 2 /* cipher_suite */ +
1 /* compression_method */)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -395,7 +395,7 @@
if (!CBS_get_u16_length_prefixed(&server_hello, &extensions) ||
CBS_len(&server_hello) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -410,14 +410,14 @@
if (!ssl_parse_extensions(&extensions, &alert, ext_types,
OPENSSL_ARRAY_SIZE(ext_types),
1 /* ignore unknown */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
if (have_supported_versions &&
(!CBS_get_u16(&supported_versions, out) ||
CBS_len(&supported_versions) != 0)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -542,7 +542,7 @@
CBS_len(&cookie) > sizeof(ssl->d1->cookie) ||
CBS_len(&hello_verify_request) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -578,7 +578,7 @@
if (!ssl_supports_version(hs, server_version)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION);
return ssl_hs_error;
}
@@ -591,11 +591,11 @@
ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version);
} else if (server_version != ssl->version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION);
return ssl_hs_error;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
hs->state = state_tls13;
return ssl_hs_ok;
}
@@ -609,7 +609,7 @@
// fallback described in draft-ietf-tls-tls13-18 appendix C.3.
if (hs->early_data_offered) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_ON_EARLY_DATA);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION);
return ssl_hs_error;
}
@@ -627,7 +627,7 @@
!CBS_get_u16(&server_hello, &cipher_suite) ||
!CBS_get_u8(&server_hello, &compression_method)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -648,7 +648,7 @@
// fill out.
ssl_set_session(ssl, NULL);
if (!ssl_get_new_session(hs, 0 /* client */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
// Note: session_id could be empty.
@@ -661,7 +661,7 @@
if (cipher == NULL) {
// unknown cipher
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -669,30 +669,30 @@
uint32_t mask_a, mask_k;
ssl_get_client_disabled(ssl, &mask_a, &mask_k);
if ((cipher->algorithm_mkey & mask_k) || (cipher->algorithm_auth & mask_a) ||
- SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
- SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl) ||
+ SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) ||
+ SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl) ||
!sk_SSL_CIPHER_find(SSL_get_ciphers(ssl), NULL, cipher)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
if (ssl->session != NULL) {
if (ssl->session->ssl_version != ssl->version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
if (ssl->session->cipher != cipher) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
if (!ssl_session_is_context_valid(ssl, ssl->session)) {
// This is actually a client application bug.
OPENSSL_PUT_ERROR(SSL,
SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
} else {
@@ -702,9 +702,9 @@
// Now that the cipher is known, initialize the handshake hash and hash the
// ServerHello.
- if (!hs->transcript.InitHash(ssl3_protocol_version(ssl), hs->new_cipher) ||
+ if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) ||
!ssl_hash_message(hs, msg)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -719,7 +719,7 @@
// Only the NULL compression algorithm is supported.
if (compression_method != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -733,7 +733,7 @@
if (CBS_len(&server_hello) != 0) {
// wrong packet length
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -744,7 +744,7 @@
} else {
OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION);
}
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -792,7 +792,7 @@
UniquePtr<STACK_OF(CRYPTO_BUFFER)> chain;
if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey, NULL, &body,
ssl->ctx->pool)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
@@ -802,14 +802,14 @@
CBS_len(&body) != 0 ||
!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
if (!ssl_check_leaf_certificate(
hs, hs->peer_pubkey.get(),
sk_CRYPTO_BUFFER_value(hs->new_session->certs, 0))) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -851,7 +851,7 @@
CBS_len(&ocsp_response) == 0 ||
CBS_len(&certificate_status) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -859,7 +859,7 @@
hs->new_session->ocsp_response =
CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool);
if (hs->new_session->ocsp_response == nullptr) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -900,7 +900,7 @@
// Some ciphers (pure PSK) have an optional ServerKeyExchange message.
if (ssl_cipher_requires_server_key_exchange(hs->new_cipher)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return ssl_hs_error;
}
@@ -922,21 +922,21 @@
if (!CBS_get_u16_length_prefixed(&server_key_exchange,
&psk_identity_hint)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
- // Store PSK identity hint for later use, hint is used in
- // ssl3_send_client_key_exchange. Assume that the maximum length of a PSK
- // identity hint can be as long as the maximum length of a PSK identity.
- // Also do not allow NULL characters; identities are saved as C strings.
+ // Store the PSK identity hint for the ClientKeyExchange. Assume that the
+ // maximum length of a PSK identity hint can be as long as the maximum
+ // length of a PSK identity. Also do not allow NULL characters; identities
+ // are saved as C strings.
//
// TODO(davidben): Should invalid hints be ignored? It's a hint rather than
// a specific identity.
if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN ||
CBS_contains_zero_byte(&psk_identity_hint)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -949,7 +949,7 @@
if (CBS_len(&psk_identity_hint) != 0 &&
!CBS_strdup(&psk_identity_hint, &raw)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
hs->peer_psk_identity_hint.reset(raw);
@@ -965,7 +965,7 @@
!CBS_get_u16(&server_key_exchange, &group_id) ||
!CBS_get_u8_length_prefixed(&server_key_exchange, &point)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
hs->new_session->group_id = group_id;
@@ -973,7 +973,7 @@
// Ensure the group is consistent with preferences.
if (!tls1_check_group_id(ssl, group_id)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -985,7 +985,7 @@
}
} else if (!(alg_k & SSL_kPSK)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return ssl_hs_error;
}
@@ -999,22 +999,22 @@
// ServerKeyExchange should be signed by the server's public key.
if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
uint16_t signature_algorithm = 0;
- if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) {
if (!CBS_get_u16(&server_key_exchange, &signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
hs->new_session->peer_signature_algorithm = signature_algorithm;
} else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm,
hs->peer_pubkey.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE);
return ssl_hs_error;
}
@@ -1023,13 +1023,12 @@
if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) ||
CBS_len(&server_key_exchange) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
ScopedCBB transcript;
- uint8_t *transcript_data;
- size_t transcript_len;
+ Array<uint8_t> transcript_data;
if (!CBB_init(transcript.get(),
2 * SSL3_RANDOM_SIZE + CBS_len(¶meter)) ||
!CBB_add_bytes(transcript.get(), ssl->s3->client_random,
@@ -1038,25 +1037,22 @@
SSL3_RANDOM_SIZE) ||
!CBB_add_bytes(transcript.get(), CBS_data(¶meter),
CBS_len(¶meter)) ||
- !CBB_finish(transcript.get(), &transcript_data, &transcript_len)) {
+ !CBBFinishArray(transcript.get(), &transcript_data)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
- int sig_ok = ssl_public_key_verify(
- ssl, CBS_data(&signature), CBS_len(&signature), signature_algorithm,
- hs->peer_pubkey.get(), transcript_data, transcript_len);
- OPENSSL_free(transcript_data);
-
+ bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm,
+ hs->peer_pubkey.get(), transcript_data);
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
- sig_ok = 1;
+ sig_ok = true;
ERR_clear_error();
#endif
if (!sig_ok) {
// bad signature
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
return ssl_hs_error;
}
} else {
@@ -1065,7 +1061,7 @@
if (CBS_len(&server_key_exchange) > 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_EXTRA_DATA_IN_MESSAGE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
}
@@ -1104,21 +1100,21 @@
// Get the certificate types.
CBS body = msg.body, certificate_types;
if (!CBS_get_u8_length_prefixed(&body, &certificate_types)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
if (!hs->certificate_types.CopyFrom(certificate_types)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
- if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) {
CBS supported_signature_algorithms;
if (!CBS_get_u16_length_prefixed(&body, &supported_signature_algorithms) ||
!tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
@@ -1128,12 +1124,12 @@
UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names =
ssl_parse_client_CA_list(ssl, &alert, &body);
if (!ca_names) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
if (CBS_len(&body) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
@@ -1161,7 +1157,7 @@
// ServerHelloDone is empty.
if (CBS_len(&msg.body) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
@@ -1184,7 +1180,7 @@
if (ssl->cert->cert_cb != NULL) {
int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
if (rv == 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
return ssl_hs_error;
}
@@ -1210,7 +1206,7 @@
}
if (!ssl_on_certificate_selected(hs) ||
- !ssl3_output_cert_chain(ssl)) {
+ !ssl_output_cert_chain(ssl)) {
return ssl_hs_error;
}
@@ -1251,7 +1247,7 @@
identity, sizeof(identity), psk, sizeof(psk));
if (psk_len == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
assert(psk_len <= PSK_MAX_PSK_LEN);
@@ -1319,7 +1315,7 @@
// Compute the premaster.
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!hs->key_share->Accept(&child, &pms, &alert, hs->peer_key)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
if (!CBB_flush(&body)) {
@@ -1337,7 +1333,7 @@
}
OPENSSL_memset(pms.data(), 0, pms.size());
} else {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -1347,19 +1343,15 @@
if (alg_a & SSL_aPSK) {
ScopedCBB pms_cbb;
CBB child;
- uint8_t *new_pms;
- size_t new_pms_len;
-
if (!CBB_init(pms_cbb.get(), 2 + psk_len + 2 + pms.size()) ||
!CBB_add_u16_length_prefixed(pms_cbb.get(), &child) ||
!CBB_add_bytes(&child, pms.data(), pms.size()) ||
!CBB_add_u16_length_prefixed(pms_cbb.get(), &child) ||
!CBB_add_bytes(&child, psk, psk_len) ||
- !CBB_finish(pms_cbb.get(), &new_pms, &new_pms_len)) {
+ !CBBFinishArray(pms_cbb.get(), &pms)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return ssl_hs_error;
}
- pms.Reset(new_pms, new_pms_len);
}
// The message must be added to the finished hash before calculating the
@@ -1399,7 +1391,7 @@
if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
return ssl_hs_error;
}
- if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) {
// Write out the digest type in TLS 1.2.
if (!CBB_add_u16(&body, signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1418,7 +1410,7 @@
size_t sig_len = max_sig_len;
// The SSL3 construction for CertificateVerify does not decompose into a
// single final digest and signature, and must be special-cased.
- if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
+ if (ssl_protocol_version(ssl) == SSL3_VERSION) {
if (ssl->cert->key_method != NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY);
return ssl_hs_error;
@@ -1438,9 +1430,9 @@
return ssl_hs_error;
}
} else {
- switch (ssl_private_key_sign(
- hs, ptr, &sig_len, max_sig_len, signature_algorithm,
- hs->transcript.buffer_data(), hs->transcript.buffer_len())) {
+ switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len,
+ signature_algorithm,
+ hs->transcript.buffer())) {
case ssl_private_key_success:
break;
case ssl_private_key_failure:
@@ -1511,7 +1503,7 @@
}
}
- if (!ssl3_send_finished(hs)) {
+ if (!ssl_send_finished(hs)) {
return ssl_hs_error;
}
@@ -1519,6 +1511,18 @@
return ssl_hs_flush;
}
+static bool can_false_start(const SSL_HANDSHAKE *hs) {
+ SSL *const ssl = hs->ssl;
+
+ // False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN.
+ return !SSL_is_dtls(ssl) &&
+ SSL_version(ssl) == TLS1_2_VERSION &&
+ (ssl->s3->alpn_selected != NULL ||
+ ssl->s3->next_proto_negotiated != NULL) &&
+ hs->new_cipher->algorithm_mkey == SSL_kECDHE &&
+ hs->new_cipher->algorithm_mac == SSL_AEAD;
+}
+
static enum ssl_hs_wait_t do_finish_flight(SSL_HANDSHAKE *hs) {
SSL *const ssl = hs->ssl;
if (ssl->session != NULL) {
@@ -1536,7 +1540,7 @@
hs->state = state_read_session_ticket;
if ((SSL_get_mode(ssl) & SSL_MODE_ENABLE_FALSE_START) &&
- ssl3_can_false_start(ssl) &&
+ can_false_start(hs) &&
// No False Start on renegotiation (would complicate the state machine).
!ssl->s3->initial_handshake_complete) {
hs->in_false_start = true;
@@ -1570,7 +1574,7 @@
if (!CBS_get_u32(&new_session_ticket, &tlsext_tick_lifetime_hint) ||
!CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
CBS_len(&new_session_ticket) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
diff --git a/src/ssl/handshake_server.cc b/src/ssl/handshake_server.cc
index 5507250..7b282d8 100644
--- a/src/ssl/handshake_server.cc
+++ b/src/ssl/handshake_server.cc
@@ -281,7 +281,7 @@
// Handle FALLBACK_SCSV.
if (ssl_client_cipher_list_contains_cipher(client_hello,
SSL3_CK_FALLBACK_SCSV & 0xffff) &&
- ssl3_protocol_version(ssl) < hs->max_version) {
+ ssl_protocol_version(ssl) < hs->max_version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
*out_alert = SSL3_AD_INAPPROPRIATE_FALLBACK;
return 0;
@@ -392,8 +392,8 @@
size_t cipher_index;
if (// Check if the cipher is supported for the current version.
- SSL_CIPHER_get_min_version(c) <= ssl3_protocol_version(ssl) &&
- ssl3_protocol_version(ssl) <= SSL_CIPHER_get_max_version(c) &&
+ SSL_CIPHER_get_min_version(c) <= ssl_protocol_version(ssl) &&
+ ssl_protocol_version(ssl) <= SSL_CIPHER_get_max_version(c) &&
// Check the cipher is supported for the server configuration.
(c->algorithm_mkey & mask_k) &&
(c->algorithm_auth & mask_a) &&
@@ -444,7 +444,7 @@
SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -457,7 +457,7 @@
case ssl_select_cert_error:
// Connection rejected.
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
default:
@@ -472,7 +472,7 @@
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!negotiate_version(hs, &alert, &client_hello)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
@@ -488,10 +488,10 @@
// advertise no other compression.
if (OPENSSL_memchr(client_hello.compression_methods, 0,
client_hello.compression_methods_len) == NULL ||
- (ssl3_protocol_version(ssl) >= TLS1_3_VERSION &&
+ (ssl_protocol_version(ssl) >= TLS1_3_VERSION &&
client_hello.compression_methods_len != 1)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -518,7 +518,7 @@
int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
if (rv == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
if (rv < 0) {
@@ -530,7 +530,7 @@
return ssl_hs_error;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
// Jump to the TLS 1.3 state machine.
hs->state = state_tls13;
return ssl_hs_ok;
@@ -547,7 +547,7 @@
ssl3_choose_cipher(hs, &client_hello, ssl_get_cipher_preferences(ssl));
if (hs->new_cipher == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -592,7 +592,7 @@
// A ClientHello without EMS that attempts to resume a session with EMS
// is fatal to the connection.
OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -626,7 +626,7 @@
ssl->ctx->dos_protection_cb(&client_hello) == 0) {
// Connection rejected for DOS reasons.
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -656,15 +656,15 @@
// deferred. Complete it now.
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
// Now that all parameters are known, initialize the handshake hash and hash
// the ClientHello.
- if (!hs->transcript.InitHash(ssl3_protocol_version(ssl), hs->new_cipher) ||
+ if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) ||
!ssl_hash_message(hs, msg)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -749,7 +749,7 @@
return ssl_hs_error;
}
- if (!ssl3_output_cert_chain(ssl)) {
+ if (!ssl_output_cert_chain(ssl)) {
return ssl_hs_error;
}
@@ -800,7 +800,7 @@
uint16_t group_id;
if (!tls1_get_shared_group(hs, &group_id)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
hs->new_session->group_id = group_id;
@@ -849,7 +849,7 @@
// Add a signature.
if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
if (!ssl_has_private_key(ssl)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -858,10 +858,10 @@
if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) {
return ssl_hs_error;
}
- if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) {
if (!CBB_add_u16(&body, signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
}
@@ -876,8 +876,7 @@
size_t sig_len;
switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len,
- signature_algorithm, hs->server_params.data(),
- hs->server_params.size())) {
+ signature_algorithm, hs->server_params)) {
case ssl_private_key_success:
if (!CBB_did_write(&child, sig_len)) {
return ssl_hs_error;
@@ -912,9 +911,9 @@
SSL3_MT_CERTIFICATE_REQUEST) ||
!CBB_add_u8_length_prefixed(&body, &cert_types) ||
!CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) ||
- (ssl3_protocol_version(ssl) >= TLS1_VERSION &&
+ (ssl_protocol_version(ssl) >= TLS1_VERSION &&
!CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN)) ||
- (ssl3_protocol_version(ssl) >= TLS1_2_VERSION &&
+ (ssl_protocol_version(ssl) >= TLS1_2_VERSION &&
(!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) ||
!tls12_add_verify_sigalgs(ssl, &sigalgs_cbb))) ||
!ssl_add_client_CA_list(ssl, &body) ||
@@ -955,7 +954,7 @@
// certificate.
if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -967,7 +966,7 @@
}
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return ssl_hs_error;
}
@@ -983,7 +982,7 @@
? hs->new_session->peer_sha256
: NULL,
&certificate_msg, ssl->ctx->pool)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free);
@@ -992,7 +991,7 @@
if (CBS_len(&certificate_msg) != 0 ||
!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -1004,14 +1003,14 @@
// Certificate message.
if (ssl->version == SSL3_VERSION) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
// Fail for TLS only if we required a certificate
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -1068,20 +1067,20 @@
if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) ||
((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN ||
CBS_contains_zero_byte(&psk_identity)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
if (!CBS_strdup(&psk_identity, &hs->new_session->psk_identity)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
}
@@ -1095,7 +1094,7 @@
&encrypted_premaster_secret) ||
CBS_len(&client_key_exchange) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
} else {
@@ -1113,8 +1112,7 @@
size_t decrypt_len;
switch (ssl_private_key_decrypt(hs, decrypt_buf.data(), &decrypt_len,
decrypt_buf.size(),
- CBS_data(&encrypted_premaster_secret),
- CBS_len(&encrypted_premaster_secret))) {
+ encrypted_premaster_secret)) {
case ssl_private_key_success:
break;
case ssl_private_key_failure:
@@ -1125,7 +1123,7 @@
if (decrypt_len != decrypt_buf.size()) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
return ssl_hs_error;
}
@@ -1140,7 +1138,7 @@
// publicly invalid.
if (decrypt_len < 11 + premaster_secret.size()) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
return ssl_hs_error;
}
@@ -1172,14 +1170,14 @@
if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) ||
CBS_len(&client_key_exchange) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
// Compute the premaster.
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!hs->key_share->Finish(&premaster_secret, &alert, peer_key)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
@@ -1187,7 +1185,7 @@
hs->key_share.reset();
} else if (!(alg_k & SSL_kPSK)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -1196,7 +1194,7 @@
if (alg_a & SSL_aPSK) {
if (ssl->psk_server_callback == NULL) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -1206,12 +1204,12 @@
ssl, hs->new_session->psk_identity, psk, sizeof(psk));
if (psk_len > PSK_MAX_PSK_LEN) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
} else if (psk_len == 0) {
// PSK related to the given identity not found.
OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNKNOWN_PSK_IDENTITY);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNKNOWN_PSK_IDENTITY);
return ssl_hs_error;
}
@@ -1226,8 +1224,6 @@
ScopedCBB new_premaster;
CBB child;
- uint8_t *new_data;
- size_t new_len;
if (!CBB_init(new_premaster.get(),
2 + psk_len + 2 + premaster_secret.size()) ||
!CBB_add_u16_length_prefixed(new_premaster.get(), &child) ||
@@ -1235,12 +1231,10 @@
premaster_secret.size()) ||
!CBB_add_u16_length_prefixed(new_premaster.get(), &child) ||
!CBB_add_bytes(&child, psk, psk_len) ||
- !CBB_finish(new_premaster.get(), &new_data, &new_len)) {
+ !CBBFinishArray(new_premaster.get(), &premaster_secret)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return ssl_hs_error;
}
-
- premaster_secret.Reset(new_data, new_len);
}
if (!ssl_hash_message(hs, msg)) {
@@ -1285,22 +1279,22 @@
// Determine the signature algorithm.
uint16_t signature_algorithm = 0;
- if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) {
if (!CBS_get_u16(&certificate_verify, &signature_algorithm)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
hs->new_session->peer_signature_algorithm = signature_algorithm;
} else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm,
hs->peer_pubkey.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE);
return ssl_hs_error;
}
@@ -1308,14 +1302,14 @@
if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) ||
CBS_len(&certificate_verify) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
- int sig_ok;
+ bool sig_ok;
// The SSL3 construction for CertificateVerify does not decompose into a
// single final digest and signature, and must be special-cased.
- if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
+ if (ssl_protocol_version(ssl) == SSL3_VERSION) {
uint8_t digest[EVP_MAX_MD_SIZE];
size_t digest_len;
if (!hs->transcript.GetSSL3CertVerifyHash(
@@ -1330,19 +1324,18 @@
EVP_PKEY_verify(pctx.get(), CBS_data(&signature),
CBS_len(&signature), digest, digest_len);
} else {
- sig_ok = ssl_public_key_verify(
- ssl, CBS_data(&signature), CBS_len(&signature), signature_algorithm,
- hs->peer_pubkey.get(), hs->transcript.buffer_data(),
- hs->transcript.buffer_len());
+ sig_ok =
+ ssl_public_key_verify(ssl, signature, signature_algorithm,
+ hs->peer_pubkey.get(), hs->transcript.buffer());
}
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
- sig_ok = 1;
+ sig_ok = true;
ERR_clear_error();
#endif
if (!sig_ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
return ssl_hs_error;
}
@@ -1395,7 +1388,7 @@
!CBS_get_u8_length_prefixed(&next_protocol, &padding) ||
CBS_len(&next_protocol) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -1493,7 +1486,7 @@
if (!ssl->method->add_change_cipher_spec(ssl) ||
!tls1_change_cipher_state(hs, evp_aead_seal) ||
- !ssl3_send_finished(hs)) {
+ !ssl_send_finished(hs)) {
return ssl_hs_error;
}
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 4247425..edbf4eb 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -153,11 +153,13 @@
#include <openssl/aead.h>
#include <openssl/err.h>
+#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/ssl.h>
#include <openssl/span.h>
#include <openssl/stack.h>
+#include "../crypto/err/internal.h"
#include "../crypto/internal.h"
@@ -171,11 +173,10 @@
#endif
-typedef struct cert_st CERT;
-
namespace bssl {
struct SSL_HANDSHAKE;
+struct SSL_PROTOCOL_METHOD;
// C++ utilities.
@@ -237,6 +238,14 @@
#define PURE_VIRTUAL { abort(); }
#endif
+// CONSTEXPR_ARRAY works around a VS 2015 bug where ranged for loops don't work
+// on constexpr arrays.
+#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1910
+#define CONSTEXPR_ARRAY const
+#else
+#define CONSTEXPR_ARRAY constexpr
+#endif
+
// Array<T> is an owning array of elements of |T|.
template <typename T>
class Array {
@@ -379,9 +388,9 @@
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
+// ssl_protocol_version returns |ssl|'s protocol version. It is an error to
// call this function before the version is determined.
-uint16_t ssl3_protocol_version(const SSL *ssl);
+uint16_t ssl_protocol_version(const SSL *ssl);
// ssl_is_resumption_experiment returns whether the version corresponds to a
// TLS 1.3 resumption experiment.
@@ -536,10 +545,10 @@
// to call this function after the handshake buffer is released.
bool InitHash(uint16_t version, const SSL_CIPHER *cipher);
- const uint8_t *buffer_data() const {
- return reinterpret_cast<const uint8_t *>(buffer_->data);
+ Span<const uint8_t> buffer() {
+ return MakeConstSpan(reinterpret_cast<const uint8_t *>(buffer_->data),
+ buffer_->length);
}
- size_t buffer_len() const { return buffer_->length; }
// FreeBuffer releases the handshake buffer. Subsequent calls to
// |Update| will not update the handshake buffer.
@@ -554,7 +563,7 @@
// Update adds |in| to the handshake buffer and handshake hash, whichever is
// enabled. It returns true on success and false on failure.
- bool Update(const uint8_t *in, size_t in_len);
+ bool Update(Span<const uint8_t> in);
// GetHash writes the handshake hash to |out| which must have room for at
// least |DigestLen| bytes. On success, it returns true and sets |*out_len| to
@@ -656,12 +665,11 @@
bool SuffixLen(size_t *out_suffix_len, size_t in_len,
size_t extra_in_len) const;
- // Open authenticates and decrypts |in_len| bytes from |in| in-place. On
- // success, it sets |*out| to the plaintext in |in| and returns true.
- // Otherwise, it returns false. The output will always be |ExplicitNonceLen|
- // bytes ahead of |in|.
- bool Open(CBS *out, uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], uint8_t *in, size_t in_len);
+ // Open authenticates and decrypts |in| in-place. On success, it sets |*out|
+ // to the plaintext in |in| and returns true. Otherwise, it returns
+ // false. The output will always be |ExplicitNonceLen| bytes ahead of |in|.
+ bool Open(Span<uint8_t> *out, uint8_t type, uint16_t record_version,
+ const uint8_t seqnum[8], Span<uint8_t> in);
// Seal encrypts and authenticates |in_len| bytes from |in| and writes the
// result to |out|. It returns true on success and false on error.
@@ -763,7 +771,6 @@
ssl_open_record_discard,
ssl_open_record_partial,
ssl_open_record_close_notify,
- ssl_open_record_fatal_alert,
ssl_open_record_error,
};
@@ -785,21 +792,22 @@
// If a record was successfully processed but should be discarded, it returns
// |ssl_open_record_discard|.
//
-// If a record was successfully processed but is a close_notify or fatal alert,
-// it returns |ssl_open_record_close_notify| or |ssl_open_record_fatal_alert|.
+// If a record was successfully processed but is a close_notify, it returns
+// |ssl_open_record_close_notify|.
//
-// On failure, it returns |ssl_open_record_error| and sets |*out_alert| to an
-// alert to emit.
-enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, CBS *out,
- size_t *out_consumed, uint8_t *out_alert,
- uint8_t *in, size_t in_len);
+// On failure or fatal alert, it returns |ssl_open_record_error| and sets
+// |*out_alert| to an alert to emit, or zero if no alert should be emitted.
+enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type,
+ Span<uint8_t> *out, size_t *out_consumed,
+ uint8_t *out_alert, Span<uint8_t> in);
-// dtls_open_record implements |tls_open_record| for DTLS. It never returns
-// |ssl_open_record_partial| but otherwise behaves analogously.
-enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, CBS *out,
+// dtls_open_record implements |tls_open_record| for DTLS. It only returns
+// |ssl_open_record_partial| if |in| was empty and sets |*out_consumed| to
+// zero. The caller should read one packet and try again.
+enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type,
+ Span<uint8_t> *out,
size_t *out_consumed,
- uint8_t *out_alert, uint8_t *in,
- size_t in_len);
+ uint8_t *out_alert, Span<uint8_t> in);
// ssl_seal_align_prefix_len returns the length of the prefix before the start
// of the bulk of the ciphertext when sealing a record with |ssl|. Callers may
@@ -853,7 +861,7 @@
// |ssl_open_record_close_notify|, or |ssl_open_record_fatal_alert| as
// appropriate.
enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,
- const uint8_t *in, size_t in_len);
+ Span<const uint8_t> in);
// Private key operations.
@@ -870,22 +878,24 @@
enum ssl_private_key_result_t ssl_private_key_sign(
SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
- uint16_t sigalg, const uint8_t *in, size_t in_len);
+ uint16_t sigalg, Span<const uint8_t> in);
-enum ssl_private_key_result_t ssl_private_key_decrypt(
- SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
- const uint8_t *in, size_t in_len);
+enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
+ uint8_t *out,
+ size_t *out_len,
+ size_t max_out,
+ Span<const uint8_t> in);
-// ssl_private_key_supports_signature_algorithm returns one if |hs|'s private
-// key supports |sigalg| and zero otherwise.
-int ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs,
+// ssl_private_key_supports_signature_algorithm returns whether |hs|'s private
+// key supports |sigalg|.
+bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs,
uint16_t sigalg);
// ssl_public_key_verify verifies that the |signature| is valid for the public
// key |pkey| and input |in|, using the signature algorithm |sigalg|.
-int ssl_public_key_verify(SSL *ssl, const uint8_t *signature,
- size_t signature_len, uint16_t sigalg, EVP_PKEY *pkey,
- const uint8_t *in, size_t in_len);
+bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature,
+ uint16_t sigalg, EVP_PKEY *pkey,
+ Span<const uint8_t> in);
// Custom extensions
@@ -991,9 +1001,13 @@
// dtls_clear_incoming_messages releases all buffered incoming messages.
void dtls_clear_incoming_messages(SSL *ssl);
-// dtls_has_incoming_messages returns one if there are buffered incoming
-// messages ahead of the current message and zero otherwise.
-int dtls_has_incoming_messages(const SSL *ssl);
+// tls_has_unprocessed_handshake_data returns whether there is buffered
+// handshake data that has not been consumed by |get_message|.
+bool tls_has_unprocessed_handshake_data(const SSL *ssl);
+
+// dtls_has_unprocessed_handshake_data behaves like
+// |tls_has_unprocessed_handshake_data| for DTLS.
+bool dtls_has_unprocessed_handshake_data(const SSL *ssl);
struct DTLS_OUTGOING_MESSAGE {
uint8_t *data;
@@ -1013,16 +1027,13 @@
// ssl_do_msg_callback calls |ssl|'s message callback, if set.
void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type,
- const void *buf, size_t len);
+ Span<const uint8_t> in);
// Transport buffers.
-// ssl_read_buffer returns a pointer to contents of the read buffer.
-uint8_t *ssl_read_buffer(SSL *ssl);
-
-// ssl_read_buffer_len returns the length of the read buffer.
-size_t ssl_read_buffer_len(const SSL *ssl);
+// ssl_read_buffer returns the current read buffer.
+Span<uint8_t> ssl_read_buffer(SSL *ssl);
// ssl_read_buffer_extend_to extends the read buffer to the desired length. For
// TLS, it reads to the end of the buffer until the buffer is |len| bytes
@@ -1292,6 +1303,9 @@
// TLS 1.3.
uint16_t retry_group = 0;
+ // error, if |wait| is |ssl_hs_error|, is the error the handshake failed on.
+ UniquePtr<ERR_SAVE_STATE> error;
+
// key_share is the current key exchange instance.
UniquePtr<SSLKeyShare> key_share;
@@ -1496,20 +1510,21 @@
int tls13_add_finished(SSL_HANDSHAKE *hs);
int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg);
-int ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
- Array<uint8_t> *out_secret,
- uint8_t *out_alert, CBS *contents);
-int ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
- Array<uint8_t> *out_secret,
- uint8_t *out_alert, CBS *contents);
-int ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);
+bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
+ Array<uint8_t> *out_secret,
+ uint8_t *out_alert, CBS *contents);
+bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
+ Array<uint8_t> *out_secret,
+ uint8_t *out_alert, CBS *contents);
+bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);
-int ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert, CBS *contents);
-int ssl_ext_pre_shared_key_parse_clienthello(
+bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert,
+ CBS *contents);
+bool ssl_ext_pre_shared_key_parse_clienthello(
SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders,
uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, CBS *contents);
-int ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);
+bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out);
// ssl_is_sct_list_valid does a shallow parse of the SCT list in |contents| and
// returns one iff it's valid.
@@ -1525,18 +1540,17 @@
// tls13_get_cert_verify_signature_input generates the message to be signed for
// TLS 1.3's CertificateVerify message. |cert_verify_context| determines the
-// type of signature. It sets |*out| and |*out_len| to a newly allocated buffer
-// containing the result. The caller must free it with |OPENSSL_free| to release
-// it. This function returns one on success and zero on failure.
-int tls13_get_cert_verify_signature_input(
- SSL_HANDSHAKE *hs, uint8_t **out, size_t *out_len,
+// type of signature. It sets |*out| to a newly allocated buffer containing the
+// result. This function returns true on success and false on failure.
+bool tls13_get_cert_verify_signature_input(
+ SSL_HANDSHAKE *hs, Array<uint8_t> *out,
enum ssl_cert_verify_context_t cert_verify_context);
// ssl_negotiate_alpn negotiates the ALPN extension, if applicable. It returns
-// one on successful negotiation or if nothing was negotiated. It returns zero
+// true on successful negotiation or if nothing was negotiated. It returns false
// and sets |*out_alert| to an alert on error.
-int ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- const SSL_CLIENT_HELLO *client_hello);
+bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ const SSL_CLIENT_HELLO *client_hello);
struct SSL_EXTENSION_TYPE {
uint16_t type;
@@ -1556,6 +1570,10 @@
// ssl_verify_peer_cert verifies the peer certificate for |hs|.
enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs);
+enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs);
+bool ssl_send_finished(SSL_HANDSHAKE *hs);
+bool ssl_output_cert_chain(SSL *ssl);
+
// SSLKEYLOGFILE functions.
@@ -1631,7 +1649,7 @@
// From RFC4492, used in encoding the curve type in ECParameters
#define NAMED_CURVE_TYPE 3
-struct SSLCertConfig {
+struct CERT {
EVP_PKEY *privatekey;
// chain contains the certificate chain, with the leaf at the beginning. The
@@ -1698,6 +1716,66 @@
bool enable_early_data:1;
};
+// |SSL_PROTOCOL_METHOD| abstracts between TLS and DTLS.
+struct SSL_PROTOCOL_METHOD {
+ // is_dtls is one if the protocol is DTLS and zero otherwise.
+ char is_dtls;
+ int (*ssl_new)(SSL *ssl);
+ void (*ssl_free)(SSL *ssl);
+ // get_message sets |*out| to the current handshake message and returns true
+ // if one has been received. It returns false if more input is needed.
+ bool (*get_message)(SSL *ssl, SSLMessage *out);
+ // read_message reads additional handshake data for |get_message|. On success,
+ // it returns one. Otherwise, it returns <= 0.
+ int (*read_message)(SSL *ssl);
+ // next_message is called to release the current handshake message.
+ void (*next_message)(SSL *ssl);
+ // read_app_data reads up to |len| bytes of application data into |buf|. On
+ // success, it returns the number of bytes read. Otherwise, it returns <= 0
+ // and sets |*out_got_handshake| to whether the failure was due to a
+ // post-handshake handshake message. If so, any handshake messages consumed
+ // may be read with |get_message|.
+ int (*read_app_data)(SSL *ssl, bool *out_got_handshake, uint8_t *buf, int len,
+ int peek);
+ int (*read_change_cipher_spec)(SSL *ssl);
+ void (*read_close_notify)(SSL *ssl);
+ int (*write_app_data)(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf,
+ int len);
+ int (*dispatch_alert)(SSL *ssl);
+ // supports_cipher returns one if |cipher| is supported by this protocol and
+ // zero otherwise.
+ int (*supports_cipher)(const SSL_CIPHER *cipher);
+ // init_message begins a new handshake message of type |type|. |cbb| is the
+ // root CBB to be passed into |finish_message|. |*body| is set to a child CBB
+ // the caller should write to. It returns one on success and zero on error.
+ int (*init_message)(SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
+ // finish_message finishes a handshake message. It sets |*out_msg| to the
+ // serialized message. It returns one on success and zero on error.
+ int (*finish_message)(SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg);
+ // add_message adds a handshake message to the pending flight. It returns one
+ // on success and zero on error.
+ int (*add_message)(SSL *ssl, Array<uint8_t> msg);
+ // add_change_cipher_spec adds a ChangeCipherSpec record to the pending
+ // flight. It returns one on success and zero on error.
+ int (*add_change_cipher_spec)(SSL *ssl);
+ // add_alert adds an alert to the pending flight. It returns one on success
+ // and zero on error.
+ int (*add_alert)(SSL *ssl, uint8_t level, uint8_t desc);
+ // flush_flight flushes the pending flight to the transport. It returns one on
+ // success and <= 0 on error.
+ int (*flush_flight)(SSL *ssl);
+ // on_handshake_complete is called when the handshake is complete.
+ void (*on_handshake_complete)(SSL *ssl);
+ // set_read_state sets |ssl|'s read cipher state to |aead_ctx|. It returns
+ // one on success and zero if changing the read state is forbidden at this
+ // point.
+ int (*set_read_state)(SSL *ssl, UniquePtr<SSLAEADContext> aead_ctx);
+ // set_write_state sets |ssl|'s write cipher state to |aead_ctx|. It returns
+ // one on success and zero if changing the write state is forbidden at this
+ // point.
+ int (*set_write_state)(SSL *ssl, UniquePtr<SSLAEADContext> aead_ctx);
+};
+
// ssl_crypto_x509_method provides the |SSL_X509_METHOD| functions using
// crypto/x509.
extern const SSL_X509_METHOD ssl_crypto_x509_method;
@@ -1706,6 +1784,327 @@
// crypto/x509.
extern const SSL_X509_METHOD ssl_noop_x509_method;
+// ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with
+// equal-preference groups. For TLS clients, the groups are moot because the
+// server picks the cipher and groups cannot be expressed on the wire. However,
+// for servers, the equal-preference groups allow the client's preferences to
+// be partially respected. (This only has an effect with
+// SSL_OP_CIPHER_SERVER_PREFERENCE).
+//
+// The equal-preference groups are expressed by grouping SSL_CIPHERs together.
+// All elements of a group have the same priority: no ordering is expressed
+// within a group.
+//
+// The values in |ciphers| are in one-to-one correspondence with
+// |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of
+// bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to
+// indicate that the corresponding SSL_CIPHER is not the last element of a
+// group, or 0 to indicate that it is.
+//
+// For example, if |in_group_flags| contains all zeros then that indicates a
+// traditional, fully-ordered preference. Every SSL_CIPHER is the last element
+// of the group (i.e. they are all in a one-element group).
+//
+// For a more complex example, consider:
+// ciphers: A B C D E F
+// in_group_flags: 1 1 0 0 1 0
+//
+// That would express the following, order:
+//
+// A E
+// B -> D -> F
+// C
+struct ssl_cipher_preference_list_st {
+ STACK_OF(SSL_CIPHER) *ciphers;
+ uint8_t *in_group_flags;
+};
+
+struct tlsext_ticket_key {
+ static constexpr bool kAllowUniquePtr = true;
+
+ uint8_t name[SSL_TICKET_KEY_NAME_LEN];
+ uint8_t hmac_key[16];
+ uint8_t aes_key[16];
+ // next_rotation_tv_sec is the time (in seconds from the epoch) when the
+ // current key should be superseded by a new key, or the time when a previous
+ // key should be dropped. If zero, then the key should not be automatically
+ // rotated.
+ uint64_t next_rotation_tv_sec;
+};
+
+} // namespace bssl
+
+DECLARE_LHASH_OF(SSL_SESSION)
+
+namespace bssl {
+
+// SSLContext backs the public |SSL_CTX| type. Due to compatibility constraints,
+// it is a base class for |ssl_ctx_st|.
+struct SSLContext {
+ const SSL_PROTOCOL_METHOD *method;
+ const SSL_X509_METHOD *x509_method;
+
+ // lock is used to protect various operations on this object.
+ CRYPTO_MUTEX lock;
+
+ // conf_max_version is the maximum acceptable protocol version configured by
+ // |SSL_CTX_set_max_proto_version|. Note this version is normalized in DTLS
+ // and is further constrainted by |SSL_OP_NO_*|.
+ uint16_t conf_max_version;
+
+ // conf_min_version is the minimum acceptable protocol version configured by
+ // |SSL_CTX_set_min_proto_version|. Note this version is normalized in DTLS
+ // and is further constrainted by |SSL_OP_NO_*|.
+ uint16_t conf_min_version;
+
+ // tls13_variant is the variant of TLS 1.3 we are using for this
+ // configuration.
+ enum tls13_variant_t tls13_variant;
+
+ struct ssl_cipher_preference_list_st *cipher_list;
+
+ X509_STORE *cert_store;
+ LHASH_OF(SSL_SESSION) *sessions;
+ // Most session-ids that will be cached, default is
+ // SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
+ unsigned long session_cache_size;
+ SSL_SESSION *session_cache_head;
+ SSL_SESSION *session_cache_tail;
+
+ // handshakes_since_cache_flush is the number of successful handshakes since
+ // the last cache flush.
+ int handshakes_since_cache_flush;
+
+ // This can have one of 2 values, ored together,
+ // SSL_SESS_CACHE_CLIENT,
+ // SSL_SESS_CACHE_SERVER,
+ // Default is SSL_SESSION_CACHE_SERVER, which means only
+ // SSL_accept which cache SSL_SESSIONS.
+ int session_cache_mode;
+
+ // session_timeout is the default lifetime for new sessions in TLS 1.2 and
+ // earlier, in seconds.
+ uint32_t session_timeout;
+
+ // session_psk_dhe_timeout is the default lifetime for new sessions in TLS
+ // 1.3, in seconds.
+ uint32_t session_psk_dhe_timeout;
+
+ // If this callback is not null, it will be called each time a session id is
+ // added to the cache. If this function returns 1, it means that the
+ // callback will do a SSL_SESSION_free() when it has finished using it.
+ // Otherwise, on 0, it means the callback has finished with it. If
+ // remove_session_cb is not null, it will be called when a session-id is
+ // removed from the cache. After the call, OpenSSL will SSL_SESSION_free()
+ // it.
+ int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess);
+ void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess);
+ SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *data, int len,
+ int *copy);
+ SSL_SESSION *(*get_session_cb_legacy)(SSL *ssl, uint8_t *data, int len,
+ int *copy);
+
+ CRYPTO_refcount_t references;
+
+ // if defined, these override the X509_verify_cert() calls
+ int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg);
+ void *app_verify_arg;
+
+ enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl,
+ uint8_t *out_alert);
+
+ // Default password callback.
+ pem_password_cb *default_passwd_callback;
+
+ // Default password callback user data.
+ void *default_passwd_callback_userdata;
+
+ // get client cert callback
+ int (*client_cert_cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey);
+
+ // get channel id callback
+ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey);
+
+ CRYPTO_EX_DATA ex_data;
+
+ // custom_*_extensions stores any callback sets for custom extensions. Note
+ // that these pointers will be NULL if the stack would otherwise be empty.
+ STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions;
+ STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions;
+
+ // Default values used when no per-SSL value is defined follow
+
+ void (*info_callback)(const SSL *ssl, int type, int value);
+
+ // what we put in client cert requests
+ STACK_OF(CRYPTO_BUFFER) *client_CA;
+
+ // cached_x509_client_CA is a cache of parsed versions of the elements of
+ // |client_CA|.
+ STACK_OF(X509_NAME) *cached_x509_client_CA;
+
+
+ // Default values to use in SSL structures follow (these are copied by
+ // SSL_new)
+
+ uint32_t options;
+ uint32_t mode;
+ uint32_t max_cert_list;
+
+ CERT *cert;
+
+ // callback that allows applications to peek at protocol messages
+ void (*msg_callback)(int write_p, int version, int content_type,
+ const void *buf, size_t len, SSL *ssl, void *arg);
+ void *msg_callback_arg;
+
+ int verify_mode;
+ int (*default_verify_callback)(
+ int ok, X509_STORE_CTX *ctx); // called 'verify_callback' in the SSL
+
+ X509_VERIFY_PARAM *param;
+
+ // select_certificate_cb is called before most ClientHello processing and
+ // before the decision whether to resume a session is made. See
+ // |ssl_select_cert_result_t| for details of the return values.
+ enum ssl_select_cert_result_t (*select_certificate_cb)(
+ const SSL_CLIENT_HELLO *);
+
+ // dos_protection_cb is called once the resumption decision for a ClientHello
+ // has been made. It returns one to continue the handshake or zero to
+ // abort.
+ int (*dos_protection_cb) (const SSL_CLIENT_HELLO *);
+
+ // Maximum amount of data to send in one fragment. actual record size can be
+ // more than this due to padding and MAC overheads.
+ uint16_t max_send_fragment;
+
+ // TLS extensions servername callback
+ int (*tlsext_servername_callback)(SSL *, int *, void *);
+ void *tlsext_servername_arg;
+
+ // RFC 4507 session ticket keys. |tlsext_ticket_key_current| may be NULL
+ // before the first handshake and |tlsext_ticket_key_prev| may be NULL at any
+ // time. Automatically generated ticket keys are rotated as needed at
+ // handshake time. Hence, all access must be synchronized through |lock|.
+ struct tlsext_ticket_key *tlsext_ticket_key_current;
+ struct tlsext_ticket_key *tlsext_ticket_key_prev;
+
+ // Callback to support customisation of ticket key setting
+ int (*tlsext_ticket_key_cb)(SSL *ssl, uint8_t *name, uint8_t *iv,
+ EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc);
+
+ // Server-only: psk_identity_hint is the default identity hint to send in
+ // PSK-based key exchanges.
+ char *psk_identity_hint;
+
+ unsigned int (*psk_client_callback)(SSL *ssl, const char *hint,
+ char *identity,
+ unsigned int max_identity_len,
+ uint8_t *psk, unsigned int max_psk_len);
+ unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
+ uint8_t *psk, unsigned int max_psk_len);
+
+
+ // Next protocol negotiation information
+ // (for experimental NPN extension).
+
+ // For a server, this contains a callback function by which the set of
+ // advertised protocols can be provided.
+ int (*next_protos_advertised_cb)(SSL *ssl, const uint8_t **out,
+ unsigned *out_len, void *arg);
+ void *next_protos_advertised_cb_arg;
+ // For a client, this contains a callback function that selects the
+ // next protocol from the list provided by the server.
+ int (*next_proto_select_cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg);
+ void *next_proto_select_cb_arg;
+
+ // ALPN information
+ // (we are in the process of transitioning from NPN to ALPN.)
+
+ // For a server, this contains a callback function that allows the
+ // server to select the protocol for the connection.
+ // out: on successful return, this must point to the raw protocol
+ // name (without the length prefix).
+ // outlen: on successful return, this contains the length of |*out|.
+ // in: points to the client's list of supported protocols in
+ // wire-format.
+ // inlen: the length of |in|.
+ int (*alpn_select_cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg);
+ void *alpn_select_cb_arg;
+
+ // For a client, this contains the list of supported protocols in wire
+ // format.
+ uint8_t *alpn_client_proto_list;
+ unsigned alpn_client_proto_list_len;
+
+ // SRTP profiles we are willing to do from RFC 5764
+ STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
+
+ // Supported group values inherited by SSL structure
+ size_t supported_group_list_len;
+ uint16_t *supported_group_list;
+
+ // The client's Channel ID private key.
+ EVP_PKEY *tlsext_channel_id_private;
+
+ // keylog_callback, if not NULL, is the key logging callback. See
+ // |SSL_CTX_set_keylog_callback|.
+ void (*keylog_callback)(const SSL *ssl, const char *line);
+
+ // current_time_cb, if not NULL, is the function to use to get the current
+ // time. It sets |*out_clock| to the current time. The |ssl| argument is
+ // always NULL. See |SSL_CTX_set_current_time_cb|.
+ void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock);
+
+ // pool is used for all |CRYPTO_BUFFER|s in case we wish to share certificate
+ // memory.
+ CRYPTO_BUFFER_POOL *pool;
+
+ // ticket_aead_method contains function pointers for opening and sealing
+ // session tickets.
+ const SSL_TICKET_AEAD_METHOD *ticket_aead_method;
+
+ // verify_sigalgs, if not empty, is the set of signature algorithms
+ // accepted from the peer in decreasing order of preference.
+ uint16_t *verify_sigalgs;
+ size_t num_verify_sigalgs;
+
+ // retain_only_sha256_of_client_certs is true if we should compute the SHA256
+ // hash of the peer's certificate and then discard it to save memory and
+ // session space. Only effective on the server side.
+ bool retain_only_sha256_of_client_certs:1;
+
+ // quiet_shutdown is true if the connection should not send a close_notify on
+ // shutdown.
+ bool quiet_shutdown:1;
+
+ // ocsp_stapling_enabled is only used by client connections and indicates
+ // whether OCSP stapling will be requested.
+ bool ocsp_stapling_enabled:1;
+
+ // If true, a client will request certificate timestamps.
+ bool signed_cert_timestamps_enabled:1;
+
+ // tlsext_channel_id_enabled is one if Channel ID is enabled and zero
+ // otherwise. For a server, means that we'll accept Channel IDs from clients.
+ // For a client, means that we'll advertise support.
+ bool tlsext_channel_id_enabled:1;
+
+ // grease_enabled is one if draft-davidben-tls-grease-01 is enabled and zero
+ // otherwise.
+ bool grease_enabled:1;
+
+ // allow_unknown_alpn_protos is one if the client allows unsolicited ALPN
+ // protocols from the peer.
+ bool allow_unknown_alpn_protos:1;
+
+ // ed25519_enabled is one if Ed25519 is advertised in the handshake.
+ bool ed25519_enabled:1;
+};
+
struct SSL3_RECORD {
// type is the record type.
uint8_t type;
@@ -1755,12 +2154,11 @@
int wpend_ret; // number of bytes submitted
const uint8_t *wpend_buf;
- // recv_shutdown is the shutdown state for the receive half of the
- // connection.
- enum ssl_shutdown_t recv_shutdown;
+ // read_shutdown is the shutdown state for the read half of the connection.
+ enum ssl_shutdown_t read_shutdown;
- // recv_shutdown is the shutdown state for the send half of the connection.
- enum ssl_shutdown_t send_shutdown;
+ // write_shutdown is the shutdown state for the write half of the connection.
+ enum ssl_shutdown_t write_shutdown;
int alert_dispatch;
@@ -2149,31 +2547,31 @@
// server is true iff the this SSL* is the server half. Note: before the SSL*
// is initialized by either SSL_set_accept_state or SSL_set_connect_state,
// the side is not determined. In this state, server is always false.
- unsigned server:1;
+ bool server:1;
// quiet_shutdown is true if the connection should not send a close_notify on
// shutdown.
- unsigned quiet_shutdown:1;
+ bool quiet_shutdown:1;
// Enable signed certificate time stamps. Currently client only.
- unsigned signed_cert_timestamps_enabled:1;
+ bool signed_cert_timestamps_enabled:1;
// ocsp_stapling_enabled is only used by client connections and indicates
// whether OCSP stapling will be requested.
- unsigned ocsp_stapling_enabled:1;
+ bool ocsp_stapling_enabled:1;
// tlsext_channel_id_enabled is copied from the |SSL_CTX|. For a server,
// means that we'll accept Channel IDs from clients. For a client, means that
// we'll advertise support.
- unsigned tlsext_channel_id_enabled:1;
+ bool tlsext_channel_id_enabled:1;
// retain_only_sha256_of_client_certs is true if we should compute the SHA256
// hash of the peer's certificate and then discard it to save memory and
// session space. Only effective on the server side.
- unsigned retain_only_sha256_of_client_certs:1;
+ bool retain_only_sha256_of_client_certs:1;
// early_data_accepted is true if early data was accepted by the server.
- unsigned early_data_accepted:1;
+ bool early_data_accepted:1;
};
// From draft-ietf-tls-tls13-18, used in determining PSK modes.
@@ -2284,22 +2682,22 @@
void ssl_update_cache(SSL_HANDSHAKE *hs, int mode);
-enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs);
-int ssl3_send_alert(SSL *ssl, int level, int desc);
+int ssl_send_alert(SSL *ssl, int level, int desc);
bool ssl3_get_message(SSL *ssl, SSLMessage *out);
int ssl3_read_message(SSL *ssl);
void ssl3_next_message(SSL *ssl);
-int ssl3_send_finished(SSL_HANDSHAKE *hs);
int ssl3_dispatch_alert(SSL *ssl);
int ssl3_read_app_data(SSL *ssl, bool *out_got_handshake, uint8_t *buf, int len,
int peek);
int ssl3_read_change_cipher_spec(SSL *ssl);
void ssl3_read_close_notify(SSL *ssl);
-int ssl3_read_handshake_bytes(SSL *ssl, uint8_t *buf, int len);
+// ssl3_get_record reads a new input record. On success, it places it in
+// |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
+// more data is needed.
+int ssl3_get_record(SSL *ssl);
int ssl3_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf,
int len);
-int ssl3_output_cert_chain(SSL *ssl);
int ssl3_new(SSL *ssl);
void ssl3_free(SSL *ssl);
@@ -2447,10 +2845,6 @@
// operation should be retried later.
int ssl_do_channel_id_callback(SSL *ssl);
-// ssl3_can_false_start returns one if |ssl| is allowed to False Start and zero
-// otherwise.
-int ssl3_can_false_start(const SSL *ssl);
-
// ssl_can_write returns one if |ssl| is allowed to write and zero otherwise.
int ssl_can_write(const SSL *ssl);
@@ -2480,75 +2874,12 @@
uint16_t version;
// method is the underlying SSL_PROTOCOL_METHOD that initializes the
// SSL_CTX.
- const SSL_PROTOCOL_METHOD *method;
+ const bssl::SSL_PROTOCOL_METHOD *method;
// x509_method contains pointers to functions that might deal with |X509|
// compatibility, or might be a no-op, depending on the application.
const SSL_X509_METHOD *x509_method;
};
-// ssl_protocol_method_st, aka |SSL_PROTOCOL_METHOD| abstracts between TLS and
-// DTLS.
-struct ssl_protocol_method_st {
- // is_dtls is one if the protocol is DTLS and zero otherwise.
- char is_dtls;
- int (*ssl_new)(SSL *ssl);
- void (*ssl_free)(SSL *ssl);
- // get_message sets |*out| to the current handshake message and returns true
- // if one has been received. It returns false if more input is needed.
- bool (*get_message)(SSL *ssl, bssl::SSLMessage *out);
- // read_message reads additional handshake data for |get_message|. On success,
- // it returns one. Otherwise, it returns <= 0.
- int (*read_message)(SSL *ssl);
- // next_message is called to release the current handshake message.
- void (*next_message)(SSL *ssl);
- // read_app_data reads up to |len| bytes of application data into |buf|. On
- // success, it returns the number of bytes read. Otherwise, it returns <= 0
- // and sets |*out_got_handshake| to whether the failure was due to a
- // post-handshake handshake message. If so, any handshake messages consumed
- // may be read with |get_message|.
- int (*read_app_data)(SSL *ssl, bool *out_got_handshake, uint8_t *buf, int len,
- int peek);
- int (*read_change_cipher_spec)(SSL *ssl);
- void (*read_close_notify)(SSL *ssl);
- int (*write_app_data)(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf,
- int len);
- int (*dispatch_alert)(SSL *ssl);
- // supports_cipher returns one if |cipher| is supported by this protocol and
- // zero otherwise.
- int (*supports_cipher)(const SSL_CIPHER *cipher);
- // init_message begins a new handshake message of type |type|. |cbb| is the
- // root CBB to be passed into |finish_message|. |*body| is set to a child CBB
- // the caller should write to. It returns one on success and zero on error.
- int (*init_message)(SSL *ssl, CBB *cbb, CBB *body, uint8_t type);
- // finish_message finishes a handshake message. It sets |*out_msg| to the
- // serialized message. It returns one on success and zero on error.
- int (*finish_message)(SSL *ssl, CBB *cbb, bssl::Array<uint8_t> *out_msg);
- // add_message adds a handshake message to the pending flight. It returns one
- // on success and zero on error.
- int (*add_message)(SSL *ssl, bssl::Array<uint8_t> msg);
- // add_change_cipher_spec adds a ChangeCipherSpec record to the pending
- // flight. It returns one on success and zero on error.
- int (*add_change_cipher_spec)(SSL *ssl);
- // add_alert adds an alert to the pending flight. It returns one on success
- // and zero on error.
- int (*add_alert)(SSL *ssl, uint8_t level, uint8_t desc);
- // flush_flight flushes the pending flight to the transport. It returns one on
- // success and <= 0 on error.
- int (*flush_flight)(SSL *ssl);
- // on_handshake_complete is called when the handshake is complete.
- void (*on_handshake_complete)(SSL *ssl);
- // set_read_state sets |ssl|'s read cipher state to |aead_ctx|. It returns
- // one on success and zero if changing the read state is forbidden at this
- // point.
- int (*set_read_state)(SSL *ssl,
- bssl::UniquePtr<bssl::SSLAEADContext> aead_ctx);
- // set_write_state sets |ssl|'s write cipher state to |aead_ctx|. It returns
- // one on success and zero if changing the write state is forbidden at this
- // point.
- int (*set_write_state)(SSL *ssl,
- bssl::UniquePtr<bssl::SSLAEADContext> aead_ctx);
-};
-
struct ssl_x509_method_st {
// check_client_CA_list returns one if |names| is a good list of X.509
// distinguished names and zero otherwise. This is used to ensure that we can
@@ -2556,17 +2887,17 @@
int (*check_client_CA_list)(STACK_OF(CRYPTO_BUFFER) *names);
// cert_clear frees and NULLs all X509 certificate-related state.
- void (*cert_clear)(CERT *cert);
+ void (*cert_clear)(bssl::CERT *cert);
// cert_free frees all X509-related state.
- void (*cert_free)(CERT *cert);
+ void (*cert_free)(bssl::CERT *cert);
// cert_flush_cached_chain drops any cached |X509|-based certificate chain
// from |cert|.
// cert_dup duplicates any needed fields from |cert| to |new_cert|.
- void (*cert_dup)(CERT *new_cert, const CERT *cert);
- void (*cert_flush_cached_chain)(CERT *cert);
+ void (*cert_dup)(bssl::CERT *new_cert, const bssl::CERT *cert);
+ void (*cert_flush_cached_chain)(bssl::CERT *cert);
// cert_flush_cached_chain drops any cached |X509|-based leaf certificate
// from |cert|.
- void (*cert_flush_cached_leaf)(CERT *cert);
+ void (*cert_flush_cached_leaf)(bssl::CERT *cert);
// session_cache_objects fills out |sess->x509_peer| and |sess->x509_chain|
// from |sess->certs| and erases |sess->x509_chain_without_leaf|. It returns
@@ -2605,12 +2936,11 @@
void (*ssl_ctx_flush_cached_client_CA)(SSL_CTX *ssl);
};
-// ssl_st backs the public |SSL| type. It subclasses the true type so that
-// SSLConnection may be a C++ type with methods and destructor without
-// polluting the global namespace.
+// The following types back public C-exposed types which must live in the global
+// namespace. We use subclassing so the implementations may be C++ types with
+// methods and destructor without polluting the global namespace.
+struct ssl_ctx_st : public bssl::SSLContext {};
struct ssl_st : public bssl::SSLConnection {};
-struct cert_st : public bssl::SSLCertConfig {};
-
#endif // OPENSSL_HEADER_SSL_INTERNAL_H
diff --git a/src/ssl/s3_both.cc b/src/ssl/s3_both.cc
index 65e2089..1c6882e 100644
--- a/src/ssl/s3_both.cc
+++ b/src/ssl/s3_both.cc
@@ -194,12 +194,11 @@
}
} while (!rest.empty());
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg.data(),
- msg.size());
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg);
// TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on
// hs.
if (ssl->s3->hs != NULL &&
- !ssl->s3->hs->transcript.Update(msg.data(), msg.size())) {
+ !ssl->s3->hs->transcript.Update(msg)) {
return 0;
}
return 1;
@@ -214,7 +213,7 @@
}
ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC,
- kChangeCipherSpec, sizeof(kChangeCipherSpec));
+ kChangeCipherSpec);
return 1;
}
@@ -224,7 +223,7 @@
return 0;
}
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, alert, sizeof(alert));
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, alert);
ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, ((int)level << 8) | desc);
return 1;
}
@@ -275,82 +274,6 @@
return 1;
}
-int ssl3_send_finished(SSL_HANDSHAKE *hs) {
- SSL *const ssl = hs->ssl;
- const SSL_SESSION *session = SSL_get_session(ssl);
-
- uint8_t finished[EVP_MAX_MD_SIZE];
- size_t finished_len;
- if (!hs->transcript.GetFinishedMAC(finished, &finished_len, session,
- ssl->server)) {
- return 0;
- }
-
- // Log the master secret, if logging is enabled.
- if (!ssl_log_secret(ssl, "CLIENT_RANDOM",
- session->master_key,
- session->master_key_length)) {
- return 0;
- }
-
- // Copy the Finished so we can use it for renegotiation checks.
- if (ssl->version != SSL3_VERSION) {
- if (finished_len > sizeof(ssl->s3->previous_client_finished) ||
- finished_len > sizeof(ssl->s3->previous_server_finished)) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (ssl->server) {
- OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len);
- ssl->s3->previous_server_finished_len = finished_len;
- } else {
- OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len);
- ssl->s3->previous_client_finished_len = finished_len;
- }
- }
-
- ScopedCBB cbb;
- CBB body;
- if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) ||
- !CBB_add_bytes(&body, finished, finished_len) ||
- !ssl_add_message_cbb(ssl, cbb.get())) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- return 1;
-}
-
-int ssl3_output_cert_chain(SSL *ssl) {
- ScopedCBB cbb;
- CBB body;
- if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) ||
- !ssl_add_cert_chain(ssl, &body) ||
- !ssl_add_message_cbb(ssl, cbb.get())) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- return 1;
-}
-
-static int extend_handshake_buffer(SSL *ssl, size_t length) {
- if (!BUF_MEM_reserve(ssl->init_buf, length)) {
- return -1;
- }
- while (ssl->init_buf->length < length) {
- int ret = ssl3_read_handshake_bytes(
- ssl, (uint8_t *)ssl->init_buf->data + ssl->init_buf->length,
- length - ssl->init_buf->length);
- if (ret <= 0) {
- return ret;
- }
- ssl->init_buf->length += (size_t)ret;
- }
- return 1;
-}
-
static int read_v2_client_hello(SSL *ssl) {
// Read the first 5 bytes, the size of the TLS record header. This is
// sufficient to detect a V2ClientHello and ensures that we never read beyond
@@ -359,7 +282,7 @@
if (ret <= 0) {
return ret;
}
- const uint8_t *p = ssl_read_buffer(ssl);
+ const uint8_t *p = ssl_read_buffer(ssl).data();
// Some dedicated error codes for protocol mixups should the application wish
// to interpret them differently. (These do not overlap with ClientHello or
@@ -402,19 +325,16 @@
return ret;
}
- CBS v2_client_hello;
- CBS_init(&v2_client_hello, ssl_read_buffer(ssl) + 2, msg_length);
-
+ CBS v2_client_hello = CBS(ssl_read_buffer(ssl).subspan(2, msg_length));
// The V2ClientHello without the length is incorporated into the handshake
// hash. This is only ever called at the start of the handshake, so hs is
// guaranteed to be non-NULL.
- if (!ssl->s3->hs->transcript.Update(CBS_data(&v2_client_hello),
- CBS_len(&v2_client_hello))) {
+ if (!ssl->s3->hs->transcript.Update(v2_client_hello)) {
return -1;
}
ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */,
- CBS_data(&v2_client_hello), CBS_len(&v2_client_hello));
+ v2_client_hello);
uint8_t msg_type;
uint16_t version, cipher_spec_length, session_id_length, challenge_length;
@@ -502,9 +422,8 @@
return 1;
}
-// TODO(davidben): Remove |out_bytes_needed| and inline into |ssl3_get_message|
-// when the entire record is copied into |init_buf|.
-static bool parse_message(SSL *ssl, SSLMessage *out, size_t *out_bytes_needed) {
+static bool parse_message(const SSL *ssl, SSLMessage *out,
+ size_t *out_bytes_needed) {
if (ssl->init_buf == NULL) {
*out_bytes_needed = 4;
return false;
@@ -528,19 +447,34 @@
CBS_init(&out->raw, reinterpret_cast<const uint8_t *>(ssl->init_buf->data),
4 + len);
out->is_v2_hello = ssl->s3->is_v2_hello;
+ return true;
+}
+
+bool ssl3_get_message(SSL *ssl, SSLMessage *out) {
+ size_t unused;
+ if (!parse_message(ssl, out, &unused)) {
+ return false;
+ }
if (!ssl->s3->has_message) {
if (!out->is_v2_hello) {
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE,
- CBS_data(&out->raw), CBS_len(&out->raw));
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw);
}
ssl->s3->has_message = true;
}
return true;
}
-bool ssl3_get_message(SSL *ssl, SSLMessage *out) {
- size_t unused;
- return parse_message(ssl, out, &unused);
+bool tls_has_unprocessed_handshake_data(const SSL *ssl) {
+ size_t msg_len = 0;
+ if (ssl->s3->has_message) {
+ SSLMessage msg;
+ size_t unused;
+ if (parse_message(ssl, &msg, &unused)) {
+ msg_len = CBS_len(&msg.raw);
+ }
+ }
+
+ return ssl->init_buf != NULL && ssl->init_buf->length > msg_len;
}
int ssl3_read_message(SSL *ssl) {
@@ -553,7 +487,7 @@
// Enforce the limit so the peer cannot force us to buffer 16MB.
if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
return -1;
}
@@ -575,7 +509,40 @@
return ret;
}
- return extend_handshake_buffer(ssl, bytes_needed);
+ SSL3_RECORD *rr = &ssl->s3->rrec;
+ // Get new packet if necessary.
+ if (rr->length == 0) {
+ int ret = ssl3_get_record(ssl);
+ if (ret <= 0) {
+ return ret;
+ }
+ }
+
+ // WatchGuard's TLS 1.3 interference bug is very distinctive: they drop the
+ // ServerHello and send the remaining encrypted application data records
+ // as-is. This manifests as an application data record when we expect
+ // handshake. Report a dedicated error code for this case.
+ if (!ssl->server && rr->type == SSL3_RT_APPLICATION_DATA &&
+ ssl->s3->aead_read_ctx->is_null_cipher()) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ return -1;
+ }
+
+ if (rr->type != SSL3_RT_HANDSHAKE) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ return -1;
+ }
+
+ // Append the entire handshake record to the buffer.
+ if (!BUF_MEM_append(ssl->init_buf, rr->data, rr->length)) {
+ return -1;
+ }
+
+ rr->length = 0;
+ ssl_read_buffer_discard(ssl);
+ return 1;
}
void ssl3_next_message(SSL *ssl) {
diff --git a/src/ssl/s3_pkt.cc b/src/ssl/s3_pkt.cc
index f7470ae..71e1a08 100644
--- a/src/ssl/s3_pkt.cc
+++ b/src/ssl/s3_pkt.cc
@@ -126,69 +126,55 @@
static int do_ssl3_write(SSL *ssl, int type, const uint8_t *buf, unsigned len);
-// ssl3_get_record reads a new input record. On success, it places it in
-// |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
-// more data is needed.
-static int ssl3_get_record(SSL *ssl) {
-again:
- switch (ssl->s3->recv_shutdown) {
- case ssl_shutdown_none:
- break;
- case ssl_shutdown_fatal_alert:
- OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
- return -1;
- case ssl_shutdown_close_notify:
- return 0;
- }
-
- CBS body;
- uint8_t type, alert = SSL_AD_DECODE_ERROR;
- size_t consumed;
- enum ssl_open_record_t open_ret =
- tls_open_record(ssl, &type, &body, &consumed, &alert,
- ssl_read_buffer(ssl), ssl_read_buffer_len(ssl));
- if (open_ret != ssl_open_record_partial) {
- ssl_read_buffer_consume(ssl, consumed);
- }
- switch (open_ret) {
- case ssl_open_record_partial: {
- int read_ret = ssl_read_buffer_extend_to(ssl, consumed);
- if (read_ret <= 0) {
- return read_ret;
- }
- goto again;
+int ssl3_get_record(SSL *ssl) {
+ for (;;) {
+ Span<uint8_t> body;
+ uint8_t type, alert = SSL_AD_DECODE_ERROR;
+ size_t consumed;
+ enum ssl_open_record_t open_ret = tls_open_record(
+ ssl, &type, &body, &consumed, &alert, ssl_read_buffer(ssl));
+ if (open_ret != ssl_open_record_partial) {
+ ssl_read_buffer_consume(ssl, consumed);
}
+ switch (open_ret) {
+ case ssl_open_record_partial: {
+ int read_ret = ssl_read_buffer_extend_to(ssl, consumed);
+ if (read_ret <= 0) {
+ return read_ret;
+ }
+ continue;
+ }
- case ssl_open_record_success: {
- if (CBS_len(&body) > 0xffff) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ case ssl_open_record_success: {
+ if (body.size() > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
+ }
+
+ SSL3_RECORD *rr = &ssl->s3->rrec;
+ rr->type = type;
+ rr->length = static_cast<uint16_t>(body.size());
+ rr->data = body.data();
+ return 1;
+ }
+
+ case ssl_open_record_discard:
+ continue;
+
+ case ssl_open_record_close_notify:
+ return 0;
+
+ case ssl_open_record_error:
+ if (alert != 0) {
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
+ }
return -1;
- }
-
- SSL3_RECORD *rr = &ssl->s3->rrec;
- rr->type = type;
- rr->length = (uint16_t)CBS_len(&body);
- rr->data = (uint8_t *)CBS_data(&body);
- return 1;
}
- case ssl_open_record_discard:
- goto again;
-
- case ssl_open_record_close_notify:
- return 0;
-
- case ssl_open_record_fatal_alert:
- return -1;
-
- case ssl_open_record_error:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
- return -1;
+ assert(0);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
-
- assert(0);
- OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
- return -1;
}
int ssl3_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf,
@@ -396,15 +382,15 @@
// by an alert.
if (SSL_in_init(ssl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
// Post-handshake data prior to TLS 1.3 is always renegotiation, which we
// never accept as a server. Otherwise |ssl3_get_message| will send
// |SSL_R_EXCESSIVE_MESSAGE_SIZE|.
- if (ssl->server && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION);
+ if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) {
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION);
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
return -1;
}
@@ -421,7 +407,7 @@
const int is_early_data_read = ssl->server &&
ssl->s3->hs != NULL &&
ssl->s3->hs->can_early_read &&
- ssl3_protocol_version(ssl) >= TLS1_3_VERSION;
+ ssl_protocol_version(ssl) >= TLS1_3_VERSION;
// Handle the end_of_early_data alert.
if (rr->type == SSL3_RT_ALERT &&
@@ -440,14 +426,14 @@
if (rr->type != SSL3_RT_APPLICATION_DATA) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
if (is_early_data_read) {
if (rr->length > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) {
OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL3_AD_UNEXPECTED_MESSAGE);
return -1;
}
@@ -464,7 +450,6 @@
int ssl3_read_change_cipher_spec(SSL *ssl) {
SSL3_RECORD *rr = &ssl->s3->rrec;
-
if (rr->length == 0) {
int ret = ssl3_get_record(ssl);
if (ret <= 0) {
@@ -472,20 +457,21 @@
}
}
- if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC ||
+ tls_has_unprocessed_handshake_data(ssl)) {
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
return -1;
}
if (rr->length != 1 || rr->data[0] != SSL3_MT_CCS) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return -1;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, rr->data,
- rr->length);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC,
+ MakeSpan(rr->data, rr->length));
rr->length = 0;
ssl_read_buffer_discard(ssl);
@@ -499,55 +485,19 @@
}
}
-int ssl3_read_handshake_bytes(SSL *ssl, uint8_t *buf, int len) {
- SSL3_RECORD *rr = &ssl->s3->rrec;
-
- for (;;) {
- // Get new packet if necessary.
- if (rr->length == 0) {
- int ret = ssl3_get_record(ssl);
- if (ret <= 0) {
- return ret;
- }
- }
-
- // WatchGuard's TLS 1.3 interference bug is very distinctive: they drop the
- // ServerHello and send the remaining encrypted application data records
- // as-is. This manifests as an application data record when we expect
- // handshake. Report a dedicated error code for this case.
- if (!ssl->server && rr->type == SSL3_RT_APPLICATION_DATA &&
- ssl->s3->aead_read_ctx->is_null_cipher()) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- return -1;
- }
-
- 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;
- }
-
- if (rr->length != 0) {
- return consume_record(ssl, buf, len, 0 /* consume data */);
- }
-
- // Discard empty records and loop again.
- }
-}
-
-int ssl3_send_alert(SSL *ssl, int level, int desc) {
+int ssl_send_alert(SSL *ssl, int level, int desc) {
// It is illegal to send an alert when we've already sent a closing one.
- if (ssl->s3->send_shutdown != ssl_shutdown_none) {
+ if (ssl->s3->write_shutdown != ssl_shutdown_none) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
return -1;
}
if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) {
- ssl->s3->send_shutdown = ssl_shutdown_close_notify;
+ ssl->s3->write_shutdown = ssl_shutdown_close_notify;
} else {
assert(level == SSL3_AL_FATAL);
- ssl->s3->send_shutdown = ssl_shutdown_fatal_alert;
+ assert(desc != SSL_AD_CLOSE_NOTIFY);
+ ssl->s3->write_shutdown = ssl_shutdown_fatal_alert;
}
ssl->s3->alert_dispatch = 1;
@@ -575,8 +525,7 @@
BIO_flush(ssl->wbio);
}
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert,
- 2);
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert);
int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1];
ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert);
diff --git a/src/ssl/ssl_aead_ctx.cc b/src/ssl/ssl_aead_ctx.cc
index 8856f74..775827c 100644
--- a/src/ssl/ssl_aead_ctx.cc
+++ b/src/ssl/ssl_aead_ctx.cc
@@ -225,11 +225,12 @@
return len;
}
-bool SSLAEADContext::Open(CBS *out, uint8_t type, uint16_t record_version,
- const uint8_t seqnum[8], uint8_t *in, size_t in_len) {
+bool SSLAEADContext::Open(Span<uint8_t> *out, uint8_t type,
+ uint16_t record_version, const uint8_t seqnum[8],
+ Span<uint8_t> in) {
if (is_null_cipher() || FUZZER_MODE) {
// Handle the initial NULL cipher.
- CBS_init(out, in, in_len);
+ *out = in;
return true;
}
@@ -238,12 +239,12 @@
size_t plaintext_len = 0;
if (!omit_length_in_ad_) {
size_t overhead = MaxOverhead();
- if (in_len < overhead) {
+ if (in.size() < overhead) {
// Publicly invalid.
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
return false;
}
- plaintext_len = in_len - overhead;
+ plaintext_len = in.size() - overhead;
}
uint8_t ad[13];
size_t ad_len =
@@ -264,14 +265,13 @@
// Add the variable nonce.
if (variable_nonce_included_in_record_) {
- if (in_len < variable_nonce_len_) {
+ if (in.size() < variable_nonce_len_) {
// Publicly invalid.
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
return false;
}
- OPENSSL_memcpy(nonce + nonce_len, in, variable_nonce_len_);
- in += variable_nonce_len_;
- in_len -= variable_nonce_len_;
+ OPENSSL_memcpy(nonce + nonce_len, in.data(), variable_nonce_len_);
+ in = in.subspan(variable_nonce_len_);
} else {
assert(variable_nonce_len_ == 8);
OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_);
@@ -288,11 +288,11 @@
// Decrypt in-place.
size_t len;
- if (!EVP_AEAD_CTX_open(ctx_.get(), in, &len, in_len, nonce, nonce_len, in,
- in_len, ad, ad_len)) {
+ if (!EVP_AEAD_CTX_open(ctx_.get(), in.data(), &len, in.size(), nonce,
+ nonce_len, in.data(), in.size(), ad, ad_len)) {
return false;
}
- CBS_init(out, in, len);
+ *out = in.subspan(0, len);
return true;
}
diff --git a/src/ssl/ssl_buffer.cc b/src/ssl/ssl_buffer.cc
index b424138..79f0cae 100644
--- a/src/ssl/ssl_buffer.cc
+++ b/src/ssl/ssl_buffer.cc
@@ -89,12 +89,9 @@
OPENSSL_memset(buf, 0, sizeof(SSL3_BUFFER));
}
-uint8_t *ssl_read_buffer(SSL *ssl) {
- return ssl->s3->read_buffer.buf + ssl->s3->read_buffer.offset;
-}
-
-size_t ssl_read_buffer_len(const SSL *ssl) {
- return ssl->s3->read_buffer.len;
+Span<uint8_t> ssl_read_buffer(SSL *ssl) {
+ return MakeSpan(ssl->s3->read_buffer.buf + ssl->s3->read_buffer.offset,
+ ssl->s3->read_buffer.len);
}
static int dtls_read_buffer_next_packet(SSL *ssl) {
diff --git a/src/ssl/ssl_cert.cc b/src/ssl/ssl_cert.cc
index 094d85a..cd586a0 100644
--- a/src/ssl/ssl_cert.cc
+++ b/src/ssl/ssl_cert.cc
@@ -599,7 +599,8 @@
!CBS_get_optional_asn1(
&tbs_cert, &outer_extensions, &has_extensions,
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) {
- goto parse_err;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
+ return 0;
}
if (!has_extensions) {
@@ -608,7 +609,8 @@
CBS extensions;
if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) {
- goto parse_err;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
+ return 0;
}
while (CBS_len(&extensions) > 0) {
@@ -619,7 +621,8 @@
!CBS_get_asn1(&extension, NULL, CBS_ASN1_BOOLEAN)) ||
!CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) ||
CBS_len(&extension) != 0) {
- goto parse_err;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
+ return 0;
}
static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f};
@@ -632,13 +635,15 @@
CBS bit_string;
if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) ||
CBS_len(&contents) != 0) {
- goto parse_err;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
+ return 0;
}
// This is the KeyUsage extension. See
// https://tools.ietf.org/html/rfc5280#section-4.2.1.3
if (!CBS_is_valid_asn1_bitstring(&bit_string)) {
- goto parse_err;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
+ return 0;
}
if (!CBS_asn1_bitstring_has_bit(&bit_string, 0)) {
@@ -651,10 +656,6 @@
// No KeyUsage extension found.
return 1;
-
-parse_err:
- OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT);
- return 0;
}
UniquePtr<STACK_OF(CRYPTO_BUFFER)> ssl_parse_client_CA_list(SSL *ssl,
@@ -731,7 +732,7 @@
int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey,
const CRYPTO_BUFFER *leaf) {
SSL *const ssl = hs->ssl;
- assert(ssl3_protocol_version(ssl) < TLS1_3_VERSION);
+ assert(ssl_protocol_version(ssl) < TLS1_3_VERSION);
// Check the certificate's type matches the cipher.
if (!(hs->new_cipher->algorithm_auth & ssl_cipher_auth_mask_for_key(pkey))) {
diff --git a/src/ssl/ssl_key_share.cc b/src/ssl/ssl_key_share.cc
index 3ceb180..52ff85d 100644
--- a/src/ssl/ssl_key_share.cc
+++ b/src/ssl/ssl_key_share.cc
@@ -168,7 +168,7 @@
uint8_t private_key_[32];
};
-const struct {
+CONSTEXPR_ARRAY struct {
int nid;
uint16_t group_id;
const char name[8];
diff --git a/src/ssl/ssl_lib.cc b/src/ssl/ssl_lib.cc
index f62d155..c975337 100644
--- a/src/ssl/ssl_lib.cc
+++ b/src/ssl/ssl_lib.cc
@@ -317,19 +317,6 @@
return 1;
}
-int ssl3_can_false_start(const SSL *ssl) {
- const SSL_CIPHER *const cipher = SSL_get_current_cipher(ssl);
-
- // False Start only for TLS 1.2 with an ECDHE+AEAD cipher and ALPN or NPN.
- return !SSL_is_dtls(ssl) &&
- SSL_version(ssl) == TLS1_2_VERSION &&
- (ssl->s3->alpn_selected != NULL ||
- ssl->s3->next_proto_negotiated != NULL) &&
- cipher != NULL &&
- cipher->algorithm_mkey == SSL_kECDHE &&
- cipher->algorithm_mac == SSL_AEAD;
-}
-
void ssl_do_info_callback(const SSL *ssl, int type, int value) {
void (*cb)(const SSL *ssl, int type, int value) = NULL;
if (ssl->info_callback != NULL) {
@@ -344,7 +331,7 @@
}
void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type,
- const void *buf, size_t len) {
+ Span<const uint8_t> in) {
if (ssl->msg_callback == NULL) {
return;
}
@@ -364,7 +351,7 @@
version = SSL_version(ssl);
}
- ssl->msg_callback(is_write, version, content_type, buf, len, ssl,
+ ssl->msg_callback(is_write, version, content_type, in.data(), in.size(), ssl,
ssl->msg_callback_arg);
}
@@ -744,12 +731,12 @@
}
void SSL_set_connect_state(SSL *ssl) {
- ssl->server = 0;
+ ssl->server = false;
ssl->do_handshake = ssl_client_handshake;
}
void SSL_set_accept_state(SSL *ssl) {
- ssl->server = 1;
+ ssl->server = true;
ssl->do_handshake = ssl_server_handshake;
}
@@ -852,7 +839,7 @@
}
static int ssl_do_post_handshake(SSL *ssl, const SSLMessage &msg) {
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return tls13_post_handshake(ssl, msg);
}
@@ -864,7 +851,7 @@
}
if (msg.type != SSL3_MT_HELLO_REQUEST || CBS_len(&msg.body) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST);
return 0;
}
@@ -909,7 +896,7 @@
return 1;
no_renegotiation:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION);
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
return 0;
}
@@ -937,28 +924,27 @@
}
}
- bool got_handshake = false;
- int ret = ssl->method->read_app_data(ssl, &got_handshake, (uint8_t *)buf,
- num, peek);
- if (ret > 0 || !got_handshake) {
- ssl->s3->key_update_count = 0;
- return ret;
- }
-
- // If we received an interrupt in early read (the end_of_early_data alert),
- // loop again for the handshake to process it.
- if (SSL_in_init(ssl)) {
- continue;
- }
-
+ // Process any buffered post-handshake messages.
SSLMessage msg;
- while (ssl->method->get_message(ssl, &msg)) {
+ if (ssl->method->get_message(ssl, &msg)) {
// Handle the post-handshake message and try again.
if (!ssl_do_post_handshake(ssl, msg)) {
return -1;
}
ssl->method->next_message(ssl);
+ continue; // Loop again. We may have begun a new handshake.
}
+
+ bool got_handshake = false;
+ int ret = ssl->method->read_app_data(ssl, &got_handshake, (uint8_t *)buf,
+ num, peek);
+ if (got_handshake) {
+ continue; // Loop again to process the handshake data.
+ }
+ if (ret > 0) {
+ ssl->s3->key_update_count = 0;
+ }
+ return ret;
}
}
@@ -978,7 +964,7 @@
return -1;
}
- if (ssl->s3->send_shutdown != ssl_shutdown_none) {
+ if (ssl->s3->write_shutdown != ssl_shutdown_none) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
return -1;
}
@@ -1021,8 +1007,8 @@
if (ssl->quiet_shutdown) {
// Do nothing if configured not to send a close_notify.
- ssl->s3->send_shutdown = ssl_shutdown_close_notify;
- ssl->s3->recv_shutdown = ssl_shutdown_close_notify;
+ ssl->s3->write_shutdown = ssl_shutdown_close_notify;
+ ssl->s3->read_shutdown = ssl_shutdown_close_notify;
return 1;
}
@@ -1030,9 +1016,9 @@
// waits for a close_notify to come in. Perform exactly one action and return
// whether or not it succeeds.
- if (ssl->s3->send_shutdown != ssl_shutdown_close_notify) {
+ if (ssl->s3->write_shutdown != ssl_shutdown_close_notify) {
// Send a close_notify.
- if (ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY) <= 0) {
+ if (ssl_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY) <= 0) {
return -1;
}
} else if (ssl->s3->alert_dispatch) {
@@ -1040,16 +1026,16 @@
if (ssl->method->dispatch_alert(ssl) <= 0) {
return -1;
}
- } else if (ssl->s3->recv_shutdown != ssl_shutdown_close_notify) {
+ } else if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) {
// Wait for the peer's close_notify.
ssl->method->read_close_notify(ssl);
- if (ssl->s3->recv_shutdown != ssl_shutdown_close_notify) {
+ if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) {
return -1;
}
}
// Return 0 for unidirectional shutdown and 1 for bidirectional shutdown.
- return ssl->s3->recv_shutdown == ssl_shutdown_close_notify;
+ return ssl->s3->read_shutdown == ssl_shutdown_close_notify;
}
int SSL_send_fatal_alert(SSL *ssl, uint8_t alert) {
@@ -1063,7 +1049,7 @@
return ssl->method->dispatch_alert(ssl);
}
- return ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
}
void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled) {
@@ -1137,7 +1123,7 @@
}
if (ret_code == 0) {
- if (ssl->s3->recv_shutdown == ssl_shutdown_close_notify) {
+ if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) {
return SSL_ERROR_ZERO_RETURN;
}
// An EOF was observed which violates the protocol, and the underlying
@@ -1272,8 +1258,8 @@
// tls-unique is not defined for SSL 3.0 or TLS 1.3.
if (!ssl->s3->initial_handshake_complete ||
- ssl3_protocol_version(ssl) < TLS1_VERSION ||
- ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ ssl_protocol_version(ssl) < TLS1_VERSION ||
+ ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return 0;
}
@@ -1411,8 +1397,8 @@
size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) {
if (!ssl->s3->initial_handshake_complete ||
- ssl3_protocol_version(ssl) < TLS1_VERSION ||
- ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ ssl_protocol_version(ssl) < TLS1_VERSION ||
+ ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return 0;
}
@@ -1427,8 +1413,8 @@
size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) {
if (!ssl->s3->initial_handshake_complete ||
- ssl3_protocol_version(ssl) < TLS1_VERSION ||
- ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ ssl_protocol_version(ssl) < TLS1_VERSION ||
+ ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return 0;
}
@@ -1449,7 +1435,7 @@
if (!ssl->s3->have_version) {
return 0;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return 1;
}
@@ -1567,7 +1553,7 @@
if (!ssl->s3->have_version) {
return 0;
}
- return ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
+ return ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
ssl->s3->send_connection_binding;
}
@@ -1795,19 +1781,19 @@
}
void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) {
- ctx->signed_cert_timestamps_enabled = 1;
+ ctx->signed_cert_timestamps_enabled = true;
}
void SSL_enable_signed_cert_timestamps(SSL *ssl) {
- ssl->signed_cert_timestamps_enabled = 1;
+ ssl->signed_cert_timestamps_enabled = true;
}
void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) {
- ctx->ocsp_stapling_enabled = 1;
+ ctx->ocsp_stapling_enabled = true;
}
void SSL_enable_ocsp_stapling(SSL *ssl) {
- ssl->ocsp_stapling_enabled = 1;
+ ssl->ocsp_stapling_enabled = true;
}
void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out,
@@ -2004,7 +1990,7 @@
EVP_PKEY_free(ctx->tlsext_channel_id_private);
EVP_PKEY_up_ref(private_key);
ctx->tlsext_channel_id_private = private_key;
- ctx->tlsext_channel_id_enabled = 1;
+ ctx->tlsext_channel_id_enabled = true;
return 1;
}
@@ -2018,7 +2004,7 @@
EVP_PKEY_free(ssl->tlsext_channel_id_private);
EVP_PKEY_up_ref(private_key);
ssl->tlsext_channel_id_private = private_key;
- ssl->tlsext_channel_id_enabled = 1;
+ ssl->tlsext_channel_id_enabled = true;
return 1;
}
@@ -2091,24 +2077,24 @@
assert((SSL_get_shutdown(ssl) & mode) == SSL_get_shutdown(ssl));
if (mode & SSL_RECEIVED_SHUTDOWN &&
- ssl->s3->recv_shutdown == ssl_shutdown_none) {
- ssl->s3->recv_shutdown = ssl_shutdown_close_notify;
+ ssl->s3->read_shutdown == ssl_shutdown_none) {
+ ssl->s3->read_shutdown = ssl_shutdown_close_notify;
}
if (mode & SSL_SENT_SHUTDOWN &&
- ssl->s3->send_shutdown == ssl_shutdown_none) {
- ssl->s3->send_shutdown = ssl_shutdown_close_notify;
+ ssl->s3->write_shutdown == ssl_shutdown_none) {
+ ssl->s3->write_shutdown = ssl_shutdown_close_notify;
}
}
int SSL_get_shutdown(const SSL *ssl) {
int ret = 0;
- if (ssl->s3->recv_shutdown != ssl_shutdown_none) {
+ if (ssl->s3->read_shutdown != ssl_shutdown_none) {
// Historically, OpenSSL set |SSL_RECEIVED_SHUTDOWN| on both close_notify
// and fatal alert.
ret |= SSL_RECEIVED_SHUTDOWN;
}
- if (ssl->s3->send_shutdown == ssl_shutdown_close_notify) {
+ if (ssl->s3->write_shutdown == ssl_shutdown_close_notify) {
// Historically, OpenSSL set |SSL_SENT_SHUTDOWN| on only close_notify.
ret |= SSL_SENT_SHUTDOWN;
}
diff --git a/src/ssl/ssl_privkey.cc b/src/ssl/ssl_privkey.cc
index d275561..b00613d 100644
--- a/src/ssl/ssl_privkey.cc
+++ b/src/ssl/ssl_privkey.cc
@@ -147,7 +147,7 @@
return 0;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
// RSA keys may only be used with RSA-PSS.
if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) {
return 0;
@@ -222,16 +222,16 @@
enum ssl_private_key_result_t ssl_private_key_sign(
SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
- uint16_t sigalg, const uint8_t *in, size_t in_len) {
+ uint16_t sigalg, Span<const uint8_t> in) {
SSL *const ssl = hs->ssl;
if (ssl->cert->key_method != NULL) {
enum ssl_private_key_result_t ret;
if (hs->pending_private_key_op) {
ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out);
} else {
- ret = (ssl->cert->key_method->sign != NULL
- ? ssl->cert->key_method->sign
- : legacy_sign)(ssl, out, out_len, max_out, sigalg, in, in_len);
+ ret = (ssl->cert->key_method->sign != NULL ? ssl->cert->key_method->sign
+ : legacy_sign)(
+ ssl, out, out_len, max_out, sigalg, in.data(), in.size());
}
hs->pending_private_key_op = ret == ssl_private_key_retry;
return ret;
@@ -240,31 +240,34 @@
*out_len = max_out;
ScopedEVP_MD_CTX ctx;
if (!setup_ctx(ssl, ctx.get(), ssl->cert->privatekey, sigalg, 0 /* sign */) ||
- !EVP_DigestSign(ctx.get(), out, out_len, in, in_len)) {
+ !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) {
return ssl_private_key_failure;
}
return ssl_private_key_success;
}
-int ssl_public_key_verify(SSL *ssl, const uint8_t *signature,
- size_t signature_len, uint16_t sigalg, EVP_PKEY *pkey,
- const uint8_t *in, size_t in_len) {
+bool ssl_public_key_verify(SSL *ssl, Span<const uint8_t> signature,
+ uint16_t sigalg, EVP_PKEY *pkey,
+ Span<const uint8_t> in) {
ScopedEVP_MD_CTX ctx;
return setup_ctx(ssl, ctx.get(), pkey, sigalg, 1 /* verify */) &&
- EVP_DigestVerify(ctx.get(), signature, signature_len, in, in_len);
+ EVP_DigestVerify(ctx.get(), signature.data(), signature.size(),
+ in.data(), in.size());
}
-enum ssl_private_key_result_t ssl_private_key_decrypt(
- SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out,
- const uint8_t *in, size_t in_len) {
+enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs,
+ uint8_t *out,
+ size_t *out_len,
+ size_t max_out,
+ Span<const uint8_t> in) {
SSL *const ssl = hs->ssl;
if (ssl->cert->key_method != NULL) {
enum ssl_private_key_result_t ret;
if (hs->pending_private_key_op) {
ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out);
} else {
- ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, in,
- in_len);
+ ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out,
+ in.data(), in.size());
}
hs->pending_private_key_op = ret == ssl_private_key_retry;
return ret;
@@ -279,17 +282,18 @@
// Decrypt with no padding. PKCS#1 padding will be removed as part of the
// timing-sensitive code by the caller.
- if (!RSA_decrypt(rsa, out_len, out, max_out, in, in_len, RSA_NO_PADDING)) {
+ if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(),
+ RSA_NO_PADDING)) {
return ssl_private_key_failure;
}
return ssl_private_key_success;
}
-int ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs,
- uint16_t sigalg) {
+bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs,
+ uint16_t sigalg) {
SSL *const ssl = hs->ssl;
if (!pkey_supports_algorithm(ssl, hs->local_pubkey.get(), sigalg)) {
- return 0;
+ return false;
}
// Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that
@@ -301,7 +305,7 @@
const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg);
if (alg->is_rsa_pss && (size_t)EVP_PKEY_size(hs->local_pubkey.get()) <
2 * EVP_MD_size(alg->digest_func()) + 2) {
- return 0;
+ return false;
}
// Newer algorithms require message-based private keys.
@@ -309,10 +313,10 @@
if (ssl->cert->key_method != NULL &&
ssl->cert->key_method->sign == NULL &&
!legacy_sign_digest_supported(alg)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
} // namespace bssl
diff --git a/src/ssl/ssl_session.cc b/src/ssl/ssl_session.cc
index aff9c0f..ea3c53f 100644
--- a/src/ssl/ssl_session.cc
+++ b/src/ssl/ssl_session.cc
@@ -377,7 +377,7 @@
ssl_get_current_time(ssl, &now);
session->time = now.tv_sec;
- uint16_t version = ssl3_protocol_version(ssl);
+ uint16_t version = ssl_protocol_version(ssl);
if (version >= TLS1_3_VERSION) {
// TLS 1.3 uses tickets as authenticators, so we are willing to use them for
// longer.
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index f9cf83c..4da109d 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -3760,6 +3760,73 @@
EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
}
+// Test that a handshake-level errors are sticky.
+TEST_P(SSLVersionTest, StickyErrorHandshake_ParseClientHello) {
+ UniquePtr<SSL_CTX> ctx = CreateContext();
+ ASSERT_TRUE(ctx);
+ UniquePtr<SSL> ssl(SSL_new(ctx.get()));
+ ASSERT_TRUE(ssl);
+ SSL_set_accept_state(ssl.get());
+
+ // Pass in an empty ClientHello.
+ if (is_dtls()) {
+ static const uint8_t kBadClientHello[] = {
+ 0x16, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ SSL_set0_rbio(ssl.get(),
+ BIO_new_mem_buf(kBadClientHello, sizeof(kBadClientHello)));
+ } else {
+ static const uint8_t kBadClientHello[] = {0x16, 0x03, 0x01, 0x00, 0x04,
+ 0x01, 0x00, 0x00, 0x00};
+ SSL_set0_rbio(ssl.get(),
+ BIO_new_mem_buf(kBadClientHello, sizeof(kBadClientHello)));
+ }
+
+ SSL_set0_wbio(ssl.get(), BIO_new(BIO_s_mem()));
+
+ // The handshake logic should reject the ClientHello.
+ int ret = SSL_do_handshake(ssl.get());
+ EXPECT_NE(1, ret);
+ EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
+ EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(ERR_peek_error()));
+ EXPECT_EQ(SSL_R_DECODE_ERROR, ERR_GET_REASON(ERR_peek_error()));
+ ERR_clear_error();
+
+ // If we drive the handshake again, the error is replayed.
+ ret = SSL_do_handshake(ssl.get());
+ EXPECT_NE(1, ret);
+ EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
+ EXPECT_EQ(ERR_LIB_SSL, ERR_GET_LIB(ERR_peek_error()));
+ EXPECT_EQ(SSL_R_DECODE_ERROR, ERR_GET_REASON(ERR_peek_error()));
+}
+
+TEST_P(SSLVersionTest, SSLPending) {
+ UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
+ ASSERT_TRUE(ssl);
+ EXPECT_EQ(0, SSL_pending(ssl.get()));
+
+ ASSERT_TRUE(Connect());
+ EXPECT_EQ(0, SSL_pending(client_.get()));
+
+ ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
+ ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
+ EXPECT_EQ(0, SSL_pending(client_.get()));
+
+ char buf[10];
+ ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
+ EXPECT_EQ(5, SSL_pending(client_.get()));
+
+ ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
+ EXPECT_EQ(4, SSL_pending(client_.get()));
+
+ ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
+ EXPECT_EQ(0, SSL_pending(client_.get()));
+
+ ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
+ EXPECT_EQ(3, SSL_pending(client_.get()));
+}
+
// TODO(davidben): Convert this file to GTest properly.
TEST(SSLTest, AllTests) {
if (!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
diff --git a/src/ssl/ssl_transcript.cc b/src/ssl/ssl_transcript.cc
index b9c1713..ab9822f 100644
--- a/src/ssl/ssl_transcript.cc
+++ b/src/ssl/ssl_transcript.cc
@@ -209,26 +209,19 @@
return EVP_MD_CTX_md(hash_.get());
}
-bool SSLTranscript::Update(const uint8_t *in, size_t in_len) {
+bool SSLTranscript::Update(Span<const uint8_t> in) {
// Depending on the state of the handshake, either the handshake buffer may be
// active, the rolling hash, or both.
- if (buffer_) {
- size_t new_len = buffer_->length + in_len;
- if (new_len < in_len) {
- OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
- return false;
- }
- if (!BUF_MEM_grow(buffer_.get(), new_len)) {
- return false;
- }
- OPENSSL_memcpy(buffer_->data + new_len - in_len, in, in_len);
+ if (buffer_ &&
+ !BUF_MEM_append(buffer_.get(), in.data(), in.size())) {
+ return false;
}
if (EVP_MD_CTX_md(hash_.get()) != NULL) {
- EVP_DigestUpdate(hash_.get(), in, in_len);
+ EVP_DigestUpdate(hash_.get(), in.data(), in.size());
}
if (EVP_MD_CTX_md(md5_.get()) != NULL) {
- EVP_DigestUpdate(md5_.get(), in, in_len);
+ EVP_DigestUpdate(md5_.get(), in.data(), in.size());
}
return true;
diff --git a/src/ssl/ssl_versions.cc b/src/ssl/ssl_versions.cc
index 56653b1..ccae6ef 100644
--- a/src/ssl/ssl_versions.cc
+++ b/src/ssl/ssl_versions.cc
@@ -287,7 +287,7 @@
return ssl->version;
}
-uint16_t ssl3_protocol_version(const SSL *ssl) {
+uint16_t ssl_protocol_version(const SSL *ssl) {
assert(ssl->s3->have_version);
uint16_t version;
if (!ssl_protocol_version_from_wire(&version, ssl->version)) {
diff --git a/src/ssl/t1_enc.cc b/src/ssl/t1_enc.cc
index 85c368c..e1578bd 100644
--- a/src/ssl/t1_enc.cc
+++ b/src/ssl/t1_enc.cc
@@ -331,7 +331,7 @@
size_t mac_secret_len, fixed_iv_len;
if (session->cipher == NULL ||
!ssl_cipher_get_evp_aead(&aead, &mac_secret_len, &fixed_iv_len,
- session->cipher, ssl3_protocol_version(ssl),
+ session->cipher, ssl_protocol_version(ssl),
SSL_is_dtls(ssl))) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return 0;
@@ -422,7 +422,7 @@
return 0;
}
} else {
- if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
+ if (ssl_protocol_version(ssl) == SSL3_VERSION) {
if (!ssl3_prf(out, SSL3_MASTER_SECRET_SIZE, premaster, premaster_len,
TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
ssl->s3->client_random, SSL3_RANDOM_SIZE,
@@ -455,7 +455,7 @@
int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) {
const SSL_SESSION *session = SSL_get_session(ssl);
- if (ssl3_protocol_version(ssl) == SSL3_VERSION) {
+ if (ssl_protocol_version(ssl) == SSL3_VERSION) {
return ssl3_prf(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,
@@ -482,7 +482,7 @@
return 0;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
return tls13_export_keying_material(ssl, out, out_len, label, label_len,
context, context_len, use_context);
}
diff --git a/src/ssl/t1_lib.cc b/src/ssl/t1_lib.cc
index 9c4231d..5d85cb0 100644
--- a/src/ssl/t1_lib.cc
+++ b/src/ssl/t1_lib.cc
@@ -537,52 +537,52 @@
// The add callbacks receive a |CBB| to which the extension can be appended but
// the function is responsible for appending the type and length bytes too.
//
-// All callbacks return one for success and zero for error. If a parse function
-// returns zero then a fatal alert with value |*out_alert| will be sent. If
-// |*out_alert| isn't set, then a |decode_error| alert will be sent.
+// All callbacks return true for success and false for error. If a parse
+// function returns zero then a fatal alert with value |*out_alert| will be
+// sent. If |*out_alert| isn't set, then a |decode_error| alert will be sent.
struct tls_extension {
uint16_t value;
void (*init)(SSL_HANDSHAKE *hs);
- int (*add_clienthello)(SSL_HANDSHAKE *hs, CBB *out);
- int (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents);
+ bool (*add_clienthello)(SSL_HANDSHAKE *hs, CBB *out);
+ bool (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents);
- int (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents);
- int (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out);
+ bool (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents);
+ bool (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out);
};
-static int forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
if (contents != NULL) {
// Servers MUST NOT send this extension.
*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
// This extension from the client is handled elsewhere.
- return 1;
+ return true;
}
-static int dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
- return 1;
+static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+ return true;
}
// Server name indication (SNI).
//
// https://tools.ietf.org/html/rfc6066#section-3.
-static int ext_sni_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_sni_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (ssl->tlsext_hostname == NULL) {
- return 1;
+ return true;
}
CBB contents, server_name_list, name;
@@ -594,24 +594,24 @@
!CBB_add_bytes(&name, (const uint8_t *)ssl->tlsext_hostname,
strlen(ssl->tlsext_hostname)) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
// The server may acknowledge SNI with an empty extension. We check the syntax
// but otherwise ignore this signal.
return contents == NULL || CBS_len(contents) == 0;
}
-static int ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
CBS server_name_list, host_name;
@@ -628,7 +628,7 @@
!CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
CBS_len(&server_name_list) != 0 ||
CBS_len(contents) != 0) {
- return 0;
+ return false;
}
if (name_type != TLSEXT_NAMETYPE_host_name ||
@@ -636,31 +636,31 @@
CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
CBS_contains_zero_byte(&host_name)) {
*out_alert = SSL_AD_UNRECOGNIZED_NAME;
- return 0;
+ return false;
}
// Copy the hostname as a string.
if (!CBS_strdup(&host_name, &ssl->s3->hostname)) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
hs->should_ack_sni = true;
- return 1;
+ return true;
}
-static int ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
if (hs->ssl->s3->session_reused ||
!hs->should_ack_sni) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -668,11 +668,11 @@
//
// https://tools.ietf.org/html/rfc5746
-static int ext_ri_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ri_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
// Renegotiation indication is not necessary in TLS 1.3.
if (hs->min_version >= TLS1_3_VERSION) {
- return 1;
+ return true;
}
assert(ssl->s3->initial_handshake_complete ==
@@ -685,18 +685,18 @@
!CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
ssl->s3->previous_client_finished_len) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
- if (contents != NULL && ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (contents != NULL && ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
// Servers may not switch between omitting the extension and supporting it.
@@ -705,7 +705,7 @@
(contents != NULL) != ssl->s3->send_connection_binding) {
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
- return 0;
+ return false;
}
if (contents == NULL) {
@@ -716,7 +716,7 @@
//
// OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in
// practical terms every client sets it so it's just assumed here.
- return 1;
+ return true;
}
const size_t expected_len = ssl->s3->previous_client_finished_len +
@@ -736,64 +736,64 @@
CBS_len(contents) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
// Check that the extension matches.
if (CBS_len(&renegotiated_connection) != expected_len) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
+ return false;
}
const uint8_t *d = CBS_data(&renegotiated_connection);
- int ok = CRYPTO_memcmp(d, ssl->s3->previous_client_finished,
- ssl->s3->previous_client_finished_len) == 0;
+ bool ok = CRYPTO_memcmp(d, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len) == 0;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
- ok = 1;
+ ok = true;
#endif
if (!ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
+ return false;
}
d += ssl->s3->previous_client_finished_len;
ok = CRYPTO_memcmp(d, ssl->s3->previous_server_finished,
ssl->s3->previous_server_finished_len) == 0;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
- ok = 1;
+ ok = true;
#endif
if (!ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
+ return false;
}
ssl->s3->send_connection_binding = true;
- return 1;
+ return true;
}
-static int ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
// Renegotiation isn't supported as a server so this function should never be
// called after the initial handshake.
assert(!ssl->s3->initial_handshake_complete);
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- return 1;
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return true;
}
if (contents == NULL) {
- return 1;
+ return true;
}
CBS renegotiated_connection;
if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
CBS_len(contents) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
- return 0;
+ return false;
}
// Check that the extension matches. We do not support renegotiation as a
@@ -801,31 +801,31 @@
if (CBS_len(&renegotiated_connection) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
+ return false;
}
ssl->s3->send_connection_binding = true;
- return 1;
+ return true;
}
-static int ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
// Renegotiation isn't supported as a server so this function should never be
// called after the initial handshake.
assert(!ssl->s3->initial_handshake_complete);
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- return 1;
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
!CBB_add_u16(out, 1 /* length */) ||
!CBB_add_u8(out, 0 /* empty renegotiation info */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -833,29 +833,29 @@
//
// https://tools.ietf.org/html/rfc7627
-static int ext_ems_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ems_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
// Extended master secret is not necessary in TLS 1.3.
if (hs->min_version >= TLS1_3_VERSION || hs->max_version <= SSL3_VERSION) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents != NULL) {
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
ssl->version == SSL3_VERSION ||
CBS_len(contents) != 0) {
- return 0;
+ return false;
}
hs->extended_master_secret = true;
@@ -867,43 +867,43 @@
!!ssl->s3->established_session->extended_master_secret) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_EMS_MISMATCH);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
- uint16_t version = ssl3_protocol_version(hs->ssl);
+static bool ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
+ uint16_t version = ssl_protocol_version(hs->ssl);
if (version >= TLS1_3_VERSION ||
version == SSL3_VERSION) {
- return 1;
+ return true;
}
if (contents == NULL) {
- return 1;
+ return true;
}
if (CBS_len(contents) != 0) {
- return 0;
+ return false;
}
hs->extended_master_secret = true;
- return 1;
+ return true;
}
-static int ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
if (!hs->extended_master_secret) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -911,12 +911,12 @@
//
// https://tools.ietf.org/html/rfc5077
-static int ext_ticket_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ticket_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
// TLS 1.3 uses a different ticket extension.
if (hs->min_version >= TLS1_3_VERSION ||
SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
- return 1;
+ return true;
}
const uint8_t *ticket_data = NULL;
@@ -940,21 +940,21 @@
!CBB_add_u16_length_prefixed(out, &ticket) ||
!CBB_add_bytes(&ticket, ticket_data, ticket_len) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- return 0;
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return false;
}
// If |SSL_OP_NO_TICKET| is set then no extension will have been sent and
@@ -963,16 +963,16 @@
assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);
if (CBS_len(contents) != 0) {
- return 0;
+ return false;
}
hs->ticket_expected = true;
- return 1;
+ return true;
}
-static int ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
if (!hs->ticket_expected) {
- return 1;
+ return true;
}
// If |SSL_OP_NO_TICKET| is set, |ticket_expected| should never be true.
@@ -980,10 +980,10 @@
if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -991,10 +991,10 @@
//
// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
-static int ext_sigalgs_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_sigalgs_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (hs->max_version < TLS1_2_VERSION) {
- return 1;
+ return true;
}
CBB contents, sigalgs_cbb;
@@ -1003,17 +1003,17 @@
!CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb) ||
!tls12_add_verify_sigalgs(ssl, &sigalgs_cbb) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
hs->peer_sigalgs.Reset();
if (contents == NULL) {
- return 1;
+ return true;
}
CBS supported_signature_algorithms;
@@ -1021,10 +1021,10 @@
CBS_len(contents) != 0 ||
CBS_len(&supported_signature_algorithms) == 0 ||
!tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -1032,10 +1032,10 @@
//
// https://tools.ietf.org/html/rfc6066#section-8
-static int ext_ocsp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ocsp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (!ssl->ocsp_stapling_enabled) {
- return 1;
+ return true;
}
CBB contents;
@@ -1045,28 +1045,28 @@
!CBB_add_u16(&contents, 0 /* empty responder ID list */) ||
!CBB_add_u16(&contents, 0 /* empty request extensions */) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
// TLS 1.3 OCSP responses are included in the Certificate extensions.
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- return 0;
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return false;
}
// OCSP stapling is forbidden on non-certificate ciphers.
if (CBS_len(contents) != 0 ||
!ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
- return 0;
+ return false;
}
// Note this does not check for resumption in TLS 1.2. Sending
@@ -1074,35 +1074,35 @@
// specification does not say anything. Tolerate it but ignore it.
hs->certificate_status_expected = true;
- return 1;
+ return true;
}
-static int ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
if (contents == NULL) {
- return 1;
+ return true;
}
uint8_t status_type;
if (!CBS_get_u8(contents, &status_type)) {
- return 0;
+ return false;
}
// We cannot decide whether OCSP stapling will occur yet because the correct
// SSL_CTX might not have been selected.
hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
- return 1;
+ return true;
}
-static int ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
!hs->ocsp_stapling_requested ||
ssl->cert->ocsp_response == NULL ||
ssl->s3->session_reused ||
!ssl_cipher_uses_certificate_auth(hs->new_cipher)) {
- return 1;
+ return true;
}
hs->certificate_status_expected = true;
@@ -1116,31 +1116,31 @@
//
// https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html
-static int ext_npn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_npn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (ssl->s3->initial_handshake_complete ||
ssl->ctx->next_proto_select_cb == NULL ||
SSL_is_dtls(ssl)) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- return 0;
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return false;
}
// If any of these are false then we should never have sent the NPN
@@ -1154,7 +1154,7 @@
// NPN and ALPN may not be negotiated in the same connection.
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
- return 0;
+ return false;
}
const uint8_t *const orig_contents = CBS_data(contents);
@@ -1164,7 +1164,7 @@
CBS proto;
if (!CBS_get_u8_length_prefixed(contents, &proto) ||
CBS_len(&proto) == 0) {
- return 0;
+ return false;
}
}
@@ -1174,7 +1174,7 @@
ssl, &selected, &selected_len, orig_contents, orig_len,
ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
OPENSSL_free(ssl->s3->next_proto_negotiated);
@@ -1182,43 +1182,43 @@
(uint8_t *)BUF_memdup(selected, selected_len);
if (ssl->s3->next_proto_negotiated == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
ssl->s3->next_proto_negotiated_len = selected_len;
hs->next_proto_neg_seen = true;
- return 1;
+ return true;
}
-static int ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- return 1;
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return true;
}
if (contents != NULL && CBS_len(contents) != 0) {
- return 0;
+ return false;
}
if (contents == NULL ||
ssl->s3->initial_handshake_complete ||
ssl->ctx->next_protos_advertised_cb == NULL ||
SSL_is_dtls(ssl)) {
- return 1;
+ return true;
}
hs->next_proto_neg_seen = true;
- return 1;
+ return true;
}
-static int ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
// |next_proto_neg_seen| might have been cleared when an ALPN extension was
// parsed.
if (!hs->next_proto_neg_seen) {
- return 1;
+ return true;
}
const uint8_t *npa;
@@ -1228,7 +1228,7 @@
ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) !=
SSL_TLSEXT_ERR_OK) {
hs->next_proto_neg_seen = false;
- return 1;
+ return true;
}
CBB contents;
@@ -1236,10 +1236,10 @@
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_bytes(&contents, npa, npa_len) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -1247,31 +1247,31 @@
//
// https://tools.ietf.org/html/rfc6962#section-3.3.1
-static int ext_sct_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_sct_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (!ssl->signed_cert_timestamps_enabled) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
// TLS 1.3 SCTs are included in the Certificate extensions.
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
// If this is false then we should never have sent the SCT extension in the
@@ -1280,7 +1280,7 @@
if (!ssl_is_sct_list_valid(contents)) {
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
// Session resumption uses the original session information. The extension
@@ -1294,34 +1294,34 @@
CRYPTO_BUFFER_new_from_CBS(contents, ssl->ctx->pool);
if (hs->new_session->signed_cert_timestamp_list == nullptr) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
}
- return 1;
+ return true;
}
-static int ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
if (contents == NULL) {
- return 1;
+ return true;
}
if (CBS_len(contents) != 0) {
- return 0;
+ return false;
}
hs->scts_requested = true;
- return 1;
+ return true;
}
-static int ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
// The extension shouldn't be sent when resuming sessions.
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION ||
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION ||
ssl->s3->session_reused ||
ssl->cert->signed_cert_timestamp_list == NULL) {
- return 1;
+ return true;
}
CBB contents;
@@ -1339,11 +1339,11 @@
//
// https://tools.ietf.org/html/rfc7301
-static int ext_alpn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_alpn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (ssl->alpn_client_proto_list == NULL ||
ssl->s3->initial_handshake_complete) {
- return 1;
+ return true;
}
CBB contents, proto_list;
@@ -1353,17 +1353,17 @@
!CBB_add_bytes(&proto_list, ssl->alpn_client_proto_list,
ssl->alpn_client_proto_list_len) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
assert(!ssl->s3->initial_handshake_complete);
@@ -1373,7 +1373,7 @@
// NPN and ALPN may not be negotiated in the same connection.
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
- return 0;
+ return false;
}
// The extension data consists of a ProtocolNameList which must have
@@ -1385,12 +1385,12 @@
// Empty protocol names are forbidden.
CBS_len(&protocol_name) == 0 ||
CBS_len(&protocol_name_list) != 0) {
- return 0;
+ return false;
}
if (!ssl->ctx->allow_unknown_alpn_protos) {
// Check that the protocol name is one of the ones we advertised.
- int protocol_ok = 0;
+ bool protocol_ok = false;
CBS client_protocol_name_list, client_protocol_name;
CBS_init(&client_protocol_name_list, ssl->alpn_client_proto_list,
ssl->alpn_client_proto_list_len);
@@ -1398,14 +1398,14 @@
if (!CBS_get_u8_length_prefixed(&client_protocol_name_list,
&client_protocol_name)) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
if (CBS_len(&client_protocol_name) == CBS_len(&protocol_name) &&
OPENSSL_memcmp(CBS_data(&client_protocol_name),
CBS_data(&protocol_name),
CBS_len(&protocol_name)) == 0) {
- protocol_ok = 1;
+ protocol_ok = true;
break;
}
}
@@ -1413,21 +1413,21 @@
if (!protocol_ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
}
if (!CBS_stow(&protocol_name, &ssl->s3->alpn_selected,
&ssl->s3->alpn_selected_len)) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-int ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- const SSL_CLIENT_HELLO *client_hello) {
+bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ const SSL_CLIENT_HELLO *client_hello) {
SSL *const ssl = hs->ssl;
CBS contents;
if (ssl->ctx->alpn_select_cb == NULL ||
@@ -1435,7 +1435,7 @@
client_hello, &contents,
TLSEXT_TYPE_application_layer_protocol_negotiation)) {
// Ignore ALPN if not configured or no extension was supplied.
- return 1;
+ return true;
}
// ALPN takes precedence over NPN.
@@ -1447,7 +1447,7 @@
CBS_len(&protocol_name_list) < 2) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
// Validate the protocol list.
@@ -1460,7 +1460,7 @@
CBS_len(&protocol_name) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
}
@@ -1474,18 +1474,18 @@
ssl->s3->alpn_selected = (uint8_t *)BUF_memdup(selected, selected_len);
if (ssl->s3->alpn_selected == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
ssl->s3->alpn_selected_len = selected_len;
}
- return 1;
+ return true;
}
-static int ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (ssl->s3->alpn_selected == NULL) {
- return 1;
+ return true;
}
CBB contents, proto_list, proto;
@@ -1496,10 +1496,10 @@
!CBB_add_bytes(&proto, ssl->s3->alpn_selected,
ssl->s3->alpn_selected_len) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -1511,68 +1511,70 @@
hs->ssl->s3->tlsext_channel_id_valid = false;
}
-static int ext_channel_id_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_channel_id_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (!ssl->tlsext_channel_id_enabled ||
SSL_is_dtls(ssl)) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert, CBS *contents) {
+static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
assert(!SSL_is_dtls(ssl));
assert(ssl->tlsext_channel_id_enabled);
if (CBS_len(contents) != 0) {
- return 0;
+ return false;
}
ssl->s3->tlsext_channel_id_valid = true;
- return 1;
+ return true;
}
-static int ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert, CBS *contents) {
+static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL ||
!ssl->tlsext_channel_id_enabled ||
SSL_is_dtls(ssl)) {
- return 1;
+ return true;
}
if (CBS_len(contents) != 0) {
- return 0;
+ return false;
}
ssl->s3->tlsext_channel_id_valid = true;
- return 1;
+ return true;
}
-static int ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (!ssl->s3->tlsext_channel_id_valid) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
!CBB_add_u16(out, 0 /* length */)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -1585,40 +1587,40 @@
hs->ssl->srtp_profile = NULL;
}
-static int ext_srtp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_srtp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
if (profiles == NULL ||
sk_SRTP_PROTECTION_PROFILE_num(profiles) == 0) {
- return 1;
+ return true;
}
CBB contents, profile_ids;
if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16_length_prefixed(&contents, &profile_ids)) {
- return 0;
+ return false;
}
for (const SRTP_PROTECTION_PROFILE *profile : profiles) {
if (!CBB_add_u16(&profile_ids, profile->id)) {
- return 0;
+ return false;
}
}
if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
// The extension consists of a u16-prefixed profile ID list containing a
@@ -1633,14 +1635,14 @@
!CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
CBS_len(contents) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- return 0;
+ return false;
}
if (CBS_len(&srtp_mki) != 0) {
// Must be no MKI, since we never offer one.
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
@@ -1650,20 +1652,20 @@
for (const SRTP_PROTECTION_PROFILE *profile : profiles) {
if (profile->id == profile_id) {
ssl->srtp_profile = profile;
- return 1;
+ return true;
}
}
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
-static int ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
CBS profile_ids, srtp_mki;
@@ -1672,7 +1674,7 @@
!CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
CBS_len(contents) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- return 0;
+ return false;
}
// Discard the MKI value for now.
@@ -1687,23 +1689,23 @@
while (CBS_len(&profile_ids_tmp) > 0) {
uint16_t profile_id;
if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) {
- return 0;
+ return false;
}
if (server_profile->id == profile_id) {
ssl->srtp_profile = server_profile;
- return 1;
+ return true;
}
}
}
- return 1;
+ return true;
}
-static int ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (ssl->srtp_profile == NULL) {
- return 1;
+ return true;
}
CBB contents, profile_ids;
@@ -1713,10 +1715,10 @@
!CBB_add_u16(&profile_ids, ssl->srtp_profile->id) ||
!CBB_add_u8(&contents, 0 /* empty MKI */) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -1724,42 +1726,42 @@
//
// https://tools.ietf.org/html/rfc4492#section-5.1.2
-static int ext_ec_point_add_extension(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ec_point_add_extension(SSL_HANDSHAKE *hs, CBB *out) {
CBB contents, formats;
if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u8_length_prefixed(&contents, &formats) ||
!CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_ec_point_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ec_point_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
// The point format extension is unneccessary in TLS 1.3.
if (hs->min_version >= TLS1_3_VERSION) {
- return 1;
+ return true;
}
return ext_ec_point_add_extension(hs, out);
}
-static int ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
- CBS *contents) {
+static bool ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+ CBS *contents) {
if (contents == NULL) {
- return 1;
+ return true;
}
- if (ssl3_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
- return 0;
+ if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
+ return false;
}
CBS ec_point_format_list;
if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) ||
CBS_len(contents) != 0) {
- return 0;
+ return false;
}
// Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed
@@ -1768,33 +1770,33 @@
TLSEXT_ECPOINTFORMAT_uncompressed,
CBS_len(&ec_point_format_list)) == NULL) {
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
+static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert,
CBS *contents) {
- if (ssl3_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
- return 1;
+ if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) {
+ return true;
}
return ext_ec_point_parse_serverhello(hs, out_alert, contents);
}
-static int ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- return 1;
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return true;
}
const uint32_t alg_k = hs->new_cipher->algorithm_mkey;
const uint32_t alg_a = hs->new_cipher->algorithm_auth;
- const int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
+ const bool using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
if (!using_ecc) {
- return 1;
+ return true;
}
return ext_ec_point_add_extension(hs, out);
@@ -1816,11 +1818,11 @@
return 15 + ssl->session->tlsext_ticklen + binder_len;
}
-static int ext_pre_shared_key_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool 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) {
- return 1;
+ return true;
}
struct OPENSSL_timeval now;
@@ -1844,35 +1846,35 @@
!CBB_add_u16_length_prefixed(&contents, &binders) ||
!CBB_add_u8_length_prefixed(&binders, &binder) ||
!CBB_add_bytes(&binder, zero_binder, binder_len)) {
- return 0;
+ return false;
}
hs->needs_psk_binder = true;
return CBB_flush(out);
}
-int ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert,
- CBS *contents) {
+bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert,
+ CBS *contents) {
uint16_t psk_id;
if (!CBS_get_u16(contents, &psk_id) ||
CBS_len(contents) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
// We only advertise one PSK identity, so the only legal index is zero.
if (psk_id != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
*out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY;
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-int ssl_ext_pre_shared_key_parse_clienthello(
+bool ssl_ext_pre_shared_key_parse_clienthello(
SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders,
uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, CBS *contents) {
// We only process the first PSK identity since we don't support pure PSK.
@@ -1885,7 +1887,7 @@
CBS_len(contents) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
*out_binders = binders;
@@ -1899,7 +1901,7 @@
!CBS_get_u32(&identities, &unused_obfuscated_ticket_age)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
num_identities++;
@@ -1913,7 +1915,7 @@
if (!CBS_get_u8_length_prefixed(&binders, &binder)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
num_binders++;
@@ -1922,15 +1924,15 @@
if (num_identities != num_binders) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-int ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
if (!hs->ssl->s3->session_reused) {
- return 1;
+ return true;
}
CBB contents;
@@ -1939,10 +1941,10 @@
// We only consider the first identity for resumption
!CBB_add_u16(&contents, 0) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -1950,10 +1952,10 @@
//
// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.7
-static int ext_psk_key_exchange_modes_add_clienthello(SSL_HANDSHAKE *hs,
- CBB *out) {
+static bool ext_psk_key_exchange_modes_add_clienthello(SSL_HANDSHAKE *hs,
+ CBB *out) {
if (hs->max_version < TLS1_3_VERSION) {
- return 1;
+ return true;
}
CBB contents, ke_modes;
@@ -1961,17 +1963,17 @@
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u8_length_prefixed(&contents, &ke_modes) ||
!CBB_add_u8(&ke_modes, SSL_PSK_DHE_KE)) {
- return 0;
+ return false;
}
return CBB_flush(out);
}
-static int ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert,
- CBS *contents) {
+static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert,
+ CBS *contents) {
if (contents == NULL) {
- return 1;
+ return true;
}
CBS ke_modes;
@@ -1979,14 +1981,14 @@
CBS_len(&ke_modes) == 0 ||
CBS_len(contents) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
// We only support tickets with PSK_DHE_KE.
hs->accept_psk_mode = OPENSSL_memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE,
CBS_len(&ke_modes)) != NULL;
- return 1;
+ return true;
}
@@ -1994,14 +1996,14 @@
//
// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.8
-static int ext_early_data_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool 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->ticket_max_early_data == 0 ||
hs->received_hello_retry_request ||
!ssl->cert->enable_early_data) {
- return 1;
+ return true;
}
hs->early_data_offered = true;
@@ -2009,63 +2011,63 @@
if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) ||
!CBB_add_u16(out, 0) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
-static int ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert, CBS *contents) {
+static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert, CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL) {
- return 1;
+ return true;
}
if (CBS_len(contents) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
if (!ssl->s3->session_reused) {
*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
- return 0;
+ return false;
}
- ssl->early_data_accepted = 1;
- return 1;
+ ssl->early_data_accepted = true;
+ return true;
}
-static int ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert, CBS *contents) {
+static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert, CBS *contents) {
SSL *const ssl = hs->ssl;
if (contents == NULL ||
- ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
- return 1;
+ ssl_protocol_version(ssl) < TLS1_3_VERSION) {
+ return true;
}
if (CBS_len(contents) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
hs->early_data_offered = true;
- return 1;
+ return true;
}
-static int ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
if (!hs->ssl->early_data_accepted) {
- return 1;
+ return true;
}
if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) ||
!CBB_add_u16(out, 0) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -2073,17 +2075,17 @@
//
// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.5
-static int ext_key_share_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_key_share_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (hs->max_version < TLS1_3_VERSION) {
- return 1;
+ return true;
}
CBB contents, kse_bytes;
if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16_length_prefixed(&contents, &kse_bytes)) {
- return 0;
+ return false;
}
uint16_t group_id = hs->retry_group;
@@ -2093,7 +2095,7 @@
if (group_id == 0 &&
!CBB_add_bytes(&kse_bytes, hs->key_share_bytes.data(),
hs->key_share_bytes.size())) {
- return 0;
+ return false;
}
hs->key_share_bytes.Reset();
if (group_id == 0) {
@@ -2106,14 +2108,14 @@
ssl_get_grease_value(ssl, ssl_grease_group)) ||
!CBB_add_u16(&kse_bytes, 1 /* length */) ||
!CBB_add_u8(&kse_bytes, 0 /* one byte key share */))) {
- return 0;
+ return false;
}
// Predict the most preferred group.
Span<const uint16_t> groups = tls1_get_grouplist(ssl);
if (groups.empty()) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED);
- return 0;
+ return false;
}
group_id = groups[0];
@@ -2126,93 +2128,93 @@
!CBB_add_u16_length_prefixed(&kse_bytes, &key_exchange) ||
!hs->key_share->Offer(&key_exchange) ||
!CBB_flush(&kse_bytes)) {
- return 0;
+ return false;
}
// Save the contents of the extension to repeat it in the second ClientHello.
if (!hs->received_hello_retry_request &&
!hs->key_share_bytes.CopyFrom(
MakeConstSpan(CBB_data(&kse_bytes), CBB_len(&kse_bytes)))) {
- return 0;
+ return false;
}
return CBB_flush(out);
}
-int ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
- Array<uint8_t> *out_secret,
- uint8_t *out_alert, CBS *contents) {
+bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs,
+ Array<uint8_t> *out_secret,
+ uint8_t *out_alert, CBS *contents) {
CBS peer_key;
uint16_t group_id;
if (!CBS_get_u16(contents, &group_id) ||
!CBS_get_u16_length_prefixed(contents, &peer_key) ||
CBS_len(contents) != 0) {
*out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ return false;
}
if (hs->key_share->GroupID() != group_id) {
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
- return 0;
+ return false;
}
if (!hs->key_share->Finish(out_secret, out_alert, peer_key)) {
*out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
+ return false;
}
hs->new_session->group_id = group_id;
hs->key_share.reset();
- return 1;
+ return true;
}
-int ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
- Array<uint8_t> *out_secret,
- uint8_t *out_alert, CBS *contents) {
+bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found,
+ Array<uint8_t> *out_secret,
+ uint8_t *out_alert, CBS *contents) {
uint16_t group_id;
CBS key_shares;
if (!tls1_get_shared_group(hs, &group_id)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP);
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
+ return false;
}
if (!CBS_get_u16_length_prefixed(contents, &key_shares) ||
CBS_len(contents) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- return 0;
+ return false;
}
// Find the corresponding key share.
- bool found = false;
CBS peer_key;
+ CBS_init(&peer_key, NULL, 0);
while (CBS_len(&key_shares) > 0) {
uint16_t id;
CBS peer_key_tmp;
if (!CBS_get_u16(&key_shares, &id) ||
- !CBS_get_u16_length_prefixed(&key_shares, &peer_key_tmp)) {
+ !CBS_get_u16_length_prefixed(&key_shares, &peer_key_tmp) ||
+ CBS_len(&peer_key_tmp) == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- return 0;
+ return false;
}
if (id == group_id) {
- if (found) {
+ if (CBS_len(&peer_key) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_KEY_SHARE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
- found = true;
peer_key = peer_key_tmp;
// Continue parsing the structure to keep peers honest.
}
}
- if (!found) {
+ if (CBS_len(&peer_key) == 0) {
*out_found = false;
out_secret->Reset();
- return 1;
+ return true;
}
// Compute the DH secret.
@@ -2224,15 +2226,15 @@
!key_share->Accept(public_key.get(), &secret, out_alert, peer_key) ||
!CBBFinishArray(public_key.get(), &hs->ecdh_public_key)) {
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return false;
}
*out_secret = std::move(secret);
*out_found = true;
- return 1;
+ return true;
}
-int ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
+bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
uint16_t group_id;
CBB kse_bytes, public_key;
if (!tls1_get_shared_group(hs, &group_id) ||
@@ -2243,13 +2245,13 @@
!CBB_add_bytes(&public_key, hs->ecdh_public_key.data(),
hs->ecdh_public_key.size()) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
hs->ecdh_public_key.Reset();
hs->new_session->group_id = group_id;
- return 1;
+ return true;
}
@@ -2257,31 +2259,31 @@
//
// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.1
-static int ext_supported_versions_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_supported_versions_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
if (hs->max_version <= TLS1_2_VERSION) {
- return 1;
+ return true;
}
CBB contents, versions;
if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u8_length_prefixed(&contents, &versions)) {
- return 0;
+ return false;
}
// Add a fake version. See draft-davidben-tls-grease-01.
if (ssl->ctx->grease_enabled &&
!CBB_add_u16(&versions, ssl_get_grease_value(ssl, ssl_grease_version))) {
- return 0;
+ return false;
}
if (!ssl_add_supported_versions(hs, &versions) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
- return 1;
+ return true;
}
@@ -2289,9 +2291,9 @@
//
// 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) {
+static bool ext_cookie_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
if (hs->cookie.empty()) {
- return 1;
+ return true;
}
CBB contents, cookie;
@@ -2300,12 +2302,12 @@
!CBB_add_u16_length_prefixed(&contents, &cookie) ||
!CBB_add_bytes(&cookie, hs->cookie.data(), hs->cookie.size()) ||
!CBB_flush(out)) {
- return 0;
+ return false;
}
// The cookie is no longer needed in memory.
hs->cookie.Reset();
- return 1;
+ return true;
}
@@ -2314,37 +2316,37 @@
// https://tools.ietf.org/html/rfc4492#section-5.1.2
// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.4
-static int ext_supported_groups_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
+static bool ext_supported_groups_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) {
SSL *const ssl = hs->ssl;
CBB contents, groups_bytes;
if (!CBB_add_u16(out, TLSEXT_TYPE_supported_groups) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
!CBB_add_u16_length_prefixed(&contents, &groups_bytes)) {
- return 0;
+ return false;
}
// Add a fake group. See draft-davidben-tls-grease-01.
if (ssl->ctx->grease_enabled &&
!CBB_add_u16(&groups_bytes,
ssl_get_grease_value(ssl, ssl_grease_group))) {
- return 0;
+ return false;
}
for (uint16_t group : tls1_get_grouplist(ssl)) {
if (!CBB_add_u16(&groups_bytes, group)) {
- return 0;
+ return false;
}
}
return CBB_flush(out);
}
-static int ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs,
- uint8_t *out_alert,
- CBS *contents) {
+static bool ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs,
+ uint8_t *out_alert,
+ CBS *contents) {
// This extension is not expected to be echoed by servers in TLS 1.2, but some
// BigIP servers send it nonetheless, so do not enforce this.
- return 1;
+ return true;
}
static bool parse_u16_array(const CBS *cbs, Array<uint16_t> *out) {
@@ -2370,11 +2372,11 @@
return 1;
}
-static int ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs,
+static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs,
uint8_t *out_alert,
- CBS *contents) {
+ CBS *contents) {
if (contents == NULL) {
- return 1;
+ return true;
}
CBS supported_group_list;
@@ -2382,15 +2384,10 @@
CBS_len(&supported_group_list) == 0 ||
CBS_len(contents) != 0 ||
!parse_u16_array(&supported_group_list, &hs->peer_supported_group_list)) {
- return 0;
+ return false;
}
- return 1;
-}
-
-static int ext_supported_groups_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) {
- // Servers don't echo this extension.
- return 1;
+ return true;
}
@@ -2543,7 +2540,7 @@
ext_supported_groups_add_clienthello,
ext_supported_groups_parse_serverhello,
ext_supported_groups_parse_clienthello,
- ext_supported_groups_add_serverhello,
+ dont_add_serverhello,
},
};
@@ -2710,7 +2707,7 @@
}
// Discard empty extensions blocks before TLS 1.3.
- if (ssl3_protocol_version(ssl) < TLS1_3_VERSION &&
+ if (ssl_protocol_version(ssl) < TLS1_3_VERSION &&
CBB_len(&extensions) == 0) {
CBB_discard_child(out);
}
@@ -2812,7 +2809,7 @@
SSL *const ssl = hs->ssl;
int alert = SSL_AD_DECODE_ERROR;
if (ssl_scan_clienthello_tlsext(hs, client_hello, &alert) <= 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
@@ -2828,7 +2825,7 @@
int *out_alert) {
SSL *const ssl = hs->ssl;
// Before TLS 1.3, ServerHello extensions blocks may be omitted if empty.
- if (CBS_len(cbs) == 0 && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
+ if (CBS_len(cbs) == 0 && ssl_protocol_version(ssl) < TLS1_3_VERSION) {
return 1;
}
@@ -2920,7 +2917,7 @@
switch (ret) {
case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, al);
return -1;
case SSL_TLSEXT_ERR_NOACK:
@@ -2936,7 +2933,7 @@
SSL *const ssl = hs->ssl;
int alert = SSL_AD_DECODE_ERROR;
if (ssl_scan_serverhello_tlsext(hs, cbs, &alert) <= 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
@@ -3144,7 +3141,7 @@
int tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *in_sigalgs) {
// Extension ignored for inappropriate versions
- if (ssl3_protocol_version(hs->ssl) < TLS1_2_VERSION) {
+ if (ssl_protocol_version(hs->ssl) < TLS1_2_VERSION) {
return 1;
}
@@ -3170,7 +3167,7 @@
// Before TLS 1.2, the signature algorithm isn't negotiated as part of the
// handshake.
- if (ssl3_protocol_version(ssl) < TLS1_2_VERSION) {
+ if (ssl_protocol_version(ssl) < TLS1_2_VERSION) {
if (!tls1_get_legacy_signature_algorithm(out, hs->local_pubkey.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS);
return 0;
@@ -3184,7 +3181,7 @@
}
Span<const uint16_t> peer_sigalgs = hs->peer_sigalgs;
- if (peer_sigalgs.empty() && ssl3_protocol_version(ssl) < TLS1_3_VERSION) {
+ if (peer_sigalgs.empty() && ssl_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
@@ -3225,7 +3222,7 @@
extension_type != TLSEXT_TYPE_channel_id ||
CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -3271,7 +3268,7 @@
#endif
if (!sig_ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
ssl->s3->tlsext_channel_id_valid = false;
return 0;
}
@@ -3332,16 +3329,14 @@
int tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) {
SSL *const ssl = hs->ssl;
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- uint8_t *msg;
- size_t msg_len;
- if (!tls13_get_cert_verify_signature_input(hs, &msg, &msg_len,
+ if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
+ Array<uint8_t> msg;
+ if (!tls13_get_cert_verify_signature_input(hs, &msg,
ssl_cert_verify_channel_id)) {
return 0;
}
- SHA256(msg, msg_len, out);
+ SHA256(msg.data(), msg.size(), out);
*out_len = SHA256_DIGEST_LENGTH;
- OPENSSL_free(msg);
return 1;
}
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 5bed962..eee1337 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -497,7 +497,11 @@
RSABadValueCorrupt
RSABadValueTooLong
RSABadValueTooShort
- RSABadValueWrongVersion
+ RSABadValueWrongVersion1
+ RSABadValueWrongVersion2
+ RSABadValueWrongBlockType
+ RSABadValueWrongLeadingByte
+ RSABadValueNoZero
NumRSABadValues
)
@@ -560,6 +564,10 @@
// NewSessionTicket message despite promising to in ServerHello.
SkipNewSessionTicket bool
+ // UseFirstSessionTicket causes the client to cache only the first session
+ // ticket received.
+ UseFirstSessionTicket bool
+
// SkipClientCertificate causes the client to skip the Certificate
// message.
SkipClientCertificate bool
@@ -948,10 +956,22 @@
// record size.
PackHandshakeFragments int
- // PackHandshakeRecords, if true, causes handshake records in DTLS to be
- // packed into individual packets, up to the specified packet size.
+ // PackHandshakeRecords, if non-zero, causes handshake and
+ // ChangeCipherSpec records in DTLS to be packed into individual
+ // packets, up to the specified packet size.
PackHandshakeRecords int
+ // PackAppDataWithHandshake, if true, extends PackHandshakeRecords to
+ // additionally include the first application data record sent after the
+ // final Finished message in a handshake. (If the final Finished message
+ // is sent by the peer, this option has no effect.) This requires that
+ // the runner rather than shim speak first in a given test.
+ PackAppDataWithHandshake bool
+
+ // SplitAndPackAppData, if true, causes application data in DTLS to be
+ // split into two records each and packed into one packet.
+ SplitAndPackAppData bool
+
// PackHandshakeFlight, if true, causes each handshake flight in TLS to
// be packed into records, up to the largest size record available.
PackHandshakeFlight bool
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index a80e3c8..0edbe5c 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -96,6 +96,7 @@
handMsg []byte // pending assembled handshake message
handMsgLen int // handshake message length, not including the header
pendingFragments [][]byte // pending outgoing handshake fragments.
+ pendingPacket []byte // pending outgoing packet.
keyUpdateRequested bool
seenOneByteRecord bool
@@ -1400,10 +1401,6 @@
c.out.Lock()
defer c.out.Unlock()
- // Flush any pending handshake data. PackHelloRequestWithFinished may
- // have been set and the handshake not followed by Renegotiate.
- c.flushHandshake()
-
if err := c.out.err; err != nil {
return 0, err
}
@@ -1486,7 +1483,10 @@
}
cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
- c.config.ClientSessionCache.Put(cacheKey, session)
+ _, ok := c.config.ClientSessionCache.Get(cacheKey)
+ if !ok || !c.config.Bugs.UseFirstSessionTicket {
+ c.config.ClientSessionCache.Put(cacheKey, session)
+ }
return nil
}
diff --git a/src/ssl/test/runner/dtls.go b/src/ssl/test/runner/dtls.go
index bd111e0..b97f829 100644
--- a/src/ssl/test/runner/dtls.go
+++ b/src/ssl/test/runner/dtls.go
@@ -129,25 +129,37 @@
}
func (c *Conn) dtlsWriteRecord(typ recordType, data []byte) (n int, err error) {
+ // Only handshake messages are fragmented.
if typ != recordTypeHandshake {
reorder := typ == recordTypeChangeCipherSpec && c.config.Bugs.ReorderChangeCipherSpec
- // Flush pending handshake messages before writing a new record.
+ // Flush pending handshake messages before encrypting a new record.
if !reorder {
- err = c.dtlsFlushHandshake()
+ err = c.dtlsPackHandshake()
if err != nil {
return
}
}
- // Only handshake messages are fragmented.
- n, err = c.dtlsWriteRawRecord(typ, data)
- if err != nil {
- return
+ if typ == recordTypeApplicationData && len(data) > 1 && c.config.Bugs.SplitAndPackAppData {
+ _, err = c.dtlsPackRecord(typ, data[:len(data)/2], false)
+ if err != nil {
+ return
+ }
+ _, err = c.dtlsPackRecord(typ, data[len(data)/2:], true)
+ if err != nil {
+ return
+ }
+ n = len(data)
+ } else {
+ n, err = c.dtlsPackRecord(typ, data, false)
+ if err != nil {
+ return
+ }
}
if reorder {
- err = c.dtlsFlushHandshake()
+ err = c.dtlsPackHandshake()
if err != nil {
return
}
@@ -158,12 +170,19 @@
if err != nil {
return n, c.sendAlertLocked(alertLevelError, err.(alert))
}
+ } else {
+ // ChangeCipherSpec is part of the handshake and not
+ // flushed until dtlsFlushPacket.
+ err = c.dtlsFlushPacket()
+ if err != nil {
+ return
+ }
}
return
}
if c.out.cipher == nil && c.config.Bugs.StrayChangeCipherSpec {
- _, err = c.dtlsWriteRawRecord(recordTypeChangeCipherSpec, []byte{1})
+ _, err = c.dtlsPackRecord(recordTypeChangeCipherSpec, []byte{1}, false)
if err != nil {
return
}
@@ -243,7 +262,9 @@
return
}
-func (c *Conn) dtlsFlushHandshake() error {
+// dtlsPackHandshake packs the pending handshake flight into the pending
+// record. Callers should follow up with dtlsFlushPacket to write the packets.
+func (c *Conn) dtlsPackHandshake() error {
// This is a test-only DTLS implementation, so there is no need to
// retain |c.pendingFragments| for a future retransmit.
var fragments [][]byte
@@ -265,7 +286,6 @@
}
maxRecordLen := c.config.Bugs.PackHandshakeFragments
- maxPacketLen := c.config.Bugs.PackHandshakeRecords
// Pack handshake fragments into records.
var records [][]byte
@@ -285,42 +305,39 @@
}
}
- // Format them into packets.
- var packets [][]byte
+ // Send the records.
for _, record := range records {
- b, err := c.dtlsSealRecord(recordTypeHandshake, record)
+ _, err := c.dtlsPackRecord(recordTypeHandshake, record, false)
if err != nil {
return err
}
-
- if i := len(packets) - 1; len(packets) > 0 && len(packets[i])+len(b.data) <= maxPacketLen {
- packets[i] = append(packets[i], b.data...)
- } else {
- // The sealed record will be appended to and reused by
- // |c.out|, so copy it.
- packets = append(packets, append([]byte{}, b.data...))
- }
- c.out.freeBlock(b)
}
- // Send all the packets.
- for _, packet := range packets {
- if _, err := c.conn.Write(packet); err != nil {
- return err
- }
- }
return nil
}
-// dtlsSealRecord seals a record into a block from |c.out|'s pool.
-func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error) {
+func (c *Conn) dtlsFlushHandshake() error {
+ if err := c.dtlsPackHandshake(); err != nil {
+ return err
+ }
+ if err := c.dtlsFlushPacket(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// dtlsPackRecord packs a single record to the pending packet, flushing it
+// if necessary. The caller should call dtlsFlushPacket to flush the current
+// pending packet afterwards.
+func (c *Conn) dtlsPackRecord(typ recordType, data []byte, mustPack bool) (n int, err error) {
recordHeaderLen := dtlsRecordHeaderLen
maxLen := c.config.Bugs.MaxHandshakeRecordLength
if maxLen <= 0 {
maxLen = 1024
}
- b = c.out.newBlock()
+ b := c.out.newBlock()
explicitIVLen := 0
explicitIVIsSeq := false
@@ -372,23 +389,30 @@
}
copy(b.data[recordHeaderLen+explicitIVLen:], data)
c.out.encrypt(b, explicitIVLen, typ)
+
+ // Flush the current pending packet if necessary.
+ if !mustPack && len(b.data)+len(c.pendingPacket) > c.config.Bugs.PackHandshakeRecords {
+ err = c.dtlsFlushPacket()
+ if err != nil {
+ c.out.freeBlock(b)
+ return
+ }
+ }
+
+ // Add the record to the pending packet.
+ c.pendingPacket = append(c.pendingPacket, b.data...)
+ c.out.freeBlock(b)
+ n = len(data)
return
}
-func (c *Conn) dtlsWriteRawRecord(typ recordType, data []byte) (n int, err error) {
- b, err := c.dtlsSealRecord(typ, data)
- if err != nil {
- return
+func (c *Conn) dtlsFlushPacket() error {
+ if len(c.pendingPacket) == 0 {
+ return nil
}
-
- _, err = c.conn.Write(b.data)
- if err != nil {
- return
- }
- n = len(data)
-
- c.out.freeBlock(b)
- return
+ _, err := c.conn.Write(c.pendingPacket)
+ c.pendingPacket = nil
+ return err
}
func (c *Conn) dtlsDoReadHandshake() ([]byte, error) {
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index 0c23793..ef6a464 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -1622,7 +1622,9 @@
}
}
- c.flushHandshake()
+ if !isResume || !c.config.Bugs.PackAppDataWithHandshake {
+ c.flushHandshake()
+ }
return nil
}
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index f67cc94..0ffb72c 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -80,7 +80,7 @@
return err
}
}
- if err := hs.sendFinished(c.firstFinished[:]); err != nil {
+ if err := hs.sendFinished(c.firstFinished[:], isResume); err != nil {
return err
}
// Most retransmits are triggered by a timeout, but the final
@@ -120,7 +120,7 @@
if err := hs.sendSessionTicket(); err != nil {
return err
}
- if err := hs.sendFinished(nil); err != nil {
+ if err := hs.sendFinished(nil, isResume); err != nil {
return err
}
}
@@ -1800,7 +1800,7 @@
return nil
}
-func (hs *serverHandshakeState) sendFinished(out []byte) error {
+func (hs *serverHandshakeState) sendFinished(out []byte, isResume bool) error {
c := hs.c
finished := new(finishedMsg)
@@ -1845,8 +1845,8 @@
}
}
- if !c.config.Bugs.PackHelloRequestWithFinished {
- // Defer flushing until renegotiation.
+ if isResume || (!c.config.Bugs.PackHelloRequestWithFinished && !c.config.Bugs.PackAppDataWithHandshake) {
+ // Defer flushing until Renegotiate() or Write().
c.flushHandshake()
}
diff --git a/src/ssl/test/runner/key_agreement.go b/src/ssl/test/runner/key_agreement.go
index e33557b..5071985 100644
--- a/src/ssl/test/runner/key_agreement.go
+++ b/src/ssl/test/runner/key_agreement.go
@@ -136,12 +136,47 @@
return errors.New("tls: unexpected ServerKeyExchange")
}
+func rsaSize(pub *rsa.PublicKey) int {
+ return (pub.N.BitLen() + 7) / 8
+}
+
+func rsaRawEncrypt(pub *rsa.PublicKey, msg []byte) ([]byte, error) {
+ k := rsaSize(pub)
+ if len(msg) != k {
+ return nil, errors.New("tls: bad padded RSA input")
+ }
+ m := new(big.Int).SetBytes(msg)
+ e := big.NewInt(int64(pub.E))
+ m.Exp(m, e, pub.N)
+ unpadded := m.Bytes()
+ ret := make([]byte, k)
+ copy(ret[len(ret)-len(unpadded):], unpadded)
+ return ret, nil
+}
+
+// nonZeroRandomBytes fills the given slice with non-zero random octets.
+func nonZeroRandomBytes(s []byte, rand io.Reader) {
+ if _, err := io.ReadFull(rand, s); err != nil {
+ panic(err)
+ }
+
+ for i := range s {
+ for s[i] == 0 {
+ if _, err := io.ReadFull(rand, s[i:i+1]); err != nil {
+ panic(err)
+ }
+ }
+ }
+}
+
func (ka *rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
bad := config.Bugs.BadRSAClientKeyExchange
preMasterSecret := make([]byte, 48)
vers := clientHello.vers
- if bad == RSABadValueWrongVersion {
+ if bad == RSABadValueWrongVersion1 {
vers ^= 1
+ } else if bad == RSABadValueWrongVersion2 {
+ vers ^= 0x100
}
preMasterSecret[0] = byte(vers >> 8)
preMasterSecret[1] = byte(vers)
@@ -152,13 +187,31 @@
sentPreMasterSecret := preMasterSecret
if bad == RSABadValueTooLong {
- sentPreMasterSecret = make([]byte, len(sentPreMasterSecret)+1)
- copy(sentPreMasterSecret, preMasterSecret)
+ sentPreMasterSecret = make([]byte, 1, len(sentPreMasterSecret)+1)
+ sentPreMasterSecret = append(sentPreMasterSecret, preMasterSecret...)
} else if bad == RSABadValueTooShort {
sentPreMasterSecret = sentPreMasterSecret[:len(sentPreMasterSecret)-1]
}
- encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), sentPreMasterSecret)
+ // Pad for PKCS#1 v1.5.
+ padded := make([]byte, rsaSize(cert.PublicKey.(*rsa.PublicKey)))
+ padded[1] = 2
+ nonZeroRandomBytes(padded[2:len(padded)-len(sentPreMasterSecret)-1], config.rand())
+ copy(padded[len(padded)-len(sentPreMasterSecret):], sentPreMasterSecret)
+
+ if bad == RSABadValueWrongBlockType {
+ padded[1] = 3
+ } else if bad == RSABadValueWrongLeadingByte {
+ padded[0] = 1
+ } else if bad == RSABadValueNoZero {
+ for i := 2; i < len(padded); i++ {
+ if padded[i] == 0 {
+ padded[i]++
+ }
+ }
+ }
+
+ encrypted, err := rsaRawEncrypt(cert.PublicKey.(*rsa.PublicKey), padded)
if err != nil {
return nil, nil, err
}
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 5918e6b..a57362d 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -837,6 +837,13 @@
if err != nil {
return err
}
+ if config.Bugs.SplitAndPackAppData {
+ m, err := tlsConn.Read(bufTmp[n:])
+ if err != nil {
+ return err
+ }
+ n += m
+ }
if n != len(buf) {
return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
}
@@ -2293,17 +2300,6 @@
flags: []string{"-async"},
},
{
- protocol: dtls,
- name: "PackDTLSHandshake",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 2,
- PackHandshakeFragments: 20,
- PackHandshakeRecords: 200,
- },
- },
- },
- {
name: "SendEmptyRecords-Pass",
sendEmptyRecords: 32,
},
@@ -2495,7 +2491,7 @@
"-expect-total-renegotiations", "1",
},
shouldFail: true,
- expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
+ expectedError: ":BAD_HELLO_REQUEST:",
},
{
name: "BadHelloRequest-2",
@@ -2796,6 +2792,27 @@
shouldFail: true,
expectedLocalError: "local error: record overflow",
},
+ {
+ // Test that DTLS can handle multiple application data
+ // records in a single packet.
+ protocol: dtls,
+ name: "SplitAndPackAppData-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitAndPackAppData: true,
+ },
+ },
+ },
+ {
+ protocol: dtls,
+ name: "SplitAndPackAppData-DTLS-Async",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitAndPackAppData: true,
+ },
+ },
+ flags: []string{"-async"},
+ },
}
testCases = append(testCases, basicTests...)
@@ -3931,11 +3948,11 @@
}
type stateMachineTestConfig struct {
- protocol protocol
- async bool
- splitHandshake bool
- packHandshakeFlight bool
- implicitHandshake bool
+ protocol protocol
+ async bool
+ splitHandshake bool
+ packHandshake bool
+ implicitHandshake bool
}
// Adds tests that try to cover the range of the handshake state machine, under
@@ -3958,13 +3975,11 @@
async: async,
splitHandshake: true,
})
- if protocol == tls {
- addStateMachineCoverageTests(stateMachineTestConfig{
- protocol: protocol,
- async: async,
- packHandshakeFlight: true,
- })
- }
+ addStateMachineCoverageTests(stateMachineTestConfig{
+ protocol: protocol,
+ async: async,
+ packHandshake: true,
+ })
}
}
}
@@ -4603,7 +4618,7 @@
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
- PackHelloRequestWithFinished: config.packHandshakeFlight,
+ PackHelloRequestWithFinished: config.packHandshake,
},
},
sendHalfHelloRequest: true,
@@ -4913,9 +4928,16 @@
test.flags = append(test.flags, "-mtu", "256")
}
}
- if config.packHandshakeFlight {
- test.name += "-PackHandshakeFlight"
- test.config.Bugs.PackHandshakeFlight = true
+ if config.packHandshake {
+ test.name += "-PackHandshake"
+ if config.protocol == dtls {
+ test.config.Bugs.MaxHandshakeRecordLength = 2
+ test.config.Bugs.PackHandshakeFragments = 20
+ test.config.Bugs.PackHandshakeRecords = 1500
+ test.config.Bugs.PackAppDataWithHandshake = true
+ } else {
+ test.config.Bugs.PackHandshakeFlight = true
+ }
}
if config.implicitHandshake {
test.name += "-ImplicitHandshake"
@@ -10871,6 +10893,27 @@
},
})
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "EarlyData-FirstTicket-Server-" + name,
+ config: Config{
+ MaxVersion: VersionTLS13,
+ MinVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ UseFirstSessionTicket: true,
+ SendEarlyData: [][]byte{{1, 2, 3, 4}},
+ ExpectEarlyDataAccepted: true,
+ ExpectHalfRTTData: [][]byte{{254, 253, 252, 251}},
+ },
+ },
+ tls13Variant: variant,
+ messageCount: 2,
+ resumeSession: true,
+ flags: []string{
+ "-enable-early-data",
+ "-expect-accept-early-data",
+ },
+ })
}
testCases = append(testCases, testCase{
diff --git a/src/ssl/tls13_both.cc b/src/ssl/tls13_both.cc
index e0fefe3..5796bf4 100644
--- a/src/ssl/tls13_both.cc
+++ b/src/ssl/tls13_both.cc
@@ -37,57 +37,55 @@
// without being able to return application data.
static const uint8_t kMaxKeyUpdates = 32;
-int tls13_get_cert_verify_signature_input(
- SSL_HANDSHAKE *hs, uint8_t **out, size_t *out_len,
+bool tls13_get_cert_verify_signature_input(
+ SSL_HANDSHAKE *hs, Array<uint8_t> *out,
enum ssl_cert_verify_context_t cert_verify_context) {
ScopedCBB cbb;
if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
+ return false;
}
for (size_t i = 0; i < 64; i++) {
if (!CBB_add_u8(cbb.get(), 0x20)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
+ return false;
}
}
- const uint8_t *context;
- size_t context_len;
+ Span<const char> context;
if (cert_verify_context == ssl_cert_verify_server) {
- // Include the NUL byte.
static const char kContext[] = "TLS 1.3, server CertificateVerify";
- context = (const uint8_t *)kContext;
- context_len = sizeof(kContext);
+ context = kContext;
} else if (cert_verify_context == ssl_cert_verify_client) {
static const char kContext[] = "TLS 1.3, client CertificateVerify";
- context = (const uint8_t *)kContext;
- context_len = sizeof(kContext);
+ context = kContext;
} else if (cert_verify_context == ssl_cert_verify_channel_id) {
static const char kContext[] = "TLS 1.3, Channel ID";
- context = (const uint8_t *)kContext;
- context_len = sizeof(kContext);
+ context = kContext;
} else {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
+ return false;
}
- if (!CBB_add_bytes(cbb.get(), context, context_len)) {
+ // Note |context| includes the NUL byte separator.
+ if (!CBB_add_bytes(cbb.get(),
+ reinterpret_cast<const uint8_t *>(context.data()),
+ context.size())) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
+ return false;
}
uint8_t context_hash[EVP_MAX_MD_SIZE];
size_t context_hash_len;
if (!hs->transcript.GetHash(context_hash, &context_hash_len) ||
!CBB_add_bytes(cbb.get(), context_hash, context_hash_len) ||
- !CBB_finish(cbb.get(), out, out_len)) {
+ !CBBFinishArray(cbb.get(), out)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
- return 0;
+ return false;
}
- return 1;
+ return true;
}
int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg,
@@ -98,14 +96,14 @@
CBS_len(&context) != 0 ||
!CBS_get_u24_length_prefixed(&body, &certificate_list) ||
CBS_len(&body) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return 0;
}
UniquePtr<STACK_OF(CRYPTO_BUFFER)> certs(sk_CRYPTO_BUFFER_new_null());
if (!certs) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -118,7 +116,7 @@
if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) ||
!CBS_get_u16_length_prefixed(&certificate_list, &extensions) ||
CBS_len(&certificate) == 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
return 0;
}
@@ -126,14 +124,14 @@
if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) {
pkey = ssl_cert_parse_pubkey(&certificate);
if (!pkey) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return 0;
}
// TLS 1.3 always uses certificate keys for signing thus the correct
// keyUsage is enforced.
if (!ssl_cert_check_digital_signature_key_usage(&certificate)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return 0;
}
@@ -148,7 +146,7 @@
CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool));
if (!buf ||
!PushToStack(certs.get(), std::move(buf))) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -165,7 +163,7 @@
if (!ssl_parse_extensions(&extensions, &alert, ext_types,
OPENSSL_ARRAY_SIZE(ext_types),
0 /* reject unknown */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
@@ -174,7 +172,7 @@
if (have_status_request) {
if (ssl->server || !ssl->ocsp_stapling_enabled) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
return 0;
}
@@ -185,7 +183,7 @@
!CBS_get_u24_length_prefixed(&status_request, &ocsp_response) ||
CBS_len(&ocsp_response) == 0 ||
CBS_len(&status_request) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -194,7 +192,7 @@
hs->new_session->ocsp_response =
CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool);
if (hs->new_session->ocsp_response == nullptr) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return 0;
}
}
@@ -203,13 +201,13 @@
if (have_sct) {
if (ssl->server || !ssl->signed_cert_timestamps_enabled) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
return 0;
}
if (!ssl_is_sct_list_valid(&sct)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -218,7 +216,7 @@
hs->new_session->signed_cert_timestamp_list =
CRYPTO_BUFFER_new_from_CBS(&sct, ssl->ctx->pool);
if (hs->new_session->signed_cert_timestamp_list == nullptr) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return 0;
}
}
@@ -238,14 +236,14 @@
if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) {
if (!allow_anonymous) {
OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
return 0;
}
@@ -274,37 +272,34 @@
!CBS_get_u16_length_prefixed(&body, &signature) ||
CBS_len(&body) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
hs->new_session->peer_signature_algorithm = signature_algorithm;
- uint8_t *input = NULL;
- size_t input_len;
+ Array<uint8_t> input;
if (!tls13_get_cert_verify_signature_input(
- hs, &input, &input_len,
+ hs, &input,
ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return 0;
}
- UniquePtr<uint8_t> free_input(input);
- int sig_ok = ssl_public_key_verify(ssl, CBS_data(&signature),
- CBS_len(&signature), signature_algorithm,
- hs->peer_pubkey.get(), input, input_len);
+ bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm,
+ hs->peer_pubkey.get(), input);
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
- sig_ok = 1;
+ sig_ok = true;
ERR_clear_error();
#endif
if (!sig_ok) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
return 0;
}
@@ -334,7 +329,7 @@
finished_ok = 1;
#endif
if (!finished_ok) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
return 0;
}
@@ -437,22 +432,20 @@
size_t sig_len;
if (!CBB_add_u16_length_prefixed(&body, &child) ||
!CBB_reserve(&child, &sig, max_sig_len)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_private_key_failure;
}
- uint8_t *msg = NULL;
- size_t msg_len;
+ Array<uint8_t> msg;
if (!tls13_get_cert_verify_signature_input(
- hs, &msg, &msg_len,
+ hs, &msg,
ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_private_key_failure;
}
- UniquePtr<uint8_t> free_msg(msg);
enum ssl_private_key_result_t sign_result = ssl_private_key_sign(
- hs, sig, &sig_len, max_sig_len, signature_algorithm, msg, msg_len);
+ hs, sig, &sig_len, max_sig_len, signature_algorithm, msg);
if (sign_result != ssl_private_key_success) {
return sign_result;
}
@@ -471,7 +464,7 @@
uint8_t verify_data[EVP_MAX_MD_SIZE];
if (!tls13_finished_mac(hs, verify_data, &verify_data_len, ssl->server)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
return 0;
}
@@ -495,7 +488,7 @@
(key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED &&
key_update_request != SSL_KEY_UPDATE_REQUESTED)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return 0;
}
@@ -531,7 +524,7 @@
ssl->s3->key_update_count++;
if (ssl->s3->key_update_count > kMaxKeyUpdates) {
OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return 0;
}
@@ -544,7 +537,7 @@
return tls13_process_new_session_ticket(ssl, msg);
}
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
return 0;
}
diff --git a/src/ssl/tls13_client.cc b/src/ssl/tls13_client.cc
index 7ed9fad..e75d976 100644
--- a/src/ssl/tls13_client.cc
+++ b/src/ssl/tls13_client.cc
@@ -70,7 +70,7 @@
CBS_len(&extensions) == 0 ||
CBS_len(&body) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -85,7 +85,7 @@
if (!ssl_parse_extensions(&extensions, &alert, ext_types,
OPENSSL_ARRAY_SIZE(ext_types),
0 /* reject unknown */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
@@ -95,7 +95,7 @@
CBS_len(&cookie_value) == 0 ||
CBS_len(&cookie) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -108,13 +108,13 @@
uint16_t group_id;
if (!CBS_get_u16(&key_share, &group_id) || CBS_len(&key_share) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
// The group must be supported.
if (!tls1_check_group_id(ssl, group_id)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
return ssl_hs_error;
}
@@ -122,7 +122,7 @@
// Check that the HelloRetryRequest does not request the key share that
// was provided in the initial ClientHello.
if (hs->key_share->GroupID() == group_id) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
return ssl_hs_error;
}
@@ -188,7 +188,7 @@
(!CBS_get_u8(&body, &compression_method) || compression_method != 0)) ||
!CBS_get_u16_length_prefixed(&body, &extensions) ||
CBS_len(&body) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
@@ -197,7 +197,7 @@
? TLS1_2_VERSION
: ssl->version;
if (server_version != expected_version) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
return ssl_hs_error;
}
@@ -209,15 +209,15 @@
const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite);
if (cipher == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
// Check if the cipher is a TLS 1.3 cipher.
- if (SSL_CIPHER_get_min_version(cipher) > ssl3_protocol_version(ssl) ||
- SSL_CIPHER_get_max_version(cipher) < ssl3_protocol_version(ssl)) {
+ if (SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) ||
+ SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -236,7 +236,7 @@
if (!ssl_parse_extensions(&extensions, &alert, ext_types,
OPENSSL_ARRAY_SIZE(ext_types),
0 /* reject unknown */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
@@ -244,7 +244,7 @@
// TLS 1.3 version.
if (have_supported_versions && !ssl_is_resumption_experiment(ssl->version)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
return ssl_hs_error;
}
@@ -252,25 +252,25 @@
if (have_pre_shared_key) {
if (ssl->session == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
return ssl_hs_error;
}
if (!ssl_ext_pre_shared_key_parse_serverhello(hs, &alert,
&pre_shared_key)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
if (ssl->session->ssl_version != ssl->version) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
if (ssl->session->cipher->algorithm_prf != cipher->algorithm_prf) {
OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_PRF_HASH_MISMATCH);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -278,7 +278,7 @@
// This is actually a client application bug.
OPENSSL_PUT_ERROR(SSL,
SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
@@ -286,7 +286,7 @@
// Only authentication information carries over in TLS 1.3.
hs->new_session = SSL_SESSION_dup(ssl->session, SSL_SESSION_DUP_AUTH_ONLY);
if (!hs->new_session) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
ssl_set_session(ssl, NULL);
@@ -295,7 +295,7 @@
ssl_session_renew_timeout(ssl, hs->new_session.get(),
ssl->session_ctx->session_psk_dhe_timeout);
} else if (!ssl_get_new_session(hs, 0)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -320,7 +320,7 @@
if (!have_key_share) {
// We do not support psk_ke and thus always require a key share.
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
return ssl_hs_error;
}
@@ -329,7 +329,7 @@
alert = SSL_AD_DECODE_ERROR;
if (!ssl_ext_key_share_parse_serverhello(hs, &dhe_secret, &alert,
&key_share)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
@@ -357,7 +357,7 @@
// If not sending early data, set client traffic keys now so that alerts are
// encrypted.
if ((ssl_is_resumption_client_ccs_experiment(ssl->version) &&
- !ssl3_add_change_cipher_spec(ssl)) ||
+ !ssl->method->add_change_cipher_spec(ssl)) ||
!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
hs->hash_len)) {
return ssl_hs_error;
@@ -385,7 +385,7 @@
}
if (CBS_len(&body) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -394,7 +394,7 @@
hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
if (hs->new_session->early_alpn == NULL) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
hs->new_session->early_alpn_len = ssl->s3->alpn_selected_len;
@@ -452,7 +452,7 @@
!CBS_get_u16_length_prefixed(&body, &supported_signature_algorithms) ||
CBS_len(&supported_signature_algorithms) == 0 ||
!tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
@@ -461,7 +461,7 @@
UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names =
ssl_parse_client_CA_list(ssl, &alert, &body);
if (!ca_names) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
@@ -469,7 +469,7 @@
CBS extensions;
if (!CBS_get_u16_length_prefixed(&body, &extensions) ||
CBS_len(&body) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return ssl_hs_error;
}
@@ -565,7 +565,7 @@
if (hs->early_data_offered) {
if ((ssl_is_resumption_client_ccs_experiment(ssl->version) &&
- !ssl3_add_change_cipher_spec(ssl)) ||
+ !ssl->method->add_change_cipher_spec(ssl)) ||
!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret,
hs->hash_len)) {
return ssl_hs_error;
@@ -589,7 +589,7 @@
if (ssl->cert->cert_cb != NULL) {
int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg);
if (rv == 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
return ssl_hs_error;
}
@@ -790,7 +790,7 @@
!CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen) ||
!CBS_get_u16_length_prefixed(&body, &extensions) ||
CBS_len(&body) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return 0;
}
@@ -813,14 +813,14 @@
if (!ssl_parse_extensions(&extensions, &alert, ext_types,
OPENSSL_ARRAY_SIZE(ext_types),
1 /* ignore unknown */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
if (have_early_data_info && ssl->cert->enable_early_data) {
if (!CBS_get_u32(&early_data_info, &session->ticket_max_early_data) ||
CBS_len(&early_data_info) != 0) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return 0;
}
diff --git a/src/ssl/tls13_enc.cc b/src/ssl/tls13_enc.cc
index 0a36aab..6c7e1da 100644
--- a/src/ssl/tls13_enc.cc
+++ b/src/ssl/tls13_enc.cc
@@ -47,7 +47,7 @@
}
int tls13_init_key_schedule(SSL_HANDSHAKE *hs) {
- if (!init_key_schedule(hs, ssl3_protocol_version(hs->ssl), hs->new_cipher)) {
+ if (!init_key_schedule(hs, ssl_protocol_version(hs->ssl), hs->new_cipher)) {
return 0;
}
@@ -382,8 +382,8 @@
uint8_t context[EVP_MAX_MD_SIZE];
unsigned context_len;
if (!EVP_DigestInit_ex(ctx.get(), digest, NULL) ||
- !EVP_DigestUpdate(ctx.get(), hs->transcript.buffer_data(),
- hs->transcript.buffer_len()) ||
+ !EVP_DigestUpdate(ctx.get(), hs->transcript.buffer().data(),
+ hs->transcript.buffer().size()) ||
!EVP_DigestUpdate(ctx.get(), msg, len - hash_len - 3) ||
!EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
return 0;
diff --git a/src/ssl/tls13_server.cc b/src/ssl/tls13_server.cc
index ea1beae..09437a5 100644
--- a/src/ssl/tls13_server.cc
+++ b/src/ssl/tls13_server.cc
@@ -69,7 +69,7 @@
if (!ssl_client_hello_get_extension(client_hello, &key_share,
TLSEXT_TYPE_key_share)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION);
return 0;
}
@@ -78,7 +78,7 @@
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret,
&alert, &key_share)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return 0;
}
@@ -114,7 +114,7 @@
client_hello->cipher_suites_len);
const int aes_is_fine = EVP_has_aes_hardware();
- const uint16_t version = ssl3_protocol_version(ssl);
+ const uint16_t version = ssl_protocol_version(ssl);
const SSL_CIPHER *best = NULL;
while (CBS_len(&cipher_suites) > 0) {
@@ -165,6 +165,10 @@
}
hs->new_session->ticket_age_add_valid = 1;
+ if (ssl->cert->enable_early_data) {
+ hs->new_session->ticket_max_early_data = kMaxEarlyDataAccepted;
+ }
+
ScopedCBB cbb;
CBB body, ticket, extensions;
if (!ssl->method->init_message(ssl, cbb.get(), &body,
@@ -178,8 +182,6 @@
}
if (ssl->cert->enable_early_data) {
- hs->new_session->ticket_max_early_data = kMaxEarlyDataAccepted;
-
CBB early_data_info;
if (!CBB_add_u16(&extensions, TLSEXT_TYPE_ticket_early_data_info) ||
!CBB_add_u16_length_prefixed(&extensions, &early_data_info) ||
@@ -216,7 +218,7 @@
SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -228,7 +230,7 @@
hs->new_cipher = choose_tls13_cipher(ssl, &client_hello);
if (hs->new_cipher == NULL) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
return ssl_hs_error;
}
@@ -236,7 +238,7 @@
// deferred. Complete it now.
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
}
@@ -347,7 +349,7 @@
SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -358,7 +360,7 @@
case ssl_ticket_aead_ignore_ticket:
assert(!session);
if (!ssl_get_new_session(hs, 1 /* server */)) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
break;
@@ -382,11 +384,11 @@
ssl->s3->alpn_selected_len == session->early_alpn_len &&
OPENSSL_memcmp(ssl->s3->alpn_selected, session->early_alpn,
ssl->s3->alpn_selected_len) == 0) {
- ssl->early_data_accepted = 1;
+ ssl->early_data_accepted = true;
}
if (hs->new_session == NULL) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -398,7 +400,7 @@
break;
case ssl_ticket_aead_error:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, alert);
return ssl_hs_error;
case ssl_ticket_aead_retry:
@@ -414,7 +416,7 @@
hs->new_session->early_alpn = (uint8_t *)BUF_memdup(
ssl->s3->alpn_selected, ssl->s3->alpn_selected_len);
if (hs->new_session->early_alpn == NULL) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
hs->new_session->early_alpn_len = ssl->s3->alpn_selected_len;
@@ -424,7 +426,7 @@
ssl->ctx->dos_protection_cb(&client_hello) == 0) {
// Connection rejected for DOS reasons.
OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return ssl_hs_error;
}
@@ -450,7 +452,7 @@
bool need_retry;
if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
if (need_retry) {
- ssl->early_data_accepted = 0;
+ ssl->early_data_accepted = false;
ssl->s3->skip_early_data = true;
ssl->method->next_message(ssl);
hs->tls13_state = state_send_hello_retry_request;
@@ -497,7 +499,7 @@
SSL_CLIENT_HELLO client_hello;
if (!ssl_client_hello_init(ssl, &client_hello, msg)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
@@ -505,7 +507,7 @@
if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) {
if (need_retry) {
// Only send one HelloRetryRequest.
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
}
return ssl_hs_error;
@@ -550,7 +552,7 @@
}
if (ssl_is_resumption_experiment(ssl->version) &&
- !ssl3_add_change_cipher_spec(ssl)) {
+ !ssl->method->add_change_cipher_spec(ssl)) {
return ssl_hs_error;
}
@@ -666,8 +668,9 @@
assert(hs->hash_len <= 0xff);
uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0,
static_cast<uint8_t>(hs->hash_len)};
- if (!hs->transcript.Update(header, sizeof(header)) ||
- !hs->transcript.Update(hs->expected_client_finished, hs->hash_len) ||
+ if (!hs->transcript.Update(header) ||
+ !hs->transcript.Update(
+ MakeConstSpan(hs->expected_client_finished, hs->hash_len)) ||
!tls13_derive_resumption_secret(hs) ||
!add_new_session_tickets(hs)) {
return ssl_hs_error;
diff --git a/src/ssl/tls_method.cc b/src/ssl/tls_method.cc
index 286bf03..b4d08a0 100644
--- a/src/ssl/tls_method.cc
+++ b/src/ssl/tls_method.cc
@@ -74,11 +74,10 @@
assert(!ssl->s3->has_message);
// During the handshake, |init_buf| is retained. Release if it there is no
- // excess in it.
+ // excess in it. There may be excess left if there server sent Finished and
+ // HelloRequest in the same record.
//
- // TODO(davidben): The second check is always true but will not be once we
- // switch to copying the entire handshake record. Replace this comment with an
- // explanation when that happens and a TODO to reject it.
+ // TODO(davidben): SChannel does not support this. Reject this case.
if (ssl->init_buf != NULL && ssl->init_buf->length == 0) {
BUF_MEM_free(ssl->init_buf);
ssl->init_buf = NULL;
@@ -86,10 +85,13 @@
}
static int ssl3_set_read_state(SSL *ssl, UniquePtr<SSLAEADContext> aead_ctx) {
- if (ssl->s3->rrec.length != 0) {
- // There may not be unprocessed record data at a cipher change.
+ // Cipher changes are forbidden if the current epoch has leftover data.
+ //
+ // TODO(davidben): ssl->s3->rrec.length should be impossible now. Remove it
+ // once it is only used for application data.
+ if (ssl->s3->rrec.length != 0 || tls_has_unprocessed_handshake_data(ssl)) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return 0;
}
diff --git a/src/ssl/tls_record.cc b/src/ssl/tls_record.cc
index 5eeff3c..44a04d9 100644
--- a/src/ssl/tls_record.cc
+++ b/src/ssl/tls_record.cc
@@ -187,13 +187,22 @@
return ret;
}
-enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, CBS *out,
- size_t *out_consumed, uint8_t *out_alert,
- uint8_t *in, size_t in_len) {
+enum ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type,
+ Span<uint8_t> *out, size_t *out_consumed,
+ uint8_t *out_alert, Span<uint8_t> in) {
*out_consumed = 0;
+ switch (ssl->s3->read_shutdown) {
+ case ssl_shutdown_none:
+ break;
+ case ssl_shutdown_fatal_alert:
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ *out_alert = 0;
+ return ssl_open_record_error;
+ case ssl_shutdown_close_notify:
+ return ssl_open_record_close_notify;
+ }
- CBS cbs;
- CBS_init(&cbs, in, in_len);
+ CBS cbs = CBS(in);
// Decode the record header.
uint8_t type;
@@ -234,10 +243,10 @@
return ssl_open_record_partial;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, in,
- SSL3_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER,
+ in.subspan(0, SSL3_RT_HEADER_LENGTH));
- *out_consumed = in_len - CBS_len(&cbs);
+ *out_consumed = in.size() - CBS_len(&cbs);
// Skip early data received when expecting a second ClientHello if we rejected
// 0RTT.
@@ -248,9 +257,9 @@
}
// Decrypt the body in-place.
- if (!ssl->s3->aead_read_ctx->Open(out, type, version, ssl->s3->read_sequence,
- (uint8_t *)CBS_data(&body),
- CBS_len(&body))) {
+ if (!ssl->s3->aead_read_ctx->Open(
+ out, type, version, ssl->s3->read_sequence,
+ MakeSpan(const_cast<uint8_t *>(CBS_data(&body)), CBS_len(&body)))) {
if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) {
ERR_clear_error();
goto skipped_data;
@@ -279,23 +288,25 @@
}
do {
- if (!CBS_get_last_u8(out, &type)) {
+ if (out->empty()) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
*out_alert = SSL_AD_DECRYPT_ERROR;
return ssl_open_record_error;
}
+ type = out->back();
+ *out = out->subspan(0, out->size() - 1);
} while (type == 0);
}
// Check the plaintext length.
- if (CBS_len(out) > SSL3_RT_MAX_PLAIN_LENGTH) {
+ if (out->size() > SSL3_RT_MAX_PLAIN_LENGTH) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
*out_alert = SSL_AD_RECORD_OVERFLOW;
return ssl_open_record_error;
}
// Limit the number of consecutive empty records.
- if (CBS_len(out) == 0) {
+ if (out->empty()) {
ssl->s3->empty_record_count++;
if (ssl->s3->empty_record_count > kMaxEmptyRecords) {
OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
@@ -310,14 +321,14 @@
if (type == SSL3_RT_ALERT) {
// Return end_of_early_data alerts as-is for the caller to process.
- if (CBS_len(out) == 2 &&
- CBS_data(out)[0] == SSL3_AL_WARNING &&
- CBS_data(out)[1] == TLS1_AD_END_OF_EARLY_DATA) {
+ if (out->size() == 2 &&
+ (*out)[0] == SSL3_AL_WARNING &&
+ (*out)[1] == TLS1_AD_END_OF_EARLY_DATA) {
*out_type = type;
return ssl_open_record_success;
}
- return ssl_process_alert(ssl, out_alert, CBS_data(out), CBS_len(out));
+ return ssl_process_alert(ssl, out_alert, *out);
}
ssl->s3->warning_alert_count = 0;
@@ -390,8 +401,8 @@
return 0;
}
- ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, out_prefix,
- SSL3_RT_HEADER_LENGTH);
+ ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER,
+ MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH));
return 1;
}
@@ -516,15 +527,15 @@
}
enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert,
- const uint8_t *in, size_t in_len) {
+ Span<const uint8_t> in) {
// Alerts records may not contain fragmented or multiple alerts.
- if (in_len != 2) {
+ if (in.size() != 2) {
*out_alert = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
return ssl_open_record_error;
}
- ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in, in_len);
+ ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in);
const uint8_t alert_level = in[0];
const uint8_t alert_descr = in[1];
@@ -534,13 +545,13 @@
if (alert_level == SSL3_AL_WARNING) {
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
- ssl->s3->recv_shutdown = ssl_shutdown_close_notify;
+ ssl->s3->read_shutdown = ssl_shutdown_close_notify;
return ssl_open_record_close_notify;
}
// Warning alerts do not exist in TLS 1.3.
if (ssl->s3->have_version &&
- ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ ssl_protocol_version(ssl) >= TLS1_3_VERSION) {
*out_alert = SSL_AD_DECODE_ERROR;
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
return ssl_open_record_error;
@@ -556,13 +567,14 @@
}
if (alert_level == SSL3_AL_FATAL) {
- ssl->s3->recv_shutdown = ssl_shutdown_fatal_alert;
+ ssl->s3->read_shutdown = ssl_shutdown_fatal_alert;
char tmp[16];
OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
- return ssl_open_record_fatal_alert;
+ *out_alert = 0; // No alert to send back to the peer.
+ return ssl_open_record_error;
}
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
@@ -577,16 +589,16 @@
// and below.
if (SSL_in_init(ssl) ||
SSL_is_dtls(ssl) ||
- ssl3_protocol_version(ssl) > TLS1_2_VERSION) {
+ ssl_protocol_version(ssl) > TLS1_2_VERSION) {
assert(false);
*out_alert = SSL_AD_INTERNAL_ERROR;
return OpenRecordResult::kError;
}
- CBS plaintext;
- uint8_t type;
+ Span<uint8_t> plaintext;
+ uint8_t type = 0;
const ssl_open_record_t result = tls_open_record(
- ssl, &type, &plaintext, out_record_len, out_alert, in.data(), in.size());
+ ssl, &type, &plaintext, out_record_len, out_alert, in);
switch (result) {
case ssl_open_record_success:
@@ -594,8 +606,7 @@
*out_alert = SSL_AD_UNEXPECTED_MESSAGE;
return OpenRecordResult::kError;
}
- *out = MakeSpan(
- const_cast<uint8_t*>(CBS_data(&plaintext)), CBS_len(&plaintext));
+ *out = plaintext;
return OpenRecordResult::kOK;
case ssl_open_record_discard:
return OpenRecordResult::kDiscard;
@@ -603,8 +614,6 @@
return OpenRecordResult::kIncompleteRecord;
case ssl_open_record_close_notify:
return OpenRecordResult::kAlertCloseNotify;
- case ssl_open_record_fatal_alert:
- return OpenRecordResult::kAlertFatal;
case ssl_open_record_error:
return OpenRecordResult::kError;
}
@@ -636,7 +645,7 @@
// and below.
if (SSL_in_init(ssl) ||
SSL_is_dtls(ssl) ||
- ssl3_protocol_version(ssl) > TLS1_2_VERSION) {
+ ssl_protocol_version(ssl) > TLS1_2_VERSION) {
assert(false);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return false;
diff --git a/src/util/bot/DEPS b/src/util/bot/DEPS
index ccaf75d..0d67e3d 100644
--- a/src/util/bot/DEPS
+++ b/src/util/bot/DEPS
@@ -14,21 +14,24 @@
vars = {
'chromium_git': 'https://chromium.googlesource.com',
+
+ 'checkout_clang': False,
+ 'checkout_fuzzer': False,
+ 'checkout_sde': False,
}
deps = {
- 'boringssl/util/bot/gyp':
- Var('chromium_git') + '/external/gyp.git' + '@' + 'eb296f67da078ec01f5e3a9ea9cdc6d26d680161',
-}
-
-deps_os = {
- 'android': {
- 'boringssl/util/bot/android_tools':
- Var('chromium_git') + '/android_tools.git' + '@' + 'e9d4018e149d50172ed462a7c21137aa915940ec',
+ 'boringssl/util/bot/android_tools': {
+ 'url': Var('chromium_git') + '/android_tools.git' + '@' + 'ca9dc7245b888c75307f0619e4a39fb46a82de66',
+ 'condition': 'checkout_android',
},
- 'unix': {
- 'boringssl/util/bot/libFuzzer':
- Var('chromium_git') + '/chromium/llvm-project/llvm/lib/Fuzzer.git' + '@' + '16f5f743c188c836d32cdaf349d5d3effb8a3518',
+
+ 'boringssl/util/bot/gyp':
+ Var('chromium_git') + '/external/gyp.git' + '@' + 'd61a9397e668fa9843c4aa7da9e79460fe590bfb',
+
+ 'boringssl/util/bot/libFuzzer': {
+ 'url': Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git' + '@' + '06fb50cc1f0197398c8a70658928a3b91912e68a',
+ 'condition': 'checkout_fuzzer',
},
}
@@ -41,6 +44,7 @@
{
'name': 'cmake_linux64',
'pattern': '.',
+ 'condition': 'host_os == "linux"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=linux*',
@@ -50,8 +54,19 @@
],
},
{
+ 'name': 'cmake_linux64_extract',
+ 'pattern': '.',
+ 'condition': 'host_os == "linux"',
+ 'action': [ 'python',
+ 'boringssl/util/bot/extract.py',
+ 'boringssl/util/bot/cmake-linux64.tar.gz',
+ 'boringssl/util/bot/cmake-linux64/',
+ ],
+ },
+ {
'name': 'cmake_mac',
'pattern': '.',
+ 'condition': 'host_os == "mac"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=darwin',
@@ -61,8 +76,19 @@
],
},
{
+ 'name': 'cmake_mac_extract',
+ 'pattern': '.',
+ 'condition': 'host_os == "mac"',
+ 'action': [ 'python',
+ 'boringssl/util/bot/extract.py',
+ 'boringssl/util/bot/cmake-mac.tar.gz',
+ 'boringssl/util/bot/cmake-mac/',
+ ],
+ },
+ {
'name': 'cmake_win32',
'pattern': '.',
+ 'condition': 'host_os == "win"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=win32',
@@ -72,8 +98,19 @@
],
},
{
+ 'name': 'cmake_win32_extract',
+ 'pattern': '.',
+ 'condition': 'host_os == "win"',
+ 'action': [ 'python',
+ 'boringssl/util/bot/extract.py',
+ 'boringssl/util/bot/cmake-win32.zip',
+ 'boringssl/util/bot/cmake-win32/',
+ ],
+ },
+ {
'name': 'perl_win32',
'pattern': '.',
+ 'condition': 'host_os == "win"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=win32',
@@ -83,8 +120,20 @@
],
},
{
+ 'name': 'perl_win32_extract',
+ 'pattern': '.',
+ 'condition': 'host_os == "win"',
+ 'action': [ 'python',
+ 'boringssl/util/bot/extract.py',
+ '--no-prefix',
+ 'boringssl/util/bot/perl-win32.zip',
+ 'boringssl/util/bot/perl-win32/',
+ ],
+ },
+ {
'name': 'yasm_win32',
'pattern': '.',
+ 'condition': 'host_os == "win"',
'action': [ 'download_from_google_storage',
'--no_resume',
'--platform=win32',
@@ -96,6 +145,7 @@
{
'name': 'win_toolchain',
'pattern': '.',
+ 'condition': 'host_os == "win"',
'action': [ 'python',
'boringssl/util/bot/vs_toolchain.py',
'update',
@@ -104,45 +154,29 @@
{
'name': 'clang',
'pattern': '.',
+ 'condition': 'checkout_clang',
'action': [ 'python',
'boringssl/util/bot/update_clang.py',
],
},
{
- 'name': 'cmake_linux64_extract',
+ 'name': 'sde_linux64',
'pattern': '.',
- 'action': [ 'python',
- 'boringssl/util/bot/extract.py',
- 'boringssl/util/bot/cmake-linux64.tar.gz',
- 'boringssl/util/bot/cmake-linux64/',
+ 'condition': 'checkout_sde and host_os == "linux"',
+ 'action': [ 'download_from_google_storage',
+ '--no_resume',
+ '--bucket', 'chrome-boringssl-sde',
+ '-s', 'boringssl/util/bot/sde-linux64.tar.bz2.sha1'
],
},
{
- 'name': 'cmake_mac_extract',
+ 'name': 'sde_linux64_extract',
'pattern': '.',
+ 'condition': 'checkout_sde and host_os == "linux"',
'action': [ 'python',
'boringssl/util/bot/extract.py',
- 'boringssl/util/bot/cmake-mac.tar.gz',
- 'boringssl/util/bot/cmake-mac/',
- ],
- },
- {
- 'name': 'cmake_win32_extract',
- 'pattern': '.',
- 'action': [ 'python',
- 'boringssl/util/bot/extract.py',
- 'boringssl/util/bot/cmake-win32.zip',
- 'boringssl/util/bot/cmake-win32/',
- ],
- },
- {
- 'name': 'perl_win32_extract',
- 'pattern': '.',
- 'action': [ 'python',
- 'boringssl/util/bot/extract.py',
- '--no-prefix',
- 'boringssl/util/bot/perl-win32.zip',
- 'boringssl/util/bot/perl-win32/',
+ 'boringssl/util/bot/sde-linux64.tar.bz2',
+ 'boringssl/util/bot/sde-linux64/',
],
},
]
diff --git a/src/util/bot/UPDATING b/src/util/bot/UPDATING
index fee8749..a9915ab 100644
--- a/src/util/bot/UPDATING
+++ b/src/util/bot/UPDATING
@@ -41,11 +41,11 @@
The current revision is cmake-3.5.0-win32-x86.zip.
-perl-win32.zip: Update to the latest 32-bit prebuilt "PortableZip" edition of
+perl-win32.zip: Update to the latest 32-bit prebuilt "Portable" edition of
Strawberry Perl, found at http://strawberryperl.com/releases.html. The
download will be named strawberry-perl-VERSION-32bit-portable.zip.
- The current revision is strawberry-perl-5.22.1.2-32bit-portable.zip.
+ The current revision is strawberry-perl-5.26.1.1-32bit-portable.zip.
yasm-win32.exe: Update to the appropriate release of Yasm. Use the same version
as Chromium, found at
@@ -62,4 +62,4 @@
upload_to_google_storage.py -b chrome-boringssl-sde sde-linux64.tar.bz2
-The current revision is sde-external-8.5.0-2017-06-08-lin.tar.bz2.
+The current revision is sde-external-8.9.0-2017-08-06-lin.tar.bz2.
diff --git a/src/util/bot/go/bootstrap.py b/src/util/bot/go/bootstrap.py
index 75bacf3..86335aa 100755
--- a/src/util/bot/go/bootstrap.py
+++ b/src/util/bot/go/bootstrap.py
@@ -45,7 +45,7 @@
EXE_SFX = '.exe' if sys.platform == 'win32' else ''
# Pinned version of Go toolset to download.
-TOOLSET_VERSION = 'go1.9'
+TOOLSET_VERSION = 'go1.9.1'
# Platform dependent portion of a download URL. See http://golang.org/dl/.
TOOLSET_VARIANTS = {
diff --git a/src/util/bot/perl-win32.zip.sha1 b/src/util/bot/perl-win32.zip.sha1
index 8874fbb..a185995 100644
--- a/src/util/bot/perl-win32.zip.sha1
+++ b/src/util/bot/perl-win32.zip.sha1
@@ -1 +1 @@
-3db2b4964d56f6e23cc48ced40a6cee05419a0af
\ No newline at end of file
+1245124da188c699fb41c4b5a60622bd0d363106
\ No newline at end of file
diff --git a/src/util/bot/sde-linux64.tar.bz2.sha1 b/src/util/bot/sde-linux64.tar.bz2.sha1
index 1598a95..cb35cf8 100644
--- a/src/util/bot/sde-linux64.tar.bz2.sha1
+++ b/src/util/bot/sde-linux64.tar.bz2.sha1
@@ -1 +1 @@
-2b13efc6fb26fcee614a8c4534b0ffa71c50a2a5
\ No newline at end of file
+dcf00ebdef4810ffd4ce0c8636dcf99d5ad760c9
\ No newline at end of file
diff --git a/src/util/bot/update_clang.py b/src/util/bot/update_clang.py
index 9595c0a..3164750 100644
--- a/src/util/bot/update_clang.py
+++ b/src/util/bot/update_clang.py
@@ -19,15 +19,15 @@
# CLANG_REVISION and CLANG_SUB_REVISION determine the build of clang
# to use. These should be synced with tools/clang/scripts/update.py in
# Chromium.
-CLANG_REVISION = '310694'
-CLANG_SUB_REVISION=2
+CLANG_REVISION = '313786'
+CLANG_SUB_REVISION=1
PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
# Path constants. (All of these should be absolute paths.)
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
LLVM_BUILD_DIR = os.path.join(THIS_DIR, 'llvm-build')
-STAMP_FILE = os.path.join(THIS_DIR, 'cr_build_revision')
+STAMP_FILE = os.path.join(LLVM_BUILD_DIR, 'cr_build_revision')
# URL for pre-built binaries.
CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE',
diff --git a/src/util/bot/vs_toolchain.py b/src/util/bot/vs_toolchain.py
index cf7b5d0..64da79a 100644
--- a/src/util/bot/vs_toolchain.py
+++ b/src/util/bot/vs_toolchain.py
@@ -87,8 +87,8 @@
# Update 3 final with 10.0.15063.468 SDK and no vctip.exe.
return ['f53e4598951162bad6330f7a167486c7ae5db1e5']
if env_version == '2017':
- # VS 2017 Update 3.2 with 10.0.15063.468 SDK.
- return ['9bc7ccbf9f4bd50d4a3bd185e8ca94ff1618de0b']
+ # VS 2017 Update 3.2 with 10.0.15063.468 SDK and patched setenv.cmd.
+ return ['a9e1098bba66d2acccc377d5ee81265910f29272']
raise Exception('Unsupported VS version %s' % env_version)
diff --git a/src/util/doc.config b/src/util/doc.config
index f7e8baa..5bee1b5 100644
--- a/src/util/doc.config
+++ b/src/util/doc.config
@@ -23,6 +23,7 @@
"Headers": [
"include/openssl/aes.h",
"include/openssl/bn.h",
+ "include/openssl/chacha.h",
"include/openssl/cmac.h",
"include/openssl/curve25519.h",
"include/openssl/des.h",