15 zmq::curve_server_t::curve_server_t (session_base_t *session_,
18 const bool downgrade_sub_) :
19 mechanism_base_t (session_,
options_),
20 zap_client_common_handshake_t (
21 session_, peer_address_,
options_, sending_ready),
22 curve_mechanism_base_t (session_,
30 memcpy (_secret_key,
options_.curve_secret_key, crypto_box_SECRETKEYBYTES);
33 memset (_cn_secret, 0, crypto_box_SECRETKEYBYTES);
34 memset (_cn_public, 0, crypto_box_PUBLICKEYBYTES);
35 rc = crypto_box_keypair (_cn_public, _cn_secret);
39 zmq::curve_server_t::~curve_server_t ()
43 int zmq::curve_server_t::next_handshake_command (msg_t *msg_)
49 rc = produce_welcome (msg_);
51 state = waiting_for_initiate;
54 rc = produce_ready (msg_);
59 rc = produce_error (msg_);
71 int zmq::curve_server_t::process_handshake_command (msg_t *msg_)
76 case waiting_for_hello:
77 rc = process_hello (msg_);
79 case waiting_for_initiate:
80 rc = process_initiate (msg_);
90 session->get_socket ()->event_handshake_failed_protocol (
105 int zmq::curve_server_t::encode (msg_t *msg_)
108 return curve_mechanism_base_t::encode (msg_);
111 int zmq::curve_server_t::decode (msg_t *msg_)
114 return curve_mechanism_base_t::decode (msg_);
117 int zmq::curve_server_t::process_hello (msg_t *msg_)
119 int rc = check_basic_command_structure (msg_);
123 const size_t size = msg_->size ();
124 const uint8_t *
const hello =
static_cast<uint8_t *
> (msg_->data ());
126 if (
size < 6 || memcmp (hello,
"\x05HELLO", 6)) {
127 session->get_socket ()->event_handshake_failed_protocol (
134 session->get_socket ()->event_handshake_failed_protocol (
135 session->get_endpoint (),
141 const uint8_t
major = hello[6];
142 const uint8_t
minor = hello[7];
146 session->get_socket ()->event_handshake_failed_protocol (
147 session->get_endpoint (),
154 memcpy (_cn_client, hello + 80, 32);
156 uint8_t hello_nonce[crypto_box_NONCEBYTES];
157 std::vector<uint8_t, secure_allocator_t<uint8_t> > hello_plaintext (
158 crypto_box_ZEROBYTES + 64);
159 uint8_t hello_box[crypto_box_BOXZEROBYTES + 80];
161 memcpy (hello_nonce,
"CurveZMQHELLO---", 16);
162 memcpy (hello_nonce + 16, hello + 112, 8);
165 memset (hello_box, 0, crypto_box_BOXZEROBYTES);
166 memcpy (hello_box + crypto_box_BOXZEROBYTES, hello + 120, 80);
169 rc = crypto_box_open (&hello_plaintext[0], hello_box,
sizeof hello_box,
170 hello_nonce, _cn_client, _secret_key);
173 session->get_socket ()->event_handshake_failed_protocol (
179 state = sending_welcome;
183 int zmq::curve_server_t::produce_welcome (msg_t *msg_)
185 uint8_t cookie_nonce[crypto_secretbox_NONCEBYTES];
186 std::vector<uint8_t, secure_allocator_t<uint8_t> > cookie_plaintext (
187 crypto_secretbox_ZEROBYTES + 64);
188 uint8_t cookie_ciphertext[crypto_secretbox_BOXZEROBYTES + 80];
192 memset (cookie_nonce, 0, crypto_secretbox_NONCEBYTES);
193 memcpy (cookie_nonce,
"COOKIE--", 8);
194 randombytes (cookie_nonce + 8, 16);
197 std::fill (cookie_plaintext.begin (),
198 cookie_plaintext.begin () + crypto_secretbox_ZEROBYTES, 0);
199 memcpy (&cookie_plaintext[crypto_secretbox_ZEROBYTES], _cn_client, 32);
200 memcpy (&cookie_plaintext[crypto_secretbox_ZEROBYTES + 32], _cn_secret, 32);
203 memset (_cookie_key, 0, crypto_secretbox_KEYBYTES);
204 randombytes (_cookie_key, crypto_secretbox_KEYBYTES);
208 crypto_secretbox (cookie_ciphertext, &cookie_plaintext[0],
209 cookie_plaintext.size (), cookie_nonce, _cookie_key);
212 uint8_t welcome_nonce[crypto_box_NONCEBYTES];
213 std::vector<uint8_t, secure_allocator_t<uint8_t> > welcome_plaintext (
214 crypto_box_ZEROBYTES + 128);
215 uint8_t welcome_ciphertext[crypto_box_BOXZEROBYTES + 144];
219 memset (welcome_nonce, 0, crypto_box_NONCEBYTES);
220 memcpy (welcome_nonce,
"WELCOME-", 8);
221 randombytes (welcome_nonce + 8, crypto_box_NONCEBYTES - 8);
224 std::fill (welcome_plaintext.begin (),
225 welcome_plaintext.begin () + crypto_box_ZEROBYTES, 0);
226 memcpy (&welcome_plaintext[crypto_box_ZEROBYTES], _cn_public, 32);
227 memcpy (&welcome_plaintext[crypto_box_ZEROBYTES + 32], cookie_nonce + 8,
229 memcpy (&welcome_plaintext[crypto_box_ZEROBYTES + 48],
230 cookie_ciphertext + crypto_secretbox_BOXZEROBYTES, 80);
232 rc = crypto_box (welcome_ciphertext, &welcome_plaintext[0],
233 welcome_plaintext.size (), welcome_nonce, _cn_client,
245 rc = msg_->init_size (168);
248 uint8_t *
const welcome =
static_cast<uint8_t *
> (msg_->data ());
249 memcpy (welcome,
"\x07WELCOME", 8);
250 memcpy (welcome + 8, welcome_nonce + 8, 16);
251 memcpy (welcome + 24, welcome_ciphertext + crypto_box_BOXZEROBYTES, 144);
256 int zmq::curve_server_t::process_initiate (msg_t *msg_)
258 int rc = check_basic_command_structure (msg_);
262 const size_t size = msg_->size ();
263 const uint8_t *initiate =
static_cast<uint8_t *
> (msg_->data ());
265 if (
size < 9 || memcmp (initiate,
"\x08INITIATE", 9)) {
266 session->get_socket ()->event_handshake_failed_protocol (
273 session->get_socket ()->event_handshake_failed_protocol (
274 session->get_endpoint (),
280 uint8_t cookie_nonce[crypto_secretbox_NONCEBYTES];
281 uint8_t cookie_plaintext[crypto_secretbox_ZEROBYTES + 64];
282 uint8_t cookie_box[crypto_secretbox_BOXZEROBYTES + 80];
285 memset (cookie_box, 0, crypto_secretbox_BOXZEROBYTES);
286 memcpy (cookie_box + crypto_secretbox_BOXZEROBYTES, initiate + 25, 80);
288 memcpy (cookie_nonce,
"COOKIE--", 8);
289 memcpy (cookie_nonce + 8, initiate + 9, 16);
291 rc = crypto_secretbox_open (cookie_plaintext, cookie_box,
sizeof cookie_box,
292 cookie_nonce, _cookie_key);
295 session->get_socket ()->event_handshake_failed_protocol (
302 if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES, _cn_client, 32)
303 || memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32,
309 session->get_socket ()->event_handshake_failed_protocol (
315 const size_t clen = (
size - 113) + crypto_box_BOXZEROBYTES;
317 uint8_t initiate_nonce[crypto_box_NONCEBYTES];
318 std::vector<uint8_t, secure_allocator_t<uint8_t> > initiate_plaintext (
319 crypto_box_ZEROBYTES + clen);
320 std::vector<uint8_t> initiate_box (crypto_box_BOXZEROBYTES + clen);
323 std::fill (initiate_box.begin (),
324 initiate_box.begin () + crypto_box_BOXZEROBYTES, 0);
325 memcpy (&initiate_box[crypto_box_BOXZEROBYTES], initiate + 113,
326 clen - crypto_box_BOXZEROBYTES);
328 memcpy (initiate_nonce,
"CurveZMQINITIATE", 16);
329 memcpy (initiate_nonce + 16, initiate + 105, 8);
332 const uint8_t *client_key = &initiate_plaintext[crypto_box_ZEROBYTES];
334 rc = crypto_box_open (&initiate_plaintext[0], &initiate_box[0], clen,
335 initiate_nonce, _cn_client, _cn_secret);
338 session->get_socket ()->event_handshake_failed_protocol (
344 uint8_t vouch_nonce[crypto_box_NONCEBYTES];
345 std::vector<uint8_t, secure_allocator_t<uint8_t> > vouch_plaintext (
346 crypto_box_ZEROBYTES + 64);
347 uint8_t vouch_box[crypto_box_BOXZEROBYTES + 80];
350 memset (vouch_box, 0, crypto_box_BOXZEROBYTES);
351 memcpy (vouch_box + crypto_box_BOXZEROBYTES,
352 &initiate_plaintext[crypto_box_ZEROBYTES + 48], 80);
354 memset (vouch_nonce, 0, crypto_box_NONCEBYTES);
355 memcpy (vouch_nonce,
"VOUCH---", 8);
356 memcpy (vouch_nonce + 8, &initiate_plaintext[crypto_box_ZEROBYTES + 32],
359 rc = crypto_box_open (&vouch_plaintext[0], vouch_box,
sizeof vouch_box,
360 vouch_nonce, client_key, _cn_secret);
363 session->get_socket ()->event_handshake_failed_protocol (
370 if (memcmp (&vouch_plaintext[crypto_box_ZEROBYTES], _cn_client, 32)) {
375 session->get_socket ()->event_handshake_failed_protocol (
382 rc = crypto_box_beforenm (get_writable_precom_buffer (), _cn_client,
388 if (zap_required () || !
options.zap_enforce_domain) {
390 rc = session->zap_connect ();
392 send_zap_request (client_key);
393 state = waiting_for_zap_reply;
399 if (-1 == receive_and_process_zap_reply ())
401 }
else if (!
options.zap_enforce_domain) {
404 state = sending_ready;
406 session->get_socket ()->event_handshake_failed_no_detail (
407 session->get_endpoint (),
EFAULT);
412 state = sending_ready;
415 return parse_metadata (&initiate_plaintext[crypto_box_ZEROBYTES + 128],
416 clen - crypto_box_ZEROBYTES - 128);
419 int zmq::curve_server_t::produce_ready (msg_t *msg_)
421 const size_t metadata_length = basic_properties_len ();
422 uint8_t ready_nonce[crypto_box_NONCEBYTES];
424 std::vector<uint8_t, secure_allocator_t<uint8_t> > ready_plaintext (
425 crypto_box_ZEROBYTES + metadata_length);
428 std::fill (ready_plaintext.begin (),
429 ready_plaintext.begin () + crypto_box_ZEROBYTES, 0);
430 uint8_t *ptr = &ready_plaintext[crypto_box_ZEROBYTES];
432 ptr += add_basic_properties (ptr, metadata_length);
433 const size_t mlen = ptr - &ready_plaintext[0];
435 memcpy (ready_nonce,
"CurveZMQREADY---", 16);
436 put_uint64 (ready_nonce + 16, get_and_inc_nonce ());
438 std::vector<uint8_t> ready_box (crypto_box_BOXZEROBYTES + 16
441 int rc = crypto_box_afternm (&ready_box[0], &ready_plaintext[0], mlen,
442 ready_nonce, get_precom_buffer ());
445 rc = msg_->init_size (14 + mlen - crypto_box_BOXZEROBYTES);
448 uint8_t *ready =
static_cast<uint8_t *
> (msg_->data ());
450 memcpy (ready,
"\x05READY", 6);
452 memcpy (ready + 6, ready_nonce + 16, 8);
454 memcpy (ready + 14, &ready_box[crypto_box_BOXZEROBYTES],
455 mlen - crypto_box_BOXZEROBYTES);
460 int zmq::curve_server_t::produce_error (msg_t *msg_)
const
462 const size_t expected_status_code_length = 3;
464 const int rc = msg_->init_size (6 + 1 + expected_status_code_length);
466 char *msg_data =
static_cast<char *
> (msg_->data ());
467 memcpy (msg_data,
"\5ERROR", 6);
468 msg_data[6] = expected_status_code_length;
469 memcpy (msg_data + 7, status_code.c_str (), expected_status_code_length);
473 void zmq::curve_server_t::send_zap_request (
const uint8_t *key_)
475 zap_client_t::send_zap_request (
"CURVE", 5, key_,
476 crypto_box_PUBLICKEYBYTES);