MINOR: quic: Make QUIC-TLS support at least two initial salts
These salts are used to derive initial secrets to decrypt the first Initial packet. We support draft-29 and v1 QUIC version initial salts. Add parameters to our QUIC-TLS API functions used to derive these secret for these salts. Make our xprt_quic use the correct initial salt upon QUIC version field found in the first paquet. Useful to support connections with curl which use draft-29 QUIC version.
This commit is contained in:
parent
2766e78f3b
commit
2fc76cffaf
|
@ -27,12 +27,28 @@
|
|||
#include <haproxy/trace.h>
|
||||
#include <haproxy/xprt_quic.h>
|
||||
|
||||
/* Initial salt depending on QUIC version to derive client/server initial secrets.
|
||||
* This one is for draft-29 QUIC version.
|
||||
*/
|
||||
unsigned char initial_salt_draft_29[20] = {
|
||||
0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c,
|
||||
0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0,
|
||||
0x43, 0x90, 0xa8, 0x99
|
||||
};
|
||||
|
||||
unsigned char initial_salt_v1[20] = {
|
||||
0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3,
|
||||
0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad,
|
||||
0xcc, 0xbb, 0x7f, 0x0a
|
||||
};
|
||||
|
||||
void quic_tls_keys_hexdump(struct buffer *buf, struct quic_tls_secrets *secs);
|
||||
|
||||
void quic_tls_secret_hexdump(struct buffer *buf,
|
||||
const unsigned char *secret, size_t secret_len);
|
||||
|
||||
int quic_derive_initial_secret(const EVP_MD *md,
|
||||
const unsigned char *initial_salt, size_t initial_salt_sz,
|
||||
unsigned char *initial_secret, size_t initial_secret_sz,
|
||||
const unsigned char *secret, size_t secret_sz);
|
||||
|
||||
|
@ -390,6 +406,7 @@ static inline void quic_tls_discard_keys(struct quic_enc_level *qel)
|
|||
* Return 1 if succeeded or 0 if not.
|
||||
*/
|
||||
static inline int qc_new_isecs(struct quic_conn *qc,
|
||||
const unsigned char *salt, size_t salt_len,
|
||||
const unsigned char *cid, size_t cidlen, int server)
|
||||
{
|
||||
unsigned char initial_secret[32];
|
||||
|
@ -404,6 +421,7 @@ static inline int qc_new_isecs(struct quic_conn *qc,
|
|||
ctx = &qc->els[QUIC_TLS_ENC_LEVEL_INITIAL].tls_ctx;
|
||||
quic_initial_tls_ctx_init(ctx);
|
||||
if (!quic_derive_initial_secret(ctx->rx.md,
|
||||
salt, salt_len,
|
||||
initial_secret, sizeof initial_secret,
|
||||
cid, cidlen))
|
||||
goto err;
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include <import/ebmbtree.h>
|
||||
|
||||
#define QUIC_PROTOCOL_VERSION_DRAFT_28 0xff00001c /* draft-28 */
|
||||
#define QUIC_PROTOCOL_VERSION_DRAFT_29 0xff00001d /* draft-29 */
|
||||
#define QUIC_PROTOCOL_VERSION_1 0x00000001 /* V1 */
|
||||
|
||||
#define QUIC_INITIAL_IPV4_MTU 1252 /* (bytes) */
|
||||
#define QUIC_INITIAL_IPV6_MTU 1232
|
||||
|
|
|
@ -18,21 +18,6 @@
|
|||
__attribute__((format (printf, 3, 4)))
|
||||
void hexdump(const void *buf, size_t buflen, const char *title_fmt, ...);
|
||||
|
||||
/* Initial salt depending on QUIC version to derive client/server initial secrets.
|
||||
* This one is for draft-29 QUIC version.
|
||||
*/
|
||||
unsigned char initial_salt[20] = {
|
||||
0xaf, 0xbf, 0xec, 0x28, 0x99, 0x93, 0xd2, 0x4c,
|
||||
0x9e, 0x97, 0x86, 0xf1, 0x9c, 0x61, 0x11, 0xe0,
|
||||
0x43, 0x90, 0xa8, 0x99
|
||||
};
|
||||
|
||||
unsigned char initial_salt_v1[20] = {
|
||||
0x38, 0x76, 0x2c, 0xf7, 0xf5, 0x59, 0x34, 0xb3,
|
||||
0x4d, 0x17, 0x9a, 0xe6, 0xa4, 0xc8, 0x0c, 0xad,
|
||||
0xcc, 0xbb, 0x7f, 0x0a
|
||||
};
|
||||
|
||||
/* Dump the RX/TX secrets of <secs> QUIC TLS secrets. */
|
||||
void quic_tls_keys_hexdump(struct buffer *buf, struct quic_tls_secrets *secs)
|
||||
{
|
||||
|
@ -67,7 +52,7 @@ void quic_tls_secret_hexdump(struct buffer *buf,
|
|||
int quic_hkdf_extract(const EVP_MD *md,
|
||||
unsigned char *buf, size_t *buflen,
|
||||
const unsigned char *key, size_t keylen,
|
||||
unsigned char *salt, size_t saltlen)
|
||||
const unsigned char *salt, size_t saltlen)
|
||||
{
|
||||
return HKDF_extract(buf, buflen, md, key, keylen, salt, saltlen);
|
||||
}
|
||||
|
@ -83,7 +68,7 @@ int quic_hkdf_expand(const EVP_MD *md,
|
|||
int quic_hkdf_extract(const EVP_MD *md,
|
||||
unsigned char *buf, size_t *buflen,
|
||||
const unsigned char *key, size_t keylen,
|
||||
unsigned char *salt, size_t saltlen)
|
||||
const unsigned char *salt, size_t saltlen)
|
||||
{
|
||||
EVP_PKEY_CTX *ctx;
|
||||
|
||||
|
@ -224,11 +209,12 @@ int quic_tls_derive_keys(const EVP_CIPHER *aead, const EVP_CIPHER *hp,
|
|||
* Returns the size of the derived secret if succeeded, 0 if not.
|
||||
*/
|
||||
int quic_derive_initial_secret(const EVP_MD *md,
|
||||
const unsigned char *initial_salt, size_t initial_salt_sz,
|
||||
unsigned char *initial_secret, size_t initial_secret_sz,
|
||||
const unsigned char *secret, size_t secret_sz)
|
||||
{
|
||||
if (!quic_hkdf_extract(md, initial_secret, &initial_secret_sz, secret, secret_sz,
|
||||
initial_salt_v1, sizeof initial_salt_v1))
|
||||
initial_salt, initial_salt_sz))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -3371,6 +3371,8 @@ static ssize_t qc_lstnr_pkt_rcv(unsigned char **buf, const unsigned char *end,
|
|||
int ipv4;
|
||||
struct quic_cid *odcid;
|
||||
struct ebmb_node *n = NULL;
|
||||
const unsigned char *salt = initial_salt_v1;
|
||||
size_t salt_len = sizeof initial_salt_v1;
|
||||
|
||||
if (pkt->type != QUIC_PACKET_TYPE_INITIAL) {
|
||||
TRACE_PROTO("Non Initiial packet", QUIC_EV_CONN_LPKT);
|
||||
|
@ -3406,7 +3408,12 @@ static ssize_t qc_lstnr_pkt_rcv(unsigned char **buf, const unsigned char *end,
|
|||
/* NOTE: the socket address has been concatenated to the destination ID
|
||||
* chosen by the client for Initial packets.
|
||||
*/
|
||||
if (!qc_new_isecs(qc, pkt->dcid.data, pkt->odcid_len, 1)) {
|
||||
if (pkt->version == QUIC_PROTOCOL_VERSION_DRAFT_29) {
|
||||
salt = initial_salt_draft_29;
|
||||
salt_len = sizeof initial_salt_draft_29;
|
||||
}
|
||||
if (!qc_new_isecs(qc, salt, salt_len,
|
||||
pkt->dcid.data, pkt->odcid_len, 1)) {
|
||||
TRACE_PROTO("Packet dropped", QUIC_EV_CONN_LPKT, qc->conn);
|
||||
goto err;
|
||||
}
|
||||
|
@ -4360,7 +4367,8 @@ static int qc_conn_init(struct connection *conn, void **xprt_ctx)
|
|||
|
||||
conn->qc = qc;
|
||||
qc->conn = conn;
|
||||
if (!qc_new_isecs(qc, dcid, sizeof dcid, 0))
|
||||
if (!qc_new_isecs(qc, initial_salt_v1, sizeof initial_salt_v1,
|
||||
dcid, sizeof dcid, 0))
|
||||
goto err;
|
||||
|
||||
if (ssl_bio_and_sess_init(conn, srv->ssl_ctx.ctx,
|
||||
|
|
Loading…
Reference in New Issue