Skip to content

Commit

Permalink
Add support for marshaling configuration lists
Browse files Browse the repository at this point in the history
  • Loading branch information
chris-wood committed May 1, 2023
1 parent d8fbd90 commit d341e80
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
20 changes: 19 additions & 1 deletion ohttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func NewConfig(keyID uint8, kemID hpke.KEM, kdfID hpke.KDF, aeadID hpke.AEAD) (P
if !kemID.IsValid() || !kdfID.IsValid() || !aeadID.IsValid() {
return PrivateConfig{}, fmt.Errorf("invalid ciphersuite")
}
ikm := make([]byte, kemID.Scheme().PrivateKeySize())
ikm := make([]byte, kemID.Scheme().SeedSize())
rand.Reader.Read(ikm)

return NewConfigFromSeed(keyID, kemID, kdfID, aeadID, ikm)
Expand Down Expand Up @@ -473,6 +473,24 @@ func (s Gateway) MatchesConfig(req EncapsulatedRequest) bool {
return ok
}

func (s Gateway) MarshalConfigs() []byte {
b := cryptobyte.NewBuilder(nil)

// Marshal the configurations in order sorted by their configuration ID
keys := make([]uint8, len(s.keyMap))
i := 0
for k := range s.keyMap {
keys[i] = k
i++
}
for _, id := range keys {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(s.keyMap[id].publicConfig.Marshal())
})
}
return b.BytesOrPanic()
}

func (s Gateway) DecapsulateRequest(req EncapsulatedRequest) ([]byte, DecapsulateRequestContext, error) {
config, ok := s.keyMap[req.KeyID]
if !ok {
Expand Down
34 changes: 34 additions & 0 deletions ohttp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/cloudflare/circl/hpke"
"github.com/cloudflare/circl/kem"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/cryptobyte"
)

const (
Expand All @@ -31,6 +32,39 @@ func TestConfigSerialize(t *testing.T) {
require.True(t, config.IsEqual(recoveredConfig), "Config mismatch")
}

func TestConfigListSerialize(t *testing.T) {
privateConfigA, err := NewConfig(0x00, hpke.KEM_X25519_HKDF_SHA256, hpke.KDF_HKDF_SHA256, hpke.AEAD_AES128GCM)
privateConfigB, err := NewConfig(0x01, hpke.KEM_X25519_KYBER768_DRAFT00, hpke.KDF_HKDF_SHA256, hpke.AEAD_AES128GCM)
require.Nil(t, err, "CreatePrivateConfig failed")

gateway := NewDefaultGateway([]PrivateConfig{privateConfigA, privateConfigB})
serializedConfigs := gateway.MarshalConfigs()

s := cryptobyte.String(serializedConfigs)

// Parse and validate configuration A
var serializedConfigA cryptobyte.String
if !s.ReadUint16LengthPrefixed(&serializedConfigA) {
t.Fatal("Failed to decode length-prefix-encoded config")
}

recoveredConfigA, err := UnmarshalPublicConfig(serializedConfigA)
require.Nil(t, err, "UnmarshalPublicConfig failed")
require.True(t, privateConfigA.publicConfig.IsEqual(recoveredConfigA), "Config A mismatch")

// Parse and validate configuration B
var serializedConfigB cryptobyte.String
if !s.ReadUint16LengthPrefixed(&serializedConfigB) {
t.Fatal("Failed to decode length-prefix-encoded config")
}

recoveredConfigB, err := UnmarshalPublicConfig(serializedConfigB)
require.Nil(t, err, "UnmarshalPublicConfig failed")
require.True(t, privateConfigB.publicConfig.IsEqual(recoveredConfigB), "Config B mismatch")

require.Equal(t, 0, len(s))
}

func TestRoundTrip(t *testing.T) {
privateConfig, err := NewConfig(0x00, hpke.KEM_X25519_HKDF_SHA256, hpke.KDF_HKDF_SHA256, hpke.AEAD_AES128GCM)
require.Nil(t, err, "CreatePrivateConfig failed")
Expand Down

0 comments on commit d341e80

Please sign in to comment.