use the mockAEAD as nullAEAD in the crypto setup tests

This commit is contained in:
Marten Seemann 2017-09-09 16:41:36 +03:00
parent 96ebb6237c
commit 2e9bc93b0c
3 changed files with 48 additions and 49 deletions

View file

@ -98,7 +98,11 @@ var _ = Describe("Client Crypto Setup", func() {
divNonce: divNonce, divNonce: divNonce,
pers: pers, pers: pers,
} }
return &mockAEAD{forwardSecure: forwardSecure, sharedSecret: sharedSecret}, nil encLevel := protocol.EncryptionSecure
if forwardSecure {
encLevel = protocol.EncryptionForwardSecure
}
return &mockAEAD{encLevel: encLevel, sharedSecret: sharedSecret}, nil
} }
stream = newMockStream() stream = newMockStream()
@ -126,6 +130,7 @@ var _ = Describe("Client Crypto Setup", func() {
cs.certManager = certManager cs.certManager = certManager
cs.keyDerivation = keyDerivation cs.keyDerivation = keyDerivation
cs.keyExchange = func() crypto.KeyExchange { return &mockKEX{ephermal: true} } cs.keyExchange = func() crypto.KeyExchange { return &mockKEX{ephermal: true} }
cs.nullAEAD = &mockAEAD{encLevel: protocol.EncryptionUnencrypted}
}) })
AfterEach(func() { AfterEach(func() {
@ -578,8 +583,6 @@ var _ = Describe("Client Crypto Setup", func() {
}) })
Context("escalating crypto", func() { Context("escalating crypto", func() {
var foobarFNVSigned []byte
doCompleteREJ := func() { doCompleteREJ := func() {
cs.serverVerified = true cs.serverVerified = true
err := cs.maybeUpgradeCrypto() err := cs.maybeUpgradeCrypto()
@ -595,7 +598,6 @@ var _ = Describe("Client Crypto Setup", func() {
// sets all values necessary for escalating to secureAEAD // sets all values necessary for escalating to secureAEAD
BeforeEach(func() { BeforeEach(func() {
foobarFNVSigned = []byte{0x18, 0x6f, 0x44, 0xba, 0x97, 0x35, 0xd, 0x6f, 0xbf, 0x64, 0x3c, 0x79, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72}
kex, err := crypto.NewCurve25519KEX() kex, err := crypto.NewCurve25519KEX()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
cs.serverConfig = &serverConfigClient{ cs.serverConfig = &serverConfigClient{
@ -688,20 +690,20 @@ var _ = Describe("Client Crypto Setup", func() {
enc, sealer := cs.GetSealer() enc, sealer := cs.GetSealer()
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
It("is used for the crypto stream", func() { It("is used for the crypto stream", func() {
enc, sealer := cs.GetSealerForCryptoStream() enc, sealer := cs.GetSealerForCryptoStream()
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
It("is accepted initially", func() { It("is accepted initially", func() {
d, enc, err := cs.Open(nil, foobarFNVSigned, 0, []byte{}) d, enc, err := cs.Open(nil, []byte("unencrypted"), 0, []byte{})
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(d).To(Equal([]byte("foobar"))) Expect(d).To(Equal([]byte("decrypted")))
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
}) })
@ -709,24 +711,23 @@ var _ = Describe("Client Crypto Setup", func() {
doCompleteREJ() doCompleteREJ()
cs.receivedSecurePacket = false cs.receivedSecurePacket = false
Expect(cs.secureAEAD).ToNot(BeNil()) Expect(cs.secureAEAD).ToNot(BeNil())
d, enc, err := cs.Open(nil, foobarFNVSigned, 0, []byte{}) d, enc, err := cs.Open(nil, []byte("unencrypted"), 0, []byte{})
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(d).To(Equal([]byte("foobar"))) Expect(d).To(Equal([]byte("decrypted")))
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
}) })
It("is not accepted after the server sent an encrypted packet", func() { It("is not accepted after the server sent an encrypted packet", func() {
doCompleteREJ() doCompleteREJ()
cs.receivedSecurePacket = true cs.receivedSecurePacket = true
_, enc, err := cs.Open(nil, foobarFNVSigned, 0, []byte{}) _, enc, err := cs.Open(nil, []byte("unecnrypted"), 0, []byte{})
Expect(err).To(MatchError("authentication failed")) Expect(err).To(MatchError("authentication failed"))
Expect(enc).To(Equal(protocol.EncryptionUnspecified)) Expect(enc).To(Equal(protocol.EncryptionUnspecified))
}) })
It("errors if the has the wrong hash", func() { It("errors if the has the wrong hash", func() {
foobarFNVSigned[0]++ _, enc, err := cs.Open(nil, []byte("not unecnrypted"), 0, []byte{})
_, enc, err := cs.Open(nil, foobarFNVSigned, 0, []byte{}) Expect(err).To(MatchError("authentication failed"))
Expect(err).To(MatchError("NullAEAD: failed to authenticate received data"))
Expect(enc).To(Equal(protocol.EncryptionUnspecified)) Expect(enc).To(Equal(protocol.EncryptionUnspecified))
}) })
}) })
@ -762,7 +763,7 @@ var _ = Describe("Client Crypto Setup", func() {
enc, sealer := cs.GetSealerForCryptoStream() enc, sealer := cs.GetSealerForCryptoStream()
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
}) })
@ -783,7 +784,7 @@ var _ = Describe("Client Crypto Setup", func() {
enc, sealer := cs.GetSealerForCryptoStream() enc, sealer := cs.GetSealerForCryptoStream()
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
}) })
@ -792,7 +793,7 @@ var _ = Describe("Client Crypto Setup", func() {
sealer, err := cs.GetSealerWithEncryptionLevel(protocol.EncryptionUnencrypted) sealer, err := cs.GetSealerWithEncryptionLevel(protocol.EncryptionUnencrypted)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
It("forces initial encryption", func() { It("forces initial encryption", func() {

View file

@ -55,8 +55,8 @@ func (*mockSigner) GetLeafCert(sni string) ([]byte, error) {
} }
type mockAEAD struct { type mockAEAD struct {
forwardSecure bool encLevel protocol.EncryptionLevel
sharedSecret []byte sharedSecret []byte
} }
var _ crypto.AEAD = &mockAEAD{} var _ crypto.AEAD = &mockAEAD{}
@ -67,18 +67,23 @@ func (m *mockAEAD) Seal(dst, src []byte, packetNumber protocol.PacketNumber, ass
} }
dst = dst[:len(src)+12] dst = dst[:len(src)+12]
copy(dst, src) copy(dst, src)
if !m.forwardSecure { switch m.encLevel {
case protocol.EncryptionUnencrypted:
copy(dst[len(src):], []byte(" unencrypted"))
case protocol.EncryptionSecure:
copy(dst[len(src):], []byte(" normal sec")) copy(dst[len(src):], []byte(" normal sec"))
} else { case protocol.EncryptionForwardSecure:
copy(dst[len(src):], []byte(" forward sec")) copy(dst[len(src):], []byte(" forward sec"))
default:
Fail("invalid encryption level")
} }
return dst return dst
} }
func (m *mockAEAD) Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) { func (m *mockAEAD) Open(dst, src []byte, packetNumber protocol.PacketNumber, associatedData []byte) ([]byte, error) {
if m.forwardSecure && string(src) == "forward secure encrypted" { if m.encLevel == protocol.EncryptionUnencrypted && string(src) == "unencrypted" ||
return []byte("decrypted"), nil m.encLevel == protocol.EncryptionForwardSecure && string(src) == "forward secure encrypted" ||
} else if !m.forwardSecure && string(src) == "encrypted" { m.encLevel == protocol.EncryptionSecure && string(src) == "encrypted" {
return []byte("decrypted"), nil return []byte("decrypted"), nil
} }
return nil, errors.New("authentication failed") return nil, errors.New("authentication failed")
@ -92,12 +97,15 @@ var expectedInitialNonceLen int
var expectedFSNonceLen int var expectedFSNonceLen int
func mockQuicCryptoKeyDerivation(forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte, pers protocol.Perspective) (crypto.AEAD, error) { func mockQuicCryptoKeyDerivation(forwardSecure bool, sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte, divNonce []byte, pers protocol.Perspective) (crypto.AEAD, error) {
var encLevel protocol.EncryptionLevel
if forwardSecure { if forwardSecure {
encLevel = protocol.EncryptionForwardSecure
Expect(nonces).To(HaveLen(expectedFSNonceLen)) Expect(nonces).To(HaveLen(expectedFSNonceLen))
} else { } else {
encLevel = protocol.EncryptionSecure
Expect(nonces).To(HaveLen(expectedInitialNonceLen)) Expect(nonces).To(HaveLen(expectedInitialNonceLen))
} }
return &mockAEAD{forwardSecure: forwardSecure, sharedSecret: sharedSecret}, nil return &mockAEAD{encLevel: encLevel, sharedSecret: sharedSecret}, nil
} }
type mockStream struct { type mockStream struct {
@ -216,6 +224,7 @@ var _ = Describe("Server Crypto Setup", func() {
cs.acceptSTKCallback = func(_ net.Addr, _ *Cookie) bool { return sourceAddrValid } cs.acceptSTKCallback = func(_ net.Addr, _ *Cookie) bool { return sourceAddrValid }
cs.keyDerivation = mockQuicCryptoKeyDerivation cs.keyDerivation = mockQuicCryptoKeyDerivation
cs.keyExchange = func() crypto.KeyExchange { return &mockKEX{ephermal: true} } cs.keyExchange = func() crypto.KeyExchange { return &mockKEX{ephermal: true} }
cs.nullAEAD = &mockAEAD{encLevel: protocol.EncryptionUnencrypted}
}) })
AfterEach(func() { AfterEach(func() {
@ -334,11 +343,11 @@ var _ = Describe("Server Crypto Setup", func() {
Expect(response).To(ContainSubstring(string(b.Bytes()))) Expect(response).To(ContainSubstring(string(b.Bytes())))
} }
Expect(cs.secureAEAD).ToNot(BeNil()) Expect(cs.secureAEAD).ToNot(BeNil())
Expect(cs.secureAEAD.(*mockAEAD).forwardSecure).To(BeFalse()) Expect(cs.secureAEAD.(*mockAEAD).encLevel).To(Equal(protocol.EncryptionSecure))
Expect(cs.secureAEAD.(*mockAEAD).sharedSecret).To(Equal([]byte("shared key"))) Expect(cs.secureAEAD.(*mockAEAD).sharedSecret).To(Equal([]byte("shared key")))
Expect(cs.forwardSecureAEAD).ToNot(BeNil()) Expect(cs.forwardSecureAEAD).ToNot(BeNil())
Expect(cs.forwardSecureAEAD.(*mockAEAD).sharedSecret).To(Equal([]byte("shared ephermal"))) Expect(cs.forwardSecureAEAD.(*mockAEAD).sharedSecret).To(Equal([]byte("shared ephermal")))
Expect(cs.forwardSecureAEAD.(*mockAEAD).forwardSecure).To(BeTrue()) Expect(cs.forwardSecureAEAD.(*mockAEAD).encLevel).To(Equal(protocol.EncryptionForwardSecure))
}) })
It("handles long handshake", func() { It("handles long handshake", func() {
@ -544,16 +553,6 @@ var _ = Describe("Server Crypto Setup", func() {
}) })
Context("escalating crypto", func() { Context("escalating crypto", func() {
var foobarServerFNVSigned []byte // a "foobar" sent by the server, FNV signed
var foobarClientFNVSigned []byte // a "foobar" sent by the client, FNV signed
BeforeEach(func() {
nullAEADServer := crypto.NewNullAEAD(protocol.PerspectiveServer, version)
foobarServerFNVSigned = nullAEADServer.Seal(nil, []byte("foobar"), 0, []byte{})
nullAEADClient := crypto.NewNullAEAD(protocol.PerspectiveClient, version)
foobarClientFNVSigned = nullAEADClient.Seal(nil, []byte("foobar"), 0, []byte{})
})
doCHLO := func() { doCHLO := func() {
_, err := cs.handleCHLO("", []byte("chlo-data"), map[Tag][]byte{ _, err := cs.handleCHLO("", []byte("chlo-data"), map[Tag][]byte{
TagPUBS: []byte("pubs-c"), TagPUBS: []byte("pubs-c"),
@ -571,34 +570,33 @@ var _ = Describe("Server Crypto Setup", func() {
enc, sealer := cs.GetSealer() enc, sealer := cs.GetSealer()
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarServerFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
It("is used for crypto stream", func() { It("is used for crypto stream", func() {
enc, sealer := cs.GetSealerForCryptoStream() enc, sealer := cs.GetSealerForCryptoStream()
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarServerFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
It("is accepted initially", func() { It("is accepted initially", func() {
d, enc, err := cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) d, enc, err := cs.Open(nil, []byte("unencrypted"), 0, []byte{})
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(d).To(Equal([]byte("foobar"))) Expect(d).To(Equal([]byte("decrypted")))
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
}) })
It("errors if the has the wrong hash", func() { It("errors if the has the wrong hash", func() {
foobarClientFNVSigned[0]++ _, enc, err := cs.Open(nil, []byte("not unencrypted"), 0, []byte{})
_, enc, err := cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) Expect(err).To(MatchError("authentication failed"))
Expect(err).To(MatchError("NullAEAD: failed to authenticate received data"))
Expect(enc).To(Equal(protocol.EncryptionUnspecified)) Expect(enc).To(Equal(protocol.EncryptionUnspecified))
}) })
It("is still accepted after CHLO", func() { It("is still accepted after CHLO", func() {
doCHLO() doCHLO()
Expect(cs.secureAEAD).ToNot(BeNil()) Expect(cs.secureAEAD).ToNot(BeNil())
_, enc, err := cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) _, enc, err := cs.Open(nil, []byte("unencrypted"), 0, []byte{})
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(enc).To(Equal(protocol.EncryptionUnencrypted)) Expect(enc).To(Equal(protocol.EncryptionUnencrypted))
}) })
@ -610,7 +608,7 @@ var _ = Describe("Server Crypto Setup", func() {
Expect(enc).To(Equal(protocol.EncryptionSecure)) Expect(enc).To(Equal(protocol.EncryptionSecure))
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
Expect(d).To(Equal([]byte("decrypted"))) Expect(d).To(Equal([]byte("decrypted")))
_, enc, err = cs.Open(nil, foobarClientFNVSigned, 0, []byte{}) _, enc, err = cs.Open(nil, []byte("foobar unencrypted"), 0, []byte{})
Expect(err).To(MatchError("authentication failed")) Expect(err).To(MatchError("authentication failed"))
Expect(enc).To(Equal(protocol.EncryptionUnspecified)) Expect(enc).To(Equal(protocol.EncryptionUnspecified))
}) })
@ -620,7 +618,7 @@ var _ = Describe("Server Crypto Setup", func() {
enc, sealer := cs.GetSealer() enc, sealer := cs.GetSealer()
Expect(enc).ToNot(Equal(protocol.EncryptionUnencrypted)) Expect(enc).ToNot(Equal(protocol.EncryptionUnencrypted))
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).ToNot(Equal(foobarServerFNVSigned)) Expect(d).ToNot(Equal([]byte("foobar unencrypted")))
}) })
}) })
@ -673,7 +671,7 @@ var _ = Describe("Server Crypto Setup", func() {
sealer, err := cs.GetSealerWithEncryptionLevel(protocol.EncryptionUnencrypted) sealer, err := cs.GetSealerWithEncryptionLevel(protocol.EncryptionUnencrypted)
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
d := sealer.Seal(nil, []byte("foobar"), 0, []byte{}) d := sealer.Seal(nil, []byte("foobar"), 0, []byte{})
Expect(d).To(Equal(foobarServerFNVSigned)) Expect(d).To(Equal([]byte("foobar unencrypted")))
}) })
It("forces initial encryption", func() { It("forces initial encryption", func() {

View file

@ -27,7 +27,7 @@ func (h *fakeMintController) ComputeExporter(label string, context []byte, keyLe
} }
func mockKeyDerivation(crypto.MintController, protocol.Perspective) (crypto.AEAD, error) { func mockKeyDerivation(crypto.MintController, protocol.Perspective) (crypto.AEAD, error) {
return &mockAEAD{forwardSecure: true}, nil return &mockAEAD{encLevel: protocol.EncryptionForwardSecure}, nil
} }
var _ = Describe("TLS Crypto Setup", func() { var _ = Describe("TLS Crypto Setup", func() {