1 /** @file
2  *
3  *  QUIC Crypto (TLS to Secure QUIC) using OpenSSL
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 #include "QUICTLS.h"
24 
25 #include <openssl/err.h>
26 #include <openssl/ssl.h>
27 #include <openssl/bio.h>
28 #include <openssl/kdf.h>
29 #include <openssl/evp.h>
30 
31 #include "QUICGlobals.h"
32 #include "QUICConnection.h"
33 #include "QUICPacketProtectionKeyInfo.h"
34 
35 static constexpr char tag[] = "quic_tls";
36 
37 static QUICEncryptionLevel
convert_level_ats2ssl(enum ssl_encryption_level_t level)38 convert_level_ats2ssl(enum ssl_encryption_level_t level)
39 {
40   switch (level) {
41   case ssl_encryption_initial:
42     return QUICEncryptionLevel::INITIAL;
43   case ssl_encryption_early_data:
44     return QUICEncryptionLevel::ZERO_RTT;
45   case ssl_encryption_handshake:
46     return QUICEncryptionLevel::HANDSHAKE;
47   case ssl_encryption_application:
48     return QUICEncryptionLevel::ONE_RTT;
49   default:
50     return QUICEncryptionLevel::NONE;
51   }
52 }
53 
54 static int
set_encryption_secrets(SSL * ssl,enum ssl_encryption_level_t level,const uint8_t * read_secret,const uint8_t * write_secret,size_t secret_len)55 set_encryption_secrets(SSL *ssl, enum ssl_encryption_level_t level, const uint8_t *read_secret, const uint8_t *write_secret,
56                        size_t secret_len)
57 {
58   QUICTLS *qtls = static_cast<QUICTLS *>(SSL_get_ex_data(ssl, QUIC::ssl_quic_tls_index));
59 
60   qtls->update_negotiated_cipher();
61 
62   QUICEncryptionLevel ats_level = convert_level_ats2ssl(level);
63   if (read_secret) {
64     qtls->update_key_materials_for_read(ats_level, read_secret, secret_len);
65   }
66   if (write_secret) {
67     qtls->update_key_materials_for_write(ats_level, write_secret, secret_len);
68   }
69 
70   if (ats_level == QUICEncryptionLevel::ONE_RTT) {
71     // FIXME Where should this be placed?
72     const uint8_t *tp_buf;
73     size_t tp_buf_len;
74     SSL_get_peer_quic_transport_params(ssl, &tp_buf, &tp_buf_len);
75     const QUICConnection *qc = static_cast<const QUICConnection *>(SSL_get_ex_data(ssl, QUIC::ssl_quic_qc_index));
76     QUICVersion version      = qc->negotiated_version();
77     if (SSL_is_server(ssl)) {
78       qtls->set_remote_transport_parameters(std::make_shared<QUICTransportParametersInClientHello>(tp_buf, tp_buf_len, version));
79     } else {
80       qtls->set_remote_transport_parameters(
81         std::make_shared<QUICTransportParametersInEncryptedExtensions>(tp_buf, tp_buf_len, version));
82     }
83   }
84 
85   return 1;
86 }
87 
88 static int
add_handshake_data(SSL * ssl,enum ssl_encryption_level_t level,const uint8_t * data,size_t len)89 add_handshake_data(SSL *ssl, enum ssl_encryption_level_t level, const uint8_t *data, size_t len)
90 {
91   QUICEncryptionLevel ats_level = convert_level_ats2ssl(level);
92 
93   QUICTLS *qtls = static_cast<QUICTLS *>(SSL_get_ex_data(ssl, QUIC::ssl_quic_tls_index));
94   qtls->on_handshake_data_generated(ats_level, data, len);
95 
96   return 1;
97 }
98 
99 static int
flush_flight(SSL * ssl)100 flush_flight(SSL *ssl)
101 {
102   QUICTLS *qtls = static_cast<QUICTLS *>(SSL_get_ex_data(ssl, QUIC::ssl_quic_tls_index));
103   qtls->set_ready_for_write();
104 
105   return 1;
106 }
107 
108 static int
send_alert(SSL * ssl,enum ssl_encryption_level_t level,uint8_t alert)109 send_alert(SSL *ssl, enum ssl_encryption_level_t level, uint8_t alert)
110 {
111   QUICTLS *qtls = static_cast<QUICTLS *>(SSL_get_ex_data(ssl, QUIC::ssl_quic_tls_index));
112   qtls->on_tls_alert(alert);
113   return 1;
114 }
115 
116 static const SSL_QUIC_METHOD quic_method = {set_encryption_secrets, add_handshake_data, flush_flight, send_alert};
117 
118 void
_msg_cb(int write_p,int version,int content_type,const void * buf,size_t len,SSL * ssl,void * arg)119 QUICTLS::_msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
120 {
121   // Debug for reading
122   if (write_p == 0) {
123     QUICTLS::_print_hs_message(content_type, buf, len);
124   }
125 }
126 
QUICTLS(QUICPacketProtectionKeyInfo & pp_key_info,SSL_CTX * ssl_ctx,NetVConnectionContext_t nvc_ctx,const NetVCOptions & netvc_options,const char * session_file,const char * keylog_file)127 QUICTLS::QUICTLS(QUICPacketProtectionKeyInfo &pp_key_info, SSL_CTX *ssl_ctx, NetVConnectionContext_t nvc_ctx,
128                  const NetVCOptions &netvc_options, const char *session_file, const char *keylog_file)
129   : QUICHandshakeProtocol(pp_key_info),
130     _session_file(session_file),
131     _keylog_file(keylog_file),
132     _ssl(SSL_new(ssl_ctx)),
133     _netvc_context(nvc_ctx)
134 {
135   ink_assert(this->_netvc_context != NET_VCONNECTION_UNSET);
136 
137   if (this->_netvc_context == NET_VCONNECTION_OUT) {
138     SSL_set_connect_state(this->_ssl);
139 
140     SSL_set_alpn_protos(this->_ssl, reinterpret_cast<const unsigned char *>(netvc_options.alpn_protos.data()),
141                         netvc_options.alpn_protos.size());
142     const ats_scoped_str &tlsext_host_name = netvc_options.sni_hostname ? netvc_options.sni_hostname : netvc_options.sni_servername;
143     SSL_set_tlsext_host_name(this->_ssl, tlsext_host_name.get());
144   } else {
145     SSL_set_accept_state(this->_ssl);
146   }
147 
148   SSL_set_ex_data(this->_ssl, QUIC::ssl_quic_tls_index, this);
149   SSL_set_quic_method(this->_ssl, &quic_method);
150 #ifdef HAVE_SSL_SET_QUIC_EARLY_DATA_ENABLED
151   SSL_set_quic_early_data_enabled(this->_ssl, 1);
152 #endif
153 
154   if (session_file && this->_netvc_context == NET_VCONNECTION_OUT) {
155     auto file = BIO_new_file(session_file, "r");
156     if (file == nullptr) {
157       Debug(tag, "Could not read tls session file %s", session_file);
158       return;
159     }
160 
161     auto session = PEM_read_bio_SSL_SESSION(file, nullptr, nullptr, nullptr);
162     if (session == nullptr) {
163       Debug(tag, "Could not read tls session file %s", session_file);
164     } else {
165       if (!SSL_set_session(this->_ssl, session)) {
166         Debug(tag, "Session resumption failed : %s", session_file);
167       } else {
168         Debug(tag, "Session resumption success : %s", session_file);
169         this->_is_session_reused = true;
170       }
171       SSL_SESSION_free(session);
172     }
173 
174     BIO_free(file);
175   }
176 }
177 
178 void
set_local_transport_parameters(std::shared_ptr<const QUICTransportParameters> tp)179 QUICTLS::set_local_transport_parameters(std::shared_ptr<const QUICTransportParameters> tp)
180 {
181   this->_local_transport_parameters = tp;
182 
183   uint8_t buf[UINT16_MAX];
184   uint16_t len;
185   this->_local_transport_parameters->store(buf, &len);
186   SSL_set_quic_transport_params(this->_ssl, buf, len);
187 }
188 
189 int
_process_post_handshake_messages(QUICHandshakeMsgs * out,const QUICHandshakeMsgs * in)190 QUICTLS::_process_post_handshake_messages(QUICHandshakeMsgs *out, const QUICHandshakeMsgs *in)
191 {
192   this->_pass_quic_data_to_ssl_impl(*in);
193   return SSL_process_quic_post_handshake(this->_ssl);
194 }
195 
196 void
_store_negotiated_cipher()197 QUICTLS::_store_negotiated_cipher()
198 {
199   ink_assert(this->_ssl);
200 
201   const EVP_CIPHER *cipher     = nullptr;
202   size_t tag_len               = 0;
203   const SSL_CIPHER *ssl_cipher = SSL_get_current_cipher(this->_ssl);
204 
205   if (ssl_cipher) {
206     switch (SSL_CIPHER_get_id(ssl_cipher)) {
207     case TLS1_3_CK_AES_128_GCM_SHA256:
208       cipher  = EVP_aes_128_gcm();
209       tag_len = EVP_GCM_TLS_TAG_LEN;
210       break;
211     case TLS1_3_CK_AES_256_GCM_SHA384:
212       cipher  = EVP_aes_256_gcm();
213       tag_len = EVP_GCM_TLS_TAG_LEN;
214       break;
215     case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
216       cipher  = EVP_chacha20_poly1305();
217       tag_len = EVP_CHACHAPOLY_TLS_TAG_LEN;
218       break;
219     case TLS1_3_CK_AES_128_CCM_SHA256:
220       cipher  = EVP_aes_128_ccm();
221       tag_len = EVP_GCM_TLS_TAG_LEN;
222       break;
223     case TLS1_3_CK_AES_128_CCM_8_SHA256:
224       cipher  = EVP_aes_128_ccm();
225       tag_len = EVP_CCM8_TLS_TAG_LEN;
226       break;
227     default:
228       ink_assert(false);
229     }
230   } else {
231     ink_assert(false);
232   }
233 
234   this->_pp_key_info.set_cipher(cipher, tag_len);
235 }
236 
237 void
_store_negotiated_cipher_for_hp()238 QUICTLS::_store_negotiated_cipher_for_hp()
239 {
240   ink_assert(this->_ssl);
241 
242   const EVP_CIPHER *cipher_for_hp = nullptr;
243   const SSL_CIPHER *ssl_cipher    = SSL_get_current_cipher(this->_ssl);
244 
245   if (ssl_cipher) {
246     switch (SSL_CIPHER_get_id(ssl_cipher)) {
247     case TLS1_3_CK_AES_128_GCM_SHA256:
248       cipher_for_hp = EVP_aes_128_ecb();
249       break;
250     case TLS1_3_CK_AES_256_GCM_SHA384:
251       cipher_for_hp = EVP_aes_256_ecb();
252       break;
253     case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
254       cipher_for_hp = EVP_chacha20();
255       break;
256     case TLS1_3_CK_AES_128_CCM_SHA256:
257     case TLS1_3_CK_AES_128_CCM_8_SHA256:
258       cipher_for_hp = EVP_aes_128_ecb();
259       break;
260     default:
261       ink_assert(false);
262       break;
263     }
264   } else {
265     ink_assert(false);
266   }
267 
268   this->_pp_key_info.set_cipher_for_hp(cipher_for_hp);
269 }
270 
271 int
_read_early_data()272 QUICTLS::_read_early_data()
273 {
274   // This is for Hacked OpenSSL. Do nothing here.
275   return 1;
276 }
277 
278 int
_write_early_data()279 QUICTLS::_write_early_data()
280 {
281   // This is for Hacked OpenSSL. Do nothing here.
282   return 1;
283 }
284 
285 void
_pass_quic_data_to_ssl_impl(const QUICHandshakeMsgs & in)286 QUICTLS::_pass_quic_data_to_ssl_impl(const QUICHandshakeMsgs &in)
287 {
288   for (auto level : QUIC_ENCRYPTION_LEVELS) {
289     int index = static_cast<int>(level);
290     ssl_encryption_level_t ossl_level;
291     switch (level) {
292     case QUICEncryptionLevel::INITIAL:
293       ossl_level = ssl_encryption_initial;
294       break;
295     case QUICEncryptionLevel::ZERO_RTT:
296       ossl_level = ssl_encryption_early_data;
297       break;
298     case QUICEncryptionLevel::HANDSHAKE:
299       ossl_level = ssl_encryption_handshake;
300       break;
301     case QUICEncryptionLevel::ONE_RTT:
302       ossl_level = ssl_encryption_application;
303       break;
304     default:
305       // Should not be happened
306       ossl_level = ssl_encryption_application;
307       break;
308     }
309     if (in.offsets[index + 1] - in.offsets[index]) {
310       int start = 0;
311       for (int i = 0; i < index; ++i) {
312         start += in.offsets[index];
313       }
314       SSL_provide_quic_data(this->_ssl, ossl_level, in.buf + start, in.offsets[index + 1] - in.offsets[index]);
315     }
316   }
317 }
318 
319 const EVP_MD *
_get_handshake_digest() const320 QUICTLS::_get_handshake_digest() const
321 {
322   switch (SSL_CIPHER_get_id(SSL_get_current_cipher(this->_ssl))) {
323   case TLS1_3_CK_AES_128_GCM_SHA256:
324   case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
325   case TLS1_3_CK_AES_128_CCM_SHA256:
326   case TLS1_3_CK_AES_128_CCM_8_SHA256:
327     return EVP_sha256();
328   case TLS1_3_CK_AES_256_GCM_SHA384:
329     return EVP_sha384();
330   default:
331     ink_assert(false);
332     return nullptr;
333   }
334 }
335