forked from quic-go/quic-go
move handshake handling and server config into handshake package
This commit is contained in:
80
handshake/handshake.go
Normal file
80
handshake/handshake.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package handshake
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/crypto"
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
)
|
||||
|
||||
// The Handshake handles all things crypto for the Session
|
||||
type Handshake struct {
|
||||
connID protocol.ConnectionID
|
||||
version protocol.VersionNumber
|
||||
aead crypto.AEAD
|
||||
scfg *ServerConfig
|
||||
}
|
||||
|
||||
// NewHandshake creates a new Handshake instance
|
||||
func NewHandshake(connID protocol.ConnectionID, version protocol.VersionNumber, scfg *ServerConfig) *Handshake {
|
||||
return &Handshake{
|
||||
connID: connID,
|
||||
version: version,
|
||||
aead: &crypto.NullAEAD{},
|
||||
scfg: scfg,
|
||||
}
|
||||
}
|
||||
|
||||
// Open a message
|
||||
func (h *Handshake) Open(packetNumber protocol.PacketNumber, associatedData []byte, ciphertext io.Reader) (*bytes.Reader, error) {
|
||||
return h.aead.Open(packetNumber, associatedData, ciphertext)
|
||||
}
|
||||
|
||||
// Seal a messageTag
|
||||
func (h *Handshake) Seal(packetNumber protocol.PacketNumber, b *bytes.Buffer, associatedData []byte, plaintext []byte) {
|
||||
h.aead.Seal(packetNumber, b, associatedData, plaintext)
|
||||
}
|
||||
|
||||
// HandleCryptoMessage handles the crypto handshake and returns the answer
|
||||
func (h *Handshake) HandleCryptoMessage(data []byte) ([]byte, error) {
|
||||
messageTag, cryptoData, err := ParseHandshakeMessage(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if messageTag != TagCHLO {
|
||||
return nil, errors.New("Session: expected CHLO")
|
||||
}
|
||||
|
||||
if _, ok := cryptoData[TagSCID]; ok {
|
||||
var sharedSecret []byte
|
||||
sharedSecret, err = h.scfg.kex.CalculateSharedKey(cryptoData[TagPUBS])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h.aead, err = crypto.DeriveKeysChacha20(sharedSecret, cryptoData[TagNONC], h.connID, data, h.scfg.Get(), h.scfg.kd.GetCertUncompressed())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO: Send SHLO
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var chloOrNil []byte
|
||||
if h.version > protocol.VersionNumber(30) {
|
||||
chloOrNil = data
|
||||
}
|
||||
proof, err := h.scfg.Sign(chloOrNil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var serverReply bytes.Buffer
|
||||
WriteHandshakeMessage(&serverReply, TagREJ, map[Tag][]byte{
|
||||
TagSCFG: h.scfg.Get(),
|
||||
TagCERT: h.scfg.GetCertCompressed(),
|
||||
TagPROF: proof,
|
||||
})
|
||||
|
||||
return serverReply.Bytes(), nil
|
||||
}
|
||||
9
handshake/handshake_test.go
Normal file
9
handshake/handshake_test.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package handshake
|
||||
|
||||
import (
|
||||
. "github.com/onsi/ginkgo"
|
||||
// . "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("Handshake", func() {
|
||||
})
|
||||
46
handshake/server_config.go
Normal file
46
handshake/server_config.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package handshake
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/crypto"
|
||||
)
|
||||
|
||||
// ServerConfig is a server config
|
||||
type ServerConfig struct {
|
||||
kex crypto.KeyExchange
|
||||
kd *crypto.KeyData
|
||||
}
|
||||
|
||||
// NewServerConfig creates a new server config
|
||||
func NewServerConfig(kex crypto.KeyExchange, kd *crypto.KeyData) *ServerConfig {
|
||||
return &ServerConfig{
|
||||
kex: kex,
|
||||
kd: kd,
|
||||
}
|
||||
}
|
||||
|
||||
// Get the server config binary representation
|
||||
func (s *ServerConfig) Get() []byte {
|
||||
var serverConfig bytes.Buffer
|
||||
WriteHandshakeMessage(&serverConfig, TagSCFG, map[Tag][]byte{
|
||||
TagSCID: []byte{0xC5, 0x1C, 0x73, 0x6B, 0x8F, 0x48, 0x49, 0xAE, 0xB3, 0x00, 0xA2, 0xD4, 0x4B, 0xA0, 0xCF, 0xDF},
|
||||
TagKEXS: []byte("C255"),
|
||||
TagAEAD: []byte("CC20"),
|
||||
TagPUBS: append([]byte{0x20, 0x00, 0x00}, s.kex.PublicKey()...),
|
||||
TagOBIT: []byte{0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7},
|
||||
TagEXPY: []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
|
||||
TagVER: []byte("Q032"),
|
||||
})
|
||||
return serverConfig.Bytes()
|
||||
}
|
||||
|
||||
// Sign the server config and CHLO with the server's keyData
|
||||
func (s *ServerConfig) Sign(chlo []byte) ([]byte, error) {
|
||||
return s.kd.SignServerProof(chlo, s.Get())
|
||||
}
|
||||
|
||||
// GetCertCompressed returns the certificate data
|
||||
func (s *ServerConfig) GetCertCompressed() []byte {
|
||||
return s.kd.GetCertCompressed()
|
||||
}
|
||||
29
handshake/server_config_test.go
Normal file
29
handshake/server_config_test.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package handshake
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/crypto"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
var _ = Describe("ServerConfig", func() {
|
||||
var (
|
||||
kex crypto.KeyExchange
|
||||
scfg *ServerConfig
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
kex = crypto.NewCurve25519KEX()
|
||||
scfg = NewServerConfig(kex, nil)
|
||||
})
|
||||
|
||||
It("gets the proper binary representation", func() {
|
||||
expected := bytes.NewBuffer([]byte{0x53, 0x43, 0x46, 0x47, 0x7, 0x0, 0x0, 0x0, 0x56, 0x45, 0x52, 0x0, 0x4, 0x0, 0x0, 0x0, 0x41, 0x45, 0x41, 0x44, 0x8, 0x0, 0x0, 0x0, 0x53, 0x43, 0x49, 0x44, 0x18, 0x0, 0x0, 0x0, 0x50, 0x55, 0x42, 0x53, 0x3b, 0x0, 0x0, 0x0, 0x4b, 0x45, 0x58, 0x53, 0x3f, 0x0, 0x0, 0x0, 0x4f, 0x42, 0x49, 0x54, 0x47, 0x0, 0x0, 0x0, 0x45, 0x58, 0x50, 0x59, 0x4f, 0x0, 0x0, 0x0, 0x51, 0x30, 0x33, 0x32, 0x43, 0x43, 0x32, 0x30, 0xc5, 0x1c, 0x73, 0x6b, 0x8f, 0x48, 0x49, 0xae, 0xb3, 0x0, 0xa2, 0xd4, 0x4b, 0xa0, 0xcf, 0xdf, 0x20, 0x0, 0x0})
|
||||
expected.Write(kex.PublicKey())
|
||||
expected.Write([]byte{0x43, 0x32, 0x35, 0x35, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff})
|
||||
Expect(scfg.Get()).To(Equal(expected.Bytes()))
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user