mirror of
https://github.com/zeromq/libzmq.git
synced 2025-01-31 22:45:38 +01:00
Implement CurveZMQ message encryption and authentication
This commit is contained in:
parent
c9638fceb4
commit
e4a211870c
@ -101,6 +101,113 @@ int zmq::curve_client_t::process_handshake_message (msg_t *msg_)
|
||||
return rc;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, "CurveZMQMESSAGEC", 16);
|
||||
memcpy (message_nonce + 16, &cn_nonce, 8);
|
||||
|
||||
const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();
|
||||
|
||||
uint8_t *message_plaintext = static_cast <uint8_t *> (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 <uint8_t *> (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 <uint8_t *> (msg_->data ());
|
||||
|
||||
memcpy (message, "MESSAGE ", 8);
|
||||
memcpy (message + 8, &cn_nonce, 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_client_t::decode (msg_t *msg_)
|
||||
{
|
||||
zmq_assert (state == connected);
|
||||
|
||||
if (msg_->size () < 33) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (message, "MESSAGE ", 8)) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, "CurveZMQMESSAGES", 16);
|
||||
memcpy (message_nonce + 16, message + 8, 8);
|
||||
|
||||
const size_t clen = crypto_box_BOXZEROBYTES + (msg_->size () - 16);
|
||||
|
||||
uint8_t *message_plaintext = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_plaintext);
|
||||
|
||||
uint8_t *message_box = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_box);
|
||||
|
||||
memset (message_box, 0, crypto_box_BOXZEROBYTES);
|
||||
memcpy (message_box + crypto_box_BOXZEROBYTES,
|
||||
message + 16, msg_->size () - 16);
|
||||
|
||||
int 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);
|
||||
|
||||
memcpy (msg_->data (),
|
||||
message_plaintext + crypto_box_ZEROBYTES + 1,
|
||||
msg_->size ());
|
||||
}
|
||||
else
|
||||
errno = EPROTO;
|
||||
|
||||
free (message_plaintext);
|
||||
free (message_box);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool zmq::curve_client_t::is_handshake_complete () const
|
||||
{
|
||||
return state == connected;
|
||||
|
@ -52,6 +52,8 @@ namespace zmq
|
||||
// mechanism implementation
|
||||
virtual int next_handshake_message (msg_t *msg_);
|
||||
virtual int process_handshake_message (msg_t *msg_);
|
||||
virtual int encode (msg_t *msg_);
|
||||
virtual int decode (msg_t *msg_);
|
||||
virtual bool is_handshake_complete () const;
|
||||
|
||||
private:
|
||||
|
@ -111,6 +111,113 @@ int zmq::curve_server_t::process_handshake_message (msg_t *msg_)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int zmq::curve_server_t::encode (msg_t *msg_)
|
||||
{
|
||||
zmq_assert (state == connected);
|
||||
|
||||
const size_t mlen = crypto_box_ZEROBYTES + 1 + msg_->size ();
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, "CurveZMQMESSAGES", 16);
|
||||
memcpy (message_nonce + 16, &cn_nonce, 8);
|
||||
|
||||
uint8_t flags = 0;
|
||||
if (msg_->flags () & msg_t::more)
|
||||
flags |= 0x01;
|
||||
|
||||
uint8_t *message_plaintext = static_cast <uint8_t *> (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 <uint8_t *> (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 <uint8_t *> (msg_->data ());
|
||||
|
||||
memcpy (message, "MESSAGE ", 8);
|
||||
memcpy (message + 8, &cn_nonce, 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_server_t::decode (msg_t *msg_)
|
||||
{
|
||||
zmq_assert (state == connected);
|
||||
|
||||
if (msg_->size () < 33) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
const uint8_t *message = static_cast <uint8_t *> (msg_->data ());
|
||||
if (memcmp (message, "MESSAGE ", 8)) {
|
||||
errno = EPROTO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t message_nonce [crypto_box_NONCEBYTES];
|
||||
memcpy (message_nonce, "CurveZMQMESSAGEC", 16);
|
||||
memcpy (message_nonce + 16, message + 8, 8);
|
||||
|
||||
const size_t clen = crypto_box_BOXZEROBYTES + msg_->size () - 16;
|
||||
|
||||
uint8_t *message_plaintext = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_plaintext);
|
||||
|
||||
uint8_t *message_box = static_cast <uint8_t *> (malloc (clen));
|
||||
alloc_assert (message_box);
|
||||
|
||||
memset (message_box, 0, crypto_box_BOXZEROBYTES);
|
||||
memcpy (message_box + crypto_box_BOXZEROBYTES,
|
||||
message + 16, msg_->size () - 16);
|
||||
|
||||
int 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);
|
||||
|
||||
memcpy (msg_->data (),
|
||||
message_plaintext + crypto_box_ZEROBYTES + 1,
|
||||
msg_->size ());
|
||||
}
|
||||
else
|
||||
errno = EPROTO;
|
||||
|
||||
free (message_plaintext);
|
||||
free (message_box);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int zmq::curve_server_t::zap_msg_available ()
|
||||
{
|
||||
if (state != expect_zap_reply) {
|
||||
|
@ -56,6 +56,8 @@ namespace zmq
|
||||
// mechanism implementation
|
||||
virtual int next_handshake_message (msg_t *msg_);
|
||||
virtual int process_handshake_message (msg_t *msg_);
|
||||
virtual int encode (msg_t *msg_);
|
||||
virtual int decode (msg_t *msg_);
|
||||
virtual int zap_msg_available ();
|
||||
virtual bool is_handshake_complete () const;
|
||||
|
||||
|
@ -46,6 +46,10 @@ namespace zmq
|
||||
// Process the handshake message received from the peer.
|
||||
virtual int process_handshake_message (msg_t *msg_) = 0;
|
||||
|
||||
virtual int encode (msg_t *msg_) { return 0; }
|
||||
|
||||
virtual int decode (msg_t *msg_) { return 0; }
|
||||
|
||||
// Notifies mechanism about availability of ZAP message.
|
||||
virtual int zap_msg_available () { return 0; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user