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) {
|
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("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
|
*(*crypto.AEAD)(unsafe.Pointer(reflect.ValueOf(cs).Elem().FieldByName("forwardSecureAEAD").UnsafeAddr())) = aead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type cryptoSetupServer struct {
|
|||||||
secureAEAD crypto.AEAD
|
secureAEAD crypto.AEAD
|
||||||
forwardSecureAEAD crypto.AEAD
|
forwardSecureAEAD crypto.AEAD
|
||||||
receivedForwardSecurePacket bool
|
receivedForwardSecurePacket bool
|
||||||
|
sentSHLO bool
|
||||||
receivedSecurePacket bool
|
receivedSecurePacket bool
|
||||||
aeadChanged chan protocol.EncryptionLevel
|
aeadChanged chan protocol.EncryptionLevel
|
||||||
|
|
||||||
@@ -187,9 +188,12 @@ func (h *cryptoSetupServer) Open(dst, src []byte, packetNumber protocol.PacketNu
|
|||||||
|
|
||||||
// Seal a message, call LockForSealing() before!
|
// Seal a message, call LockForSealing() before!
|
||||||
func (h *cryptoSetupServer) Seal(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, protocol.EncryptionLevel) {
|
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
|
return h.forwardSecureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionForwardSecure
|
||||||
} else if h.secureAEAD != nil {
|
} 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
|
return h.secureAEAD.Seal(dst, src, packetNumber, associatedData), protocol.EncryptionSecure
|
||||||
} else {
|
} else {
|
||||||
return (&crypto.NullAEAD{}).Seal(dst, src, packetNumber, associatedData), protocol.EncryptionUnencrypted
|
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[TagSNO] = serverNonce
|
||||||
replyMap[TagVER] = protocol.SupportedVersionsAsTags
|
replyMap[TagVER] = protocol.SupportedVersionsAsTags
|
||||||
|
|
||||||
|
// note that the SHLO *has* to fit into one packet
|
||||||
var reply bytes.Buffer
|
var reply bytes.Buffer
|
||||||
WriteHandshakeMessage(&reply, TagSHLO, replyMap)
|
WriteHandshakeMessage(&reply, TagSHLO, replyMap)
|
||||||
utils.Debugf("Sending SHLO:\n%s", printHandshakeMessage(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()!
|
// DiversificationNonce returns a diversification nonce if required in the next packet to be Seal'ed. See LockForSealing()!
|
||||||
func (h *cryptoSetupServer) DiversificationNonce() []byte {
|
func (h *cryptoSetupServer) DiversificationNonce() []byte {
|
||||||
if h.receivedForwardSecurePacket || h.secureAEAD == nil {
|
if h.secureAEAD == nil || h.sentSHLO {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return h.diversificationNonce
|
return h.diversificationNonce
|
||||||
|
|||||||
@@ -194,8 +194,8 @@ var _ = Describe("Crypto setup", func() {
|
|||||||
Expect(cs.DiversificationNonce()).To(HaveLen(32))
|
Expect(cs.DiversificationNonce()).To(HaveLen(32))
|
||||||
})
|
})
|
||||||
|
|
||||||
It("does not return nonce for FS packets", func() {
|
It("does not return nonce after sending the SHLO", func() {
|
||||||
cs.receivedForwardSecurePacket = true
|
cs.sentSHLO = true
|
||||||
Expect(cs.DiversificationNonce()).To(BeEmpty())
|
Expect(cs.DiversificationNonce()).To(BeEmpty())
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -633,15 +633,6 @@ var _ = Describe("Crypto setup", func() {
|
|||||||
Expect(d).To(Equal([]byte("decrypted")))
|
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() {
|
It("is not accepted after receiving forward secure packet", func() {
|
||||||
doCHLO()
|
doCHLO()
|
||||||
_, _, err := cs.Open(nil, []byte("forward secure encrypted"), 0, []byte{})
|
_, _, err := cs.Open(nil, []byte("forward secure encrypted"), 0, []byte{})
|
||||||
@@ -653,15 +644,25 @@ var _ = Describe("Crypto setup", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
Context("forward secure encryption", 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()
|
doCHLO()
|
||||||
_, enc, err := cs.Open(nil, []byte("forward secure encrypted"), 0, []byte{})
|
_, enc := cs.Seal(nil, []byte("SHLO"), 0, []byte{})
|
||||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
Expect(enc).To(Equal(protocol.EncryptionSecure))
|
||||||
Expect(err).ToNot(HaveOccurred())
|
|
||||||
d, enc := cs.Seal(nil, []byte("foobar"), 0, []byte{})
|
d, enc := cs.Seal(nil, []byte("foobar"), 0, []byte{})
|
||||||
Expect(d).To(Equal([]byte("foobar forward sec")))
|
Expect(d).To(Equal([]byte("foobar forward sec")))
|
||||||
Expect(enc).To(Equal(protocol.EncryptionForwardSecure))
|
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() {
|
Context("forcing encryption levels", func() {
|
||||||
|
|||||||
Reference in New Issue
Block a user