@@ -20,7 +20,7 @@ import (
2020)
2121
2222const (
23- keySize = 32 // Size of public and private keys
23+ keySize = 32 // Size of public and private keyFunc
2424 nonceSize = 24 // Size of nonce
2525)
2626
@@ -44,18 +44,20 @@ func NewKeyPair() (*KeyPair, error) {
4444
4545// security implements the CURVE security mechanism.
4646type 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+ keyFunc 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.
5454func SecurityForClient (serverKey [keySize ]byte , clientKeys * KeyPair ) zmq4.Security {
5555 sec := & security {
5656 serverPubKey : serverKey ,
57- keys : clientKeys ,
58- asServer : false ,
57+ keyFunc : 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.
6567func SecurityForServer (serverKeys * KeyPair ) zmq4.Security {
6668 sec := & security {
67- keys : serverKeys ,
69+ keyFunc : 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+ keyFunc : 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 .keyFunc (conn )
126+ if err != nil {
127+ return fmt .Errorf ("security/curve: could not generate keyFunc: %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
136155func (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 .keyFunc (conn )
160+ if err != nil {
161+ return fmt .Errorf ("security/curve: could not generate keyFunc: %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