1 /** @file
2
3 A brief file description
4
5 @section license License
6
7 Licensed to the Apache Software Foundation (ASF) under one
8 or more contributor license agreements. See the NOTICE file
9 distributed with this work for additional information
10 regarding copyright ownership. The ASF licenses this file
11 to you under the Apache License, Version 2.0 (the
12 "License"); you may not use this file except in compliance
13 with the License. You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
23
24 #include "tscore/ink_config.h"
25 #include "tscore/EventNotify.h"
26 #include "tscore/I_Layout.h"
27 #include "tscore/TSSystemState.h"
28
29 #include "InkAPIInternal.h" // Added to include the ssl_hook definitions
30 #include "Log.h"
31 #include "HttpTunnel.h"
32 #include "ProxyProtocol.h"
33 #include "HttpConfig.h"
34
35 #include "P_Net.h"
36 #include "P_SSLUtils.h"
37 #include "P_SSLNextProtocolSet.h"
38 #include "P_SSLConfig.h"
39 #include "P_SSLClientUtils.h"
40 #include "P_SSLSNI.h"
41 #include "BIO_fastopen.h"
42 #include "SSLStats.h"
43 #include "SSLInternal.h"
44 #include "P_ALPNSupport.h"
45
46 #include <climits>
47 #include <string>
48 #include <cstring>
49
50 using namespace std::literals;
51
52 #if TS_USE_TLS_ASYNC
53 #include <openssl/async.h>
54 #endif
55
56 // This is missing from BoringSSL
57 #ifndef BIO_eof
58 #define BIO_eof(b) (int)BIO_ctrl(b, BIO_CTRL_EOF, 0, nullptr)
59 #endif
60
61 #define SSL_READ_ERROR_NONE 0
62 #define SSL_READ_ERROR 1
63 #define SSL_READ_READY 2
64 #define SSL_READ_COMPLETE 3
65 #define SSL_READ_WOULD_BLOCK 4
66 #define SSL_READ_EOS 5
67 #define SSL_HANDSHAKE_WANT_READ 6
68 #define SSL_HANDSHAKE_WANT_WRITE 7
69 #define SSL_HANDSHAKE_WANT_ACCEPT 8
70 #define SSL_HANDSHAKE_WANT_CONNECT 9
71 #define SSL_WRITE_WOULD_BLOCK 10
72 #define SSL_WAIT_FOR_HOOK 11
73 #define SSL_WAIT_FOR_ASYNC 12
74
75 ClassAllocator<SSLNetVConnection> sslNetVCAllocator("sslNetVCAllocator");
76
77 namespace
78 {
79 /// Callback to get two locks.
80 /// The lock for this continuation, and for the target continuation.
81 class ContWrapper : public Continuation
82 {
83 public:
84 /** Constructor.
85 This takes the secondary @a mutex and the @a target continuation
86 to invoke, along with the arguments for that invocation.
87 */
ContWrapper(ProxyMutex * mutex,Continuation * target,int eventId=EVENT_IMMEDIATE,void * edata=nullptr)88 ContWrapper(ProxyMutex *mutex, ///< Mutex for this continuation (primary lock).
89 Continuation *target, ///< "Real" continuation we want to call.
90 int eventId = EVENT_IMMEDIATE, ///< Event ID for invocation of @a target.
91 void *edata = nullptr ///< Data for invocation of @a target.
92 )
93 : Continuation(mutex), _target(target), _eventId(eventId), _edata(edata)
94 {
95 SET_HANDLER(&ContWrapper::event_handler);
96 }
97
98 /// Required event handler method.
99 int
event_handler(int,void *)100 event_handler(int, void *)
101 {
102 EThread *eth = this_ethread();
103
104 MUTEX_TRY_LOCK(lock, _target->mutex, eth);
105 if (lock.is_locked()) { // got the target lock, we can proceed.
106 _target->handleEvent(_eventId, _edata);
107 delete this;
108 } else { // can't get both locks, try again.
109 eventProcessor.schedule_imm(this, ET_NET);
110 }
111 return 0;
112 }
113
114 /** Convenience static method.
115
116 This lets a client make one call and not have to (accurately)
117 copy the invocation logic embedded here. We duplicate it near
118 by textually so it is easier to keep in sync.
119
120 This takes the same arguments as the constructor but, if the
121 lock can be obtained immediately, does not construct an
122 instance but simply calls the @a target.
123 */
124 static void
wrap(ProxyMutex * mutex,Continuation * target,int eventId=EVENT_IMMEDIATE,void * edata=nullptr)125 wrap(ProxyMutex *mutex, ///< Mutex for this continuation (primary lock).
126 Continuation *target, ///< "Real" continuation we want to call.
127 int eventId = EVENT_IMMEDIATE, ///< Event ID for invocation of @a target.
128 void *edata = nullptr ///< Data for invocation of @a target.
129 )
130 {
131 EThread *eth = this_ethread();
132 if (!target->mutex) {
133 // If there's no mutex, plugin doesn't care about locking so why should we?
134 target->handleEvent(eventId, edata);
135 } else {
136 MUTEX_TRY_LOCK(lock, target->mutex, eth);
137 if (lock.is_locked()) {
138 target->handleEvent(eventId, edata);
139 } else {
140 eventProcessor.schedule_imm(new ContWrapper(mutex, target, eventId, edata), ET_NET);
141 }
142 }
143 }
144
145 private:
146 Continuation *_target; ///< Continuation to invoke.
147 int _eventId; ///< with this event
148 void *_edata; ///< and this data
149 };
150 } // namespace
151
152 //
153 // Private
154 //
155
156 void
_make_ssl_connection(SSL_CTX * ctx)157 SSLNetVConnection::_make_ssl_connection(SSL_CTX *ctx)
158 {
159 if (likely(this->ssl = SSL_new(ctx))) {
160 // Only set up the bio stuff for the server side
161 if (this->get_context() == NET_VCONNECTION_OUT) {
162 BIO *bio = BIO_new(const_cast<BIO_METHOD *>(BIO_s_fastopen()));
163 BIO_set_fd(bio, this->get_socket(), BIO_NOCLOSE);
164
165 if (this->options.f_tcp_fastopen) {
166 BIO_set_conn_address(bio, this->get_remote_addr());
167 }
168
169 SSL_set_bio(ssl, bio, bio);
170 } else {
171 this->initialize_handshake_buffers();
172 BIO *rbio = BIO_new(BIO_s_mem());
173 BIO *wbio = BIO_new_fd(this->get_socket(), BIO_NOCLOSE);
174 BIO_set_mem_eof_return(wbio, -1);
175 SSL_set_bio(ssl, rbio, wbio);
176
177 #if TS_HAS_TLS_EARLY_DATA
178 // Must disable OpenSSL's internal anti-replay if external cache is used with
179 // 0-rtt, otherwise session reuse will be broken. The freshness check described
180 // in https://tools.ietf.org/html/rfc8446#section-8.3 is still performed. But we
181 // still need to implement something to try to prevent replay atacks.
182 //
183 // We are now also disabling this when using OpenSSL's internal cache, since we
184 // are calling "ssl_accept" non-blocking, it seems to be confusing the anti-replay
185 // mechanism and causing session resumption to fail.
186 SSLConfig::scoped_config params;
187 if (SSL_version(ssl) >= TLS1_3_VERSION && params->server_max_early_data > 0) {
188 bool ret1 = false;
189 bool ret2 = false;
190 if ((ret1 = SSL_set_max_early_data(ssl, params->server_max_early_data)) == 1) {
191 Debug("ssl_early_data", "SSL_set_max_early_data: success");
192 } else {
193 Debug("ssl_early_data", "SSL_set_max_early_data: failed");
194 }
195
196 if ((ret2 = SSL_set_recv_max_early_data(ssl, params->server_recv_max_early_data)) == 1) {
197 Debug("ssl_early_data", "SSL_set_recv_max_early_data: success");
198 } else {
199 Debug("ssl_early_data", "SSL_set_recv_max_early_data: failed");
200 }
201
202 if (ret1 && ret2) {
203 Debug("ssl_early_data", "Must disable anti-replay if 0-rtt is enabled.");
204 SSL_set_options(ssl, SSL_OP_NO_ANTI_REPLAY);
205 }
206 }
207 #endif
208 }
209 this->_bindSSLObject();
210 }
211 }
212
213 void
_bindSSLObject()214 SSLNetVConnection::_bindSSLObject()
215 {
216 SSLNetVCAttach(this->ssl, this);
217 TLSSessionResumptionSupport::bind(this->ssl, this);
218 TLSSNISupport::bind(this->ssl, this);
219 }
220
221 void
_unbindSSLObject()222 SSLNetVConnection::_unbindSSLObject()
223 {
224 SSLNetVCDetach(this->ssl);
225 TLSSessionResumptionSupport::unbind(this->ssl);
226 TLSSNISupport::unbind(this->ssl);
227 }
228
229 static void
debug_certificate_name(const char * msg,X509_NAME * name)230 debug_certificate_name(const char *msg, X509_NAME *name)
231 {
232 BIO *bio;
233
234 if (name == nullptr) {
235 return;
236 }
237
238 bio = BIO_new(BIO_s_mem());
239 if (bio == nullptr) {
240 return;
241 }
242
243 if (X509_NAME_print_ex(bio, name, 0 /* indent */, XN_FLAG_ONELINE) > 0) {
244 long len;
245 char *ptr;
246 len = BIO_get_mem_data(bio, &ptr);
247 Debug("ssl", "%s %.*s", msg, (int)len, ptr);
248 }
249
250 BIO_free(bio);
251 }
252
253 static int
ssl_read_from_net(SSLNetVConnection * sslvc,EThread * lthread,int64_t & ret)254 ssl_read_from_net(SSLNetVConnection *sslvc, EThread *lthread, int64_t &ret)
255 {
256 NetState *s = &sslvc->read;
257 MIOBufferAccessor &buf = s->vio.buffer;
258 int event = SSL_READ_ERROR_NONE;
259 int64_t bytes_read = 0;
260 ssl_error_t sslErr = SSL_ERROR_NONE;
261
262 int64_t toread = buf.writer()->write_avail();
263 ink_release_assert(toread > 0);
264 if (toread > s->vio.ntodo()) {
265 toread = s->vio.ntodo();
266 }
267
268 bytes_read = 0;
269 while (sslErr == SSL_ERROR_NONE && bytes_read < toread) {
270 int64_t nread = 0;
271 int64_t block_write_avail = buf.writer()->block_write_avail();
272 ink_release_assert(block_write_avail > 0);
273 int64_t amount_to_read = toread - bytes_read;
274 if (amount_to_read > block_write_avail) {
275 amount_to_read = block_write_avail;
276 }
277
278 Debug("ssl", "amount_to_read=%" PRId64, amount_to_read);
279 char *current_block = buf.writer()->end();
280 ink_release_assert(current_block != nullptr);
281 sslErr = SSLReadBuffer(sslvc->ssl, current_block, amount_to_read, nread);
282
283 Debug("ssl", "nread=%" PRId64, nread);
284
285 switch (sslErr) {
286 case SSL_ERROR_NONE:
287
288 #if DEBUG
289 SSLDebugBufferPrint("ssl_buff", current_block, nread, "SSL Read");
290 #endif
291 ink_assert(nread);
292 bytes_read += nread;
293 if (nread > 0) {
294 buf.writer()->fill(nread); // Tell the buffer, we've used the bytes
295 sslvc->netActivity(lthread);
296 }
297 break;
298 case SSL_ERROR_WANT_WRITE:
299 event = SSL_WRITE_WOULD_BLOCK;
300 Debug("ssl.error", "SSL_ERROR_WOULD_BLOCK(write)");
301 break;
302 case SSL_ERROR_WANT_READ:
303 event = SSL_READ_WOULD_BLOCK;
304 Debug("ssl.error", "SSL_ERROR_WOULD_BLOCK(read)");
305 break;
306 #ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB
307 case SSL_ERROR_WANT_CLIENT_HELLO_CB:
308 event = SSL_READ_WOULD_BLOCK;
309 Debug("ssl.error", "SSL_ERROR_WOULD_BLOCK(read/client hello cb)");
310 break;
311 #endif
312 case SSL_ERROR_WANT_X509_LOOKUP:
313 event = SSL_READ_WOULD_BLOCK;
314 Debug("ssl.error", "SSL_ERROR_WOULD_BLOCK(read/x509 lookup)");
315 break;
316 case SSL_ERROR_SYSCALL:
317 if (nread != 0) {
318 // not EOF
319 SSL_INCREMENT_DYN_STAT(ssl_error_syscall);
320 event = SSL_READ_ERROR;
321 ret = errno;
322 Debug("ssl.error", "SSL_ERROR_SYSCALL, underlying IO error: %s", strerror(errno));
323 } else {
324 // then EOF observed, treat it as EOS
325 event = SSL_READ_EOS;
326 }
327 break;
328 case SSL_ERROR_ZERO_RETURN:
329 event = SSL_READ_EOS;
330 Debug("ssl.error", "SSL_ERROR_ZERO_RETURN");
331 break;
332 case SSL_ERROR_SSL:
333 default: {
334 char buf[512];
335 unsigned long e = ERR_peek_last_error();
336 ERR_error_string_n(e, buf, sizeof(buf));
337 event = SSL_READ_ERROR;
338 ret = errno;
339 SSL_CLR_ERR_INCR_DYN_STAT(sslvc, ssl_error_ssl, "errno=%d", errno);
340 } break;
341 } // switch
342 } // while
343
344 if (bytes_read > 0) {
345 Debug("ssl", "bytes_read=%" PRId64, bytes_read);
346
347 s->vio.ndone += bytes_read;
348 sslvc->netActivity(lthread);
349
350 ret = bytes_read;
351
352 // If we read it all, don't worry about the other events and just send read complete
353 event = (s->vio.ntodo() <= 0) ? SSL_READ_COMPLETE : SSL_READ_READY;
354 if (sslErr == SSL_ERROR_NONE && s->vio.ntodo() > 0) {
355 // We stopped with data on the wire (to avoid overbuffering). Make sure we are triggered
356 sslvc->read.triggered = 1;
357 }
358 } else { // if( bytes_read > 0 )
359 #if defined(_DEBUG)
360 if (bytes_read == 0) {
361 Debug("ssl", "bytes_read == 0");
362 }
363 #endif
364 }
365 return event;
366 }
367
368 /** Read from socket directly for handshake data. Store the data in an MIOBuffer. Place the data in
369 * the read BIO so the openssl library has access to it. If for some reason we must abort out of the
370 * handshake, the stored data can be replayed (e.g. back out to blind tunneling)
371 */
372 int64_t
read_raw_data()373 SSLNetVConnection::read_raw_data()
374 {
375 // read data
376 int64_t r = 0;
377 int64_t total_read = 0;
378 int64_t rattempted = 0;
379 char *buffer = nullptr;
380 int buf_len;
381 IOBufferBlock *b = this->handShakeBuffer->first_write_block();
382
383 rattempted = b->write_avail();
384 while (rattempted) {
385 buffer = b->_end;
386 buf_len = rattempted;
387 b = b->next.get();
388
389 r = socketManager.read(this->con.fd, buffer, buf_len);
390 NET_INCREMENT_DYN_STAT(net_calls_to_read_stat);
391 total_read += rattempted;
392
393 Debug("ssl", "read_raw_data r=%" PRId64 " rattempted=%" PRId64 " total_read=%" PRId64 " fd=%d", r, rattempted, total_read,
394 con.fd);
395 // last read failed or was incomplete
396 if (r != rattempted || !b) {
397 break;
398 }
399
400 rattempted = b->write_avail();
401 }
402 // If we have already moved some bytes successfully, adjust total_read to reflect reality
403 // If any read succeeded, we should return success
404 if (r != rattempted) {
405 // If the first read fails, we should return error
406 if (r <= 0 && total_read > rattempted) {
407 r = total_read - rattempted;
408 } else {
409 r = total_read - rattempted + r;
410 }
411 }
412 NET_SUM_DYN_STAT(net_read_bytes_stat, r);
413
414 IpMap *pp_ipmap;
415 pp_ipmap = SSLConfigParams::proxy_protocol_ipmap;
416
417 if (this->get_is_proxy_protocol() && this->get_proxy_protocol_version() == ProxyProtocolVersion::UNDEFINED) {
418 Debug("proxyprotocol", "proxy protocol is enabled on this port");
419 if (pp_ipmap->count() > 0) {
420 Debug("proxyprotocol", "proxy protocol has a configured allowlist of trusted IPs - checking");
421
422 // At this point, using get_remote_addr() will return the ip of the
423 // proxy source IP, not the Proxy Protocol client ip. Since we are
424 // checking the ip of the actual source of this connection, this is
425 // what we want now.
426 void *payload = nullptr;
427 if (!pp_ipmap->contains(get_remote_addr(), &payload)) {
428 Debug("proxyprotocol", "proxy protocol src IP is NOT in the configured allowlist of trusted IPs - "
429 "closing connection");
430 r = -ENOTCONN; // Need a quick close/exit here to refuse the connection!!!!!!!!!
431 goto proxy_protocol_bypass;
432 } else {
433 char new_host[INET6_ADDRSTRLEN];
434 Debug("proxyprotocol", "Source IP [%s] is in the trusted allowlist for proxy protocol",
435 ats_ip_ntop(this->get_remote_addr(), new_host, sizeof(new_host)));
436 }
437 } else {
438 Debug("proxyprotocol", "proxy protocol DOES NOT have a configured allowlist of trusted IPs but "
439 "proxy protocol is enabled on this port - processing all connections");
440 }
441
442 if (this->has_proxy_protocol(buffer, &r)) {
443 Debug("proxyprotocol", "ssl has proxy protocol header");
444 set_remote_addr(get_proxy_protocol_src_addr());
445 } else {
446 Debug("proxyprotocol", "proxy protocol was enabled, but required header was not present in the "
447 "transaction - closing connection");
448 }
449 } // end of Proxy Protocol processing
450
451 proxy_protocol_bypass:
452
453 if (r > 0) {
454 this->handShakeBuffer->fill(r);
455
456 char *start = this->handShakeReader->start();
457 char *end = this->handShakeReader->end();
458 this->handShakeBioStored = end - start;
459
460 // Sets up the buffer as a read only bio target
461 // Must be reset on each read
462 BIO *rbio = BIO_new_mem_buf(start, this->handShakeBioStored);
463 BIO_set_mem_eof_return(rbio, -1);
464 SSL_set0_rbio(this->ssl, rbio);
465 } else {
466 this->handShakeBioStored = 0;
467 }
468
469 Debug("ssl", "%p read r=%" PRId64 " total=%" PRId64 " bio=%d\n", this, r, total_read, this->handShakeBioStored);
470
471 // check for errors
472 if (r <= 0) {
473 if (r == -EAGAIN || r == -ENOTCONN) {
474 NET_INCREMENT_DYN_STAT(net_calls_to_read_nodata_stat);
475 }
476 }
477
478 return r;
479 }
480
481 //
482 // Return true if we updated the rbio with another
483 // memory chunk (should be ready for another read right away)
484 //
485 bool
update_rbio(bool move_to_socket)486 SSLNetVConnection::update_rbio(bool move_to_socket)
487 {
488 bool retval = false;
489 if (BIO_eof(SSL_get_rbio(this->ssl)) && this->handShakeReader != nullptr) {
490 this->handShakeReader->consume(this->handShakeBioStored);
491 this->handShakeBioStored = 0;
492 // Load up the next block if present
493 if (this->handShakeReader->is_read_avail_more_than(0)) {
494 // Setup the next iobuffer block to drain
495 char *start = this->handShakeReader->start();
496 char *end = this->handShakeReader->end();
497 this->handShakeBioStored = end - start;
498
499 // Sets up the buffer as a read only bio target
500 // Must be reset on each read
501 BIO *rbio = BIO_new_mem_buf(start, this->handShakeBioStored);
502 BIO_set_mem_eof_return(rbio, -1);
503 SSL_set0_rbio(this->ssl, rbio);
504 retval = true;
505 // Handshake buffer is empty but we have read something, move to the socket rbio
506 } else if (move_to_socket && this->handShakeHolder->is_read_avail_more_than(0)) {
507 BIO *rbio = BIO_new_fd(this->get_socket(), BIO_NOCLOSE);
508 BIO_set_mem_eof_return(rbio, -1);
509 SSL_set0_rbio(this->ssl, rbio);
510 free_handshake_buffers();
511 }
512 }
513 return retval;
514 }
515
516 // changed by YTS Team, yamsat
517 void
net_read_io(NetHandler * nh,EThread * lthread)518 SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread)
519 {
520 int ret;
521 int64_t r = 0;
522 int64_t bytes = 0;
523 NetState *s = &this->read;
524
525 if (HttpProxyPort::TRANSPORT_BLIND_TUNNEL == this->attributes) {
526 this->super::net_read_io(nh, lthread);
527 return;
528 }
529
530 MUTEX_TRY_LOCK(lock, s->vio.mutex, lthread);
531 if (!lock.is_locked()) {
532 readReschedule(nh);
533 return;
534 }
535 // Got closed by the HttpSessionManager thread during a migration
536 // The closed flag should be stable once we get the s->vio.mutex in that case
537 // (the global session pool mutex).
538 if (this->closed) {
539 this->super::net_read_io(nh, lthread);
540 return;
541 }
542 // If the key renegotiation failed it's over, just signal the error and finish.
543 if (sslClientRenegotiationAbort == true) {
544 this->read.triggered = 0;
545 readSignalError(nh, -ENET_SSL_FAILED);
546 Debug("ssl", "client renegotiation setting read signal error");
547 return;
548 }
549
550 // If it is not enabled, lower its priority. This allows
551 // a fast connection to speed match a slower connection by
552 // shifting down in priority even if it could read.
553 if (!s->enabled || s->vio.op != VIO::READ || s->vio.is_disabled()) {
554 read_disable(nh, this);
555 return;
556 }
557
558 MIOBufferAccessor &buf = s->vio.buffer;
559 int64_t ntodo = s->vio.ntodo();
560 ink_assert(buf.writer());
561
562 // Continue on if we are still in the handshake
563 if (!getSSLHandShakeComplete()) {
564 int err = 0;
565
566 if (get_context() == NET_VCONNECTION_OUT) {
567 ret = sslStartHandShake(SSL_EVENT_CLIENT, err);
568 } else {
569 ret = sslStartHandShake(SSL_EVENT_SERVER, err);
570 }
571 // If we have flipped to blind tunnel, don't read ahead
572 if (this->handShakeReader) {
573 if (this->attributes == HttpProxyPort::TRANSPORT_BLIND_TUNNEL) {
574 // Now in blind tunnel. Set things up to read what is in the buffer
575 // Must send the READ_COMPLETE here before considering
576 // forwarding on the handshake buffer, so the
577 // SSLNextProtocolTrampoline has a chance to do its
578 // thing before forwarding the buffers.
579 this->readSignalDone(VC_EVENT_READ_COMPLETE, nh);
580
581 // If the handshake isn't set yet, this means the tunnel
582 // decision was make in the SNI callback. We must move
583 // the client hello message back into the standard read.vio
584 // so it will get forwarded onto the origin server
585 if (!this->getSSLHandShakeComplete()) {
586 this->sslHandshakeStatus = SSL_HANDSHAKE_DONE;
587
588 // Copy over all data already read in during the SSL_accept
589 // (the client hello message)
590 NetState *s = &this->read;
591 MIOBufferAccessor &buf = s->vio.buffer;
592 int64_t r = buf.writer()->write(this->handShakeHolder);
593 s->vio.nbytes += r;
594 s->vio.ndone += r;
595
596 // Clean up the handshake buffers
597 this->free_handshake_buffers();
598
599 if (r > 0) {
600 // Kick things again, so the data that was copied into the
601 // vio.read buffer gets processed
602 this->readSignalDone(VC_EVENT_READ_COMPLETE, nh);
603 }
604 }
605 return; // Leave if we are tunneling
606 }
607 }
608 if (ret == EVENT_ERROR) {
609 this->read.triggered = 0;
610 readSignalError(nh, err);
611 } else if (ret == SSL_HANDSHAKE_WANT_READ || ret == SSL_HANDSHAKE_WANT_ACCEPT) {
612 if (SSLConfigParams::ssl_handshake_timeout_in > 0) {
613 double handshake_time = (static_cast<double>(Thread::get_hrtime() - sslHandshakeBeginTime) / 1000000000);
614 Debug("ssl", "ssl handshake for vc %p, took %.3f seconds, configured handshake_timer: %d", this, handshake_time,
615 SSLConfigParams::ssl_handshake_timeout_in);
616 if (handshake_time > SSLConfigParams::ssl_handshake_timeout_in) {
617 Debug("ssl", "ssl handshake for vc %p, expired, release the connection", this);
618 read.triggered = 0;
619 nh->read_ready_list.remove(this);
620 readSignalError(nh, ETIMEDOUT);
621 return;
622 }
623 }
624 // move over to the socket if we haven't already
625 if (this->handShakeBuffer != nullptr) {
626 read.triggered = update_rbio(true);
627 } else {
628 read.triggered = 0;
629 }
630 if (!read.triggered) {
631 nh->read_ready_list.remove(this);
632 }
633 readReschedule(nh);
634 } else if (ret == SSL_HANDSHAKE_WANT_CONNECT || ret == SSL_HANDSHAKE_WANT_WRITE) {
635 write.triggered = 0;
636 nh->write_ready_list.remove(this);
637 writeReschedule(nh);
638 } else if (ret == EVENT_DONE) {
639 Debug("ssl", "ssl handshake EVENT_DONE ntodo=%" PRId64, ntodo);
640 // If this was driven by a zero length read, signal complete when
641 // the handshake is complete. Otherwise set up for continuing read
642 // operations.
643 if (ntodo <= 0) {
644 readSignalDone(VC_EVENT_READ_COMPLETE, nh);
645 } else {
646 read.triggered = 1;
647 if (read.enabled) {
648 nh->read_ready_list.in_or_enqueue(this);
649 }
650 }
651 } else if (ret == SSL_WAIT_FOR_HOOK || ret == SSL_WAIT_FOR_ASYNC) {
652 // avoid readReschedule - done when the plugin calls us back to reenable
653 } else {
654 readReschedule(nh);
655 }
656 return;
657 }
658
659 // If there is nothing to do or no space available, disable connection
660 if (ntodo <= 0 || !buf.writer()->write_avail() || s->vio.is_disabled()) {
661 read_disable(nh, this);
662 return;
663 }
664
665 // At this point we are at the post-handshake SSL processing
666 //
667 // not sure if this do-while loop is really needed here, please replace
668 // this comment if you know
669 int ssl_read_errno = 0;
670 do {
671 ret = ssl_read_from_net(this, lthread, r);
672 if (ret == SSL_READ_READY || ret == SSL_READ_ERROR_NONE) {
673 bytes += r;
674 }
675 ink_assert(bytes >= 0);
676 } while ((ret == SSL_READ_READY && bytes == 0) || ret == SSL_READ_ERROR_NONE);
677 ssl_read_errno = errno;
678
679 if (bytes > 0) {
680 if (ret == SSL_READ_WOULD_BLOCK || ret == SSL_READ_READY) {
681 if (readSignalAndUpdate(VC_EVENT_READ_READY) != EVENT_CONT) {
682 Debug("ssl", "readSignal != EVENT_CONT");
683 return;
684 }
685 }
686 }
687
688 switch (ret) {
689 case SSL_READ_READY:
690 readReschedule(nh);
691 return;
692 break;
693 case SSL_WRITE_WOULD_BLOCK:
694 case SSL_READ_WOULD_BLOCK:
695 if (lock.get_mutex() != s->vio.mutex.get()) {
696 Debug("ssl", "mutex switched");
697 if (ret == SSL_READ_WOULD_BLOCK) {
698 readReschedule(nh);
699 } else {
700 writeReschedule(nh);
701 }
702 return;
703 }
704 // reset the trigger and remove from the ready queue
705 // we will need to be retriggered to read from this socket again
706 read.triggered = 0;
707 nh->read_ready_list.remove(this);
708 Debug("ssl", "read finished - would block");
709 #if TS_USE_PORT
710 if (ret == SSL_READ_WOULD_BLOCK) {
711 readReschedule(nh);
712 } else {
713 writeReschedule(nh);
714 }
715 #endif
716 break;
717
718 case SSL_READ_EOS:
719 // close the connection if we have SSL_READ_EOS, this is the return value from ssl_read_from_net() if we get an
720 // SSL_ERROR_ZERO_RETURN from SSL_get_error()
721 // SSL_ERROR_ZERO_RETURN means that the origin server closed the SSL connection
722 read.triggered = 0;
723 readSignalDone(VC_EVENT_EOS, nh);
724
725 if (bytes > 0) {
726 Debug("ssl", "read finished - EOS");
727 } else {
728 Debug("ssl", "read finished - 0 useful bytes read, bytes used by SSL layer");
729 }
730 break;
731 case SSL_READ_COMPLETE:
732 readSignalDone(VC_EVENT_READ_COMPLETE, nh);
733 Debug("ssl", "read finished - signal done");
734 break;
735 case SSL_READ_ERROR:
736 this->read.triggered = 0;
737 readSignalError(nh, (ssl_read_errno) ? ssl_read_errno : -ENET_SSL_FAILED);
738 Debug("ssl", "read finished - read error");
739 break;
740 }
741 }
742
743 int64_t
load_buffer_and_write(int64_t towrite,MIOBufferAccessor & buf,int64_t & total_written,int & needs)744 SSLNetVConnection::load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs)
745 {
746 int64_t try_to_write;
747 int64_t num_really_written = 0;
748 int64_t l = 0;
749 uint32_t dynamic_tls_record_size = 0;
750 ssl_error_t err = SSL_ERROR_NONE;
751
752 // Dynamic TLS record sizing
753 ink_hrtime now = 0;
754 if (SSLConfigParams::ssl_maxrecord == -1) {
755 now = Thread::get_hrtime_updated();
756 int msec_since_last_write = ink_hrtime_diff_msec(now, sslLastWriteTime);
757
758 if (msec_since_last_write > SSL_DEF_TLS_RECORD_MSEC_THRESHOLD) {
759 // reset sslTotalBytesSent upon inactivity for SSL_DEF_TLS_RECORD_MSEC_THRESHOLD
760 sslTotalBytesSent = 0;
761 }
762 Debug("ssl", "now=%" PRId64 " lastwrite=%" PRId64 " msec_since_last_write=%d", now, sslLastWriteTime, msec_since_last_write);
763 }
764
765 if (HttpProxyPort::TRANSPORT_BLIND_TUNNEL == this->attributes) {
766 return this->super::load_buffer_and_write(towrite, buf, total_written, needs);
767 }
768
769 Debug("ssl", "towrite=%" PRId64, towrite);
770
771 do {
772 // What is remaining left in the next block?
773 l = buf.reader()->block_read_avail();
774 char *current_block = buf.reader()->start();
775
776 // check if to amount to write exceeds that in this buffer
777 int64_t wavail = towrite - total_written;
778
779 if (l > wavail) {
780 l = wavail;
781 }
782
783 // TS-2365: If the SSL max record size is set and we have
784 // more data than that, break this into smaller write
785 // operations.
786 //
787 // TS-4424: Don't mess with record size if last SSL_write failed with
788 // needs write
789 if (redoWriteSize) {
790 l = redoWriteSize;
791 redoWriteSize = 0;
792 } else {
793 if (SSLConfigParams::ssl_maxrecord > 0 && l > SSLConfigParams::ssl_maxrecord) {
794 l = SSLConfigParams::ssl_maxrecord;
795 } else if (SSLConfigParams::ssl_maxrecord == -1) {
796 if (sslTotalBytesSent < SSL_DEF_TLS_RECORD_BYTE_THRESHOLD) {
797 dynamic_tls_record_size = SSL_DEF_TLS_RECORD_SIZE;
798 SSL_INCREMENT_DYN_STAT(ssl_total_dyn_def_tls_record_count);
799 } else {
800 dynamic_tls_record_size = SSL_MAX_TLS_RECORD_SIZE;
801 SSL_INCREMENT_DYN_STAT(ssl_total_dyn_max_tls_record_count);
802 }
803 if (l > dynamic_tls_record_size) {
804 l = dynamic_tls_record_size;
805 }
806 }
807 }
808
809 if (!l) {
810 break;
811 }
812
813 try_to_write = l;
814 num_really_written = 0;
815 Debug("v_ssl", "b=%p l=%" PRId64, current_block, l);
816 err = SSLWriteBuffer(ssl, current_block, l, num_really_written);
817
818 // We wrote all that we thought we should
819 if (num_really_written > 0) {
820 total_written += num_really_written;
821 buf.reader()->consume(num_really_written);
822 }
823
824 Debug("ssl", "try_to_write=%" PRId64 " written=%" PRId64 " total_written=%" PRId64, try_to_write, num_really_written,
825 total_written);
826 NET_INCREMENT_DYN_STAT(net_calls_to_write_stat);
827 } while (num_really_written == try_to_write && total_written < towrite);
828
829 if (total_written > 0) {
830 sslLastWriteTime = now;
831 sslTotalBytesSent += total_written;
832 }
833 redoWriteSize = 0;
834 if (num_really_written > 0) {
835 needs |= EVENTIO_WRITE;
836 } else {
837 switch (err) {
838 case SSL_ERROR_NONE:
839 Debug("ssl", "SSL_write-SSL_ERROR_NONE");
840 break;
841 case SSL_ERROR_WANT_READ:
842 needs |= EVENTIO_READ;
843 num_really_written = -EAGAIN;
844 Debug("ssl.error", "SSL_write-SSL_ERROR_WANT_READ");
845 break;
846 case SSL_ERROR_WANT_WRITE:
847 #ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB
848 case SSL_ERROR_WANT_CLIENT_HELLO_CB:
849 #endif
850 case SSL_ERROR_WANT_X509_LOOKUP: {
851 if (SSL_ERROR_WANT_WRITE == err) {
852 redoWriteSize = l;
853 }
854 needs |= EVENTIO_WRITE;
855 num_really_written = -EAGAIN;
856 Debug("ssl.error", "SSL_write-SSL_ERROR_WANT_WRITE");
857 break;
858 }
859 case SSL_ERROR_SYSCALL:
860 num_really_written = -errno;
861 SSL_INCREMENT_DYN_STAT(ssl_error_syscall);
862 Debug("ssl.error", "SSL_write-SSL_ERROR_SYSCALL");
863 break;
864 // end of stream
865 case SSL_ERROR_ZERO_RETURN:
866 num_really_written = -errno;
867 Debug("ssl.error", "SSL_write-SSL_ERROR_ZERO_RETURN");
868 break;
869 case SSL_ERROR_SSL:
870 default: {
871 // Treat SSL_ERROR_SSL as EPIPE error.
872 num_really_written = -EPIPE;
873 SSL_CLR_ERR_INCR_DYN_STAT(this, ssl_error_ssl, "SSL_write-SSL_ERROR_SSL errno=%d", errno);
874 } break;
875 }
876 }
877 return num_really_written;
878 }
879
SSLNetVConnection()880 SSLNetVConnection::SSLNetVConnection() {}
881
882 void
do_io_close(int lerrno)883 SSLNetVConnection::do_io_close(int lerrno)
884 {
885 if (this->ssl != nullptr) {
886 if (get_context() == NET_VCONNECTION_OUT) {
887 callHooks(TS_EVENT_VCONN_OUTBOUND_CLOSE);
888 } else {
889 callHooks(TS_EVENT_VCONN_CLOSE);
890 }
891
892 if (getSSLHandShakeComplete()) {
893 int shutdown_mode = SSL_get_shutdown(ssl);
894 Debug("ssl-shutdown", "previous shutdown state 0x%x", shutdown_mode);
895 int new_shutdown_mode = shutdown_mode | SSL_RECEIVED_SHUTDOWN;
896
897 if (new_shutdown_mode != shutdown_mode) {
898 // We do not need to sit around and wait for the client's close-notify if
899 // they have not already sent it. We will still be standards compliant
900 Debug("ssl-shutdown", "new SSL_set_shutdown 0x%x", new_shutdown_mode);
901 SSL_set_shutdown(ssl, new_shutdown_mode);
902 }
903
904 // If the peer has already sent a FIN, don't bother with the shutdown
905 // They will just send us a RST for our troubles
906 // This test is not foolproof. The client's fin could be on the wire
907 // at the same time we send the close-notify. If so, the client will likely
908 // send RST anyway
909 char c;
910 ssize_t x = recv(this->con.fd, &c, 1, MSG_PEEK);
911 // x < 0 means error. x == 0 means fin sent
912 bool do_shutdown = (x > 0);
913 if (x < 0) {
914 do_shutdown = (errno == EAGAIN || errno == EWOULDBLOCK);
915 }
916 if (do_shutdown) {
917 // Send the close-notify
918 int ret = SSL_shutdown(ssl);
919 Debug("ssl-shutdown", "SSL_shutdown %s", (ret) ? "success" : "failed");
920 } else {
921 // Request a quiet shutdown to OpenSSL
922 SSL_set_quiet_shutdown(ssl, 1);
923 SSL_set_shutdown(ssl, SSL_RECEIVED_SHUTDOWN | SSL_SENT_SHUTDOWN);
924 Debug("ssl-shutdown", "Enable quiet shutdown");
925 }
926 }
927 }
928 // Go on and do the unix socket cleanups
929 super::do_io_close(lerrno);
930 }
931
932 void
clear()933 SSLNetVConnection::clear()
934 {
935 _ca_cert_file.reset();
936 _ca_cert_dir.reset();
937
938 if (ssl != nullptr) {
939 SSL_free(ssl);
940 ssl = nullptr;
941 }
942 ALPNSupport::clear();
943 TLSSessionResumptionSupport::clear();
944 TLSSNISupport::_clear();
945
946 sslHandshakeStatus = SSL_HANDSHAKE_ONGOING;
947 sslHandshakeBeginTime = 0;
948 sslLastWriteTime = 0;
949 sslTotalBytesSent = 0;
950 sslClientRenegotiationAbort = false;
951
952 curHook = nullptr;
953 hookOpRequested = SSL_HOOK_OP_DEFAULT;
954 free_handshake_buffers();
955
956 super::clear();
957 }
958 void
free(EThread * t)959 SSLNetVConnection::free(EThread *t)
960 {
961 ink_release_assert(t == this_ethread());
962
963 // cancel OOB
964 cancel_OOB();
965 // close socket fd
966 if (con.fd != NO_FD) {
967 NET_SUM_GLOBAL_DYN_STAT(net_connections_currently_open_stat, -1);
968 }
969 con.close();
970
971 ats_free(tunnel_host);
972
973 if (early_data_reader != nullptr) {
974 early_data_reader->dealloc();
975 }
976
977 if (early_data_buf != nullptr) {
978 free_MIOBuffer(early_data_buf);
979 }
980
981 early_data_reader = nullptr;
982 early_data_buf = nullptr;
983
984 clear();
985 SET_CONTINUATION_HANDLER(this, (SSLNetVConnHandler)&SSLNetVConnection::startEvent);
986 ink_assert(con.fd == NO_FD);
987 ink_assert(t == this_ethread());
988
989 if (from_accept_thread) {
990 sslNetVCAllocator.free(this);
991 } else {
992 ink_assert(con.fd == NO_FD);
993 THREAD_FREE(this, sslNetVCAllocator, t);
994 }
995 }
996
997 int
sslStartHandShake(int event,int & err)998 SSLNetVConnection::sslStartHandShake(int event, int &err)
999 {
1000 if (TSSystemState::is_ssl_handshaking_stopped()) {
1001 Debug("ssl", "Stopping handshake due to server shutting down.");
1002 return EVENT_ERROR;
1003 }
1004 if (sslHandshakeBeginTime == 0) {
1005 sslHandshakeBeginTime = Thread::get_hrtime();
1006 // net_activity will not be triggered until after the handshake
1007 set_inactivity_timeout(HRTIME_SECONDS(SSLConfigParams::ssl_handshake_timeout_in));
1008 }
1009 SSLConfig::scoped_config params;
1010 switch (event) {
1011 case SSL_EVENT_SERVER:
1012 if (this->ssl == nullptr) {
1013 SSLCertificateConfig::scoped_config lookup;
1014 IpEndpoint dst;
1015 int namelen = sizeof(dst);
1016 if (0 != safe_getsockname(this->get_socket(), &dst.sa, &namelen)) {
1017 Debug("ssl", "Failed to get dest ip, errno = [%d]", errno);
1018 return EVENT_ERROR;
1019 }
1020 SSLCertContext *cc = lookup->find(dst);
1021 if (is_debug_tag_set("ssl")) {
1022 IpEndpoint src;
1023 ip_port_text_buffer ipb1, ipb2;
1024 int ip_len = sizeof(src);
1025
1026 if (0 != safe_getpeername(this->get_socket(), &src.sa, &ip_len)) {
1027 Debug("ssl", "Failed to get src ip, errno = [%d]", errno);
1028 return EVENT_ERROR;
1029 }
1030 ats_ip_nptop(&dst, ipb1, sizeof(ipb1));
1031 ats_ip_nptop(&src, ipb2, sizeof(ipb2));
1032 Debug("ssl", "IP context is %p for [%s] -> [%s], default context %p", cc, ipb2, ipb1, lookup->defaultContext());
1033 }
1034
1035 // Escape if this is marked to be a tunnel.
1036 // No data has been read at this point, so we can go
1037 // directly into blind tunnel mode
1038
1039 if (cc && SSLCertContextOption::OPT_TUNNEL == cc->opt) {
1040 if (this->is_transparent) {
1041 this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
1042 sslHandshakeStatus = SSL_HANDSHAKE_DONE;
1043 SSL_free(this->ssl);
1044 this->ssl = nullptr;
1045 return EVENT_DONE;
1046 } else {
1047 hookOpRequested = SSL_HOOK_OP_TUNNEL;
1048 }
1049 }
1050
1051 // Attach the default SSL_CTX to this SSL session. The default context is never going to be able
1052 // to negotiate a SSL session, but it's enough to trampoline us into the SNI callback where we
1053 // can select the right server certificate.
1054 this->_make_ssl_connection(lookup->defaultContext());
1055 }
1056
1057 if (this->ssl == nullptr) {
1058 SSLErrorVC(this, "failed to create SSL server session");
1059 return EVENT_ERROR;
1060 }
1061 return sslServerHandShakeEvent(err);
1062
1063 case SSL_EVENT_CLIENT:
1064
1065 char buff[INET6_ADDRSTRLEN];
1066
1067 if (this->ssl == nullptr) {
1068 // Making the check here instead of later, so we only
1069 // do this setting immediately after we create the SSL object
1070 SNIConfig::scoped_config sniParam;
1071 const char *serverKey = this->options.sni_servername;
1072 if (!serverKey) {
1073 ats_ip_ntop(this->get_remote_addr(), buff, INET6_ADDRSTRLEN);
1074 serverKey = buff;
1075 }
1076 auto nps = sniParam->getPropertyConfig(serverKey);
1077 shared_SSL_CTX sharedCTX = nullptr;
1078 SSL_CTX *clientCTX = nullptr;
1079
1080 // First Look to see if there are override parameters
1081 if (options.ssl_client_cert_name) {
1082 std::string certFilePath = Layout::get()->relative_to(params->clientCertPathOnly, options.ssl_client_cert_name.get());
1083 std::string keyFilePath;
1084 if (options.ssl_client_private_key_name) {
1085 keyFilePath = Layout::get()->relative_to(params->clientKeyPathOnly, options.ssl_client_private_key_name);
1086 }
1087 std::string caCertFilePath;
1088 if (options.ssl_client_ca_cert_name) {
1089 caCertFilePath = Layout::get()->relative_to(params->clientCACertPath, options.ssl_client_ca_cert_name);
1090 }
1091 sharedCTX =
1092 params->getCTX(certFilePath.c_str(), keyFilePath.empty() ? nullptr : keyFilePath.c_str(),
1093 caCertFilePath.empty() ? params->clientCACertFilename : caCertFilePath.c_str(), params->clientCACertPath);
1094 } else if (options.ssl_client_ca_cert_name) {
1095 std::string caCertFilePath = Layout::get()->relative_to(params->clientCACertPath, options.ssl_client_ca_cert_name);
1096 sharedCTX = params->getCTX(params->clientCertPath, params->clientKeyPath, caCertFilePath.c_str(), params->clientCACertPath);
1097 } else if (nps && !nps->client_cert_file.empty()) {
1098 // If no overrides available, try the available nextHopProperty by reading from context mappings
1099 sharedCTX =
1100 params->getCTX(nps->client_cert_file.c_str(), nps->client_key_file.empty() ? nullptr : nps->client_key_file.c_str(),
1101 params->clientCACertFilename, params->clientCACertPath);
1102 } else { // Just stay with the values passed down from the SM for verify
1103 clientCTX = params->client_ctx.get();
1104 }
1105
1106 if (sharedCTX) {
1107 clientCTX = sharedCTX.get();
1108 }
1109
1110 if (options.verifyServerPolicy != YamlSNIConfig::Policy::UNSET) {
1111 // Stay with conf-override version as the highest priority
1112 } else if (nps && nps->verifyServerPolicy != YamlSNIConfig::Policy::UNSET) {
1113 options.verifyServerPolicy = nps->verifyServerPolicy;
1114 } else {
1115 options.verifyServerPolicy = params->verifyServerPolicy;
1116 }
1117
1118 if (options.verifyServerProperties != YamlSNIConfig::Property::UNSET) {
1119 // Stay with conf-override version as the highest priority
1120 } else if (nps && nps->verifyServerProperties != YamlSNIConfig::Property::UNSET) {
1121 options.verifyServerProperties = nps->verifyServerProperties;
1122 } else {
1123 options.verifyServerProperties = params->verifyServerProperties;
1124 }
1125
1126 if (!clientCTX) {
1127 SSLErrorVC(this, "failed to create SSL client session");
1128 return EVENT_ERROR;
1129 }
1130
1131 this->_make_ssl_connection(clientCTX);
1132 if (this->ssl == nullptr) {
1133 SSLErrorVC(this, "failed to create SSL client session");
1134 return EVENT_ERROR;
1135 }
1136
1137 SSL_set_verify(this->ssl, SSL_VERIFY_PEER, verify_callback);
1138
1139 // SNI
1140 ats_scoped_str &tlsext_host_name = this->options.sni_hostname ? this->options.sni_hostname : this->options.sni_servername;
1141 if (tlsext_host_name) {
1142 if (SSL_set_tlsext_host_name(this->ssl, tlsext_host_name)) {
1143 Debug("ssl", "using SNI name '%s' for client handshake", tlsext_host_name.get());
1144 } else {
1145 Debug("ssl.error", "failed to set SNI name '%s' for client handshake", tlsext_host_name.get());
1146 SSL_INCREMENT_DYN_STAT(ssl_sni_name_set_failure);
1147 }
1148 }
1149
1150 // ALPN
1151 if (!this->options.alpn_protos.empty()) {
1152 if (int res = SSL_set_alpn_protos(this->ssl, reinterpret_cast<const uint8_t *>(this->options.alpn_protos.data()),
1153 this->options.alpn_protos.size());
1154 res != 0) {
1155 Debug("ssl.error", "failed to set ALPN '%.*s' for client handshake", static_cast<int>(this->options.alpn_protos.size()),
1156 this->options.alpn_protos.data());
1157 }
1158 }
1159 }
1160
1161 return sslClientHandShakeEvent(err);
1162
1163 default:
1164 ink_assert(0);
1165 return EVENT_ERROR;
1166 }
1167 }
1168
1169 int
sslServerHandShakeEvent(int & err)1170 SSLNetVConnection::sslServerHandShakeEvent(int &err)
1171 {
1172 // Continue on if we are in the invoked state. The hook has not yet reenabled
1173 if (sslHandshakeHookState == HANDSHAKE_HOOKS_CERT_INVOKE || sslHandshakeHookState == HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE ||
1174 sslHandshakeHookState == HANDSHAKE_HOOKS_PRE_INVOKE || sslHandshakeHookState == HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE) {
1175 return SSL_WAIT_FOR_HOOK;
1176 }
1177
1178 // Go do the preaccept hooks
1179 if (sslHandshakeHookState == HANDSHAKE_HOOKS_PRE) {
1180 SSL_INCREMENT_DYN_STAT(ssl_total_attempts_handshake_count_in_stat);
1181 if (!curHook) {
1182 Debug("ssl", "Initialize preaccept curHook from NULL");
1183 curHook = ssl_hooks->get(TSSslHookInternalID(TS_VCONN_START_HOOK));
1184 } else {
1185 curHook = curHook->next();
1186 }
1187 // If no more hooks, move onto CLIENT HELLO
1188
1189 if (nullptr == curHook) {
1190 sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_HELLO;
1191 } else {
1192 sslHandshakeHookState = HANDSHAKE_HOOKS_PRE_INVOKE;
1193 ContWrapper::wrap(nh->mutex.get(), curHook->m_cont, TS_EVENT_VCONN_START, this);
1194 return SSL_WAIT_FOR_HOOK;
1195 }
1196 }
1197
1198 // If a blind tunnel was requested in the pre-accept calls, convert.
1199 // Again no data has been exchanged, so we can go directly
1200 // without data replay.
1201 // Note we can't arrive here if a hook is active.
1202
1203 if (SSL_HOOK_OP_TUNNEL == hookOpRequested) {
1204 this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
1205 SSL_free(this->ssl);
1206 this->ssl = nullptr;
1207 // Don't mark the handshake as complete yet,
1208 // Will be checking for that flag not being set after
1209 // we get out of this callback, and then will shuffle
1210 // over the buffered handshake packets to the O.S.
1211 return EVENT_DONE;
1212 } else if (SSL_HOOK_OP_TERMINATE == hookOpRequested) {
1213 sslHandshakeStatus = SSL_HANDSHAKE_DONE;
1214 return EVENT_DONE;
1215 }
1216
1217 Debug("ssl", "Go on with the handshake state=%d", sslHandshakeHookState);
1218
1219 // All the pre-accept hooks have completed, proceed with the actual accept.
1220 if (this->handShakeReader) {
1221 if (BIO_eof(SSL_get_rbio(this->ssl))) { // No more data in the buffer
1222 // Is this the first read?
1223 if (!this->handShakeReader->is_read_avail_more_than(0) && !this->handShakeHolder->is_read_avail_more_than(0)) {
1224 #if TS_USE_TLS_ASYNC
1225 if (SSLConfigParams::async_handshake_enabled) {
1226 SSL_set_mode(ssl, SSL_MODE_ASYNC);
1227 }
1228 #endif
1229
1230 Debug("ssl", "%p first read\n", this);
1231 // Read from socket to fill in the BIO buffer with the
1232 // raw handshake data before calling the ssl accept calls.
1233 int retval = this->read_raw_data();
1234 if (retval < 0) {
1235 if (retval == -EAGAIN) {
1236 // No data at the moment, hang tight
1237 SSLVCDebug(this, "SSL handshake: EAGAIN");
1238 return SSL_HANDSHAKE_WANT_READ;
1239 } else {
1240 // An error, make us go away
1241 SSLVCDebug(this, "SSL handshake error: read_retval=%d", retval);
1242 return EVENT_ERROR;
1243 }
1244 } else if (retval == 0) {
1245 // EOF, go away, we stopped in the handshake
1246 SSLVCDebug(this, "SSL handshake error: EOF");
1247 return EVENT_ERROR;
1248 }
1249 } else {
1250 update_rbio(false);
1251 }
1252 } // Still data in the BIO
1253 }
1254
1255 ssl_error_t ssl_error = SSLAccept(ssl);
1256 #if TS_USE_TLS_ASYNC
1257 if (ssl_error == SSL_ERROR_WANT_ASYNC) {
1258 // Do we need to set up the async eventfd? Or is it already registered?
1259 if (async_ep.fd < 0) {
1260 size_t numfds;
1261 OSSL_ASYNC_FD *waitfds;
1262 // Set up the epoll entry for the signalling
1263 if (SSL_get_all_async_fds(ssl, nullptr, &numfds) && numfds > 0) {
1264 // Allocate space for the waitfd on the stack, should only be one most all of the time
1265 waitfds = reinterpret_cast<OSSL_ASYNC_FD *>(alloca(sizeof(OSSL_ASYNC_FD) * numfds));
1266 if (SSL_get_all_async_fds(ssl, waitfds, &numfds) && numfds > 0) {
1267 this->read.triggered = false;
1268 this->write.triggered = false;
1269 // Have to have the read NetState enabled because we are using it for the signal vc
1270 read.enabled = true;
1271 PollDescriptor *pd = get_PollDescriptor(this_ethread());
1272 this->async_ep.start(pd, waitfds[0], static_cast<NetEvent *>(this), EVENTIO_READ);
1273 this->async_ep.type = EVENTIO_READWRITE_VC;
1274 }
1275 }
1276 }
1277 } else if (SSLConfigParams::async_handshake_enabled) {
1278 // Make sure the net fd read vio is in the right state
1279 if (ssl_error == SSL_ERROR_WANT_READ) {
1280 this->reenable(&read.vio);
1281 this->read.triggered = 1;
1282 }
1283 }
1284 #endif
1285 if (ssl_error != SSL_ERROR_NONE) {
1286 err = errno;
1287 SSLVCDebug(this, "SSL handshake error: %s (%d), errno=%d", SSLErrorName(ssl_error), ssl_error, err);
1288
1289 // start a blind tunnel if tr-pass is set and data does not look like ClientHello
1290 char *buf = handShakeBuffer ? handShakeBuffer->buf() : nullptr;
1291 if (getTransparentPassThrough() && buf && *buf != SSL_OP_HANDSHAKE) {
1292 SSLVCDebug(this, "Data does not look like SSL handshake, starting blind tunnel");
1293 this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
1294 sslHandshakeStatus = SSL_HANDSHAKE_ONGOING;
1295 return EVENT_CONT;
1296 }
1297 }
1298
1299 switch (ssl_error) {
1300 case SSL_ERROR_NONE:
1301 if (is_debug_tag_set("ssl")) {
1302 X509 *cert = SSL_get_peer_certificate(ssl);
1303
1304 Debug("ssl", "SSL server handshake completed successfully");
1305 if (cert) {
1306 debug_certificate_name("client certificate subject CN is", X509_get_subject_name(cert));
1307 debug_certificate_name("client certificate issuer CN is", X509_get_issuer_name(cert));
1308 X509_free(cert);
1309 }
1310 }
1311
1312 sslHandshakeStatus = SSL_HANDSHAKE_DONE;
1313
1314 if (sslHandshakeBeginTime) {
1315 sslHandshakeEndTime = Thread::get_hrtime();
1316 const ink_hrtime ssl_handshake_time = sslHandshakeEndTime - sslHandshakeBeginTime;
1317
1318 Debug("ssl", "ssl handshake time:%" PRId64, ssl_handshake_time);
1319 SSL_INCREMENT_DYN_STAT_EX(ssl_total_handshake_time_stat, ssl_handshake_time);
1320 SSL_INCREMENT_DYN_STAT(ssl_total_success_handshake_count_in_stat);
1321 }
1322
1323 if (_tunnel_type != SNIRoutingType::NONE) {
1324 // Foce to use HTTP/1.1 endpoint for SNI Routing
1325 if (!this->setSelectedProtocol(reinterpret_cast<const unsigned char *>(IP_PROTO_TAG_HTTP_1_1.data()),
1326 IP_PROTO_TAG_HTTP_1_1.size())) {
1327 return EVENT_ERROR;
1328 }
1329 }
1330
1331 {
1332 const unsigned char *proto = nullptr;
1333 unsigned len = 0;
1334
1335 increment_ssl_version_metric(SSL_version(ssl));
1336
1337 // If it's possible to negotiate both NPN and ALPN, then ALPN
1338 // is preferred since it is the server's preference. The server
1339 // preference would not be meaningful if we let the client
1340 // preference have priority.
1341 SSL_get0_alpn_selected(ssl, &proto, &len);
1342 if (len == 0) {
1343 SSL_get0_next_proto_negotiated(ssl, &proto, &len);
1344 }
1345
1346 if (len) {
1347 if (_tunnel_type == SNIRoutingType::NONE && !this->setSelectedProtocol(proto, len)) {
1348 return EVENT_ERROR;
1349 }
1350 this->set_negotiated_protocol_id({reinterpret_cast<const char *>(proto), static_cast<size_t>(len)});
1351
1352 Debug("ssl", "client selected next protocol '%.*s'", len, proto);
1353 } else {
1354 Debug("ssl", "client did not select a next protocol");
1355 }
1356 }
1357
1358 #if TS_USE_TLS_ASYNC
1359 if (SSLConfigParams::async_handshake_enabled) {
1360 SSL_clear_mode(ssl, SSL_MODE_ASYNC);
1361 if (async_ep.fd >= 0) {
1362 async_ep.stop();
1363 }
1364 }
1365 #endif
1366 return EVENT_DONE;
1367
1368 case SSL_ERROR_WANT_CONNECT:
1369 return SSL_HANDSHAKE_WANT_CONNECT;
1370
1371 case SSL_ERROR_WANT_WRITE:
1372 return SSL_HANDSHAKE_WANT_WRITE;
1373
1374 case SSL_ERROR_WANT_READ:
1375 return SSL_HANDSHAKE_WANT_READ;
1376 #ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB
1377 case SSL_ERROR_WANT_CLIENT_HELLO_CB:
1378 return EVENT_CONT;
1379 #endif
1380 // This value is only defined in openssl has been patched to
1381 // enable the sni callback to break out of the SSL_accept processing
1382 #ifdef SSL_ERROR_WANT_SNI_RESOLVE
1383 case SSL_ERROR_WANT_X509_LOOKUP:
1384 return EVENT_CONT;
1385 case SSL_ERROR_WANT_SNI_RESOLVE:
1386 #elif SSL_ERROR_WANT_X509_LOOKUP
1387 case SSL_ERROR_WANT_X509_LOOKUP:
1388 #endif
1389 #if defined(SSL_ERROR_WANT_SNI_RESOLVE) || defined(SSL_ERROR_WANT_X509_LOOKUP)
1390 if (this->attributes == HttpProxyPort::TRANSPORT_BLIND_TUNNEL || SSL_HOOK_OP_TUNNEL == hookOpRequested) {
1391 this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
1392 sslHandshakeStatus = SSL_HANDSHAKE_ONGOING;
1393 return EVENT_CONT;
1394 } else {
1395 // Stopping for some other reason, perhaps loading certificate
1396 return SSL_WAIT_FOR_HOOK;
1397 }
1398 #endif
1399
1400 #if TS_USE_TLS_ASYNC
1401 case SSL_ERROR_WANT_ASYNC:
1402 SSL_INCREMENT_DYN_STAT(ssl_error_async);
1403 return SSL_WAIT_FOR_ASYNC;
1404 #endif
1405
1406 case SSL_ERROR_WANT_ACCEPT:
1407 return EVENT_CONT;
1408
1409 case SSL_ERROR_SSL: {
1410 SSL_CLR_ERR_INCR_DYN_STAT(this, ssl_error_ssl, "SSLNetVConnection::sslServerHandShakeEvent, SSL_ERROR_SSL errno=%d", errno);
1411 return EVENT_ERROR;
1412 }
1413
1414 case SSL_ERROR_ZERO_RETURN:
1415 return EVENT_ERROR;
1416 case SSL_ERROR_SYSCALL:
1417 return EVENT_ERROR;
1418 default:
1419 return EVENT_ERROR;
1420 }
1421 }
1422
1423 int
sslClientHandShakeEvent(int & err)1424 SSLNetVConnection::sslClientHandShakeEvent(int &err)
1425 {
1426 ssl_error_t ssl_error;
1427
1428 ink_assert(SSLNetVCAccess(ssl) == this);
1429
1430 // Initialize properly for a client connection
1431 if (sslHandshakeHookState == HANDSHAKE_HOOKS_PRE) {
1432 if (this->pp_info.version != ProxyProtocolVersion::UNDEFINED) {
1433 // Outbound PROXY Protocol
1434 VIO &vio = this->write.vio;
1435 int64_t ntodo = vio.ntodo();
1436 int64_t towrite = vio.buffer.reader()->read_avail();
1437
1438 if (ntodo > 0 && towrite > 0) {
1439 MIOBufferAccessor &buf = vio.buffer;
1440 int needs = 0;
1441 int64_t total_written = 0;
1442 int64_t r = super::load_buffer_and_write(towrite, buf, total_written, needs);
1443
1444 if (total_written > 0) {
1445 vio.ndone += total_written;
1446 if (vio.ntodo() != 0) {
1447 return SSL_WAIT_FOR_HOOK;
1448 }
1449 }
1450
1451 if (r < 0) {
1452 if (r == -EAGAIN || r == -ENOTCONN || -r == EINPROGRESS) {
1453 return SSL_WAIT_FOR_HOOK;
1454 } else {
1455 return EVENT_ERROR;
1456 }
1457 }
1458 }
1459 }
1460
1461 sslHandshakeHookState = HANDSHAKE_HOOKS_OUTBOUND_PRE;
1462 }
1463
1464 // Do outbound hook processing here
1465 // Continue on if we are in the invoked state. The hook has not yet reenabled
1466 if (sslHandshakeHookState == HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE) {
1467 return SSL_WAIT_FOR_HOOK;
1468 }
1469
1470 // Go do the preaccept hooks
1471 if (sslHandshakeHookState == HANDSHAKE_HOOKS_OUTBOUND_PRE) {
1472 SSL_INCREMENT_DYN_STAT(ssl_total_attempts_handshake_count_out_stat);
1473 if (!curHook) {
1474 Debug("ssl", "Initialize outbound connect curHook from NULL");
1475 curHook = ssl_hooks->get(TSSslHookInternalID(TS_VCONN_OUTBOUND_START_HOOK));
1476 } else {
1477 curHook = curHook->next();
1478 }
1479 // If no more hooks, carry on
1480 if (nullptr != curHook) {
1481 sslHandshakeHookState = HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE;
1482 ContWrapper::wrap(nh->mutex.get(), curHook->m_cont, TS_EVENT_VCONN_OUTBOUND_START, this);
1483 return SSL_WAIT_FOR_HOOK;
1484 }
1485 }
1486
1487 ssl_error = SSLConnect(ssl);
1488 switch (ssl_error) {
1489 case SSL_ERROR_NONE:
1490 if (is_debug_tag_set("ssl")) {
1491 X509 *cert = SSL_get_peer_certificate(ssl);
1492
1493 Debug("ssl", "SSL client handshake completed successfully");
1494
1495 if (cert) {
1496 debug_certificate_name("server certificate subject CN is", X509_get_subject_name(cert));
1497 debug_certificate_name("server certificate issuer CN is", X509_get_issuer_name(cert));
1498 X509_free(cert);
1499 }
1500 }
1501
1502 // if the handshake is complete and write is enabled reschedule the write
1503 if (closed == 0 && write.enabled) {
1504 writeReschedule(nh);
1505 }
1506
1507 SSL_INCREMENT_DYN_STAT(ssl_total_success_handshake_count_out_stat);
1508
1509 sslHandshakeStatus = SSL_HANDSHAKE_DONE;
1510 return EVENT_DONE;
1511
1512 case SSL_ERROR_WANT_WRITE:
1513 Debug("ssl.error", "SSL_ERROR_WANT_WRITE");
1514 return SSL_HANDSHAKE_WANT_WRITE;
1515
1516 case SSL_ERROR_WANT_READ:
1517 Debug("ssl.error", "SSL_ERROR_WANT_READ");
1518 return SSL_HANDSHAKE_WANT_READ;
1519 #ifdef SSL_ERROR_WANT_CLIENT_HELLO_CB
1520 case SSL_ERROR_WANT_CLIENT_HELLO_CB:
1521 Debug("ssl.error", "SSL_ERROR_WANT_CLIENT_HELLO_CB");
1522 break;
1523 #endif
1524 case SSL_ERROR_WANT_X509_LOOKUP:
1525 Debug("ssl.error", "SSL_ERROR_WANT_X509_LOOKUP");
1526 break;
1527
1528 case SSL_ERROR_WANT_ACCEPT:
1529 return SSL_HANDSHAKE_WANT_ACCEPT;
1530
1531 case SSL_ERROR_WANT_CONNECT:
1532 break;
1533
1534 case SSL_ERROR_ZERO_RETURN:
1535 Debug("ssl.error", "EOS");
1536 return EVENT_ERROR;
1537
1538 case SSL_ERROR_SYSCALL:
1539 err = errno;
1540 SSL_INCREMENT_DYN_STAT(ssl_error_syscall);
1541 Debug("ssl.error", "syscall");
1542 return EVENT_ERROR;
1543 break;
1544
1545 case SSL_ERROR_SSL:
1546 default: {
1547 err = (errno) ? errno : -ENET_SSL_CONNECT_FAILED;
1548 char buf[512];
1549 unsigned long e = ERR_peek_last_error();
1550 ERR_error_string_n(e, buf, sizeof(buf));
1551 // FIXME -- This triggers a retry on cases of cert validation errors....
1552 SSL_CLR_ERR_INCR_DYN_STAT(this, ssl_error_ssl, "SSL_ERROR_SSL errno=%d", errno);
1553 Debug("ssl.error", "SSL_ERROR_SSL");
1554 if (e) {
1555 if (this->options.sni_servername) {
1556 Debug("ssl.error", "SSL connection failed for '%s': %s", this->options.sni_servername.get(), buf);
1557 } else {
1558 char buff[INET6_ADDRSTRLEN];
1559 ats_ip_ntop(this->get_remote_addr(), buff, INET6_ADDRSTRLEN);
1560 Debug("ssl.error", "SSL connection failed for '%s': %s", buff, buf);
1561 }
1562 }
1563 return EVENT_ERROR;
1564 } break;
1565 }
1566 return EVENT_CONT;
1567 }
1568
1569 // NextProtocolNegotiation TLS extension callback. The NPN extension
1570 // allows the client to select a preferred protocol, so all we have
1571 // to do here is tell them what out protocol set is.
1572 int
advertise_next_protocol(SSL * ssl,const unsigned char ** out,unsigned int * outlen,void *)1573 SSLNetVConnection::advertise_next_protocol(SSL *ssl, const unsigned char **out, unsigned int *outlen, void * /*arg ATS_UNUSED */)
1574 {
1575 SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
1576
1577 ink_release_assert(netvc && netvc->ssl == ssl);
1578
1579 if (netvc->getNPN(out, outlen)) {
1580 // Successful return tells OpenSSL to advertise.
1581 return SSL_TLSEXT_ERR_OK;
1582 }
1583 return SSL_TLSEXT_ERR_NOACK;
1584 }
1585
1586 // ALPN TLS extension callback. Given the client's set of offered
1587 // protocols, we have to select a protocol to use for this session.
1588 int
select_next_protocol(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in ATS_UNUSED,unsigned inlen ATS_UNUSED,void *)1589 SSLNetVConnection::select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen,
1590 const unsigned char *in ATS_UNUSED, unsigned inlen ATS_UNUSED, void *)
1591 {
1592 SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
1593
1594 ink_release_assert(netvc && netvc->ssl == ssl);
1595 const unsigned char *npnptr = nullptr;
1596 unsigned int npnsize = 0;
1597 if (netvc->getNPN(&npnptr, &npnsize)) {
1598 // SSL_select_next_proto chooses the first server-offered protocol that appears in the clients protocol set, ie. the
1599 // server selects the protocol. This is a n^2 search, so it's preferable to keep the protocol set short.
1600 if (SSL_select_next_proto(const_cast<unsigned char **>(out), outlen, npnptr, npnsize, in, inlen) == OPENSSL_NPN_NEGOTIATED) {
1601 Debug("ssl", "selected ALPN protocol %.*s", (int)(*outlen), *out);
1602 return SSL_TLSEXT_ERR_OK;
1603 }
1604 }
1605
1606 *out = nullptr;
1607 *outlen = 0;
1608 return SSL_TLSEXT_ERR_NOACK;
1609 }
1610
1611 void
reenable(NetHandler * nh,int event)1612 SSLNetVConnection::reenable(NetHandler *nh, int event)
1613 {
1614 Debug("ssl", "Handshake reenable from state=%d", sslHandshakeHookState);
1615
1616 // Mark as error to stop the Handshake
1617 if (event == TS_EVENT_ERROR) {
1618 sslHandshakeStatus = SSL_HANDSHAKE_ERROR;
1619 }
1620
1621 switch (sslHandshakeHookState) {
1622 case HANDSHAKE_HOOKS_PRE_INVOKE:
1623 sslHandshakeHookState = HANDSHAKE_HOOKS_PRE;
1624 break;
1625 case HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE:
1626 sslHandshakeHookState = HANDSHAKE_HOOKS_OUTBOUND_PRE;
1627 break;
1628 case HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE:
1629 sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_HELLO;
1630 break;
1631 case HANDSHAKE_HOOKS_CERT_INVOKE:
1632 sslHandshakeHookState = HANDSHAKE_HOOKS_CERT;
1633 break;
1634 case HANDSHAKE_HOOKS_VERIFY_SERVER:
1635 case HANDSHAKE_HOOKS_CLIENT_CERT:
1636 break;
1637 default:
1638 break;
1639 }
1640
1641 // Reenabling from the handshake callback
1642 //
1643 // Originally, we would wait for the callback to go again to execute additional
1644 // hooks, but since the callbacks are associated with the context and the context
1645 // can be replaced by the plugin, it didn't seem reasonable to assume that the
1646 // callback would be executed again. So we walk through the rest of the hooks
1647 // here in the reenable.
1648 if (curHook != nullptr) {
1649 curHook = curHook->next();
1650 Debug("ssl", "iterate from reenable curHook=%p", curHook);
1651 }
1652 if (curHook != nullptr) {
1653 // Invoke the hook and return, wait for next reenable
1654 if (sslHandshakeHookState == HANDSHAKE_HOOKS_CLIENT_HELLO) {
1655 sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE;
1656 curHook->invoke(TS_EVENT_SSL_CLIENT_HELLO, this);
1657 } else if (sslHandshakeHookState == HANDSHAKE_HOOKS_CLIENT_CERT) {
1658 sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE;
1659 curHook->invoke(TS_EVENT_SSL_VERIFY_CLIENT, this);
1660 } else if (sslHandshakeHookState == HANDSHAKE_HOOKS_CERT) {
1661 sslHandshakeHookState = HANDSHAKE_HOOKS_CERT_INVOKE;
1662 curHook->invoke(TS_EVENT_SSL_CERT, this);
1663 } else if (sslHandshakeHookState == HANDSHAKE_HOOKS_SNI) {
1664 curHook->invoke(TS_EVENT_SSL_SERVERNAME, this);
1665 } else if (sslHandshakeHookState == HANDSHAKE_HOOKS_PRE) {
1666 Debug("ssl", "Reenable preaccept");
1667 sslHandshakeHookState = HANDSHAKE_HOOKS_PRE_INVOKE;
1668 ContWrapper::wrap(nh->mutex.get(), curHook->m_cont, TS_EVENT_VCONN_START, this);
1669 } else if (sslHandshakeHookState == HANDSHAKE_HOOKS_OUTBOUND_PRE) {
1670 Debug("ssl", "Reenable outbound connect");
1671 sslHandshakeHookState = HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE;
1672 ContWrapper::wrap(nh->mutex.get(), curHook->m_cont, TS_EVENT_VCONN_OUTBOUND_START, this);
1673 } else if (sslHandshakeHookState == HANDSHAKE_HOOKS_DONE) {
1674 if (this->get_context() == NET_VCONNECTION_OUT) {
1675 ContWrapper::wrap(nh->mutex.get(), curHook->m_cont, TS_EVENT_VCONN_OUTBOUND_CLOSE, this);
1676 } else {
1677 ContWrapper::wrap(nh->mutex.get(), curHook->m_cont, TS_EVENT_VCONN_CLOSE, this);
1678 }
1679 } else if (sslHandshakeHookState == HANDSHAKE_HOOKS_VERIFY_SERVER) {
1680 Debug("ssl", "ServerVerify");
1681 ContWrapper::wrap(nh->mutex.get(), curHook->m_cont, TS_EVENT_SSL_VERIFY_SERVER, this);
1682 }
1683 return;
1684 } else {
1685 // Move onto the "next" state
1686 switch (this->sslHandshakeHookState) {
1687 case HANDSHAKE_HOOKS_PRE:
1688 case HANDSHAKE_HOOKS_PRE_INVOKE:
1689 sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_HELLO;
1690 break;
1691 case HANDSHAKE_HOOKS_CLIENT_HELLO:
1692 case HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE:
1693 sslHandshakeHookState = HANDSHAKE_HOOKS_SNI;
1694 break;
1695 case HANDSHAKE_HOOKS_SNI:
1696 sslHandshakeHookState = HANDSHAKE_HOOKS_CERT;
1697 break;
1698 case HANDSHAKE_HOOKS_CERT:
1699 case HANDSHAKE_HOOKS_CERT_INVOKE:
1700 sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_CERT;
1701 break;
1702 case HANDSHAKE_HOOKS_OUTBOUND_PRE:
1703 case HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE:
1704 this->write.triggered = true;
1705 this->write.enabled = true;
1706 this->writeReschedule(nh);
1707 sslHandshakeHookState = HANDSHAKE_HOOKS_DONE;
1708 break;
1709 case HANDSHAKE_HOOKS_CLIENT_CERT:
1710 case HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE:
1711 sslHandshakeHookState = HANDSHAKE_HOOKS_DONE;
1712 break;
1713 case HANDSHAKE_HOOKS_VERIFY_SERVER:
1714 sslHandshakeHookState = HANDSHAKE_HOOKS_DONE;
1715 break;
1716 default:
1717 break;
1718 }
1719 Debug("ssl", "iterate from reenable curHook=%p %d", curHook, sslHandshakeHookState);
1720 }
1721
1722 this->readReschedule(nh);
1723 }
1724
1725 bool
callHooks(TSEvent eventId)1726 SSLNetVConnection::callHooks(TSEvent eventId)
1727 {
1728 // Only dealing with the SNI/CERT hook so far.
1729 ink_assert(eventId == TS_EVENT_SSL_CLIENT_HELLO || eventId == TS_EVENT_SSL_CERT || eventId == TS_EVENT_SSL_SERVERNAME ||
1730 eventId == TS_EVENT_SSL_VERIFY_SERVER || eventId == TS_EVENT_SSL_VERIFY_CLIENT || eventId == TS_EVENT_VCONN_CLOSE ||
1731 eventId == TS_EVENT_VCONN_OUTBOUND_CLOSE);
1732 Debug("ssl", "sslHandshakeHookState=%d eventID=%d", this->sslHandshakeHookState, eventId);
1733
1734 // Move state if it is appropriate
1735 if (eventId == TS_EVENT_VCONN_CLOSE) {
1736 // Regardless of state, if the connection is closing, then transition to
1737 // the DONE state. This will trigger us to call the appropriate cleanup
1738 // routines.
1739 this->sslHandshakeHookState = HANDSHAKE_HOOKS_DONE;
1740 } else {
1741 switch (this->sslHandshakeHookState) {
1742 case HANDSHAKE_HOOKS_PRE:
1743 case HANDSHAKE_HOOKS_OUTBOUND_PRE:
1744 if (eventId == TS_EVENT_SSL_CLIENT_HELLO) {
1745 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_HELLO;
1746 } else if (eventId == TS_EVENT_SSL_SERVERNAME) {
1747 this->sslHandshakeHookState = HANDSHAKE_HOOKS_SNI;
1748 } else if (eventId == TS_EVENT_SSL_VERIFY_SERVER) {
1749 this->sslHandshakeHookState = HANDSHAKE_HOOKS_VERIFY_SERVER;
1750 } else if (eventId == TS_EVENT_SSL_CERT) {
1751 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CERT;
1752 }
1753 break;
1754 case HANDSHAKE_HOOKS_CLIENT_HELLO:
1755 if (eventId == TS_EVENT_SSL_SERVERNAME) {
1756 this->sslHandshakeHookState = HANDSHAKE_HOOKS_SNI;
1757 } else if (eventId == TS_EVENT_SSL_CERT) {
1758 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CERT;
1759 }
1760 break;
1761 case HANDSHAKE_HOOKS_SNI:
1762 if (eventId == TS_EVENT_SSL_CERT) {
1763 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CERT;
1764 }
1765 break;
1766 default:
1767 break;
1768 }
1769 }
1770
1771 // Look for hooks associated with the event
1772 switch (this->sslHandshakeHookState) {
1773 case HANDSHAKE_HOOKS_CLIENT_HELLO:
1774 case HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE:
1775 if (!curHook) {
1776 curHook = ssl_hooks->get(TSSslHookInternalID(TS_SSL_CLIENT_HELLO_HOOK));
1777 } else {
1778 curHook = curHook->next();
1779 }
1780 if (curHook == nullptr) {
1781 this->sslHandshakeHookState = HANDSHAKE_HOOKS_SNI;
1782 } else {
1783 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE;
1784 }
1785 break;
1786 case HANDSHAKE_HOOKS_VERIFY_SERVER:
1787 // The server verify event addresses ATS to origin handshake
1788 // All the other events are for client to ATS
1789 if (!curHook) {
1790 curHook = ssl_hooks->get(TSSslHookInternalID(TS_SSL_VERIFY_SERVER_HOOK));
1791 } else {
1792 curHook = curHook->next();
1793 }
1794 break;
1795 case HANDSHAKE_HOOKS_SNI:
1796 if (!curHook) {
1797 curHook = ssl_hooks->get(TSSslHookInternalID(TS_SSL_SERVERNAME_HOOK));
1798 } else {
1799 curHook = curHook->next();
1800 }
1801 if (!curHook) {
1802 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CERT;
1803 }
1804 break;
1805 case HANDSHAKE_HOOKS_CERT:
1806 case HANDSHAKE_HOOKS_CERT_INVOKE:
1807 if (!curHook) {
1808 curHook = ssl_hooks->get(TSSslHookInternalID(TS_SSL_CERT_HOOK));
1809 } else {
1810 curHook = curHook->next();
1811 }
1812 if (curHook == nullptr) {
1813 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CLIENT_CERT;
1814 } else {
1815 this->sslHandshakeHookState = HANDSHAKE_HOOKS_CERT_INVOKE;
1816 }
1817 break;
1818 case HANDSHAKE_HOOKS_CLIENT_CERT:
1819 case HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE:
1820 if (!curHook) {
1821 curHook = ssl_hooks->get(TSSslHookInternalID(TS_SSL_VERIFY_CLIENT_HOOK));
1822 } else {
1823 curHook = curHook->next();
1824 }
1825 // fallthrough
1826 case HANDSHAKE_HOOKS_DONE:
1827 case HANDSHAKE_HOOKS_OUTBOUND_PRE:
1828 if (eventId == TS_EVENT_VCONN_CLOSE) {
1829 sslHandshakeHookState = HANDSHAKE_HOOKS_DONE;
1830 if (curHook == nullptr) {
1831 curHook = ssl_hooks->get(TSSslHookInternalID(TS_VCONN_CLOSE_HOOK));
1832 } else {
1833 curHook = curHook->next();
1834 }
1835 } else if (eventId == TS_EVENT_VCONN_OUTBOUND_CLOSE) {
1836 sslHandshakeHookState = HANDSHAKE_HOOKS_DONE;
1837 if (curHook == nullptr) {
1838 curHook = ssl_hooks->get(TSSslHookInternalID(TS_VCONN_OUTBOUND_CLOSE_HOOK));
1839 } else {
1840 curHook = curHook->next();
1841 }
1842 }
1843 break;
1844 default:
1845 curHook = nullptr;
1846 this->sslHandshakeHookState = HANDSHAKE_HOOKS_DONE;
1847 return true;
1848 }
1849
1850 Debug("ssl", "iterated to curHook=%p", curHook);
1851
1852 bool reenabled = true;
1853
1854 if (SSL_HOOK_OP_TUNNEL == hookOpRequested) {
1855 this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL;
1856 // Don't mark the handshake as complete yet,
1857 // Will be checking for that flag not being set after
1858 // we get out of this callback, and then will shuffle
1859 // over the buffered handshake packets to the O.S.
1860 // sslHandShakeComplete = 1;
1861 return reenabled;
1862 }
1863
1864 if (curHook != nullptr) {
1865 WEAK_SCOPED_MUTEX_LOCK(lock, curHook->m_cont->mutex, this_ethread());
1866 curHook->invoke(eventId, this);
1867 reenabled =
1868 (this->sslHandshakeHookState != HANDSHAKE_HOOKS_CERT_INVOKE && this->sslHandshakeHookState != HANDSHAKE_HOOKS_PRE_INVOKE &&
1869 this->sslHandshakeHookState != HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE);
1870 Debug("ssl", "Called hook on state=%d reenabled=%d", sslHandshakeHookState, reenabled);
1871 }
1872
1873 return reenabled;
1874 }
1875
1876 int
populate(Connection & con,Continuation * c,void * arg)1877 SSLNetVConnection::populate(Connection &con, Continuation *c, void *arg)
1878 {
1879 int retval = super::populate(con, c, arg);
1880 if (retval != EVENT_DONE) {
1881 return retval;
1882 }
1883 // Add in the SSL data
1884 this->ssl = static_cast<SSL *>(arg);
1885 // Maybe bring over the stats?
1886
1887 sslHandshakeStatus = SSL_HANDSHAKE_DONE;
1888 this->_bindSSLObject();
1889 return EVENT_DONE;
1890 }
1891
1892 void
increment_ssl_version_metric(int version) const1893 SSLNetVConnection::increment_ssl_version_metric(int version) const
1894 {
1895 switch (version) {
1896 case SSL3_VERSION:
1897 SSL_INCREMENT_DYN_STAT(ssl_total_sslv3);
1898 break;
1899 case TLS1_VERSION:
1900 SSL_INCREMENT_DYN_STAT(ssl_total_tlsv1);
1901 break;
1902 case TLS1_1_VERSION:
1903 SSL_INCREMENT_DYN_STAT(ssl_total_tlsv11);
1904 break;
1905 case TLS1_2_VERSION:
1906 SSL_INCREMENT_DYN_STAT(ssl_total_tlsv12);
1907 break;
1908 #ifdef TLS1_3_VERSION
1909 case TLS1_3_VERSION:
1910 SSL_INCREMENT_DYN_STAT(ssl_total_tlsv13);
1911 break;
1912 #endif
1913 default:
1914 Debug("ssl", "Unrecognized SSL version %d", version);
1915 break;
1916 }
1917 }
1918
1919 std::string_view
map_tls_protocol_to_tag(const char * proto_string) const1920 SSLNetVConnection::map_tls_protocol_to_tag(const char *proto_string) const
1921 {
1922 std::string_view retval{"tls/?.?"sv}; // return this if the protocol lookup doesn't work.
1923
1924 if (proto_string) {
1925 // openSSL guarantees the case of the protocol string.
1926 if (proto_string[0] == 'T' && proto_string[1] == 'L' && proto_string[2] == 'S' && proto_string[3] == 'v' &&
1927 proto_string[4] == '1') {
1928 if (proto_string[5] == 0) {
1929 retval = IP_PROTO_TAG_TLS_1_0;
1930 } else if (proto_string[5] == '.' && proto_string[7] == 0) {
1931 switch (proto_string[6]) {
1932 case '1':
1933 retval = IP_PROTO_TAG_TLS_1_1;
1934 break;
1935 case '2':
1936 retval = IP_PROTO_TAG_TLS_1_2;
1937 break;
1938 case '3':
1939 retval = IP_PROTO_TAG_TLS_1_3;
1940 break;
1941 default:
1942 break;
1943 }
1944 }
1945 }
1946 }
1947 return retval;
1948 }
1949
1950 int
populate_protocol(std::string_view * results,int n) const1951 SSLNetVConnection::populate_protocol(std::string_view *results, int n) const
1952 {
1953 int retval = 0;
1954 if (n > retval) {
1955 results[retval] = map_tls_protocol_to_tag(getSSLProtocol());
1956 if (!results[retval].empty()) {
1957 ++retval;
1958 }
1959 if (n > retval) {
1960 retval += super::populate_protocol(results + retval, n - retval);
1961 }
1962 }
1963 return retval;
1964 }
1965
1966 const char *
protocol_contains(std::string_view prefix) const1967 SSLNetVConnection::protocol_contains(std::string_view prefix) const
1968 {
1969 const char *retval = nullptr;
1970 std::string_view tag = map_tls_protocol_to_tag(getSSLProtocol());
1971 if (prefix.size() <= tag.size() && strncmp(tag.data(), prefix.data(), prefix.size()) == 0) {
1972 retval = tag.data();
1973 } else {
1974 retval = super::protocol_contains(prefix);
1975 }
1976 return retval;
1977 }
1978
1979 void
_fire_ssl_servername_event()1980 SSLNetVConnection::_fire_ssl_servername_event()
1981 {
1982 this->callHooks(TS_EVENT_SSL_SERVERNAME);
1983 }
1984
1985 void
set_ca_cert_file(std::string_view file,std::string_view dir)1986 SSLNetVConnection::set_ca_cert_file(std::string_view file, std::string_view dir)
1987 {
1988 if (file.size()) {
1989 char *n = new char[file.size() + 1];
1990 std::memcpy(n, file.data(), file.size());
1991 n[file.size()] = '\0';
1992 _ca_cert_file.reset(n);
1993 }
1994 if (dir.size()) {
1995 char *n = new char[dir.size() + 1];
1996 std::memcpy(n, dir.data(), dir.size());
1997 n[dir.size()] = '\0';
1998 _ca_cert_dir.reset(n);
1999 }
2000 }
2001
2002 void *
_prepareForMigration()2003 SSLNetVConnection::_prepareForMigration()
2004 {
2005 SSL *save_ssl = this->ssl;
2006
2007 this->_unbindSSLObject();
2008 this->ssl = nullptr;
2009
2010 return save_ssl;
2011 }
2012
2013 NetProcessor *
_getNetProcessor()2014 SSLNetVConnection::_getNetProcessor()
2015 {
2016 return &sslNetProcessor;
2017 }
2018