forked from quic-go/quic-go
add a method to force the encryption level when sealing a packet
This commit is contained in:
@@ -312,6 +312,25 @@ func (h *cryptoSetupClient) Seal(dst, src []byte, packetNumber protocol.PacketNu
|
||||
return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData), protocol.EncryptionUnencrypted
|
||||
}
|
||||
|
||||
func (h *cryptoSetupClient) SealWith(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte, forceEncryptionLevel protocol.EncryptionLevel) ([]byte, protocol.EncryptionLevel, error) {
|
||||
switch forceEncryptionLevel {
|
||||
case protocol.EncryptionUnencrypted:
|
||||
return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData), protocol.EncryptionUnencrypted, nil
|
||||
case protocol.EncryptionSecure:
|
||||
if h.secureAEAD == nil {
|
||||
return nil, protocol.EncryptionUnspecified, errors.New("CryptoSetupClient: no secureAEAD")
|
||||
}
|
||||
return h.secureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionSecure, nil
|
||||
case protocol.EncryptionForwardSecure:
|
||||
if h.forwardSecureAEAD == nil {
|
||||
return nil, protocol.EncryptionUnspecified, errors.New("CryptoSetupClient: no forwardSecureAEAD")
|
||||
}
|
||||
return h.forwardSecureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionForwardSecure, nil
|
||||
}
|
||||
|
||||
return nil, protocol.EncryptionUnspecified, errors.New("no encryption level specified")
|
||||
}
|
||||
|
||||
func (h *cryptoSetupClient) DiversificationNonce() []byte {
|
||||
panic("not needed for cryptoSetupClient")
|
||||
}
|
||||
|
||||
@@ -744,6 +744,48 @@ var _ = Describe("Crypto setup", func() {
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
})
|
||||
})
|
||||
|
||||
Context("forcing encryption levels", func() {
|
||||
It("forces null encryption", func() {
|
||||
d, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionUnencrypted)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(d).To(Equal(foobarFNVSigned))
|
||||
Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
|
||||
})
|
||||
|
||||
It("forces initial encryption", func() {
|
||||
doCompleteREJ()
|
||||
d, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionSecure)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(d).To(Equal([]byte("foobar normal sec")))
|
||||
Expect(enc).To(Equal(protocol.EncryptionSecure))
|
||||
})
|
||||
|
||||
It("errors of no AEAD for initial encryption is available", func() {
|
||||
_, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionSecure)
|
||||
Expect(err).To(MatchError("CryptoSetupClient: no secureAEAD"))
|
||||
Expect(enc).To(Equal(protocol.EncryptionUnspecified))
|
||||
})
|
||||
|
||||
It("forces forward-secure encryption", func() {
|
||||
doSHLO()
|
||||
d, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionForwardSecure)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(d).To(Equal([]byte("foobar forward sec")))
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
})
|
||||
|
||||
It("errors of no AEAD for forward-secure encryption is available", func() {
|
||||
_, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionForwardSecure)
|
||||
Expect(err).To(MatchError("CryptoSetupClient: no forwardSecureAEAD"))
|
||||
Expect(enc).To(Equal(protocol.EncryptionUnspecified))
|
||||
})
|
||||
|
||||
It("errors if no encryption level is specified", func() {
|
||||
_, _, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionUnspecified)
|
||||
Expect(err).To(MatchError("no encryption level specified"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("Diversification Nonces", func() {
|
||||
|
||||
@@ -7,6 +7,7 @@ type CryptoSetup interface {
|
||||
HandleCryptoStream() error
|
||||
Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel, error)
|
||||
Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel)
|
||||
SealWith(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte, forceEncryptionLevel protocol.EncryptionLevel) ([]byte, protocol.EncryptionLevel, error)
|
||||
LockForSealing()
|
||||
UnlockForSealing()
|
||||
HandshakeComplete() bool
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
@@ -195,6 +196,25 @@ func (h *cryptoSetupServer) Seal(dst, src []byte, packetNumber protocol.PacketNu
|
||||
}
|
||||
}
|
||||
|
||||
func (h *cryptoSetupServer) SealWith(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte, forceEncryptionLevel protocol.EncryptionLevel) ([]byte, protocol.EncryptionLevel, error) {
|
||||
switch forceEncryptionLevel {
|
||||
case protocol.EncryptionUnencrypted:
|
||||
return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData), protocol.EncryptionUnencrypted, nil
|
||||
case protocol.EncryptionSecure:
|
||||
if h.secureAEAD == nil {
|
||||
return nil, protocol.EncryptionUnspecified, errors.New("CryptoSetupServer: no secureAEAD")
|
||||
}
|
||||
return h.secureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionSecure, nil
|
||||
case protocol.EncryptionForwardSecure:
|
||||
if h.forwardSecureAEAD == nil {
|
||||
return nil, protocol.EncryptionUnspecified, errors.New("CryptoSetupServer: no forwardSecureAEAD")
|
||||
}
|
||||
return h.forwardSecureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionForwardSecure, nil
|
||||
}
|
||||
|
||||
return nil, protocol.EncryptionUnspecified, errors.New("no encryption level specified")
|
||||
}
|
||||
|
||||
func (h *cryptoSetupServer) isInchoateCHLO(cryptoData map[Tag][]byte, cert []byte) bool {
|
||||
if _, ok := cryptoData[TagPUBS]; !ok {
|
||||
return true
|
||||
|
||||
@@ -659,6 +659,48 @@ var _ = Describe("Crypto setup", func() {
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
})
|
||||
})
|
||||
|
||||
Context("forcing encryption levels", func() {
|
||||
It("forces null encryption", func() {
|
||||
d, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionUnencrypted)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(d).To(Equal(foobarFNVSigned))
|
||||
Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
|
||||
})
|
||||
|
||||
It("forces initial encryption", func() {
|
||||
doCHLO()
|
||||
d, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionSecure)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(d).To(Equal([]byte("foobar normal sec")))
|
||||
Expect(enc).To(Equal(protocol.EncryptionSecure))
|
||||
})
|
||||
|
||||
It("errors of no AEAD for initial encryption is available", func() {
|
||||
_, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionSecure)
|
||||
Expect(err).To(MatchError("CryptoSetupServer: no secureAEAD"))
|
||||
Expect(enc).To(Equal(protocol.EncryptionUnspecified))
|
||||
})
|
||||
|
||||
It("forces forward-secure encryption", func() {
|
||||
doCHLO()
|
||||
d, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionForwardSecure)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(d).To(Equal([]byte("foobar forward sec")))
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
})
|
||||
|
||||
It("errors of no AEAD for forward-secure encryption is available", func() {
|
||||
_, enc, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionForwardSecure)
|
||||
Expect(err).To(MatchError("CryptoSetupServer: no forwardSecureAEAD"))
|
||||
Expect(enc).To(Equal(protocol.EncryptionUnspecified))
|
||||
})
|
||||
|
||||
It("errors if no encryption level is specified", func() {
|
||||
_, _, err := cs.SealWith(nil, []byte("foobar"), 0, []byte{}, protocol.EncryptionUnspecified)
|
||||
Expect(err).To(MatchError("no encryption level specified"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context("STK verification and creation", func() {
|
||||
|
||||
@@ -24,6 +24,9 @@ func (m *mockCryptoSetup) Open(dst, src []byte, packetNumber protocol.PacketNumb
|
||||
func (m *mockCryptoSetup) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel) {
|
||||
return append(src, bytes.Repeat([]byte{0}, 12)...), m.encLevelSeal
|
||||
}
|
||||
func (m *mockCryptoSetup) SealWith(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte, encLevel protocol.EncryptionLevel) ([]byte, protocol.EncryptionLevel, error) {
|
||||
panic("not implemented")
|
||||
}
|
||||
func (m *mockCryptoSetup) LockForSealing() {}
|
||||
func (m *mockCryptoSetup) UnlockForSealing() {}
|
||||
func (m *mockCryptoSetup) HandshakeComplete() bool { return m.handshakeComplete }
|
||||
|
||||
Reference in New Issue
Block a user