Skip to content

Commit

Permalink
define & install quic_method_cb
Browse files Browse the repository at this point in the history
Summary:
- installs quic handshake callbacks on ssl context in constructor

- defines a friend struct, `MbedTlsQuicMethodCb`, to proxy c-style callbacks to `MbedClientHandshake`

- no-op MbedClientHandshake definitions of the mbedtls callbacks as of now (implemented over next few diffs)

Reviewed By: lhuang04

Differential Revision: D51173192

fbshipit-source-id: c8c9c44c46188734db0729a4a1d70477e9d8122f
  • Loading branch information
hanidamlaj authored and facebook-github-bot committed Nov 20, 2023
1 parent 4bb293a commit d5d9615
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 0 deletions.
72 changes: 72 additions & 0 deletions quic/mbed/MbedClientHandshake.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,89 @@ void initSslConfigDefaults(mbedtls_ssl_config* conf) {
// TODO(@damlaj) early data support likely goes here
}

// convert mbedtls_ssl_crypto_level to quic::EncryptionLevel
quic::EncryptionLevel toQuicEncLevel(mbedtls_ssl_crypto_level level) {
switch (level) {
case MBEDTLS_SSL_CRYPTO_LEVEL_INITIAL:
return quic::EncryptionLevel::Initial;
case MBEDTLS_SSL_CRYPTO_LEVEL_HANDSHAKE:
return quic::EncryptionLevel::Handshake;
case MBEDTLS_SSL_CRYPTO_LEVEL_APPLICATION:
return quic::EncryptionLevel::AppData;
case MBEDTLS_SSL_CRYPTO_LEVEL_EARLY_DATA:
return quic::EncryptionLevel::EarlyData;
default:
folly::assume_unreachable();
};
}

} // namespace

namespace quic {

/**
* MbedTlsQuicMethodCb is a friend struct of MbedClientHandshake that proxies
* c-style callbacks to the corresponding private MbedClientHandshake member
* methods. We likely don't want mbed callbacks to be exposed publicly.
*/
struct MbedTlsQuicMethodCb {
// cb invoked when secrets are derived by the tls layer for a given enc level
static int mbedtls_quic_set_encryption_secrets(
void* param,
mbedtls_ssl_crypto_level level,
const uint8_t* read_secret,
const uint8_t* write_secret,
size_t len) {
return reinterpret_cast<MbedClientHandshake*>(param)->setEncryptionSecrets(
toQuicEncLevel(level), read_secret, write_secret, len);
}

// cb invoked when new handshake data is available to send to peer
static int mbedtls_quic_add_handshake_data(
void* param,
mbedtls_ssl_crypto_level level,
const uint8_t* data,
size_t len) {
return reinterpret_cast<MbedClientHandshake*>(param)->addHandshakeData(
toQuicEncLevel(level), data, len);
}

// cb invoked to inform quic to deliver alert to peer
static int mbedtls_quic_send_alert(
void* param,
mbedtls_ssl_crypto_level level,
uint8_t alert) {
return reinterpret_cast<MbedClientHandshake*>(param)->sendAlert(
toQuicEncLevel(level), alert);
}

// cb invoked on new TLS session
static void mbedtls_quic_process_new_session(
void* param,
mbedtls_ssl_session* session_ticket) {
return reinterpret_cast<MbedClientHandshake*>(param)->processNewSession(
session_ticket);
}
};

struct mbedtls_quic_method mbedtls_quic_method_cb {
.set_encryption_secrets =
MbedTlsQuicMethodCb::mbedtls_quic_set_encryption_secrets,
.add_handshake_data = MbedTlsQuicMethodCb::mbedtls_quic_add_handshake_data,
.send_alert = MbedTlsQuicMethodCb::mbedtls_quic_send_alert,
.process_new_session = MbedTlsQuicMethodCb::mbedtls_quic_process_new_session,
};

MbedClientHandshake::MbedClientHandshake(QuicClientConnectionState* conn)
: ClientHandshake(conn) {
// init ssl_ctx
mbedtls_ssl_init(&ssl_ctx);
// init & apply ssl config defaults
initSslConfigDefaults(&ssl_conf);
CHECK_EQ(mbedtls_ssl_setup(&ssl_ctx, &ssl_conf), 0);

// install quic callbacks
mbedtls_ssl_set_hs_quic_method(&ssl_ctx, this, &mbedtls_quic_method_cb);
}

MbedClientHandshake::~MbedClientHandshake() {
Expand Down
34 changes: 34 additions & 0 deletions quic/mbed/MbedClientHandshake.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,41 @@ class MbedClientHandshake : public ClientHandshake {
std::pair<std::unique_ptr<Aead>, std::unique_ptr<PacketNumberCipher>>
buildCiphers(CipherKind kind, folly::ByteRange secret) override;

/**
* Struct used to define static c-style callbacks and proxy them to the
* corresponding methods on this object. This allows us to mark the MbedTLS
* callback functions as private.
*/
friend struct MbedTlsQuicMethodCb;

private:
// MbedTLS quic callbacks

// cb invoked when secrets are derived by the tls layer for a given enc level
int setEncryptionSecrets(
EncryptionLevel /*level*/,
const uint8_t* /*readKey*/,
const uint8_t* /*writeKey*/,
size_t /*length*/) {
return 0;
}

// cb invoked when new handshake data is available to send to peer
int addHandshakeData(
EncryptionLevel /*level*/,
const uint8_t* /*data*/,
size_t /*length*/) {
return 0;
}

// cb invoked to inform quic to deliver alert to peer
int sendAlert(EncryptionLevel /*level*/, uint8_t /*alert*/) {
return 0;
}

// cb invoked on new TLS session ticket post-handshake
void processNewSession(mbedtls_ssl_session* /*sessionTicket*/) {}

mbedtls_ssl_config ssl_conf;
mbedtls_ssl_context ssl_ctx;
MbedCryptoFactory crypto_factory;
Expand Down

0 comments on commit d5d9615

Please sign in to comment.