xref: /aosp_15_r20/external/pigweed/pw_tls_client/test_server.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2021 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker 
15*61c4878aSAndroid Build Coastguard Worker #include "pw_tls_client/test/test_server.h"
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker #include <cstring>
18*61c4878aSAndroid Build Coastguard Worker 
19*61c4878aSAndroid Build Coastguard Worker #include "pw_log/log.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_result/result.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_status/status.h"
22*61c4878aSAndroid Build Coastguard Worker #include "pw_stream/stream.h"
23*61c4878aSAndroid Build Coastguard Worker 
24*61c4878aSAndroid Build Coastguard Worker namespace {
25*61c4878aSAndroid Build Coastguard Worker 
TestBioNew(BIO * bio)26*61c4878aSAndroid Build Coastguard Worker int TestBioNew(BIO* bio) {
27*61c4878aSAndroid Build Coastguard Worker   bio->init = 1;
28*61c4878aSAndroid Build Coastguard Worker   return 1;
29*61c4878aSAndroid Build Coastguard Worker }
30*61c4878aSAndroid Build Coastguard Worker 
TestBioCtrl(BIO *,int,long,void *)31*61c4878aSAndroid Build Coastguard Worker long TestBioCtrl(BIO*, int, long, void*) { return 1; }
32*61c4878aSAndroid Build Coastguard Worker 
TestBioFree(BIO *)33*61c4878aSAndroid Build Coastguard Worker int TestBioFree(BIO*) { return 1; }
34*61c4878aSAndroid Build Coastguard Worker 
35*61c4878aSAndroid Build Coastguard Worker }  // namespace
36*61c4878aSAndroid Build Coastguard Worker 
37*61c4878aSAndroid Build Coastguard Worker namespace pw::tls_client::test {
38*61c4878aSAndroid Build Coastguard Worker 
ParseDerCertificate(ConstByteSpan cert)39*61c4878aSAndroid Build Coastguard Worker Result<X509*> ParseDerCertificate(ConstByteSpan cert) {
40*61c4878aSAndroid Build Coastguard Worker   BIO* bio = BIO_new_mem_buf(cert.data(), cert.size());
41*61c4878aSAndroid Build Coastguard Worker   if (!bio) {
42*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
43*61c4878aSAndroid Build Coastguard Worker   }
44*61c4878aSAndroid Build Coastguard Worker 
45*61c4878aSAndroid Build Coastguard Worker   X509* x509 = d2i_X509_bio(bio, nullptr);
46*61c4878aSAndroid Build Coastguard Worker   if (x509 == nullptr) {
47*61c4878aSAndroid Build Coastguard Worker     PW_LOG_DEBUG("Failed to parse x509");
48*61c4878aSAndroid Build Coastguard Worker     BIO_free(bio);
49*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
50*61c4878aSAndroid Build Coastguard Worker   }
51*61c4878aSAndroid Build Coastguard Worker 
52*61c4878aSAndroid Build Coastguard Worker   BIO_free(bio);
53*61c4878aSAndroid Build Coastguard Worker   return x509;
54*61c4878aSAndroid Build Coastguard Worker }
55*61c4878aSAndroid Build Coastguard Worker 
DoRead(ByteSpan dest)56*61c4878aSAndroid Build Coastguard Worker StatusWithSize FixedSizeFIFOBuffer::DoRead(ByteSpan dest) {
57*61c4878aSAndroid Build Coastguard Worker   size_t to_read = std::min(current_size_, dest.size());
58*61c4878aSAndroid Build Coastguard Worker   memcpy(dest.data(), buffer_.data(), to_read);
59*61c4878aSAndroid Build Coastguard Worker   // Push out the read data.
60*61c4878aSAndroid Build Coastguard Worker   memmove(buffer_.data(), buffer_.data() + to_read, current_size_ - to_read);
61*61c4878aSAndroid Build Coastguard Worker   current_size_ -= to_read;
62*61c4878aSAndroid Build Coastguard Worker   return StatusWithSize(to_read);
63*61c4878aSAndroid Build Coastguard Worker }
64*61c4878aSAndroid Build Coastguard Worker 
DoWrite(ConstByteSpan data)65*61c4878aSAndroid Build Coastguard Worker Status FixedSizeFIFOBuffer::DoWrite(ConstByteSpan data) {
66*61c4878aSAndroid Build Coastguard Worker   if (data.size() + current_size_ > buffer_.size()) {
67*61c4878aSAndroid Build Coastguard Worker     PW_LOG_ERROR("Write overflow. Buffer is too small.");
68*61c4878aSAndroid Build Coastguard Worker     return Status::ResourceExhausted();
69*61c4878aSAndroid Build Coastguard Worker   }
70*61c4878aSAndroid Build Coastguard Worker 
71*61c4878aSAndroid Build Coastguard Worker   // Append incoming data at the end.
72*61c4878aSAndroid Build Coastguard Worker   memcpy(buffer_.begin() + current_size_, data.data(), data.size());
73*61c4878aSAndroid Build Coastguard Worker   current_size_ += data.size();
74*61c4878aSAndroid Build Coastguard Worker   return OkStatus();
75*61c4878aSAndroid Build Coastguard Worker }
76*61c4878aSAndroid Build Coastguard Worker 
InMemoryTestServer(ByteSpan input_buffer,ByteSpan output_buffer)77*61c4878aSAndroid Build Coastguard Worker InMemoryTestServer::InMemoryTestServer(ByteSpan input_buffer,
78*61c4878aSAndroid Build Coastguard Worker                                        ByteSpan output_buffer)
79*61c4878aSAndroid Build Coastguard Worker     : input_buffer_(input_buffer), output_buffer_(output_buffer) {}
80*61c4878aSAndroid Build Coastguard Worker 
BioRead(BIO * bio,char * out,int output_length)81*61c4878aSAndroid Build Coastguard Worker int InMemoryTestServer::BioRead(BIO* bio, char* out, int output_length) {
82*61c4878aSAndroid Build Coastguard Worker   auto server = static_cast<InMemoryTestServer*>(bio->ptr);
83*61c4878aSAndroid Build Coastguard Worker   auto read = server->input_buffer_.Read(
84*61c4878aSAndroid Build Coastguard Worker       as_writable_bytes(span{out, static_cast<size_t>(output_length)}));
85*61c4878aSAndroid Build Coastguard Worker   if (!read.ok()) {
86*61c4878aSAndroid Build Coastguard Worker     server->last_bio_status_ = read.status();
87*61c4878aSAndroid Build Coastguard Worker     return -1;
88*61c4878aSAndroid Build Coastguard Worker   }
89*61c4878aSAndroid Build Coastguard Worker   if (read.value().empty()) {
90*61c4878aSAndroid Build Coastguard Worker     BIO_set_retry_read(bio);
91*61c4878aSAndroid Build Coastguard Worker     return -1;
92*61c4878aSAndroid Build Coastguard Worker   }
93*61c4878aSAndroid Build Coastguard Worker   return static_cast<int>(read.value().size());
94*61c4878aSAndroid Build Coastguard Worker }
95*61c4878aSAndroid Build Coastguard Worker 
BioWrite(BIO * bio,const char * input,int input_length)96*61c4878aSAndroid Build Coastguard Worker int InMemoryTestServer::BioWrite(BIO* bio,
97*61c4878aSAndroid Build Coastguard Worker                                  const char* input,
98*61c4878aSAndroid Build Coastguard Worker                                  int input_length) {
99*61c4878aSAndroid Build Coastguard Worker   auto server = static_cast<InMemoryTestServer*>(bio->ptr);
100*61c4878aSAndroid Build Coastguard Worker   if (auto status = server->output_buffer_.Write(
101*61c4878aSAndroid Build Coastguard Worker           as_bytes(span{input, static_cast<size_t>(input_length)}));
102*61c4878aSAndroid Build Coastguard Worker       !status.ok()) {
103*61c4878aSAndroid Build Coastguard Worker     server->last_bio_status_ = status;
104*61c4878aSAndroid Build Coastguard Worker     return -1;
105*61c4878aSAndroid Build Coastguard Worker   }
106*61c4878aSAndroid Build Coastguard Worker 
107*61c4878aSAndroid Build Coastguard Worker   return input_length;
108*61c4878aSAndroid Build Coastguard Worker }
109*61c4878aSAndroid Build Coastguard Worker 
Initialize(ConstByteSpan key,ConstByteSpan cert,span<const ConstByteSpan> chains)110*61c4878aSAndroid Build Coastguard Worker Status InMemoryTestServer::Initialize(ConstByteSpan key,
111*61c4878aSAndroid Build Coastguard Worker                                       ConstByteSpan cert,
112*61c4878aSAndroid Build Coastguard Worker                                       span<const ConstByteSpan> chains) {
113*61c4878aSAndroid Build Coastguard Worker   input_buffer_.clear();
114*61c4878aSAndroid Build Coastguard Worker   output_buffer_.clear();
115*61c4878aSAndroid Build Coastguard Worker   is_handshake_done_ = false;
116*61c4878aSAndroid Build Coastguard Worker 
117*61c4878aSAndroid Build Coastguard Worker   ctx_ = bssl::UniquePtr<SSL_CTX>(SSL_CTX_new(TLS_method()));
118*61c4878aSAndroid Build Coastguard Worker   if (!ctx_) {
119*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
120*61c4878aSAndroid Build Coastguard Worker   }
121*61c4878aSAndroid Build Coastguard Worker 
122*61c4878aSAndroid Build Coastguard Worker   if (auto status = LoadPrivateKey(key); !status.ok()) {
123*61c4878aSAndroid Build Coastguard Worker     return status;
124*61c4878aSAndroid Build Coastguard Worker   }
125*61c4878aSAndroid Build Coastguard Worker 
126*61c4878aSAndroid Build Coastguard Worker   if (auto status = LoadCertificate(cert); !status.ok()) {
127*61c4878aSAndroid Build Coastguard Worker     return status;
128*61c4878aSAndroid Build Coastguard Worker   }
129*61c4878aSAndroid Build Coastguard Worker 
130*61c4878aSAndroid Build Coastguard Worker   if (auto status = LoadCAChain(chains); !status.ok()) {
131*61c4878aSAndroid Build Coastguard Worker     return status;
132*61c4878aSAndroid Build Coastguard Worker   }
133*61c4878aSAndroid Build Coastguard Worker 
134*61c4878aSAndroid Build Coastguard Worker   ssl_ = bssl::UniquePtr<SSL>(SSL_new(ctx_.get()));
135*61c4878aSAndroid Build Coastguard Worker   if (!ssl_) {
136*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
137*61c4878aSAndroid Build Coastguard Worker   }
138*61c4878aSAndroid Build Coastguard Worker 
139*61c4878aSAndroid Build Coastguard Worker   static const BIO_METHOD bio_method = {
140*61c4878aSAndroid Build Coastguard Worker       BIO_TYPE_MEM,
141*61c4878aSAndroid Build Coastguard Worker       "bio boringssl test server",
142*61c4878aSAndroid Build Coastguard Worker       InMemoryTestServer::BioWrite,
143*61c4878aSAndroid Build Coastguard Worker       InMemoryTestServer::BioRead,
144*61c4878aSAndroid Build Coastguard Worker       nullptr,      // puts
145*61c4878aSAndroid Build Coastguard Worker       nullptr,      // gets
146*61c4878aSAndroid Build Coastguard Worker       TestBioCtrl,  // ctrl
147*61c4878aSAndroid Build Coastguard Worker       TestBioNew,
148*61c4878aSAndroid Build Coastguard Worker       TestBioFree,  // free
149*61c4878aSAndroid Build Coastguard Worker       nullptr       // callback_ctrl
150*61c4878aSAndroid Build Coastguard Worker   };
151*61c4878aSAndroid Build Coastguard Worker 
152*61c4878aSAndroid Build Coastguard Worker   BIO* bio = BIO_new(&bio_method);
153*61c4878aSAndroid Build Coastguard Worker   if (!bio) {
154*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
155*61c4878aSAndroid Build Coastguard Worker   }
156*61c4878aSAndroid Build Coastguard Worker 
157*61c4878aSAndroid Build Coastguard Worker   bio->ptr = this;
158*61c4878aSAndroid Build Coastguard Worker 
159*61c4878aSAndroid Build Coastguard Worker   SSL_set_bio(ssl_.get(), bio, bio);
160*61c4878aSAndroid Build Coastguard Worker   return OkStatus();
161*61c4878aSAndroid Build Coastguard Worker }
162*61c4878aSAndroid Build Coastguard Worker 
LoadPrivateKey(ConstByteSpan key)163*61c4878aSAndroid Build Coastguard Worker Status InMemoryTestServer::LoadPrivateKey(ConstByteSpan key) {
164*61c4878aSAndroid Build Coastguard Worker   BIO* bio = BIO_new_mem_buf(key.data(), key.size());
165*61c4878aSAndroid Build Coastguard Worker   if (!bio) {
166*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
167*61c4878aSAndroid Build Coastguard Worker   }
168*61c4878aSAndroid Build Coastguard Worker 
169*61c4878aSAndroid Build Coastguard Worker   // Requires PEM format.
170*61c4878aSAndroid Build Coastguard Worker   EVP_PKEY* pkey = d2i_PrivateKey_bio(bio, nullptr);
171*61c4878aSAndroid Build Coastguard Worker   int ret = SSL_CTX_use_PrivateKey(ctx_.get(), pkey);
172*61c4878aSAndroid Build Coastguard Worker   if (ret != 1) {
173*61c4878aSAndroid Build Coastguard Worker     BIO_free(bio);
174*61c4878aSAndroid Build Coastguard Worker     PW_LOG_DEBUG("Failed to load private key for test server");
175*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
176*61c4878aSAndroid Build Coastguard Worker   }
177*61c4878aSAndroid Build Coastguard Worker 
178*61c4878aSAndroid Build Coastguard Worker   EVP_PKEY_free(pkey);
179*61c4878aSAndroid Build Coastguard Worker   BIO_free(bio);
180*61c4878aSAndroid Build Coastguard Worker   return OkStatus();
181*61c4878aSAndroid Build Coastguard Worker }
182*61c4878aSAndroid Build Coastguard Worker 
LoadCertificate(ConstByteSpan cert)183*61c4878aSAndroid Build Coastguard Worker Status InMemoryTestServer::LoadCertificate(ConstByteSpan cert) {
184*61c4878aSAndroid Build Coastguard Worker   auto res = ParseDerCertificate(cert);
185*61c4878aSAndroid Build Coastguard Worker   if (!res.ok()) {
186*61c4878aSAndroid Build Coastguard Worker     return res.status();
187*61c4878aSAndroid Build Coastguard Worker   }
188*61c4878aSAndroid Build Coastguard Worker 
189*61c4878aSAndroid Build Coastguard Worker   int ret = SSL_CTX_use_certificate(ctx_.get(), res.value());
190*61c4878aSAndroid Build Coastguard Worker   if (ret != 1) {
191*61c4878aSAndroid Build Coastguard Worker     X509_free(res.value());
192*61c4878aSAndroid Build Coastguard Worker     PW_LOG_DEBUG("Failed to user server certificate %d", ret);
193*61c4878aSAndroid Build Coastguard Worker     return Status::Internal();
194*61c4878aSAndroid Build Coastguard Worker   }
195*61c4878aSAndroid Build Coastguard Worker 
196*61c4878aSAndroid Build Coastguard Worker   X509_free(res.value());
197*61c4878aSAndroid Build Coastguard Worker   return OkStatus();
198*61c4878aSAndroid Build Coastguard Worker }
199*61c4878aSAndroid Build Coastguard Worker 
LoadCAChain(span<const ConstByteSpan> chains)200*61c4878aSAndroid Build Coastguard Worker Status InMemoryTestServer::LoadCAChain(span<const ConstByteSpan> chains) {
201*61c4878aSAndroid Build Coastguard Worker   for (auto cert : chains) {
202*61c4878aSAndroid Build Coastguard Worker     auto res = ParseDerCertificate(cert);
203*61c4878aSAndroid Build Coastguard Worker     if (!res.ok()) {
204*61c4878aSAndroid Build Coastguard Worker       return res.status();
205*61c4878aSAndroid Build Coastguard Worker     }
206*61c4878aSAndroid Build Coastguard Worker 
207*61c4878aSAndroid Build Coastguard Worker     int ret = SSL_CTX_add0_chain_cert(ctx_.get(), res.value());
208*61c4878aSAndroid Build Coastguard Worker     if (ret != 1) {
209*61c4878aSAndroid Build Coastguard Worker       X509_free(res.value());
210*61c4878aSAndroid Build Coastguard Worker       PW_LOG_DEBUG("Failed to add certificate to chain %d", ret);
211*61c4878aSAndroid Build Coastguard Worker       return Status::Internal();
212*61c4878aSAndroid Build Coastguard Worker     }
213*61c4878aSAndroid Build Coastguard Worker   }
214*61c4878aSAndroid Build Coastguard Worker   return OkStatus();
215*61c4878aSAndroid Build Coastguard Worker }
216*61c4878aSAndroid Build Coastguard Worker 
ClientShutdownReceived()217*61c4878aSAndroid Build Coastguard Worker bool InMemoryTestServer::ClientShutdownReceived() {
218*61c4878aSAndroid Build Coastguard Worker   return SSL_get_shutdown(ssl_.get()) & SSL_RECEIVED_SHUTDOWN;
219*61c4878aSAndroid Build Coastguard Worker }
220*61c4878aSAndroid Build Coastguard Worker 
ProcessPackets()221*61c4878aSAndroid Build Coastguard Worker Status InMemoryTestServer::ProcessPackets() {
222*61c4878aSAndroid Build Coastguard Worker   // Process handshake if it has not been completed.
223*61c4878aSAndroid Build Coastguard Worker   if (!is_handshake_done_) {
224*61c4878aSAndroid Build Coastguard Worker     int ret = SSL_accept(ssl_.get());
225*61c4878aSAndroid Build Coastguard Worker     if (ret != 1) {
226*61c4878aSAndroid Build Coastguard Worker       int ssl_err = SSL_get_error(ssl_.get(), ret);
227*61c4878aSAndroid Build Coastguard Worker       if (ssl_err != SSL_ERROR_WANT_READ) {
228*61c4878aSAndroid Build Coastguard Worker         PW_LOG_DEBUG("Error while server accepting, %d, %d", ssl_err, ret);
229*61c4878aSAndroid Build Coastguard Worker         return Status::Internal();
230*61c4878aSAndroid Build Coastguard Worker       }
231*61c4878aSAndroid Build Coastguard Worker     } else {
232*61c4878aSAndroid Build Coastguard Worker       // handshake complete.
233*61c4878aSAndroid Build Coastguard Worker       is_handshake_done_ = true;
234*61c4878aSAndroid Build Coastguard Worker     }
235*61c4878aSAndroid Build Coastguard Worker   }
236*61c4878aSAndroid Build Coastguard Worker 
237*61c4878aSAndroid Build Coastguard Worker   // Hanshake may be completed above and there may already be application data.
238*61c4878aSAndroid Build Coastguard Worker   if (is_handshake_done_) {
239*61c4878aSAndroid Build Coastguard Worker     static std::array<std::byte, 1024> buf;
240*61c4878aSAndroid Build Coastguard Worker     while (true) {
241*61c4878aSAndroid Build Coastguard Worker       int ssl_ret = SSL_read(ssl_.get(), buf.data(), buf.size());
242*61c4878aSAndroid Build Coastguard Worker 
243*61c4878aSAndroid Build Coastguard Worker       if (ssl_ret == 0) {
244*61c4878aSAndroid Build Coastguard Worker         // All input has been processed.
245*61c4878aSAndroid Build Coastguard Worker         break;
246*61c4878aSAndroid Build Coastguard Worker       }
247*61c4878aSAndroid Build Coastguard Worker 
248*61c4878aSAndroid Build Coastguard Worker       if (ssl_ret < 0) {
249*61c4878aSAndroid Build Coastguard Worker         // An error may have occured.
250*61c4878aSAndroid Build Coastguard Worker         int ssl_err = SSL_get_error(ssl_.get(), ssl_ret);
251*61c4878aSAndroid Build Coastguard Worker         if (ssl_err == SSL_ERROR_WANT_READ) {
252*61c4878aSAndroid Build Coastguard Worker           // Need to wait for client to finish sending data. Non-blocking
253*61c4878aSAndroid Build Coastguard Worker           // return.
254*61c4878aSAndroid Build Coastguard Worker           break;
255*61c4878aSAndroid Build Coastguard Worker         }
256*61c4878aSAndroid Build Coastguard Worker 
257*61c4878aSAndroid Build Coastguard Worker         PW_LOG_DEBUG("Error while server reading");
258*61c4878aSAndroid Build Coastguard Worker         return Status::Internal();
259*61c4878aSAndroid Build Coastguard Worker       }
260*61c4878aSAndroid Build Coastguard Worker 
261*61c4878aSAndroid Build Coastguard Worker       // Echo the message
262*61c4878aSAndroid Build Coastguard Worker       int write_status = SSL_write(ssl_.get(), buf.data(), ssl_ret);
263*61c4878aSAndroid Build Coastguard Worker       if (write_status <= 0) {
264*61c4878aSAndroid Build Coastguard Worker         PW_LOG_DEBUG("Failed to write for test server");
265*61c4878aSAndroid Build Coastguard Worker         return Status::Internal();
266*61c4878aSAndroid Build Coastguard Worker       }
267*61c4878aSAndroid Build Coastguard Worker     }
268*61c4878aSAndroid Build Coastguard Worker   }
269*61c4878aSAndroid Build Coastguard Worker 
270*61c4878aSAndroid Build Coastguard Worker   return OkStatus();
271*61c4878aSAndroid Build Coastguard Worker }
272*61c4878aSAndroid Build Coastguard Worker 
DoRead(ByteSpan dest)273*61c4878aSAndroid Build Coastguard Worker StatusWithSize InMemoryTestServer::DoRead(ByteSpan dest) {
274*61c4878aSAndroid Build Coastguard Worker   auto res = output_buffer_.Read(dest);
275*61c4878aSAndroid Build Coastguard Worker   if (!res.ok()) {
276*61c4878aSAndroid Build Coastguard Worker     return StatusWithSize(res.status(), 0);
277*61c4878aSAndroid Build Coastguard Worker   }
278*61c4878aSAndroid Build Coastguard Worker 
279*61c4878aSAndroid Build Coastguard Worker   return StatusWithSize(res.value().size());
280*61c4878aSAndroid Build Coastguard Worker }
281*61c4878aSAndroid Build Coastguard Worker 
DoWrite(ConstByteSpan data)282*61c4878aSAndroid Build Coastguard Worker Status InMemoryTestServer::DoWrite(ConstByteSpan data) {
283*61c4878aSAndroid Build Coastguard Worker   auto status = input_buffer_.Write(data);
284*61c4878aSAndroid Build Coastguard Worker   if (!status.ok()) {
285*61c4878aSAndroid Build Coastguard Worker     return status;
286*61c4878aSAndroid Build Coastguard Worker   }
287*61c4878aSAndroid Build Coastguard Worker 
288*61c4878aSAndroid Build Coastguard Worker   // Invoke the server to process the data.
289*61c4878aSAndroid Build Coastguard Worker   return ProcessPackets();
290*61c4878aSAndroid Build Coastguard Worker }
291*61c4878aSAndroid Build Coastguard Worker 
292*61c4878aSAndroid Build Coastguard Worker }  // namespace pw::tls_client::test
293