blob: e60d9206c8f52e0ad39a555aaa88a49fd217d3dc [file] [log] [blame]
/** @file
*
* QUIC TLS
*
* @section license License
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <openssl/ssl.h>
#ifdef OPENSSL_IS_BORINGSSL
#include <openssl/digest.h>
#include <openssl/cipher.h>
#else
#include <openssl/evp.h>
#endif
#include "I_EventSystem.h"
#include "I_NetVConnection.h"
#include "QUICHandshakeProtocol.h"
// TODO: fix size
static constexpr int MAX_HANDSHAKE_MSG_LEN = 65527;
class QUICTLS : public QUICHandshakeProtocol
{
public:
QUICTLS(QUICPacketProtectionKeyInfo &pp_key_info, SSL_CTX *ssl_ctx, NetVConnectionContext_t nvc_ctx,
const NetVCOptions &netvc_options, const char *session_file = nullptr, const char *keylog_file = nullptr);
~QUICTLS();
// TODO: integrate with _early_data_processed
enum class HandshakeState {
PROCESSING,
ABORTED,
};
static QUICEncryptionLevel get_encryption_level(int msg_type);
static uint64_t convert_to_quic_trans_error_code(uint8_t alert);
std::shared_ptr<const QUICTransportParameters> local_transport_parameters() override;
std::shared_ptr<const QUICTransportParameters> remote_transport_parameters() override;
void set_local_transport_parameters(std::shared_ptr<const QUICTransportParameters> tp) override;
void set_remote_transport_parameters(std::shared_ptr<const QUICTransportParameters> tp) override;
const char *session_file() const;
const char *keylog_file() const;
// FIXME Should not exist
SSL *ssl_handle();
// QUICHandshakeProtocol
int handshake(QUICHandshakeMsgs **out, const QUICHandshakeMsgs *in) override;
void reset() override;
bool is_handshake_finished() const override;
bool is_ready_to_derive() const override;
int initialize_key_materials(QUICConnectionId cid) override;
void update_negotiated_cipher();
void update_key_materials_for_read(QUICEncryptionLevel level, const uint8_t *secret, size_t secret_len);
void update_key_materials_for_write(QUICEncryptionLevel level, const uint8_t *secret, size_t secret_len);
const char *negotiated_cipher_suite() const override;
void negotiated_application_name(const uint8_t **name, unsigned int *len) const override;
QUICEncryptionLevel current_encryption_level() const override;
void abort_handshake() override;
bool has_crypto_error() const override;
uint64_t crypto_error() const override;
void set_ready_for_write();
void on_handshake_data_generated(QUICEncryptionLevel level, const uint8_t *data, size_t len);
void on_tls_alert(uint8_t alert);
private:
QUICKeyGenerator _keygen_for_client = QUICKeyGenerator(QUICKeyGenerator::Context::CLIENT);
QUICKeyGenerator _keygen_for_server = QUICKeyGenerator(QUICKeyGenerator::Context::SERVER);
const EVP_MD *_get_handshake_digest() const;
int _read_early_data();
int _write_early_data();
void _pass_quic_data_to_ssl_impl(const QUICHandshakeMsgs &in);
int _handshake(QUICHandshakeMsgs **out, const QUICHandshakeMsgs *in);
int _process_post_handshake_messages(QUICHandshakeMsgs *out, const QUICHandshakeMsgs *in);
void _generate_0rtt_key();
void _update_encryption_level(QUICEncryptionLevel level);
void _store_negotiated_cipher();
void _store_negotiated_cipher_for_hp();
void _print_km(const char *header, const uint8_t *key_for_hp, size_t key_for_hp_len, const uint8_t *key, size_t key_len,
const uint8_t *iv, size_t iv_len, const uint8_t *secret = nullptr, size_t secret_len = 0,
QUICKeyPhase phase = QUICKeyPhase::INITIAL);
static void _print_hs_message(int content_type, const void *buf, size_t len);
static void _msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg);
const char *_session_file = nullptr;
const char *_keylog_file = nullptr;
SSL *_ssl = nullptr;
NetVConnectionContext_t _netvc_context = NET_VCONNECTION_UNSET;
bool _early_data_processed = false;
bool _is_session_reused = false;
bool _early_data = true;
QUICEncryptionLevel _current_level = QUICEncryptionLevel::INITIAL;
HandshakeState _state = HandshakeState::PROCESSING;
std::shared_ptr<const QUICTransportParameters> _local_transport_parameters = nullptr;
std::shared_ptr<const QUICTransportParameters> _remote_transport_parameters = nullptr;
uint8_t _out_buf[MAX_HANDSHAKE_MSG_LEN] = {0};
QUICHandshakeMsgs _out = {_out_buf, MAX_HANDSHAKE_MSG_LEN, {0}, 0};
bool _should_flush = false;
bool _has_crypto_error = false;
uint64_t _crypto_error = 0;
};