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