diff --git a/CMakeLists.txt b/CMakeLists.txt
index c3eadb21..9af932d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -484,6 +484,7 @@ set (cxx-sources
client.cpp
clock.cpp
ctx.cpp
+ curve_mechanism_base.cpp
curve_client.cpp
curve_server.cpp
dealer.cpp
@@ -504,6 +505,7 @@ set (cxx-sources
mailbox.cpp
mailbox_safe.cpp
mechanism.cpp
+ mechanism_base.cpp
metadata.cpp
msg.cpp
mtrie.cpp
diff --git a/Makefile.am b/Makefile.am
index 671640f3..bd971d49 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,6 +38,8 @@ src_libzmq_la_SOURCES = \
src/curve_client.cpp \
src/curve_client.hpp \
src/curve_client_tools.hpp \
+ src/curve_mechanism_base.cpp \
+ src/curve_mechanism_base.hpp \
src/curve_server.cpp \
src/curve_server.hpp \
src/dbuffer.hpp \
@@ -97,6 +99,8 @@ src_libzmq_la_SOURCES = \
src/mailbox_safe.hpp \
src/mechanism.cpp \
src/mechanism.hpp \
+ src/mechanism_base.cpp \
+ src/mechanism_base.hpp \
src/metadata.cpp \
src/metadata.hpp \
src/msg.cpp \
diff --git a/builds/gyp/project.gyp b/builds/gyp/project.gyp
index 73fa3bbb..a89366c0 100644
--- a/builds/gyp/project.gyp
+++ b/builds/gyp/project.gyp
@@ -80,6 +80,9 @@
'../../src/ctx.hpp',
'../../src/curve_client.cpp',
'../../src/curve_client.hpp',
+ '../../src/curve_client_tools.hpp',
+ '../../src/curve_mechanism_base.cpp',
+ '../../src/curve_mechanism_base.hpp',
'../../src/curve_server.cpp',
'../../src/curve_server.hpp',
'../../src/dbuffer.hpp',
@@ -136,6 +139,8 @@
'../../src/mailbox_safe.hpp',
'../../src/mechanism.cpp',
'../../src/mechanism.hpp ',
+ '../../src/mechanism_base.cpp',
+ '../../src/mechanism_base.hpp ',
'../../src/metadata.cpp',
'../../src/metadata.hpp',
'../../src/msg.cpp',
diff --git a/builds/msvc/vs2008/libzmq/libzmq.vcproj b/builds/msvc/vs2008/libzmq/libzmq.vcproj
index 2077bbce..18c5521e 100644
--- a/builds/msvc/vs2008/libzmq/libzmq.vcproj
+++ b/builds/msvc/vs2008/libzmq/libzmq.vcproj
@@ -121,6 +121,7 @@
+
@@ -173,6 +174,7 @@
+
diff --git a/builds/msvc/vs2010/libzmq/libzmq.vcxproj b/builds/msvc/vs2010/libzmq/libzmq.vcxproj
index 603dec3a..bc07be2b 100644
--- a/builds/msvc/vs2010/libzmq/libzmq.vcxproj
+++ b/builds/msvc/vs2010/libzmq/libzmq.vcxproj
@@ -180,6 +180,7 @@
+
@@ -205,6 +206,7 @@
+
@@ -266,6 +268,7 @@
+
diff --git a/builds/msvc/vs2012/libzmq/libzmq.vcxproj b/builds/msvc/vs2012/libzmq/libzmq.vcxproj
index c5c52f5c..cc0d84fd 100644
--- a/builds/msvc/vs2012/libzmq/libzmq.vcxproj
+++ b/builds/msvc/vs2012/libzmq/libzmq.vcxproj
@@ -1,4 +1,4 @@
-
+
{641C5F36-32EE-4323-B740-992B651CF9D6}
@@ -180,6 +180,7 @@
+
@@ -205,6 +206,7 @@
+
@@ -266,6 +268,7 @@
+
diff --git a/builds/msvc/vs2013/libzmq/libzmq.vcxproj b/builds/msvc/vs2013/libzmq/libzmq.vcxproj
index 6957c364..3d42eaa6 100644
--- a/builds/msvc/vs2013/libzmq/libzmq.vcxproj
+++ b/builds/msvc/vs2013/libzmq/libzmq.vcxproj
@@ -1,4 +1,4 @@
-
+
{641C5F36-32EE-4323-B740-992B651CF9D6}
@@ -180,6 +180,7 @@
+
@@ -205,6 +206,7 @@
+
@@ -266,6 +268,7 @@
+
diff --git a/builds/msvc/vs2015/libzmq/libzmq.vcxproj b/builds/msvc/vs2015/libzmq/libzmq.vcxproj
index 14070e0a..1b56266d 100644
--- a/builds/msvc/vs2015/libzmq/libzmq.vcxproj
+++ b/builds/msvc/vs2015/libzmq/libzmq.vcxproj
@@ -1,4 +1,4 @@
-
+
{641C5F36-32EE-4323-B740-992B651CF9D6}
@@ -180,6 +180,7 @@
+
@@ -205,6 +206,7 @@
+
@@ -266,6 +268,7 @@
+
diff --git a/builds/msvc/vs2015_xp/libzmq.vcxproj b/builds/msvc/vs2015_xp/libzmq.vcxproj
index 36ee6431..69623b5a 100644
--- a/builds/msvc/vs2015_xp/libzmq.vcxproj
+++ b/builds/msvc/vs2015_xp/libzmq.vcxproj
@@ -1,4 +1,4 @@
-
+
@@ -152,6 +152,7 @@
+
@@ -177,6 +178,7 @@
+
@@ -242,6 +244,7 @@
+
diff --git a/builds/msvc/vs2017/libzmq/libzmq.vcxproj b/builds/msvc/vs2017/libzmq/libzmq.vcxproj
index 23491d12..8f3eee8d 100644
--- a/builds/msvc/vs2017/libzmq/libzmq.vcxproj
+++ b/builds/msvc/vs2017/libzmq/libzmq.vcxproj
@@ -1,4 +1,4 @@
-
+
{641C5F36-32EE-4323-B740-992B651CF9D6}
@@ -180,6 +180,7 @@
+
@@ -205,6 +206,7 @@
+
@@ -266,6 +268,7 @@
+
diff --git a/src/curve_client.cpp b/src/curve_client.cpp
index 49e7c471..e1012e7c 100644
--- a/src/curve_client.cpp
+++ b/src/curve_client.cpp
@@ -42,12 +42,12 @@
zmq::curve_client_t::curve_client_t (session_base_t *session_,
const options_t &options_) :
mechanism_base_t (session_, options_),
+ curve_mechanism_base_t (
+ session_, options_, "CurveZMQMESSAGEC", "CurveZMQMESSAGES"),
state (send_hello),
tools (options_.curve_public_key,
options_.curve_secret_key,
- options_.curve_server_key),
- cn_nonce (1),
- cn_peer_nonce (1)
+ options_.curve_server_key)
{
}
@@ -113,134 +113,13 @@ int zmq::curve_client_t::process_handshake_command (msg_t *msg_)
int zmq::curve_client_t::encode (msg_t *msg_)
{
zmq_assert (state == connected);
-
- uint8_t flags = 0;
- if (msg_->flags () & msg_t::more)
- flags |= 0x01;
- if (msg_->flags () & msg_t::command)
- flags |= 0x02;
-
- uint8_t message_nonce [crypto_box_NONCEBYTES];
- memcpy (message_nonce, "CurveZMQMESSAGEC", 16);
- put_uint64 (message_nonce + 16, cn_nonce);
-
- const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();
-
- uint8_t *message_plaintext = static_cast (malloc (mlen));
- alloc_assert (message_plaintext);
-
- memset (message_plaintext, 0, crypto_box_ZEROBYTES);
- message_plaintext [crypto_box_ZEROBYTES] = flags;
- memcpy (message_plaintext + crypto_box_ZEROBYTES + 1,
- msg_->data (), msg_->size ());
-
- uint8_t *message_box = static_cast (malloc (mlen));
- alloc_assert (message_box);
-
- int rc = crypto_box_afternm (message_box, message_plaintext, mlen,
- message_nonce, tools.cn_precom);
- zmq_assert (rc == 0);
-
- rc = msg_->close ();
- zmq_assert (rc == 0);
-
- rc = msg_->init_size (16 + mlen - crypto_box_BOXZEROBYTES);
- zmq_assert (rc == 0);
-
- uint8_t *message = static_cast (msg_->data ());
-
- memcpy (message, "\x07MESSAGE", 8);
- memcpy (message + 8, message_nonce + 16, 8);
- memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
- mlen - crypto_box_BOXZEROBYTES);
-
- free (message_plaintext);
- free (message_box);
-
- cn_nonce++;
-
- return 0;
+ return curve_mechanism_base_t::encode (msg_);
}
int zmq::curve_client_t::decode (msg_t *msg_)
{
zmq_assert (state == connected);
- int rc = check_basic_command_structure (msg_);
- if (rc == -1)
- return rc;
-
- const uint8_t *message = static_cast (msg_->data ());
- if (msg_->size() < 8 || memcmp (message, "\x07MESSAGE", 8)) {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (),
- ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
- errno = EPROTO;
- return -1;
- }
-
- if (msg_->size () < 33) {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (),
- ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
- errno = EPROTO;
- return -1;
- }
-
- uint8_t message_nonce [crypto_box_NONCEBYTES];
- memcpy (message_nonce, "CurveZMQMESSAGES", 16);
- memcpy (message_nonce + 16, message + 8, 8);
- uint64_t nonce = get_uint64(message + 8);
- if (nonce <= cn_peer_nonce) {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (),
- ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE);
- errno = EPROTO;
- return -1;
- }
- cn_peer_nonce = nonce;
-
- const size_t clen = crypto_box_BOXZEROBYTES + (msg_->size () - 16);
-
- uint8_t *message_plaintext = static_cast (malloc (clen));
- alloc_assert (message_plaintext);
-
- uint8_t *message_box = static_cast (malloc (clen));
- alloc_assert (message_box);
-
- memset (message_box, 0, crypto_box_BOXZEROBYTES);
- memcpy (message_box + crypto_box_BOXZEROBYTES,
- message + 16, msg_->size () - 16);
-
- rc = crypto_box_open_afternm (message_plaintext, message_box, clen,
- message_nonce, tools.cn_precom);
- if (rc == 0) {
- rc = msg_->close ();
- zmq_assert (rc == 0);
-
- rc = msg_->init_size (clen - 1 - crypto_box_ZEROBYTES);
- zmq_assert (rc == 0);
-
- const uint8_t flags = message_plaintext [crypto_box_ZEROBYTES];
- if (flags & 0x01)
- msg_->set_flags (msg_t::more);
- if (flags & 0x02)
- msg_->set_flags (msg_t::command);
-
- memcpy (msg_->data (),
- message_plaintext + crypto_box_ZEROBYTES + 1,
- msg_->size ());
- }
- else {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (),
- ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
- errno = EPROTO;
- }
-
- free (message_plaintext);
- free (message_box);
-
- return rc;
+ return curve_mechanism_base_t::decode (msg_);
}
zmq::mechanism_t::status_t zmq::curve_client_t::status () const
@@ -281,7 +160,7 @@ int zmq::curve_client_t::produce_hello (msg_t *msg_)
int zmq::curve_client_t::process_welcome (const uint8_t *msg_data,
size_t msg_size)
{
- int rc = tools.process_welcome (msg_data, msg_size);
+ int rc = tools.process_welcome (msg_data, msg_size, cn_precom);
if (rc == -1) {
session->get_socket ()->event_handshake_failed_protocol (
@@ -358,7 +237,7 @@ int zmq::curve_client_t::process_ready (
cn_peer_nonce = get_uint64(msg_data + 6);
int rc = crypto_box_open_afternm (ready_plaintext, ready_box,
- clen, ready_nonce, tools.cn_precom);
+ clen, ready_nonce, cn_precom);
free (ready_box);
if (rc != 0) {
diff --git a/src/curve_client.hpp b/src/curve_client.hpp
index f5be67e7..7693ac64 100644
--- a/src/curve_client.hpp
+++ b/src/curve_client.hpp
@@ -32,7 +32,7 @@
#ifdef ZMQ_HAVE_CURVE
-#include "mechanism.hpp"
+#include "curve_mechanism_base.hpp"
#include "options.hpp"
#include "curve_client_tools.hpp"
@@ -42,7 +42,7 @@ namespace zmq
class msg_t;
class session_base_t;
- class curve_client_t : public mechanism_base_t
+ class curve_client_t : public curve_mechanism_base_t
{
public:
@@ -72,11 +72,7 @@ namespace zmq
// CURVE protocol tools
curve_client_tools_t tools;
-
- // Nonce
- uint64_t cn_nonce;
- uint64_t cn_peer_nonce;
-
+
int produce_hello (msg_t *msg_);
int process_welcome (const uint8_t *cmd_data, size_t data_size);
int produce_initiate (msg_t *msg_);
diff --git a/src/curve_client_tools.hpp b/src/curve_client_tools.hpp
index 7ce35270..cb162115 100644
--- a/src/curve_client_tools.hpp
+++ b/src/curve_client_tools.hpp
@@ -251,7 +251,9 @@ struct curve_client_tools_t
return produce_hello (data, server_key, cn_nonce, cn_public, cn_secret);
}
- int process_welcome (const uint8_t *msg_data, size_t msg_size)
+ int process_welcome (const uint8_t *msg_data,
+ size_t msg_size,
+ uint8_t *cn_precom)
{
return process_welcome (msg_data, msg_size, server_key, cn_secret,
cn_server, cn_cookie, cn_precom);
@@ -289,10 +291,6 @@ struct curve_client_tools_t
// Cookie received from server
uint8_t cn_cookie[16 + 80];
- // Intermediary buffer used to speed up boxing and unboxing.
- uint8_t cn_precom[crypto_box_BEFORENMBYTES];
-
-
private:
template
static bool is_handshake_command (const uint8_t *msg_data,
diff --git a/src/curve_mechanism_base.cpp b/src/curve_mechanism_base.cpp
new file mode 100644
index 00000000..b61edd2e
--- /dev/null
+++ b/src/curve_mechanism_base.cpp
@@ -0,0 +1,181 @@
+/*
+ Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
+
+ This file is part of libzmq, the ZeroMQ core engine in C++.
+
+ libzmq is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ As a special exception, the Contributors give you permission to link
+ this library with independent modules to produce an executable,
+ regardless of the license terms of these independent modules, and to
+ copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the
+ terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library.
+ If you modify this library, you must extend this exception to your
+ version of the library.
+
+ libzmq is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+
+#include "precompiled.hpp"
+#include "curve_mechanism_base.hpp"
+#include "msg.hpp"
+#include "wire.hpp"
+#include "session_base.hpp"
+
+#ifdef ZMQ_HAVE_CURVE
+
+zmq::curve_mechanism_base_t::curve_mechanism_base_t (
+ session_base_t *session_,
+ const options_t &options_,
+ const char *encode_nonce_prefix_,
+ const char *decode_nonce_prefix_) :
+ mechanism_base_t (session_, options_),
+ encode_nonce_prefix (encode_nonce_prefix_),
+ decode_nonce_prefix (decode_nonce_prefix_),
+ cn_nonce (1),
+ cn_peer_nonce (1)
+{
+}
+
+int zmq::curve_mechanism_base_t::encode (msg_t *msg_)
+{
+ const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();
+
+ uint8_t message_nonce [crypto_box_NONCEBYTES];
+ memcpy (message_nonce, encode_nonce_prefix, 16);
+ put_uint64 (message_nonce + 16, cn_nonce);
+
+ uint8_t flags = 0;
+ if (msg_->flags () & msg_t::more)
+ flags |= 0x01;
+ if (msg_->flags () & msg_t::command)
+ flags |= 0x02;
+
+ uint8_t *message_plaintext = static_cast (malloc (mlen));
+ alloc_assert (message_plaintext);
+
+ memset (message_plaintext, 0, crypto_box_ZEROBYTES);
+ message_plaintext [crypto_box_ZEROBYTES] = flags;
+ memcpy (message_plaintext + crypto_box_ZEROBYTES + 1,
+ msg_->data (), msg_->size ());
+
+ uint8_t *message_box = static_cast (malloc (mlen));
+ alloc_assert (message_box);
+
+ int rc = crypto_box_afternm (message_box, message_plaintext,
+ mlen, message_nonce, cn_precom);
+ zmq_assert (rc == 0);
+
+ rc = msg_->close ();
+ zmq_assert (rc == 0);
+
+ rc = msg_->init_size (16 + mlen - crypto_box_BOXZEROBYTES);
+ zmq_assert (rc == 0);
+
+ uint8_t *message = static_cast (msg_->data ());
+
+ memcpy (message, "\x07MESSAGE", 8);
+ memcpy (message + 8, message_nonce + 16, 8);
+ memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
+ mlen - crypto_box_BOXZEROBYTES);
+
+ free (message_plaintext);
+ free (message_box);
+
+ cn_nonce++;
+
+ return 0;
+}
+
+int zmq::curve_mechanism_base_t::decode (msg_t *msg_)
+{
+ int rc = check_basic_command_structure (msg_);
+ if (rc == -1)
+ return -1;
+
+ const size_t size = msg_->size ();
+ const uint8_t *message = static_cast (msg_->data ());
+
+ if (size < 8 || memcmp (message, "\x07MESSAGE", 8)) {
+ session->get_socket ()->event_handshake_failed_protocol (
+ session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
+ errno = EPROTO;
+ return -1;
+ }
+
+ if (size < 33) {
+ session->get_socket ()->event_handshake_failed_protocol (
+ session->get_endpoint (),
+ ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
+ errno = EPROTO;
+ return -1;
+ }
+
+ uint8_t message_nonce [crypto_box_NONCEBYTES];
+ memcpy (message_nonce, decode_nonce_prefix, 16);
+ memcpy (message_nonce + 16, message + 8, 8);
+ uint64_t nonce = get_uint64(message + 8);
+ if (nonce <= cn_peer_nonce) {
+ session->get_socket ()->event_handshake_failed_protocol (
+ session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE);
+ errno = EPROTO;
+ return -1;
+ }
+ cn_peer_nonce = nonce;
+
+ const size_t clen = crypto_box_BOXZEROBYTES + msg_->size () - 16;
+
+ uint8_t *message_plaintext = static_cast (malloc (clen));
+ alloc_assert (message_plaintext);
+
+ uint8_t *message_box = static_cast (malloc (clen));
+ alloc_assert (message_box);
+
+ memset (message_box, 0, crypto_box_BOXZEROBYTES);
+ memcpy (message_box + crypto_box_BOXZEROBYTES,
+ message + 16, msg_->size () - 16);
+
+ rc = crypto_box_open_afternm (message_plaintext, message_box, clen,
+ message_nonce, cn_precom);
+ if (rc == 0) {
+ rc = msg_->close ();
+ zmq_assert (rc == 0);
+
+ rc = msg_->init_size (clen - 1 - crypto_box_ZEROBYTES);
+ zmq_assert (rc == 0);
+
+ const uint8_t flags = message_plaintext [crypto_box_ZEROBYTES];
+ if (flags & 0x01)
+ msg_->set_flags (msg_t::more);
+ if (flags & 0x02)
+ msg_->set_flags (msg_t::command);
+
+ memcpy (msg_->data (),
+ message_plaintext + crypto_box_ZEROBYTES + 1,
+ msg_->size ());
+ }
+ else {
+ // CURVE I : connection key used for MESSAGE is wrong
+ session->get_socket ()->event_handshake_failed_protocol (
+ session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
+ errno = EPROTO;
+ }
+ free (message_plaintext);
+ free (message_box);
+
+ return rc;
+}
+
+#endif
diff --git a/src/curve_mechanism_base.hpp b/src/curve_mechanism_base.hpp
new file mode 100644
index 00000000..98cfd03d
--- /dev/null
+++ b/src/curve_mechanism_base.hpp
@@ -0,0 +1,79 @@
+/*
+ Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
+
+ This file is part of libzmq, the ZeroMQ core engine in C++.
+
+ libzmq is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ As a special exception, the Contributors give you permission to link
+ this library with independent modules to produce an executable,
+ regardless of the license terms of these independent modules, and to
+ copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the
+ terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library.
+ If you modify this library, you must extend this exception to your
+ version of the library.
+
+ libzmq is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef __ZMQ_CURVE_MECHANISM_BASE_HPP_INCLUDED__
+#define __ZMQ_CURVE_MECHANISM_BASE_HPP_INCLUDED__
+
+#ifdef ZMQ_HAVE_CURVE
+
+#if defined(ZMQ_USE_TWEETNACL)
+#include "tweetnacl.h"
+#elif defined(ZMQ_USE_LIBSODIUM)
+#include "sodium.h"
+#endif
+
+#if crypto_box_NONCEBYTES != 24 || crypto_box_PUBLICKEYBYTES != 32 \
+ || crypto_box_SECRETKEYBYTES != 32 || crypto_box_ZEROBYTES != 32 \
+ || crypto_box_BOXZEROBYTES != 16 || crypto_secretbox_NONCEBYTES != 24 \
+ || crypto_secretbox_ZEROBYTES != 32 || crypto_secretbox_BOXZEROBYTES != 16
+#error "CURVE library not built properly"
+#endif
+
+#include "mechanism_base.hpp"
+#include "options.hpp"
+
+namespace zmq
+{
+class curve_mechanism_base_t : public virtual mechanism_base_t
+{
+ public:
+ curve_mechanism_base_t (session_base_t *session_,
+ const options_t &options_,
+ const char *encode_nonce_prefix_,
+ const char *decode_nonce_prefix_);
+
+ // mechanism implementation
+ virtual int encode (msg_t *msg_);
+ virtual int decode (msg_t *msg_);
+
+ protected:
+ const char *encode_nonce_prefix;
+ const char *decode_nonce_prefix;
+
+ uint64_t cn_nonce;
+ uint64_t cn_peer_nonce;
+
+ // Intermediary buffer used to speed up boxing and unboxing.
+ uint8_t cn_precom [crypto_box_BEFORENMBYTES];
+};
+}
+
+#endif
+
+#endif
diff --git a/src/curve_server.cpp b/src/curve_server.cpp
index aa9f5425..bbcec99b 100644
--- a/src/curve_server.cpp
+++ b/src/curve_server.cpp
@@ -44,8 +44,8 @@ zmq::curve_server_t::curve_server_t (session_base_t *session_,
mechanism_base_t (session_, options_),
zap_client_common_handshake_t (
session_, peer_address_, options_, sending_ready),
- cn_nonce (1),
- cn_peer_nonce (1)
+ curve_mechanism_base_t (
+ session_, options_, "CurveZMQMESSAGES", "CurveZMQMESSAGEC")
{
int rc;
// Fetch our secret key from socket options
@@ -125,134 +125,13 @@ int zmq::curve_server_t::process_handshake_command (msg_t *msg_)
int zmq::curve_server_t::encode (msg_t *msg_)
{
zmq_assert (state == ready);
-
- const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();
-
- uint8_t message_nonce [crypto_box_NONCEBYTES];
- memcpy (message_nonce, "CurveZMQMESSAGES", 16);
- put_uint64 (message_nonce + 16, cn_nonce);
-
- uint8_t flags = 0;
- if (msg_->flags () & msg_t::more)
- flags |= 0x01;
- if (msg_->flags () & msg_t::command)
- flags |= 0x02;
-
- uint8_t *message_plaintext = static_cast (malloc (mlen));
- alloc_assert (message_plaintext);
-
- memset (message_plaintext, 0, crypto_box_ZEROBYTES);
- message_plaintext [crypto_box_ZEROBYTES] = flags;
- memcpy (message_plaintext + crypto_box_ZEROBYTES + 1,
- msg_->data (), msg_->size ());
-
- uint8_t *message_box = static_cast (malloc (mlen));
- alloc_assert (message_box);
-
- int rc = crypto_box_afternm (message_box, message_plaintext,
- mlen, message_nonce, cn_precom);
- zmq_assert (rc == 0);
-
- rc = msg_->close ();
- zmq_assert (rc == 0);
-
- rc = msg_->init_size (16 + mlen - crypto_box_BOXZEROBYTES);
- zmq_assert (rc == 0);
-
- uint8_t *message = static_cast (msg_->data ());
-
- memcpy (message, "\x07MESSAGE", 8);
- memcpy (message + 8, message_nonce + 16, 8);
- memcpy (message + 16, message_box + crypto_box_BOXZEROBYTES,
- mlen - crypto_box_BOXZEROBYTES);
-
- free (message_plaintext);
- free (message_box);
-
- cn_nonce++;
-
- return 0;
+ return curve_mechanism_base_t::encode (msg_);
}
int zmq::curve_server_t::decode (msg_t *msg_)
{
zmq_assert (state == ready);
-
- int rc = check_basic_command_structure (msg_);
- if (rc == -1)
- return -1;
-
- const size_t size = msg_->size ();
- const uint8_t *message = static_cast (msg_->data ());
-
- if (size < 8 || memcmp (message, "\x07MESSAGE", 8)) {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
- errno = EPROTO;
- return -1;
- }
-
- if (size < 33) {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (),
- ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_MESSAGE);
- errno = EPROTO;
- return -1;
- }
-
- uint8_t message_nonce [crypto_box_NONCEBYTES];
- memcpy (message_nonce, "CurveZMQMESSAGEC", 16);
- memcpy (message_nonce + 16, message + 8, 8);
- uint64_t nonce = get_uint64(message + 8);
- if (nonce <= cn_peer_nonce) {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_INVALID_SEQUENCE);
- errno = EPROTO;
- return -1;
- }
- cn_peer_nonce = nonce;
-
- const size_t clen = crypto_box_BOXZEROBYTES + msg_->size () - 16;
-
- uint8_t *message_plaintext = static_cast (malloc (clen));
- alloc_assert (message_plaintext);
-
- uint8_t *message_box = static_cast (malloc (clen));
- alloc_assert (message_box);
-
- memset (message_box, 0, crypto_box_BOXZEROBYTES);
- memcpy (message_box + crypto_box_BOXZEROBYTES,
- message + 16, msg_->size () - 16);
-
- rc = crypto_box_open_afternm (message_plaintext, message_box, clen,
- message_nonce, cn_precom);
- if (rc == 0) {
- rc = msg_->close ();
- zmq_assert (rc == 0);
-
- rc = msg_->init_size (clen - 1 - crypto_box_ZEROBYTES);
- zmq_assert (rc == 0);
-
- const uint8_t flags = message_plaintext [crypto_box_ZEROBYTES];
- if (flags & 0x01)
- msg_->set_flags (msg_t::more);
- if (flags & 0x02)
- msg_->set_flags (msg_t::command);
-
- memcpy (msg_->data (),
- message_plaintext + crypto_box_ZEROBYTES + 1,
- msg_->size ());
- }
- else {
- // CURVE I : connection key used for MESSAGE is wrong
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (), ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
- errno = EPROTO;
- }
- free (message_plaintext);
- free (message_box);
-
- return rc;
+ return curve_mechanism_base_t::decode (msg_);
}
int zmq::curve_server_t::process_hello (msg_t *msg_)
diff --git a/src/curve_server.hpp b/src/curve_server.hpp
index 44562716..30efda5d 100644
--- a/src/curve_server.hpp
+++ b/src/curve_server.hpp
@@ -32,34 +32,18 @@
#ifdef ZMQ_HAVE_CURVE
-#if defined (ZMQ_USE_TWEETNACL)
-# include "tweetnacl.h"
-#elif defined (ZMQ_USE_LIBSODIUM)
-# include "sodium.h"
-#endif
-
-#if crypto_box_NONCEBYTES != 24 \
-|| crypto_box_PUBLICKEYBYTES != 32 \
-|| crypto_box_SECRETKEYBYTES != 32 \
-|| crypto_box_ZEROBYTES != 32 \
-|| crypto_box_BOXZEROBYTES != 16 \
-|| crypto_secretbox_NONCEBYTES != 24 \
-|| crypto_secretbox_ZEROBYTES != 32 \
-|| crypto_secretbox_BOXZEROBYTES != 16
-# error "CURVE library not built properly"
-#endif
-
-#include "mechanism.hpp"
+#include "curve_mechanism_base.hpp"
#include "options.hpp"
#include "zap_client.hpp"
namespace zmq
{
-
- class msg_t;
- class session_base_t;
-
- class curve_server_t : public zap_client_common_handshake_t
+#ifdef _MSC_VER
+#pragma warning (push)
+#pragma warning (disable: 4250)
+#endif
+ class curve_server_t : public zap_client_common_handshake_t,
+ public curve_mechanism_base_t
{
public:
@@ -76,9 +60,6 @@ namespace zmq
private:
- uint64_t cn_nonce;
- uint64_t cn_peer_nonce;
-
// Our secret key (s)
uint8_t secret_key [crypto_box_SECRETKEYBYTES];
@@ -94,9 +75,6 @@ namespace zmq
// 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];
-
int process_hello (msg_t *msg_);
int produce_welcome (msg_t *msg_);
int process_initiate (msg_t *msg_);
@@ -105,6 +83,9 @@ namespace zmq
void send_zap_request (const uint8_t *key);
};
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
}
diff --git a/src/mechanism.cpp b/src/mechanism.cpp
index 39117359..54c36bc3 100644
--- a/src/mechanism.cpp
+++ b/src/mechanism.cpp
@@ -282,24 +282,3 @@ bool zmq::mechanism_t::check_socket_type (const std::string& type_) const
}
return false;
}
-
-zmq::mechanism_base_t::mechanism_base_t (session_base_t *const session_,
- const options_t &options_) :
- mechanism_t (options_),
- session (session_)
-{
-
-}
-
-int zmq::mechanism_base_t::check_basic_command_structure (msg_t *msg_)
-{
- if (msg_->size () <= 1 || msg_->size () <= ((uint8_t *) msg_->data ())[0]) {
- session->get_socket ()->event_handshake_failed_protocol (
- session->get_endpoint (),
- ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED);
- errno = EPROTO;
- return -1;
- }
- return 0;
-}
-
diff --git a/src/mechanism.hpp b/src/mechanism.hpp
index e07ce567..f8c05b66 100644
--- a/src/mechanism.hpp
+++ b/src/mechanism.hpp
@@ -147,16 +147,6 @@ namespace zmq
bool check_socket_type (const std::string& type_) const;
};
- class mechanism_base_t : public mechanism_t
- {
- protected:
- mechanism_base_t (session_base_t *const session_,
- const options_t &options_);
-
- session_base_t *const session;
-
- int check_basic_command_structure (msg_t *msg_);
- };
- }
+}
#endif
diff --git a/src/mechanism_base.cpp b/src/mechanism_base.cpp
new file mode 100644
index 00000000..e255cb01
--- /dev/null
+++ b/src/mechanism_base.cpp
@@ -0,0 +1,54 @@
+/*
+ Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
+
+ This file is part of libzmq, the ZeroMQ core engine in C++.
+
+ libzmq is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ As a special exception, the Contributors give you permission to link
+ this library with independent modules to produce an executable,
+ regardless of the license terms of these independent modules, and to
+ copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the
+ terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library.
+ If you modify this library, you must extend this exception to your
+ version of the library.
+
+ libzmq is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#include "precompiled.hpp"
+
+#include "mechanism_base.hpp"
+#include "session_base.hpp"
+
+zmq::mechanism_base_t::mechanism_base_t (session_base_t *const session_,
+ const options_t &options_) :
+ mechanism_t (options_),
+ session (session_)
+{
+
+}
+
+int zmq::mechanism_base_t::check_basic_command_structure (msg_t *msg_)
+{
+ if (msg_->size () <= 1 || msg_->size () <= ((uint8_t *) msg_->data ())[0]) {
+ session->get_socket ()->event_handshake_failed_protocol (
+ session->get_endpoint (),
+ ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_UNSPECIFIED);
+ errno = EPROTO;
+ return -1;
+ }
+ return 0;
+}
+
diff --git a/src/mechanism_base.hpp b/src/mechanism_base.hpp
new file mode 100644
index 00000000..e98a7f7e
--- /dev/null
+++ b/src/mechanism_base.hpp
@@ -0,0 +1,49 @@
+/*
+ Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
+
+ This file is part of libzmq, the ZeroMQ core engine in C++.
+
+ libzmq is free software; you can redistribute it and/or modify it under
+ the terms of the GNU Lesser General Public License (LGPL) as published
+ by the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ As a special exception, the Contributors give you permission to link
+ this library with independent modules to produce an executable,
+ regardless of the license terms of these independent modules, and to
+ copy and distribute the resulting executable under terms of your choice,
+ provided that you also meet, for each linked independent module, the
+ terms and conditions of the license of that module. An independent
+ module is a module which is not derived from or based on this library.
+ If you modify this library, you must extend this exception to your
+ version of the library.
+
+ libzmq is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef __ZMQ_MECHANISM_BASE_HPP_INCLUDED__
+#define __ZMQ_MECHANISM_BASE_HPP_INCLUDED__
+
+#include "mechanism.hpp"
+
+namespace zmq
+{
+class mechanism_base_t : public mechanism_t
+{
+ protected:
+ mechanism_base_t (session_base_t *const session_,
+ const options_t &options_);
+
+ session_base_t *const session;
+
+ int check_basic_command_structure (msg_t *msg_);
+};
+}
+
+#endif
diff --git a/src/plain_client.hpp b/src/plain_client.hpp
index 6e5b5586..76789e09 100644
--- a/src/plain_client.hpp
+++ b/src/plain_client.hpp
@@ -30,7 +30,7 @@
#ifndef __ZMQ_PLAIN_CLIENT_HPP_INCLUDED__
#define __ZMQ_PLAIN_CLIENT_HPP_INCLUDED__
-#include "mechanism.hpp"
+#include "mechanism_base.hpp"
#include "options.hpp"
namespace zmq
diff --git a/src/zap_client.hpp b/src/zap_client.hpp
index c2652bb8..557cab60 100644
--- a/src/zap_client.hpp
+++ b/src/zap_client.hpp
@@ -30,7 +30,7 @@
#ifndef __ZMQ_ZAP_CLIENT_HPP_INCLUDED__
#define __ZMQ_ZAP_CLIENT_HPP_INCLUDED__
-#include "mechanism.hpp"
+#include "mechanism_base.hpp"
namespace zmq
{
diff --git a/tests/test_security_curve.cpp b/tests/test_security_curve.cpp
index 04ed9bfd..89bc3f05 100644
--- a/tests/test_security_curve.cpp
+++ b/tests/test_security_curve.cpp
@@ -491,7 +491,8 @@ int connect_exchange_greeting_and_hello_welcome (
uint8_t welcome[welcome_length + 2];
recv_all (s, welcome, welcome_length + 2);
- int res = tools.process_welcome (welcome + 2, welcome_length);
+ uint8_t cn_precom [crypto_box_BEFORENMBYTES];
+ int res = tools.process_welcome (welcome + 2, welcome_length, cn_precom);
assert (res == 0);
#ifdef ZMQ_BUILD_DRAFT_API