Communicate transport parameters via encrypted payload

This commit is contained in:
Mark Spanbroek 2020-10-06 12:00:59 +02:00 committed by markspanbroek
parent 20d3b009dc
commit 81cfe64137
5 changed files with 47 additions and 17 deletions

View File

@ -6,3 +6,6 @@ proc `[]=`*[T,U,V](
doAssert replacement.len == slice.len doAssert replacement.len == slice.len
for i in 0..<replacement.len: for i in 0..<replacement.len:
target[slice.a + i] = replacement[i] target[slice.a + i] = replacement[i]
template toOpenArray*[T](a: ptr T, length: uint): openArray[T] =
toOpenArray(cast[ptr UncheckedArray[T]](a), 0, length.int-1)

View File

@ -1,3 +1,4 @@
import quic/openarray
import ngtcp2 import ngtcp2
import ids import ids
import encrypt import encrypt
@ -5,21 +6,18 @@ import decrypt
import hp import hp
import keys import keys
import settings import settings
import params
import crypto
let zeroKey = Key() let zeroKey = Key()
var cryptoData: array[4096, uint8]
var randomId: ngtcp2_cid var randomId: ngtcp2_cid
proc clientInitial(connection: ptr ngtcp2_conn, user_data: pointer): cint {.cdecl.} = proc clientInitial(connection: ptr ngtcp2_conn, user_data: pointer): cint {.cdecl.} =
connection.install0RttKey(zeroKey) connection.install0RttKey(zeroKey)
connection.submitCryptoData()
assert 0 == ngtcp2_conn_submit_crypto_data(
connection, NGTCP2_CRYPTO_LEVEL_INITIAL, addr cryptoData[0], sizeof(cryptoData).uint
)
proc receiveCryptoData(connection: ptr ngtcp2_conn, level: ngtcp2_crypto_level, offset: uint64, data: ptr uint8, datalen: uint, userData: pointer): cint {.cdecl.} = proc receiveCryptoData(connection: ptr ngtcp2_conn, level: ngtcp2_crypto_level, offset: uint64, data: ptr uint8, datalen: uint, userData: pointer): cint {.cdecl.} =
var params = defaultSettings().transport_params var params = decodeTransportParameters(toOpenArray(data, datalen))
params.initial_scid = connection.ngtcp2_conn_get_dcid()[]
params.original_dcid = randomId params.original_dcid = randomId
assert 0 == ngtcp2_conn_set_remote_transport_params(connection, addr params) assert 0 == ngtcp2_conn_set_remote_transport_params(connection, addr params)

View File

@ -0,0 +1,11 @@
import ngtcp2
import params
proc submitCryptoData*(connection: ptr ngtcp2_conn) =
var cryptoData = connection.encodeTransportParameters()
assert 0 == ngtcp2_conn_submit_crypto_data(
connection,
NGTCP2_CRYPTO_LEVEL_INITIAL,
addr cryptoData[0],
cryptoData.len.uint
)

View File

@ -0,0 +1,22 @@
import ngtcp2
proc encodeTransportParameters*(connection: ptr ngtcp2_conn): seq[byte] =
var buffer: array[4096, byte]
var params: ngtcp2_transport_params
connection.ngtcp2_conn_get_local_transport_params(addr params)
let length = ngtcp2_encode_transport_params(
addr buffer[0],
buffer.len.uint,
NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
addr params
)
buffer[0..<length]
proc decodeTransportParameters*(bytes: openArray[byte]): ngtcp2_transport_params =
assert 0 == ngtcp2_decode_transport_params(
addr result,
NGTCP2_TRANSPORT_PARAMS_TYPE_CLIENT_HELLO,
unsafeAddr bytes[0],
bytes.len.uint
)

View File

@ -1,3 +1,4 @@
import quic/openarray
import ngtcp2 import ngtcp2
import encrypt import encrypt
import decrypt import decrypt
@ -5,26 +6,21 @@ import hp
import ids import ids
import keys import keys
import settings import settings
import params
import crypto
let zeroKey = Key() let zeroKey = Key()
var cryptoData: array[4096, uint8]
proc receiveClientInitial(connection: ptr ngtcp2_conn, dcid: ptr ngtcp2_cid, userData: pointer): cint {.cdecl.} = proc receiveClientInitial(connection: ptr ngtcp2_conn, dcid: ptr ngtcp2_cid, userData: pointer): cint {.cdecl.} =
connection.install0RttKey(zeroKey) connection.install0RttKey(zeroKey)
connection.installHandshakeKeys(zeroKey, zeroKey) connection.installHandshakeKeys(zeroKey, zeroKey)
proc receiveCryptoData(connection: ptr ngtcp2_conn, level: ngtcp2_crypto_level, offset: uint64, data: ptr uint8, datalen: uint, userData: pointer): cint {.cdecl.} = proc receiveCryptoData(connection: ptr ngtcp2_conn, level: ngtcp2_crypto_level, offset: uint64, data: ptr uint8, datalen: uint, userData: pointer): cint {.cdecl.} =
assert 0 == ngtcp2_conn_submit_crypto_data( var params = decodeTransportParameters(toOpenArray(data, datalen))
connection,
if level == NGTCP2_CRYPTO_LEVEL_INITIAL: NGTCP2_CRYPTO_LEVEL_INITIAL else: NGTCP2_CRYPTO_LEVEL_HANDSHAKE,
addr cryptoData[0],
sizeof(cryptoData).uint
)
var params = defaultSettings().transport_params
params.initial_scid = connection.ngtcp2_conn_get_dcid()[]
assert 0 == ngtcp2_conn_set_remote_transport_params(connection, addr params) assert 0 == ngtcp2_conn_set_remote_transport_params(connection, addr params)
connection.submitCryptoData()
ngtcp2_conn_handshake_completed(connection) ngtcp2_conn_handshake_completed(connection)
proc updateKey(conn: ptr ngtcp2_conn, rx_secret: ptr uint8, tx_secret: ptr uint8, rx_aead_ctx: ptr ngtcp2_crypto_aead_ctx, rx_iv: ptr uint8, tx_aead_ctx: ptr ngtcp2_crypto_aead_ctx, tx_iv: ptr uint8, current_rx_secret: ptr uint8, current_tx_secret: ptr uint8, secretlen: uint, user_data: pointer): cint {.cdecl} = proc updateKey(conn: ptr ngtcp2_conn, rx_secret: ptr uint8, tx_secret: ptr uint8, rx_aead_ctx: ptr ngtcp2_crypto_aead_ctx, rx_iv: ptr uint8, tx_aead_ctx: ptr ngtcp2_crypto_aead_ctx, tx_iv: ptr uint8, current_rx_secret: ptr uint8, current_tx_secret: ptr uint8, secretlen: uint, user_data: pointer): cint {.cdecl} =