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 /****************************************************************************
25 
26   SSLNetVConnection.h
27 
28   This file implements an I/O Processor for network I/O.
29 
30 
31  ****************************************************************************/
32 #pragma once
33 
34 #include <memory>
35 
36 #include "tscore/ink_platform.h"
37 #include "ts/apidefs.h"
38 #include <string_view>
39 #include <cstring>
40 #include <memory>
41 
42 #include <openssl/ssl.h>
43 #include <openssl/err.h>
44 #include <openssl/objects.h>
45 
46 #include "P_EventSystem.h"
47 #include "P_UnixNetVConnection.h"
48 #include "P_UnixNet.h"
49 #include "P_ALPNSupport.h"
50 #include "TLSSessionResumptionSupport.h"
51 #include "TLSSNISupport.h"
52 #include "P_SSLUtils.h"
53 #include "P_SSLConfig.h"
54 
55 // These are included here because older OpenSSL libraries don't have them.
56 // Don't copy these defines, or use their values directly, they are merely
57 // here to avoid compiler errors.
58 #ifndef SSL_TLSEXT_ERR_OK
59 #define SSL_TLSEXT_ERR_OK 0
60 #endif
61 
62 #ifndef SSL_TLSEXT_ERR_NOACK
63 #define SSL_TLSEXT_ERR_NOACK 3
64 #endif
65 
66 #define SSL_OP_HANDSHAKE 0x16
67 
68 // TS-2503: dynamic TLS record sizing
69 // For smaller records, we should also reserve space for various TCP options
70 // (timestamps, SACKs.. up to 40 bytes [1]), and account for TLS record overhead
71 // (another 20-60 bytes on average, depending on the negotiated ciphersuite [2]).
72 // All in all: 1500 - 40 (IP) - 20 (TCP) - 40 (TCP options) - TLS overhead (60-100)
73 // For larger records, the size is determined by TLS protocol record size
74 #define SSL_DEF_TLS_RECORD_SIZE 1300  // 1500 - 40 (IP) - 20 (TCP) - 40 (TCP options) - TLS overhead (60-100)
75 #define SSL_MAX_TLS_RECORD_SIZE 16383 // 2^14 - 1
76 #define SSL_DEF_TLS_RECORD_BYTE_THRESHOLD 1000000
77 #define SSL_DEF_TLS_RECORD_MSEC_THRESHOLD 1000
78 
79 struct SSLCertLookup;
80 
81 typedef enum {
82   SSL_HOOK_OP_DEFAULT,                     ///< Null / initialization value. Do normal processing.
83   SSL_HOOK_OP_TUNNEL,                      ///< Switch to blind tunnel
84   SSL_HOOK_OP_TERMINATE,                   ///< Termination connection / transaction.
85   SSL_HOOK_OP_LAST = SSL_HOOK_OP_TERMINATE ///< End marker value.
86 } SslVConnOp;
87 
88 enum SSLHandshakeStatus { SSL_HANDSHAKE_ONGOING, SSL_HANDSHAKE_DONE, SSL_HANDSHAKE_ERROR };
89 
90 //////////////////////////////////////////////////////////////////
91 //
92 //  class NetVConnection
93 //
94 //  A VConnection for a network socket.
95 //
96 //////////////////////////////////////////////////////////////////
97 class SSLNetVConnection : public UnixNetVConnection, public ALPNSupport, public TLSSessionResumptionSupport, public TLSSNISupport
98 {
99   typedef UnixNetVConnection super; ///< Parent type.
100 
101 public:
102   int sslStartHandShake(int event, int &err) override;
103   void clear() override;
104   void free(EThread *t) override;
105 
106   bool
trackFirstHandshake()107   trackFirstHandshake() override
108   {
109     bool retval = sslHandshakeBeginTime == 0;
110     if (retval) {
111       sslHandshakeBeginTime = Thread::get_hrtime();
112     }
113     return retval;
114   }
115 
116   bool
getSSLHandShakeComplete()117   getSSLHandShakeComplete() const override
118   {
119     return sslHandshakeStatus != SSL_HANDSHAKE_ONGOING;
120   }
121 
122   virtual void
setSSLHandShakeComplete(enum SSLHandshakeStatus state)123   setSSLHandShakeComplete(enum SSLHandshakeStatus state)
124   {
125     sslHandshakeStatus = state;
126   }
127 
128   int sslServerHandShakeEvent(int &err);
129   int sslClientHandShakeEvent(int &err);
130   void net_read_io(NetHandler *nh, EThread *lthread) override;
131   int64_t load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs) override;
132   void do_io_close(int lerrno = -1) override;
133 
134   ////////////////////////////////////////////////////////////
135   // Instances of NetVConnection should be allocated        //
136   // only from the free list using NetVConnection::alloc(). //
137   // The constructor is public just to avoid compile errors.//
138   ////////////////////////////////////////////////////////////
139   SSLNetVConnection();
~SSLNetVConnection()140   ~SSLNetVConnection() override {}
141   static int advertise_next_protocol(SSL *ssl, const unsigned char **out, unsigned *outlen, void *);
142   static int select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in,
143                                   unsigned inlen, void *);
144 
145   bool
getSSLClientRenegotiationAbort()146   getSSLClientRenegotiationAbort() const
147   {
148     return sslClientRenegotiationAbort;
149   }
150 
151   void
setSSLClientRenegotiationAbort(bool state)152   setSSLClientRenegotiationAbort(bool state)
153   {
154     sslClientRenegotiationAbort = state;
155   }
156 
157   bool
getTransparentPassThrough()158   getTransparentPassThrough() const
159   {
160     return transparentPassThrough;
161   }
162 
163   void
setTransparentPassThrough(bool val)164   setTransparentPassThrough(bool val)
165   {
166     transparentPassThrough = val;
167   }
168 
169   // Copy up here so we overload but don't override
170   using super::reenable;
171 
172   /// Reenable the VC after a pre-accept or SNI hook is called.
173   virtual void reenable(NetHandler *nh, int event = TS_EVENT_CONTINUE);
174 
175   int64_t read_raw_data();
176 
177   void
initialize_handshake_buffers()178   initialize_handshake_buffers()
179   {
180     this->handShakeBuffer    = new_MIOBuffer(SSLConfigParams::ssl_misc_max_iobuffer_size_index);
181     this->handShakeReader    = this->handShakeBuffer->alloc_reader();
182     this->handShakeHolder    = this->handShakeReader->clone();
183     this->handShakeBioStored = 0;
184   }
185 
186   void
free_handshake_buffers()187   free_handshake_buffers()
188   {
189     if (this->handShakeReader) {
190       this->handShakeReader->dealloc();
191     }
192     if (this->handShakeHolder) {
193       this->handShakeHolder->dealloc();
194     }
195     if (this->handShakeBuffer) {
196       free_MIOBuffer(this->handShakeBuffer);
197     }
198     this->handShakeReader    = nullptr;
199     this->handShakeHolder    = nullptr;
200     this->handShakeBuffer    = nullptr;
201     this->handShakeBioStored = 0;
202   }
203 
204   // Returns true if all the hooks reenabled
205   bool callHooks(TSEvent eventId);
206 
207   // Returns true if we have already called at
208   // least some of the hooks
209   bool
calledHooks(TSEvent eventId)210   calledHooks(TSEvent eventId) const
211   {
212     bool retval = false;
213     switch (this->sslHandshakeHookState) {
214     case HANDSHAKE_HOOKS_PRE:
215     case HANDSHAKE_HOOKS_PRE_INVOKE:
216       if (eventId == TS_EVENT_VCONN_START) {
217         if (curHook) {
218           retval = true;
219         }
220       }
221       break;
222     case HANDSHAKE_HOOKS_CLIENT_HELLO:
223     case HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE:
224       if (eventId == TS_EVENT_VCONN_START) {
225         retval = true;
226       } else if (eventId == TS_EVENT_SSL_CLIENT_HELLO) {
227         if (curHook) {
228           retval = true;
229         }
230       }
231       break;
232     case HANDSHAKE_HOOKS_SNI:
233       if (eventId == TS_EVENT_VCONN_START || eventId == TS_EVENT_SSL_CLIENT_HELLO) {
234         retval = true;
235       } else if (eventId == TS_EVENT_SSL_SERVERNAME) {
236         if (curHook) {
237           retval = true;
238         }
239       }
240       break;
241     case HANDSHAKE_HOOKS_CERT:
242     case HANDSHAKE_HOOKS_CERT_INVOKE:
243       if (eventId == TS_EVENT_VCONN_START || eventId == TS_EVENT_SSL_CLIENT_HELLO || eventId == TS_EVENT_SSL_SERVERNAME) {
244         retval = true;
245       } else if (eventId == TS_EVENT_SSL_CERT) {
246         if (curHook) {
247           retval = true;
248         }
249       }
250       break;
251     case HANDSHAKE_HOOKS_CLIENT_CERT:
252     case HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE:
253       if (eventId == TS_EVENT_SSL_VERIFY_CLIENT || eventId == TS_EVENT_VCONN_START) {
254         retval = true;
255       }
256       break;
257 
258     case HANDSHAKE_HOOKS_OUTBOUND_PRE:
259     case HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE:
260       if (eventId == TS_EVENT_VCONN_OUTBOUND_START) {
261         if (curHook) {
262           retval = true;
263         }
264       }
265       break;
266 
267     case HANDSHAKE_HOOKS_VERIFY_SERVER:
268       retval = (eventId == TS_EVENT_SSL_VERIFY_SERVER);
269       break;
270 
271     case HANDSHAKE_HOOKS_DONE:
272       retval = true;
273       break;
274     }
275     return retval;
276   }
277 
278   const char *
getSSLProtocol()279   getSSLProtocol() const
280   {
281     return ssl ? SSL_get_version(ssl) : nullptr;
282   }
283 
284   const char *
getSSLCipherSuite()285   getSSLCipherSuite() const
286   {
287     return ssl ? SSL_get_cipher_name(ssl) : nullptr;
288   }
289 
290   const char *
getSSLCurve()291   getSSLCurve() const
292   {
293     if (!ssl) {
294       return nullptr;
295     }
296     ssl_curve_id curve;
297     if (getSSLSessionCacheHit()) {
298       curve = getSSLCurveNID();
299     } else {
300       curve = SSLGetCurveNID(ssl);
301     }
302 #ifndef OPENSSL_IS_BORINGSSL
303     if (curve == NID_undef) {
304       return nullptr;
305     }
306     return OBJ_nid2sn(curve);
307 #else
308     if (curve == 0) {
309       return nullptr;
310     }
311     return SSL_get_curve_name(curve);
312 #endif
313   }
314 
315   bool
has_tunnel_destination()316   has_tunnel_destination() const
317   {
318     return tunnel_host != nullptr;
319   }
320 
321   const char *
get_tunnel_host()322   get_tunnel_host() const
323   {
324     return tunnel_host;
325   }
326 
327   ushort
get_tunnel_port()328   get_tunnel_port() const
329   {
330     return tunnel_port;
331   }
332 
333   bool decrypt_tunnel() const;
334   bool upstream_tls() const;
335   SNIRoutingType tunnel_type() const;
336 
337   void
set_tunnel_destination(const std::string_view & destination,SNIRoutingType type)338   set_tunnel_destination(const std::string_view &destination, SNIRoutingType type)
339   {
340     _tunnel_type = type;
341 
342     auto pos = destination.find(":");
343     if (nullptr != tunnel_host) {
344       ats_free(tunnel_host);
345     }
346     if (pos != std::string::npos) {
347       tunnel_port = std::stoi(destination.substr(pos + 1).data());
348       tunnel_host = ats_strndup(destination.substr(0, pos).data(), pos);
349     } else {
350       tunnel_port = 0;
351       tunnel_host = ats_strndup(destination.data(), destination.length());
352     }
353   }
354 
355   int populate_protocol(std::string_view *results, int n) const override;
356   const char *protocol_contains(std::string_view tag) const override;
357 
358   /**
359    * Populate the current object based on the socket information in in the
360    * con parameter and the ssl object in the arg parameter
361    * This is logic is invoked when the NetVC object is created in a new thread context
362    */
363   int populate(Connection &con, Continuation *c, void *arg) override;
364 
365   SSL *ssl                         = nullptr;
366   ink_hrtime sslHandshakeBeginTime = 0;
367   ink_hrtime sslHandshakeEndTime   = 0;
368   ink_hrtime sslLastWriteTime      = 0;
369   int64_t sslTotalBytesSent        = 0;
370 
371   // The serverName is either a pointer to the (null-terminated) name fetched from the
372   // SSL object or the empty string.
373   const char *
get_server_name()374   get_server_name() const override
375   {
376     return _get_sni_server_name() ? _get_sni_server_name() : "";
377   }
378 
379   bool
support_sni()380   support_sni() const override
381   {
382     return true;
383   }
384 
385   /// Set by asynchronous hooks to request a specific operation.
386   SslVConnOp hookOpRequested = SSL_HOOK_OP_DEFAULT;
387 
388   // noncopyable
389   SSLNetVConnection(const SSLNetVConnection &) = delete;
390   SSLNetVConnection &operator=(const SSLNetVConnection &) = delete;
391 
392   bool protocol_mask_set = false;
393   unsigned long protocol_mask;
394 
395   // early data related stuff
396   bool early_data_finish            = false;
397   MIOBuffer *early_data_buf         = nullptr;
398   IOBufferReader *early_data_reader = nullptr;
399   int64_t read_from_early_data      = 0;
400 
401   // Only applies during the VERIFY certificate hooks (client and server side)
402   // Means to give the plugin access to the data structure passed in during the underlying
403   // openssl callback so the plugin can make more detailed decisions about the
404   // validity of the certificate in their cases
405   X509_STORE_CTX *
get_verify_cert()406   get_verify_cert()
407   {
408     return verify_cert;
409   }
410   void
set_verify_cert(X509_STORE_CTX * ctx)411   set_verify_cert(X509_STORE_CTX *ctx)
412   {
413     verify_cert = ctx;
414   }
415 
416   const char *
get_sni_servername()417   get_sni_servername() const override
418   {
419     return SSL_get_servername(this->ssl, TLSEXT_NAMETYPE_host_name);
420   }
421 
422   bool
peer_provided_cert()423   peer_provided_cert() const override
424   {
425     X509 *cert = SSL_get_peer_certificate(this->ssl);
426     if (cert != nullptr) {
427       X509_free(cert);
428       return true;
429     } else {
430       return false;
431     }
432   }
433 
434   int
provided_cert()435   provided_cert() const override
436   {
437     if (this->get_context() == NET_VCONNECTION_OUT) {
438       return this->sent_cert;
439     } else {
440       return 1;
441     }
442   }
443 
444   void
set_sent_cert(int send_the_cert)445   set_sent_cert(int send_the_cert)
446   {
447     sent_cert = send_the_cert;
448   }
449 
450   void set_ca_cert_file(std::string_view file, std::string_view dir);
451 
452   const char *
get_ca_cert_file()453   get_ca_cert_file()
454   {
455     return _ca_cert_file.get();
456   }
457   const char *
get_ca_cert_dir()458   get_ca_cert_dir()
459   {
460     return _ca_cert_dir.get();
461   }
462 
463   void
set_valid_tls_protocols(unsigned long proto_mask,unsigned long max_mask)464   set_valid_tls_protocols(unsigned long proto_mask, unsigned long max_mask)
465   {
466     SSL_set_options(this->ssl, proto_mask);
467     SSL_clear_options(this->ssl, max_mask & ~proto_mask);
468   }
469 
470 protected:
471   const IpEndpoint &
_getLocalEndpoint()472   _getLocalEndpoint() override
473   {
474     return local_addr;
475   }
476 
477   void _fire_ssl_servername_event() override;
478 
479 private:
480   std::string_view map_tls_protocol_to_tag(const char *proto_string) const;
481   bool update_rbio(bool move_to_socket);
482   void increment_ssl_version_metric(int version) const;
483   NetProcessor *_getNetProcessor() override;
484   void *_prepareForMigration() override;
485 
486   enum SSLHandshakeStatus sslHandshakeStatus = SSL_HANDSHAKE_ONGOING;
487   bool sslClientRenegotiationAbort           = false;
488   MIOBuffer *handShakeBuffer                 = nullptr;
489   IOBufferReader *handShakeHolder            = nullptr;
490   IOBufferReader *handShakeReader            = nullptr;
491   int handShakeBioStored                     = 0;
492 
493   bool transparentPassThrough = false;
494 
495   int sent_cert = 0;
496 
497   /// The current hook.
498   /// @note For @C SSL_HOOKS_INVOKE, this is the hook to invoke.
499   class APIHook *curHook = nullptr;
500 
501   enum SSLHandshakeHookState {
502     HANDSHAKE_HOOKS_PRE,
503     HANDSHAKE_HOOKS_PRE_INVOKE,
504     HANDSHAKE_HOOKS_CLIENT_HELLO,
505     HANDSHAKE_HOOKS_CLIENT_HELLO_INVOKE,
506     HANDSHAKE_HOOKS_SNI,
507     HANDSHAKE_HOOKS_CERT,
508     HANDSHAKE_HOOKS_CERT_INVOKE,
509     HANDSHAKE_HOOKS_CLIENT_CERT,
510     HANDSHAKE_HOOKS_CLIENT_CERT_INVOKE,
511     HANDSHAKE_HOOKS_OUTBOUND_PRE,
512     HANDSHAKE_HOOKS_OUTBOUND_PRE_INVOKE,
513     HANDSHAKE_HOOKS_VERIFY_SERVER,
514     HANDSHAKE_HOOKS_DONE
515   } sslHandshakeHookState = HANDSHAKE_HOOKS_PRE;
516 
517   int64_t redoWriteSize       = 0;
518   char *tunnel_host           = nullptr;
519   in_port_t tunnel_port       = 0;
520   SNIRoutingType _tunnel_type = SNIRoutingType::NONE;
521   X509_STORE_CTX *verify_cert = nullptr;
522 
523   // Null-terminated string, or nullptr if there is no SNI server name.
524   std::unique_ptr<char[]> _ca_cert_file;
525   std::unique_ptr<char[]> _ca_cert_dir;
526 
527   EventIO async_ep{};
528 
529 private:
530   void _make_ssl_connection(SSL_CTX *ctx);
531   void _bindSSLObject();
532   void _unbindSSLObject();
533 };
534 
535 typedef int (SSLNetVConnection::*SSLNetVConnHandler)(int, void *);
536 
537 extern ClassAllocator<SSLNetVConnection> sslNetVCAllocator;
538 
539 //
540 // Inline Functions
541 //
542 inline SNIRoutingType
tunnel_type()543 SSLNetVConnection::tunnel_type() const
544 {
545   return _tunnel_type;
546 }
547 
548 /**
549    Returns true if this vc was configured for forward_route or partial_blind_route
550  */
551 inline bool
decrypt_tunnel()552 SSLNetVConnection::decrypt_tunnel() const
553 {
554   return _tunnel_type == SNIRoutingType::FORWARD || _tunnel_type == SNIRoutingType::PARTIAL_BLIND;
555 }
556 
557 /**
558    Returns true if this vc was configured partial_blind_route
559  */
560 inline bool
upstream_tls()561 SSLNetVConnection::upstream_tls() const
562 {
563   return _tunnel_type == SNIRoutingType::PARTIAL_BLIND;
564 }
565