forked from quic-go/quic-go
switch to forward-secure encryption after sending the SHLO
This commit is contained in:
@@ -68,6 +68,7 @@ func (c *linkedConnection) Close() error { return nil }
|
||||
|
||||
func setAEAD(cs handshake.CryptoSetup, aead crypto.AEAD) {
|
||||
*(*bool)(unsafe.Pointer(reflect.ValueOf(cs).Elem().FieldByName("receivedForwardSecurePacket").UnsafeAddr())) = true
|
||||
*(*bool)(unsafe.Pointer(reflect.ValueOf(cs).Elem().FieldByName("sentSHLO").UnsafeAddr())) = true
|
||||
*(*crypto.AEAD)(unsafe.Pointer(reflect.ValueOf(cs).Elem().FieldByName("forwardSecureAEAD").UnsafeAddr())) = aead
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ type cryptoSetupServer struct {
|
||||
secureAEAD crypto.AEAD
|
||||
forwardSecureAEAD crypto.AEAD
|
||||
receivedForwardSecurePacket bool
|
||||
sentSHLO bool
|
||||
receivedSecurePacket bool
|
||||
aeadChanged chan protocol.EncryptionLevel
|
||||
|
||||
@@ -187,9 +188,12 @@ func (h *cryptoSetupServer) Open(dst, src []byte, packetNumber protocol.PacketNu
|
||||
|
||||
// Seal a message, call LockForSealing() before!
|
||||
func (h *cryptoSetupServer) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel) {
|
||||
if h.receivedForwardSecurePacket {
|
||||
if h.forwardSecureAEAD != nil && h.sentSHLO {
|
||||
return h.forwardSecureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionForwardSecure
|
||||
} else if h.secureAEAD != nil {
|
||||
// secureAEAD and forwardSecureAEAD are created at the same time (when receiving the CHLO)
|
||||
// make sure that the SHLO isn't sent forward-secure
|
||||
h.sentSHLO = true
|
||||
return h.secureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionSecure
|
||||
} else {
|
||||
return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData), protocol.EncryptionUnencrypted
|
||||
@@ -375,6 +379,7 @@ func (h *cryptoSetupServer) handleCHLO(sni string, data []byte, cryptoData map[T
|
||||
replyMap[TagSNO] = serverNonce
|
||||
replyMap[TagVER] = protocol.SupportedVersionsAsTags
|
||||
|
||||
// note that the SHLO *has* to fit into one packet
|
||||
var reply bytes.Buffer
|
||||
WriteHandshakeMessage(&reply, TagSHLO, replyMap)
|
||||
utils.Debugf("Sending SHLO:\n%s", printHandshakeMessage(replyMap))
|
||||
@@ -386,7 +391,7 @@ func (h *cryptoSetupServer) handleCHLO(sni string, data []byte, cryptoData map[T
|
||||
|
||||
// DiversificationNonce returns a diversification nonce if required in the next packet to be Seal'ed. See LockForSealing()!
|
||||
func (h *cryptoSetupServer) DiversificationNonce() []byte {
|
||||
if h.receivedForwardSecurePacket || h.secureAEAD == nil {
|
||||
if h.secureAEAD == nil || h.sentSHLO {
|
||||
return nil
|
||||
}
|
||||
return h.diversificationNonce
|
||||
|
||||
@@ -194,8 +194,8 @@ var _ = Describe("Crypto setup", func() {
|
||||
Expect(cs.DiversificationNonce()).To(HaveLen(32))
|
||||
})
|
||||
|
||||
It("does not return nonce for FS packets", func() {
|
||||
cs.receivedForwardSecurePacket = true
|
||||
It("does not return nonce after sending the SHLO", func() {
|
||||
cs.sentSHLO = true
|
||||
Expect(cs.DiversificationNonce()).To(BeEmpty())
|
||||
})
|
||||
|
||||
@@ -633,15 +633,6 @@ var _ = Describe("Crypto setup", func() {
|
||||
Expect(d).To(Equal([]byte("decrypted")))
|
||||
})
|
||||
|
||||
It("is not used after receiving forward secure packet", func() {
|
||||
doCHLO()
|
||||
_, _, err := cs.Open(nil, []byte("forward secure encrypted"), 0, []byte{})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
d, enc := cs.Seal(nil, []byte("foobar"), 0, []byte{})
|
||||
Expect(d).To(Equal([]byte("foobar forward sec")))
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
})
|
||||
|
||||
It("is not accepted after receiving forward secure packet", func() {
|
||||
doCHLO()
|
||||
_, _, err := cs.Open(nil, []byte("forward secure encrypted"), 0, []byte{})
|
||||
@@ -653,15 +644,25 @@ var _ = Describe("Crypto setup", func() {
|
||||
})
|
||||
|
||||
Context("forward secure encryption", func() {
|
||||
It("is used after receiving forward secure packet", func() {
|
||||
It("is used after sending out one packet with initial encryption", func() {
|
||||
doCHLO()
|
||||
_, enc, err := cs.Open(nil, []byte("forward secure encrypted"), 0, []byte{})
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
_, enc := cs.Seal(nil, []byte("SHLO"), 0, []byte{})
|
||||
Expect(enc).To(Equal(protocol.EncryptionSecure))
|
||||
d, enc := cs.Seal(nil, []byte("foobar"), 0, []byte{})
|
||||
Expect(d).To(Equal([]byte("foobar forward sec")))
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
})
|
||||
|
||||
It("regards the handshake as complete once it receives a forward encrypted packet", func() {
|
||||
doCHLO()
|
||||
_, enc := cs.Seal(nil, []byte("SHLO"), 0, []byte{})
|
||||
Expect(enc).To(Equal(protocol.EncryptionSecure))
|
||||
_, enc = cs.Seal(nil, []byte("foobar"), 0, []byte{})
|
||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
||||
Expect(cs.HandshakeComplete()).To(BeFalse())
|
||||
cs.receivedForwardSecurePacket = true
|
||||
Expect(cs.HandshakeComplete()).To(BeTrue())
|
||||
})
|
||||
})
|
||||
|
||||
Context("forcing encryption levels", func() {
|
||||
|
||||
Reference in New Issue
Block a user