external/boringssl: Sync to 3ef7697ed30f28367395a5aafb57a12a19906d96.
am: 95add82835
Change-Id: I479f3ead51ffd6fb4cc326a31409a38928f51b34
diff --git a/BORINGSSL_REVISION b/BORINGSSL_REVISION
index dff0ac7..9fe48a4 100644
--- a/BORINGSSL_REVISION
+++ b/BORINGSSL_REVISION
@@ -1 +1 @@
-3cbdc34619daafb9f8527fb9dd27afc8ee7dcf19
+3ef7697ed30f28367395a5aafb57a12a19906d96
diff --git a/UPDATING b/UPDATING
old mode 100644
new mode 100755
index c7019e4..f818987
--- a/UPDATING
+++ b/UPDATING
@@ -1,9 +1,24 @@
+#!/bin/sh
+
+set -xe
+
+old_revision=$(cat BORINGSSL_REVISION)
rm -Rf src
git clone https://boringssl.googlesource.com/boringssl src
cd src
-git show -s --pretty=%H > ../BORINGSSL_REVISION
+new_revision=$(git show -s --pretty=%H)
cd ..
+echo ${new_revision} > BORINGSSL_REVISION
+
rm -Rf src/.git
rm -Rf src/fuzz
rm -Rf linux-aarch64/ linux-arm/ linux-x86/ linux-x86_64/ mac-x86/ mac-x86_64/ win-x86_64/ win-x86/
python src/util/generate_build_files.py android
+
+git add .
+git commit -m "external/boringssl: Sync to ${new_revision}.
+
+This includes the following changes:
+
+https://boringssl.googlesource.com/boringssl/+log/${old_revision}..${new_revision}
+"
diff --git a/err_data.c b/err_data.c
index 6b0b8cc..001145d 100644
--- a/err_data.c
+++ b/err_data.c
@@ -178,42 +178,42 @@
0x28340c19,
0x283480ac,
0x283500ea,
- 0x2c3228da,
- 0x2c32a8e8,
- 0x2c3328fa,
- 0x2c33a90c,
- 0x2c342920,
- 0x2c34a932,
- 0x2c35294d,
- 0x2c35a95f,
- 0x2c362972,
+ 0x2c322910,
+ 0x2c32a91e,
+ 0x2c332930,
+ 0x2c33a942,
+ 0x2c342956,
+ 0x2c34a968,
+ 0x2c352983,
+ 0x2c35a995,
+ 0x2c3629a8,
0x2c36832d,
- 0x2c37297f,
- 0x2c37a991,
- 0x2c3829a4,
- 0x2c38a9bb,
- 0x2c3929c9,
- 0x2c39a9d9,
- 0x2c3a29eb,
- 0x2c3aa9ff,
- 0x2c3b2a10,
- 0x2c3baa2f,
- 0x2c3c2a43,
- 0x2c3caa59,
- 0x2c3d2a72,
- 0x2c3daa8f,
- 0x2c3e2aa0,
- 0x2c3eaaae,
- 0x2c3f2ac6,
- 0x2c3faade,
- 0x2c402aeb,
+ 0x2c3729b5,
+ 0x2c37a9c7,
+ 0x2c3829da,
+ 0x2c38a9f1,
+ 0x2c3929ff,
+ 0x2c39aa0f,
+ 0x2c3a2a21,
+ 0x2c3aaa35,
+ 0x2c3b2a46,
+ 0x2c3baa65,
+ 0x2c3c2a79,
+ 0x2c3caa8f,
+ 0x2c3d2aa8,
+ 0x2c3daac5,
+ 0x2c3e2ad6,
+ 0x2c3eaae4,
+ 0x2c3f2afc,
+ 0x2c3fab14,
+ 0x2c402b21,
0x2c4090e7,
- 0x2c412afc,
- 0x2c41ab0f,
+ 0x2c412b32,
+ 0x2c41ab45,
0x2c4210c0,
- 0x2c42ab20,
+ 0x2c42ab56,
0x2c430720,
- 0x2c43aa21,
+ 0x2c43aa57,
0x30320000,
0x30328015,
0x3033001f,
@@ -461,42 +461,42 @@
0x406b2370,
0x406ba393,
0x406c23a9,
- 0x406ca5d5,
- 0x406d2604,
- 0x406da62c,
- 0x406e265a,
- 0x406ea672,
- 0x406f2691,
- 0x406fa6a6,
- 0x407026b9,
- 0x4070a6d6,
+ 0x406ca60b,
+ 0x406d263a,
+ 0x406da662,
+ 0x406e2690,
+ 0x406ea6a8,
+ 0x406f26c7,
+ 0x406fa6dc,
+ 0x407026ef,
+ 0x4070a70c,
0x40710800,
- 0x4071a6e8,
- 0x407226fb,
- 0x4072a714,
- 0x4073272c,
+ 0x4071a71e,
+ 0x40722731,
+ 0x4072a74a,
+ 0x40732762,
0x4073936d,
- 0x40742740,
- 0x4074a75a,
- 0x4075276b,
- 0x4075a77f,
- 0x4076278d,
+ 0x40742776,
+ 0x4074a790,
+ 0x407527a1,
+ 0x4075a7b5,
+ 0x407627c3,
0x407691aa,
- 0x407727b2,
- 0x4077a7d4,
- 0x407827ef,
- 0x4078a828,
- 0x4079283f,
- 0x4079a855,
- 0x407a2861,
- 0x407aa874,
- 0x407b2889,
- 0x407ba89b,
- 0x407c28b0,
- 0x407ca8b9,
+ 0x407727e8,
+ 0x4077a80a,
+ 0x40782825,
+ 0x4078a85e,
+ 0x40792875,
+ 0x4079a88b,
+ 0x407a2897,
+ 0x407aa8aa,
+ 0x407b28bf,
+ 0x407ba8d1,
+ 0x407c28e6,
+ 0x407ca8ef,
0x407d2162,
0x407d9c57,
- 0x407e2804,
+ 0x407e283a,
0x407e9e16,
0x407f1a67,
0x407f9887,
@@ -504,7 +504,7 @@
0x40809a8f,
0x40811cd9,
0x40819c08,
- 0x40822645,
+ 0x4082267b,
0x4082986d,
0x40831df1,
0x4083a038,
@@ -536,11 +536,13 @@
0x421f2453,
0x42212520,
0x422624b3,
- 0x422b25b9,
- 0x422ba582,
- 0x422c25a1,
+ 0x422b25ef,
+ 0x422ba59d,
+ 0x422c25d7,
0x422ca55c,
0x422d253b,
+ 0x422da5bc,
+ 0x422e2582,
0x4432072b,
0x4432873a,
0x44330746,
@@ -583,69 +585,69 @@
0x4c3d136d,
0x4c3d937c,
0x4c3e1389,
- 0x50322b32,
- 0x5032ab41,
- 0x50332b4c,
- 0x5033ab5c,
- 0x50342b75,
- 0x5034ab8f,
- 0x50352b9d,
- 0x5035abb3,
- 0x50362bc5,
- 0x5036abdb,
- 0x50372bf4,
- 0x5037ac07,
- 0x50382c1f,
- 0x5038ac30,
- 0x50392c45,
- 0x5039ac59,
- 0x503a2c79,
- 0x503aac8f,
- 0x503b2ca7,
- 0x503bacb9,
- 0x503c2cd5,
- 0x503cacec,
- 0x503d2d05,
- 0x503dad1b,
- 0x503e2d28,
- 0x503ead3e,
- 0x503f2d50,
+ 0x50322b68,
+ 0x5032ab77,
+ 0x50332b82,
+ 0x5033ab92,
+ 0x50342bab,
+ 0x5034abc5,
+ 0x50352bd3,
+ 0x5035abe9,
+ 0x50362bfb,
+ 0x5036ac11,
+ 0x50372c2a,
+ 0x5037ac3d,
+ 0x50382c55,
+ 0x5038ac66,
+ 0x50392c7b,
+ 0x5039ac8f,
+ 0x503a2caf,
+ 0x503aacc5,
+ 0x503b2cdd,
+ 0x503bacef,
+ 0x503c2d0b,
+ 0x503cad22,
+ 0x503d2d3b,
+ 0x503dad51,
+ 0x503e2d5e,
+ 0x503ead74,
+ 0x503f2d86,
0x503f8382,
- 0x50402d63,
- 0x5040ad73,
- 0x50412d8d,
- 0x5041ad9c,
- 0x50422db6,
- 0x5042add3,
- 0x50432de3,
- 0x5043adf3,
- 0x50442e02,
+ 0x50402d99,
+ 0x5040ada9,
+ 0x50412dc3,
+ 0x5041add2,
+ 0x50422dec,
+ 0x5042ae09,
+ 0x50432e19,
+ 0x5043ae29,
+ 0x50442e38,
0x5044843f,
- 0x50452e16,
- 0x5045ae34,
- 0x50462e47,
- 0x5046ae5d,
- 0x50472e6f,
- 0x5047ae84,
- 0x50482eaa,
- 0x5048aeb8,
- 0x50492ecb,
- 0x5049aee0,
- 0x504a2ef6,
- 0x504aaf06,
- 0x504b2f26,
- 0x504baf39,
- 0x504c2f5c,
- 0x504caf8a,
- 0x504d2f9c,
- 0x504dafb9,
- 0x504e2fd4,
- 0x504eaff0,
- 0x504f3002,
- 0x504fb019,
- 0x50503028,
+ 0x50452e4c,
+ 0x5045ae6a,
+ 0x50462e7d,
+ 0x5046ae93,
+ 0x50472ea5,
+ 0x5047aeba,
+ 0x50482ee0,
+ 0x5048aeee,
+ 0x50492f01,
+ 0x5049af16,
+ 0x504a2f2c,
+ 0x504aaf3c,
+ 0x504b2f5c,
+ 0x504baf6f,
+ 0x504c2f92,
+ 0x504cafc0,
+ 0x504d2fd2,
+ 0x504dafef,
+ 0x504e300a,
+ 0x504eb026,
+ 0x504f3038,
+ 0x504fb04f,
+ 0x5050305e,
0x505086ef,
- 0x5051303b,
+ 0x50513071,
0x58320ec9,
0x68320e8b,
0x68328c25,
@@ -1141,7 +1143,9 @@
"TLSV1_ALERT_USER_CANCELLED\0"
"TLSV1_BAD_CERTIFICATE_HASH_VALUE\0"
"TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\0"
+ "TLSV1_CERTIFICATE_REQUIRED\0"
"TLSV1_CERTIFICATE_UNOBTAINABLE\0"
+ "TLSV1_UNKNOWN_PSK_IDENTITY\0"
"TLSV1_UNRECOGNIZED_NAME\0"
"TLSV1_UNSUPPORTED_EXTENSION\0"
"TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0"
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3d1ea78..8ab4066 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -126,7 +126,7 @@
endif()
add_definitions(-DBORINGSSL_UNSAFE_FUZZER_MODE)
- set(RUNNER_ARGS "-fuzzer")
+ set(RUNNER_ARGS "-fuzzer" "-deterministic" "-shim-config" "fuzzer_mode.json")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-coverage=edge,indirect-calls,8bit-counters")
diff --git a/src/crypto/asn1/tasn_utl.c b/src/crypto/asn1/tasn_utl.c
index 55037a1..d409cfa 100644
--- a/src/crypto/asn1/tasn_utl.c
+++ b/src/crypto/asn1/tasn_utl.c
@@ -70,7 +70,7 @@
/* Utility functions for manipulating fields and offsets */
/* Add 'offset' to 'addr' */
-#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
+#define offset2ptr(addr, offset) (void *)(((char *)(addr)) + (offset))
/* Given an ASN1_ITEM CHOICE type return the selector value */
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) {
diff --git a/src/crypto/bio/socket.c b/src/crypto/bio/socket.c
index 0520c3e..f70ea92 100644
--- a/src/crypto/bio/socket.c
+++ b/src/crypto/bio/socket.c
@@ -67,7 +67,7 @@
#include <winsock2.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
-#pragma comment(lib, "Ws2_32.lib")
+OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
#endif
#include "internal.h"
diff --git a/src/crypto/bn/asm/x86_64-gcc.c b/src/crypto/bn/asm/x86_64-gcc.c
index 214c12a..177d335 100644
--- a/src/crypto/bn/asm/x86_64-gcc.c
+++ b/src/crypto/bn/asm/x86_64-gcc.c
@@ -80,7 +80,7 @@
: "+m"(r), "+d"(high) \
: "r"(carry), "g"(0) \
: "cc"); \
- carry = high; \
+ (carry) = high; \
} while (0)
#define mul(r, a, word, carry) \
@@ -91,7 +91,8 @@
: "+r"(carry), "+d"(high) \
: "a"(low), "g"(0) \
: "cc"); \
- (r) = carry, carry = high; \
+ (r) = (carry); \
+ (carry) = high; \
} while (0)
#undef sqr
#define sqr(r0, r1, a) asm("mulq %2" : "=a"(r0), "=d"(r1) : "a"(a) : "cc");
@@ -256,14 +257,14 @@
: "cc"); \
} while (0)
-#define sqr_add_c(a, i, c0, c1, c2) \
- do { \
- BN_ULONG t1, t2; \
- asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"(a[i]) : "cc"); \
- asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
- : "+r"(c0), "+r"(c1), "+r"(c2) \
- : "r"(t1), "r"(t2), "g"(0) \
- : "cc"); \
+#define sqr_add_c(a, i, c0, c1, c2) \
+ do { \
+ BN_ULONG t1, t2; \
+ asm("mulq %2" : "=a"(t1), "=d"(t2) : "a"((a)[i]) : "cc"); \
+ asm("addq %3,%0; adcq %4,%1; adcq %5,%2" \
+ : "+r"(c0), "+r"(c1), "+r"(c2) \
+ : "r"(t1), "r"(t2), "g"(0) \
+ : "cc"); \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
diff --git a/src/crypto/bn/generic.c b/src/crypto/bn/generic.c
index f552d99..de77cc5 100644
--- a/src/crypto/bn/generic.c
+++ b/src/crypto/bn/generic.c
@@ -67,34 +67,34 @@
!(defined(OPENSSL_X86) || (defined(OPENSSL_X86_64) && defined(__GNUC__)))
#ifdef BN_ULLONG
-#define mul_add(r, a, w, c) \
- { \
- BN_ULLONG t; \
- t = (BN_ULLONG)w * (a) + (r) + (c); \
- (r) = Lw(t); \
- (c) = Hw(t); \
- }
+#define mul_add(r, a, w, c) \
+ do { \
+ BN_ULLONG t; \
+ t = (BN_ULLONG)(w) * (a) + (r) + (c); \
+ (r) = Lw(t); \
+ (c) = Hw(t); \
+ } while (0)
-#define mul(r, a, w, c) \
- { \
- BN_ULLONG t; \
- t = (BN_ULLONG)w * (a) + (c); \
- (r) = Lw(t); \
- (c) = Hw(t); \
- }
+#define mul(r, a, w, c) \
+ do { \
+ BN_ULLONG t; \
+ t = (BN_ULLONG)(w) * (a) + (c); \
+ (r) = Lw(t); \
+ (c) = Hw(t); \
+ } while (0)
#define sqr(r0, r1, a) \
- { \
+ do { \
BN_ULLONG t; \
t = (BN_ULLONG)(a) * (a); \
(r0) = Lw(t); \
(r1) = Hw(t); \
- }
+ } while (0)
#else
#define mul_add(r, a, w, c) \
- { \
+ do { \
BN_ULONG high, low, ret, tmp = (a); \
ret = (r); \
BN_UMULT_LOHI(low, high, w, tmp); \
@@ -104,23 +104,23 @@
ret += low; \
(c) += (ret < low) ? 1 : 0; \
(r) = ret; \
- }
+ } while (0)
#define mul(r, a, w, c) \
- { \
+ do { \
BN_ULONG high, low, ret, ta = (a); \
BN_UMULT_LOHI(low, high, w, ta); \
ret = low + (c); \
(c) = high; \
(c) += (ret < low) ? 1 : 0; \
(r) = ret; \
- }
+ } while (0)
#define sqr(r0, r1, a) \
- { \
+ do { \
BN_ULONG tmp = (a); \
BN_UMULT_LOHI(r0, r1, tmp, tmp); \
- }
+ } while (0)
#endif /* !BN_ULLONG */
@@ -369,42 +369,46 @@
do { \
BN_ULONG hi; \
BN_ULLONG t = (BN_ULLONG)(a) * (b); \
- t += c0; /* no carry */ \
- c0 = (BN_ULONG)Lw(t); \
+ t += (c0); /* no carry */ \
+ (c0) = (BN_ULONG)Lw(t); \
hi = (BN_ULONG)Hw(t); \
- c1 = (c1 + hi) & BN_MASK2; \
- if (c1 < hi) \
- c2++; \
+ (c1) = ((c1) + (hi)) & BN_MASK2; \
+ if ((c1) < hi) { \
+ (c2)++; \
+ } \
} while (0)
-#define mul_add_c2(a, b, c0, c1, c2) \
- do { \
- BN_ULONG hi; \
- BN_ULLONG t = (BN_ULLONG)(a) * (b); \
- BN_ULLONG tt = t + c0; /* no carry */ \
- c0 = (BN_ULONG)Lw(tt); \
- hi = (BN_ULONG)Hw(tt); \
- c1 = (c1 + hi) & BN_MASK2; \
- if (c1 < hi) \
- c2++; \
- t += c0; /* no carry */ \
- c0 = (BN_ULONG)Lw(t); \
- hi = (BN_ULONG)Hw(t); \
- c1 = (c1 + hi) & BN_MASK2; \
- if (c1 < hi) \
- c2++; \
+#define mul_add_c2(a, b, c0, c1, c2) \
+ do { \
+ BN_ULONG hi; \
+ BN_ULLONG t = (BN_ULLONG)(a) * (b); \
+ BN_ULLONG tt = t + (c0); /* no carry */ \
+ (c0) = (BN_ULONG)Lw(tt); \
+ hi = (BN_ULONG)Hw(tt); \
+ (c1) = ((c1) + hi) & BN_MASK2; \
+ if ((c1) < hi) { \
+ (c2)++; \
+ } \
+ t += (c0); /* no carry */ \
+ (c0) = (BN_ULONG)Lw(t); \
+ hi = (BN_ULONG)Hw(t); \
+ (c1) = ((c1) + hi) & BN_MASK2; \
+ if ((c1) < hi) { \
+ (c2)++; \
+ } \
} while (0)
-#define sqr_add_c(a, i, c0, c1, c2) \
- do { \
- BN_ULONG hi; \
- BN_ULLONG t = (BN_ULLONG)a[i] * a[i]; \
- t += c0; /* no carry */ \
- c0 = (BN_ULONG)Lw(t); \
- hi = (BN_ULONG)Hw(t); \
- c1 = (c1 + hi) & BN_MASK2; \
- if (c1 < hi) \
- c2++; \
+#define sqr_add_c(a, i, c0, c1, c2) \
+ do { \
+ BN_ULONG hi; \
+ BN_ULLONG t = (BN_ULLONG)(a)[i] * (a)[i]; \
+ t += (c0); /* no carry */ \
+ (c0) = (BN_ULONG)Lw(t); \
+ hi = (BN_ULONG)Hw(t); \
+ (c1) = ((c1) + hi) & BN_MASK2; \
+ if ((c1) < hi) { \
+ (c2)++; \
+ } \
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
@@ -418,10 +422,10 @@
BN_ULONG ta = (a), tb = (b); \
BN_ULONG lo, hi; \
BN_UMULT_LOHI(lo, hi, ta, tb); \
- c0 += lo; \
- hi += (c0 < lo) ? 1 : 0; \
- c1 += hi; \
- c2 += (c1 < hi) ? 1 : 0; \
+ (c0) += lo; \
+ hi += ((c0) < lo) ? 1 : 0; \
+ (c1) += hi; \
+ (c2) += ((c1) < hi) ? 1 : 0; \
} while (0)
#define mul_add_c2(a, b, c0, c1, c2) \
@@ -429,14 +433,14 @@
BN_ULONG ta = (a), tb = (b); \
BN_ULONG lo, hi, tt; \
BN_UMULT_LOHI(lo, hi, ta, tb); \
- c0 += lo; \
- tt = hi + ((c0 < lo) ? 1 : 0); \
- c1 += tt; \
- c2 += (c1 < tt) ? 1 : 0; \
- c0 += lo; \
+ (c0) += lo; \
+ tt = hi + (((c0) < lo) ? 1 : 0); \
+ (c1) += tt; \
+ (c2) += ((c1) < tt) ? 1 : 0; \
+ (c0) += lo; \
hi += (c0 < lo) ? 1 : 0; \
- c1 += hi; \
- c2 += (c1 < hi) ? 1 : 0; \
+ (c1) += hi; \
+ (c2) += ((c1) < hi) ? 1 : 0; \
} while (0)
#define sqr_add_c(a, i, c0, c1, c2) \
@@ -444,10 +448,10 @@
BN_ULONG ta = (a)[i]; \
BN_ULONG lo, hi; \
BN_UMULT_LOHI(lo, hi, ta, ta); \
- c0 += lo; \
+ (c0) += lo; \
hi += (c0 < lo) ? 1 : 0; \
- c1 += hi; \
- c2 += (c1 < hi) ? 1 : 0; \
+ (c1) += hi; \
+ (c2) += ((c1) < hi) ? 1 : 0; \
} while (0)
#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2)
diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h
index aafd175..99fc306 100644
--- a/src/crypto/bn/internal.h
+++ b/src/crypto/bn/internal.h
@@ -188,10 +188,10 @@
#endif
-#define STATIC_BIGNUM(x) \
- { \
- (BN_ULONG *)x, sizeof(x) / sizeof(BN_ULONG), \
- sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
+#define STATIC_BIGNUM(x) \
+ { \
+ (BN_ULONG *)(x), sizeof(x) / sizeof(BN_ULONG), \
+ sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \
}
#if defined(BN_ULLONG)
diff --git a/src/crypto/cipher/e_rc2.c b/src/crypto/cipher/e_rc2.c
index 67418d5..e1b4301 100644
--- a/src/crypto/cipher/e_rc2.c
+++ b/src/crypto/cipher/e_rc2.c
@@ -60,63 +60,68 @@
#include "internal.h"
-#define c2l(c, l) \
- (l = ((uint32_t)(*((c)++))), l |= ((uint32_t)(*((c)++))) << 8L, \
- l |= ((uint32_t)(*((c)++))) << 16L, \
- l |= ((uint32_t)(*((c)++))) << 24L)
+#define c2l(c, l) \
+ do { \
+ (l) = ((uint32_t)(*((c)++))); \
+ (l) |= ((uint32_t)(*((c)++))) << 8L; \
+ (l) |= ((uint32_t)(*((c)++))) << 16L; \
+ (l) |= ((uint32_t)(*((c)++))) << 24L; \
+ } while (0)
-#define c2ln(c, l1, l2, n) \
- { \
- c += n; \
- l1 = l2 = 0; \
- switch (n) { \
- case 8: \
- l2 = ((uint32_t)(*(--(c)))) << 24L; \
- case 7: \
- l2 |= ((uint32_t)(*(--(c)))) << 16L; \
- case 6: \
- l2 |= ((uint32_t)(*(--(c)))) << 8L; \
- case 5: \
- l2 |= ((uint32_t)(*(--(c)))); \
- case 4: \
- l1 = ((uint32_t)(*(--(c)))) << 24L; \
- case 3: \
- l1 |= ((uint32_t)(*(--(c)))) << 16L; \
- case 2: \
- l1 |= ((uint32_t)(*(--(c)))) << 8L; \
- case 1: \
- l1 |= ((uint32_t)(*(--(c)))); \
- } \
- }
+#define c2ln(c, l1, l2, n) \
+ do { \
+ (c) += (n); \
+ (l1) = (l2) = 0; \
+ switch (n) { \
+ case 8: \
+ (l2) = ((uint32_t)(*(--(c)))) << 24L; \
+ case 7: \
+ (l2) |= ((uint32_t)(*(--(c)))) << 16L; \
+ case 6: \
+ (l2) |= ((uint32_t)(*(--(c)))) << 8L; \
+ case 5: \
+ (l2) |= ((uint32_t)(*(--(c)))); \
+ case 4: \
+ (l1) = ((uint32_t)(*(--(c)))) << 24L; \
+ case 3: \
+ (l1) |= ((uint32_t)(*(--(c)))) << 16L; \
+ case 2: \
+ (l1) |= ((uint32_t)(*(--(c)))) << 8L; \
+ case 1: \
+ (l1) |= ((uint32_t)(*(--(c)))); \
+ } \
+ } while (0)
-#define l2c(l, c) \
- (*((c)++) = (uint8_t)(((l)) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 8L) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 16L) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 24L) & 0xff))
+#define l2c(l, c) \
+ do { \
+ *((c)++) = (uint8_t)(((l)) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 8L) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 16L) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 24L) & 0xff); \
+ } while (0)
-#define l2cn(l1, l2, c, n) \
- { \
- c += n; \
- switch (n) { \
- case 8: \
+#define l2cn(l1, l2, c, n) \
+ do { \
+ (c) += (n); \
+ switch (n) { \
+ case 8: \
*(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \
- case 7: \
+ case 7: \
*(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \
- case 6: \
+ case 6: \
*(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \
- case 5: \
+ case 5: \
*(--(c)) = (uint8_t)(((l2)) & 0xff); \
- case 4: \
+ case 4: \
*(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \
- case 3: \
+ case 3: \
*(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \
- case 2: \
+ case 2: \
*(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \
- case 1: \
+ case 1: \
*(--(c)) = (uint8_t)(((l1)) & 0xff); \
- } \
- }
+ } \
+ } while (0)
typedef struct rc2_key_st { uint16_t data[64]; } RC2_KEY;
diff --git a/src/crypto/cipher/tls_cbc.c b/src/crypto/cipher/tls_cbc.c
index 02d6745..dd6ab8c 100644
--- a/src/crypto/cipher/tls_cbc.c
+++ b/src/crypto/cipher/tls_cbc.c
@@ -264,23 +264,27 @@
/* u32toBE serialises an unsigned, 32-bit number (n) as four bytes at (p) in
* big-endian order. The value of p is advanced by four. */
-#define u32toBE(n, p) \
- (*((p)++)=(uint8_t)(n>>24), \
- *((p)++)=(uint8_t)(n>>16), \
- *((p)++)=(uint8_t)(n>>8), \
- *((p)++)=(uint8_t)(n))
+#define u32toBE(n, p) \
+ do { \
+ *((p)++) = (uint8_t)((n) >> 24); \
+ *((p)++) = (uint8_t)((n) >> 16); \
+ *((p)++) = (uint8_t)((n) >> 8); \
+ *((p)++) = (uint8_t)((n)); \
+ } while (0)
/* u64toBE serialises an unsigned, 64-bit number (n) as eight bytes at (p) in
* big-endian order. The value of p is advanced by eight. */
-#define u64toBE(n, p) \
- (*((p)++)=(uint8_t)(n>>56), \
- *((p)++)=(uint8_t)(n>>48), \
- *((p)++)=(uint8_t)(n>>40), \
- *((p)++)=(uint8_t)(n>>32), \
- *((p)++)=(uint8_t)(n>>24), \
- *((p)++)=(uint8_t)(n>>16), \
- *((p)++)=(uint8_t)(n>>8), \
- *((p)++)=(uint8_t)(n))
+#define u64toBE(n, p) \
+ do { \
+ *((p)++) = (uint8_t)((n) >> 56); \
+ *((p)++) = (uint8_t)((n) >> 48); \
+ *((p)++) = (uint8_t)((n) >> 40); \
+ *((p)++) = (uint8_t)((n) >> 32); \
+ *((p)++) = (uint8_t)((n) >> 24); \
+ *((p)++) = (uint8_t)((n) >> 16); \
+ *((p)++) = (uint8_t)((n) >> 8); \
+ *((p)++) = (uint8_t)((n)); \
+ } while (0)
/* These functions serialize the state of a hash and thus perform the standard
* "final" operation without adding the padding and length that such a function
diff --git a/src/crypto/des/des.c b/src/crypto/des/des.c
index 1d27ebe..cada7d1 100644
--- a/src/crypto/des/des.c
+++ b/src/crypto/des/des.c
@@ -291,7 +291,7 @@
#define HPERM_OP(a, t, n, m) \
((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \
- (a) = (a) ^ (t) ^ (t >> (16 - (n))))
+ (a) = (a) ^ (t) ^ ((t) >> (16 - (n))))
void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) {
static const int shifts2[16] = {0, 0, 1, 1, 1, 1, 1, 1,
diff --git a/src/crypto/des/internal.h b/src/crypto/des/internal.h
index 00b4558..21eb933 100644
--- a/src/crypto/des/internal.h
+++ b/src/crypto/des/internal.h
@@ -64,45 +64,51 @@
#endif
-#define c2l(c, l) \
- (l = ((uint32_t)(*((c)++))), l |= ((uint32_t)(*((c)++))) << 8L, \
- l |= ((uint32_t)(*((c)++))) << 16L, l |= ((uint32_t)(*((c)++))) << 24L)
+#define c2l(c, l) \
+ do { \
+ (l) = ((uint32_t)(*((c)++))); \
+ (l) |= ((uint32_t)(*((c)++))) << 8L; \
+ (l) |= ((uint32_t)(*((c)++))) << 16L; \
+ (l) |= ((uint32_t)(*((c)++))) << 24L; \
+ } while (0)
-#define l2c(l, c) \
- (*((c)++) = (unsigned char)(((l)) & 0xff), \
- *((c)++) = (unsigned char)(((l) >> 8L) & 0xff), \
- *((c)++) = (unsigned char)(((l) >> 16L) & 0xff), \
- *((c)++) = (unsigned char)(((l) >> 24L) & 0xff))
+#define l2c(l, c) \
+ do { \
+ *((c)++) = (unsigned char)(((l)) & 0xff); \
+ *((c)++) = (unsigned char)(((l) >> 8L) & 0xff); \
+ *((c)++) = (unsigned char)(((l) >> 16L) & 0xff); \
+ *((c)++) = (unsigned char)(((l) >> 24L) & 0xff); \
+ } while (0)
/* NOTE - c is not incremented as per c2l */
-#define c2ln(c, l1, l2, n) \
- { \
- c += n; \
- l1 = l2 = 0; \
- switch (n) { \
- case 8: \
- l2 = ((uint32_t)(*(--(c)))) << 24L; \
- case 7: \
- l2 |= ((uint32_t)(*(--(c)))) << 16L; \
- case 6: \
- l2 |= ((uint32_t)(*(--(c)))) << 8L; \
- case 5: \
- l2 |= ((uint32_t)(*(--(c)))); \
- case 4: \
- l1 = ((uint32_t)(*(--(c)))) << 24L; \
- case 3: \
- l1 |= ((uint32_t)(*(--(c)))) << 16L; \
- case 2: \
- l1 |= ((uint32_t)(*(--(c)))) << 8L; \
- case 1: \
- l1 |= ((uint32_t)(*(--(c)))); \
- } \
- }
+#define c2ln(c, l1, l2, n) \
+ do { \
+ (c) += (n); \
+ (l1) = (l2) = 0; \
+ switch (n) { \
+ case 8: \
+ (l2) = ((uint32_t)(*(--(c)))) << 24L; \
+ case 7: \
+ (l2) |= ((uint32_t)(*(--(c)))) << 16L; \
+ case 6: \
+ (l2) |= ((uint32_t)(*(--(c)))) << 8L; \
+ case 5: \
+ (l2) |= ((uint32_t)(*(--(c)))); \
+ case 4: \
+ (l1) = ((uint32_t)(*(--(c)))) << 24L; \
+ case 3: \
+ (l1) |= ((uint32_t)(*(--(c)))) << 16L; \
+ case 2: \
+ (l1) |= ((uint32_t)(*(--(c)))) << 8L; \
+ case 1: \
+ (l1) |= ((uint32_t)(*(--(c)))); \
+ } \
+ } while (0)
/* NOTE - c is not incremented as per l2c */
#define l2cn(l1, l2, c, n) \
- { \
- c += n; \
+ do { \
+ (c) += (n); \
switch (n) { \
case 8: \
*(--(c)) = (unsigned char)(((l2) >> 24L) & 0xff); \
@@ -121,7 +127,7 @@
case 1: \
*(--(c)) = (unsigned char)(((l1)) & 0xff); \
} \
- }
+ } while (0)
/* IP and FP
* The problem is more of a geometric problem that random bit fiddling.
@@ -160,44 +166,50 @@
I first got ~42 operations without xors. When I remembered
how to use xors :-) I got it to its final state.
*/
-#define PERM_OP(a, b, t, n, m) \
- ((t) = ((((a) >> (n)) ^ (b)) & (m)), (b) ^= (t), (a) ^= ((t) << (n)))
+#define PERM_OP(a, b, t, n, m) \
+ do { \
+ (t) = ((((a) >> (n)) ^ (b)) & (m)); \
+ (b) ^= (t); \
+ (a) ^= ((t) << (n)); \
+ } while (0)
#define IP(l, r) \
- { \
+ do { \
uint32_t tt; \
PERM_OP(r, l, tt, 4, 0x0f0f0f0fL); \
PERM_OP(l, r, tt, 16, 0x0000ffffL); \
PERM_OP(r, l, tt, 2, 0x33333333L); \
PERM_OP(l, r, tt, 8, 0x00ff00ffL); \
PERM_OP(r, l, tt, 1, 0x55555555L); \
- }
+ } while (0)
#define FP(l, r) \
- { \
+ do { \
uint32_t tt; \
PERM_OP(l, r, tt, 1, 0x55555555L); \
PERM_OP(r, l, tt, 8, 0x00ff00ffL); \
PERM_OP(l, r, tt, 2, 0x33333333L); \
PERM_OP(r, l, tt, 16, 0x0000ffffL); \
PERM_OP(l, r, tt, 4, 0x0f0f0f0fL); \
- }
+ } while (0)
#define LOAD_DATA(ks, R, S, u, t, E0, E1) \
- u = R ^ ks->subkeys[S][0]; \
- t = R ^ ks->subkeys[S][1]
+ do { \
+ (u) = (R) ^ (ks)->subkeys[S][0]; \
+ (t) = (R) ^ (ks)->subkeys[S][1]; \
+ } while (0)
#define D_ENCRYPT(ks, LL, R, S) \
- { \
+ do { \
LOAD_DATA(ks, R, S, u, t, E0, E1); \
t = ROTATE(t, 4); \
- LL ^= \
+ (LL) ^= \
DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \
DES_SPtrans[4][(u >> 18L) & 0x3f] ^ \
DES_SPtrans[6][(u >> 26L) & 0x3f] ^ DES_SPtrans[1][(t >> 2L) & 0x3f] ^ \
DES_SPtrans[3][(t >> 10L) & 0x3f] ^ \
DES_SPtrans[5][(t >> 18L) & 0x3f] ^ DES_SPtrans[7][(t >> 26L) & 0x3f]; \
- }
+ } while (0)
#define ITERATIONS 16
#define HALF_ITERATIONS 8
diff --git a/src/crypto/digest/md32_common.h b/src/crypto/digest/md32_common.h
index 4cf050c..818eb63 100644
--- a/src/crypto/digest/md32_common.h
+++ b/src/crypto/digest/md32_common.h
@@ -140,29 +140,39 @@
#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-#define HOST_c2l(c, l) \
- (void)(l = (((uint32_t)(*((c)++))) << 24), \
- l |= (((uint32_t)(*((c)++))) << 16), \
- l |= (((uint32_t)(*((c)++))) << 8), l |= (((uint32_t)(*((c)++)))))
+#define HOST_c2l(c, l) \
+ do { \
+ (l) = (((uint32_t)(*((c)++))) << 24); \
+ (l) |= (((uint32_t)(*((c)++))) << 16); \
+ (l) |= (((uint32_t)(*((c)++))) << 8); \
+ (l) |= (((uint32_t)(*((c)++)))); \
+ } while (0)
-#define HOST_l2c(l, c) \
- (void)(*((c)++) = (uint8_t)(((l) >> 24) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
- *((c)++) = (uint8_t)(((l)) & 0xff))
+#define HOST_l2c(l, c) \
+ do { \
+ *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \
+ *((c)++) = (uint8_t)(((l)) & 0xff); \
+ } while (0)
#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-#define HOST_c2l(c, l) \
- (void)(l = (((uint32_t)(*((c)++)))), l |= (((uint32_t)(*((c)++))) << 8), \
- l |= (((uint32_t)(*((c)++))) << 16), \
- l |= (((uint32_t)(*((c)++))) << 24))
+#define HOST_c2l(c, l) \
+ do { \
+ (l) = (((uint32_t)(*((c)++)))); \
+ (l) |= (((uint32_t)(*((c)++))) << 8); \
+ (l) |= (((uint32_t)(*((c)++))) << 16); \
+ (l) |= (((uint32_t)(*((c)++))) << 24); \
+ } while (0)
-#define HOST_l2c(l, c) \
- (void)(*((c)++) = (uint8_t)(((l)) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 8) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 16) & 0xff), \
- *((c)++) = (uint8_t)(((l) >> 24) & 0xff))
+#define HOST_l2c(l, c) \
+ do { \
+ *((c)++) = (uint8_t)(((l)) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \
+ *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \
+ } while (0)
#endif /* DATA_ORDER */
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index a0e4df5..6a54200 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -175,9 +175,9 @@
out[7] *= scalar;
}
-#define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9)
+#define two105m41m9 ((((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9))
#define two105 (((limb)1) << 105)
-#define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9)
+#define two105m41p9 ((((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9))
/* zero105 is 0 mod p */
static const felem zero105 = {two105m41m9, two105, two105m41p9, two105m41p9};
@@ -211,9 +211,11 @@
out[3] -= in[3];
}
-#define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11)
+#define two107m43m11 \
+ ((((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11))
#define two107 (((limb)1) << 107)
-#define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11)
+#define two107m43p11 \
+ ((((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11))
/* zero107 is 0 mod p */
static const felem zero107 = {two107m43m11, two107, two107m43p11, two107m43p11};
@@ -272,10 +274,10 @@
out[7] -= in[7];
}
-#define two64m0 (((limb)1) << 64) - 1
-#define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1
-#define two64m46 (((limb)1) << 64) - (((limb)1) << 46)
-#define two64m32 (((limb)1) << 64) - (((limb)1) << 32)
+#define two64m0 ((((limb)1) << 64) - 1)
+#define two110p32m0 ((((limb)1) << 110) + (((limb)1) << 32) - 1)
+#define two64m46 ((((limb)1) << 64) - (((limb)1) << 46))
+#define two64m32 ((((limb)1) << 64) - (((limb)1) << 32))
/* zero110 is 0 mod p. */
static const felem zero110 = {two64m0, two110p32m0, two64m46, two64m32};
@@ -594,9 +596,9 @@
smallfelem_mul(out, small1, small2);
}
-#define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4)
+#define two100m36m4 ((((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4))
#define two100 (((limb)1) << 100)
-#define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4)
+#define two100m36p4 ((((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4))
/* zero100 is 0 mod p */
static const felem zero100 = {two100m36m4, two100, two100m36p4, two100m36p4};
diff --git a/src/crypto/ecdh/ecdh.c b/src/crypto/ecdh/ecdh.c
index 37a67b2..50a844e 100644
--- a/src/crypto/ecdh/ecdh.c
+++ b/src/crypto/ecdh/ecdh.c
@@ -76,7 +76,7 @@
int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
- EC_KEY *priv_key,
+ const EC_KEY *priv_key,
void *(*kdf)(const void *in, size_t inlen, void *out,
size_t *outlen)) {
const BIGNUM *const priv = EC_KEY_get0_private_key(priv_key);
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index 9045e9a..c25683e 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -157,7 +157,9 @@
SSL,1090,TLSV1_ALERT_USER_CANCELLED
SSL,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
+SSL,1116,TLSV1_CERTIFICATE_REQUIRED
SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
+SSL,1115,TLSV1_UNKNOWN_PSK_IDENTITY
SSL,1112,TLSV1_UNRECOGNIZED_NAME
SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
diff --git a/src/crypto/md4/md4.c b/src/crypto/md4/md4.c
index f79da9f..7da3ec8 100644
--- a/src/crypto/md4/md4.c
+++ b/src/crypto/md4/md4.c
@@ -114,23 +114,23 @@
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
-#define R0(a, b, c, d, k, s, t) \
- { \
- a += ((k) + (t)+F((b), (c), (d))); \
- a = ROTATE(a, s); \
- };
+#define R0(a, b, c, d, k, s, t) \
+ do { \
+ (a) += ((k) + (t) + F((b), (c), (d))); \
+ (a) = ROTATE(a, s); \
+ } while (0)
-#define R1(a, b, c, d, k, s, t) \
- { \
- a += ((k) + (t)+G((b), (c), (d))); \
- a = ROTATE(a, s); \
- };
+#define R1(a, b, c, d, k, s, t) \
+ do { \
+ (a) += ((k) + (t) + G((b), (c), (d))); \
+ (a) = ROTATE(a, s); \
+ } while (0)
-#define R2(a, b, c, d, k, s, t) \
- { \
- a += ((k) + (t)+H((b), (c), (d))); \
- a = ROTATE(a, s); \
- };
+#define R2(a, b, c, d, k, s, t) \
+ do { \
+ (a) += ((k) + (t) + H((b), (c), (d))); \
+ (a) = ROTATE(a, s); \
+ } while (0)
void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num) {
uint32_t A, B, C, D, l;
diff --git a/src/crypto/md5/md5.c b/src/crypto/md5/md5.c
index 66483b8..a66fa7f 100644
--- a/src/crypto/md5/md5.c
+++ b/src/crypto/md5/md5.c
@@ -122,32 +122,40 @@
* simplified to the code below. Wei attributes these optimizations
* to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
*/
-#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
-#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c))
-#define H(b,c,d) ((b) ^ (c) ^ (d))
-#define I(b,c,d) (((~(d)) | (b)) ^ (c))
+#define F(b, c, d) ((((c) ^ (d)) & (b)) ^ (d))
+#define G(b, c, d) ((((b) ^ (c)) & (d)) ^ (c))
+#define H(b, c, d) ((b) ^ (c) ^ (d))
+#define I(b, c, d) (((~(d)) | (b)) ^ (c))
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
-#define R0(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+F((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };\
+#define R0(a, b, c, d, k, s, t) \
+ do { \
+ (a) += ((k) + (t) + F((b), (c), (d))); \
+ (a) = ROTATE(a, s); \
+ (a) += (b); \
+ } while (0)
-#define R1(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+G((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };
+#define R1(a, b, c, d, k, s, t) \
+ do { \
+ (a) += ((k) + (t) + G((b), (c), (d))); \
+ (a) = ROTATE(a, s); \
+ (a) += (b); \
+ } while (0)
-#define R2(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+H((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };
+#define R2(a, b, c, d, k, s, t) \
+ do { \
+ (a) += ((k) + (t) + H((b), (c), (d))); \
+ (a) = ROTATE(a, s); \
+ (a) += (b); \
+ } while (0)
-#define R3(a,b,c,d,k,s,t) { \
- a+=((k)+(t)+I((b),(c),(d))); \
- a=ROTATE(a,s); \
- a+=b; };
+#define R3(a, b, c, d, k, s, t) \
+ do { \
+ (a) += ((k) + (t) + I((b), (c), (d))); \
+ (a) = ROTATE(a, s); \
+ (a) += (b); \
+ } while (0)
#ifndef md5_block_data_order
#ifdef X
diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c
index 69bdfdc..eb63aa0 100644
--- a/src/crypto/modes/gcm.c
+++ b/src/crypto/modes/gcm.c
@@ -74,17 +74,17 @@
#endif
#define PACK(s) ((size_t)(s) << (sizeof(size_t) * 8 - 16))
-#define REDUCE1BIT(V) \
- do { \
- if (sizeof(size_t) == 8) { \
- uint64_t T = UINT64_C(0xe100000000000000) & (0 - (V.lo & 1)); \
- V.lo = (V.hi << 63) | (V.lo >> 1); \
- V.hi = (V.hi >> 1) ^ T; \
- } else { \
- uint32_t T = 0xe1000000U & (0 - (uint32_t)(V.lo & 1)); \
- V.lo = (V.hi << 63) | (V.lo >> 1); \
- V.hi = (V.hi >> 1) ^ ((uint64_t)T << 32); \
- } \
+#define REDUCE1BIT(V) \
+ do { \
+ if (sizeof(size_t) == 8) { \
+ uint64_t T = UINT64_C(0xe100000000000000) & (0 - ((V).lo & 1)); \
+ (V).lo = ((V).hi << 63) | ((V).lo >> 1); \
+ (V).hi = ((V).hi >> 1) ^ T; \
+ } else { \
+ uint32_t T = 0xe1000000U & (0 - (uint32_t)((V).lo & 1)); \
+ (V).lo = ((V).hi << 63) | ((V).lo >> 1); \
+ (V).hi = ((V).hi >> 1) ^ ((uint64_t)T << 32); \
+ } \
} while (0)
// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four
@@ -313,7 +313,7 @@
size_t len);
#endif
-#define GCM_MUL(ctx, Xi) gcm_gmult_4bit(ctx->Xi.u, ctx->Htable)
+#define GCM_MUL(ctx, Xi) gcm_gmult_4bit((ctx)->Xi.u, (ctx)->Htable)
#if defined(GHASH_ASM)
#define GHASH(ctx, in, len) gcm_ghash_4bit((ctx)->Xi.u, (ctx)->Htable, in, len)
/* GHASH_CHUNK is "stride parameter" missioned to mitigate cache
@@ -418,10 +418,10 @@
#ifdef GCM_FUNCREF_4BIT
#undef GCM_MUL
-#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)(ctx->Xi.u, ctx->Htable)
+#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)((ctx)->Xi.u, (ctx)->Htable)
#ifdef GHASH
#undef GHASH
-#define GHASH(ctx, in, len) (*gcm_ghash_p)(ctx->Xi.u, ctx->Htable, in, len)
+#define GHASH(ctx, in, len) (*gcm_ghash_p)((ctx)->Xi.u, (ctx)->Htable, in, len)
#endif
#endif
diff --git a/src/crypto/sha/sha1.c b/src/crypto/sha/sha1.c
index 74e841c..0ebed99 100644
--- a/src/crypto/sha/sha1.c
+++ b/src/crypto/sha/sha1.c
@@ -119,7 +119,10 @@
#define HASH_BLOCK_DATA_ORDER sha1_block_data_order
#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n))))
#define Xupdate(a, ix, ia, ib, ic, id) \
- ((a) = (ia ^ ib ^ ic ^ id), ix = (a) = ROTATE((a), 1))
+ do { \
+ (a) = ((ia) ^ (ib) ^ (ic) ^ (id)); \
+ (ix) = (a) = ROTATE((a), 1); \
+ } while (0)
#ifndef SHA1_ASM
static
@@ -143,34 +146,46 @@
#define F_40_59(b, c, d) (((b) & (c)) | (((b) | (c)) & (d)))
#define F_60_79(b, c, d) F_20_39(b, c, d)
-#define BODY_00_15(i, a, b, c, d, e, f, xi) \
- (f) = xi + (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
- (b) = ROTATE((b), 30);
+#define BODY_00_15(i, a, b, c, d, e, f, xi) \
+ do { \
+ (f) = (xi) + (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
+ (b) = ROTATE((b), 30); \
+ } while (0)
-#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
- Xupdate(f, xi, xa, xb, xc, xd); \
- (f) += (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
- (b) = ROTATE((b), 30);
+#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
+ do { \
+ Xupdate(f, xi, xa, xb, xc, xd); \
+ (f) += (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \
+ (b) = ROTATE((b), 30); \
+ } while (0)
-#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
- Xupdate(f, xi, xa, xb, xc, xd); \
- (f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
- (b) = ROTATE((b), 30);
+#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \
+ do { \
+ Xupdate(f, xi, xa, xb, xc, xd); \
+ (f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
+ (b) = ROTATE((b), 30); \
+ } while (0)
-#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \
- Xupdate(f, xa, xa, xb, xc, xd); \
- (f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
- (b) = ROTATE((b), 30);
+#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \
+ do { \
+ Xupdate(f, xa, xa, xb, xc, xd); \
+ (f) += (e) + K_20_39 + ROTATE((a), 5) + F_20_39((b), (c), (d)); \
+ (b) = ROTATE((b), 30); \
+ } while (0)
-#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \
- Xupdate(f, xa, xa, xb, xc, xd); \
- (f) += (e) + K_40_59 + ROTATE((a), 5) + F_40_59((b), (c), (d)); \
- (b) = ROTATE((b), 30);
+#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \
+ do { \
+ Xupdate(f, xa, xa, xb, xc, xd); \
+ (f) += (e) + K_40_59 + ROTATE((a), 5) + F_40_59((b), (c), (d)); \
+ (b) = ROTATE((b), 30); \
+ } while (0)
-#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \
- Xupdate(f, xa, xa, xb, xc, xd); \
- (f) = xa + (e) + K_60_79 + ROTATE((a), 5) + F_60_79((b), (c), (d)); \
- (b) = ROTATE((b), 30);
+#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \
+ do { \
+ Xupdate(f, xa, xa, xb, xc, xd); \
+ (f) = (xa) + (e) + K_60_79 + ROTATE((a), 5) + F_60_79((b), (c), (d)); \
+ (b) = ROTATE((b), 30); \
+ } while (0)
#ifdef X
#undef X
@@ -199,51 +214,51 @@
E = state[4];
for (;;) {
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(0) = l;
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(1) = l;
BODY_00_15(0, A, B, C, D, E, T, X(0));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(2) = l;
BODY_00_15(1, T, A, B, C, D, E, X(1));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(3) = l;
BODY_00_15(2, E, T, A, B, C, D, X(2));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(4) = l;
BODY_00_15(3, D, E, T, A, B, C, X(3));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(5) = l;
BODY_00_15(4, C, D, E, T, A, B, X(4));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(6) = l;
BODY_00_15(5, B, C, D, E, T, A, X(5));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(7) = l;
BODY_00_15(6, A, B, C, D, E, T, X(6));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(8) = l;
BODY_00_15(7, T, A, B, C, D, E, X(7));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(9) = l;
BODY_00_15(8, E, T, A, B, C, D, X(8));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(10) = l;
BODY_00_15(9, D, E, T, A, B, C, X(9));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(11) = l;
BODY_00_15(10, C, D, E, T, A, B, X(10));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(12) = l;
BODY_00_15(11, B, C, D, E, T, A, X(11));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(13) = l;
BODY_00_15(12, A, B, C, D, E, T, X(12));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(14) = l;
BODY_00_15(13, T, A, B, C, D, E, X(13));
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(15) = l;
BODY_00_15(14, E, T, A, B, C, D, X(14));
BODY_00_15(15, D, E, T, A, B, C, X(15));
diff --git a/src/crypto/test/malloc.cc b/src/crypto/test/malloc.cc
index 47ee6da..33f0972 100644
--- a/src/crypto/test/malloc.cc
+++ b/src/crypto/test/malloc.cc
@@ -26,9 +26,13 @@
// This file isn't built on ARM or Aarch64 because we link statically in those
// builds and trying to override malloc in a static link doesn't work. It also
-// requires glibc.
+// requires glibc. It's also disabled on ASan builds as this interferes with
+// ASan's malloc interceptor.
+//
+// TODO(davidben): See if this and ASan's and MSan's interceptors can be made to
+// coexist.
#if defined(__linux__) && defined(OPENSSL_GLIBC) && !defined(OPENSSL_ARM) && \
- !defined(OPENSSL_AARCH64)
+ !defined(OPENSSL_AARCH64) && !defined(OPENSSL_ASAN)
#include <errno.h>
#include <signal.h>
@@ -40,38 +44,23 @@
#include <new>
-/* This file defines overrides for the standard allocation functions that allow
- * a given allocation to be made to fail for testing. If the program is run
- * with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will
- * return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation
- * will signal SIGTRAP rather than return NULL.
- *
- * This code is not thread safe. */
+// This file defines overrides for the standard allocation functions that allow
+// a given allocation to be made to fail for testing. If the program is run
+// with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will
+// return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation
+// will signal SIGTRAP rather than return NULL.
+//
+// This code is not thread safe.
static uint64_t current_malloc_count = 0;
static uint64_t malloc_number_to_fail = 0;
-static char failure_enabled = 0, break_on_fail = 0;
-static int in_call = 0;
+static bool failure_enabled = false, break_on_fail = false, in_call = false;
extern "C" {
-
-#if defined(OPENSSL_ASAN)
-#define REAL_MALLOC __interceptor_malloc
-#define REAL_CALLOC __interceptor_calloc
-#define REAL_REALLOC __interceptor_realloc
-#define REAL_FREE __interceptor_free
-#else
-#define REAL_MALLOC __libc_malloc
-#define REAL_CALLOC __libc_calloc
-#define REAL_REALLOC __libc_realloc
-#define REAL_FREE __libc_free
-#endif
-
-/* These are other names for the standard allocation functions. */
-extern void *REAL_MALLOC(size_t size);
-extern void *REAL_CALLOC(size_t num_elems, size_t size);
-extern void *REAL_REALLOC(void *ptr, size_t size);
-extern void REAL_FREE(void *ptr);
+// These are other names for the standard allocation functions.
+extern void *__libc_malloc(size_t size);
+extern void *__libc_calloc(size_t num_elems, size_t size);
+extern void *__libc_realloc(void *ptr, size_t size);
}
static void exit_handler(void) {
@@ -85,16 +74,15 @@
return;
}
-/* should_fail_allocation returns true if the current allocation should fail. */
-static int should_fail_allocation() {
- static int init = 0;
- char should_fail;
+// should_fail_allocation returns true if the current allocation should fail.
+static bool should_fail_allocation() {
+ static bool init = false;
if (in_call) {
- return 0;
+ return false;
}
- in_call = 1;
+ in_call = true;
if (!init) {
const char *env = getenv("MALLOC_NUMBER_TO_FAIL");
@@ -102,22 +90,22 @@
char *endptr;
malloc_number_to_fail = strtoull(env, &endptr, 10);
if (*endptr == 0) {
- failure_enabled = 1;
+ failure_enabled = true;
atexit(exit_handler);
std::set_new_handler(cpp_new_handler);
}
}
break_on_fail = (NULL != getenv("MALLOC_BREAK_ON_FAIL"));
- init = 1;
+ init = true;
}
- in_call = 0;
+ in_call = false;
if (!failure_enabled) {
- return 0;
+ return false;
}
- should_fail = (current_malloc_count == malloc_number_to_fail);
+ bool should_fail = (current_malloc_count == malloc_number_to_fail);
current_malloc_count++;
if (should_fail && break_on_fail) {
@@ -134,7 +122,7 @@
return NULL;
}
- return REAL_MALLOC(size);
+ return __libc_malloc(size);
}
void *calloc(size_t num_elems, size_t size) {
@@ -143,7 +131,7 @@
return NULL;
}
- return REAL_CALLOC(num_elems, size);
+ return __libc_calloc(num_elems, size);
}
void *realloc(void *ptr, size_t size) {
@@ -152,11 +140,7 @@
return NULL;
}
- return REAL_REALLOC(ptr, size);
-}
-
-void free(void *ptr) {
- REAL_FREE(ptr);
+ return __libc_realloc(ptr, size);
}
} // extern "C"
diff --git a/src/crypto/x509/x509_vpm.c b/src/crypto/x509/x509_vpm.c
index 9e9dbf5..924cfa7 100644
--- a/src/crypto/x509/x509_vpm.c
+++ b/src/crypto/x509/x509_vpm.c
@@ -227,8 +227,8 @@
/* Macro to test if a field should be copied from src to dest */
#define test_x509_verify_param_copy(field, def) \
- (to_overwrite || \
- ((src->field != def) && (to_default || (dest->field == def))))
+ (to_overwrite || \
+ ((src->field != (def)) && (to_default || (dest->field == (def)))))
/* As above but for ID fields */
@@ -513,7 +513,7 @@
static const X509_VERIFY_PARAM_ID _empty_id =
{ NULL, 0U, NULL, NULL, 0, NULL, 0 };
-#define vpm_empty_id (X509_VERIFY_PARAM_ID *)&_empty_id
+#define vpm_empty_id ((X509_VERIFY_PARAM_ID *)&_empty_id)
/*
* Default verify parameters: these are used for various applications and can
diff --git a/src/crypto/x509v3/pcy_int.h b/src/crypto/x509v3/pcy_int.h
index b5075f9..1e76503 100644
--- a/src/crypto/x509v3/pcy_int.h
+++ b/src/crypto/x509v3/pcy_int.h
@@ -180,8 +180,8 @@
/* Useful macros */
-#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL)
-#define node_critical(node) node_data_critical(node->data)
+#define node_data_critical(data) ((data)->flags & POLICY_DATA_FLAG_CRITICAL)
+#define node_critical(node) node_data_critical((node)->data)
/* Internal functions */
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index f9324d4..9152444 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -647,7 +647,7 @@
* key types.
*/
#define KU_TLS \
- KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT
+ (KU_DIGITAL_SIGNATURE|KU_KEY_ENCIPHERMENT|KU_KEY_AGREEMENT)
static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x,
int ca)
diff --git a/src/decrepit/ripemd/internal.h b/src/decrepit/ripemd/internal.h
index c4db4b2..cbf7a8d 100644
--- a/src/decrepit/ripemd/internal.h
+++ b/src/decrepit/ripemd/internal.h
@@ -79,15 +79,15 @@
do { \
unsigned long ll; \
ll = (c)->h[0]; \
- (void)HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[1]; \
- (void)HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[2]; \
- (void)HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[3]; \
- (void)HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
ll = (c)->h[4]; \
- (void)HOST_l2c(ll, (s)); \
+ HOST_l2c(ll, (s)); \
} while (0)
#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order
diff --git a/src/decrepit/ripemd/ripemd.c b/src/decrepit/ripemd/ripemd.c
index 6ed7816..ce47c28 100644
--- a/src/decrepit/ripemd/ripemd.c
+++ b/src/decrepit/ripemd/ripemd.c
@@ -86,51 +86,51 @@
D = h[3];
E = h[4];
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(0) = l;
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(1) = l;
RIP1(A, B, C, D, E, WL00, SL00);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(2) = l;
RIP1(E, A, B, C, D, WL01, SL01);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(3) = l;
RIP1(D, E, A, B, C, WL02, SL02);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(4) = l;
RIP1(C, D, E, A, B, WL03, SL03);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(5) = l;
RIP1(B, C, D, E, A, WL04, SL04);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(6) = l;
RIP1(A, B, C, D, E, WL05, SL05);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(7) = l;
RIP1(E, A, B, C, D, WL06, SL06);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(8) = l;
RIP1(D, E, A, B, C, WL07, SL07);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(9) = l;
RIP1(C, D, E, A, B, WL08, SL08);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(10) = l;
RIP1(B, C, D, E, A, WL09, SL09);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(11) = l;
RIP1(A, B, C, D, E, WL10, SL10);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(12) = l;
RIP1(E, A, B, C, D, WL11, SL11);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(13) = l;
RIP1(D, E, A, B, C, WL12, SL12);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(14) = l;
RIP1(C, D, E, A, B, WL13, SL13);
- (void)HOST_c2l(data, l);
+ HOST_c2l(data, l);
X(15) = l;
RIP1(B, C, D, E, A, WL14, SL14);
RIP1(A, B, C, D, E, WL15, SL15);
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index 888b594..10a22ce 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -60,6 +60,11 @@
#include <stdint.h>
#include <sys/types.h>
+#if defined(__MINGW32__)
+/* stdio.h is needed on MinGW for __MINGW_PRINTF_FORMAT. */
+#include <stdio.h>
+#endif
+
#include <openssl/opensslconf.h>
#if defined(BORINGSSL_PREFIX)
@@ -158,8 +163,17 @@
#if defined(__GNUC__)
+/* MinGW has two different printf implementations. Ensure the format macro
+ * matches the selected implementation. See
+ * https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. */
+#if defined(__MINGW_PRINTF_FORMAT)
#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \
- __attribute__((__format__(__printf__, string_index, first_to_check)))
+ __attribute__( \
+ (__format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check)))
+#else
+#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \
+ __attribute__((__format__(__printf__, string_index, first_to_check)))
+#endif
#else
#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check)
#endif
diff --git a/src/include/openssl/ecdh.h b/src/include/openssl/ecdh.h
index 5fe3ae9..c167503 100644
--- a/src/include/openssl/ecdh.h
+++ b/src/include/openssl/ecdh.h
@@ -85,10 +85,9 @@
* return value. Otherwise, as many bytes of the shared key as will fit are
* copied directly to, at most, |outlen| bytes at |out|. It returns the number
* of bytes written to |out|, or -1 on error. */
-OPENSSL_EXPORT int ECDH_compute_key(void *out, size_t outlen,
- const EC_POINT *pub_key, EC_KEY *priv_key,
- void *(*kdf)(const void *in, size_t inlen,
- void *out, size_t *outlen));
+OPENSSL_EXPORT int ECDH_compute_key(
+ void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *priv_key,
+ void *(*kdf)(const void *in, size_t inlen, void *out, size_t *outlen));
#if defined(__cplusplus)
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index cac50e0..f6efa12 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -467,7 +467,7 @@
#define ERR_R_OVERFLOW (5 | ERR_R_FATAL)
#define ERR_PACK(lib, reason) \
- (((((uint32_t)lib) & 0xff) << 24) | ((((uint32_t)reason) & 0xfff)))
+ (((((uint32_t)(lib)) & 0xff) << 24) | ((((uint32_t)(reason)) & 0xfff)))
#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff))
#define ERR_GET_FUNC(packed_error) 0
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 88fe845..0d78754 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -562,7 +562,7 @@
#define DTLS1_VERSION 0xfeff
#define DTLS1_2_VERSION 0xfefd
-#define TLS1_3_DRAFT_VERSION 0x7f0f
+#define TLS1_3_DRAFT_VERSION 0x7f10
/* SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to
* |version|. If |version| is zero, the default minimum version is used. It
@@ -2708,6 +2708,7 @@
#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION
#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY
#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR
+#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK
#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
#define SSL_AD_MISSING_EXTENSION TLS1_AD_MISSING_EXTENSION
@@ -2718,7 +2719,7 @@
TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY
-#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK
+#define SSL_AD_CERTIFICATE_REQUIRED TLS1_AD_CERTIFICATE_REQUIRED
/* SSL_alert_type_string_long returns a string description of |value| as an
* alert type (warning or fatal). */
@@ -2897,7 +2898,7 @@
/* SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer
* certificate chain. */
-#define SSL_MAX_CERT_LIST_DEFAULT 1024 * 100
+#define SSL_MAX_CERT_LIST_DEFAULT (1024 * 100)
/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
* certificate chain accepted by |ctx|. */
@@ -3114,8 +3115,8 @@
OPENSSL_EXPORT void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx,
int enable);
-/* SSL_CTX_set_grease_enabled configures whether client sockets on |ctx| should
- * enable GREASE. See draft-davidben-tls-grease-01. */
+/* SSL_CTX_set_grease_enabled configures whether sockets on |ctx| should enable
+ * GREASE. See draft-davidben-tls-grease-01. */
OPENSSL_EXPORT void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled);
@@ -3342,14 +3343,14 @@
/* SSL_get_server_tmp_key returns zero. */
OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key);
-#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
+#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)(arg)))
#define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
#define SSL_SESSION_set_app_data(s, a) \
- (SSL_SESSION_set_ex_data(s, 0, (char *)a))
+ (SSL_SESSION_set_ex_data(s, 0, (char *)(a)))
#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s, 0))
#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx, 0))
#define SSL_CTX_set_app_data(ctx, arg) \
- (SSL_CTX_set_ex_data(ctx, 0, (char *)arg))
+ (SSL_CTX_set_ex_data(ctx, 0, (char *)(arg)))
#define OpenSSL_add_ssl_algorithms() SSL_library_init()
#define SSLeay_add_ssl_algorithms() SSL_library_init()
@@ -3471,14 +3472,15 @@
/* SSL_get_finished writes up to |count| bytes of the Finished message sent by
* |ssl| to |buf|. It returns the total untruncated length or zero if none has
- * been sent yet.
+ * been sent yet. At SSL 3.0 or TLS 1.3 and later, it returns zero.
*
* Use |SSL_get_tls_unique| instead. */
OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count);
/* SSL_get_peer_finished writes up to |count| bytes of the Finished message
* received from |ssl|'s peer to |buf|. It returns the total untruncated length
- * or zero if none has been received yet.
+ * or zero if none has been received yet. At SSL 3.0 or TLS 1.3 and later, it
+ * returns zero.
*
* Use |SSL_get_tls_unique| instead. */
OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf,
@@ -4200,283 +4202,6 @@
int tlsext_status_type;
};
-typedef struct ssl3_record_st {
- /* type is the record type. */
- uint8_t type;
- /* length is the number of unconsumed bytes in the record. */
- uint16_t length;
- /* data is a non-owning pointer to the first unconsumed byte of the record. */
- uint8_t *data;
-} SSL3_RECORD;
-
-typedef struct ssl3_buffer_st {
- /* buf is the memory allocated for this buffer. */
- uint8_t *buf;
- /* offset is the offset into |buf| which the buffer contents start at. */
- uint16_t offset;
- /* len is the length of the buffer contents from |buf| + |offset|. */
- uint16_t len;
- /* cap is how much memory beyond |buf| + |offset| is available. */
- uint16_t cap;
-} SSL3_BUFFER;
-
-/* An ssl_shutdown_t describes the shutdown state of one end of the connection,
- * whether it is alive or has been shutdown via close_notify or fatal alert. */
-enum ssl_shutdown_t {
- ssl_shutdown_none = 0,
- ssl_shutdown_close_notify = 1,
- ssl_shutdown_fatal_alert = 2,
-};
-
-typedef struct ssl3_state_st {
- uint8_t read_sequence[8];
- uint8_t write_sequence[8];
-
- uint8_t server_random[SSL3_RANDOM_SIZE];
- uint8_t client_random[SSL3_RANDOM_SIZE];
-
- /* have_version is true if the connection's final version is known. Otherwise
- * the version has not been negotiated yet. */
- unsigned have_version:1;
-
- /* v2_hello_done is true if the peer's V2ClientHello, if any, has been handled
- * and future messages should use the record layer. */
- unsigned v2_hello_done:1;
-
- /* initial_handshake_complete is true if the initial handshake has
- * completed. */
- unsigned initial_handshake_complete:1;
-
- /* read_buffer holds data from the transport to be processed. */
- SSL3_BUFFER read_buffer;
- /* write_buffer holds data to be written to the transport. */
- SSL3_BUFFER write_buffer;
-
- SSL3_RECORD rrec; /* each decoded record goes in here */
-
- /* partial write - check the numbers match */
- unsigned int wnum; /* number of bytes sent so far */
- int wpend_tot; /* number bytes written */
- int wpend_type;
- int wpend_ret; /* number of bytes submitted */
- const uint8_t *wpend_buf;
-
- /* handshake_buffer, if non-NULL, contains the handshake transcript. */
- BUF_MEM *handshake_buffer;
- /* handshake_hash, if initialized with an |EVP_MD|, maintains the handshake
- * hash. For TLS 1.1 and below, it is the SHA-1 half. */
- EVP_MD_CTX handshake_hash;
- /* handshake_md5, if initialized with an |EVP_MD|, maintains the MD5 half of
- * the handshake hash for TLS 1.1 and below. */
- EVP_MD_CTX handshake_md5;
-
- /* recv_shutdown is the shutdown state for the receive half of the
- * connection. */
- enum ssl_shutdown_t recv_shutdown;
-
- /* recv_shutdown is the shutdown state for the send half of the connection. */
- enum ssl_shutdown_t send_shutdown;
-
- int alert_dispatch;
- uint8_t send_alert[2];
-
- int total_renegotiations;
-
- /* empty_record_count is the number of consecutive empty records received. */
- uint8_t empty_record_count;
-
- /* warning_alert_count is the number of consecutive warning alerts
- * received. */
- uint8_t warning_alert_count;
-
- /* key_update_count is the number of consecutive KeyUpdates received. */
- uint8_t key_update_count;
-
- /* aead_read_ctx is the current read cipher state. */
- SSL_AEAD_CTX *aead_read_ctx;
-
- /* aead_write_ctx is the current write cipher state. */
- SSL_AEAD_CTX *aead_write_ctx;
-
- /* enc_method is the method table corresponding to the current protocol
- * version. */
- const SSL3_ENC_METHOD *enc_method;
-
- /* pending_message is the current outgoing handshake message. */
- uint8_t *pending_message;
- uint32_t pending_message_len;
-
- /* hs is the handshake state for the current handshake or NULL if there isn't
- * one. */
- SSL_HANDSHAKE *hs;
-
- uint8_t write_traffic_secret[EVP_MAX_MD_SIZE];
- uint8_t write_traffic_secret_len;
- uint8_t read_traffic_secret[EVP_MAX_MD_SIZE];
- uint8_t read_traffic_secret_len;
- uint8_t exporter_secret[EVP_MAX_MD_SIZE];
- uint8_t exporter_secret_len;
-
- /* State pertaining to the pending handshake.
- *
- * TODO(davidben): Move everything not needed after the handshake completes to
- * |hs| and remove this. */
- struct {
- uint8_t finish_md[EVP_MAX_MD_SIZE];
- uint8_t finish_md_len;
- uint8_t peer_finish_md[EVP_MAX_MD_SIZE];
- uint8_t peer_finish_md_len;
-
- int message_type;
-
- /* used to hold the new cipher we are going to use */
- const SSL_CIPHER *new_cipher;
-
- /* used when SSL_ST_FLUSH_DATA is entered */
- int next_state;
-
- int reuse_message;
-
- union {
- /* sent is a bitset where the bits correspond to elements of kExtensions
- * in t1_lib.c. Each bit is set if that extension was sent in a
- * ClientHello. It's not used by servers. */
- uint32_t sent;
- /* received is a bitset, like |sent|, but is used by servers to record
- * which extensions were received from a client. */
- uint32_t received;
- } extensions;
-
- union {
- /* sent is a bitset where the bits correspond to elements of
- * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
- * extension was sent in a ClientHello. It's not used by servers. */
- uint16_t sent;
- /* received is a bitset, like |sent|, but is used by servers to record
- * which custom extensions were received from a client. The bits here
- * correspond to |server_custom_extensions|. */
- uint16_t received;
- } custom_extensions;
-
- /* should_ack_sni is used by a server and indicates that the SNI extension
- * should be echoed in the ServerHello. */
- unsigned should_ack_sni:1;
-
- /* Client-only: ca_names contains the list of CAs received in a
- * CertificateRequest message. */
- STACK_OF(X509_NAME) *ca_names;
-
- /* Client-only: certificate_types contains the set of certificate types
- * received in a CertificateRequest message. */
- uint8_t *certificate_types;
- size_t num_certificate_types;
-
- uint8_t *key_block;
- uint8_t key_block_length;
-
- uint8_t new_mac_secret_len;
- uint8_t new_key_len;
- uint8_t new_fixed_iv_len;
-
- /* cert_request is true if a client certificate was requested and false
- * otherwise. */
- unsigned cert_request:1;
-
- /* certificate_status_expected is true if OCSP stapling was negotiated and
- * the server is expected to send a CertificateStatus message. (This is
- * used on both the client and server sides.) */
- unsigned certificate_status_expected:1;
-
- /* ocsp_stapling_requested is true if a client requested OCSP stapling. */
- unsigned ocsp_stapling_requested:1;
-
- /* Server-only: peer_supported_group_list contains the supported group IDs
- * advertised by the peer. This is only set on the server's end. The server
- * does not advertise this extension to the client. */
- uint16_t *peer_supported_group_list;
- size_t peer_supported_group_list_len;
-
- /* extended_master_secret indicates whether the extended master secret
- * computation is used in this handshake. Note that this is different from
- * whether it was used for the current session. If this is a resumption
- * handshake then EMS might be negotiated in the client and server hello
- * messages, but it doesn't matter if the session that's being resumed
- * didn't use it to create the master secret initially. */
- char extended_master_secret;
-
- /* Client-only: in_false_start is one if there is a pending handshake in
- * False Start. The client may write data at this point. */
- char in_false_start;
-
- /* peer_signature_algorithm is the signature algorithm used to authenticate
- * the peer, or zero if not applicable. */
- uint16_t peer_signature_algorithm;
-
- /* ecdh_ctx is the current ECDH instance. */
- SSL_ECDH_CTX ecdh_ctx;
-
- /* peer_key is the peer's ECDH key. */
- uint8_t *peer_key;
- uint16_t peer_key_len;
-
- /* server_params stores the ServerKeyExchange parameters to be signed while
- * the signature is being computed. */
- uint8_t *server_params;
- uint32_t server_params_len;
- } tmp;
-
- /* new_session is the new mutable session being established by the current
- * handshake. It should not be cached. */
- SSL_SESSION *new_session;
-
- /* established_session is the session established by the connection. This
- * session is only filled upon the completion of the handshake and is
- * immutable. */
- SSL_SESSION *established_session;
-
- /* session_reused indicates whether a session was resumed. */
- unsigned session_reused:1;
-
- /* Connection binding to prevent renegotiation attacks */
- uint8_t previous_client_finished[EVP_MAX_MD_SIZE];
- uint8_t previous_client_finished_len;
- uint8_t previous_server_finished[EVP_MAX_MD_SIZE];
- uint8_t previous_server_finished_len;
- int send_connection_binding;
-
- /* Set if we saw the Next Protocol Negotiation extension from our peer. */
- int next_proto_neg_seen;
-
- /* Next protocol negotiation. For the client, this is the protocol that we
- * sent in NextProtocol and is set when handling ServerHello extensions.
- *
- * For a server, this is the client's selected_protocol from NextProtocol and
- * is set when handling the NextProtocol message, before the Finished
- * message. */
- uint8_t *next_proto_negotiated;
- size_t next_proto_negotiated_len;
-
- /* ALPN information
- * (we are in the process of transitioning from NPN to ALPN.) */
-
- /* In a server these point to the selected ALPN protocol after the
- * ClientHello has been processed. In a client these contain the protocol
- * that the server selected once the ServerHello has been processed. */
- uint8_t *alpn_selected;
- size_t alpn_selected_len;
-
- /* In a client, this means that the server supported Channel ID and that a
- * Channel ID was sent. In a server it means that we echoed support for
- * Channel IDs and that tlsext_channel_id will be valid after the
- * handshake. */
- char tlsext_channel_id_valid;
- /* For a server:
- * If |tlsext_channel_id_valid| is true, then this contains the
- * verified Channel ID from the client: a P256 point, (x,y), where
- * each are big-endian values. */
- uint8_t tlsext_channel_id[64];
-} SSL3_STATE;
-
/* Nodejs compatibility section (hidden).
*
@@ -4839,5 +4564,7 @@
#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113
#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114
+#define SSL_R_TLSV1_UNKNOWN_PSK_IDENTITY 1115
+#define SSL_R_TLSV1_CERTIFICATE_REQUIRED 1116
#endif /* OPENSSL_HEADER_SSL_H */
diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h
index c1db7ab..35d3145 100644
--- a/src/include/openssl/tls1.h
+++ b/src/include/openssl/tls1.h
@@ -160,14 +160,14 @@
#define TLS1_AD_END_OF_EARLY_DATA 1
#define TLS1_AD_DECRYPTION_FAILED 21
#define TLS1_AD_RECORD_OVERFLOW 22
-#define TLS1_AD_UNKNOWN_CA 48 /* fatal */
-#define TLS1_AD_ACCESS_DENIED 49 /* fatal */
-#define TLS1_AD_DECODE_ERROR 50 /* fatal */
+#define TLS1_AD_UNKNOWN_CA 48
+#define TLS1_AD_ACCESS_DENIED 49
+#define TLS1_AD_DECODE_ERROR 50
#define TLS1_AD_DECRYPT_ERROR 51
-#define TLS1_AD_EXPORT_RESTRICTION 60 /* fatal */
-#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */
-#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */
-#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */
+#define TLS1_AD_EXPORT_RESTRICTION 60
+#define TLS1_AD_PROTOCOL_VERSION 70
+#define TLS1_AD_INSUFFICIENT_SECURITY 71
+#define TLS1_AD_INTERNAL_ERROR 80
#define TLS1_AD_USER_CANCELLED 90
#define TLS1_AD_NO_RENEGOTIATION 100
#define TLS1_AD_MISSING_EXTENSION 109
@@ -177,7 +177,8 @@
#define TLS1_AD_UNRECOGNIZED_NAME 112
#define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113
#define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114
-#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */
+#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115
+#define TLS1_AD_CERTIFICATE_REQUIRED 116
/* ExtensionType values from RFC6066 */
#define TLSEXT_TYPE_server_name 0
@@ -204,7 +205,7 @@
/* ExtensionType value from RFC4507 */
#define TLSEXT_TYPE_session_ticket 35
-/* ExtensionType values from draft-ietf-tls-tls13-13 */
+/* ExtensionType values from draft-ietf-tls-tls13-16 */
#define TLSEXT_TYPE_supported_groups 10
#define TLSEXT_TYPE_key_share 40
#define TLSEXT_TYPE_pre_shared_key 41
@@ -418,7 +419,7 @@
#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 \
TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
-/* TLS 1.3 ciphersuites from draft-ietf-tls-tls13-15 */
+/* TLS 1.3 ciphersuites from draft-ietf-tls-tls13-16 */
#define TLS1_CK_AES_128_GCM_SHA256 0x03001301
#define TLS1_CK_AES_256_GCM_SHA384 0x03001302
#define TLS1_CK_CHACHA20_POLY1305_SHA256 0x03001303
@@ -609,7 +610,7 @@
#define TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305 \
TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
-/* TLS 1.3 ciphersuites from draft-ietf-tls-tls13-15 */
+/* TLS 1.3 ciphersuites from draft-ietf-tls-tls13-16 */
#define TLS1_TXT_AES_128_GCM_SHA256 "AEAD-AES128-GCM-SHA256"
#define TLS1_TXT_AES_256_GCM_SHA384 "AEAD-AES256-GCM-SHA384"
#define TLS1_TXT_CHACHA20_POLY1305_SHA256 "AEAD-CHACHA20-POLY1305-SHA256"
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index 51be320..8204486 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -286,7 +286,7 @@
/* standard trust ids */
-#define X509_TRUST_DEFAULT -1 /* Only valid in purpose settings */
+#define X509_TRUST_DEFAULT (-1) /* Only valid in purpose settings */
#define X509_TRUST_COMPAT 1
#define X509_TRUST_SSL_CLIENT 2
diff --git a/src/include/openssl/x509_vfy.h b/src/include/openssl/x509_vfy.h
index 0a45aad..1182bc2 100644
--- a/src/include/openssl/x509_vfy.h
+++ b/src/include/openssl/x509_vfy.h
@@ -110,7 +110,7 @@
*/
/* The following are legacy constants that should not be used. */
-#define X509_LU_RETRY -1
+#define X509_LU_RETRY (-1)
#define X509_LU_FAIL 0
#define X509_LU_X509 1
diff --git a/src/include/openssl/x509v3.h b/src/include/openssl/x509v3.h
index d25a125..4754f71 100644
--- a/src/include/openssl/x509v3.h
+++ b/src/include/openssl/x509v3.h
@@ -230,7 +230,7 @@
/* All existing reasons */
#define CRLDP_ALL_REASONS 0x807f
-#define CRL_REASON_NONE -1
+#define CRL_REASON_NONE (-1)
#define CRL_REASON_UNSPECIFIED 0
#define CRL_REASON_KEY_COMPROMISE 1
#define CRL_REASON_CA_COMPROMISE 2
@@ -376,8 +376,8 @@
/* onlysomereasons present */
#define IDP_REASONS 0x40
-#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \
-",name:", val->name, ",value:", val->value);
+#define X509V3_conf_err(val) ERR_add_error_data(6, "section:", (val)->section, \
+",name:", (val)->name, ",value:", (val)->value);
#define X509V3_set_ctx_test(ctx) \
X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST)
@@ -389,7 +389,7 @@
(X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \
(X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \
NULL, NULL, \
- (void *)table}
+ (void *)(table)}
#define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \
0,0,0,0, \
diff --git a/src/ssl/custom_extensions.c b/src/ssl/custom_extensions.c
index ed802ee..780cdc6 100644
--- a/src/ssl/custom_extensions.c
+++ b/src/ssl/custom_extensions.c
@@ -72,7 +72,7 @@
const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
if (ssl->server &&
- !(ssl->s3->tmp.custom_extensions.received & (1u << i))) {
+ !(ssl->s3->hs->custom_extensions.received & (1u << i))) {
/* Servers cannot echo extensions that the client didn't send. */
continue;
}
@@ -102,8 +102,8 @@
}
if (!ssl->server) {
- assert((ssl->s3->tmp.custom_extensions.sent & (1u << i)) == 0);
- ssl->s3->tmp.custom_extensions.sent |= (1u << i);
+ assert((ssl->s3->hs->custom_extensions.sent & (1u << i)) == 0);
+ ssl->s3->hs->custom_extensions.sent |= (1u << i);
}
break;
@@ -134,7 +134,7 @@
if (/* Unknown extensions are not allowed in a ServerHello. */
ext == NULL ||
/* Also, if we didn't send the extension, that's also unacceptable. */
- !(ssl->s3->tmp.custom_extensions.sent & (1u << index))) {
+ !(ssl->s3->hs->custom_extensions.sent & (1u << index))) {
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
ERR_add_error_dataf("extension: %u", (unsigned)value);
*out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
@@ -162,8 +162,8 @@
return 1;
}
- assert((ssl->s3->tmp.custom_extensions.received & (1u << index)) == 0);
- ssl->s3->tmp.custom_extensions.received |= (1u << index);
+ assert((ssl->s3->hs->custom_extensions.received & (1u << index)) == 0);
+ ssl->s3->hs->custom_extensions.received |= (1u << index);
if (ext->parse_callback &&
!ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
@@ -184,7 +184,7 @@
* can be set on an |SSL_CTX|. It's determined by the size of the bitset used
* to track when an extension has been sent. */
#define MAX_NUM_CUSTOM_EXTENSIONS \
- (sizeof(((struct ssl3_state_st *)NULL)->tmp.custom_extensions.sent) * 8)
+ (sizeof(((SSL_HANDSHAKE *)NULL)->custom_extensions.sent) * 8)
static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack,
unsigned extension_value,
diff --git a/src/ssl/handshake_client.c b/src/ssl/handshake_client.c
index 31394c0..a917e02 100644
--- a/src/ssl/handshake_client.c
+++ b/src/ssl/handshake_client.c
@@ -276,7 +276,7 @@
break;
case SSL3_ST_CR_CERT_STATUS_A:
- if (ssl->s3->tmp.certificate_status_expected) {
+ if (ssl->s3->hs->certificate_status_expected) {
ret = ssl3_get_cert_status(ssl);
if (ret <= 0) {
goto end;
@@ -331,7 +331,7 @@
case SSL3_ST_CW_CERT_A:
case SSL3_ST_CW_CERT_B:
case SSL3_ST_CW_CERT_C:
- if (ssl->s3->tmp.cert_request) {
+ if (ssl->s3->hs->cert_request) {
ret = ssl3_send_client_certificate(ssl);
if (ret <= 0) {
goto end;
@@ -354,7 +354,7 @@
case SSL3_ST_CW_CERT_VRFY_A:
case SSL3_ST_CW_CERT_VRFY_B:
case SSL3_ST_CW_CERT_VRFY_C:
- if (ssl->s3->tmp.cert_request) {
+ if (ssl->s3->hs->cert_request) {
ret = ssl3_send_cert_verify(ssl);
if (ret <= 0) {
goto end;
@@ -382,7 +382,7 @@
case SSL3_ST_CW_NEXT_PROTO_A:
case SSL3_ST_CW_NEXT_PROTO_B:
- if (ssl->s3->next_proto_neg_seen) {
+ if (ssl->s3->hs->next_proto_neg_seen) {
ret = ssl3_send_next_proto(ssl);
if (ret <= 0) {
goto end;
@@ -440,7 +440,7 @@
case SSL3_ST_FALSE_START:
ssl->state = SSL3_ST_CR_SESSION_TICKET_A;
- ssl->s3->tmp.in_false_start = 1;
+ ssl->s3->hs->in_false_start = 1;
ssl_free_wbio_buffer(ssl);
ret = 1;
@@ -541,10 +541,7 @@
ssl->s3->hs = NULL;
const int is_initial_handshake = !ssl->s3->initial_handshake_complete;
-
- ssl->s3->tmp.in_false_start = 0;
ssl->s3->initial_handshake_complete = 1;
-
if (is_initial_handshake) {
/* Renegotiations do not participate in session resumption. */
ssl_update_cache(ssl, SSL_SESS_CACHE_CLIENT);
@@ -1216,18 +1213,13 @@
goto err;
}
- SSL_ECDH_CTX_init_for_dhe(&ssl->s3->tmp.ecdh_ctx, dh);
+ SSL_ECDH_CTX_init_for_dhe(&ssl->s3->hs->ecdh_ctx, dh);
dh = NULL;
/* Save the peer public key for later. */
- size_t peer_key_len;
- if (!CBS_stow(&dh_Ys, &ssl->s3->tmp.peer_key, &peer_key_len)) {
+ if (!CBS_stow(&dh_Ys, &ssl->s3->hs->peer_key, &ssl->s3->hs->peer_key_len)) {
goto err;
}
- /* |dh_Ys| was initialized with CBS_get_u16_length_prefixed, so peer_key_len
- * fits in a uint16_t. */
- assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff);
- ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len;
} else if (alg_k & SSL_kECDHE) {
/* Parse the server parameters. */
uint8_t group_type;
@@ -1251,17 +1243,12 @@
}
/* Initialize ECDH and save the peer public key for later. */
- size_t peer_key_len;
- if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, group_id) ||
- !CBS_stow(&point, &ssl->s3->tmp.peer_key, &peer_key_len)) {
+ if (!SSL_ECDH_CTX_init(&ssl->s3->hs->ecdh_ctx, group_id) ||
+ !CBS_stow(&point, &ssl->s3->hs->peer_key, &ssl->s3->hs->peer_key_len)) {
goto err;
}
- /* |point| was initialized with CBS_get_u8_length_prefixed, so peer_key_len
- * fits in a uint16_t. */
- assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff);
- ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len;
} else if (alg_k & SSL_kCECPQ1) {
- SSL_ECDH_CTX_init_for_cecpq1(&ssl->s3->tmp.ecdh_ctx);
+ SSL_ECDH_CTX_init_for_cecpq1(&ssl->s3->hs->ecdh_ctx);
CBS key;
if (!CBS_get_u16_length_prefixed(&server_key_exchange, &key)) {
al = SSL_AD_DECODE_ERROR;
@@ -1269,14 +1256,9 @@
goto f_err;
}
- size_t peer_key_len;
- if (!CBS_stow(&key, &ssl->s3->tmp.peer_key, &peer_key_len)) {
+ if (!CBS_stow(&key, &ssl->s3->hs->peer_key, &ssl->s3->hs->peer_key_len)) {
goto err;
}
- /* |key| was initialized with CBS_get_u16_length_prefixed, so peer_key_len
- * fits in a uint16_t. */
- assert(sizeof(ssl->s3->tmp.peer_key_len) == 2 && peer_key_len <= 0xffff);
- ssl->s3->tmp.peer_key_len = (uint16_t)peer_key_len;
} else if (!(alg_k & SSL_kPSK)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
@@ -1385,8 +1367,6 @@
return msg_ret;
}
- ssl->s3->tmp.cert_request = 0;
-
if (ssl->s3->tmp.message_type == SSL3_MT_SERVER_HELLO_DONE) {
ssl->s3->tmp.reuse_message = 1;
/* If we get here we don't need the handshake buffer as we won't be doing
@@ -1412,8 +1392,8 @@
return -1;
}
- if (!CBS_stow(&certificate_types, &ssl->s3->tmp.certificate_types,
- &ssl->s3->tmp.num_certificate_types)) {
+ if (!CBS_stow(&certificate_types, &ssl->s3->hs->certificate_types,
+ &ssl->s3->hs->num_certificate_types)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return -1;
}
@@ -1442,9 +1422,9 @@
return -1;
}
- ssl->s3->tmp.cert_request = 1;
- sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
- ssl->s3->tmp.ca_names = ca_sk;
+ ssl->s3->hs->cert_request = 1;
+ sk_X509_NAME_pop_free(ssl->s3->hs->ca_names, X509_NAME_free);
+ ssl->s3->hs->ca_names = ca_sk;
return 1;
}
@@ -1494,7 +1474,7 @@
}
if (!ssl_has_certificate(ssl)) {
- ssl->s3->tmp.cert_request = 0;
+ ssl->s3->hs->cert_request = 0;
/* Without a client certificate, the handshake buffer may be released. */
ssl3_free_handshake_buffer(ssl);
@@ -1625,15 +1605,15 @@
} else if (alg_k & (SSL_kECDHE|SSL_kDHE|SSL_kCECPQ1)) {
/* Generate a keypair and serialize the public half. */
CBB child;
- if (!SSL_ECDH_CTX_add_key(&ssl->s3->tmp.ecdh_ctx, &body, &child)) {
+ if (!SSL_ECDH_CTX_add_key(&ssl->s3->hs->ecdh_ctx, &body, &child)) {
goto err;
}
/* Compute the premaster. */
uint8_t alert;
- if (!SSL_ECDH_CTX_accept(&ssl->s3->tmp.ecdh_ctx, &child, &pms, &pms_len,
- &alert, ssl->s3->tmp.peer_key,
- ssl->s3->tmp.peer_key_len)) {
+ if (!SSL_ECDH_CTX_accept(&ssl->s3->hs->ecdh_ctx, &child, &pms, &pms_len,
+ &alert, ssl->s3->hs->peer_key,
+ ssl->s3->hs->peer_key_len)) {
ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
goto err;
}
@@ -1642,9 +1622,10 @@
}
/* The key exchange state may now be discarded. */
- SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
- OPENSSL_free(ssl->s3->tmp.peer_key);
- ssl->s3->tmp.peer_key = NULL;
+ SSL_ECDH_CTX_cleanup(&ssl->s3->hs->ecdh_ctx);
+ OPENSSL_free(ssl->s3->hs->peer_key);
+ ssl->s3->hs->peer_key = NULL;
+ ssl->s3->hs->peer_key_len = 0;
} else if (alg_k & SSL_kPSK) {
/* For plain PSK, other_secret is a block of 0s with the same length as
* the pre-shared key. */
diff --git a/src/ssl/handshake_server.c b/src/ssl/handshake_server.c
index fd0223f..e018680 100644
--- a/src/ssl/handshake_server.c
+++ b/src/ssl/handshake_server.c
@@ -270,7 +270,7 @@
case SSL3_ST_SW_CERT_STATUS_A:
case SSL3_ST_SW_CERT_STATUS_B:
- if (ssl->s3->tmp.certificate_status_expected) {
+ if (ssl->s3->hs->certificate_status_expected) {
ret = ssl3_send_certificate_status(ssl);
if (ret <= 0) {
goto end;
@@ -302,7 +302,7 @@
case SSL3_ST_SW_CERT_REQ_A:
case SSL3_ST_SW_CERT_REQ_B:
- if (ssl->s3->tmp.cert_request) {
+ if (ssl->s3->hs->cert_request) {
ret = ssl3_send_certificate_request(ssl);
if (ret <= 0) {
goto end;
@@ -324,7 +324,7 @@
break;
case SSL3_ST_SR_CERT_A:
- if (ssl->s3->tmp.cert_request) {
+ if (ssl->s3->hs->cert_request) {
ret = ssl3_get_client_certificate(ssl);
if (ret <= 0) {
goto end;
@@ -366,7 +366,7 @@
break;
case SSL3_ST_SR_NEXT_PROTO_A:
- if (ssl->s3->next_proto_neg_seen) {
+ if (ssl->s3->hs->next_proto_neg_seen) {
ret = ssl3_get_next_proto(ssl);
if (ret <= 0) {
goto end;
@@ -836,7 +836,6 @@
}
ssl->s3->tmp.new_cipher = ssl->session->cipher;
- ssl->s3->tmp.cert_request = 0;
} else {
/* Call |cert_cb| to update server certificates if required. */
if (ssl->cert->cert_cb != NULL) {
@@ -864,18 +863,18 @@
ssl->s3->tmp.new_cipher = c;
/* Determine whether to request a client certificate. */
- ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
+ ssl->s3->hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
/* Only request a certificate if Channel ID isn't negotiated. */
if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) &&
ssl->s3->tlsext_channel_id_valid) {
- ssl->s3->tmp.cert_request = 0;
+ ssl->s3->hs->cert_request = 0;
}
/* CertificateRequest may only be sent in certificate-based ciphers. */
if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) {
- ssl->s3->tmp.cert_request = 0;
+ ssl->s3->hs->cert_request = 0;
}
- if (!ssl->s3->tmp.cert_request) {
+ if (!ssl->s3->hs->cert_request) {
/* OpenSSL returns X509_V_OK when no certificates are requested. This is
* classed by them as a bug, but it's assumed by at least NGINX. */
ssl->s3->new_session->verify_result = X509_V_OK;
@@ -888,7 +887,7 @@
}
/* Release the handshake buffer if client authentication isn't required. */
- if (!ssl->s3->tmp.cert_request) {
+ if (!ssl->s3->hs->cert_request) {
ssl3_free_handshake_buffer(ssl);
}
@@ -1051,13 +1050,13 @@
goto err;
}
- SSL_ECDH_CTX_init_for_dhe(&ssl->s3->tmp.ecdh_ctx, dh);
+ SSL_ECDH_CTX_init_for_dhe(&ssl->s3->hs->ecdh_ctx, dh);
if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
!BN_bn2cbb_padded(&child, BN_num_bytes(params->p), params->p) ||
!CBB_add_u16_length_prefixed(&cbb, &child) ||
!BN_bn2cbb_padded(&child, BN_num_bytes(params->g), params->g) ||
!CBB_add_u16_length_prefixed(&cbb, &child) ||
- !SSL_ECDH_CTX_offer(&ssl->s3->tmp.ecdh_ctx, &child)) {
+ !SSL_ECDH_CTX_offer(&ssl->s3->hs->ecdh_ctx, &child)) {
goto err;
}
} else if (alg_k & SSL_kECDHE) {
@@ -1071,39 +1070,35 @@
ssl->s3->new_session->key_exchange_info = group_id;
/* Set up ECDH, generate a key, and emit the public half. */
- if (!SSL_ECDH_CTX_init(&ssl->s3->tmp.ecdh_ctx, group_id) ||
+ if (!SSL_ECDH_CTX_init(&ssl->s3->hs->ecdh_ctx, group_id) ||
!CBB_add_u8(&cbb, NAMED_CURVE_TYPE) ||
!CBB_add_u16(&cbb, group_id) ||
!CBB_add_u8_length_prefixed(&cbb, &child) ||
- !SSL_ECDH_CTX_offer(&ssl->s3->tmp.ecdh_ctx, &child)) {
+ !SSL_ECDH_CTX_offer(&ssl->s3->hs->ecdh_ctx, &child)) {
goto err;
}
} else if (alg_k & SSL_kCECPQ1) {
- SSL_ECDH_CTX_init_for_cecpq1(&ssl->s3->tmp.ecdh_ctx);
+ SSL_ECDH_CTX_init_for_cecpq1(&ssl->s3->hs->ecdh_ctx);
if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
- !SSL_ECDH_CTX_offer(&ssl->s3->tmp.ecdh_ctx, &child)) {
+ !SSL_ECDH_CTX_offer(&ssl->s3->hs->ecdh_ctx, &child)) {
goto err;
}
} else {
assert(alg_k & SSL_kPSK);
}
- size_t len;
- if (!CBB_finish(&cbb, &ssl->s3->tmp.server_params, &len) ||
- len > 0xffffffffu) {
- OPENSSL_free(ssl->s3->tmp.server_params);
- ssl->s3->tmp.server_params = NULL;
+ if (!CBB_finish(&cbb, &ssl->s3->hs->server_params,
+ &ssl->s3->hs->server_params_len)) {
goto err;
}
- ssl->s3->tmp.server_params_len = (uint32_t)len;
}
/* Assemble the message. */
CBB body;
if (!ssl->method->init_message(ssl, &cbb, &body,
SSL3_MT_SERVER_KEY_EXCHANGE) ||
- !CBB_add_bytes(&body, ssl->s3->tmp.server_params,
- ssl->s3->tmp.server_params_len)) {
+ !CBB_add_bytes(&body, ssl->s3->hs->server_params,
+ ssl->s3->hs->server_params_len)) {
goto err;
}
@@ -1142,11 +1137,11 @@
uint8_t *transcript_data;
size_t transcript_len;
if (!CBB_init(&transcript,
- 2*SSL3_RANDOM_SIZE + ssl->s3->tmp.server_params_len) ||
+ 2*SSL3_RANDOM_SIZE + ssl->s3->hs->server_params_len) ||
!CBB_add_bytes(&transcript, ssl->s3->client_random, SSL3_RANDOM_SIZE) ||
!CBB_add_bytes(&transcript, ssl->s3->server_random, SSL3_RANDOM_SIZE) ||
- !CBB_add_bytes(&transcript, ssl->s3->tmp.server_params,
- ssl->s3->tmp.server_params_len) ||
+ !CBB_add_bytes(&transcript, ssl->s3->hs->server_params,
+ ssl->s3->hs->server_params_len) ||
!CBB_finish(&transcript, &transcript_data, &transcript_len)) {
CBB_cleanup(&transcript);
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
@@ -1182,9 +1177,9 @@
goto err;
}
- OPENSSL_free(ssl->s3->tmp.server_params);
- ssl->s3->tmp.server_params = NULL;
- ssl->s3->tmp.server_params_len = 0;
+ OPENSSL_free(ssl->s3->hs->server_params);
+ ssl->s3->hs->server_params = NULL;
+ ssl->s3->hs->server_params_len = 0;
ssl->state = SSL3_ST_SW_KEY_EXCH_C;
return ssl->method->write_message(ssl);
@@ -1199,8 +1194,8 @@
int have_rsa_sign = 0;
int have_ecdsa_sign = 0;
const uint16_t *sig_algs;
- size_t sig_algs_len = tls12_get_psigalgs(ssl, &sig_algs);
- for (size_t i = 0; i < sig_algs_len; i++) {
+ size_t num_sig_algs = tls12_get_verify_sigalgs(ssl, &sig_algs);
+ for (size_t i = 0; i < num_sig_algs; i++) {
switch (sig_algs[i]) {
case SSL_SIGN_RSA_PKCS1_SHA512:
case SSL_SIGN_RSA_PKCS1_SHA384:
@@ -1247,7 +1242,7 @@
if (ssl3_protocol_version(ssl) >= TLS1_2_VERSION) {
const uint16_t *sigalgs;
- size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
+ size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
goto err;
}
@@ -1291,7 +1286,7 @@
}
static int ssl3_get_client_certificate(SSL *ssl) {
- assert(ssl->s3->tmp.cert_request);
+ assert(ssl->s3->hs->cert_request);
int msg_ret = ssl->method->ssl_get_message(ssl, -1, ssl_hash_message);
if (msg_ret <= 0) {
@@ -1572,7 +1567,7 @@
} else if (alg_k & (SSL_kECDHE|SSL_kDHE|SSL_kCECPQ1)) {
/* Parse the ClientKeyExchange. */
CBS peer_key;
- if (!SSL_ECDH_CTX_get_key(&ssl->s3->tmp.ecdh_ctx, &client_key_exchange,
+ if (!SSL_ECDH_CTX_get_key(&ssl->s3->hs->ecdh_ctx, &client_key_exchange,
&peer_key) ||
CBS_len(&client_key_exchange) != 0) {
al = SSL_AD_DECODE_ERROR;
@@ -1582,7 +1577,7 @@
/* Compute the premaster. */
uint8_t alert;
- if (!SSL_ECDH_CTX_finish(&ssl->s3->tmp.ecdh_ctx, &premaster_secret,
+ if (!SSL_ECDH_CTX_finish(&ssl->s3->hs->ecdh_ctx, &premaster_secret,
&premaster_secret_len, &alert, CBS_data(&peer_key),
CBS_len(&peer_key))) {
al = alert;
@@ -1590,7 +1585,7 @@
}
/* The key exchange state may now be discarded. */
- SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
+ SSL_ECDH_CTX_cleanup(&ssl->s3->hs->ecdh_ctx);
} else if (alg_k & SSL_kPSK) {
/* For plain PSK, other_secret is a block of 0s with the same length as the
* pre-shared key. */
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 3e7c053..7e9954d 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -896,15 +896,43 @@
size_t hash_len;
uint8_t resumption_hash[EVP_MAX_MD_SIZE];
uint8_t secret[EVP_MAX_MD_SIZE];
- uint8_t traffic_secret_0[EVP_MAX_MD_SIZE];
+ uint8_t client_traffic_secret_0[EVP_MAX_MD_SIZE];
+ uint8_t server_traffic_secret_0[EVP_MAX_MD_SIZE];
- /* ecdh_ctx is the active client ECDH offer in TLS 1.3. */
+ union {
+ /* sent is a bitset where the bits correspond to elements of kExtensions
+ * in t1_lib.c. Each bit is set if that extension was sent in a
+ * ClientHello. It's not used by servers. */
+ uint32_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which extensions were received from a client. */
+ uint32_t received;
+ } extensions;
+
+ union {
+ /* sent is a bitset where the bits correspond to elements of
+ * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
+ * extension was sent in a ClientHello. It's not used by servers. */
+ uint16_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which custom extensions were received from a client. The bits here
+ * correspond to |server_custom_extensions|. */
+ uint16_t received;
+ } custom_extensions;
+
+ /* ecdh_ctx is the current ECDH instance. */
SSL_ECDH_CTX ecdh_ctx;
+ unsigned received_hello_retry_request:1;
+
/* retry_group is the group ID selected by the server in HelloRetryRequest in
* TLS 1.3. */
uint16_t retry_group;
+ /* cookie is the value of the cookie received from the server, if any. */
+ uint8_t *cookie;
+ size_t cookie_len;
+
/* key_share_bytes is the value of the previously sent KeyShare extension by
* the client in TLS 1.3. */
uint8_t *key_share_bytes;
@@ -922,11 +950,60 @@
/* num_peer_sigalgs is the number of entries in |peer_sigalgs|. */
size_t num_peer_sigalgs;
+ /* peer_supported_group_list contains the supported group IDs advertised by
+ * the peer. This is only set on the server's end. The server does not
+ * advertise this extension to the client. */
+ uint16_t *peer_supported_group_list;
+ size_t peer_supported_group_list_len;
+
+ /* peer_key is the peer's ECDH key for a TLS 1.2 client. */
+ uint8_t *peer_key;
+ size_t peer_key_len;
+
+ /* server_params, in TLS 1.2, stores the ServerKeyExchange parameters to be
+ * signed while the signature is being computed. */
+ uint8_t *server_params;
+ size_t server_params_len;
+
+ /* session_tickets_sent, in TLS 1.3, is the number of tickets the server has
+ * sent. */
uint8_t session_tickets_sent;
+ /* cert_request is one if a client certificate was requested and zero
+ * otherwise. */
+ unsigned cert_request:1;
+
+ /* certificate_status_expected is one if OCSP stapling was negotiated and the
+ * server is expected to send a CertificateStatus message. (This is used on
+ * both the client and server sides.) */
+ unsigned certificate_status_expected:1;
+
+ /* ocsp_stapling_requested is one if a client requested OCSP stapling. */
+ unsigned ocsp_stapling_requested:1;
+
+ /* should_ack_sni is used by a server and indicates that the SNI extension
+ * should be echoed in the ServerHello. */
+ unsigned should_ack_sni:1;
+
+ /* in_false_start is one if there is a pending client handshake in False
+ * Start. The client may write data at this point. */
+ unsigned in_false_start:1;
+
+ /* next_proto_neg_seen is one of NPN was negotiated. */
+ unsigned next_proto_neg_seen:1;
+
/* peer_psk_identity_hint, on the client, is the psk_identity_hint sent by the
* server when using a TLS 1.2 PSK key exchange. */
char *peer_psk_identity_hint;
+
+ /* ca_names, on the client, contains the list of CAs received in a
+ * CertificateRequest message. */
+ STACK_OF(X509_NAME) *ca_names;
+
+ /* certificate_types, on the client, contains the set of certificate types
+ * received in a CertificateRequest message. */
+ uint8_t *certificate_types;
+ size_t num_certificate_types;
} /* SSL_HANDSHAKE */;
SSL_HANDSHAKE *ssl_handshake_new(enum ssl_hs_wait_t (*do_handshake)(SSL *ssl));
@@ -1024,6 +1101,7 @@
ssl_grease_extension1,
ssl_grease_extension2,
ssl_grease_version,
+ ssl_grease_ticket_extension,
};
/* ssl_get_grease_value returns a GREASE value for |ssl|. For a given
@@ -1033,6 +1111,27 @@
uint16_t ssl_get_grease_value(const SSL *ssl, enum ssl_grease_index_t index);
+/* Signature algorithms. */
+
+/* tls1_parse_peer_sigalgs parses |sigalgs| as the list of peer signature
+ * algorithms and them on |ssl|. It returns one on success and zero on error. */
+int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *sigalgs);
+
+/* tls1_choose_signature_algorithm sets |*out| to a signature algorithm for use
+ * with |ssl|'s private key based on the peer's preferences and the algorithms
+ * supported. It returns one on success and zero on error. */
+int tls1_choose_signature_algorithm(SSL *ssl, uint16_t *out);
+
+/* tls12_get_verify_sigalgs sets |*out| to the signature algorithms acceptable
+ * for the peer signature and returns the length of the list. */
+size_t tls12_get_verify_sigalgs(const SSL *ssl, const uint16_t **out);
+
+/* tls12_check_peer_sigalg checks if |sigalg| is acceptable for the peer
+ * signature. It returns one on success and zero on error, setting |*out_alert|
+ * to an alert to send. */
+int tls12_check_peer_sigalg(SSL *ssl, int *out_alert, uint16_t sigalg);
+
+
/* Underdocumented functions.
*
* Functions below here haven't been touched up and may be underdocumented. */
@@ -1184,6 +1283,207 @@
int (*final_finish_mac)(SSL *ssl, int from_server, uint8_t *out);
};
+typedef struct ssl3_record_st {
+ /* type is the record type. */
+ uint8_t type;
+ /* length is the number of unconsumed bytes in the record. */
+ uint16_t length;
+ /* data is a non-owning pointer to the first unconsumed byte of the record. */
+ uint8_t *data;
+} SSL3_RECORD;
+
+typedef struct ssl3_buffer_st {
+ /* buf is the memory allocated for this buffer. */
+ uint8_t *buf;
+ /* offset is the offset into |buf| which the buffer contents start at. */
+ uint16_t offset;
+ /* len is the length of the buffer contents from |buf| + |offset|. */
+ uint16_t len;
+ /* cap is how much memory beyond |buf| + |offset| is available. */
+ uint16_t cap;
+} SSL3_BUFFER;
+
+/* An ssl_shutdown_t describes the shutdown state of one end of the connection,
+ * whether it is alive or has been shutdown via close_notify or fatal alert. */
+enum ssl_shutdown_t {
+ ssl_shutdown_none = 0,
+ ssl_shutdown_close_notify = 1,
+ ssl_shutdown_fatal_alert = 2,
+};
+
+typedef struct ssl3_state_st {
+ uint8_t read_sequence[8];
+ uint8_t write_sequence[8];
+
+ uint8_t server_random[SSL3_RANDOM_SIZE];
+ uint8_t client_random[SSL3_RANDOM_SIZE];
+
+ /* have_version is true if the connection's final version is known. Otherwise
+ * the version has not been negotiated yet. */
+ unsigned have_version:1;
+
+ /* v2_hello_done is true if the peer's V2ClientHello, if any, has been handled
+ * and future messages should use the record layer. */
+ unsigned v2_hello_done:1;
+
+ /* initial_handshake_complete is true if the initial handshake has
+ * completed. */
+ unsigned initial_handshake_complete:1;
+
+ /* read_buffer holds data from the transport to be processed. */
+ SSL3_BUFFER read_buffer;
+ /* write_buffer holds data to be written to the transport. */
+ SSL3_BUFFER write_buffer;
+
+ SSL3_RECORD rrec; /* each decoded record goes in here */
+
+ /* partial write - check the numbers match */
+ unsigned int wnum; /* number of bytes sent so far */
+ int wpend_tot; /* number bytes written */
+ int wpend_type;
+ int wpend_ret; /* number of bytes submitted */
+ const uint8_t *wpend_buf;
+
+ /* handshake_buffer, if non-NULL, contains the handshake transcript. */
+ BUF_MEM *handshake_buffer;
+ /* handshake_hash, if initialized with an |EVP_MD|, maintains the handshake
+ * hash. For TLS 1.1 and below, it is the SHA-1 half. */
+ EVP_MD_CTX handshake_hash;
+ /* handshake_md5, if initialized with an |EVP_MD|, maintains the MD5 half of
+ * the handshake hash for TLS 1.1 and below. */
+ EVP_MD_CTX handshake_md5;
+
+ /* recv_shutdown is the shutdown state for the receive half of the
+ * connection. */
+ enum ssl_shutdown_t recv_shutdown;
+
+ /* recv_shutdown is the shutdown state for the send half of the connection. */
+ enum ssl_shutdown_t send_shutdown;
+
+ int alert_dispatch;
+ uint8_t send_alert[2];
+
+ int total_renegotiations;
+
+ /* empty_record_count is the number of consecutive empty records received. */
+ uint8_t empty_record_count;
+
+ /* warning_alert_count is the number of consecutive warning alerts
+ * received. */
+ uint8_t warning_alert_count;
+
+ /* key_update_count is the number of consecutive KeyUpdates received. */
+ uint8_t key_update_count;
+
+ /* aead_read_ctx is the current read cipher state. */
+ SSL_AEAD_CTX *aead_read_ctx;
+
+ /* aead_write_ctx is the current write cipher state. */
+ SSL_AEAD_CTX *aead_write_ctx;
+
+ /* enc_method is the method table corresponding to the current protocol
+ * version. */
+ const SSL3_ENC_METHOD *enc_method;
+
+ /* pending_message is the current outgoing handshake message. */
+ uint8_t *pending_message;
+ uint32_t pending_message_len;
+
+ /* hs is the handshake state for the current handshake or NULL if there isn't
+ * one. */
+ SSL_HANDSHAKE *hs;
+
+ uint8_t write_traffic_secret[EVP_MAX_MD_SIZE];
+ uint8_t write_traffic_secret_len;
+ uint8_t read_traffic_secret[EVP_MAX_MD_SIZE];
+ uint8_t read_traffic_secret_len;
+ uint8_t exporter_secret[EVP_MAX_MD_SIZE];
+ uint8_t exporter_secret_len;
+
+ /* State pertaining to the pending handshake.
+ *
+ * TODO(davidben): Move everything not needed after the handshake completes to
+ * |hs| and remove this. */
+ struct {
+ int message_type;
+
+ /* used to hold the new cipher we are going to use */
+ const SSL_CIPHER *new_cipher;
+
+ /* used when SSL_ST_FLUSH_DATA is entered */
+ int next_state;
+
+ int reuse_message;
+
+ uint8_t *key_block;
+ uint8_t key_block_length;
+
+ uint8_t new_mac_secret_len;
+ uint8_t new_key_len;
+ uint8_t new_fixed_iv_len;
+
+ /* extended_master_secret indicates whether the extended master secret
+ * computation is used in this handshake. Note that this is different from
+ * whether it was used for the current session. If this is a resumption
+ * handshake then EMS might be negotiated in the client and server hello
+ * messages, but it doesn't matter if the session that's being resumed
+ * didn't use it to create the master secret initially. */
+ char extended_master_secret;
+
+ /* peer_signature_algorithm is the signature algorithm used to authenticate
+ * the peer, or zero if not applicable. */
+ uint16_t peer_signature_algorithm;
+ } tmp;
+
+ /* new_session is the new mutable session being established by the current
+ * handshake. It should not be cached. */
+ SSL_SESSION *new_session;
+
+ /* established_session is the session established by the connection. This
+ * session is only filled upon the completion of the handshake and is
+ * immutable. */
+ SSL_SESSION *established_session;
+
+ /* session_reused indicates whether a session was resumed. */
+ unsigned session_reused:1;
+
+ /* Connection binding to prevent renegotiation attacks */
+ uint8_t previous_client_finished[12];
+ uint8_t previous_client_finished_len;
+ uint8_t previous_server_finished[12];
+ uint8_t previous_server_finished_len;
+ int send_connection_binding;
+
+ /* Next protocol negotiation. For the client, this is the protocol that we
+ * sent in NextProtocol and is set when handling ServerHello extensions.
+ *
+ * For a server, this is the client's selected_protocol from NextProtocol and
+ * is set when handling the NextProtocol message, before the Finished
+ * message. */
+ uint8_t *next_proto_negotiated;
+ size_t next_proto_negotiated_len;
+
+ /* ALPN information
+ * (we are in the process of transitioning from NPN to ALPN.) */
+
+ /* In a server these point to the selected ALPN protocol after the
+ * ClientHello has been processed. In a client these contain the protocol
+ * that the server selected once the ServerHello has been processed. */
+ uint8_t *alpn_selected;
+ size_t alpn_selected_len;
+
+ /* In a client, this means that the server supported Channel ID and that a
+ * Channel ID was sent. In a server it means that we echoed support for
+ * Channel IDs and that tlsext_channel_id will be valid after the
+ * handshake. */
+ char tlsext_channel_id_valid;
+ /* For a server:
+ * If |tlsext_channel_id_valid| is true, then this contains the
+ * verified Channel ID from the client: a P256 point, (x,y), where
+ * each are big-endian values. */
+ uint8_t tlsext_channel_id[64];
+} SSL3_STATE;
+
/* lengths of messages */
#define DTLS1_COOKIE_LENGTH 256
@@ -1269,13 +1569,18 @@
extern const SSL3_ENC_METHOD TLSv1_enc_data;
extern const SSL3_ENC_METHOD SSLv3_enc_data;
-/* From draft-ietf-tls-tls13-15, used in determining PSK modes. */
+/* From draft-ietf-tls-tls13-16, used in determining PSK modes. */
#define SSL_PSK_KE 0x0
#define SSL_PSK_DHE_KE 0x1
#define SSL_PSK_AUTH 0x0
#define SSL_PSK_SIGN_AUTH 0x1
+/* From draft-ietf-tls-tls13-16, used in determining whether to respond with a
+ * KeyUpdate. */
+#define SSL_KEY_UPDATE_NOT_REQUESTED 0
+#define SSL_KEY_UPDATE_REQUESTED 1
+
CERT *ssl_cert_new(void);
CERT *ssl_cert_dup(CERT *cert);
void ssl_cert_clear_certs(CERT *c);
@@ -1453,15 +1758,12 @@
size_t premaster_len);
/* tls1_get_grouplist sets |*out_group_ids| and |*out_group_ids_len| to the
- * list of allowed group IDs. If |get_peer_groups| is non-zero, return the
- * peer's group list. Otherwise, return the preferred list. */
-void tls1_get_grouplist(SSL *ssl, int get_peer_groups,
- const uint16_t **out_group_ids,
+ * locally-configured group preference list. */
+void tls1_get_grouplist(SSL *ssl, const uint16_t **out_group_ids,
size_t *out_group_ids_len);
-/* tls1_check_group_id returns one if |group_id| is consistent with both our
- * and the peer's group preferences. Note: if called as the client, only our
- * preferences are checked; the peer (the server) does not send preferences. */
+/* tls1_check_group_id returns one if |group_id| is consistent with
+ * locally-configured group preferences. */
int tls1_check_group_id(SSL *ssl, uint16_t group_id);
/* tls1_get_shared_group sets |*out_group_id| to the first preferred shared
@@ -1483,11 +1785,6 @@
int tls1_set_curves_list(uint16_t **out_group_ids, size_t *out_group_ids_len,
const char *curves);
-/* tls1_check_ec_cert returns one if |x| is an ECC certificate with curve and
- * point format compatible with the client's preferences. Otherwise it returns
- * zero. */
-int tls1_check_ec_cert(SSL *ssl, X509 *x);
-
/* ssl_add_clienthello_tlsext writes ClientHello extensions to |out|. It
* returns one on success and zero on failure. The |header_len| argument is the
* length of the ClientHello written so far and is used to compute the padding
@@ -1536,20 +1833,7 @@
uint16_t ssl3_protocol_version(const SSL *ssl);
uint32_t ssl_get_algorithm_prf(const SSL *ssl);
-int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *sigalgs);
-/* tls1_choose_signature_algorithm sets |*out| to a signature algorithm for use
- * with |ssl|'s private key based on the peer's preferences and the digests
- * supported. It returns one on success and zero on error. */
-int tls1_choose_signature_algorithm(SSL *ssl, uint16_t *out);
-
-size_t tls12_get_psigalgs(SSL *ssl, const uint16_t **psigs);
-
-/* tls12_check_peer_sigalg checks that |signature_algorithm| is consistent with
- * |ssl|'s sent, supported signature algorithms and returns 1. Otherwise it
- * returns 0 and writes an alert into |*out_alert|. */
-int tls12_check_peer_sigalg(SSL *ssl, int *out_alert,
- uint16_t signature_algorithm);
void ssl_set_client_disabled(SSL *ssl);
void ssl_get_current_time(const SSL *ssl, struct timeval *out_clock);
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index 52c93aa..1e7e4e1 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -148,12 +148,21 @@
}
OPENSSL_cleanse(hs->secret, sizeof(hs->secret));
- OPENSSL_cleanse(hs->traffic_secret_0, sizeof(hs->traffic_secret_0));
+ OPENSSL_cleanse(hs->client_traffic_secret_0,
+ sizeof(hs->client_traffic_secret_0));
+ OPENSSL_cleanse(hs->server_traffic_secret_0,
+ sizeof(hs->server_traffic_secret_0));
SSL_ECDH_CTX_cleanup(&hs->ecdh_ctx);
+ OPENSSL_free(hs->cookie);
OPENSSL_free(hs->key_share_bytes);
OPENSSL_free(hs->public_key);
OPENSSL_free(hs->peer_sigalgs);
+ OPENSSL_free(hs->peer_supported_group_list);
+ OPENSSL_free(hs->peer_key);
+ OPENSSL_free(hs->server_params);
OPENSSL_free(hs->peer_psk_identity_hint);
+ sk_X509_NAME_pop_free(hs->ca_names, X509_NAME_free);
+ OPENSSL_free(hs->certificate_types);
OPENSSL_free(hs);
}
@@ -235,12 +244,12 @@
return ssl->method->write_message(ssl);
}
- int n = ssl->s3->enc_method->final_finish_mac(ssl, ssl->server,
- ssl->s3->tmp.finish_md);
- if (n == 0) {
+ uint8_t finished[EVP_MAX_MD_SIZE];
+ size_t finished_len =
+ ssl->s3->enc_method->final_finish_mac(ssl, ssl->server, finished);
+ if (finished_len == 0) {
return 0;
}
- ssl->s3->tmp.finish_md_len = n;
/* Log the master secret, if logging is enabled. */
if (!ssl_log_secret(ssl, "CLIENT_RANDOM",
@@ -249,21 +258,26 @@
return 0;
}
- /* Copy the finished so we can use it for renegotiation checks */
- if (ssl->server) {
- assert(n <= EVP_MAX_MD_SIZE);
- memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.finish_md, n);
- ssl->s3->previous_server_finished_len = n;
- } else {
- assert(n <= EVP_MAX_MD_SIZE);
- memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.finish_md, n);
- ssl->s3->previous_client_finished_len = n;
+ /* 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 -1;
+ }
+
+ if (ssl->server) {
+ memcpy(ssl->s3->previous_server_finished, finished, finished_len);
+ ssl->s3->previous_server_finished_len = finished_len;
+ } else {
+ memcpy(ssl->s3->previous_client_finished, finished, finished_len);
+ ssl->s3->previous_client_finished_len = finished_len;
+ }
}
CBB cbb, body;
if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_FINISHED) ||
- !CBB_add_bytes(&body, ssl->s3->tmp.finish_md,
- ssl->s3->tmp.finish_md_len) ||
+ !CBB_add_bytes(&body, finished, finished_len) ||
!ssl->method->finish_message(ssl, &cbb)) {
OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
CBB_cleanup(&cbb);
@@ -274,21 +288,7 @@
return ssl->method->write_message(ssl);
}
-/* ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
- * so far. */
-static void ssl3_take_mac(SSL *ssl) {
- /* If no new cipher setup then return immediately: other functions will set
- * the appropriate error. */
- if (ssl->s3->tmp.new_cipher == NULL) {
- return;
- }
-
- ssl->s3->tmp.peer_finish_md_len = ssl->s3->enc_method->final_finish_mac(
- ssl, !ssl->server, ssl->s3->tmp.peer_finish_md);
-}
-
int ssl3_get_finished(SSL *ssl) {
- int al;
int ret = ssl->method->ssl_get_message(ssl, SSL3_MT_FINISHED,
ssl_dont_hash_message);
if (ret <= 0) {
@@ -296,44 +296,43 @@
}
/* Snapshot the finished hash before incorporating the new message. */
- ssl3_take_mac(ssl);
- if (!ssl->method->hash_current_message(ssl)) {
- goto err;
+ uint8_t finished[EVP_MAX_MD_SIZE];
+ size_t finished_len =
+ ssl->s3->enc_method->final_finish_mac(ssl, !ssl->server, finished);
+ if (finished_len == 0 ||
+ !ssl->method->hash_current_message(ssl)) {
+ return -1;
}
- size_t finished_len = ssl->s3->tmp.peer_finish_md_len;
-
int finished_ok = ssl->init_num == finished_len &&
- CRYPTO_memcmp(ssl->init_msg, ssl->s3->tmp.peer_finish_md,
- finished_len) == 0;
+ CRYPTO_memcmp(ssl->init_msg, finished, finished_len) == 0;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
finished_ok = 1;
#endif
if (!finished_ok) {
- al = SSL_AD_DECRYPT_ERROR;
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR);
OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
- goto f_err;
+ return -1;
}
- /* Copy the finished so we can use it for renegotiation checks */
- if (ssl->server) {
- assert(finished_len <= EVP_MAX_MD_SIZE);
- memcpy(ssl->s3->previous_client_finished, ssl->s3->tmp.peer_finish_md,
- finished_len);
- ssl->s3->previous_client_finished_len = finished_len;
- } else {
- assert(finished_len <= EVP_MAX_MD_SIZE);
- memcpy(ssl->s3->previous_server_finished, ssl->s3->tmp.peer_finish_md,
- finished_len);
- ssl->s3->previous_server_finished_len = finished_len;
+ /* 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 -1;
+ }
+
+ if (ssl->server) {
+ memcpy(ssl->s3->previous_client_finished, finished, finished_len);
+ ssl->s3->previous_client_finished_len = finished_len;
+ } else {
+ memcpy(ssl->s3->previous_server_finished, finished, finished_len);
+ ssl->s3->previous_server_finished_len = finished_len;
+ }
}
return 1;
-
-f_err:
- ssl3_send_alert(ssl, SSL3_AL_FATAL, al);
-err:
- return 0;
}
int ssl3_send_change_cipher_spec(SSL *ssl) {
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 2a7bbae..69d3a9d 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -203,13 +203,7 @@
ssl3_cleanup_key_block(ssl);
ssl_read_buffer_clear(ssl);
ssl_write_buffer_clear(ssl);
- SSL_ECDH_CTX_cleanup(&ssl->s3->tmp.ecdh_ctx);
- OPENSSL_free(ssl->s3->tmp.peer_key);
- OPENSSL_free(ssl->s3->tmp.server_params);
- sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
- OPENSSL_free(ssl->s3->tmp.certificate_types);
- OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
SSL_SESSION_free(ssl->s3->new_session);
SSL_SESSION_free(ssl->s3->established_session);
ssl3_free_handshake_buffer(ssl);
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 0c5a7af..55b464f 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -395,7 +395,11 @@
* |SSL_set_connect_state|. If |handshake_func| is NULL, |ssl| is in an
* indeterminate mode and |ssl->server| is unset. */
if (ssl->handshake_func != NULL && !ssl->server) {
- return ssl->s3->tmp.ca_names;
+ if (ssl->s3->hs != NULL) {
+ return ssl->s3->hs->ca_names;
+ }
+
+ return NULL;
}
if (ssl->client_CA != NULL) {
@@ -774,6 +778,8 @@
}
int ssl_check_leaf_certificate(SSL *ssl, X509 *leaf) {
+ assert(ssl3_protocol_version(ssl) < TLS1_3_VERSION);
+
int ret = 0;
EVP_PKEY *pkey = X509_get_pubkey(leaf);
if (pkey == NULL) {
@@ -800,7 +806,18 @@
goto err;
}
- if (!tls1_check_ec_cert(ssl, leaf)) {
+ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
+ if (ec_key == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
+ goto err;
+ }
+
+ /* Check the key's group and point format are acceptable. */
+ uint16_t group_id;
+ if (!ssl_nid_to_group_id(
+ &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) ||
+ !tls1_check_group_id(ssl, group_id) ||
+ EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) {
OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT);
goto err;
}
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index f17dc0a..491c408 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -151,7 +151,6 @@
#include <openssl/lhash.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
-#include <openssl/x509v3.h>
#include "internal.h"
#include "../crypto/internal.h"
@@ -636,8 +635,10 @@
}
static int ssl_do_renegotiate(SSL *ssl) {
- /* We do not accept renegotiations as a server. */
- if (ssl->server) {
+ /* We do not accept renegotiations as a server or SSL 3.0. SSL 3.0 will be
+ * removed entirely in the future and requires retaining more data for
+ * renegotiation_info. */
+ if (ssl->server || ssl->version == SSL3_VERSION) {
goto no_renegotiation;
}
@@ -1065,6 +1066,13 @@
int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
size_t max_out) {
+ /* 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) {
+ goto err;
+ }
+
/* The tls-unique value is the first Finished message in the handshake, which
* is the client's in a full handshake and the server's for a resumption. See
* https://tools.ietf.org/html/rfc5929#section-3.1. */
@@ -1079,11 +1087,6 @@
finished_len = ssl->s3->previous_server_finished_len;
}
- if (!ssl->s3->initial_handshake_complete ||
- ssl->version < TLS1_VERSION) {
- goto err;
- }
-
*out_len = finished_len;
if (finished_len > max_out) {
*out_len = max_out;
@@ -1232,32 +1235,45 @@
return 1;
}
-size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) {
- size_t ret = 0;
+static size_t copy_finished(void *out, size_t out_len, const uint8_t *in,
+ size_t in_len) {
+ if (out_len > in_len) {
+ out_len = in_len;
+ }
+ memcpy(out, in, out_len);
+ return in_len;
+}
- if (ssl->s3 != NULL) {
- ret = ssl->s3->tmp.finish_md_len;
- if (count > ret) {
- count = ret;
- }
- memcpy(buf, ssl->s3->tmp.finish_md, count);
+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) {
+ return 0;
}
- return ret;
+ if (ssl->server) {
+ return copy_finished(buf, count, ssl->s3->previous_server_finished,
+ ssl->s3->previous_server_finished_len);
+ }
+
+ return copy_finished(buf, count, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len);
}
size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) {
- size_t ret = 0;
-
- if (ssl->s3 != NULL) {
- ret = ssl->s3->tmp.peer_finish_md_len;
- if (count > ret) {
- count = ret;
- }
- memcpy(buf, ssl->s3->tmp.peer_finish_md, count);
+ if (!ssl->s3->initial_handshake_complete ||
+ ssl3_protocol_version(ssl) < TLS1_VERSION ||
+ ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
+ return 0;
}
- return ret;
+ if (ssl->server) {
+ return copy_finished(buf, count, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len);
+ }
+
+ return copy_finished(buf, count, ssl->s3->previous_server_finished,
+ ssl->s3->previous_server_finished_len);
}
int SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; }
@@ -2021,12 +2037,12 @@
}
size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
- if (ssl->server) {
+ if (ssl->server || ssl->s3->hs == NULL) {
*out_types = NULL;
return 0;
}
- *out_types = ssl->s3->tmp.certificate_types;
- return ssl->s3->tmp.num_certificate_types;
+ *out_types = ssl->s3->hs->certificate_types;
+ return ssl->s3->hs->num_certificate_types;
}
void ssl_get_compatible_server_ciphers(SSL *ssl, uint32_t *out_mask_k,
@@ -2046,17 +2062,7 @@
mask_k |= SSL_kRSA;
mask_a |= SSL_aRSA;
} else if (ssl_is_ecdsa_key_type(type)) {
- /* An ECC certificate may be usable for ECDSA cipher suites depending on
- * the key usage extension and on the client's group preferences. */
- X509 *x = ssl->cert->x509;
- /* This call populates extension flags (ex_flags). */
- X509_check_purpose(x, -1, 0);
- int ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
- ? (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)
- : 1;
- if (ecdsa_ok && tls1_check_ec_cert(ssl, x)) {
- mask_a |= SSL_aECDSA;
- }
+ mask_a |= SSL_aECDSA;
}
}
@@ -2674,7 +2680,10 @@
}
int SSL_in_false_start(const SSL *ssl) {
- return ssl->s3->tmp.in_false_start;
+ if (ssl->s3->hs == NULL) {
+ return 0;
+ }
+ return ssl->s3->hs->in_false_start;
}
int SSL_cutthrough_complete(const SSL *ssl) {
@@ -2694,7 +2703,8 @@
/* 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 || ssl->s3->next_proto_neg_seen) &&
+ (ssl->s3->alpn_selected != NULL ||
+ ssl->s3->next_proto_negotiated != NULL) &&
cipher != NULL &&
(cipher->algorithm_mkey == SSL_kECDHE ||
cipher->algorithm_mkey == SSL_kCECPQ1) &&
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index 6f8ceae..29e5f19 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -65,6 +65,7 @@
#include <openssl/mem.h>
#include <openssl/type_check.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include "internal.h"
@@ -217,6 +218,19 @@
return 0;
}
+ /* An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA
+ * certificates, so sanity-check the key usage extension. */
+ if (pkey->type == EVP_PKEY_EC) {
+ /* This call populates extension flags (ex_flags). */
+ X509_check_purpose(x, -1, 0);
+ if ((x->ex_flags & EXFLAG_KUSAGE) &&
+ !(x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ EVP_PKEY_free(pkey);
+ return 0;
+ }
+ }
+
if (c->privatekey != NULL) {
/* Sanity-check that the private key and the certificate match, unless the
* key is opaque (in case of, say, a smartcard). */
@@ -338,6 +352,8 @@
static int set_signing_algorithm_prefs(CERT *cert, const uint16_t *prefs,
size_t num_prefs) {
+ OPENSSL_free(cert->sigalgs);
+
cert->num_sigalgs = 0;
cert->sigalgs = BUF_memdup(prefs, num_prefs * sizeof(prefs[0]));
if (cert->sigalgs == NULL) {
diff --git a/src/ssl/ssl_stat.c b/src/ssl/ssl_stat.c
index 3fdc6e5..1ed0bdf 100644
--- a/src/ssl/ssl_stat.c
+++ b/src/ssl/ssl_stat.c
@@ -476,6 +476,9 @@
case TLS1_AD_INTERNAL_ERROR:
return "internal error";
+ case SSL3_AD_INAPPROPRIATE_FALLBACK:
+ return "inappropriate fallback";
+
case TLS1_AD_USER_CANCELLED:
return "user canceled";
@@ -500,8 +503,8 @@
case TLS1_AD_UNKNOWN_PSK_IDENTITY:
return "unknown PSK identity";
- case SSL3_AD_INAPPROPRIATE_FALLBACK:
- return "inappropriate fallback";
+ case TLS1_AD_CERTIFICATE_REQUIRED:
+ return "certificate required";
default:
return "unknown";
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 419cce5..cfce2d0 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -924,7 +924,10 @@
return 0;
}
bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
- if (!ssl || !SSL_set_session(ssl.get(), session.get())) {
+ // Test at TLS 1.2. TLS 1.3 adds enough extensions that the ClientHello is
+ // longer than our test vectors.
+ if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
+ !SSL_set_max_proto_version(ssl.get(), TLS1_2_VERSION)) {
return 0;
}
std::vector<uint8_t> client_hello;
@@ -1270,70 +1273,100 @@
return true;
}
-static bool TestSequenceNumber(bool dtls) {
- bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
- bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(dtls ? DTLS_method() : TLS_method()));
- if (!client_ctx || !server_ctx) {
- return false;
- }
+static uint16_t kTLSVersions[] = {
+ SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
+};
- bssl::UniquePtr<X509> cert = GetTestCertificate();
- bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
- if (!cert || !key ||
- !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
- !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
- return false;
- }
+static uint16_t kDTLSVersions[] = {
+ DTLS1_VERSION, DTLS1_2_VERSION,
+};
- bssl::UniquePtr<SSL> client, server;
- if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
- server_ctx.get(), nullptr /* no session */)) {
- return false;
- }
+static bool TestSequenceNumber() {
+ for (bool is_dtls : std::vector<bool>{false, true}) {
+ const SSL_METHOD *method = is_dtls ? DTLS_method() : TLS_method();
+ const uint16_t *versions = is_dtls ? kDTLSVersions : kTLSVersions;
+ size_t num_versions = is_dtls ? OPENSSL_ARRAY_SIZE(kDTLSVersions)
+ : OPENSSL_ARRAY_SIZE(kTLSVersions);
+ for (size_t i = 0; i < num_versions; i++) {
+ uint16_t version = versions[i];
+ bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(method));
+ bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(method));
+ if (!server_ctx || !client_ctx ||
+ !SSL_CTX_set_min_proto_version(client_ctx.get(), version) ||
+ !SSL_CTX_set_max_proto_version(client_ctx.get(), version) ||
+ !SSL_CTX_set_min_proto_version(server_ctx.get(), version) ||
+ !SSL_CTX_set_max_proto_version(server_ctx.get(), version)) {
+ return false;
+ }
- uint64_t client_read_seq = SSL_get_read_sequence(client.get());
- uint64_t client_write_seq = SSL_get_write_sequence(client.get());
- uint64_t server_read_seq = SSL_get_read_sequence(server.get());
- uint64_t server_write_seq = SSL_get_write_sequence(server.get());
+ bssl::UniquePtr<X509> cert = GetTestCertificate();
+ bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
+ if (!cert || !key ||
+ !SSL_CTX_use_certificate(server_ctx.get(), cert.get()) ||
+ !SSL_CTX_use_PrivateKey(server_ctx.get(), key.get())) {
+ return false;
+ }
- if (dtls) {
- // Both client and server must be at epoch 1.
- if (EpochFromSequence(client_read_seq) != 1 ||
- EpochFromSequence(client_write_seq) != 1 ||
- EpochFromSequence(server_read_seq) != 1 ||
- EpochFromSequence(server_write_seq) != 1) {
- fprintf(stderr, "Bad epochs.\n");
- return false;
+ bssl::UniquePtr<SSL> client, server;
+ if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
+ server_ctx.get(), nullptr /* no session */)) {
+ return false;
+ }
+
+ // Drain any post-handshake messages to ensure there are no unread records
+ // on either end.
+ uint8_t byte = 0;
+ if (SSL_read(client.get(), &byte, 1) > 0 ||
+ SSL_read(server.get(), &byte, 1) > 0) {
+ fprintf(stderr, "Received unexpected data.\n");
+ return false;
+ }
+
+ uint64_t client_read_seq = SSL_get_read_sequence(client.get());
+ uint64_t client_write_seq = SSL_get_write_sequence(client.get());
+ uint64_t server_read_seq = SSL_get_read_sequence(server.get());
+ uint64_t server_write_seq = SSL_get_write_sequence(server.get());
+
+ if (is_dtls) {
+ // Both client and server must be at epoch 1.
+ if (EpochFromSequence(client_read_seq) != 1 ||
+ EpochFromSequence(client_write_seq) != 1 ||
+ EpochFromSequence(server_read_seq) != 1 ||
+ EpochFromSequence(server_write_seq) != 1) {
+ fprintf(stderr, "Bad epochs.\n");
+ return false;
+ }
+
+ // The next record to be written should exceed the largest received.
+ if (client_write_seq <= server_read_seq ||
+ server_write_seq <= client_read_seq) {
+ fprintf(stderr, "Inconsistent sequence numbers.\n");
+ return false;
+ }
+ } else {
+ // The next record to be written should equal the next to be received.
+ if (client_write_seq != server_read_seq ||
+ server_write_seq != client_read_seq) {
+ fprintf(stderr, "Inconsistent sequence numbers.\n");
+ return false;
+ }
+ }
+
+ // Send a record from client to server.
+ if (SSL_write(client.get(), &byte, 1) != 1 ||
+ SSL_read(server.get(), &byte, 1) != 1) {
+ fprintf(stderr, "Could not send byte.\n");
+ return false;
+ }
+
+ // The client write and server read sequence numbers should have
+ // incremented.
+ if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
+ server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
+ fprintf(stderr, "Sequence numbers did not increment.\n");
+ return false;
+ }
}
-
- // The next record to be written should exceed the largest received.
- if (client_write_seq <= server_read_seq ||
- server_write_seq <= client_read_seq) {
- fprintf(stderr, "Inconsistent sequence numbers.\n");
- return false;
- }
- } else {
- // The next record to be written should equal the next to be received.
- if (client_write_seq != server_read_seq ||
- server_write_seq != client_write_seq) {
- fprintf(stderr, "Inconsistent sequence numbers.\n");
- return false;
- }
- }
-
- // Send a record from client to server.
- uint8_t byte = 0;
- if (SSL_write(client.get(), &byte, 1) != 1 ||
- SSL_read(server.get(), &byte, 1) != 1) {
- fprintf(stderr, "Could not send byte.\n");
- return false;
- }
-
- // The client write and server read sequence numbers should have incremented.
- if (client_write_seq + 1 != SSL_get_write_sequence(client.get()) ||
- server_read_seq + 1 != SSL_get_read_sequence(server.get())) {
- fprintf(stderr, "Sequence numbers did not increment.\n");\
- return false;
}
return true;
@@ -1596,14 +1629,6 @@
return true;
}
-static uint16_t kTLSVersions[] = {
- SSL3_VERSION, TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, TLS1_3_VERSION,
-};
-
-static uint16_t kDTLSVersions[] = {
- DTLS1_VERSION, DTLS1_2_VERSION,
-};
-
static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
static bool TestGetPeerCertificate() {
@@ -1865,7 +1890,7 @@
}
static const uint8_t kTLS12ClientHello[] = {
- 0x16, 0x03, 0x01, 0x00, 0xa2, 0x01, 0x00, 0x00, 0x9e, 0x03, 0x03, 0x00,
+ 0x16, 0x03, 0x01, 0x00, 0x9e, 0x01, 0x00, 0x00, 0x9a, 0x03, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0xcc, 0xa9,
@@ -1873,12 +1898,12 @@
0xc0, 0x2c, 0xc0, 0x30, 0x00, 0x9f, 0xc0, 0x09, 0xc0, 0x23, 0xc0, 0x13,
0xc0, 0x27, 0x00, 0x33, 0x00, 0x67, 0xc0, 0x0a, 0xc0, 0x24, 0xc0, 0x14,
0xc0, 0x28, 0x00, 0x39, 0x00, 0x6b, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
- 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x3b,
+ 0x00, 0x3c, 0x00, 0x35, 0x00, 0x3d, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x37,
0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x23, 0x00,
- 0x00, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x08, 0x06, 0x06, 0x01, 0x06,
- 0x03, 0x08, 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04,
- 0x03, 0x02, 0x01, 0x02, 0x03, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00,
- 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
+ 0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x08, 0x06, 0x06, 0x01, 0x08,
+ 0x05, 0x05, 0x01, 0x05, 0x03, 0x08, 0x04, 0x04, 0x01, 0x04, 0x03, 0x02,
+ 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00,
+ 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18,
};
if (!ClientHelloMatches(TLS1_2_VERSION, kTLS12ClientHello,
sizeof(kTLS12ClientHello))) {
@@ -2324,8 +2349,7 @@
!TestPaddingExtension() ||
!TestClientCAList() ||
!TestInternalSessionCache() ||
- !TestSequenceNumber(false /* TLS */) ||
- !TestSequenceNumber(true /* DTLS */) ||
+ !TestSequenceNumber() ||
!TestOneSidedShutdown() ||
!TestSessionDuplication() ||
!TestSetFD() ||
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index 2aca268..9655b83 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -312,18 +312,8 @@
#endif
};
-void tls1_get_grouplist(SSL *ssl, int get_peer_groups,
- const uint16_t **out_group_ids,
+void tls1_get_grouplist(SSL *ssl, const uint16_t **out_group_ids,
size_t *out_group_ids_len) {
- if (get_peer_groups) {
- /* Only clients send a supported group list, so this function is only
- * called on the server. */
- assert(ssl->server);
- *out_group_ids = ssl->s3->tmp.peer_supported_group_list;
- *out_group_ids_len = ssl->s3->tmp.peer_supported_group_list_len;
- return;
- }
-
*out_group_ids = ssl->supported_group_list;
*out_group_ids_len = ssl->supported_group_list_len;
if (!*out_group_ids) {
@@ -333,42 +323,35 @@
}
int tls1_get_shared_group(SSL *ssl, uint16_t *out_group_id) {
- const uint16_t *groups, *peer_groups, *pref, *supp;
- size_t groups_len, peer_groups_len, pref_len, supp_len, i, j;
+ assert(ssl->server);
- /* Can't do anything on client side */
- if (ssl->server == 0) {
- return 0;
- }
+ const uint16_t *groups, *pref, *supp;
+ size_t groups_len, pref_len, supp_len;
+ tls1_get_grouplist(ssl, &groups, &groups_len);
- tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
- tls1_get_grouplist(ssl, 1 /* peer groups */, &peer_groups, &peer_groups_len);
-
- if (peer_groups_len == 0) {
- /* Clients are not required to send a supported_groups extension. In this
- * case, the server is free to pick any group it likes. See RFC 4492,
- * section 4, paragraph 3.
- *
- * However, in the interests of compatibility, we will skip ECDH if the
- * client didn't send an extension because we can't be sure that they'll
- * support our favoured group. */
- return 0;
- }
+ /* Clients are not required to send a supported_groups extension. In this
+ * case, the server is free to pick any group it likes. See RFC 4492,
+ * section 4, paragraph 3.
+ *
+ * However, in the interests of compatibility, we will skip ECDH if the
+ * client didn't send an extension because we can't be sure that they'll
+ * support our favoured group. Thus we do not special-case an emtpy
+ * |peer_supported_group_list|. */
if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
pref = groups;
pref_len = groups_len;
- supp = peer_groups;
- supp_len = peer_groups_len;
+ supp = ssl->s3->hs->peer_supported_group_list;
+ supp_len = ssl->s3->hs->peer_supported_group_list_len;
} else {
- pref = peer_groups;
- pref_len = peer_groups_len;
+ pref = ssl->s3->hs->peer_supported_group_list;
+ pref_len = ssl->s3->hs->peer_supported_group_list_len;
supp = groups;
supp_len = groups_len;
}
- for (i = 0; i < pref_len; i++) {
- for (j = 0; j < supp_len; j++) {
+ for (size_t i = 0; i < pref_len; i++) {
+ for (size_t j = 0; j < supp_len; j++) {
if (pref[i] == supp[j]) {
*out_group_id = pref[i];
return 1;
@@ -445,117 +428,54 @@
return 0;
}
-/* tls1_curve_params_from_ec_key sets |*out_group_id| and |*out_comp_id| to the
- * TLS group ID and point format, respectively, for |ec|. It returns one on
- * success and zero on failure. */
-static int tls1_curve_params_from_ec_key(uint16_t *out_group_id,
- uint8_t *out_comp_id, EC_KEY *ec) {
- int nid;
- uint16_t id;
- const EC_GROUP *grp;
-
- if (ec == NULL) {
- return 0;
- }
-
- grp = EC_KEY_get0_group(ec);
- if (grp == NULL) {
- return 0;
- }
-
- /* Determine group ID */
- nid = EC_GROUP_get_curve_name(grp);
- if (!ssl_nid_to_group_id(&id, nid)) {
- return 0;
- }
-
- /* Set the named group ID. Arbitrary explicit groups are not supported. */
- *out_group_id = id;
-
- if (out_comp_id) {
- if (EC_KEY_get0_public_key(ec) == NULL) {
- return 0;
- }
- if (EC_KEY_get_conv_form(ec) == POINT_CONVERSION_COMPRESSED) {
- *out_comp_id = TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime;
- } else {
- *out_comp_id = TLSEXT_ECPOINTFORMAT_uncompressed;
- }
- }
-
- return 1;
-}
-
-/* tls1_check_group_id returns one if |group_id| is consistent with both our
- * and the peer's group preferences. Note: if called as the client, only our
- * preferences are checked; the peer (the server) does not send preferences. */
int tls1_check_group_id(SSL *ssl, uint16_t group_id) {
const uint16_t *groups;
- size_t groups_len, i, get_peer_groups;
-
- /* Check against our list, then the peer's list. */
- for (get_peer_groups = 0; get_peer_groups <= 1; get_peer_groups++) {
- if (get_peer_groups && !ssl->server) {
- /* Servers do not present a preference list so, if we are a client, only
- * check our list. */
- continue;
- }
-
- tls1_get_grouplist(ssl, get_peer_groups, &groups, &groups_len);
- if (get_peer_groups && groups_len == 0) {
- /* Clients are not required to send a supported_groups extension. In this
- * case, the server is free to pick any group it likes. See RFC 4492,
- * section 4, paragraph 3. */
- continue;
- }
- for (i = 0; i < groups_len; i++) {
- if (groups[i] == group_id) {
- break;
- }
- }
-
- if (i == groups_len) {
- return 0;
+ size_t groups_len;
+ tls1_get_grouplist(ssl, &groups, &groups_len);
+ for (size_t i = 0; i < groups_len; i++) {
+ if (groups[i] == group_id) {
+ return 1;
}
}
- return 1;
+ return 0;
}
-int tls1_check_ec_cert(SSL *ssl, X509 *x) {
- if (ssl3_protocol_version(ssl) >= TLS1_3_VERSION) {
- /* In TLS 1.3, the ECDSA curve is negotiated via signature algorithms. */
- return 1;
- }
+/* kVerifySignatureAlgorithms is the default list of accepted signature
+ * algorithms for verifying. */
+static const uint16_t kVerifySignatureAlgorithms[] = {
+ /* For now, do not enable RSA-PSS signature algorithms on Android's system
+ * BoringSSL. Once TLS 1.3 is finalized and the change in Chrome has stuck,
+ * restore them. */
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
+ SSL_SIGN_RSA_PSS_SHA512,
+#endif
+ SSL_SIGN_RSA_PKCS1_SHA512,
+ /* TODO(davidben): Remove this entry and SSL_CURVE_SECP521R1 from
+ * kDefaultGroups. */
+#if defined(BORINGSSL_ANDROID_SYSTEM)
+ SSL_SIGN_ECDSA_SECP521R1_SHA512,
+#endif
- EVP_PKEY *pkey = X509_get_pubkey(x);
- if (pkey == NULL) {
- return 0;
- }
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
+ SSL_SIGN_RSA_PSS_SHA384,
+#endif
+ SSL_SIGN_RSA_PKCS1_SHA384,
+ SSL_SIGN_ECDSA_SECP384R1_SHA384,
- int ret = 0;
- uint16_t group_id;
- uint8_t comp_id;
- EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
- if (ec_key == NULL ||
- !tls1_curve_params_from_ec_key(&group_id, &comp_id, ec_key) ||
- !tls1_check_group_id(ssl, group_id) ||
- comp_id != TLSEXT_ECPOINTFORMAT_uncompressed) {
- goto done;
- }
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
+ SSL_SIGN_RSA_PSS_SHA256,
+#endif
+ SSL_SIGN_RSA_PKCS1_SHA256,
+ SSL_SIGN_ECDSA_SECP256R1_SHA256,
- ret = 1;
+ SSL_SIGN_RSA_PKCS1_SHA1,
+};
-done:
- EVP_PKEY_free(pkey);
- return ret;
-}
-
-/* List of supported signature algorithms and hashes. Should make this
- * customisable at some point, for now include everything we support. */
-
-static const uint16_t kDefaultSignatureAlgorithms[] = {
- /* For now, do not ship RSA-PSS signature algorithms on Android's system
+/* kSignSignatureAlgorithms is the default list of supported signature
+ * algorithms for signing. */
+static const uint16_t kSignSignatureAlgorithms[] = {
+ /* For now, do not enable RSA-PSS signature algorithms on Android's system
* BoringSSL. Once TLS 1.3 is finalized and the change in Chrome has stuck,
* restore them. */
#if !defined(BORINGSSL_ANDROID_SYSTEM)
@@ -580,30 +500,23 @@
SSL_SIGN_ECDSA_SHA1,
};
-size_t tls12_get_psigalgs(SSL *ssl, const uint16_t **psigs) {
- *psigs = kDefaultSignatureAlgorithms;
- return OPENSSL_ARRAY_SIZE(kDefaultSignatureAlgorithms);
+size_t tls12_get_verify_sigalgs(const SSL *ssl, const uint16_t **out) {
+ *out = kVerifySignatureAlgorithms;
+ return OPENSSL_ARRAY_SIZE(kVerifySignatureAlgorithms);
}
int tls12_check_peer_sigalg(SSL *ssl, int *out_alert, uint16_t sigalg) {
- const uint16_t *sent_sigs;
- size_t sent_sigslen, i;
-
- /* Check signature matches a type we sent */
- sent_sigslen = tls12_get_psigalgs(ssl, &sent_sigs);
- for (i = 0; i < sent_sigslen; i++) {
- if (sigalg == sent_sigs[i]) {
- break;
+ const uint16_t *verify_sigalgs;
+ size_t num_verify_sigalgs = tls12_get_verify_sigalgs(ssl, &verify_sigalgs);
+ for (size_t i = 0; i < num_verify_sigalgs; i++) {
+ if (sigalg == verify_sigalgs[i]) {
+ return 1;
}
}
- if (i == sent_sigslen) {
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
-
- return 1;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
}
/* Get a mask of disabled algorithms: an algorithm is disabled if it isn't
@@ -616,10 +529,10 @@
c->mask_a = 0;
c->mask_k = 0;
- /* Now go through all signature algorithms seeing if we support any for RSA,
- * DSA, ECDSA. Do this for all versions not just TLS 1.2. */
+ /* Now go through all signature algorithms seeing if we support any for RSA or
+ * ECDSA. Do this for all versions not just TLS 1.2. */
const uint16_t *sigalgs;
- size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
+ size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
for (size_t i = 0; i < num_sigalgs; i++) {
switch (sigalgs[i]) {
case SSL_SIGN_RSA_PSS_SHA512:
@@ -706,10 +619,6 @@
*
* https://tools.ietf.org/html/rfc6066#section-3. */
-static void ext_sni_init(SSL *ssl) {
- ssl->s3->tmp.should_ack_sni = 0;
-}
-
static int ext_sni_add_clienthello(SSL *ssl, CBB *out) {
if (ssl->tlsext_hostname == NULL) {
return 1;
@@ -797,7 +706,7 @@
return 0;
}
- ssl->s3->tmp.should_ack_sni = 1;
+ ssl->s3->hs->should_ack_sni = 1;
}
return 1;
@@ -805,7 +714,7 @@
static int ext_sni_add_serverhello(SSL *ssl, CBB *out) {
if (ssl->session != NULL ||
- !ssl->s3->tmp.should_ack_sni ||
+ !ssl->s3->hs->should_ack_sni ||
ssl->s3->new_session->tlsext_hostname == NULL) {
return 1;
}
@@ -834,6 +743,9 @@
return 1;
}
+ assert(ssl->s3->initial_handshake_complete ==
+ (ssl->s3->previous_client_finished_len != 0));
+
CBB contents, prev_finished;
if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
!CBB_add_u16_length_prefixed(out, &contents) ||
@@ -879,6 +791,10 @@
/* Check for logic errors */
assert(!expected_len || ssl->s3->previous_client_finished_len);
assert(!expected_len || ssl->s3->previous_server_finished_len);
+ assert(ssl->s3->initial_handshake_complete ==
+ (ssl->s3->previous_client_finished_len != 0));
+ assert(ssl->s3->initial_handshake_complete ==
+ (ssl->s3->previous_server_finished_len != 0));
/* Parse out the extension contents. */
CBS renegotiated_connection;
@@ -937,10 +853,9 @@
return 0;
}
- /* Check that the extension matches */
- if (!CBS_mem_equal(&renegotiated_connection,
- ssl->s3->previous_client_finished,
- ssl->s3->previous_client_finished_len)) {
+ /* Check that the extension matches. We do not support renegotiation as a
+ * server, so this must be empty. */
+ if (CBS_len(&renegotiated_connection) != 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
*out_alert = SSL_AD_HANDSHAKE_FAILURE;
return 0;
@@ -952,19 +867,17 @@
}
static int ext_ri_add_serverhello(SSL *ssl, CBB *out) {
+ /* 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;
}
- CBB contents, prev_finished;
if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
- !CBB_add_u16_length_prefixed(out, &contents) ||
- !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
- !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
- ssl->s3->previous_client_finished_len) ||
- !CBB_add_bytes(&prev_finished, ssl->s3->previous_server_finished,
- ssl->s3->previous_server_finished_len) ||
- !CBB_flush(out)) {
+ !CBB_add_u16(out, 1 /* length */) ||
+ !CBB_add_u8(out, 0 /* empty renegotiation info */)) {
return 0;
}
@@ -1162,7 +1075,7 @@
}
const uint16_t *sigalgs;
- const size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
+ const size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
CBB contents, sigalgs_cbb;
if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) ||
@@ -1211,7 +1124,6 @@
* https://tools.ietf.org/html/rfc6066#section-8 */
static void ext_ocsp_init(SSL *ssl) {
- ssl->s3->tmp.certificate_status_expected = 0;
ssl->tlsext_status_type = -1;
}
@@ -1251,7 +1163,7 @@
* status_request here does not make sense, but OpenSSL does so and the
* specification does not say anything. Tolerate it but ignore it. */
- ssl->s3->tmp.certificate_status_expected = 1;
+ ssl->s3->hs->certificate_status_expected = 1;
return 1;
}
@@ -1292,13 +1204,13 @@
/* We cannot decide whether OCSP stapling will occur yet because the correct
* SSL_CTX might not have been selected. */
- ssl->s3->tmp.ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
+ ssl->s3->hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
return 1;
}
static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
- if (!ssl->s3->tmp.ocsp_stapling_requested ||
+ if (!ssl->s3->hs->ocsp_stapling_requested ||
ssl->ctx->ocsp_response_length == 0 ||
ssl->s3->session_reused ||
(ssl3_protocol_version(ssl) < TLS1_3_VERSION &&
@@ -1312,7 +1224,7 @@
return 1;
}
- ssl->s3->tmp.certificate_status_expected = 1;
+ ssl->s3->hs->certificate_status_expected = 1;
return CBB_add_u16(out, TLSEXT_TYPE_status_request) &&
CBB_add_u16(out, 0 /* length */);
@@ -1333,10 +1245,6 @@
*
* https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html */
-static void ext_npn_init(SSL *ssl) {
- ssl->s3->next_proto_neg_seen = 0;
-}
-
static int ext_npn_add_clienthello(SSL *ssl, CBB *out) {
if (ssl->s3->initial_handshake_complete ||
ssl->ctx->next_proto_select_cb == NULL ||
@@ -1406,7 +1314,7 @@
}
ssl->s3->next_proto_negotiated_len = selected_len;
- ssl->s3->next_proto_neg_seen = 1;
+ ssl->s3->hs->next_proto_neg_seen = 1;
return 1;
}
@@ -1432,14 +1340,14 @@
return 1;
}
- ssl->s3->next_proto_neg_seen = 1;
+ ssl->s3->hs->next_proto_neg_seen = 1;
return 1;
}
static int ext_npn_add_serverhello(SSL *ssl, CBB *out) {
/* |next_proto_neg_seen| might have been cleared when an ALPN extension was
* parsed. */
- if (!ssl->s3->next_proto_neg_seen) {
+ if (!ssl->s3->hs->next_proto_neg_seen) {
return 1;
}
@@ -1449,7 +1357,7 @@
if (ssl->ctx->next_protos_advertised_cb(
ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) !=
SSL_TLSEXT_ERR_OK) {
- ssl->s3->next_proto_neg_seen = 0;
+ ssl->s3->hs->next_proto_neg_seen = 0;
return 1;
}
@@ -1572,7 +1480,7 @@
assert(!ssl->s3->initial_handshake_complete);
assert(ssl->alpn_client_proto_list != NULL);
- if (ssl->s3->next_proto_neg_seen) {
+ if (ssl->s3->hs->next_proto_neg_seen) {
/* 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);
@@ -1638,7 +1546,7 @@
}
/* ALPN takes precedence over NPN. */
- ssl->s3->next_proto_neg_seen = 0;
+ ssl->s3->hs->next_proto_neg_seen = 0;
CBS protocol_name_list;
if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) ||
@@ -2023,7 +1931,7 @@
/* Pre Shared Key
*
- * https://tools.ietf.org/html/draft-ietf-tls-tls13-15 */
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.6 */
static int ext_pre_shared_key_add_clienthello(SSL *ssl, CBB *out) {
uint16_t min_version, max_version;
@@ -2125,7 +2033,7 @@
/* Key Share
*
- * https://tools.ietf.org/html/draft-ietf-tls-tls13-12 */
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.5 */
static int ext_key_share_add_clienthello(SSL *ssl, CBB *out) {
uint16_t min_version, max_version;
@@ -2133,7 +2041,7 @@
return 0;
}
- if (max_version < TLS1_3_VERSION || !ssl_any_ec_cipher_suites_enabled(ssl)) {
+ if (max_version < TLS1_3_VERSION) {
return 1;
}
@@ -2145,8 +2053,8 @@
}
uint16_t group_id;
- if (ssl->s3->hs->retry_group) {
- /* Append the new key share to the old list. */
+ if (ssl->s3->hs->received_hello_retry_request) {
+ /* Replay the old key shares. */
if (!CBB_add_bytes(&kse_bytes, ssl->s3->hs->key_share_bytes,
ssl->s3->hs->key_share_bytes_len)) {
return 0;
@@ -2156,6 +2064,12 @@
ssl->s3->hs->key_share_bytes_len = 0;
group_id = ssl->s3->hs->retry_group;
+
+ /* We received a HelloRetryRequest without a new curve, so there is no new
+ * share to append. Leave |ecdh_ctx| as-is. */
+ if (group_id == 0) {
+ return CBB_flush(out);
+ }
} else {
/* Add a fake group. See draft-davidben-tls-grease-01. */
if (ssl->ctx->grease_enabled &&
@@ -2169,7 +2083,7 @@
/* Predict the most preferred group. */
const uint16_t *groups;
size_t groups_len;
- tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
+ tls1_get_grouplist(ssl, &groups, &groups_len);
if (groups_len == 0) {
OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED);
return 0;
@@ -2187,7 +2101,7 @@
return 0;
}
- if (!ssl->s3->hs->retry_group) {
+ if (!ssl->s3->hs->received_hello_retry_request) {
/* Save the contents of the extension to repeat it in the second
* ClientHello. */
ssl->s3->hs->key_share_bytes_len = CBB_len(&kse_bytes);
@@ -2373,16 +2287,36 @@
}
+/* Cookie
+ *
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.2 */
+
+static int ext_cookie_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->s3->hs->cookie == NULL) {
+ return 1;
+ }
+
+ CBB contents, cookie;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_cookie) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &cookie) ||
+ !CBB_add_bytes(&cookie, ssl->s3->hs->cookie, ssl->s3->hs->cookie_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ /* The cookie is no longer needed in memory. */
+ OPENSSL_free(ssl->s3->hs->cookie);
+ ssl->s3->hs->cookie = NULL;
+ ssl->s3->hs->cookie_len = 0;
+ return 1;
+}
+
+
/* Negotiated Groups
*
* https://tools.ietf.org/html/rfc4492#section-5.1.2
- * https://tools.ietf.org/html/draft-ietf-tls-tls13-12#section-6.3.2.2 */
-
-static void ext_supported_groups_init(SSL *ssl) {
- OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
- ssl->s3->tmp.peer_supported_group_list = NULL;
- ssl->s3->tmp.peer_supported_group_list_len = 0;
-}
+ * https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.4 */
static int ext_supported_groups_add_clienthello(SSL *ssl, CBB *out) {
if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
@@ -2405,7 +2339,7 @@
const uint16_t *groups;
size_t groups_len;
- tls1_get_grouplist(ssl, 0, &groups, &groups_len);
+ tls1_get_grouplist(ssl, &groups, &groups_len);
for (size_t i = 0; i < groups_len; i++) {
if (!CBB_add_u16(&groups_bytes, groups[i])) {
@@ -2437,9 +2371,9 @@
return 0;
}
- ssl->s3->tmp.peer_supported_group_list = OPENSSL_malloc(
+ ssl->s3->hs->peer_supported_group_list = OPENSSL_malloc(
CBS_len(&supported_group_list));
- if (ssl->s3->tmp.peer_supported_group_list == NULL) {
+ if (ssl->s3->hs->peer_supported_group_list == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
@@ -2447,19 +2381,19 @@
const size_t num_groups = CBS_len(&supported_group_list) / 2;
for (size_t i = 0; i < num_groups; i++) {
if (!CBS_get_u16(&supported_group_list,
- &ssl->s3->tmp.peer_supported_group_list[i])) {
+ &ssl->s3->hs->peer_supported_group_list[i])) {
goto err;
}
}
assert(CBS_len(&supported_group_list) == 0);
- ssl->s3->tmp.peer_supported_group_list_len = num_groups;
+ ssl->s3->hs->peer_supported_group_list_len = num_groups;
return 1;
err:
- OPENSSL_free(ssl->s3->tmp.peer_supported_group_list);
- ssl->s3->tmp.peer_supported_group_list = NULL;
+ OPENSSL_free(ssl->s3->hs->peer_supported_group_list);
+ ssl->s3->hs->peer_supported_group_list = NULL;
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
@@ -2482,7 +2416,7 @@
},
{
TLSEXT_TYPE_server_name,
- ext_sni_init,
+ NULL,
ext_sni_add_clienthello,
ext_sni_parse_serverhello,
ext_sni_parse_clienthello,
@@ -2523,7 +2457,7 @@
},
{
TLSEXT_TYPE_next_proto_neg,
- ext_npn_init,
+ NULL,
ext_npn_add_clienthello,
ext_npn_parse_serverhello,
ext_npn_parse_clienthello,
@@ -2593,12 +2527,20 @@
ignore_parse_clienthello,
dont_add_serverhello,
},
+ {
+ TLSEXT_TYPE_cookie,
+ NULL,
+ ext_cookie_add_clienthello,
+ forbid_parse_serverhello,
+ ignore_parse_clienthello,
+ dont_add_serverhello,
+ },
/* The final extension must be non-empty. WebSphere Application Server 7.0 is
* intolerant to the last extension being zero-length. See
* https://crbug.com/363583. */
{
TLSEXT_TYPE_supported_groups,
- ext_supported_groups_init,
+ NULL,
ext_supported_groups_add_clienthello,
ext_supported_groups_parse_serverhello,
ext_supported_groups_parse_clienthello,
@@ -2609,12 +2551,11 @@
#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
OPENSSL_COMPILE_ASSERT(kNumExtensions <=
- sizeof(((SSL *)NULL)->s3->tmp.extensions.sent) * 8,
+ sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8,
too_many_extensions_for_sent_bitset);
-OPENSSL_COMPILE_ASSERT(kNumExtensions <=
- sizeof(((SSL *)NULL)->s3->tmp.extensions.received) *
- 8,
- too_many_extensions_for_received_bitset);
+OPENSSL_COMPILE_ASSERT(
+ kNumExtensions <= sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8,
+ too_many_extensions_for_received_bitset);
static const struct tls_extension *tls_extension_find(uint32_t *out_index,
uint16_t value) {
@@ -2647,8 +2588,8 @@
goto err;
}
- ssl->s3->tmp.extensions.sent = 0;
- ssl->s3->tmp.custom_extensions.sent = 0;
+ ssl->s3->hs->extensions.sent = 0;
+ ssl->s3->hs->custom_extensions.sent = 0;
for (size_t i = 0; i < kNumExtensions; i++) {
if (kExtensions[i].init != NULL) {
@@ -2675,7 +2616,7 @@
}
if (CBB_len(&extensions) != len_before) {
- ssl->s3->tmp.extensions.sent |= (1u << i);
+ ssl->s3->hs->extensions.sent |= (1u << i);
}
}
@@ -2750,7 +2691,7 @@
unsigned i;
for (i = 0; i < kNumExtensions; i++) {
- if (!(ssl->s3->tmp.extensions.received & (1u << i))) {
+ if (!(ssl->s3->hs->extensions.received & (1u << i))) {
/* Don't send extensions that were not received. */
continue;
}
@@ -2788,8 +2729,8 @@
}
}
- ssl->s3->tmp.extensions.received = 0;
- ssl->s3->tmp.custom_extensions.received = 0;
+ ssl->s3->hs->extensions.received = 0;
+ ssl->s3->hs->custom_extensions.received = 0;
CBS extensions;
CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len);
@@ -2822,7 +2763,7 @@
continue;
}
- ssl->s3->tmp.extensions.received |= (1u << ext_index);
+ ssl->s3->hs->extensions.received |= (1u << ext_index);
uint8_t alert = SSL_AD_DECODE_ERROR;
if (!ext->parse_clienthello(ssl, &alert, &extension)) {
*out_alert = alert;
@@ -2833,7 +2774,7 @@
}
for (size_t i = 0; i < kNumExtensions; i++) {
- if (ssl->s3->tmp.extensions.received & (1u << i)) {
+ if (ssl->s3->hs->extensions.received & (1u << i)) {
continue;
}
@@ -2847,7 +2788,7 @@
CBS_init(&fake_contents, kFakeRenegotiateExtension,
sizeof(kFakeRenegotiateExtension));
contents = &fake_contents;
- ssl->s3->tmp.extensions.received |= (1u << i);
+ ssl->s3->hs->extensions.received |= (1u << i);
}
/* Extension wasn't observed so call the callback with a NULL
@@ -2919,7 +2860,7 @@
continue;
}
- if (!(ssl->s3->tmp.extensions.sent & (1u << ext_index)) &&
+ if (!(ssl->s3->hs->extensions.sent & (1u << ext_index)) &&
type != TLSEXT_TYPE_renegotiate) {
/* If the extension was never sent then it is illegal, except for the
* renegotiation extension which, in SSL 3.0, is signaled via SCSV. */
@@ -2979,7 +2920,7 @@
return 1;
case SSL_TLSEXT_ERR_NOACK:
- ssl->s3->tmp.should_ack_sni = 0;
+ ssl->s3->hs->should_ack_sni = 0;
return 1;
default:
@@ -3226,11 +3167,11 @@
return 0;
}
- const uint16_t *sigalgs;
- size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
- if (cert->sigalgs != NULL) {
- sigalgs = cert->sigalgs;
- num_sigalgs = cert->num_sigalgs;
+ const uint16_t *sigalgs = cert->sigalgs;
+ size_t num_sigalgs = cert->num_sigalgs;
+ if (sigalgs == NULL) {
+ sigalgs = kSignSignatureAlgorithms;
+ num_sigalgs = OPENSSL_ARRAY_SIZE(kSignSignatureAlgorithms);
}
const uint16_t *peer_sigalgs = hs->peer_sigalgs;
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index c4407da..76caa4e 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -33,7 +33,7 @@
#include <ws2tcpip.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
-#pragma comment(lib, "Ws2_32.lib")
+OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
#endif
#include <assert.h>
@@ -603,6 +603,31 @@
}
static int CertCallback(SSL *ssl, void *arg) {
+ const TestConfig *config = GetTestConfig(ssl);
+
+ // Check the CertificateRequest metadata is as expected.
+ //
+ // TODO(davidben): Test |SSL_get_client_CA_list|.
+ if (!SSL_is_server(ssl) &&
+ !config->expected_certificate_types.empty()) {
+ const uint8_t *certificate_types;
+ size_t certificate_types_len =
+ SSL_get0_certificate_types(ssl, &certificate_types);
+ if (certificate_types_len != config->expected_certificate_types.size() ||
+ memcmp(certificate_types,
+ config->expected_certificate_types.data(),
+ certificate_types_len) != 0) {
+ fprintf(stderr, "certificate types mismatch\n");
+ return 0;
+ }
+ }
+
+ // The certificate will be installed via other means.
+ if (!config->async || config->use_early_callback ||
+ config->use_old_client_cert_callback) {
+ return 1;
+ }
+
if (!GetTestState(ssl)->cert_ready) {
return -1;
}
@@ -1153,19 +1178,6 @@
}
}
- if (!config->expected_certificate_types.empty()) {
- const uint8_t *certificate_types;
- size_t certificate_types_len =
- SSL_get0_certificate_types(ssl, &certificate_types);
- if (certificate_types_len != config->expected_certificate_types.size() ||
- memcmp(certificate_types,
- config->expected_certificate_types.data(),
- certificate_types_len) != 0) {
- fprintf(stderr, "certificate types mismatch\n");
- return false;
- }
- }
-
if (!config->expected_next_proto.empty()) {
const uint8_t *next_proto;
unsigned next_proto_len;
@@ -1309,13 +1321,14 @@
!SSL_set_mode(ssl.get(), SSL_MODE_SEND_FALLBACK_SCSV)) {
return false;
}
- if (!config->use_early_callback && !config->use_old_client_cert_callback) {
- if (config->async) {
- SSL_set_cert_cb(ssl.get(), CertCallback, NULL);
- } else if (!InstallCertificate(ssl.get())) {
- return false;
- }
+ // Install the certificate synchronously if nothing else will handle it.
+ if (!config->use_early_callback &&
+ !config->use_old_client_cert_callback &&
+ !config->async &&
+ !InstallCertificate(ssl.get())) {
+ return false;
}
+ SSL_set_cert_cb(ssl.get(), CertCallback, nullptr);
if (config->require_any_client_certificate) {
SSL_set_verify(ssl.get(), SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
NULL);
diff --git a/src/ssl/test/runner/alert.go b/src/ssl/test/runner/alert.go
index b690c6f..8320b7e 100644
--- a/src/ssl/test/runner/alert.go
+++ b/src/ssl/test/runner/alert.go
@@ -43,6 +43,7 @@
alertUnsupportedExtension alert = 110
alertUnrecognizedName alert = 112
alertUnknownPSKIdentity alert = 115
+ alertCertificateRequired alert = 116
)
var alertText = map[alert]string{
@@ -73,6 +74,7 @@
alertUnsupportedExtension: "unsupported extension",
alertUnrecognizedName: "unrecognized name",
alertUnknownPSKIdentity: "unknown PSK identity",
+ alertCertificateRequired: "certificate required",
}
func (e alert) String() string {
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index 309cd82..62c8dd3 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -27,7 +27,7 @@
)
// A draft version of TLS 1.3 that is sent over the wire for the current draft.
-const tls13DraftVersion = 0x7f0f
+const tls13DraftVersion = 0x7f10
const (
maxPlaintext = 16384 // maximum plaintext payload length
@@ -57,8 +57,8 @@
typeServerHello uint8 = 2
typeHelloVerifyRequest uint8 = 3
typeNewSessionTicket uint8 = 4
- typeHelloRetryRequest uint8 = 6 // draft-ietf-tls-tls13-13
- typeEncryptedExtensions uint8 = 8 // draft-ietf-tls-tls13-13
+ typeHelloRetryRequest uint8 = 6 // draft-ietf-tls-tls13-16
+ typeEncryptedExtensions uint8 = 8 // draft-ietf-tls-tls13-16
typeCertificate uint8 = 11
typeServerKeyExchange uint8 = 12
typeCertificateRequest uint8 = 13
@@ -67,7 +67,7 @@
typeClientKeyExchange uint8 = 16
typeFinished uint8 = 20
typeCertificateStatus uint8 = 22
- typeKeyUpdate uint8 = 24 // draft-ietf-tls-tls13-13
+ typeKeyUpdate uint8 = 24 // draft-ietf-tls-tls13-16
typeNextProtocol uint8 = 67 // Not IANA assigned
typeChannelID uint8 = 203 // Not IANA assigned
)
@@ -89,17 +89,22 @@
extensionSignedCertificateTimestamp uint16 = 18
extensionExtendedMasterSecret uint16 = 23
extensionSessionTicket uint16 = 35
- extensionKeyShare uint16 = 40 // draft-ietf-tls-tls13-13
- extensionPreSharedKey uint16 = 41 // draft-ietf-tls-tls13-13
- extensionEarlyData uint16 = 42 // draft-ietf-tls-tls13-13
+ extensionKeyShare uint16 = 40 // draft-ietf-tls-tls13-16
+ extensionPreSharedKey uint16 = 41 // draft-ietf-tls-tls13-16
+ extensionEarlyData uint16 = 42 // draft-ietf-tls-tls13-16
extensionSupportedVersions uint16 = 43 // draft-ietf-tls-tls13-16
- extensionCookie uint16 = 44 // draft-ietf-tls-tls13-13
+ extensionCookie uint16 = 44 // draft-ietf-tls-tls13-16
extensionCustom uint16 = 1234 // not IANA assigned
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
extensionChannelID uint16 = 30032 // not IANA assigned
)
+// TLS ticket extension numbers
+const (
+ ticketExtensionCustom uint16 = 1234 // not IANA assigned
+)
+
// TLS signaling cipher suite values
const (
scsvRenegotiation uint16 = 0x00ff
@@ -189,18 +194,24 @@
SRTP_AES128_CM_HMAC_SHA1_32 = 0x0002
)
-// PskKeyExchangeMode values (see draft-ietf-tls-tls13-15)
+// PskKeyExchangeMode values (see draft-ietf-tls-tls13-16)
const (
pskKEMode = 0
pskDHEKEMode = 1
)
-// PskAuthenticationMode values (see draft-ietf-tls-tls13-15)
+// PskAuthenticationMode values (see draft-ietf-tls-tls13-16)
const (
pskAuthMode = 0
pskSignAuthMode = 1
)
+// KeyUpdateRequest values (see draft-ietf-tls-tls13-16, section 4.5.3)
+const (
+ keyUpdateNotRequested = 0
+ keyUpdateRequested = 1
+)
+
// ConnectionState records basic TLS details about the connection.
type ConnectionState struct {
Version uint16 // TLS version used by the connection (e.g. VersionTLS12)
@@ -458,11 +469,6 @@
// than the negotiated one.
SendCurve CurveID
- // SendHelloRetryRequestCurve, if non-zero, causes the server to send
- // the specified curve in HelloRetryRequest rather than the negotiated
- // one.
- SendHelloRetryRequestCurve CurveID
-
// InvalidECDHPoint, if true, causes the ECC points in
// ServerKeyExchange or ClientKeyExchange messages to be invalid.
InvalidECDHPoint bool
@@ -883,10 +889,22 @@
// that will be added to client/server hellos.
CustomExtension string
+ // CustomUnencryptedExtension, if not empty, contains the contents of
+ // an extension that will be added to ServerHello in TLS 1.3.
+ CustomUnencryptedExtension string
+
// ExpectedCustomExtension, if not nil, contains the expected contents
// of a custom extension.
ExpectedCustomExtension *string
+ // CustomTicketExtension, if not empty, contains the contents of an
+ // extension what will be added to NewSessionTicket in TLS 1.3.
+ CustomTicketExtension string
+
+ // CustomTicketExtension, if not empty, contains the contents of an
+ // extension what will be added to HelloRetryRequest in TLS 1.3.
+ CustomHelloRetryRequestExtension string
+
// NoCloseNotify, if true, causes the close_notify alert to be skipped
// on connection shutdown.
NoCloseNotify bool
@@ -913,6 +931,10 @@
// the client offer.
SendALPN string
+ // SendUnencryptedALPN, if non-empty, causes the server to send the
+ // specified string in a ServerHello ALPN extension in TLS 1.3.
+ SendUnencryptedALPN string
+
// SendEmptySessionTicket, if true, causes the server to send an empty
// session ticket.
SendEmptySessionTicket bool
@@ -939,10 +961,6 @@
// message. This only makes sense for a server.
SendHelloRequestBeforeEveryHandshakeMessage bool
- // SendKeyUpdateBeforeEveryAppDataRecord, if true, causes a KeyUpdate
- // handshake message to be sent before each application data record.
- SendKeyUpdateBeforeEveryAppDataRecord bool
-
// RequireDHPublicValueLen causes a fatal error if the length (in
// bytes) of the server's Diffie-Hellman public value is not equal to
// this.
@@ -1073,14 +1091,26 @@
// include the KeyShare extension in the EncryptedExtensions block.
EncryptedExtensionsWithKeyShare bool
- // UnnecessaryHelloRetryRequest, if true, causes the TLS 1.3 server to
- // send a HelloRetryRequest regardless of whether it needs to.
- UnnecessaryHelloRetryRequest bool
+ // AlwaysSendHelloRetryRequest, if true, causes a HelloRetryRequest to
+ // be sent by the server, even if empty.
+ AlwaysSendHelloRetryRequest bool
// SecondHelloRetryRequest, if true, causes the TLS 1.3 server to send
// two HelloRetryRequests instead of one.
SecondHelloRetryRequest bool
+ // SendHelloRetryRequestCurve, if non-zero, causes the server to send
+ // the specified curve in a HelloRetryRequest.
+ SendHelloRetryRequestCurve CurveID
+
+ // SendHelloRetryRequestCookie, if not nil, contains a cookie to be
+ // sent by the server in HelloRetryRequest.
+ SendHelloRetryRequestCookie []byte
+
+ // DuplicateHelloRetryRequestExtensions, if true, causes all
+ // HelloRetryRequest extensions to be sent twice.
+ DuplicateHelloRetryRequestExtensions bool
+
// SendServerHelloVersion, if non-zero, causes the server to send the
// specified value in ServerHello version field.
SendServerHelloVersion uint16
@@ -1127,8 +1157,8 @@
// invalid Channel ID signature.
InvalidChannelIDSignature bool
- // ExpectGREASE, if true, causes the server to reject a ClientHello
- // unless it contains GREASE values. See draft-davidben-tls-grease-01.
+ // ExpectGREASE, if true, causes messages without GREASE values to be
+ // rejected. See draft-davidben-tls-grease-01.
ExpectGREASE bool
}
@@ -1505,7 +1535,7 @@
}
var (
- // See draft-ietf-tls-tls13-13, section 6.3.1.2.
+ // See draft-ietf-tls-tls13-16, section 6.3.1.2.
downgradeTLS13 = []byte{0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x01}
downgradeTLS12 = []byte{0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00}
)
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index 84e1eb8..f5014d4 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -92,6 +92,8 @@
handMsgLen int // handshake message length, not including the header
pendingFragments [][]byte // pending outgoing handshake fragments.
+ keyUpdateRequested bool
+
tmp [16]byte
}
@@ -159,8 +161,7 @@
// used to save allocating a new buffer for each MAC.
inDigestBuf, outDigestBuf []byte
- trafficSecret []byte
- keyUpdateGeneration int
+ trafficSecret []byte
config *Config
}
@@ -223,7 +224,6 @@
side = clientWrite
}
hc.useTrafficSecret(hc.version, c.cipherSuite, updateTrafficSecret(c.cipherSuite.hash(), hc.trafficSecret), applicationPhase, side)
- hc.keyUpdateGeneration++
}
// incSeq increments the sequence number.
@@ -1328,11 +1328,11 @@
return 0, alertInternalError
}
- // Catch up with KeyUpdates from the peer.
- for c.out.keyUpdateGeneration < c.in.keyUpdateGeneration {
- if err := c.sendKeyUpdateLocked(); err != nil {
+ if c.keyUpdateRequested {
+ if err := c.sendKeyUpdateLocked(keyUpdateNotRequested); err != nil {
return 0, err
}
+ c.keyUpdateRequested = false
}
if c.config.Bugs.SendSpuriousAlert != 0 {
@@ -1344,12 +1344,6 @@
c.flushHandshake()
}
- if c.config.Bugs.SendKeyUpdateBeforeEveryAppDataRecord {
- if err := c.sendKeyUpdateLocked(); err != nil {
- return 0, err
- }
- }
-
// SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
// attack when using block mode ciphers due to predictable IVs.
// This can be prevented by splitting each Application Data
@@ -1398,6 +1392,10 @@
if c.isClient {
if newSessionTicket, ok := msg.(*newSessionTicketMsg); ok {
+ if c.config.Bugs.ExpectGREASE && !newSessionTicket.hasGREASEExtension {
+ return errors.New("tls: no GREASE ticket extension found")
+ }
+
if c.config.ClientSessionCache == nil || newSessionTicket.ticketLifetime == 0 {
return nil
}
@@ -1437,8 +1435,11 @@
}
}
- if _, ok := msg.(*keyUpdateMsg); ok {
+ if keyUpdate, ok := msg.(*keyUpdateMsg); ok {
c.in.doKeyUpdate(c, false)
+ if keyUpdate.keyUpdateRequest == keyUpdateRequested {
+ c.keyUpdateRequested = true
+ }
return nil
}
@@ -1710,10 +1711,11 @@
// TODO(davidben): Allow configuring these values.
m := &newSessionTicketMsg{
- version: c.vers,
- ticketLifetime: uint32(24 * time.Hour / time.Second),
- keModes: []byte{pskDHEKEMode},
- authModes: []byte{pskAuthMode},
+ version: c.vers,
+ ticketLifetime: uint32(24 * time.Hour / time.Second),
+ keModes: []byte{pskDHEKEMode},
+ authModes: []byte{pskAuthMode},
+ customExtension: c.config.Bugs.CustomTicketExtension,
}
if len(c.config.Bugs.SendPSKKeyExchangeModes) != 0 {
@@ -1746,18 +1748,20 @@
return err
}
-func (c *Conn) SendKeyUpdate() error {
+func (c *Conn) SendKeyUpdate(keyUpdateRequest byte) error {
c.out.Lock()
defer c.out.Unlock()
- return c.sendKeyUpdateLocked()
+ return c.sendKeyUpdateLocked(keyUpdateRequest)
}
-func (c *Conn) sendKeyUpdateLocked() error {
+func (c *Conn) sendKeyUpdateLocked(keyUpdateRequest byte) error {
if c.vers < VersionTLS13 {
return errors.New("tls: attempted to send KeyUpdate before TLS 1.3")
}
- m := new(keyUpdateMsg)
+ m := keyUpdateMsg{
+ keyUpdateRequest: keyUpdateRequest,
+ }
if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
return err
}
diff --git a/src/ssl/test/runner/fuzzer_mode.json b/src/ssl/test/runner/fuzzer_mode.json
index 94903c5..8fc1a56 100644
--- a/src/ssl/test/runner/fuzzer_mode.json
+++ b/src/ssl/test/runner/fuzzer_mode.json
@@ -15,6 +15,8 @@
"CECPQ1-*-BadX25519Part": "Fuzzer mode does not notice a bad premaster secret.",
"TrailingMessageData-TLS13-ServerHello": "Fuzzer mode will not read the peer's alert as a MAC error",
+ "UnexpectedUnencryptedExtension-Client-TLS13": "Fuzzer mode will not read the peer's alert as a MAC error",
+ "UnknownUnencryptedExtension-Client-TLS13": "Fuzzer mode will not read the peer's alert as a MAC error",
"WrongMessageType-TLS13-ServerHello": "Fuzzer mode will not read the peer's alert as a MAC error",
"*Auth-Verify-RSA-PKCS1-*-TLS13": "Fuzzer mode always accepts a signature.",
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index c5be2b7..ae3228a 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -389,34 +389,41 @@
helloRetryRequest, haveHelloRetryRequest := msg.(*helloRetryRequestMsg)
var secondHelloBytes []byte
if haveHelloRetryRequest {
- var hrrCurveFound bool
+ if len(helloRetryRequest.cookie) > 0 {
+ hello.tls13Cookie = helloRetryRequest.cookie
+ }
+
if c.config.Bugs.MisinterpretHelloRetryRequestCurve != 0 {
+ helloRetryRequest.hasSelectedGroup = true
helloRetryRequest.selectedGroup = c.config.Bugs.MisinterpretHelloRetryRequestCurve
}
- group := helloRetryRequest.selectedGroup
- for _, curveID := range hello.supportedCurves {
- if group == curveID {
- hrrCurveFound = true
- break
+ if helloRetryRequest.hasSelectedGroup {
+ var hrrCurveFound bool
+ group := helloRetryRequest.selectedGroup
+ for _, curveID := range hello.supportedCurves {
+ if group == curveID {
+ hrrCurveFound = true
+ break
+ }
}
+ if !hrrCurveFound || keyShares[group] != nil {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: received invalid HelloRetryRequest")
+ }
+ curve, ok := curveForCurveID(group)
+ if !ok {
+ return errors.New("tls: Unable to get curve requested in HelloRetryRequest")
+ }
+ publicKey, err := curve.offer(c.config.rand())
+ if err != nil {
+ return err
+ }
+ keyShares[group] = curve
+ hello.keyShares = append(hello.keyShares, keyShareEntry{
+ group: group,
+ keyExchange: publicKey,
+ })
}
- if !hrrCurveFound || keyShares[group] != nil {
- c.sendAlert(alertHandshakeFailure)
- return errors.New("tls: received invalid HelloRetryRequest")
- }
- curve, ok := curveForCurveID(group)
- if !ok {
- return errors.New("tls: Unable to get curve requested in HelloRetryRequest")
- }
- publicKey, err := curve.offer(c.config.rand())
- if err != nil {
- return err
- }
- keyShares[group] = curve
- hello.keyShares = append(hello.keyShares, keyShareEntry{
- group: group,
- keyExchange: publicKey,
- })
if c.config.Bugs.SecondClientHelloMissingKeyShare {
hello.hasKeyShares = false
@@ -448,7 +455,7 @@
}
// Check for downgrade signals in the server random, per
- // draft-ietf-tls-tls13-14, section 6.3.1.2.
+ // draft-ietf-tls-tls13-16, section 4.1.3.
if c.vers <= VersionTLS12 && c.config.maxVersion(c.isDTLS) >= VersionTLS13 {
if bytes.Equal(serverHello.random[len(serverHello.random)-8:], downgradeTLS13) {
c.sendAlert(alertProtocolVersion)
@@ -468,7 +475,7 @@
return fmt.Errorf("tls: server selected an unsupported cipher suite")
}
- if haveHelloRetryRequest && (helloRetryRequest.cipherSuite != serverHello.cipherSuite || helloRetryRequest.selectedGroup != serverHello.keyShare.group) {
+ if haveHelloRetryRequest && helloRetryRequest.hasSelectedGroup && helloRetryRequest.selectedGroup != serverHello.keyShare.group {
c.sendAlert(alertHandshakeFailure)
return errors.New("tls: ServerHello parameters did not match HelloRetryRequest")
}
@@ -644,9 +651,10 @@
handshakeSecret := hs.finishedHash.extractKey(earlySecret, ecdheSecret)
// Switch to handshake traffic keys.
- handshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, handshakeTrafficLabel)
- c.out.useTrafficSecret(c.vers, hs.suite, handshakeTrafficSecret, handshakePhase, clientWrite)
- c.in.useTrafficSecret(c.vers, hs.suite, handshakeTrafficSecret, handshakePhase, serverWrite)
+ clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, clientHandshakeTrafficLabel)
+ c.out.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, handshakePhase, clientWrite)
+ serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, serverHandshakeTrafficLabel)
+ c.in.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, handshakePhase, serverWrite)
msg, err := c.readHandshake()
if err != nil {
@@ -756,7 +764,7 @@
return unexpectedMessageError(serverFinished, msg)
}
- verify := hs.finishedHash.serverSum(handshakeTrafficSecret)
+ verify := hs.finishedHash.serverSum(serverHandshakeTrafficSecret)
if len(verify) != len(serverFinished.verifyData) ||
subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
c.sendAlert(alertHandshakeFailure)
@@ -768,7 +776,8 @@
// The various secrets do not incorporate the client's final leg, so
// derive them now before updating the handshake context.
masterSecret := hs.finishedHash.extractKey(handshakeSecret, zeroSecret)
- trafficSecret := hs.finishedHash.deriveSecret(masterSecret, applicationTrafficLabel)
+ clientTrafficSecret := hs.finishedHash.deriveSecret(masterSecret, clientApplicationTrafficLabel)
+ serverTrafficSecret := hs.finishedHash.deriveSecret(masterSecret, serverApplicationTrafficLabel)
if certReq != nil && !c.config.Bugs.SkipClientCertificate {
certMsg := &certificateMsg{
@@ -813,7 +822,7 @@
// Send a client Finished message.
finished := new(finishedMsg)
- finished.verifyData = hs.finishedHash.clientSum(handshakeTrafficSecret)
+ finished.verifyData = hs.finishedHash.clientSum(clientHandshakeTrafficSecret)
if c.config.Bugs.BadFinished {
finished.verifyData[0]++
}
@@ -830,8 +839,8 @@
c.flushHandshake()
// Switch to application data keys.
- c.out.useTrafficSecret(c.vers, hs.suite, trafficSecret, applicationPhase, clientWrite)
- c.in.useTrafficSecret(c.vers, hs.suite, trafficSecret, applicationPhase, serverWrite)
+ c.out.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, applicationPhase, clientWrite)
+ c.in.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, applicationPhase, serverWrite)
c.exporterSecret = hs.finishedHash.deriveSecret(masterSecret, exporterLabel)
c.resumptionSecret = hs.finishedHash.deriveSecret(masterSecret, resumptionLabel)
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index 19578e8..285587e 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -131,13 +131,11 @@
}
type clientHelloMsg struct {
- raw []byte
- isDTLS bool
- vers uint16
- random []byte
- sessionId []byte
- // TODO(davidben): Add support for TLS 1.3 cookies which are larger and
- // use an extension.
+ raw []byte
+ isDTLS bool
+ vers uint16
+ random []byte
+ sessionId []byte
cookie []byte
cipherSuites []uint16
compressionMethods []uint8
@@ -152,6 +150,7 @@
pskIdentities []pskIdentity
hasEarlyData bool
earlyDataContext []byte
+ tls13Cookie []byte
ticketSupported bool
sessionTicket []uint8
signatureAlgorithms []signatureAlgorithm
@@ -194,6 +193,7 @@
eqPSKIdentityLists(m.pskIdentities, m1.pskIdentities) &&
m.hasEarlyData == m1.hasEarlyData &&
bytes.Equal(m.earlyDataContext, m1.earlyDataContext) &&
+ bytes.Equal(m.tls13Cookie, m1.tls13Cookie) &&
m.ticketSupported == m1.ticketSupported &&
bytes.Equal(m.sessionTicket, m1.sessionTicket) &&
eqSignatureAlgorithms(m.signatureAlgorithms, m1.signatureAlgorithms) &&
@@ -334,6 +334,11 @@
context := earlyDataIndication.addU8LengthPrefixed()
context.addBytes(m.earlyDataContext)
}
+ if len(m.tls13Cookie) > 0 {
+ extensions.addU16(extensionCookie)
+ body := extensions.addU16LengthPrefixed()
+ body.addU16LengthPrefixed().addBytes(m.tls13Cookie)
+ }
if m.ticketSupported {
// http://tools.ietf.org/html/rfc5077#section-3.2
extensions.addU16(extensionSessionTicket)
@@ -666,6 +671,15 @@
}
m.hasEarlyData = true
m.earlyDataContext = data[1:length]
+ case extensionCookie:
+ if length < 2 {
+ return false
+ }
+ l := int(data[0])<<8 | int(data[1])
+ if l != length-2 || l == 0 {
+ return false
+ }
+ m.tls13Cookie = data[2 : 2+l]
case extensionSignatureAlgorithms:
// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
if length < 2 || length&1 != 0 {
@@ -782,6 +796,8 @@
useCertAuth bool
earlyDataIndication bool
compressionMethod uint8
+ customExtension string
+ unencryptedALPN string
extensions serverExtensions
}
@@ -840,6 +856,19 @@
extensions.addU16(extensionEarlyData)
extensions.addU16(0) // Length
}
+ if len(m.customExtension) > 0 {
+ extensions.addU16(extensionCustom)
+ customExt := extensions.addU16LengthPrefixed()
+ customExt.addBytes([]byte(m.customExtension))
+ }
+ if len(m.unencryptedALPN) > 0 {
+ extensions.addU16(extensionALPN)
+ extension := extensions.addU16LengthPrefixed()
+
+ protocolNameList := extension.addU16LengthPrefixed()
+ protocolName := protocolNameList.addU8LengthPrefixed()
+ protocolName.addBytes([]byte(m.unencryptedALPN))
+ }
} else {
m.extensions.marshal(extensions, vers)
if extensions.len() == 0 {
@@ -1255,10 +1284,13 @@
}
type helloRetryRequestMsg struct {
- raw []byte
- vers uint16
- cipherSuite uint16
- selectedGroup CurveID
+ raw []byte
+ vers uint16
+ hasSelectedGroup bool
+ selectedGroup CurveID
+ cookie []byte
+ customExtension string
+ duplicateExtensions bool
}
func (m *helloRetryRequestMsg) marshal() []byte {
@@ -1270,10 +1302,29 @@
retryRequestMsg.addU8(typeHelloRetryRequest)
retryRequest := retryRequestMsg.addU24LengthPrefixed()
retryRequest.addU16(m.vers)
- retryRequest.addU16(m.cipherSuite)
- retryRequest.addU16(uint16(m.selectedGroup))
- // Extensions field. We have none to send.
- retryRequest.addU16(0)
+ extensions := retryRequest.addU16LengthPrefixed()
+
+ count := 1
+ if m.duplicateExtensions {
+ count = 2
+ }
+
+ for i := 0; i < count; i++ {
+ if m.hasSelectedGroup {
+ extensions.addU16(extensionKeyShare)
+ extensions.addU16(2) // length
+ extensions.addU16(uint16(m.selectedGroup))
+ }
+ if len(m.cookie) > 0 {
+ extensions.addU16(extensionCookie)
+ body := extensions.addU16LengthPrefixed()
+ body.addU16LengthPrefixed().addBytes(m.cookie)
+ }
+ if len(m.customExtension) > 0 {
+ extensions.addU16(extensionCustom)
+ extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
+ }
+ }
m.raw = retryRequestMsg.finish()
return m.raw
@@ -1281,17 +1332,48 @@
func (m *helloRetryRequestMsg) unmarshal(data []byte) bool {
m.raw = data
- if len(data) < 12 {
+ if len(data) < 8 {
return false
}
m.vers = uint16(data[4])<<8 | uint16(data[5])
- m.cipherSuite = uint16(data[6])<<8 | uint16(data[7])
- m.selectedGroup = CurveID(data[8])<<8 | CurveID(data[9])
- extLen := int(data[10])<<8 | int(data[11])
- data = data[12:]
- if len(data) != extLen {
+ extLen := int(data[6])<<8 | int(data[7])
+ data = data[8:]
+ if len(data) != extLen || len(data) == 0 {
return false
}
+ for len(data) > 0 {
+ if len(data) < 4 {
+ return false
+ }
+ extension := uint16(data[0])<<8 | uint16(data[1])
+ length := int(data[2])<<8 | int(data[3])
+ data = data[4:]
+ if len(data) < length {
+ return false
+ }
+
+ switch extension {
+ case extensionKeyShare:
+ if length != 2 {
+ return false
+ }
+ m.hasSelectedGroup = true
+ m.selectedGroup = CurveID(data[0])<<8 | CurveID(data[1])
+ case extensionCookie:
+ if length < 2 {
+ return false
+ }
+ cookieLen := int(data[0])<<8 | int(data[1])
+ if 2+cookieLen != length {
+ return false
+ }
+ m.cookie = data[2 : 2+cookieLen]
+ default:
+ // Unknown extensions are illegal from the server.
+ return false
+ }
+ data = data[length:]
+ }
return true
}
@@ -1819,12 +1901,14 @@
}
type newSessionTicketMsg struct {
- raw []byte
- version uint16
- ticketLifetime uint32
- keModes []byte
- authModes []byte
- ticket []byte
+ raw []byte
+ version uint16
+ ticketLifetime uint32
+ keModes []byte
+ authModes []byte
+ ticket []byte
+ customExtension string
+ hasGREASEExtension bool
}
func (m *newSessionTicketMsg) marshal() []byte {
@@ -1846,11 +1930,11 @@
ticket.addBytes(m.ticket)
if m.version >= VersionTLS13 {
- // Send no extensions.
- //
- // TODO(davidben): Add an option to send a custom extension to
- // test we correctly ignore unknown ones.
- body.addU16(0)
+ extensions := body.addU16LengthPrefixed()
+ if len(m.customExtension) > 0 {
+ extensions.addU16(ticketExtensionCustom)
+ extensions.addU16LengthPrefixed().addBytes([]byte(m.customExtension))
+ }
}
m.raw = ticketMsg.finish()
@@ -1913,7 +1997,24 @@
if len(data) < extsLength {
return false
}
+ extensions := data[:extsLength]
data = data[extsLength:]
+
+ for len(extensions) > 0 {
+ if len(extensions) < 4 {
+ return false
+ }
+ extValue := uint16(extensions[0])<<8 | uint16(extensions[1])
+ extLength := int(extensions[2])<<8 | int(extensions[3])
+ if len(extensions) < 4+extLength {
+ return false
+ }
+ extensions = extensions[4+extLength:]
+
+ if isGREASEValue(extValue) {
+ m.hasGREASEExtension = true
+ }
+ }
}
if len(data) > 0 {
@@ -2060,14 +2161,32 @@
}
type keyUpdateMsg struct {
+ raw []byte
+ keyUpdateRequest byte
}
-func (*keyUpdateMsg) marshal() []byte {
- return []byte{typeKeyUpdate, 0, 0, 0}
+func (m *keyUpdateMsg) marshal() []byte {
+ if m.raw != nil {
+ return m.raw
+ }
+
+ return []byte{typeKeyUpdate, 0, 0, 1, m.keyUpdateRequest}
}
-func (*keyUpdateMsg) unmarshal(data []byte) bool {
- return len(data) == 4
+func (m *keyUpdateMsg) unmarshal(data []byte) bool {
+ m.raw = data
+
+ if len(data) != 5 {
+ return false
+ }
+
+ length := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+ if len(data)-4 != length {
+ return false
+ }
+
+ m.keyUpdateRequest = data[4]
+ return m.keyUpdateRequest == keyUpdateNotRequested || m.keyUpdateRequest == keyUpdateRequested
}
func eqUint16s(x, y []uint16) bool {
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 7c2fd17..9147134 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -359,9 +359,11 @@
config := c.config
hs.hello = &serverHelloMsg{
- isDTLS: c.isDTLS,
- vers: versionToWire(c.vers, c.isDTLS),
- versOverride: config.Bugs.SendServerHelloVersion,
+ isDTLS: c.isDTLS,
+ vers: versionToWire(c.vers, c.isDTLS),
+ versOverride: config.Bugs.SendServerHelloVersion,
+ customExtension: config.Bugs.CustomUnencryptedExtension,
+ unencryptedALPN: config.Bugs.SendUnencryptedALPN,
}
hs.hello.random = make([]byte, 32)
@@ -541,11 +543,32 @@
hs.hello.hasKeyShare = false
}
- // Resolve ECDHE and compute the handshake secret.
- var ecdheSecret []byte
+ firstHelloRetryRequest := true
+
+ResendHelloRetryRequest:
+ var sendHelloRetryRequest bool
+ helloRetryRequest := &helloRetryRequestMsg{
+ vers: versionToWire(c.vers, c.isDTLS),
+ duplicateExtensions: config.Bugs.DuplicateHelloRetryRequestExtensions,
+ }
+
+ if config.Bugs.AlwaysSendHelloRetryRequest {
+ sendHelloRetryRequest = true
+ }
+
+ if config.Bugs.SendHelloRetryRequestCookie != nil {
+ sendHelloRetryRequest = true
+ helloRetryRequest.cookie = config.Bugs.SendHelloRetryRequestCookie
+ }
+
+ if len(config.Bugs.CustomHelloRetryRequestExtension) > 0 {
+ sendHelloRetryRequest = true
+ helloRetryRequest.customExtension = config.Bugs.CustomHelloRetryRequestExtension
+ }
+
+ var selectedKeyShare *keyShareEntry
if hs.hello.hasKeyShare {
// Look for the key share corresponding to our selected curve.
- var selectedKeyShare *keyShareEntry
for i := range hs.clientHello.keyShares {
if hs.clientHello.keyShares[i].group == selectedCurve {
selectedKeyShare = &hs.clientHello.keyShares[i]
@@ -557,67 +580,80 @@
return errors.New("tls: expected missing key share")
}
- sendHelloRetryRequest := selectedKeyShare == nil
- if config.Bugs.UnnecessaryHelloRetryRequest {
+ if selectedKeyShare == nil {
+ helloRetryRequest.hasSelectedGroup = true
+ helloRetryRequest.selectedGroup = selectedCurve
sendHelloRetryRequest = true
}
- if config.Bugs.SkipHelloRetryRequest {
- sendHelloRetryRequest = false
+ }
+
+ if config.Bugs.SendHelloRetryRequestCurve != 0 {
+ helloRetryRequest.hasSelectedGroup = true
+ helloRetryRequest.selectedGroup = config.Bugs.SendHelloRetryRequestCurve
+ sendHelloRetryRequest = true
+ }
+
+ if config.Bugs.SkipHelloRetryRequest {
+ sendHelloRetryRequest = false
+ }
+
+ if sendHelloRetryRequest {
+ hs.writeServerHash(helloRetryRequest.marshal())
+ c.writeRecord(recordTypeHandshake, helloRetryRequest.marshal())
+ c.flushHandshake()
+
+ // Read new ClientHello.
+ newMsg, err := c.readHandshake()
+ if err != nil {
+ return err
}
- if sendHelloRetryRequest {
- firstTime := true
- ResendHelloRetryRequest:
- // Send HelloRetryRequest.
- helloRetryRequestMsg := helloRetryRequestMsg{
- vers: versionToWire(c.vers, c.isDTLS),
- cipherSuite: hs.hello.cipherSuite,
- selectedGroup: selectedCurve,
- }
- if config.Bugs.SendHelloRetryRequestCurve != 0 {
- helloRetryRequestMsg.selectedGroup = config.Bugs.SendHelloRetryRequestCurve
- }
- hs.writeServerHash(helloRetryRequestMsg.marshal())
- c.writeRecord(recordTypeHandshake, helloRetryRequestMsg.marshal())
- c.flushHandshake()
+ newClientHello, ok := newMsg.(*clientHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(newClientHello, newMsg)
+ }
+ hs.writeClientHash(newClientHello.marshal())
- // Read new ClientHello.
- newMsg, err := c.readHandshake()
- if err != nil {
- return err
- }
- newClientHello, ok := newMsg.(*clientHelloMsg)
- if !ok {
- c.sendAlert(alertUnexpectedMessage)
- return unexpectedMessageError(newClientHello, newMsg)
- }
- hs.writeClientHash(newClientHello.marshal())
+ // Check that the new ClientHello matches the old ClientHello,
+ // except for relevant modifications.
+ //
+ // TODO(davidben): Make this check more precise.
+ oldClientHelloCopy := *hs.clientHello
+ oldClientHelloCopy.raw = nil
+ oldClientHelloCopy.hasEarlyData = false
+ oldClientHelloCopy.earlyDataContext = nil
+ newClientHelloCopy := *newClientHello
+ newClientHelloCopy.raw = nil
- // Check that the new ClientHello matches the old ClientHello, except for
- // the addition of the new KeyShareEntry at the end of the list, and
- // removing the EarlyDataIndication extension (if present).
- newKeyShares := newClientHello.keyShares
- if len(newKeyShares) == 0 || newKeyShares[len(newKeyShares)-1].group != selectedCurve {
+ if helloRetryRequest.hasSelectedGroup {
+ newKeyShares := newClientHelloCopy.keyShares
+ if len(newKeyShares) == 0 || newKeyShares[len(newKeyShares)-1].group != helloRetryRequest.selectedGroup {
return errors.New("tls: KeyShare from HelloRetryRequest not present in new ClientHello")
}
- oldClientHelloCopy := *hs.clientHello
- oldClientHelloCopy.raw = nil
- oldClientHelloCopy.hasEarlyData = false
- oldClientHelloCopy.earlyDataContext = nil
- newClientHelloCopy := *newClientHello
- newClientHelloCopy.raw = nil
- newClientHelloCopy.keyShares = newKeyShares[:len(newKeyShares)-1]
- if !oldClientHelloCopy.equal(&newClientHelloCopy) {
- return errors.New("tls: new ClientHello does not match")
- }
-
- if firstTime && config.Bugs.SecondHelloRetryRequest {
- firstTime = false
- goto ResendHelloRetryRequest
- }
-
selectedKeyShare = &newKeyShares[len(newKeyShares)-1]
+ newClientHelloCopy.keyShares = newKeyShares[:len(newKeyShares)-1]
}
+ if len(helloRetryRequest.cookie) > 0 {
+ if !bytes.Equal(newClientHelloCopy.tls13Cookie, helloRetryRequest.cookie) {
+ return errors.New("tls: cookie from HelloRetryRequest not present in new ClientHello")
+ }
+ newClientHelloCopy.tls13Cookie = nil
+ }
+
+ if !oldClientHelloCopy.equal(&newClientHelloCopy) {
+ return errors.New("tls: new ClientHello does not match")
+ }
+
+ if firstHelloRetryRequest && config.Bugs.SecondHelloRetryRequest {
+ firstHelloRetryRequest = false
+ goto ResendHelloRetryRequest
+ }
+ }
+
+ // Resolve ECDHE and compute the handshake secret.
+ var ecdheSecret []byte
+ if hs.hello.hasKeyShare {
// Once a curve has been selected and a key share identified,
// the server needs to generate a public value and send it in
// the ServerHello.
@@ -691,9 +727,10 @@
handshakeSecret := hs.finishedHash.extractKey(earlySecret, ecdheSecret)
// Switch to handshake traffic keys.
- handshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, handshakeTrafficLabel)
- c.out.useTrafficSecret(c.vers, hs.suite, handshakeTrafficSecret, handshakePhase, serverWrite)
- c.in.useTrafficSecret(c.vers, hs.suite, handshakeTrafficSecret, handshakePhase, clientWrite)
+ serverHandshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, serverHandshakeTrafficLabel)
+ c.out.useTrafficSecret(c.vers, hs.suite, serverHandshakeTrafficSecret, handshakePhase, serverWrite)
+ clientHandshakeTrafficSecret := hs.finishedHash.deriveSecret(handshakeSecret, clientHandshakeTrafficLabel)
+ c.in.useTrafficSecret(c.vers, hs.suite, clientHandshakeTrafficSecret, handshakePhase, clientWrite)
if hs.hello.useCertAuth {
if hs.clientHello.ocspStapling {
@@ -791,7 +828,7 @@
}
finished := new(finishedMsg)
- finished.verifyData = hs.finishedHash.serverSum(handshakeTrafficSecret)
+ finished.verifyData = hs.finishedHash.serverSum(serverHandshakeTrafficSecret)
if config.Bugs.BadFinished {
finished.verifyData[0]++
}
@@ -805,11 +842,12 @@
// The various secrets do not incorporate the client's final leg, so
// derive them now before updating the handshake context.
masterSecret := hs.finishedHash.extractKey(handshakeSecret, hs.finishedHash.zeroSecret())
- trafficSecret := hs.finishedHash.deriveSecret(masterSecret, applicationTrafficLabel)
+ clientTrafficSecret := hs.finishedHash.deriveSecret(masterSecret, clientApplicationTrafficLabel)
+ serverTrafficSecret := hs.finishedHash.deriveSecret(masterSecret, serverApplicationTrafficLabel)
// Switch to application data keys on write. In particular, any alerts
// from the client certificate are sent over these keys.
- c.out.useTrafficSecret(c.vers, hs.suite, trafficSecret, applicationPhase, serverWrite)
+ c.out.useTrafficSecret(c.vers, hs.suite, serverTrafficSecret, applicationPhase, serverWrite)
// If we requested a client certificate, then the client must send a
// certificate message, even if it's empty.
@@ -830,7 +868,7 @@
// The client didn't actually send a certificate
switch config.ClientAuth {
case RequireAnyClientCert, RequireAndVerifyClientCert:
- c.sendAlert(alertBadCertificate)
+ c.sendAlert(alertCertificateRequired)
return errors.New("tls: client didn't provide a certificate")
}
}
@@ -873,7 +911,7 @@
return unexpectedMessageError(clientFinished, msg)
}
- verify := hs.finishedHash.clientSum(handshakeTrafficSecret)
+ verify := hs.finishedHash.clientSum(clientHandshakeTrafficSecret)
if len(verify) != len(clientFinished.verifyData) ||
subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
c.sendAlert(alertHandshakeFailure)
@@ -882,7 +920,7 @@
hs.writeClientHash(clientFinished.marshal())
// Switch to application data keys on read.
- c.in.useTrafficSecret(c.vers, hs.suite, trafficSecret, applicationPhase, clientWrite)
+ c.in.useTrafficSecret(c.vers, hs.suite, clientTrafficSecret, applicationPhase, clientWrite)
c.cipherSuite = hs.suite
c.exporterSecret = hs.finishedHash.deriveSecret(masterSecret, exporterLabel)
@@ -918,8 +956,8 @@
c.sendAlert(alertInternalError)
return false, err
}
- // Signal downgrades in the server random, per draft-ietf-tls-tls13-14,
- // section 6.3.1.2.
+ // Signal downgrades in the server random, per draft-ietf-tls-tls13-16,
+ // section 4.1.3.
if c.vers <= VersionTLS12 && config.maxVersion(c.isDTLS) >= VersionTLS13 {
copy(hs.hello.random[len(hs.hello.random)-8:], downgradeTLS13)
}
diff --git a/src/ssl/test/runner/prf.go b/src/ssl/test/runner/prf.go
index 5c7b3ab..ffa68e9 100644
--- a/src/ssl/test/runner/prf.go
+++ b/src/ssl/test/runner/prf.go
@@ -119,6 +119,7 @@
var keyExpansionLabel = []byte("key expansion")
var clientFinishedLabel = []byte("client finished")
var serverFinishedLabel = []byte("server finished")
+var finishedLabel = []byte("finished")
var channelIDLabel = []byte("TLS Channel ID signature\x00")
var channelIDResumeLabel = []byte("Resumption\x00")
@@ -311,7 +312,7 @@
return out
}
- clientFinishedKey := hkdfExpandLabel(h.hash, baseKey, clientFinishedLabel, nil, h.hash.Size())
+ clientFinishedKey := hkdfExpandLabel(h.hash, baseKey, finishedLabel, nil, h.hash.Size())
finishedHMAC := hmac.New(h.hash.New, clientFinishedKey)
finishedHMAC.Write(h.appendContextHashes(nil))
return finishedHMAC.Sum(nil)
@@ -330,7 +331,7 @@
return out
}
- serverFinishedKey := hkdfExpandLabel(h.hash, baseKey, serverFinishedLabel, nil, h.hash.Size())
+ serverFinishedKey := hkdfExpandLabel(h.hash, baseKey, finishedLabel, nil, h.hash.Size())
finishedHMAC := hmac.New(h.hash.New, serverFinishedKey)
finishedHMAC.Write(h.appendContextHashes(nil))
return finishedHMAC.Sum(nil)
@@ -367,7 +368,7 @@
}
// zeroSecretTLS13 returns the default all zeros secret for TLS 1.3, used when a
-// given secret is not available in the handshake. See draft-ietf-tls-tls13-13,
+// given secret is not available in the handshake. See draft-ietf-tls-tls13-16,
// section 7.1.
func (h *finishedHash) zeroSecret() []byte {
return make([]byte, h.hash.Size())
@@ -387,7 +388,7 @@
}
// hkdfExpandLabel implements TLS 1.3's HKDF-Expand-Label function, as defined
-// in section 7.1 of draft-ietf-tls-tls13-13.
+// in section 7.1 of draft-ietf-tls-tls13-16.
func hkdfExpandLabel(hash crypto.Hash, secret, label, hashValue []byte, length int) []byte {
if len(label) > 255 || len(hashValue) > 255 {
panic("hkdfExpandLabel: label or hashValue too long")
@@ -417,15 +418,18 @@
// The following are labels for traffic secret derivation in TLS 1.3.
var (
- earlyTrafficLabel = []byte("early traffic secret")
- handshakeTrafficLabel = []byte("handshake traffic secret")
- applicationTrafficLabel = []byte("application traffic secret")
- exporterLabel = []byte("exporter master secret")
- resumptionLabel = []byte("resumption master secret")
+ earlyTrafficLabel = []byte("client early traffic secret")
+ clientHandshakeTrafficLabel = []byte("client handshake traffic secret")
+ serverHandshakeTrafficLabel = []byte("server handshake traffic secret")
+ clientApplicationTrafficLabel = []byte("client application traffic secret")
+ serverApplicationTrafficLabel = []byte("server application traffic secret")
+ applicationTrafficLabel = []byte("application traffic secret")
+ exporterLabel = []byte("exporter master secret")
+ resumptionLabel = []byte("resumption master secret")
)
// deriveSecret implements TLS 1.3's Derive-Secret function, as defined in
-// section 7.1 of draft ietf-tls-tls13-13.
+// section 7.1 of draft ietf-tls-tls13-16.
func (h *finishedHash) deriveSecret(secret, label []byte) []byte {
if h.resumptionContextHash == nil {
panic("Resumption context not set.")
@@ -474,11 +478,7 @@
func deriveTrafficAEAD(version uint16, suite *cipherSuite, secret, phase []byte, side trafficDirection) interface{} {
label := make([]byte, 0, len(phase)+2+16)
label = append(label, phase...)
- if side == clientWrite {
- label = append(label, []byte(", client write key")...)
- } else {
- label = append(label, []byte(", server write key")...)
- }
+ label = append(label, []byte(", key")...)
key := hkdfExpandLabel(suite.hash(), secret, label, nil, suite.keyLen)
label = label[:len(label)-3] // Remove "key" from the end.
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 248c6eb..367fef1 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -359,6 +359,8 @@
// sendKeyUpdates is the number of consecutive key updates to send
// before and after the test message.
sendKeyUpdates int
+ // keyUpdateRequest is the KeyUpdateRequest value to send in KeyUpdate messages.
+ keyUpdateRequest byte
// expectMessageDropped, if true, means the test message is expected to
// be dropped by the client rather than echoed back.
expectMessageDropped bool
@@ -616,7 +618,7 @@
}
for i := 0; i < test.sendKeyUpdates; i++ {
- if err := tlsConn.SendKeyUpdate(); err != nil {
+ if err := tlsConn.SendKeyUpdate(test.keyUpdateRequest); err != nil {
return err
}
}
@@ -678,7 +680,7 @@
tlsConn.Write(testMessage)
for i := 0; i < test.sendKeyUpdates; i++ {
- tlsConn.SendKeyUpdate()
+ tlsConn.SendKeyUpdate(test.keyUpdateRequest)
}
for i := 0; i < test.sendEmptyRecords; i++ {
@@ -1981,13 +1983,14 @@
expectedError: ":TOO_MANY_WARNING_ALERTS:",
},
{
- name: "SendKeyUpdates",
+ name: "TooManyKeyUpdates",
config: Config{
MaxVersion: VersionTLS13,
},
- sendKeyUpdates: 33,
- shouldFail: true,
- expectedError: ":TOO_MANY_KEY_UPDATES:",
+ sendKeyUpdates: 33,
+ keyUpdateRequest: keyUpdateNotRequested,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_KEY_UPDATES:",
},
{
name: "EmptySessionID",
@@ -2195,14 +2198,22 @@
expectedError: ":WRONG_VERSION_NUMBER:",
},
{
- testType: clientTest,
- name: "KeyUpdate",
+ name: "KeyUpdate",
config: Config{
MaxVersion: VersionTLS13,
- Bugs: ProtocolBugs{
- SendKeyUpdateBeforeEveryAppDataRecord: true,
- },
},
+ sendKeyUpdates: 1,
+ keyUpdateRequest: keyUpdateNotRequested,
+ },
+ {
+ name: "KeyUpdate-InvalidRequestMode",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ },
+ sendKeyUpdates: 1,
+ keyUpdateRequest: 42,
+ shouldFail: true,
+ expectedError: ":DECODE_ERROR:",
},
{
name: "SendSNIWarningAlert",
@@ -2263,7 +2274,7 @@
expectedLocalError: "remote error: illegal parameter",
},
{
- name: "GREASE-TLS12",
+ name: "GREASE-Client-TLS12",
config: Config{
MaxVersion: VersionTLS12,
Bugs: ProtocolBugs{
@@ -2273,7 +2284,18 @@
flags: []string{"-enable-grease"},
},
{
- name: "GREASE-TLS13",
+ name: "GREASE-Client-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ ExpectGREASE: true,
+ },
+ },
+ flags: []string{"-enable-grease"},
+ },
+ {
+ testType: serverTest,
+ name: "GREASE-Server-TLS13",
config: Config{
MaxVersion: VersionTLS13,
Bugs: ProtocolBugs{
@@ -2920,9 +2942,7 @@
flags: []string{
"-expect-verify-result",
},
- // TODO(davidben): Switch this to true when TLS 1.3
- // supports session resumption.
- resumeSession: ver.version < VersionTLS13,
+ resumeSession: true,
})
testCases = append(testCases, testCase{
@@ -2938,11 +2958,15 @@
"-expect-verify-result",
"-verify-peer",
},
- // TODO(davidben): Switch this to true when TLS 1.3
- // supports session resumption.
- resumeSession: ver.version < VersionTLS13,
+ resumeSession: true,
})
+ certificateRequired := "remote error: certificate required"
+ if ver.version < VersionTLS13 {
+ // Prior to TLS 1.3, the generic handshake_failure alert
+ // was used.
+ certificateRequired = "remote error: handshake failure"
+ }
testCases = append(testCases, testCase{
testType: serverTest,
name: "RequireAnyClientCertificate-" + ver.name,
@@ -2950,9 +2974,10 @@
MinVersion: ver.version,
MaxVersion: ver.version,
},
- flags: []string{"-require-any-client-certificate"},
- shouldFail: true,
- expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
+ flags: []string{"-require-any-client-certificate"},
+ shouldFail: true,
+ expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:",
+ expectedLocalError: certificateRequired,
})
if ver.version != VersionSSL30 {
@@ -3356,10 +3381,8 @@
config: Config{
MaxVersion: VersionTLS13,
MinVersion: VersionTLS13,
- // P-384 requires a HelloRetryRequest against
- // BoringSSL's default configuration. Assert
- // that we do indeed test this with
- // ExpectMissingKeyShare.
+ // P-384 requires a HelloRetryRequest against BoringSSL's default
+ // configuration. Assert this with ExpectMissingKeyShare.
CurvePreferences: []CurveID{CurveP384},
Bugs: ProtocolBugs{
ExpectMissingKeyShare: true,
@@ -5678,6 +5701,22 @@
},
})
+ // Renegotiation is not allowed at SSL 3.0.
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-Client-SSL3",
+ config: Config{
+ MaxVersion: VersionSSL30,
+ },
+ renegotiate: 1,
+ flags: []string{
+ "-renegotiate-freely",
+ "-expect-total-renegotiations", "1",
+ },
+ shouldFail: true,
+ expectedError: ":NO_RENEGOTIATION:",
+ expectedLocalError: "remote error: no renegotiation",
+ })
+
// Stray HelloRequests during the handshake are ignored in TLS 1.2.
testCases = append(testCases, testCase{
name: "StrayHelloRequest",
@@ -5845,19 +5884,28 @@
continue
}
- var shouldFail bool
+ var shouldSignFail, shouldVerifyFail bool
// ecdsa_sha1 does not exist in TLS 1.3.
if ver.version >= VersionTLS13 && alg.id == signatureECDSAWithSHA1 {
- shouldFail = true
+ shouldSignFail = true
+ shouldVerifyFail = true
}
// RSA-PKCS1 does not exist in TLS 1.3.
if ver.version == VersionTLS13 && hasComponent(alg.name, "PKCS1") {
- shouldFail = true
+ shouldSignFail = true
+ shouldVerifyFail = true
+ }
+
+ // BoringSSL will sign SHA-1 and SHA-512 with ECDSA but not accept them.
+ if alg.id == signatureECDSAWithSHA1 || alg.id == signatureECDSAWithP521AndSHA512 {
+ shouldVerifyFail = true
}
var signError, verifyError string
- if shouldFail {
+ if shouldSignFail {
signError = ":NO_COMMON_SIGNATURE_ALGORITHMS:"
+ }
+ if shouldVerifyFail {
verifyError = ":WRONG_SIGNATURE_TYPE:"
}
@@ -5879,7 +5927,7 @@
"-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
"-enable-all-curves",
},
- shouldFail: shouldFail,
+ shouldFail: shouldSignFail,
expectedError: signError,
expectedPeerSignatureAlgorithm: alg.id,
})
@@ -5894,11 +5942,10 @@
alg.id,
},
Bugs: ProtocolBugs{
- SkipECDSACurveCheck: shouldFail,
- IgnoreSignatureVersionChecks: shouldFail,
- // The client won't advertise 1.3-only algorithms after
- // version negotiation.
- IgnorePeerSignatureAlgorithmPreferences: shouldFail,
+ SkipECDSACurveCheck: shouldVerifyFail,
+ IgnoreSignatureVersionChecks: shouldVerifyFail,
+ // Some signature algorithms may not be advertised.
+ IgnorePeerSignatureAlgorithmPreferences: shouldVerifyFail,
},
},
flags: []string{
@@ -5906,7 +5953,7 @@
"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
"-enable-all-curves",
},
- shouldFail: shouldFail,
+ shouldFail: shouldVerifyFail,
expectedError: verifyError,
})
@@ -5927,7 +5974,7 @@
"-key-file", path.Join(*resourceDir, getShimKey(alg.cert)),
"-enable-all-curves",
},
- shouldFail: shouldFail,
+ shouldFail: shouldSignFail,
expectedError: signError,
expectedPeerSignatureAlgorithm: alg.id,
})
@@ -5942,19 +5989,21 @@
alg.id,
},
Bugs: ProtocolBugs{
- SkipECDSACurveCheck: shouldFail,
- IgnoreSignatureVersionChecks: shouldFail,
+ SkipECDSACurveCheck: shouldVerifyFail,
+ IgnoreSignatureVersionChecks: shouldVerifyFail,
+ // Some signature algorithms may not be advertised.
+ IgnorePeerSignatureAlgorithmPreferences: shouldVerifyFail,
},
},
flags: []string{
"-expect-peer-signature-algorithm", strconv.Itoa(int(alg.id)),
"-enable-all-curves",
},
- shouldFail: shouldFail,
+ shouldFail: shouldVerifyFail,
expectedError: verifyError,
})
- if !shouldFail {
+ if !shouldVerifyFail {
testCases = append(testCases, testCase{
testType: serverTest,
name: "ClientAuth-InvalidSignature" + suffix,
@@ -5995,7 +6044,7 @@
})
}
- if ver.version >= VersionTLS12 && !shouldFail {
+ if ver.version >= VersionTLS12 && !shouldSignFail {
testCases = append(testCases, testCase{
name: "ClientAuth-Sign-Negotiate" + suffix,
config: Config{
@@ -7080,6 +7129,39 @@
expectedError: ":UNEXPECTED_EXTENSION:",
expectedLocalError: "remote error: unsupported extension",
})
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "UnknownUnencryptedExtension-Client-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ CustomUnencryptedExtension: expectedContents,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_EXTENSION:",
+ // The shim must send an alert, but alerts at this point do not
+ // get successfully decrypted by the runner.
+ expectedLocalError: "local error: bad record MAC",
+ })
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "UnexpectedUnencryptedExtension-Client-TLS13",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendUnencryptedALPN: "foo",
+ },
+ },
+ flags: []string{
+ "-advertise-alpn", "\x03foo\x03bar",
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_EXTENSION:",
+ // The shim must send an alert, but alerts at this point do not
+ // get successfully decrypted by the runner.
+ expectedLocalError: "local error: bad record MAC",
+ })
// Test a known but unoffered extension from the server.
testCases = append(testCases, testCase{
@@ -8431,9 +8513,10 @@
testCases = append(testCases, testCase{
name: "UnnecessaryHelloRetryRequest",
config: Config{
- MaxVersion: VersionTLS13,
+ MaxVersion: VersionTLS13,
+ CurvePreferences: []CurveID{CurveX25519},
Bugs: ProtocolBugs{
- UnnecessaryHelloRetryRequest: true,
+ SendHelloRetryRequestCurve: CurveX25519,
},
},
shouldFail: true,
@@ -8455,6 +8538,97 @@
})
testCases = append(testCases, testCase{
+ name: "HelloRetryRequest-Empty",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ AlwaysSendHelloRetryRequest: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DECODE_ERROR:",
+ })
+
+ testCases = append(testCases, testCase{
+ name: "HelloRetryRequest-DuplicateCurve",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ // P-384 requires a HelloRetryRequest against BoringSSL's default
+ // configuration. Assert this ExpectMissingKeyShare.
+ CurvePreferences: []CurveID{CurveP384},
+ Bugs: ProtocolBugs{
+ ExpectMissingKeyShare: true,
+ DuplicateHelloRetryRequestExtensions: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DUPLICATE_EXTENSION:",
+ expectedLocalError: "remote error: illegal parameter",
+ })
+
+ testCases = append(testCases, testCase{
+ name: "HelloRetryRequest-Cookie",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendHelloRetryRequestCookie: []byte("cookie"),
+ },
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ name: "HelloRetryRequest-DuplicateCookie",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendHelloRetryRequestCookie: []byte("cookie"),
+ DuplicateHelloRetryRequestExtensions: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DUPLICATE_EXTENSION:",
+ expectedLocalError: "remote error: illegal parameter",
+ })
+
+ testCases = append(testCases, testCase{
+ name: "HelloRetryRequest-EmptyCookie",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ SendHelloRetryRequestCookie: []byte{},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DECODE_ERROR:",
+ })
+
+ testCases = append(testCases, testCase{
+ name: "HelloRetryRequest-Cookie-Curve",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ // P-384 requires HelloRetryRequest in BoringSSL.
+ CurvePreferences: []CurveID{CurveP384},
+ Bugs: ProtocolBugs{
+ SendHelloRetryRequestCookie: []byte("cookie"),
+ ExpectMissingKeyShare: true,
+ },
+ },
+ })
+
+ testCases = append(testCases, testCase{
+ name: "HelloRetryRequest-Unknown",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ CustomHelloRetryRequestExtension: "extension",
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_EXTENSION:",
+ expectedLocalError: "remote error: unsupported extension",
+ })
+
+ testCases = append(testCases, testCase{
testType: serverTest,
name: "SecondClientHelloMissingKeyShare",
config: Config{
@@ -8584,6 +8758,17 @@
shouldFail: true,
expectedError: ":PSK_IDENTITY_NOT_FOUND:",
})
+
+ // Test that unknown NewSessionTicket extensions are tolerated.
+ testCases = append(testCases, testCase{
+ name: "TLS13-CustomTicketExtension",
+ config: Config{
+ MaxVersion: VersionTLS13,
+ Bugs: ProtocolBugs{
+ CustomTicketExtension: "1234",
+ },
+ },
+ })
}
func addPeekTests() {
@@ -8649,11 +8834,10 @@
name: "Peek-KeyUpdate",
config: Config{
MaxVersion: VersionTLS13,
- Bugs: ProtocolBugs{
- SendKeyUpdateBeforeEveryAppDataRecord: true,
- },
},
- flags: []string{"-peek-then-read"},
+ sendKeyUpdates: 1,
+ keyUpdateRequest: keyUpdateNotRequested,
+ flags: []string{"-peek-then-read"},
})
}
diff --git a/src/ssl/tls13_both.c b/src/ssl/tls13_both.c
index e634790..e32464d 100644
--- a/src/ssl/tls13_both.c
+++ b/src/ssl/tls13_both.c
@@ -178,7 +178,7 @@
if (sk_X509_num(chain) == 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_HANDSHAKE_FAILURE);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED);
goto err;
}
@@ -403,13 +403,20 @@
}
static int tls13_receive_key_update(SSL *ssl) {
- if (ssl->init_num != 0) {
+ CBS cbs;
+ uint8_t key_update_request;
+ CBS_init(&cbs, ssl->init_msg, ssl->init_num);
+ if (!CBS_get_u8(&cbs, &key_update_request) ||
+ CBS_len(&cbs) != 0 ||
+ (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);
return 0;
}
- // TODO(svaldez): Send KeyUpdate.
+ /* TODO(svaldez): Send KeyUpdate if |key_update_request| is
+ * |SSL_KEY_UPDATE_REQUESTED|. */
return tls13_rotate_traffic_key(ssl, evp_aead_open);
}
diff --git a/src/ssl/tls13_client.c b/src/ssl/tls13_client.c
index 8f1b516..87ccdc4 100644
--- a/src/ssl/tls13_client.c
+++ b/src/ssl/tls13_client.c
@@ -54,48 +54,110 @@
}
CBS cbs, extensions;
- uint16_t server_wire_version, cipher_suite, group_id;
+ uint16_t server_wire_version;
CBS_init(&cbs, ssl->init_msg, ssl->init_num);
if (!CBS_get_u16(&cbs, &server_wire_version) ||
- !CBS_get_u16(&cbs, &cipher_suite) ||
- !CBS_get_u16(&cbs, &group_id) ||
- /* We do not currently parse any HelloRetryRequest extensions. */
!CBS_get_u16_length_prefixed(&cbs, &extensions) ||
+ /* HelloRetryRequest may not be empty. */
+ CBS_len(&extensions) == 0 ||
CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
return ssl_hs_error;
}
- /* TODO(svaldez): Don't do early_data on HelloRetryRequest. */
+ while (CBS_len(&extensions) != 0) {
+ uint16_t type;
+ CBS extension;
+ if (!CBS_get_u16(&extensions, &type) ||
+ !CBS_get_u16_length_prefixed(&extensions, &extension)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
- const uint16_t *groups;
- size_t groups_len;
- tls1_get_grouplist(ssl, 0 /* local groups */, &groups, &groups_len);
- int found = 0;
- for (size_t i = 0; i < groups_len; i++) {
- if (groups[i] == group_id) {
- found = 1;
- break;
+ switch (type) {
+ case TLSEXT_TYPE_cookie: {
+ if (hs->cookie != NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+
+ /* Cookies may be requested whether or not advertised, so no need to
+ * check. */
+
+ CBS cookie;
+ if (!CBS_get_u16_length_prefixed(&extension, &cookie) ||
+ CBS_len(&cookie) == 0 ||
+ CBS_len(&extension) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+
+ if (!CBS_stow(&cookie, &hs->cookie, &hs->cookie_len)) {
+ return ssl_hs_error;
+ }
+ break;
+ }
+
+ case TLSEXT_TYPE_key_share: {
+ if (hs->retry_group != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ return ssl_hs_error;
+ }
+
+ /* key_share is always advertised, so no need to check. */
+
+ uint16_t group_id;
+ if (!CBS_get_u16(&extension, &group_id) ||
+ CBS_len(&extension) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ return ssl_hs_error;
+ }
+
+ /* The group must be supported. */
+ const uint16_t *groups;
+ size_t groups_len;
+ tls1_get_grouplist(ssl, &groups, &groups_len);
+ int found = 0;
+ for (size_t i = 0; i < groups_len; i++) {
+ if (groups[i] == group_id) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
+ return ssl_hs_error;
+ }
+
+ /* Check that the HelloRetryRequest does not request the key share that
+ * was provided in the initial ClientHello. */
+ if (SSL_ECDH_CTX_get_id(&hs->ecdh_ctx) == group_id) {
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
+ return ssl_hs_error;
+ }
+
+ SSL_ECDH_CTX_cleanup(&hs->ecdh_ctx);
+ hs->retry_group = group_id;
+ break;
+ }
+
+ default:
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION);
+ return ssl_hs_error;
}
}
- if (!found) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
- return ssl_hs_error;
- }
-
- /* Check that the HelloRetryRequest does not request the key share that was
- * provided in the initial ClientHello. */
- if (SSL_ECDH_CTX_get_id(&ssl->s3->hs->ecdh_ctx) == group_id) {
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
- OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
- return ssl_hs_error;
- }
-
- SSL_ECDH_CTX_cleanup(&ssl->s3->hs->ecdh_ctx);
- ssl->s3->hs->retry_group = group_id;
-
+ hs->received_hello_retry_request = 1;
hs->state = state_send_second_client_hello;
return ssl_hs_ok;
}
@@ -183,7 +245,7 @@
case TLSEXT_TYPE_key_share:
if (have_key_share) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
key_share = extension;
@@ -192,7 +254,7 @@
case TLSEXT_TYPE_pre_shared_key:
if (have_pre_shared_key) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
pre_shared_key = extension;
@@ -201,7 +263,7 @@
case TLSEXT_TYPE_signature_algorithms:
if (have_sigalgs) {
OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION);
- ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return ssl_hs_error;
}
sigalgs = extension;
@@ -318,7 +380,7 @@
/* If there was no HelloRetryRequest, the version negotiation logic has
* already hashed the message. */
- if (ssl->s3->hs->retry_group != 0 &&
+ if (hs->received_hello_retry_request &&
!ssl->method->hash_current_message(ssl)) {
return ssl_hs_error;
}
@@ -359,8 +421,6 @@
static enum ssl_hs_wait_t do_process_certificate_request(SSL *ssl,
SSL_HANDSHAKE *hs) {
- ssl->s3->tmp.cert_request = 0;
-
/* CertificateRequest may only be sent in non-resumption handshakes. */
if (ssl->s3->session_reused) {
hs->state = state_process_server_finished;
@@ -403,9 +463,9 @@
return ssl_hs_error;
}
- ssl->s3->tmp.cert_request = 1;
- sk_X509_NAME_pop_free(ssl->s3->tmp.ca_names, X509_NAME_free);
- ssl->s3->tmp.ca_names = ca_sk;
+ ssl->s3->hs->cert_request = 1;
+ sk_X509_NAME_pop_free(ssl->s3->hs->ca_names, X509_NAME_free);
+ ssl->s3->hs->ca_names = ca_sk;
if (!ssl->method->hash_current_message(ssl)) {
return ssl_hs_error;
@@ -458,7 +518,7 @@
static enum ssl_hs_wait_t do_certificate_callback(SSL *ssl, SSL_HANDSHAKE *hs) {
/* The peer didn't request a certificate. */
- if (!ssl->s3->tmp.cert_request) {
+ if (!ssl->s3->hs->cert_request) {
hs->state = state_send_client_finished;
return ssl_hs_ok;
}
@@ -538,9 +598,9 @@
static enum ssl_hs_wait_t do_flush(SSL *ssl, SSL_HANDSHAKE *hs) {
if (!tls13_set_traffic_key(ssl, type_data, evp_aead_open,
- hs->traffic_secret_0, hs->hash_len) ||
+ hs->server_traffic_secret_0, hs->hash_len) ||
!tls13_set_traffic_key(ssl, type_data, evp_aead_seal,
- hs->traffic_secret_0, hs->hash_len) ||
+ hs->client_traffic_secret_0, hs->hash_len) ||
!tls13_finalize_keys(ssl)) {
return ssl_hs_error;
}
diff --git a/src/ssl/tls13_enc.c b/src/ssl/tls13_enc.c
index 88fe8f0..1fcde51 100644
--- a/src/ssl/tls13_enc.c
+++ b/src/ssl/tls13_enc.c
@@ -134,42 +134,27 @@
return 0;
}
- const char *phase;
+ const char *key_label, *iv_label;
switch (type) {
case type_early_handshake:
- phase = "early handshake key expansion, ";
+ key_label = "early handshake key expansion, key";
+ iv_label = "early handshake key expansion, iv";
break;
case type_early_data:
- phase = "early application data key expansion, ";
+ key_label = "early application data key expansion, key";
+ iv_label = "early application data key expansion, iv";
break;
case type_handshake:
- phase = "handshake key expansion, ";
+ key_label = "handshake key expansion, key";
+ iv_label = "handshake key expansion, iv";
break;
case type_data:
- phase = "application data key expansion, ";
+ key_label = "application data key expansion, key";
+ iv_label = "application data key expansion, iv";
break;
default:
return 0;
}
- size_t phase_len = strlen(phase);
-
- const char *purpose = "client write key";
- if ((ssl->server && direction == evp_aead_seal) ||
- (!ssl->server && direction == evp_aead_open)) {
- purpose = "server write key";
- }
- size_t purpose_len = strlen(purpose);
-
- /* The longest label has length 38 (type_early_data) + 16 (either purpose
- * value). */
- uint8_t label[38 + 16];
- size_t label_len = phase_len + purpose_len;
- if (label_len > sizeof(label)) {
- assert(0);
- return 0;
- }
- memcpy(label, phase, phase_len);
- memcpy(label + phase_len, purpose, purpose_len);
/* Look up cipher suite properties. */
const EVP_AEAD *aead;
@@ -184,25 +169,18 @@
/* Derive the key. */
size_t key_len = EVP_AEAD_key_length(aead);
uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
- if (!hkdf_expand_label(key, digest, traffic_secret, traffic_secret_len, label,
- label_len, NULL, 0, key_len)) {
+ if (!hkdf_expand_label(key, digest, traffic_secret, traffic_secret_len,
+ (const uint8_t *)key_label, strlen(key_label), NULL, 0,
+ key_len)) {
return 0;
}
- /* The IV's label ends in "iv" instead of "key". */
- if (label_len < 3) {
- assert(0);
- return 0;
- }
- label_len--;
- label[label_len - 2] = 'i';
- label[label_len - 1] = 'v';
-
/* Derive the IV. */
size_t iv_len = EVP_AEAD_nonce_length(aead);
uint8_t iv[EVP_AEAD_MAX_NONCE_LENGTH];
- if (!hkdf_expand_label(iv, digest, traffic_secret, traffic_secret_len, label,
- label_len, NULL, 0, iv_len)) {
+ if (!hkdf_expand_label(iv, digest, traffic_secret, traffic_secret_len,
+ (const uint8_t *)iv_label, strlen(iv_label), NULL, 0,
+ iv_len)) {
return 0;
}
@@ -235,38 +213,69 @@
return 1;
}
-static const char kTLS13LabelHandshakeTraffic[] = "handshake traffic secret";
-static const char kTLS13LabelApplicationTraffic[] =
- "application traffic secret";
+static const char kTLS13LabelClientHandshakeTraffic[] =
+ "client handshake traffic secret";
+static const char kTLS13LabelServerHandshakeTraffic[] =
+ "server handshake traffic secret";
+static const char kTLS13LabelClientApplicationTraffic[] =
+ "client application traffic secret";
+static const char kTLS13LabelServerApplicationTraffic[] =
+ "server application traffic secret";
int tls13_set_handshake_traffic(SSL *ssl) {
SSL_HANDSHAKE *hs = ssl->s3->hs;
- uint8_t traffic_secret[EVP_MAX_MD_SIZE];
- if (!derive_secret(ssl, traffic_secret, hs->hash_len,
- (const uint8_t *)kTLS13LabelHandshakeTraffic,
- strlen(kTLS13LabelHandshakeTraffic)) ||
- !ssl_log_secret(ssl, "HANDSHAKE_TRAFFIC_SECRET", traffic_secret,
- hs->hash_len) ||
- !tls13_set_traffic_key(ssl, type_handshake, evp_aead_open, traffic_secret,
- hs->hash_len) ||
- !tls13_set_traffic_key(ssl, type_handshake, evp_aead_seal, traffic_secret,
- hs->hash_len)) {
+ uint8_t client_traffic_secret[EVP_MAX_MD_SIZE];
+ uint8_t server_traffic_secret[EVP_MAX_MD_SIZE];
+ if (!derive_secret(ssl, client_traffic_secret, hs->hash_len,
+ (const uint8_t *)kTLS13LabelClientHandshakeTraffic,
+ strlen(kTLS13LabelClientHandshakeTraffic)) ||
+ !ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
+ client_traffic_secret, hs->hash_len) ||
+ !derive_secret(ssl, server_traffic_secret, hs->hash_len,
+ (const uint8_t *)kTLS13LabelServerHandshakeTraffic,
+ strlen(kTLS13LabelServerHandshakeTraffic)) ||
+ !ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
+ server_traffic_secret, hs->hash_len)) {
return 0;
}
+
+ if (ssl->server) {
+ if (!tls13_set_traffic_key(ssl, type_handshake, evp_aead_open,
+ client_traffic_secret, hs->hash_len) ||
+ !tls13_set_traffic_key(ssl, type_handshake, evp_aead_seal,
+ server_traffic_secret, hs->hash_len)) {
+ return 0;
+ }
+ } else {
+ if (!tls13_set_traffic_key(ssl, type_handshake, evp_aead_open,
+ server_traffic_secret, hs->hash_len) ||
+ !tls13_set_traffic_key(ssl, type_handshake, evp_aead_seal,
+ client_traffic_secret, hs->hash_len)) {
+ return 0;
+ }
+ }
return 1;
}
int tls13_derive_traffic_secret_0(SSL *ssl) {
SSL_HANDSHAKE *hs = ssl->s3->hs;
- return derive_secret(ssl, hs->traffic_secret_0, hs->hash_len,
- (const uint8_t *)kTLS13LabelApplicationTraffic,
- strlen(kTLS13LabelApplicationTraffic)) &&
- ssl_log_secret(ssl, "TRAFFIC_SECRET_0", hs->traffic_secret_0,
- hs->hash_len);
+ return derive_secret(ssl, hs->client_traffic_secret_0, hs->hash_len,
+ (const uint8_t *)kTLS13LabelClientApplicationTraffic,
+ strlen(kTLS13LabelClientApplicationTraffic)) &&
+ ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0",
+ hs->client_traffic_secret_0, hs->hash_len) &&
+ derive_secret(ssl, hs->server_traffic_secret_0, hs->hash_len,
+ (const uint8_t *)kTLS13LabelServerApplicationTraffic,
+ strlen(kTLS13LabelServerApplicationTraffic)) &&
+ ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0",
+ hs->server_traffic_secret_0, hs->hash_len);
}
+static const char kTLS13LabelApplicationTraffic[] =
+ "application traffic secret";
+
int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) {
const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));
@@ -319,21 +328,11 @@
size_t key_len = EVP_MD_size(digest);
const uint8_t *traffic_secret;
- const char *label;
- if (is_server) {
- label = "server finished";
- if (ssl->server) {
- traffic_secret = ssl->s3->write_traffic_secret;
- } else {
- traffic_secret = ssl->s3->read_traffic_secret;
- }
+ const char *label = "finished";
+ if (is_server == ssl->server) {
+ traffic_secret = ssl->s3->write_traffic_secret;
} else {
- label = "client finished";
- if (!ssl->server) {
- traffic_secret = ssl->s3->write_traffic_secret;
- } else {
- traffic_secret = ssl->s3->read_traffic_secret;
- }
+ traffic_secret = ssl->s3->read_traffic_secret;
}
uint8_t context_hashes[2 * EVP_MAX_MD_SIZE];
diff --git a/src/ssl/tls13_server.c b/src/ssl/tls13_server.c
index 984cc5c..2570069 100644
--- a/src/ssl/tls13_server.c
+++ b/src/ssl/tls13_server.c
@@ -254,10 +254,11 @@
if (!ssl->method->init_message(ssl, &cbb, &body,
SSL3_MT_HELLO_RETRY_REQUEST) ||
!CBB_add_u16(&body, ssl->version) ||
- !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) ||
!tls1_get_shared_group(ssl, &group_id) ||
- !CBB_add_u16(&body, group_id) ||
!CBB_add_u16_length_prefixed(&body, &extensions) ||
+ !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) ||
+ !CBB_add_u16(&extensions, 2 /* length */) ||
+ !CBB_add_u16(&extensions, group_id) ||
!ssl->method->finish_message(ssl, &cbb)) {
CBB_cleanup(&cbb);
return ssl_hs_error;
@@ -360,13 +361,13 @@
static enum ssl_hs_wait_t do_send_certificate_request(SSL *ssl,
SSL_HANDSHAKE *hs) {
/* Determine whether to request a client certificate. */
- ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
+ ssl->s3->hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER);
/* CertificateRequest may only be sent in non-resumption handshakes. */
if (ssl->s3->session_reused) {
- ssl->s3->tmp.cert_request = 0;
+ ssl->s3->hs->cert_request = 0;
}
- if (!ssl->s3->tmp.cert_request) {
+ if (!ssl->s3->hs->cert_request) {
/* Skip this state. */
hs->state = state_send_server_certificate;
return ssl_hs_ok;
@@ -380,7 +381,7 @@
}
const uint16_t *sigalgs;
- size_t num_sigalgs = tls12_get_psigalgs(ssl, &sigalgs);
+ size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs);
if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) {
goto err;
}
@@ -459,7 +460,7 @@
if (!tls13_advance_key_schedule(ssl, kZeroes, hs->hash_len) ||
!tls13_derive_traffic_secret_0(ssl) ||
!tls13_set_traffic_key(ssl, type_data, evp_aead_seal,
- hs->traffic_secret_0, hs->hash_len)) {
+ hs->server_traffic_secret_0, hs->hash_len)) {
return ssl_hs_error;
}
@@ -469,7 +470,7 @@
static enum ssl_hs_wait_t do_process_client_certificate(SSL *ssl,
SSL_HANDSHAKE *hs) {
- if (!ssl->s3->tmp.cert_request) {
+ if (!ssl->s3->hs->cert_request) {
/* OpenSSL returns X509_V_OK when no certificates are requested. This is
* classed by them as a bug, but it's assumed by at least NGINX. */
ssl->s3->new_session->verify_result = X509_V_OK;
@@ -523,7 +524,7 @@
!ssl->method->hash_current_message(ssl) ||
/* evp_aead_seal keys have already been switched. */
!tls13_set_traffic_key(ssl, type_data, evp_aead_open,
- hs->traffic_secret_0, hs->hash_len) ||
+ hs->client_traffic_secret_0, hs->hash_len) ||
!tls13_finalize_keys(ssl)) {
return ssl_hs_error;
}
@@ -541,7 +542,7 @@
/* TODO(svaldez): Add support for sending 0RTT through TicketEarlyDataInfo
* extension. */
- CBB cbb, body, ke_modes, auth_modes, ticket;
+ CBB cbb, body, ke_modes, auth_modes, ticket, extensions;
if (!ssl->method->init_message(ssl, &cbb, &body,
SSL3_MT_NEW_SESSION_TICKET) ||
!CBB_add_u32(&body, session->tlsext_tick_lifetime_hint) ||
@@ -551,16 +552,31 @@
!CBB_add_u8(&auth_modes, SSL_PSK_AUTH) ||
!CBB_add_u16_length_prefixed(&body, &ticket) ||
!ssl_encrypt_ticket(ssl, &ticket, session) ||
- !CBB_add_u16(&body, 0 /* no ticket extensions */) ||
- !ssl->method->finish_message(ssl, &cbb)) {
- CBB_cleanup(&cbb);
- return ssl_hs_error;
+ !CBB_add_u16_length_prefixed(&body, &extensions)) {
+ goto err;
+ }
+
+ /* Add a fake extension. See draft-davidben-tls-grease-01. */
+ if (ssl->ctx->grease_enabled) {
+ if (!CBB_add_u16(&extensions,
+ ssl_get_grease_value(ssl, ssl_grease_ticket_extension)) ||
+ !CBB_add_u16(&extensions, 0 /* empty */)) {
+ goto err;
+ }
+ }
+
+ if (!ssl->method->finish_message(ssl, &cbb)) {
+ goto err;
}
hs->session_tickets_sent++;
hs->state = state_flush_new_session_ticket;
return ssl_hs_write_message;
+
+err:
+ CBB_cleanup(&cbb);
+ return ssl_hs_error;
}
/* TLS 1.3 recommends single-use tickets, so issue multiple tickets in case the
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 9a3612c..d5326b5 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -40,7 +40,7 @@
OPENSSL_MSVC_PRAGMA(warning(pop))
typedef int ssize_t;
-#pragma comment(lib, "Ws2_32.lib")
+OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib"))
#endif
#include <openssl/err.h>