Skip to content

Commit 671e727

Browse files
committed
use function for dynamic key support
1 parent e515a92 commit 671e727

File tree

2 files changed

+49
-16
lines changed

2 files changed

+49
-16
lines changed

conn.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ func (c *Conn) Write(p []byte) (int, error) {
6464
return n, err
6565
}
6666

67+
func (c *Conn) LocalAddr() net.Addr {
68+
return c.rw.LocalAddr()
69+
}
70+
71+
func (c *Conn) RemoteAddr() net.Addr {
72+
return c.rw.RemoteAddr()
73+
}
74+
6775
// Open opens a ZMTP connection over rw with the given security, socket type and identity.
6876
// An optional onCloseErrorCB can be provided to inform the caller when this Conn is closed.
6977
// Open performs a complete ZMTP handshake.

security/curve/curve.go

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ func NewKeyPair() (*KeyPair, error) {
4444

4545
// security implements the CURVE security mechanism.
4646
type security struct {
47-
serverPubKey [keySize]byte // Long-term server public key
48-
keys *KeyPair // Long-term client key pair (optional for client, required for server)
49-
asServer bool // True if this is a server
47+
serverPubKey [keySize]byte // Long-term server public key
48+
keys func(conn *zmq4.Conn) (*KeyPair, error) // Long-term client key pair (optional for client, required for server)
49+
asServer bool // True if this is a server
5050
}
5151

5252
// SecurityForClient returns a CURVE security mechanism for a client.
5353
// The client must know the server's public key.
5454
func SecurityForClient(serverKey [keySize]byte, clientKeys *KeyPair) zmq4.Security {
5555
sec := &security{
5656
serverPubKey: serverKey,
57-
keys: clientKeys,
58-
asServer: false,
57+
keys: func(_ *zmq4.Conn) (*KeyPair, error) {
58+
return clientKeys, nil
59+
},
60+
asServer: false,
5961
}
6062
return sec
6163
}
@@ -64,7 +66,19 @@ func SecurityForClient(serverKey [keySize]byte, clientKeys *KeyPair) zmq4.Securi
6466
// The server must have its own key pair.
6567
func SecurityForServer(serverKeys *KeyPair) zmq4.Security {
6668
sec := &security{
67-
keys: serverKeys,
69+
keys: func(_ *zmq4.Conn) (*KeyPair, error) {
70+
return serverKeys, nil
71+
},
72+
asServer: true,
73+
}
74+
return sec
75+
}
76+
77+
// SecurityForServerFunc returns a CURVE security mechanism for a server.
78+
// The server must have its own key pair.
79+
func SecurityForServerFunc(getServerKeys func(_ *zmq4.Conn) (*KeyPair, error)) zmq4.Security {
80+
sec := &security{
81+
keys: getServerKeys,
6882
asServer: true,
6983
}
7084
return sec
@@ -108,7 +122,12 @@ func (sec *security) clientHandshake(conn *zmq4.Conn, ephemeral *KeyPair) error
108122
return fmt.Errorf("security/curve: failed WELCOME: %w", err)
109123
}
110124

111-
err = sec.doInitiate(conn, servCookie, &nonce, secretKey, ephemeral)
125+
keys, err := sec.keys(conn)
126+
if err != nil {
127+
return fmt.Errorf("security/curve: could not generate keys: %w", err)
128+
}
129+
130+
err = sec.doInitiate(conn, servCookie, &nonce, keys, secretKey, ephemeral)
112131
if err != nil {
113132
return fmt.Errorf("security/curve: failed INITIATE: %w", err)
114133
}
@@ -136,7 +155,13 @@ func (sec *security) clientHandshake(conn *zmq4.Conn, ephemeral *KeyPair) error
136155
func (sec *security) serverHandshake(conn *zmq4.Conn) error {
137156
var nonce Nonce
138157
var cookieKey [32]byte
139-
clientTransPubKey, err := sec.doServerHello(&nonce, conn)
158+
159+
keys, err := sec.keys(conn)
160+
if err != nil {
161+
return fmt.Errorf("security/curve: could not generate keys: %w", err)
162+
}
163+
164+
clientTransPubKey, err := sec.doServerHello(&nonce, conn, keys)
140165
if err != nil {
141166
return fmt.Errorf("security/curve: Client hello failed: %w", err)
142167
}
@@ -145,7 +170,7 @@ func (sec *security) serverHandshake(conn *zmq4.Conn) error {
145170
if err != nil {
146171
panic(fmt.Sprintf("Failed creaing cookie key: %s", err.Error()))
147172
}
148-
err = sec.doServerWelcome(&nonce, conn, &clientTransPubKey, &cookieKey, kp)
173+
err = sec.doServerWelcome(&nonce, conn, keys, &clientTransPubKey, &cookieKey, kp)
149174
if err != nil {
150175
return fmt.Errorf("security/curve: Failed sending welcome: %w", err)
151176
}
@@ -266,7 +291,7 @@ func (sec *security) doWelcome(nonce *Nonce, conn *zmq4.Conn, ephemeral *KeyPair
266291
return welcomeBox[32:], &secretKey, nil
267292
}
268293

269-
func (sec *security) doInitiate(conn *zmq4.Conn, servCookie []byte, nonce *Nonce, secretKey *[32]byte, ephemeral *KeyPair) error {
294+
func (sec *security) doInitiate(conn *zmq4.Conn, servCookie []byte, nonce *Nonce, keys *KeyPair, secretKey *[32]byte, ephemeral *KeyPair) error {
270295
meta, err := conn.Meta.MarshalZMTP()
271296
if err != nil {
272297
return fmt.Errorf("security/curve: could not marshal metadata: %w", err)
@@ -281,10 +306,10 @@ func (sec *security) doInitiate(conn *zmq4.Conn, servCookie []byte, nonce *Nonce
281306
copy(vouch, ephemeral.Public[:])
282307
copy(vouch[32:], sec.serverPubKey[:])
283308
vouchBox := make([]byte, 80)
284-
box.Seal(vouchBox[0:0], vouch, nonce.N(), secretKey, &sec.keys.Private)
309+
box.Seal(vouchBox[0:0], vouch, nonce.N(), secretKey, &keys.Private)
285310

286311
initBox := make([]byte, 128+len(meta))
287-
copy(initBox, sec.keys.Public[:])
312+
copy(initBox, keys.Public[:])
288313
copy(initBox[32:48], nonce[8:])
289314
copy(initBox[48:128], vouchBox)
290315
copy(initBox[128:], meta)
@@ -317,7 +342,7 @@ func (sec *security) doReady(conn *zmq4.Conn, nonce *Nonce, secretKey *[32]byte,
317342
return servMeta, nil
318343
}
319344

320-
func (sec *security) doServerHello(nonce *Nonce, conn *zmq4.Conn) (clientTransPubKey [32]byte, err error) {
345+
func (sec *security) doServerHello(nonce *Nonce, conn *zmq4.Conn, keys *KeyPair) (clientTransPubKey [32]byte, err error) {
321346
cmd, err := conn.RecvCmd()
322347
if err != nil {
323348
return clientTransPubKey, err
@@ -343,7 +368,7 @@ func (sec *security) doServerHello(nonce *Nonce, conn *zmq4.Conn) (clientTransPu
343368
return
344369
}
345370
var out [64]byte
346-
_, ok := box.Open(out[0:0], cmd.Body[114:], nonce.N(), &clientTransPubKey, &sec.keys.Private)
371+
_, ok := box.Open(out[0:0], cmd.Body[114:], nonce.N(), &clientTransPubKey, &keys.Private)
347372
if !ok {
348373
err = fmt.Errorf("security/curve: Invalid signature in hello command")
349374
return
@@ -358,7 +383,7 @@ func (sec *security) doServerHello(nonce *Nonce, conn *zmq4.Conn) (clientTransPu
358383
return
359384
}
360385

361-
func (sec *security) doServerWelcome(nonce *Nonce, conn *zmq4.Conn, clientTransPubKey, cookieKey *[32]byte, kp *KeyPair) error {
386+
func (sec *security) doServerWelcome(nonce *Nonce, conn *zmq4.Conn, keys *KeyPair, clientTransPubKey, cookieKey *[32]byte, kp *KeyPair) error {
362387
welcomeBody := make([]byte, 160)
363388
var cookie [64]byte
364389
copy(cookie[:], clientTransPubKey[:])
@@ -375,7 +400,7 @@ func (sec *security) doServerWelcome(nonce *Nonce, conn *zmq4.Conn, clientTransP
375400
copy(welcomeBox[32:], cookieData)
376401
nonce.Long("WELCOME-")
377402
copy(welcomeBody, nonce[8:])
378-
box.Seal(welcomeBody[16:16], welcomeBox, nonce.N(), clientTransPubKey, &sec.keys.Private)
403+
box.Seal(welcomeBody[16:16], welcomeBox, nonce.N(), clientTransPubKey, &keys.Private)
379404
return conn.SendCmd(zmq4.CmdWelcome, welcomeBody)
380405
}
381406

0 commit comments

Comments
 (0)