xref: /aosp_15_r20/external/boringssl/src/ssl/ssl_test.cc (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
1*8fb009dcSAndroid Build Coastguard Worker /* Copyright (c) 2014, Google Inc.
2*8fb009dcSAndroid Build Coastguard Worker  *
3*8fb009dcSAndroid Build Coastguard Worker  * Permission to use, copy, modify, and/or distribute this software for any
4*8fb009dcSAndroid Build Coastguard Worker  * purpose with or without fee is hereby granted, provided that the above
5*8fb009dcSAndroid Build Coastguard Worker  * copyright notice and this permission notice appear in all copies.
6*8fb009dcSAndroid Build Coastguard Worker  *
7*8fb009dcSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8*8fb009dcSAndroid Build Coastguard Worker  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9*8fb009dcSAndroid Build Coastguard Worker  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10*8fb009dcSAndroid Build Coastguard Worker  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11*8fb009dcSAndroid Build Coastguard Worker  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12*8fb009dcSAndroid Build Coastguard Worker  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13*8fb009dcSAndroid Build Coastguard Worker  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14*8fb009dcSAndroid Build Coastguard Worker 
15*8fb009dcSAndroid Build Coastguard Worker #include <limits.h>
16*8fb009dcSAndroid Build Coastguard Worker #include <stdio.h>
17*8fb009dcSAndroid Build Coastguard Worker #include <string.h>
18*8fb009dcSAndroid Build Coastguard Worker #include <time.h>
19*8fb009dcSAndroid Build Coastguard Worker 
20*8fb009dcSAndroid Build Coastguard Worker #include <algorithm>
21*8fb009dcSAndroid Build Coastguard Worker #include <limits>
22*8fb009dcSAndroid Build Coastguard Worker #include <string>
23*8fb009dcSAndroid Build Coastguard Worker #include <utility>
24*8fb009dcSAndroid Build Coastguard Worker #include <vector>
25*8fb009dcSAndroid Build Coastguard Worker 
26*8fb009dcSAndroid Build Coastguard Worker #include <gmock/gmock.h>
27*8fb009dcSAndroid Build Coastguard Worker #include <gtest/gtest.h>
28*8fb009dcSAndroid Build Coastguard Worker 
29*8fb009dcSAndroid Build Coastguard Worker #include <openssl/aead.h>
30*8fb009dcSAndroid Build Coastguard Worker #include <openssl/base64.h>
31*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bytestring.h>
32*8fb009dcSAndroid Build Coastguard Worker #include <openssl/bio.h>
33*8fb009dcSAndroid Build Coastguard Worker #include <openssl/cipher.h>
34*8fb009dcSAndroid Build Coastguard Worker #include <openssl/crypto.h>
35*8fb009dcSAndroid Build Coastguard Worker #include <openssl/curve25519.h>
36*8fb009dcSAndroid Build Coastguard Worker #include <openssl/err.h>
37*8fb009dcSAndroid Build Coastguard Worker #include <openssl/hmac.h>
38*8fb009dcSAndroid Build Coastguard Worker #include <openssl/hpke.h>
39*8fb009dcSAndroid Build Coastguard Worker #include <openssl/pem.h>
40*8fb009dcSAndroid Build Coastguard Worker #include <openssl/sha.h>
41*8fb009dcSAndroid Build Coastguard Worker #include <openssl/ssl.h>
42*8fb009dcSAndroid Build Coastguard Worker #include <openssl/rand.h>
43*8fb009dcSAndroid Build Coastguard Worker #include <openssl/x509.h>
44*8fb009dcSAndroid Build Coastguard Worker 
45*8fb009dcSAndroid Build Coastguard Worker #include "internal.h"
46*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/internal.h"
47*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/test/file_util.h"
48*8fb009dcSAndroid Build Coastguard Worker #include "../crypto/test/test_util.h"
49*8fb009dcSAndroid Build Coastguard Worker 
50*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_WINDOWS)
51*8fb009dcSAndroid Build Coastguard Worker // Windows defines struct timeval in winsock2.h.
52*8fb009dcSAndroid Build Coastguard Worker OPENSSL_MSVC_PRAGMA(warning(push, 3))
53*8fb009dcSAndroid Build Coastguard Worker #include <winsock2.h>
54*8fb009dcSAndroid Build Coastguard Worker OPENSSL_MSVC_PRAGMA(warning(pop))
55*8fb009dcSAndroid Build Coastguard Worker #else
56*8fb009dcSAndroid Build Coastguard Worker #include <sys/time.h>
57*8fb009dcSAndroid Build Coastguard Worker #endif
58*8fb009dcSAndroid Build Coastguard Worker 
59*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_THREADS)
60*8fb009dcSAndroid Build Coastguard Worker #include <thread>
61*8fb009dcSAndroid Build Coastguard Worker #endif
62*8fb009dcSAndroid Build Coastguard Worker 
63*8fb009dcSAndroid Build Coastguard Worker 
64*8fb009dcSAndroid Build Coastguard Worker using testing::ElementsAre;
65*8fb009dcSAndroid Build Coastguard Worker using testing::Key;
66*8fb009dcSAndroid Build Coastguard Worker 
67*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_BEGIN
68*8fb009dcSAndroid Build Coastguard Worker 
69*8fb009dcSAndroid Build Coastguard Worker namespace {
70*8fb009dcSAndroid Build Coastguard Worker 
71*8fb009dcSAndroid Build Coastguard Worker #define TRACED_CALL(code)                     \
72*8fb009dcSAndroid Build Coastguard Worker   do {                                        \
73*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE("<- called from here");      \
74*8fb009dcSAndroid Build Coastguard Worker     code;                                     \
75*8fb009dcSAndroid Build Coastguard Worker     if (::testing::Test::HasFatalFailure()) { \
76*8fb009dcSAndroid Build Coastguard Worker       return;                                 \
77*8fb009dcSAndroid Build Coastguard Worker     }                                         \
78*8fb009dcSAndroid Build Coastguard Worker   } while (false)
79*8fb009dcSAndroid Build Coastguard Worker 
80*8fb009dcSAndroid Build Coastguard Worker struct VersionParam {
81*8fb009dcSAndroid Build Coastguard Worker   uint16_t version;
82*8fb009dcSAndroid Build Coastguard Worker   enum { is_tls, is_dtls } ssl_method;
83*8fb009dcSAndroid Build Coastguard Worker   const char name[8];
84*8fb009dcSAndroid Build Coastguard Worker };
85*8fb009dcSAndroid Build Coastguard Worker 
86*8fb009dcSAndroid Build Coastguard Worker static const size_t kTicketKeyLen = 48;
87*8fb009dcSAndroid Build Coastguard Worker 
88*8fb009dcSAndroid Build Coastguard Worker static const VersionParam kAllVersions[] = {
89*8fb009dcSAndroid Build Coastguard Worker     {TLS1_VERSION, VersionParam::is_tls, "TLS1"},
90*8fb009dcSAndroid Build Coastguard Worker     {TLS1_1_VERSION, VersionParam::is_tls, "TLS1_1"},
91*8fb009dcSAndroid Build Coastguard Worker     {TLS1_2_VERSION, VersionParam::is_tls, "TLS1_2"},
92*8fb009dcSAndroid Build Coastguard Worker     {TLS1_3_VERSION, VersionParam::is_tls, "TLS1_3"},
93*8fb009dcSAndroid Build Coastguard Worker     {DTLS1_VERSION, VersionParam::is_dtls, "DTLS1"},
94*8fb009dcSAndroid Build Coastguard Worker     {DTLS1_2_VERSION, VersionParam::is_dtls, "DTLS1_2"},
95*8fb009dcSAndroid Build Coastguard Worker };
96*8fb009dcSAndroid Build Coastguard Worker 
97*8fb009dcSAndroid Build Coastguard Worker struct ExpectedCipher {
98*8fb009dcSAndroid Build Coastguard Worker   unsigned long id;
99*8fb009dcSAndroid Build Coastguard Worker   int in_group_flag;
100*8fb009dcSAndroid Build Coastguard Worker };
101*8fb009dcSAndroid Build Coastguard Worker 
102*8fb009dcSAndroid Build Coastguard Worker struct CipherTest {
103*8fb009dcSAndroid Build Coastguard Worker   // The rule string to apply.
104*8fb009dcSAndroid Build Coastguard Worker   const char *rule;
105*8fb009dcSAndroid Build Coastguard Worker   // The list of expected ciphers, in order.
106*8fb009dcSAndroid Build Coastguard Worker   std::vector<ExpectedCipher> expected;
107*8fb009dcSAndroid Build Coastguard Worker   // True if this cipher list should fail in strict mode.
108*8fb009dcSAndroid Build Coastguard Worker   bool strict_fail;
109*8fb009dcSAndroid Build Coastguard Worker };
110*8fb009dcSAndroid Build Coastguard Worker 
111*8fb009dcSAndroid Build Coastguard Worker struct CurveTest {
112*8fb009dcSAndroid Build Coastguard Worker   // The rule string to apply.
113*8fb009dcSAndroid Build Coastguard Worker   const char *rule;
114*8fb009dcSAndroid Build Coastguard Worker   // The list of expected curves, in order.
115*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint16_t> expected;
116*8fb009dcSAndroid Build Coastguard Worker };
117*8fb009dcSAndroid Build Coastguard Worker 
118*8fb009dcSAndroid Build Coastguard Worker template <typename T>
119*8fb009dcSAndroid Build Coastguard Worker class UnownedSSLExData {
120*8fb009dcSAndroid Build Coastguard Worker  public:
UnownedSSLExData()121*8fb009dcSAndroid Build Coastguard Worker   UnownedSSLExData() {
122*8fb009dcSAndroid Build Coastguard Worker     index_ = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
123*8fb009dcSAndroid Build Coastguard Worker   }
124*8fb009dcSAndroid Build Coastguard Worker 
Get(const SSL * ssl)125*8fb009dcSAndroid Build Coastguard Worker   T *Get(const SSL *ssl) {
126*8fb009dcSAndroid Build Coastguard Worker     return index_ < 0 ? nullptr
127*8fb009dcSAndroid Build Coastguard Worker                       : static_cast<T *>(SSL_get_ex_data(ssl, index_));
128*8fb009dcSAndroid Build Coastguard Worker   }
129*8fb009dcSAndroid Build Coastguard Worker 
Set(SSL * ssl,T * t)130*8fb009dcSAndroid Build Coastguard Worker   bool Set(SSL *ssl, T *t) {
131*8fb009dcSAndroid Build Coastguard Worker     return index_ >= 0 && SSL_set_ex_data(ssl, index_, t);
132*8fb009dcSAndroid Build Coastguard Worker   }
133*8fb009dcSAndroid Build Coastguard Worker 
134*8fb009dcSAndroid Build Coastguard Worker  private:
135*8fb009dcSAndroid Build Coastguard Worker   int index_;
136*8fb009dcSAndroid Build Coastguard Worker };
137*8fb009dcSAndroid Build Coastguard Worker 
138*8fb009dcSAndroid Build Coastguard Worker static const CipherTest kCipherTests[] = {
139*8fb009dcSAndroid Build Coastguard Worker     // Selecting individual ciphers should work.
140*8fb009dcSAndroid Build Coastguard Worker     {
141*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-CHACHA20-POLY1305:"
142*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-CHACHA20-POLY1305:"
143*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-AES128-GCM-SHA256:"
144*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256",
145*8fb009dcSAndroid Build Coastguard Worker         {
146*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
147*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
148*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
149*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
150*8fb009dcSAndroid Build Coastguard Worker         },
151*8fb009dcSAndroid Build Coastguard Worker         false,
152*8fb009dcSAndroid Build Coastguard Worker     },
153*8fb009dcSAndroid Build Coastguard Worker     // + reorders selected ciphers to the end, keeping their relative order.
154*8fb009dcSAndroid Build Coastguard Worker     {
155*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-CHACHA20-POLY1305:"
156*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-CHACHA20-POLY1305:"
157*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-AES128-GCM-SHA256:"
158*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256:"
159*8fb009dcSAndroid Build Coastguard Worker         "+aRSA",
160*8fb009dcSAndroid Build Coastguard Worker         {
161*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
162*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
163*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
164*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
165*8fb009dcSAndroid Build Coastguard Worker         },
166*8fb009dcSAndroid Build Coastguard Worker         false,
167*8fb009dcSAndroid Build Coastguard Worker     },
168*8fb009dcSAndroid Build Coastguard Worker     // ! banishes ciphers from future selections.
169*8fb009dcSAndroid Build Coastguard Worker     {
170*8fb009dcSAndroid Build Coastguard Worker         "!aRSA:"
171*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-CHACHA20-POLY1305:"
172*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-CHACHA20-POLY1305:"
173*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-AES128-GCM-SHA256:"
174*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256",
175*8fb009dcSAndroid Build Coastguard Worker         {
176*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
177*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
178*8fb009dcSAndroid Build Coastguard Worker         },
179*8fb009dcSAndroid Build Coastguard Worker         false,
180*8fb009dcSAndroid Build Coastguard Worker     },
181*8fb009dcSAndroid Build Coastguard Worker     // Multiple masks can be ANDed in a single rule.
182*8fb009dcSAndroid Build Coastguard Worker     {
183*8fb009dcSAndroid Build Coastguard Worker         "kRSA+AESGCM+AES128",
184*8fb009dcSAndroid Build Coastguard Worker         {
185*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
186*8fb009dcSAndroid Build Coastguard Worker         },
187*8fb009dcSAndroid Build Coastguard Worker         false,
188*8fb009dcSAndroid Build Coastguard Worker     },
189*8fb009dcSAndroid Build Coastguard Worker     // - removes selected ciphers, but preserves their order for future
190*8fb009dcSAndroid Build Coastguard Worker     // selections. Select AES_128_GCM, but order the key exchanges RSA,
191*8fb009dcSAndroid Build Coastguard Worker     // ECDHE_RSA.
192*8fb009dcSAndroid Build Coastguard Worker     {
193*8fb009dcSAndroid Build Coastguard Worker         "ALL:-kECDHE:"
194*8fb009dcSAndroid Build Coastguard Worker         "-kRSA:-ALL:"
195*8fb009dcSAndroid Build Coastguard Worker         "AESGCM+AES128+aRSA",
196*8fb009dcSAndroid Build Coastguard Worker         {
197*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
198*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
199*8fb009dcSAndroid Build Coastguard Worker         },
200*8fb009dcSAndroid Build Coastguard Worker         false,
201*8fb009dcSAndroid Build Coastguard Worker     },
202*8fb009dcSAndroid Build Coastguard Worker     // Unknown selectors are no-ops, except in strict mode.
203*8fb009dcSAndroid Build Coastguard Worker     {
204*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-CHACHA20-POLY1305:"
205*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-CHACHA20-POLY1305:"
206*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-AES128-GCM-SHA256:"
207*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256:"
208*8fb009dcSAndroid Build Coastguard Worker         "BOGUS1",
209*8fb009dcSAndroid Build Coastguard Worker         {
210*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
211*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
212*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
213*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
214*8fb009dcSAndroid Build Coastguard Worker         },
215*8fb009dcSAndroid Build Coastguard Worker         true,
216*8fb009dcSAndroid Build Coastguard Worker     },
217*8fb009dcSAndroid Build Coastguard Worker     // Unknown selectors are no-ops, except in strict mode.
218*8fb009dcSAndroid Build Coastguard Worker     {
219*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-CHACHA20-POLY1305:"
220*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-CHACHA20-POLY1305:"
221*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-AES128-GCM-SHA256:"
222*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256:"
223*8fb009dcSAndroid Build Coastguard Worker         "-BOGUS2:+BOGUS3:!BOGUS4",
224*8fb009dcSAndroid Build Coastguard Worker         {
225*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 0},
226*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
227*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
228*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
229*8fb009dcSAndroid Build Coastguard Worker         },
230*8fb009dcSAndroid Build Coastguard Worker         true,
231*8fb009dcSAndroid Build Coastguard Worker     },
232*8fb009dcSAndroid Build Coastguard Worker     // Square brackets specify equi-preference groups.
233*8fb009dcSAndroid Build Coastguard Worker     {
234*8fb009dcSAndroid Build Coastguard Worker         "[ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256]:"
235*8fb009dcSAndroid Build Coastguard Worker         "[ECDHE-RSA-CHACHA20-POLY1305]:"
236*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256",
237*8fb009dcSAndroid Build Coastguard Worker         {
238*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
239*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
240*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
241*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
242*8fb009dcSAndroid Build Coastguard Worker         },
243*8fb009dcSAndroid Build Coastguard Worker         false,
244*8fb009dcSAndroid Build Coastguard Worker     },
245*8fb009dcSAndroid Build Coastguard Worker     // Standard names may be used instead of OpenSSL names.
246*8fb009dcSAndroid Build Coastguard Worker     {
247*8fb009dcSAndroid Build Coastguard Worker         "[TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256|"
248*8fb009dcSAndroid Build Coastguard Worker         "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256]:"
249*8fb009dcSAndroid Build Coastguard Worker         "[TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256]:"
250*8fb009dcSAndroid Build Coastguard Worker         "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
251*8fb009dcSAndroid Build Coastguard Worker         {
252*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 1},
253*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
254*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
255*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
256*8fb009dcSAndroid Build Coastguard Worker         },
257*8fb009dcSAndroid Build Coastguard Worker         false,
258*8fb009dcSAndroid Build Coastguard Worker     },
259*8fb009dcSAndroid Build Coastguard Worker     // @STRENGTH performs a stable strength-sort of the selected ciphers and
260*8fb009dcSAndroid Build Coastguard Worker     // only the selected ciphers.
261*8fb009dcSAndroid Build Coastguard Worker     {
262*8fb009dcSAndroid Build Coastguard Worker         // To simplify things, banish all but {ECDHE_RSA,RSA} x
263*8fb009dcSAndroid Build Coastguard Worker         // {CHACHA20,AES_256_CBC,AES_128_CBC} x SHA1.
264*8fb009dcSAndroid Build Coastguard Worker         "!AESGCM:!3DES:"
265*8fb009dcSAndroid Build Coastguard Worker         // Order some ciphers backwards by strength.
266*8fb009dcSAndroid Build Coastguard Worker         "ALL:-CHACHA20:-AES256:-AES128:-ALL:"
267*8fb009dcSAndroid Build Coastguard Worker         // Select ECDHE ones and sort them by strength. Ties should resolve
268*8fb009dcSAndroid Build Coastguard Worker         // based on the order above.
269*8fb009dcSAndroid Build Coastguard Worker         "kECDHE:@STRENGTH:-ALL:"
270*8fb009dcSAndroid Build Coastguard Worker         // Now bring back everything uses RSA. ECDHE_RSA should be first, sorted
271*8fb009dcSAndroid Build Coastguard Worker         // by strength. Then RSA, backwards by strength.
272*8fb009dcSAndroid Build Coastguard Worker         "aRSA",
273*8fb009dcSAndroid Build Coastguard Worker         {
274*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, 0},
275*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
276*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, 0},
277*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
278*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
279*8fb009dcSAndroid Build Coastguard Worker         },
280*8fb009dcSAndroid Build Coastguard Worker         false,
281*8fb009dcSAndroid Build Coastguard Worker     },
282*8fb009dcSAndroid Build Coastguard Worker     // Additional masks after @STRENGTH get silently discarded.
283*8fb009dcSAndroid Build Coastguard Worker     //
284*8fb009dcSAndroid Build Coastguard Worker     // TODO(davidben): Make this an error. If not silently discarded, they get
285*8fb009dcSAndroid Build Coastguard Worker     // interpreted as + opcodes which are very different.
286*8fb009dcSAndroid Build Coastguard Worker     {
287*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256:"
288*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES256-GCM-SHA384:"
289*8fb009dcSAndroid Build Coastguard Worker         "@STRENGTH+AES256",
290*8fb009dcSAndroid Build Coastguard Worker         {
291*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
292*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
293*8fb009dcSAndroid Build Coastguard Worker         },
294*8fb009dcSAndroid Build Coastguard Worker         false,
295*8fb009dcSAndroid Build Coastguard Worker     },
296*8fb009dcSAndroid Build Coastguard Worker     {
297*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256:"
298*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES256-GCM-SHA384:"
299*8fb009dcSAndroid Build Coastguard Worker         "@STRENGTH+AES256:"
300*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-CHACHA20-POLY1305",
301*8fb009dcSAndroid Build Coastguard Worker         {
302*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 0},
303*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
304*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 0},
305*8fb009dcSAndroid Build Coastguard Worker         },
306*8fb009dcSAndroid Build Coastguard Worker         false,
307*8fb009dcSAndroid Build Coastguard Worker     },
308*8fb009dcSAndroid Build Coastguard Worker     // Exact ciphers may not be used in multi-part rules; they are treated
309*8fb009dcSAndroid Build Coastguard Worker     // as unknown aliases.
310*8fb009dcSAndroid Build Coastguard Worker     {
311*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-ECDSA-AES128-GCM-SHA256:"
312*8fb009dcSAndroid Build Coastguard Worker         "ECDHE-RSA-AES128-GCM-SHA256:"
313*8fb009dcSAndroid Build Coastguard Worker         "!ECDHE-RSA-AES128-GCM-SHA256+RSA:"
314*8fb009dcSAndroid Build Coastguard Worker         "!ECDSA+ECDHE-ECDSA-AES128-GCM-SHA256",
315*8fb009dcSAndroid Build Coastguard Worker         {
316*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
317*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
318*8fb009dcSAndroid Build Coastguard Worker         },
319*8fb009dcSAndroid Build Coastguard Worker         true,
320*8fb009dcSAndroid Build Coastguard Worker     },
321*8fb009dcSAndroid Build Coastguard Worker     // SSLv3 matches everything that existed before TLS 1.2.
322*8fb009dcSAndroid Build Coastguard Worker     {
323*8fb009dcSAndroid Build Coastguard Worker         "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!SSLv3",
324*8fb009dcSAndroid Build Coastguard Worker         {
325*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
326*8fb009dcSAndroid Build Coastguard Worker         },
327*8fb009dcSAndroid Build Coastguard Worker         false,
328*8fb009dcSAndroid Build Coastguard Worker     },
329*8fb009dcSAndroid Build Coastguard Worker     // TLSv1.2 matches everything added in TLS 1.2.
330*8fb009dcSAndroid Build Coastguard Worker     {
331*8fb009dcSAndroid Build Coastguard Worker         "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2",
332*8fb009dcSAndroid Build Coastguard Worker         {
333*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
334*8fb009dcSAndroid Build Coastguard Worker         },
335*8fb009dcSAndroid Build Coastguard Worker         false,
336*8fb009dcSAndroid Build Coastguard Worker     },
337*8fb009dcSAndroid Build Coastguard Worker     // The two directives have no intersection.  But each component is valid, so
338*8fb009dcSAndroid Build Coastguard Worker     // even in strict mode it is accepted.
339*8fb009dcSAndroid Build Coastguard Worker     {
340*8fb009dcSAndroid Build Coastguard Worker         "AES128-SHA:ECDHE-RSA-AES128-GCM-SHA256:!TLSv1.2+SSLv3",
341*8fb009dcSAndroid Build Coastguard Worker         {
342*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
343*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
344*8fb009dcSAndroid Build Coastguard Worker         },
345*8fb009dcSAndroid Build Coastguard Worker         false,
346*8fb009dcSAndroid Build Coastguard Worker     },
347*8fb009dcSAndroid Build Coastguard Worker     // Spaces, semi-colons and commas are separators.
348*8fb009dcSAndroid Build Coastguard Worker     {
349*8fb009dcSAndroid Build Coastguard Worker         "AES128-SHA: ECDHE-RSA-AES128-GCM-SHA256 AES256-SHA ,ECDHE-ECDSA-AES128-GCM-SHA256 ; AES128-GCM-SHA256",
350*8fb009dcSAndroid Build Coastguard Worker         {
351*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
352*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 0},
353*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
354*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
355*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
356*8fb009dcSAndroid Build Coastguard Worker         },
357*8fb009dcSAndroid Build Coastguard Worker         // …but not in strict mode.
358*8fb009dcSAndroid Build Coastguard Worker         true,
359*8fb009dcSAndroid Build Coastguard Worker     },
360*8fb009dcSAndroid Build Coastguard Worker     // 3DES ciphers are disabled by default.
361*8fb009dcSAndroid Build Coastguard Worker     {
362*8fb009dcSAndroid Build Coastguard Worker         "RSA",
363*8fb009dcSAndroid Build Coastguard Worker         {
364*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
365*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, 0},
366*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
367*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
368*8fb009dcSAndroid Build Coastguard Worker         },
369*8fb009dcSAndroid Build Coastguard Worker         false,
370*8fb009dcSAndroid Build Coastguard Worker     },
371*8fb009dcSAndroid Build Coastguard Worker     // But 3DES ciphers may be specified by name.
372*8fb009dcSAndroid Build Coastguard Worker     {
373*8fb009dcSAndroid Build Coastguard Worker         "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
374*8fb009dcSAndroid Build Coastguard Worker         {
375*8fb009dcSAndroid Build Coastguard Worker             {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
376*8fb009dcSAndroid Build Coastguard Worker         },
377*8fb009dcSAndroid Build Coastguard Worker         false,
378*8fb009dcSAndroid Build Coastguard Worker     },
379*8fb009dcSAndroid Build Coastguard Worker     {
380*8fb009dcSAndroid Build Coastguard Worker         "DES-CBC3-SHA",
381*8fb009dcSAndroid Build Coastguard Worker         {
382*8fb009dcSAndroid Build Coastguard Worker             {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
383*8fb009dcSAndroid Build Coastguard Worker         },
384*8fb009dcSAndroid Build Coastguard Worker         false,
385*8fb009dcSAndroid Build Coastguard Worker     },
386*8fb009dcSAndroid Build Coastguard Worker     // Or by a selector that specifically includes deprecated ciphers.
387*8fb009dcSAndroid Build Coastguard Worker     {
388*8fb009dcSAndroid Build Coastguard Worker         "3DES",
389*8fb009dcSAndroid Build Coastguard Worker         {
390*8fb009dcSAndroid Build Coastguard Worker             {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
391*8fb009dcSAndroid Build Coastguard Worker         },
392*8fb009dcSAndroid Build Coastguard Worker         false,
393*8fb009dcSAndroid Build Coastguard Worker     },
394*8fb009dcSAndroid Build Coastguard Worker     // Such selectors may be combined with other selectors that would otherwise
395*8fb009dcSAndroid Build Coastguard Worker     // not allow deprecated ciphers.
396*8fb009dcSAndroid Build Coastguard Worker     {
397*8fb009dcSAndroid Build Coastguard Worker         "RSA+3DES",
398*8fb009dcSAndroid Build Coastguard Worker         {
399*8fb009dcSAndroid Build Coastguard Worker             {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
400*8fb009dcSAndroid Build Coastguard Worker         },
401*8fb009dcSAndroid Build Coastguard Worker         false,
402*8fb009dcSAndroid Build Coastguard Worker     },
403*8fb009dcSAndroid Build Coastguard Worker     // The cipher must still match all combined selectors, however. "ECDHE+3DES"
404*8fb009dcSAndroid Build Coastguard Worker     // matches nothing because we do not implement
405*8fb009dcSAndroid Build Coastguard Worker     // TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA. (The test includes
406*8fb009dcSAndroid Build Coastguard Worker     // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 so the final list is not empty.)
407*8fb009dcSAndroid Build Coastguard Worker     {
408*8fb009dcSAndroid Build Coastguard Worker         "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:ECDHE+3DES",
409*8fb009dcSAndroid Build Coastguard Worker         {
410*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
411*8fb009dcSAndroid Build Coastguard Worker         },
412*8fb009dcSAndroid Build Coastguard Worker         false,
413*8fb009dcSAndroid Build Coastguard Worker     },
414*8fb009dcSAndroid Build Coastguard Worker     // Although alises like "RSA" do not match 3DES when adding ciphers, they do
415*8fb009dcSAndroid Build Coastguard Worker     // match it when removing ciphers.
416*8fb009dcSAndroid Build Coastguard Worker     {
417*8fb009dcSAndroid Build Coastguard Worker         "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:RSA:RSA+3DES:!RSA",
418*8fb009dcSAndroid Build Coastguard Worker         {
419*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 0},
420*8fb009dcSAndroid Build Coastguard Worker         },
421*8fb009dcSAndroid Build Coastguard Worker         false,
422*8fb009dcSAndroid Build Coastguard Worker     },
423*8fb009dcSAndroid Build Coastguard Worker     // 3DES still participates in strength sorting.
424*8fb009dcSAndroid Build Coastguard Worker     {
425*8fb009dcSAndroid Build Coastguard Worker         "RSA:3DES:@STRENGTH",
426*8fb009dcSAndroid Build Coastguard Worker         {
427*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, 0},
428*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_256_SHA, 0},
429*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, 0},
430*8fb009dcSAndroid Build Coastguard Worker             {TLS1_CK_RSA_WITH_AES_128_SHA, 0},
431*8fb009dcSAndroid Build Coastguard Worker             {SSL3_CK_RSA_DES_192_CBC3_SHA, 0},
432*8fb009dcSAndroid Build Coastguard Worker         },
433*8fb009dcSAndroid Build Coastguard Worker         false,
434*8fb009dcSAndroid Build Coastguard Worker     },
435*8fb009dcSAndroid Build Coastguard Worker };
436*8fb009dcSAndroid Build Coastguard Worker 
437*8fb009dcSAndroid Build Coastguard Worker static const char *kBadRules[] = {
438*8fb009dcSAndroid Build Coastguard Worker   // Invalid brackets.
439*8fb009dcSAndroid Build Coastguard Worker   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256",
440*8fb009dcSAndroid Build Coastguard Worker   "RSA]",
441*8fb009dcSAndroid Build Coastguard Worker   "[[RSA]]",
442*8fb009dcSAndroid Build Coastguard Worker   // Operators inside brackets.
443*8fb009dcSAndroid Build Coastguard Worker   "[+RSA]",
444*8fb009dcSAndroid Build Coastguard Worker   // Unknown directive.
445*8fb009dcSAndroid Build Coastguard Worker   "@BOGUS",
446*8fb009dcSAndroid Build Coastguard Worker   // Empty cipher lists error at SSL_CTX_set_cipher_list.
447*8fb009dcSAndroid Build Coastguard Worker   "",
448*8fb009dcSAndroid Build Coastguard Worker   "BOGUS",
449*8fb009dcSAndroid Build Coastguard Worker   // COMPLEMENTOFDEFAULT is empty.
450*8fb009dcSAndroid Build Coastguard Worker   "COMPLEMENTOFDEFAULT",
451*8fb009dcSAndroid Build Coastguard Worker   // Invalid command.
452*8fb009dcSAndroid Build Coastguard Worker   "?BAR",
453*8fb009dcSAndroid Build Coastguard Worker   // Special operators are not allowed if equi-preference groups are used.
454*8fb009dcSAndroid Build Coastguard Worker   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:+FOO",
455*8fb009dcSAndroid Build Coastguard Worker   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:!FOO",
456*8fb009dcSAndroid Build Coastguard Worker   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:-FOO",
457*8fb009dcSAndroid Build Coastguard Worker   "[ECDHE-RSA-CHACHA20-POLY1305|ECDHE-RSA-AES128-GCM-SHA256]:@STRENGTH",
458*8fb009dcSAndroid Build Coastguard Worker   // Opcode supplied, but missing selector.
459*8fb009dcSAndroid Build Coastguard Worker   "+",
460*8fb009dcSAndroid Build Coastguard Worker   // Spaces are forbidden in equal-preference groups.
461*8fb009dcSAndroid Build Coastguard Worker   "[AES128-SHA | AES128-SHA256]",
462*8fb009dcSAndroid Build Coastguard Worker };
463*8fb009dcSAndroid Build Coastguard Worker 
464*8fb009dcSAndroid Build Coastguard Worker static const char *kMustNotIncludeDeprecated[] = {
465*8fb009dcSAndroid Build Coastguard Worker   "ALL",
466*8fb009dcSAndroid Build Coastguard Worker   "DEFAULT",
467*8fb009dcSAndroid Build Coastguard Worker   "HIGH",
468*8fb009dcSAndroid Build Coastguard Worker   "FIPS",
469*8fb009dcSAndroid Build Coastguard Worker   "SHA",
470*8fb009dcSAndroid Build Coastguard Worker   "SHA1",
471*8fb009dcSAndroid Build Coastguard Worker   "RSA",
472*8fb009dcSAndroid Build Coastguard Worker   "SSLv3",
473*8fb009dcSAndroid Build Coastguard Worker   "TLSv1",
474*8fb009dcSAndroid Build Coastguard Worker   "TLSv1.2",
475*8fb009dcSAndroid Build Coastguard Worker };
476*8fb009dcSAndroid Build Coastguard Worker 
477*8fb009dcSAndroid Build Coastguard Worker static const char* kShouldIncludeCBCSHA256[] = {
478*8fb009dcSAndroid Build Coastguard Worker   "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
479*8fb009dcSAndroid Build Coastguard Worker   "ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256",
480*8fb009dcSAndroid Build Coastguard Worker };
481*8fb009dcSAndroid Build Coastguard Worker 
482*8fb009dcSAndroid Build Coastguard Worker static const CurveTest kCurveTests[] = {
483*8fb009dcSAndroid Build Coastguard Worker   {
484*8fb009dcSAndroid Build Coastguard Worker     "P-256",
485*8fb009dcSAndroid Build Coastguard Worker     { SSL_GROUP_SECP256R1 },
486*8fb009dcSAndroid Build Coastguard Worker   },
487*8fb009dcSAndroid Build Coastguard Worker   {
488*8fb009dcSAndroid Build Coastguard Worker     "P-256:X25519Kyber768Draft00",
489*8fb009dcSAndroid Build Coastguard Worker     { SSL_GROUP_SECP256R1, SSL_GROUP_X25519_KYBER768_DRAFT00 },
490*8fb009dcSAndroid Build Coastguard Worker   },
491*8fb009dcSAndroid Build Coastguard Worker 
492*8fb009dcSAndroid Build Coastguard Worker   {
493*8fb009dcSAndroid Build Coastguard Worker     "P-256:P-384:P-521:X25519",
494*8fb009dcSAndroid Build Coastguard Worker     {
495*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_SECP256R1,
496*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_SECP384R1,
497*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_SECP521R1,
498*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_X25519,
499*8fb009dcSAndroid Build Coastguard Worker     },
500*8fb009dcSAndroid Build Coastguard Worker   },
501*8fb009dcSAndroid Build Coastguard Worker   {
502*8fb009dcSAndroid Build Coastguard Worker     "prime256v1:secp384r1:secp521r1:x25519",
503*8fb009dcSAndroid Build Coastguard Worker     {
504*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_SECP256R1,
505*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_SECP384R1,
506*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_SECP521R1,
507*8fb009dcSAndroid Build Coastguard Worker       SSL_GROUP_X25519,
508*8fb009dcSAndroid Build Coastguard Worker     },
509*8fb009dcSAndroid Build Coastguard Worker   },
510*8fb009dcSAndroid Build Coastguard Worker };
511*8fb009dcSAndroid Build Coastguard Worker 
512*8fb009dcSAndroid Build Coastguard Worker static const char *kBadCurvesLists[] = {
513*8fb009dcSAndroid Build Coastguard Worker   "",
514*8fb009dcSAndroid Build Coastguard Worker   ":",
515*8fb009dcSAndroid Build Coastguard Worker   "::",
516*8fb009dcSAndroid Build Coastguard Worker   "P-256::X25519",
517*8fb009dcSAndroid Build Coastguard Worker   "RSA:P-256",
518*8fb009dcSAndroid Build Coastguard Worker   "P-256:RSA",
519*8fb009dcSAndroid Build Coastguard Worker   "X25519:P-256:",
520*8fb009dcSAndroid Build Coastguard Worker   ":X25519:P-256",
521*8fb009dcSAndroid Build Coastguard Worker };
522*8fb009dcSAndroid Build Coastguard Worker 
CipherListToString(SSL_CTX * ctx)523*8fb009dcSAndroid Build Coastguard Worker static std::string CipherListToString(SSL_CTX *ctx) {
524*8fb009dcSAndroid Build Coastguard Worker   bool in_group = false;
525*8fb009dcSAndroid Build Coastguard Worker   std::string ret;
526*8fb009dcSAndroid Build Coastguard Worker   const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
527*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
528*8fb009dcSAndroid Build Coastguard Worker     const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
529*8fb009dcSAndroid Build Coastguard Worker     if (!in_group && SSL_CTX_cipher_in_group(ctx, i)) {
530*8fb009dcSAndroid Build Coastguard Worker       ret += "\t[\n";
531*8fb009dcSAndroid Build Coastguard Worker       in_group = true;
532*8fb009dcSAndroid Build Coastguard Worker     }
533*8fb009dcSAndroid Build Coastguard Worker     ret += "\t";
534*8fb009dcSAndroid Build Coastguard Worker     if (in_group) {
535*8fb009dcSAndroid Build Coastguard Worker       ret += "  ";
536*8fb009dcSAndroid Build Coastguard Worker     }
537*8fb009dcSAndroid Build Coastguard Worker     ret += SSL_CIPHER_get_name(cipher);
538*8fb009dcSAndroid Build Coastguard Worker     ret += "\n";
539*8fb009dcSAndroid Build Coastguard Worker     if (in_group && !SSL_CTX_cipher_in_group(ctx, i)) {
540*8fb009dcSAndroid Build Coastguard Worker       ret += "\t]\n";
541*8fb009dcSAndroid Build Coastguard Worker       in_group = false;
542*8fb009dcSAndroid Build Coastguard Worker     }
543*8fb009dcSAndroid Build Coastguard Worker   }
544*8fb009dcSAndroid Build Coastguard Worker   return ret;
545*8fb009dcSAndroid Build Coastguard Worker }
546*8fb009dcSAndroid Build Coastguard Worker 
CipherListsEqual(SSL_CTX * ctx,const std::vector<ExpectedCipher> & expected)547*8fb009dcSAndroid Build Coastguard Worker static bool CipherListsEqual(SSL_CTX *ctx,
548*8fb009dcSAndroid Build Coastguard Worker                              const std::vector<ExpectedCipher> &expected) {
549*8fb009dcSAndroid Build Coastguard Worker   const STACK_OF(SSL_CIPHER) *ciphers = SSL_CTX_get_ciphers(ctx);
550*8fb009dcSAndroid Build Coastguard Worker   if (sk_SSL_CIPHER_num(ciphers) != expected.size()) {
551*8fb009dcSAndroid Build Coastguard Worker     return false;
552*8fb009dcSAndroid Build Coastguard Worker   }
553*8fb009dcSAndroid Build Coastguard Worker 
554*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < expected.size(); i++) {
555*8fb009dcSAndroid Build Coastguard Worker     const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(ciphers, i);
556*8fb009dcSAndroid Build Coastguard Worker     if (expected[i].id != SSL_CIPHER_get_id(cipher) ||
557*8fb009dcSAndroid Build Coastguard Worker         expected[i].in_group_flag != !!SSL_CTX_cipher_in_group(ctx, i)) {
558*8fb009dcSAndroid Build Coastguard Worker       return false;
559*8fb009dcSAndroid Build Coastguard Worker     }
560*8fb009dcSAndroid Build Coastguard Worker   }
561*8fb009dcSAndroid Build Coastguard Worker 
562*8fb009dcSAndroid Build Coastguard Worker   return true;
563*8fb009dcSAndroid Build Coastguard Worker }
564*8fb009dcSAndroid Build Coastguard Worker 
TEST(GrowableArrayTest,Resize)565*8fb009dcSAndroid Build Coastguard Worker TEST(GrowableArrayTest, Resize) {
566*8fb009dcSAndroid Build Coastguard Worker   GrowableArray<size_t> array;
567*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(array.empty());
568*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(array.size(), 0u);
569*8fb009dcSAndroid Build Coastguard Worker 
570*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(array.Push(42));
571*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(!array.empty());
572*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(array.size(), 1u);
573*8fb009dcSAndroid Build Coastguard Worker 
574*8fb009dcSAndroid Build Coastguard Worker   // Force a resize operation to occur
575*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < 16; i++) {
576*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(array.Push(i + 1));
577*8fb009dcSAndroid Build Coastguard Worker   }
578*8fb009dcSAndroid Build Coastguard Worker 
579*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(array.size(), 17u);
580*8fb009dcSAndroid Build Coastguard Worker 
581*8fb009dcSAndroid Build Coastguard Worker   // Verify that expected values are still contained in array
582*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < array.size(); i++) {
583*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(array[i], i == 0 ? 42 : i);
584*8fb009dcSAndroid Build Coastguard Worker   }
585*8fb009dcSAndroid Build Coastguard Worker }
586*8fb009dcSAndroid Build Coastguard Worker 
TEST(GrowableArrayTest,MoveConstructor)587*8fb009dcSAndroid Build Coastguard Worker TEST(GrowableArrayTest, MoveConstructor) {
588*8fb009dcSAndroid Build Coastguard Worker   GrowableArray<size_t> array;
589*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < 100; i++) {
590*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(array.Push(i));
591*8fb009dcSAndroid Build Coastguard Worker   }
592*8fb009dcSAndroid Build Coastguard Worker 
593*8fb009dcSAndroid Build Coastguard Worker   GrowableArray<size_t> array_moved(std::move(array));
594*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < 100; i++) {
595*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(array_moved[i], i);
596*8fb009dcSAndroid Build Coastguard Worker   }
597*8fb009dcSAndroid Build Coastguard Worker }
598*8fb009dcSAndroid Build Coastguard Worker 
TEST(GrowableArrayTest,GrowableArrayContainingGrowableArrays)599*8fb009dcSAndroid Build Coastguard Worker TEST(GrowableArrayTest, GrowableArrayContainingGrowableArrays) {
600*8fb009dcSAndroid Build Coastguard Worker   // Representative example of a struct that contains a GrowableArray.
601*8fb009dcSAndroid Build Coastguard Worker   struct TagAndArray {
602*8fb009dcSAndroid Build Coastguard Worker     size_t tag;
603*8fb009dcSAndroid Build Coastguard Worker     GrowableArray<size_t> array;
604*8fb009dcSAndroid Build Coastguard Worker   };
605*8fb009dcSAndroid Build Coastguard Worker 
606*8fb009dcSAndroid Build Coastguard Worker   GrowableArray<TagAndArray> array;
607*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < 100; i++) {
608*8fb009dcSAndroid Build Coastguard Worker     TagAndArray elem;
609*8fb009dcSAndroid Build Coastguard Worker     elem.tag = i;
610*8fb009dcSAndroid Build Coastguard Worker     for (size_t j = 0; j < i; j++) {
611*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(elem.array.Push(j));
612*8fb009dcSAndroid Build Coastguard Worker     }
613*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(array.Push(std::move(elem)));
614*8fb009dcSAndroid Build Coastguard Worker   }
615*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(array.size(), static_cast<size_t>(100));
616*8fb009dcSAndroid Build Coastguard Worker 
617*8fb009dcSAndroid Build Coastguard Worker   GrowableArray<TagAndArray> array_moved(std::move(array));
618*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(array_moved.size(), static_cast<size_t>(100));
619*8fb009dcSAndroid Build Coastguard Worker   size_t count = 0;
620*8fb009dcSAndroid Build Coastguard Worker   for (const TagAndArray &elem : array_moved) {
621*8fb009dcSAndroid Build Coastguard Worker     // Test the square bracket operator returns the same value as iteration.
622*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(&elem, &array_moved[count]);
623*8fb009dcSAndroid Build Coastguard Worker 
624*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(elem.tag, count);
625*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(elem.array.size(), count);
626*8fb009dcSAndroid Build Coastguard Worker     for (size_t j = 0; j < count; j++) {
627*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(elem.array[j], j);
628*8fb009dcSAndroid Build Coastguard Worker     }
629*8fb009dcSAndroid Build Coastguard Worker     count++;
630*8fb009dcSAndroid Build Coastguard Worker   }
631*8fb009dcSAndroid Build Coastguard Worker }
632*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CipherRules)633*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CipherRules) {
634*8fb009dcSAndroid Build Coastguard Worker   for (const CipherTest &t : kCipherTests) {
635*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(t.rule);
636*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
637*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ctx);
638*8fb009dcSAndroid Build Coastguard Worker 
639*8fb009dcSAndroid Build Coastguard Worker     // Test lax mode.
640*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set_cipher_list(ctx.get(), t.rule));
641*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
642*8fb009dcSAndroid Build Coastguard Worker         << "Cipher rule evaluated to:\n"
643*8fb009dcSAndroid Build Coastguard Worker         << CipherListToString(ctx.get());
644*8fb009dcSAndroid Build Coastguard Worker 
645*8fb009dcSAndroid Build Coastguard Worker     // Test strict mode.
646*8fb009dcSAndroid Build Coastguard Worker     if (t.strict_fail) {
647*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
648*8fb009dcSAndroid Build Coastguard Worker     } else {
649*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), t.rule));
650*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(CipherListsEqual(ctx.get(), t.expected))
651*8fb009dcSAndroid Build Coastguard Worker           << "Cipher rule evaluated to:\n"
652*8fb009dcSAndroid Build Coastguard Worker           << CipherListToString(ctx.get());
653*8fb009dcSAndroid Build Coastguard Worker     }
654*8fb009dcSAndroid Build Coastguard Worker   }
655*8fb009dcSAndroid Build Coastguard Worker 
656*8fb009dcSAndroid Build Coastguard Worker   for (const char *rule : kBadRules) {
657*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(rule);
658*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
659*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ctx);
660*8fb009dcSAndroid Build Coastguard Worker 
661*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), rule));
662*8fb009dcSAndroid Build Coastguard Worker     ERR_clear_error();
663*8fb009dcSAndroid Build Coastguard Worker   }
664*8fb009dcSAndroid Build Coastguard Worker 
665*8fb009dcSAndroid Build Coastguard Worker   for (const char *rule : kMustNotIncludeDeprecated) {
666*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(rule);
667*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
668*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ctx);
669*8fb009dcSAndroid Build Coastguard Worker 
670*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
671*8fb009dcSAndroid Build Coastguard Worker     for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
672*8fb009dcSAndroid Build Coastguard Worker       EXPECT_NE(NID_undef, SSL_CIPHER_get_cipher_nid(cipher));
673*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(ssl_cipher_is_deprecated(cipher));
674*8fb009dcSAndroid Build Coastguard Worker     }
675*8fb009dcSAndroid Build Coastguard Worker   }
676*8fb009dcSAndroid Build Coastguard Worker 
677*8fb009dcSAndroid Build Coastguard Worker   {
678*8fb009dcSAndroid Build Coastguard Worker     for (const char *rule : kShouldIncludeCBCSHA256) {
679*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
680*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ctx);
681*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), rule));
682*8fb009dcSAndroid Build Coastguard Worker 
683*8fb009dcSAndroid Build Coastguard Worker       bool found = false;
684*8fb009dcSAndroid Build Coastguard Worker       for (const SSL_CIPHER *cipher : SSL_CTX_get_ciphers(ctx.get())) {
685*8fb009dcSAndroid Build Coastguard Worker         if ((TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA256 & 0xffff) ==
686*8fb009dcSAndroid Build Coastguard Worker             SSL_CIPHER_get_protocol_id(cipher)) {
687*8fb009dcSAndroid Build Coastguard Worker           found = true;
688*8fb009dcSAndroid Build Coastguard Worker           break;
689*8fb009dcSAndroid Build Coastguard Worker         }
690*8fb009dcSAndroid Build Coastguard Worker       }
691*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(found);
692*8fb009dcSAndroid Build Coastguard Worker     }
693*8fb009dcSAndroid Build Coastguard Worker   }
694*8fb009dcSAndroid Build Coastguard Worker }
695*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CurveRules)696*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CurveRules) {
697*8fb009dcSAndroid Build Coastguard Worker   for (const CurveTest &t : kCurveTests) {
698*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(t.rule);
699*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
700*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ctx);
701*8fb009dcSAndroid Build Coastguard Worker 
702*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set1_groups_list(ctx.get(), t.rule));
703*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(t.expected.size(), ctx->supported_group_list.size());
704*8fb009dcSAndroid Build Coastguard Worker     for (size_t i = 0; i < t.expected.size(); i++) {
705*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(t.expected[i], ctx->supported_group_list[i]);
706*8fb009dcSAndroid Build Coastguard Worker     }
707*8fb009dcSAndroid Build Coastguard Worker   }
708*8fb009dcSAndroid Build Coastguard Worker 
709*8fb009dcSAndroid Build Coastguard Worker   for (const char *rule : kBadCurvesLists) {
710*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(rule);
711*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
712*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ctx);
713*8fb009dcSAndroid Build Coastguard Worker 
714*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_CTX_set1_groups_list(ctx.get(), rule));
715*8fb009dcSAndroid Build Coastguard Worker     ERR_clear_error();
716*8fb009dcSAndroid Build Coastguard Worker   }
717*8fb009dcSAndroid Build Coastguard Worker }
718*8fb009dcSAndroid Build Coastguard Worker 
719*8fb009dcSAndroid Build Coastguard Worker // kOpenSSLSession is a serialized SSL_SESSION.
720*8fb009dcSAndroid Build Coastguard Worker static const char kOpenSSLSession[] =
721*8fb009dcSAndroid Build Coastguard Worker     "MIIFqgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
722*8fb009dcSAndroid Build Coastguard Worker     "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
723*8fb009dcSAndroid Build Coastguard Worker     "IWoJoQYCBFRDO46iBAICASyjggR6MIIEdjCCA16gAwIBAgIIK9dUvsPWSlUwDQYJ"
724*8fb009dcSAndroid Build Coastguard Worker     "KoZIhvcNAQEFBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
725*8fb009dcSAndroid Build Coastguard Worker     "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTQxMDA4"
726*8fb009dcSAndroid Build Coastguard Worker     "MTIwNzU3WhcNMTUwMTA2MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
727*8fb009dcSAndroid Build Coastguard Worker     "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
728*8fb009dcSAndroid Build Coastguard Worker     "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
729*8fb009dcSAndroid Build Coastguard Worker     "AQUAA4IBDwAwggEKAoIBAQCcKeLrplAC+Lofy8t/wDwtB6eu72CVp0cJ4V3lknN6"
730*8fb009dcSAndroid Build Coastguard Worker     "huH9ct6FFk70oRIh/VBNBBz900jYy+7111Jm1b8iqOTQ9aT5C7SEhNcQFJvqzH3e"
731*8fb009dcSAndroid Build Coastguard Worker     "MPkb6ZSWGm1yGF7MCQTGQXF20Sk/O16FSjAynU/b3oJmOctcycWYkY0ytS/k3LBu"
732*8fb009dcSAndroid Build Coastguard Worker     "Id45PJaoMqjB0WypqvNeJHC3q5JjCB4RP7Nfx5jjHSrCMhw8lUMW4EaDxjaR9KDh"
733*8fb009dcSAndroid Build Coastguard Worker     "PLgjsk+LDIySRSRDaCQGhEOWLJZVLzLo4N6/UlctCHEllpBUSvEOyFga52qroGjg"
734*8fb009dcSAndroid Build Coastguard Worker     "rf3WOQ925MFwzd6AK+Ich0gDRg8sQfdLH5OuP1cfLfU1AgMBAAGjggFBMIIBPTAd"
735*8fb009dcSAndroid Build Coastguard Worker     "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
736*8fb009dcSAndroid Build Coastguard Worker     "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
737*8fb009dcSAndroid Build Coastguard Worker     "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
738*8fb009dcSAndroid Build Coastguard Worker     "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBQ7a+CcxsZByOpc+xpYFcIbnUMZ"
739*8fb009dcSAndroid Build Coastguard Worker     "hTAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
740*8fb009dcSAndroid Build Coastguard Worker     "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
741*8fb009dcSAndroid Build Coastguard Worker     "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCa"
742*8fb009dcSAndroid Build Coastguard Worker     "OXCBdoqUy5bxyq+Wrh1zsyyCFim1PH5VU2+yvDSWrgDY8ibRGJmfff3r4Lud5kal"
743*8fb009dcSAndroid Build Coastguard Worker     "dKs9k8YlKD3ITG7P0YT/Rk8hLgfEuLcq5cc0xqmE42xJ+Eo2uzq9rYorc5emMCxf"
744*8fb009dcSAndroid Build Coastguard Worker     "5L0TJOXZqHQpOEcuptZQ4OjdYMfSxk5UzueUhA3ogZKRcRkdB3WeWRp+nYRhx4St"
745*8fb009dcSAndroid Build Coastguard Worker     "o2rt2A0MKmY9165GHUqMK9YaaXHDXqBu7Sefr1uSoAP9gyIJKeihMivsGqJ1TD6Z"
746*8fb009dcSAndroid Build Coastguard Worker     "cc6LMe+dN2P8cZEQHtD1y296ul4Mivqk3jatUVL8/hCwgch9A8O4PGZq9WqBfEWm"
747*8fb009dcSAndroid Build Coastguard Worker     "IyHh1dPtbg1lOXdYCWtjpAIEAKUDAgEUqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36S"
748*8fb009dcSAndroid Build Coastguard Worker     "YTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9B"
749*8fb009dcSAndroid Build Coastguard Worker     "sNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yE"
750*8fb009dcSAndroid Build Coastguard Worker     "OTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdA"
751*8fb009dcSAndroid Build Coastguard Worker     "i4gv7Y5oliyntgMBAQA=";
752*8fb009dcSAndroid Build Coastguard Worker 
753*8fb009dcSAndroid Build Coastguard Worker // kCustomSession is a custom serialized SSL_SESSION generated by
754*8fb009dcSAndroid Build Coastguard Worker // filling in missing fields from |kOpenSSLSession|. This includes
755*8fb009dcSAndroid Build Coastguard Worker // providing |peer_sha256|, so |peer| is not serialized.
756*8fb009dcSAndroid Build Coastguard Worker static const char kCustomSession[] =
757*8fb009dcSAndroid Build Coastguard Worker     "MIIBZAIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
758*8fb009dcSAndroid Build Coastguard Worker     "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
759*8fb009dcSAndroid Build Coastguard Worker     "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUqAcEBXdvcmxkqQUCAwGJwKqBpwSB"
760*8fb009dcSAndroid Build Coastguard Worker     "pBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0NxeLwjcDTpsuh3qXEaZ992r1N38"
761*8fb009dcSAndroid Build Coastguard Worker     "VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751CLoXFPoaMOe57dbBpXoro6Pd"
762*8fb009dcSAndroid Build Coastguard Worker     "3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyPq+Topyzvx9USFgRvyuoxn0Hg"
763*8fb009dcSAndroid Build Coastguard Worker     "b+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG"
764*8fb009dcSAndroid Build Coastguard Worker     "BgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
765*8fb009dcSAndroid Build Coastguard Worker 
766*8fb009dcSAndroid Build Coastguard Worker // kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
767*8fb009dcSAndroid Build Coastguard Worker static const char kBoringSSLSession[] =
768*8fb009dcSAndroid Build Coastguard Worker     "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
769*8fb009dcSAndroid Build Coastguard Worker     "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
770*8fb009dcSAndroid Build Coastguard Worker     "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
771*8fb009dcSAndroid Build Coastguard Worker     "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
772*8fb009dcSAndroid Build Coastguard Worker     "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
773*8fb009dcSAndroid Build Coastguard Worker     "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
774*8fb009dcSAndroid Build Coastguard Worker     "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
775*8fb009dcSAndroid Build Coastguard Worker     "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
776*8fb009dcSAndroid Build Coastguard Worker     "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
777*8fb009dcSAndroid Build Coastguard Worker     "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
778*8fb009dcSAndroid Build Coastguard Worker     "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
779*8fb009dcSAndroid Build Coastguard Worker     "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
780*8fb009dcSAndroid Build Coastguard Worker     "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
781*8fb009dcSAndroid Build Coastguard Worker     "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
782*8fb009dcSAndroid Build Coastguard Worker     "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
783*8fb009dcSAndroid Build Coastguard Worker     "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
784*8fb009dcSAndroid Build Coastguard Worker     "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
785*8fb009dcSAndroid Build Coastguard Worker     "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
786*8fb009dcSAndroid Build Coastguard Worker     "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
787*8fb009dcSAndroid Build Coastguard Worker     "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
788*8fb009dcSAndroid Build Coastguard Worker     "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
789*8fb009dcSAndroid Build Coastguard Worker     "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
790*8fb009dcSAndroid Build Coastguard Worker     "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
791*8fb009dcSAndroid Build Coastguard Worker     "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
792*8fb009dcSAndroid Build Coastguard Worker     "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
793*8fb009dcSAndroid Build Coastguard Worker     "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
794*8fb009dcSAndroid Build Coastguard Worker     "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
795*8fb009dcSAndroid Build Coastguard Worker     "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
796*8fb009dcSAndroid Build Coastguard Worker     "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
797*8fb009dcSAndroid Build Coastguard Worker     "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
798*8fb009dcSAndroid Build Coastguard Worker     "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
799*8fb009dcSAndroid Build Coastguard Worker     "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
800*8fb009dcSAndroid Build Coastguard Worker     "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
801*8fb009dcSAndroid Build Coastguard Worker     "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
802*8fb009dcSAndroid Build Coastguard Worker     "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
803*8fb009dcSAndroid Build Coastguard Worker     "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
804*8fb009dcSAndroid Build Coastguard Worker     "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
805*8fb009dcSAndroid Build Coastguard Worker     "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
806*8fb009dcSAndroid Build Coastguard Worker     "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
807*8fb009dcSAndroid Build Coastguard Worker     "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
808*8fb009dcSAndroid Build Coastguard Worker     "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
809*8fb009dcSAndroid Build Coastguard Worker     "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
810*8fb009dcSAndroid Build Coastguard Worker     "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
811*8fb009dcSAndroid Build Coastguard Worker     "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
812*8fb009dcSAndroid Build Coastguard Worker     "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
813*8fb009dcSAndroid Build Coastguard Worker     "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
814*8fb009dcSAndroid Build Coastguard Worker     "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
815*8fb009dcSAndroid Build Coastguard Worker     "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
816*8fb009dcSAndroid Build Coastguard Worker     "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
817*8fb009dcSAndroid Build Coastguard Worker     "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
818*8fb009dcSAndroid Build Coastguard Worker     "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
819*8fb009dcSAndroid Build Coastguard Worker     "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
820*8fb009dcSAndroid Build Coastguard Worker     "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
821*8fb009dcSAndroid Build Coastguard Worker     "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
822*8fb009dcSAndroid Build Coastguard Worker     "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
823*8fb009dcSAndroid Build Coastguard Worker     "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
824*8fb009dcSAndroid Build Coastguard Worker     "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
825*8fb009dcSAndroid Build Coastguard Worker     "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
826*8fb009dcSAndroid Build Coastguard Worker     "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
827*8fb009dcSAndroid Build Coastguard Worker     "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
828*8fb009dcSAndroid Build Coastguard Worker     "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
829*8fb009dcSAndroid Build Coastguard Worker     "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
830*8fb009dcSAndroid Build Coastguard Worker     "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
831*8fb009dcSAndroid Build Coastguard Worker     "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
832*8fb009dcSAndroid Build Coastguard Worker     "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
833*8fb009dcSAndroid Build Coastguard Worker     "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
834*8fb009dcSAndroid Build Coastguard Worker     "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
835*8fb009dcSAndroid Build Coastguard Worker     "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
836*8fb009dcSAndroid Build Coastguard Worker     "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
837*8fb009dcSAndroid Build Coastguard Worker     "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
838*8fb009dcSAndroid Build Coastguard Worker     "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
839*8fb009dcSAndroid Build Coastguard Worker     "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
840*8fb009dcSAndroid Build Coastguard Worker     "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
841*8fb009dcSAndroid Build Coastguard Worker     "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
842*8fb009dcSAndroid Build Coastguard Worker     "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
843*8fb009dcSAndroid Build Coastguard Worker     "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
844*8fb009dcSAndroid Build Coastguard Worker     "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
845*8fb009dcSAndroid Build Coastguard Worker     "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
846*8fb009dcSAndroid Build Coastguard Worker     "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
847*8fb009dcSAndroid Build Coastguard Worker     "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
848*8fb009dcSAndroid Build Coastguard Worker     "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
849*8fb009dcSAndroid Build Coastguard Worker     "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
850*8fb009dcSAndroid Build Coastguard Worker     "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
851*8fb009dcSAndroid Build Coastguard Worker     "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
852*8fb009dcSAndroid Build Coastguard Worker     "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
853*8fb009dcSAndroid Build Coastguard Worker     "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
854*8fb009dcSAndroid Build Coastguard Worker     "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
855*8fb009dcSAndroid Build Coastguard Worker     "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
856*8fb009dcSAndroid Build Coastguard Worker     "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
857*8fb009dcSAndroid Build Coastguard Worker     "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
858*8fb009dcSAndroid Build Coastguard Worker     "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
859*8fb009dcSAndroid Build Coastguard Worker     "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
860*8fb009dcSAndroid Build Coastguard Worker     "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
861*8fb009dcSAndroid Build Coastguard Worker     "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
862*8fb009dcSAndroid Build Coastguard Worker     "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
863*8fb009dcSAndroid Build Coastguard Worker 
864*8fb009dcSAndroid Build Coastguard Worker // kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
865*8fb009dcSAndroid Build Coastguard Worker // the final (optional) element of |kCustomSession| with tag number 99.
866*8fb009dcSAndroid Build Coastguard Worker static const char kBadSessionExtraField[] =
867*8fb009dcSAndroid Build Coastguard Worker     "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
868*8fb009dcSAndroid Build Coastguard Worker     "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
869*8fb009dcSAndroid Build Coastguard Worker     "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
870*8fb009dcSAndroid Build Coastguard Worker     "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
871*8fb009dcSAndroid Build Coastguard Worker     "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
872*8fb009dcSAndroid Build Coastguard Worker     "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
873*8fb009dcSAndroid Build Coastguard Worker     "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
874*8fb009dcSAndroid Build Coastguard Worker     "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBOMDBAEF";
875*8fb009dcSAndroid Build Coastguard Worker 
876*8fb009dcSAndroid Build Coastguard Worker // kBadSessionVersion is a custom serialized SSL_SESSION generated by replacing
877*8fb009dcSAndroid Build Coastguard Worker // the version of |kCustomSession| with 2.
878*8fb009dcSAndroid Build Coastguard Worker static const char kBadSessionVersion[] =
879*8fb009dcSAndroid Build Coastguard Worker     "MIIBdgIBAgICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
880*8fb009dcSAndroid Build Coastguard Worker     "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
881*8fb009dcSAndroid Build Coastguard Worker     "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
882*8fb009dcSAndroid Build Coastguard Worker     "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
883*8fb009dcSAndroid Build Coastguard Worker     "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
884*8fb009dcSAndroid Build Coastguard Worker     "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
885*8fb009dcSAndroid Build Coastguard Worker     "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
886*8fb009dcSAndroid Build Coastguard Worker     "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
887*8fb009dcSAndroid Build Coastguard Worker 
888*8fb009dcSAndroid Build Coastguard Worker // kBadSessionTrailingData is a custom serialized SSL_SESSION with trailing data
889*8fb009dcSAndroid Build Coastguard Worker // appended.
890*8fb009dcSAndroid Build Coastguard Worker static const char kBadSessionTrailingData[] =
891*8fb009dcSAndroid Build Coastguard Worker     "MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
892*8fb009dcSAndroid Build Coastguard Worker     "kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
893*8fb009dcSAndroid Build Coastguard Worker     "IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
894*8fb009dcSAndroid Build Coastguard Worker     "BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
895*8fb009dcSAndroid Build Coastguard Worker     "LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
896*8fb009dcSAndroid Build Coastguard Worker     "CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
897*8fb009dcSAndroid Build Coastguard Worker     "q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
898*8fb009dcSAndroid Build Coastguard Worker     "BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEFAAAA";
899*8fb009dcSAndroid Build Coastguard Worker 
DecodeBase64(std::vector<uint8_t> * out,const char * in)900*8fb009dcSAndroid Build Coastguard Worker static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
901*8fb009dcSAndroid Build Coastguard Worker   size_t len;
902*8fb009dcSAndroid Build Coastguard Worker   if (!EVP_DecodedLength(&len, strlen(in))) {
903*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "EVP_DecodedLength failed\n");
904*8fb009dcSAndroid Build Coastguard Worker     return false;
905*8fb009dcSAndroid Build Coastguard Worker   }
906*8fb009dcSAndroid Build Coastguard Worker 
907*8fb009dcSAndroid Build Coastguard Worker   out->resize(len);
908*8fb009dcSAndroid Build Coastguard Worker   if (!EVP_DecodeBase64(out->data(), &len, len, (const uint8_t *)in,
909*8fb009dcSAndroid Build Coastguard Worker                         strlen(in))) {
910*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "EVP_DecodeBase64 failed\n");
911*8fb009dcSAndroid Build Coastguard Worker     return false;
912*8fb009dcSAndroid Build Coastguard Worker   }
913*8fb009dcSAndroid Build Coastguard Worker   out->resize(len);
914*8fb009dcSAndroid Build Coastguard Worker   return true;
915*8fb009dcSAndroid Build Coastguard Worker }
916*8fb009dcSAndroid Build Coastguard Worker 
DecodeLowerHex(std::vector<uint8_t> * out,bssl::Span<const char> in)917*8fb009dcSAndroid Build Coastguard Worker static bool DecodeLowerHex(std::vector<uint8_t> *out,
918*8fb009dcSAndroid Build Coastguard Worker                            bssl::Span<const char> in) {
919*8fb009dcSAndroid Build Coastguard Worker   if (in.size() % 2 != 0) {
920*8fb009dcSAndroid Build Coastguard Worker     return false;
921*8fb009dcSAndroid Build Coastguard Worker   }
922*8fb009dcSAndroid Build Coastguard Worker   out->resize(in.size() / 2);
923*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < out->size(); i++) {
924*8fb009dcSAndroid Build Coastguard Worker     char hi = in[2 * i], lo = in[2 * i + 1];
925*8fb009dcSAndroid Build Coastguard Worker     uint8_t b = 0;
926*8fb009dcSAndroid Build Coastguard Worker     if ('0' <= hi && hi <= '9') {
927*8fb009dcSAndroid Build Coastguard Worker       b |= hi - '0';
928*8fb009dcSAndroid Build Coastguard Worker     } else if ('a' <= hi && hi <= 'f') {
929*8fb009dcSAndroid Build Coastguard Worker       b |= hi - 'a' + 10;
930*8fb009dcSAndroid Build Coastguard Worker     } else {
931*8fb009dcSAndroid Build Coastguard Worker       return false;
932*8fb009dcSAndroid Build Coastguard Worker     }
933*8fb009dcSAndroid Build Coastguard Worker     b <<= 4;
934*8fb009dcSAndroid Build Coastguard Worker     if ('0' <= lo && lo <= '9') {
935*8fb009dcSAndroid Build Coastguard Worker       b |= lo - '0';
936*8fb009dcSAndroid Build Coastguard Worker     } else if ('a' <= lo && lo <= 'f') {
937*8fb009dcSAndroid Build Coastguard Worker       b |= lo - 'a' + 10;
938*8fb009dcSAndroid Build Coastguard Worker     } else {
939*8fb009dcSAndroid Build Coastguard Worker       return false;
940*8fb009dcSAndroid Build Coastguard Worker     }
941*8fb009dcSAndroid Build Coastguard Worker     (*out)[i] = b;
942*8fb009dcSAndroid Build Coastguard Worker   }
943*8fb009dcSAndroid Build Coastguard Worker   return true;
944*8fb009dcSAndroid Build Coastguard Worker }
945*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SessionEncoding)946*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SessionEncoding) {
947*8fb009dcSAndroid Build Coastguard Worker   for (const char *input_b64 : {
948*8fb009dcSAndroid Build Coastguard Worker            kOpenSSLSession,
949*8fb009dcSAndroid Build Coastguard Worker            kCustomSession,
950*8fb009dcSAndroid Build Coastguard Worker            kBoringSSLSession,
951*8fb009dcSAndroid Build Coastguard Worker        }) {
952*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(std::string(input_b64));
953*8fb009dcSAndroid Build Coastguard Worker     // Decode the input.
954*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> input;
955*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(DecodeBase64(&input, input_b64));
956*8fb009dcSAndroid Build Coastguard Worker 
957*8fb009dcSAndroid Build Coastguard Worker     // Verify the SSL_SESSION decodes.
958*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
959*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ssl_ctx);
960*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session(
961*8fb009dcSAndroid Build Coastguard Worker         SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
962*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session) << "SSL_SESSION_from_bytes failed";
963*8fb009dcSAndroid Build Coastguard Worker 
964*8fb009dcSAndroid Build Coastguard Worker     // Verify the SSL_SESSION encoding round-trips.
965*8fb009dcSAndroid Build Coastguard Worker     size_t encoded_len;
966*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<uint8_t> encoded;
967*8fb009dcSAndroid Build Coastguard Worker     uint8_t *encoded_raw;
968*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_SESSION_to_bytes(session.get(), &encoded_raw, &encoded_len))
969*8fb009dcSAndroid Build Coastguard Worker         << "SSL_SESSION_to_bytes failed";
970*8fb009dcSAndroid Build Coastguard Worker     encoded.reset(encoded_raw);
971*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
972*8fb009dcSAndroid Build Coastguard Worker         << "SSL_SESSION_to_bytes did not round-trip";
973*8fb009dcSAndroid Build Coastguard Worker 
974*8fb009dcSAndroid Build Coastguard Worker     // Verify the SSL_SESSION also decodes with the legacy API.
975*8fb009dcSAndroid Build Coastguard Worker     const uint8_t *cptr = input.data();
976*8fb009dcSAndroid Build Coastguard Worker     session.reset(d2i_SSL_SESSION(NULL, &cptr, input.size()));
977*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session) << "d2i_SSL_SESSION failed";
978*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(cptr, input.data() + input.size());
979*8fb009dcSAndroid Build Coastguard Worker 
980*8fb009dcSAndroid Build Coastguard Worker     // Verify the SSL_SESSION encoding round-trips via the legacy API.
981*8fb009dcSAndroid Build Coastguard Worker     int len = i2d_SSL_SESSION(session.get(), NULL);
982*8fb009dcSAndroid Build Coastguard Worker     ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
983*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(static_cast<size_t>(len), input.size())
984*8fb009dcSAndroid Build Coastguard Worker         << "i2d_SSL_SESSION(NULL) returned invalid length";
985*8fb009dcSAndroid Build Coastguard Worker 
986*8fb009dcSAndroid Build Coastguard Worker     encoded.reset((uint8_t *)OPENSSL_malloc(input.size()));
987*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(encoded);
988*8fb009dcSAndroid Build Coastguard Worker 
989*8fb009dcSAndroid Build Coastguard Worker     uint8_t *ptr = encoded.get();
990*8fb009dcSAndroid Build Coastguard Worker     len = i2d_SSL_SESSION(session.get(), &ptr);
991*8fb009dcSAndroid Build Coastguard Worker     ASSERT_GT(len, 0) << "i2d_SSL_SESSION failed";
992*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(static_cast<size_t>(len), input.size())
993*8fb009dcSAndroid Build Coastguard Worker         << "i2d_SSL_SESSION(NULL) returned invalid length";
994*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(ptr, encoded.get() + input.size())
995*8fb009dcSAndroid Build Coastguard Worker         << "i2d_SSL_SESSION did not advance ptr correctly";
996*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes(encoded.get(), encoded_len), Bytes(input))
997*8fb009dcSAndroid Build Coastguard Worker         << "SSL_SESSION_to_bytes did not round-trip";
998*8fb009dcSAndroid Build Coastguard Worker   }
999*8fb009dcSAndroid Build Coastguard Worker 
1000*8fb009dcSAndroid Build Coastguard Worker   for (const char *input_b64 : {
1001*8fb009dcSAndroid Build Coastguard Worker            kBadSessionExtraField,
1002*8fb009dcSAndroid Build Coastguard Worker            kBadSessionVersion,
1003*8fb009dcSAndroid Build Coastguard Worker            kBadSessionTrailingData,
1004*8fb009dcSAndroid Build Coastguard Worker        }) {
1005*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(std::string(input_b64));
1006*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> input;
1007*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(DecodeBase64(&input, input_b64));
1008*8fb009dcSAndroid Build Coastguard Worker 
1009*8fb009dcSAndroid Build Coastguard Worker     // Verify that the SSL_SESSION fails to decode.
1010*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1011*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ssl_ctx);
1012*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session(
1013*8fb009dcSAndroid Build Coastguard Worker         SSL_SESSION_from_bytes(input.data(), input.size(), ssl_ctx.get()));
1014*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(session) << "SSL_SESSION_from_bytes unexpectedly succeeded";
1015*8fb009dcSAndroid Build Coastguard Worker     ERR_clear_error();
1016*8fb009dcSAndroid Build Coastguard Worker   }
1017*8fb009dcSAndroid Build Coastguard Worker }
1018*8fb009dcSAndroid Build Coastguard Worker 
ExpectDefaultVersion(uint16_t min_version,uint16_t max_version,const SSL_METHOD * (* method)(void))1019*8fb009dcSAndroid Build Coastguard Worker static void ExpectDefaultVersion(uint16_t min_version, uint16_t max_version,
1020*8fb009dcSAndroid Build Coastguard Worker                                  const SSL_METHOD *(*method)(void)) {
1021*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method()));
1022*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
1023*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(min_version, SSL_CTX_get_min_proto_version(ctx.get()));
1024*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(max_version, SSL_CTX_get_max_proto_version(ctx.get()));
1025*8fb009dcSAndroid Build Coastguard Worker }
1026*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,DefaultVersion)1027*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, DefaultVersion) {
1028*8fb009dcSAndroid Build Coastguard Worker   ExpectDefaultVersion(TLS1_2_VERSION, TLS1_3_VERSION, &TLS_method);
1029*8fb009dcSAndroid Build Coastguard Worker   ExpectDefaultVersion(TLS1_VERSION, TLS1_VERSION, &TLSv1_method);
1030*8fb009dcSAndroid Build Coastguard Worker   ExpectDefaultVersion(TLS1_1_VERSION, TLS1_1_VERSION, &TLSv1_1_method);
1031*8fb009dcSAndroid Build Coastguard Worker   ExpectDefaultVersion(TLS1_2_VERSION, TLS1_2_VERSION, &TLSv1_2_method);
1032*8fb009dcSAndroid Build Coastguard Worker   ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLS_method);
1033*8fb009dcSAndroid Build Coastguard Worker   ExpectDefaultVersion(DTLS1_VERSION, DTLS1_VERSION, &DTLSv1_method);
1034*8fb009dcSAndroid Build Coastguard Worker   ExpectDefaultVersion(DTLS1_2_VERSION, DTLS1_2_VERSION, &DTLSv1_2_method);
1035*8fb009dcSAndroid Build Coastguard Worker }
1036*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CipherProperties)1037*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CipherProperties) {
1038*8fb009dcSAndroid Build Coastguard Worker   static const struct {
1039*8fb009dcSAndroid Build Coastguard Worker     int id;
1040*8fb009dcSAndroid Build Coastguard Worker     const char *standard_name;
1041*8fb009dcSAndroid Build Coastguard Worker     int cipher_nid;
1042*8fb009dcSAndroid Build Coastguard Worker     int digest_nid;
1043*8fb009dcSAndroid Build Coastguard Worker     int kx_nid;
1044*8fb009dcSAndroid Build Coastguard Worker     int auth_nid;
1045*8fb009dcSAndroid Build Coastguard Worker     int prf_nid;
1046*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
1047*8fb009dcSAndroid Build Coastguard Worker       {
1048*8fb009dcSAndroid Build Coastguard Worker           SSL3_CK_RSA_DES_192_CBC3_SHA,
1049*8fb009dcSAndroid Build Coastguard Worker           "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
1050*8fb009dcSAndroid Build Coastguard Worker           NID_des_ede3_cbc,
1051*8fb009dcSAndroid Build Coastguard Worker           NID_sha1,
1052*8fb009dcSAndroid Build Coastguard Worker           NID_kx_rsa,
1053*8fb009dcSAndroid Build Coastguard Worker           NID_auth_rsa,
1054*8fb009dcSAndroid Build Coastguard Worker           NID_md5_sha1,
1055*8fb009dcSAndroid Build Coastguard Worker       },
1056*8fb009dcSAndroid Build Coastguard Worker       {
1057*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_RSA_WITH_AES_128_SHA,
1058*8fb009dcSAndroid Build Coastguard Worker           "TLS_RSA_WITH_AES_128_CBC_SHA",
1059*8fb009dcSAndroid Build Coastguard Worker           NID_aes_128_cbc,
1060*8fb009dcSAndroid Build Coastguard Worker           NID_sha1,
1061*8fb009dcSAndroid Build Coastguard Worker           NID_kx_rsa,
1062*8fb009dcSAndroid Build Coastguard Worker           NID_auth_rsa,
1063*8fb009dcSAndroid Build Coastguard Worker           NID_md5_sha1,
1064*8fb009dcSAndroid Build Coastguard Worker       },
1065*8fb009dcSAndroid Build Coastguard Worker       {
1066*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
1067*8fb009dcSAndroid Build Coastguard Worker           "TLS_PSK_WITH_AES_256_CBC_SHA",
1068*8fb009dcSAndroid Build Coastguard Worker           NID_aes_256_cbc,
1069*8fb009dcSAndroid Build Coastguard Worker           NID_sha1,
1070*8fb009dcSAndroid Build Coastguard Worker           NID_kx_psk,
1071*8fb009dcSAndroid Build Coastguard Worker           NID_auth_psk,
1072*8fb009dcSAndroid Build Coastguard Worker           NID_md5_sha1,
1073*8fb009dcSAndroid Build Coastguard Worker       },
1074*8fb009dcSAndroid Build Coastguard Worker       {
1075*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
1076*8fb009dcSAndroid Build Coastguard Worker           "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
1077*8fb009dcSAndroid Build Coastguard Worker           NID_aes_128_cbc,
1078*8fb009dcSAndroid Build Coastguard Worker           NID_sha1,
1079*8fb009dcSAndroid Build Coastguard Worker           NID_kx_ecdhe,
1080*8fb009dcSAndroid Build Coastguard Worker           NID_auth_rsa,
1081*8fb009dcSAndroid Build Coastguard Worker           NID_md5_sha1,
1082*8fb009dcSAndroid Build Coastguard Worker       },
1083*8fb009dcSAndroid Build Coastguard Worker       {
1084*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
1085*8fb009dcSAndroid Build Coastguard Worker           "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA",
1086*8fb009dcSAndroid Build Coastguard Worker           NID_aes_256_cbc,
1087*8fb009dcSAndroid Build Coastguard Worker           NID_sha1,
1088*8fb009dcSAndroid Build Coastguard Worker           NID_kx_ecdhe,
1089*8fb009dcSAndroid Build Coastguard Worker           NID_auth_rsa,
1090*8fb009dcSAndroid Build Coastguard Worker           NID_md5_sha1,
1091*8fb009dcSAndroid Build Coastguard Worker       },
1092*8fb009dcSAndroid Build Coastguard Worker       {
1093*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
1094*8fb009dcSAndroid Build Coastguard Worker           "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
1095*8fb009dcSAndroid Build Coastguard Worker           NID_aes_128_gcm,
1096*8fb009dcSAndroid Build Coastguard Worker           NID_undef,
1097*8fb009dcSAndroid Build Coastguard Worker           NID_kx_ecdhe,
1098*8fb009dcSAndroid Build Coastguard Worker           NID_auth_rsa,
1099*8fb009dcSAndroid Build Coastguard Worker           NID_sha256,
1100*8fb009dcSAndroid Build Coastguard Worker       },
1101*8fb009dcSAndroid Build Coastguard Worker       {
1102*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
1103*8fb009dcSAndroid Build Coastguard Worker           "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
1104*8fb009dcSAndroid Build Coastguard Worker           NID_aes_128_gcm,
1105*8fb009dcSAndroid Build Coastguard Worker           NID_undef,
1106*8fb009dcSAndroid Build Coastguard Worker           NID_kx_ecdhe,
1107*8fb009dcSAndroid Build Coastguard Worker           NID_auth_ecdsa,
1108*8fb009dcSAndroid Build Coastguard Worker           NID_sha256,
1109*8fb009dcSAndroid Build Coastguard Worker       },
1110*8fb009dcSAndroid Build Coastguard Worker       {
1111*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
1112*8fb009dcSAndroid Build Coastguard Worker           "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
1113*8fb009dcSAndroid Build Coastguard Worker           NID_aes_256_gcm,
1114*8fb009dcSAndroid Build Coastguard Worker           NID_undef,
1115*8fb009dcSAndroid Build Coastguard Worker           NID_kx_ecdhe,
1116*8fb009dcSAndroid Build Coastguard Worker           NID_auth_ecdsa,
1117*8fb009dcSAndroid Build Coastguard Worker           NID_sha384,
1118*8fb009dcSAndroid Build Coastguard Worker       },
1119*8fb009dcSAndroid Build Coastguard Worker       {
1120*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA,
1121*8fb009dcSAndroid Build Coastguard Worker           "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA",
1122*8fb009dcSAndroid Build Coastguard Worker           NID_aes_128_cbc,
1123*8fb009dcSAndroid Build Coastguard Worker           NID_sha1,
1124*8fb009dcSAndroid Build Coastguard Worker           NID_kx_ecdhe,
1125*8fb009dcSAndroid Build Coastguard Worker           NID_auth_psk,
1126*8fb009dcSAndroid Build Coastguard Worker           NID_md5_sha1,
1127*8fb009dcSAndroid Build Coastguard Worker       },
1128*8fb009dcSAndroid Build Coastguard Worker       {
1129*8fb009dcSAndroid Build Coastguard Worker           TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256,
1130*8fb009dcSAndroid Build Coastguard Worker           "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
1131*8fb009dcSAndroid Build Coastguard Worker           NID_chacha20_poly1305,
1132*8fb009dcSAndroid Build Coastguard Worker           NID_undef,
1133*8fb009dcSAndroid Build Coastguard Worker           NID_kx_ecdhe,
1134*8fb009dcSAndroid Build Coastguard Worker           NID_auth_rsa,
1135*8fb009dcSAndroid Build Coastguard Worker           NID_sha256,
1136*8fb009dcSAndroid Build Coastguard Worker       },
1137*8fb009dcSAndroid Build Coastguard Worker       {
1138*8fb009dcSAndroid Build Coastguard Worker           TLS1_3_CK_AES_256_GCM_SHA384,
1139*8fb009dcSAndroid Build Coastguard Worker           "TLS_AES_256_GCM_SHA384",
1140*8fb009dcSAndroid Build Coastguard Worker           NID_aes_256_gcm,
1141*8fb009dcSAndroid Build Coastguard Worker           NID_undef,
1142*8fb009dcSAndroid Build Coastguard Worker           NID_kx_any,
1143*8fb009dcSAndroid Build Coastguard Worker           NID_auth_any,
1144*8fb009dcSAndroid Build Coastguard Worker           NID_sha384,
1145*8fb009dcSAndroid Build Coastguard Worker       },
1146*8fb009dcSAndroid Build Coastguard Worker       {
1147*8fb009dcSAndroid Build Coastguard Worker           TLS1_3_CK_AES_128_GCM_SHA256,
1148*8fb009dcSAndroid Build Coastguard Worker           "TLS_AES_128_GCM_SHA256",
1149*8fb009dcSAndroid Build Coastguard Worker           NID_aes_128_gcm,
1150*8fb009dcSAndroid Build Coastguard Worker           NID_undef,
1151*8fb009dcSAndroid Build Coastguard Worker           NID_kx_any,
1152*8fb009dcSAndroid Build Coastguard Worker           NID_auth_any,
1153*8fb009dcSAndroid Build Coastguard Worker           NID_sha256,
1154*8fb009dcSAndroid Build Coastguard Worker       },
1155*8fb009dcSAndroid Build Coastguard Worker       {
1156*8fb009dcSAndroid Build Coastguard Worker           TLS1_3_CK_CHACHA20_POLY1305_SHA256,
1157*8fb009dcSAndroid Build Coastguard Worker           "TLS_CHACHA20_POLY1305_SHA256",
1158*8fb009dcSAndroid Build Coastguard Worker           NID_chacha20_poly1305,
1159*8fb009dcSAndroid Build Coastguard Worker           NID_undef,
1160*8fb009dcSAndroid Build Coastguard Worker           NID_kx_any,
1161*8fb009dcSAndroid Build Coastguard Worker           NID_auth_any,
1162*8fb009dcSAndroid Build Coastguard Worker           NID_sha256,
1163*8fb009dcSAndroid Build Coastguard Worker       },
1164*8fb009dcSAndroid Build Coastguard Worker   };
1165*8fb009dcSAndroid Build Coastguard Worker 
1166*8fb009dcSAndroid Build Coastguard Worker   for (const auto &t : kTests) {
1167*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(t.standard_name);
1168*8fb009dcSAndroid Build Coastguard Worker 
1169*8fb009dcSAndroid Build Coastguard Worker     const SSL_CIPHER *cipher = SSL_get_cipher_by_value(t.id & 0xffff);
1170*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(cipher);
1171*8fb009dcSAndroid Build Coastguard Worker     EXPECT_STREQ(t.standard_name, SSL_CIPHER_standard_name(cipher));
1172*8fb009dcSAndroid Build Coastguard Worker 
1173*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(t.cipher_nid, SSL_CIPHER_get_cipher_nid(cipher));
1174*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(t.digest_nid, SSL_CIPHER_get_digest_nid(cipher));
1175*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(t.kx_nid, SSL_CIPHER_get_kx_nid(cipher));
1176*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(t.auth_nid, SSL_CIPHER_get_auth_nid(cipher));
1177*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(t.prf_nid, EVP_MD_nid(SSL_CIPHER_get_handshake_digest(cipher)));
1178*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(t.prf_nid, SSL_CIPHER_get_prf_nid(cipher));
1179*8fb009dcSAndroid Build Coastguard Worker   }
1180*8fb009dcSAndroid Build Coastguard Worker }
1181*8fb009dcSAndroid Build Coastguard Worker 
1182*8fb009dcSAndroid Build Coastguard Worker // CreateSessionWithTicket returns a sample |SSL_SESSION| with the specified
1183*8fb009dcSAndroid Build Coastguard Worker // version and ticket length or nullptr on failure.
CreateSessionWithTicket(uint16_t version,size_t ticket_len)1184*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<SSL_SESSION> CreateSessionWithTicket(uint16_t version,
1185*8fb009dcSAndroid Build Coastguard Worker                                                             size_t ticket_len) {
1186*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> der;
1187*8fb009dcSAndroid Build Coastguard Worker   if (!DecodeBase64(&der, kOpenSSLSession)) {
1188*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1189*8fb009dcSAndroid Build Coastguard Worker   }
1190*8fb009dcSAndroid Build Coastguard Worker 
1191*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
1192*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_ctx) {
1193*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1194*8fb009dcSAndroid Build Coastguard Worker   }
1195*8fb009dcSAndroid Build Coastguard Worker   // Use a garbage ticket.
1196*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> ticket(ticket_len, 'a');
1197*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session(
1198*8fb009dcSAndroid Build Coastguard Worker       SSL_SESSION_from_bytes(der.data(), der.size(), ssl_ctx.get()));
1199*8fb009dcSAndroid Build Coastguard Worker   if (!session ||
1200*8fb009dcSAndroid Build Coastguard Worker       !SSL_SESSION_set_protocol_version(session.get(), version) ||
1201*8fb009dcSAndroid Build Coastguard Worker       !SSL_SESSION_set_ticket(session.get(), ticket.data(), ticket.size())) {
1202*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1203*8fb009dcSAndroid Build Coastguard Worker   }
1204*8fb009dcSAndroid Build Coastguard Worker   // Fix up the timeout.
1205*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE)
1206*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION_set_time(session.get(), 1234);
1207*8fb009dcSAndroid Build Coastguard Worker #else
1208*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION_set_time(session.get(), time(nullptr));
1209*8fb009dcSAndroid Build Coastguard Worker #endif
1210*8fb009dcSAndroid Build Coastguard Worker   return session;
1211*8fb009dcSAndroid Build Coastguard Worker }
1212*8fb009dcSAndroid Build Coastguard Worker 
GetClientHello(SSL * ssl,std::vector<uint8_t> * out)1213*8fb009dcSAndroid Build Coastguard Worker static bool GetClientHello(SSL *ssl, std::vector<uint8_t> *out) {
1214*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
1215*8fb009dcSAndroid Build Coastguard Worker   if (!bio) {
1216*8fb009dcSAndroid Build Coastguard Worker     return false;
1217*8fb009dcSAndroid Build Coastguard Worker   }
1218*8fb009dcSAndroid Build Coastguard Worker   // Do not configure a reading BIO, but record what's written to a memory BIO.
1219*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio.get());
1220*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl, nullptr /* rbio */, bio.get());
1221*8fb009dcSAndroid Build Coastguard Worker   int ret = SSL_connect(ssl);
1222*8fb009dcSAndroid Build Coastguard Worker   if (ret > 0) {
1223*8fb009dcSAndroid Build Coastguard Worker     // SSL_connect should fail without a BIO to write to.
1224*8fb009dcSAndroid Build Coastguard Worker     return false;
1225*8fb009dcSAndroid Build Coastguard Worker   }
1226*8fb009dcSAndroid Build Coastguard Worker   ERR_clear_error();
1227*8fb009dcSAndroid Build Coastguard Worker 
1228*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *client_hello;
1229*8fb009dcSAndroid Build Coastguard Worker   size_t client_hello_len;
1230*8fb009dcSAndroid Build Coastguard Worker   if (!BIO_mem_contents(bio.get(), &client_hello, &client_hello_len)) {
1231*8fb009dcSAndroid Build Coastguard Worker     return false;
1232*8fb009dcSAndroid Build Coastguard Worker   }
1233*8fb009dcSAndroid Build Coastguard Worker 
1234*8fb009dcSAndroid Build Coastguard Worker   // We did not get far enough to write a ClientHello.
1235*8fb009dcSAndroid Build Coastguard Worker   if (client_hello_len == 0) {
1236*8fb009dcSAndroid Build Coastguard Worker     return false;
1237*8fb009dcSAndroid Build Coastguard Worker   }
1238*8fb009dcSAndroid Build Coastguard Worker 
1239*8fb009dcSAndroid Build Coastguard Worker   *out = std::vector<uint8_t>(client_hello, client_hello + client_hello_len);
1240*8fb009dcSAndroid Build Coastguard Worker   return true;
1241*8fb009dcSAndroid Build Coastguard Worker }
1242*8fb009dcSAndroid Build Coastguard Worker 
1243*8fb009dcSAndroid Build Coastguard Worker // GetClientHelloLen creates a client SSL connection with the specified version
1244*8fb009dcSAndroid Build Coastguard Worker // and ticket length. It returns the length of the ClientHello, not including
1245*8fb009dcSAndroid Build Coastguard Worker // the record header, on success and zero on error.
GetClientHelloLen(uint16_t max_version,uint16_t session_version,size_t ticket_len)1246*8fb009dcSAndroid Build Coastguard Worker static size_t GetClientHelloLen(uint16_t max_version, uint16_t session_version,
1247*8fb009dcSAndroid Build Coastguard Worker                                 size_t ticket_len) {
1248*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1249*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
1250*8fb009dcSAndroid Build Coastguard Worker       CreateSessionWithTicket(session_version, ticket_len);
1251*8fb009dcSAndroid Build Coastguard Worker   if (!ctx || !session) {
1252*8fb009dcSAndroid Build Coastguard Worker     return 0;
1253*8fb009dcSAndroid Build Coastguard Worker   }
1254*8fb009dcSAndroid Build Coastguard Worker 
1255*8fb009dcSAndroid Build Coastguard Worker   // Set a one-element cipher list so the baseline ClientHello is unpadded.
1256*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1257*8fb009dcSAndroid Build Coastguard Worker   if (!ssl || !SSL_set_session(ssl.get(), session.get()) ||
1258*8fb009dcSAndroid Build Coastguard Worker       !SSL_set_strict_cipher_list(ssl.get(), "ECDHE-RSA-AES128-GCM-SHA256") ||
1259*8fb009dcSAndroid Build Coastguard Worker       !SSL_set_max_proto_version(ssl.get(), max_version)) {
1260*8fb009dcSAndroid Build Coastguard Worker     return 0;
1261*8fb009dcSAndroid Build Coastguard Worker   }
1262*8fb009dcSAndroid Build Coastguard Worker 
1263*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> client_hello;
1264*8fb009dcSAndroid Build Coastguard Worker   if (!GetClientHello(ssl.get(), &client_hello) ||
1265*8fb009dcSAndroid Build Coastguard Worker       client_hello.size() <= SSL3_RT_HEADER_LENGTH) {
1266*8fb009dcSAndroid Build Coastguard Worker     return 0;
1267*8fb009dcSAndroid Build Coastguard Worker   }
1268*8fb009dcSAndroid Build Coastguard Worker 
1269*8fb009dcSAndroid Build Coastguard Worker   return client_hello.size() - SSL3_RT_HEADER_LENGTH;
1270*8fb009dcSAndroid Build Coastguard Worker }
1271*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,Padding)1272*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, Padding) {
1273*8fb009dcSAndroid Build Coastguard Worker   struct PaddingVersions {
1274*8fb009dcSAndroid Build Coastguard Worker     uint16_t max_version, session_version;
1275*8fb009dcSAndroid Build Coastguard Worker   };
1276*8fb009dcSAndroid Build Coastguard Worker   static const PaddingVersions kPaddingVersions[] = {
1277*8fb009dcSAndroid Build Coastguard Worker       // Test the padding extension at TLS 1.2.
1278*8fb009dcSAndroid Build Coastguard Worker       {TLS1_2_VERSION, TLS1_2_VERSION},
1279*8fb009dcSAndroid Build Coastguard Worker       // Test the padding extension at TLS 1.3 with a TLS 1.2 session, so there
1280*8fb009dcSAndroid Build Coastguard Worker       // will be no PSK binder after the padding extension.
1281*8fb009dcSAndroid Build Coastguard Worker       {TLS1_3_VERSION, TLS1_2_VERSION},
1282*8fb009dcSAndroid Build Coastguard Worker       // Test the padding extension at TLS 1.3 with a TLS 1.3 session, so there
1283*8fb009dcSAndroid Build Coastguard Worker       // will be a PSK binder after the padding extension.
1284*8fb009dcSAndroid Build Coastguard Worker       {TLS1_3_VERSION, TLS1_3_VERSION},
1285*8fb009dcSAndroid Build Coastguard Worker 
1286*8fb009dcSAndroid Build Coastguard Worker   };
1287*8fb009dcSAndroid Build Coastguard Worker 
1288*8fb009dcSAndroid Build Coastguard Worker   struct PaddingTest {
1289*8fb009dcSAndroid Build Coastguard Worker     size_t input_len, padded_len;
1290*8fb009dcSAndroid Build Coastguard Worker   };
1291*8fb009dcSAndroid Build Coastguard Worker   static const PaddingTest kPaddingTests[] = {
1292*8fb009dcSAndroid Build Coastguard Worker       // ClientHellos of length below 0x100 do not require padding.
1293*8fb009dcSAndroid Build Coastguard Worker       {0xfe, 0xfe},
1294*8fb009dcSAndroid Build Coastguard Worker       {0xff, 0xff},
1295*8fb009dcSAndroid Build Coastguard Worker       // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
1296*8fb009dcSAndroid Build Coastguard Worker       {0x100, 0x200},
1297*8fb009dcSAndroid Build Coastguard Worker       {0x123, 0x200},
1298*8fb009dcSAndroid Build Coastguard Worker       {0x1fb, 0x200},
1299*8fb009dcSAndroid Build Coastguard Worker       // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
1300*8fb009dcSAndroid Build Coastguard Worker       // padding extension takes a minimum of four bytes plus one required
1301*8fb009dcSAndroid Build Coastguard Worker       // content
1302*8fb009dcSAndroid Build Coastguard Worker       // byte. (To work around yet more server bugs, we avoid empty final
1303*8fb009dcSAndroid Build Coastguard Worker       // extensions.)
1304*8fb009dcSAndroid Build Coastguard Worker       {0x1fc, 0x201},
1305*8fb009dcSAndroid Build Coastguard Worker       {0x1fd, 0x202},
1306*8fb009dcSAndroid Build Coastguard Worker       {0x1fe, 0x203},
1307*8fb009dcSAndroid Build Coastguard Worker       {0x1ff, 0x204},
1308*8fb009dcSAndroid Build Coastguard Worker       // Finally, larger ClientHellos need no padding.
1309*8fb009dcSAndroid Build Coastguard Worker       {0x200, 0x200},
1310*8fb009dcSAndroid Build Coastguard Worker       {0x201, 0x201},
1311*8fb009dcSAndroid Build Coastguard Worker   };
1312*8fb009dcSAndroid Build Coastguard Worker 
1313*8fb009dcSAndroid Build Coastguard Worker   for (const PaddingVersions &versions : kPaddingVersions) {
1314*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(versions.max_version);
1315*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(versions.session_version);
1316*8fb009dcSAndroid Build Coastguard Worker 
1317*8fb009dcSAndroid Build Coastguard Worker     // Sample a baseline length.
1318*8fb009dcSAndroid Build Coastguard Worker     size_t base_len =
1319*8fb009dcSAndroid Build Coastguard Worker         GetClientHelloLen(versions.max_version, versions.session_version, 1);
1320*8fb009dcSAndroid Build Coastguard Worker     ASSERT_NE(base_len, 0u) << "Baseline length could not be sampled";
1321*8fb009dcSAndroid Build Coastguard Worker 
1322*8fb009dcSAndroid Build Coastguard Worker     for (const PaddingTest &test : kPaddingTests) {
1323*8fb009dcSAndroid Build Coastguard Worker       SCOPED_TRACE(test.input_len);
1324*8fb009dcSAndroid Build Coastguard Worker       ASSERT_LE(base_len, test.input_len) << "Baseline ClientHello too long";
1325*8fb009dcSAndroid Build Coastguard Worker 
1326*8fb009dcSAndroid Build Coastguard Worker       size_t padded_len =
1327*8fb009dcSAndroid Build Coastguard Worker           GetClientHelloLen(versions.max_version, versions.session_version,
1328*8fb009dcSAndroid Build Coastguard Worker                             1 + test.input_len - base_len);
1329*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(padded_len, test.padded_len)
1330*8fb009dcSAndroid Build Coastguard Worker           << "ClientHello was not padded to expected length";
1331*8fb009dcSAndroid Build Coastguard Worker     }
1332*8fb009dcSAndroid Build Coastguard Worker   }
1333*8fb009dcSAndroid Build Coastguard Worker }
1334*8fb009dcSAndroid Build Coastguard Worker 
CertFromPEM(const char * pem)1335*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<X509> CertFromPEM(const char *pem) {
1336*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1337*8fb009dcSAndroid Build Coastguard Worker   if (!bio) {
1338*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1339*8fb009dcSAndroid Build Coastguard Worker   }
1340*8fb009dcSAndroid Build Coastguard Worker   return bssl::UniquePtr<X509>(
1341*8fb009dcSAndroid Build Coastguard Worker       PEM_read_bio_X509(bio.get(), nullptr, nullptr, nullptr));
1342*8fb009dcSAndroid Build Coastguard Worker }
1343*8fb009dcSAndroid Build Coastguard Worker 
KeyFromPEM(const char * pem)1344*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<EVP_PKEY> KeyFromPEM(const char *pem) {
1345*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1346*8fb009dcSAndroid Build Coastguard Worker   if (!bio) {
1347*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1348*8fb009dcSAndroid Build Coastguard Worker   }
1349*8fb009dcSAndroid Build Coastguard Worker   return bssl::UniquePtr<EVP_PKEY>(
1350*8fb009dcSAndroid Build Coastguard Worker       PEM_read_bio_PrivateKey(bio.get(), nullptr, nullptr, nullptr));
1351*8fb009dcSAndroid Build Coastguard Worker }
1352*8fb009dcSAndroid Build Coastguard Worker 
BufferFromPEM(const char * pem)1353*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<CRYPTO_BUFFER> BufferFromPEM(const char *pem) {
1354*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
1355*8fb009dcSAndroid Build Coastguard Worker   char *name, *header;
1356*8fb009dcSAndroid Build Coastguard Worker   uint8_t *data;
1357*8fb009dcSAndroid Build Coastguard Worker   long data_len;
1358*8fb009dcSAndroid Build Coastguard Worker   if (!PEM_read_bio(bio.get(), &name, &header, &data,
1359*8fb009dcSAndroid Build Coastguard Worker                     &data_len)) {
1360*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1361*8fb009dcSAndroid Build Coastguard Worker   }
1362*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(name);
1363*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(header);
1364*8fb009dcSAndroid Build Coastguard Worker 
1365*8fb009dcSAndroid Build Coastguard Worker   auto ret = bssl::UniquePtr<CRYPTO_BUFFER>(
1366*8fb009dcSAndroid Build Coastguard Worker       CRYPTO_BUFFER_new(data, data_len, nullptr));
1367*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_free(data);
1368*8fb009dcSAndroid Build Coastguard Worker   return ret;
1369*8fb009dcSAndroid Build Coastguard Worker }
1370*8fb009dcSAndroid Build Coastguard Worker 
X509FromBuffer(bssl::UniquePtr<CRYPTO_BUFFER> buffer)1371*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<X509> X509FromBuffer(
1372*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<CRYPTO_BUFFER> buffer) {
1373*8fb009dcSAndroid Build Coastguard Worker   if (!buffer) {
1374*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1375*8fb009dcSAndroid Build Coastguard Worker   }
1376*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *derp = CRYPTO_BUFFER_data(buffer.get());
1377*8fb009dcSAndroid Build Coastguard Worker   return bssl::UniquePtr<X509>(
1378*8fb009dcSAndroid Build Coastguard Worker       d2i_X509(NULL, &derp, CRYPTO_BUFFER_len(buffer.get())));
1379*8fb009dcSAndroid Build Coastguard Worker }
1380*8fb009dcSAndroid Build Coastguard Worker 
GetTestCertificate()1381*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<X509> GetTestCertificate() {
1382*8fb009dcSAndroid Build Coastguard Worker   static const char kCertPEM[] =
1383*8fb009dcSAndroid Build Coastguard Worker       "-----BEGIN CERTIFICATE-----\n"
1384*8fb009dcSAndroid Build Coastguard Worker       "MIICWDCCAcGgAwIBAgIJAPuwTC6rEJsMMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV\n"
1385*8fb009dcSAndroid Build Coastguard Worker       "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n"
1386*8fb009dcSAndroid Build Coastguard Worker       "aWRnaXRzIFB0eSBMdGQwHhcNMTQwNDIzMjA1MDQwWhcNMTcwNDIyMjA1MDQwWjBF\n"
1387*8fb009dcSAndroid Build Coastguard Worker       "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n"
1388*8fb009dcSAndroid Build Coastguard Worker       "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB\n"
1389*8fb009dcSAndroid Build Coastguard Worker       "gQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92kWdGMdAQhLci\n"
1390*8fb009dcSAndroid Build Coastguard Worker       "HnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiFKKAnHmUcrgfV\n"
1391*8fb009dcSAndroid Build Coastguard Worker       "W28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQABo1AwTjAdBgNV\n"
1392*8fb009dcSAndroid Build Coastguard Worker       "HQ4EFgQUi3XVrMsIvg4fZbf6Vr5sp3Xaha8wHwYDVR0jBBgwFoAUi3XVrMsIvg4f\n"
1393*8fb009dcSAndroid Build Coastguard Worker       "Zbf6Vr5sp3Xaha8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQA76Hht\n"
1394*8fb009dcSAndroid Build Coastguard Worker       "ldY9avcTGSwbwoiuIqv0jTL1fHFnzy3RHMLDh+Lpvolc5DSrSJHCP5WuK0eeJXhr\n"
1395*8fb009dcSAndroid Build Coastguard Worker       "T5oQpHL9z/cCDLAKCKRa4uV0fhEdOWBqyR9p8y5jJtye72t6CuFUV5iqcpF4BH4f\n"
1396*8fb009dcSAndroid Build Coastguard Worker       "j2VNHwsSrJwkD4QUGlUtH7vwnQmyCFxZMmWAJg==\n"
1397*8fb009dcSAndroid Build Coastguard Worker       "-----END CERTIFICATE-----\n";
1398*8fb009dcSAndroid Build Coastguard Worker   return CertFromPEM(kCertPEM);
1399*8fb009dcSAndroid Build Coastguard Worker }
1400*8fb009dcSAndroid Build Coastguard Worker 
GetTestKey()1401*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<EVP_PKEY> GetTestKey() {
1402*8fb009dcSAndroid Build Coastguard Worker   static const char kKeyPEM[] =
1403*8fb009dcSAndroid Build Coastguard Worker       "-----BEGIN RSA PRIVATE KEY-----\n"
1404*8fb009dcSAndroid Build Coastguard Worker       "MIICXgIBAAKBgQDYK8imMuRi/03z0K1Zi0WnvfFHvwlYeyK9Na6XJYaUoIDAtB92\n"
1405*8fb009dcSAndroid Build Coastguard Worker       "kWdGMdAQhLciHnAjkXLI6W15OoV3gA/ElRZ1xUpxTMhjP6PyY5wqT5r6y8FxbiiF\n"
1406*8fb009dcSAndroid Build Coastguard Worker       "KKAnHmUcrgfVW28tQ+0rkLGMryRtrukXOgXBv7gcrmU7G1jC2a7WqmeI8QIDAQAB\n"
1407*8fb009dcSAndroid Build Coastguard Worker       "AoGBAIBy09Fd4DOq/Ijp8HeKuCMKTHqTW1xGHshLQ6jwVV2vWZIn9aIgmDsvkjCe\n"
1408*8fb009dcSAndroid Build Coastguard Worker       "i6ssZvnbjVcwzSoByhjN8ZCf/i15HECWDFFh6gt0P5z0MnChwzZmvatV/FXCT0j+\n"
1409*8fb009dcSAndroid Build Coastguard Worker       "WmGNB/gkehKjGXLLcjTb6dRYVJSCZhVuOLLcbWIV10gggJQBAkEA8S8sGe4ezyyZ\n"
1410*8fb009dcSAndroid Build Coastguard Worker       "m4e9r95g6s43kPqtj5rewTsUxt+2n4eVodD+ZUlCULWVNAFLkYRTBCASlSrm9Xhj\n"
1411*8fb009dcSAndroid Build Coastguard Worker       "QpmWAHJUkQJBAOVzQdFUaewLtdOJoPCtpYoY1zd22eae8TQEmpGOR11L6kbxLQsk\n"
1412*8fb009dcSAndroid Build Coastguard Worker       "aMly/DOnOaa82tqAGTdqDEZgSNmCeKKknmECQAvpnY8GUOVAubGR6c+W90iBuQLj\n"
1413*8fb009dcSAndroid Build Coastguard Worker       "LtFp/9ihd2w/PoDwrHZaoUYVcT4VSfJQog/k7kjE4MYXYWL8eEKg3WTWQNECQQDk\n"
1414*8fb009dcSAndroid Build Coastguard Worker       "104Wi91Umd1PzF0ijd2jXOERJU1wEKe6XLkYYNHWQAe5l4J4MWj9OdxFXAxIuuR/\n"
1415*8fb009dcSAndroid Build Coastguard Worker       "tfDwbqkta4xcux67//khAkEAvvRXLHTaa6VFzTaiiO8SaFsHV3lQyXOtMrBpB5jd\n"
1416*8fb009dcSAndroid Build Coastguard Worker       "moZWgjHvB2W9Ckn7sDqsPB+U2tyX0joDdQEyuiMECDY8oQ==\n"
1417*8fb009dcSAndroid Build Coastguard Worker       "-----END RSA PRIVATE KEY-----\n";
1418*8fb009dcSAndroid Build Coastguard Worker   return KeyFromPEM(kKeyPEM);
1419*8fb009dcSAndroid Build Coastguard Worker }
1420*8fb009dcSAndroid Build Coastguard Worker 
CreateContextWithTestCertificate(const SSL_METHOD * method)1421*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<SSL_CTX> CreateContextWithTestCertificate(
1422*8fb009dcSAndroid Build Coastguard Worker     const SSL_METHOD *method) {
1423*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1424*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetTestCertificate();
1425*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
1426*8fb009dcSAndroid Build Coastguard Worker   if (!ctx || !cert || !key ||
1427*8fb009dcSAndroid Build Coastguard Worker       !SSL_CTX_use_certificate(ctx.get(), cert.get()) ||
1428*8fb009dcSAndroid Build Coastguard Worker       !SSL_CTX_use_PrivateKey(ctx.get(), key.get())) {
1429*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1430*8fb009dcSAndroid Build Coastguard Worker   }
1431*8fb009dcSAndroid Build Coastguard Worker   return ctx;
1432*8fb009dcSAndroid Build Coastguard Worker }
1433*8fb009dcSAndroid Build Coastguard Worker 
GetECDSATestCertificateBuffer()1434*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<CRYPTO_BUFFER> GetECDSATestCertificateBuffer() {
1435*8fb009dcSAndroid Build Coastguard Worker   static const char kCertPEM[] =
1436*8fb009dcSAndroid Build Coastguard Worker       "-----BEGIN CERTIFICATE-----\n"
1437*8fb009dcSAndroid Build Coastguard Worker       "MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC\n"
1438*8fb009dcSAndroid Build Coastguard Worker       "QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp\n"
1439*8fb009dcSAndroid Build Coastguard Worker       "dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ\n"
1440*8fb009dcSAndroid Build Coastguard Worker       "BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l\n"
1441*8fb009dcSAndroid Build Coastguard Worker       "dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni\n"
1442*8fb009dcSAndroid Build Coastguard Worker       "v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa\n"
1443*8fb009dcSAndroid Build Coastguard Worker       "HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw\n"
1444*8fb009dcSAndroid Build Coastguard Worker       "HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ\n"
1445*8fb009dcSAndroid Build Coastguard Worker       "BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E\n"
1446*8fb009dcSAndroid Build Coastguard Worker       "BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=\n"
1447*8fb009dcSAndroid Build Coastguard Worker       "-----END CERTIFICATE-----\n";
1448*8fb009dcSAndroid Build Coastguard Worker   return BufferFromPEM(kCertPEM);
1449*8fb009dcSAndroid Build Coastguard Worker }
1450*8fb009dcSAndroid Build Coastguard Worker 
GetECDSATestCertificate()1451*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<X509> GetECDSATestCertificate() {
1452*8fb009dcSAndroid Build Coastguard Worker   return X509FromBuffer(GetECDSATestCertificateBuffer());
1453*8fb009dcSAndroid Build Coastguard Worker }
1454*8fb009dcSAndroid Build Coastguard Worker 
1455*8fb009dcSAndroid Build Coastguard Worker 
GetECDSATestKey()1456*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<EVP_PKEY> GetECDSATestKey() {
1457*8fb009dcSAndroid Build Coastguard Worker   static const char kKeyPEM[] =
1458*8fb009dcSAndroid Build Coastguard Worker       "-----BEGIN PRIVATE KEY-----\n"
1459*8fb009dcSAndroid Build Coastguard Worker       "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBw8IcnrUoEqc3VnJ\n"
1460*8fb009dcSAndroid Build Coastguard Worker       "TYlodwi1b8ldMHcO6NHJzgqLtGqhRANCAATmK2niv2Wfl74vHg2UikzVl2u3qR4N\n"
1461*8fb009dcSAndroid Build Coastguard Worker       "Rvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYaHPUdfvGULUvPciLB\n"
1462*8fb009dcSAndroid Build Coastguard Worker       "-----END PRIVATE KEY-----\n";
1463*8fb009dcSAndroid Build Coastguard Worker   return KeyFromPEM(kKeyPEM);
1464*8fb009dcSAndroid Build Coastguard Worker }
1465*8fb009dcSAndroid Build Coastguard Worker 
GetChainTestCertificateBuffer()1466*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestCertificateBuffer() {
1467*8fb009dcSAndroid Build Coastguard Worker   static const char kCertPEM[] =
1468*8fb009dcSAndroid Build Coastguard Worker       "-----BEGIN CERTIFICATE-----\n"
1469*8fb009dcSAndroid Build Coastguard Worker       "MIIC0jCCAbqgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwDzENMAsGA1UEAwwEQiBD\n"
1470*8fb009dcSAndroid Build Coastguard Worker       "QTAeFw0xNjAyMjgyMDI3MDNaFw0yNjAyMjUyMDI3MDNaMBgxFjAUBgNVBAMMDUNs\n"
1471*8fb009dcSAndroid Build Coastguard Worker       "aWVudCBDZXJ0IEEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvaz8\n"
1472*8fb009dcSAndroid Build Coastguard Worker       "CC/cshpCafJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/\n"
1473*8fb009dcSAndroid Build Coastguard Worker       "kLRcH89M/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3\n"
1474*8fb009dcSAndroid Build Coastguard Worker       "tHb+xs2PSs8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+c\n"
1475*8fb009dcSAndroid Build Coastguard Worker       "IDs2rQ+lP7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1\n"
1476*8fb009dcSAndroid Build Coastguard Worker       "z7C8jU50Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9V\n"
1477*8fb009dcSAndroid Build Coastguard Worker       "iLeXANgZi+Xx9KgfAgMBAAGjLzAtMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYI\n"
1478*8fb009dcSAndroid Build Coastguard Worker       "KwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBFEVbmYl+2RtNw\n"
1479*8fb009dcSAndroid Build Coastguard Worker       "rDftRDF1v2QUbcN2ouSnQDHxeDQdSgasLzT3ui8iYu0Rw2WWcZ0DV5e0ztGPhWq7\n"
1480*8fb009dcSAndroid Build Coastguard Worker       "AO0B120aFRMOY+4+bzu9Q2FFkQqc7/fKTvTDzIJI5wrMnFvUfzzvxh3OHWMYSs/w\n"
1481*8fb009dcSAndroid Build Coastguard Worker       "giq33hTKeHEq6Jyk3btCny0Ycecyc3yGXH10sizUfiHlhviCkDuESk8mFDwDDzqW\n"
1482*8fb009dcSAndroid Build Coastguard Worker       "ZF0IipzFbEDHoIxLlm3GQxpiLoEV4k8KYJp3R5KBLFyxM6UGPz8h72mIPCJp2RuK\n"
1483*8fb009dcSAndroid Build Coastguard Worker       "MYgF91UDvVzvnYm6TfseM2+ewKirC00GOrZ7rEcFvtxnKSqYf4ckqfNdSU1Y+RRC\n"
1484*8fb009dcSAndroid Build Coastguard Worker       "1ngWZ7Ih\n"
1485*8fb009dcSAndroid Build Coastguard Worker       "-----END CERTIFICATE-----\n";
1486*8fb009dcSAndroid Build Coastguard Worker   return BufferFromPEM(kCertPEM);
1487*8fb009dcSAndroid Build Coastguard Worker }
1488*8fb009dcSAndroid Build Coastguard Worker 
GetChainTestCertificate()1489*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<X509> GetChainTestCertificate() {
1490*8fb009dcSAndroid Build Coastguard Worker   return X509FromBuffer(GetChainTestCertificateBuffer());
1491*8fb009dcSAndroid Build Coastguard Worker }
1492*8fb009dcSAndroid Build Coastguard Worker 
GetChainTestIntermediateBuffer()1493*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<CRYPTO_BUFFER> GetChainTestIntermediateBuffer() {
1494*8fb009dcSAndroid Build Coastguard Worker   static const char kCertPEM[] =
1495*8fb009dcSAndroid Build Coastguard Worker       "-----BEGIN CERTIFICATE-----\n"
1496*8fb009dcSAndroid Build Coastguard Worker       "MIICwjCCAaqgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFDESMBAGA1UEAwwJQyBS\n"
1497*8fb009dcSAndroid Build Coastguard Worker       "b290IENBMB4XDTE2MDIyODIwMjcwM1oXDTI2MDIyNTIwMjcwM1owDzENMAsGA1UE\n"
1498*8fb009dcSAndroid Build Coastguard Worker       "AwwEQiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALsSCYmDip2D\n"
1499*8fb009dcSAndroid Build Coastguard Worker       "GkjFxw7ykz26JSjELkl6ArlYjFJ3aT/SCh8qbS4gln7RH8CPBd78oFdfhIKQrwtZ\n"
1500*8fb009dcSAndroid Build Coastguard Worker       "3/q21ykD9BAS3qHe2YdcJfm8/kWAy5DvXk6NXU4qX334KofBAEpgdA/igEFq1P1l\n"
1501*8fb009dcSAndroid Build Coastguard Worker       "HAuIfZCpMRfT+i5WohVsGi8f/NgpRvVaMONLNfgw57mz1lbtFeBEISmX0kbsuJxF\n"
1502*8fb009dcSAndroid Build Coastguard Worker       "Qj/Bwhi5/0HAEXG8e7zN4cEx0yPRvmOATRdVb/8dW2pwOHRJq9R5M0NUkIsTSnL7\n"
1503*8fb009dcSAndroid Build Coastguard Worker       "6N/z8hRAHMsV3IudC5Yd7GXW1AGu9a+iKU+Q4xcZCoj0DC99tL4VKujrV1kAeqsM\n"
1504*8fb009dcSAndroid Build Coastguard Worker       "cz5/dKzi6+cCAwEAAaMjMCEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
1505*8fb009dcSAndroid Build Coastguard Worker       "AQYwDQYJKoZIhvcNAQELBQADggEBAIIeZiEeNhWWQ8Y4D+AGDwqUUeG8NjCbKrXQ\n"
1506*8fb009dcSAndroid Build Coastguard Worker       "BlHg5wZ8xftFaiP1Dp/UAezmx2LNazdmuwrYB8lm3FVTyaPDTKEGIPS4wJKHgqH1\n"
1507*8fb009dcSAndroid Build Coastguard Worker       "QPDhqNm85ey7TEtI9oYjsNim/Rb+iGkIAMXaxt58SzxbjvP0kMr1JfJIZbic9vye\n"
1508*8fb009dcSAndroid Build Coastguard Worker       "NwIspMFIpP3FB8ywyu0T0hWtCQgL4J47nigCHpOu58deP88fS/Nyz/fyGVWOZ76b\n"
1509*8fb009dcSAndroid Build Coastguard Worker       "WhWwgM3P3X95fQ3d7oFPR/bVh0YV+Cf861INwplokXgXQ3/TCQ+HNXeAMWn3JLWv\n"
1510*8fb009dcSAndroid Build Coastguard Worker       "XFwk8owk9dq/kQGdndGgy3KTEW4ctPX5GNhf3LJ9Q7dLji4ReQ4=\n"
1511*8fb009dcSAndroid Build Coastguard Worker       "-----END CERTIFICATE-----\n";
1512*8fb009dcSAndroid Build Coastguard Worker   return BufferFromPEM(kCertPEM);
1513*8fb009dcSAndroid Build Coastguard Worker }
1514*8fb009dcSAndroid Build Coastguard Worker 
GetChainTestIntermediate()1515*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<X509> GetChainTestIntermediate() {
1516*8fb009dcSAndroid Build Coastguard Worker   return X509FromBuffer(GetChainTestIntermediateBuffer());
1517*8fb009dcSAndroid Build Coastguard Worker }
1518*8fb009dcSAndroid Build Coastguard Worker 
GetChainTestKey()1519*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<EVP_PKEY> GetChainTestKey() {
1520*8fb009dcSAndroid Build Coastguard Worker   static const char kKeyPEM[] =
1521*8fb009dcSAndroid Build Coastguard Worker       "-----BEGIN PRIVATE KEY-----\n"
1522*8fb009dcSAndroid Build Coastguard Worker       "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDRvaz8CC/cshpC\n"
1523*8fb009dcSAndroid Build Coastguard Worker       "afJo4jLkHEoBqDLhdgFelJoAiQUyIqyWl2O7YHPnpJH+TgR7oelzNzt/kLRcH89M\n"
1524*8fb009dcSAndroid Build Coastguard Worker       "/TszB6zqyLTC4aqmvzKL0peD/jL2LWBucR0WXIvjA3zoRuF/x86+rYH3tHb+xs2P\n"
1525*8fb009dcSAndroid Build Coastguard Worker       "Ss8EGL/Ev+ss+qTzTGEn26fuGNHkNw6tOwPpc+o8+wUtzf/kAthamo+cIDs2rQ+l\n"
1526*8fb009dcSAndroid Build Coastguard Worker       "P7+aLZTLeU/q4gcLutlzcK5imex5xy2jPkweq48kijK0kIzl1cPlA5d1z7C8jU50\n"
1527*8fb009dcSAndroid Build Coastguard Worker       "Pj9X9sQDJTN32j7UYRisJeeYQF8GaaN8SbrDI6zHgKzrRLyxDt/KQa9ViLeXANgZ\n"
1528*8fb009dcSAndroid Build Coastguard Worker       "i+Xx9KgfAgMBAAECggEBAK0VjSJzkyPaamcyTVSWjo7GdaBGcK60lk657RjR+lK0\n"
1529*8fb009dcSAndroid Build Coastguard Worker       "YJ7pkej4oM2hdsVZFsP8Cs4E33nXLa/0pDsRov/qrp0WQm2skwqGMC1I/bZ0WRPk\n"
1530*8fb009dcSAndroid Build Coastguard Worker       "wHaDrBBfESWnJDX/AGpVtlyOjPmgmK6J2usMPihQUDkKdAYrVWJePrMIxt1q6BMe\n"
1531*8fb009dcSAndroid Build Coastguard Worker       "iczs3qriMmtY3bUc4UyUwJ5fhDLjshHvfuIpYQyI6EXZM6dZksn9LylXJnigY6QJ\n"
1532*8fb009dcSAndroid Build Coastguard Worker       "HxOYO0BDwOsZ8yQ8J8afLk88i0GizEkgE1z3REtQUwgWfxr1WV/ud+T6/ZhSAgH9\n"
1533*8fb009dcSAndroid Build Coastguard Worker       "042mQvSFZnIUSEsmCvjhWuAunfxHKCTcAoYISWfzWpkCgYEA7gpf3HHU5Tn+CgUn\n"
1534*8fb009dcSAndroid Build Coastguard Worker       "1X5uGpG3DmcMgfeGgs2r2f/IIg/5Ac1dfYILiybL1tN9zbyLCJfcbFpWBc9hJL6f\n"
1535*8fb009dcSAndroid Build Coastguard Worker       "CPc5hUiwWFJqBJewxQkC1Ae/HakHbip+IZ+Jr0842O4BAArvixk4Lb7/N2Ct9sTE\n"
1536*8fb009dcSAndroid Build Coastguard Worker       "NJO6RtK9lbEZ5uK61DglHy8CS2UCgYEA4ZC1o36kPAMQBggajgnucb2yuUEelk0f\n"
1537*8fb009dcSAndroid Build Coastguard Worker       "AEr+GI32MGE+93xMr7rAhBoqLg4AITyIfEnOSQ5HwagnIHonBbv1LV/Gf9ursx8Z\n"
1538*8fb009dcSAndroid Build Coastguard Worker       "YOGbvT8zzzC+SU1bkDzdjAYnFQVGIjMtKOBJ3K07++ypwX1fr4QsQ8uKL8WSOWwt\n"
1539*8fb009dcSAndroid Build Coastguard Worker       "Z3Bym6XiZzMCgYADnhy+2OwHX85AkLt+PyGlPbmuelpyTzS4IDAQbBa6jcuW/2wA\n"
1540*8fb009dcSAndroid Build Coastguard Worker       "UE2km75VUXmD+u2R/9zVuLm99NzhFhSMqlUxdV1YukfqMfP5yp1EY6m/5aW7QuIP\n"
1541*8fb009dcSAndroid Build Coastguard Worker       "2MDa7TVL9rIFMiVZ09RKvbBbQxjhuzPQKL6X/PPspnhiTefQ+dl2k9xREQKBgHDS\n"
1542*8fb009dcSAndroid Build Coastguard Worker       "fMfGNEeAEKezrfSVqxphE9/tXms3L+ZpnCaT+yu/uEr5dTIAawKoQ6i9f/sf1/Sy\n"
1543*8fb009dcSAndroid Build Coastguard Worker       "xedsqR+IB+oKrzIDDWMgoJybN4pkZ8E5lzhVQIjFjKgFdWLzzqyW9z1gYfABQPlN\n"
1544*8fb009dcSAndroid Build Coastguard Worker       "FiS20WX0vgP1vcKAjdNrHzc9zyHBpgQzDmAj3NZZAoGBAI8vKCKdH7w3aL5CNkZQ\n"
1545*8fb009dcSAndroid Build Coastguard Worker       "2buIeWNA2HZazVwAGG5F2TU/LmXfRKnG6dX5bkU+AkBZh56jNZy//hfFSewJB4Kk\n"
1546*8fb009dcSAndroid Build Coastguard Worker       "buB7ERSdaNbO21zXt9FEA3+z0RfMd/Zv2vlIWOSB5nzl/7UKti3sribK6s9ZVLfi\n"
1547*8fb009dcSAndroid Build Coastguard Worker       "SxpiPQ8d/hmSGwn4ksrWUsJD\n"
1548*8fb009dcSAndroid Build Coastguard Worker       "-----END PRIVATE KEY-----\n";
1549*8fb009dcSAndroid Build Coastguard Worker   return KeyFromPEM(kKeyPEM);
1550*8fb009dcSAndroid Build Coastguard Worker }
1551*8fb009dcSAndroid Build Coastguard Worker 
CompleteHandshakes(SSL * client,SSL * server)1552*8fb009dcSAndroid Build Coastguard Worker static bool CompleteHandshakes(SSL *client, SSL *server) {
1553*8fb009dcSAndroid Build Coastguard Worker   // Drive both their handshakes to completion.
1554*8fb009dcSAndroid Build Coastguard Worker   for (;;) {
1555*8fb009dcSAndroid Build Coastguard Worker     int client_ret = SSL_do_handshake(client);
1556*8fb009dcSAndroid Build Coastguard Worker     int client_err = SSL_get_error(client, client_ret);
1557*8fb009dcSAndroid Build Coastguard Worker     if (client_err != SSL_ERROR_NONE &&
1558*8fb009dcSAndroid Build Coastguard Worker         client_err != SSL_ERROR_WANT_READ &&
1559*8fb009dcSAndroid Build Coastguard Worker         client_err != SSL_ERROR_WANT_WRITE &&
1560*8fb009dcSAndroid Build Coastguard Worker         client_err != SSL_ERROR_PENDING_TICKET) {
1561*8fb009dcSAndroid Build Coastguard Worker       fprintf(stderr, "Client error: %s\n", SSL_error_description(client_err));
1562*8fb009dcSAndroid Build Coastguard Worker       return false;
1563*8fb009dcSAndroid Build Coastguard Worker     }
1564*8fb009dcSAndroid Build Coastguard Worker 
1565*8fb009dcSAndroid Build Coastguard Worker     int server_ret = SSL_do_handshake(server);
1566*8fb009dcSAndroid Build Coastguard Worker     int server_err = SSL_get_error(server, server_ret);
1567*8fb009dcSAndroid Build Coastguard Worker     if (server_err != SSL_ERROR_NONE &&
1568*8fb009dcSAndroid Build Coastguard Worker         server_err != SSL_ERROR_WANT_READ &&
1569*8fb009dcSAndroid Build Coastguard Worker         server_err != SSL_ERROR_WANT_WRITE &&
1570*8fb009dcSAndroid Build Coastguard Worker         server_err != SSL_ERROR_PENDING_TICKET) {
1571*8fb009dcSAndroid Build Coastguard Worker       fprintf(stderr, "Server error: %s\n", SSL_error_description(server_err));
1572*8fb009dcSAndroid Build Coastguard Worker       return false;
1573*8fb009dcSAndroid Build Coastguard Worker     }
1574*8fb009dcSAndroid Build Coastguard Worker 
1575*8fb009dcSAndroid Build Coastguard Worker     if (client_ret == 1 && server_ret == 1) {
1576*8fb009dcSAndroid Build Coastguard Worker       break;
1577*8fb009dcSAndroid Build Coastguard Worker     }
1578*8fb009dcSAndroid Build Coastguard Worker   }
1579*8fb009dcSAndroid Build Coastguard Worker 
1580*8fb009dcSAndroid Build Coastguard Worker   return true;
1581*8fb009dcSAndroid Build Coastguard Worker }
1582*8fb009dcSAndroid Build Coastguard Worker 
FlushNewSessionTickets(SSL * client,SSL * server)1583*8fb009dcSAndroid Build Coastguard Worker static bool FlushNewSessionTickets(SSL *client, SSL *server) {
1584*8fb009dcSAndroid Build Coastguard Worker   // NewSessionTickets are deferred on the server to |SSL_write|, and clients do
1585*8fb009dcSAndroid Build Coastguard Worker   // not pick them up until |SSL_read|.
1586*8fb009dcSAndroid Build Coastguard Worker   for (;;) {
1587*8fb009dcSAndroid Build Coastguard Worker     int server_ret = SSL_write(server, nullptr, 0);
1588*8fb009dcSAndroid Build Coastguard Worker     int server_err = SSL_get_error(server, server_ret);
1589*8fb009dcSAndroid Build Coastguard Worker     // The server may either succeed (|server_ret| is zero) or block on write
1590*8fb009dcSAndroid Build Coastguard Worker     // (|server_ret| is -1 and |server_err| is |SSL_ERROR_WANT_WRITE|).
1591*8fb009dcSAndroid Build Coastguard Worker     if (server_ret > 0 ||
1592*8fb009dcSAndroid Build Coastguard Worker         (server_ret < 0 && server_err != SSL_ERROR_WANT_WRITE)) {
1593*8fb009dcSAndroid Build Coastguard Worker       fprintf(stderr, "Unexpected server result: %d %d\n", server_ret,
1594*8fb009dcSAndroid Build Coastguard Worker               server_err);
1595*8fb009dcSAndroid Build Coastguard Worker       return false;
1596*8fb009dcSAndroid Build Coastguard Worker     }
1597*8fb009dcSAndroid Build Coastguard Worker 
1598*8fb009dcSAndroid Build Coastguard Worker     int client_ret = SSL_read(client, nullptr, 0);
1599*8fb009dcSAndroid Build Coastguard Worker     int client_err = SSL_get_error(client, client_ret);
1600*8fb009dcSAndroid Build Coastguard Worker     // The client must always block on read.
1601*8fb009dcSAndroid Build Coastguard Worker     if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
1602*8fb009dcSAndroid Build Coastguard Worker       fprintf(stderr, "Unexpected client result: %d %d\n", client_ret,
1603*8fb009dcSAndroid Build Coastguard Worker               client_err);
1604*8fb009dcSAndroid Build Coastguard Worker       return false;
1605*8fb009dcSAndroid Build Coastguard Worker     }
1606*8fb009dcSAndroid Build Coastguard Worker 
1607*8fb009dcSAndroid Build Coastguard Worker     // The server flushed everything it had to write.
1608*8fb009dcSAndroid Build Coastguard Worker     if (server_ret == 0) {
1609*8fb009dcSAndroid Build Coastguard Worker       return true;
1610*8fb009dcSAndroid Build Coastguard Worker     }
1611*8fb009dcSAndroid Build Coastguard Worker   }
1612*8fb009dcSAndroid Build Coastguard Worker }
1613*8fb009dcSAndroid Build Coastguard Worker 
1614*8fb009dcSAndroid Build Coastguard Worker // CreateClientAndServer creates a client and server |SSL| objects whose |BIO|s
1615*8fb009dcSAndroid Build Coastguard Worker // are paired with each other. It does not run the handshake. The caller is
1616*8fb009dcSAndroid Build Coastguard Worker // expected to configure the objects and drive the handshake as needed.
CreateClientAndServer(bssl::UniquePtr<SSL> * out_client,bssl::UniquePtr<SSL> * out_server,SSL_CTX * client_ctx,SSL_CTX * server_ctx)1617*8fb009dcSAndroid Build Coastguard Worker static bool CreateClientAndServer(bssl::UniquePtr<SSL> *out_client,
1618*8fb009dcSAndroid Build Coastguard Worker                                   bssl::UniquePtr<SSL> *out_server,
1619*8fb009dcSAndroid Build Coastguard Worker                                   SSL_CTX *client_ctx, SSL_CTX *server_ctx) {
1620*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
1621*8fb009dcSAndroid Build Coastguard Worker   if (!client || !server) {
1622*8fb009dcSAndroid Build Coastguard Worker     return false;
1623*8fb009dcSAndroid Build Coastguard Worker   }
1624*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(client.get());
1625*8fb009dcSAndroid Build Coastguard Worker   SSL_set_accept_state(server.get());
1626*8fb009dcSAndroid Build Coastguard Worker 
1627*8fb009dcSAndroid Build Coastguard Worker   BIO *bio1, *bio2;
1628*8fb009dcSAndroid Build Coastguard Worker   if (!BIO_new_bio_pair(&bio1, 0, &bio2, 0)) {
1629*8fb009dcSAndroid Build Coastguard Worker     return false;
1630*8fb009dcSAndroid Build Coastguard Worker   }
1631*8fb009dcSAndroid Build Coastguard Worker   // SSL_set_bio takes ownership.
1632*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(client.get(), bio1, bio1);
1633*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(server.get(), bio2, bio2);
1634*8fb009dcSAndroid Build Coastguard Worker 
1635*8fb009dcSAndroid Build Coastguard Worker   *out_client = std::move(client);
1636*8fb009dcSAndroid Build Coastguard Worker   *out_server = std::move(server);
1637*8fb009dcSAndroid Build Coastguard Worker   return true;
1638*8fb009dcSAndroid Build Coastguard Worker }
1639*8fb009dcSAndroid Build Coastguard Worker 
1640*8fb009dcSAndroid Build Coastguard Worker struct ClientConfig {
1641*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *session = nullptr;
1642*8fb009dcSAndroid Build Coastguard Worker   std::string servername;
1643*8fb009dcSAndroid Build Coastguard Worker   std::string verify_hostname;
1644*8fb009dcSAndroid Build Coastguard Worker   unsigned hostflags = 0;
1645*8fb009dcSAndroid Build Coastguard Worker   bool early_data = false;
1646*8fb009dcSAndroid Build Coastguard Worker };
1647*8fb009dcSAndroid Build Coastguard Worker 
ConnectClientAndServer(bssl::UniquePtr<SSL> * out_client,bssl::UniquePtr<SSL> * out_server,SSL_CTX * client_ctx,SSL_CTX * server_ctx,const ClientConfig & config=ClientConfig (),bool shed_handshake_config=true)1648*8fb009dcSAndroid Build Coastguard Worker static bool ConnectClientAndServer(bssl::UniquePtr<SSL> *out_client,
1649*8fb009dcSAndroid Build Coastguard Worker                                    bssl::UniquePtr<SSL> *out_server,
1650*8fb009dcSAndroid Build Coastguard Worker                                    SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1651*8fb009dcSAndroid Build Coastguard Worker                                    const ClientConfig &config = ClientConfig(),
1652*8fb009dcSAndroid Build Coastguard Worker                                    bool shed_handshake_config = true) {
1653*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
1654*8fb009dcSAndroid Build Coastguard Worker   if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx)) {
1655*8fb009dcSAndroid Build Coastguard Worker     return false;
1656*8fb009dcSAndroid Build Coastguard Worker   }
1657*8fb009dcSAndroid Build Coastguard Worker   if (config.early_data) {
1658*8fb009dcSAndroid Build Coastguard Worker     SSL_set_early_data_enabled(client.get(), 1);
1659*8fb009dcSAndroid Build Coastguard Worker   }
1660*8fb009dcSAndroid Build Coastguard Worker   if (config.session) {
1661*8fb009dcSAndroid Build Coastguard Worker     SSL_set_session(client.get(), config.session);
1662*8fb009dcSAndroid Build Coastguard Worker   }
1663*8fb009dcSAndroid Build Coastguard Worker   if (!config.servername.empty() &&
1664*8fb009dcSAndroid Build Coastguard Worker       !SSL_set_tlsext_host_name(client.get(), config.servername.c_str())) {
1665*8fb009dcSAndroid Build Coastguard Worker     return false;
1666*8fb009dcSAndroid Build Coastguard Worker   }
1667*8fb009dcSAndroid Build Coastguard Worker   if (!config.verify_hostname.empty()) {
1668*8fb009dcSAndroid Build Coastguard Worker     if (!SSL_set1_host(client.get(), config.verify_hostname.c_str())) {
1669*8fb009dcSAndroid Build Coastguard Worker       return false;
1670*8fb009dcSAndroid Build Coastguard Worker     }
1671*8fb009dcSAndroid Build Coastguard Worker     SSL_set_hostflags(client.get(), config.hostflags);
1672*8fb009dcSAndroid Build Coastguard Worker   }
1673*8fb009dcSAndroid Build Coastguard Worker 
1674*8fb009dcSAndroid Build Coastguard Worker   SSL_set_shed_handshake_config(client.get(), shed_handshake_config);
1675*8fb009dcSAndroid Build Coastguard Worker   SSL_set_shed_handshake_config(server.get(), shed_handshake_config);
1676*8fb009dcSAndroid Build Coastguard Worker 
1677*8fb009dcSAndroid Build Coastguard Worker   if (!CompleteHandshakes(client.get(), server.get())) {
1678*8fb009dcSAndroid Build Coastguard Worker     return false;
1679*8fb009dcSAndroid Build Coastguard Worker   }
1680*8fb009dcSAndroid Build Coastguard Worker 
1681*8fb009dcSAndroid Build Coastguard Worker   *out_client = std::move(client);
1682*8fb009dcSAndroid Build Coastguard Worker   *out_server = std::move(server);
1683*8fb009dcSAndroid Build Coastguard Worker   return true;
1684*8fb009dcSAndroid Build Coastguard Worker }
1685*8fb009dcSAndroid Build Coastguard Worker 
1686*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<SSL_SESSION> g_last_session;
1687*8fb009dcSAndroid Build Coastguard Worker 
SaveLastSession(SSL * ssl,SSL_SESSION * session)1688*8fb009dcSAndroid Build Coastguard Worker static int SaveLastSession(SSL *ssl, SSL_SESSION *session) {
1689*8fb009dcSAndroid Build Coastguard Worker   // Save the most recent session.
1690*8fb009dcSAndroid Build Coastguard Worker   g_last_session.reset(session);
1691*8fb009dcSAndroid Build Coastguard Worker   return 1;
1692*8fb009dcSAndroid Build Coastguard Worker }
1693*8fb009dcSAndroid Build Coastguard Worker 
CreateClientSession(SSL_CTX * client_ctx,SSL_CTX * server_ctx,const ClientConfig & config=ClientConfig ())1694*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<SSL_SESSION> CreateClientSession(
1695*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX *client_ctx, SSL_CTX *server_ctx,
1696*8fb009dcSAndroid Build Coastguard Worker     const ClientConfig &config = ClientConfig()) {
1697*8fb009dcSAndroid Build Coastguard Worker   g_last_session = nullptr;
1698*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
1699*8fb009dcSAndroid Build Coastguard Worker 
1700*8fb009dcSAndroid Build Coastguard Worker   // Connect client and server to get a session.
1701*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
1702*8fb009dcSAndroid Build Coastguard Worker   if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
1703*8fb009dcSAndroid Build Coastguard Worker                               config) ||
1704*8fb009dcSAndroid Build Coastguard Worker       !FlushNewSessionTickets(client.get(), server.get())) {
1705*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Failed to connect client and server.\n");
1706*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1707*8fb009dcSAndroid Build Coastguard Worker   }
1708*8fb009dcSAndroid Build Coastguard Worker 
1709*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
1710*8fb009dcSAndroid Build Coastguard Worker 
1711*8fb009dcSAndroid Build Coastguard Worker   if (!g_last_session) {
1712*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Client did not receive a session.\n");
1713*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1714*8fb009dcSAndroid Build Coastguard Worker   }
1715*8fb009dcSAndroid Build Coastguard Worker   return std::move(g_last_session);
1716*8fb009dcSAndroid Build Coastguard Worker }
1717*8fb009dcSAndroid Build Coastguard Worker 
SetUpExpectedNewCodePoint(SSL_CTX * ctx)1718*8fb009dcSAndroid Build Coastguard Worker static void SetUpExpectedNewCodePoint(SSL_CTX *ctx) {
1719*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_select_certificate_cb(
1720*8fb009dcSAndroid Build Coastguard Worker       ctx,
1721*8fb009dcSAndroid Build Coastguard Worker       [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
1722*8fb009dcSAndroid Build Coastguard Worker         const uint8_t *data;
1723*8fb009dcSAndroid Build Coastguard Worker         size_t len;
1724*8fb009dcSAndroid Build Coastguard Worker         if (!SSL_early_callback_ctx_extension_get(
1725*8fb009dcSAndroid Build Coastguard Worker                 client_hello, TLSEXT_TYPE_application_settings, &data,
1726*8fb009dcSAndroid Build Coastguard Worker                 &len)) {
1727*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "Could not find alps new codepoint.";
1728*8fb009dcSAndroid Build Coastguard Worker           return ssl_select_cert_error;
1729*8fb009dcSAndroid Build Coastguard Worker         }
1730*8fb009dcSAndroid Build Coastguard Worker         return ssl_select_cert_success;
1731*8fb009dcSAndroid Build Coastguard Worker       });
1732*8fb009dcSAndroid Build Coastguard Worker }
1733*8fb009dcSAndroid Build Coastguard Worker 
SetUpExpectedOldCodePoint(SSL_CTX * ctx)1734*8fb009dcSAndroid Build Coastguard Worker static void SetUpExpectedOldCodePoint(SSL_CTX *ctx) {
1735*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_select_certificate_cb(
1736*8fb009dcSAndroid Build Coastguard Worker       ctx,
1737*8fb009dcSAndroid Build Coastguard Worker       [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
1738*8fb009dcSAndroid Build Coastguard Worker         const uint8_t *data;
1739*8fb009dcSAndroid Build Coastguard Worker         size_t len;
1740*8fb009dcSAndroid Build Coastguard Worker         if (!SSL_early_callback_ctx_extension_get(
1741*8fb009dcSAndroid Build Coastguard Worker                 client_hello, TLSEXT_TYPE_application_settings_old, &data,
1742*8fb009dcSAndroid Build Coastguard Worker                 &len)) {
1743*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "Could not find alps old codepoint.";
1744*8fb009dcSAndroid Build Coastguard Worker           return ssl_select_cert_error;
1745*8fb009dcSAndroid Build Coastguard Worker         }
1746*8fb009dcSAndroid Build Coastguard Worker         return ssl_select_cert_success;
1747*8fb009dcSAndroid Build Coastguard Worker       });
1748*8fb009dcSAndroid Build Coastguard Worker }
1749*8fb009dcSAndroid Build Coastguard Worker 
1750*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_get_client_CA_list| echoes back the configured parameter even
1751*8fb009dcSAndroid Build Coastguard Worker // before configuring as a server.
TEST(SSLTest,ClientCAList)1752*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ClientCAList) {
1753*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1754*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
1755*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1756*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
1757*8fb009dcSAndroid Build Coastguard Worker 
1758*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
1759*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(name);
1760*8fb009dcSAndroid Build Coastguard Worker 
1761*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509_NAME> name_dup(X509_NAME_dup(name.get()));
1762*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(name_dup);
1763*8fb009dcSAndroid Build Coastguard Worker 
1764*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
1765*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(stack);
1766*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(PushToStack(stack.get(), std::move(name_dup)));
1767*8fb009dcSAndroid Build Coastguard Worker 
1768*8fb009dcSAndroid Build Coastguard Worker   // |SSL_set_client_CA_list| takes ownership.
1769*8fb009dcSAndroid Build Coastguard Worker   SSL_set_client_CA_list(ssl.get(), stack.release());
1770*8fb009dcSAndroid Build Coastguard Worker 
1771*8fb009dcSAndroid Build Coastguard Worker   STACK_OF(X509_NAME) *result = SSL_get_client_CA_list(ssl.get());
1772*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(result);
1773*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(1u, sk_X509_NAME_num(result));
1774*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(result, 0), name.get()));
1775*8fb009dcSAndroid Build Coastguard Worker }
1776*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,AddClientCA)1777*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, AddClientCA) {
1778*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
1779*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
1780*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
1781*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
1782*8fb009dcSAndroid Build Coastguard Worker 
1783*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert1 = GetTestCertificate();
1784*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert2 = GetChainTestCertificate();
1785*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert1 && cert2);
1786*8fb009dcSAndroid Build Coastguard Worker   X509_NAME *name1 = X509_get_subject_name(cert1.get());
1787*8fb009dcSAndroid Build Coastguard Worker   X509_NAME *name2 = X509_get_subject_name(cert2.get());
1788*8fb009dcSAndroid Build Coastguard Worker 
1789*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0u, sk_X509_NAME_num(SSL_get_client_CA_list(ssl.get())));
1790*8fb009dcSAndroid Build Coastguard Worker 
1791*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1792*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert2.get()));
1793*8fb009dcSAndroid Build Coastguard Worker 
1794*8fb009dcSAndroid Build Coastguard Worker   STACK_OF(X509_NAME) *list = SSL_get_client_CA_list(ssl.get());
1795*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(2u, sk_X509_NAME_num(list));
1796*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1797*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1798*8fb009dcSAndroid Build Coastguard Worker 
1799*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_add_client_CA(ssl.get(), cert1.get()));
1800*8fb009dcSAndroid Build Coastguard Worker 
1801*8fb009dcSAndroid Build Coastguard Worker   list = SSL_get_client_CA_list(ssl.get());
1802*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(3u, sk_X509_NAME_num(list));
1803*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 0), name1));
1804*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 1), name2));
1805*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_NAME_cmp(sk_X509_NAME_value(list, 2), name1));
1806*8fb009dcSAndroid Build Coastguard Worker }
1807*8fb009dcSAndroid Build Coastguard Worker 
1808*8fb009dcSAndroid Build Coastguard Worker struct ECHConfigParams {
1809*8fb009dcSAndroid Build Coastguard Worker   uint16_t version = TLSEXT_TYPE_encrypted_client_hello;
1810*8fb009dcSAndroid Build Coastguard Worker   uint16_t config_id = 1;
1811*8fb009dcSAndroid Build Coastguard Worker   std::string public_name = "example.com";
1812*8fb009dcSAndroid Build Coastguard Worker   const EVP_HPKE_KEY *key = nullptr;
1813*8fb009dcSAndroid Build Coastguard Worker   // kem_id, if zero, takes its value from |key|.
1814*8fb009dcSAndroid Build Coastguard Worker   uint16_t kem_id = 0;
1815*8fb009dcSAndroid Build Coastguard Worker   // public_key, if empty takes its value from |key|.
1816*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> public_key;
1817*8fb009dcSAndroid Build Coastguard Worker   size_t max_name_len = 16;
1818*8fb009dcSAndroid Build Coastguard Worker   // cipher_suites is a list of code points which should contain pairs of KDF
1819*8fb009dcSAndroid Build Coastguard Worker   // and AEAD IDs.
1820*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint16_t> cipher_suites = {EVP_HPKE_HKDF_SHA256,
1821*8fb009dcSAndroid Build Coastguard Worker                                          EVP_HPKE_AES_128_GCM};
1822*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> extensions;
1823*8fb009dcSAndroid Build Coastguard Worker };
1824*8fb009dcSAndroid Build Coastguard Worker 
1825*8fb009dcSAndroid Build Coastguard Worker // MakeECHConfig serializes an ECHConfig from |params| and writes it to
1826*8fb009dcSAndroid Build Coastguard Worker // |*out|.
MakeECHConfig(std::vector<uint8_t> * out,const ECHConfigParams & params)1827*8fb009dcSAndroid Build Coastguard Worker bool MakeECHConfig(std::vector<uint8_t> *out,
1828*8fb009dcSAndroid Build Coastguard Worker                          const ECHConfigParams &params) {
1829*8fb009dcSAndroid Build Coastguard Worker   uint16_t kem_id = params.kem_id == 0
1830*8fb009dcSAndroid Build Coastguard Worker                         ? EVP_HPKE_KEM_id(EVP_HPKE_KEY_kem(params.key))
1831*8fb009dcSAndroid Build Coastguard Worker                         : params.kem_id;
1832*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> public_key = params.public_key;
1833*8fb009dcSAndroid Build Coastguard Worker   if (public_key.empty()) {
1834*8fb009dcSAndroid Build Coastguard Worker     public_key.resize(EVP_HPKE_MAX_PUBLIC_KEY_LENGTH);
1835*8fb009dcSAndroid Build Coastguard Worker     size_t len;
1836*8fb009dcSAndroid Build Coastguard Worker     if (!EVP_HPKE_KEY_public_key(params.key, public_key.data(), &len,
1837*8fb009dcSAndroid Build Coastguard Worker                                  public_key.size())) {
1838*8fb009dcSAndroid Build Coastguard Worker       return false;
1839*8fb009dcSAndroid Build Coastguard Worker     }
1840*8fb009dcSAndroid Build Coastguard Worker     public_key.resize(len);
1841*8fb009dcSAndroid Build Coastguard Worker   }
1842*8fb009dcSAndroid Build Coastguard Worker 
1843*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedCBB cbb;
1844*8fb009dcSAndroid Build Coastguard Worker   CBB contents, child;
1845*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_init(cbb.get(), 64) ||
1846*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(cbb.get(), params.version) ||
1847*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(cbb.get(), &contents) ||
1848*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8(&contents, params.config_id) ||
1849*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16(&contents, kem_id) ||
1850*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(&contents, &child) ||
1851*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&child, public_key.data(), public_key.size()) ||
1852*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(&contents, &child)) {
1853*8fb009dcSAndroid Build Coastguard Worker     return false;
1854*8fb009dcSAndroid Build Coastguard Worker   }
1855*8fb009dcSAndroid Build Coastguard Worker   for (uint16_t cipher_suite : params.cipher_suites) {
1856*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u16(&child, cipher_suite)) {
1857*8fb009dcSAndroid Build Coastguard Worker       return false;
1858*8fb009dcSAndroid Build Coastguard Worker     }
1859*8fb009dcSAndroid Build Coastguard Worker   }
1860*8fb009dcSAndroid Build Coastguard Worker   if (!CBB_add_u8(&contents, params.max_name_len) ||
1861*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u8_length_prefixed(&contents, &child) ||
1862*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(
1863*8fb009dcSAndroid Build Coastguard Worker           &child, reinterpret_cast<const uint8_t *>(params.public_name.data()),
1864*8fb009dcSAndroid Build Coastguard Worker           params.public_name.size()) ||
1865*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_u16_length_prefixed(&contents, &child) ||
1866*8fb009dcSAndroid Build Coastguard Worker       !CBB_add_bytes(&child, params.extensions.data(),
1867*8fb009dcSAndroid Build Coastguard Worker                      params.extensions.size()) ||
1868*8fb009dcSAndroid Build Coastguard Worker       !CBB_flush(cbb.get())) {
1869*8fb009dcSAndroid Build Coastguard Worker     return false;
1870*8fb009dcSAndroid Build Coastguard Worker   }
1871*8fb009dcSAndroid Build Coastguard Worker 
1872*8fb009dcSAndroid Build Coastguard Worker   out->assign(CBB_data(cbb.get()), CBB_data(cbb.get()) + CBB_len(cbb.get()));
1873*8fb009dcSAndroid Build Coastguard Worker   return true;
1874*8fb009dcSAndroid Build Coastguard Worker }
1875*8fb009dcSAndroid Build Coastguard Worker 
MakeTestECHKeys(uint8_t config_id=1)1876*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<SSL_ECH_KEYS> MakeTestECHKeys(uint8_t config_id = 1) {
1877*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key;
1878*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config;
1879*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config_len;
1880*8fb009dcSAndroid Build Coastguard Worker   if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
1881*8fb009dcSAndroid Build Coastguard Worker       !SSL_marshal_ech_config(&ech_config, &ech_config_len, config_id,
1882*8fb009dcSAndroid Build Coastguard Worker                               key.get(), "public.example", 16)) {
1883*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1884*8fb009dcSAndroid Build Coastguard Worker   }
1885*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1886*8fb009dcSAndroid Build Coastguard Worker 
1887*8fb009dcSAndroid Build Coastguard Worker   // Install a non-retry config.
1888*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1889*8fb009dcSAndroid Build Coastguard Worker   if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1890*8fb009dcSAndroid Build Coastguard Worker                                  ech_config_len, key.get())) {
1891*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
1892*8fb009dcSAndroid Build Coastguard Worker   }
1893*8fb009dcSAndroid Build Coastguard Worker   return keys;
1894*8fb009dcSAndroid Build Coastguard Worker }
1895*8fb009dcSAndroid Build Coastguard Worker 
InstallECHConfigList(SSL * client,const SSL_ECH_KEYS * keys)1896*8fb009dcSAndroid Build Coastguard Worker static bool InstallECHConfigList(SSL *client, const SSL_ECH_KEYS *keys) {
1897*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config_list;
1898*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config_list_len;
1899*8fb009dcSAndroid Build Coastguard Worker   if (!SSL_ECH_KEYS_marshal_retry_configs(keys, &ech_config_list,
1900*8fb009dcSAndroid Build Coastguard Worker                                           &ech_config_list_len)) {
1901*8fb009dcSAndroid Build Coastguard Worker     return false;
1902*8fb009dcSAndroid Build Coastguard Worker   }
1903*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1904*8fb009dcSAndroid Build Coastguard Worker   return SSL_set1_ech_config_list(client, ech_config_list, ech_config_list_len);
1905*8fb009dcSAndroid Build Coastguard Worker }
1906*8fb009dcSAndroid Build Coastguard Worker 
1907*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_marshal_ech_config| and |SSL_ECH_KEYS_marshal_retry_configs|
1908*8fb009dcSAndroid Build Coastguard Worker // output values as expected.
TEST(SSLTest,MarshalECHConfig)1909*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, MarshalECHConfig) {
1910*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kPrivateKey[X25519_PRIVATE_KEY_LEN] = {
1911*8fb009dcSAndroid Build Coastguard Worker       0xbc, 0xb5, 0x51, 0x29, 0x31, 0x10, 0x30, 0xc9, 0xed, 0x26, 0xde,
1912*8fb009dcSAndroid Build Coastguard Worker       0xd4, 0xb3, 0xdf, 0x3a, 0xce, 0x06, 0x8a, 0xee, 0x17, 0xab, 0xce,
1913*8fb009dcSAndroid Build Coastguard Worker       0xd7, 0xdb, 0xf3, 0x11, 0xe5, 0xa8, 0xf3, 0xb1, 0x8e, 0x24};
1914*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key;
1915*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_init(key.get(), EVP_hpke_x25519_hkdf_sha256(),
1916*8fb009dcSAndroid Build Coastguard Worker                                 kPrivateKey, sizeof(kPrivateKey)));
1917*8fb009dcSAndroid Build Coastguard Worker 
1918*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kECHConfig[] = {
1919*8fb009dcSAndroid Build Coastguard Worker       // version
1920*8fb009dcSAndroid Build Coastguard Worker       0xfe, 0x0d,
1921*8fb009dcSAndroid Build Coastguard Worker       // length
1922*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x41,
1923*8fb009dcSAndroid Build Coastguard Worker       // contents.config_id
1924*8fb009dcSAndroid Build Coastguard Worker       0x01,
1925*8fb009dcSAndroid Build Coastguard Worker       // contents.kem_id
1926*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x20,
1927*8fb009dcSAndroid Build Coastguard Worker       // contents.public_key
1928*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x20, 0xa6, 0x9a, 0x41, 0x48, 0x5d, 0x32, 0x96, 0xa4, 0xe0, 0xc3,
1929*8fb009dcSAndroid Build Coastguard Worker       0x6a, 0xee, 0xf6, 0x63, 0x0f, 0x59, 0x32, 0x6f, 0xdc, 0xff, 0x81, 0x29,
1930*8fb009dcSAndroid Build Coastguard Worker       0x59, 0xa5, 0x85, 0xd3, 0x9b, 0x3b, 0xde, 0x98, 0x55, 0x5c,
1931*8fb009dcSAndroid Build Coastguard Worker       // contents.cipher_suites
1932*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x08, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x03,
1933*8fb009dcSAndroid Build Coastguard Worker       // contents.maximum_name_length
1934*8fb009dcSAndroid Build Coastguard Worker       0x10,
1935*8fb009dcSAndroid Build Coastguard Worker       // contents.public_name
1936*8fb009dcSAndroid Build Coastguard Worker       0x0e, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2e, 0x65, 0x78, 0x61, 0x6d,
1937*8fb009dcSAndroid Build Coastguard Worker       0x70, 0x6c, 0x65,
1938*8fb009dcSAndroid Build Coastguard Worker       // contents.extensions
1939*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x00};
1940*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config;
1941*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config_len;
1942*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
1943*8fb009dcSAndroid Build Coastguard Worker                                      /*config_id=*/1, key.get(),
1944*8fb009dcSAndroid Build Coastguard Worker                                      "public.example", 16));
1945*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
1946*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(kECHConfig), Bytes(ech_config, ech_config_len));
1947*8fb009dcSAndroid Build Coastguard Worker 
1948*8fb009dcSAndroid Build Coastguard Worker   // Generate a second ECHConfig.
1949*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key2;
1950*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
1951*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config2;
1952*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config2_len;
1953*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
1954*8fb009dcSAndroid Build Coastguard Worker                                      /*config_id=*/2, key2.get(),
1955*8fb009dcSAndroid Build Coastguard Worker                                      "public.example", 16));
1956*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
1957*8fb009dcSAndroid Build Coastguard Worker 
1958*8fb009dcSAndroid Build Coastguard Worker   // Install both ECHConfigs in an |SSL_ECH_KEYS|.
1959*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1960*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys);
1961*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
1962*8fb009dcSAndroid Build Coastguard Worker                                ech_config_len, key.get()));
1963*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config2,
1964*8fb009dcSAndroid Build Coastguard Worker                                ech_config2_len, key2.get()));
1965*8fb009dcSAndroid Build Coastguard Worker 
1966*8fb009dcSAndroid Build Coastguard Worker   // The ECHConfigList should be correctly serialized.
1967*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config_list;
1968*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config_list_len;
1969*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_marshal_retry_configs(keys.get(), &ech_config_list,
1970*8fb009dcSAndroid Build Coastguard Worker                                                  &ech_config_list_len));
1971*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config_list(ech_config_list);
1972*8fb009dcSAndroid Build Coastguard Worker 
1973*8fb009dcSAndroid Build Coastguard Worker   // ECHConfigList is just the concatenation with a length prefix.
1974*8fb009dcSAndroid Build Coastguard Worker   size_t len = ech_config_len + ech_config2_len;
1975*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> expected = {uint8_t(len >> 8), uint8_t(len)};
1976*8fb009dcSAndroid Build Coastguard Worker   expected.insert(expected.end(), ech_config, ech_config + ech_config_len);
1977*8fb009dcSAndroid Build Coastguard Worker   expected.insert(expected.end(), ech_config2, ech_config2 + ech_config2_len);
1978*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(expected), Bytes(ech_config_list, ech_config_list_len));
1979*8fb009dcSAndroid Build Coastguard Worker }
1980*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ECHHasDuplicateConfigID)1981*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHHasDuplicateConfigID) {
1982*8fb009dcSAndroid Build Coastguard Worker   const struct {
1983*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> ids;
1984*8fb009dcSAndroid Build Coastguard Worker     bool has_duplicate;
1985*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
1986*8fb009dcSAndroid Build Coastguard Worker       {{}, false},
1987*8fb009dcSAndroid Build Coastguard Worker       {{1}, false},
1988*8fb009dcSAndroid Build Coastguard Worker       {{1, 2, 3, 255}, false},
1989*8fb009dcSAndroid Build Coastguard Worker       {{1, 2, 3, 1}, true},
1990*8fb009dcSAndroid Build Coastguard Worker   };
1991*8fb009dcSAndroid Build Coastguard Worker   for (const auto &test : kTests) {
1992*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
1993*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(keys);
1994*8fb009dcSAndroid Build Coastguard Worker     for (const uint8_t id : test.ids) {
1995*8fb009dcSAndroid Build Coastguard Worker       bssl::ScopedEVP_HPKE_KEY key;
1996*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(
1997*8fb009dcSAndroid Build Coastguard Worker           EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
1998*8fb009dcSAndroid Build Coastguard Worker       uint8_t *ech_config;
1999*8fb009dcSAndroid Build Coastguard Worker       size_t ech_config_len;
2000*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len, id,
2001*8fb009dcSAndroid Build Coastguard Worker                                          key.get(), "public.example", 16));
2002*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
2003*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2004*8fb009dcSAndroid Build Coastguard Worker                                    ech_config, ech_config_len, key.get()));
2005*8fb009dcSAndroid Build Coastguard Worker     }
2006*8fb009dcSAndroid Build Coastguard Worker 
2007*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(test.has_duplicate ? 1 : 0,
2008*8fb009dcSAndroid Build Coastguard Worker               SSL_ECH_KEYS_has_duplicate_config_id(keys.get()));
2009*8fb009dcSAndroid Build Coastguard Worker   }
2010*8fb009dcSAndroid Build Coastguard Worker }
2011*8fb009dcSAndroid Build Coastguard Worker 
2012*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_ECH_KEYS_add| checks consistency between the public and
2013*8fb009dcSAndroid Build Coastguard Worker // private key.
TEST(SSLTest,ECHKeyConsistency)2014*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHKeyConsistency) {
2015*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2016*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys);
2017*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key;
2018*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
2019*8fb009dcSAndroid Build Coastguard Worker   uint8_t public_key[EVP_HPKE_MAX_PUBLIC_KEY_LENGTH];
2020*8fb009dcSAndroid Build Coastguard Worker   size_t public_key_len;
2021*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_public_key(key.get(), public_key, &public_key_len,
2022*8fb009dcSAndroid Build Coastguard Worker                                       sizeof(public_key)));
2023*8fb009dcSAndroid Build Coastguard Worker 
2024*8fb009dcSAndroid Build Coastguard Worker   // Adding an ECHConfig with the matching public key succeeds.
2025*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams params;
2026*8fb009dcSAndroid Build Coastguard Worker   params.key = key.get();
2027*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> ech_config;
2028*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, params));
2029*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2030*8fb009dcSAndroid Build Coastguard Worker                                ech_config.data(), ech_config.size(),
2031*8fb009dcSAndroid Build Coastguard Worker                                key.get()));
2032*8fb009dcSAndroid Build Coastguard Worker 
2033*8fb009dcSAndroid Build Coastguard Worker   // Adding an ECHConfig with the wrong public key is an error.
2034*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY wrong_key;
2035*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
2036*8fb009dcSAndroid Build Coastguard Worker       EVP_HPKE_KEY_generate(wrong_key.get(), EVP_hpke_x25519_hkdf_sha256()));
2037*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2038*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(),
2039*8fb009dcSAndroid Build Coastguard Worker                                 wrong_key.get()));
2040*8fb009dcSAndroid Build Coastguard Worker 
2041*8fb009dcSAndroid Build Coastguard Worker   // Adding an ECHConfig with a truncated public key is an error.
2042*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams truncated;
2043*8fb009dcSAndroid Build Coastguard Worker   truncated.key = key.get();
2044*8fb009dcSAndroid Build Coastguard Worker   truncated.public_key.assign(public_key, public_key + public_key_len - 1);
2045*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, truncated));
2046*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2047*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(), key.get()));
2048*8fb009dcSAndroid Build Coastguard Worker 
2049*8fb009dcSAndroid Build Coastguard Worker   // Adding an ECHConfig with the right public key, but wrong KEM ID, is an
2050*8fb009dcSAndroid Build Coastguard Worker   // error.
2051*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams wrong_kem;
2052*8fb009dcSAndroid Build Coastguard Worker   wrong_kem.key = key.get();
2053*8fb009dcSAndroid Build Coastguard Worker   wrong_kem.kem_id = 0x0010;  // DHKEM(P-256, HKDF-SHA256)
2054*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, wrong_kem));
2055*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2056*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(),
2057*8fb009dcSAndroid Build Coastguard Worker                                 key.get()));
2058*8fb009dcSAndroid Build Coastguard Worker }
2059*8fb009dcSAndroid Build Coastguard Worker 
2060*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_CTX_set1_ech_keys| fails when the config list
2061*8fb009dcSAndroid Build Coastguard Worker // has no retry configs.
TEST(SSLTest,ECHServerConfigsWithoutRetryConfigs)2062*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHServerConfigsWithoutRetryConfigs) {
2063*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key;
2064*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
2065*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config;
2066*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config_len;
2067*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_marshal_ech_config(&ech_config, &ech_config_len,
2068*8fb009dcSAndroid Build Coastguard Worker                                      /*config_id=*/1, key.get(),
2069*8fb009dcSAndroid Build Coastguard Worker                                      "public.example", 16));
2070*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
2071*8fb009dcSAndroid Build Coastguard Worker 
2072*8fb009dcSAndroid Build Coastguard Worker   // Install a non-retry config.
2073*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2074*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys);
2075*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/0, ech_config,
2076*8fb009dcSAndroid Build Coastguard Worker                                ech_config_len, key.get()));
2077*8fb009dcSAndroid Build Coastguard Worker 
2078*8fb009dcSAndroid Build Coastguard Worker   // |keys| has no retry configs.
2079*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2080*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
2081*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
2082*8fb009dcSAndroid Build Coastguard Worker 
2083*8fb009dcSAndroid Build Coastguard Worker   // Add the same ECHConfig to the list, but this time mark it as a retry
2084*8fb009dcSAndroid Build Coastguard Worker   // config.
2085*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
2086*8fb009dcSAndroid Build Coastguard Worker                                ech_config_len, key.get()));
2087*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set1_ech_keys(ctx.get(), keys.get()));
2088*8fb009dcSAndroid Build Coastguard Worker }
2089*8fb009dcSAndroid Build Coastguard Worker 
2090*8fb009dcSAndroid Build Coastguard Worker // Test that the server APIs reject ECHConfigs with unsupported features.
TEST(SSLTest,UnsupportedECHConfig)2091*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, UnsupportedECHConfig) {
2092*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2093*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys);
2094*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key;
2095*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()));
2096*8fb009dcSAndroid Build Coastguard Worker 
2097*8fb009dcSAndroid Build Coastguard Worker   // Unsupported versions are rejected.
2098*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams unsupported_version;
2099*8fb009dcSAndroid Build Coastguard Worker   unsupported_version.version = 0xffff;
2100*8fb009dcSAndroid Build Coastguard Worker   unsupported_version.key = key.get();
2101*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> ech_config;
2102*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_version));
2103*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2104*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(),
2105*8fb009dcSAndroid Build Coastguard Worker                                 key.get()));
2106*8fb009dcSAndroid Build Coastguard Worker 
2107*8fb009dcSAndroid Build Coastguard Worker   // Unsupported cipher suites are rejected. (We only support HKDF-SHA256.)
2108*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams unsupported_kdf;
2109*8fb009dcSAndroid Build Coastguard Worker   unsupported_kdf.key = key.get();
2110*8fb009dcSAndroid Build Coastguard Worker   unsupported_kdf.cipher_suites = {0x002 /* HKDF-SHA384 */,
2111*8fb009dcSAndroid Build Coastguard Worker                                    EVP_HPKE_AES_128_GCM};
2112*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_kdf));
2113*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2114*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(),
2115*8fb009dcSAndroid Build Coastguard Worker                                 key.get()));
2116*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams unsupported_aead;
2117*8fb009dcSAndroid Build Coastguard Worker   unsupported_aead.key = key.get();
2118*8fb009dcSAndroid Build Coastguard Worker   unsupported_aead.cipher_suites = {EVP_HPKE_HKDF_SHA256, 0xffff};
2119*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, unsupported_aead));
2120*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2121*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(),
2122*8fb009dcSAndroid Build Coastguard Worker                                 key.get()));
2123*8fb009dcSAndroid Build Coastguard Worker 
2124*8fb009dcSAndroid Build Coastguard Worker 
2125*8fb009dcSAndroid Build Coastguard Worker   // Unsupported extensions are rejected.
2126*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams extensions;
2127*8fb009dcSAndroid Build Coastguard Worker   extensions.key = key.get();
2128*8fb009dcSAndroid Build Coastguard Worker   extensions.extensions = {0x00, 0x01, 0x00, 0x00};
2129*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, extensions));
2130*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2131*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(),
2132*8fb009dcSAndroid Build Coastguard Worker                                 key.get()));
2133*8fb009dcSAndroid Build Coastguard Worker 
2134*8fb009dcSAndroid Build Coastguard Worker   // Invalid public names are rejected.
2135*8fb009dcSAndroid Build Coastguard Worker   ECHConfigParams invalid_public_name;
2136*8fb009dcSAndroid Build Coastguard Worker   invalid_public_name.key = key.get();
2137*8fb009dcSAndroid Build Coastguard Worker   invalid_public_name.public_name = "dns_names_have_no_underscores.example";
2138*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(MakeECHConfig(&ech_config, invalid_public_name));
2139*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1,
2140*8fb009dcSAndroid Build Coastguard Worker                                 ech_config.data(), ech_config.size(),
2141*8fb009dcSAndroid Build Coastguard Worker                                 key.get()));
2142*8fb009dcSAndroid Build Coastguard Worker }
2143*8fb009dcSAndroid Build Coastguard Worker 
2144*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_get_client_random| reports the correct value on both client
2145*8fb009dcSAndroid Build Coastguard Worker // and server in ECH. The client sends two different random values. When ECH is
2146*8fb009dcSAndroid Build Coastguard Worker // accepted, we should report the inner one.
TEST(SSLTest,ECHClientRandomsMatch)2147*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHClientRandomsMatch) {
2148*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
2149*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
2150*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
2151*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
2152*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys);
2153*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys.get()));
2154*8fb009dcSAndroid Build Coastguard Worker 
2155*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2156*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
2157*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
2158*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2159*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx.get()));
2160*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
2161*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2162*8fb009dcSAndroid Build Coastguard Worker 
2163*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_ech_accepted(client.get()));
2164*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_ech_accepted(server.get()));
2165*8fb009dcSAndroid Build Coastguard Worker 
2166*8fb009dcSAndroid Build Coastguard Worker   // An ECH server will fairly naturally record the inner ClientHello random,
2167*8fb009dcSAndroid Build Coastguard Worker   // but an ECH client may forget to update the random once ClientHelloInner is
2168*8fb009dcSAndroid Build Coastguard Worker   // selected.
2169*8fb009dcSAndroid Build Coastguard Worker   uint8_t client_random1[SSL3_RANDOM_SIZE];
2170*8fb009dcSAndroid Build Coastguard Worker   uint8_t client_random2[SSL3_RANDOM_SIZE];
2171*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(client_random1),
2172*8fb009dcSAndroid Build Coastguard Worker             SSL_get_client_random(client.get(), client_random1,
2173*8fb009dcSAndroid Build Coastguard Worker                                   sizeof(client_random1)));
2174*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(client_random2),
2175*8fb009dcSAndroid Build Coastguard Worker             SSL_get_client_random(server.get(), client_random2,
2176*8fb009dcSAndroid Build Coastguard Worker                                   sizeof(client_random2)));
2177*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(client_random1), Bytes(client_random2));
2178*8fb009dcSAndroid Build Coastguard Worker }
2179*8fb009dcSAndroid Build Coastguard Worker 
2180*8fb009dcSAndroid Build Coastguard Worker // GetECHLength sets |*out_client_hello_len| and |*out_ech_len| to the lengths
2181*8fb009dcSAndroid Build Coastguard Worker // of the ClientHello and ECH extension, respectively, when a client created
2182*8fb009dcSAndroid Build Coastguard Worker // from |ctx| constructs a ClientHello with name |name| and an ECHConfig with
2183*8fb009dcSAndroid Build Coastguard Worker // maximum name length |max_name_len|.
GetECHLength(SSL_CTX * ctx,size_t * out_client_hello_len,size_t * out_ech_len,size_t max_name_len,const char * name)2184*8fb009dcSAndroid Build Coastguard Worker static bool GetECHLength(SSL_CTX *ctx, size_t *out_client_hello_len,
2185*8fb009dcSAndroid Build Coastguard Worker                          size_t *out_ech_len, size_t max_name_len,
2186*8fb009dcSAndroid Build Coastguard Worker                          const char *name) {
2187*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key;
2188*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config;
2189*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config_len;
2190*8fb009dcSAndroid Build Coastguard Worker   if (!EVP_HPKE_KEY_generate(key.get(), EVP_hpke_x25519_hkdf_sha256()) ||
2191*8fb009dcSAndroid Build Coastguard Worker       !SSL_marshal_ech_config(&ech_config, &ech_config_len,
2192*8fb009dcSAndroid Build Coastguard Worker                               /*config_id=*/1, key.get(), "public.example",
2193*8fb009dcSAndroid Build Coastguard Worker                               max_name_len)) {
2194*8fb009dcSAndroid Build Coastguard Worker     return false;
2195*8fb009dcSAndroid Build Coastguard Worker   }
2196*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config(ech_config);
2197*8fb009dcSAndroid Build Coastguard Worker 
2198*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys(SSL_ECH_KEYS_new());
2199*8fb009dcSAndroid Build Coastguard Worker   if (!keys || !SSL_ECH_KEYS_add(keys.get(), /*is_retry_config=*/1, ech_config,
2200*8fb009dcSAndroid Build Coastguard Worker                                  ech_config_len, key.get())) {
2201*8fb009dcSAndroid Build Coastguard Worker     return false;
2202*8fb009dcSAndroid Build Coastguard Worker   }
2203*8fb009dcSAndroid Build Coastguard Worker 
2204*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx));
2205*8fb009dcSAndroid Build Coastguard Worker   if (!ssl || !InstallECHConfigList(ssl.get(), keys.get()) ||
2206*8fb009dcSAndroid Build Coastguard Worker       (name != nullptr && !SSL_set_tlsext_host_name(ssl.get(), name))) {
2207*8fb009dcSAndroid Build Coastguard Worker     return false;
2208*8fb009dcSAndroid Build Coastguard Worker   }
2209*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(ssl.get());
2210*8fb009dcSAndroid Build Coastguard Worker 
2211*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> client_hello;
2212*8fb009dcSAndroid Build Coastguard Worker   SSL_CLIENT_HELLO parsed;
2213*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *unused;
2214*8fb009dcSAndroid Build Coastguard Worker   if (!GetClientHello(ssl.get(), &client_hello) ||
2215*8fb009dcSAndroid Build Coastguard Worker       !ssl_client_hello_init(
2216*8fb009dcSAndroid Build Coastguard Worker           ssl.get(), &parsed,
2217*8fb009dcSAndroid Build Coastguard Worker           // Skip record and handshake headers. This assumes the ClientHello
2218*8fb009dcSAndroid Build Coastguard Worker           // fits in one record.
2219*8fb009dcSAndroid Build Coastguard Worker           MakeConstSpan(client_hello)
2220*8fb009dcSAndroid Build Coastguard Worker               .subspan(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH)) ||
2221*8fb009dcSAndroid Build Coastguard Worker       !SSL_early_callback_ctx_extension_get(
2222*8fb009dcSAndroid Build Coastguard Worker           &parsed, TLSEXT_TYPE_encrypted_client_hello, &unused, out_ech_len)) {
2223*8fb009dcSAndroid Build Coastguard Worker     return false;
2224*8fb009dcSAndroid Build Coastguard Worker   }
2225*8fb009dcSAndroid Build Coastguard Worker   *out_client_hello_len = client_hello.size();
2226*8fb009dcSAndroid Build Coastguard Worker   return true;
2227*8fb009dcSAndroid Build Coastguard Worker }
2228*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ECHPadding)2229*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHPadding) {
2230*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2231*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
2232*8fb009dcSAndroid Build Coastguard Worker 
2233*8fb009dcSAndroid Build Coastguard Worker   // Sample lengths with max_name_len = 128 as baseline.
2234*8fb009dcSAndroid Build Coastguard Worker   size_t client_hello_len_baseline, ech_len_baseline;
2235*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline,
2236*8fb009dcSAndroid Build Coastguard Worker                            &ech_len_baseline, 128, "example.com"));
2237*8fb009dcSAndroid Build Coastguard Worker 
2238*8fb009dcSAndroid Build Coastguard Worker   // Check that all name lengths under the server's maximum look the same.
2239*8fb009dcSAndroid Build Coastguard Worker   for (size_t name_len : {1, 2, 32, 64, 127, 128}) {
2240*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(name_len);
2241*8fb009dcSAndroid Build Coastguard Worker     size_t client_hello_len, ech_len;
2242*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2243*8fb009dcSAndroid Build Coastguard Worker                              std::string(name_len, 'a').c_str()));
2244*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2245*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(ech_len, ech_len_baseline);
2246*8fb009dcSAndroid Build Coastguard Worker   }
2247*8fb009dcSAndroid Build Coastguard Worker 
2248*8fb009dcSAndroid Build Coastguard Worker   // When sending no SNI, we must still pad as if we are sending one.
2249*8fb009dcSAndroid Build Coastguard Worker   size_t client_hello_len, ech_len;
2250*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
2251*8fb009dcSAndroid Build Coastguard Worker       GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128, nullptr));
2252*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(client_hello_len, client_hello_len_baseline);
2253*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ech_len, ech_len_baseline);
2254*8fb009dcSAndroid Build Coastguard Worker 
2255*8fb009dcSAndroid Build Coastguard Worker   // Name lengths above the maximum do not get named-based padding, but the
2256*8fb009dcSAndroid Build Coastguard Worker   // overall input is padded to a multiple of 32.
2257*8fb009dcSAndroid Build Coastguard Worker   size_t client_hello_len_baseline2, ech_len_baseline2;
2258*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len_baseline2,
2259*8fb009dcSAndroid Build Coastguard Worker                            &ech_len_baseline2, 128,
2260*8fb009dcSAndroid Build Coastguard Worker                            std::string(128 + 32, 'a').c_str()));
2261*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ech_len_baseline2, ech_len_baseline + 32);
2262*8fb009dcSAndroid Build Coastguard Worker   // The ClientHello lengths may match if we are still under the threshold for
2263*8fb009dcSAndroid Build Coastguard Worker   // padding extension.
2264*8fb009dcSAndroid Build Coastguard Worker   EXPECT_GE(client_hello_len_baseline2, client_hello_len_baseline);
2265*8fb009dcSAndroid Build Coastguard Worker 
2266*8fb009dcSAndroid Build Coastguard Worker   for (size_t name_len = 128 + 1; name_len < 128 + 32; name_len++) {
2267*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(name_len);
2268*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(GetECHLength(ctx.get(), &client_hello_len, &ech_len, 128,
2269*8fb009dcSAndroid Build Coastguard Worker                              std::string(name_len, 'a').c_str()));
2270*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(ech_len == ech_len_baseline || ech_len == ech_len_baseline2)
2271*8fb009dcSAndroid Build Coastguard Worker         << ech_len;
2272*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(client_hello_len == client_hello_len_baseline ||
2273*8fb009dcSAndroid Build Coastguard Worker                 client_hello_len == client_hello_len_baseline2)
2274*8fb009dcSAndroid Build Coastguard Worker         << client_hello_len;
2275*8fb009dcSAndroid Build Coastguard Worker   }
2276*8fb009dcSAndroid Build Coastguard Worker }
2277*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ECHPublicName)2278*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHPublicName) {
2279*8fb009dcSAndroid Build Coastguard Worker   auto str_to_span = [](const char *str) -> Span<const uint8_t> {
2280*8fb009dcSAndroid Build Coastguard Worker     return MakeConstSpan(reinterpret_cast<const uint8_t *>(str), strlen(str));
2281*8fb009dcSAndroid Build Coastguard Worker   };
2282*8fb009dcSAndroid Build Coastguard Worker 
2283*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("")));
2284*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span("example.com")));
2285*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(".example.com")));
2286*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.com.")));
2287*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example..com")));
2288*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.-example.com")));
2289*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("www.example-.com")));
2290*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(
2291*8fb009dcSAndroid Build Coastguard Worker       ssl_is_valid_ech_public_name(str_to_span("no_underscores.example")));
2292*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(
2293*8fb009dcSAndroid Build Coastguard Worker       str_to_span("invalid_chars.\x01.example")));
2294*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(
2295*8fb009dcSAndroid Build Coastguard Worker       str_to_span("invalid_chars.\xff.example")));
2296*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kWithNUL[] = {'t', 'e', 's', 't', 0};
2297*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(kWithNUL));
2298*8fb009dcSAndroid Build Coastguard Worker 
2299*8fb009dcSAndroid Build Coastguard Worker   // Test an LDH label with every character and the maximum length.
2300*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ssl_is_valid_ech_public_name(str_to_span(
2301*8fb009dcSAndroid Build Coastguard Worker       "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789")));
2302*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span(
2303*8fb009dcSAndroid Build Coastguard Worker       "abcdefhijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ-01234567899")));
2304*8fb009dcSAndroid Build Coastguard Worker 
2305*8fb009dcSAndroid Build Coastguard Worker   // Inputs with trailing numeric components are rejected.
2306*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("127.0.0.1")));
2307*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.1")));
2308*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.01")));
2309*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.0x01")));
2310*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("example.0X01")));
2311*8fb009dcSAndroid Build Coastguard Worker   // Leading zeros and values that overflow |uint32_t| are still rejected.
2312*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(
2313*8fb009dcSAndroid Build Coastguard Worker       str_to_span("example.123456789000000000000000")));
2314*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(
2315*8fb009dcSAndroid Build Coastguard Worker       str_to_span("example.012345678900000000000000")));
2316*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(
2317*8fb009dcSAndroid Build Coastguard Worker       str_to_span("example.0x123456789abcdefABCDEF0")));
2318*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(
2319*8fb009dcSAndroid Build Coastguard Worker       str_to_span("example.0x0123456789abcdefABCDEF")));
2320*8fb009dcSAndroid Build Coastguard Worker   // Adding a non-digit or non-hex character makes it a valid DNS name again.
2321*8fb009dcSAndroid Build Coastguard Worker   // Single-component numbers are rejected.
2322*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ssl_is_valid_ech_public_name(
2323*8fb009dcSAndroid Build Coastguard Worker       str_to_span("example.1234567890a")));
2324*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ssl_is_valid_ech_public_name(
2325*8fb009dcSAndroid Build Coastguard Worker       str_to_span("example.01234567890a")));
2326*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ssl_is_valid_ech_public_name(
2327*8fb009dcSAndroid Build Coastguard Worker       str_to_span("example.0x123456789abcdefg")));
2328*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("1")));
2329*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("01")));
2330*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0x01")));
2331*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0X01")));
2332*8fb009dcSAndroid Build Coastguard Worker   // Numbers with trailing dots are rejected. (They are already rejected by the
2333*8fb009dcSAndroid Build Coastguard Worker   // LDH label rules, but the WHATWG URL parser additionally rejects them.)
2334*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("1.")));
2335*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("01.")));
2336*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0x01.")));
2337*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ssl_is_valid_ech_public_name(str_to_span("0X01.")));
2338*8fb009dcSAndroid Build Coastguard Worker }
2339*8fb009dcSAndroid Build Coastguard Worker 
2340*8fb009dcSAndroid Build Coastguard Worker // When using the built-in verifier, test that |SSL_get0_ech_name_override| is
2341*8fb009dcSAndroid Build Coastguard Worker // applied automatically.
TEST(SSLTest,ECHBuiltinVerifier)2342*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHBuiltinVerifier) {
2343*8fb009dcSAndroid Build Coastguard Worker   // These test certificates generated with the following Go program.
2344*8fb009dcSAndroid Build Coastguard Worker   /* clang-format off
2345*8fb009dcSAndroid Build Coastguard Worker func main() {
2346*8fb009dcSAndroid Build Coastguard Worker   notBefore := time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)
2347*8fb009dcSAndroid Build Coastguard Worker   notAfter := time.Date(2099, time.January, 1, 0, 0, 0, 0, time.UTC)
2348*8fb009dcSAndroid Build Coastguard Worker   rootKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
2349*8fb009dcSAndroid Build Coastguard Worker   rootTemplate := &x509.Certificate{
2350*8fb009dcSAndroid Build Coastguard Worker     SerialNumber:          big.NewInt(1),
2351*8fb009dcSAndroid Build Coastguard Worker     Subject:               pkix.Name{CommonName: "Test CA"},
2352*8fb009dcSAndroid Build Coastguard Worker     NotBefore:             notBefore,
2353*8fb009dcSAndroid Build Coastguard Worker     NotAfter:              notAfter,
2354*8fb009dcSAndroid Build Coastguard Worker     BasicConstraintsValid: true,
2355*8fb009dcSAndroid Build Coastguard Worker     IsCA:                  true,
2356*8fb009dcSAndroid Build Coastguard Worker   }
2357*8fb009dcSAndroid Build Coastguard Worker   rootDER, _ := x509.CreateCertificate(rand.Reader, rootTemplate, rootTemplate, &rootKey.PublicKey, rootKey)
2358*8fb009dcSAndroid Build Coastguard Worker   root, _ := x509.ParseCertificate(rootDER)
2359*8fb009dcSAndroid Build Coastguard Worker   pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: rootDER})
2360*8fb009dcSAndroid Build Coastguard Worker   leafKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
2361*8fb009dcSAndroid Build Coastguard Worker   leafKeyDER, _ := x509.MarshalPKCS8PrivateKey(leafKey)
2362*8fb009dcSAndroid Build Coastguard Worker   pem.Encode(os.Stdout, &pem.Block{Type: "PRIVATE KEY", Bytes: leafKeyDER})
2363*8fb009dcSAndroid Build Coastguard Worker   for i, name := range []string{"public.example", "secret.example"} {
2364*8fb009dcSAndroid Build Coastguard Worker     leafTemplate := &x509.Certificate{
2365*8fb009dcSAndroid Build Coastguard Worker       SerialNumber:          big.NewInt(int64(i) + 2),
2366*8fb009dcSAndroid Build Coastguard Worker       Subject:               pkix.Name{CommonName: name},
2367*8fb009dcSAndroid Build Coastguard Worker       NotBefore:             notBefore,
2368*8fb009dcSAndroid Build Coastguard Worker       NotAfter:              notAfter,
2369*8fb009dcSAndroid Build Coastguard Worker       BasicConstraintsValid: true,
2370*8fb009dcSAndroid Build Coastguard Worker       DNSNames:              []string{name},
2371*8fb009dcSAndroid Build Coastguard Worker     }
2372*8fb009dcSAndroid Build Coastguard Worker     leafDER, _ := x509.CreateCertificate(rand.Reader, leafTemplate, root, &leafKey.PublicKey, rootKey)
2373*8fb009dcSAndroid Build Coastguard Worker     pem.Encode(os.Stdout, &pem.Block{Type: "CERTIFICATE", Bytes: leafDER})
2374*8fb009dcSAndroid Build Coastguard Worker   }
2375*8fb009dcSAndroid Build Coastguard Worker }
2376*8fb009dcSAndroid Build Coastguard Worker clang-format on */
2377*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> root = CertFromPEM(R"(
2378*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
2379*8fb009dcSAndroid Build Coastguard Worker MIIBRzCB7aADAgECAgEBMAoGCCqGSM49BAMCMBIxEDAOBgNVBAMTB1Rlc3QgQ0Ew
2380*8fb009dcSAndroid Build Coastguard Worker IBcNMDAwMTAxMDAwMDAwWhgPMjA5OTAxMDEwMDAwMDBaMBIxEDAOBgNVBAMTB1Rl
2381*8fb009dcSAndroid Build Coastguard Worker c3QgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT5JUjrI1DAxSpEl88UkmJw
2382*8fb009dcSAndroid Build Coastguard Worker tAJqxo/YrSFo9V3MkcNkfTixi5p6MUtO8DazhEgekBcd2+tBAWtl7dy0qpvTqx92
2383*8fb009dcSAndroid Build Coastguard Worker ozIwMDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTw6ftkexAI6o4r5FntJIfL
2384*8fb009dcSAndroid Build Coastguard Worker GU5F4zAKBggqhkjOPQQDAgNJADBGAiEAiiNowddQeHZaZFIygwe6RW5/WG4sUXWC
2385*8fb009dcSAndroid Build Coastguard Worker dkyl9CQzRaYCIQCFS1EvwZbZtMny27fYm1eeYciY0TkJTEi34H1KwyzzIA==
2386*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
2387*8fb009dcSAndroid Build Coastguard Worker )");
2388*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(root);
2389*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> leaf_key = KeyFromPEM(R"(
2390*8fb009dcSAndroid Build Coastguard Worker -----BEGIN PRIVATE KEY-----
2391*8fb009dcSAndroid Build Coastguard Worker MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgj5WKHwHnziiyPauf
2392*8fb009dcSAndroid Build Coastguard Worker 7QukxTwtTyGZkk8qNdms4puJfxqhRANCAARNrkhxabALDlJrHtvkuDwvCWUF/oVC
2393*8fb009dcSAndroid Build Coastguard Worker hr6PDITHi1lDlJzvVT4aXBH87sH2n2UV5zpx13NHkq1bIC8eRT8eOIe0
2394*8fb009dcSAndroid Build Coastguard Worker -----END PRIVATE KEY-----
2395*8fb009dcSAndroid Build Coastguard Worker )");
2396*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf_key);
2397*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf_public = CertFromPEM(R"(
2398*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
2399*8fb009dcSAndroid Build Coastguard Worker MIIBaDCCAQ6gAwIBAgIBAjAKBggqhkjOPQQDAjASMRAwDgYDVQQDEwdUZXN0IENB
2400*8fb009dcSAndroid Build Coastguard Worker MCAXDTAwMDEwMTAwMDAwMFoYDzIwOTkwMTAxMDAwMDAwWjAZMRcwFQYDVQQDEw5w
2401*8fb009dcSAndroid Build Coastguard Worker dWJsaWMuZXhhbXBsZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE2uSHFpsAsO
2402*8fb009dcSAndroid Build Coastguard Worker Umse2+S4PC8JZQX+hUKGvo8MhMeLWUOUnO9VPhpcEfzuwfafZRXnOnHXc0eSrVsg
2403*8fb009dcSAndroid Build Coastguard Worker Lx5FPx44h7SjTDBKMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU8On7ZHsQCOqO
2404*8fb009dcSAndroid Build Coastguard Worker K+RZ7SSHyxlOReMwGQYDVR0RBBIwEIIOcHVibGljLmV4YW1wbGUwCgYIKoZIzj0E
2405*8fb009dcSAndroid Build Coastguard Worker AwIDSAAwRQIhANqZRhDR/+QL05hsWXMYEwaiHifd9iakKoFEhKFchcF3AiBRAeXw
2406*8fb009dcSAndroid Build Coastguard Worker wRGGT6+iPmTYM6N5/IDyAb5B9Ke38O6lLEsUwA==
2407*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
2408*8fb009dcSAndroid Build Coastguard Worker )");
2409*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf_public);
2410*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf_secret = CertFromPEM(R"(
2411*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
2412*8fb009dcSAndroid Build Coastguard Worker MIIBaTCCAQ6gAwIBAgIBAzAKBggqhkjOPQQDAjASMRAwDgYDVQQDEwdUZXN0IENB
2413*8fb009dcSAndroid Build Coastguard Worker MCAXDTAwMDEwMTAwMDAwMFoYDzIwOTkwMTAxMDAwMDAwWjAZMRcwFQYDVQQDEw5z
2414*8fb009dcSAndroid Build Coastguard Worker ZWNyZXQuZXhhbXBsZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE2uSHFpsAsO
2415*8fb009dcSAndroid Build Coastguard Worker Umse2+S4PC8JZQX+hUKGvo8MhMeLWUOUnO9VPhpcEfzuwfafZRXnOnHXc0eSrVsg
2416*8fb009dcSAndroid Build Coastguard Worker Lx5FPx44h7SjTDBKMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAU8On7ZHsQCOqO
2417*8fb009dcSAndroid Build Coastguard Worker K+RZ7SSHyxlOReMwGQYDVR0RBBIwEIIOc2VjcmV0LmV4YW1wbGUwCgYIKoZIzj0E
2418*8fb009dcSAndroid Build Coastguard Worker AwIDSQAwRgIhAPQdIz1xCFkc9WuSkxOxJDpywZiEp9SnKcxJ9nwrlRp3AiEA+O3+
2419*8fb009dcSAndroid Build Coastguard Worker XRqE7XFhHL+7TNC2a9OOAjQsEF137YPWo+rhgko=
2420*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
2421*8fb009dcSAndroid Build Coastguard Worker )");
2422*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf_secret);
2423*8fb009dcSAndroid Build Coastguard Worker 
2424*8fb009dcSAndroid Build Coastguard Worker   // Use different config IDs so that fuzzer mode, which breaks trial
2425*8fb009dcSAndroid Build Coastguard Worker   // decryption, will observe the key mismatch.
2426*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys(/*config_id=*/1);
2427*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys);
2428*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> wrong_keys = MakeTestECHKeys(/*config_id=*/2);
2429*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(wrong_keys);
2430*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
2431*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
2432*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
2433*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2434*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
2435*8fb009dcSAndroid Build Coastguard Worker 
2436*8fb009dcSAndroid Build Coastguard Worker   // Configure the client to verify certificates and expect the secret name.
2437*8fb009dcSAndroid Build Coastguard Worker   // This is the name the client is trying to connect to. If ECH is rejected,
2438*8fb009dcSAndroid Build Coastguard Worker   // BoringSSL will internally override this setting with the public name.
2439*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509_STORE> store(X509_STORE_new());
2440*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(store);
2441*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(X509_STORE_add_cert(store.get(), root.get()));
2442*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_store(client_ctx.get(), store.release());
2443*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(client_ctx.get(), SSL_VERIFY_PEER, nullptr);
2444*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()),
2445*8fb009dcSAndroid Build Coastguard Worker                               X509_V_FLAG_NO_CHECK_TIME);
2446*8fb009dcSAndroid Build Coastguard Worker   static const char kSecretName[] = "secret.example";
2447*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(X509_VERIFY_PARAM_set1_host(SSL_CTX_get0_param(client_ctx.get()),
2448*8fb009dcSAndroid Build Coastguard Worker                                           kSecretName, strlen(kSecretName)));
2449*8fb009dcSAndroid Build Coastguard Worker 
2450*8fb009dcSAndroid Build Coastguard Worker   // For simplicity, we only run through a pair of representative scenarios here
2451*8fb009dcSAndroid Build Coastguard Worker   // and rely on runner.go to verify that |SSL_get0_ech_name_override| behaves
2452*8fb009dcSAndroid Build Coastguard Worker   // correctly.
2453*8fb009dcSAndroid Build Coastguard Worker   for (bool accept_ech : {false, true}) {
2454*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(accept_ech);
2455*8fb009dcSAndroid Build Coastguard Worker     for (bool use_leaf_secret : {false, true}) {
2456*8fb009dcSAndroid Build Coastguard Worker       SCOPED_TRACE(use_leaf_secret);
2457*8fb009dcSAndroid Build Coastguard Worker 
2458*8fb009dcSAndroid Build Coastguard Worker       // The server will reject ECH when configured with the wrong keys.
2459*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_CTX_set1_ech_keys(
2460*8fb009dcSAndroid Build Coastguard Worker           server_ctx.get(), accept_ech ? keys.get() : wrong_keys.get()));
2461*8fb009dcSAndroid Build Coastguard Worker 
2462*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<SSL> client, server;
2463*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2464*8fb009dcSAndroid Build Coastguard Worker                                         server_ctx.get()));
2465*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(InstallECHConfigList(client.get(), keys.get()));
2466*8fb009dcSAndroid Build Coastguard Worker 
2467*8fb009dcSAndroid Build Coastguard Worker       // Configure the server with the selected certificate.
2468*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_use_certificate(server.get(), use_leaf_secret
2469*8fb009dcSAndroid Build Coastguard Worker                                                         ? leaf_secret.get()
2470*8fb009dcSAndroid Build Coastguard Worker                                                         : leaf_public.get()));
2471*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_use_PrivateKey(server.get(), leaf_key.get()));
2472*8fb009dcSAndroid Build Coastguard Worker 
2473*8fb009dcSAndroid Build Coastguard Worker       // The handshake may fail due to name mismatch or ECH reject. We check
2474*8fb009dcSAndroid Build Coastguard Worker       // |SSL_get_verify_result| to confirm the handshake got far enough.
2475*8fb009dcSAndroid Build Coastguard Worker       CompleteHandshakes(client.get(), server.get());
2476*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(accept_ech == use_leaf_secret ? X509_V_OK
2477*8fb009dcSAndroid Build Coastguard Worker                                               : X509_V_ERR_HOSTNAME_MISMATCH,
2478*8fb009dcSAndroid Build Coastguard Worker                 SSL_get_verify_result(client.get()));
2479*8fb009dcSAndroid Build Coastguard Worker     }
2480*8fb009dcSAndroid Build Coastguard Worker   }
2481*8fb009dcSAndroid Build Coastguard Worker }
2482*8fb009dcSAndroid Build Coastguard Worker 
2483*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_THREADS)
2484*8fb009dcSAndroid Build Coastguard Worker // Test that the server ECH config can be swapped out while the |SSL_CTX| is
2485*8fb009dcSAndroid Build Coastguard Worker // in use on other threads. This test is intended to be run with TSan.
TEST(SSLTest,ECHThreads)2486*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ECHThreads) {
2487*8fb009dcSAndroid Build Coastguard Worker   // Generate a pair of ECHConfigs.
2488*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key1;
2489*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_generate(key1.get(), EVP_hpke_x25519_hkdf_sha256()));
2490*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config1;
2491*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config1_len;
2492*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_marshal_ech_config(&ech_config1, &ech_config1_len,
2493*8fb009dcSAndroid Build Coastguard Worker                                      /*config_id=*/1, key1.get(),
2494*8fb009dcSAndroid Build Coastguard Worker                                      "public.example", 16));
2495*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config1(ech_config1);
2496*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_HPKE_KEY key2;
2497*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_HPKE_KEY_generate(key2.get(), EVP_hpke_x25519_hkdf_sha256()));
2498*8fb009dcSAndroid Build Coastguard Worker   uint8_t *ech_config2;
2499*8fb009dcSAndroid Build Coastguard Worker   size_t ech_config2_len;
2500*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_marshal_ech_config(&ech_config2, &ech_config2_len,
2501*8fb009dcSAndroid Build Coastguard Worker                                      /*config_id=*/2, key2.get(),
2502*8fb009dcSAndroid Build Coastguard Worker                                      "public.example", 16));
2503*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_ech_config2(ech_config2);
2504*8fb009dcSAndroid Build Coastguard Worker 
2505*8fb009dcSAndroid Build Coastguard Worker   // |keys1| contains the first config. |keys12| contains both.
2506*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys1(SSL_ECH_KEYS_new());
2507*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys1);
2508*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_add(keys1.get(), /*is_retry_config=*/1, ech_config1,
2509*8fb009dcSAndroid Build Coastguard Worker                                ech_config1_len, key1.get()));
2510*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys12(SSL_ECH_KEYS_new());
2511*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys12);
2512*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/1, ech_config2,
2513*8fb009dcSAndroid Build Coastguard Worker                                ech_config2_len, key2.get()));
2514*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_ECH_KEYS_add(keys12.get(), /*is_retry_config=*/0, ech_config1,
2515*8fb009dcSAndroid Build Coastguard Worker                                ech_config1_len, key1.get()));
2516*8fb009dcSAndroid Build Coastguard Worker 
2517*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
2518*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
2519*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
2520*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys1.get()));
2521*8fb009dcSAndroid Build Coastguard Worker 
2522*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2523*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
2524*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
2525*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2526*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx.get()));
2527*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(InstallECHConfigList(client.get(), keys1.get()));
2528*8fb009dcSAndroid Build Coastguard Worker 
2529*8fb009dcSAndroid Build Coastguard Worker   // In parallel, complete the connection and reconfigure the ECHConfig. Note
2530*8fb009dcSAndroid Build Coastguard Worker   // |keys12| supports all the keys in |keys1|, so the handshake should complete
2531*8fb009dcSAndroid Build Coastguard Worker   // the same whichever the server uses.
2532*8fb009dcSAndroid Build Coastguard Worker   std::vector<std::thread> threads;
2533*8fb009dcSAndroid Build Coastguard Worker   threads.emplace_back([&] {
2534*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
2535*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_ech_accepted(client.get()));
2536*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_ech_accepted(server.get()));
2537*8fb009dcSAndroid Build Coastguard Worker   });
2538*8fb009dcSAndroid Build Coastguard Worker   threads.emplace_back([&] {
2539*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_CTX_set1_ech_keys(server_ctx.get(), keys12.get()));
2540*8fb009dcSAndroid Build Coastguard Worker   });
2541*8fb009dcSAndroid Build Coastguard Worker   for (auto &thread : threads) {
2542*8fb009dcSAndroid Build Coastguard Worker     thread.join();
2543*8fb009dcSAndroid Build Coastguard Worker   }
2544*8fb009dcSAndroid Build Coastguard Worker }
2545*8fb009dcSAndroid Build Coastguard Worker #endif  // OPENSSL_THREADS
2546*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,TLS13ExporterAvailability)2547*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, TLS13ExporterAvailability) {
2548*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
2549*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
2550*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
2551*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
2552*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
2553*8fb009dcSAndroid Build Coastguard Worker   // Configure only TLS 1.3.
2554*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
2555*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
2556*8fb009dcSAndroid Build Coastguard Worker 
2557*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
2558*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
2559*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx.get()));
2560*8fb009dcSAndroid Build Coastguard Worker 
2561*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> buffer(32);
2562*8fb009dcSAndroid Build Coastguard Worker   const char *label = "EXPORTER-test-label";
2563*8fb009dcSAndroid Build Coastguard Worker 
2564*8fb009dcSAndroid Build Coastguard Worker   // The exporters are not available before the handshake starts.
2565*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(),
2566*8fb009dcSAndroid Build Coastguard Worker                                           buffer.size(), label, strlen(label),
2567*8fb009dcSAndroid Build Coastguard Worker                                           nullptr, 0, 0));
2568*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_export_keying_material(server.get(), buffer.data(),
2569*8fb009dcSAndroid Build Coastguard Worker                                           buffer.size(), label, strlen(label),
2570*8fb009dcSAndroid Build Coastguard Worker                                           nullptr, 0, 0));
2571*8fb009dcSAndroid Build Coastguard Worker 
2572*8fb009dcSAndroid Build Coastguard Worker   // Send the client's first flight of handshake messages.
2573*8fb009dcSAndroid Build Coastguard Worker   int client_ret = SSL_do_handshake(client.get());
2574*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(client.get(), client_ret), SSL_ERROR_WANT_READ);
2575*8fb009dcSAndroid Build Coastguard Worker 
2576*8fb009dcSAndroid Build Coastguard Worker   // The handshake isn't far enough for the exporters to work.
2577*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(),
2578*8fb009dcSAndroid Build Coastguard Worker                                           buffer.size(), label, strlen(label),
2579*8fb009dcSAndroid Build Coastguard Worker                                           nullptr, 0, 0));
2580*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_export_keying_material(server.get(), buffer.data(),
2581*8fb009dcSAndroid Build Coastguard Worker                                           buffer.size(), label, strlen(label),
2582*8fb009dcSAndroid Build Coastguard Worker                                           nullptr, 0, 0));
2583*8fb009dcSAndroid Build Coastguard Worker 
2584*8fb009dcSAndroid Build Coastguard Worker   // Send all the server's handshake messages.
2585*8fb009dcSAndroid Build Coastguard Worker   int server_ret = SSL_do_handshake(server.get());
2586*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(server.get(), server_ret), SSL_ERROR_WANT_READ);
2587*8fb009dcSAndroid Build Coastguard Worker 
2588*8fb009dcSAndroid Build Coastguard Worker   // At this point in the handshake, the server should have the exporter key
2589*8fb009dcSAndroid Build Coastguard Worker   // derived since it's sent its Finished message. The client hasn't yet
2590*8fb009dcSAndroid Build Coastguard Worker   // processed the server's handshake messages, so the exporter shouldn't be
2591*8fb009dcSAndroid Build Coastguard Worker   // available to the client.
2592*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_export_keying_material(client.get(), buffer.data(),
2593*8fb009dcSAndroid Build Coastguard Worker                                           buffer.size(), label, strlen(label),
2594*8fb009dcSAndroid Build Coastguard Worker                                           nullptr, 0, 0));
2595*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(),
2596*8fb009dcSAndroid Build Coastguard Worker                                          buffer.size(), label, strlen(label),
2597*8fb009dcSAndroid Build Coastguard Worker                                          nullptr, 0, 0));
2598*8fb009dcSAndroid Build Coastguard Worker 
2599*8fb009dcSAndroid Build Coastguard Worker   // Finish the handshake on the client.
2600*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_do_handshake(client.get()), 1);
2601*8fb009dcSAndroid Build Coastguard Worker 
2602*8fb009dcSAndroid Build Coastguard Worker   // The exporter should be available on both endpoints.
2603*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_export_keying_material(client.get(), buffer.data(),
2604*8fb009dcSAndroid Build Coastguard Worker                                          buffer.size(), label, strlen(label),
2605*8fb009dcSAndroid Build Coastguard Worker                                          nullptr, 0, 0));
2606*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(),
2607*8fb009dcSAndroid Build Coastguard Worker                                          buffer.size(), label, strlen(label),
2608*8fb009dcSAndroid Build Coastguard Worker                                          nullptr, 0, 0));
2609*8fb009dcSAndroid Build Coastguard Worker 
2610*8fb009dcSAndroid Build Coastguard Worker   // Finish the handshake on the server.
2611*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_do_handshake(server.get()), 1);
2612*8fb009dcSAndroid Build Coastguard Worker 
2613*8fb009dcSAndroid Build Coastguard Worker   // The exporter should still be available on both endpoints.
2614*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_export_keying_material(client.get(), buffer.data(),
2615*8fb009dcSAndroid Build Coastguard Worker                                          buffer.size(), label, strlen(label),
2616*8fb009dcSAndroid Build Coastguard Worker                                          nullptr, 0, 0));
2617*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_export_keying_material(server.get(), buffer.data(),
2618*8fb009dcSAndroid Build Coastguard Worker                                          buffer.size(), label, strlen(label),
2619*8fb009dcSAndroid Build Coastguard Worker                                          nullptr, 0, 0));
2620*8fb009dcSAndroid Build Coastguard Worker }
2621*8fb009dcSAndroid Build Coastguard Worker 
AppendSession(SSL_SESSION * session,void * arg)2622*8fb009dcSAndroid Build Coastguard Worker static void AppendSession(SSL_SESSION *session, void *arg) {
2623*8fb009dcSAndroid Build Coastguard Worker   std::vector<SSL_SESSION*> *out =
2624*8fb009dcSAndroid Build Coastguard Worker       reinterpret_cast<std::vector<SSL_SESSION*>*>(arg);
2625*8fb009dcSAndroid Build Coastguard Worker   out->push_back(session);
2626*8fb009dcSAndroid Build Coastguard Worker }
2627*8fb009dcSAndroid Build Coastguard Worker 
2628*8fb009dcSAndroid Build Coastguard Worker // CacheEquals returns true if |ctx|'s session cache consists of |expected|, in
2629*8fb009dcSAndroid Build Coastguard Worker // order.
CacheEquals(SSL_CTX * ctx,const std::vector<SSL_SESSION * > & expected)2630*8fb009dcSAndroid Build Coastguard Worker static bool CacheEquals(SSL_CTX *ctx,
2631*8fb009dcSAndroid Build Coastguard Worker                         const std::vector<SSL_SESSION*> &expected) {
2632*8fb009dcSAndroid Build Coastguard Worker   // Check the linked list.
2633*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *ptr = ctx->session_cache_head;
2634*8fb009dcSAndroid Build Coastguard Worker   for (SSL_SESSION *session : expected) {
2635*8fb009dcSAndroid Build Coastguard Worker     if (ptr != session) {
2636*8fb009dcSAndroid Build Coastguard Worker       return false;
2637*8fb009dcSAndroid Build Coastguard Worker     }
2638*8fb009dcSAndroid Build Coastguard Worker     // TODO(davidben): This is an absurd way to denote the end of the list.
2639*8fb009dcSAndroid Build Coastguard Worker     if (ptr->next ==
2640*8fb009dcSAndroid Build Coastguard Worker         reinterpret_cast<SSL_SESSION *>(&ctx->session_cache_tail)) {
2641*8fb009dcSAndroid Build Coastguard Worker       ptr = nullptr;
2642*8fb009dcSAndroid Build Coastguard Worker     } else {
2643*8fb009dcSAndroid Build Coastguard Worker       ptr = ptr->next;
2644*8fb009dcSAndroid Build Coastguard Worker     }
2645*8fb009dcSAndroid Build Coastguard Worker   }
2646*8fb009dcSAndroid Build Coastguard Worker   if (ptr != nullptr) {
2647*8fb009dcSAndroid Build Coastguard Worker     return false;
2648*8fb009dcSAndroid Build Coastguard Worker   }
2649*8fb009dcSAndroid Build Coastguard Worker 
2650*8fb009dcSAndroid Build Coastguard Worker   // Check the hash table.
2651*8fb009dcSAndroid Build Coastguard Worker   std::vector<SSL_SESSION*> actual, expected_copy;
2652*8fb009dcSAndroid Build Coastguard Worker   lh_SSL_SESSION_doall_arg(ctx->sessions, AppendSession, &actual);
2653*8fb009dcSAndroid Build Coastguard Worker   expected_copy = expected;
2654*8fb009dcSAndroid Build Coastguard Worker 
2655*8fb009dcSAndroid Build Coastguard Worker   std::sort(actual.begin(), actual.end());
2656*8fb009dcSAndroid Build Coastguard Worker   std::sort(expected_copy.begin(), expected_copy.end());
2657*8fb009dcSAndroid Build Coastguard Worker 
2658*8fb009dcSAndroid Build Coastguard Worker   return actual == expected_copy;
2659*8fb009dcSAndroid Build Coastguard Worker }
2660*8fb009dcSAndroid Build Coastguard Worker 
CreateTestSession(uint32_t number)2661*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<SSL_SESSION> CreateTestSession(uint32_t number) {
2662*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
2663*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_ctx) {
2664*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
2665*8fb009dcSAndroid Build Coastguard Worker   }
2666*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> ret(SSL_SESSION_new(ssl_ctx.get()));
2667*8fb009dcSAndroid Build Coastguard Worker   if (!ret) {
2668*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
2669*8fb009dcSAndroid Build Coastguard Worker   }
2670*8fb009dcSAndroid Build Coastguard Worker 
2671*8fb009dcSAndroid Build Coastguard Worker   uint8_t id[SSL3_SSL_SESSION_ID_LENGTH] = {0};
2672*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_memcpy(id, &number, sizeof(number));
2673*8fb009dcSAndroid Build Coastguard Worker   if (!SSL_SESSION_set1_id(ret.get(), id, sizeof(id))) {
2674*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
2675*8fb009dcSAndroid Build Coastguard Worker   }
2676*8fb009dcSAndroid Build Coastguard Worker   return ret;
2677*8fb009dcSAndroid Build Coastguard Worker }
2678*8fb009dcSAndroid Build Coastguard Worker 
2679*8fb009dcSAndroid Build Coastguard Worker // Test that the internal session cache behaves as expected.
TEST(SSLTest,InternalSessionCache)2680*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, InternalSessionCache) {
2681*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
2682*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
2683*8fb009dcSAndroid Build Coastguard Worker 
2684*8fb009dcSAndroid Build Coastguard Worker   // Prepare 10 test sessions.
2685*8fb009dcSAndroid Build Coastguard Worker   std::vector<bssl::UniquePtr<SSL_SESSION>> sessions;
2686*8fb009dcSAndroid Build Coastguard Worker   for (int i = 0; i < 10; i++) {
2687*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session = CreateTestSession(i);
2688*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session);
2689*8fb009dcSAndroid Build Coastguard Worker     sessions.push_back(std::move(session));
2690*8fb009dcSAndroid Build Coastguard Worker   }
2691*8fb009dcSAndroid Build Coastguard Worker 
2692*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_cache_size(ctx.get(), 5);
2693*8fb009dcSAndroid Build Coastguard Worker 
2694*8fb009dcSAndroid Build Coastguard Worker   // Insert all the test sessions.
2695*8fb009dcSAndroid Build Coastguard Worker   for (const auto &session : sessions) {
2696*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), session.get()));
2697*8fb009dcSAndroid Build Coastguard Worker   }
2698*8fb009dcSAndroid Build Coastguard Worker 
2699*8fb009dcSAndroid Build Coastguard Worker   // Only the last five should be in the list.
2700*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CacheEquals(
2701*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2702*8fb009dcSAndroid Build Coastguard Worker                   sessions[6].get(), sessions[5].get()}));
2703*8fb009dcSAndroid Build Coastguard Worker 
2704*8fb009dcSAndroid Build Coastguard Worker   // Inserting an element already in the cache should fail and leave the cache
2705*8fb009dcSAndroid Build Coastguard Worker   // unchanged.
2706*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_CTX_add_session(ctx.get(), sessions[7].get()));
2707*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CacheEquals(
2708*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), {sessions[9].get(), sessions[8].get(), sessions[7].get(),
2709*8fb009dcSAndroid Build Coastguard Worker                   sessions[6].get(), sessions[5].get()}));
2710*8fb009dcSAndroid Build Coastguard Worker 
2711*8fb009dcSAndroid Build Coastguard Worker   // Although collisions should be impossible (256-bit session IDs), the cache
2712*8fb009dcSAndroid Build Coastguard Worker   // must handle them gracefully.
2713*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> collision(CreateTestSession(7));
2714*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(collision);
2715*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_add_session(ctx.get(), collision.get()));
2716*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CacheEquals(
2717*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), {collision.get(), sessions[9].get(), sessions[8].get(),
2718*8fb009dcSAndroid Build Coastguard Worker                   sessions[6].get(), sessions[5].get()}));
2719*8fb009dcSAndroid Build Coastguard Worker 
2720*8fb009dcSAndroid Build Coastguard Worker   // Removing sessions behaves correctly.
2721*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_remove_session(ctx.get(), sessions[6].get()));
2722*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2723*8fb009dcSAndroid Build Coastguard Worker                                       sessions[8].get(), sessions[5].get()}));
2724*8fb009dcSAndroid Build Coastguard Worker 
2725*8fb009dcSAndroid Build Coastguard Worker   // Removing sessions requires an exact match.
2726*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[0].get()));
2727*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_CTX_remove_session(ctx.get(), sessions[7].get()));
2728*8fb009dcSAndroid Build Coastguard Worker 
2729*8fb009dcSAndroid Build Coastguard Worker   // The cache remains unchanged.
2730*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CacheEquals(ctx.get(), {collision.get(), sessions[9].get(),
2731*8fb009dcSAndroid Build Coastguard Worker                                       sessions[8].get(), sessions[5].get()}));
2732*8fb009dcSAndroid Build Coastguard Worker }
2733*8fb009dcSAndroid Build Coastguard Worker 
EpochFromSequence(uint64_t seq)2734*8fb009dcSAndroid Build Coastguard Worker static uint16_t EpochFromSequence(uint64_t seq) {
2735*8fb009dcSAndroid Build Coastguard Worker   return static_cast<uint16_t>(seq >> 48);
2736*8fb009dcSAndroid Build Coastguard Worker }
2737*8fb009dcSAndroid Build Coastguard Worker 
2738*8fb009dcSAndroid Build Coastguard Worker static const uint8_t kTestName[] = {
2739*8fb009dcSAndroid Build Coastguard Worker     0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
2740*8fb009dcSAndroid Build Coastguard Worker     0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
2741*8fb009dcSAndroid Build Coastguard Worker     0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
2742*8fb009dcSAndroid Build Coastguard Worker     0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
2743*8fb009dcSAndroid Build Coastguard Worker     0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
2744*8fb009dcSAndroid Build Coastguard Worker     0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64,
2745*8fb009dcSAndroid Build Coastguard Worker };
2746*8fb009dcSAndroid Build Coastguard Worker 
2747*8fb009dcSAndroid Build Coastguard Worker // SSLVersionTest executes its test cases under all available protocol versions.
2748*8fb009dcSAndroid Build Coastguard Worker // Test cases call |Connect| to create a connection using context objects with
2749*8fb009dcSAndroid Build Coastguard Worker // the protocol version fixed to the current version under test.
2750*8fb009dcSAndroid Build Coastguard Worker class SSLVersionTest : public ::testing::TestWithParam<VersionParam> {
2751*8fb009dcSAndroid Build Coastguard Worker  protected:
SSLVersionTest()2752*8fb009dcSAndroid Build Coastguard Worker   SSLVersionTest() : cert_(GetTestCertificate()), key_(GetTestKey()) {}
2753*8fb009dcSAndroid Build Coastguard Worker 
SetUp()2754*8fb009dcSAndroid Build Coastguard Worker   void SetUp() { ResetContexts(); }
2755*8fb009dcSAndroid Build Coastguard Worker 
CreateContext() const2756*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> CreateContext() const {
2757*8fb009dcSAndroid Build Coastguard Worker     const SSL_METHOD *method = is_dtls() ? DTLS_method() : TLS_method();
2758*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(method));
2759*8fb009dcSAndroid Build Coastguard Worker     if (!ctx || !SSL_CTX_set_min_proto_version(ctx.get(), version()) ||
2760*8fb009dcSAndroid Build Coastguard Worker         !SSL_CTX_set_max_proto_version(ctx.get(), version())) {
2761*8fb009dcSAndroid Build Coastguard Worker       return nullptr;
2762*8fb009dcSAndroid Build Coastguard Worker     }
2763*8fb009dcSAndroid Build Coastguard Worker     return ctx;
2764*8fb009dcSAndroid Build Coastguard Worker   }
2765*8fb009dcSAndroid Build Coastguard Worker 
ResetContexts()2766*8fb009dcSAndroid Build Coastguard Worker   void ResetContexts() {
2767*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(cert_);
2768*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(key_);
2769*8fb009dcSAndroid Build Coastguard Worker     client_ctx_ = CreateContext();
2770*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(client_ctx_);
2771*8fb009dcSAndroid Build Coastguard Worker     server_ctx_ = CreateContext();
2772*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx_);
2773*8fb009dcSAndroid Build Coastguard Worker     // Set up a server cert. Client certs can be set up explicitly.
2774*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
2775*8fb009dcSAndroid Build Coastguard Worker   }
2776*8fb009dcSAndroid Build Coastguard Worker 
UseCertAndKey(SSL_CTX * ctx) const2777*8fb009dcSAndroid Build Coastguard Worker   bool UseCertAndKey(SSL_CTX *ctx) const {
2778*8fb009dcSAndroid Build Coastguard Worker     return SSL_CTX_use_certificate(ctx, cert_.get()) &&
2779*8fb009dcSAndroid Build Coastguard Worker            SSL_CTX_use_PrivateKey(ctx, key_.get());
2780*8fb009dcSAndroid Build Coastguard Worker   }
2781*8fb009dcSAndroid Build Coastguard Worker 
Connect(const ClientConfig & config=ClientConfig ())2782*8fb009dcSAndroid Build Coastguard Worker   bool Connect(const ClientConfig &config = ClientConfig()) {
2783*8fb009dcSAndroid Build Coastguard Worker     return ConnectClientAndServer(&client_, &server_, client_ctx_.get(),
2784*8fb009dcSAndroid Build Coastguard Worker                                   server_ctx_.get(), config,
2785*8fb009dcSAndroid Build Coastguard Worker                                   shed_handshake_config_);
2786*8fb009dcSAndroid Build Coastguard Worker   }
2787*8fb009dcSAndroid Build Coastguard Worker 
version() const2788*8fb009dcSAndroid Build Coastguard Worker   uint16_t version() const { return GetParam().version; }
2789*8fb009dcSAndroid Build Coastguard Worker 
is_dtls() const2790*8fb009dcSAndroid Build Coastguard Worker   bool is_dtls() const {
2791*8fb009dcSAndroid Build Coastguard Worker     return GetParam().ssl_method == VersionParam::is_dtls;
2792*8fb009dcSAndroid Build Coastguard Worker   }
2793*8fb009dcSAndroid Build Coastguard Worker 
2794*8fb009dcSAndroid Build Coastguard Worker   bool shed_handshake_config_ = true;
2795*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client_, server_;
2796*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx_, client_ctx_;
2797*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert_;
2798*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key_;
2799*8fb009dcSAndroid Build Coastguard Worker };
2800*8fb009dcSAndroid Build Coastguard Worker 
2801*8fb009dcSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(WithVersion, SSLVersionTest,
2802*8fb009dcSAndroid Build Coastguard Worker                          testing::ValuesIn(kAllVersions),
__anon018734c60a02(const testing::TestParamInfo<VersionParam> &i) 2803*8fb009dcSAndroid Build Coastguard Worker                          [](const testing::TestParamInfo<VersionParam> &i) {
2804*8fb009dcSAndroid Build Coastguard Worker                            return i.param.name;
2805*8fb009dcSAndroid Build Coastguard Worker                          });
2806*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SequenceNumber)2807*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SequenceNumber) {
2808*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
2809*8fb009dcSAndroid Build Coastguard Worker 
2810*8fb009dcSAndroid Build Coastguard Worker   // Drain any post-handshake messages to ensure there are no unread records
2811*8fb009dcSAndroid Build Coastguard Worker   // on either end.
2812*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(FlushNewSessionTickets(client_.get(), server_.get()));
2813*8fb009dcSAndroid Build Coastguard Worker 
2814*8fb009dcSAndroid Build Coastguard Worker   uint64_t client_read_seq = SSL_get_read_sequence(client_.get());
2815*8fb009dcSAndroid Build Coastguard Worker   uint64_t client_write_seq = SSL_get_write_sequence(client_.get());
2816*8fb009dcSAndroid Build Coastguard Worker   uint64_t server_read_seq = SSL_get_read_sequence(server_.get());
2817*8fb009dcSAndroid Build Coastguard Worker   uint64_t server_write_seq = SSL_get_write_sequence(server_.get());
2818*8fb009dcSAndroid Build Coastguard Worker 
2819*8fb009dcSAndroid Build Coastguard Worker   if (is_dtls()) {
2820*8fb009dcSAndroid Build Coastguard Worker     // Both client and server must be at epoch 1.
2821*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(EpochFromSequence(client_read_seq), 1);
2822*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(EpochFromSequence(client_write_seq), 1);
2823*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(EpochFromSequence(server_read_seq), 1);
2824*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(EpochFromSequence(server_write_seq), 1);
2825*8fb009dcSAndroid Build Coastguard Worker 
2826*8fb009dcSAndroid Build Coastguard Worker     // The next record to be written should exceed the largest received.
2827*8fb009dcSAndroid Build Coastguard Worker     EXPECT_GT(client_write_seq, server_read_seq);
2828*8fb009dcSAndroid Build Coastguard Worker     EXPECT_GT(server_write_seq, client_read_seq);
2829*8fb009dcSAndroid Build Coastguard Worker   } else {
2830*8fb009dcSAndroid Build Coastguard Worker     // The next record to be written should equal the next to be received.
2831*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(client_write_seq, server_read_seq);
2832*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(server_write_seq, client_read_seq);
2833*8fb009dcSAndroid Build Coastguard Worker   }
2834*8fb009dcSAndroid Build Coastguard Worker 
2835*8fb009dcSAndroid Build Coastguard Worker   // Send a record from client to server.
2836*8fb009dcSAndroid Build Coastguard Worker   uint8_t byte = 0;
2837*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_write(client_.get(), &byte, 1), 1);
2838*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_read(server_.get(), &byte, 1), 1);
2839*8fb009dcSAndroid Build Coastguard Worker 
2840*8fb009dcSAndroid Build Coastguard Worker   // The client write and server read sequence numbers should have
2841*8fb009dcSAndroid Build Coastguard Worker   // incremented.
2842*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(client_write_seq + 1, SSL_get_write_sequence(client_.get()));
2843*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(server_read_seq + 1, SSL_get_read_sequence(server_.get()));
2844*8fb009dcSAndroid Build Coastguard Worker }
2845*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,OneSidedShutdown)2846*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, OneSidedShutdown) {
2847*8fb009dcSAndroid Build Coastguard Worker   // SSL_shutdown is a no-op in DTLS.
2848*8fb009dcSAndroid Build Coastguard Worker   if (is_dtls()) {
2849*8fb009dcSAndroid Build Coastguard Worker     return;
2850*8fb009dcSAndroid Build Coastguard Worker   }
2851*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
2852*8fb009dcSAndroid Build Coastguard Worker 
2853*8fb009dcSAndroid Build Coastguard Worker   // Shut down half the connection. |SSL_shutdown| will return 0 to signal only
2854*8fb009dcSAndroid Build Coastguard Worker   // one side has shut down.
2855*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_shutdown(client_.get()), 0);
2856*8fb009dcSAndroid Build Coastguard Worker 
2857*8fb009dcSAndroid Build Coastguard Worker   // Reading from the server should consume the EOF.
2858*8fb009dcSAndroid Build Coastguard Worker   uint8_t byte;
2859*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_read(server_.get(), &byte, 1), 0);
2860*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(server_.get(), 0), SSL_ERROR_ZERO_RETURN);
2861*8fb009dcSAndroid Build Coastguard Worker 
2862*8fb009dcSAndroid Build Coastguard Worker   // However, the server may continue to write data and then shut down the
2863*8fb009dcSAndroid Build Coastguard Worker   // connection.
2864*8fb009dcSAndroid Build Coastguard Worker   byte = 42;
2865*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_write(server_.get(), &byte, 1), 1);
2866*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_read(client_.get(), &byte, 1), 1);
2867*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(byte, 42);
2868*8fb009dcSAndroid Build Coastguard Worker 
2869*8fb009dcSAndroid Build Coastguard Worker   // The server may then shutdown the connection.
2870*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_shutdown(server_.get()), 1);
2871*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_shutdown(client_.get()), 1);
2872*8fb009dcSAndroid Build Coastguard Worker }
2873*8fb009dcSAndroid Build Coastguard Worker 
2874*8fb009dcSAndroid Build Coastguard Worker // Test that, after calling |SSL_shutdown|, |SSL_write| fails.
TEST_P(SSLVersionTest,WriteAfterShutdown)2875*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, WriteAfterShutdown) {
2876*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
2877*8fb009dcSAndroid Build Coastguard Worker 
2878*8fb009dcSAndroid Build Coastguard Worker   for (SSL *ssl : {client_.get(), server_.get()}) {
2879*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(SSL_is_server(ssl) ? "server" : "client");
2880*8fb009dcSAndroid Build Coastguard Worker 
2881*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2882*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(mem);
2883*8fb009dcSAndroid Build Coastguard Worker     SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2884*8fb009dcSAndroid Build Coastguard Worker 
2885*8fb009dcSAndroid Build Coastguard Worker     // Shut down half the connection. |SSL_shutdown| will return 0 to signal
2886*8fb009dcSAndroid Build Coastguard Worker     // only one side has shut down.
2887*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_shutdown(ssl), 0);
2888*8fb009dcSAndroid Build Coastguard Worker 
2889*8fb009dcSAndroid Build Coastguard Worker     // |ssl| should have written an alert to the transport.
2890*8fb009dcSAndroid Build Coastguard Worker     const uint8_t *unused;
2891*8fb009dcSAndroid Build Coastguard Worker     size_t len;
2892*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2893*8fb009dcSAndroid Build Coastguard Worker     EXPECT_NE(0u, len);
2894*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(BIO_reset(mem.get()));
2895*8fb009dcSAndroid Build Coastguard Worker 
2896*8fb009dcSAndroid Build Coastguard Worker     // Writing should fail.
2897*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2898*8fb009dcSAndroid Build Coastguard Worker 
2899*8fb009dcSAndroid Build Coastguard Worker     // Nothing should be written to the transport.
2900*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2901*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(0u, len);
2902*8fb009dcSAndroid Build Coastguard Worker   }
2903*8fb009dcSAndroid Build Coastguard Worker }
2904*8fb009dcSAndroid Build Coastguard Worker 
2905*8fb009dcSAndroid Build Coastguard Worker // Test that, after sending a fatal alert in a failed |SSL_read|, |SSL_write|
2906*8fb009dcSAndroid Build Coastguard Worker // fails.
TEST_P(SSLVersionTest,WriteAfterReadSentFatalAlert)2907*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, WriteAfterReadSentFatalAlert) {
2908*8fb009dcSAndroid Build Coastguard Worker   // Decryption failures are not fatal in DTLS.
2909*8fb009dcSAndroid Build Coastguard Worker   if (is_dtls()) {
2910*8fb009dcSAndroid Build Coastguard Worker     return;
2911*8fb009dcSAndroid Build Coastguard Worker   }
2912*8fb009dcSAndroid Build Coastguard Worker 
2913*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
2914*8fb009dcSAndroid Build Coastguard Worker 
2915*8fb009dcSAndroid Build Coastguard Worker   // Save the write |BIO|s as the test will overwrite them.
2916*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> client_wbio = bssl::UpRef(SSL_get_wbio(client_.get()));
2917*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> server_wbio = bssl::UpRef(SSL_get_wbio(server_.get()));
2918*8fb009dcSAndroid Build Coastguard Worker 
2919*8fb009dcSAndroid Build Coastguard Worker   for (bool test_server : {false, true}) {
2920*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(test_server ? "server" : "client");
2921*8fb009dcSAndroid Build Coastguard Worker     SSL *ssl = test_server ? server_.get() : client_.get();
2922*8fb009dcSAndroid Build Coastguard Worker     BIO *other_wbio = test_server ? client_wbio.get() : server_wbio.get();
2923*8fb009dcSAndroid Build Coastguard Worker 
2924*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2925*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(mem);
2926*8fb009dcSAndroid Build Coastguard Worker     SSL_set0_wbio(ssl, bssl::UpRef(mem).release());
2927*8fb009dcSAndroid Build Coastguard Worker 
2928*8fb009dcSAndroid Build Coastguard Worker     // Read an invalid record from the peer.
2929*8fb009dcSAndroid Build Coastguard Worker     static const uint8_t kInvalidRecord[] = "invalid record";
2930*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(int{sizeof(kInvalidRecord)},
2931*8fb009dcSAndroid Build Coastguard Worker               BIO_write(other_wbio, kInvalidRecord, sizeof(kInvalidRecord)));
2932*8fb009dcSAndroid Build Coastguard Worker     char buf[256];
2933*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(-1, SSL_read(ssl, buf, sizeof(buf)));
2934*8fb009dcSAndroid Build Coastguard Worker 
2935*8fb009dcSAndroid Build Coastguard Worker     // |ssl| should have written an alert to the transport.
2936*8fb009dcSAndroid Build Coastguard Worker     const uint8_t *unused;
2937*8fb009dcSAndroid Build Coastguard Worker     size_t len;
2938*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2939*8fb009dcSAndroid Build Coastguard Worker     EXPECT_NE(0u, len);
2940*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(BIO_reset(mem.get()));
2941*8fb009dcSAndroid Build Coastguard Worker 
2942*8fb009dcSAndroid Build Coastguard Worker     // Writing should fail.
2943*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(-1, SSL_write(ssl, "a", 1));
2944*8fb009dcSAndroid Build Coastguard Worker 
2945*8fb009dcSAndroid Build Coastguard Worker     // Nothing should be written to the transport.
2946*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
2947*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(0u, len);
2948*8fb009dcSAndroid Build Coastguard Worker   }
2949*8fb009dcSAndroid Build Coastguard Worker }
2950*8fb009dcSAndroid Build Coastguard Worker 
2951*8fb009dcSAndroid Build Coastguard Worker // Test that, after sending a fatal alert from the handshake, |SSL_write| fails.
TEST_P(SSLVersionTest,WriteAfterHandshakeSentFatalAlert)2952*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, WriteAfterHandshakeSentFatalAlert) {
2953*8fb009dcSAndroid Build Coastguard Worker   for (bool test_server : {false, true}) {
2954*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(test_server ? "server" : "client");
2955*8fb009dcSAndroid Build Coastguard Worker 
2956*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> ssl(
2957*8fb009dcSAndroid Build Coastguard Worker         SSL_new(test_server ? server_ctx_.get() : client_ctx_.get()));
2958*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ssl);
2959*8fb009dcSAndroid Build Coastguard Worker     if (test_server) {
2960*8fb009dcSAndroid Build Coastguard Worker       SSL_set_accept_state(ssl.get());
2961*8fb009dcSAndroid Build Coastguard Worker     } else {
2962*8fb009dcSAndroid Build Coastguard Worker       SSL_set_connect_state(ssl.get());
2963*8fb009dcSAndroid Build Coastguard Worker     }
2964*8fb009dcSAndroid Build Coastguard Worker 
2965*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> invalid;
2966*8fb009dcSAndroid Build Coastguard Worker     if (is_dtls()) {
2967*8fb009dcSAndroid Build Coastguard Worker       // In DTLS, invalid records are discarded. To cause the handshake to fail,
2968*8fb009dcSAndroid Build Coastguard Worker       // use a valid handshake record with invalid contents.
2969*8fb009dcSAndroid Build Coastguard Worker       invalid.push_back(SSL3_RT_HANDSHAKE);
2970*8fb009dcSAndroid Build Coastguard Worker       invalid.push_back(DTLS1_VERSION >> 8);
2971*8fb009dcSAndroid Build Coastguard Worker       invalid.push_back(DTLS1_VERSION & 0xff);
2972*8fb009dcSAndroid Build Coastguard Worker       // epoch and sequence_number
2973*8fb009dcSAndroid Build Coastguard Worker       for (int i = 0; i < 8; i++) {
2974*8fb009dcSAndroid Build Coastguard Worker         invalid.push_back(0);
2975*8fb009dcSAndroid Build Coastguard Worker       }
2976*8fb009dcSAndroid Build Coastguard Worker       // A one-byte fragment is invalid.
2977*8fb009dcSAndroid Build Coastguard Worker       invalid.push_back(0);
2978*8fb009dcSAndroid Build Coastguard Worker       invalid.push_back(1);
2979*8fb009dcSAndroid Build Coastguard Worker       // Arbitrary contents.
2980*8fb009dcSAndroid Build Coastguard Worker       invalid.push_back(0);
2981*8fb009dcSAndroid Build Coastguard Worker     } else {
2982*8fb009dcSAndroid Build Coastguard Worker       invalid = {'i', 'n', 'v', 'a', 'l', 'i', 'd'};
2983*8fb009dcSAndroid Build Coastguard Worker     }
2984*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<BIO> rbio(
2985*8fb009dcSAndroid Build Coastguard Worker         BIO_new_mem_buf(invalid.data(), invalid.size()));
2986*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(rbio);
2987*8fb009dcSAndroid Build Coastguard Worker     SSL_set0_rbio(ssl.get(), rbio.release());
2988*8fb009dcSAndroid Build Coastguard Worker 
2989*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
2990*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(mem);
2991*8fb009dcSAndroid Build Coastguard Worker     SSL_set0_wbio(ssl.get(), bssl::UpRef(mem).release());
2992*8fb009dcSAndroid Build Coastguard Worker 
2993*8fb009dcSAndroid Build Coastguard Worker     // The handshake should fail.
2994*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(-1, SSL_do_handshake(ssl.get()));
2995*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
2996*8fb009dcSAndroid Build Coastguard Worker     uint32_t err = ERR_get_error();
2997*8fb009dcSAndroid Build Coastguard Worker 
2998*8fb009dcSAndroid Build Coastguard Worker     // |ssl| should have written an alert (and, in the client's case, a
2999*8fb009dcSAndroid Build Coastguard Worker     // ClientHello) to the transport.
3000*8fb009dcSAndroid Build Coastguard Worker     const uint8_t *unused;
3001*8fb009dcSAndroid Build Coastguard Worker     size_t len;
3002*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
3003*8fb009dcSAndroid Build Coastguard Worker     EXPECT_NE(0u, len);
3004*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(BIO_reset(mem.get()));
3005*8fb009dcSAndroid Build Coastguard Worker 
3006*8fb009dcSAndroid Build Coastguard Worker     // Writing should fail, with the same error as the handshake.
3007*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(-1, SSL_write(ssl.get(), "a", 1));
3008*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), -1));
3009*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(err, ERR_get_error());
3010*8fb009dcSAndroid Build Coastguard Worker 
3011*8fb009dcSAndroid Build Coastguard Worker     // Nothing should be written to the transport.
3012*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
3013*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(0u, len);
3014*8fb009dcSAndroid Build Coastguard Worker   }
3015*8fb009dcSAndroid Build Coastguard Worker }
3016*8fb009dcSAndroid Build Coastguard Worker 
3017*8fb009dcSAndroid Build Coastguard Worker // Test that, after seeing TLS 1.2 in response to early data, |SSL_write|
3018*8fb009dcSAndroid Build Coastguard Worker // continues to report |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. See
3019*8fb009dcSAndroid Build Coastguard Worker // https://crbug.com/1078515.
TEST(SSLTest,WriteAfterWrongVersionOnEarlyData)3020*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, WriteAfterWrongVersionOnEarlyData) {
3021*8fb009dcSAndroid Build Coastguard Worker   // Set up some 0-RTT-enabled contexts.
3022*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3023*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
3024*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
3025*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
3026*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
3027*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
3028*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
3029*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
3030*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
3031*8fb009dcSAndroid Build Coastguard Worker 
3032*8fb009dcSAndroid Build Coastguard Worker   // Get an early-data-capable session.
3033*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
3034*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx.get(), server_ctx.get());
3035*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
3036*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_SESSION_early_data_capable(session.get()));
3037*8fb009dcSAndroid Build Coastguard Worker 
3038*8fb009dcSAndroid Build Coastguard Worker   // Offer the session to the server, but now the server speaks TLS 1.2.
3039*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
3040*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
3041*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx.get()));
3042*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client.get(), session.get());
3043*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_max_proto_version(server.get(), TLS1_2_VERSION));
3044*8fb009dcSAndroid Build Coastguard Worker 
3045*8fb009dcSAndroid Build Coastguard Worker   // The client handshake initially succeeds in the early data state.
3046*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, SSL_do_handshake(client.get()));
3047*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(client.get()));
3048*8fb009dcSAndroid Build Coastguard Worker 
3049*8fb009dcSAndroid Build Coastguard Worker   // The server processes the ClientHello and negotiates TLS 1.2.
3050*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(-1, SSL_do_handshake(server.get()));
3051*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server.get(), -1));
3052*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(TLS1_2_VERSION, SSL_version(server.get()));
3053*8fb009dcSAndroid Build Coastguard Worker 
3054*8fb009dcSAndroid Build Coastguard Worker   // Capture the client's output.
3055*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> mem(BIO_new(BIO_s_mem()));
3056*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(mem);
3057*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_wbio(client.get(), bssl::UpRef(mem).release());
3058*8fb009dcSAndroid Build Coastguard Worker 
3059*8fb009dcSAndroid Build Coastguard Worker   // The client processes the ServerHello and fails.
3060*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(-1, SSL_do_handshake(client.get()));
3061*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
3062*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_SSL,
3063*8fb009dcSAndroid Build Coastguard Worker                           SSL_R_WRONG_VERSION_ON_EARLY_DATA));
3064*8fb009dcSAndroid Build Coastguard Worker 
3065*8fb009dcSAndroid Build Coastguard Worker   // The client should have written an alert to the transport.
3066*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *unused;
3067*8fb009dcSAndroid Build Coastguard Worker   size_t len;
3068*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
3069*8fb009dcSAndroid Build Coastguard Worker   EXPECT_NE(0u, len);
3070*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(BIO_reset(mem.get()));
3071*8fb009dcSAndroid Build Coastguard Worker 
3072*8fb009dcSAndroid Build Coastguard Worker   // Writing should fail, with the same error as the handshake.
3073*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(-1, SSL_write(client.get(), "a", 1));
3074*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(client.get(), -1));
3075*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ErrorEquals(ERR_get_error(), ERR_LIB_SSL,
3076*8fb009dcSAndroid Build Coastguard Worker                           SSL_R_WRONG_VERSION_ON_EARLY_DATA));
3077*8fb009dcSAndroid Build Coastguard Worker 
3078*8fb009dcSAndroid Build Coastguard Worker   // Nothing should be written to the transport.
3079*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_mem_contents(mem.get(), &unused, &len));
3080*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0u, len);
3081*8fb009dcSAndroid Build Coastguard Worker }
3082*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SessionDuplication)3083*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SessionDuplication) {
3084*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3085*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
3086*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
3087*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
3088*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
3089*8fb009dcSAndroid Build Coastguard Worker 
3090*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
3091*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3092*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
3093*8fb009dcSAndroid Build Coastguard Worker 
3094*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *session0 = SSL_get_session(client.get());
3095*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session1 =
3096*8fb009dcSAndroid Build Coastguard Worker       bssl::SSL_SESSION_dup(session0, SSL_SESSION_DUP_ALL);
3097*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session1);
3098*8fb009dcSAndroid Build Coastguard Worker 
3099*8fb009dcSAndroid Build Coastguard Worker   session1->not_resumable = false;
3100*8fb009dcSAndroid Build Coastguard Worker 
3101*8fb009dcSAndroid Build Coastguard Worker   uint8_t *s0_bytes, *s1_bytes;
3102*8fb009dcSAndroid Build Coastguard Worker   size_t s0_len, s1_len;
3103*8fb009dcSAndroid Build Coastguard Worker 
3104*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_SESSION_to_bytes(session0, &s0_bytes, &s0_len));
3105*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_s0(s0_bytes);
3106*8fb009dcSAndroid Build Coastguard Worker 
3107*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_SESSION_to_bytes(session1.get(), &s1_bytes, &s1_len));
3108*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_s1(s1_bytes);
3109*8fb009dcSAndroid Build Coastguard Worker 
3110*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(s0_bytes, s0_len), Bytes(s1_bytes, s1_len));
3111*8fb009dcSAndroid Build Coastguard Worker }
3112*8fb009dcSAndroid Build Coastguard Worker 
ExpectFDs(const SSL * ssl,int rfd,int wfd)3113*8fb009dcSAndroid Build Coastguard Worker static void ExpectFDs(const SSL *ssl, int rfd, int wfd) {
3114*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(rfd, SSL_get_fd(ssl));
3115*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(rfd, SSL_get_rfd(ssl));
3116*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(wfd, SSL_get_wfd(ssl));
3117*8fb009dcSAndroid Build Coastguard Worker 
3118*8fb009dcSAndroid Build Coastguard Worker   // The wrapper BIOs are always equal when fds are equal, even if set
3119*8fb009dcSAndroid Build Coastguard Worker   // individually.
3120*8fb009dcSAndroid Build Coastguard Worker   if (rfd == wfd) {
3121*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_get_rbio(ssl), SSL_get_wbio(ssl));
3122*8fb009dcSAndroid Build Coastguard Worker   }
3123*8fb009dcSAndroid Build Coastguard Worker }
3124*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SetFD)3125*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SetFD) {
3126*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3127*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
3128*8fb009dcSAndroid Build Coastguard Worker 
3129*8fb009dcSAndroid Build Coastguard Worker   // Test setting different read and write FDs.
3130*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3131*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3132*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3133*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
3134*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 1, 2);
3135*8fb009dcSAndroid Build Coastguard Worker 
3136*8fb009dcSAndroid Build Coastguard Worker   // Test setting the same FD.
3137*8fb009dcSAndroid Build Coastguard Worker   ssl.reset(SSL_new(ctx.get()));
3138*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3139*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3140*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 1, 1);
3141*8fb009dcSAndroid Build Coastguard Worker 
3142*8fb009dcSAndroid Build Coastguard Worker   // Test setting the same FD one side at a time.
3143*8fb009dcSAndroid Build Coastguard Worker   ssl.reset(SSL_new(ctx.get()));
3144*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3145*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3146*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
3147*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 1, 1);
3148*8fb009dcSAndroid Build Coastguard Worker 
3149*8fb009dcSAndroid Build Coastguard Worker   // Test setting the same FD in the other order.
3150*8fb009dcSAndroid Build Coastguard Worker   ssl.reset(SSL_new(ctx.get()));
3151*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3152*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
3153*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3154*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 1, 1);
3155*8fb009dcSAndroid Build Coastguard Worker 
3156*8fb009dcSAndroid Build Coastguard Worker   // Test changing the read FD partway through.
3157*8fb009dcSAndroid Build Coastguard Worker   ssl.reset(SSL_new(ctx.get()));
3158*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3159*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3160*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_rfd(ssl.get(), 2));
3161*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 2, 1);
3162*8fb009dcSAndroid Build Coastguard Worker 
3163*8fb009dcSAndroid Build Coastguard Worker   // Test changing the write FD partway through.
3164*8fb009dcSAndroid Build Coastguard Worker   ssl.reset(SSL_new(ctx.get()));
3165*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3166*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3167*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_wfd(ssl.get(), 2));
3168*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 1, 2);
3169*8fb009dcSAndroid Build Coastguard Worker 
3170*8fb009dcSAndroid Build Coastguard Worker   // Test a no-op change to the read FD partway through.
3171*8fb009dcSAndroid Build Coastguard Worker   ssl.reset(SSL_new(ctx.get()));
3172*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3173*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3174*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_rfd(ssl.get(), 1));
3175*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 1, 1);
3176*8fb009dcSAndroid Build Coastguard Worker 
3177*8fb009dcSAndroid Build Coastguard Worker   // Test a no-op change to the write FD partway through.
3178*8fb009dcSAndroid Build Coastguard Worker   ssl.reset(SSL_new(ctx.get()));
3179*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3180*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_fd(ssl.get(), 1));
3181*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_set_wfd(ssl.get(), 1));
3182*8fb009dcSAndroid Build Coastguard Worker   ExpectFDs(ssl.get(), 1, 1);
3183*8fb009dcSAndroid Build Coastguard Worker 
3184*8fb009dcSAndroid Build Coastguard Worker   // ASan builds will implicitly test that the internal |BIO| reference-counting
3185*8fb009dcSAndroid Build Coastguard Worker   // is correct.
3186*8fb009dcSAndroid Build Coastguard Worker }
3187*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SetBIO)3188*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SetBIO) {
3189*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3190*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
3191*8fb009dcSAndroid Build Coastguard Worker 
3192*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3193*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> bio1(BIO_new(BIO_s_mem())), bio2(BIO_new(BIO_s_mem())),
3194*8fb009dcSAndroid Build Coastguard Worker       bio3(BIO_new(BIO_s_mem()));
3195*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
3196*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bio1);
3197*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bio2);
3198*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bio3);
3199*8fb009dcSAndroid Build Coastguard Worker 
3200*8fb009dcSAndroid Build Coastguard Worker   // SSL_set_bio takes one reference when the parameters are the same.
3201*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio1.get());
3202*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
3203*8fb009dcSAndroid Build Coastguard Worker 
3204*8fb009dcSAndroid Build Coastguard Worker   // Repeating the call does nothing.
3205*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
3206*8fb009dcSAndroid Build Coastguard Worker 
3207*8fb009dcSAndroid Build Coastguard Worker   // It takes one reference each when the parameters are different.
3208*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio2.get());
3209*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio3.get());
3210*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
3211*8fb009dcSAndroid Build Coastguard Worker 
3212*8fb009dcSAndroid Build Coastguard Worker   // Repeating the call does nothing.
3213*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio2.get(), bio3.get());
3214*8fb009dcSAndroid Build Coastguard Worker 
3215*8fb009dcSAndroid Build Coastguard Worker   // It takes one reference when changing only wbio.
3216*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio1.get());
3217*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
3218*8fb009dcSAndroid Build Coastguard Worker 
3219*8fb009dcSAndroid Build Coastguard Worker   // It takes one reference when changing only rbio and the two are different.
3220*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio3.get());
3221*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
3222*8fb009dcSAndroid Build Coastguard Worker 
3223*8fb009dcSAndroid Build Coastguard Worker   // If setting wbio to rbio, it takes no additional references.
3224*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio3.get(), bio3.get());
3225*8fb009dcSAndroid Build Coastguard Worker 
3226*8fb009dcSAndroid Build Coastguard Worker   // From there, wbio may be switched to something else.
3227*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio1.get());
3228*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio3.get(), bio1.get());
3229*8fb009dcSAndroid Build Coastguard Worker 
3230*8fb009dcSAndroid Build Coastguard Worker   // If setting rbio to wbio, it takes no additional references.
3231*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio1.get(), bio1.get());
3232*8fb009dcSAndroid Build Coastguard Worker 
3233*8fb009dcSAndroid Build Coastguard Worker   // From there, rbio may be switched to something else, but, for historical
3234*8fb009dcSAndroid Build Coastguard Worker   // reasons, it takes a reference to both parameters.
3235*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio1.get());
3236*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(bio2.get());
3237*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(ssl.get(), bio2.get(), bio1.get());
3238*8fb009dcSAndroid Build Coastguard Worker 
3239*8fb009dcSAndroid Build Coastguard Worker   // ASAN builds will implicitly test that the internal |BIO| reference-counting
3240*8fb009dcSAndroid Build Coastguard Worker   // is correct.
3241*8fb009dcSAndroid Build Coastguard Worker }
3242*8fb009dcSAndroid Build Coastguard Worker 
VerifySucceed(X509_STORE_CTX * store_ctx,void * arg)3243*8fb009dcSAndroid Build Coastguard Worker static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) { return 1; }
3244*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,GetPeerCertificate)3245*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, GetPeerCertificate) {
3246*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3247*8fb009dcSAndroid Build Coastguard Worker 
3248*8fb009dcSAndroid Build Coastguard Worker   // Configure both client and server to accept any certificate.
3249*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(client_ctx_.get(),
3250*8fb009dcSAndroid Build Coastguard Worker                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3251*8fb009dcSAndroid Build Coastguard Worker                      nullptr);
3252*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3253*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(server_ctx_.get(),
3254*8fb009dcSAndroid Build Coastguard Worker                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3255*8fb009dcSAndroid Build Coastguard Worker                      nullptr);
3256*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
3257*8fb009dcSAndroid Build Coastguard Worker 
3258*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
3259*8fb009dcSAndroid Build Coastguard Worker 
3260*8fb009dcSAndroid Build Coastguard Worker   // Client and server should both see the leaf certificate.
3261*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3262*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(peer);
3263*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
3264*8fb009dcSAndroid Build Coastguard Worker 
3265*8fb009dcSAndroid Build Coastguard Worker   peer.reset(SSL_get_peer_certificate(client_.get()));
3266*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(peer);
3267*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(X509_cmp(cert_.get(), peer.get()), 0);
3268*8fb009dcSAndroid Build Coastguard Worker 
3269*8fb009dcSAndroid Build Coastguard Worker   // However, for historical reasons, the X509 chain includes the leaf on the
3270*8fb009dcSAndroid Build Coastguard Worker   // client, but does not on the server.
3271*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(client_.get())), 1u);
3272*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(client_.get())),
3273*8fb009dcSAndroid Build Coastguard Worker             1u);
3274*8fb009dcSAndroid Build Coastguard Worker 
3275*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(sk_X509_num(SSL_get_peer_cert_chain(server_.get())), 0u);
3276*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(sk_CRYPTO_BUFFER_num(SSL_get0_peer_certificates(server_.get())),
3277*8fb009dcSAndroid Build Coastguard Worker             1u);
3278*8fb009dcSAndroid Build Coastguard Worker }
3279*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,NoPeerCertificate)3280*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, NoPeerCertificate) {
3281*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
3282*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
3283*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3284*8fb009dcSAndroid Build Coastguard Worker 
3285*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
3286*8fb009dcSAndroid Build Coastguard Worker 
3287*8fb009dcSAndroid Build Coastguard Worker   // Server should not see a peer certificate.
3288*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3289*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(peer);
3290*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_get0_peer_certificates(server_.get()));
3291*8fb009dcSAndroid Build Coastguard Worker }
3292*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,RetainOnlySHA256OfCerts)3293*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, RetainOnlySHA256OfCerts) {
3294*8fb009dcSAndroid Build Coastguard Worker   uint8_t *cert_der = NULL;
3295*8fb009dcSAndroid Build Coastguard Worker   int cert_der_len = i2d_X509(cert_.get(), &cert_der);
3296*8fb009dcSAndroid Build Coastguard Worker   ASSERT_GE(cert_der_len, 0);
3297*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_cert_der(cert_der);
3298*8fb009dcSAndroid Build Coastguard Worker 
3299*8fb009dcSAndroid Build Coastguard Worker   uint8_t cert_sha256[SHA256_DIGEST_LENGTH];
3300*8fb009dcSAndroid Build Coastguard Worker   SHA256(cert_der, cert_der_len, cert_sha256);
3301*8fb009dcSAndroid Build Coastguard Worker 
3302*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
3303*8fb009dcSAndroid Build Coastguard Worker 
3304*8fb009dcSAndroid Build Coastguard Worker   // Configure both client and server to accept any certificate, but the
3305*8fb009dcSAndroid Build Coastguard Worker   // server must retain only the SHA-256 of the peer.
3306*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(client_ctx_.get(),
3307*8fb009dcSAndroid Build Coastguard Worker                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3308*8fb009dcSAndroid Build Coastguard Worker                      nullptr);
3309*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(server_ctx_.get(),
3310*8fb009dcSAndroid Build Coastguard Worker                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
3311*8fb009dcSAndroid Build Coastguard Worker                      nullptr);
3312*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
3313*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
3314*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_retain_only_sha256_of_client_certs(server_ctx_.get(), 1);
3315*8fb009dcSAndroid Build Coastguard Worker 
3316*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
3317*8fb009dcSAndroid Build Coastguard Worker 
3318*8fb009dcSAndroid Build Coastguard Worker   // The peer certificate has been dropped.
3319*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(server_.get()));
3320*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(peer);
3321*8fb009dcSAndroid Build Coastguard Worker 
3322*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION *session = SSL_get_session(server_.get());
3323*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_SESSION_has_peer_sha256(session));
3324*8fb009dcSAndroid Build Coastguard Worker 
3325*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *peer_sha256;
3326*8fb009dcSAndroid Build Coastguard Worker   size_t peer_sha256_len;
3327*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION_get0_peer_sha256(session, &peer_sha256, &peer_sha256_len);
3328*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(cert_sha256), Bytes(peer_sha256, peer_sha256_len));
3329*8fb009dcSAndroid Build Coastguard Worker }
3330*8fb009dcSAndroid Build Coastguard Worker 
3331*8fb009dcSAndroid Build Coastguard Worker // Tests that our ClientHellos do not change unexpectedly. These are purely
3332*8fb009dcSAndroid Build Coastguard Worker // change detection tests. If they fail as part of an intentional ClientHello
3333*8fb009dcSAndroid Build Coastguard Worker // change, update the test vector.
TEST(SSLTest,ClientHello)3334*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ClientHello) {
3335*8fb009dcSAndroid Build Coastguard Worker   struct {
3336*8fb009dcSAndroid Build Coastguard Worker     uint16_t max_version;
3337*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> expected;
3338*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
3339*8fb009dcSAndroid Build Coastguard Worker       {TLS1_VERSION,
3340*8fb009dcSAndroid Build Coastguard Worker        {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x01, 0x00,
3341*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3342*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3343*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09,
3344*8fb009dcSAndroid Build Coastguard Worker         0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00,
3345*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
3346*8fb009dcSAndroid Build Coastguard Worker         0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
3347*8fb009dcSAndroid Build Coastguard Worker         0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
3348*8fb009dcSAndroid Build Coastguard Worker       {TLS1_1_VERSION,
3349*8fb009dcSAndroid Build Coastguard Worker        {0x16, 0x03, 0x01, 0x00, 0x58, 0x01, 0x00, 0x00, 0x54, 0x03, 0x02, 0x00,
3350*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3351*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3352*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc0, 0x09,
3353*8fb009dcSAndroid Build Coastguard Worker         0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00,
3354*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x1f, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
3355*8fb009dcSAndroid Build Coastguard Worker         0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
3356*8fb009dcSAndroid Build Coastguard Worker         0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00}},
3357*8fb009dcSAndroid Build Coastguard Worker       {TLS1_2_VERSION,
3358*8fb009dcSAndroid Build Coastguard Worker        {0x16, 0x03, 0x01, 0x00, 0x80, 0x01, 0x00, 0x00, 0x7c, 0x03, 0x03, 0x00,
3359*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3360*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3361*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xcc, 0xa9,
3362*8fb009dcSAndroid Build Coastguard Worker         0xcc, 0xa8, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xc0, 0x09,
3363*8fb009dcSAndroid Build Coastguard Worker         0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f,
3364*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x35, 0x01, 0x00, 0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01,
3365*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00,
3366*8fb009dcSAndroid Build Coastguard Worker         0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00,
3367*8fb009dcSAndroid Build Coastguard Worker         0x00, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04,
3368*8fb009dcSAndroid Build Coastguard Worker         0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02,
3369*8fb009dcSAndroid Build Coastguard Worker         0x01}},
3370*8fb009dcSAndroid Build Coastguard Worker       // TODO(davidben): Add a change detector for TLS 1.3 once the spec and our
3371*8fb009dcSAndroid Build Coastguard Worker       // implementation has settled enough that it won't change.
3372*8fb009dcSAndroid Build Coastguard Worker   };
3373*8fb009dcSAndroid Build Coastguard Worker 
3374*8fb009dcSAndroid Build Coastguard Worker   for (const auto &t : kTests) {
3375*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(t.max_version);
3376*8fb009dcSAndroid Build Coastguard Worker 
3377*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3378*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ctx);
3379*8fb009dcSAndroid Build Coastguard Worker     // Our default cipher list varies by CPU capabilities, so manually place the
3380*8fb009dcSAndroid Build Coastguard Worker     // ChaCha20 ciphers in front.
3381*8fb009dcSAndroid Build Coastguard Worker     const char *cipher_list = "CHACHA20:ALL";
3382*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3383*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), t.max_version));
3384*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(ctx.get(), cipher_list));
3385*8fb009dcSAndroid Build Coastguard Worker 
3386*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
3387*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ssl);
3388*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> client_hello;
3389*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(GetClientHello(ssl.get(), &client_hello));
3390*8fb009dcSAndroid Build Coastguard Worker 
3391*8fb009dcSAndroid Build Coastguard Worker     // Zero the client_random.
3392*8fb009dcSAndroid Build Coastguard Worker     constexpr size_t kRandomOffset = 1 + 2 + 2 +  // record header
3393*8fb009dcSAndroid Build Coastguard Worker                                      1 + 3 +      // handshake message header
3394*8fb009dcSAndroid Build Coastguard Worker                                      2;           // client_version
3395*8fb009dcSAndroid Build Coastguard Worker     ASSERT_GE(client_hello.size(), kRandomOffset + SSL3_RANDOM_SIZE);
3396*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_memset(client_hello.data() + kRandomOffset, 0, SSL3_RANDOM_SIZE);
3397*8fb009dcSAndroid Build Coastguard Worker 
3398*8fb009dcSAndroid Build Coastguard Worker     if (client_hello != t.expected) {
3399*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "ClientHellos did not match.";
3400*8fb009dcSAndroid Build Coastguard Worker       // Print the value manually so it is easier to update the test vector.
3401*8fb009dcSAndroid Build Coastguard Worker       for (size_t i = 0; i < client_hello.size(); i += 12) {
3402*8fb009dcSAndroid Build Coastguard Worker         printf("     %c", i == 0 ? '{' : ' ');
3403*8fb009dcSAndroid Build Coastguard Worker         for (size_t j = i; j < client_hello.size() && j < i + 12; j++) {
3404*8fb009dcSAndroid Build Coastguard Worker           if (j > i) {
3405*8fb009dcSAndroid Build Coastguard Worker             printf(" ");
3406*8fb009dcSAndroid Build Coastguard Worker           }
3407*8fb009dcSAndroid Build Coastguard Worker           printf("0x%02x", client_hello[j]);
3408*8fb009dcSAndroid Build Coastguard Worker           if (j < client_hello.size() - 1) {
3409*8fb009dcSAndroid Build Coastguard Worker             printf(",");
3410*8fb009dcSAndroid Build Coastguard Worker           }
3411*8fb009dcSAndroid Build Coastguard Worker         }
3412*8fb009dcSAndroid Build Coastguard Worker         if (i + 12 >= client_hello.size()) {
3413*8fb009dcSAndroid Build Coastguard Worker           printf("}},");
3414*8fb009dcSAndroid Build Coastguard Worker         }
3415*8fb009dcSAndroid Build Coastguard Worker         printf("\n");
3416*8fb009dcSAndroid Build Coastguard Worker       }
3417*8fb009dcSAndroid Build Coastguard Worker     }
3418*8fb009dcSAndroid Build Coastguard Worker   }
3419*8fb009dcSAndroid Build Coastguard Worker }
3420*8fb009dcSAndroid Build Coastguard Worker 
ExpectSessionReused(SSL_CTX * client_ctx,SSL_CTX * server_ctx,SSL_SESSION * session,bool want_reused)3421*8fb009dcSAndroid Build Coastguard Worker static void ExpectSessionReused(SSL_CTX *client_ctx, SSL_CTX *server_ctx,
3422*8fb009dcSAndroid Build Coastguard Worker                                 SSL_SESSION *session, bool want_reused) {
3423*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
3424*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
3425*8fb009dcSAndroid Build Coastguard Worker   config.session = session;
3426*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
3427*8fb009dcSAndroid Build Coastguard Worker       ConnectClientAndServer(&client, &server, client_ctx, server_ctx, config));
3428*8fb009dcSAndroid Build Coastguard Worker 
3429*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_session_reused(client.get()), SSL_session_reused(server.get()));
3430*8fb009dcSAndroid Build Coastguard Worker 
3431*8fb009dcSAndroid Build Coastguard Worker   bool was_reused = !!SSL_session_reused(client.get());
3432*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(was_reused, want_reused);
3433*8fb009dcSAndroid Build Coastguard Worker }
3434*8fb009dcSAndroid Build Coastguard Worker 
ExpectSessionRenewed(SSL_CTX * client_ctx,SSL_CTX * server_ctx,SSL_SESSION * session)3435*8fb009dcSAndroid Build Coastguard Worker static bssl::UniquePtr<SSL_SESSION> ExpectSessionRenewed(SSL_CTX *client_ctx,
3436*8fb009dcSAndroid Build Coastguard Worker                                                          SSL_CTX *server_ctx,
3437*8fb009dcSAndroid Build Coastguard Worker                                                          SSL_SESSION *session) {
3438*8fb009dcSAndroid Build Coastguard Worker   g_last_session = nullptr;
3439*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx, SaveLastSession);
3440*8fb009dcSAndroid Build Coastguard Worker 
3441*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
3442*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
3443*8fb009dcSAndroid Build Coastguard Worker   config.session = session;
3444*8fb009dcSAndroid Build Coastguard Worker   if (!ConnectClientAndServer(&client, &server, client_ctx, server_ctx,
3445*8fb009dcSAndroid Build Coastguard Worker                               config) ||
3446*8fb009dcSAndroid Build Coastguard Worker       !FlushNewSessionTickets(client.get(), server.get())) {
3447*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Failed to connect client and server.\n");
3448*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
3449*8fb009dcSAndroid Build Coastguard Worker   }
3450*8fb009dcSAndroid Build Coastguard Worker 
3451*8fb009dcSAndroid Build Coastguard Worker   if (SSL_session_reused(client.get()) != SSL_session_reused(server.get())) {
3452*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Client and server were inconsistent.\n");
3453*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
3454*8fb009dcSAndroid Build Coastguard Worker   }
3455*8fb009dcSAndroid Build Coastguard Worker 
3456*8fb009dcSAndroid Build Coastguard Worker   if (!SSL_session_reused(client.get())) {
3457*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Session was not reused.\n");
3458*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
3459*8fb009dcSAndroid Build Coastguard Worker   }
3460*8fb009dcSAndroid Build Coastguard Worker 
3461*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx, nullptr);
3462*8fb009dcSAndroid Build Coastguard Worker 
3463*8fb009dcSAndroid Build Coastguard Worker   if (!g_last_session) {
3464*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Client did not receive a renewed session.\n");
3465*8fb009dcSAndroid Build Coastguard Worker     return nullptr;
3466*8fb009dcSAndroid Build Coastguard Worker   }
3467*8fb009dcSAndroid Build Coastguard Worker   return std::move(g_last_session);
3468*8fb009dcSAndroid Build Coastguard Worker }
3469*8fb009dcSAndroid Build Coastguard Worker 
ExpectTicketKeyChanged(SSL_CTX * ctx,uint8_t * inout_key,bool changed)3470*8fb009dcSAndroid Build Coastguard Worker static void ExpectTicketKeyChanged(SSL_CTX *ctx, uint8_t *inout_key,
3471*8fb009dcSAndroid Build Coastguard Worker                                    bool changed) {
3472*8fb009dcSAndroid Build Coastguard Worker   uint8_t new_key[kTicketKeyLen];
3473*8fb009dcSAndroid Build Coastguard Worker   // May return 0, 1 or 48.
3474*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_CTX_get_tlsext_ticket_keys(ctx, new_key, kTicketKeyLen), 1);
3475*8fb009dcSAndroid Build Coastguard Worker   if (changed) {
3476*8fb009dcSAndroid Build Coastguard Worker     ASSERT_NE(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
3477*8fb009dcSAndroid Build Coastguard Worker   } else {
3478*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(Bytes(inout_key, kTicketKeyLen), Bytes(new_key));
3479*8fb009dcSAndroid Build Coastguard Worker   }
3480*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_memcpy(inout_key, new_key, kTicketKeyLen);
3481*8fb009dcSAndroid Build Coastguard Worker }
3482*8fb009dcSAndroid Build Coastguard Worker 
SwitchSessionIDContextSNI(SSL * ssl,int * out_alert,void * arg)3483*8fb009dcSAndroid Build Coastguard Worker static int SwitchSessionIDContextSNI(SSL *ssl, int *out_alert, void *arg) {
3484*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kContext[] = {3};
3485*8fb009dcSAndroid Build Coastguard Worker 
3486*8fb009dcSAndroid Build Coastguard Worker   if (!SSL_set_session_id_context(ssl, kContext, sizeof(kContext))) {
3487*8fb009dcSAndroid Build Coastguard Worker     return SSL_TLSEXT_ERR_ALERT_FATAL;
3488*8fb009dcSAndroid Build Coastguard Worker   }
3489*8fb009dcSAndroid Build Coastguard Worker 
3490*8fb009dcSAndroid Build Coastguard Worker   return SSL_TLSEXT_ERR_OK;
3491*8fb009dcSAndroid Build Coastguard Worker }
3492*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SessionIDContext)3493*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SessionIDContext) {
3494*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kContext1[] = {1};
3495*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kContext2[] = {2};
3496*8fb009dcSAndroid Build Coastguard Worker 
3497*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3498*8fb009dcSAndroid Build Coastguard Worker                                              sizeof(kContext1)));
3499*8fb009dcSAndroid Build Coastguard Worker 
3500*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3501*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3502*8fb009dcSAndroid Build Coastguard Worker 
3503*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
3504*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
3505*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
3506*8fb009dcSAndroid Build Coastguard Worker 
3507*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3508*8fb009dcSAndroid Build Coastguard Worker                                   session.get(),
3509*8fb009dcSAndroid Build Coastguard Worker                                   true /* expect session reused */));
3510*8fb009dcSAndroid Build Coastguard Worker 
3511*8fb009dcSAndroid Build Coastguard Worker   // Change the session ID context.
3512*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext2,
3513*8fb009dcSAndroid Build Coastguard Worker                                              sizeof(kContext2)));
3514*8fb009dcSAndroid Build Coastguard Worker 
3515*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3516*8fb009dcSAndroid Build Coastguard Worker                                   session.get(),
3517*8fb009dcSAndroid Build Coastguard Worker                                   false /* expect session not reused */));
3518*8fb009dcSAndroid Build Coastguard Worker 
3519*8fb009dcSAndroid Build Coastguard Worker   // Change the session ID context back and install an SNI callback to switch
3520*8fb009dcSAndroid Build Coastguard Worker   // it.
3521*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_session_id_context(server_ctx_.get(), kContext1,
3522*8fb009dcSAndroid Build Coastguard Worker                                              sizeof(kContext1)));
3523*8fb009dcSAndroid Build Coastguard Worker 
3524*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(),
3525*8fb009dcSAndroid Build Coastguard Worker                                          SwitchSessionIDContextSNI);
3526*8fb009dcSAndroid Build Coastguard Worker 
3527*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3528*8fb009dcSAndroid Build Coastguard Worker                                   session.get(),
3529*8fb009dcSAndroid Build Coastguard Worker                                   false /* expect session not reused */));
3530*8fb009dcSAndroid Build Coastguard Worker 
3531*8fb009dcSAndroid Build Coastguard Worker   // Switch the session ID context with the early callback instead.
3532*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), nullptr);
3533*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_select_certificate_cb(
3534*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(),
3535*8fb009dcSAndroid Build Coastguard Worker       [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
3536*8fb009dcSAndroid Build Coastguard Worker         static const uint8_t kContext[] = {3};
3537*8fb009dcSAndroid Build Coastguard Worker 
3538*8fb009dcSAndroid Build Coastguard Worker         if (!SSL_set_session_id_context(client_hello->ssl, kContext,
3539*8fb009dcSAndroid Build Coastguard Worker                                         sizeof(kContext))) {
3540*8fb009dcSAndroid Build Coastguard Worker           return ssl_select_cert_error;
3541*8fb009dcSAndroid Build Coastguard Worker         }
3542*8fb009dcSAndroid Build Coastguard Worker 
3543*8fb009dcSAndroid Build Coastguard Worker         return ssl_select_cert_success;
3544*8fb009dcSAndroid Build Coastguard Worker       });
3545*8fb009dcSAndroid Build Coastguard Worker 
3546*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3547*8fb009dcSAndroid Build Coastguard Worker                                   session.get(),
3548*8fb009dcSAndroid Build Coastguard Worker                                   false /* expect session not reused */));
3549*8fb009dcSAndroid Build Coastguard Worker }
3550*8fb009dcSAndroid Build Coastguard Worker 
3551*8fb009dcSAndroid Build Coastguard Worker static timeval g_current_time;
3552*8fb009dcSAndroid Build Coastguard Worker 
CurrentTimeCallback(const SSL * ssl,timeval * out_clock)3553*8fb009dcSAndroid Build Coastguard Worker static void CurrentTimeCallback(const SSL *ssl, timeval *out_clock) {
3554*8fb009dcSAndroid Build Coastguard Worker   *out_clock = g_current_time;
3555*8fb009dcSAndroid Build Coastguard Worker }
3556*8fb009dcSAndroid Build Coastguard Worker 
FrozenTimeCallback(const SSL * ssl,timeval * out_clock)3557*8fb009dcSAndroid Build Coastguard Worker static void FrozenTimeCallback(const SSL *ssl, timeval *out_clock) {
3558*8fb009dcSAndroid Build Coastguard Worker   out_clock->tv_sec = 1000;
3559*8fb009dcSAndroid Build Coastguard Worker   out_clock->tv_usec = 0;
3560*8fb009dcSAndroid Build Coastguard Worker }
3561*8fb009dcSAndroid Build Coastguard Worker 
RenewTicketCallback(SSL * ssl,uint8_t * key_name,uint8_t * iv,EVP_CIPHER_CTX * ctx,HMAC_CTX * hmac_ctx,int encrypt)3562*8fb009dcSAndroid Build Coastguard Worker static int RenewTicketCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
3563*8fb009dcSAndroid Build Coastguard Worker                                EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
3564*8fb009dcSAndroid Build Coastguard Worker                                int encrypt) {
3565*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kZeros[16] = {0};
3566*8fb009dcSAndroid Build Coastguard Worker 
3567*8fb009dcSAndroid Build Coastguard Worker   if (encrypt) {
3568*8fb009dcSAndroid Build Coastguard Worker     OPENSSL_memcpy(key_name, kZeros, sizeof(kZeros));
3569*8fb009dcSAndroid Build Coastguard Worker     RAND_bytes(iv, 16);
3570*8fb009dcSAndroid Build Coastguard Worker   } else if (OPENSSL_memcmp(key_name, kZeros, 16) != 0) {
3571*8fb009dcSAndroid Build Coastguard Worker     return 0;
3572*8fb009dcSAndroid Build Coastguard Worker   }
3573*8fb009dcSAndroid Build Coastguard Worker 
3574*8fb009dcSAndroid Build Coastguard Worker   if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
3575*8fb009dcSAndroid Build Coastguard Worker       !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
3576*8fb009dcSAndroid Build Coastguard Worker     return -1;
3577*8fb009dcSAndroid Build Coastguard Worker   }
3578*8fb009dcSAndroid Build Coastguard Worker 
3579*8fb009dcSAndroid Build Coastguard Worker   // Returning two from the callback in decrypt mode renews the
3580*8fb009dcSAndroid Build Coastguard Worker   // session in TLS 1.2 and below.
3581*8fb009dcSAndroid Build Coastguard Worker   return encrypt ? 1 : 2;
3582*8fb009dcSAndroid Build Coastguard Worker }
3583*8fb009dcSAndroid Build Coastguard Worker 
GetServerTicketTime(long * out,const SSL_SESSION * session)3584*8fb009dcSAndroid Build Coastguard Worker static bool GetServerTicketTime(long *out, const SSL_SESSION *session) {
3585*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *ticket;
3586*8fb009dcSAndroid Build Coastguard Worker   size_t ticket_len;
3587*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION_get0_ticket(session, &ticket, &ticket_len);
3588*8fb009dcSAndroid Build Coastguard Worker   if (ticket_len < 16 + 16 + SHA256_DIGEST_LENGTH) {
3589*8fb009dcSAndroid Build Coastguard Worker     return false;
3590*8fb009dcSAndroid Build Coastguard Worker   }
3591*8fb009dcSAndroid Build Coastguard Worker 
3592*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *ciphertext = ticket + 16 + 16;
3593*8fb009dcSAndroid Build Coastguard Worker   size_t len = ticket_len - 16 - 16 - SHA256_DIGEST_LENGTH;
3594*8fb009dcSAndroid Build Coastguard Worker   auto plaintext = std::make_unique<uint8_t[]>(len);
3595*8fb009dcSAndroid Build Coastguard Worker 
3596*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
3597*8fb009dcSAndroid Build Coastguard Worker   // Fuzzer-mode tickets are unencrypted.
3598*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_memcpy(plaintext.get(), ciphertext, len);
3599*8fb009dcSAndroid Build Coastguard Worker #else
3600*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kZeros[16] = {0};
3601*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *iv = ticket + 16;
3602*8fb009dcSAndroid Build Coastguard Worker   bssl::ScopedEVP_CIPHER_CTX ctx;
3603*8fb009dcSAndroid Build Coastguard Worker   int len1, len2;
3604*8fb009dcSAndroid Build Coastguard Worker   if (len > INT_MAX ||
3605*8fb009dcSAndroid Build Coastguard Worker       !EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_cbc(), nullptr, kZeros, iv) ||
3606*8fb009dcSAndroid Build Coastguard Worker       !EVP_DecryptUpdate(ctx.get(), plaintext.get(), &len1, ciphertext,
3607*8fb009dcSAndroid Build Coastguard Worker                          static_cast<int>(len)) ||
3608*8fb009dcSAndroid Build Coastguard Worker       !EVP_DecryptFinal_ex(ctx.get(), plaintext.get() + len1, &len2)) {
3609*8fb009dcSAndroid Build Coastguard Worker     return false;
3610*8fb009dcSAndroid Build Coastguard Worker   }
3611*8fb009dcSAndroid Build Coastguard Worker 
3612*8fb009dcSAndroid Build Coastguard Worker   len = static_cast<size_t>(len1 + len2);
3613*8fb009dcSAndroid Build Coastguard Worker #endif
3614*8fb009dcSAndroid Build Coastguard Worker 
3615*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ssl_ctx(SSL_CTX_new(TLS_method()));
3616*8fb009dcSAndroid Build Coastguard Worker   if (!ssl_ctx) {
3617*8fb009dcSAndroid Build Coastguard Worker     return false;
3618*8fb009dcSAndroid Build Coastguard Worker   }
3619*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> server_session(
3620*8fb009dcSAndroid Build Coastguard Worker       SSL_SESSION_from_bytes(plaintext.get(), len, ssl_ctx.get()));
3621*8fb009dcSAndroid Build Coastguard Worker   if (!server_session) {
3622*8fb009dcSAndroid Build Coastguard Worker     return false;
3623*8fb009dcSAndroid Build Coastguard Worker   }
3624*8fb009dcSAndroid Build Coastguard Worker 
3625*8fb009dcSAndroid Build Coastguard Worker   *out = SSL_SESSION_get_time(server_session.get());
3626*8fb009dcSAndroid Build Coastguard Worker   return true;
3627*8fb009dcSAndroid Build Coastguard Worker }
3628*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SessionTimeout)3629*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SessionTimeout) {
3630*8fb009dcSAndroid Build Coastguard Worker   for (bool server_test : {false, true}) {
3631*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(server_test);
3632*8fb009dcSAndroid Build Coastguard Worker 
3633*8fb009dcSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(ResetContexts());
3634*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3635*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
3636*8fb009dcSAndroid Build Coastguard Worker 
3637*8fb009dcSAndroid Build Coastguard Worker     static const time_t kStartTime = 1000;
3638*8fb009dcSAndroid Build Coastguard Worker     g_current_time.tv_sec = kStartTime;
3639*8fb009dcSAndroid Build Coastguard Worker 
3640*8fb009dcSAndroid Build Coastguard Worker     // We are willing to use a longer lifetime for TLS 1.3 sessions as
3641*8fb009dcSAndroid Build Coastguard Worker     // resumptions still perform ECDHE.
3642*8fb009dcSAndroid Build Coastguard Worker     const time_t timeout = version() == TLS1_3_VERSION
3643*8fb009dcSAndroid Build Coastguard Worker                                ? SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT
3644*8fb009dcSAndroid Build Coastguard Worker                                : SSL_DEFAULT_SESSION_TIMEOUT;
3645*8fb009dcSAndroid Build Coastguard Worker 
3646*8fb009dcSAndroid Build Coastguard Worker     // Both client and server must enforce session timeouts. We configure the
3647*8fb009dcSAndroid Build Coastguard Worker     // other side with a frozen clock so it never expires tickets.
3648*8fb009dcSAndroid Build Coastguard Worker     if (server_test) {
3649*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3650*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
3651*8fb009dcSAndroid Build Coastguard Worker     } else {
3652*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_current_time_cb(client_ctx_.get(), CurrentTimeCallback);
3653*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_current_time_cb(server_ctx_.get(), FrozenTimeCallback);
3654*8fb009dcSAndroid Build Coastguard Worker     }
3655*8fb009dcSAndroid Build Coastguard Worker 
3656*8fb009dcSAndroid Build Coastguard Worker     // Configure a ticket callback which renews tickets.
3657*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
3658*8fb009dcSAndroid Build Coastguard Worker 
3659*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session =
3660*8fb009dcSAndroid Build Coastguard Worker         CreateClientSession(client_ctx_.get(), server_ctx_.get());
3661*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session);
3662*8fb009dcSAndroid Build Coastguard Worker 
3663*8fb009dcSAndroid Build Coastguard Worker     // Advance the clock just behind the timeout.
3664*8fb009dcSAndroid Build Coastguard Worker     g_current_time.tv_sec += timeout - 1;
3665*8fb009dcSAndroid Build Coastguard Worker 
3666*8fb009dcSAndroid Build Coastguard Worker     TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3667*8fb009dcSAndroid Build Coastguard Worker                                     session.get(),
3668*8fb009dcSAndroid Build Coastguard Worker                                     true /* expect session reused */));
3669*8fb009dcSAndroid Build Coastguard Worker 
3670*8fb009dcSAndroid Build Coastguard Worker     // Advance the clock one more second.
3671*8fb009dcSAndroid Build Coastguard Worker     g_current_time.tv_sec++;
3672*8fb009dcSAndroid Build Coastguard Worker 
3673*8fb009dcSAndroid Build Coastguard Worker     TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3674*8fb009dcSAndroid Build Coastguard Worker                                     session.get(),
3675*8fb009dcSAndroid Build Coastguard Worker                                     false /* expect session not reused */));
3676*8fb009dcSAndroid Build Coastguard Worker 
3677*8fb009dcSAndroid Build Coastguard Worker     // Rewind the clock to before the session was minted.
3678*8fb009dcSAndroid Build Coastguard Worker     g_current_time.tv_sec = kStartTime - 1;
3679*8fb009dcSAndroid Build Coastguard Worker 
3680*8fb009dcSAndroid Build Coastguard Worker     TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3681*8fb009dcSAndroid Build Coastguard Worker                                     session.get(),
3682*8fb009dcSAndroid Build Coastguard Worker                                     false /* expect session not reused */));
3683*8fb009dcSAndroid Build Coastguard Worker 
3684*8fb009dcSAndroid Build Coastguard Worker     // Renew the session 10 seconds before expiration.
3685*8fb009dcSAndroid Build Coastguard Worker     time_t new_start_time = kStartTime + timeout - 10;
3686*8fb009dcSAndroid Build Coastguard Worker     g_current_time.tv_sec = new_start_time;
3687*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> new_session = ExpectSessionRenewed(
3688*8fb009dcSAndroid Build Coastguard Worker         client_ctx_.get(), server_ctx_.get(), session.get());
3689*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(new_session);
3690*8fb009dcSAndroid Build Coastguard Worker 
3691*8fb009dcSAndroid Build Coastguard Worker     // This new session is not the same object as before.
3692*8fb009dcSAndroid Build Coastguard Worker     EXPECT_NE(session.get(), new_session.get());
3693*8fb009dcSAndroid Build Coastguard Worker 
3694*8fb009dcSAndroid Build Coastguard Worker     // Check the sessions have timestamps measured from issuance.
3695*8fb009dcSAndroid Build Coastguard Worker     long session_time = 0;
3696*8fb009dcSAndroid Build Coastguard Worker     if (server_test) {
3697*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(GetServerTicketTime(&session_time, new_session.get()));
3698*8fb009dcSAndroid Build Coastguard Worker     } else {
3699*8fb009dcSAndroid Build Coastguard Worker       session_time = SSL_SESSION_get_time(new_session.get());
3700*8fb009dcSAndroid Build Coastguard Worker     }
3701*8fb009dcSAndroid Build Coastguard Worker 
3702*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(session_time, g_current_time.tv_sec);
3703*8fb009dcSAndroid Build Coastguard Worker 
3704*8fb009dcSAndroid Build Coastguard Worker     if (version() == TLS1_3_VERSION) {
3705*8fb009dcSAndroid Build Coastguard Worker       // Renewal incorporates fresh key material in TLS 1.3, so we extend the
3706*8fb009dcSAndroid Build Coastguard Worker       // lifetime TLS 1.3.
3707*8fb009dcSAndroid Build Coastguard Worker       g_current_time.tv_sec = new_start_time + timeout - 1;
3708*8fb009dcSAndroid Build Coastguard Worker       TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3709*8fb009dcSAndroid Build Coastguard Worker                                       new_session.get(),
3710*8fb009dcSAndroid Build Coastguard Worker                                       true /* expect session reused */));
3711*8fb009dcSAndroid Build Coastguard Worker 
3712*8fb009dcSAndroid Build Coastguard Worker       // The new session expires after the new timeout.
3713*8fb009dcSAndroid Build Coastguard Worker       g_current_time.tv_sec = new_start_time + timeout + 1;
3714*8fb009dcSAndroid Build Coastguard Worker       TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3715*8fb009dcSAndroid Build Coastguard Worker                                       new_session.get(),
3716*8fb009dcSAndroid Build Coastguard Worker                                       false /* expect session ot reused */));
3717*8fb009dcSAndroid Build Coastguard Worker 
3718*8fb009dcSAndroid Build Coastguard Worker       // Renew the session until it begins just past the auth timeout.
3719*8fb009dcSAndroid Build Coastguard Worker       time_t auth_end_time = kStartTime + SSL_DEFAULT_SESSION_AUTH_TIMEOUT;
3720*8fb009dcSAndroid Build Coastguard Worker       while (new_start_time < auth_end_time - 1000) {
3721*8fb009dcSAndroid Build Coastguard Worker         // Get as close as possible to target start time.
3722*8fb009dcSAndroid Build Coastguard Worker         new_start_time =
3723*8fb009dcSAndroid Build Coastguard Worker             std::min(auth_end_time - 1000, new_start_time + timeout - 1);
3724*8fb009dcSAndroid Build Coastguard Worker         g_current_time.tv_sec = new_start_time;
3725*8fb009dcSAndroid Build Coastguard Worker         new_session = ExpectSessionRenewed(client_ctx_.get(), server_ctx_.get(),
3726*8fb009dcSAndroid Build Coastguard Worker                                            new_session.get());
3727*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(new_session);
3728*8fb009dcSAndroid Build Coastguard Worker       }
3729*8fb009dcSAndroid Build Coastguard Worker 
3730*8fb009dcSAndroid Build Coastguard Worker       // Now the session's lifetime is bound by the auth timeout.
3731*8fb009dcSAndroid Build Coastguard Worker       g_current_time.tv_sec = auth_end_time - 1;
3732*8fb009dcSAndroid Build Coastguard Worker       TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3733*8fb009dcSAndroid Build Coastguard Worker                                       new_session.get(),
3734*8fb009dcSAndroid Build Coastguard Worker                                       true /* expect session reused */));
3735*8fb009dcSAndroid Build Coastguard Worker 
3736*8fb009dcSAndroid Build Coastguard Worker       g_current_time.tv_sec = auth_end_time + 1;
3737*8fb009dcSAndroid Build Coastguard Worker       TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3738*8fb009dcSAndroid Build Coastguard Worker                                       new_session.get(),
3739*8fb009dcSAndroid Build Coastguard Worker                                       false /* expect session ot reused */));
3740*8fb009dcSAndroid Build Coastguard Worker     } else {
3741*8fb009dcSAndroid Build Coastguard Worker       // The new session is usable just before the old expiration.
3742*8fb009dcSAndroid Build Coastguard Worker       g_current_time.tv_sec = kStartTime + timeout - 1;
3743*8fb009dcSAndroid Build Coastguard Worker       TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3744*8fb009dcSAndroid Build Coastguard Worker                                       new_session.get(),
3745*8fb009dcSAndroid Build Coastguard Worker                                       true /* expect session reused */));
3746*8fb009dcSAndroid Build Coastguard Worker 
3747*8fb009dcSAndroid Build Coastguard Worker       // Renewal does not extend the lifetime, so it is not usable beyond the
3748*8fb009dcSAndroid Build Coastguard Worker       // old expiration.
3749*8fb009dcSAndroid Build Coastguard Worker       g_current_time.tv_sec = kStartTime + timeout + 1;
3750*8fb009dcSAndroid Build Coastguard Worker       TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3751*8fb009dcSAndroid Build Coastguard Worker                                       new_session.get(),
3752*8fb009dcSAndroid Build Coastguard Worker                                       false /* expect session not reused */));
3753*8fb009dcSAndroid Build Coastguard Worker     }
3754*8fb009dcSAndroid Build Coastguard Worker   }
3755*8fb009dcSAndroid Build Coastguard Worker }
3756*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,DefaultTicketKeyInitialization)3757*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, DefaultTicketKeyInitialization) {
3758*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kZeroKey[kTicketKeyLen] = {};
3759*8fb009dcSAndroid Build Coastguard Worker   uint8_t ticket_key[kTicketKeyLen];
3760*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(1, SSL_CTX_get_tlsext_ticket_keys(server_ctx_.get(), ticket_key,
3761*8fb009dcSAndroid Build Coastguard Worker                                               kTicketKeyLen));
3762*8fb009dcSAndroid Build Coastguard Worker   ASSERT_NE(0, OPENSSL_memcmp(ticket_key, kZeroKey, kTicketKeyLen));
3763*8fb009dcSAndroid Build Coastguard Worker }
3764*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,DefaultTicketKeyRotation)3765*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, DefaultTicketKeyRotation) {
3766*8fb009dcSAndroid Build Coastguard Worker   static const time_t kStartTime = 1001;
3767*8fb009dcSAndroid Build Coastguard Worker   g_current_time.tv_sec = kStartTime;
3768*8fb009dcSAndroid Build Coastguard Worker 
3769*8fb009dcSAndroid Build Coastguard Worker   // We use session reuse as a proxy for ticket decryption success, hence
3770*8fb009dcSAndroid Build Coastguard Worker   // disable session timeouts.
3771*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_timeout(server_ctx_.get(), std::numeric_limits<uint32_t>::max());
3772*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_psk_dhe_timeout(server_ctx_.get(),
3773*8fb009dcSAndroid Build Coastguard Worker                                       std::numeric_limits<uint32_t>::max());
3774*8fb009dcSAndroid Build Coastguard Worker 
3775*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_current_time_cb(client_ctx_.get(), FrozenTimeCallback);
3776*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
3777*8fb009dcSAndroid Build Coastguard Worker 
3778*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
3779*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_OFF);
3780*8fb009dcSAndroid Build Coastguard Worker 
3781*8fb009dcSAndroid Build Coastguard Worker   // Initialize ticket_key with the current key and check that it was
3782*8fb009dcSAndroid Build Coastguard Worker   // initialized to something, not all zeros.
3783*8fb009dcSAndroid Build Coastguard Worker   uint8_t ticket_key[kTicketKeyLen] = {0};
3784*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3785*8fb009dcSAndroid Build Coastguard Worker                                      true /* changed */));
3786*8fb009dcSAndroid Build Coastguard Worker 
3787*8fb009dcSAndroid Build Coastguard Worker   // Verify ticket resumption actually works.
3788*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
3789*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
3790*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
3791*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
3792*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3793*8fb009dcSAndroid Build Coastguard Worker                                   session.get(), true /* reused */));
3794*8fb009dcSAndroid Build Coastguard Worker 
3795*8fb009dcSAndroid Build Coastguard Worker   // Advance time to just before key rotation.
3796*8fb009dcSAndroid Build Coastguard Worker   g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL - 1;
3797*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3798*8fb009dcSAndroid Build Coastguard Worker                                   session.get(), true /* reused */));
3799*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3800*8fb009dcSAndroid Build Coastguard Worker                                      false /* NOT changed */));
3801*8fb009dcSAndroid Build Coastguard Worker 
3802*8fb009dcSAndroid Build Coastguard Worker   // Force key rotation.
3803*8fb009dcSAndroid Build Coastguard Worker   g_current_time.tv_sec += 1;
3804*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> new_session =
3805*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
3806*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3807*8fb009dcSAndroid Build Coastguard Worker                                      true /* changed */));
3808*8fb009dcSAndroid Build Coastguard Worker 
3809*8fb009dcSAndroid Build Coastguard Worker   // Resumption with both old and new ticket should work.
3810*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3811*8fb009dcSAndroid Build Coastguard Worker                                   session.get(), true /* reused */));
3812*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3813*8fb009dcSAndroid Build Coastguard Worker                                   new_session.get(), true /* reused */));
3814*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3815*8fb009dcSAndroid Build Coastguard Worker                                      false /* NOT changed */));
3816*8fb009dcSAndroid Build Coastguard Worker 
3817*8fb009dcSAndroid Build Coastguard Worker   // Force key rotation again. Resumption with the old ticket now fails.
3818*8fb009dcSAndroid Build Coastguard Worker   g_current_time.tv_sec += SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL;
3819*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3820*8fb009dcSAndroid Build Coastguard Worker                                   session.get(), false /* NOT reused */));
3821*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectTicketKeyChanged(server_ctx_.get(), ticket_key,
3822*8fb009dcSAndroid Build Coastguard Worker                                      true /* changed */));
3823*8fb009dcSAndroid Build Coastguard Worker 
3824*8fb009dcSAndroid Build Coastguard Worker   // But resumption with the newer session still works.
3825*8fb009dcSAndroid Build Coastguard Worker   TRACED_CALL(ExpectSessionReused(client_ctx_.get(), server_ctx_.get(),
3826*8fb009dcSAndroid Build Coastguard Worker                                   new_session.get(), true /* reused */));
3827*8fb009dcSAndroid Build Coastguard Worker }
3828*8fb009dcSAndroid Build Coastguard Worker 
SwitchContext(SSL * ssl,int * out_alert,void * arg)3829*8fb009dcSAndroid Build Coastguard Worker static int SwitchContext(SSL *ssl, int *out_alert, void *arg) {
3830*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(arg);
3831*8fb009dcSAndroid Build Coastguard Worker   SSL_set_SSL_CTX(ssl, ctx);
3832*8fb009dcSAndroid Build Coastguard Worker   return SSL_TLSEXT_ERR_OK;
3833*8fb009dcSAndroid Build Coastguard Worker }
3834*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SNICallback)3835*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SNICallback) {
3836*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert2 = GetECDSATestCertificate();
3837*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert2);
3838*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
3839*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key2);
3840*8fb009dcSAndroid Build Coastguard Worker 
3841*8fb009dcSAndroid Build Coastguard Worker   // Test that switching the |SSL_CTX| at the SNI callback behaves correctly.
3842*8fb009dcSAndroid Build Coastguard Worker   static const uint16_t kECDSAWithSHA256 = SSL_SIGN_ECDSA_SECP256R1_SHA256;
3843*8fb009dcSAndroid Build Coastguard Worker 
3844*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kSCTList[] = {0, 6, 0, 4, 5, 6, 7, 8};
3845*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kOCSPResponse[] = {1, 2, 3, 4};
3846*8fb009dcSAndroid Build Coastguard Worker 
3847*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
3848*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx2);
3849*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx2.get(), cert2.get()));
3850*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx2.get(), key2.get()));
3851*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_signed_cert_timestamp_list(
3852*8fb009dcSAndroid Build Coastguard Worker       server_ctx2.get(), kSCTList, sizeof(kSCTList)));
3853*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_ocsp_response(server_ctx2.get(), kOCSPResponse,
3854*8fb009dcSAndroid Build Coastguard Worker                                         sizeof(kOCSPResponse)));
3855*8fb009dcSAndroid Build Coastguard Worker   // Historically signing preferences would be lost in some cases with the
3856*8fb009dcSAndroid Build Coastguard Worker   // SNI callback, which triggers the TLS 1.2 SHA-1 default. To ensure
3857*8fb009dcSAndroid Build Coastguard Worker   // this doesn't happen when |version| is TLS 1.2, configure the private
3858*8fb009dcSAndroid Build Coastguard Worker   // key to only sign SHA-256.
3859*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_signing_algorithm_prefs(server_ctx2.get(),
3860*8fb009dcSAndroid Build Coastguard Worker                                                   &kECDSAWithSHA256, 1));
3861*8fb009dcSAndroid Build Coastguard Worker 
3862*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_servername_callback(server_ctx_.get(), SwitchContext);
3863*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), server_ctx2.get());
3864*8fb009dcSAndroid Build Coastguard Worker 
3865*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_enable_signed_cert_timestamps(client_ctx_.get());
3866*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_enable_ocsp_stapling(client_ctx_.get());
3867*8fb009dcSAndroid Build Coastguard Worker 
3868*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
3869*8fb009dcSAndroid Build Coastguard Worker 
3870*8fb009dcSAndroid Build Coastguard Worker   // The client should have received |cert2|.
3871*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client_.get()));
3872*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(peer);
3873*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(X509_cmp(peer.get(), cert2.get()), 0);
3874*8fb009dcSAndroid Build Coastguard Worker 
3875*8fb009dcSAndroid Build Coastguard Worker   // The client should have received |server_ctx2|'s SCT list.
3876*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *data;
3877*8fb009dcSAndroid Build Coastguard Worker   size_t len;
3878*8fb009dcSAndroid Build Coastguard Worker   SSL_get0_signed_cert_timestamp_list(client_.get(), &data, &len);
3879*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(kSCTList), Bytes(data, len));
3880*8fb009dcSAndroid Build Coastguard Worker 
3881*8fb009dcSAndroid Build Coastguard Worker   // The client should have received |server_ctx2|'s OCSP response.
3882*8fb009dcSAndroid Build Coastguard Worker   SSL_get0_ocsp_response(client_.get(), &data, &len);
3883*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(kOCSPResponse), Bytes(data, len));
3884*8fb009dcSAndroid Build Coastguard Worker }
3885*8fb009dcSAndroid Build Coastguard Worker 
3886*8fb009dcSAndroid Build Coastguard Worker // Test that the early callback can swap the maximum version.
TEST(SSLTest,EarlyCallbackVersionSwitch)3887*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, EarlyCallbackVersionSwitch) {
3888*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
3889*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
3890*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
3891*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
3892*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
3893*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
3894*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
3895*8fb009dcSAndroid Build Coastguard Worker 
3896*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_select_certificate_cb(
3897*8fb009dcSAndroid Build Coastguard Worker       server_ctx.get(),
3898*8fb009dcSAndroid Build Coastguard Worker       [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
3899*8fb009dcSAndroid Build Coastguard Worker         if (!SSL_set_max_proto_version(client_hello->ssl, TLS1_2_VERSION)) {
3900*8fb009dcSAndroid Build Coastguard Worker           return ssl_select_cert_error;
3901*8fb009dcSAndroid Build Coastguard Worker         }
3902*8fb009dcSAndroid Build Coastguard Worker 
3903*8fb009dcSAndroid Build Coastguard Worker         return ssl_select_cert_success;
3904*8fb009dcSAndroid Build Coastguard Worker       });
3905*8fb009dcSAndroid Build Coastguard Worker 
3906*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
3907*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
3908*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
3909*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(TLS1_2_VERSION, SSL_version(client.get()));
3910*8fb009dcSAndroid Build Coastguard Worker }
3911*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SetVersion)3912*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SetVersion) {
3913*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
3914*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
3915*8fb009dcSAndroid Build Coastguard Worker 
3916*8fb009dcSAndroid Build Coastguard Worker   // Set valid TLS versions.
3917*8fb009dcSAndroid Build Coastguard Worker   for (const auto &vers : kAllVersions) {
3918*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(vers.name);
3919*8fb009dcSAndroid Build Coastguard Worker     if (vers.ssl_method == VersionParam::is_tls) {
3920*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), vers.version));
3921*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_CTX_get_max_proto_version(ctx.get()), vers.version);
3922*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), vers.version));
3923*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_CTX_get_min_proto_version(ctx.get()), vers.version);
3924*8fb009dcSAndroid Build Coastguard Worker     }
3925*8fb009dcSAndroid Build Coastguard Worker   }
3926*8fb009dcSAndroid Build Coastguard Worker 
3927*8fb009dcSAndroid Build Coastguard Worker   // Invalid TLS versions are rejected.
3928*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), DTLS1_VERSION));
3929*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x0200));
3930*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3931*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), DTLS1_VERSION));
3932*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x0200));
3933*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
3934*8fb009dcSAndroid Build Coastguard Worker 
3935*8fb009dcSAndroid Build Coastguard Worker   // Zero is the default version.
3936*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
3937*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(TLS1_3_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
3938*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
3939*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(TLS1_2_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
3940*8fb009dcSAndroid Build Coastguard Worker 
3941*8fb009dcSAndroid Build Coastguard Worker   // SSL 3.0 is not available.
3942*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), SSL3_VERSION));
3943*8fb009dcSAndroid Build Coastguard Worker 
3944*8fb009dcSAndroid Build Coastguard Worker   ctx.reset(SSL_CTX_new(DTLS_method()));
3945*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
3946*8fb009dcSAndroid Build Coastguard Worker 
3947*8fb009dcSAndroid Build Coastguard Worker   // Set valid DTLS versions.
3948*8fb009dcSAndroid Build Coastguard Worker   for (const auto &vers : kAllVersions) {
3949*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(vers.name);
3950*8fb009dcSAndroid Build Coastguard Worker     if (vers.ssl_method == VersionParam::is_dtls) {
3951*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), vers.version));
3952*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_CTX_get_max_proto_version(ctx.get()), vers.version);
3953*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), vers.version));
3954*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_CTX_get_min_proto_version(ctx.get()), vers.version);
3955*8fb009dcSAndroid Build Coastguard Worker     }
3956*8fb009dcSAndroid Build Coastguard Worker   }
3957*8fb009dcSAndroid Build Coastguard Worker 
3958*8fb009dcSAndroid Build Coastguard Worker   // Invalid DTLS versions are rejected.
3959*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_VERSION));
3960*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3961*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3962*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_max_proto_version(ctx.get(), 0x1234));
3963*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_VERSION));
3964*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfefe /* DTLS 1.1 */));
3965*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0xfffe /* DTLS 0.1 */));
3966*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_min_proto_version(ctx.get(), 0x1234));
3967*8fb009dcSAndroid Build Coastguard Worker 
3968*8fb009dcSAndroid Build Coastguard Worker   // Zero is the default version.
3969*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), 0));
3970*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_max_proto_version(ctx.get()));
3971*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), 0));
3972*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(DTLS1_2_VERSION, SSL_CTX_get_min_proto_version(ctx.get()));
3973*8fb009dcSAndroid Build Coastguard Worker }
3974*8fb009dcSAndroid Build Coastguard Worker 
GetVersionName(uint16_t version)3975*8fb009dcSAndroid Build Coastguard Worker static const char *GetVersionName(uint16_t version) {
3976*8fb009dcSAndroid Build Coastguard Worker   switch (version) {
3977*8fb009dcSAndroid Build Coastguard Worker     case TLS1_VERSION:
3978*8fb009dcSAndroid Build Coastguard Worker       return "TLSv1";
3979*8fb009dcSAndroid Build Coastguard Worker     case TLS1_1_VERSION:
3980*8fb009dcSAndroid Build Coastguard Worker       return "TLSv1.1";
3981*8fb009dcSAndroid Build Coastguard Worker     case TLS1_2_VERSION:
3982*8fb009dcSAndroid Build Coastguard Worker       return "TLSv1.2";
3983*8fb009dcSAndroid Build Coastguard Worker     case TLS1_3_VERSION:
3984*8fb009dcSAndroid Build Coastguard Worker       return "TLSv1.3";
3985*8fb009dcSAndroid Build Coastguard Worker     case DTLS1_VERSION:
3986*8fb009dcSAndroid Build Coastguard Worker       return "DTLSv1";
3987*8fb009dcSAndroid Build Coastguard Worker     case DTLS1_2_VERSION:
3988*8fb009dcSAndroid Build Coastguard Worker       return "DTLSv1.2";
3989*8fb009dcSAndroid Build Coastguard Worker     default:
3990*8fb009dcSAndroid Build Coastguard Worker       return "???";
3991*8fb009dcSAndroid Build Coastguard Worker   }
3992*8fb009dcSAndroid Build Coastguard Worker }
3993*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,Version)3994*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, Version) {
3995*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
3996*8fb009dcSAndroid Build Coastguard Worker 
3997*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_version(client_.get()), version());
3998*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_version(server_.get()), version());
3999*8fb009dcSAndroid Build Coastguard Worker 
4000*8fb009dcSAndroid Build Coastguard Worker   // Test the version name is reported as expected.
4001*8fb009dcSAndroid Build Coastguard Worker   const char *version_name = GetVersionName(version());
4002*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(strcmp(version_name, SSL_get_version(client_.get())), 0);
4003*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(strcmp(version_name, SSL_get_version(server_.get())), 0);
4004*8fb009dcSAndroid Build Coastguard Worker 
4005*8fb009dcSAndroid Build Coastguard Worker   // Test SSL_SESSION reports the same name.
4006*8fb009dcSAndroid Build Coastguard Worker   const char *client_name =
4007*8fb009dcSAndroid Build Coastguard Worker       SSL_SESSION_get_version(SSL_get_session(client_.get()));
4008*8fb009dcSAndroid Build Coastguard Worker   const char *server_name =
4009*8fb009dcSAndroid Build Coastguard Worker       SSL_SESSION_get_version(SSL_get_session(server_.get()));
4010*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(strcmp(version_name, client_name), 0);
4011*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(strcmp(version_name, server_name), 0);
4012*8fb009dcSAndroid Build Coastguard Worker }
4013*8fb009dcSAndroid Build Coastguard Worker 
4014*8fb009dcSAndroid Build Coastguard Worker // Tests that that |SSL_get_pending_cipher| is available during the ALPN
4015*8fb009dcSAndroid Build Coastguard Worker // selection callback.
TEST_P(SSLVersionTest,ALPNCipherAvailable)4016*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, ALPNCipherAvailable) {
4017*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4018*8fb009dcSAndroid Build Coastguard Worker 
4019*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
4020*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
4021*8fb009dcSAndroid Build Coastguard Worker                                     sizeof(kALPNProtos)),
4022*8fb009dcSAndroid Build Coastguard Worker             0);
4023*8fb009dcSAndroid Build Coastguard Worker 
4024*8fb009dcSAndroid Build Coastguard Worker   // The ALPN callback does not fail the handshake on error, so have the
4025*8fb009dcSAndroid Build Coastguard Worker   // callback write a boolean.
4026*8fb009dcSAndroid Build Coastguard Worker   std::pair<uint16_t, bool> callback_state(version(), false);
4027*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_alpn_select_cb(
4028*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(),
4029*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
4030*8fb009dcSAndroid Build Coastguard Worker          unsigned in_len, void *arg) -> int {
4031*8fb009dcSAndroid Build Coastguard Worker         auto state = reinterpret_cast<std::pair<uint16_t, bool> *>(arg);
4032*8fb009dcSAndroid Build Coastguard Worker         if (SSL_get_pending_cipher(ssl) != nullptr &&
4033*8fb009dcSAndroid Build Coastguard Worker             SSL_version(ssl) == state->first) {
4034*8fb009dcSAndroid Build Coastguard Worker           state->second = true;
4035*8fb009dcSAndroid Build Coastguard Worker         }
4036*8fb009dcSAndroid Build Coastguard Worker         return SSL_TLSEXT_ERR_NOACK;
4037*8fb009dcSAndroid Build Coastguard Worker       },
4038*8fb009dcSAndroid Build Coastguard Worker       &callback_state);
4039*8fb009dcSAndroid Build Coastguard Worker 
4040*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
4041*8fb009dcSAndroid Build Coastguard Worker 
4042*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(callback_state.second);
4043*8fb009dcSAndroid Build Coastguard Worker }
4044*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SSLClearSessionResumption)4045*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SSLClearSessionResumption) {
4046*8fb009dcSAndroid Build Coastguard Worker   // Skip this for TLS 1.3. TLS 1.3's ticket mechanism is incompatible with this
4047*8fb009dcSAndroid Build Coastguard Worker   // API pattern.
4048*8fb009dcSAndroid Build Coastguard Worker   if (version() == TLS1_3_VERSION) {
4049*8fb009dcSAndroid Build Coastguard Worker     return;
4050*8fb009dcSAndroid Build Coastguard Worker   }
4051*8fb009dcSAndroid Build Coastguard Worker 
4052*8fb009dcSAndroid Build Coastguard Worker   shed_handshake_config_ = false;
4053*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
4054*8fb009dcSAndroid Build Coastguard Worker 
4055*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client_.get()));
4056*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server_.get()));
4057*8fb009dcSAndroid Build Coastguard Worker 
4058*8fb009dcSAndroid Build Coastguard Worker   // Reset everything.
4059*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_clear(client_.get()));
4060*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_clear(server_.get()));
4061*8fb009dcSAndroid Build Coastguard Worker 
4062*8fb009dcSAndroid Build Coastguard Worker   // Attempt to connect a second time.
4063*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
4064*8fb009dcSAndroid Build Coastguard Worker 
4065*8fb009dcSAndroid Build Coastguard Worker   // |SSL_clear| should implicitly offer the previous session to the server.
4066*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client_.get()));
4067*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server_.get()));
4068*8fb009dcSAndroid Build Coastguard Worker }
4069*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SSLClearFailsWithShedding)4070*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SSLClearFailsWithShedding) {
4071*8fb009dcSAndroid Build Coastguard Worker   shed_handshake_config_ = false;
4072*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
4073*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
4074*8fb009dcSAndroid Build Coastguard Worker 
4075*8fb009dcSAndroid Build Coastguard Worker   // Reset everything.
4076*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_clear(client_.get()));
4077*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_clear(server_.get()));
4078*8fb009dcSAndroid Build Coastguard Worker 
4079*8fb009dcSAndroid Build Coastguard Worker   // Now enable shedding, and connect a second time.
4080*8fb009dcSAndroid Build Coastguard Worker   shed_handshake_config_ = true;
4081*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
4082*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
4083*8fb009dcSAndroid Build Coastguard Worker 
4084*8fb009dcSAndroid Build Coastguard Worker   // |SSL_clear| should now fail.
4085*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_clear(client_.get()));
4086*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_clear(server_.get()));
4087*8fb009dcSAndroid Build Coastguard Worker }
4088*8fb009dcSAndroid Build Coastguard Worker 
ChainsEqual(const STACK_OF (X509)* chain,const std::vector<X509 * > & expected)4089*8fb009dcSAndroid Build Coastguard Worker static bool ChainsEqual(const STACK_OF(X509) *chain,
4090*8fb009dcSAndroid Build Coastguard Worker                         const std::vector<X509 *> &expected) {
4091*8fb009dcSAndroid Build Coastguard Worker   if (sk_X509_num(chain) != expected.size()) {
4092*8fb009dcSAndroid Build Coastguard Worker     return false;
4093*8fb009dcSAndroid Build Coastguard Worker   }
4094*8fb009dcSAndroid Build Coastguard Worker 
4095*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < expected.size(); i++) {
4096*8fb009dcSAndroid Build Coastguard Worker     if (X509_cmp(sk_X509_value(chain, i), expected[i]) != 0) {
4097*8fb009dcSAndroid Build Coastguard Worker       return false;
4098*8fb009dcSAndroid Build Coastguard Worker     }
4099*8fb009dcSAndroid Build Coastguard Worker   }
4100*8fb009dcSAndroid Build Coastguard Worker 
4101*8fb009dcSAndroid Build Coastguard Worker   return true;
4102*8fb009dcSAndroid Build Coastguard Worker }
4103*8fb009dcSAndroid Build Coastguard Worker 
BuffersEqual(const STACK_OF (CRYPTO_BUFFER)* chain,const std::vector<CRYPTO_BUFFER * > & expected)4104*8fb009dcSAndroid Build Coastguard Worker static bool BuffersEqual(const STACK_OF(CRYPTO_BUFFER) *chain,
4105*8fb009dcSAndroid Build Coastguard Worker                          const std::vector<CRYPTO_BUFFER *> &expected) {
4106*8fb009dcSAndroid Build Coastguard Worker   if (sk_CRYPTO_BUFFER_num(chain) != expected.size()) {
4107*8fb009dcSAndroid Build Coastguard Worker     return false;
4108*8fb009dcSAndroid Build Coastguard Worker   }
4109*8fb009dcSAndroid Build Coastguard Worker 
4110*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < expected.size(); i++) {
4111*8fb009dcSAndroid Build Coastguard Worker     const CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_value(chain, i);
4112*8fb009dcSAndroid Build Coastguard Worker     if (Bytes(CRYPTO_BUFFER_data(buf), CRYPTO_BUFFER_len(buf)) !=
4113*8fb009dcSAndroid Build Coastguard Worker         Bytes(CRYPTO_BUFFER_data(expected[i]),
4114*8fb009dcSAndroid Build Coastguard Worker               CRYPTO_BUFFER_len(expected[i]))) {
4115*8fb009dcSAndroid Build Coastguard Worker       return false;
4116*8fb009dcSAndroid Build Coastguard Worker     }
4117*8fb009dcSAndroid Build Coastguard Worker   }
4118*8fb009dcSAndroid Build Coastguard Worker 
4119*8fb009dcSAndroid Build Coastguard Worker   return true;
4120*8fb009dcSAndroid Build Coastguard Worker }
4121*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,AutoChain)4122*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, AutoChain) {
4123*8fb009dcSAndroid Build Coastguard Worker   cert_ = GetChainTestCertificate();
4124*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert_);
4125*8fb009dcSAndroid Build Coastguard Worker   key_ = GetChainTestKey();
4126*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key_);
4127*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
4128*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(intermediate);
4129*8fb009dcSAndroid Build Coastguard Worker 
4130*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
4131*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
4132*8fb009dcSAndroid Build Coastguard Worker 
4133*8fb009dcSAndroid Build Coastguard Worker   // Configure both client and server to accept any certificate. Add
4134*8fb009dcSAndroid Build Coastguard Worker   // |intermediate| to the cert store.
4135*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx_.get()),
4136*8fb009dcSAndroid Build Coastguard Worker                                   intermediate.get()));
4137*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(server_ctx_.get()),
4138*8fb009dcSAndroid Build Coastguard Worker                                   intermediate.get()));
4139*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(client_ctx_.get(),
4140*8fb009dcSAndroid Build Coastguard Worker                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
4141*8fb009dcSAndroid Build Coastguard Worker                      nullptr);
4142*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(server_ctx_.get(),
4143*8fb009dcSAndroid Build Coastguard Worker                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
4144*8fb009dcSAndroid Build Coastguard Worker                      nullptr);
4145*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed, NULL);
4146*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_verify_callback(server_ctx_.get(), VerifySucceed, NULL);
4147*8fb009dcSAndroid Build Coastguard Worker 
4148*8fb009dcSAndroid Build Coastguard Worker   // By default, the client and server should each only send the leaf.
4149*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
4150*8fb009dcSAndroid Build Coastguard Worker 
4151*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(
4152*8fb009dcSAndroid Build Coastguard Worker       ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()), {cert_.get()}));
4153*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(
4154*8fb009dcSAndroid Build Coastguard Worker       ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()), {cert_.get()}));
4155*8fb009dcSAndroid Build Coastguard Worker 
4156*8fb009dcSAndroid Build Coastguard Worker   // If auto-chaining is enabled, then the intermediate is sent.
4157*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_clear_mode(client_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
4158*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_clear_mode(server_ctx_.get(), SSL_MODE_NO_AUTO_CHAIN);
4159*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
4160*8fb009dcSAndroid Build Coastguard Worker 
4161*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
4162*8fb009dcSAndroid Build Coastguard Worker                           {cert_.get(), intermediate.get()}));
4163*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
4164*8fb009dcSAndroid Build Coastguard Worker                           {cert_.get(), intermediate.get()}));
4165*8fb009dcSAndroid Build Coastguard Worker 
4166*8fb009dcSAndroid Build Coastguard Worker   // Auto-chaining does not override explicitly-configured intermediates.
4167*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_add1_chain_cert(client_ctx_.get(), cert_.get()));
4168*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_add1_chain_cert(server_ctx_.get(), cert_.get()));
4169*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
4170*8fb009dcSAndroid Build Coastguard Worker 
4171*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client_.get()),
4172*8fb009dcSAndroid Build Coastguard Worker                           {cert_.get(), cert_.get()}));
4173*8fb009dcSAndroid Build Coastguard Worker 
4174*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(server_.get()),
4175*8fb009dcSAndroid Build Coastguard Worker                           {cert_.get(), cert_.get()}));
4176*8fb009dcSAndroid Build Coastguard Worker }
4177*8fb009dcSAndroid Build Coastguard Worker 
ExpectSingleError(int lib,int reason)4178*8fb009dcSAndroid Build Coastguard Worker static bool ExpectSingleError(int lib, int reason) {
4179*8fb009dcSAndroid Build Coastguard Worker   const char *expected = ERR_reason_error_string(ERR_PACK(lib, reason));
4180*8fb009dcSAndroid Build Coastguard Worker   int err = ERR_get_error();
4181*8fb009dcSAndroid Build Coastguard Worker   if (ERR_GET_LIB(err) != lib || ERR_GET_REASON(err) != reason) {
4182*8fb009dcSAndroid Build Coastguard Worker     char buf[ERR_ERROR_STRING_BUF_LEN];
4183*8fb009dcSAndroid Build Coastguard Worker     ERR_error_string_n(err, buf, sizeof(buf));
4184*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Wanted %s, got: %s.\n", expected, buf);
4185*8fb009dcSAndroid Build Coastguard Worker     return false;
4186*8fb009dcSAndroid Build Coastguard Worker   }
4187*8fb009dcSAndroid Build Coastguard Worker 
4188*8fb009dcSAndroid Build Coastguard Worker   if (ERR_peek_error() != 0) {
4189*8fb009dcSAndroid Build Coastguard Worker     fprintf(stderr, "Unexpected error following %s.\n", expected);
4190*8fb009dcSAndroid Build Coastguard Worker     return false;
4191*8fb009dcSAndroid Build Coastguard Worker   }
4192*8fb009dcSAndroid Build Coastguard Worker 
4193*8fb009dcSAndroid Build Coastguard Worker   return true;
4194*8fb009dcSAndroid Build Coastguard Worker }
4195*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SSLWriteRetry)4196*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SSLWriteRetry) {
4197*8fb009dcSAndroid Build Coastguard Worker   if (is_dtls()) {
4198*8fb009dcSAndroid Build Coastguard Worker     return;
4199*8fb009dcSAndroid Build Coastguard Worker   }
4200*8fb009dcSAndroid Build Coastguard Worker 
4201*8fb009dcSAndroid Build Coastguard Worker   for (bool enable_partial_write : {false, true}) {
4202*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(enable_partial_write);
4203*8fb009dcSAndroid Build Coastguard Worker 
4204*8fb009dcSAndroid Build Coastguard Worker     // Connect a client and server.
4205*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(Connect());
4206*8fb009dcSAndroid Build Coastguard Worker 
4207*8fb009dcSAndroid Build Coastguard Worker     if (enable_partial_write) {
4208*8fb009dcSAndroid Build Coastguard Worker       SSL_set_mode(client_.get(), SSL_MODE_ENABLE_PARTIAL_WRITE);
4209*8fb009dcSAndroid Build Coastguard Worker     }
4210*8fb009dcSAndroid Build Coastguard Worker 
4211*8fb009dcSAndroid Build Coastguard Worker     // Write without reading until the buffer is full and we have an unfinished
4212*8fb009dcSAndroid Build Coastguard Worker     // write. Keep a count so we may reread it again later. "hello!" will be
4213*8fb009dcSAndroid Build Coastguard Worker     // written in two chunks, "hello" and "!".
4214*8fb009dcSAndroid Build Coastguard Worker     char data[] = "hello!";
4215*8fb009dcSAndroid Build Coastguard Worker     static const int kChunkLen = 5;  // The length of "hello".
4216*8fb009dcSAndroid Build Coastguard Worker     unsigned count = 0;
4217*8fb009dcSAndroid Build Coastguard Worker     for (;;) {
4218*8fb009dcSAndroid Build Coastguard Worker       int ret = SSL_write(client_.get(), data, kChunkLen);
4219*8fb009dcSAndroid Build Coastguard Worker       if (ret <= 0) {
4220*8fb009dcSAndroid Build Coastguard Worker         ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
4221*8fb009dcSAndroid Build Coastguard Worker         break;
4222*8fb009dcSAndroid Build Coastguard Worker       }
4223*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(ret, 5);
4224*8fb009dcSAndroid Build Coastguard Worker       count++;
4225*8fb009dcSAndroid Build Coastguard Worker     }
4226*8fb009dcSAndroid Build Coastguard Worker 
4227*8fb009dcSAndroid Build Coastguard Worker     // Retrying with the same parameters is legal.
4228*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(
4229*8fb009dcSAndroid Build Coastguard Worker         SSL_get_error(client_.get(), SSL_write(client_.get(), data, kChunkLen)),
4230*8fb009dcSAndroid Build Coastguard Worker         SSL_ERROR_WANT_WRITE);
4231*8fb009dcSAndroid Build Coastguard Worker 
4232*8fb009dcSAndroid Build Coastguard Worker     // Retrying with the same buffer but shorter length is not legal.
4233*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_get_error(client_.get(),
4234*8fb009dcSAndroid Build Coastguard Worker                             SSL_write(client_.get(), data, kChunkLen - 1)),
4235*8fb009dcSAndroid Build Coastguard Worker               SSL_ERROR_SSL);
4236*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
4237*8fb009dcSAndroid Build Coastguard Worker 
4238*8fb009dcSAndroid Build Coastguard Worker     // Retrying with a different buffer pointer is not legal.
4239*8fb009dcSAndroid Build Coastguard Worker     char data2[] = "hello";
4240*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_get_error(client_.get(),
4241*8fb009dcSAndroid Build Coastguard Worker                             SSL_write(client_.get(), data2, kChunkLen)),
4242*8fb009dcSAndroid Build Coastguard Worker               SSL_ERROR_SSL);
4243*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
4244*8fb009dcSAndroid Build Coastguard Worker 
4245*8fb009dcSAndroid Build Coastguard Worker     // With |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, the buffer may move.
4246*8fb009dcSAndroid Build Coastguard Worker     SSL_set_mode(client_.get(), SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
4247*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_get_error(client_.get(),
4248*8fb009dcSAndroid Build Coastguard Worker                             SSL_write(client_.get(), data2, kChunkLen)),
4249*8fb009dcSAndroid Build Coastguard Worker               SSL_ERROR_WANT_WRITE);
4250*8fb009dcSAndroid Build Coastguard Worker 
4251*8fb009dcSAndroid Build Coastguard Worker     // |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| does not disable length checks.
4252*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_get_error(client_.get(),
4253*8fb009dcSAndroid Build Coastguard Worker                             SSL_write(client_.get(), data2, kChunkLen - 1)),
4254*8fb009dcSAndroid Build Coastguard Worker               SSL_ERROR_SSL);
4255*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_WRITE_RETRY));
4256*8fb009dcSAndroid Build Coastguard Worker 
4257*8fb009dcSAndroid Build Coastguard Worker     // Retrying with a larger buffer is legal.
4258*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_get_error(client_.get(),
4259*8fb009dcSAndroid Build Coastguard Worker                             SSL_write(client_.get(), data, kChunkLen + 1)),
4260*8fb009dcSAndroid Build Coastguard Worker               SSL_ERROR_WANT_WRITE);
4261*8fb009dcSAndroid Build Coastguard Worker 
4262*8fb009dcSAndroid Build Coastguard Worker     // Drain the buffer.
4263*8fb009dcSAndroid Build Coastguard Worker     char buf[20];
4264*8fb009dcSAndroid Build Coastguard Worker     for (unsigned i = 0; i < count; i++) {
4265*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4266*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4267*8fb009dcSAndroid Build Coastguard Worker     }
4268*8fb009dcSAndroid Build Coastguard Worker 
4269*8fb009dcSAndroid Build Coastguard Worker     // Now that there is space, a retry with a larger buffer should flush the
4270*8fb009dcSAndroid Build Coastguard Worker     // pending record, skip over that many bytes of input (on assumption they
4271*8fb009dcSAndroid Build Coastguard Worker     // are the same), and write the remainder. If SSL_MODE_ENABLE_PARTIAL_WRITE
4272*8fb009dcSAndroid Build Coastguard Worker     // is set, this will complete in two steps.
4273*8fb009dcSAndroid Build Coastguard Worker     char data_longer[] = "_____!!!!!";
4274*8fb009dcSAndroid Build Coastguard Worker     if (enable_partial_write) {
4275*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4276*8fb009dcSAndroid Build Coastguard Worker                 kChunkLen);
4277*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen),
4278*8fb009dcSAndroid Build Coastguard Worker                 kChunkLen);
4279*8fb009dcSAndroid Build Coastguard Worker     } else {
4280*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4281*8fb009dcSAndroid Build Coastguard Worker                 2 * kChunkLen);
4282*8fb009dcSAndroid Build Coastguard Worker     }
4283*8fb009dcSAndroid Build Coastguard Worker 
4284*8fb009dcSAndroid Build Coastguard Worker     // Check the last write was correct. The data will be spread over two
4285*8fb009dcSAndroid Build Coastguard Worker     // records, so SSL_read returns twice.
4286*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4287*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4288*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4289*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0);
4290*8fb009dcSAndroid Build Coastguard Worker 
4291*8fb009dcSAndroid Build Coastguard Worker     // Fill the transport buffer again. This time only leave room for one
4292*8fb009dcSAndroid Build Coastguard Worker     // record.
4293*8fb009dcSAndroid Build Coastguard Worker     count = 0;
4294*8fb009dcSAndroid Build Coastguard Worker     for (;;) {
4295*8fb009dcSAndroid Build Coastguard Worker       int ret = SSL_write(client_.get(), data, kChunkLen);
4296*8fb009dcSAndroid Build Coastguard Worker       if (ret <= 0) {
4297*8fb009dcSAndroid Build Coastguard Worker         ASSERT_EQ(SSL_get_error(client_.get(), ret), SSL_ERROR_WANT_WRITE);
4298*8fb009dcSAndroid Build Coastguard Worker         break;
4299*8fb009dcSAndroid Build Coastguard Worker       }
4300*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(ret, 5);
4301*8fb009dcSAndroid Build Coastguard Worker       count++;
4302*8fb009dcSAndroid Build Coastguard Worker     }
4303*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4304*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4305*8fb009dcSAndroid Build Coastguard Worker     count--;
4306*8fb009dcSAndroid Build Coastguard Worker 
4307*8fb009dcSAndroid Build Coastguard Worker     // Retry the last write, with a longer input. The first half is the most
4308*8fb009dcSAndroid Build Coastguard Worker     // recently failed write, from filling the buffer. |SSL_write| should write
4309*8fb009dcSAndroid Build Coastguard Worker     // that to the transport, and then attempt to write the second half.
4310*8fb009dcSAndroid Build Coastguard Worker     int ret = SSL_write(client_.get(), data_longer, 2 * kChunkLen);
4311*8fb009dcSAndroid Build Coastguard Worker     if (enable_partial_write) {
4312*8fb009dcSAndroid Build Coastguard Worker       // If partial writes are allowed, the write will succeed partially.
4313*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(ret, kChunkLen);
4314*8fb009dcSAndroid Build Coastguard Worker 
4315*8fb009dcSAndroid Build Coastguard Worker       // Check the first half and make room for another record.
4316*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4317*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4318*8fb009dcSAndroid Build Coastguard Worker       count--;
4319*8fb009dcSAndroid Build Coastguard Worker 
4320*8fb009dcSAndroid Build Coastguard Worker       // Finish writing the input.
4321*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_write(client_.get(), data_longer + kChunkLen, kChunkLen),
4322*8fb009dcSAndroid Build Coastguard Worker                 kChunkLen);
4323*8fb009dcSAndroid Build Coastguard Worker     } else {
4324*8fb009dcSAndroid Build Coastguard Worker       // Otherwise, although the first half made it to the transport, the second
4325*8fb009dcSAndroid Build Coastguard Worker       // half is blocked.
4326*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(ret, -1);
4327*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_WRITE);
4328*8fb009dcSAndroid Build Coastguard Worker 
4329*8fb009dcSAndroid Build Coastguard Worker       // Check the first half and make room for another record.
4330*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4331*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4332*8fb009dcSAndroid Build Coastguard Worker       count--;
4333*8fb009dcSAndroid Build Coastguard Worker 
4334*8fb009dcSAndroid Build Coastguard Worker       // Retrying with fewer bytes than previously attempted is an error. If the
4335*8fb009dcSAndroid Build Coastguard Worker       // input length is less than the number of bytes successfully written, the
4336*8fb009dcSAndroid Build Coastguard Worker       // check happens at a different point, with a different error.
4337*8fb009dcSAndroid Build Coastguard Worker       //
4338*8fb009dcSAndroid Build Coastguard Worker       // TODO(davidben): Should these cases use the same error?
4339*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(
4340*8fb009dcSAndroid Build Coastguard Worker           SSL_get_error(client_.get(),
4341*8fb009dcSAndroid Build Coastguard Worker                         SSL_write(client_.get(), data_longer, kChunkLen - 1)),
4342*8fb009dcSAndroid Build Coastguard Worker           SSL_ERROR_SSL);
4343*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ExpectSingleError(ERR_LIB_SSL, SSL_R_BAD_LENGTH));
4344*8fb009dcSAndroid Build Coastguard Worker 
4345*8fb009dcSAndroid Build Coastguard Worker       // Complete the write with the correct retry.
4346*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_write(client_.get(), data_longer, 2 * kChunkLen),
4347*8fb009dcSAndroid Build Coastguard Worker                 2 * kChunkLen);
4348*8fb009dcSAndroid Build Coastguard Worker     }
4349*8fb009dcSAndroid Build Coastguard Worker 
4350*8fb009dcSAndroid Build Coastguard Worker     // Drain the input and ensure everything was written correctly.
4351*8fb009dcSAndroid Build Coastguard Worker     for (unsigned i = 0; i < count; i++) {
4352*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4353*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4354*8fb009dcSAndroid Build Coastguard Worker     }
4355*8fb009dcSAndroid Build Coastguard Worker 
4356*8fb009dcSAndroid Build Coastguard Worker     // The final write is spread over two records.
4357*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4358*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(OPENSSL_memcmp(buf, "hello", kChunkLen), 0);
4359*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_read(server_.get(), buf, sizeof(buf)), kChunkLen);
4360*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(OPENSSL_memcmp(buf, "!!!!!", kChunkLen), 0);
4361*8fb009dcSAndroid Build Coastguard Worker   }
4362*8fb009dcSAndroid Build Coastguard Worker }
4363*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,RecordCallback)4364*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, RecordCallback) {
4365*8fb009dcSAndroid Build Coastguard Worker   for (bool test_server : {true, false}) {
4366*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(test_server);
4367*8fb009dcSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(ResetContexts());
4368*8fb009dcSAndroid Build Coastguard Worker 
4369*8fb009dcSAndroid Build Coastguard Worker     bool read_seen = false;
4370*8fb009dcSAndroid Build Coastguard Worker     bool write_seen = false;
4371*8fb009dcSAndroid Build Coastguard Worker     auto cb = [&](int is_write, int cb_version, int cb_type, const void *buf,
4372*8fb009dcSAndroid Build Coastguard Worker                   size_t len, SSL *ssl) {
4373*8fb009dcSAndroid Build Coastguard Worker       if (cb_type != SSL3_RT_HEADER) {
4374*8fb009dcSAndroid Build Coastguard Worker         return;
4375*8fb009dcSAndroid Build Coastguard Worker       }
4376*8fb009dcSAndroid Build Coastguard Worker 
4377*8fb009dcSAndroid Build Coastguard Worker       // The callback does not report a version for records.
4378*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(0, cb_version);
4379*8fb009dcSAndroid Build Coastguard Worker 
4380*8fb009dcSAndroid Build Coastguard Worker       if (is_write) {
4381*8fb009dcSAndroid Build Coastguard Worker         write_seen = true;
4382*8fb009dcSAndroid Build Coastguard Worker       } else {
4383*8fb009dcSAndroid Build Coastguard Worker         read_seen = true;
4384*8fb009dcSAndroid Build Coastguard Worker       }
4385*8fb009dcSAndroid Build Coastguard Worker 
4386*8fb009dcSAndroid Build Coastguard Worker       // Sanity-check that the record header is plausible.
4387*8fb009dcSAndroid Build Coastguard Worker       CBS cbs;
4388*8fb009dcSAndroid Build Coastguard Worker       CBS_init(&cbs, reinterpret_cast<const uint8_t *>(buf), len);
4389*8fb009dcSAndroid Build Coastguard Worker       uint8_t type;
4390*8fb009dcSAndroid Build Coastguard Worker       uint16_t record_version, length;
4391*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CBS_get_u8(&cbs, &type));
4392*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CBS_get_u16(&cbs, &record_version));
4393*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(record_version & 0xff00, version() & 0xff00);
4394*8fb009dcSAndroid Build Coastguard Worker       if (is_dtls()) {
4395*8fb009dcSAndroid Build Coastguard Worker         uint16_t epoch;
4396*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(CBS_get_u16(&cbs, &epoch));
4397*8fb009dcSAndroid Build Coastguard Worker         EXPECT_TRUE(epoch == 0 || epoch == 1) << "Invalid epoch: " << epoch;
4398*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(CBS_skip(&cbs, 6));
4399*8fb009dcSAndroid Build Coastguard Worker       }
4400*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CBS_get_u16(&cbs, &length));
4401*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(0u, CBS_len(&cbs));
4402*8fb009dcSAndroid Build Coastguard Worker     };
4403*8fb009dcSAndroid Build Coastguard Worker     using CallbackType = decltype(cb);
4404*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX *ctx = test_server ? server_ctx_.get() : client_ctx_.get();
4405*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_msg_callback(
4406*8fb009dcSAndroid Build Coastguard Worker         ctx, [](int is_write, int cb_version, int cb_type, const void *buf,
4407*8fb009dcSAndroid Build Coastguard Worker                 size_t len, SSL *ssl, void *arg) {
4408*8fb009dcSAndroid Build Coastguard Worker           CallbackType *cb_ptr = reinterpret_cast<CallbackType *>(arg);
4409*8fb009dcSAndroid Build Coastguard Worker           (*cb_ptr)(is_write, cb_version, cb_type, buf, len, ssl);
4410*8fb009dcSAndroid Build Coastguard Worker         });
4411*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_msg_callback_arg(ctx, &cb);
4412*8fb009dcSAndroid Build Coastguard Worker 
4413*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(Connect());
4414*8fb009dcSAndroid Build Coastguard Worker 
4415*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(read_seen);
4416*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(write_seen);
4417*8fb009dcSAndroid Build Coastguard Worker   }
4418*8fb009dcSAndroid Build Coastguard Worker }
4419*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,GetServerName)4420*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, GetServerName) {
4421*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
4422*8fb009dcSAndroid Build Coastguard Worker   config.servername = "host1";
4423*8fb009dcSAndroid Build Coastguard Worker 
4424*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_servername_callback(
4425*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
4426*8fb009dcSAndroid Build Coastguard Worker         // During the handshake, |SSL_get_servername| must match |config|.
4427*8fb009dcSAndroid Build Coastguard Worker         ClientConfig *config_p = reinterpret_cast<ClientConfig *>(arg);
4428*8fb009dcSAndroid Build Coastguard Worker         EXPECT_STREQ(config_p->servername.c_str(),
4429*8fb009dcSAndroid Build Coastguard Worker                      SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name));
4430*8fb009dcSAndroid Build Coastguard Worker         return SSL_TLSEXT_ERR_OK;
4431*8fb009dcSAndroid Build Coastguard Worker       });
4432*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_servername_arg(server_ctx_.get(), &config);
4433*8fb009dcSAndroid Build Coastguard Worker 
4434*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect(config));
4435*8fb009dcSAndroid Build Coastguard Worker   // After the handshake, it must also be available.
4436*8fb009dcSAndroid Build Coastguard Worker   EXPECT_STREQ(config.servername.c_str(),
4437*8fb009dcSAndroid Build Coastguard Worker                SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4438*8fb009dcSAndroid Build Coastguard Worker 
4439*8fb009dcSAndroid Build Coastguard Worker   // Establish a session under host1.
4440*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4441*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
4442*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
4443*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get(), config);
4444*8fb009dcSAndroid Build Coastguard Worker 
4445*8fb009dcSAndroid Build Coastguard Worker   // If the client resumes a session with a different name, |SSL_get_servername|
4446*8fb009dcSAndroid Build Coastguard Worker   // must return the new name.
4447*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
4448*8fb009dcSAndroid Build Coastguard Worker   config.session = session.get();
4449*8fb009dcSAndroid Build Coastguard Worker   config.servername = "host2";
4450*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect(config));
4451*8fb009dcSAndroid Build Coastguard Worker   EXPECT_STREQ(config.servername.c_str(),
4452*8fb009dcSAndroid Build Coastguard Worker                SSL_get_servername(server_.get(), TLSEXT_NAMETYPE_host_name));
4453*8fb009dcSAndroid Build Coastguard Worker }
4454*8fb009dcSAndroid Build Coastguard Worker 
4455*8fb009dcSAndroid Build Coastguard Worker // Test that session cache mode bits are honored in the client session callback.
TEST_P(SSLVersionTest,ClientSessionCacheMode)4456*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, ClientSessionCacheMode) {
4457*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_OFF);
4458*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4459*8fb009dcSAndroid Build Coastguard Worker 
4460*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_CLIENT);
4461*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4462*8fb009dcSAndroid Build Coastguard Worker 
4463*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_SERVER);
4464*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
4465*8fb009dcSAndroid Build Coastguard Worker }
4466*8fb009dcSAndroid Build Coastguard Worker 
4467*8fb009dcSAndroid Build Coastguard Worker // Test that all versions survive tiny write buffers. In particular, TLS 1.3
4468*8fb009dcSAndroid Build Coastguard Worker // NewSessionTickets are written post-handshake. Servers that block
4469*8fb009dcSAndroid Build Coastguard Worker // |SSL_do_handshake| on writing them will deadlock if clients are not draining
4470*8fb009dcSAndroid Build Coastguard Worker // the buffer. Test that we do not do this.
TEST_P(SSLVersionTest,SmallBuffer)4471*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SmallBuffer) {
4472*8fb009dcSAndroid Build Coastguard Worker   // DTLS is a datagram protocol and requires packet-sized buffers.
4473*8fb009dcSAndroid Build Coastguard Worker   if (is_dtls()) {
4474*8fb009dcSAndroid Build Coastguard Worker     return;
4475*8fb009dcSAndroid Build Coastguard Worker   }
4476*8fb009dcSAndroid Build Coastguard Worker 
4477*8fb009dcSAndroid Build Coastguard Worker   // Test both flushing NewSessionTickets with a zero-sized write and
4478*8fb009dcSAndroid Build Coastguard Worker   // non-zero-sized write.
4479*8fb009dcSAndroid Build Coastguard Worker   for (bool use_zero_write : {false, true}) {
4480*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(use_zero_write);
4481*8fb009dcSAndroid Build Coastguard Worker 
4482*8fb009dcSAndroid Build Coastguard Worker     g_last_session = nullptr;
4483*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
4484*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
4485*8fb009dcSAndroid Build Coastguard Worker 
4486*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client(SSL_new(client_ctx_.get())),
4487*8fb009dcSAndroid Build Coastguard Worker         server(SSL_new(server_ctx_.get()));
4488*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(client);
4489*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server);
4490*8fb009dcSAndroid Build Coastguard Worker     SSL_set_connect_state(client.get());
4491*8fb009dcSAndroid Build Coastguard Worker     SSL_set_accept_state(server.get());
4492*8fb009dcSAndroid Build Coastguard Worker 
4493*8fb009dcSAndroid Build Coastguard Worker     // Use a tiny buffer.
4494*8fb009dcSAndroid Build Coastguard Worker     BIO *bio1, *bio2;
4495*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
4496*8fb009dcSAndroid Build Coastguard Worker 
4497*8fb009dcSAndroid Build Coastguard Worker     // SSL_set_bio takes ownership.
4498*8fb009dcSAndroid Build Coastguard Worker     SSL_set_bio(client.get(), bio1, bio1);
4499*8fb009dcSAndroid Build Coastguard Worker     SSL_set_bio(server.get(), bio2, bio2);
4500*8fb009dcSAndroid Build Coastguard Worker 
4501*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4502*8fb009dcSAndroid Build Coastguard Worker     if (version() >= TLS1_3_VERSION) {
4503*8fb009dcSAndroid Build Coastguard Worker       // The post-handshake ticket should not have been processed yet.
4504*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(g_last_session);
4505*8fb009dcSAndroid Build Coastguard Worker     }
4506*8fb009dcSAndroid Build Coastguard Worker 
4507*8fb009dcSAndroid Build Coastguard Worker     if (use_zero_write) {
4508*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
4509*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(g_last_session);
4510*8fb009dcSAndroid Build Coastguard Worker     }
4511*8fb009dcSAndroid Build Coastguard Worker 
4512*8fb009dcSAndroid Build Coastguard Worker     // Send some data from server to client. If |use_zero_write| is false, this
4513*8fb009dcSAndroid Build Coastguard Worker     // will also flush the NewSessionTickets.
4514*8fb009dcSAndroid Build Coastguard Worker     static const char kMessage[] = "hello world";
4515*8fb009dcSAndroid Build Coastguard Worker     char buf[sizeof(kMessage)];
4516*8fb009dcSAndroid Build Coastguard Worker     for (;;) {
4517*8fb009dcSAndroid Build Coastguard Worker       int server_ret = SSL_write(server.get(), kMessage, sizeof(kMessage));
4518*8fb009dcSAndroid Build Coastguard Worker       int server_err = SSL_get_error(server.get(), server_ret);
4519*8fb009dcSAndroid Build Coastguard Worker       int client_ret = SSL_read(client.get(), buf, sizeof(buf));
4520*8fb009dcSAndroid Build Coastguard Worker       int client_err = SSL_get_error(client.get(), client_ret);
4521*8fb009dcSAndroid Build Coastguard Worker 
4522*8fb009dcSAndroid Build Coastguard Worker       // The server will write a single record, so every iteration should see
4523*8fb009dcSAndroid Build Coastguard Worker       // |SSL_ERROR_WANT_WRITE| and |SSL_ERROR_WANT_READ|, until the final
4524*8fb009dcSAndroid Build Coastguard Worker       // iteration, where both will complete.
4525*8fb009dcSAndroid Build Coastguard Worker       if (server_ret > 0) {
4526*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(server_ret, static_cast<int>(sizeof(kMessage)));
4527*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(client_ret, static_cast<int>(sizeof(kMessage)));
4528*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(Bytes(buf), Bytes(kMessage));
4529*8fb009dcSAndroid Build Coastguard Worker         break;
4530*8fb009dcSAndroid Build Coastguard Worker       }
4531*8fb009dcSAndroid Build Coastguard Worker 
4532*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(server_ret, -1);
4533*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(server_err, SSL_ERROR_WANT_WRITE);
4534*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(client_ret, -1);
4535*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
4536*8fb009dcSAndroid Build Coastguard Worker     }
4537*8fb009dcSAndroid Build Coastguard Worker 
4538*8fb009dcSAndroid Build Coastguard Worker     // The NewSessionTickets should have been flushed and processed.
4539*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(g_last_session);
4540*8fb009dcSAndroid Build Coastguard Worker   }
4541*8fb009dcSAndroid Build Coastguard Worker }
4542*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,AddChainCertHack)4543*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, AddChainCertHack) {
4544*8fb009dcSAndroid Build Coastguard Worker   // Ensure that we don't accidently break the hack that we have in place to
4545*8fb009dcSAndroid Build Coastguard Worker   // keep curl and serf happy when they use an |X509| even after transfering
4546*8fb009dcSAndroid Build Coastguard Worker   // ownership.
4547*8fb009dcSAndroid Build Coastguard Worker 
4548*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4549*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4550*8fb009dcSAndroid Build Coastguard Worker   X509 *cert = GetTestCertificate().release();
4551*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
4552*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_add0_chain_cert(ctx.get(), cert);
4553*8fb009dcSAndroid Build Coastguard Worker 
4554*8fb009dcSAndroid Build Coastguard Worker   // This should not trigger a use-after-free.
4555*8fb009dcSAndroid Build Coastguard Worker   X509_cmp(cert, cert);
4556*8fb009dcSAndroid Build Coastguard Worker }
4557*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,GetCertificate)4558*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, GetCertificate) {
4559*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4560*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4561*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetTestCertificate();
4562*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
4563*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
4564*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
4565*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
4566*8fb009dcSAndroid Build Coastguard Worker 
4567*8fb009dcSAndroid Build Coastguard Worker   X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
4568*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert2);
4569*8fb009dcSAndroid Build Coastguard Worker   X509 *cert3 = SSL_get_certificate(ssl.get());
4570*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert3);
4571*8fb009dcSAndroid Build Coastguard Worker 
4572*8fb009dcSAndroid Build Coastguard Worker   // The old and new certificates must be identical.
4573*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
4574*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_cmp(cert.get(), cert3));
4575*8fb009dcSAndroid Build Coastguard Worker 
4576*8fb009dcSAndroid Build Coastguard Worker   uint8_t *der = nullptr;
4577*8fb009dcSAndroid Build Coastguard Worker   long der_len = i2d_X509(cert.get(), &der);
4578*8fb009dcSAndroid Build Coastguard Worker   ASSERT_LT(0, der_len);
4579*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_der(der);
4580*8fb009dcSAndroid Build Coastguard Worker 
4581*8fb009dcSAndroid Build Coastguard Worker   uint8_t *der2 = nullptr;
4582*8fb009dcSAndroid Build Coastguard Worker   long der2_len = i2d_X509(cert2, &der2);
4583*8fb009dcSAndroid Build Coastguard Worker   ASSERT_LT(0, der2_len);
4584*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_der2(der2);
4585*8fb009dcSAndroid Build Coastguard Worker 
4586*8fb009dcSAndroid Build Coastguard Worker   uint8_t *der3 = nullptr;
4587*8fb009dcSAndroid Build Coastguard Worker   long der3_len = i2d_X509(cert3, &der3);
4588*8fb009dcSAndroid Build Coastguard Worker   ASSERT_LT(0, der3_len);
4589*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> free_der3(der3);
4590*8fb009dcSAndroid Build Coastguard Worker 
4591*8fb009dcSAndroid Build Coastguard Worker   // They must also encode identically.
4592*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(der, der_len), Bytes(der2, der2_len));
4593*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(der, der_len), Bytes(der3, der3_len));
4594*8fb009dcSAndroid Build Coastguard Worker }
4595*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SetChainAndKeyMismatch)4596*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SetChainAndKeyMismatch) {
4597*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_with_buffers_method()));
4598*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4599*8fb009dcSAndroid Build Coastguard Worker 
4600*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4601*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4602*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4603*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4604*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER*> chain = {
4605*8fb009dcSAndroid Build Coastguard Worker       leaf.get(),
4606*8fb009dcSAndroid Build Coastguard Worker   };
4607*8fb009dcSAndroid Build Coastguard Worker 
4608*8fb009dcSAndroid Build Coastguard Worker   // Should fail because |GetTestKey| doesn't match the chain-test certificate.
4609*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_CTX_set_chain_and_key(ctx.get(), chain.data(), chain.size(),
4610*8fb009dcSAndroid Build Coastguard Worker                                          key.get(), nullptr));
4611*8fb009dcSAndroid Build Coastguard Worker   ERR_clear_error();
4612*8fb009dcSAndroid Build Coastguard Worker }
4613*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CertThenKeyMismatch)4614*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CertThenKeyMismatch) {
4615*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4616*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4617*8fb009dcSAndroid Build Coastguard Worker 
4618*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4619*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4620*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf = GetChainTestCertificate();
4621*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4622*8fb009dcSAndroid Build Coastguard Worker 
4623*8fb009dcSAndroid Build Coastguard Worker   // There is no key or certificate, so |SSL_CTX_check_private_key| fails.
4624*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4625*8fb009dcSAndroid Build Coastguard Worker 
4626*8fb009dcSAndroid Build Coastguard Worker   // With only a certificate, |SSL_CTX_check_private_key| still fails.
4627*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4628*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4629*8fb009dcSAndroid Build Coastguard Worker 
4630*8fb009dcSAndroid Build Coastguard Worker   // The private key does not match the certificate, so it should fail.
4631*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4632*8fb009dcSAndroid Build Coastguard Worker 
4633*8fb009dcSAndroid Build Coastguard Worker   // Checking the private key fails, but this is really because there is still
4634*8fb009dcSAndroid Build Coastguard Worker   // no private key.
4635*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4636*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, SSL_CTX_get0_privatekey(ctx.get()));
4637*8fb009dcSAndroid Build Coastguard Worker }
4638*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,KeyThenCertMismatch)4639*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, KeyThenCertMismatch) {
4640*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4641*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4642*8fb009dcSAndroid Build Coastguard Worker 
4643*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4644*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4645*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf = GetChainTestCertificate();
4646*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4647*8fb009dcSAndroid Build Coastguard Worker 
4648*8fb009dcSAndroid Build Coastguard Worker   // There is no key or certificate, so |SSL_CTX_check_private_key| fails.
4649*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4650*8fb009dcSAndroid Build Coastguard Worker 
4651*8fb009dcSAndroid Build Coastguard Worker   // With only a key, |SSL_CTX_check_private_key| still fails.
4652*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4653*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4654*8fb009dcSAndroid Build Coastguard Worker 
4655*8fb009dcSAndroid Build Coastguard Worker   // If configuring a certificate that doesn't match the key, configuration
4656*8fb009dcSAndroid Build Coastguard Worker   // actually succeeds. We just silently drop the private key.
4657*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4658*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, SSL_CTX_get0_privatekey(ctx.get()));
4659*8fb009dcSAndroid Build Coastguard Worker 
4660*8fb009dcSAndroid Build Coastguard Worker   // Some callers configure the private key, then the certificate, and then
4661*8fb009dcSAndroid Build Coastguard Worker   // expect |SSL_CTX_check_private_key| to check consistency. It does, but only
4662*8fb009dcSAndroid Build Coastguard Worker   // by way of noticing there is no private key. The actual consistency check
4663*8fb009dcSAndroid Build Coastguard Worker   // happened in |SSL_CTX_use_certificate|.
4664*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_check_private_key(ctx.get()));
4665*8fb009dcSAndroid Build Coastguard Worker }
4666*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,OverrideCertAndKey)4667*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, OverrideCertAndKey) {
4668*8fb009dcSAndroid Build Coastguard Worker   // It is possible to override an existing certificate by configuring
4669*8fb009dcSAndroid Build Coastguard Worker   // certificate, then key, due to |SSL_CTX_use_certificate|'s above silent
4670*8fb009dcSAndroid Build Coastguard Worker   // dropping behavior.
4671*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4672*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4673*8fb009dcSAndroid Build Coastguard Worker 
4674*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4675*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4676*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf = GetTestCertificate();
4677*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4678*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key2 = GetChainTestKey();
4679*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key2);
4680*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf2 = GetChainTestCertificate();
4681*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf2);
4682*8fb009dcSAndroid Build Coastguard Worker 
4683*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4684*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4685*8fb009dcSAndroid Build Coastguard Worker 
4686*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf2.get()));
4687*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key2.get()));
4688*8fb009dcSAndroid Build Coastguard Worker }
4689*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,OverrideKeyMethodWithKey)4690*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, OverrideKeyMethodWithKey) {
4691*8fb009dcSAndroid Build Coastguard Worker   // Make an SSL_PRIVATE_KEY_METHOD that should never be called.
4692*8fb009dcSAndroid Build Coastguard Worker   static const SSL_PRIVATE_KEY_METHOD kErrorMethod = {
4693*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
4694*8fb009dcSAndroid Build Coastguard Worker          uint16_t signature_algorithm, const uint8_t *in,
4695*8fb009dcSAndroid Build Coastguard Worker          size_t in_len) { return ssl_private_key_failure; },
4696*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
4697*8fb009dcSAndroid Build Coastguard Worker          const uint8_t *in, size_t in_len) { return ssl_private_key_failure; },
4698*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out, size_t *out_len, size_t max_oun) {
4699*8fb009dcSAndroid Build Coastguard Worker         return ssl_private_key_failure;
4700*8fb009dcSAndroid Build Coastguard Worker       },
4701*8fb009dcSAndroid Build Coastguard Worker   };
4702*8fb009dcSAndroid Build Coastguard Worker 
4703*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
4704*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4705*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf = GetTestCertificate();
4706*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4707*8fb009dcSAndroid Build Coastguard Worker 
4708*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4709*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4710*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4711*8fb009dcSAndroid Build Coastguard Worker 
4712*8fb009dcSAndroid Build Coastguard Worker   // Configuring an |SSL_PRIVATE_KEY_METHOD| and then overwriting it with an
4713*8fb009dcSAndroid Build Coastguard Worker   // |EVP_PKEY| should clear the |SSL_PRIVATE_KEY_METHOD|.
4714*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_private_key_method(ctx.get(), &kErrorMethod);
4715*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4716*8fb009dcSAndroid Build Coastguard Worker 
4717*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4718*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4719*8fb009dcSAndroid Build Coastguard Worker }
4720*8fb009dcSAndroid Build Coastguard Worker 
4721*8fb009dcSAndroid Build Coastguard Worker // Configuring a chain and then overwriting it with a different chain should
4722*8fb009dcSAndroid Build Coastguard Worker // clear the old one.
TEST(SSLTest,OverrideChain)4723*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, OverrideChain) {
4724*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4725*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4726*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> leaf = GetChainTestCertificate();
4727*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4728*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> ca = GetChainTestIntermediate();
4729*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ca);
4730*8fb009dcSAndroid Build Coastguard Worker 
4731*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
4732*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(chain);
4733*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bssl::PushToStack(chain.get(), bssl::UpRef(ca)));
4734*8fb009dcSAndroid Build Coastguard Worker 
4735*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<STACK_OF(X509)> wrong_chain(sk_X509_new_null());
4736*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(wrong_chain);
4737*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bssl::PushToStack(wrong_chain.get(), bssl::UpRef(leaf)));
4738*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bssl::PushToStack(wrong_chain.get(), bssl::UpRef(leaf)));
4739*8fb009dcSAndroid Build Coastguard Worker 
4740*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4741*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4742*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), leaf.get()));
4743*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
4744*8fb009dcSAndroid Build Coastguard Worker 
4745*8fb009dcSAndroid Build Coastguard Worker   // Configure one chain, then replace it with another. Note this API considers
4746*8fb009dcSAndroid Build Coastguard Worker   // the chain to exclude the leaf.
4747*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_chain(ctx.get(), wrong_chain.get()));
4748*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_chain(ctx.get(), chain.get()));
4749*8fb009dcSAndroid Build Coastguard Worker 
4750*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4751*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4752*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ChainsEqual(SSL_get_peer_full_cert_chain(client.get()),
4753*8fb009dcSAndroid Build Coastguard Worker                           {leaf.get(), ca.get()}));
4754*8fb009dcSAndroid Build Coastguard Worker }
4755*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,OverrideChainAndKey)4756*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, OverrideChainAndKey) {
4757*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key1 = GetChainTestKey();
4758*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key1);
4759*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf1 = GetChainTestCertificateBuffer();
4760*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf1);
4761*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> ca1 = GetChainTestIntermediateBuffer();
4762*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ca1);
4763*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key2 = GetECDSATestKey();
4764*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key2);
4765*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf2 = GetECDSATestCertificateBuffer();
4766*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf2);
4767*8fb009dcSAndroid Build Coastguard Worker 
4768*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4769*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4770*8fb009dcSAndroid Build Coastguard Worker 
4771*8fb009dcSAndroid Build Coastguard Worker   // Configure one cert and key pair, then replace it with noather.
4772*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER *> certs = {leaf1.get(), ca1.get()};
4773*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_chain_and_key(ctx.get(), certs.data(), certs.size(),
4774*8fb009dcSAndroid Build Coastguard Worker                                         key1.get(), nullptr));
4775*8fb009dcSAndroid Build Coastguard Worker   certs = {leaf2.get()};
4776*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_chain_and_key(ctx.get(), certs.data(), certs.size(),
4777*8fb009dcSAndroid Build Coastguard Worker                                         key2.get(), nullptr));
4778*8fb009dcSAndroid Build Coastguard Worker 
4779*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4780*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4781*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(
4782*8fb009dcSAndroid Build Coastguard Worker       BuffersEqual(SSL_get0_peer_certificates(client.get()), {leaf2.get()}));
4783*8fb009dcSAndroid Build Coastguard Worker }
4784*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,OverrideCredentialChain)4785*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, OverrideCredentialChain) {
4786*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4787*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4788*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4789*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4790*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> ca = GetChainTestIntermediateBuffer();
4791*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ca);
4792*8fb009dcSAndroid Build Coastguard Worker 
4793*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER *> chain = {leaf.get(), ca.get()};
4794*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER *> wrong_chain = {leaf.get(), leaf.get(),
4795*8fb009dcSAndroid Build Coastguard Worker                                               leaf.get()};
4796*8fb009dcSAndroid Build Coastguard Worker 
4797*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
4798*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
4799*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CREDENTIAL> cred(SSL_CREDENTIAL_new_x509());
4800*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cred);
4801*8fb009dcSAndroid Build Coastguard Worker 
4802*8fb009dcSAndroid Build Coastguard Worker   // Configure one chain (including the leaf), then replace it with another.
4803*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CREDENTIAL_set1_cert_chain(cred.get(), wrong_chain.data(),
4804*8fb009dcSAndroid Build Coastguard Worker                                              wrong_chain.size()));
4805*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
4806*8fb009dcSAndroid Build Coastguard Worker       SSL_CREDENTIAL_set1_cert_chain(cred.get(), chain.data(), chain.size()));
4807*8fb009dcSAndroid Build Coastguard Worker 
4808*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CREDENTIAL_set1_private_key(cred.get(), key.get()));
4809*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_add1_credential(ctx.get(), cred.get()));
4810*8fb009dcSAndroid Build Coastguard Worker 
4811*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4812*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
4813*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(BuffersEqual(SSL_get0_peer_certificates(client.get()),
4814*8fb009dcSAndroid Build Coastguard Worker                            {leaf.get(), ca.get()}));
4815*8fb009dcSAndroid Build Coastguard Worker }
4816*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SetChainAndKeyCtx)4817*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SetChainAndKeyCtx) {
4818*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4819*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
4820*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4821*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
4822*8fb009dcSAndroid Build Coastguard Worker 
4823*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(nullptr, SSL_CTX_get0_chain(server_ctx.get()));
4824*8fb009dcSAndroid Build Coastguard Worker 
4825*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4826*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4827*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4828*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4829*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4830*8fb009dcSAndroid Build Coastguard Worker       GetChainTestIntermediateBuffer();
4831*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(intermediate);
4832*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER*> chain = {
4833*8fb009dcSAndroid Build Coastguard Worker       leaf.get(), intermediate.get(),
4834*8fb009dcSAndroid Build Coastguard Worker   };
4835*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
4836*8fb009dcSAndroid Build Coastguard Worker                                         chain.size(), key.get(), nullptr));
4837*8fb009dcSAndroid Build Coastguard Worker 
4838*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(chain.size(),
4839*8fb009dcSAndroid Build Coastguard Worker             sk_CRYPTO_BUFFER_num(SSL_CTX_get0_chain(server_ctx.get())));
4840*8fb009dcSAndroid Build Coastguard Worker 
4841*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
4842*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(), SSL_VERIFY_PEER,
4843*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4844*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_ok;
4845*8fb009dcSAndroid Build Coastguard Worker       });
4846*8fb009dcSAndroid Build Coastguard Worker 
4847*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4848*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4849*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
4850*8fb009dcSAndroid Build Coastguard Worker }
4851*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SetChainAndKeySSL)4852*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SetChainAndKeySSL) {
4853*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4854*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
4855*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4856*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
4857*8fb009dcSAndroid Build Coastguard Worker 
4858*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4859*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
4860*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx.get()));
4861*8fb009dcSAndroid Build Coastguard Worker   SSL_set_shed_handshake_config(client.get(), true);
4862*8fb009dcSAndroid Build Coastguard Worker   SSL_set_shed_handshake_config(server.get(), true);
4863*8fb009dcSAndroid Build Coastguard Worker 
4864*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(nullptr, SSL_get0_chain(server.get()));
4865*8fb009dcSAndroid Build Coastguard Worker 
4866*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4867*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4868*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4869*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4870*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4871*8fb009dcSAndroid Build Coastguard Worker       GetChainTestIntermediateBuffer();
4872*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(intermediate);
4873*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER*> chain = {
4874*8fb009dcSAndroid Build Coastguard Worker       leaf.get(), intermediate.get(),
4875*8fb009dcSAndroid Build Coastguard Worker   };
4876*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_chain_and_key(server.get(), chain.data(),
4877*8fb009dcSAndroid Build Coastguard Worker                                     chain.size(), key.get(), nullptr));
4878*8fb009dcSAndroid Build Coastguard Worker 
4879*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(chain.size(),
4880*8fb009dcSAndroid Build Coastguard Worker             sk_CRYPTO_BUFFER_num(SSL_get0_chain(server.get())));
4881*8fb009dcSAndroid Build Coastguard Worker 
4882*8fb009dcSAndroid Build Coastguard Worker   SSL_set_custom_verify(
4883*8fb009dcSAndroid Build Coastguard Worker       client.get(), SSL_VERIFY_PEER,
4884*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4885*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_ok;
4886*8fb009dcSAndroid Build Coastguard Worker       });
4887*8fb009dcSAndroid Build Coastguard Worker 
4888*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
4889*8fb009dcSAndroid Build Coastguard Worker 
4890*8fb009dcSAndroid Build Coastguard Worker   // The server is configured to shed handshake config, so the certificate is no
4891*8fb009dcSAndroid Build Coastguard Worker   // longer available after the handshake.
4892*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(nullptr, SSL_get0_chain(server.get()));
4893*8fb009dcSAndroid Build Coastguard Worker }
4894*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,BuffersFailWithoutCustomVerify)4895*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, BuffersFailWithoutCustomVerify) {
4896*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4897*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
4898*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4899*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
4900*8fb009dcSAndroid Build Coastguard Worker 
4901*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4902*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4903*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4904*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4905*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4906*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
4907*8fb009dcSAndroid Build Coastguard Worker                                         chain.size(), key.get(), nullptr));
4908*8fb009dcSAndroid Build Coastguard Worker 
4909*8fb009dcSAndroid Build Coastguard Worker   // Without SSL_CTX_set_custom_verify(), i.e. with everything in the default
4910*8fb009dcSAndroid Build Coastguard Worker   // configuration, certificate verification should fail.
4911*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4912*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4913*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx.get()));
4914*8fb009dcSAndroid Build Coastguard Worker 
4915*8fb009dcSAndroid Build Coastguard Worker   // Whereas with a verifier, the connection should succeed.
4916*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
4917*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(), SSL_VERIFY_PEER,
4918*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4919*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_ok;
4920*8fb009dcSAndroid Build Coastguard Worker       });
4921*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4922*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
4923*8fb009dcSAndroid Build Coastguard Worker }
4924*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CustomVerify)4925*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CustomVerify) {
4926*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4927*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
4928*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4929*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
4930*8fb009dcSAndroid Build Coastguard Worker 
4931*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4932*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4933*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4934*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4935*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER*> chain = { leaf.get() };
4936*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
4937*8fb009dcSAndroid Build Coastguard Worker                                         chain.size(), key.get(), nullptr));
4938*8fb009dcSAndroid Build Coastguard Worker 
4939*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
4940*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(), SSL_VERIFY_PEER,
4941*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4942*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_ok;
4943*8fb009dcSAndroid Build Coastguard Worker       });
4944*8fb009dcSAndroid Build Coastguard Worker 
4945*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
4946*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4947*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
4948*8fb009dcSAndroid Build Coastguard Worker 
4949*8fb009dcSAndroid Build Coastguard Worker   // With SSL_VERIFY_PEER, ssl_verify_invalid should result in a dropped
4950*8fb009dcSAndroid Build Coastguard Worker   // connection.
4951*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
4952*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(), SSL_VERIFY_PEER,
4953*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4954*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_invalid;
4955*8fb009dcSAndroid Build Coastguard Worker       });
4956*8fb009dcSAndroid Build Coastguard Worker 
4957*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4958*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx.get()));
4959*8fb009dcSAndroid Build Coastguard Worker 
4960*8fb009dcSAndroid Build Coastguard Worker   // But with SSL_VERIFY_NONE, ssl_verify_invalid should not cause a dropped
4961*8fb009dcSAndroid Build Coastguard Worker   // connection.
4962*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
4963*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(), SSL_VERIFY_NONE,
4964*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
4965*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_invalid;
4966*8fb009dcSAndroid Build Coastguard Worker       });
4967*8fb009dcSAndroid Build Coastguard Worker 
4968*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
4969*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
4970*8fb009dcSAndroid Build Coastguard Worker }
4971*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ClientCABuffers)4972*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ClientCABuffers) {
4973*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4974*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
4975*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_with_buffers_method()));
4976*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
4977*8fb009dcSAndroid Build Coastguard Worker 
4978*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
4979*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
4980*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> leaf = GetChainTestCertificateBuffer();
4981*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(leaf);
4982*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> intermediate =
4983*8fb009dcSAndroid Build Coastguard Worker       GetChainTestIntermediateBuffer();
4984*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(intermediate);
4985*8fb009dcSAndroid Build Coastguard Worker   std::vector<CRYPTO_BUFFER *> chain = {
4986*8fb009dcSAndroid Build Coastguard Worker       leaf.get(),
4987*8fb009dcSAndroid Build Coastguard Worker       intermediate.get(),
4988*8fb009dcSAndroid Build Coastguard Worker   };
4989*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_chain_and_key(server_ctx.get(), chain.data(),
4990*8fb009dcSAndroid Build Coastguard Worker                                         chain.size(), key.get(), nullptr));
4991*8fb009dcSAndroid Build Coastguard Worker 
4992*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<CRYPTO_BUFFER> ca_name(
4993*8fb009dcSAndroid Build Coastguard Worker       CRYPTO_BUFFER_new(kTestName, sizeof(kTestName), nullptr));
4994*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ca_name);
4995*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<STACK_OF(CRYPTO_BUFFER)> ca_names(
4996*8fb009dcSAndroid Build Coastguard Worker       sk_CRYPTO_BUFFER_new_null());
4997*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ca_names);
4998*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(PushToStack(ca_names.get(), std::move(ca_name)));
4999*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set0_client_CAs(server_ctx.get(), ca_names.release());
5000*8fb009dcSAndroid Build Coastguard Worker 
5001*8fb009dcSAndroid Build Coastguard Worker   // Configure client and server to accept all certificates.
5002*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
5003*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(), SSL_VERIFY_PEER,
5004*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5005*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_ok;
5006*8fb009dcSAndroid Build Coastguard Worker       });
5007*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
5008*8fb009dcSAndroid Build Coastguard Worker       server_ctx.get(), SSL_VERIFY_PEER,
5009*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
5010*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_ok;
5011*8fb009dcSAndroid Build Coastguard Worker       });
5012*8fb009dcSAndroid Build Coastguard Worker 
5013*8fb009dcSAndroid Build Coastguard Worker   bool cert_cb_called = false;
5014*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_cb(
5015*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(),
5016*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, void *arg) -> int {
5017*8fb009dcSAndroid Build Coastguard Worker         const STACK_OF(CRYPTO_BUFFER) *peer_names =
5018*8fb009dcSAndroid Build Coastguard Worker             SSL_get0_server_requested_CAs(ssl);
5019*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(1u, sk_CRYPTO_BUFFER_num(peer_names));
5020*8fb009dcSAndroid Build Coastguard Worker         CRYPTO_BUFFER *peer_name = sk_CRYPTO_BUFFER_value(peer_names, 0);
5021*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(Bytes(kTestName), Bytes(CRYPTO_BUFFER_data(peer_name),
5022*8fb009dcSAndroid Build Coastguard Worker                                           CRYPTO_BUFFER_len(peer_name)));
5023*8fb009dcSAndroid Build Coastguard Worker         *reinterpret_cast<bool *>(arg) = true;
5024*8fb009dcSAndroid Build Coastguard Worker         return 1;
5025*8fb009dcSAndroid Build Coastguard Worker       },
5026*8fb009dcSAndroid Build Coastguard Worker       &cert_cb_called);
5027*8fb009dcSAndroid Build Coastguard Worker 
5028*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
5029*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5030*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
5031*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(cert_cb_called);
5032*8fb009dcSAndroid Build Coastguard Worker }
5033*8fb009dcSAndroid Build Coastguard Worker 
5034*8fb009dcSAndroid Build Coastguard Worker // Configuring the empty cipher list, though an error, should still modify the
5035*8fb009dcSAndroid Build Coastguard Worker // configuration.
TEST(SSLTest,EmptyCipherList)5036*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, EmptyCipherList) {
5037*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5038*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
5039*8fb009dcSAndroid Build Coastguard Worker 
5040*8fb009dcSAndroid Build Coastguard Worker   // Initially, the cipher list is not empty.
5041*8fb009dcSAndroid Build Coastguard Worker   EXPECT_NE(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
5042*8fb009dcSAndroid Build Coastguard Worker 
5043*8fb009dcSAndroid Build Coastguard Worker   // Configuring the empty cipher list fails.
5044*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_cipher_list(ctx.get(), ""));
5045*8fb009dcSAndroid Build Coastguard Worker   ERR_clear_error();
5046*8fb009dcSAndroid Build Coastguard Worker 
5047*8fb009dcSAndroid Build Coastguard Worker   // But the cipher list is still updated to empty.
5048*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0u, sk_SSL_CIPHER_num(SSL_CTX_get_ciphers(ctx.get())));
5049*8fb009dcSAndroid Build Coastguard Worker }
5050*8fb009dcSAndroid Build Coastguard Worker 
5051*8fb009dcSAndroid Build Coastguard Worker // ssl_test_ticket_aead_failure_mode enumerates the possible ways in which the
5052*8fb009dcSAndroid Build Coastguard Worker // test |SSL_TICKET_AEAD_METHOD| can fail.
5053*8fb009dcSAndroid Build Coastguard Worker enum ssl_test_ticket_aead_failure_mode {
5054*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_ok = 0,
5055*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_seal_fail,
5056*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_open_soft_fail,
5057*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_open_hard_fail,
5058*8fb009dcSAndroid Build Coastguard Worker };
5059*8fb009dcSAndroid Build Coastguard Worker 
5060*8fb009dcSAndroid Build Coastguard Worker struct ssl_test_ticket_aead_state {
5061*8fb009dcSAndroid Build Coastguard Worker   unsigned retry_count = 0;
5062*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_failure_mode failure_mode = ssl_test_ticket_aead_ok;
5063*8fb009dcSAndroid Build Coastguard Worker };
5064*8fb009dcSAndroid Build Coastguard Worker 
ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA * to,const CRYPTO_EX_DATA * from,void ** from_d,int index,long argl,void * argp)5065*8fb009dcSAndroid Build Coastguard Worker static int ssl_test_ticket_aead_ex_index_dup(CRYPTO_EX_DATA *to,
5066*8fb009dcSAndroid Build Coastguard Worker                                              const CRYPTO_EX_DATA *from,
5067*8fb009dcSAndroid Build Coastguard Worker                                              void **from_d, int index,
5068*8fb009dcSAndroid Build Coastguard Worker                                              long argl, void *argp) {
5069*8fb009dcSAndroid Build Coastguard Worker   abort();
5070*8fb009dcSAndroid Build Coastguard Worker }
5071*8fb009dcSAndroid Build Coastguard Worker 
ssl_test_ticket_aead_ex_index_free(void * parent,void * ptr,CRYPTO_EX_DATA * ad,int index,long argl,void * argp)5072*8fb009dcSAndroid Build Coastguard Worker static void ssl_test_ticket_aead_ex_index_free(void *parent, void *ptr,
5073*8fb009dcSAndroid Build Coastguard Worker                                                CRYPTO_EX_DATA *ad, int index,
5074*8fb009dcSAndroid Build Coastguard Worker                                                long argl, void *argp) {
5075*8fb009dcSAndroid Build Coastguard Worker   delete reinterpret_cast<ssl_test_ticket_aead_state*>(ptr);
5076*8fb009dcSAndroid Build Coastguard Worker }
5077*8fb009dcSAndroid Build Coastguard Worker 
5078*8fb009dcSAndroid Build Coastguard Worker static CRYPTO_once_t g_ssl_test_ticket_aead_ex_index_once = CRYPTO_ONCE_INIT;
5079*8fb009dcSAndroid Build Coastguard Worker static int g_ssl_test_ticket_aead_ex_index;
5080*8fb009dcSAndroid Build Coastguard Worker 
ssl_test_ticket_aead_get_ex_index()5081*8fb009dcSAndroid Build Coastguard Worker static int ssl_test_ticket_aead_get_ex_index() {
5082*8fb009dcSAndroid Build Coastguard Worker   CRYPTO_once(&g_ssl_test_ticket_aead_ex_index_once, [] {
5083*8fb009dcSAndroid Build Coastguard Worker     g_ssl_test_ticket_aead_ex_index = SSL_get_ex_new_index(
5084*8fb009dcSAndroid Build Coastguard Worker         0, nullptr, nullptr, ssl_test_ticket_aead_ex_index_dup,
5085*8fb009dcSAndroid Build Coastguard Worker         ssl_test_ticket_aead_ex_index_free);
5086*8fb009dcSAndroid Build Coastguard Worker   });
5087*8fb009dcSAndroid Build Coastguard Worker   return g_ssl_test_ticket_aead_ex_index;
5088*8fb009dcSAndroid Build Coastguard Worker }
5089*8fb009dcSAndroid Build Coastguard Worker 
ssl_test_ticket_aead_max_overhead(SSL * ssl)5090*8fb009dcSAndroid Build Coastguard Worker static size_t ssl_test_ticket_aead_max_overhead(SSL *ssl) {
5091*8fb009dcSAndroid Build Coastguard Worker   return 1;
5092*8fb009dcSAndroid Build Coastguard Worker }
5093*8fb009dcSAndroid Build Coastguard Worker 
ssl_test_ticket_aead_seal(SSL * ssl,uint8_t * out,size_t * out_len,size_t max_out_len,const uint8_t * in,size_t in_len)5094*8fb009dcSAndroid Build Coastguard Worker static int ssl_test_ticket_aead_seal(SSL *ssl, uint8_t *out, size_t *out_len,
5095*8fb009dcSAndroid Build Coastguard Worker                                      size_t max_out_len, const uint8_t *in,
5096*8fb009dcSAndroid Build Coastguard Worker                                      size_t in_len) {
5097*8fb009dcSAndroid Build Coastguard Worker   auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
5098*8fb009dcSAndroid Build Coastguard Worker       SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
5099*8fb009dcSAndroid Build Coastguard Worker 
5100*8fb009dcSAndroid Build Coastguard Worker   if (state->failure_mode == ssl_test_ticket_aead_seal_fail ||
5101*8fb009dcSAndroid Build Coastguard Worker       max_out_len < in_len + 1) {
5102*8fb009dcSAndroid Build Coastguard Worker     return 0;
5103*8fb009dcSAndroid Build Coastguard Worker   }
5104*8fb009dcSAndroid Build Coastguard Worker 
5105*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_memmove(out, in, in_len);
5106*8fb009dcSAndroid Build Coastguard Worker   out[in_len] = 0xff;
5107*8fb009dcSAndroid Build Coastguard Worker   *out_len = in_len + 1;
5108*8fb009dcSAndroid Build Coastguard Worker 
5109*8fb009dcSAndroid Build Coastguard Worker   return 1;
5110*8fb009dcSAndroid Build Coastguard Worker }
5111*8fb009dcSAndroid Build Coastguard Worker 
ssl_test_ticket_aead_open(SSL * ssl,uint8_t * out,size_t * out_len,size_t max_out_len,const uint8_t * in,size_t in_len)5112*8fb009dcSAndroid Build Coastguard Worker static ssl_ticket_aead_result_t ssl_test_ticket_aead_open(
5113*8fb009dcSAndroid Build Coastguard Worker     SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len,
5114*8fb009dcSAndroid Build Coastguard Worker     const uint8_t *in, size_t in_len) {
5115*8fb009dcSAndroid Build Coastguard Worker   auto state = reinterpret_cast<ssl_test_ticket_aead_state *>(
5116*8fb009dcSAndroid Build Coastguard Worker       SSL_get_ex_data(ssl, ssl_test_ticket_aead_get_ex_index()));
5117*8fb009dcSAndroid Build Coastguard Worker 
5118*8fb009dcSAndroid Build Coastguard Worker   if (state->retry_count > 0) {
5119*8fb009dcSAndroid Build Coastguard Worker     state->retry_count--;
5120*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_retry;
5121*8fb009dcSAndroid Build Coastguard Worker   }
5122*8fb009dcSAndroid Build Coastguard Worker 
5123*8fb009dcSAndroid Build Coastguard Worker   switch (state->failure_mode) {
5124*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_ok:
5125*8fb009dcSAndroid Build Coastguard Worker       break;
5126*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_seal_fail:
5127*8fb009dcSAndroid Build Coastguard Worker       // If |seal| failed then there shouldn't be any ticket to try and
5128*8fb009dcSAndroid Build Coastguard Worker       // decrypt.
5129*8fb009dcSAndroid Build Coastguard Worker       abort();
5130*8fb009dcSAndroid Build Coastguard Worker       break;
5131*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_soft_fail:
5132*8fb009dcSAndroid Build Coastguard Worker       return ssl_ticket_aead_ignore_ticket;
5133*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_hard_fail:
5134*8fb009dcSAndroid Build Coastguard Worker       return ssl_ticket_aead_error;
5135*8fb009dcSAndroid Build Coastguard Worker   }
5136*8fb009dcSAndroid Build Coastguard Worker 
5137*8fb009dcSAndroid Build Coastguard Worker   if (in_len == 0 || in[in_len - 1] != 0xff) {
5138*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_ignore_ticket;
5139*8fb009dcSAndroid Build Coastguard Worker   }
5140*8fb009dcSAndroid Build Coastguard Worker 
5141*8fb009dcSAndroid Build Coastguard Worker   if (max_out_len < in_len - 1) {
5142*8fb009dcSAndroid Build Coastguard Worker     return ssl_ticket_aead_error;
5143*8fb009dcSAndroid Build Coastguard Worker   }
5144*8fb009dcSAndroid Build Coastguard Worker 
5145*8fb009dcSAndroid Build Coastguard Worker   OPENSSL_memmove(out, in, in_len - 1);
5146*8fb009dcSAndroid Build Coastguard Worker   *out_len = in_len - 1;
5147*8fb009dcSAndroid Build Coastguard Worker   return ssl_ticket_aead_success;
5148*8fb009dcSAndroid Build Coastguard Worker }
5149*8fb009dcSAndroid Build Coastguard Worker 
5150*8fb009dcSAndroid Build Coastguard Worker static const SSL_TICKET_AEAD_METHOD kSSLTestTicketMethod = {
5151*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_max_overhead,
5152*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_seal,
5153*8fb009dcSAndroid Build Coastguard Worker   ssl_test_ticket_aead_open,
5154*8fb009dcSAndroid Build Coastguard Worker };
5155*8fb009dcSAndroid Build Coastguard Worker 
ConnectClientAndServerWithTicketMethod(bssl::UniquePtr<SSL> * out_client,bssl::UniquePtr<SSL> * out_server,SSL_CTX * client_ctx,SSL_CTX * server_ctx,unsigned retry_count,ssl_test_ticket_aead_failure_mode failure_mode,SSL_SESSION * session)5156*8fb009dcSAndroid Build Coastguard Worker static void ConnectClientAndServerWithTicketMethod(
5157*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> *out_client, bssl::UniquePtr<SSL> *out_server,
5158*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX *client_ctx, SSL_CTX *server_ctx, unsigned retry_count,
5159*8fb009dcSAndroid Build Coastguard Worker     ssl_test_ticket_aead_failure_mode failure_mode, SSL_SESSION *session) {
5160*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client(SSL_new(client_ctx)), server(SSL_new(server_ctx));
5161*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client);
5162*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server);
5163*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(client.get());
5164*8fb009dcSAndroid Build Coastguard Worker   SSL_set_accept_state(server.get());
5165*8fb009dcSAndroid Build Coastguard Worker 
5166*8fb009dcSAndroid Build Coastguard Worker   auto state = new ssl_test_ticket_aead_state;
5167*8fb009dcSAndroid Build Coastguard Worker   state->retry_count = retry_count;
5168*8fb009dcSAndroid Build Coastguard Worker   state->failure_mode = failure_mode;
5169*8fb009dcSAndroid Build Coastguard Worker 
5170*8fb009dcSAndroid Build Coastguard Worker   ASSERT_GE(ssl_test_ticket_aead_get_ex_index(), 0);
5171*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_ex_data(server.get(), ssl_test_ticket_aead_get_ex_index(),
5172*8fb009dcSAndroid Build Coastguard Worker                               state));
5173*8fb009dcSAndroid Build Coastguard Worker 
5174*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client.get(), session);
5175*8fb009dcSAndroid Build Coastguard Worker 
5176*8fb009dcSAndroid Build Coastguard Worker   BIO *bio1, *bio2;
5177*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
5178*8fb009dcSAndroid Build Coastguard Worker 
5179*8fb009dcSAndroid Build Coastguard Worker   // SSL_set_bio takes ownership.
5180*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(client.get(), bio1, bio1);
5181*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(server.get(), bio2, bio2);
5182*8fb009dcSAndroid Build Coastguard Worker 
5183*8fb009dcSAndroid Build Coastguard Worker   if (CompleteHandshakes(client.get(), server.get())) {
5184*8fb009dcSAndroid Build Coastguard Worker     *out_client = std::move(client);
5185*8fb009dcSAndroid Build Coastguard Worker     *out_server = std::move(server);
5186*8fb009dcSAndroid Build Coastguard Worker   } else {
5187*8fb009dcSAndroid Build Coastguard Worker     out_client->reset();
5188*8fb009dcSAndroid Build Coastguard Worker     out_server->reset();
5189*8fb009dcSAndroid Build Coastguard Worker   }
5190*8fb009dcSAndroid Build Coastguard Worker }
5191*8fb009dcSAndroid Build Coastguard Worker 
5192*8fb009dcSAndroid Build Coastguard Worker using TicketAEADMethodParam =
5193*8fb009dcSAndroid Build Coastguard Worker     testing::tuple<uint16_t, unsigned, ssl_test_ticket_aead_failure_mode>;
5194*8fb009dcSAndroid Build Coastguard Worker 
5195*8fb009dcSAndroid Build Coastguard Worker class TicketAEADMethodTest
5196*8fb009dcSAndroid Build Coastguard Worker     : public ::testing::TestWithParam<TicketAEADMethodParam> {};
5197*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(TicketAEADMethodTest,Resume)5198*8fb009dcSAndroid Build Coastguard Worker TEST_P(TicketAEADMethodTest, Resume) {
5199*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
5200*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
5201*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
5202*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5203*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
5204*8fb009dcSAndroid Build Coastguard Worker 
5205*8fb009dcSAndroid Build Coastguard Worker   const uint16_t version = testing::get<0>(GetParam());
5206*8fb009dcSAndroid Build Coastguard Worker   const unsigned retry_count = testing::get<1>(GetParam());
5207*8fb009dcSAndroid Build Coastguard Worker   const ssl_test_ticket_aead_failure_mode failure_mode =
5208*8fb009dcSAndroid Build Coastguard Worker       testing::get<2>(GetParam());
5209*8fb009dcSAndroid Build Coastguard Worker 
5210*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), version));
5211*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), version));
5212*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), version));
5213*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), version));
5214*8fb009dcSAndroid Build Coastguard Worker 
5215*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
5216*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
5217*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_current_time_cb(client_ctx.get(), FrozenTimeCallback);
5218*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_current_time_cb(server_ctx.get(), FrozenTimeCallback);
5219*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
5220*8fb009dcSAndroid Build Coastguard Worker 
5221*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_ticket_aead_method(server_ctx.get(), &kSSLTestTicketMethod);
5222*8fb009dcSAndroid Build Coastguard Worker 
5223*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
5224*8fb009dcSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(ConnectClientAndServerWithTicketMethod(
5225*8fb009dcSAndroid Build Coastguard Worker       &client, &server, client_ctx.get(), server_ctx.get(), retry_count,
5226*8fb009dcSAndroid Build Coastguard Worker       failure_mode, nullptr));
5227*8fb009dcSAndroid Build Coastguard Worker   switch (failure_mode) {
5228*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_ok:
5229*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_hard_fail:
5230*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_soft_fail:
5231*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(client);
5232*8fb009dcSAndroid Build Coastguard Worker       break;
5233*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_seal_fail:
5234*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(client);
5235*8fb009dcSAndroid Build Coastguard Worker       return;
5236*8fb009dcSAndroid Build Coastguard Worker   }
5237*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client.get()));
5238*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server.get()));
5239*8fb009dcSAndroid Build Coastguard Worker 
5240*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(FlushNewSessionTickets(client.get(), server.get()));
5241*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
5242*8fb009dcSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(ConnectClientAndServerWithTicketMethod(
5243*8fb009dcSAndroid Build Coastguard Worker       &client, &server, client_ctx.get(), server_ctx.get(), retry_count,
5244*8fb009dcSAndroid Build Coastguard Worker       failure_mode, session.get()));
5245*8fb009dcSAndroid Build Coastguard Worker   switch (failure_mode) {
5246*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_ok:
5247*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(client);
5248*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(SSL_session_reused(client.get()));
5249*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(SSL_session_reused(server.get()));
5250*8fb009dcSAndroid Build Coastguard Worker       break;
5251*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_seal_fail:
5252*8fb009dcSAndroid Build Coastguard Worker       abort();
5253*8fb009dcSAndroid Build Coastguard Worker       break;
5254*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_hard_fail:
5255*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(client);
5256*8fb009dcSAndroid Build Coastguard Worker       break;
5257*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_soft_fail:
5258*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(client);
5259*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(SSL_session_reused(client.get()));
5260*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(SSL_session_reused(server.get()));
5261*8fb009dcSAndroid Build Coastguard Worker   }
5262*8fb009dcSAndroid Build Coastguard Worker }
5263*8fb009dcSAndroid Build Coastguard Worker 
TicketAEADMethodParamToString(const testing::TestParamInfo<TicketAEADMethodParam> & params)5264*8fb009dcSAndroid Build Coastguard Worker std::string TicketAEADMethodParamToString(
5265*8fb009dcSAndroid Build Coastguard Worker     const testing::TestParamInfo<TicketAEADMethodParam> &params) {
5266*8fb009dcSAndroid Build Coastguard Worker   std::string ret = GetVersionName(std::get<0>(params.param));
5267*8fb009dcSAndroid Build Coastguard Worker   // GTest only allows alphanumeric characters and '_' in the parameter
5268*8fb009dcSAndroid Build Coastguard Worker   // string. Additionally filter out the 'v' to get "TLS13" over "TLSv13".
5269*8fb009dcSAndroid Build Coastguard Worker   for (auto it = ret.begin(); it != ret.end();) {
5270*8fb009dcSAndroid Build Coastguard Worker     if (*it == '.' || *it == 'v') {
5271*8fb009dcSAndroid Build Coastguard Worker       it = ret.erase(it);
5272*8fb009dcSAndroid Build Coastguard Worker     } else {
5273*8fb009dcSAndroid Build Coastguard Worker       ++it;
5274*8fb009dcSAndroid Build Coastguard Worker     }
5275*8fb009dcSAndroid Build Coastguard Worker   }
5276*8fb009dcSAndroid Build Coastguard Worker   char retry_count[256];
5277*8fb009dcSAndroid Build Coastguard Worker   snprintf(retry_count, sizeof(retry_count), "%u", std::get<1>(params.param));
5278*8fb009dcSAndroid Build Coastguard Worker   ret += "_";
5279*8fb009dcSAndroid Build Coastguard Worker   ret += retry_count;
5280*8fb009dcSAndroid Build Coastguard Worker   ret += "Retries_";
5281*8fb009dcSAndroid Build Coastguard Worker   switch (std::get<2>(params.param)) {
5282*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_ok:
5283*8fb009dcSAndroid Build Coastguard Worker       ret += "OK";
5284*8fb009dcSAndroid Build Coastguard Worker       break;
5285*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_seal_fail:
5286*8fb009dcSAndroid Build Coastguard Worker       ret += "SealFail";
5287*8fb009dcSAndroid Build Coastguard Worker       break;
5288*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_soft_fail:
5289*8fb009dcSAndroid Build Coastguard Worker       ret += "OpenSoftFail";
5290*8fb009dcSAndroid Build Coastguard Worker       break;
5291*8fb009dcSAndroid Build Coastguard Worker     case ssl_test_ticket_aead_open_hard_fail:
5292*8fb009dcSAndroid Build Coastguard Worker       ret += "OpenHardFail";
5293*8fb009dcSAndroid Build Coastguard Worker       break;
5294*8fb009dcSAndroid Build Coastguard Worker   }
5295*8fb009dcSAndroid Build Coastguard Worker   return ret;
5296*8fb009dcSAndroid Build Coastguard Worker }
5297*8fb009dcSAndroid Build Coastguard Worker 
5298*8fb009dcSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
5299*8fb009dcSAndroid Build Coastguard Worker     TicketAEADMethodTests, TicketAEADMethodTest,
5300*8fb009dcSAndroid Build Coastguard Worker     testing::Combine(testing::Values(TLS1_2_VERSION, TLS1_3_VERSION),
5301*8fb009dcSAndroid Build Coastguard Worker                      testing::Values(0, 1, 2),
5302*8fb009dcSAndroid Build Coastguard Worker                      testing::Values(ssl_test_ticket_aead_ok,
5303*8fb009dcSAndroid Build Coastguard Worker                                      ssl_test_ticket_aead_seal_fail,
5304*8fb009dcSAndroid Build Coastguard Worker                                      ssl_test_ticket_aead_open_soft_fail,
5305*8fb009dcSAndroid Build Coastguard Worker                                      ssl_test_ticket_aead_open_hard_fail)),
5306*8fb009dcSAndroid Build Coastguard Worker     TicketAEADMethodParamToString);
5307*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SelectNextProto)5308*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SelectNextProto) {
5309*8fb009dcSAndroid Build Coastguard Worker   uint8_t *result;
5310*8fb009dcSAndroid Build Coastguard Worker   uint8_t result_len;
5311*8fb009dcSAndroid Build Coastguard Worker 
5312*8fb009dcSAndroid Build Coastguard Worker   // If there is an overlap, it should be returned.
5313*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5314*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5315*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9,
5316*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1x\1y\1a\1z", 8));
5317*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
5318*8fb009dcSAndroid Build Coastguard Worker 
5319*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5320*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5321*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9,
5322*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1x\1y\2bb\1z", 9));
5323*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes("bb"), Bytes(result, result_len));
5324*8fb009dcSAndroid Build Coastguard Worker 
5325*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5326*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5327*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9,
5328*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1x\1y\3ccc\1z", 10));
5329*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes("ccc"), Bytes(result, result_len));
5330*8fb009dcSAndroid Build Coastguard Worker 
5331*8fb009dcSAndroid Build Coastguard Worker   // Peer preference order takes precedence over local.
5332*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NEGOTIATED,
5333*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5334*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9,
5335*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\3ccc\2bb\1a", 9));
5336*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes("a"), Bytes(result, result_len));
5337*8fb009dcSAndroid Build Coastguard Worker 
5338*8fb009dcSAndroid Build Coastguard Worker   // If there is no overlap, opportunistically select the first local protocol.
5339*8fb009dcSAndroid Build Coastguard Worker   // ALPN callers should ignore this, but NPN callers may use this per
5340*8fb009dcSAndroid Build Coastguard Worker   // draft-agl-tls-nextprotoneg-03, section 6.
5341*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
5342*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5343*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9,
5344*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1x\2yy\3zzz", 9));
5345*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
5346*8fb009dcSAndroid Build Coastguard Worker 
5347*8fb009dcSAndroid Build Coastguard Worker   // The peer preference order may be empty in NPN. This should be treated as no
5348*8fb009dcSAndroid Build Coastguard Worker   // overlap and continue to select an opportunistic protocol.
5349*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
5350*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len, nullptr, 0,
5351*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1x\2yy\3zzz", 9));
5352*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes("x"), Bytes(result, result_len));
5353*8fb009dcSAndroid Build Coastguard Worker 
5354*8fb009dcSAndroid Build Coastguard Worker   // Although calling this function with no local protocols is a caller error,
5355*8fb009dcSAndroid Build Coastguard Worker   // it should cleanly return an empty protocol.
5356*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(
5357*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_NPN_NO_OVERLAP,
5358*8fb009dcSAndroid Build Coastguard Worker       SSL_select_next_proto(&result, &result_len,
5359*8fb009dcSAndroid Build Coastguard Worker                             (const uint8_t *)"\1a\2bb\3ccc", 9, nullptr, 0));
5360*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(""), Bytes(result, result_len));
5361*8fb009dcSAndroid Build Coastguard Worker 
5362*8fb009dcSAndroid Build Coastguard Worker   // Syntax errors are similarly caller errors.
5363*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(
5364*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_NPN_NO_OVERLAP,
5365*8fb009dcSAndroid Build Coastguard Worker       SSL_select_next_proto(&result, &result_len, (const uint8_t *)"\4aaa", 4,
5366*8fb009dcSAndroid Build Coastguard Worker                             (const uint8_t *)"\1a\2bb\3ccc", 9));
5367*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(""), Bytes(result, result_len));
5368*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
5369*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5370*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9,
5371*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\4aaa", 4));
5372*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(""), Bytes(result, result_len));
5373*8fb009dcSAndroid Build Coastguard Worker 
5374*8fb009dcSAndroid Build Coastguard Worker   // Protocols in protocol lists may not be empty.
5375*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
5376*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5377*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\0\2bb\3ccc", 8,
5378*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9));
5379*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(OPENSSL_NPN_NO_OVERLAP,
5380*8fb009dcSAndroid Build Coastguard Worker             SSL_select_next_proto(&result, &result_len,
5381*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\1a\2bb\3ccc", 9,
5382*8fb009dcSAndroid Build Coastguard Worker                                   (const uint8_t *)"\0\2bb\3ccc", 8));
5383*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(""), Bytes(result, result_len));
5384*8fb009dcSAndroid Build Coastguard Worker }
5385*8fb009dcSAndroid Build Coastguard Worker 
5386*8fb009dcSAndroid Build Coastguard Worker // The client should gracefully handle no suitable ciphers being enabled.
TEST(SSLTest,NoCiphersAvailable)5387*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, NoCiphersAvailable) {
5388*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5389*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
5390*8fb009dcSAndroid Build Coastguard Worker 
5391*8fb009dcSAndroid Build Coastguard Worker   // Configure |client_ctx| with a cipher list that does not intersect with its
5392*8fb009dcSAndroid Build Coastguard Worker   // version configuration.
5393*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
5394*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
5395*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_1_VERSION));
5396*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_1_VERSION));
5397*8fb009dcSAndroid Build Coastguard Worker 
5398*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
5399*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
5400*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(ssl.get());
5401*8fb009dcSAndroid Build Coastguard Worker 
5402*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<BIO> rbio(BIO_new(BIO_s_mem())), wbio(BIO_new(BIO_s_mem()));
5403*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(rbio);
5404*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(wbio);
5405*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_rbio(ssl.get(), rbio.release());
5406*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_wbio(ssl.get(), wbio.release());
5407*8fb009dcSAndroid Build Coastguard Worker 
5408*8fb009dcSAndroid Build Coastguard Worker   int ret = SSL_do_handshake(ssl.get());
5409*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(-1, ret);
5410*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_ERROR_SSL, SSL_get_error(ssl.get(), ret));
5411*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(
5412*8fb009dcSAndroid Build Coastguard Worker       ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_NO_CIPHERS_AVAILABLE));
5413*8fb009dcSAndroid Build Coastguard Worker }
5414*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SessionVersion)5415*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SessionVersion) {
5416*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
5417*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
5418*8fb009dcSAndroid Build Coastguard Worker 
5419*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
5420*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
5421*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
5422*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
5423*8fb009dcSAndroid Build Coastguard Worker 
5424*8fb009dcSAndroid Build Coastguard Worker   // Sessions in TLS 1.3 and later should be single-use.
5425*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(version() == TLS1_3_VERSION,
5426*8fb009dcSAndroid Build Coastguard Worker             !!SSL_SESSION_should_be_single_use(session.get()));
5427*8fb009dcSAndroid Build Coastguard Worker 
5428*8fb009dcSAndroid Build Coastguard Worker   // Making fake sessions for testing works.
5429*8fb009dcSAndroid Build Coastguard Worker   session.reset(SSL_SESSION_new(client_ctx_.get()));
5430*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
5431*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_SESSION_set_protocol_version(session.get(), version()));
5432*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(version(), SSL_SESSION_get_protocol_version(session.get()));
5433*8fb009dcSAndroid Build Coastguard Worker }
5434*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SSLPending)5435*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SSLPending) {
5436*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL> ssl(SSL_new(client_ctx_.get()));
5437*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
5438*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_pending(ssl.get()));
5439*8fb009dcSAndroid Build Coastguard Worker 
5440*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
5441*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_pending(client_.get()));
5442*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_has_pending(client_.get()));
5443*8fb009dcSAndroid Build Coastguard Worker 
5444*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(5, SSL_write(server_.get(), "hello", 5));
5445*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(5, SSL_write(server_.get(), "world", 5));
5446*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_pending(client_.get()));
5447*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_has_pending(client_.get()));
5448*8fb009dcSAndroid Build Coastguard Worker 
5449*8fb009dcSAndroid Build Coastguard Worker   char buf[10];
5450*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(1, SSL_peek(client_.get(), buf, 1));
5451*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(5, SSL_pending(client_.get()));
5452*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, SSL_has_pending(client_.get()));
5453*8fb009dcSAndroid Build Coastguard Worker 
5454*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(1, SSL_read(client_.get(), buf, 1));
5455*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(4, SSL_pending(client_.get()));
5456*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, SSL_has_pending(client_.get()));
5457*8fb009dcSAndroid Build Coastguard Worker 
5458*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(4, SSL_read(client_.get(), buf, 10));
5459*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_pending(client_.get()));
5460*8fb009dcSAndroid Build Coastguard Worker   if (is_dtls()) {
5461*8fb009dcSAndroid Build Coastguard Worker     // In DTLS, the two records would have been read as a single datagram and
5462*8fb009dcSAndroid Build Coastguard Worker     // buffered inside |client_|. Thus, |SSL_has_pending| should return true.
5463*8fb009dcSAndroid Build Coastguard Worker     //
5464*8fb009dcSAndroid Build Coastguard Worker     // This test is slightly unrealistic. It relies on |ConnectClientAndServer|
5465*8fb009dcSAndroid Build Coastguard Worker     // using a |BIO| pair, which does not preserve datagram boundaries. Reading
5466*8fb009dcSAndroid Build Coastguard Worker     // 1 byte, then 4 bytes, from the first record also relies on
5467*8fb009dcSAndroid Build Coastguard Worker     // https://crbug.com/boringssl/65. But it does test the codepaths. When
5468*8fb009dcSAndroid Build Coastguard Worker     // fixing either of these bugs, this test may need to be redone.
5469*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(1, SSL_has_pending(client_.get()));
5470*8fb009dcSAndroid Build Coastguard Worker   } else {
5471*8fb009dcSAndroid Build Coastguard Worker     // In TLS, we do not overread, so |SSL_has_pending| should report no data is
5472*8fb009dcSAndroid Build Coastguard Worker     // buffered.
5473*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(0, SSL_has_pending(client_.get()));
5474*8fb009dcSAndroid Build Coastguard Worker   }
5475*8fb009dcSAndroid Build Coastguard Worker 
5476*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(2, SSL_read(client_.get(), buf, 2));
5477*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(3, SSL_pending(client_.get()));
5478*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, SSL_has_pending(client_.get()));
5479*8fb009dcSAndroid Build Coastguard Worker }
5480*8fb009dcSAndroid Build Coastguard Worker 
5481*8fb009dcSAndroid Build Coastguard Worker // Test that post-handshake tickets consumed by |SSL_shutdown| are ignored.
TEST(SSLTest,ShutdownIgnoresTickets)5482*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ShutdownIgnoresTickets) {
5483*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
5484*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
5485*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_3_VERSION));
5486*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_3_VERSION));
5487*8fb009dcSAndroid Build Coastguard Worker 
5488*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_BOTH);
5489*8fb009dcSAndroid Build Coastguard Worker 
5490*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
5491*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
5492*8fb009dcSAndroid Build Coastguard Worker 
5493*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(ctx.get(), [](SSL *ssl, SSL_SESSION *session) -> int {
5494*8fb009dcSAndroid Build Coastguard Worker     ADD_FAILURE() << "New session callback called during SSL_shutdown";
5495*8fb009dcSAndroid Build Coastguard Worker     return 0;
5496*8fb009dcSAndroid Build Coastguard Worker   });
5497*8fb009dcSAndroid Build Coastguard Worker 
5498*8fb009dcSAndroid Build Coastguard Worker   // Send close_notify.
5499*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_shutdown(server.get()));
5500*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_shutdown(client.get()));
5501*8fb009dcSAndroid Build Coastguard Worker 
5502*8fb009dcSAndroid Build Coastguard Worker   // Receive close_notify.
5503*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, SSL_shutdown(server.get()));
5504*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, SSL_shutdown(client.get()));
5505*8fb009dcSAndroid Build Coastguard Worker }
5506*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SignatureAlgorithmProperties)5507*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SignatureAlgorithmProperties) {
5508*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(EVP_PKEY_NONE, SSL_get_signature_algorithm_key_type(0x1234));
5509*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(nullptr, SSL_get_signature_algorithm_digest(0x1234));
5510*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(0x1234));
5511*8fb009dcSAndroid Build Coastguard Worker 
5512*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(EVP_PKEY_RSA,
5513*8fb009dcSAndroid Build Coastguard Worker             SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5514*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(EVP_md5_sha1(),
5515*8fb009dcSAndroid Build Coastguard Worker             SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5516*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PKCS1_MD5_SHA1));
5517*8fb009dcSAndroid Build Coastguard Worker 
5518*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(EVP_PKEY_EC, SSL_get_signature_algorithm_key_type(
5519*8fb009dcSAndroid Build Coastguard Worker                              SSL_SIGN_ECDSA_SECP256R1_SHA256));
5520*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(EVP_sha256(), SSL_get_signature_algorithm_digest(
5521*8fb009dcSAndroid Build Coastguard Worker                               SSL_SIGN_ECDSA_SECP256R1_SHA256));
5522*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(
5523*8fb009dcSAndroid Build Coastguard Worker       SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_ECDSA_SECP256R1_SHA256));
5524*8fb009dcSAndroid Build Coastguard Worker 
5525*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(EVP_PKEY_RSA,
5526*8fb009dcSAndroid Build Coastguard Worker             SSL_get_signature_algorithm_key_type(SSL_SIGN_RSA_PSS_RSAE_SHA384));
5527*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(EVP_sha384(),
5528*8fb009dcSAndroid Build Coastguard Worker             SSL_get_signature_algorithm_digest(SSL_SIGN_RSA_PSS_RSAE_SHA384));
5529*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_is_signature_algorithm_rsa_pss(SSL_SIGN_RSA_PSS_RSAE_SHA384));
5530*8fb009dcSAndroid Build Coastguard Worker }
5531*8fb009dcSAndroid Build Coastguard Worker 
XORCompressFunc(SSL * ssl,CBB * out,const uint8_t * in,size_t in_len)5532*8fb009dcSAndroid Build Coastguard Worker static int XORCompressFunc(SSL *ssl, CBB *out, const uint8_t *in,
5533*8fb009dcSAndroid Build Coastguard Worker                            size_t in_len) {
5534*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < in_len; i++) {
5535*8fb009dcSAndroid Build Coastguard Worker     if (!CBB_add_u8(out, in[i] ^ 0x55)) {
5536*8fb009dcSAndroid Build Coastguard Worker       return 0;
5537*8fb009dcSAndroid Build Coastguard Worker     }
5538*8fb009dcSAndroid Build Coastguard Worker   }
5539*8fb009dcSAndroid Build Coastguard Worker 
5540*8fb009dcSAndroid Build Coastguard Worker   SSL_set_app_data(ssl, XORCompressFunc);
5541*8fb009dcSAndroid Build Coastguard Worker 
5542*8fb009dcSAndroid Build Coastguard Worker   return 1;
5543*8fb009dcSAndroid Build Coastguard Worker }
5544*8fb009dcSAndroid Build Coastguard Worker 
XORDecompressFunc(SSL * ssl,CRYPTO_BUFFER ** out,size_t uncompressed_len,const uint8_t * in,size_t in_len)5545*8fb009dcSAndroid Build Coastguard Worker static int XORDecompressFunc(SSL *ssl, CRYPTO_BUFFER **out,
5546*8fb009dcSAndroid Build Coastguard Worker                              size_t uncompressed_len, const uint8_t *in,
5547*8fb009dcSAndroid Build Coastguard Worker                              size_t in_len) {
5548*8fb009dcSAndroid Build Coastguard Worker   if (in_len != uncompressed_len) {
5549*8fb009dcSAndroid Build Coastguard Worker     return 0;
5550*8fb009dcSAndroid Build Coastguard Worker   }
5551*8fb009dcSAndroid Build Coastguard Worker 
5552*8fb009dcSAndroid Build Coastguard Worker   uint8_t *data;
5553*8fb009dcSAndroid Build Coastguard Worker   *out = CRYPTO_BUFFER_alloc(&data, uncompressed_len);
5554*8fb009dcSAndroid Build Coastguard Worker   if (*out == nullptr) {
5555*8fb009dcSAndroid Build Coastguard Worker     return 0;
5556*8fb009dcSAndroid Build Coastguard Worker   }
5557*8fb009dcSAndroid Build Coastguard Worker 
5558*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < in_len; i++) {
5559*8fb009dcSAndroid Build Coastguard Worker     data[i] = in[i] ^ 0x55;
5560*8fb009dcSAndroid Build Coastguard Worker   }
5561*8fb009dcSAndroid Build Coastguard Worker 
5562*8fb009dcSAndroid Build Coastguard Worker   SSL_set_app_data(ssl, XORDecompressFunc);
5563*8fb009dcSAndroid Build Coastguard Worker 
5564*8fb009dcSAndroid Build Coastguard Worker   return 1;
5565*8fb009dcSAndroid Build Coastguard Worker }
5566*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CertCompression)5567*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CertCompression) {
5568*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5569*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(
5570*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method()));
5571*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
5572*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
5573*8fb009dcSAndroid Build Coastguard Worker 
5574*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
5575*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
5576*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5577*8fb009dcSAndroid Build Coastguard Worker       client_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5578*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_add_cert_compression_alg(
5579*8fb009dcSAndroid Build Coastguard Worker       server_ctx.get(), 0x1234, XORCompressFunc, XORDecompressFunc));
5580*8fb009dcSAndroid Build Coastguard Worker 
5581*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
5582*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
5583*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
5584*8fb009dcSAndroid Build Coastguard Worker 
5585*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_get_app_data(client.get()) == XORDecompressFunc);
5586*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_get_app_data(server.get()) == XORCompressFunc);
5587*8fb009dcSAndroid Build Coastguard Worker }
5588*8fb009dcSAndroid Build Coastguard Worker 
MoveBIOs(SSL * dest,SSL * src)5589*8fb009dcSAndroid Build Coastguard Worker void MoveBIOs(SSL *dest, SSL *src) {
5590*8fb009dcSAndroid Build Coastguard Worker   BIO *rbio = SSL_get_rbio(src);
5591*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(rbio);
5592*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_rbio(dest, rbio);
5593*8fb009dcSAndroid Build Coastguard Worker 
5594*8fb009dcSAndroid Build Coastguard Worker   BIO *wbio = SSL_get_wbio(src);
5595*8fb009dcSAndroid Build Coastguard Worker   BIO_up_ref(wbio);
5596*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_wbio(dest, wbio);
5597*8fb009dcSAndroid Build Coastguard Worker 
5598*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_rbio(src, nullptr);
5599*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_wbio(src, nullptr);
5600*8fb009dcSAndroid Build Coastguard Worker }
5601*8fb009dcSAndroid Build Coastguard Worker 
VerifyHandoff(bool use_new_alps_codepoint)5602*8fb009dcSAndroid Build Coastguard Worker void VerifyHandoff(bool use_new_alps_codepoint) {
5603*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t alpn[] = {0x03, 'f', 'o', 'o'};
5604*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t proto[] = {'f', 'o', 'o'};
5605*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t alps[] = {0x04, 'a', 'l', 'p', 's'};
5606*8fb009dcSAndroid Build Coastguard Worker 
5607*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5608*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5609*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> handshaker_ctx(
5610*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method()));
5611*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
5612*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
5613*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(handshaker_ctx);
5614*8fb009dcSAndroid Build Coastguard Worker 
5615*8fb009dcSAndroid Build Coastguard Worker   if (!use_new_alps_codepoint) {
5616*8fb009dcSAndroid Build Coastguard Worker     SetUpExpectedOldCodePoint(server_ctx.get());
5617*8fb009dcSAndroid Build Coastguard Worker   } else {
5618*8fb009dcSAndroid Build Coastguard Worker     SetUpExpectedNewCodePoint(server_ctx.get());
5619*8fb009dcSAndroid Build Coastguard Worker   }
5620*8fb009dcSAndroid Build Coastguard Worker 
5621*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_CLIENT);
5622*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx.get(), SaveLastSession);
5623*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_handoff_mode(server_ctx.get(), true);
5624*8fb009dcSAndroid Build Coastguard Worker   uint8_t keys[48];
5625*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_get_tlsext_ticket_keys(server_ctx.get(), &keys, sizeof(keys));
5626*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_ticket_keys(handshaker_ctx.get(), &keys, sizeof(keys));
5627*8fb009dcSAndroid Build Coastguard Worker 
5628*8fb009dcSAndroid Build Coastguard Worker   for (bool early_data : {false, true}) {
5629*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(early_data);
5630*8fb009dcSAndroid Build Coastguard Worker     for (bool is_resume : {false, true}) {
5631*8fb009dcSAndroid Build Coastguard Worker       SCOPED_TRACE(is_resume);
5632*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<SSL> client, server;
5633*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5634*8fb009dcSAndroid Build Coastguard Worker                                         server_ctx.get()));
5635*8fb009dcSAndroid Build Coastguard Worker       SSL_set_early_data_enabled(client.get(), early_data);
5636*8fb009dcSAndroid Build Coastguard Worker 
5637*8fb009dcSAndroid Build Coastguard Worker       // Set up client ALPS settings.
5638*8fb009dcSAndroid Build Coastguard Worker       SSL_set_alps_use_new_codepoint(client.get(), use_new_alps_codepoint);
5639*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_set_alpn_protos(client.get(), alpn, sizeof(alpn)) == 0);
5640*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_add_application_settings(client.get(), proto,
5641*8fb009dcSAndroid Build Coastguard Worker                                               sizeof(proto), nullptr, 0));
5642*8fb009dcSAndroid Build Coastguard Worker       if (is_resume) {
5643*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(g_last_session);
5644*8fb009dcSAndroid Build Coastguard Worker         SSL_set_session(client.get(), g_last_session.get());
5645*8fb009dcSAndroid Build Coastguard Worker         if (early_data) {
5646*8fb009dcSAndroid Build Coastguard Worker           EXPECT_GT(g_last_session->ticket_max_early_data, 0u);
5647*8fb009dcSAndroid Build Coastguard Worker         }
5648*8fb009dcSAndroid Build Coastguard Worker       }
5649*8fb009dcSAndroid Build Coastguard Worker 
5650*8fb009dcSAndroid Build Coastguard Worker 
5651*8fb009dcSAndroid Build Coastguard Worker       int client_ret = SSL_do_handshake(client.get());
5652*8fb009dcSAndroid Build Coastguard Worker       int client_err = SSL_get_error(client.get(), client_ret);
5653*8fb009dcSAndroid Build Coastguard Worker 
5654*8fb009dcSAndroid Build Coastguard Worker       uint8_t byte_written;
5655*8fb009dcSAndroid Build Coastguard Worker       if (early_data && is_resume) {
5656*8fb009dcSAndroid Build Coastguard Worker         ASSERT_EQ(client_err, 0);
5657*8fb009dcSAndroid Build Coastguard Worker         EXPECT_TRUE(SSL_in_early_data(client.get()));
5658*8fb009dcSAndroid Build Coastguard Worker         // Attempt to write early data.
5659*8fb009dcSAndroid Build Coastguard Worker         byte_written = 43;
5660*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5661*8fb009dcSAndroid Build Coastguard Worker       } else {
5662*8fb009dcSAndroid Build Coastguard Worker         ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5663*8fb009dcSAndroid Build Coastguard Worker       }
5664*8fb009dcSAndroid Build Coastguard Worker 
5665*8fb009dcSAndroid Build Coastguard Worker       int server_ret = SSL_do_handshake(server.get());
5666*8fb009dcSAndroid Build Coastguard Worker       int server_err = SSL_get_error(server.get(), server_ret);
5667*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5668*8fb009dcSAndroid Build Coastguard Worker 
5669*8fb009dcSAndroid Build Coastguard Worker       ScopedCBB cbb;
5670*8fb009dcSAndroid Build Coastguard Worker       Array<uint8_t> handoff;
5671*8fb009dcSAndroid Build Coastguard Worker       SSL_CLIENT_HELLO hello;
5672*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_init(cbb.get(), 256));
5673*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
5674*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CBBFinishArray(cbb.get(), &handoff));
5675*8fb009dcSAndroid Build Coastguard Worker 
5676*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<SSL> handshaker(SSL_new(handshaker_ctx.get()));
5677*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(handshaker);
5678*8fb009dcSAndroid Build Coastguard Worker       // Note split handshakes determines 0-RTT support, for both the current
5679*8fb009dcSAndroid Build Coastguard Worker       // handshake and newly-issued tickets, entirely by |handshaker|. There is
5680*8fb009dcSAndroid Build Coastguard Worker       // no need to call |SSL_set_early_data_enabled| on |server|.
5681*8fb009dcSAndroid Build Coastguard Worker       SSL_set_early_data_enabled(handshaker.get(), 1);
5682*8fb009dcSAndroid Build Coastguard Worker 
5683*8fb009dcSAndroid Build Coastguard Worker       // Set up handshaker ALPS settings.
5684*8fb009dcSAndroid Build Coastguard Worker       SSL_set_alps_use_new_codepoint(handshaker.get(), use_new_alps_codepoint);
5685*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_alpn_select_cb(
5686*8fb009dcSAndroid Build Coastguard Worker           handshaker_ctx.get(),
5687*8fb009dcSAndroid Build Coastguard Worker           [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
5688*8fb009dcSAndroid Build Coastguard Worker               unsigned in_len, void *arg) -> int {
5689*8fb009dcSAndroid Build Coastguard Worker             return SSL_select_next_proto(
5690*8fb009dcSAndroid Build Coastguard Worker                         const_cast<uint8_t **>(out), out_len, in, in_len,
5691*8fb009dcSAndroid Build Coastguard Worker                         alpn, sizeof(alpn)) == OPENSSL_NPN_NEGOTIATED
5692*8fb009dcSAndroid Build Coastguard Worker                         ? SSL_TLSEXT_ERR_OK
5693*8fb009dcSAndroid Build Coastguard Worker                         : SSL_TLSEXT_ERR_NOACK;
5694*8fb009dcSAndroid Build Coastguard Worker           },
5695*8fb009dcSAndroid Build Coastguard Worker           nullptr);
5696*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_add_application_settings(handshaker.get(), proto,
5697*8fb009dcSAndroid Build Coastguard Worker                                               sizeof(proto), alps, sizeof(alps)));
5698*8fb009dcSAndroid Build Coastguard Worker 
5699*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_apply_handoff(handshaker.get(), handoff));
5700*8fb009dcSAndroid Build Coastguard Worker 
5701*8fb009dcSAndroid Build Coastguard Worker       MoveBIOs(handshaker.get(), server.get());
5702*8fb009dcSAndroid Build Coastguard Worker 
5703*8fb009dcSAndroid Build Coastguard Worker       int handshake_ret = SSL_do_handshake(handshaker.get());
5704*8fb009dcSAndroid Build Coastguard Worker       int handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5705*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5706*8fb009dcSAndroid Build Coastguard Worker 
5707*8fb009dcSAndroid Build Coastguard Worker       // Double-check that additional calls to |SSL_do_handshake| continue
5708*8fb009dcSAndroid Build Coastguard Worker       // to get |SSL_ERROR_HANDBACK|.
5709*8fb009dcSAndroid Build Coastguard Worker       handshake_ret = SSL_do_handshake(handshaker.get());
5710*8fb009dcSAndroid Build Coastguard Worker       handshake_err = SSL_get_error(handshaker.get(), handshake_ret);
5711*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(handshake_err, SSL_ERROR_HANDBACK);
5712*8fb009dcSAndroid Build Coastguard Worker 
5713*8fb009dcSAndroid Build Coastguard Worker       ScopedCBB cbb_handback;
5714*8fb009dcSAndroid Build Coastguard Worker       Array<uint8_t> handback;
5715*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CBB_init(cbb_handback.get(), 1024));
5716*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_serialize_handback(handshaker.get(), cbb_handback.get()));
5717*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CBBFinishArray(cbb_handback.get(), &handback));
5718*8fb009dcSAndroid Build Coastguard Worker 
5719*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<SSL> server2(SSL_new(server_ctx.get()));
5720*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(server2);
5721*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_apply_handback(server2.get(), handback));
5722*8fb009dcSAndroid Build Coastguard Worker 
5723*8fb009dcSAndroid Build Coastguard Worker       MoveBIOs(server2.get(), handshaker.get());
5724*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(CompleteHandshakes(client.get(), server2.get()));
5725*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(is_resume, SSL_session_reused(client.get()));
5726*8fb009dcSAndroid Build Coastguard Worker       // Verify application settings.
5727*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_has_application_settings(client.get()));
5728*8fb009dcSAndroid Build Coastguard Worker 
5729*8fb009dcSAndroid Build Coastguard Worker       if (early_data && is_resume) {
5730*8fb009dcSAndroid Build Coastguard Worker         // In this case, one byte of early data has already been written above.
5731*8fb009dcSAndroid Build Coastguard Worker         EXPECT_TRUE(SSL_early_data_accepted(client.get()));
5732*8fb009dcSAndroid Build Coastguard Worker       } else {
5733*8fb009dcSAndroid Build Coastguard Worker         byte_written = 42;
5734*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(SSL_write(client.get(), &byte_written, 1), 1);
5735*8fb009dcSAndroid Build Coastguard Worker       }
5736*8fb009dcSAndroid Build Coastguard Worker       uint8_t byte;
5737*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_read(server2.get(), &byte, 1), 1);
5738*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(byte_written, byte);
5739*8fb009dcSAndroid Build Coastguard Worker 
5740*8fb009dcSAndroid Build Coastguard Worker       byte = 44;
5741*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_write(server2.get(), &byte, 1), 1);
5742*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5743*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(44, byte);
5744*8fb009dcSAndroid Build Coastguard Worker     }
5745*8fb009dcSAndroid Build Coastguard Worker   }
5746*8fb009dcSAndroid Build Coastguard Worker }
5747*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,Handoff)5748*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, Handoff) {
5749*8fb009dcSAndroid Build Coastguard Worker   for (bool use_new_alps_codepoint : {false, true}) {
5750*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(use_new_alps_codepoint);
5751*8fb009dcSAndroid Build Coastguard Worker     VerifyHandoff(use_new_alps_codepoint);
5752*8fb009dcSAndroid Build Coastguard Worker   }
5753*8fb009dcSAndroid Build Coastguard Worker }
5754*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,HandoffDeclined)5755*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, HandoffDeclined) {
5756*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
5757*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(
5758*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method()));
5759*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
5760*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
5761*8fb009dcSAndroid Build Coastguard Worker 
5762*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_handoff_mode(server_ctx.get(), true);
5763*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
5764*8fb009dcSAndroid Build Coastguard Worker 
5765*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
5766*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
5767*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx.get()));
5768*8fb009dcSAndroid Build Coastguard Worker 
5769*8fb009dcSAndroid Build Coastguard Worker   int client_ret = SSL_do_handshake(client.get());
5770*8fb009dcSAndroid Build Coastguard Worker   int client_err = SSL_get_error(client.get(), client_ret);
5771*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(client_err, SSL_ERROR_WANT_READ);
5772*8fb009dcSAndroid Build Coastguard Worker 
5773*8fb009dcSAndroid Build Coastguard Worker   int server_ret = SSL_do_handshake(server.get());
5774*8fb009dcSAndroid Build Coastguard Worker   int server_err = SSL_get_error(server.get(), server_ret);
5775*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(server_err, SSL_ERROR_HANDOFF);
5776*8fb009dcSAndroid Build Coastguard Worker 
5777*8fb009dcSAndroid Build Coastguard Worker   ScopedCBB cbb;
5778*8fb009dcSAndroid Build Coastguard Worker   SSL_CLIENT_HELLO hello;
5779*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CBB_init(cbb.get(), 256));
5780*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_serialize_handoff(server.get(), cbb.get(), &hello));
5781*8fb009dcSAndroid Build Coastguard Worker 
5782*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_decline_handoff(server.get()));
5783*8fb009dcSAndroid Build Coastguard Worker 
5784*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
5785*8fb009dcSAndroid Build Coastguard Worker 
5786*8fb009dcSAndroid Build Coastguard Worker   uint8_t byte = 42;
5787*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_write(client.get(), &byte, 1), 1);
5788*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_read(server.get(), &byte, 1), 1);
5789*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(42, byte);
5790*8fb009dcSAndroid Build Coastguard Worker 
5791*8fb009dcSAndroid Build Coastguard Worker   byte = 43;
5792*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_write(server.get(), &byte, 1), 1);
5793*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_read(client.get(), &byte, 1), 1);
5794*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(43, byte);
5795*8fb009dcSAndroid Build Coastguard Worker }
5796*8fb009dcSAndroid Build Coastguard Worker 
SigAlgsToString(Span<const uint16_t> sigalgs)5797*8fb009dcSAndroid Build Coastguard Worker static std::string SigAlgsToString(Span<const uint16_t> sigalgs) {
5798*8fb009dcSAndroid Build Coastguard Worker   std::string ret = "{";
5799*8fb009dcSAndroid Build Coastguard Worker 
5800*8fb009dcSAndroid Build Coastguard Worker   for (uint16_t v : sigalgs) {
5801*8fb009dcSAndroid Build Coastguard Worker     if (ret.size() > 1) {
5802*8fb009dcSAndroid Build Coastguard Worker       ret += ", ";
5803*8fb009dcSAndroid Build Coastguard Worker     }
5804*8fb009dcSAndroid Build Coastguard Worker 
5805*8fb009dcSAndroid Build Coastguard Worker     char buf[8];
5806*8fb009dcSAndroid Build Coastguard Worker     snprintf(buf, sizeof(buf) - 1, "0x%02x", v);
5807*8fb009dcSAndroid Build Coastguard Worker     buf[sizeof(buf)-1] = 0;
5808*8fb009dcSAndroid Build Coastguard Worker     ret += std::string(buf);
5809*8fb009dcSAndroid Build Coastguard Worker   }
5810*8fb009dcSAndroid Build Coastguard Worker 
5811*8fb009dcSAndroid Build Coastguard Worker   ret += "}";
5812*8fb009dcSAndroid Build Coastguard Worker   return ret;
5813*8fb009dcSAndroid Build Coastguard Worker }
5814*8fb009dcSAndroid Build Coastguard Worker 
ExpectSigAlgsEqual(Span<const uint16_t> expected,Span<const uint16_t> actual)5815*8fb009dcSAndroid Build Coastguard Worker void ExpectSigAlgsEqual(Span<const uint16_t> expected,
5816*8fb009dcSAndroid Build Coastguard Worker                         Span<const uint16_t> actual) {
5817*8fb009dcSAndroid Build Coastguard Worker   bool matches = false;
5818*8fb009dcSAndroid Build Coastguard Worker   if (expected.size() == actual.size()) {
5819*8fb009dcSAndroid Build Coastguard Worker     matches = true;
5820*8fb009dcSAndroid Build Coastguard Worker 
5821*8fb009dcSAndroid Build Coastguard Worker     for (size_t i = 0; i < expected.size(); i++) {
5822*8fb009dcSAndroid Build Coastguard Worker       if (expected[i] != actual[i]) {
5823*8fb009dcSAndroid Build Coastguard Worker         matches = false;
5824*8fb009dcSAndroid Build Coastguard Worker         break;
5825*8fb009dcSAndroid Build Coastguard Worker       }
5826*8fb009dcSAndroid Build Coastguard Worker     }
5827*8fb009dcSAndroid Build Coastguard Worker   }
5828*8fb009dcSAndroid Build Coastguard Worker 
5829*8fb009dcSAndroid Build Coastguard Worker   if (!matches) {
5830*8fb009dcSAndroid Build Coastguard Worker     ADD_FAILURE() << "expected: " << SigAlgsToString(expected)
5831*8fb009dcSAndroid Build Coastguard Worker                   << " got: " << SigAlgsToString(actual);
5832*8fb009dcSAndroid Build Coastguard Worker   }
5833*8fb009dcSAndroid Build Coastguard Worker }
5834*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SigAlgs)5835*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SigAlgs) {
5836*8fb009dcSAndroid Build Coastguard Worker   static const struct {
5837*8fb009dcSAndroid Build Coastguard Worker     std::vector<int> input;
5838*8fb009dcSAndroid Build Coastguard Worker     bool ok;
5839*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint16_t> expected;
5840*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
5841*8fb009dcSAndroid Build Coastguard Worker       {{}, true, {}},
5842*8fb009dcSAndroid Build Coastguard Worker       {{1}, false, {}},
5843*8fb009dcSAndroid Build Coastguard Worker       {{1, 2, 3}, false, {}},
5844*8fb009dcSAndroid Build Coastguard Worker       {{NID_sha256, EVP_PKEY_ED25519}, false, {}},
5845*8fb009dcSAndroid Build Coastguard Worker       {{NID_sha256, EVP_PKEY_RSA, NID_sha256, EVP_PKEY_RSA}, false, {}},
5846*8fb009dcSAndroid Build Coastguard Worker 
5847*8fb009dcSAndroid Build Coastguard Worker       {{NID_sha256, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5848*8fb009dcSAndroid Build Coastguard Worker       {{NID_sha512, EVP_PKEY_RSA}, true, {SSL_SIGN_RSA_PKCS1_SHA512}},
5849*8fb009dcSAndroid Build Coastguard Worker       {{NID_sha256, EVP_PKEY_RSA_PSS}, true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5850*8fb009dcSAndroid Build Coastguard Worker       {{NID_undef, EVP_PKEY_ED25519}, true, {SSL_SIGN_ED25519}},
5851*8fb009dcSAndroid Build Coastguard Worker       {{NID_undef, EVP_PKEY_ED25519, NID_sha384, EVP_PKEY_EC},
5852*8fb009dcSAndroid Build Coastguard Worker        true,
5853*8fb009dcSAndroid Build Coastguard Worker        {SSL_SIGN_ED25519, SSL_SIGN_ECDSA_SECP384R1_SHA384}},
5854*8fb009dcSAndroid Build Coastguard Worker   };
5855*8fb009dcSAndroid Build Coastguard Worker 
5856*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5857*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
5858*8fb009dcSAndroid Build Coastguard Worker 
5859*8fb009dcSAndroid Build Coastguard Worker   unsigned n = 1;
5860*8fb009dcSAndroid Build Coastguard Worker   for (const auto &test : kTests) {
5861*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(n++);
5862*8fb009dcSAndroid Build Coastguard Worker 
5863*8fb009dcSAndroid Build Coastguard Worker     const bool ok =
5864*8fb009dcSAndroid Build Coastguard Worker         SSL_CTX_set1_sigalgs(ctx.get(), test.input.data(), test.input.size());
5865*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(ok, test.ok);
5866*8fb009dcSAndroid Build Coastguard Worker 
5867*8fb009dcSAndroid Build Coastguard Worker     if (!ok) {
5868*8fb009dcSAndroid Build Coastguard Worker       ERR_clear_error();
5869*8fb009dcSAndroid Build Coastguard Worker     }
5870*8fb009dcSAndroid Build Coastguard Worker 
5871*8fb009dcSAndroid Build Coastguard Worker     if (!test.ok) {
5872*8fb009dcSAndroid Build Coastguard Worker       continue;
5873*8fb009dcSAndroid Build Coastguard Worker     }
5874*8fb009dcSAndroid Build Coastguard Worker 
5875*8fb009dcSAndroid Build Coastguard Worker     ExpectSigAlgsEqual(test.expected, ctx->cert->default_credential->sigalgs);
5876*8fb009dcSAndroid Build Coastguard Worker   }
5877*8fb009dcSAndroid Build Coastguard Worker }
5878*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,SigAlgsList)5879*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, SigAlgsList) {
5880*8fb009dcSAndroid Build Coastguard Worker   static const struct {
5881*8fb009dcSAndroid Build Coastguard Worker     const char *input;
5882*8fb009dcSAndroid Build Coastguard Worker     bool ok;
5883*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint16_t> expected;
5884*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
5885*8fb009dcSAndroid Build Coastguard Worker       {"", false, {}},
5886*8fb009dcSAndroid Build Coastguard Worker       {":", false, {}},
5887*8fb009dcSAndroid Build Coastguard Worker       {"+", false, {}},
5888*8fb009dcSAndroid Build Coastguard Worker       {"RSA", false, {}},
5889*8fb009dcSAndroid Build Coastguard Worker       {"RSA+", false, {}},
5890*8fb009dcSAndroid Build Coastguard Worker       {"RSA+SHA256:", false, {}},
5891*8fb009dcSAndroid Build Coastguard Worker       {":RSA+SHA256:", false, {}},
5892*8fb009dcSAndroid Build Coastguard Worker       {":RSA+SHA256+:", false, {}},
5893*8fb009dcSAndroid Build Coastguard Worker       {"!", false, {}},
5894*8fb009dcSAndroid Build Coastguard Worker       {"\x01", false, {}},
5895*8fb009dcSAndroid Build Coastguard Worker       {"RSA+SHA256:RSA+SHA384:RSA+SHA256", false, {}},
5896*8fb009dcSAndroid Build Coastguard Worker       {"RSA-PSS+SHA256:rsa_pss_rsae_sha256", false, {}},
5897*8fb009dcSAndroid Build Coastguard Worker 
5898*8fb009dcSAndroid Build Coastguard Worker       {"RSA+SHA256", true, {SSL_SIGN_RSA_PKCS1_SHA256}},
5899*8fb009dcSAndroid Build Coastguard Worker       {"RSA+SHA256:ed25519",
5900*8fb009dcSAndroid Build Coastguard Worker        true,
5901*8fb009dcSAndroid Build Coastguard Worker        {SSL_SIGN_RSA_PKCS1_SHA256, SSL_SIGN_ED25519}},
5902*8fb009dcSAndroid Build Coastguard Worker       {"ECDSA+SHA256:RSA+SHA512",
5903*8fb009dcSAndroid Build Coastguard Worker        true,
5904*8fb009dcSAndroid Build Coastguard Worker        {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PKCS1_SHA512}},
5905*8fb009dcSAndroid Build Coastguard Worker       {"ecdsa_secp256r1_sha256:rsa_pss_rsae_sha256",
5906*8fb009dcSAndroid Build Coastguard Worker        true,
5907*8fb009dcSAndroid Build Coastguard Worker        {SSL_SIGN_ECDSA_SECP256R1_SHA256, SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5908*8fb009dcSAndroid Build Coastguard Worker       {"RSA-PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5909*8fb009dcSAndroid Build Coastguard Worker       {"PSS+SHA256", true, {SSL_SIGN_RSA_PSS_RSAE_SHA256}},
5910*8fb009dcSAndroid Build Coastguard Worker   };
5911*8fb009dcSAndroid Build Coastguard Worker 
5912*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
5913*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
5914*8fb009dcSAndroid Build Coastguard Worker 
5915*8fb009dcSAndroid Build Coastguard Worker   unsigned n = 1;
5916*8fb009dcSAndroid Build Coastguard Worker   for (const auto &test : kTests) {
5917*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(n++);
5918*8fb009dcSAndroid Build Coastguard Worker 
5919*8fb009dcSAndroid Build Coastguard Worker     const bool ok = SSL_CTX_set1_sigalgs_list(ctx.get(), test.input);
5920*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(ok, test.ok);
5921*8fb009dcSAndroid Build Coastguard Worker 
5922*8fb009dcSAndroid Build Coastguard Worker     if (!ok) {
5923*8fb009dcSAndroid Build Coastguard Worker       if (test.ok) {
5924*8fb009dcSAndroid Build Coastguard Worker         ERR_print_errors_fp(stderr);
5925*8fb009dcSAndroid Build Coastguard Worker       }
5926*8fb009dcSAndroid Build Coastguard Worker       ERR_clear_error();
5927*8fb009dcSAndroid Build Coastguard Worker     }
5928*8fb009dcSAndroid Build Coastguard Worker 
5929*8fb009dcSAndroid Build Coastguard Worker     if (!test.ok) {
5930*8fb009dcSAndroid Build Coastguard Worker       continue;
5931*8fb009dcSAndroid Build Coastguard Worker     }
5932*8fb009dcSAndroid Build Coastguard Worker 
5933*8fb009dcSAndroid Build Coastguard Worker     ExpectSigAlgsEqual(test.expected, ctx->cert->default_credential->sigalgs);
5934*8fb009dcSAndroid Build Coastguard Worker   }
5935*8fb009dcSAndroid Build Coastguard Worker }
5936*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ApplyHandoffRemovesUnsupportedCiphers)5937*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ApplyHandoffRemovesUnsupportedCiphers) {
5938*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5939*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
5940*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5941*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server);
5942*8fb009dcSAndroid Build Coastguard Worker 
5943*8fb009dcSAndroid Build Coastguard Worker   // handoff is a handoff message that has been artificially modified to pretend
5944*8fb009dcSAndroid Build Coastguard Worker   // that only TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) is supported. When
5945*8fb009dcSAndroid Build Coastguard Worker   // it is applied to |server|, all ciphers but that one should be removed.
5946*8fb009dcSAndroid Build Coastguard Worker   //
5947*8fb009dcSAndroid Build Coastguard Worker   // To make a new one of these, try sticking this in the |Handoff| test above:
5948*8fb009dcSAndroid Build Coastguard Worker   //
5949*8fb009dcSAndroid Build Coastguard Worker   // hexdump(stderr, "", handoff.data(), handoff.size());
5950*8fb009dcSAndroid Build Coastguard Worker   // sed -e 's/\(..\)/0x\1, /g'
5951*8fb009dcSAndroid Build Coastguard Worker   //
5952*8fb009dcSAndroid Build Coastguard Worker   // and modify serialize_features() to emit only cipher 0x0A.
5953*8fb009dcSAndroid Build Coastguard Worker 
5954*8fb009dcSAndroid Build Coastguard Worker   uint8_t handoff[] = {
5955*8fb009dcSAndroid Build Coastguard Worker       0x30, 0x81, 0x9a, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5956*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x00, 0x7e, 0x03, 0x03, 0x30, 0x8e, 0x8f, 0x79, 0xd2, 0x87, 0x39,
5957*8fb009dcSAndroid Build Coastguard Worker       0xc2, 0x23, 0x23, 0x13, 0xca, 0x3c, 0x80, 0x44, 0xfd, 0x80, 0x83, 0x62,
5958*8fb009dcSAndroid Build Coastguard Worker       0x3c, 0xcc, 0xf8, 0x76, 0xd3, 0x62, 0xbb, 0x54, 0xe3, 0xc4, 0x39, 0x24,
5959*8fb009dcSAndroid Build Coastguard Worker       0xa5, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5960*8fb009dcSAndroid Build Coastguard Worker       0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5961*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5962*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5963*8fb009dcSAndroid Build Coastguard Worker       0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5964*8fb009dcSAndroid Build Coastguard Worker       0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
5965*8fb009dcSAndroid Build Coastguard Worker       0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
5966*8fb009dcSAndroid Build Coastguard Worker       0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x02, 0xc0,
5967*8fb009dcSAndroid Build Coastguard Worker       0x2f, 0x04, 0x0a, 0x00, 0x15, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x00,
5968*8fb009dcSAndroid Build Coastguard Worker       0x1d,
5969*8fb009dcSAndroid Build Coastguard Worker   };
5970*8fb009dcSAndroid Build Coastguard Worker 
5971*8fb009dcSAndroid Build Coastguard Worker   EXPECT_LT(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5972*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
5973*8fb009dcSAndroid Build Coastguard Worker       SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
5974*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1u, sk_SSL_CIPHER_num(SSL_get_ciphers(server.get())));
5975*8fb009dcSAndroid Build Coastguard Worker }
5976*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ApplyHandoffRemovesUnsupportedCurves)5977*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ApplyHandoffRemovesUnsupportedCurves) {
5978*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
5979*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
5980*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> server(SSL_new(server_ctx.get()));
5981*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server);
5982*8fb009dcSAndroid Build Coastguard Worker 
5983*8fb009dcSAndroid Build Coastguard Worker   // handoff is a handoff message that has been artificially modified to pretend
5984*8fb009dcSAndroid Build Coastguard Worker   // that only one ECDH group is supported.  When it is applied to |server|, all
5985*8fb009dcSAndroid Build Coastguard Worker   // groups but that one should be removed.
5986*8fb009dcSAndroid Build Coastguard Worker   //
5987*8fb009dcSAndroid Build Coastguard Worker   // See |ApplyHandoffRemovesUnsupportedCiphers| for how to make a new one of
5988*8fb009dcSAndroid Build Coastguard Worker   // these.
5989*8fb009dcSAndroid Build Coastguard Worker   uint8_t handoff[] = {
5990*8fb009dcSAndroid Build Coastguard Worker       0x30, 0x81, 0xc0, 0x02, 0x01, 0x00, 0x04, 0x00, 0x04, 0x81, 0x82, 0x01,
5991*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x00, 0x7e, 0x03, 0x03, 0x98, 0x30, 0xce, 0xd9, 0xb0, 0xdf, 0x5f,
5992*8fb009dcSAndroid Build Coastguard Worker       0x82, 0x05, 0x4a, 0x43, 0x67, 0x7e, 0xdb, 0x6a, 0x4f, 0x21, 0x18, 0x4e,
5993*8fb009dcSAndroid Build Coastguard Worker       0x0d, 0x94, 0x63, 0x18, 0x8b, 0x54, 0x89, 0xdb, 0x8b, 0x1d, 0x84, 0xbc,
5994*8fb009dcSAndroid Build Coastguard Worker       0x09, 0x00, 0x00, 0x1e, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30,
5995*8fb009dcSAndroid Build Coastguard Worker       0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x0a, 0xc0, 0x14,
5996*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x0a, 0x01, 0x00,
5997*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x37, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00,
5998*8fb009dcSAndroid Build Coastguard Worker       0x0a, 0x00, 0x08, 0x00, 0x06, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00,
5999*8fb009dcSAndroid Build Coastguard Worker       0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x0d, 0x00,
6000*8fb009dcSAndroid Build Coastguard Worker       0x14, 0x00, 0x12, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x05, 0x03, 0x08,
6001*8fb009dcSAndroid Build Coastguard Worker       0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x02, 0x01, 0x04, 0x30, 0x00,
6002*8fb009dcSAndroid Build Coastguard Worker       0x02, 0x00, 0x0a, 0x00, 0x2f, 0x00, 0x35, 0x00, 0x8c, 0x00, 0x8d, 0x00,
6003*8fb009dcSAndroid Build Coastguard Worker       0x9c, 0x00, 0x9d, 0x13, 0x01, 0x13, 0x02, 0x13, 0x03, 0xc0, 0x09, 0xc0,
6004*8fb009dcSAndroid Build Coastguard Worker       0x0a, 0xc0, 0x13, 0xc0, 0x14, 0xc0, 0x2b, 0xc0, 0x2c, 0xc0, 0x2f, 0xc0,
6005*8fb009dcSAndroid Build Coastguard Worker       0x30, 0xc0, 0x35, 0xc0, 0x36, 0xcc, 0xa8, 0xcc, 0xa9, 0xcc, 0xac, 0x04,
6006*8fb009dcSAndroid Build Coastguard Worker       0x02, 0x00, 0x17,
6007*8fb009dcSAndroid Build Coastguard Worker   };
6008*8fb009dcSAndroid Build Coastguard Worker 
6009*8fb009dcSAndroid Build Coastguard Worker   // The zero length means that the default list of groups is used.
6010*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0u, server->config->supported_group_list.size());
6011*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
6012*8fb009dcSAndroid Build Coastguard Worker       SSL_apply_handoff(server.get(), {handoff, OPENSSL_ARRAY_SIZE(handoff)}));
6013*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1u, server->config->supported_group_list.size());
6014*8fb009dcSAndroid Build Coastguard Worker }
6015*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ZeroSizedWiteFlushesHandshakeMessages)6016*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ZeroSizedWiteFlushesHandshakeMessages) {
6017*8fb009dcSAndroid Build Coastguard Worker   // If there are pending handshake mesages, an |SSL_write| of zero bytes should
6018*8fb009dcSAndroid Build Coastguard Worker   // flush them.
6019*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(
6020*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method()));
6021*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
6022*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
6023*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
6024*8fb009dcSAndroid Build Coastguard Worker 
6025*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
6026*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
6027*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
6028*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
6029*8fb009dcSAndroid Build Coastguard Worker 
6030*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
6031*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
6032*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
6033*8fb009dcSAndroid Build Coastguard Worker 
6034*8fb009dcSAndroid Build Coastguard Worker   BIO *client_wbio = SSL_get_wbio(client.get());
6035*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0u, BIO_wpending(client_wbio));
6036*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_key_update(client.get(), SSL_KEY_UPDATE_NOT_REQUESTED));
6037*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0u, BIO_wpending(client_wbio));
6038*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_write(client.get(), nullptr, 0));
6039*8fb009dcSAndroid Build Coastguard Worker   EXPECT_NE(0u, BIO_wpending(client_wbio));
6040*8fb009dcSAndroid Build Coastguard Worker }
6041*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,VerifyBeforeCertRequest)6042*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, VerifyBeforeCertRequest) {
6043*8fb009dcSAndroid Build Coastguard Worker   // Configure the server to request client certificates.
6044*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
6045*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(), SSL_VERIFY_PEER,
6046*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
6047*8fb009dcSAndroid Build Coastguard Worker 
6048*8fb009dcSAndroid Build Coastguard Worker   // Configure the client to reject the server certificate.
6049*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
6050*8fb009dcSAndroid Build Coastguard Worker       client_ctx_.get(), SSL_VERIFY_PEER,
6051*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_invalid; });
6052*8fb009dcSAndroid Build Coastguard Worker 
6053*8fb009dcSAndroid Build Coastguard Worker   // cert_cb should not be called. Verification should fail first.
6054*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_cert_cb(client_ctx_.get(),
6055*8fb009dcSAndroid Build Coastguard Worker                       [](SSL *ssl, void *arg) {
6056*8fb009dcSAndroid Build Coastguard Worker                         ADD_FAILURE() << "cert_cb unexpectedly called";
6057*8fb009dcSAndroid Build Coastguard Worker                         return 0;
6058*8fb009dcSAndroid Build Coastguard Worker                       },
6059*8fb009dcSAndroid Build Coastguard Worker                       nullptr);
6060*8fb009dcSAndroid Build Coastguard Worker 
6061*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
6062*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6063*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx_.get()));
6064*8fb009dcSAndroid Build Coastguard Worker }
6065*8fb009dcSAndroid Build Coastguard Worker 
6066*8fb009dcSAndroid Build Coastguard Worker // Test that ticket-based sessions on the client get fake session IDs.
TEST_P(SSLVersionTest,FakeIDsForTickets)6067*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, FakeIDsForTickets) {
6068*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6069*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6070*8fb009dcSAndroid Build Coastguard Worker 
6071*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
6072*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
6073*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
6074*8fb009dcSAndroid Build Coastguard Worker 
6075*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_SESSION_has_ticket(session.get()));
6076*8fb009dcSAndroid Build Coastguard Worker   unsigned session_id_length;
6077*8fb009dcSAndroid Build Coastguard Worker   SSL_SESSION_get_id(session.get(), &session_id_length);
6078*8fb009dcSAndroid Build Coastguard Worker   EXPECT_NE(session_id_length, 0u);
6079*8fb009dcSAndroid Build Coastguard Worker }
6080*8fb009dcSAndroid Build Coastguard Worker 
6081*8fb009dcSAndroid Build Coastguard Worker // These tests test multi-threaded behavior. They are intended to run with
6082*8fb009dcSAndroid Build Coastguard Worker // ThreadSanitizer.
6083*8fb009dcSAndroid Build Coastguard Worker #if defined(OPENSSL_THREADS)
TEST_P(SSLVersionTest,SessionCacheThreads)6084*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SessionCacheThreads) {
6085*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
6086*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6087*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6088*8fb009dcSAndroid Build Coastguard Worker 
6089*8fb009dcSAndroid Build Coastguard Worker   if (version() == TLS1_3_VERSION) {
6090*8fb009dcSAndroid Build Coastguard Worker     // Our TLS 1.3 implementation does not support stateful resumption.
6091*8fb009dcSAndroid Build Coastguard Worker     ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
6092*8fb009dcSAndroid Build Coastguard Worker     return;
6093*8fb009dcSAndroid Build Coastguard Worker   }
6094*8fb009dcSAndroid Build Coastguard Worker 
6095*8fb009dcSAndroid Build Coastguard Worker   // Establish two client sessions to test with.
6096*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session1 =
6097*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
6098*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session1);
6099*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session2 =
6100*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
6101*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session2);
6102*8fb009dcSAndroid Build Coastguard Worker 
6103*8fb009dcSAndroid Build Coastguard Worker   auto connect_with_session = [&](SSL_SESSION *session) {
6104*8fb009dcSAndroid Build Coastguard Worker     ClientConfig config;
6105*8fb009dcSAndroid Build Coastguard Worker     config.session = session;
6106*8fb009dcSAndroid Build Coastguard Worker     UniquePtr<SSL> client, server;
6107*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6108*8fb009dcSAndroid Build Coastguard Worker                                        server_ctx_.get(), config));
6109*8fb009dcSAndroid Build Coastguard Worker   };
6110*8fb009dcSAndroid Build Coastguard Worker 
6111*8fb009dcSAndroid Build Coastguard Worker   // Resume sessions in parallel with establishing new ones.
6112*8fb009dcSAndroid Build Coastguard Worker   {
6113*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::thread> threads;
6114*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] { connect_with_session(nullptr); });
6115*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] { connect_with_session(nullptr); });
6116*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] { connect_with_session(session1.get()); });
6117*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] { connect_with_session(session1.get()); });
6118*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] { connect_with_session(session2.get()); });
6119*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] { connect_with_session(session2.get()); });
6120*8fb009dcSAndroid Build Coastguard Worker     for (auto &thread : threads) {
6121*8fb009dcSAndroid Build Coastguard Worker       thread.join();
6122*8fb009dcSAndroid Build Coastguard Worker     }
6123*8fb009dcSAndroid Build Coastguard Worker   }
6124*8fb009dcSAndroid Build Coastguard Worker 
6125*8fb009dcSAndroid Build Coastguard Worker   // Hit the maximum session cache size across multiple threads, to test the
6126*8fb009dcSAndroid Build Coastguard Worker   // size enforcement logic.
6127*8fb009dcSAndroid Build Coastguard Worker   size_t limit = SSL_CTX_sess_number(server_ctx_.get()) + 2;
6128*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_cache_size(server_ctx_.get(), limit);
6129*8fb009dcSAndroid Build Coastguard Worker   {
6130*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::thread> threads;
6131*8fb009dcSAndroid Build Coastguard Worker     for (int i = 0; i < 4; i++) {
6132*8fb009dcSAndroid Build Coastguard Worker       threads.emplace_back([&]() {
6133*8fb009dcSAndroid Build Coastguard Worker         connect_with_session(nullptr);
6134*8fb009dcSAndroid Build Coastguard Worker         EXPECT_LE(SSL_CTX_sess_number(server_ctx_.get()), limit);
6135*8fb009dcSAndroid Build Coastguard Worker       });
6136*8fb009dcSAndroid Build Coastguard Worker     }
6137*8fb009dcSAndroid Build Coastguard Worker     for (auto &thread : threads) {
6138*8fb009dcSAndroid Build Coastguard Worker       thread.join();
6139*8fb009dcSAndroid Build Coastguard Worker     }
6140*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_CTX_sess_number(server_ctx_.get()), limit);
6141*8fb009dcSAndroid Build Coastguard Worker   }
6142*8fb009dcSAndroid Build Coastguard Worker 
6143*8fb009dcSAndroid Build Coastguard Worker   // Reset the session cache, this time with a mock clock.
6144*8fb009dcSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(ResetContexts());
6145*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
6146*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6147*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6148*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_current_time_cb(server_ctx_.get(), CurrentTimeCallback);
6149*8fb009dcSAndroid Build Coastguard Worker 
6150*8fb009dcSAndroid Build Coastguard Worker   // Make some sessions at an arbitrary start time. Then expire them.
6151*8fb009dcSAndroid Build Coastguard Worker   g_current_time.tv_sec = 1000;
6152*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> expired_session1 =
6153*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
6154*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(expired_session1);
6155*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> expired_session2 =
6156*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
6157*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(expired_session2);
6158*8fb009dcSAndroid Build Coastguard Worker   g_current_time.tv_sec += 100 * SSL_DEFAULT_SESSION_TIMEOUT;
6159*8fb009dcSAndroid Build Coastguard Worker 
6160*8fb009dcSAndroid Build Coastguard Worker   session1 = CreateClientSession(client_ctx_.get(), server_ctx_.get());
6161*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session1);
6162*8fb009dcSAndroid Build Coastguard Worker 
6163*8fb009dcSAndroid Build Coastguard Worker   // Every 256 connections, we flush stale sessions from the session cache. Test
6164*8fb009dcSAndroid Build Coastguard Worker   // this logic is correctly synchronized with other connection attempts.
6165*8fb009dcSAndroid Build Coastguard Worker   static const int kNumConnections = 256;
6166*8fb009dcSAndroid Build Coastguard Worker   {
6167*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::thread> threads;
6168*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] {
6169*8fb009dcSAndroid Build Coastguard Worker       for (int i = 0; i < kNumConnections; i++) {
6170*8fb009dcSAndroid Build Coastguard Worker         connect_with_session(nullptr);
6171*8fb009dcSAndroid Build Coastguard Worker       }
6172*8fb009dcSAndroid Build Coastguard Worker     });
6173*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] {
6174*8fb009dcSAndroid Build Coastguard Worker       for (int i = 0; i < kNumConnections; i++) {
6175*8fb009dcSAndroid Build Coastguard Worker         connect_with_session(nullptr);
6176*8fb009dcSAndroid Build Coastguard Worker       }
6177*8fb009dcSAndroid Build Coastguard Worker     });
6178*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] {
6179*8fb009dcSAndroid Build Coastguard Worker       // Never connect with |expired_session2|. The session cache eagerly
6180*8fb009dcSAndroid Build Coastguard Worker       // removes expired sessions when it sees them. Leaving |expired_session2|
6181*8fb009dcSAndroid Build Coastguard Worker       // untouched ensures it is instead cleared by periodic flushing.
6182*8fb009dcSAndroid Build Coastguard Worker       for (int i = 0; i < kNumConnections; i++) {
6183*8fb009dcSAndroid Build Coastguard Worker         connect_with_session(expired_session1.get());
6184*8fb009dcSAndroid Build Coastguard Worker       }
6185*8fb009dcSAndroid Build Coastguard Worker     });
6186*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&] {
6187*8fb009dcSAndroid Build Coastguard Worker       for (int i = 0; i < kNumConnections; i++) {
6188*8fb009dcSAndroid Build Coastguard Worker         connect_with_session(session1.get());
6189*8fb009dcSAndroid Build Coastguard Worker       }
6190*8fb009dcSAndroid Build Coastguard Worker     });
6191*8fb009dcSAndroid Build Coastguard Worker     for (auto &thread : threads) {
6192*8fb009dcSAndroid Build Coastguard Worker       thread.join();
6193*8fb009dcSAndroid Build Coastguard Worker     }
6194*8fb009dcSAndroid Build Coastguard Worker   }
6195*8fb009dcSAndroid Build Coastguard Worker }
6196*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SessionTicketThreads)6197*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SessionTicketThreads) {
6198*8fb009dcSAndroid Build Coastguard Worker   for (bool renew_ticket : {false, true}) {
6199*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(renew_ticket);
6200*8fb009dcSAndroid Build Coastguard Worker     ASSERT_NO_FATAL_FAILURE(ResetContexts());
6201*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6202*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6203*8fb009dcSAndroid Build Coastguard Worker     if (renew_ticket) {
6204*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_tlsext_ticket_key_cb(server_ctx_.get(), RenewTicketCallback);
6205*8fb009dcSAndroid Build Coastguard Worker     }
6206*8fb009dcSAndroid Build Coastguard Worker 
6207*8fb009dcSAndroid Build Coastguard Worker     // Establish two client sessions to test with.
6208*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session1 =
6209*8fb009dcSAndroid Build Coastguard Worker         CreateClientSession(client_ctx_.get(), server_ctx_.get());
6210*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session1);
6211*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session2 =
6212*8fb009dcSAndroid Build Coastguard Worker         CreateClientSession(client_ctx_.get(), server_ctx_.get());
6213*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session2);
6214*8fb009dcSAndroid Build Coastguard Worker 
6215*8fb009dcSAndroid Build Coastguard Worker     auto connect_with_session = [&](SSL_SESSION *session) {
6216*8fb009dcSAndroid Build Coastguard Worker       ClientConfig config;
6217*8fb009dcSAndroid Build Coastguard Worker       config.session = session;
6218*8fb009dcSAndroid Build Coastguard Worker       UniquePtr<SSL> client, server;
6219*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
6220*8fb009dcSAndroid Build Coastguard Worker                                          server_ctx_.get(), config));
6221*8fb009dcSAndroid Build Coastguard Worker     };
6222*8fb009dcSAndroid Build Coastguard Worker 
6223*8fb009dcSAndroid Build Coastguard Worker     // Resume sessions in parallel with establishing new ones.
6224*8fb009dcSAndroid Build Coastguard Worker     {
6225*8fb009dcSAndroid Build Coastguard Worker       std::vector<std::thread> threads;
6226*8fb009dcSAndroid Build Coastguard Worker       threads.emplace_back([&] { connect_with_session(nullptr); });
6227*8fb009dcSAndroid Build Coastguard Worker       threads.emplace_back([&] { connect_with_session(nullptr); });
6228*8fb009dcSAndroid Build Coastguard Worker       threads.emplace_back([&] { connect_with_session(session1.get()); });
6229*8fb009dcSAndroid Build Coastguard Worker       threads.emplace_back([&] { connect_with_session(session1.get()); });
6230*8fb009dcSAndroid Build Coastguard Worker       threads.emplace_back([&] { connect_with_session(session2.get()); });
6231*8fb009dcSAndroid Build Coastguard Worker       threads.emplace_back([&] { connect_with_session(session2.get()); });
6232*8fb009dcSAndroid Build Coastguard Worker       for (auto &thread : threads) {
6233*8fb009dcSAndroid Build Coastguard Worker         thread.join();
6234*8fb009dcSAndroid Build Coastguard Worker       }
6235*8fb009dcSAndroid Build Coastguard Worker     }
6236*8fb009dcSAndroid Build Coastguard Worker   }
6237*8fb009dcSAndroid Build Coastguard Worker }
6238*8fb009dcSAndroid Build Coastguard Worker 
6239*8fb009dcSAndroid Build Coastguard Worker // SSL_CTX_get0_certificate needs to lock internally. Test this works.
TEST(SSLTest,GetCertificateThreads)6240*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, GetCertificateThreads) {
6241*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6242*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
6243*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetTestCertificate();
6244*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
6245*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
6246*8fb009dcSAndroid Build Coastguard Worker 
6247*8fb009dcSAndroid Build Coastguard Worker   // Existing code expects |SSL_CTX_get0_certificate| to be callable from two
6248*8fb009dcSAndroid Build Coastguard Worker   // threads concurrently. It originally was an immutable operation. Now we
6249*8fb009dcSAndroid Build Coastguard Worker   // implement it with a thread-safe cache, so it is worth testing.
6250*8fb009dcSAndroid Build Coastguard Worker   X509 *cert2_thread;
6251*8fb009dcSAndroid Build Coastguard Worker   std::thread thread(
6252*8fb009dcSAndroid Build Coastguard Worker       [&] { cert2_thread = SSL_CTX_get0_certificate(ctx.get()); });
6253*8fb009dcSAndroid Build Coastguard Worker   X509 *cert2 = SSL_CTX_get0_certificate(ctx.get());
6254*8fb009dcSAndroid Build Coastguard Worker   thread.join();
6255*8fb009dcSAndroid Build Coastguard Worker 
6256*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert2);
6257*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert2_thread);
6258*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(cert2, cert2_thread);
6259*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, X509_cmp(cert.get(), cert2));
6260*8fb009dcSAndroid Build Coastguard Worker }
6261*8fb009dcSAndroid Build Coastguard Worker 
6262*8fb009dcSAndroid Build Coastguard Worker // Functions which access properties on the negotiated session are thread-safe
6263*8fb009dcSAndroid Build Coastguard Worker // where needed. Prior to TLS 1.3, clients resuming sessions and servers
6264*8fb009dcSAndroid Build Coastguard Worker // performing stateful resumption will share an underlying SSL_SESSION object,
6265*8fb009dcSAndroid Build Coastguard Worker // potentially across threads.
TEST_P(SSLVersionTest,SessionPropertiesThreads)6266*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SessionPropertiesThreads) {
6267*8fb009dcSAndroid Build Coastguard Worker   if (version() == TLS1_3_VERSION) {
6268*8fb009dcSAndroid Build Coastguard Worker     // Our TLS 1.3 implementation does not support stateful resumption.
6269*8fb009dcSAndroid Build Coastguard Worker     ASSERT_FALSE(CreateClientSession(client_ctx_.get(), server_ctx_.get()));
6270*8fb009dcSAndroid Build Coastguard Worker     return;
6271*8fb009dcSAndroid Build Coastguard Worker   }
6272*8fb009dcSAndroid Build Coastguard Worker 
6273*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
6274*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6275*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
6276*8fb009dcSAndroid Build Coastguard Worker 
6277*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(client_ctx_.get()));
6278*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(server_ctx_.get()));
6279*8fb009dcSAndroid Build Coastguard Worker 
6280*8fb009dcSAndroid Build Coastguard Worker   // Configure mutual authentication, so we have more session state.
6281*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
6282*8fb009dcSAndroid Build Coastguard Worker       client_ctx_.get(), SSL_VERIFY_PEER,
6283*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
6284*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_custom_verify(
6285*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(), SSL_VERIFY_PEER,
6286*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
6287*8fb009dcSAndroid Build Coastguard Worker 
6288*8fb009dcSAndroid Build Coastguard Worker   // Establish a client session to test with.
6289*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
6290*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
6291*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
6292*8fb009dcSAndroid Build Coastguard Worker 
6293*8fb009dcSAndroid Build Coastguard Worker   // Resume with it twice.
6294*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL> ssls[4];
6295*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
6296*8fb009dcSAndroid Build Coastguard Worker   config.session = session.get();
6297*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&ssls[0], &ssls[1], client_ctx_.get(),
6298*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx_.get(), config));
6299*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&ssls[2], &ssls[3], client_ctx_.get(),
6300*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx_.get(), config));
6301*8fb009dcSAndroid Build Coastguard Worker 
6302*8fb009dcSAndroid Build Coastguard Worker   // Read properties in parallel.
6303*8fb009dcSAndroid Build Coastguard Worker   auto read_properties = [](const SSL *ssl) {
6304*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_get_peer_cert_chain(ssl));
6305*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(ssl));
6306*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(peer);
6307*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_get_current_cipher(ssl));
6308*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_get_group_id(ssl));
6309*8fb009dcSAndroid Build Coastguard Worker   };
6310*8fb009dcSAndroid Build Coastguard Worker 
6311*8fb009dcSAndroid Build Coastguard Worker   std::vector<std::thread> threads;
6312*8fb009dcSAndroid Build Coastguard Worker   for (const auto &ssl_ptr : ssls) {
6313*8fb009dcSAndroid Build Coastguard Worker     const SSL *ssl = ssl_ptr.get();
6314*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([=] { read_properties(ssl); });
6315*8fb009dcSAndroid Build Coastguard Worker   }
6316*8fb009dcSAndroid Build Coastguard Worker   for (auto &thread : threads) {
6317*8fb009dcSAndroid Build Coastguard Worker     thread.join();
6318*8fb009dcSAndroid Build Coastguard Worker   }
6319*8fb009dcSAndroid Build Coastguard Worker }
6320*8fb009dcSAndroid Build Coastguard Worker 
SetValueOnFree(void * parent,void * ptr,CRYPTO_EX_DATA * ad,int index,long argl,void * argp)6321*8fb009dcSAndroid Build Coastguard Worker static void SetValueOnFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
6322*8fb009dcSAndroid Build Coastguard Worker                           int index, long argl, void *argp) {
6323*8fb009dcSAndroid Build Coastguard Worker   if (ptr != nullptr) {
6324*8fb009dcSAndroid Build Coastguard Worker     *static_cast<long *>(ptr) = argl;
6325*8fb009dcSAndroid Build Coastguard Worker   }
6326*8fb009dcSAndroid Build Coastguard Worker }
6327*8fb009dcSAndroid Build Coastguard Worker 
6328*8fb009dcSAndroid Build Coastguard Worker // Test that one thread can register ex_data while another thread is destroying
6329*8fb009dcSAndroid Build Coastguard Worker // an object that uses it.
TEST(SSLTest,ExDataThreads)6330*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ExDataThreads) {
6331*8fb009dcSAndroid Build Coastguard Worker   static bool already_run = false;
6332*8fb009dcSAndroid Build Coastguard Worker   if (already_run) {
6333*8fb009dcSAndroid Build Coastguard Worker     GTEST_SKIP() << "This test consumes process-global resources and can only "
6334*8fb009dcSAndroid Build Coastguard Worker                     "be run once in a process. It is not compatible with "
6335*8fb009dcSAndroid Build Coastguard Worker                     "--gtest_repeat.";
6336*8fb009dcSAndroid Build Coastguard Worker   }
6337*8fb009dcSAndroid Build Coastguard Worker   already_run = true;
6338*8fb009dcSAndroid Build Coastguard Worker 
6339*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
6340*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
6341*8fb009dcSAndroid Build Coastguard Worker 
6342*8fb009dcSAndroid Build Coastguard Worker   // Register an initial index, so the threads can exercise having any ex_data.
6343*8fb009dcSAndroid Build Coastguard Worker   int first_index =
6344*8fb009dcSAndroid Build Coastguard Worker       SSL_get_ex_new_index(-1, nullptr, nullptr, nullptr, SetValueOnFree);
6345*8fb009dcSAndroid Build Coastguard Worker   ASSERT_GE(first_index, 0);
6346*8fb009dcSAndroid Build Coastguard Worker 
6347*8fb009dcSAndroid Build Coastguard Worker   // Callers may register indices concurrently with using other indices. This
6348*8fb009dcSAndroid Build Coastguard Worker   // may happen if one part of an application is initializing while another part
6349*8fb009dcSAndroid Build Coastguard Worker   // is already running.
6350*8fb009dcSAndroid Build Coastguard Worker   static constexpr int kNumIndices = 3;
6351*8fb009dcSAndroid Build Coastguard Worker   static constexpr int kNumSSLs = 10;
6352*8fb009dcSAndroid Build Coastguard Worker   int index[kNumIndices];
6353*8fb009dcSAndroid Build Coastguard Worker   long values[kNumSSLs];
6354*8fb009dcSAndroid Build Coastguard Worker   std::fill(std::begin(values), std::end(values), -2);
6355*8fb009dcSAndroid Build Coastguard Worker   std::vector<std::thread> threads;
6356*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumIndices; i++) {
6357*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&, i] {
6358*8fb009dcSAndroid Build Coastguard Worker       index[i] = SSL_get_ex_new_index(static_cast<long>(i), nullptr, nullptr,
6359*8fb009dcSAndroid Build Coastguard Worker                                       nullptr, SetValueOnFree);
6360*8fb009dcSAndroid Build Coastguard Worker       ASSERT_GE(index[i], 0);
6361*8fb009dcSAndroid Build Coastguard Worker     });
6362*8fb009dcSAndroid Build Coastguard Worker   }
6363*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumSSLs; i++) {
6364*8fb009dcSAndroid Build Coastguard Worker     threads.emplace_back([&, i] {
6365*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
6366*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ssl);
6367*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_set_ex_data(ssl.get(), first_index, &values[i]));
6368*8fb009dcSAndroid Build Coastguard Worker     });
6369*8fb009dcSAndroid Build Coastguard Worker   }
6370*8fb009dcSAndroid Build Coastguard Worker   for (auto &thread : threads) {
6371*8fb009dcSAndroid Build Coastguard Worker     thread.join();
6372*8fb009dcSAndroid Build Coastguard Worker   }
6373*8fb009dcSAndroid Build Coastguard Worker 
6374*8fb009dcSAndroid Build Coastguard Worker   // Each of the SSL threads should have set their flag via ex_data.
6375*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumSSLs; i++) {
6376*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(values[i], -1);
6377*8fb009dcSAndroid Build Coastguard Worker   }
6378*8fb009dcSAndroid Build Coastguard Worker 
6379*8fb009dcSAndroid Build Coastguard Worker   // Each of the newly-registered indices should be distinct and work correctly.
6380*8fb009dcSAndroid Build Coastguard Worker   static_assert(kNumIndices <= kNumSSLs, "values buffer too small");
6381*8fb009dcSAndroid Build Coastguard Worker   std::fill(std::begin(values), std::end(values), -2);
6382*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl(SSL_new(ctx.get()));
6383*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl);
6384*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumIndices; i++) {
6385*8fb009dcSAndroid Build Coastguard Worker     for (size_t j = 0; j < i; j++) {
6386*8fb009dcSAndroid Build Coastguard Worker       EXPECT_NE(index[i], index[j]);
6387*8fb009dcSAndroid Build Coastguard Worker     }
6388*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_set_ex_data(ssl.get(), index[i], &values[i]));
6389*8fb009dcSAndroid Build Coastguard Worker   }
6390*8fb009dcSAndroid Build Coastguard Worker   ssl = nullptr;
6391*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < kNumIndices; i++) {
6392*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(values[i], static_cast<long>(i));
6393*8fb009dcSAndroid Build Coastguard Worker   }
6394*8fb009dcSAndroid Build Coastguard Worker }
6395*8fb009dcSAndroid Build Coastguard Worker #endif  // OPENSSL_THREADS
6396*8fb009dcSAndroid Build Coastguard Worker 
6397*8fb009dcSAndroid Build Coastguard Worker constexpr size_t kNumQUICLevels = 4;
6398*8fb009dcSAndroid Build Coastguard Worker static_assert(ssl_encryption_initial < kNumQUICLevels,
6399*8fb009dcSAndroid Build Coastguard Worker               "kNumQUICLevels is wrong");
6400*8fb009dcSAndroid Build Coastguard Worker static_assert(ssl_encryption_early_data < kNumQUICLevels,
6401*8fb009dcSAndroid Build Coastguard Worker               "kNumQUICLevels is wrong");
6402*8fb009dcSAndroid Build Coastguard Worker static_assert(ssl_encryption_handshake < kNumQUICLevels,
6403*8fb009dcSAndroid Build Coastguard Worker               "kNumQUICLevels is wrong");
6404*8fb009dcSAndroid Build Coastguard Worker static_assert(ssl_encryption_application < kNumQUICLevels,
6405*8fb009dcSAndroid Build Coastguard Worker               "kNumQUICLevels is wrong");
6406*8fb009dcSAndroid Build Coastguard Worker 
LevelToString(ssl_encryption_level_t level)6407*8fb009dcSAndroid Build Coastguard Worker const char *LevelToString(ssl_encryption_level_t level) {
6408*8fb009dcSAndroid Build Coastguard Worker   switch (level) {
6409*8fb009dcSAndroid Build Coastguard Worker     case ssl_encryption_initial:
6410*8fb009dcSAndroid Build Coastguard Worker       return "initial";
6411*8fb009dcSAndroid Build Coastguard Worker     case ssl_encryption_early_data:
6412*8fb009dcSAndroid Build Coastguard Worker       return "early data";
6413*8fb009dcSAndroid Build Coastguard Worker     case ssl_encryption_handshake:
6414*8fb009dcSAndroid Build Coastguard Worker       return "handshake";
6415*8fb009dcSAndroid Build Coastguard Worker     case ssl_encryption_application:
6416*8fb009dcSAndroid Build Coastguard Worker       return "application";
6417*8fb009dcSAndroid Build Coastguard Worker   }
6418*8fb009dcSAndroid Build Coastguard Worker   return "<unknown>";
6419*8fb009dcSAndroid Build Coastguard Worker }
6420*8fb009dcSAndroid Build Coastguard Worker 
6421*8fb009dcSAndroid Build Coastguard Worker class MockQUICTransport {
6422*8fb009dcSAndroid Build Coastguard Worker  public:
6423*8fb009dcSAndroid Build Coastguard Worker   enum class Role { kClient, kServer };
6424*8fb009dcSAndroid Build Coastguard Worker 
MockQUICTransport(Role role)6425*8fb009dcSAndroid Build Coastguard Worker   explicit MockQUICTransport(Role role) : role_(role) {
6426*8fb009dcSAndroid Build Coastguard Worker     // The caller is expected to configure initial secrets.
6427*8fb009dcSAndroid Build Coastguard Worker     levels_[ssl_encryption_initial].write_secret = {1};
6428*8fb009dcSAndroid Build Coastguard Worker     levels_[ssl_encryption_initial].read_secret = {1};
6429*8fb009dcSAndroid Build Coastguard Worker   }
6430*8fb009dcSAndroid Build Coastguard Worker 
set_peer(MockQUICTransport * peer)6431*8fb009dcSAndroid Build Coastguard Worker   void set_peer(MockQUICTransport *peer) { peer_ = peer; }
6432*8fb009dcSAndroid Build Coastguard Worker 
has_alert() const6433*8fb009dcSAndroid Build Coastguard Worker   bool has_alert() const { return has_alert_; }
alert_level() const6434*8fb009dcSAndroid Build Coastguard Worker   ssl_encryption_level_t alert_level() const { return alert_level_; }
alert() const6435*8fb009dcSAndroid Build Coastguard Worker   uint8_t alert() const { return alert_; }
6436*8fb009dcSAndroid Build Coastguard Worker 
PeerSecretsMatch(ssl_encryption_level_t level) const6437*8fb009dcSAndroid Build Coastguard Worker   bool PeerSecretsMatch(ssl_encryption_level_t level) const {
6438*8fb009dcSAndroid Build Coastguard Worker     return levels_[level].write_secret == peer_->levels_[level].read_secret &&
6439*8fb009dcSAndroid Build Coastguard Worker            levels_[level].read_secret == peer_->levels_[level].write_secret &&
6440*8fb009dcSAndroid Build Coastguard Worker            levels_[level].cipher == peer_->levels_[level].cipher;
6441*8fb009dcSAndroid Build Coastguard Worker   }
6442*8fb009dcSAndroid Build Coastguard Worker 
HasReadSecret(ssl_encryption_level_t level) const6443*8fb009dcSAndroid Build Coastguard Worker   bool HasReadSecret(ssl_encryption_level_t level) const {
6444*8fb009dcSAndroid Build Coastguard Worker     return !levels_[level].read_secret.empty();
6445*8fb009dcSAndroid Build Coastguard Worker   }
6446*8fb009dcSAndroid Build Coastguard Worker 
HasWriteSecret(ssl_encryption_level_t level) const6447*8fb009dcSAndroid Build Coastguard Worker   bool HasWriteSecret(ssl_encryption_level_t level) const {
6448*8fb009dcSAndroid Build Coastguard Worker     return !levels_[level].write_secret.empty();
6449*8fb009dcSAndroid Build Coastguard Worker   }
6450*8fb009dcSAndroid Build Coastguard Worker 
AllowOutOfOrderWrites()6451*8fb009dcSAndroid Build Coastguard Worker   void AllowOutOfOrderWrites() { allow_out_of_order_writes_ = true; }
6452*8fb009dcSAndroid Build Coastguard Worker 
SetReadSecret(ssl_encryption_level_t level,const SSL_CIPHER * cipher,Span<const uint8_t> secret)6453*8fb009dcSAndroid Build Coastguard Worker   bool SetReadSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
6454*8fb009dcSAndroid Build Coastguard Worker                      Span<const uint8_t> secret) {
6455*8fb009dcSAndroid Build Coastguard Worker     if (HasReadSecret(level)) {
6456*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << LevelToString(level) << " read secret configured twice";
6457*8fb009dcSAndroid Build Coastguard Worker       return false;
6458*8fb009dcSAndroid Build Coastguard Worker     }
6459*8fb009dcSAndroid Build Coastguard Worker 
6460*8fb009dcSAndroid Build Coastguard Worker     if (role_ == Role::kClient && level == ssl_encryption_early_data) {
6461*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "Unexpected early data read secret";
6462*8fb009dcSAndroid Build Coastguard Worker       return false;
6463*8fb009dcSAndroid Build Coastguard Worker     }
6464*8fb009dcSAndroid Build Coastguard Worker 
6465*8fb009dcSAndroid Build Coastguard Worker     ssl_encryption_level_t ack_level =
6466*8fb009dcSAndroid Build Coastguard Worker         level == ssl_encryption_early_data ? ssl_encryption_application : level;
6467*8fb009dcSAndroid Build Coastguard Worker     if (!HasWriteSecret(ack_level)) {
6468*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << LevelToString(level)
6469*8fb009dcSAndroid Build Coastguard Worker                     << " read secret configured before ACK write secret";
6470*8fb009dcSAndroid Build Coastguard Worker       return false;
6471*8fb009dcSAndroid Build Coastguard Worker     }
6472*8fb009dcSAndroid Build Coastguard Worker 
6473*8fb009dcSAndroid Build Coastguard Worker     if (cipher == nullptr) {
6474*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "Unexpected null cipher";
6475*8fb009dcSAndroid Build Coastguard Worker       return false;
6476*8fb009dcSAndroid Build Coastguard Worker     }
6477*8fb009dcSAndroid Build Coastguard Worker 
6478*8fb009dcSAndroid Build Coastguard Worker     if (level != ssl_encryption_early_data &&
6479*8fb009dcSAndroid Build Coastguard Worker         SSL_CIPHER_get_id(cipher) != levels_[level].cipher) {
6480*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "Cipher suite inconsistent";
6481*8fb009dcSAndroid Build Coastguard Worker       return false;
6482*8fb009dcSAndroid Build Coastguard Worker     }
6483*8fb009dcSAndroid Build Coastguard Worker 
6484*8fb009dcSAndroid Build Coastguard Worker     levels_[level].read_secret.assign(secret.begin(), secret.end());
6485*8fb009dcSAndroid Build Coastguard Worker     levels_[level].cipher = SSL_CIPHER_get_id(cipher);
6486*8fb009dcSAndroid Build Coastguard Worker     return true;
6487*8fb009dcSAndroid Build Coastguard Worker   }
6488*8fb009dcSAndroid Build Coastguard Worker 
SetWriteSecret(ssl_encryption_level_t level,const SSL_CIPHER * cipher,Span<const uint8_t> secret)6489*8fb009dcSAndroid Build Coastguard Worker   bool SetWriteSecret(ssl_encryption_level_t level, const SSL_CIPHER *cipher,
6490*8fb009dcSAndroid Build Coastguard Worker                       Span<const uint8_t> secret) {
6491*8fb009dcSAndroid Build Coastguard Worker     if (HasWriteSecret(level)) {
6492*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << LevelToString(level) << " write secret configured twice";
6493*8fb009dcSAndroid Build Coastguard Worker       return false;
6494*8fb009dcSAndroid Build Coastguard Worker     }
6495*8fb009dcSAndroid Build Coastguard Worker 
6496*8fb009dcSAndroid Build Coastguard Worker     if (role_ == Role::kServer && level == ssl_encryption_early_data) {
6497*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "Unexpected early data write secret";
6498*8fb009dcSAndroid Build Coastguard Worker       return false;
6499*8fb009dcSAndroid Build Coastguard Worker     }
6500*8fb009dcSAndroid Build Coastguard Worker 
6501*8fb009dcSAndroid Build Coastguard Worker     if (cipher == nullptr) {
6502*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "Unexpected null cipher";
6503*8fb009dcSAndroid Build Coastguard Worker       return false;
6504*8fb009dcSAndroid Build Coastguard Worker     }
6505*8fb009dcSAndroid Build Coastguard Worker 
6506*8fb009dcSAndroid Build Coastguard Worker     levels_[level].write_secret.assign(secret.begin(), secret.end());
6507*8fb009dcSAndroid Build Coastguard Worker     levels_[level].cipher = SSL_CIPHER_get_id(cipher);
6508*8fb009dcSAndroid Build Coastguard Worker     return true;
6509*8fb009dcSAndroid Build Coastguard Worker   }
6510*8fb009dcSAndroid Build Coastguard Worker 
WriteHandshakeData(ssl_encryption_level_t level,Span<const uint8_t> data)6511*8fb009dcSAndroid Build Coastguard Worker   bool WriteHandshakeData(ssl_encryption_level_t level,
6512*8fb009dcSAndroid Build Coastguard Worker                           Span<const uint8_t> data) {
6513*8fb009dcSAndroid Build Coastguard Worker     if (levels_[level].write_secret.empty()) {
6514*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << LevelToString(level)
6515*8fb009dcSAndroid Build Coastguard Worker                     << " write secret not yet configured";
6516*8fb009dcSAndroid Build Coastguard Worker       return false;
6517*8fb009dcSAndroid Build Coastguard Worker     }
6518*8fb009dcSAndroid Build Coastguard Worker 
6519*8fb009dcSAndroid Build Coastguard Worker     // Although the levels are conceptually separate, BoringSSL finishes writing
6520*8fb009dcSAndroid Build Coastguard Worker     // data from a previous level before installing keys for the next level.
6521*8fb009dcSAndroid Build Coastguard Worker     if (!allow_out_of_order_writes_) {
6522*8fb009dcSAndroid Build Coastguard Worker       switch (level) {
6523*8fb009dcSAndroid Build Coastguard Worker         case ssl_encryption_early_data:
6524*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "unexpected handshake data at early data level";
6525*8fb009dcSAndroid Build Coastguard Worker           return false;
6526*8fb009dcSAndroid Build Coastguard Worker         case ssl_encryption_initial:
6527*8fb009dcSAndroid Build Coastguard Worker           if (!levels_[ssl_encryption_handshake].write_secret.empty()) {
6528*8fb009dcSAndroid Build Coastguard Worker             ADD_FAILURE()
6529*8fb009dcSAndroid Build Coastguard Worker                 << LevelToString(level)
6530*8fb009dcSAndroid Build Coastguard Worker                 << " handshake data written after handshake keys installed";
6531*8fb009dcSAndroid Build Coastguard Worker             return false;
6532*8fb009dcSAndroid Build Coastguard Worker           }
6533*8fb009dcSAndroid Build Coastguard Worker           OPENSSL_FALLTHROUGH;
6534*8fb009dcSAndroid Build Coastguard Worker         case ssl_encryption_handshake:
6535*8fb009dcSAndroid Build Coastguard Worker           if (!levels_[ssl_encryption_application].write_secret.empty()) {
6536*8fb009dcSAndroid Build Coastguard Worker             ADD_FAILURE()
6537*8fb009dcSAndroid Build Coastguard Worker                 << LevelToString(level)
6538*8fb009dcSAndroid Build Coastguard Worker                 << " handshake data written after application keys installed";
6539*8fb009dcSAndroid Build Coastguard Worker             return false;
6540*8fb009dcSAndroid Build Coastguard Worker           }
6541*8fb009dcSAndroid Build Coastguard Worker           OPENSSL_FALLTHROUGH;
6542*8fb009dcSAndroid Build Coastguard Worker         case ssl_encryption_application:
6543*8fb009dcSAndroid Build Coastguard Worker           break;
6544*8fb009dcSAndroid Build Coastguard Worker       }
6545*8fb009dcSAndroid Build Coastguard Worker     }
6546*8fb009dcSAndroid Build Coastguard Worker 
6547*8fb009dcSAndroid Build Coastguard Worker     levels_[level].write_data.insert(levels_[level].write_data.end(),
6548*8fb009dcSAndroid Build Coastguard Worker                                      data.begin(), data.end());
6549*8fb009dcSAndroid Build Coastguard Worker     return true;
6550*8fb009dcSAndroid Build Coastguard Worker   }
6551*8fb009dcSAndroid Build Coastguard Worker 
SendAlert(ssl_encryption_level_t level,uint8_t alert_value)6552*8fb009dcSAndroid Build Coastguard Worker   bool SendAlert(ssl_encryption_level_t level, uint8_t alert_value) {
6553*8fb009dcSAndroid Build Coastguard Worker     if (has_alert_) {
6554*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "duplicate alert sent";
6555*8fb009dcSAndroid Build Coastguard Worker       return false;
6556*8fb009dcSAndroid Build Coastguard Worker     }
6557*8fb009dcSAndroid Build Coastguard Worker 
6558*8fb009dcSAndroid Build Coastguard Worker     if (levels_[level].write_secret.empty()) {
6559*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << LevelToString(level)
6560*8fb009dcSAndroid Build Coastguard Worker                     << " write secret not yet configured";
6561*8fb009dcSAndroid Build Coastguard Worker       return false;
6562*8fb009dcSAndroid Build Coastguard Worker     }
6563*8fb009dcSAndroid Build Coastguard Worker 
6564*8fb009dcSAndroid Build Coastguard Worker     has_alert_ = true;
6565*8fb009dcSAndroid Build Coastguard Worker     alert_level_ = level;
6566*8fb009dcSAndroid Build Coastguard Worker     alert_ = alert_value;
6567*8fb009dcSAndroid Build Coastguard Worker     return true;
6568*8fb009dcSAndroid Build Coastguard Worker   }
6569*8fb009dcSAndroid Build Coastguard Worker 
ReadHandshakeData(std::vector<uint8_t> * out,ssl_encryption_level_t level,size_t num=std::numeric_limits<size_t>::max ())6570*8fb009dcSAndroid Build Coastguard Worker   bool ReadHandshakeData(std::vector<uint8_t> *out,
6571*8fb009dcSAndroid Build Coastguard Worker                          ssl_encryption_level_t level,
6572*8fb009dcSAndroid Build Coastguard Worker                          size_t num = std::numeric_limits<size_t>::max()) {
6573*8fb009dcSAndroid Build Coastguard Worker     if (levels_[level].read_secret.empty()) {
6574*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "data read before keys configured in level " << level;
6575*8fb009dcSAndroid Build Coastguard Worker       return false;
6576*8fb009dcSAndroid Build Coastguard Worker     }
6577*8fb009dcSAndroid Build Coastguard Worker     // The peer may not have configured any keys yet.
6578*8fb009dcSAndroid Build Coastguard Worker     if (peer_->levels_[level].write_secret.empty()) {
6579*8fb009dcSAndroid Build Coastguard Worker       out->clear();
6580*8fb009dcSAndroid Build Coastguard Worker       return true;
6581*8fb009dcSAndroid Build Coastguard Worker     }
6582*8fb009dcSAndroid Build Coastguard Worker     // Check the peer computed the same key.
6583*8fb009dcSAndroid Build Coastguard Worker     if (peer_->levels_[level].write_secret != levels_[level].read_secret) {
6584*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "peer write key does not match read key in level "
6585*8fb009dcSAndroid Build Coastguard Worker                     << level;
6586*8fb009dcSAndroid Build Coastguard Worker       return false;
6587*8fb009dcSAndroid Build Coastguard Worker     }
6588*8fb009dcSAndroid Build Coastguard Worker     if (peer_->levels_[level].cipher != levels_[level].cipher) {
6589*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "peer cipher does not match in level " << level;
6590*8fb009dcSAndroid Build Coastguard Worker       return false;
6591*8fb009dcSAndroid Build Coastguard Worker     }
6592*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> *peer_data = &peer_->levels_[level].write_data;
6593*8fb009dcSAndroid Build Coastguard Worker     num = std::min(num, peer_data->size());
6594*8fb009dcSAndroid Build Coastguard Worker     out->assign(peer_data->begin(), peer_data->begin() + num);
6595*8fb009dcSAndroid Build Coastguard Worker     peer_data->erase(peer_data->begin(), peer_data->begin() + num);
6596*8fb009dcSAndroid Build Coastguard Worker     return true;
6597*8fb009dcSAndroid Build Coastguard Worker   }
6598*8fb009dcSAndroid Build Coastguard Worker 
6599*8fb009dcSAndroid Build Coastguard Worker  private:
6600*8fb009dcSAndroid Build Coastguard Worker   Role role_;
6601*8fb009dcSAndroid Build Coastguard Worker   MockQUICTransport *peer_ = nullptr;
6602*8fb009dcSAndroid Build Coastguard Worker 
6603*8fb009dcSAndroid Build Coastguard Worker   bool allow_out_of_order_writes_ = false;
6604*8fb009dcSAndroid Build Coastguard Worker   bool has_alert_ = false;
6605*8fb009dcSAndroid Build Coastguard Worker   ssl_encryption_level_t alert_level_ = ssl_encryption_initial;
6606*8fb009dcSAndroid Build Coastguard Worker   uint8_t alert_ = 0;
6607*8fb009dcSAndroid Build Coastguard Worker 
6608*8fb009dcSAndroid Build Coastguard Worker   struct Level {
6609*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> write_data;
6610*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> write_secret;
6611*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> read_secret;
6612*8fb009dcSAndroid Build Coastguard Worker     uint32_t cipher = 0;
6613*8fb009dcSAndroid Build Coastguard Worker   };
6614*8fb009dcSAndroid Build Coastguard Worker   Level levels_[kNumQUICLevels];
6615*8fb009dcSAndroid Build Coastguard Worker };
6616*8fb009dcSAndroid Build Coastguard Worker 
6617*8fb009dcSAndroid Build Coastguard Worker class MockQUICTransportPair {
6618*8fb009dcSAndroid Build Coastguard Worker  public:
MockQUICTransportPair()6619*8fb009dcSAndroid Build Coastguard Worker   MockQUICTransportPair()
6620*8fb009dcSAndroid Build Coastguard Worker       : client_(MockQUICTransport::Role::kClient),
6621*8fb009dcSAndroid Build Coastguard Worker         server_(MockQUICTransport::Role::kServer) {
6622*8fb009dcSAndroid Build Coastguard Worker     client_.set_peer(&server_);
6623*8fb009dcSAndroid Build Coastguard Worker     server_.set_peer(&client_);
6624*8fb009dcSAndroid Build Coastguard Worker   }
6625*8fb009dcSAndroid Build Coastguard Worker 
~MockQUICTransportPair()6626*8fb009dcSAndroid Build Coastguard Worker   ~MockQUICTransportPair() {
6627*8fb009dcSAndroid Build Coastguard Worker     client_.set_peer(nullptr);
6628*8fb009dcSAndroid Build Coastguard Worker     server_.set_peer(nullptr);
6629*8fb009dcSAndroid Build Coastguard Worker   }
6630*8fb009dcSAndroid Build Coastguard Worker 
client()6631*8fb009dcSAndroid Build Coastguard Worker   MockQUICTransport *client() { return &client_; }
server()6632*8fb009dcSAndroid Build Coastguard Worker   MockQUICTransport *server() { return &server_; }
6633*8fb009dcSAndroid Build Coastguard Worker 
SecretsMatch(ssl_encryption_level_t level) const6634*8fb009dcSAndroid Build Coastguard Worker   bool SecretsMatch(ssl_encryption_level_t level) const {
6635*8fb009dcSAndroid Build Coastguard Worker     // We only need to check |HasReadSecret| and |HasWriteSecret| on |client_|.
6636*8fb009dcSAndroid Build Coastguard Worker     // |PeerSecretsMatch| checks that |server_| is analogously configured.
6637*8fb009dcSAndroid Build Coastguard Worker     return client_.PeerSecretsMatch(level) &&
6638*8fb009dcSAndroid Build Coastguard Worker            client_.HasWriteSecret(level) &&
6639*8fb009dcSAndroid Build Coastguard Worker            (level == ssl_encryption_early_data || client_.HasReadSecret(level));
6640*8fb009dcSAndroid Build Coastguard Worker   }
6641*8fb009dcSAndroid Build Coastguard Worker 
6642*8fb009dcSAndroid Build Coastguard Worker  private:
6643*8fb009dcSAndroid Build Coastguard Worker   MockQUICTransport client_;
6644*8fb009dcSAndroid Build Coastguard Worker   MockQUICTransport server_;
6645*8fb009dcSAndroid Build Coastguard Worker };
6646*8fb009dcSAndroid Build Coastguard Worker 
6647*8fb009dcSAndroid Build Coastguard Worker class QUICMethodTest : public testing::Test {
6648*8fb009dcSAndroid Build Coastguard Worker  protected:
SetUp()6649*8fb009dcSAndroid Build Coastguard Worker   void SetUp() override {
6650*8fb009dcSAndroid Build Coastguard Worker     client_ctx_.reset(SSL_CTX_new(TLS_method()));
6651*8fb009dcSAndroid Build Coastguard Worker     server_ctx_ = CreateContextWithTestCertificate(TLS_method());
6652*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(client_ctx_);
6653*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx_);
6654*8fb009dcSAndroid Build Coastguard Worker 
6655*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_min_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6656*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_max_proto_version(server_ctx_.get(), TLS1_3_VERSION);
6657*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_min_proto_version(client_ctx_.get(), TLS1_3_VERSION);
6658*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_max_proto_version(client_ctx_.get(), TLS1_3_VERSION);
6659*8fb009dcSAndroid Build Coastguard Worker 
6660*8fb009dcSAndroid Build Coastguard Worker     static const uint8_t kALPNProtos[] = {0x03, 'f', 'o', 'o'};
6661*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_CTX_set_alpn_protos(client_ctx_.get(), kALPNProtos,
6662*8fb009dcSAndroid Build Coastguard Worker                                       sizeof(kALPNProtos)),
6663*8fb009dcSAndroid Build Coastguard Worker               0);
6664*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_alpn_select_cb(
6665*8fb009dcSAndroid Build Coastguard Worker         server_ctx_.get(),
6666*8fb009dcSAndroid Build Coastguard Worker         [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
6667*8fb009dcSAndroid Build Coastguard Worker            unsigned in_len, void *arg) -> int {
6668*8fb009dcSAndroid Build Coastguard Worker           return SSL_select_next_proto(
6669*8fb009dcSAndroid Build Coastguard Worker                      const_cast<uint8_t **>(out), out_len, in, in_len,
6670*8fb009dcSAndroid Build Coastguard Worker                      kALPNProtos, sizeof(kALPNProtos)) == OPENSSL_NPN_NEGOTIATED
6671*8fb009dcSAndroid Build Coastguard Worker                      ? SSL_TLSEXT_ERR_OK
6672*8fb009dcSAndroid Build Coastguard Worker                      : SSL_TLSEXT_ERR_NOACK;
6673*8fb009dcSAndroid Build Coastguard Worker         },
6674*8fb009dcSAndroid Build Coastguard Worker         nullptr);
6675*8fb009dcSAndroid Build Coastguard Worker   }
6676*8fb009dcSAndroid Build Coastguard Worker 
TransportFromSSL(const SSL * ssl)6677*8fb009dcSAndroid Build Coastguard Worker   static MockQUICTransport *TransportFromSSL(const SSL *ssl) {
6678*8fb009dcSAndroid Build Coastguard Worker     return ex_data_.Get(ssl);
6679*8fb009dcSAndroid Build Coastguard Worker   }
6680*8fb009dcSAndroid Build Coastguard Worker 
ProvideHandshakeData(SSL * ssl,size_t num=std::numeric_limits<size_t>::max ())6681*8fb009dcSAndroid Build Coastguard Worker   static bool ProvideHandshakeData(
6682*8fb009dcSAndroid Build Coastguard Worker       SSL *ssl, size_t num = std::numeric_limits<size_t>::max()) {
6683*8fb009dcSAndroid Build Coastguard Worker     MockQUICTransport *transport = TransportFromSSL(ssl);
6684*8fb009dcSAndroid Build Coastguard Worker     ssl_encryption_level_t level = SSL_quic_read_level(ssl);
6685*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> data;
6686*8fb009dcSAndroid Build Coastguard Worker     return transport->ReadHandshakeData(&data, level, num) &&
6687*8fb009dcSAndroid Build Coastguard Worker            SSL_provide_quic_data(ssl, level, data.data(), data.size());
6688*8fb009dcSAndroid Build Coastguard Worker   }
6689*8fb009dcSAndroid Build Coastguard Worker 
AllowOutOfOrderWrites()6690*8fb009dcSAndroid Build Coastguard Worker   void AllowOutOfOrderWrites() {
6691*8fb009dcSAndroid Build Coastguard Worker     allow_out_of_order_writes_ = true;
6692*8fb009dcSAndroid Build Coastguard Worker   }
6693*8fb009dcSAndroid Build Coastguard Worker 
CreateClientAndServer()6694*8fb009dcSAndroid Build Coastguard Worker   bool CreateClientAndServer() {
6695*8fb009dcSAndroid Build Coastguard Worker     client_.reset(SSL_new(client_ctx_.get()));
6696*8fb009dcSAndroid Build Coastguard Worker     server_.reset(SSL_new(server_ctx_.get()));
6697*8fb009dcSAndroid Build Coastguard Worker     if (!client_ || !server_) {
6698*8fb009dcSAndroid Build Coastguard Worker       return false;
6699*8fb009dcSAndroid Build Coastguard Worker     }
6700*8fb009dcSAndroid Build Coastguard Worker 
6701*8fb009dcSAndroid Build Coastguard Worker     SSL_set_connect_state(client_.get());
6702*8fb009dcSAndroid Build Coastguard Worker     SSL_set_accept_state(server_.get());
6703*8fb009dcSAndroid Build Coastguard Worker 
6704*8fb009dcSAndroid Build Coastguard Worker     transport_ = std::make_unique<MockQUICTransportPair>();
6705*8fb009dcSAndroid Build Coastguard Worker     if (!ex_data_.Set(client_.get(), transport_->client()) ||
6706*8fb009dcSAndroid Build Coastguard Worker         !ex_data_.Set(server_.get(), transport_->server())) {
6707*8fb009dcSAndroid Build Coastguard Worker       return false;
6708*8fb009dcSAndroid Build Coastguard Worker     }
6709*8fb009dcSAndroid Build Coastguard Worker     if (allow_out_of_order_writes_) {
6710*8fb009dcSAndroid Build Coastguard Worker       transport_->client()->AllowOutOfOrderWrites();
6711*8fb009dcSAndroid Build Coastguard Worker       transport_->server()->AllowOutOfOrderWrites();
6712*8fb009dcSAndroid Build Coastguard Worker     }
6713*8fb009dcSAndroid Build Coastguard Worker     static const uint8_t client_transport_params[] = {0};
6714*8fb009dcSAndroid Build Coastguard Worker     if (!SSL_set_quic_transport_params(client_.get(), client_transport_params,
6715*8fb009dcSAndroid Build Coastguard Worker                                        sizeof(client_transport_params)) ||
6716*8fb009dcSAndroid Build Coastguard Worker         !SSL_set_quic_transport_params(server_.get(),
6717*8fb009dcSAndroid Build Coastguard Worker                                        server_transport_params_.data(),
6718*8fb009dcSAndroid Build Coastguard Worker                                        server_transport_params_.size()) ||
6719*8fb009dcSAndroid Build Coastguard Worker         !SSL_set_quic_early_data_context(
6720*8fb009dcSAndroid Build Coastguard Worker             server_.get(), server_quic_early_data_context_.data(),
6721*8fb009dcSAndroid Build Coastguard Worker             server_quic_early_data_context_.size())) {
6722*8fb009dcSAndroid Build Coastguard Worker       return false;
6723*8fb009dcSAndroid Build Coastguard Worker     }
6724*8fb009dcSAndroid Build Coastguard Worker     return true;
6725*8fb009dcSAndroid Build Coastguard Worker   }
6726*8fb009dcSAndroid Build Coastguard Worker 
6727*8fb009dcSAndroid Build Coastguard Worker   enum class ExpectedError {
6728*8fb009dcSAndroid Build Coastguard Worker     kNoError,
6729*8fb009dcSAndroid Build Coastguard Worker     kClientError,
6730*8fb009dcSAndroid Build Coastguard Worker     kServerError,
6731*8fb009dcSAndroid Build Coastguard Worker   };
6732*8fb009dcSAndroid Build Coastguard Worker 
6733*8fb009dcSAndroid Build Coastguard Worker   // CompleteHandshakesForQUIC runs |SSL_do_handshake| on |client_| and
6734*8fb009dcSAndroid Build Coastguard Worker   // |server_| until each completes once. It returns true on success and false
6735*8fb009dcSAndroid Build Coastguard Worker   // on failure.
CompleteHandshakesForQUIC()6736*8fb009dcSAndroid Build Coastguard Worker   bool CompleteHandshakesForQUIC() {
6737*8fb009dcSAndroid Build Coastguard Worker     return RunQUICHandshakesAndExpectError(ExpectedError::kNoError);
6738*8fb009dcSAndroid Build Coastguard Worker   }
6739*8fb009dcSAndroid Build Coastguard Worker 
6740*8fb009dcSAndroid Build Coastguard Worker   // Runs |SSL_do_handshake| on |client_| and |server_| until each completes
6741*8fb009dcSAndroid Build Coastguard Worker   // once. If |expect_client_error| is true, it will return true only if the
6742*8fb009dcSAndroid Build Coastguard Worker   // client handshake failed. Otherwise, it returns true if both handshakes
6743*8fb009dcSAndroid Build Coastguard Worker   // succeed and false otherwise.
RunQUICHandshakesAndExpectError(ExpectedError expected_error)6744*8fb009dcSAndroid Build Coastguard Worker   bool RunQUICHandshakesAndExpectError(ExpectedError expected_error) {
6745*8fb009dcSAndroid Build Coastguard Worker     bool client_done = false, server_done = false;
6746*8fb009dcSAndroid Build Coastguard Worker     while (!client_done || !server_done) {
6747*8fb009dcSAndroid Build Coastguard Worker       if (!client_done) {
6748*8fb009dcSAndroid Build Coastguard Worker         if (!ProvideHandshakeData(client_.get())) {
6749*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "ProvideHandshakeData(client_) failed";
6750*8fb009dcSAndroid Build Coastguard Worker           return false;
6751*8fb009dcSAndroid Build Coastguard Worker         }
6752*8fb009dcSAndroid Build Coastguard Worker         int client_ret = SSL_do_handshake(client_.get());
6753*8fb009dcSAndroid Build Coastguard Worker         int client_err = SSL_get_error(client_.get(), client_ret);
6754*8fb009dcSAndroid Build Coastguard Worker         if (client_ret == 1) {
6755*8fb009dcSAndroid Build Coastguard Worker           client_done = true;
6756*8fb009dcSAndroid Build Coastguard Worker         } else if (client_ret != -1 || client_err != SSL_ERROR_WANT_READ) {
6757*8fb009dcSAndroid Build Coastguard Worker           if (expected_error == ExpectedError::kClientError) {
6758*8fb009dcSAndroid Build Coastguard Worker             return true;
6759*8fb009dcSAndroid Build Coastguard Worker           }
6760*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "Unexpected client output: " << client_ret << " "
6761*8fb009dcSAndroid Build Coastguard Worker                         << client_err;
6762*8fb009dcSAndroid Build Coastguard Worker           return false;
6763*8fb009dcSAndroid Build Coastguard Worker         }
6764*8fb009dcSAndroid Build Coastguard Worker       }
6765*8fb009dcSAndroid Build Coastguard Worker 
6766*8fb009dcSAndroid Build Coastguard Worker       if (!server_done) {
6767*8fb009dcSAndroid Build Coastguard Worker         if (!ProvideHandshakeData(server_.get())) {
6768*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "ProvideHandshakeData(server_) failed";
6769*8fb009dcSAndroid Build Coastguard Worker           return false;
6770*8fb009dcSAndroid Build Coastguard Worker         }
6771*8fb009dcSAndroid Build Coastguard Worker         int server_ret = SSL_do_handshake(server_.get());
6772*8fb009dcSAndroid Build Coastguard Worker         int server_err = SSL_get_error(server_.get(), server_ret);
6773*8fb009dcSAndroid Build Coastguard Worker         if (server_ret == 1) {
6774*8fb009dcSAndroid Build Coastguard Worker           server_done = true;
6775*8fb009dcSAndroid Build Coastguard Worker         } else if (server_ret != -1 || server_err != SSL_ERROR_WANT_READ) {
6776*8fb009dcSAndroid Build Coastguard Worker           if (expected_error == ExpectedError::kServerError) {
6777*8fb009dcSAndroid Build Coastguard Worker             return true;
6778*8fb009dcSAndroid Build Coastguard Worker           }
6779*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "Unexpected server output: " << server_ret << " "
6780*8fb009dcSAndroid Build Coastguard Worker                         << server_err;
6781*8fb009dcSAndroid Build Coastguard Worker           return false;
6782*8fb009dcSAndroid Build Coastguard Worker         }
6783*8fb009dcSAndroid Build Coastguard Worker       }
6784*8fb009dcSAndroid Build Coastguard Worker     }
6785*8fb009dcSAndroid Build Coastguard Worker     return expected_error == ExpectedError::kNoError;
6786*8fb009dcSAndroid Build Coastguard Worker   }
6787*8fb009dcSAndroid Build Coastguard Worker 
CreateClientSessionForQUIC()6788*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> CreateClientSessionForQUIC() {
6789*8fb009dcSAndroid Build Coastguard Worker     g_last_session = nullptr;
6790*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6791*8fb009dcSAndroid Build Coastguard Worker     if (!CreateClientAndServer() ||
6792*8fb009dcSAndroid Build Coastguard Worker         !CompleteHandshakesForQUIC()) {
6793*8fb009dcSAndroid Build Coastguard Worker       return nullptr;
6794*8fb009dcSAndroid Build Coastguard Worker     }
6795*8fb009dcSAndroid Build Coastguard Worker 
6796*8fb009dcSAndroid Build Coastguard Worker     // The server sent NewSessionTicket messages in the handshake.
6797*8fb009dcSAndroid Build Coastguard Worker     if (!ProvideHandshakeData(client_.get()) ||
6798*8fb009dcSAndroid Build Coastguard Worker         !SSL_process_quic_post_handshake(client_.get())) {
6799*8fb009dcSAndroid Build Coastguard Worker       return nullptr;
6800*8fb009dcSAndroid Build Coastguard Worker     }
6801*8fb009dcSAndroid Build Coastguard Worker 
6802*8fb009dcSAndroid Build Coastguard Worker     return std::move(g_last_session);
6803*8fb009dcSAndroid Build Coastguard Worker   }
6804*8fb009dcSAndroid Build Coastguard Worker 
ExpectHandshakeSuccess()6805*8fb009dcSAndroid Build Coastguard Worker   void ExpectHandshakeSuccess() {
6806*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
6807*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(client_.get()));
6808*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(client_.get()));
6809*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(ssl_encryption_application, SSL_quic_read_level(server_.get()));
6810*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(ssl_encryption_application, SSL_quic_write_level(server_.get()));
6811*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(transport_->client()->has_alert());
6812*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(transport_->server()->has_alert());
6813*8fb009dcSAndroid Build Coastguard Worker 
6814*8fb009dcSAndroid Build Coastguard Worker     // SSL_do_handshake is now idempotent.
6815*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
6816*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
6817*8fb009dcSAndroid Build Coastguard Worker   }
6818*8fb009dcSAndroid Build Coastguard Worker 
6819*8fb009dcSAndroid Build Coastguard Worker   // Returns a default SSL_QUIC_METHOD. Individual methods may be overwritten by
6820*8fb009dcSAndroid Build Coastguard Worker   // the test.
DefaultQUICMethod()6821*8fb009dcSAndroid Build Coastguard Worker   SSL_QUIC_METHOD DefaultQUICMethod() {
6822*8fb009dcSAndroid Build Coastguard Worker     return SSL_QUIC_METHOD{
6823*8fb009dcSAndroid Build Coastguard Worker         SetReadSecretCallback, SetWriteSecretCallback, AddHandshakeDataCallback,
6824*8fb009dcSAndroid Build Coastguard Worker         FlushFlightCallback,   SendAlertCallback,
6825*8fb009dcSAndroid Build Coastguard Worker     };
6826*8fb009dcSAndroid Build Coastguard Worker   }
6827*8fb009dcSAndroid Build Coastguard Worker 
SetReadSecretCallback(SSL * ssl,ssl_encryption_level_t level,const SSL_CIPHER * cipher,const uint8_t * secret,size_t secret_len)6828*8fb009dcSAndroid Build Coastguard Worker   static int SetReadSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6829*8fb009dcSAndroid Build Coastguard Worker                                    const SSL_CIPHER *cipher,
6830*8fb009dcSAndroid Build Coastguard Worker                                    const uint8_t *secret, size_t secret_len) {
6831*8fb009dcSAndroid Build Coastguard Worker     return TransportFromSSL(ssl)->SetReadSecret(
6832*8fb009dcSAndroid Build Coastguard Worker         level, cipher, MakeConstSpan(secret, secret_len));
6833*8fb009dcSAndroid Build Coastguard Worker   }
6834*8fb009dcSAndroid Build Coastguard Worker 
SetWriteSecretCallback(SSL * ssl,ssl_encryption_level_t level,const SSL_CIPHER * cipher,const uint8_t * secret,size_t secret_len)6835*8fb009dcSAndroid Build Coastguard Worker   static int SetWriteSecretCallback(SSL *ssl, ssl_encryption_level_t level,
6836*8fb009dcSAndroid Build Coastguard Worker                                     const SSL_CIPHER *cipher,
6837*8fb009dcSAndroid Build Coastguard Worker                                     const uint8_t *secret, size_t secret_len) {
6838*8fb009dcSAndroid Build Coastguard Worker     return TransportFromSSL(ssl)->SetWriteSecret(
6839*8fb009dcSAndroid Build Coastguard Worker         level, cipher, MakeConstSpan(secret, secret_len));
6840*8fb009dcSAndroid Build Coastguard Worker   }
6841*8fb009dcSAndroid Build Coastguard Worker 
AddHandshakeDataCallback(SSL * ssl,enum ssl_encryption_level_t level,const uint8_t * data,size_t len)6842*8fb009dcSAndroid Build Coastguard Worker   static int AddHandshakeDataCallback(SSL *ssl,
6843*8fb009dcSAndroid Build Coastguard Worker                                       enum ssl_encryption_level_t level,
6844*8fb009dcSAndroid Build Coastguard Worker                                       const uint8_t *data, size_t len) {
6845*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(level, SSL_quic_write_level(ssl));
6846*8fb009dcSAndroid Build Coastguard Worker     return TransportFromSSL(ssl)->WriteHandshakeData(level,
6847*8fb009dcSAndroid Build Coastguard Worker                                                      MakeConstSpan(data, len));
6848*8fb009dcSAndroid Build Coastguard Worker   }
6849*8fb009dcSAndroid Build Coastguard Worker 
FlushFlightCallback(SSL * ssl)6850*8fb009dcSAndroid Build Coastguard Worker   static int FlushFlightCallback(SSL *ssl) { return 1; }
6851*8fb009dcSAndroid Build Coastguard Worker 
SendAlertCallback(SSL * ssl,ssl_encryption_level_t level,uint8_t alert)6852*8fb009dcSAndroid Build Coastguard Worker   static int SendAlertCallback(SSL *ssl, ssl_encryption_level_t level,
6853*8fb009dcSAndroid Build Coastguard Worker                                uint8_t alert) {
6854*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(level, SSL_quic_write_level(ssl));
6855*8fb009dcSAndroid Build Coastguard Worker     return TransportFromSSL(ssl)->SendAlert(level, alert);
6856*8fb009dcSAndroid Build Coastguard Worker   }
6857*8fb009dcSAndroid Build Coastguard Worker 
6858*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx_;
6859*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx_;
6860*8fb009dcSAndroid Build Coastguard Worker 
6861*8fb009dcSAndroid Build Coastguard Worker   static UnownedSSLExData<MockQUICTransport> ex_data_;
6862*8fb009dcSAndroid Build Coastguard Worker   std::unique_ptr<MockQUICTransportPair> transport_;
6863*8fb009dcSAndroid Build Coastguard Worker 
6864*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client_;
6865*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> server_;
6866*8fb009dcSAndroid Build Coastguard Worker 
6867*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> server_transport_params_ = {1};
6868*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> server_quic_early_data_context_ = {2};
6869*8fb009dcSAndroid Build Coastguard Worker 
6870*8fb009dcSAndroid Build Coastguard Worker   bool allow_out_of_order_writes_ = false;
6871*8fb009dcSAndroid Build Coastguard Worker };
6872*8fb009dcSAndroid Build Coastguard Worker 
6873*8fb009dcSAndroid Build Coastguard Worker UnownedSSLExData<MockQUICTransport> QUICMethodTest::ex_data_;
6874*8fb009dcSAndroid Build Coastguard Worker 
6875*8fb009dcSAndroid Build Coastguard Worker // Test a full handshake and resumption work.
TEST_F(QUICMethodTest,Basic)6876*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, Basic) {
6877*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6878*8fb009dcSAndroid Build Coastguard Worker 
6879*8fb009dcSAndroid Build Coastguard Worker   g_last_session = nullptr;
6880*8fb009dcSAndroid Build Coastguard Worker 
6881*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6882*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
6883*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6884*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6885*8fb009dcSAndroid Build Coastguard Worker 
6886*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
6887*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
6888*8fb009dcSAndroid Build Coastguard Worker 
6889*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
6890*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client_.get()));
6891*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server_.get()));
6892*8fb009dcSAndroid Build Coastguard Worker 
6893*8fb009dcSAndroid Build Coastguard Worker   // The server sent NewSessionTicket messages in the handshake.
6894*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(g_last_session);
6895*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(client_.get()));
6896*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
6897*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(g_last_session);
6898*8fb009dcSAndroid Build Coastguard Worker 
6899*8fb009dcSAndroid Build Coastguard Worker   // Create a second connection to verify resumption works.
6900*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
6901*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
6902*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client_.get(), session.get());
6903*8fb009dcSAndroid Build Coastguard Worker 
6904*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
6905*8fb009dcSAndroid Build Coastguard Worker 
6906*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
6907*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client_.get()));
6908*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server_.get()));
6909*8fb009dcSAndroid Build Coastguard Worker }
6910*8fb009dcSAndroid Build Coastguard Worker 
6911*8fb009dcSAndroid Build Coastguard Worker // Test that HelloRetryRequest in QUIC works.
TEST_F(QUICMethodTest,HelloRetryRequest)6912*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, HelloRetryRequest) {
6913*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6914*8fb009dcSAndroid Build Coastguard Worker 
6915*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6916*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6917*8fb009dcSAndroid Build Coastguard Worker 
6918*8fb009dcSAndroid Build Coastguard Worker   // BoringSSL predicts the most preferred ECDH group, so using different
6919*8fb009dcSAndroid Build Coastguard Worker   // preferences will trigger HelloRetryRequest.
6920*8fb009dcSAndroid Build Coastguard Worker   static const int kClientPrefs[] = {NID_X25519, NID_X9_62_prime256v1};
6921*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_groups(client_ctx_.get(), kClientPrefs,
6922*8fb009dcSAndroid Build Coastguard Worker                                   OPENSSL_ARRAY_SIZE(kClientPrefs)));
6923*8fb009dcSAndroid Build Coastguard Worker   static const int kServerPrefs[] = {NID_X9_62_prime256v1, NID_X25519};
6924*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_groups(server_ctx_.get(), kServerPrefs,
6925*8fb009dcSAndroid Build Coastguard Worker                                   OPENSSL_ARRAY_SIZE(kServerPrefs)));
6926*8fb009dcSAndroid Build Coastguard Worker 
6927*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
6928*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
6929*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
6930*8fb009dcSAndroid Build Coastguard Worker }
6931*8fb009dcSAndroid Build Coastguard Worker 
6932*8fb009dcSAndroid Build Coastguard Worker // Test that the client does not send a legacy_session_id in the ClientHello.
TEST_F(QUICMethodTest,NoLegacySessionId)6933*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, NoLegacySessionId) {
6934*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6935*8fb009dcSAndroid Build Coastguard Worker 
6936*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6937*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6938*8fb009dcSAndroid Build Coastguard Worker   // Check that the session ID length is 0 in an early callback.
6939*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_select_certificate_cb(
6940*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(),
6941*8fb009dcSAndroid Build Coastguard Worker       [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
6942*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(client_hello->session_id_len, 0u);
6943*8fb009dcSAndroid Build Coastguard Worker         return ssl_select_cert_success;
6944*8fb009dcSAndroid Build Coastguard Worker       });
6945*8fb009dcSAndroid Build Coastguard Worker 
6946*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
6947*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
6948*8fb009dcSAndroid Build Coastguard Worker 
6949*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
6950*8fb009dcSAndroid Build Coastguard Worker }
6951*8fb009dcSAndroid Build Coastguard Worker 
6952*8fb009dcSAndroid Build Coastguard Worker // Test that, even in a 1-RTT handshake, the server installs keys at the right
6953*8fb009dcSAndroid Build Coastguard Worker // time. Half-RTT keys are available early, but 1-RTT read keys are deferred.
TEST_F(QUICMethodTest,HalfRTTKeys)6954*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, HalfRTTKeys) {
6955*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6956*8fb009dcSAndroid Build Coastguard Worker 
6957*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6958*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6959*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
6960*8fb009dcSAndroid Build Coastguard Worker 
6961*8fb009dcSAndroid Build Coastguard Worker   // The client sends ClientHello.
6962*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
6963*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client_.get(), -1));
6964*8fb009dcSAndroid Build Coastguard Worker 
6965*8fb009dcSAndroid Build Coastguard Worker   // The server reads ClientHello and sends ServerHello..Finished.
6966*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(server_.get()));
6967*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
6968*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
6969*8fb009dcSAndroid Build Coastguard Worker 
6970*8fb009dcSAndroid Build Coastguard Worker   // At this point, the server has half-RTT write keys, but it cannot access
6971*8fb009dcSAndroid Build Coastguard Worker   // 1-RTT read keys until client Finished.
6972*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
6973*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
6974*8fb009dcSAndroid Build Coastguard Worker 
6975*8fb009dcSAndroid Build Coastguard Worker   // Finish up the client and server handshakes.
6976*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
6977*8fb009dcSAndroid Build Coastguard Worker 
6978*8fb009dcSAndroid Build Coastguard Worker   // Both sides can now exchange 1-RTT data.
6979*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
6980*8fb009dcSAndroid Build Coastguard Worker }
6981*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,ZeroRTTAccept)6982*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ZeroRTTAccept) {
6983*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
6984*8fb009dcSAndroid Build Coastguard Worker 
6985*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
6986*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
6987*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
6988*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
6989*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
6990*8fb009dcSAndroid Build Coastguard Worker 
6991*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
6992*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
6993*8fb009dcSAndroid Build Coastguard Worker 
6994*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
6995*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client_.get(), session.get());
6996*8fb009dcSAndroid Build Coastguard Worker 
6997*8fb009dcSAndroid Build Coastguard Worker   // The client handshake should return immediately into the early data state.
6998*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
6999*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(client_.get()));
7000*8fb009dcSAndroid Build Coastguard Worker   // The transport should have keys for sending 0-RTT data.
7001*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
7002*8fb009dcSAndroid Build Coastguard Worker 
7003*8fb009dcSAndroid Build Coastguard Worker   // The server will consume the ClientHello and also enter the early data
7004*8fb009dcSAndroid Build Coastguard Worker   // state.
7005*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7006*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
7007*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(server_.get()));
7008*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
7009*8fb009dcSAndroid Build Coastguard Worker   // At this point, the server has half-RTT write keys, but it cannot access
7010*8fb009dcSAndroid Build Coastguard Worker   // 1-RTT read keys until client Finished.
7011*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
7012*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
7013*8fb009dcSAndroid Build Coastguard Worker 
7014*8fb009dcSAndroid Build Coastguard Worker   // Finish up the client and server handshakes.
7015*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7016*8fb009dcSAndroid Build Coastguard Worker 
7017*8fb009dcSAndroid Build Coastguard Worker   // Both sides can now exchange 1-RTT data.
7018*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7019*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client_.get()));
7020*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server_.get()));
7021*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_in_early_data(client_.get()));
7022*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_in_early_data(server_.get()));
7023*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
7024*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
7025*8fb009dcSAndroid Build Coastguard Worker 
7026*8fb009dcSAndroid Build Coastguard Worker   // Finish handling post-handshake messages after the first 0-RTT resumption.
7027*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(ProvideHandshakeData(client_.get()));
7028*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_process_quic_post_handshake(client_.get()));
7029*8fb009dcSAndroid Build Coastguard Worker 
7030*8fb009dcSAndroid Build Coastguard Worker   // Perform a second 0-RTT resumption attempt, and confirm that 0-RTT is
7031*8fb009dcSAndroid Build Coastguard Worker   // accepted again.
7032*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7033*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client_.get(), g_last_session.get());
7034*8fb009dcSAndroid Build Coastguard Worker 
7035*8fb009dcSAndroid Build Coastguard Worker   // The client handshake should return immediately into the early data state.
7036*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
7037*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(client_.get()));
7038*8fb009dcSAndroid Build Coastguard Worker   // The transport should have keys for sending 0-RTT data.
7039*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
7040*8fb009dcSAndroid Build Coastguard Worker 
7041*8fb009dcSAndroid Build Coastguard Worker   // The server will consume the ClientHello and also enter the early data
7042*8fb009dcSAndroid Build Coastguard Worker   // state.
7043*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7044*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(server_.get()), 1);
7045*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(server_.get()));
7046*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_early_data));
7047*8fb009dcSAndroid Build Coastguard Worker   // At this point, the server has half-RTT write keys, but it cannot access
7048*8fb009dcSAndroid Build Coastguard Worker   // 1-RTT read keys until client Finished.
7049*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->server()->HasWriteSecret(ssl_encryption_application));
7050*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_application));
7051*8fb009dcSAndroid Build Coastguard Worker 
7052*8fb009dcSAndroid Build Coastguard Worker   // Finish up the client and server handshakes.
7053*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7054*8fb009dcSAndroid Build Coastguard Worker 
7055*8fb009dcSAndroid Build Coastguard Worker   // Both sides can now exchange 1-RTT data.
7056*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7057*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client_.get()));
7058*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server_.get()));
7059*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_in_early_data(client_.get()));
7060*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_in_early_data(server_.get()));
7061*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_early_data_accepted(client_.get()));
7062*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_early_data_accepted(server_.get()));
7063*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_early_data_reason(client_.get()), ssl_early_data_accepted);
7064*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_early_data_reason(server_.get()), ssl_early_data_accepted);
7065*8fb009dcSAndroid Build Coastguard Worker }
7066*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,ZeroRTTRejectMismatchedParameters)7067*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ZeroRTTRejectMismatchedParameters) {
7068*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7069*8fb009dcSAndroid Build Coastguard Worker 
7070*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7071*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
7072*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
7073*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7074*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7075*8fb009dcSAndroid Build Coastguard Worker 
7076*8fb009dcSAndroid Build Coastguard Worker 
7077*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
7078*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
7079*8fb009dcSAndroid Build Coastguard Worker 
7080*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7081*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t new_context[] = {4};
7082*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_early_data_context(server_.get(), new_context,
7083*8fb009dcSAndroid Build Coastguard Worker                                               sizeof(new_context)));
7084*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client_.get(), session.get());
7085*8fb009dcSAndroid Build Coastguard Worker 
7086*8fb009dcSAndroid Build Coastguard Worker   // The client handshake should return immediately into the early data
7087*8fb009dcSAndroid Build Coastguard Worker   // state.
7088*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
7089*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(client_.get()));
7090*8fb009dcSAndroid Build Coastguard Worker   // The transport should have keys for sending 0-RTT data.
7091*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
7092*8fb009dcSAndroid Build Coastguard Worker 
7093*8fb009dcSAndroid Build Coastguard Worker   // The server will consume the ClientHello, but it will not accept 0-RTT.
7094*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7095*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
7096*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
7097*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_in_early_data(server_.get()));
7098*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->server()->HasReadSecret(ssl_encryption_early_data));
7099*8fb009dcSAndroid Build Coastguard Worker 
7100*8fb009dcSAndroid Build Coastguard Worker   // The client consumes the server response and signals 0-RTT rejection.
7101*8fb009dcSAndroid Build Coastguard Worker   for (;;) {
7102*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7103*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
7104*8fb009dcSAndroid Build Coastguard Worker     int err = SSL_get_error(client_.get(), -1);
7105*8fb009dcSAndroid Build Coastguard Worker     if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
7106*8fb009dcSAndroid Build Coastguard Worker       break;
7107*8fb009dcSAndroid Build Coastguard Worker     }
7108*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_ERROR_WANT_READ, err);
7109*8fb009dcSAndroid Build Coastguard Worker   }
7110*8fb009dcSAndroid Build Coastguard Worker 
7111*8fb009dcSAndroid Build Coastguard Worker   // As in TLS over TCP, 0-RTT rejection is sticky.
7112*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
7113*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
7114*8fb009dcSAndroid Build Coastguard Worker 
7115*8fb009dcSAndroid Build Coastguard Worker   // Finish up the client and server handshakes.
7116*8fb009dcSAndroid Build Coastguard Worker   SSL_reset_early_data_reject(client_.get());
7117*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7118*8fb009dcSAndroid Build Coastguard Worker 
7119*8fb009dcSAndroid Build Coastguard Worker   // Both sides can now exchange 1-RTT data.
7120*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7121*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client_.get()));
7122*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server_.get()));
7123*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_in_early_data(client_.get()));
7124*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_in_early_data(server_.get()));
7125*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
7126*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
7127*8fb009dcSAndroid Build Coastguard Worker }
7128*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,NoZeroRTTTicketWithoutEarlyDataContext)7129*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, NoZeroRTTTicketWithoutEarlyDataContext) {
7130*8fb009dcSAndroid Build Coastguard Worker   server_quic_early_data_context_ = {};
7131*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7132*8fb009dcSAndroid Build Coastguard Worker 
7133*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7134*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
7135*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
7136*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7137*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7138*8fb009dcSAndroid Build Coastguard Worker 
7139*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
7140*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
7141*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_SESSION_early_data_capable(session.get()));
7142*8fb009dcSAndroid Build Coastguard Worker }
7143*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,ZeroRTTReject)7144*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ZeroRTTReject) {
7145*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7146*8fb009dcSAndroid Build Coastguard Worker 
7147*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7148*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
7149*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
7150*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7151*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7152*8fb009dcSAndroid Build Coastguard Worker 
7153*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
7154*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
7155*8fb009dcSAndroid Build Coastguard Worker 
7156*8fb009dcSAndroid Build Coastguard Worker   for (bool reject_hrr : {false, true}) {
7157*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(reject_hrr);
7158*8fb009dcSAndroid Build Coastguard Worker 
7159*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateClientAndServer());
7160*8fb009dcSAndroid Build Coastguard Worker     if (reject_hrr) {
7161*8fb009dcSAndroid Build Coastguard Worker       // Configure the server to prefer P-256, which will reject 0-RTT via
7162*8fb009dcSAndroid Build Coastguard Worker       // HelloRetryRequest.
7163*8fb009dcSAndroid Build Coastguard Worker       int p256 = NID_X9_62_prime256v1;
7164*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(SSL_set1_groups(server_.get(), &p256, 1));
7165*8fb009dcSAndroid Build Coastguard Worker     } else {
7166*8fb009dcSAndroid Build Coastguard Worker       // Disable 0-RTT on the server, so it will reject it.
7167*8fb009dcSAndroid Build Coastguard Worker       SSL_set_early_data_enabled(server_.get(), 0);
7168*8fb009dcSAndroid Build Coastguard Worker     }
7169*8fb009dcSAndroid Build Coastguard Worker     SSL_set_session(client_.get(), session.get());
7170*8fb009dcSAndroid Build Coastguard Worker 
7171*8fb009dcSAndroid Build Coastguard Worker     // The client handshake should return immediately into the early data state.
7172*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
7173*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_in_early_data(client_.get()));
7174*8fb009dcSAndroid Build Coastguard Worker     // The transport should have keys for sending 0-RTT data.
7175*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(
7176*8fb009dcSAndroid Build Coastguard Worker         transport_->client()->HasWriteSecret(ssl_encryption_early_data));
7177*8fb009dcSAndroid Build Coastguard Worker 
7178*8fb009dcSAndroid Build Coastguard Worker     // The server will consume the ClientHello, but it will not accept 0-RTT.
7179*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7180*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
7181*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server_.get(), -1));
7182*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_in_early_data(server_.get()));
7183*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(
7184*8fb009dcSAndroid Build Coastguard Worker         transport_->server()->HasReadSecret(ssl_encryption_early_data));
7185*8fb009dcSAndroid Build Coastguard Worker 
7186*8fb009dcSAndroid Build Coastguard Worker     // The client consumes the server response and signals 0-RTT rejection.
7187*8fb009dcSAndroid Build Coastguard Worker     for (;;) {
7188*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7189*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
7190*8fb009dcSAndroid Build Coastguard Worker       int err = SSL_get_error(client_.get(), -1);
7191*8fb009dcSAndroid Build Coastguard Worker       if (err == SSL_ERROR_EARLY_DATA_REJECTED) {
7192*8fb009dcSAndroid Build Coastguard Worker         break;
7193*8fb009dcSAndroid Build Coastguard Worker       }
7194*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_ERROR_WANT_READ, err);
7195*8fb009dcSAndroid Build Coastguard Worker     }
7196*8fb009dcSAndroid Build Coastguard Worker 
7197*8fb009dcSAndroid Build Coastguard Worker     // As in TLS over TCP, 0-RTT rejection is sticky.
7198*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(-1, SSL_do_handshake(client_.get()));
7199*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_ERROR_EARLY_DATA_REJECTED, SSL_get_error(client_.get(), -1));
7200*8fb009dcSAndroid Build Coastguard Worker 
7201*8fb009dcSAndroid Build Coastguard Worker     // Finish up the client and server handshakes.
7202*8fb009dcSAndroid Build Coastguard Worker     SSL_reset_early_data_reject(client_.get());
7203*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CompleteHandshakesForQUIC());
7204*8fb009dcSAndroid Build Coastguard Worker 
7205*8fb009dcSAndroid Build Coastguard Worker     // Both sides can now exchange 1-RTT data.
7206*8fb009dcSAndroid Build Coastguard Worker     ExpectHandshakeSuccess();
7207*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_session_reused(client_.get()));
7208*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_session_reused(server_.get()));
7209*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_in_early_data(client_.get()));
7210*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_in_early_data(server_.get()));
7211*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_early_data_accepted(client_.get()));
7212*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_early_data_accepted(server_.get()));
7213*8fb009dcSAndroid Build Coastguard Worker   }
7214*8fb009dcSAndroid Build Coastguard Worker }
7215*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,NoZeroRTTKeysBeforeReverify)7216*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, NoZeroRTTKeysBeforeReverify) {
7217*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7218*8fb009dcSAndroid Build Coastguard Worker 
7219*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7220*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(client_ctx_.get(), 1);
7221*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_reverify_on_resume(client_ctx_.get(), 1);
7222*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(server_ctx_.get(), 1);
7223*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7224*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7225*8fb009dcSAndroid Build Coastguard Worker 
7226*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = CreateClientSessionForQUIC();
7227*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
7228*8fb009dcSAndroid Build Coastguard Worker 
7229*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7230*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client_.get(), session.get());
7231*8fb009dcSAndroid Build Coastguard Worker 
7232*8fb009dcSAndroid Build Coastguard Worker   // Configure the certificate (re)verification to never complete. The client
7233*8fb009dcSAndroid Build Coastguard Worker   // handshake should pause.
7234*8fb009dcSAndroid Build Coastguard Worker   SSL_set_custom_verify(
7235*8fb009dcSAndroid Build Coastguard Worker       client_.get(), SSL_VERIFY_PEER,
7236*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7237*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_retry;
7238*8fb009dcSAndroid Build Coastguard Worker       });
7239*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7240*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(client_.get(), -1),
7241*8fb009dcSAndroid Build Coastguard Worker             SSL_ERROR_WANT_CERTIFICATE_VERIFY);
7242*8fb009dcSAndroid Build Coastguard Worker 
7243*8fb009dcSAndroid Build Coastguard Worker   // The early data keys have not yet been released.
7244*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
7245*8fb009dcSAndroid Build Coastguard Worker 
7246*8fb009dcSAndroid Build Coastguard Worker   // After the verification completes, the handshake progresses to the 0-RTT
7247*8fb009dcSAndroid Build Coastguard Worker   // point and releases keys.
7248*8fb009dcSAndroid Build Coastguard Worker   SSL_set_custom_verify(
7249*8fb009dcSAndroid Build Coastguard Worker       client_.get(), SSL_VERIFY_PEER,
7250*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7251*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_ok;
7252*8fb009dcSAndroid Build Coastguard Worker       });
7253*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), 1);
7254*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(client_.get()));
7255*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_early_data));
7256*8fb009dcSAndroid Build Coastguard Worker }
7257*8fb009dcSAndroid Build Coastguard Worker 
7258*8fb009dcSAndroid Build Coastguard Worker // Test only releasing data to QUIC one byte at a time on request, to maximize
7259*8fb009dcSAndroid Build Coastguard Worker // state machine pauses. Additionally, test that existing asynchronous callbacks
7260*8fb009dcSAndroid Build Coastguard Worker // still work.
TEST_F(QUICMethodTest,Async)7261*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, Async) {
7262*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7263*8fb009dcSAndroid Build Coastguard Worker 
7264*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7265*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7266*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7267*8fb009dcSAndroid Build Coastguard Worker 
7268*8fb009dcSAndroid Build Coastguard Worker   // Install an asynchronous certificate callback.
7269*8fb009dcSAndroid Build Coastguard Worker   bool cert_cb_ok = false;
7270*8fb009dcSAndroid Build Coastguard Worker   SSL_set_cert_cb(server_.get(),
7271*8fb009dcSAndroid Build Coastguard Worker                   [](SSL *, void *arg) -> int {
7272*8fb009dcSAndroid Build Coastguard Worker                     return *static_cast<bool *>(arg) ? 1 : -1;
7273*8fb009dcSAndroid Build Coastguard Worker                   },
7274*8fb009dcSAndroid Build Coastguard Worker                   &cert_cb_ok);
7275*8fb009dcSAndroid Build Coastguard Worker 
7276*8fb009dcSAndroid Build Coastguard Worker   for (;;) {
7277*8fb009dcSAndroid Build Coastguard Worker     int client_ret = SSL_do_handshake(client_.get());
7278*8fb009dcSAndroid Build Coastguard Worker     if (client_ret != 1) {
7279*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(client_ret, -1);
7280*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_get_error(client_.get(), client_ret), SSL_ERROR_WANT_READ);
7281*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ProvideHandshakeData(client_.get(), 1));
7282*8fb009dcSAndroid Build Coastguard Worker     }
7283*8fb009dcSAndroid Build Coastguard Worker 
7284*8fb009dcSAndroid Build Coastguard Worker     int server_ret = SSL_do_handshake(server_.get());
7285*8fb009dcSAndroid Build Coastguard Worker     if (server_ret != 1) {
7286*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(server_ret, -1);
7287*8fb009dcSAndroid Build Coastguard Worker       int ssl_err = SSL_get_error(server_.get(), server_ret);
7288*8fb009dcSAndroid Build Coastguard Worker       switch (ssl_err) {
7289*8fb009dcSAndroid Build Coastguard Worker         case SSL_ERROR_WANT_READ:
7290*8fb009dcSAndroid Build Coastguard Worker           ASSERT_TRUE(ProvideHandshakeData(server_.get(), 1));
7291*8fb009dcSAndroid Build Coastguard Worker           break;
7292*8fb009dcSAndroid Build Coastguard Worker         case SSL_ERROR_WANT_X509_LOOKUP:
7293*8fb009dcSAndroid Build Coastguard Worker           ASSERT_FALSE(cert_cb_ok);
7294*8fb009dcSAndroid Build Coastguard Worker           cert_cb_ok = true;
7295*8fb009dcSAndroid Build Coastguard Worker           break;
7296*8fb009dcSAndroid Build Coastguard Worker         default:
7297*8fb009dcSAndroid Build Coastguard Worker           FAIL() << "Unexpected SSL_get_error result: " << ssl_err;
7298*8fb009dcSAndroid Build Coastguard Worker       }
7299*8fb009dcSAndroid Build Coastguard Worker     }
7300*8fb009dcSAndroid Build Coastguard Worker 
7301*8fb009dcSAndroid Build Coastguard Worker     if (client_ret == 1 && server_ret == 1) {
7302*8fb009dcSAndroid Build Coastguard Worker       break;
7303*8fb009dcSAndroid Build Coastguard Worker     }
7304*8fb009dcSAndroid Build Coastguard Worker   }
7305*8fb009dcSAndroid Build Coastguard Worker 
7306*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7307*8fb009dcSAndroid Build Coastguard Worker }
7308*8fb009dcSAndroid Build Coastguard Worker 
7309*8fb009dcSAndroid Build Coastguard Worker // Test buffering write data until explicit flushes.
TEST_F(QUICMethodTest,Buffered)7310*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, Buffered) {
7311*8fb009dcSAndroid Build Coastguard Worker   AllowOutOfOrderWrites();
7312*8fb009dcSAndroid Build Coastguard Worker 
7313*8fb009dcSAndroid Build Coastguard Worker   struct BufferedFlight {
7314*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> data[kNumQUICLevels];
7315*8fb009dcSAndroid Build Coastguard Worker   };
7316*8fb009dcSAndroid Build Coastguard Worker   static UnownedSSLExData<BufferedFlight> buffered_flights;
7317*8fb009dcSAndroid Build Coastguard Worker 
7318*8fb009dcSAndroid Build Coastguard Worker   auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
7319*8fb009dcSAndroid Build Coastguard Worker                                const uint8_t *data, size_t len) -> int {
7320*8fb009dcSAndroid Build Coastguard Worker     BufferedFlight *flight = buffered_flights.Get(ssl);
7321*8fb009dcSAndroid Build Coastguard Worker     flight->data[level].insert(flight->data[level].end(), data, data + len);
7322*8fb009dcSAndroid Build Coastguard Worker     return 1;
7323*8fb009dcSAndroid Build Coastguard Worker   };
7324*8fb009dcSAndroid Build Coastguard Worker 
7325*8fb009dcSAndroid Build Coastguard Worker   auto flush_flight = [](SSL *ssl) -> int {
7326*8fb009dcSAndroid Build Coastguard Worker     BufferedFlight *flight = buffered_flights.Get(ssl);
7327*8fb009dcSAndroid Build Coastguard Worker     for (size_t level = 0; level < kNumQUICLevels; level++) {
7328*8fb009dcSAndroid Build Coastguard Worker       if (!flight->data[level].empty()) {
7329*8fb009dcSAndroid Build Coastguard Worker         if (!TransportFromSSL(ssl)->WriteHandshakeData(
7330*8fb009dcSAndroid Build Coastguard Worker                 static_cast<ssl_encryption_level_t>(level),
7331*8fb009dcSAndroid Build Coastguard Worker                 flight->data[level])) {
7332*8fb009dcSAndroid Build Coastguard Worker           return 0;
7333*8fb009dcSAndroid Build Coastguard Worker         }
7334*8fb009dcSAndroid Build Coastguard Worker         flight->data[level].clear();
7335*8fb009dcSAndroid Build Coastguard Worker       }
7336*8fb009dcSAndroid Build Coastguard Worker     }
7337*8fb009dcSAndroid Build Coastguard Worker     return 1;
7338*8fb009dcSAndroid Build Coastguard Worker   };
7339*8fb009dcSAndroid Build Coastguard Worker 
7340*8fb009dcSAndroid Build Coastguard Worker   SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7341*8fb009dcSAndroid Build Coastguard Worker   quic_method.add_handshake_data = add_handshake_data;
7342*8fb009dcSAndroid Build Coastguard Worker   quic_method.flush_flight = flush_flight;
7343*8fb009dcSAndroid Build Coastguard Worker 
7344*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7345*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7346*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7347*8fb009dcSAndroid Build Coastguard Worker 
7348*8fb009dcSAndroid Build Coastguard Worker   BufferedFlight client_flight, server_flight;
7349*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(buffered_flights.Set(client_.get(), &client_flight));
7350*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(buffered_flights.Set(server_.get(), &server_flight));
7351*8fb009dcSAndroid Build Coastguard Worker 
7352*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7353*8fb009dcSAndroid Build Coastguard Worker 
7354*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7355*8fb009dcSAndroid Build Coastguard Worker }
7356*8fb009dcSAndroid Build Coastguard Worker 
7357*8fb009dcSAndroid Build Coastguard Worker // Test that excess data at one level is rejected. That is, if a single
7358*8fb009dcSAndroid Build Coastguard Worker // |SSL_provide_quic_data| call included both ServerHello and
7359*8fb009dcSAndroid Build Coastguard Worker // EncryptedExtensions in a single chunk, BoringSSL notices and rejects this on
7360*8fb009dcSAndroid Build Coastguard Worker // key change.
TEST_F(QUICMethodTest,ExcessProvidedData)7361*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ExcessProvidedData) {
7362*8fb009dcSAndroid Build Coastguard Worker   AllowOutOfOrderWrites();
7363*8fb009dcSAndroid Build Coastguard Worker 
7364*8fb009dcSAndroid Build Coastguard Worker   auto add_handshake_data = [](SSL *ssl, enum ssl_encryption_level_t level,
7365*8fb009dcSAndroid Build Coastguard Worker                                const uint8_t *data, size_t len) -> int {
7366*8fb009dcSAndroid Build Coastguard Worker     // Switch everything to the initial level.
7367*8fb009dcSAndroid Build Coastguard Worker     return TransportFromSSL(ssl)->WriteHandshakeData(ssl_encryption_initial,
7368*8fb009dcSAndroid Build Coastguard Worker                                                      MakeConstSpan(data, len));
7369*8fb009dcSAndroid Build Coastguard Worker   };
7370*8fb009dcSAndroid Build Coastguard Worker 
7371*8fb009dcSAndroid Build Coastguard Worker   SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7372*8fb009dcSAndroid Build Coastguard Worker   quic_method.add_handshake_data = add_handshake_data;
7373*8fb009dcSAndroid Build Coastguard Worker 
7374*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7375*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7376*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7377*8fb009dcSAndroid Build Coastguard Worker 
7378*8fb009dcSAndroid Build Coastguard Worker   // Send the ClientHello and ServerHello through Finished.
7379*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7380*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
7381*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7382*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
7383*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
7384*8fb009dcSAndroid Build Coastguard Worker 
7385*8fb009dcSAndroid Build Coastguard Worker   // The client is still waiting for the ServerHello at initial
7386*8fb009dcSAndroid Build Coastguard Worker   // encryption.
7387*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
7388*8fb009dcSAndroid Build Coastguard Worker 
7389*8fb009dcSAndroid Build Coastguard Worker   // |add_handshake_data| incorrectly wrote everything at the initial level, so
7390*8fb009dcSAndroid Build Coastguard Worker   // this queues up ServerHello through Finished in one chunk.
7391*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7392*8fb009dcSAndroid Build Coastguard Worker 
7393*8fb009dcSAndroid Build Coastguard Worker   // The client reads ServerHello successfully, but then rejects the buffered
7394*8fb009dcSAndroid Build Coastguard Worker   // EncryptedExtensions on key change.
7395*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7396*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_SSL);
7397*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(
7398*8fb009dcSAndroid Build Coastguard Worker       ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_EXCESS_HANDSHAKE_DATA));
7399*8fb009dcSAndroid Build Coastguard Worker 
7400*8fb009dcSAndroid Build Coastguard Worker   // The client sends an alert in response to this. The alert is sent at
7401*8fb009dcSAndroid Build Coastguard Worker   // handshake level because we install write secrets before read secrets and
7402*8fb009dcSAndroid Build Coastguard Worker   // the error is discovered when installing the read secret. (How to send
7403*8fb009dcSAndroid Build Coastguard Worker   // alerts on protocol syntax errors near key changes is ambiguous in general.)
7404*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(transport_->client()->has_alert());
7405*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(transport_->client()->alert_level(), ssl_encryption_handshake);
7406*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(transport_->client()->alert(), SSL_AD_UNEXPECTED_MESSAGE);
7407*8fb009dcSAndroid Build Coastguard Worker 
7408*8fb009dcSAndroid Build Coastguard Worker   // Sanity-check handshake secrets. The error is discovered while setting the
7409*8fb009dcSAndroid Build Coastguard Worker   // read secret, so only the write secret has been installed.
7410*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->client()->HasWriteSecret(ssl_encryption_handshake));
7411*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->client()->HasReadSecret(ssl_encryption_handshake));
7412*8fb009dcSAndroid Build Coastguard Worker }
7413*8fb009dcSAndroid Build Coastguard Worker 
7414*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_provide_quic_data| will reject data at the wrong level.
TEST_F(QUICMethodTest,ProvideWrongLevel)7415*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ProvideWrongLevel) {
7416*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7417*8fb009dcSAndroid Build Coastguard Worker 
7418*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7419*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7420*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7421*8fb009dcSAndroid Build Coastguard Worker 
7422*8fb009dcSAndroid Build Coastguard Worker   // Send the ClientHello and ServerHello through Finished.
7423*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7424*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
7425*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(server_.get()));
7426*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(server_.get()), -1);
7427*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(server_.get(), -1), SSL_ERROR_WANT_READ);
7428*8fb009dcSAndroid Build Coastguard Worker 
7429*8fb009dcSAndroid Build Coastguard Worker   // The client is still waiting for the ServerHello at initial
7430*8fb009dcSAndroid Build Coastguard Worker   // encryption.
7431*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(ssl_encryption_initial, SSL_quic_read_level(client_.get()));
7432*8fb009dcSAndroid Build Coastguard Worker 
7433*8fb009dcSAndroid Build Coastguard Worker   // Data cannot be provided at the next level.
7434*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> data;
7435*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
7436*8fb009dcSAndroid Build Coastguard Worker       transport_->client()->ReadHandshakeData(&data, ssl_encryption_initial));
7437*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_handshake,
7438*8fb009dcSAndroid Build Coastguard Worker                                      data.data(), data.size()));
7439*8fb009dcSAndroid Build Coastguard Worker   ERR_clear_error();
7440*8fb009dcSAndroid Build Coastguard Worker 
7441*8fb009dcSAndroid Build Coastguard Worker   // Progress to EncryptedExtensions.
7442*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
7443*8fb009dcSAndroid Build Coastguard Worker                                     data.data(), data.size()));
7444*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_do_handshake(client_.get()), -1);
7445*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(client_.get(), -1), SSL_ERROR_WANT_READ);
7446*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(ssl_encryption_handshake, SSL_quic_read_level(client_.get()));
7447*8fb009dcSAndroid Build Coastguard Worker 
7448*8fb009dcSAndroid Build Coastguard Worker   // Data cannot be provided at the previous level.
7449*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
7450*8fb009dcSAndroid Build Coastguard Worker       transport_->client()->ReadHandshakeData(&data, ssl_encryption_handshake));
7451*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_provide_quic_data(client_.get(), ssl_encryption_initial,
7452*8fb009dcSAndroid Build Coastguard Worker                                      data.data(), data.size()));
7453*8fb009dcSAndroid Build Coastguard Worker }
7454*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,TooMuchData)7455*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, TooMuchData) {
7456*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7457*8fb009dcSAndroid Build Coastguard Worker 
7458*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7459*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7460*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7461*8fb009dcSAndroid Build Coastguard Worker 
7462*8fb009dcSAndroid Build Coastguard Worker   size_t limit =
7463*8fb009dcSAndroid Build Coastguard Worker       SSL_quic_max_handshake_flight_len(client_.get(), ssl_encryption_initial);
7464*8fb009dcSAndroid Build Coastguard Worker   uint8_t b = 0;
7465*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < limit; i++) {
7466*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(
7467*8fb009dcSAndroid Build Coastguard Worker         SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
7468*8fb009dcSAndroid Build Coastguard Worker   }
7469*8fb009dcSAndroid Build Coastguard Worker 
7470*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(
7471*8fb009dcSAndroid Build Coastguard Worker       SSL_provide_quic_data(client_.get(), ssl_encryption_initial, &b, 1));
7472*8fb009dcSAndroid Build Coastguard Worker }
7473*8fb009dcSAndroid Build Coastguard Worker 
7474*8fb009dcSAndroid Build Coastguard Worker // Provide invalid post-handshake data.
TEST_F(QUICMethodTest,BadPostHandshake)7475*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, BadPostHandshake) {
7476*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7477*8fb009dcSAndroid Build Coastguard Worker 
7478*8fb009dcSAndroid Build Coastguard Worker   g_last_session = nullptr;
7479*8fb009dcSAndroid Build Coastguard Worker 
7480*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7481*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7482*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7483*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7484*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7485*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7486*8fb009dcSAndroid Build Coastguard Worker 
7487*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_do_handshake(client_.get()), 1);
7488*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_do_handshake(server_.get()), 1);
7489*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(transport_->SecretsMatch(ssl_encryption_application));
7490*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->client()->has_alert());
7491*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(transport_->server()->has_alert());
7492*8fb009dcSAndroid Build Coastguard Worker 
7493*8fb009dcSAndroid Build Coastguard Worker   // Junk sent as part of post-handshake data should cause an error.
7494*8fb009dcSAndroid Build Coastguard Worker   uint8_t kJunk[] = {0x17, 0x0, 0x0, 0x4, 0xB, 0xE, 0xE, 0xF};
7495*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_provide_quic_data(client_.get(), ssl_encryption_application,
7496*8fb009dcSAndroid Build Coastguard Worker                                     kJunk, sizeof(kJunk)));
7497*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 0);
7498*8fb009dcSAndroid Build Coastguard Worker }
7499*8fb009dcSAndroid Build Coastguard Worker 
ExpectReceivedTransportParamsEqual(const SSL * ssl,Span<const uint8_t> expected)7500*8fb009dcSAndroid Build Coastguard Worker static void ExpectReceivedTransportParamsEqual(const SSL *ssl,
7501*8fb009dcSAndroid Build Coastguard Worker                                                Span<const uint8_t> expected) {
7502*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *received;
7503*8fb009dcSAndroid Build Coastguard Worker   size_t received_len;
7504*8fb009dcSAndroid Build Coastguard Worker   SSL_get_peer_quic_transport_params(ssl, &received, &received_len);
7505*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(received_len, expected.size());
7506*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(received, received_len), Bytes(expected));
7507*8fb009dcSAndroid Build Coastguard Worker }
7508*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,SetTransportParameters)7509*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, SetTransportParameters) {
7510*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7511*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7512*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7513*8fb009dcSAndroid Build Coastguard Worker 
7514*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7515*8fb009dcSAndroid Build Coastguard Worker   uint8_t kClientParams[] = {1, 2, 3, 4};
7516*8fb009dcSAndroid Build Coastguard Worker   uint8_t kServerParams[] = {5, 6, 7};
7517*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7518*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kClientParams)));
7519*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7520*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kServerParams)));
7521*8fb009dcSAndroid Build Coastguard Worker 
7522*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7523*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7524*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7525*8fb009dcSAndroid Build Coastguard Worker }
7526*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,SetTransportParamsInCallback)7527*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, SetTransportParamsInCallback) {
7528*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7529*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7530*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7531*8fb009dcSAndroid Build Coastguard Worker 
7532*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7533*8fb009dcSAndroid Build Coastguard Worker   uint8_t kClientParams[] = {1, 2, 3, 4};
7534*8fb009dcSAndroid Build Coastguard Worker   static uint8_t kServerParams[] = {5, 6, 7};
7535*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7536*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kClientParams)));
7537*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_tlsext_servername_callback(
7538*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(), [](SSL *ssl, int *out_alert, void *arg) -> int {
7539*8fb009dcSAndroid Build Coastguard Worker         EXPECT_TRUE(SSL_set_quic_transport_params(ssl, kServerParams,
7540*8fb009dcSAndroid Build Coastguard Worker                                                   sizeof(kServerParams)));
7541*8fb009dcSAndroid Build Coastguard Worker         return SSL_TLSEXT_ERR_OK;
7542*8fb009dcSAndroid Build Coastguard Worker       });
7543*8fb009dcSAndroid Build Coastguard Worker 
7544*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7545*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7546*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7547*8fb009dcSAndroid Build Coastguard Worker }
7548*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,ForbidCrossProtocolResumptionClient)7549*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionClient) {
7550*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7551*8fb009dcSAndroid Build Coastguard Worker 
7552*8fb009dcSAndroid Build Coastguard Worker   g_last_session = nullptr;
7553*8fb009dcSAndroid Build Coastguard Worker 
7554*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7555*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7556*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7557*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7558*8fb009dcSAndroid Build Coastguard Worker 
7559*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7560*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7561*8fb009dcSAndroid Build Coastguard Worker 
7562*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7563*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client_.get()));
7564*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server_.get()));
7565*8fb009dcSAndroid Build Coastguard Worker 
7566*8fb009dcSAndroid Build Coastguard Worker   // The server sent NewSessionTicket messages in the handshake.
7567*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(g_last_session);
7568*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7569*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
7570*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(g_last_session);
7571*8fb009dcSAndroid Build Coastguard Worker 
7572*8fb009dcSAndroid Build Coastguard Worker   // Pretend that g_last_session came from a TLS-over-TCP connection.
7573*8fb009dcSAndroid Build Coastguard Worker   g_last_session->is_quic = false;
7574*8fb009dcSAndroid Build Coastguard Worker 
7575*8fb009dcSAndroid Build Coastguard Worker   // Create a second connection and verify that resumption does not occur with
7576*8fb009dcSAndroid Build Coastguard Worker   // a session from a non-QUIC connection. This tests that the client does not
7577*8fb009dcSAndroid Build Coastguard Worker   // offer over QUIC a session believed to be received over TCP. The server
7578*8fb009dcSAndroid Build Coastguard Worker   // believes this is a QUIC session, so if the client offered the session, the
7579*8fb009dcSAndroid Build Coastguard Worker   // server would have resumed it.
7580*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7581*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session = std::move(g_last_session);
7582*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client_.get(), session.get());
7583*8fb009dcSAndroid Build Coastguard Worker 
7584*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7585*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7586*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client_.get()));
7587*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server_.get()));
7588*8fb009dcSAndroid Build Coastguard Worker }
7589*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,ForbidCrossProtocolResumptionServer)7590*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ForbidCrossProtocolResumptionServer) {
7591*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7592*8fb009dcSAndroid Build Coastguard Worker 
7593*8fb009dcSAndroid Build Coastguard Worker   g_last_session = nullptr;
7594*8fb009dcSAndroid Build Coastguard Worker 
7595*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7596*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx_.get(), SaveLastSession);
7597*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7598*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7599*8fb009dcSAndroid Build Coastguard Worker 
7600*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7601*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7602*8fb009dcSAndroid Build Coastguard Worker 
7603*8fb009dcSAndroid Build Coastguard Worker   ExpectHandshakeSuccess();
7604*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client_.get()));
7605*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server_.get()));
7606*8fb009dcSAndroid Build Coastguard Worker 
7607*8fb009dcSAndroid Build Coastguard Worker   // The server sent NewSessionTicket messages in the handshake.
7608*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(g_last_session);
7609*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ProvideHandshakeData(client_.get()));
7610*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_process_quic_post_handshake(client_.get()), 1);
7611*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(g_last_session);
7612*8fb009dcSAndroid Build Coastguard Worker 
7613*8fb009dcSAndroid Build Coastguard Worker   // Attempt a resumption with g_last_session using TLS_method.
7614*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
7615*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
7616*8fb009dcSAndroid Build Coastguard Worker 
7617*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), nullptr));
7618*8fb009dcSAndroid Build Coastguard Worker 
7619*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
7620*8fb009dcSAndroid Build Coastguard Worker       server(SSL_new(server_ctx_.get()));
7621*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client);
7622*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server);
7623*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(client.get());
7624*8fb009dcSAndroid Build Coastguard Worker   SSL_set_accept_state(server.get());
7625*8fb009dcSAndroid Build Coastguard Worker 
7626*8fb009dcSAndroid Build Coastguard Worker   // The TLS-over-TCP client will refuse to resume with a quic session, so
7627*8fb009dcSAndroid Build Coastguard Worker   // mark is_quic = false to bypass the client check to test the server check.
7628*8fb009dcSAndroid Build Coastguard Worker   g_last_session->is_quic = false;
7629*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client.get(), g_last_session.get());
7630*8fb009dcSAndroid Build Coastguard Worker 
7631*8fb009dcSAndroid Build Coastguard Worker   BIO *bio1, *bio2;
7632*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_new_bio_pair(&bio1, 0, &bio2, 0));
7633*8fb009dcSAndroid Build Coastguard Worker 
7634*8fb009dcSAndroid Build Coastguard Worker   // SSL_set_bio takes ownership.
7635*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(client.get(), bio1, bio1);
7636*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(server.get(), bio2, bio2);
7637*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
7638*8fb009dcSAndroid Build Coastguard Worker 
7639*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client.get()));
7640*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server.get()));
7641*8fb009dcSAndroid Build Coastguard Worker }
7642*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,ClientRejectsMissingTransportParams)7643*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ClientRejectsMissingTransportParams) {
7644*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7645*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7646*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7647*8fb009dcSAndroid Build Coastguard Worker 
7648*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7649*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), nullptr, 0));
7650*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7651*8fb009dcSAndroid Build Coastguard Worker }
7652*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,ServerRejectsMissingTransportParams)7653*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, ServerRejectsMissingTransportParams) {
7654*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7655*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7656*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7657*8fb009dcSAndroid Build Coastguard Worker 
7658*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7659*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), nullptr, 0));
7660*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kClientError));
7661*8fb009dcSAndroid Build Coastguard Worker }
7662*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,QuicLegacyCodepointEnabled)7663*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, QuicLegacyCodepointEnabled) {
7664*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7665*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7666*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7667*8fb009dcSAndroid Build Coastguard Worker 
7668*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7669*8fb009dcSAndroid Build Coastguard Worker   uint8_t kClientParams[] = {1, 2, 3, 4};
7670*8fb009dcSAndroid Build Coastguard Worker   uint8_t kServerParams[] = {5, 6, 7};
7671*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7672*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7673*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7674*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kClientParams)));
7675*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7676*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kServerParams)));
7677*8fb009dcSAndroid Build Coastguard Worker 
7678*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7679*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7680*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7681*8fb009dcSAndroid Build Coastguard Worker }
7682*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,QuicLegacyCodepointDisabled)7683*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, QuicLegacyCodepointDisabled) {
7684*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7685*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7686*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7687*8fb009dcSAndroid Build Coastguard Worker 
7688*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7689*8fb009dcSAndroid Build Coastguard Worker   uint8_t kClientParams[] = {1, 2, 3, 4};
7690*8fb009dcSAndroid Build Coastguard Worker   uint8_t kServerParams[] = {5, 6, 7};
7691*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7692*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7693*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7694*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kClientParams)));
7695*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7696*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kServerParams)));
7697*8fb009dcSAndroid Build Coastguard Worker 
7698*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7699*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(client_.get(), kServerParams);
7700*8fb009dcSAndroid Build Coastguard Worker   ExpectReceivedTransportParamsEqual(server_.get(), kClientParams);
7701*8fb009dcSAndroid Build Coastguard Worker }
7702*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,QuicLegacyCodepointClientOnly)7703*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, QuicLegacyCodepointClientOnly) {
7704*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7705*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7706*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7707*8fb009dcSAndroid Build Coastguard Worker 
7708*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7709*8fb009dcSAndroid Build Coastguard Worker   uint8_t kClientParams[] = {1, 2, 3, 4};
7710*8fb009dcSAndroid Build Coastguard Worker   uint8_t kServerParams[] = {5, 6, 7};
7711*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(client_.get(), 1);
7712*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(server_.get(), 0);
7713*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7714*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kClientParams)));
7715*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7716*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kServerParams)));
7717*8fb009dcSAndroid Build Coastguard Worker 
7718*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7719*8fb009dcSAndroid Build Coastguard Worker }
7720*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(QUICMethodTest,QuicLegacyCodepointServerOnly)7721*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, QuicLegacyCodepointServerOnly) {
7722*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7723*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7724*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7725*8fb009dcSAndroid Build Coastguard Worker 
7726*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7727*8fb009dcSAndroid Build Coastguard Worker   uint8_t kClientParams[] = {1, 2, 3, 4};
7728*8fb009dcSAndroid Build Coastguard Worker   uint8_t kServerParams[] = {5, 6, 7};
7729*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(client_.get(), 0);
7730*8fb009dcSAndroid Build Coastguard Worker   SSL_set_quic_use_legacy_codepoint(server_.get(), 1);
7731*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(client_.get(), kClientParams,
7732*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kClientParams)));
7733*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_set_quic_transport_params(server_.get(), kServerParams,
7734*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(kServerParams)));
7735*8fb009dcSAndroid Build Coastguard Worker 
7736*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(RunQUICHandshakesAndExpectError(ExpectedError::kServerError));
7737*8fb009dcSAndroid Build Coastguard Worker }
7738*8fb009dcSAndroid Build Coastguard Worker 
7739*8fb009dcSAndroid Build Coastguard Worker // Test that the default QUIC code point is consistent with
7740*8fb009dcSAndroid Build Coastguard Worker // |TLSEXT_TYPE_quic_transport_parameters|. This test ensures we remember to
7741*8fb009dcSAndroid Build Coastguard Worker // update the two values together.
TEST_F(QUICMethodTest,QuicCodePointDefault)7742*8fb009dcSAndroid Build Coastguard Worker TEST_F(QUICMethodTest, QuicCodePointDefault) {
7743*8fb009dcSAndroid Build Coastguard Worker   const SSL_QUIC_METHOD quic_method = DefaultQUICMethod();
7744*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(client_ctx_.get(), &quic_method));
7745*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_quic_method(server_ctx_.get(), &quic_method));
7746*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_select_certificate_cb(
7747*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(),
7748*8fb009dcSAndroid Build Coastguard Worker       [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
7749*8fb009dcSAndroid Build Coastguard Worker         const uint8_t *data;
7750*8fb009dcSAndroid Build Coastguard Worker         size_t len;
7751*8fb009dcSAndroid Build Coastguard Worker         if (!SSL_early_callback_ctx_extension_get(
7752*8fb009dcSAndroid Build Coastguard Worker                 client_hello, TLSEXT_TYPE_quic_transport_parameters, &data,
7753*8fb009dcSAndroid Build Coastguard Worker                 &len)) {
7754*8fb009dcSAndroid Build Coastguard Worker           ADD_FAILURE() << "Could not find quic_transport_parameters extension";
7755*8fb009dcSAndroid Build Coastguard Worker           return ssl_select_cert_error;
7756*8fb009dcSAndroid Build Coastguard Worker         }
7757*8fb009dcSAndroid Build Coastguard Worker         return ssl_select_cert_success;
7758*8fb009dcSAndroid Build Coastguard Worker       });
7759*8fb009dcSAndroid Build Coastguard Worker 
7760*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer());
7761*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakesForQUIC());
7762*8fb009dcSAndroid Build Coastguard Worker }
7763*8fb009dcSAndroid Build Coastguard Worker 
7764*8fb009dcSAndroid Build Coastguard Worker extern "C" {
7765*8fb009dcSAndroid Build Coastguard Worker int BORINGSSL_enum_c_type_test(void);
7766*8fb009dcSAndroid Build Coastguard Worker }
7767*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,EnumTypes)7768*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, EnumTypes) {
7769*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(sizeof(int), sizeof(ssl_private_key_result_t));
7770*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, BORINGSSL_enum_c_type_test());
7771*8fb009dcSAndroid Build Coastguard Worker }
7772*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,DoubleSSLError)7773*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, DoubleSSLError) {
7774*8fb009dcSAndroid Build Coastguard Worker   // Connect the inner SSL connections.
7775*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
7776*8fb009dcSAndroid Build Coastguard Worker 
7777*8fb009dcSAndroid Build Coastguard Worker   // Make a pair of |BIO|s which wrap |client_| and |server_|.
7778*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<BIO_METHOD> bio_method(BIO_meth_new(0, nullptr));
7779*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bio_method);
7780*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_meth_set_read(
7781*8fb009dcSAndroid Build Coastguard Worker       bio_method.get(), [](BIO *bio, char *out, int len) -> int {
7782*8fb009dcSAndroid Build Coastguard Worker         SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7783*8fb009dcSAndroid Build Coastguard Worker         int ret = SSL_read(ssl, out, len);
7784*8fb009dcSAndroid Build Coastguard Worker         int ssl_ret = SSL_get_error(ssl, ret);
7785*8fb009dcSAndroid Build Coastguard Worker         if (ssl_ret == SSL_ERROR_WANT_READ) {
7786*8fb009dcSAndroid Build Coastguard Worker           BIO_set_retry_read(bio);
7787*8fb009dcSAndroid Build Coastguard Worker         }
7788*8fb009dcSAndroid Build Coastguard Worker         return ret;
7789*8fb009dcSAndroid Build Coastguard Worker       }));
7790*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_meth_set_write(
7791*8fb009dcSAndroid Build Coastguard Worker       bio_method.get(), [](BIO *bio, const char *in, int len) -> int {
7792*8fb009dcSAndroid Build Coastguard Worker         SSL *ssl = static_cast<SSL *>(BIO_get_data(bio));
7793*8fb009dcSAndroid Build Coastguard Worker         int ret = SSL_write(ssl, in, len);
7794*8fb009dcSAndroid Build Coastguard Worker         int ssl_ret = SSL_get_error(ssl, ret);
7795*8fb009dcSAndroid Build Coastguard Worker         if (ssl_ret == SSL_ERROR_WANT_WRITE) {
7796*8fb009dcSAndroid Build Coastguard Worker           BIO_set_retry_write(bio);
7797*8fb009dcSAndroid Build Coastguard Worker         }
7798*8fb009dcSAndroid Build Coastguard Worker         return ret;
7799*8fb009dcSAndroid Build Coastguard Worker       }));
7800*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_meth_set_ctrl(
7801*8fb009dcSAndroid Build Coastguard Worker       bio_method.get(), [](BIO *bio, int cmd, long larg, void *parg) -> long {
7802*8fb009dcSAndroid Build Coastguard Worker         // |SSL| objects require |BIO_flush| support.
7803*8fb009dcSAndroid Build Coastguard Worker         if (cmd == BIO_CTRL_FLUSH) {
7804*8fb009dcSAndroid Build Coastguard Worker           return 1;
7805*8fb009dcSAndroid Build Coastguard Worker         }
7806*8fb009dcSAndroid Build Coastguard Worker         return 0;
7807*8fb009dcSAndroid Build Coastguard Worker       }));
7808*8fb009dcSAndroid Build Coastguard Worker 
7809*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<BIO> client_bio(BIO_new(bio_method.get()));
7810*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_bio);
7811*8fb009dcSAndroid Build Coastguard Worker   BIO_set_data(client_bio.get(), client_.get());
7812*8fb009dcSAndroid Build Coastguard Worker   BIO_set_init(client_bio.get(), 1);
7813*8fb009dcSAndroid Build Coastguard Worker 
7814*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<BIO> server_bio(BIO_new(bio_method.get()));
7815*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_bio);
7816*8fb009dcSAndroid Build Coastguard Worker   BIO_set_data(server_bio.get(), server_.get());
7817*8fb009dcSAndroid Build Coastguard Worker   BIO_set_init(server_bio.get(), 1);
7818*8fb009dcSAndroid Build Coastguard Worker 
7819*8fb009dcSAndroid Build Coastguard Worker   // Wrap the inner connections in another layer of SSL.
7820*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL> client_outer(SSL_new(client_ctx_.get()));
7821*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_outer);
7822*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(client_outer.get());
7823*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(client_outer.get(), client_bio.get(), client_bio.get());
7824*8fb009dcSAndroid Build Coastguard Worker   client_bio.release();  // |SSL_set_bio| takes ownership.
7825*8fb009dcSAndroid Build Coastguard Worker 
7826*8fb009dcSAndroid Build Coastguard Worker   UniquePtr<SSL> server_outer(SSL_new(server_ctx_.get()));
7827*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_outer);
7828*8fb009dcSAndroid Build Coastguard Worker   SSL_set_accept_state(server_outer.get());
7829*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(server_outer.get(), server_bio.get(), server_bio.get());
7830*8fb009dcSAndroid Build Coastguard Worker   server_bio.release();  // |SSL_set_bio| takes ownership.
7831*8fb009dcSAndroid Build Coastguard Worker 
7832*8fb009dcSAndroid Build Coastguard Worker   // Configure |client_outer| to reject the server certificate.
7833*8fb009dcSAndroid Build Coastguard Worker   SSL_set_custom_verify(
7834*8fb009dcSAndroid Build Coastguard Worker       client_outer.get(), SSL_VERIFY_PEER,
7835*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, uint8_t *out_alert) -> ssl_verify_result_t {
7836*8fb009dcSAndroid Build Coastguard Worker         return ssl_verify_invalid;
7837*8fb009dcSAndroid Build Coastguard Worker       });
7838*8fb009dcSAndroid Build Coastguard Worker 
7839*8fb009dcSAndroid Build Coastguard Worker   for (;;) {
7840*8fb009dcSAndroid Build Coastguard Worker     int client_ret = SSL_do_handshake(client_outer.get());
7841*8fb009dcSAndroid Build Coastguard Worker     int client_err = SSL_get_error(client_outer.get(), client_ret);
7842*8fb009dcSAndroid Build Coastguard Worker     if (client_err != SSL_ERROR_WANT_READ &&
7843*8fb009dcSAndroid Build Coastguard Worker         client_err != SSL_ERROR_WANT_WRITE) {
7844*8fb009dcSAndroid Build Coastguard Worker       // The client handshake should terminate on a certificate verification
7845*8fb009dcSAndroid Build Coastguard Worker       // error.
7846*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(SSL_ERROR_SSL, client_err);
7847*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(ErrorEquals(ERR_peek_error(), ERR_LIB_SSL,
7848*8fb009dcSAndroid Build Coastguard Worker                               SSL_R_CERTIFICATE_VERIFY_FAILED));
7849*8fb009dcSAndroid Build Coastguard Worker       break;
7850*8fb009dcSAndroid Build Coastguard Worker     }
7851*8fb009dcSAndroid Build Coastguard Worker 
7852*8fb009dcSAndroid Build Coastguard Worker     // Run the server handshake and continue.
7853*8fb009dcSAndroid Build Coastguard Worker     int server_ret = SSL_do_handshake(server_outer.get());
7854*8fb009dcSAndroid Build Coastguard Worker     int server_err = SSL_get_error(server_outer.get(), server_ret);
7855*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_err == SSL_ERROR_NONE ||
7856*8fb009dcSAndroid Build Coastguard Worker                 server_err == SSL_ERROR_WANT_READ ||
7857*8fb009dcSAndroid Build Coastguard Worker                 server_err == SSL_ERROR_WANT_WRITE);
7858*8fb009dcSAndroid Build Coastguard Worker   }
7859*8fb009dcSAndroid Build Coastguard Worker }
7860*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,SameKeyResume)7861*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, SameKeyResume) {
7862*8fb009dcSAndroid Build Coastguard Worker   uint8_t key[48];
7863*8fb009dcSAndroid Build Coastguard Worker   RAND_bytes(key, sizeof(key));
7864*8fb009dcSAndroid Build Coastguard Worker 
7865*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7866*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx2);
7867*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7868*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
7869*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key, sizeof(key)));
7870*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
7871*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key, sizeof(key)));
7872*8fb009dcSAndroid Build Coastguard Worker 
7873*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7874*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7875*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7876*8fb009dcSAndroid Build Coastguard Worker 
7877*8fb009dcSAndroid Build Coastguard Worker   // Establish a session for |server_ctx_|.
7878*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
7879*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
7880*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
7881*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
7882*8fb009dcSAndroid Build Coastguard Worker   config.session = session.get();
7883*8fb009dcSAndroid Build Coastguard Worker 
7884*8fb009dcSAndroid Build Coastguard Worker   // Resuming with |server_ctx_| again works.
7885*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
7886*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7887*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx_.get(), config));
7888*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client.get()));
7889*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server.get()));
7890*8fb009dcSAndroid Build Coastguard Worker 
7891*8fb009dcSAndroid Build Coastguard Worker   // Resuming with |server_ctx2| also works.
7892*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7893*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx2.get(), config));
7894*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client.get()));
7895*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server.get()));
7896*8fb009dcSAndroid Build Coastguard Worker }
7897*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,DifferentKeyNoResume)7898*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, DifferentKeyNoResume) {
7899*8fb009dcSAndroid Build Coastguard Worker   uint8_t key1[48], key2[48];
7900*8fb009dcSAndroid Build Coastguard Worker   RAND_bytes(key1, sizeof(key1));
7901*8fb009dcSAndroid Build Coastguard Worker   RAND_bytes(key2, sizeof(key2));
7902*8fb009dcSAndroid Build Coastguard Worker 
7903*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7904*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx2);
7905*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7906*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
7907*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_tlsext_ticket_keys(server_ctx_.get(), key1, sizeof(key1)));
7908*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
7909*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_tlsext_ticket_keys(server_ctx2.get(), key2, sizeof(key2)));
7910*8fb009dcSAndroid Build Coastguard Worker 
7911*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7912*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7913*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7914*8fb009dcSAndroid Build Coastguard Worker 
7915*8fb009dcSAndroid Build Coastguard Worker   // Establish a session for |server_ctx_|.
7916*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
7917*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
7918*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
7919*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
7920*8fb009dcSAndroid Build Coastguard Worker   config.session = session.get();
7921*8fb009dcSAndroid Build Coastguard Worker 
7922*8fb009dcSAndroid Build Coastguard Worker   // Resuming with |server_ctx_| again works.
7923*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
7924*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7925*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx_.get(), config));
7926*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client.get()));
7927*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server.get()));
7928*8fb009dcSAndroid Build Coastguard Worker 
7929*8fb009dcSAndroid Build Coastguard Worker   // Resuming with |server_ctx2| does not work.
7930*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7931*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx2.get(), config));
7932*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client.get()));
7933*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server.get()));
7934*8fb009dcSAndroid Build Coastguard Worker }
7935*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,UnrelatedServerNoResume)7936*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, UnrelatedServerNoResume) {
7937*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx2 = CreateContext();
7938*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx2);
7939*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(UseCertAndKey(server_ctx2.get()));
7940*8fb009dcSAndroid Build Coastguard Worker 
7941*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7942*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7943*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx2.get(), SSL_SESS_CACHE_BOTH);
7944*8fb009dcSAndroid Build Coastguard Worker 
7945*8fb009dcSAndroid Build Coastguard Worker   // Establish a session for |server_ctx_|.
7946*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
7947*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
7948*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
7949*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
7950*8fb009dcSAndroid Build Coastguard Worker   config.session = session.get();
7951*8fb009dcSAndroid Build Coastguard Worker 
7952*8fb009dcSAndroid Build Coastguard Worker   // Resuming with |server_ctx_| again works.
7953*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
7954*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7955*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx_.get(), config));
7956*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client.get()));
7957*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server.get()));
7958*8fb009dcSAndroid Build Coastguard Worker 
7959*8fb009dcSAndroid Build Coastguard Worker   // Resuming with |server_ctx2| does not work.
7960*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7961*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx2.get(), config));
7962*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(client.get()));
7963*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_session_reused(server.get()));
7964*8fb009dcSAndroid Build Coastguard Worker }
7965*8fb009dcSAndroid Build Coastguard Worker 
SessionIDOf(const SSL * ssl)7966*8fb009dcSAndroid Build Coastguard Worker Span<const uint8_t> SessionIDOf(const SSL* ssl) {
7967*8fb009dcSAndroid Build Coastguard Worker   const SSL_SESSION *session = SSL_get_session(ssl);
7968*8fb009dcSAndroid Build Coastguard Worker   unsigned len;
7969*8fb009dcSAndroid Build Coastguard Worker   const uint8_t *data = SSL_SESSION_get_id(session, &len);
7970*8fb009dcSAndroid Build Coastguard Worker   return MakeConstSpan(data, len);
7971*8fb009dcSAndroid Build Coastguard Worker }
7972*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,TicketSessionIDsMatch)7973*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, TicketSessionIDsMatch) {
7974*8fb009dcSAndroid Build Coastguard Worker   // This checks that the session IDs at client and server match after a ticket
7975*8fb009dcSAndroid Build Coastguard Worker   // resumption. It's unclear whether this should be true, but Envoy depends
7976*8fb009dcSAndroid Build Coastguard Worker   // on it in their tests so this will give an early signal if we break it.
7977*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);
7978*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx_.get(), SSL_SESS_CACHE_BOTH);
7979*8fb009dcSAndroid Build Coastguard Worker 
7980*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
7981*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx_.get(), server_ctx_.get());
7982*8fb009dcSAndroid Build Coastguard Worker 
7983*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
7984*8fb009dcSAndroid Build Coastguard Worker   ClientConfig config;
7985*8fb009dcSAndroid Build Coastguard Worker   config.session = session.get();
7986*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx_.get(),
7987*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx_.get(), config));
7988*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client.get()));
7989*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(server.get()));
7990*8fb009dcSAndroid Build Coastguard Worker 
7991*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(SessionIDOf(client.get())), Bytes(SessionIDOf(server.get())));
7992*8fb009dcSAndroid Build Coastguard Worker }
7993*8fb009dcSAndroid Build Coastguard Worker 
WriteHelloRequest(SSL * server)7994*8fb009dcSAndroid Build Coastguard Worker static void WriteHelloRequest(SSL *server) {
7995*8fb009dcSAndroid Build Coastguard Worker   // This function assumes TLS 1.2 with ChaCha20-Poly1305.
7996*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_version(server), TLS1_2_VERSION);
7997*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_CIPHER_get_cipher_nid(SSL_get_current_cipher(server)),
7998*8fb009dcSAndroid Build Coastguard Worker             NID_chacha20_poly1305);
7999*8fb009dcSAndroid Build Coastguard Worker 
8000*8fb009dcSAndroid Build Coastguard Worker   // Encrypt a HelloRequest.
8001*8fb009dcSAndroid Build Coastguard Worker   uint8_t in[] = {SSL3_MT_HELLO_REQUEST, 0, 0, 0};
8002*8fb009dcSAndroid Build Coastguard Worker #if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
8003*8fb009dcSAndroid Build Coastguard Worker   // Fuzzer-mode records are unencrypted.
8004*8fb009dcSAndroid Build Coastguard Worker   uint8_t record[5 + sizeof(in)];
8005*8fb009dcSAndroid Build Coastguard Worker   record[0] = SSL3_RT_HANDSHAKE;
8006*8fb009dcSAndroid Build Coastguard Worker   record[1] = 3;
8007*8fb009dcSAndroid Build Coastguard Worker   record[2] = 3;  // TLS 1.2
8008*8fb009dcSAndroid Build Coastguard Worker   record[3] = 0;
8009*8fb009dcSAndroid Build Coastguard Worker   record[4] = sizeof(record) - 5;
8010*8fb009dcSAndroid Build Coastguard Worker   memcpy(record + 5, in, sizeof(in));
8011*8fb009dcSAndroid Build Coastguard Worker #else
8012*8fb009dcSAndroid Build Coastguard Worker   // Extract key material from |server|.
8013*8fb009dcSAndroid Build Coastguard Worker   static const size_t kKeyLen = 32;
8014*8fb009dcSAndroid Build Coastguard Worker   static const size_t kNonceLen = 12;
8015*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(2u * (kKeyLen + kNonceLen), SSL_get_key_block_len(server));
8016*8fb009dcSAndroid Build Coastguard Worker   uint8_t key_block[2u * (kKeyLen + kNonceLen)];
8017*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_generate_key_block(server, key_block, sizeof(key_block)));
8018*8fb009dcSAndroid Build Coastguard Worker   Span<uint8_t> key = MakeSpan(key_block + kKeyLen, kKeyLen);
8019*8fb009dcSAndroid Build Coastguard Worker   Span<uint8_t> nonce =
8020*8fb009dcSAndroid Build Coastguard Worker       MakeSpan(key_block + kKeyLen + kKeyLen + kNonceLen, kNonceLen);
8021*8fb009dcSAndroid Build Coastguard Worker 
8022*8fb009dcSAndroid Build Coastguard Worker   uint8_t ad[13];
8023*8fb009dcSAndroid Build Coastguard Worker   uint64_t seq = SSL_get_write_sequence(server);
8024*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < 8; i++) {
8025*8fb009dcSAndroid Build Coastguard Worker     // The nonce is XORed with the sequence number.
8026*8fb009dcSAndroid Build Coastguard Worker     nonce[11 - i] ^= uint8_t(seq);
8027*8fb009dcSAndroid Build Coastguard Worker     ad[7 - i] = uint8_t(seq);
8028*8fb009dcSAndroid Build Coastguard Worker     seq >>= 8;
8029*8fb009dcSAndroid Build Coastguard Worker   }
8030*8fb009dcSAndroid Build Coastguard Worker 
8031*8fb009dcSAndroid Build Coastguard Worker   ad[8] = SSL3_RT_HANDSHAKE;
8032*8fb009dcSAndroid Build Coastguard Worker   ad[9] = 3;
8033*8fb009dcSAndroid Build Coastguard Worker   ad[10] = 3;  // TLS 1.2
8034*8fb009dcSAndroid Build Coastguard Worker   ad[11] = 0;
8035*8fb009dcSAndroid Build Coastguard Worker   ad[12] = sizeof(in);
8036*8fb009dcSAndroid Build Coastguard Worker 
8037*8fb009dcSAndroid Build Coastguard Worker   uint8_t record[5 + sizeof(in) + 16];
8038*8fb009dcSAndroid Build Coastguard Worker   record[0] = SSL3_RT_HANDSHAKE;
8039*8fb009dcSAndroid Build Coastguard Worker   record[1] = 3;
8040*8fb009dcSAndroid Build Coastguard Worker   record[2] = 3;  // TLS 1.2
8041*8fb009dcSAndroid Build Coastguard Worker   record[3] = 0;
8042*8fb009dcSAndroid Build Coastguard Worker   record[4] = sizeof(record) - 5;
8043*8fb009dcSAndroid Build Coastguard Worker 
8044*8fb009dcSAndroid Build Coastguard Worker   ScopedEVP_AEAD_CTX aead;
8045*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_AEAD_CTX_init(aead.get(), EVP_aead_chacha20_poly1305(),
8046*8fb009dcSAndroid Build Coastguard Worker                                 key.data(), key.size(),
8047*8fb009dcSAndroid Build Coastguard Worker                                 EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr));
8048*8fb009dcSAndroid Build Coastguard Worker   size_t len;
8049*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(EVP_AEAD_CTX_seal(aead.get(), record + 5, &len,
8050*8fb009dcSAndroid Build Coastguard Worker                                 sizeof(record) - 5, nonce.data(), nonce.size(),
8051*8fb009dcSAndroid Build Coastguard Worker                                 in, sizeof(in), ad, sizeof(ad)));
8052*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(sizeof(record) - 5, len);
8053*8fb009dcSAndroid Build Coastguard Worker #endif  // BORINGSSL_UNSAFE_FUZZER_MODE
8054*8fb009dcSAndroid Build Coastguard Worker 
8055*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(int(sizeof(record)),
8056*8fb009dcSAndroid Build Coastguard Worker             BIO_write(SSL_get_wbio(server), record, sizeof(record)));
8057*8fb009dcSAndroid Build Coastguard Worker }
8058*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,WriteWhileExplicitRenegotiate)8059*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, WriteWhileExplicitRenegotiate) {
8060*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(CreateContextWithTestCertificate(TLS_method()));
8061*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
8062*8fb009dcSAndroid Build Coastguard Worker 
8063*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
8064*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
8065*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
8066*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
8067*8fb009dcSAndroid Build Coastguard Worker 
8068*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
8069*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
8070*8fb009dcSAndroid Build Coastguard Worker   SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_explicit);
8071*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
8072*8fb009dcSAndroid Build Coastguard Worker 
8073*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kInput[] = {'h', 'e', 'l', 'l', 'o'};
8074*8fb009dcSAndroid Build Coastguard Worker 
8075*8fb009dcSAndroid Build Coastguard Worker   // Write "hello" until the buffer is full, so |client| has a pending write.
8076*8fb009dcSAndroid Build Coastguard Worker   size_t num_writes = 0;
8077*8fb009dcSAndroid Build Coastguard Worker   for (;;) {
8078*8fb009dcSAndroid Build Coastguard Worker     int ret = SSL_write(client.get(), kInput, sizeof(kInput));
8079*8fb009dcSAndroid Build Coastguard Worker     if (ret != int(sizeof(kInput))) {
8080*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(-1, ret);
8081*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(SSL_ERROR_WANT_WRITE, SSL_get_error(client.get(), ret));
8082*8fb009dcSAndroid Build Coastguard Worker       break;
8083*8fb009dcSAndroid Build Coastguard Worker     }
8084*8fb009dcSAndroid Build Coastguard Worker     num_writes++;
8085*8fb009dcSAndroid Build Coastguard Worker   }
8086*8fb009dcSAndroid Build Coastguard Worker 
8087*8fb009dcSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get()));
8088*8fb009dcSAndroid Build Coastguard Worker 
8089*8fb009dcSAndroid Build Coastguard Worker   // |SSL_read| should pick up the HelloRequest.
8090*8fb009dcSAndroid Build Coastguard Worker   uint8_t byte;
8091*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
8092*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
8093*8fb009dcSAndroid Build Coastguard Worker 
8094*8fb009dcSAndroid Build Coastguard Worker   // Drain the data from the |client|.
8095*8fb009dcSAndroid Build Coastguard Worker   uint8_t buf[sizeof(kInput)];
8096*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < num_writes; i++) {
8097*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
8098*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes(buf), Bytes(kInput));
8099*8fb009dcSAndroid Build Coastguard Worker   }
8100*8fb009dcSAndroid Build Coastguard Worker 
8101*8fb009dcSAndroid Build Coastguard Worker   // |client| should be able to finish the pending write and continue to write,
8102*8fb009dcSAndroid Build Coastguard Worker   // despite the paused HelloRequest.
8103*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(int(sizeof(kInput)),
8104*8fb009dcSAndroid Build Coastguard Worker             SSL_write(client.get(), kInput, sizeof(kInput)));
8105*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
8106*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(buf), Bytes(kInput));
8107*8fb009dcSAndroid Build Coastguard Worker 
8108*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(int(sizeof(kInput)),
8109*8fb009dcSAndroid Build Coastguard Worker             SSL_write(client.get(), kInput, sizeof(kInput)));
8110*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(int(sizeof(buf)), SSL_read(server.get(), buf, sizeof(buf)));
8111*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(Bytes(buf), Bytes(kInput));
8112*8fb009dcSAndroid Build Coastguard Worker 
8113*8fb009dcSAndroid Build Coastguard Worker   // |SSL_read| is stuck until we acknowledge the HelloRequest.
8114*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
8115*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_WANT_RENEGOTIATE, SSL_get_error(client.get(), -1));
8116*8fb009dcSAndroid Build Coastguard Worker 
8117*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_renegotiate(client.get()));
8118*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
8119*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
8120*8fb009dcSAndroid Build Coastguard Worker 
8121*8fb009dcSAndroid Build Coastguard Worker   // We never renegotiate as a server.
8122*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(-1, SSL_read(server.get(), buf, sizeof(buf)));
8123*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_SSL, SSL_get_error(server.get(), -1));
8124*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(
8125*8fb009dcSAndroid Build Coastguard Worker       ErrorEquals(ERR_get_error(), ERR_LIB_SSL, SSL_R_NO_RENEGOTIATION));
8126*8fb009dcSAndroid Build Coastguard Worker }
8127*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ConnectionPropertiesDuringRenegotiate)8128*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ConnectionPropertiesDuringRenegotiate) {
8129*8fb009dcSAndroid Build Coastguard Worker   // Configure known connection properties, so we can check against them.
8130*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8131*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
8132*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetTestCertificate();
8133*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
8134*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8135*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
8136*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
8137*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
8138*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(ctx.get(), TLS1_2_VERSION));
8139*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(ctx.get(), TLS1_2_VERSION));
8140*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
8141*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256"));
8142*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_groups_list(ctx.get(), "X25519"));
8143*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set1_sigalgs_list(ctx.get(), "rsa_pkcs1_sha256"));
8144*8fb009dcSAndroid Build Coastguard Worker 
8145*8fb009dcSAndroid Build Coastguard Worker   // Connect a client and server that accept renegotiation.
8146*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
8147*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, ctx.get(), ctx.get()));
8148*8fb009dcSAndroid Build Coastguard Worker   SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
8149*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
8150*8fb009dcSAndroid Build Coastguard Worker 
8151*8fb009dcSAndroid Build Coastguard Worker   auto check_properties = [&] {
8152*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_version(client.get()), TLS1_2_VERSION);
8153*8fb009dcSAndroid Build Coastguard Worker     const SSL_CIPHER *cipher = SSL_get_current_cipher(client.get());
8154*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(cipher);
8155*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_CIPHER_get_id(cipher),
8156*8fb009dcSAndroid Build Coastguard Worker               uint32_t{TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256});
8157*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_get_group_id(client.get()), SSL_GROUP_X25519);
8158*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_get_negotiated_group(client.get()), NID_X25519);
8159*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_get_peer_signature_algorithm(client.get()),
8160*8fb009dcSAndroid Build Coastguard Worker               SSL_SIGN_RSA_PKCS1_SHA256);
8161*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<X509> peer(SSL_get_peer_certificate(client.get()));
8162*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(peer);
8163*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(X509_cmp(cert.get(), peer.get()), 0);
8164*8fb009dcSAndroid Build Coastguard Worker   };
8165*8fb009dcSAndroid Build Coastguard Worker   check_properties();
8166*8fb009dcSAndroid Build Coastguard Worker 
8167*8fb009dcSAndroid Build Coastguard Worker   // The server sends a HelloRequest.
8168*8fb009dcSAndroid Build Coastguard Worker   ASSERT_NO_FATAL_FAILURE(WriteHelloRequest(server.get()));
8169*8fb009dcSAndroid Build Coastguard Worker 
8170*8fb009dcSAndroid Build Coastguard Worker   // Reading from the client will consume the HelloRequest, start a
8171*8fb009dcSAndroid Build Coastguard Worker   // renegotiation, and then block on a ServerHello from the server.
8172*8fb009dcSAndroid Build Coastguard Worker   uint8_t byte;
8173*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(-1, SSL_read(client.get(), &byte, 1));
8174*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
8175*8fb009dcSAndroid Build Coastguard Worker 
8176*8fb009dcSAndroid Build Coastguard Worker   // Connection properties should continue to report values from the original
8177*8fb009dcSAndroid Build Coastguard Worker   // handshake.
8178*8fb009dcSAndroid Build Coastguard Worker   check_properties();
8179*8fb009dcSAndroid Build Coastguard Worker }
8180*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CopyWithoutEarlyData)8181*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CopyWithoutEarlyData) {
8182*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8183*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(
8184*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method()));
8185*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
8186*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
8187*8fb009dcSAndroid Build Coastguard Worker 
8188*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8189*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
8190*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(client_ctx.get(), 1);
8191*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_early_data_enabled(server_ctx.get(), 1);
8192*8fb009dcSAndroid Build Coastguard Worker 
8193*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session =
8194*8fb009dcSAndroid Build Coastguard Worker       CreateClientSession(client_ctx.get(), server_ctx.get());
8195*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
8196*8fb009dcSAndroid Build Coastguard Worker 
8197*8fb009dcSAndroid Build Coastguard Worker   // The client should attempt early data with |session|.
8198*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
8199*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8200*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
8201*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client.get(), session.get());
8202*8fb009dcSAndroid Build Coastguard Worker   SSL_set_early_data_enabled(client.get(), 1);
8203*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(1, SSL_do_handshake(client.get()));
8204*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_in_early_data(client.get()));
8205*8fb009dcSAndroid Build Coastguard Worker 
8206*8fb009dcSAndroid Build Coastguard Worker   // |SSL_SESSION_copy_without_early_data| should disable early data but
8207*8fb009dcSAndroid Build Coastguard Worker   // still resume the session.
8208*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session2(
8209*8fb009dcSAndroid Build Coastguard Worker       SSL_SESSION_copy_without_early_data(session.get()));
8210*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session2);
8211*8fb009dcSAndroid Build Coastguard Worker   EXPECT_NE(session.get(), session2.get());
8212*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8213*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx.get()));
8214*8fb009dcSAndroid Build Coastguard Worker   SSL_set_session(client.get(), session2.get());
8215*8fb009dcSAndroid Build Coastguard Worker   SSL_set_early_data_enabled(client.get(), 1);
8216*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(CompleteHandshakes(client.get(), server.get()));
8217*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_session_reused(client.get()));
8218*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ssl_early_data_unsupported_for_session,
8219*8fb009dcSAndroid Build Coastguard Worker             SSL_get_early_data_reason(client.get()));
8220*8fb009dcSAndroid Build Coastguard Worker 
8221*8fb009dcSAndroid Build Coastguard Worker   // |SSL_SESSION_copy_without_early_data| should be a reference count increase
8222*8fb009dcSAndroid Build Coastguard Worker   // when passed an early-data-incapable session.
8223*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session3(
8224*8fb009dcSAndroid Build Coastguard Worker       SSL_SESSION_copy_without_early_data(session2.get()));
8225*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(session2.get(), session3.get());
8226*8fb009dcSAndroid Build Coastguard Worker }
8227*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ProcessTLS13NewSessionTicket)8228*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ProcessTLS13NewSessionTicket) {
8229*8fb009dcSAndroid Build Coastguard Worker   // Configure client and server to negotiate TLS 1.3 only.
8230*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8231*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(
8232*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method()));
8233*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
8234*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
8235*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
8236*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(server_ctx.get(), TLS1_3_VERSION));
8237*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
8238*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
8239*8fb009dcSAndroid Build Coastguard Worker 
8240*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
8241*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
8242*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
8243*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(TLS1_3_VERSION, SSL_version(client.get()));
8244*8fb009dcSAndroid Build Coastguard Worker 
8245*8fb009dcSAndroid Build Coastguard Worker   // Process a TLS 1.3 NewSessionTicket.
8246*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kTicket[] = {
8247*8fb009dcSAndroid Build Coastguard Worker       0x04, 0x00, 0x00, 0xb2, 0x00, 0x02, 0xa3, 0x00, 0x04, 0x03, 0x02, 0x01,
8248*8fb009dcSAndroid Build Coastguard Worker       0x01, 0x00, 0x00, 0xa0, 0x01, 0x06, 0x09, 0x11, 0x16, 0x19, 0x21, 0x26,
8249*8fb009dcSAndroid Build Coastguard Worker       0x29, 0x31, 0x36, 0x39, 0x41, 0x46, 0x49, 0x51, 0x03, 0x06, 0x09, 0x13,
8250*8fb009dcSAndroid Build Coastguard Worker       0x16, 0x19, 0x23, 0x26, 0x29, 0x33, 0x36, 0x39, 0x43, 0x46, 0x49, 0x53,
8251*8fb009dcSAndroid Build Coastguard Worker       0xf7, 0x00, 0x29, 0xec, 0xf2, 0xc4, 0xa4, 0x41, 0xfc, 0x30, 0x17, 0x2e,
8252*8fb009dcSAndroid Build Coastguard Worker       0x9f, 0x7c, 0xa8, 0xaf, 0x75, 0x70, 0xf0, 0x1f, 0xc7, 0x98, 0xf7, 0xcf,
8253*8fb009dcSAndroid Build Coastguard Worker       0x5a, 0x5a, 0x6b, 0x5b, 0xfe, 0xf1, 0xe7, 0x3a, 0xe8, 0xf7, 0x6c, 0xd2,
8254*8fb009dcSAndroid Build Coastguard Worker       0xa8, 0xa6, 0x92, 0x5b, 0x96, 0x8d, 0xde, 0xdb, 0xd3, 0x20, 0x6a, 0xcb,
8255*8fb009dcSAndroid Build Coastguard Worker       0x69, 0x06, 0xf4, 0x91, 0x85, 0x2e, 0xe6, 0x5e, 0x0c, 0x59, 0xf2, 0x9e,
8256*8fb009dcSAndroid Build Coastguard Worker       0x9b, 0x79, 0x91, 0x24, 0x7e, 0x4a, 0x32, 0x3d, 0xbe, 0x4b, 0x80, 0x70,
8257*8fb009dcSAndroid Build Coastguard Worker       0xaf, 0xd0, 0x1d, 0xe2, 0xca, 0x05, 0x35, 0x09, 0x09, 0x05, 0x0f, 0xbb,
8258*8fb009dcSAndroid Build Coastguard Worker       0xc4, 0xae, 0xd7, 0xc4, 0xed, 0xd7, 0xae, 0x35, 0xc8, 0x73, 0x63, 0x78,
8259*8fb009dcSAndroid Build Coastguard Worker       0x64, 0xc9, 0x7a, 0x1f, 0xed, 0x7a, 0x9a, 0x47, 0x44, 0xfd, 0x50, 0xf7,
8260*8fb009dcSAndroid Build Coastguard Worker       0xb7, 0xe0, 0x64, 0xa9, 0x02, 0xc1, 0x5c, 0x23, 0x18, 0x3f, 0xc4, 0xcf,
8261*8fb009dcSAndroid Build Coastguard Worker       0x72, 0x02, 0x59, 0x2d, 0xe1, 0xaa, 0x61, 0x72, 0x00, 0x04, 0x5a, 0x5a,
8262*8fb009dcSAndroid Build Coastguard Worker       0x00, 0x00,
8263*8fb009dcSAndroid Build Coastguard Worker   };
8264*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_SESSION> session(SSL_process_tls13_new_session_ticket(
8265*8fb009dcSAndroid Build Coastguard Worker       client.get(), kTicket, sizeof(kTicket)));
8266*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session);
8267*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_SESSION_has_ticket(session.get()));
8268*8fb009dcSAndroid Build Coastguard Worker 
8269*8fb009dcSAndroid Build Coastguard Worker   uint8_t *session_buf = nullptr;
8270*8fb009dcSAndroid Build Coastguard Worker   size_t session_length = 0;
8271*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(
8272*8fb009dcSAndroid Build Coastguard Worker       SSL_SESSION_to_bytes(session.get(), &session_buf, &session_length));
8273*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<uint8_t> session_buf_free(session_buf);
8274*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(session_buf);
8275*8fb009dcSAndroid Build Coastguard Worker   ASSERT_GT(session_length, 0u);
8276*8fb009dcSAndroid Build Coastguard Worker 
8277*8fb009dcSAndroid Build Coastguard Worker   // Servers cannot call |SSL_process_tls13_new_session_ticket|.
8278*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_process_tls13_new_session_ticket(server.get(), kTicket,
8279*8fb009dcSAndroid Build Coastguard Worker                                                     sizeof(kTicket)));
8280*8fb009dcSAndroid Build Coastguard Worker 
8281*8fb009dcSAndroid Build Coastguard Worker   // Clients cannot call |SSL_process_tls13_new_session_ticket| before the
8282*8fb009dcSAndroid Build Coastguard Worker   // handshake completes.
8283*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client2(SSL_new(client_ctx.get()));
8284*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client2);
8285*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(client2.get());
8286*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_process_tls13_new_session_ticket(client2.get(), kTicket,
8287*8fb009dcSAndroid Build Coastguard Worker                                                     sizeof(kTicket)));
8288*8fb009dcSAndroid Build Coastguard Worker }
8289*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,BIO)8290*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, BIO) {
8291*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8292*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(
8293*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method()));
8294*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
8295*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
8296*8fb009dcSAndroid Build Coastguard Worker 
8297*8fb009dcSAndroid Build Coastguard Worker   for (bool take_ownership : {true, false}) {
8298*8fb009dcSAndroid Build Coastguard Worker     // For simplicity, get the handshake out of the way first.
8299*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8300*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
8301*8fb009dcSAndroid Build Coastguard Worker                                        server_ctx.get()));
8302*8fb009dcSAndroid Build Coastguard Worker 
8303*8fb009dcSAndroid Build Coastguard Worker     // Wrap |client| in an SSL BIO.
8304*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<BIO> client_bio(BIO_new(BIO_f_ssl()));
8305*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(client_bio);
8306*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(1, BIO_set_ssl(client_bio.get(), client.get(), take_ownership));
8307*8fb009dcSAndroid Build Coastguard Worker     if (take_ownership) {
8308*8fb009dcSAndroid Build Coastguard Worker       client.release();
8309*8fb009dcSAndroid Build Coastguard Worker     }
8310*8fb009dcSAndroid Build Coastguard Worker 
8311*8fb009dcSAndroid Build Coastguard Worker     // Flushing the BIO should not crash.
8312*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(1, BIO_flush(client_bio.get()));
8313*8fb009dcSAndroid Build Coastguard Worker 
8314*8fb009dcSAndroid Build Coastguard Worker     // Exchange some data.
8315*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(5, BIO_write(client_bio.get(), "hello", 5));
8316*8fb009dcSAndroid Build Coastguard Worker     uint8_t buf[5];
8317*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(5, SSL_read(server.get(), buf, sizeof(buf)));
8318*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes("hello"), Bytes(buf));
8319*8fb009dcSAndroid Build Coastguard Worker 
8320*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(5, SSL_write(server.get(), "world", 5));
8321*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(5, BIO_read(client_bio.get(), buf, sizeof(buf)));
8322*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes("world"), Bytes(buf));
8323*8fb009dcSAndroid Build Coastguard Worker 
8324*8fb009dcSAndroid Build Coastguard Worker     // |BIO_should_read| should work.
8325*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(-1, BIO_read(client_bio.get(), buf, sizeof(buf)));
8326*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(BIO_should_read(client_bio.get()));
8327*8fb009dcSAndroid Build Coastguard Worker 
8328*8fb009dcSAndroid Build Coastguard Worker     // Writing data should eventually exceed the buffer size and fail, reporting
8329*8fb009dcSAndroid Build Coastguard Worker     // |BIO_should_write|.
8330*8fb009dcSAndroid Build Coastguard Worker     int ret;
8331*8fb009dcSAndroid Build Coastguard Worker     for (int i = 0; i < 1024; i++) {
8332*8fb009dcSAndroid Build Coastguard Worker       const uint8_t kZeros[1024] = {0};
8333*8fb009dcSAndroid Build Coastguard Worker       ret = BIO_write(client_bio.get(), kZeros, sizeof(kZeros));
8334*8fb009dcSAndroid Build Coastguard Worker       if (ret <= 0) {
8335*8fb009dcSAndroid Build Coastguard Worker         break;
8336*8fb009dcSAndroid Build Coastguard Worker       }
8337*8fb009dcSAndroid Build Coastguard Worker     }
8338*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(-1, ret);
8339*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(BIO_should_write(client_bio.get()));
8340*8fb009dcSAndroid Build Coastguard Worker   }
8341*8fb009dcSAndroid Build Coastguard Worker }
8342*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,ALPNConfig)8343*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ALPNConfig) {
8344*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8345*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
8346*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetTestCertificate();
8347*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8348*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
8349*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
8350*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
8351*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx.get(), key.get()));
8352*8fb009dcSAndroid Build Coastguard Worker 
8353*8fb009dcSAndroid Build Coastguard Worker   // Set up some machinery to check the configured ALPN against what is actually
8354*8fb009dcSAndroid Build Coastguard Worker   // sent over the wire. Note that the ALPN callback is only called when the
8355*8fb009dcSAndroid Build Coastguard Worker   // client offers ALPN.
8356*8fb009dcSAndroid Build Coastguard Worker   std::vector<uint8_t> observed_alpn;
8357*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_alpn_select_cb(
8358*8fb009dcSAndroid Build Coastguard Worker       ctx.get(),
8359*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
8360*8fb009dcSAndroid Build Coastguard Worker          unsigned in_len, void *arg) -> int {
8361*8fb009dcSAndroid Build Coastguard Worker         std::vector<uint8_t> *observed_alpn_ptr =
8362*8fb009dcSAndroid Build Coastguard Worker             static_cast<std::vector<uint8_t> *>(arg);
8363*8fb009dcSAndroid Build Coastguard Worker         observed_alpn_ptr->assign(in, in + in_len);
8364*8fb009dcSAndroid Build Coastguard Worker         return SSL_TLSEXT_ERR_NOACK;
8365*8fb009dcSAndroid Build Coastguard Worker       },
8366*8fb009dcSAndroid Build Coastguard Worker       &observed_alpn);
8367*8fb009dcSAndroid Build Coastguard Worker   auto check_alpn_proto = [&](Span<const uint8_t> expected) {
8368*8fb009dcSAndroid Build Coastguard Worker     observed_alpn.clear();
8369*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8370*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(ConnectClientAndServer(&client, &server, ctx.get(), ctx.get()));
8371*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes(expected), Bytes(observed_alpn));
8372*8fb009dcSAndroid Build Coastguard Worker   };
8373*8fb009dcSAndroid Build Coastguard Worker 
8374*8fb009dcSAndroid Build Coastguard Worker   // Note that |SSL_CTX_set_alpn_protos|'s return value is reversed.
8375*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kValidList[] = {0x03, 'f', 'o', 'o',
8376*8fb009dcSAndroid Build Coastguard Worker                                        0x03, 'b', 'a', 'r'};
8377*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0,
8378*8fb009dcSAndroid Build Coastguard Worker             SSL_CTX_set_alpn_protos(ctx.get(), kValidList, sizeof(kValidList)));
8379*8fb009dcSAndroid Build Coastguard Worker   check_alpn_proto(kValidList);
8380*8fb009dcSAndroid Build Coastguard Worker 
8381*8fb009dcSAndroid Build Coastguard Worker   // Invalid lists are rejected.
8382*8fb009dcSAndroid Build Coastguard Worker   static const uint8_t kInvalidList[] = {0x04, 'f', 'o', 'o'};
8383*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(1, SSL_CTX_set_alpn_protos(ctx.get(), kInvalidList,
8384*8fb009dcSAndroid Build Coastguard Worker                                        sizeof(kInvalidList)));
8385*8fb009dcSAndroid Build Coastguard Worker 
8386*8fb009dcSAndroid Build Coastguard Worker   // Empty lists are valid and are interpreted as disabling ALPN.
8387*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(0, SSL_CTX_set_alpn_protos(ctx.get(), nullptr, 0));
8388*8fb009dcSAndroid Build Coastguard Worker   check_alpn_proto({});
8389*8fb009dcSAndroid Build Coastguard Worker }
8390*8fb009dcSAndroid Build Coastguard Worker 
8391*8fb009dcSAndroid Build Coastguard Worker // This is a basic unit-test class to verify completing handshake successfully,
8392*8fb009dcSAndroid Build Coastguard Worker // sending the correct codepoint extension and having correct application
8393*8fb009dcSAndroid Build Coastguard Worker // setting on different combination of ALPS codepoint settings. More integration
8394*8fb009dcSAndroid Build Coastguard Worker // tests on runner.go.
8395*8fb009dcSAndroid Build Coastguard Worker class AlpsNewCodepointTest : public testing::Test {
8396*8fb009dcSAndroid Build Coastguard Worker  protected:
SetUp()8397*8fb009dcSAndroid Build Coastguard Worker   void SetUp() override {
8398*8fb009dcSAndroid Build Coastguard Worker     client_ctx_.reset(SSL_CTX_new(TLS_method()));
8399*8fb009dcSAndroid Build Coastguard Worker     server_ctx_ = CreateContextWithTestCertificate(TLS_method());
8400*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(client_ctx_);
8401*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx_);
8402*8fb009dcSAndroid Build Coastguard Worker   }
8403*8fb009dcSAndroid Build Coastguard Worker 
SetUpApplicationSetting()8404*8fb009dcSAndroid Build Coastguard Worker   void SetUpApplicationSetting() {
8405*8fb009dcSAndroid Build Coastguard Worker     static const uint8_t alpn[] = {0x03, 'f', 'o', 'o'};
8406*8fb009dcSAndroid Build Coastguard Worker     static const uint8_t proto[] = {'f', 'o', 'o'};
8407*8fb009dcSAndroid Build Coastguard Worker     static const uint8_t alps[] = {0x04, 'a', 'l', 'p', 's'};
8408*8fb009dcSAndroid Build Coastguard Worker     // SSL_set_alpn_protos's return value is backwards. It returns zero on
8409*8fb009dcSAndroid Build Coastguard Worker     // success and one on failure.
8410*8fb009dcSAndroid Build Coastguard Worker     ASSERT_FALSE(SSL_set_alpn_protos(client_.get(), alpn, sizeof(alpn)));
8411*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_alpn_select_cb(
8412*8fb009dcSAndroid Build Coastguard Worker       server_ctx_.get(),
8413*8fb009dcSAndroid Build Coastguard Worker       [](SSL *ssl, const uint8_t **out, uint8_t *out_len, const uint8_t *in,
8414*8fb009dcSAndroid Build Coastguard Worker           unsigned in_len, void *arg) -> int {
8415*8fb009dcSAndroid Build Coastguard Worker         return SSL_select_next_proto(
8416*8fb009dcSAndroid Build Coastguard Worker                     const_cast<uint8_t **>(out), out_len, in, in_len,
8417*8fb009dcSAndroid Build Coastguard Worker                     alpn, sizeof(alpn)) == OPENSSL_NPN_NEGOTIATED
8418*8fb009dcSAndroid Build Coastguard Worker                     ? SSL_TLSEXT_ERR_OK
8419*8fb009dcSAndroid Build Coastguard Worker                     : SSL_TLSEXT_ERR_NOACK;
8420*8fb009dcSAndroid Build Coastguard Worker       },
8421*8fb009dcSAndroid Build Coastguard Worker       nullptr);
8422*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_add_application_settings(client_.get(), proto,
8423*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(proto), nullptr, 0));
8424*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_add_application_settings(server_.get(), proto,
8425*8fb009dcSAndroid Build Coastguard Worker                                             sizeof(proto), alps, sizeof(alps)));
8426*8fb009dcSAndroid Build Coastguard Worker   }
8427*8fb009dcSAndroid Build Coastguard Worker 
8428*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx_;
8429*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx_;
8430*8fb009dcSAndroid Build Coastguard Worker 
8431*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client_;
8432*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> server_;
8433*8fb009dcSAndroid Build Coastguard Worker };
8434*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(AlpsNewCodepointTest,Enabled)8435*8fb009dcSAndroid Build Coastguard Worker TEST_F(AlpsNewCodepointTest, Enabled) {
8436*8fb009dcSAndroid Build Coastguard Worker   SetUpExpectedNewCodePoint(server_ctx_.get());
8437*8fb009dcSAndroid Build Coastguard Worker 
8438*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8439*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx_.get()));
8440*8fb009dcSAndroid Build Coastguard Worker 
8441*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(client_.get(), 1);
8442*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(server_.get(), 1);
8443*8fb009dcSAndroid Build Coastguard Worker 
8444*8fb009dcSAndroid Build Coastguard Worker   SetUpApplicationSetting();
8445*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8446*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_has_application_settings(client_.get()));
8447*8fb009dcSAndroid Build Coastguard Worker }
8448*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(AlpsNewCodepointTest,Disabled)8449*8fb009dcSAndroid Build Coastguard Worker TEST_F(AlpsNewCodepointTest, Disabled) {
8450*8fb009dcSAndroid Build Coastguard Worker   // Both client and server disable alps new codepoint.
8451*8fb009dcSAndroid Build Coastguard Worker   SetUpExpectedOldCodePoint(server_ctx_.get());
8452*8fb009dcSAndroid Build Coastguard Worker 
8453*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8454*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx_.get()));
8455*8fb009dcSAndroid Build Coastguard Worker 
8456*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(client_.get(), 0);
8457*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(server_.get(), 0);
8458*8fb009dcSAndroid Build Coastguard Worker 
8459*8fb009dcSAndroid Build Coastguard Worker   SetUpApplicationSetting();
8460*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8461*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_has_application_settings(client_.get()));
8462*8fb009dcSAndroid Build Coastguard Worker }
8463*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(AlpsNewCodepointTest,ClientOnly)8464*8fb009dcSAndroid Build Coastguard Worker TEST_F(AlpsNewCodepointTest, ClientOnly) {
8465*8fb009dcSAndroid Build Coastguard Worker   // If client set new codepoint but server doesn't set, server ignores it.
8466*8fb009dcSAndroid Build Coastguard Worker   SetUpExpectedNewCodePoint(server_ctx_.get());
8467*8fb009dcSAndroid Build Coastguard Worker 
8468*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8469*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx_.get()));
8470*8fb009dcSAndroid Build Coastguard Worker 
8471*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(client_.get(), 1);
8472*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(server_.get(), 0);
8473*8fb009dcSAndroid Build Coastguard Worker 
8474*8fb009dcSAndroid Build Coastguard Worker   SetUpApplicationSetting();
8475*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8476*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_has_application_settings(client_.get()));
8477*8fb009dcSAndroid Build Coastguard Worker }
8478*8fb009dcSAndroid Build Coastguard Worker 
TEST_F(AlpsNewCodepointTest,ServerOnly)8479*8fb009dcSAndroid Build Coastguard Worker TEST_F(AlpsNewCodepointTest, ServerOnly) {
8480*8fb009dcSAndroid Build Coastguard Worker   // If client doesn't set new codepoint, while server set.
8481*8fb009dcSAndroid Build Coastguard Worker   SetUpExpectedOldCodePoint(server_ctx_.get());
8482*8fb009dcSAndroid Build Coastguard Worker 
8483*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CreateClientAndServer(&client_, &server_, client_ctx_.get(),
8484*8fb009dcSAndroid Build Coastguard Worker                                     server_ctx_.get()));
8485*8fb009dcSAndroid Build Coastguard Worker 
8486*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(client_.get(), 0);
8487*8fb009dcSAndroid Build Coastguard Worker   SSL_set_alps_use_new_codepoint(server_.get(), 1);
8488*8fb009dcSAndroid Build Coastguard Worker 
8489*8fb009dcSAndroid Build Coastguard Worker   SetUpApplicationSetting();
8490*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client_.get(), server_.get()));
8491*8fb009dcSAndroid Build Coastguard Worker   ASSERT_FALSE(SSL_has_application_settings(client_.get()));
8492*8fb009dcSAndroid Build Coastguard Worker }
8493*8fb009dcSAndroid Build Coastguard Worker 
8494*8fb009dcSAndroid Build Coastguard Worker // Test that the key usage checker can correctly handle issuerUID and
8495*8fb009dcSAndroid Build Coastguard Worker // subjectUID. See https://crbug.com/1199744.
TEST(SSLTest,KeyUsageWithUIDs)8496*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, KeyUsageWithUIDs) {
8497*8fb009dcSAndroid Build Coastguard Worker   static const char kGoodKeyUsage[] = R"(
8498*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
8499*8fb009dcSAndroid Build Coastguard Worker MIIB7DCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
8500*8fb009dcSAndroid Build Coastguard Worker AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
8501*8fb009dcSAndroid Build Coastguard Worker aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
8502*8fb009dcSAndroid Build Coastguard Worker CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
8503*8fb009dcSAndroid Build Coastguard Worker ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
8504*8fb009dcSAndroid Build Coastguard Worker 4r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
8505*8fb009dcSAndroid Build Coastguard Worker Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
8506*8fb009dcSAndroid Build Coastguard Worker ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
8507*8fb009dcSAndroid Build Coastguard Worker A1UdDwEB/wQEAwIHgDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0cAMEQCIEWJ
8508*8fb009dcSAndroid Build Coastguard Worker 34EcqW5MHwLIA1hZ2Tj/jV2QjN02KLxis9mFsqDKAiAMlMTkzsM51vVs9Ohqa+Rc
8509*8fb009dcSAndroid Build Coastguard Worker 4Z7qDhjIhiF4dM0uEDYRVA==
8510*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
8511*8fb009dcSAndroid Build Coastguard Worker )";
8512*8fb009dcSAndroid Build Coastguard Worker   static const char kBadKeyUsage[] = R"(
8513*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
8514*8fb009dcSAndroid Build Coastguard Worker MIIB7jCCAZOgAwIBAgIJANlMBNpJfb/rMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT
8515*8fb009dcSAndroid Build Coastguard Worker AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
8516*8fb009dcSAndroid Build Coastguard Worker aXRzIFB0eSBMdGQwHhcNMTQwNDIzMjMyMTU3WhcNMTQwNTIzMjMyMTU3WjBFMQsw
8517*8fb009dcSAndroid Build Coastguard Worker CQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJu
8518*8fb009dcSAndroid Build Coastguard Worker ZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE5itp
8519*8fb009dcSAndroid Build Coastguard Worker 4r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aXqAoY+cPEox5W4nyDSNsW
8520*8fb009dcSAndroid Build Coastguard Worker Ghz1HX7xlC1Lz3IiwYEEABI0VoIEABI0VqNgMF4wHQYDVR0OBBYEFKuE0qyrlfCC
8521*8fb009dcSAndroid Build Coastguard Worker ThZ4B1VXX+QmjYLRMB8GA1UdIwQYMBaAFKuE0qyrlfCCThZ4B1VXX+QmjYLRMA4G
8522*8fb009dcSAndroid Build Coastguard Worker A1UdDwEB/wQEAwIDCDAMBgNVHRMEBTADAQH/MAoGCCqGSM49BAMCA0kAMEYCIQC6
8523*8fb009dcSAndroid Build Coastguard Worker taYBUDu2gcZC6EMk79FBHArYI0ucF+kzvETegZCbBAIhANtObFec5gtso/47moPD
8524*8fb009dcSAndroid Build Coastguard Worker RHrQbWsFUakETXL9QMlegh5t
8525*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
8526*8fb009dcSAndroid Build Coastguard Worker )";
8527*8fb009dcSAndroid Build Coastguard Worker 
8528*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> good = CertFromPEM(kGoodKeyUsage);
8529*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(good);
8530*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> bad = CertFromPEM(kBadKeyUsage);
8531*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bad);
8532*8fb009dcSAndroid Build Coastguard Worker 
8533*8fb009dcSAndroid Build Coastguard Worker   // We check key usage when configuring EC certificates to distinguish ECDSA
8534*8fb009dcSAndroid Build Coastguard Worker   // and ECDH.
8535*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8536*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
8537*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_CTX_use_certificate(ctx.get(), good.get()));
8538*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_use_certificate(ctx.get(), bad.get()));
8539*8fb009dcSAndroid Build Coastguard Worker }
8540*8fb009dcSAndroid Build Coastguard Worker 
8541*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_can_release_private_key| reports true as early as expected.
8542*8fb009dcSAndroid Build Coastguard Worker // The internal asserts in the library check we do not report true too early.
TEST(SSLTest,CanReleasePrivateKey)8543*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CanReleasePrivateKey) {
8544*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx =
8545*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
8546*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
8547*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8548*8fb009dcSAndroid Build Coastguard Worker 
8549*8fb009dcSAndroid Build Coastguard Worker   // Note this assumes the transport buffer is large enough to fit the client
8550*8fb009dcSAndroid Build Coastguard Worker   // and server first flights. We check this with |SSL_ERROR_WANT_READ|. If the
8551*8fb009dcSAndroid Build Coastguard Worker   // transport buffer was too small it would return |SSL_ERROR_WANT_WRITE|.
8552*8fb009dcSAndroid Build Coastguard Worker   auto check_first_server_round_trip = [&](SSL *client, SSL *server) {
8553*8fb009dcSAndroid Build Coastguard Worker     // Write the ClientHello.
8554*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(-1, SSL_do_handshake(client));
8555*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client, -1));
8556*8fb009dcSAndroid Build Coastguard Worker 
8557*8fb009dcSAndroid Build Coastguard Worker     // Consume the ClientHello and write the server flight.
8558*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(-1, SSL_do_handshake(server));
8559*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(server, -1));
8560*8fb009dcSAndroid Build Coastguard Worker 
8561*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_can_release_private_key(server));
8562*8fb009dcSAndroid Build Coastguard Worker   };
8563*8fb009dcSAndroid Build Coastguard Worker 
8564*8fb009dcSAndroid Build Coastguard Worker   {
8565*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE("TLS 1.2 ECDHE");
8566*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> server_ctx(
8567*8fb009dcSAndroid Build Coastguard Worker         CreateContextWithTestCertificate(TLS_method()));
8568*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx);
8569*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(
8570*8fb009dcSAndroid Build Coastguard Worker         SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
8571*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set_strict_cipher_list(
8572*8fb009dcSAndroid Build Coastguard Worker         server_ctx.get(), "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"));
8573*8fb009dcSAndroid Build Coastguard Worker     // Configure the server to request client certificates, so we can also test
8574*8fb009dcSAndroid Build Coastguard Worker     // the client half.
8575*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX_set_custom_verify(
8576*8fb009dcSAndroid Build Coastguard Worker         server_ctx.get(), SSL_VERIFY_PEER,
8577*8fb009dcSAndroid Build Coastguard Worker         [](SSL *ssl, uint8_t *out_alert) { return ssl_verify_ok; });
8578*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8579*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8580*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx.get()));
8581*8fb009dcSAndroid Build Coastguard Worker     check_first_server_round_trip(client.get(), server.get());
8582*8fb009dcSAndroid Build Coastguard Worker 
8583*8fb009dcSAndroid Build Coastguard Worker     // Consume the server flight and write the client response. The client still
8584*8fb009dcSAndroid Build Coastguard Worker     // has a Finished message to consume but can also release its key early.
8585*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(-1, SSL_do_handshake(client.get()));
8586*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
8587*8fb009dcSAndroid Build Coastguard Worker     EXPECT_TRUE(SSL_can_release_private_key(client.get()));
8588*8fb009dcSAndroid Build Coastguard Worker 
8589*8fb009dcSAndroid Build Coastguard Worker     // However, a client that has not disabled renegotiation can never release
8590*8fb009dcSAndroid Build Coastguard Worker     // the key.
8591*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8592*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx.get()));
8593*8fb009dcSAndroid Build Coastguard Worker     SSL_set_renegotiate_mode(client.get(), ssl_renegotiate_freely);
8594*8fb009dcSAndroid Build Coastguard Worker     check_first_server_round_trip(client.get(), server.get());
8595*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(-1, SSL_do_handshake(client.get()));
8596*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_ERROR_WANT_READ, SSL_get_error(client.get(), -1));
8597*8fb009dcSAndroid Build Coastguard Worker     EXPECT_FALSE(SSL_can_release_private_key(client.get()));
8598*8fb009dcSAndroid Build Coastguard Worker   }
8599*8fb009dcSAndroid Build Coastguard Worker 
8600*8fb009dcSAndroid Build Coastguard Worker   {
8601*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE("TLS 1.2 resumption");
8602*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> server_ctx(
8603*8fb009dcSAndroid Build Coastguard Worker         CreateContextWithTestCertificate(TLS_method()));
8604*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx);
8605*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(
8606*8fb009dcSAndroid Build Coastguard Worker         SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_2_VERSION));
8607*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session =
8608*8fb009dcSAndroid Build Coastguard Worker         CreateClientSession(client_ctx.get(), server_ctx.get());
8609*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session);
8610*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8611*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8612*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx.get()));
8613*8fb009dcSAndroid Build Coastguard Worker     SSL_set_session(client.get(), session.get());
8614*8fb009dcSAndroid Build Coastguard Worker     check_first_server_round_trip(client.get(), server.get());
8615*8fb009dcSAndroid Build Coastguard Worker   }
8616*8fb009dcSAndroid Build Coastguard Worker 
8617*8fb009dcSAndroid Build Coastguard Worker   {
8618*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE("TLS 1.3 1-RTT");
8619*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> server_ctx(
8620*8fb009dcSAndroid Build Coastguard Worker         CreateContextWithTestCertificate(TLS_method()));
8621*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx);
8622*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(
8623*8fb009dcSAndroid Build Coastguard Worker         SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
8624*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8625*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8626*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx.get()));
8627*8fb009dcSAndroid Build Coastguard Worker     check_first_server_round_trip(client.get(), server.get());
8628*8fb009dcSAndroid Build Coastguard Worker   }
8629*8fb009dcSAndroid Build Coastguard Worker 
8630*8fb009dcSAndroid Build Coastguard Worker   {
8631*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE("TLS 1.3 resumption");
8632*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> server_ctx(
8633*8fb009dcSAndroid Build Coastguard Worker         CreateContextWithTestCertificate(TLS_method()));
8634*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx);
8635*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(
8636*8fb009dcSAndroid Build Coastguard Worker         SSL_CTX_set_max_proto_version(server_ctx.get(), TLS1_3_VERSION));
8637*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_SESSION> session =
8638*8fb009dcSAndroid Build Coastguard Worker         CreateClientSession(client_ctx.get(), server_ctx.get());
8639*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(session);
8640*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8641*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(CreateClientAndServer(&client, &server, client_ctx.get(),
8642*8fb009dcSAndroid Build Coastguard Worker                                       server_ctx.get()));
8643*8fb009dcSAndroid Build Coastguard Worker     SSL_set_session(client.get(), session.get());
8644*8fb009dcSAndroid Build Coastguard Worker     check_first_server_round_trip(client.get(), server.get());
8645*8fb009dcSAndroid Build Coastguard Worker   }
8646*8fb009dcSAndroid Build Coastguard Worker }
8647*8fb009dcSAndroid Build Coastguard Worker 
8648*8fb009dcSAndroid Build Coastguard Worker // GetExtensionOrder sets |*out| to the list of extensions a client attached to
8649*8fb009dcSAndroid Build Coastguard Worker // |ctx| will send in the ClientHello. If |ech_keys| is non-null, the client
8650*8fb009dcSAndroid Build Coastguard Worker // will offer ECH with the public component. If |decrypt_ech| is true, |*out|
8651*8fb009dcSAndroid Build Coastguard Worker // will be set to the ClientHelloInner's extensions, rather than
8652*8fb009dcSAndroid Build Coastguard Worker // ClientHelloOuter.
GetExtensionOrder(SSL_CTX * client_ctx,std::vector<uint16_t> * out,SSL_ECH_KEYS * ech_keys,bool decrypt_ech)8653*8fb009dcSAndroid Build Coastguard Worker static bool GetExtensionOrder(SSL_CTX *client_ctx, std::vector<uint16_t> *out,
8654*8fb009dcSAndroid Build Coastguard Worker                               SSL_ECH_KEYS *ech_keys, bool decrypt_ech) {
8655*8fb009dcSAndroid Build Coastguard Worker   struct AppData {
8656*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint16_t> *out;
8657*8fb009dcSAndroid Build Coastguard Worker     bool decrypt_ech;
8658*8fb009dcSAndroid Build Coastguard Worker     bool callback_done = false;
8659*8fb009dcSAndroid Build Coastguard Worker   };
8660*8fb009dcSAndroid Build Coastguard Worker   AppData app_data;
8661*8fb009dcSAndroid Build Coastguard Worker   app_data.out = out;
8662*8fb009dcSAndroid Build Coastguard Worker   app_data.decrypt_ech = decrypt_ech;
8663*8fb009dcSAndroid Build Coastguard Worker 
8664*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
8665*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
8666*8fb009dcSAndroid Build Coastguard Worker   if (!server_ctx ||  //
8667*8fb009dcSAndroid Build Coastguard Worker       !SSL_CTX_set_app_data(server_ctx.get(), &app_data) ||
8668*8fb009dcSAndroid Build Coastguard Worker       (decrypt_ech && !SSL_CTX_set1_ech_keys(server_ctx.get(), ech_keys))) {
8669*8fb009dcSAndroid Build Coastguard Worker     return false;
8670*8fb009dcSAndroid Build Coastguard Worker   }
8671*8fb009dcSAndroid Build Coastguard Worker 
8672*8fb009dcSAndroid Build Coastguard Worker   // Configure the server to record the ClientHello extension order. We use a
8673*8fb009dcSAndroid Build Coastguard Worker   // server rather than |GetClientHello| so it can decrypt ClientHelloInner.
8674*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_select_certificate_cb(
8675*8fb009dcSAndroid Build Coastguard Worker       server_ctx.get(),
8676*8fb009dcSAndroid Build Coastguard Worker       [](const SSL_CLIENT_HELLO *client_hello) -> ssl_select_cert_result_t {
8677*8fb009dcSAndroid Build Coastguard Worker         AppData *app_data_ptr = static_cast<AppData *>(
8678*8fb009dcSAndroid Build Coastguard Worker             SSL_CTX_get_app_data(SSL_get_SSL_CTX(client_hello->ssl)));
8679*8fb009dcSAndroid Build Coastguard Worker         EXPECT_EQ(app_data_ptr->decrypt_ech ? 1 : 0,
8680*8fb009dcSAndroid Build Coastguard Worker                   SSL_ech_accepted(client_hello->ssl));
8681*8fb009dcSAndroid Build Coastguard Worker 
8682*8fb009dcSAndroid Build Coastguard Worker         app_data_ptr->out->clear();
8683*8fb009dcSAndroid Build Coastguard Worker         CBS extensions;
8684*8fb009dcSAndroid Build Coastguard Worker         CBS_init(&extensions, client_hello->extensions,
8685*8fb009dcSAndroid Build Coastguard Worker                  client_hello->extensions_len);
8686*8fb009dcSAndroid Build Coastguard Worker         while (CBS_len(&extensions)) {
8687*8fb009dcSAndroid Build Coastguard Worker           uint16_t type;
8688*8fb009dcSAndroid Build Coastguard Worker           CBS body;
8689*8fb009dcSAndroid Build Coastguard Worker           if (!CBS_get_u16(&extensions, &type) ||
8690*8fb009dcSAndroid Build Coastguard Worker               !CBS_get_u16_length_prefixed(&extensions, &body)) {
8691*8fb009dcSAndroid Build Coastguard Worker             return ssl_select_cert_error;
8692*8fb009dcSAndroid Build Coastguard Worker           }
8693*8fb009dcSAndroid Build Coastguard Worker           app_data_ptr->out->push_back(type);
8694*8fb009dcSAndroid Build Coastguard Worker         }
8695*8fb009dcSAndroid Build Coastguard Worker 
8696*8fb009dcSAndroid Build Coastguard Worker         // Don't bother completing the handshake.
8697*8fb009dcSAndroid Build Coastguard Worker         app_data_ptr->callback_done = true;
8698*8fb009dcSAndroid Build Coastguard Worker         return ssl_select_cert_error;
8699*8fb009dcSAndroid Build Coastguard Worker       });
8700*8fb009dcSAndroid Build Coastguard Worker 
8701*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
8702*8fb009dcSAndroid Build Coastguard Worker   if (!CreateClientAndServer(&client, &server, client_ctx, server_ctx.get()) ||
8703*8fb009dcSAndroid Build Coastguard Worker       (ech_keys != nullptr && !InstallECHConfigList(client.get(), ech_keys))) {
8704*8fb009dcSAndroid Build Coastguard Worker     return false;
8705*8fb009dcSAndroid Build Coastguard Worker   }
8706*8fb009dcSAndroid Build Coastguard Worker 
8707*8fb009dcSAndroid Build Coastguard Worker   // Run the handshake far enough to process the ClientHello.
8708*8fb009dcSAndroid Build Coastguard Worker   SSL_do_handshake(client.get());
8709*8fb009dcSAndroid Build Coastguard Worker   SSL_do_handshake(server.get());
8710*8fb009dcSAndroid Build Coastguard Worker   return app_data.callback_done;
8711*8fb009dcSAndroid Build Coastguard Worker }
8712*8fb009dcSAndroid Build Coastguard Worker 
8713*8fb009dcSAndroid Build Coastguard Worker // Test that, when extension permutation is enabled, the ClientHello extension
8714*8fb009dcSAndroid Build Coastguard Worker // order changes, both with and without ECH, and in both ClientHelloInner and
8715*8fb009dcSAndroid Build Coastguard Worker // ClientHelloOuter.
TEST(SSLTest,PermuteExtensions)8716*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, PermuteExtensions) {
8717*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_ECH_KEYS> keys = MakeTestECHKeys();
8718*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(keys);
8719*8fb009dcSAndroid Build Coastguard Worker   for (bool offer_ech : {false, true}) {
8720*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(offer_ech);
8721*8fb009dcSAndroid Build Coastguard Worker     SSL_ECH_KEYS *maybe_keys = offer_ech ? keys.get() : nullptr;
8722*8fb009dcSAndroid Build Coastguard Worker     for (bool decrypt_ech : {false, true}) {
8723*8fb009dcSAndroid Build Coastguard Worker       SCOPED_TRACE(decrypt_ech);
8724*8fb009dcSAndroid Build Coastguard Worker       if (!offer_ech && decrypt_ech) {
8725*8fb009dcSAndroid Build Coastguard Worker         continue;
8726*8fb009dcSAndroid Build Coastguard Worker       }
8727*8fb009dcSAndroid Build Coastguard Worker 
8728*8fb009dcSAndroid Build Coastguard Worker       // When extension permutation is disabled, the order should be consistent.
8729*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
8730*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ctx);
8731*8fb009dcSAndroid Build Coastguard Worker       std::vector<uint16_t> order1, order2;
8732*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(
8733*8fb009dcSAndroid Build Coastguard Worker           GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
8734*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(
8735*8fb009dcSAndroid Build Coastguard Worker           GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
8736*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(order1, order2);
8737*8fb009dcSAndroid Build Coastguard Worker 
8738*8fb009dcSAndroid Build Coastguard Worker       ctx.reset(SSL_CTX_new(TLS_method()));
8739*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(ctx);
8740*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX_set_permute_extensions(ctx.get(), 1);
8741*8fb009dcSAndroid Build Coastguard Worker 
8742*8fb009dcSAndroid Build Coastguard Worker       // When extension permutation is enabled, each ClientHello should have a
8743*8fb009dcSAndroid Build Coastguard Worker       // different order.
8744*8fb009dcSAndroid Build Coastguard Worker       //
8745*8fb009dcSAndroid Build Coastguard Worker       // This test is inherently flaky, so we run it multiple times. We send at
8746*8fb009dcSAndroid Build Coastguard Worker       // least five extensions by default from TLS 1.3: supported_versions,
8747*8fb009dcSAndroid Build Coastguard Worker       // key_share, supported_groups, psk_key_exchange_modes, and
8748*8fb009dcSAndroid Build Coastguard Worker       // signature_algorithms. That means the probability of a false negative is
8749*8fb009dcSAndroid Build Coastguard Worker       // at most 1/120. Repeating the test 14 times lowers false negative rate
8750*8fb009dcSAndroid Build Coastguard Worker       // to under 2^-96.
8751*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(
8752*8fb009dcSAndroid Build Coastguard Worker           GetExtensionOrder(ctx.get(), &order1, maybe_keys, decrypt_ech));
8753*8fb009dcSAndroid Build Coastguard Worker       EXPECT_GE(order1.size(), 5u);
8754*8fb009dcSAndroid Build Coastguard Worker       static const int kNumIterations = 14;
8755*8fb009dcSAndroid Build Coastguard Worker       bool passed = false;
8756*8fb009dcSAndroid Build Coastguard Worker       for (int i = 0; i < kNumIterations; i++) {
8757*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(
8758*8fb009dcSAndroid Build Coastguard Worker             GetExtensionOrder(ctx.get(), &order2, maybe_keys, decrypt_ech));
8759*8fb009dcSAndroid Build Coastguard Worker         if (order1 != order2) {
8760*8fb009dcSAndroid Build Coastguard Worker           passed = true;
8761*8fb009dcSAndroid Build Coastguard Worker           break;
8762*8fb009dcSAndroid Build Coastguard Worker         }
8763*8fb009dcSAndroid Build Coastguard Worker       }
8764*8fb009dcSAndroid Build Coastguard Worker       EXPECT_TRUE(passed) << "Extensions were not permuted";
8765*8fb009dcSAndroid Build Coastguard Worker     }
8766*8fb009dcSAndroid Build Coastguard Worker   }
8767*8fb009dcSAndroid Build Coastguard Worker }
8768*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,HostMatching)8769*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, HostMatching) {
8770*8fb009dcSAndroid Build Coastguard Worker   static const char kCertPEM[] = R"(
8771*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
8772*8fb009dcSAndroid Build Coastguard Worker MIIB9jCCAZ2gAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjApMRAw
8773*8fb009dcSAndroid Build Coastguard Worker DgYDVQQKEwdBY21lIENvMRUwEwYDVQQDEwxleGFtcGxlMy5jb20wHhcNMjExMjA2
8774*8fb009dcSAndroid Build Coastguard Worker MjA1NjU2WhcNMjIxMjA2MjA1NjU2WjApMRAwDgYDVQQKEwdBY21lIENvMRUwEwYD
8775*8fb009dcSAndroid Build Coastguard Worker VQQDEwxleGFtcGxlMy5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS7l2VO
8776*8fb009dcSAndroid Build Coastguard Worker Bl2TjVm9WfGk24+hMbVFUNB+RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaW
8777*8fb009dcSAndroid Build Coastguard Worker ULDDaoeDl1M0t4Hmo4GmMIGjMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggr
8778*8fb009dcSAndroid Build Coastguard Worker BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTTJWurcc1t+VPQBko3
8779*8fb009dcSAndroid Build Coastguard Worker Gsw6cbcWSTBMBgNVHREERTBDggxleGFtcGxlMS5jb22CDGV4YW1wbGUyLmNvbYIP
8780*8fb009dcSAndroid Build Coastguard Worker YSouZXhhbXBsZTQuY29tgg4qLmV4YW1wbGU1LmNvbYcEAQIDBDAKBggqhkjOPQQD
8781*8fb009dcSAndroid Build Coastguard Worker AgNHADBEAiAAv0ljHJGrgyzZDkG6XvNZ5ewxRfnXcZuD0Y7E4giCZgIgNK1qjilu
8782*8fb009dcSAndroid Build Coastguard Worker 5DyVbfKeeJhOCtGxqE1dWLXyJBnoRomSYBY=
8783*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
8784*8fb009dcSAndroid Build Coastguard Worker )";
8785*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert(CertFromPEM(kCertPEM));
8786*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
8787*8fb009dcSAndroid Build Coastguard Worker   static const char kCertNoSANsPEM[] = R"(
8788*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
8789*8fb009dcSAndroid Build Coastguard Worker MIIBqzCCAVGgAwIBAgIQeudG9R61BOxUvWkeVhU5DTAKBggqhkjOPQQDAjArMRIw
8790*8fb009dcSAndroid Build Coastguard Worker EAYDVQQKEwlBY21lIENvIDIxFTATBgNVBAMTDGV4YW1wbGUzLmNvbTAeFw0yMTEy
8791*8fb009dcSAndroid Build Coastguard Worker MDYyMDU2NTZaFw0yMjEyMDYyMDU2NTZaMCsxEjAQBgNVBAoTCUFjbWUgQ28gMjEV
8792*8fb009dcSAndroid Build Coastguard Worker MBMGA1UEAxMMZXhhbXBsZTMuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
8793*8fb009dcSAndroid Build Coastguard Worker u5dlTgZdk41ZvVnxpNuPoTG1RVDQfkVR1mwrxbzWQKFoiCds9+ESxiJ8mbwmfMSw
8794*8fb009dcSAndroid Build Coastguard Worker L7LmllCww2qHg5dTNLeB5qNXMFUwDgYDVR0PAQH/BAQDAgKEMBMGA1UdJQQMMAoG
8795*8fb009dcSAndroid Build Coastguard Worker CCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNMla6txzW35U9AG
8796*8fb009dcSAndroid Build Coastguard Worker SjcazDpxtxZJMAoGCCqGSM49BAMCA0gAMEUCIG3YWGWtpVhbcGV7wFKQwTfmvwHW
8797*8fb009dcSAndroid Build Coastguard Worker pw4qCFZlool4hCwsAiEA+2fc6NfSbNpFEtQkDOMJW2ANiScAVEmImNqPfb2klz4=
8798*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
8799*8fb009dcSAndroid Build Coastguard Worker )";
8800*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert_no_sans(CertFromPEM(kCertNoSANsPEM));
8801*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert_no_sans);
8802*8fb009dcSAndroid Build Coastguard Worker 
8803*8fb009dcSAndroid Build Coastguard Worker   static const char kKeyPEM[] = R"(
8804*8fb009dcSAndroid Build Coastguard Worker -----BEGIN PRIVATE KEY-----
8805*8fb009dcSAndroid Build Coastguard Worker MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQghsaSZhUzZAcQlLyJ
8806*8fb009dcSAndroid Build Coastguard Worker MDuy7WPdyqNsAX9rmEP650LF/q2hRANCAAS7l2VOBl2TjVm9WfGk24+hMbVFUNB+
8807*8fb009dcSAndroid Build Coastguard Worker RVHWbCvFvNZAoWiIJ2z34RLGInyZvCZ8xLAvsuaWULDDaoeDl1M0t4Hm
8808*8fb009dcSAndroid Build Coastguard Worker -----END PRIVATE KEY-----
8809*8fb009dcSAndroid Build Coastguard Worker )";
8810*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key(KeyFromPEM(kKeyPEM));
8811*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
8812*8fb009dcSAndroid Build Coastguard Worker 
8813*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8814*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
8815*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8816*8fb009dcSAndroid Build Coastguard Worker                                   cert.get()));
8817*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(X509_STORE_add_cert(SSL_CTX_get_cert_store(client_ctx.get()),
8818*8fb009dcSAndroid Build Coastguard Worker                                   cert_no_sans.get()));
8819*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_verify(client_ctx.get(),
8820*8fb009dcSAndroid Build Coastguard Worker                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
8821*8fb009dcSAndroid Build Coastguard Worker                      nullptr);
8822*8fb009dcSAndroid Build Coastguard Worker   X509_VERIFY_PARAM_set_flags(SSL_CTX_get0_param(client_ctx.get()),
8823*8fb009dcSAndroid Build Coastguard Worker                               X509_V_FLAG_NO_CHECK_TIME);
8824*8fb009dcSAndroid Build Coastguard Worker 
8825*8fb009dcSAndroid Build Coastguard Worker   struct TestCase {
8826*8fb009dcSAndroid Build Coastguard Worker     X509 *cert;
8827*8fb009dcSAndroid Build Coastguard Worker     std::string hostname;
8828*8fb009dcSAndroid Build Coastguard Worker     unsigned flags;
8829*8fb009dcSAndroid Build Coastguard Worker     bool should_match;
8830*8fb009dcSAndroid Build Coastguard Worker   };
8831*8fb009dcSAndroid Build Coastguard Worker   std::vector<TestCase> kTests = {
8832*8fb009dcSAndroid Build Coastguard Worker       // These two names are present as SANs in the certificate.
8833*8fb009dcSAndroid Build Coastguard Worker       {cert.get(), "example1.com", 0, true},
8834*8fb009dcSAndroid Build Coastguard Worker       {cert.get(), "example2.com", 0, true},
8835*8fb009dcSAndroid Build Coastguard Worker       // This is the CN of the certificate, but that shouldn't matter if a SAN
8836*8fb009dcSAndroid Build Coastguard Worker       // extension is present.
8837*8fb009dcSAndroid Build Coastguard Worker       {cert.get(), "example3.com", 0, false},
8838*8fb009dcSAndroid Build Coastguard Worker       // If the SAN is not present, we, for now, look for DNS names in the CN.
8839*8fb009dcSAndroid Build Coastguard Worker       {cert_no_sans.get(), "example3.com", 0, true},
8840*8fb009dcSAndroid Build Coastguard Worker       // ... but this can be turned off.
8841*8fb009dcSAndroid Build Coastguard Worker       {cert_no_sans.get(), "example3.com", X509_CHECK_FLAG_NEVER_CHECK_SUBJECT,
8842*8fb009dcSAndroid Build Coastguard Worker        false},
8843*8fb009dcSAndroid Build Coastguard Worker       // a*.example4.com is a SAN, but is invalid.
8844*8fb009dcSAndroid Build Coastguard Worker       {cert.get(), "abc.example4.com", 0, false},
8845*8fb009dcSAndroid Build Coastguard Worker       // *.example5.com is a SAN in the certificate, which is a normal and valid
8846*8fb009dcSAndroid Build Coastguard Worker       // wildcard.
8847*8fb009dcSAndroid Build Coastguard Worker       {cert.get(), "abc.example5.com", 0, true},
8848*8fb009dcSAndroid Build Coastguard Worker       // This name is not present.
8849*8fb009dcSAndroid Build Coastguard Worker       {cert.get(), "notexample1.com", 0, false},
8850*8fb009dcSAndroid Build Coastguard Worker       // The IPv4 address 1.2.3.4 is a SAN, but that shouldn't match against a
8851*8fb009dcSAndroid Build Coastguard Worker       // hostname that happens to be its textual representation.
8852*8fb009dcSAndroid Build Coastguard Worker       {cert.get(), "1.2.3.4", 0, false},
8853*8fb009dcSAndroid Build Coastguard Worker   };
8854*8fb009dcSAndroid Build Coastguard Worker 
8855*8fb009dcSAndroid Build Coastguard Worker   for (const TestCase &test : kTests) {
8856*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(test.hostname);
8857*8fb009dcSAndroid Build Coastguard Worker 
8858*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8859*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(server_ctx);
8860*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), test.cert));
8861*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8862*8fb009dcSAndroid Build Coastguard Worker 
8863*8fb009dcSAndroid Build Coastguard Worker     ClientConfig config;
8864*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8865*8fb009dcSAndroid Build Coastguard Worker     config.verify_hostname = test.hostname;
8866*8fb009dcSAndroid Build Coastguard Worker     config.hostflags = test.flags;
8867*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(test.should_match,
8868*8fb009dcSAndroid Build Coastguard Worker               ConnectClientAndServer(&client, &server, client_ctx.get(),
8869*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get(), config));
8870*8fb009dcSAndroid Build Coastguard Worker   }
8871*8fb009dcSAndroid Build Coastguard Worker }
8872*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,NumTickets)8873*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, NumTickets) {
8874*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx(SSL_CTX_new(TLS_method()));
8875*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
8876*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
8877*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
8878*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetTestCertificate();
8879*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
8880*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
8881*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
8882*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(server_ctx.get(), cert.get()));
8883*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_PrivateKey(server_ctx.get(), key.get()));
8884*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(server_ctx.get(), SSL_SESS_CACHE_BOTH);
8885*8fb009dcSAndroid Build Coastguard Worker 
8886*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_session_cache_mode(client_ctx.get(), SSL_SESS_CACHE_BOTH);
8887*8fb009dcSAndroid Build Coastguard Worker   static size_t ticket_count;
8888*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_sess_set_new_cb(client_ctx.get(), [](SSL *, SSL_SESSION *) -> int {
8889*8fb009dcSAndroid Build Coastguard Worker     ticket_count++;
8890*8fb009dcSAndroid Build Coastguard Worker     return 0;
8891*8fb009dcSAndroid Build Coastguard Worker   });
8892*8fb009dcSAndroid Build Coastguard Worker 
8893*8fb009dcSAndroid Build Coastguard Worker   auto count_tickets = [&]() -> size_t {
8894*8fb009dcSAndroid Build Coastguard Worker     ticket_count = 0;
8895*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<SSL> client, server;
8896*8fb009dcSAndroid Build Coastguard Worker     if (!ConnectClientAndServer(&client, &server, client_ctx.get(),
8897*8fb009dcSAndroid Build Coastguard Worker                                 server_ctx.get()) ||
8898*8fb009dcSAndroid Build Coastguard Worker         !FlushNewSessionTickets(client.get(), server.get())) {
8899*8fb009dcSAndroid Build Coastguard Worker       ADD_FAILURE() << "Could not run handshake";
8900*8fb009dcSAndroid Build Coastguard Worker       return 0;
8901*8fb009dcSAndroid Build Coastguard Worker     }
8902*8fb009dcSAndroid Build Coastguard Worker     return ticket_count;
8903*8fb009dcSAndroid Build Coastguard Worker   };
8904*8fb009dcSAndroid Build Coastguard Worker 
8905*8fb009dcSAndroid Build Coastguard Worker   // By default, we should send two tickets.
8906*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(count_tickets(), 2u);
8907*8fb009dcSAndroid Build Coastguard Worker 
8908*8fb009dcSAndroid Build Coastguard Worker   for (size_t num_tickets : {0, 1, 2, 3, 4, 5}) {
8909*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(num_tickets);
8910*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), num_tickets));
8911*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), num_tickets);
8912*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(count_tickets(), num_tickets);
8913*8fb009dcSAndroid Build Coastguard Worker   }
8914*8fb009dcSAndroid Build Coastguard Worker 
8915*8fb009dcSAndroid Build Coastguard Worker   // Configuring too many tickets causes us to stop at some point.
8916*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_num_tickets(server_ctx.get(), 100000));
8917*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_CTX_get_num_tickets(server_ctx.get()), 16u);
8918*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(count_tickets(), 16u);
8919*8fb009dcSAndroid Build Coastguard Worker }
8920*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,CertSubjectsToStack)8921*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, CertSubjectsToStack) {
8922*8fb009dcSAndroid Build Coastguard Worker   const std::string kCert1 = R"(
8923*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
8924*8fb009dcSAndroid Build Coastguard Worker MIIBzzCCAXagAwIBAgIJANlMBNpJfb/rMAkGByqGSM49BAEwRTELMAkGA1UEBhMC
8925*8fb009dcSAndroid Build Coastguard Worker QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdp
8926*8fb009dcSAndroid Build Coastguard Worker dHMgUHR5IEx0ZDAeFw0xNDA0MjMyMzIxNTdaFw0xNDA1MjMyMzIxNTdaMEUxCzAJ
8927*8fb009dcSAndroid Build Coastguard Worker BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
8928*8fb009dcSAndroid Build Coastguard Worker dCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATmK2ni
8929*8fb009dcSAndroid Build Coastguard Worker v2Wfl74vHg2UikzVl2u3qR4NRvvdqakendy6WgHn1peoChj5w8SjHlbifINI2xYa
8930*8fb009dcSAndroid Build Coastguard Worker HPUdfvGULUvPciLBo1AwTjAdBgNVHQ4EFgQUq4TSrKuV8IJOFngHVVdf5CaNgtEw
8931*8fb009dcSAndroid Build Coastguard Worker HwYDVR0jBBgwFoAUq4TSrKuV8IJOFngHVVdf5CaNgtEwDAYDVR0TBAUwAwEB/zAJ
8932*8fb009dcSAndroid Build Coastguard Worker BgcqhkjOPQQBA0gAMEUCIQDyoDVeUTo2w4J5m+4nUIWOcAZ0lVfSKXQA9L4Vh13E
8933*8fb009dcSAndroid Build Coastguard Worker BwIgfB55FGohg/B6dGh5XxSZmmi08cueFV7mHzJSYV51yRQ=
8934*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
8935*8fb009dcSAndroid Build Coastguard Worker )";
8936*8fb009dcSAndroid Build Coastguard Worker   const std::vector<uint8_t> kName1 = {
8937*8fb009dcSAndroid Build Coastguard Worker       0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
8938*8fb009dcSAndroid Build Coastguard Worker       0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08,
8939*8fb009dcSAndroid Build Coastguard Worker       0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
8940*8fb009dcSAndroid Build Coastguard Worker       0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49,
8941*8fb009dcSAndroid Build Coastguard Worker       0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
8942*8fb009dcSAndroid Build Coastguard Worker       0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64};
8943*8fb009dcSAndroid Build Coastguard Worker   const std::string kCert2 = R"(
8944*8fb009dcSAndroid Build Coastguard Worker -----BEGIN CERTIFICATE-----
8945*8fb009dcSAndroid Build Coastguard Worker MIICXjCCAcegAwIBAgIIWjO48ufpunYwDQYJKoZIhvcNAQELBQAwNjEaMBgGA1UE
8946*8fb009dcSAndroid Build Coastguard Worker ChMRQm9yaW5nU1NMIFRFU1RJTkcxGDAWBgNVBAMTD0ludGVybWVkaWF0ZSBDQTAg
8947*8fb009dcSAndroid Build Coastguard Worker Fw0xNTAxMDEwMDAwMDBaGA8yMTAwMDEwMTAwMDAwMFowMjEaMBgGA1UEChMRQm9y
8948*8fb009dcSAndroid Build Coastguard Worker aW5nU1NMIFRFU1RJTkcxFDASBgNVBAMTC2V4YW1wbGUuY29tMIGfMA0GCSqGSIb3
8949*8fb009dcSAndroid Build Coastguard Worker DQEBAQUAA4GNADCBiQKBgQDD0U0ZYgqShJ7oOjsyNKyVXEHqeafmk/bAoPqY/h1c
8950*8fb009dcSAndroid Build Coastguard Worker oPw2E8KmeqiUSoTPjG5IXSblOxcqpbAXgnjPzo8DI3GNMhAf8SYNYsoH7gc7Uy7j
8951*8fb009dcSAndroid Build Coastguard Worker 5x8bUrisGnuTHqkqH6d4/e7ETJ7i3CpR8bvK16DggEvQTudLipz8FBHtYhFakfdh
8952*8fb009dcSAndroid Build Coastguard Worker TwIDAQABo3cwdTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
8953*8fb009dcSAndroid Build Coastguard Worker CCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwGQYDVR0OBBIEEKN5pvbur7mlXjeMEYA0
8954*8fb009dcSAndroid Build Coastguard Worker 4nUwGwYDVR0jBBQwEoAQjBpoqLV2211Xex+NFLIGozANBgkqhkiG9w0BAQsFAAOB
8955*8fb009dcSAndroid Build Coastguard Worker gQBj/p+JChp//LnXWC1k121LM/ii7hFzQzMrt70bny406SGz9jAjaPOX4S3gt38y
8956*8fb009dcSAndroid Build Coastguard Worker rhjpPukBlSzgQXFg66y6q5qp1nQTD1Cw6NkKBe9WuBlY3iYfmsf7WT8nhlT1CttU
8957*8fb009dcSAndroid Build Coastguard Worker xNCwyMX9mtdXdQicOfNjIGUCD5OLV5PgHFPRKiHHioBAhg==
8958*8fb009dcSAndroid Build Coastguard Worker -----END CERTIFICATE-----
8959*8fb009dcSAndroid Build Coastguard Worker )";
8960*8fb009dcSAndroid Build Coastguard Worker   const std::vector<uint8_t> kName2 = {
8961*8fb009dcSAndroid Build Coastguard Worker       0x30, 0x32, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a,
8962*8fb009dcSAndroid Build Coastguard Worker       0x13, 0x11, 0x42, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x53, 0x53, 0x4c,
8963*8fb009dcSAndroid Build Coastguard Worker       0x20, 0x54, 0x45, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x31, 0x14, 0x30,
8964*8fb009dcSAndroid Build Coastguard Worker       0x12, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0b, 0x65, 0x78, 0x61,
8965*8fb009dcSAndroid Build Coastguard Worker       0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d};
8966*8fb009dcSAndroid Build Coastguard Worker 
8967*8fb009dcSAndroid Build Coastguard Worker   const struct {
8968*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::vector<uint8_t>> existing;
8969*8fb009dcSAndroid Build Coastguard Worker     std::string pem;
8970*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::vector<uint8_t>> expected;
8971*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
8972*8fb009dcSAndroid Build Coastguard Worker       // Do nothing.
8973*8fb009dcSAndroid Build Coastguard Worker       {{}, "", {}},
8974*8fb009dcSAndroid Build Coastguard Worker       // Append to an empty list, skipping duplicates.
8975*8fb009dcSAndroid Build Coastguard Worker       {{}, kCert1 + kCert2 + kCert1, {kName1, kName2}},
8976*8fb009dcSAndroid Build Coastguard Worker       // One of the names was already present.
8977*8fb009dcSAndroid Build Coastguard Worker       {{kName1}, kCert1 + kCert2, {kName1, kName2}},
8978*8fb009dcSAndroid Build Coastguard Worker       // Both names were already present.
8979*8fb009dcSAndroid Build Coastguard Worker       {{kName1, kName2}, kCert1 + kCert2, {kName1, kName2}},
8980*8fb009dcSAndroid Build Coastguard Worker       // Preserve existing duplicates.
8981*8fb009dcSAndroid Build Coastguard Worker       {{kName1, kName2, kName2}, kCert1 + kCert2, {kName1, kName2, kName2}},
8982*8fb009dcSAndroid Build Coastguard Worker   };
8983*8fb009dcSAndroid Build Coastguard Worker   for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) {
8984*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(i);
8985*8fb009dcSAndroid Build Coastguard Worker     const auto &t = kTests[i];
8986*8fb009dcSAndroid Build Coastguard Worker 
8987*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<STACK_OF(X509_NAME)> stack(sk_X509_NAME_new_null());
8988*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(stack);
8989*8fb009dcSAndroid Build Coastguard Worker     for (const auto& name : t.existing) {
8990*8fb009dcSAndroid Build Coastguard Worker       const uint8_t *inp = name.data();
8991*8fb009dcSAndroid Build Coastguard Worker       bssl::UniquePtr<X509_NAME> name_obj(
8992*8fb009dcSAndroid Build Coastguard Worker           d2i_X509_NAME(nullptr, &inp, name.size()));
8993*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(name_obj);
8994*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(inp, name.data() + name.size());
8995*8fb009dcSAndroid Build Coastguard Worker       ASSERT_TRUE(bssl::PushToStack(stack.get(), std::move(name_obj)));
8996*8fb009dcSAndroid Build Coastguard Worker     }
8997*8fb009dcSAndroid Build Coastguard Worker 
8998*8fb009dcSAndroid Build Coastguard Worker     bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(t.pem.data(), t.pem.size()));
8999*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(bio);
9000*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(SSL_add_bio_cert_subjects_to_stack(stack.get(), bio.get()));
9001*8fb009dcSAndroid Build Coastguard Worker 
9002*8fb009dcSAndroid Build Coastguard Worker     // The function should have left |stack|'s comparison function alone.
9003*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(nullptr, sk_X509_NAME_set_cmp_func(stack.get(), nullptr));
9004*8fb009dcSAndroid Build Coastguard Worker 
9005*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::vector<uint8_t>> expected = t.expected, result;
9006*8fb009dcSAndroid Build Coastguard Worker     for (X509_NAME *name : stack.get()) {
9007*8fb009dcSAndroid Build Coastguard Worker       uint8_t *der = nullptr;
9008*8fb009dcSAndroid Build Coastguard Worker       int der_len = i2d_X509_NAME(name, &der);
9009*8fb009dcSAndroid Build Coastguard Worker       ASSERT_GE(der_len, 0);
9010*8fb009dcSAndroid Build Coastguard Worker       result.push_back(std::vector<uint8_t>(der, der + der_len));
9011*8fb009dcSAndroid Build Coastguard Worker       OPENSSL_free(der);
9012*8fb009dcSAndroid Build Coastguard Worker     }
9013*8fb009dcSAndroid Build Coastguard Worker 
9014*8fb009dcSAndroid Build Coastguard Worker     // |SSL_add_bio_cert_subjects_to_stack| does not return the output in a
9015*8fb009dcSAndroid Build Coastguard Worker     // well-defined order.
9016*8fb009dcSAndroid Build Coastguard Worker     std::sort(expected.begin(), expected.end());
9017*8fb009dcSAndroid Build Coastguard Worker     std::sort(result.begin(), result.end());
9018*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(result, expected);
9019*8fb009dcSAndroid Build Coastguard Worker   }
9020*8fb009dcSAndroid Build Coastguard Worker }
9021*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,EmptyClientCAList)9022*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, EmptyClientCAList) {
9023*8fb009dcSAndroid Build Coastguard Worker   if (SkipTempFileTests()) {
9024*8fb009dcSAndroid Build Coastguard Worker     GTEST_SKIP();
9025*8fb009dcSAndroid Build Coastguard Worker   }
9026*8fb009dcSAndroid Build Coastguard Worker 
9027*8fb009dcSAndroid Build Coastguard Worker   TemporaryFile empty;
9028*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(empty.Init());
9029*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<STACK_OF(X509_NAME)> names(
9030*8fb009dcSAndroid Build Coastguard Worker       SSL_load_client_CA_file(empty.path().c_str()));
9031*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(names);
9032*8fb009dcSAndroid Build Coastguard Worker }
9033*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,EmptyWriteBlockedOnHandshakeData)9034*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, EmptyWriteBlockedOnHandshakeData) {
9035*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
9036*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
9037*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
9038*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
9039*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
9040*8fb009dcSAndroid Build Coastguard Worker   // Configure only TLS 1.3. This test requires post-handshake NewSessionTicket.
9041*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_min_proto_version(client_ctx.get(), TLS1_3_VERSION));
9042*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_set_max_proto_version(client_ctx.get(), TLS1_3_VERSION));
9043*8fb009dcSAndroid Build Coastguard Worker 
9044*8fb009dcSAndroid Build Coastguard Worker   // Connect a client and server with tiny buffer between the two.
9045*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client(SSL_new(client_ctx.get())),
9046*8fb009dcSAndroid Build Coastguard Worker       server(SSL_new(server_ctx.get()));
9047*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client);
9048*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server);
9049*8fb009dcSAndroid Build Coastguard Worker   SSL_set_connect_state(client.get());
9050*8fb009dcSAndroid Build Coastguard Worker   SSL_set_accept_state(server.get());
9051*8fb009dcSAndroid Build Coastguard Worker   BIO *bio1, *bio2;
9052*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(BIO_new_bio_pair(&bio1, 1, &bio2, 1));
9053*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(client.get(), bio1, bio1);
9054*8fb009dcSAndroid Build Coastguard Worker   SSL_set_bio(server.get(), bio2, bio2);
9055*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(CompleteHandshakes(client.get(), server.get()));
9056*8fb009dcSAndroid Build Coastguard Worker 
9057*8fb009dcSAndroid Build Coastguard Worker   // We defer NewSessionTicket to the first write, so the server has a pending
9058*8fb009dcSAndroid Build Coastguard Worker   // NewSessionTicket. See https://boringssl-review.googlesource.com/34948. This
9059*8fb009dcSAndroid Build Coastguard Worker   // means an empty write will flush the ticket. However, the transport only
9060*8fb009dcSAndroid Build Coastguard Worker   // allows one byte through, so this will fail with |SSL_ERROR_WANT_WRITE|.
9061*8fb009dcSAndroid Build Coastguard Worker   int ret = SSL_write(server.get(), nullptr, 0);
9062*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(ret, -1);
9063*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
9064*8fb009dcSAndroid Build Coastguard Worker 
9065*8fb009dcSAndroid Build Coastguard Worker   // Attempting to write non-zero data should not trip |SSL_R_BAD_WRITE_RETRY|.
9066*8fb009dcSAndroid Build Coastguard Worker   const uint8_t kData[] = {'h', 'e', 'l', 'l', 'o'};
9067*8fb009dcSAndroid Build Coastguard Worker   ret = SSL_write(server.get(), kData, sizeof(kData));
9068*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(ret, -1);
9069*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
9070*8fb009dcSAndroid Build Coastguard Worker 
9071*8fb009dcSAndroid Build Coastguard Worker   // Byte by byte, the data should eventually get through.
9072*8fb009dcSAndroid Build Coastguard Worker   uint8_t buf[sizeof(kData)];
9073*8fb009dcSAndroid Build Coastguard Worker   for (;;) {
9074*8fb009dcSAndroid Build Coastguard Worker     ret = SSL_read(client.get(), buf, sizeof(buf));
9075*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(ret, -1);
9076*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_WANT_READ);
9077*8fb009dcSAndroid Build Coastguard Worker 
9078*8fb009dcSAndroid Build Coastguard Worker     ret = SSL_write(server.get(), kData, sizeof(kData));
9079*8fb009dcSAndroid Build Coastguard Worker     if (ret > 0) {
9080*8fb009dcSAndroid Build Coastguard Worker       ASSERT_EQ(ret, 5);
9081*8fb009dcSAndroid Build Coastguard Worker       break;
9082*8fb009dcSAndroid Build Coastguard Worker     }
9083*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(ret, -1);
9084*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_WANT_WRITE);
9085*8fb009dcSAndroid Build Coastguard Worker   }
9086*8fb009dcSAndroid Build Coastguard Worker 
9087*8fb009dcSAndroid Build Coastguard Worker   ret = SSL_read(client.get(), buf, sizeof(buf));
9088*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(ret, static_cast<int>(sizeof(kData)));
9089*8fb009dcSAndroid Build Coastguard Worker   ASSERT_EQ(Bytes(buf, ret), Bytes(kData));
9090*8fb009dcSAndroid Build Coastguard Worker }
9091*8fb009dcSAndroid Build Coastguard Worker 
9092*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_ERROR_SYSCALL| continues to work after a close_notify.
TEST(SSLTest,ErrorSyscallAfterCloseNotify)9093*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, ErrorSyscallAfterCloseNotify) {
9094*8fb009dcSAndroid Build Coastguard Worker   // Make a custom |BIO| where writes fail, but without pushing to the error
9095*8fb009dcSAndroid Build Coastguard Worker   // queue.
9096*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO_METHOD> method(BIO_meth_new(0, nullptr));
9097*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(method);
9098*8fb009dcSAndroid Build Coastguard Worker   BIO_meth_set_create(method.get(), [](BIO *b) -> int {
9099*8fb009dcSAndroid Build Coastguard Worker     BIO_set_init(b, 1);
9100*8fb009dcSAndroid Build Coastguard Worker     return 1;
9101*8fb009dcSAndroid Build Coastguard Worker   });
9102*8fb009dcSAndroid Build Coastguard Worker   static bool write_failed = false;
9103*8fb009dcSAndroid Build Coastguard Worker   BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int {
9104*8fb009dcSAndroid Build Coastguard Worker     // Fail the operation and don't add to the error queue.
9105*8fb009dcSAndroid Build Coastguard Worker     write_failed = true;
9106*8fb009dcSAndroid Build Coastguard Worker     return -1;
9107*8fb009dcSAndroid Build Coastguard Worker   });
9108*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<BIO> wbio_silent_error(BIO_new(method.get()));
9109*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(wbio_silent_error);
9110*8fb009dcSAndroid Build Coastguard Worker 
9111*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
9112*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
9113*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
9114*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
9115*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
9116*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
9117*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
9118*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
9119*8fb009dcSAndroid Build Coastguard Worker 
9120*8fb009dcSAndroid Build Coastguard Worker   // Replace the write |BIO| with |wbio_silent_error|.
9121*8fb009dcSAndroid Build Coastguard Worker   SSL_set0_wbio(client.get(), wbio_silent_error.release());
9122*8fb009dcSAndroid Build Coastguard Worker 
9123*8fb009dcSAndroid Build Coastguard Worker   // Writes should fail. There is nothing in the error queue, so
9124*8fb009dcSAndroid Build Coastguard Worker   // |SSL_ERROR_SYSCALL| indicates the caller needs to check out-of-band.
9125*8fb009dcSAndroid Build Coastguard Worker   const uint8_t data[1] = {0};
9126*8fb009dcSAndroid Build Coastguard Worker   int ret = SSL_write(client.get(), data, sizeof(data));
9127*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ret, -1);
9128*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
9129*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(write_failed);
9130*8fb009dcSAndroid Build Coastguard Worker   write_failed = false;
9131*8fb009dcSAndroid Build Coastguard Worker 
9132*8fb009dcSAndroid Build Coastguard Worker   // Send a close_notify from the server. It should return 0 because
9133*8fb009dcSAndroid Build Coastguard Worker   // close_notify was sent, but not received. Confusingly, this is a success
9134*8fb009dcSAndroid Build Coastguard Worker   // output for |SSL_shutdown|'s API.
9135*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_shutdown(server.get()), 0);
9136*8fb009dcSAndroid Build Coastguard Worker 
9137*8fb009dcSAndroid Build Coastguard Worker   // Read the close_notify on the client.
9138*8fb009dcSAndroid Build Coastguard Worker   uint8_t buf[1];
9139*8fb009dcSAndroid Build Coastguard Worker   ret = SSL_read(client.get(), buf, sizeof(buf));
9140*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ret, 0);
9141*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
9142*8fb009dcSAndroid Build Coastguard Worker 
9143*8fb009dcSAndroid Build Coastguard Worker   // Further calls to |SSL_read| continue to report |SSL_ERROR_ZERO_RETURN|.
9144*8fb009dcSAndroid Build Coastguard Worker   ret = SSL_read(client.get(), buf, sizeof(buf));
9145*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ret, 0);
9146*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_ZERO_RETURN);
9147*8fb009dcSAndroid Build Coastguard Worker 
9148*8fb009dcSAndroid Build Coastguard Worker   // Although the client has seen close_notify, it should continue to report
9149*8fb009dcSAndroid Build Coastguard Worker   // |SSL_ERROR_SYSCALL| when its writes fail.
9150*8fb009dcSAndroid Build Coastguard Worker   ret = SSL_write(client.get(), data, sizeof(data));
9151*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ret, -1);
9152*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
9153*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(write_failed);
9154*8fb009dcSAndroid Build Coastguard Worker   write_failed = false;
9155*8fb009dcSAndroid Build Coastguard Worker 
9156*8fb009dcSAndroid Build Coastguard Worker   // Cause |BIO_write| to fail with a return value of zero instead.
9157*8fb009dcSAndroid Build Coastguard Worker   // |SSL_get_error| should not misinterpret this as a close_notify.
9158*8fb009dcSAndroid Build Coastguard Worker   //
9159*8fb009dcSAndroid Build Coastguard Worker   // This is not actually a correct implementation of |BIO_write|, but the rest
9160*8fb009dcSAndroid Build Coastguard Worker   // of the code treats zero from |BIO_write| as an error, so ensure it does so
9161*8fb009dcSAndroid Build Coastguard Worker   // correctly. Fixing https://crbug.com/boringssl/503 will make this case moot.
9162*8fb009dcSAndroid Build Coastguard Worker   BIO_meth_set_write(method.get(), [](BIO *, const char *, int) -> int {
9163*8fb009dcSAndroid Build Coastguard Worker     write_failed = true;
9164*8fb009dcSAndroid Build Coastguard Worker     return 0;
9165*8fb009dcSAndroid Build Coastguard Worker   });
9166*8fb009dcSAndroid Build Coastguard Worker   ret = SSL_write(client.get(), data, sizeof(data));
9167*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ret, 0);
9168*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
9169*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(write_failed);
9170*8fb009dcSAndroid Build Coastguard Worker   write_failed = false;
9171*8fb009dcSAndroid Build Coastguard Worker }
9172*8fb009dcSAndroid Build Coastguard Worker 
9173*8fb009dcSAndroid Build Coastguard Worker // Test that |SSL_shutdown|, when quiet shutdown is enabled, simulates receiving
9174*8fb009dcSAndroid Build Coastguard Worker // a close_notify, down to |SSL_read| reporting |SSL_ERROR_ZERO_RETURN|.
TEST(SSLTest,QuietShutdown)9175*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, QuietShutdown) {
9176*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> client_ctx(SSL_CTX_new(TLS_method()));
9177*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> server_ctx =
9178*8fb009dcSAndroid Build Coastguard Worker       CreateContextWithTestCertificate(TLS_method());
9179*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(client_ctx);
9180*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(server_ctx);
9181*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_quiet_shutdown(server_ctx.get(), 1);
9182*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> client, server;
9183*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ConnectClientAndServer(&client, &server, client_ctx.get(),
9184*8fb009dcSAndroid Build Coastguard Worker                                      server_ctx.get()));
9185*8fb009dcSAndroid Build Coastguard Worker 
9186*8fb009dcSAndroid Build Coastguard Worker   // Quiet shutdown is enabled, so |SSL_shutdown| on the server should
9187*8fb009dcSAndroid Build Coastguard Worker   // immediately return that bidirectional shutdown "completed".
9188*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_shutdown(server.get()), 1);
9189*8fb009dcSAndroid Build Coastguard Worker 
9190*8fb009dcSAndroid Build Coastguard Worker   // Shut down writes so the client gets an EOF.
9191*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(BIO_shutdown_wr(SSL_get_wbio(server.get())));
9192*8fb009dcSAndroid Build Coastguard Worker 
9193*8fb009dcSAndroid Build Coastguard Worker   // Confirm no close notify was actually sent. Client reads should report a
9194*8fb009dcSAndroid Build Coastguard Worker   // transport EOF, not a close_notify. (Both have zero return, but
9195*8fb009dcSAndroid Build Coastguard Worker   // |SSL_get_error| is different.)
9196*8fb009dcSAndroid Build Coastguard Worker   char buf[1];
9197*8fb009dcSAndroid Build Coastguard Worker   int ret = SSL_read(client.get(), buf, sizeof(buf));
9198*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ret, 0);
9199*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(client.get(), ret), SSL_ERROR_SYSCALL);
9200*8fb009dcSAndroid Build Coastguard Worker 
9201*8fb009dcSAndroid Build Coastguard Worker   // The server believes bidirectional shutdown completed, so reads should
9202*8fb009dcSAndroid Build Coastguard Worker   // replay the (simulated) close_notify.
9203*8fb009dcSAndroid Build Coastguard Worker   ret = SSL_read(server.get(), buf, sizeof(buf));
9204*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(ret, 0);
9205*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(SSL_get_error(server.get(), ret), SSL_ERROR_ZERO_RETURN);
9206*8fb009dcSAndroid Build Coastguard Worker }
9207*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,InvalidSignatureAlgorithm)9208*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, InvalidSignatureAlgorithm) {
9209*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
9210*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
9211*8fb009dcSAndroid Build Coastguard Worker 
9212*8fb009dcSAndroid Build Coastguard Worker   static const uint16_t kInvalidPrefs[] = {1234};
9213*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_signing_algorithm_prefs(
9214*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), kInvalidPrefs, OPENSSL_ARRAY_SIZE(kInvalidPrefs)));
9215*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_verify_algorithm_prefs(
9216*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), kInvalidPrefs, OPENSSL_ARRAY_SIZE(kInvalidPrefs)));
9217*8fb009dcSAndroid Build Coastguard Worker 
9218*8fb009dcSAndroid Build Coastguard Worker   static const uint16_t kDuplicatePrefs[] = {SSL_SIGN_RSA_PKCS1_SHA256,
9219*8fb009dcSAndroid Build Coastguard Worker                                              SSL_SIGN_RSA_PKCS1_SHA256};
9220*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_signing_algorithm_prefs(
9221*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), kDuplicatePrefs, OPENSSL_ARRAY_SIZE(kDuplicatePrefs)));
9222*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set_verify_algorithm_prefs(
9223*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), kDuplicatePrefs, OPENSSL_ARRAY_SIZE(kDuplicatePrefs)));
9224*8fb009dcSAndroid Build Coastguard Worker }
9225*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,InvalidGroups)9226*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, InvalidGroups) {
9227*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
9228*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
9229*8fb009dcSAndroid Build Coastguard Worker 
9230*8fb009dcSAndroid Build Coastguard Worker   static const uint16_t kInvalidIDs[] = {1234};
9231*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set1_group_ids(
9232*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), kInvalidIDs, OPENSSL_ARRAY_SIZE(kInvalidIDs)));
9233*8fb009dcSAndroid Build Coastguard Worker 
9234*8fb009dcSAndroid Build Coastguard Worker   // This is a valid NID, but it is not a valid group.
9235*8fb009dcSAndroid Build Coastguard Worker   static const int kInvalidNIDs[] = {NID_rsaEncryption};
9236*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_set1_groups(
9237*8fb009dcSAndroid Build Coastguard Worker       ctx.get(), kInvalidNIDs, OPENSSL_ARRAY_SIZE(kInvalidNIDs)));
9238*8fb009dcSAndroid Build Coastguard Worker }
9239*8fb009dcSAndroid Build Coastguard Worker 
TEST(SSLTest,NameLists)9240*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, NameLists) {
9241*8fb009dcSAndroid Build Coastguard Worker   struct {
9242*8fb009dcSAndroid Build Coastguard Worker     size_t (*func)(const char **, size_t);
9243*8fb009dcSAndroid Build Coastguard Worker     std::vector<std::string> expected;
9244*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
9245*8fb009dcSAndroid Build Coastguard Worker       {SSL_get_all_version_names, {"TLSv1.3", "DTLSv1.2", "unknown"}},
9246*8fb009dcSAndroid Build Coastguard Worker       {SSL_get_all_standard_cipher_names,
9247*8fb009dcSAndroid Build Coastguard Worker        {"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_AES_128_GCM_SHA256"}},
9248*8fb009dcSAndroid Build Coastguard Worker       {SSL_get_all_cipher_names,
9249*8fb009dcSAndroid Build Coastguard Worker        {"ECDHE-ECDSA-AES128-GCM-SHA256", "TLS_AES_128_GCM_SHA256", "(NONE)"}},
9250*8fb009dcSAndroid Build Coastguard Worker       {SSL_get_all_group_names, {"P-256", "X25519"}},
9251*8fb009dcSAndroid Build Coastguard Worker       {SSL_get_all_signature_algorithm_names,
9252*8fb009dcSAndroid Build Coastguard Worker        {"rsa_pkcs1_sha256", "ecdsa_secp256r1_sha256", "ecdsa_sha256"}},
9253*8fb009dcSAndroid Build Coastguard Worker   };
9254*8fb009dcSAndroid Build Coastguard Worker   for (const auto &t : kTests) {
9255*8fb009dcSAndroid Build Coastguard Worker     size_t num = t.func(nullptr, 0);
9256*8fb009dcSAndroid Build Coastguard Worker     EXPECT_GT(num, 0u);
9257*8fb009dcSAndroid Build Coastguard Worker 
9258*8fb009dcSAndroid Build Coastguard Worker     std::vector<const char*> list(num);
9259*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(num, t.func(list.data(), list.size()));
9260*8fb009dcSAndroid Build Coastguard Worker 
9261*8fb009dcSAndroid Build Coastguard Worker     // Check the expected values are in the list.
9262*8fb009dcSAndroid Build Coastguard Worker     for (const auto &s : t.expected) {
9263*8fb009dcSAndroid Build Coastguard Worker       EXPECT_NE(list.end(), std::find(list.begin(), list.end(), s))
9264*8fb009dcSAndroid Build Coastguard Worker           << "Could not find " << s;
9265*8fb009dcSAndroid Build Coastguard Worker     }
9266*8fb009dcSAndroid Build Coastguard Worker 
9267*8fb009dcSAndroid Build Coastguard Worker     // Passing in a larger buffer should leave excess space alone.
9268*8fb009dcSAndroid Build Coastguard Worker     std::vector<const char *> list2(num + 1, "placeholder");
9269*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(num, t.func(list2.data(), list2.size()));
9270*8fb009dcSAndroid Build Coastguard Worker     for (size_t i = 0; i < num; i++) {
9271*8fb009dcSAndroid Build Coastguard Worker       EXPECT_STREQ(list[i], list2[i]);
9272*8fb009dcSAndroid Build Coastguard Worker     }
9273*8fb009dcSAndroid Build Coastguard Worker     EXPECT_STREQ(list2.back(), "placeholder");
9274*8fb009dcSAndroid Build Coastguard Worker 
9275*8fb009dcSAndroid Build Coastguard Worker     // Passing in a shorter buffer should truncate the list.
9276*8fb009dcSAndroid Build Coastguard Worker     for (size_t l = 0; l < num; l++) {
9277*8fb009dcSAndroid Build Coastguard Worker       SCOPED_TRACE(l);
9278*8fb009dcSAndroid Build Coastguard Worker       list2.resize(l);
9279*8fb009dcSAndroid Build Coastguard Worker       EXPECT_EQ(num, t.func(list2.data(), list2.size()));
9280*8fb009dcSAndroid Build Coastguard Worker       for (size_t i = 0; i < l; i++) {
9281*8fb009dcSAndroid Build Coastguard Worker         EXPECT_STREQ(list[i], list2[i]);
9282*8fb009dcSAndroid Build Coastguard Worker       }
9283*8fb009dcSAndroid Build Coastguard Worker     }
9284*8fb009dcSAndroid Build Coastguard Worker   }
9285*8fb009dcSAndroid Build Coastguard Worker }
9286*8fb009dcSAndroid Build Coastguard Worker 
9287*8fb009dcSAndroid Build Coastguard Worker // Test that it is possible for the certificate to be configured on a mix of
9288*8fb009dcSAndroid Build Coastguard Worker // SSL_CTX and SSL. This ensures that we do not inadvertently overshare objects
9289*8fb009dcSAndroid Build Coastguard Worker // in SSL_new.
TEST(SSLTest,MixContextAndConnection)9290*8fb009dcSAndroid Build Coastguard Worker TEST(SSLTest, MixContextAndConnection) {
9291*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL_CTX> ctx(SSL_CTX_new(TLS_method()));
9292*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ctx);
9293*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetTestCertificate();
9294*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
9295*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetTestKey();
9296*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
9297*8fb009dcSAndroid Build Coastguard Worker 
9298*8fb009dcSAndroid Build Coastguard Worker   // Configure the certificate, but not the private key, on the context.
9299*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_CTX_use_certificate(ctx.get(), cert.get()));
9300*8fb009dcSAndroid Build Coastguard Worker 
9301*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl1(SSL_new(ctx.get()));
9302*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl1.get());
9303*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<SSL> ssl2(SSL_new(ctx.get()));
9304*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(ssl2.get());
9305*8fb009dcSAndroid Build Coastguard Worker 
9306*8fb009dcSAndroid Build Coastguard Worker   // There is no private key configured yet.
9307*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_get0_privatekey(ctx.get()));
9308*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_get_privatekey(ssl1.get()));
9309*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_get_privatekey(ssl2.get()));
9310*8fb009dcSAndroid Build Coastguard Worker 
9311*8fb009dcSAndroid Build Coastguard Worker   // Configuring the private key on |ssl1| works.
9312*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(SSL_use_PrivateKey(ssl1.get(), key.get()));
9313*8fb009dcSAndroid Build Coastguard Worker   EXPECT_TRUE(SSL_get_privatekey(ssl1.get()));
9314*8fb009dcSAndroid Build Coastguard Worker 
9315*8fb009dcSAndroid Build Coastguard Worker   // It does not impact the other connection or the context.
9316*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_CTX_get0_privatekey(ctx.get()));
9317*8fb009dcSAndroid Build Coastguard Worker   EXPECT_FALSE(SSL_get_privatekey(ssl2.get()));
9318*8fb009dcSAndroid Build Coastguard Worker }
9319*8fb009dcSAndroid Build Coastguard Worker 
9320*8fb009dcSAndroid Build Coastguard Worker // Test that the server handshake cleanly fails if it had no certificate
9321*8fb009dcSAndroid Build Coastguard Worker // configured, at all versions.
TEST_P(SSLVersionTest,NoCertOrKey)9322*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, NoCertOrKey) {
9323*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> cert = GetChainTestCertificate();
9324*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(cert);
9325*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> key = GetChainTestKey();
9326*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(key);
9327*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<X509> intermediate = GetChainTestIntermediate();
9328*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(intermediate);
9329*8fb009dcSAndroid Build Coastguard Worker   bssl::UniquePtr<STACK_OF(X509)> chain(sk_X509_new_null());
9330*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(chain);
9331*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(bssl::PushToStack(chain.get(), std::move(intermediate)));
9332*8fb009dcSAndroid Build Coastguard Worker 
9333*8fb009dcSAndroid Build Coastguard Worker   const struct {
9334*8fb009dcSAndroid Build Coastguard Worker     bool has_cert;
9335*8fb009dcSAndroid Build Coastguard Worker     bool has_key;
9336*8fb009dcSAndroid Build Coastguard Worker     bool has_chain;
9337*8fb009dcSAndroid Build Coastguard Worker   } kTests[] = {
9338*8fb009dcSAndroid Build Coastguard Worker     // If nothing is configured, there is unambiguously no certificate.
9339*8fb009dcSAndroid Build Coastguard Worker     {/*has_cert=*/false, /*has_key=*/false, /*has_chain=*/false},
9340*8fb009dcSAndroid Build Coastguard Worker 
9341*8fb009dcSAndroid Build Coastguard Worker     // If only one of the key and certificate is configured, it is still treated
9342*8fb009dcSAndroid Build Coastguard Worker     // as if there is no certificate.
9343*8fb009dcSAndroid Build Coastguard Worker     {/*has_cert=*/true, /*has_key=*/false, /*has_chain=*/false},
9344*8fb009dcSAndroid Build Coastguard Worker     {/*has_cert=*/false, /*has_key=*/true, /*has_chain=*/false},
9345*8fb009dcSAndroid Build Coastguard Worker 
9346*8fb009dcSAndroid Build Coastguard Worker     // The key and intermediates may be configured, but without a leaf there is
9347*8fb009dcSAndroid Build Coastguard Worker     // no certificate. This case is interesting because we internally store the
9348*8fb009dcSAndroid Build Coastguard Worker     // chain with a somewhat fragile null fist entry.
9349*8fb009dcSAndroid Build Coastguard Worker     {/*has_cert=*/false, /*has_key=*/true, /*has_chain=*/true},
9350*8fb009dcSAndroid Build Coastguard Worker   };
9351*8fb009dcSAndroid Build Coastguard Worker   for (const auto &t : kTests) {
9352*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message() << "has_cert = " << t.has_cert);
9353*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message() << "has_key = " << t.has_key);
9354*8fb009dcSAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message() << "has_chain = " << t.has_chain);
9355*8fb009dcSAndroid Build Coastguard Worker     for (bool client : {false, true}) {
9356*8fb009dcSAndroid Build Coastguard Worker       SCOPED_TRACE(testing::Message() << "client = " << client);
9357*8fb009dcSAndroid Build Coastguard Worker 
9358*8fb009dcSAndroid Build Coastguard Worker       EXPECT_NO_FATAL_FAILURE(ResetContexts());
9359*8fb009dcSAndroid Build Coastguard Worker       if (client) {
9360*8fb009dcSAndroid Build Coastguard Worker         // Request client certificates from the server.
9361*8fb009dcSAndroid Build Coastguard Worker         SSL_CTX_set_verify(server_ctx_.get(), SSL_VERIFY_PEER, nullptr);
9362*8fb009dcSAndroid Build Coastguard Worker         SSL_CTX_set_cert_verify_callback(client_ctx_.get(), VerifySucceed,
9363*8fb009dcSAndroid Build Coastguard Worker                                          nullptr);
9364*8fb009dcSAndroid Build Coastguard Worker       } else {
9365*8fb009dcSAndroid Build Coastguard Worker         // Recreate the server context. ResetContexts automatically adds server
9366*8fb009dcSAndroid Build Coastguard Worker         // certificates.
9367*8fb009dcSAndroid Build Coastguard Worker         server_ctx_ = CreateContext();
9368*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(server_ctx_);
9369*8fb009dcSAndroid Build Coastguard Worker       }
9370*8fb009dcSAndroid Build Coastguard Worker 
9371*8fb009dcSAndroid Build Coastguard Worker       SSL_CTX *ctx = client ? client_ctx_.get() : server_ctx_.get();
9372*8fb009dcSAndroid Build Coastguard Worker       if (t.has_cert) {
9373*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(SSL_CTX_use_certificate(ctx, cert.get()));
9374*8fb009dcSAndroid Build Coastguard Worker       }
9375*8fb009dcSAndroid Build Coastguard Worker       if (t.has_key) {
9376*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(SSL_CTX_use_PrivateKey(ctx, key.get()));
9377*8fb009dcSAndroid Build Coastguard Worker       }
9378*8fb009dcSAndroid Build Coastguard Worker       if (t.has_chain) {
9379*8fb009dcSAndroid Build Coastguard Worker         ASSERT_TRUE(SSL_CTX_set1_chain(ctx, chain.get()));
9380*8fb009dcSAndroid Build Coastguard Worker       }
9381*8fb009dcSAndroid Build Coastguard Worker 
9382*8fb009dcSAndroid Build Coastguard Worker       // In each of these cases, |SSL_CTX_check_private_key| should report the
9383*8fb009dcSAndroid Build Coastguard Worker       // certificate was not configured.
9384*8fb009dcSAndroid Build Coastguard Worker       EXPECT_FALSE(SSL_CTX_check_private_key(ctx));
9385*8fb009dcSAndroid Build Coastguard Worker       ERR_clear_error();
9386*8fb009dcSAndroid Build Coastguard Worker 
9387*8fb009dcSAndroid Build Coastguard Worker       if (client) {
9388*8fb009dcSAndroid Build Coastguard Worker         // The client should cleanly handshake without asserting a certificate.
9389*8fb009dcSAndroid Build Coastguard Worker         EXPECT_TRUE(Connect());
9390*8fb009dcSAndroid Build Coastguard Worker         EXPECT_FALSE(SSL_get0_peer_certificates(server_.get()));
9391*8fb009dcSAndroid Build Coastguard Worker       } else {
9392*8fb009dcSAndroid Build Coastguard Worker         // Servers cannot be anonymous. The connection should fail.
9393*8fb009dcSAndroid Build Coastguard Worker         EXPECT_FALSE(Connect());
9394*8fb009dcSAndroid Build Coastguard Worker         // Depending on the TLS version, this should either appear as
9395*8fb009dcSAndroid Build Coastguard Worker         // NO_SHARED_CIPHER (TLS 1.2) or NO_CERTIFICATE_SET (TLS 1.3).
9396*8fb009dcSAndroid Build Coastguard Worker         uint32_t err = ERR_get_error();
9397*8fb009dcSAndroid Build Coastguard Worker         if (!ErrorEquals(err, ERR_LIB_SSL, SSL_R_NO_SHARED_CIPHER)) {
9398*8fb009dcSAndroid Build Coastguard Worker           EXPECT_TRUE(ErrorEquals(err, ERR_LIB_SSL, SSL_R_NO_CERTIFICATE_SET));
9399*8fb009dcSAndroid Build Coastguard Worker         }
9400*8fb009dcSAndroid Build Coastguard Worker       }
9401*8fb009dcSAndroid Build Coastguard Worker     }
9402*8fb009dcSAndroid Build Coastguard Worker   }
9403*8fb009dcSAndroid Build Coastguard Worker }
9404*8fb009dcSAndroid Build Coastguard Worker 
TEST_P(SSLVersionTest,KeyLog)9405*8fb009dcSAndroid Build Coastguard Worker TEST_P(SSLVersionTest, KeyLog) {
9406*8fb009dcSAndroid Build Coastguard Worker   using KeyLog = std::map<std::string, std::vector<uint8_t>>;
9407*8fb009dcSAndroid Build Coastguard Worker   KeyLog client_log, server_log;
9408*8fb009dcSAndroid Build Coastguard Worker 
9409*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_app_data(client_ctx_.get(), &client_log);
9410*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_app_data(server_ctx_.get(), &server_log);
9411*8fb009dcSAndroid Build Coastguard Worker 
9412*8fb009dcSAndroid Build Coastguard Worker   auto keylog_callback = [](const SSL *ssl, const char *line) {
9413*8fb009dcSAndroid Build Coastguard Worker     SSL_CTX *ctx = SSL_get_SSL_CTX(ssl);
9414*8fb009dcSAndroid Build Coastguard Worker     KeyLog *log = static_cast<KeyLog *>(SSL_CTX_get_app_data(ctx));
9415*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(log);
9416*8fb009dcSAndroid Build Coastguard Worker 
9417*8fb009dcSAndroid Build Coastguard Worker     const char *space1 = strchr(line, ' ');
9418*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(space1);
9419*8fb009dcSAndroid Build Coastguard Worker     std::string name(line, space1 - line);
9420*8fb009dcSAndroid Build Coastguard Worker     space1++;
9421*8fb009dcSAndroid Build Coastguard Worker     const char *space2 = strchr(space1, ' ');
9422*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(space2);
9423*8fb009dcSAndroid Build Coastguard Worker     bssl::Span<const char> client_random_hex(space1, space2 - space1);
9424*8fb009dcSAndroid Build Coastguard Worker     space2++;
9425*8fb009dcSAndroid Build Coastguard Worker     bssl::Span<const char> secret_hex(space2, strlen(space2));
9426*8fb009dcSAndroid Build Coastguard Worker 
9427*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> client_random, secret;
9428*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(DecodeLowerHex(&client_random, client_random_hex));
9429*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(DecodeLowerHex(&secret, secret_hex));
9430*8fb009dcSAndroid Build Coastguard Worker 
9431*8fb009dcSAndroid Build Coastguard Worker     // The client_random field identifies the connection. Check it matches
9432*8fb009dcSAndroid Build Coastguard Worker     // the connection.
9433*8fb009dcSAndroid Build Coastguard Worker     uint8_t expected_random[SSL3_RANDOM_SIZE];
9434*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(
9435*8fb009dcSAndroid Build Coastguard Worker         sizeof(expected_random),
9436*8fb009dcSAndroid Build Coastguard Worker         SSL_get_client_random(ssl, expected_random, sizeof(expected_random)));
9437*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(Bytes(expected_random), Bytes(client_random));
9438*8fb009dcSAndroid Build Coastguard Worker 
9439*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(log->count(name), 0u) << "duplicate name " << name;
9440*8fb009dcSAndroid Build Coastguard Worker     log->emplace(std::move(name), std::move(secret));
9441*8fb009dcSAndroid Build Coastguard Worker   };
9442*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_keylog_callback(client_ctx_.get(), keylog_callback);
9443*8fb009dcSAndroid Build Coastguard Worker   SSL_CTX_set_keylog_callback(server_ctx_.get(), keylog_callback);
9444*8fb009dcSAndroid Build Coastguard Worker 
9445*8fb009dcSAndroid Build Coastguard Worker   // Connect and capture the various secrets.
9446*8fb009dcSAndroid Build Coastguard Worker   ASSERT_TRUE(Connect());
9447*8fb009dcSAndroid Build Coastguard Worker 
9448*8fb009dcSAndroid Build Coastguard Worker   // Check that we logged the secrets we expected to log.
9449*8fb009dcSAndroid Build Coastguard Worker   if (version() == TLS1_3_VERSION) {
9450*8fb009dcSAndroid Build Coastguard Worker     EXPECT_THAT(client_log, ElementsAre(Key("CLIENT_HANDSHAKE_TRAFFIC_SECRET"),
9451*8fb009dcSAndroid Build Coastguard Worker                                         Key("CLIENT_TRAFFIC_SECRET_0"),
9452*8fb009dcSAndroid Build Coastguard Worker                                         Key("EXPORTER_SECRET"),
9453*8fb009dcSAndroid Build Coastguard Worker                                         Key("SERVER_HANDSHAKE_TRAFFIC_SECRET"),
9454*8fb009dcSAndroid Build Coastguard Worker                                         Key("SERVER_TRAFFIC_SECRET_0")));
9455*8fb009dcSAndroid Build Coastguard Worker 
9456*8fb009dcSAndroid Build Coastguard Worker     // Ideally we'd check the other values, but those are harder to check
9457*8fb009dcSAndroid Build Coastguard Worker     // without actually decrypting the records.
9458*8fb009dcSAndroid Build Coastguard Worker     Span<const uint8_t> read_secret, write_secret;
9459*8fb009dcSAndroid Build Coastguard Worker     ASSERT_TRUE(bssl::SSL_get_traffic_secrets(client_.get(), &read_secret,
9460*8fb009dcSAndroid Build Coastguard Worker                                               &write_secret));
9461*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes(read_secret), Bytes(client_log["SERVER_TRAFFIC_SECRET_0"]));
9462*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes(write_secret),
9463*8fb009dcSAndroid Build Coastguard Worker               Bytes(client_log["CLIENT_TRAFFIC_SECRET_0"]));
9464*8fb009dcSAndroid Build Coastguard Worker   } else {
9465*8fb009dcSAndroid Build Coastguard Worker     EXPECT_THAT(client_log, ElementsAre(Key("CLIENT_RANDOM")));
9466*8fb009dcSAndroid Build Coastguard Worker 
9467*8fb009dcSAndroid Build Coastguard Worker     size_t len =
9468*8fb009dcSAndroid Build Coastguard Worker         SSL_SESSION_get_master_key(SSL_get0_session(client_.get()), nullptr, 0);
9469*8fb009dcSAndroid Build Coastguard Worker     std::vector<uint8_t> expected(len);
9470*8fb009dcSAndroid Build Coastguard Worker     ASSERT_EQ(SSL_SESSION_get_master_key(SSL_get0_session(client_.get()),
9471*8fb009dcSAndroid Build Coastguard Worker                                          expected.data(), expected.size()),
9472*8fb009dcSAndroid Build Coastguard Worker               expected.size());
9473*8fb009dcSAndroid Build Coastguard Worker     EXPECT_EQ(Bytes(expected), Bytes(client_log["CLIENT_RANDOM"]));
9474*8fb009dcSAndroid Build Coastguard Worker   }
9475*8fb009dcSAndroid Build Coastguard Worker 
9476*8fb009dcSAndroid Build Coastguard Worker   // The server should have logged the same secrets as the client.
9477*8fb009dcSAndroid Build Coastguard Worker   EXPECT_EQ(client_log, server_log);
9478*8fb009dcSAndroid Build Coastguard Worker }
9479*8fb009dcSAndroid Build Coastguard Worker 
9480*8fb009dcSAndroid Build Coastguard Worker }  // namespace
9481*8fb009dcSAndroid Build Coastguard Worker BSSL_NAMESPACE_END
9482