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
|
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 {
|
func (h *cryptoSetupClient) DiversificationNonce() []byte {
|
||||||
panic("not needed for cryptoSetupClient")
|
panic("not needed for cryptoSetupClient")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -744,6 +744,48 @@ var _ = Describe("Crypto setup", func() {
|
|||||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
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() {
|
Context("Diversification Nonces", func() {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ type CryptoSetup interface {
|
|||||||
HandleCryptoStream() error
|
HandleCryptoStream() error
|
||||||
Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel, 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)
|
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()
|
LockForSealing()
|
||||||
UnlockForSealing()
|
UnlockForSealing()
|
||||||
HandshakeComplete() bool
|
HandshakeComplete() bool
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"sync"
|
"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 {
|
func (h *cryptoSetupServer) isInchoateCHLO(cryptoData map[Tag][]byte, cert []byte) bool {
|
||||||
if _, ok := cryptoData[TagPUBS]; !ok {
|
if _, ok := cryptoData[TagPUBS]; !ok {
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -659,6 +659,48 @@ var _ = Describe("Crypto setup", func() {
|
|||||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
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() {
|
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) {
|
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
|
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) LockForSealing() {}
|
||||||
func (m *mockCryptoSetup) UnlockForSealing() {}
|
func (m *mockCryptoSetup) UnlockForSealing() {}
|
||||||
func (m *mockCryptoSetup) HandshakeComplete() bool { return m.handshakeComplete }
|
func (m *mockCryptoSetup) HandshakeComplete() bool { return m.handshakeComplete }
|
||||||
|
|||||||
Reference in New Issue
Block a user