Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieve long term static key for Conn #4

Merged
merged 5 commits into from
Feb 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions noise/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,13 @@ func (c *Conn) Handshake() error {
var remoteKeyPair *KeyPair
if c.config.RemoteKey != nil {
if len(c.config.RemoteKey) != 32 {
return errors.New("Noise: the provided remote key is not 32-byte.")
return errors.New("noise: the provided remote key is not 32-byte")
}
remoteKeyPair = &KeyPair{}
copy(remoteKeyPair.PublicKey[:], c.config.RemoteKey)
}
hs := initialize(c.config.HandshakePattern, c.isClient, c.config.Prologue, c.config.KeyPair, nil, remoteKeyPair, nil)
c.hs = initialize(c.config.HandshakePattern, c.isClient, c.config.Prologue, c.config.KeyPair, nil, remoteKeyPair, nil)
hs := &c.hs

// pre-shared key
hs.psk = c.config.PreSharedKey
Expand Down Expand Up @@ -340,7 +341,6 @@ ContinueHandshake:
// TODO: preserve c.hs.symmetricState.h
// At that point the HandshakeState should be deleted except for the hash value h, which may be used for post-handshake channel binding (see Section 11.2).
c.hs.clear()

// no errors :)
c.handshakeComplete = true
return nil
Expand All @@ -351,6 +351,15 @@ func (c *Conn) IsRemoteAuthenticated() bool {
return c.isRemoteAuthenticated
}

// StaticKey returns the static key of the remote peer. It is useful in case the
// static key is only transmitted during the handshake.
func (c *Conn) StaticKey() ([]byte, error) {
if !c.handshakeComplete {
return nil, errors.New("noise: handshake not completed")
}
return c.hs.rs.PublicKey[:], nil
}

//
// input/output functions
//
Expand Down
4 changes: 0 additions & 4 deletions noise/noise.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ type handshakeState struct {
// * s, e, rs, re are the local and remote static/ephemeral key pairs to be set (if they exist)
// the function returns a handshakeState object.
func initialize(handshakeType noiseHandshakeType, initiator bool, prologue []byte, s, e, rs, re *KeyPair) (h handshakeState) {

handshakePattern, ok := patterns[handshakeType]
if !ok {
panic("Noise: the supplied handshakePattern does not exist")
Expand Down Expand Up @@ -500,7 +499,4 @@ func (kp *KeyPair) clear() {
for i := 0; i < len(kp.PrivateKey); i++ {
kp.PrivateKey[i] = 0
}
for i := 0; i < len(kp.PublicKey); i++ {
kp.PublicKey[i] = 0
}
}
17 changes: 16 additions & 1 deletion noise/patterns_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,13 @@ func TestNoiseXX(t *testing.T) {
if _, err = serverSocket.Write([]byte("ca va?")); err != nil {
t.Fatal("server can't write on socket")
}

clientStatic, err := serverSocket.(*Conn).StaticKey()
if err != nil {
t.Fatal("client static key not retrieved")
}
if !bytes.Equal(clientStatic, clientKeyPair.PublicKey[:]) {
t.Fatalf("client static retrieved not correct %x", clientStatic)
}
}()

// Run the client
Expand All @@ -211,6 +217,15 @@ func TestNoiseXX(t *testing.T) {
if !bytes.Equal(buf[:n], []byte("ca va?")) {
t.Fatal("server message failed")
}

serverStatic, err := clientSocket.StaticKey()
if err != nil {
t.Fatal("server static key not retrieved after exchange", err)
}

if !bytes.Equal(serverStatic, serverKeyPair.PublicKey[:]) {
t.Fatalf("(conn %p) static key received different than server's one %x", clientSocket, serverStatic)
}
}

func TestNoiseN(t *testing.T) {
Expand Down