@@ -44,18 +44,20 @@ func NewKeyPair() (*KeyPair, error) {
44
44
45
45
// security implements the CURVE security mechanism.
46
46
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
50
50
}
51
51
52
52
// SecurityForClient returns a CURVE security mechanism for a client.
53
53
// The client must know the server's public key.
54
54
func SecurityForClient (serverKey [keySize ]byte , clientKeys * KeyPair ) zmq4.Security {
55
55
sec := & security {
56
56
serverPubKey : serverKey ,
57
- keys : clientKeys ,
58
- asServer : false ,
57
+ keys : func (_ * zmq4.Conn ) (* KeyPair , error ) {
58
+ return clientKeys , nil
59
+ },
60
+ asServer : false ,
59
61
}
60
62
return sec
61
63
}
@@ -64,7 +66,19 @@ func SecurityForClient(serverKey [keySize]byte, clientKeys *KeyPair) zmq4.Securi
64
66
// The server must have its own key pair.
65
67
func SecurityForServer (serverKeys * KeyPair ) zmq4.Security {
66
68
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 ,
68
82
asServer : true ,
69
83
}
70
84
return sec
@@ -108,7 +122,12 @@ func (sec *security) clientHandshake(conn *zmq4.Conn, ephemeral *KeyPair) error
108
122
return fmt .Errorf ("security/curve: failed WELCOME: %w" , err )
109
123
}
110
124
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 )
112
131
if err != nil {
113
132
return fmt .Errorf ("security/curve: failed INITIATE: %w" , err )
114
133
}
@@ -136,7 +155,13 @@ func (sec *security) clientHandshake(conn *zmq4.Conn, ephemeral *KeyPair) error
136
155
func (sec * security ) serverHandshake (conn * zmq4.Conn ) error {
137
156
var nonce Nonce
138
157
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 )
140
165
if err != nil {
141
166
return fmt .Errorf ("security/curve: Client hello failed: %w" , err )
142
167
}
@@ -145,7 +170,7 @@ func (sec *security) serverHandshake(conn *zmq4.Conn) error {
145
170
if err != nil {
146
171
panic (fmt .Sprintf ("Failed creaing cookie key: %s" , err .Error ()))
147
172
}
148
- err = sec .doServerWelcome (& nonce , conn , & clientTransPubKey , & cookieKey , kp )
173
+ err = sec .doServerWelcome (& nonce , conn , keys , & clientTransPubKey , & cookieKey , kp )
149
174
if err != nil {
150
175
return fmt .Errorf ("security/curve: Failed sending welcome: %w" , err )
151
176
}
@@ -266,7 +291,7 @@ func (sec *security) doWelcome(nonce *Nonce, conn *zmq4.Conn, ephemeral *KeyPair
266
291
return welcomeBox [32 :], & secretKey , nil
267
292
}
268
293
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 {
270
295
meta , err := conn .Meta .MarshalZMTP ()
271
296
if err != nil {
272
297
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
281
306
copy (vouch , ephemeral .Public [:])
282
307
copy (vouch [32 :], sec .serverPubKey [:])
283
308
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 )
285
310
286
311
initBox := make ([]byte , 128 + len (meta ))
287
- copy (initBox , sec . keys .Public [:])
312
+ copy (initBox , keys .Public [:])
288
313
copy (initBox [32 :48 ], nonce [8 :])
289
314
copy (initBox [48 :128 ], vouchBox )
290
315
copy (initBox [128 :], meta )
@@ -317,7 +342,7 @@ func (sec *security) doReady(conn *zmq4.Conn, nonce *Nonce, secretKey *[32]byte,
317
342
return servMeta , nil
318
343
}
319
344
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 ) {
321
346
cmd , err := conn .RecvCmd ()
322
347
if err != nil {
323
348
return clientTransPubKey , err
@@ -343,7 +368,7 @@ func (sec *security) doServerHello(nonce *Nonce, conn *zmq4.Conn) (clientTransPu
343
368
return
344
369
}
345
370
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 )
347
372
if ! ok {
348
373
err = fmt .Errorf ("security/curve: Invalid signature in hello command" )
349
374
return
@@ -358,7 +383,7 @@ func (sec *security) doServerHello(nonce *Nonce, conn *zmq4.Conn) (clientTransPu
358
383
return
359
384
}
360
385
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 {
362
387
welcomeBody := make ([]byte , 160 )
363
388
var cookie [64 ]byte
364
389
copy (cookie [:], clientTransPubKey [:])
@@ -375,7 +400,7 @@ func (sec *security) doServerWelcome(nonce *Nonce, conn *zmq4.Conn, clientTransP
375
400
copy (welcomeBox [32 :], cookieData )
376
401
nonce .Long ("WELCOME-" )
377
402
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 )
379
404
return conn .SendCmd (zmq4 .CmdWelcome , welcomeBody )
380
405
}
381
406
0 commit comments