From bfd472f97cad5e37fa384b687a906f515600bac4 Mon Sep 17 00:00:00 2001 From: Laurent Alebarde Date: Tue, 17 Sep 2013 12:44:14 +0200 Subject: [PATCH] makes curve keys symetric as in libcurve + factorisation --- include/zmq.h | 21 +++--- src/curve_client.cpp | 54 +++++++-------- src/curve_client.hpp | 30 ++++----- src/curve_server.cpp | 54 +++++++-------- src/curve_server.hpp | 20 +++--- src/options.cpp | 122 ++++++++++++++-------------------- src/options.hpp | 10 ++- tests/test_security_curve.cpp | 37 ++++++----- 8 files changed, 169 insertions(+), 179 deletions(-) diff --git a/include/zmq.h b/include/zmq.h index 3cb95262..baaff432 100644 --- a/include/zmq.h +++ b/include/zmq.h @@ -273,14 +273,19 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval); #define ZMQ_PLAIN_USERNAME 45 #define ZMQ_PLAIN_PASSWORD 46 #define ZMQ_CURVE_SERVER 47 -#define ZMQ_CURVE_PUBLICKEY 48 -#define ZMQ_CURVE_SECRETKEY 49 -#define ZMQ_CURVE_SERVERKEY 50 -#define ZMQ_PROBE_ROUTER 51 -#define ZMQ_REQ_REQUEST_IDS 52 -#define ZMQ_REQ_STRICT 53 -#define ZMQ_CONFLATE 54 -#define ZMQ_ZAP_DOMAIN 55 +#define ZMQ_CURVE_OUR_PERMA_PUB_KEY 48 +#define ZMQ_CURVE_OUR_PERMA_SEC_KEY 49 +#define ZMQ_CURVE_PEER_PERMA_PUB_KEY 50 +#define ZMQ_CURVE_PEER_PERMA_SEC_KEY 51 +#define ZMQ_PROBE_ROUTER 52 +#define ZMQ_REQ_REQUEST_IDS 53 +#define ZMQ_REQ_STRICT 54 +#define ZMQ_CONFLATE 55 +#define ZMQ_ZAP_DOMAIN 56 + +/* Peer type : server or client */ +#define ZMQ_SERVER 1 +#define ZMQ_CLIENT 0 /* Message options */ #define ZMQ_MORE 1 diff --git a/src/curve_client.cpp b/src/curve_client.cpp index 296756a2..46d90030 100644 --- a/src/curve_client.cpp +++ b/src/curve_client.cpp @@ -37,12 +37,12 @@ zmq::curve_client_t::curve_client_t (const options_t &options_) : mechanism_t (options_), state (send_hello) { - memcpy (public_key, options_.curve_public_key, crypto_box_PUBLICKEYBYTES); - memcpy (secret_key, options_.curve_secret_key, crypto_box_SECRETKEYBYTES); - memcpy (server_key, options_.curve_server_key, crypto_box_PUBLICKEYBYTES); + memcpy (our_perma_pub_key, options_.curve_our_perma_pub_key, crypto_box_PUBLICKEYBYTES); + memcpy (our_perma_sec_key, options_.curve_our_perma_sec_key, crypto_box_SECRETKEYBYTES); + memcpy (peer_perma_pub_key, options_.curve_peer_perma_pub_key, crypto_box_PUBLICKEYBYTES); - // Generate short-term key pair - const int rc = crypto_box_keypair (cn_public, cn_secret); + // Generate transient key pair + const int rc = crypto_box_keypair (our_trans_pub_key, our_trans_sec_key); zmq_assert (rc == 0); } @@ -111,7 +111,7 @@ int zmq::curve_client_t::encode (msg_t *msg_) uint8_t message_nonce [crypto_box_NONCEBYTES]; memcpy (message_nonce, "CurveZMQMESSAGEC", 16); - memcpy (message_nonce + 16, &cn_nonce, 8); + memcpy (message_nonce + 16, &nonce, 8); const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size (); @@ -127,7 +127,7 @@ int zmq::curve_client_t::encode (msg_t *msg_) alloc_assert (message_box); int rc = crypto_box_afternm (message_box, message_plaintext, - mlen, message_nonce, cn_precom); + mlen, message_nonce, precomputed); zmq_assert (rc == 0); rc = msg_->close (); @@ -139,14 +139,14 @@ int zmq::curve_client_t::encode (msg_t *msg_) uint8_t *message = static_cast (msg_->data ()); memcpy (message, "\x07MESSAGE", 8); - memcpy (message + 8, &cn_nonce, 8); + memcpy (message + 8, &nonce, 8); memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES); free (message_plaintext); free (message_box); - cn_nonce++; + nonce++; return 0; } @@ -183,7 +183,7 @@ int zmq::curve_client_t::decode (msg_t *msg_) message + 16, msg_->size () - 16); int rc = crypto_box_open_afternm (message_plaintext, message_box, - clen, message_nonce, cn_precom); + clen, message_nonce, precomputed); if (rc == 0) { rc = msg_->close (); zmq_assert (rc == 0); @@ -221,14 +221,14 @@ int zmq::curve_client_t::produce_hello (msg_t *msg_) // Prepare the full nonce memcpy (hello_nonce, "CurveZMQHELLO---", 16); - memcpy (hello_nonce + 16, &cn_nonce, 8); + memcpy (hello_nonce + 16, &nonce, 8); // Create Box [64 * %x0](C'->S) memset (hello_plaintext, 0, sizeof hello_plaintext); int rc = crypto_box (hello_box, hello_plaintext, sizeof hello_plaintext, - hello_nonce, server_key, cn_secret); + hello_nonce, peer_perma_pub_key, our_trans_sec_key); zmq_assert (rc == 0); rc = msg_->init_size (200); @@ -241,13 +241,13 @@ int zmq::curve_client_t::produce_hello (msg_t *msg_) // Anti-amplification padding memset (hello + 8, 0, 72); // Client public connection key - memcpy (hello + 80, cn_public, crypto_box_PUBLICKEYBYTES); + memcpy (hello + 80, our_trans_pub_key, crypto_box_PUBLICKEYBYTES); // Short nonce, prefixed by "CurveZMQHELLO---" memcpy (hello + 112, hello_nonce + 16, 8); // Signature, Box [64 * %x0](C'->S) memcpy (hello + 120, hello_box + crypto_box_BOXZEROBYTES, 80); - cn_nonce++; + nonce++; return 0; } @@ -278,17 +278,17 @@ int zmq::curve_client_t::process_welcome (msg_t *msg_) int rc = crypto_box_open (welcome_plaintext, welcome_box, sizeof welcome_box, - welcome_nonce, server_key, cn_secret); + welcome_nonce, peer_perma_pub_key, our_trans_sec_key); if (rc != 0) { errno = EPROTO; return -1; } - memcpy (cn_server, welcome_plaintext + crypto_box_ZEROBYTES, 32); - memcpy (cn_cookie, welcome_plaintext + crypto_box_ZEROBYTES + 32, 16 + 80); + memcpy (peer_trans_pub_key, welcome_plaintext + crypto_box_ZEROBYTES, 32); + memcpy (cookie, welcome_plaintext + crypto_box_ZEROBYTES + 32, 16 + 80); // Message independent precomputation - rc = crypto_box_beforenm (cn_precom, cn_server, cn_secret); + rc = crypto_box_beforenm (precomputed, peer_trans_pub_key, our_trans_sec_key); zmq_assert (rc == 0); return 0; @@ -302,14 +302,14 @@ int zmq::curve_client_t::produce_initiate (msg_t *msg_) // Create vouch = Box [C'](C->S) memset (vouch_plaintext, 0, crypto_box_ZEROBYTES); - memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public, 32); + memcpy (vouch_plaintext + crypto_box_ZEROBYTES, our_trans_pub_key, 32); memcpy (vouch_nonce, "VOUCH---", 8); randombytes (vouch_nonce + 8, 16); int rc = crypto_box (vouch_box, vouch_plaintext, sizeof vouch_plaintext, - vouch_nonce, server_key, secret_key); + vouch_nonce, peer_perma_pub_key, our_perma_sec_key); zmq_assert (rc == 0); uint8_t initiate_nonce [crypto_box_NONCEBYTES]; @@ -318,7 +318,7 @@ int zmq::curve_client_t::produce_initiate (msg_t *msg_) // Create Box [C + vouch + metadata](C'->S') memset (initiate_plaintext, 0, crypto_box_ZEROBYTES); - memcpy (initiate_plaintext + crypto_box_ZEROBYTES, public_key, 32); + memcpy (initiate_plaintext + crypto_box_ZEROBYTES, our_perma_pub_key, 32); memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32, vouch_nonce + 8, 16); memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48, @@ -340,10 +340,10 @@ int zmq::curve_client_t::produce_initiate (msg_t *msg_) const size_t mlen = ptr - initiate_plaintext; memcpy (initiate_nonce, "CurveZMQINITIATE", 16); - memcpy (initiate_nonce + 16, &cn_nonce, 8); + memcpy (initiate_nonce + 16, &nonce, 8); rc = crypto_box (initiate_box, initiate_plaintext, - mlen, initiate_nonce, cn_server, cn_secret); + mlen, initiate_nonce, peer_trans_pub_key, our_trans_sec_key); zmq_assert (rc == 0); rc = msg_->init_size (113 + mlen - crypto_box_BOXZEROBYTES); @@ -353,14 +353,14 @@ int zmq::curve_client_t::produce_initiate (msg_t *msg_) memcpy (initiate, "\x08INITIATE", 9); // Cookie provided by the server in the WELCOME command - memcpy (initiate + 9, cn_cookie, 96); + memcpy (initiate + 9, cookie, 96); // Short nonce, prefixed by "CurveZMQINITIATE" - memcpy (initiate + 105, &cn_nonce, 8); + memcpy (initiate + 105, &nonce, 8); // Box [C + vouch + metadata](C'->S') memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES); - cn_nonce++; + nonce++; return 0; } @@ -392,7 +392,7 @@ int zmq::curve_client_t::process_ready (msg_t *msg_) memcpy (ready_nonce + 16, ready + 6, 8); int rc = crypto_box_open_afternm (ready_plaintext, ready_box, - clen, ready_nonce, cn_precom); + clen, ready_nonce, precomputed); if (rc != 0) { errno = EPROTO; diff --git a/src/curve_client.hpp b/src/curve_client.hpp index c1569d28..42cdda42 100644 --- a/src/curve_client.hpp +++ b/src/curve_client.hpp @@ -69,32 +69,32 @@ namespace zmq // Current FSM state state_t state; - // Our public key (C) - uint8_t public_key [crypto_box_PUBLICKEYBYTES]; + // Our permanent public key (C) + uint8_t our_perma_pub_key [crypto_box_PUBLICKEYBYTES]; - // Our secret key (c) - uint8_t secret_key [crypto_box_SECRETKEYBYTES]; + // Our permanent secret key (c) + uint8_t our_perma_sec_key [crypto_box_SECRETKEYBYTES]; - // Our short-term public key (C') - uint8_t cn_public [crypto_box_PUBLICKEYBYTES]; + // Our transient public key (C') + uint8_t our_trans_pub_key [crypto_box_PUBLICKEYBYTES]; - // Our short-term secret key (c') - uint8_t cn_secret [crypto_box_SECRETKEYBYTES]; + // Our transient secret key (c') + uint8_t our_trans_sec_key [crypto_box_SECRETKEYBYTES]; - // Server's public key (S) - uint8_t server_key [crypto_box_PUBLICKEYBYTES]; + // Peer's public key (S) + uint8_t peer_perma_pub_key [crypto_box_PUBLICKEYBYTES]; - // Server's short-term public key (S') - uint8_t cn_server [crypto_box_PUBLICKEYBYTES]; + // Server's transient public key (S') + uint8_t peer_trans_pub_key [crypto_box_PUBLICKEYBYTES]; // Cookie received from server - uint8_t cn_cookie [16 + 80]; + uint8_t cookie [16 + 80]; // Intermediary buffer used to seepd up boxing and unboxing. - uint8_t cn_precom [crypto_box_BEFORENMBYTES]; + uint8_t precomputed [crypto_box_BEFORENMBYTES]; // Nonce - uint64_t cn_nonce; + uint64_t nonce; int produce_hello (msg_t *msg_); int process_welcome (msg_t *msg_); diff --git a/src/curve_server.cpp b/src/curve_server.cpp index 74a09965..f0837c71 100644 --- a/src/curve_server.cpp +++ b/src/curve_server.cpp @@ -40,13 +40,13 @@ zmq::curve_server_t::curve_server_t (session_base_t *session_, peer_address (peer_address_), state (expect_hello), expecting_zap_reply (false), - cn_nonce (1) + nonce (1) { // Fetch our secret key from socket options - memcpy (secret_key, options_.curve_secret_key, crypto_box_SECRETKEYBYTES); + memcpy (our_perma_sec_key, options_.curve_our_perma_sec_key, crypto_box_SECRETKEYBYTES); - // Generate short-term key pair - const int rc = crypto_box_keypair (cn_public, cn_secret); + // Generate transient key pair + const int rc = crypto_box_keypair (our_trans_pub_key, our_trans_sec_key); zmq_assert (rc == 0); } @@ -114,7 +114,7 @@ int zmq::curve_server_t::encode (msg_t *msg_) uint8_t message_nonce [crypto_box_NONCEBYTES]; memcpy (message_nonce, "CurveZMQMESSAGES", 16); - memcpy (message_nonce + 16, &cn_nonce, 8); + memcpy (message_nonce + 16, &nonce, 8); uint8_t flags = 0; if (msg_->flags () & msg_t::more) @@ -132,7 +132,7 @@ int zmq::curve_server_t::encode (msg_t *msg_) alloc_assert (message_box); int rc = crypto_box_afternm (message_box, message_plaintext, - mlen, message_nonce, cn_precom); + mlen, message_nonce, precomputed); zmq_assert (rc == 0); rc = msg_->close (); @@ -144,14 +144,14 @@ int zmq::curve_server_t::encode (msg_t *msg_) uint8_t *message = static_cast (msg_->data ()); memcpy (message, "\x07MESSAGE", 8); - memcpy (message + 8, &cn_nonce, 8); + memcpy (message + 8, &nonce, 8); memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES); free (message_plaintext); free (message_box); - cn_nonce++; + nonce++; return 0; } @@ -188,7 +188,7 @@ int zmq::curve_server_t::decode (msg_t *msg_) message + 16, msg_->size () - 16); int rc = crypto_box_open_afternm (message_plaintext, message_box, - clen, message_nonce, cn_precom); + clen, message_nonce, precomputed); if (rc == 0) { rc = msg_->close (); zmq_assert (rc == 0); @@ -251,8 +251,8 @@ int zmq::curve_server_t::process_hello (msg_t *msg_) return -1; } - // Save client's short-term public key (C') - memcpy (cn_client, hello + 80, 32); + // Save client's transient public key (C') + memcpy (peer_trans_pub_key, hello + 80, 32); uint8_t hello_nonce [crypto_box_NONCEBYTES]; uint8_t hello_plaintext [crypto_box_ZEROBYTES + 64]; @@ -267,7 +267,7 @@ int zmq::curve_server_t::process_hello (msg_t *msg_) // Open Box [64 * %x0](C'->S) int rc = crypto_box_open (hello_plaintext, hello_box, sizeof hello_box, - hello_nonce, cn_client, secret_key); + hello_nonce, peer_trans_pub_key, our_perma_sec_key); if (rc != 0) { errno = EPROTO; return -1; @@ -290,9 +290,9 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_) // Generate cookie = Box [C' + s'](t) memset (cookie_plaintext, 0, crypto_secretbox_ZEROBYTES); memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES, - cn_client, 32); + peer_trans_pub_key, 32); memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, - cn_secret, 32); + our_trans_sec_key, 32); // Generate fresh cookie key randombytes (cookie_key, crypto_secretbox_KEYBYTES); @@ -314,7 +314,7 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_) // Create 144-byte Box [S' + cookie](S->C') memset (welcome_plaintext, 0, crypto_box_ZEROBYTES); - memcpy (welcome_plaintext + crypto_box_ZEROBYTES, cn_public, 32); + memcpy (welcome_plaintext + crypto_box_ZEROBYTES, our_trans_pub_key, 32); memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 32, cookie_nonce + 8, 16); memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 48, @@ -322,7 +322,7 @@ int zmq::curve_server_t::produce_welcome (msg_t *msg_) rc = crypto_box (welcome_ciphertext, welcome_plaintext, sizeof welcome_plaintext, - welcome_nonce, cn_client, secret_key); + welcome_nonce, peer_trans_pub_key, our_perma_sec_key); zmq_assert (rc == 0); rc = msg_->init_size (168); @@ -370,9 +370,9 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_) // Check cookie plain text is as expected [C' + s'] if (memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES, - cn_client, 32) + peer_trans_pub_key, 32) || memcmp (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, - cn_secret, 32)) { + our_trans_sec_key, 32)) { errno = EAGAIN; return -1; } @@ -392,7 +392,7 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_) memcpy (initiate_nonce + 16, initiate + 105, 8); rc = crypto_box_open (initiate_plaintext, initiate_box, - clen, initiate_nonce, cn_client, cn_secret); + clen, initiate_nonce, peer_trans_pub_key, our_trans_sec_key); if (rc != 0) { errno = EPROTO; return -1; @@ -415,20 +415,20 @@ int zmq::curve_server_t::process_initiate (msg_t *msg_) rc = crypto_box_open (vouch_plaintext, vouch_box, sizeof vouch_box, - vouch_nonce, client_key, secret_key); + vouch_nonce, client_key, our_perma_sec_key); if (rc != 0) { errno = EPROTO; return -1; } - // What we decrypted must be the client's short-term public key - if (memcmp (vouch_plaintext + crypto_box_ZEROBYTES, cn_client, 32)) { + // What we decrypted must be the client's transient public key + if (memcmp (vouch_plaintext + crypto_box_ZEROBYTES, peer_trans_pub_key, 32)) { errno = EPROTO; return -1; } // Precompute connection secret from client key - rc = crypto_box_beforenm (cn_precom, cn_client, cn_secret); + rc = crypto_box_beforenm (precomputed, peer_trans_pub_key, our_trans_sec_key); zmq_assert (rc == 0); // Use ZAP protocol (RFC 27) to authenticate the user. @@ -471,10 +471,10 @@ int zmq::curve_server_t::produce_ready (msg_t *msg_) const size_t mlen = ptr - ready_plaintext; memcpy (ready_nonce, "CurveZMQREADY---", 16); - memcpy (ready_nonce + 16, &cn_nonce, 8); + memcpy (ready_nonce + 16, &nonce, 8); int rc = crypto_box_afternm (ready_box, ready_plaintext, - mlen, ready_nonce, cn_precom); + mlen, ready_nonce, precomputed); zmq_assert (rc == 0); rc = msg_->init_size (14 + mlen - crypto_box_BOXZEROBYTES); @@ -484,12 +484,12 @@ int zmq::curve_server_t::produce_ready (msg_t *msg_) memcpy (ready, "\x05READY", 6); // Short nonce, prefixed by "CurveZMQREADY---" - memcpy (ready + 6, &cn_nonce, 8); + memcpy (ready + 6, &nonce, 8); // Box [metadata](S'->C') memcpy (ready + 14, ready_box + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES); - cn_nonce++; + nonce++; return 0; } diff --git a/src/curve_server.hpp b/src/curve_server.hpp index c165b541..71718366 100644 --- a/src/curve_server.hpp +++ b/src/curve_server.hpp @@ -83,25 +83,25 @@ namespace zmq // True iff we are awaiting reply from ZAP handler. bool expecting_zap_reply; - uint64_t cn_nonce; + uint64_t nonce; - // Our secret key (s) - uint8_t secret_key [crypto_box_SECRETKEYBYTES]; + // Our permanent secret key (s) + uint8_t our_perma_sec_key [crypto_box_SECRETKEYBYTES]; - // Our short-term public key (S') - uint8_t cn_public [crypto_box_PUBLICKEYBYTES]; + // Our transient public key (S') + uint8_t our_trans_pub_key [crypto_box_PUBLICKEYBYTES]; - // Our short-term secret key (s') - uint8_t cn_secret [crypto_box_SECRETKEYBYTES]; + // Our transient secret key (s') + uint8_t our_trans_sec_key [crypto_box_SECRETKEYBYTES]; - // Client's short-term public key (C') - uint8_t cn_client [crypto_box_PUBLICKEYBYTES]; + // Client's transient public key (C') + uint8_t peer_trans_pub_key [crypto_box_PUBLICKEYBYTES]; // Key used to produce cookie uint8_t cookie_key [crypto_secretbox_KEYBYTES]; // Intermediary buffer used to speed up boxing and unboxing. - uint8_t cn_precom [crypto_box_BEFORENMBYTES]; + uint8_t precomputed [crypto_box_BEFORENMBYTES]; int process_hello (msg_t *msg_); int produce_welcome (msg_t *msg_); diff --git a/src/options.cpp b/src/options.cpp index 84f36a7f..d5bba9ce 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -57,6 +57,32 @@ zmq::options_t::options_t () : { } +int zmq::options_t::setcurvekey (uint8_t* curve_key, const void *optval_, + size_t optvallen_) +{ + if (optvallen_ == CURVE_KEYSIZE) { + memcpy (curve_key, optval_, CURVE_KEYSIZE); + } + else + if (optvallen_ == CURVE_KEYSIZE_Z85) { + zmq_z85_decode (curve_key, (char *) optval_); + } + return 0; +} + +int zmq::options_t::getcurvekey (uint8_t* curve_key, void *optval_, + size_t *optvallen_) +{ + if (*optvallen_ == CURVE_KEYSIZE) { + memcpy (optval_, curve_key, CURVE_KEYSIZE); + } + else + if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) { + zmq_z85_encode ((char *) optval_, curve_key, CURVE_KEYSIZE); + } + return 0; +} + int zmq::options_t::setsockopt (int option_, const void *optval_, size_t optvallen_) { @@ -295,55 +321,27 @@ int zmq::options_t::setsockopt (int option_, const void *optval_, // If libsodium isn't installed, these options provoke EINVAL # ifdef HAVE_LIBSODIUM case ZMQ_CURVE_SERVER: - if (is_int && (value == 0 || value == 1)) { + if (is_int && (value == ZMQ_CLIENT || value == ZMQ_SERVER)) { as_server = value; - mechanism = value? ZMQ_CURVE: ZMQ_NULL; - return 0; - } - break; - - case ZMQ_CURVE_PUBLICKEY: - if (optvallen_ == CURVE_KEYSIZE) { - memcpy (curve_public_key, optval_, CURVE_KEYSIZE); - mechanism = ZMQ_CURVE; - return 0; - } - else - if (optvallen_ == CURVE_KEYSIZE_Z85) { - zmq_z85_decode (curve_public_key, (char *) optval_); mechanism = ZMQ_CURVE; return 0; } break; - case ZMQ_CURVE_SECRETKEY: - if (optvallen_ == CURVE_KEYSIZE) { - memcpy (curve_secret_key, optval_, CURVE_KEYSIZE); - mechanism = ZMQ_CURVE; - return 0; - } - else - if (optvallen_ == CURVE_KEYSIZE_Z85) { - zmq_z85_decode (curve_secret_key, (char *) optval_); - mechanism = ZMQ_CURVE; - return 0; - } + case ZMQ_CURVE_OUR_PERMA_PUB_KEY: + return setcurvekey (curve_our_perma_pub_key, optval_, optvallen_); break; - case ZMQ_CURVE_SERVERKEY: - if (optvallen_ == CURVE_KEYSIZE) { - memcpy (curve_server_key, optval_, CURVE_KEYSIZE); - as_server = 0; - mechanism = ZMQ_CURVE; - return 0; - } - else - if (optvallen_ == CURVE_KEYSIZE_Z85) { - zmq_z85_decode (curve_server_key, (char *) optval_); - as_server = 0; - mechanism = ZMQ_CURVE; - return 0; - } + case ZMQ_CURVE_OUR_PERMA_SEC_KEY: + return setcurvekey (curve_our_perma_sec_key, optval_, optvallen_); + break; + + case ZMQ_CURVE_PEER_PERMA_PUB_KEY: + return setcurvekey (curve_peer_perma_pub_key, optval_, optvallen_); + break; + + case ZMQ_CURVE_PEER_PERMA_SEC_KEY: + return setcurvekey (curve_peer_perma_sec_key, optval_, optvallen_); break; # endif @@ -579,45 +577,25 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_) # ifdef HAVE_LIBSODIUM case ZMQ_CURVE_SERVER: if (is_int) { - *value = as_server && mechanism == ZMQ_CURVE; + *value = as_server; return 0; } break; - case ZMQ_CURVE_PUBLICKEY: - if (*optvallen_ == CURVE_KEYSIZE) { - memcpy (optval_, curve_public_key, CURVE_KEYSIZE); - return 0; - } - else - if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) { - zmq_z85_encode ((char *) optval_, curve_public_key, CURVE_KEYSIZE); - return 0; - } + case ZMQ_CURVE_OUR_PERMA_PUB_KEY: + return getcurvekey (curve_our_perma_pub_key, optval_, optvallen_); break; - case ZMQ_CURVE_SECRETKEY: - if (*optvallen_ == CURVE_KEYSIZE) { - memcpy (optval_, curve_secret_key, CURVE_KEYSIZE); - return 0; - } - else - if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) { - zmq_z85_encode ((char *) optval_, curve_secret_key, CURVE_KEYSIZE); - return 0; - } + case ZMQ_CURVE_OUR_PERMA_SEC_KEY: + return getcurvekey (curve_our_perma_sec_key, optval_, optvallen_); break; - case ZMQ_CURVE_SERVERKEY: - if (*optvallen_ == CURVE_KEYSIZE) { - memcpy (optval_, curve_server_key, CURVE_KEYSIZE); - return 0; - } - else - if (*optvallen_ == CURVE_KEYSIZE_Z85 + 1) { - zmq_z85_encode ((char *) optval_, curve_server_key, CURVE_KEYSIZE); - return 0; - } + case ZMQ_CURVE_PEER_PERMA_PUB_KEY: + return getcurvekey (curve_peer_perma_pub_key, optval_, optvallen_); + break; + + case ZMQ_CURVE_PEER_PERMA_SEC_KEY: + return getcurvekey (curve_peer_perma_sec_key, optval_, optvallen_); break; # endif diff --git a/src/options.hpp b/src/options.hpp index 5154fab6..899d5d98 100644 --- a/src/options.hpp +++ b/src/options.hpp @@ -42,6 +42,9 @@ namespace zmq int setsockopt (int option_, const void *optval_, size_t optvallen_); int getsockopt (int option_, void *optval_, size_t *optvallen_); + int setcurvekey (uint8_t* curve_key, const void *optval_, size_t optvallen_); + int getcurvekey (uint8_t* curve_key, void *optval_, size_t *optvallen_); + // High-water marks for message pipes. int sndhwm; int rcvhwm; @@ -131,9 +134,10 @@ namespace zmq std::string plain_password; // Security credentials for CURVE mechanism - uint8_t curve_public_key [CURVE_KEYSIZE]; - uint8_t curve_secret_key [CURVE_KEYSIZE]; - uint8_t curve_server_key [CURVE_KEYSIZE]; + uint8_t curve_our_perma_pub_key [CURVE_KEYSIZE]; + uint8_t curve_our_perma_sec_key [CURVE_KEYSIZE]; + uint8_t curve_peer_perma_pub_key [CURVE_KEYSIZE]; + uint8_t curve_peer_perma_sec_key [CURVE_KEYSIZE]; // normally unused - for test and possible future extensions // ID of the socket. int socket_id; diff --git a/tests/test_security_curve.cpp b/tests/test_security_curve.cpp index e9214cb7..b8b16c4d 100644 --- a/tests/test_security_curve.cpp +++ b/tests/test_security_curve.cpp @@ -102,10 +102,10 @@ int main (void) // Server socket will accept connections void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); - int as_server = 1; + int as_server = ZMQ_SERVER; rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); - rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 40); + rc = zmq_setsockopt (server, ZMQ_CURVE_OUR_PERMA_SEC_KEY, server_secret, 40); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); @@ -115,11 +115,14 @@ int main (void) // Check CURVE security with valid credentials void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + as_server = ZMQ_CLIENT; + rc = zmq_setsockopt (client, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PEER_PERMA_PUB_KEY, server_public, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_PUB_KEY, client_public, 40); + assert (rc == 0); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_SEC_KEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -132,11 +135,11 @@ int main (void) char garbage_key [] = "0000111122223333444455556666777788889999"; client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PEER_PERMA_PUB_KEY, garbage_key, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_PUB_KEY, client_public, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_SEC_KEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -147,11 +150,11 @@ int main (void) // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PEER_PERMA_PUB_KEY, server_public, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_PUB_KEY, garbage_key, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_SEC_KEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -162,11 +165,11 @@ int main (void) // This will be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PEER_PERMA_PUB_KEY, server_public, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_PUB_KEY, client_public, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_SEC_KEY, garbage_key, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); @@ -180,11 +183,11 @@ int main (void) client = zmq_socket (ctx, ZMQ_DEALER); assert (client); - rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_PEER_PERMA_PUB_KEY, server_public, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_PUB_KEY, bogus_public, 40); assert (rc == 0); - rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 40); + rc = zmq_setsockopt (client, ZMQ_CURVE_OUR_PERMA_SEC_KEY, bogus_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0);