mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-27 15:41:05 +08:00
Merge pull request #577 from hintjens/master
API for CURVE configuration
This commit is contained in:
commit
1fe7820629
2
.gitignore
vendored
2
.gitignore
vendored
@ -20,6 +20,8 @@ autom4te.cache
|
||||
.*
|
||||
*~
|
||||
.*~
|
||||
tools/curve_keygen.o
|
||||
tools/curve_keygen
|
||||
tests/test_term_endpoint
|
||||
tests/test_monitor
|
||||
tests/test_last_endpoint
|
||||
|
@ -187,10 +187,10 @@ The following security mechanisms are provided for IPC and TCP connections:
|
||||
Null security::
|
||||
linkzmq:zmq_null[7]
|
||||
|
||||
Clear-text authentication using username and password::
|
||||
linkzmq:zmq_clear[7]
|
||||
Plain-text authentication using username and password::
|
||||
linkzmq:zmq_plain[7]
|
||||
|
||||
Secure authentication and encryption::
|
||||
Elliptic curve authentication and encryption::
|
||||
linkzmq:zmq_curve[7]
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@ zmq_curve(7)
|
||||
|
||||
NAME
|
||||
----
|
||||
zmq_curve - clear-text authentication
|
||||
zmq_curve - secure authentication and confidentiality
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
@ -15,16 +15,44 @@ is intended for use on public networks. The CURVE mechanism is defined
|
||||
by this document: <http://rfc.zeromq.org/spec:25>.
|
||||
|
||||
|
||||
SERVER AND CLIENT ROLES
|
||||
CLIENT AND SERVER ROLES
|
||||
-----------------------
|
||||
To use CURVE, the server shall set the ZMQ_CURVE_SERVER option, and the
|
||||
client shall set the ZMQ_CURVE_PUBLICKEY and ZMQ_CURVE_SERVERKEY socket
|
||||
options. Which peer binds, and which connects, is not relevant.
|
||||
A socket using CURVE can be either client or server, at any moment, but
|
||||
not both. The role is independent of bind/connect direction.
|
||||
|
||||
NOTE: this isn't implemented and not fully defined. The server keypair
|
||||
needs to be persistent, and it would be sensible to define a format for
|
||||
this as a CurveZMQ RFC.
|
||||
A socket can change roles at any point by setting new options. The role
|
||||
affects all zmq_connect and zmq_bind calls that follow it.
|
||||
|
||||
To become a CURVE server, the application sets the ZMQ_CURVE_SERVER option
|
||||
on the socket, and then sets the ZMQ_CURVE_SECRETKEY option to provide the
|
||||
socket with its long-term secret key. The application does not provide the
|
||||
socket with its long-term public key, which is used only by clients.
|
||||
|
||||
To become a CURVE client, the application sets the ZMQ_CURVE_SERVERKEY
|
||||
option with the long-term public key of the server it intends to connect
|
||||
to, or accept connections from, next. The application then sets the
|
||||
ZMQ_CURVE_PUBLICKEY and ZMQ_CURVE_SECRETKEY options with its client
|
||||
long-term key pair.
|
||||
|
||||
If the server does authentication it will be based on the client's long
|
||||
term public key.
|
||||
|
||||
TEST KEY VALUES
|
||||
---------------
|
||||
|
||||
For test cases, the client shall use this long-term key pair:
|
||||
|
||||
----
|
||||
public: BB88471D65E2659B30C55A5321CEBB5AAB2B70A398645C26DCA2B2FCB43FC518
|
||||
secret: 7BB864B489AFA3671FBE69101F94B38972F24816DFB01B51656B3FEC8DFD0888
|
||||
----
|
||||
|
||||
And the server shall use this long-term key pair:
|
||||
|
||||
----
|
||||
public: 54FCBA24E93249969316FB617C872BB0C1D1FF14800427C594CBFACF1BC2D652
|
||||
secret: 8E0BDD697628B91D8F245587EE95C5B04D48963F79259877B49CD9063AEAD3B7
|
||||
----
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
|
@ -13,8 +13,10 @@ SYNOPSIS
|
||||
*int zmq_setsockopt (void '*socket', int 'option_name', const void '*option_value', size_t 'option_len');*
|
||||
|
||||
Caution: All options, with the exception of ZMQ_SUBSCRIBE, ZMQ_UNSUBSCRIBE,
|
||||
ZMQ_LINGER, ZMQ_ROUTER_MANDATORY, ZMQ_PROBE_ROUTER, and ZMQ_XPUB_VERBOSE
|
||||
only take effect for subsequent socket bind/connects.
|
||||
ZMQ_LINGER, ZMQ_ROUTER_MANDATORY, ZMQ_PROBE_ROUTER, ZMQ_XPUB_VERBOSE only
|
||||
take effect for subsequent socket bind/connects. Specifically, security
|
||||
options take effect for subsequent binds/connects and can be changed at any
|
||||
time to affect subsequent binds and/or connects.
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
@ -528,7 +530,7 @@ ZMQ_PLAIN_SERVER: Set PLAIN server role
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Defines whether the socket will act as server for PLAIN security, see
|
||||
linkzmq:zmq_plain[3]. A value of '1' means the socket will act as
|
||||
linkzmq:zmq_plain[7]. A value of '1' means the socket will act as
|
||||
PLAIN server. A value of '0' means the socket will not act as PLAIN
|
||||
server, and its security role then depends on other option settings.
|
||||
Setting this to '0' shall reset the socket security to NULL.
|
||||
@ -537,7 +539,7 @@ Setting this to '0' shall reset the socket security to NULL.
|
||||
Option value type:: int
|
||||
Option value unit:: 0, 1
|
||||
Default value:: 0
|
||||
Applicable socket types:: all, when using TCP or IPC transports
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_PLAIN_USERNAME: Set PLAIN security username
|
||||
@ -545,14 +547,14 @@ ZMQ_PLAIN_USERNAME: Set PLAIN security username
|
||||
|
||||
Sets the username for outgoing connections over TCP or IPC. If you set this
|
||||
to a non-null value, the security mechanism used for connections shall be
|
||||
PLAIN, see linkzmq:zmq_plain[3]. If you set this to a null value, the security
|
||||
PLAIN, see linkzmq:zmq_plain[7]. If you set this to a null value, the security
|
||||
mechanism used for connections shall be NULL, see linkzmq:zmq_null[3].
|
||||
|
||||
[horizontal]
|
||||
Option value type:: character string
|
||||
Option value unit:: N/A
|
||||
Default value:: not set
|
||||
Applicable socket types:: all, when using TCP or IPC transports
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_PLAIN_PASSWORD: Set PLAIN security password
|
||||
@ -567,7 +569,66 @@ mechanism used for connections shall be NULL, see linkzmq:zmq_null[3].
|
||||
Option value type:: character string
|
||||
Option value unit:: N/A
|
||||
Default value:: not set
|
||||
Applicable socket types:: all, when using TCP or IPC transports
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_CURVE_SERVER: Set CURVE server role
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Defines whether the socket will act as server for CURVE security, see
|
||||
linkzmq:zmq_curve[7]. A value of '1' means the socket will act as
|
||||
CURVE server. A value of '0' means the socket will not act as CURVE
|
||||
server, and its security role then depends on other option settings.
|
||||
Setting this to '0' shall reset the socket security to NULL. When you
|
||||
set this you must also set the ZMQ_CURVE_PUBLICKEY option.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: int
|
||||
Option value unit:: 0, 1
|
||||
Default value:: 0
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_CURVE_PUBLICKEY: Set CURVE public key
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sets the socket's long term public key. You must set this on a CURVE
|
||||
client or server socket, see linkzmq:zmq_curve[7]. The key is 32 bytes.
|
||||
For servers, it must be persisted and shared through some unspecified
|
||||
secure mechanism to clients.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: binary data
|
||||
Option value size:: 32
|
||||
Default value:: NULL
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_CURVE_SECRETKEY: Set CURVE secret key
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sets the socket's long term secret key. You must set this on a CURVE
|
||||
client socket, see linkzmq:zmq_curve[7]. The key is 32 bytes.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: binary data
|
||||
Option value size:: 32
|
||||
Default value:: NULL
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
ZMQ_CURVE_SERVERKEY: Set CURVE server key
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sets the socket's long term server key. You must set this on a CURVE
|
||||
client socket, see linkzmq:zmq_curve[7]. The key is 32 bytes. This
|
||||
key must be the same as the public key set on the server socket.
|
||||
|
||||
[horizontal]
|
||||
Option value type:: binary data
|
||||
Option value size:: 32
|
||||
Default value:: NULL
|
||||
Applicable socket types:: all, when using TCP transport
|
||||
|
||||
|
||||
RETURN VALUE
|
||||
@ -630,5 +691,3 @@ AUTHORS
|
||||
-------
|
||||
This page was written by the 0MQ community. To make a change please
|
||||
read the 0MQ Contribution Policy at <http://www.zeromq.org/docs:contributing>.
|
||||
|
||||
|
||||
|
@ -255,7 +255,6 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
|
||||
#define ZMQ_MULTICAST_HOPS 25
|
||||
#define ZMQ_RCVTIMEO 27
|
||||
#define ZMQ_SNDTIMEO 28
|
||||
#define ZMQ_IPV4ONLY 31 /* Request replacement by IPV6 */
|
||||
#define ZMQ_LAST_ENDPOINT 32
|
||||
#define ZMQ_ROUTER_MANDATORY 33
|
||||
#define ZMQ_TCP_KEEPALIVE 34
|
||||
@ -273,8 +272,9 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
|
||||
#define ZMQ_PLAIN_PASSWORD 46
|
||||
#define ZMQ_CURVE_SERVER 47
|
||||
#define ZMQ_CURVE_PUBLICKEY 48
|
||||
#define ZMQ_CURVE_SERVERKEY 49
|
||||
#define ZMQ_PROBE_ROUTER 50
|
||||
#define ZMQ_CURVE_SECRETKEY 49
|
||||
#define ZMQ_CURVE_SERVERKEY 50
|
||||
#define ZMQ_PROBE_ROUTER 51
|
||||
|
||||
/* Message options */
|
||||
#define ZMQ_MORE 1
|
||||
@ -288,7 +288,8 @@ ZMQ_EXPORT int zmq_msg_set (zmq_msg_t *msg, int option, int optval);
|
||||
#define ZMQ_PLAIN 1
|
||||
#define ZMQ_CURVE 2
|
||||
|
||||
/* Deprecated aliases */
|
||||
/* Deprecated options and aliases */
|
||||
#define ZMQ_IPV4ONLY 31
|
||||
#define ZMQ_DELAY_ATTACH_ON_CONNECT ZMQ_IMMEDIATE
|
||||
#define ZMQ_NOBLOCK ZMQ_DONTWAIT
|
||||
#define ZMQ_FAIL_UNROUTABLE ZMQ_ROUTER_MANDATORY
|
||||
|
@ -37,14 +37,9 @@ zmq::curve_client_t::curve_client_t (const options_t &options_) :
|
||||
mechanism_t (options_),
|
||||
state (send_hello)
|
||||
{
|
||||
zmq_assert (options_.public_key_size == crypto_box_PUBLICKEYBYTES);
|
||||
memcpy (public_key, options_.public_key, crypto_box_PUBLICKEYBYTES);
|
||||
|
||||
zmq_assert (options_.secret_key_size == crypto_box_SECRETKEYBYTES);
|
||||
memcpy (secret_key, options_.secret_key, crypto_box_SECRETKEYBYTES);
|
||||
|
||||
zmq_assert (options_.server_key_size == crypto_box_PUBLICKEYBYTES);
|
||||
memcpy (server_key, options_.server_key, crypto_box_PUBLICKEYBYTES);
|
||||
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);
|
||||
|
||||
// Generate short-term key pair
|
||||
const int rc = crypto_box_keypair (cn_public, cn_secret);
|
||||
|
@ -40,8 +40,7 @@ zmq::curve_server_t::curve_server_t (session_base_t *session_,
|
||||
cn_nonce (1)
|
||||
{
|
||||
// Fetch our secret key from socket options
|
||||
zmq_assert (options_.secret_key_size == crypto_box_SECRETKEYBYTES);
|
||||
memcpy (secret_key, options_.secret_key, crypto_box_SECRETKEYBYTES);
|
||||
memcpy (secret_key, options_.curve_secret_key, crypto_box_SECRETKEYBYTES);
|
||||
|
||||
// Generate short-term key pair
|
||||
const int rc = crypto_box_keypair (cn_public, cn_secret);
|
||||
|
@ -285,6 +285,35 @@ int zmq::options_t::setsockopt (int option_, const void *optval_,
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_CURVE_SERVER:
|
||||
if (is_int && (value == 0 || value == 1)) {
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_CURVE_SECRETKEY:
|
||||
if (optvallen_ == CURVE_KEYSIZE) {
|
||||
memcpy (curve_secret_key, optval_, CURVE_KEYSIZE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_CURVE_SERVERKEY:
|
||||
if (optvallen_ == CURVE_KEYSIZE) {
|
||||
memcpy (curve_server_key, optval_, CURVE_KEYSIZE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -505,6 +534,34 @@ int zmq::options_t::getsockopt (int option_, void *optval_, size_t *optvallen_)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_CURVE_SERVER:
|
||||
if (is_int) {
|
||||
*value = as_server && mechanism == ZMQ_CURVE;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_CURVE_PUBLICKEY:
|
||||
if (*optvallen_ == CURVE_KEYSIZE) {
|
||||
memcpy (optval_, curve_public_key, CURVE_KEYSIZE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_CURVE_SECRETKEY:
|
||||
if (*optvallen_ == CURVE_KEYSIZE) {
|
||||
memcpy (optval_, curve_secret_key, CURVE_KEYSIZE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ZMQ_CURVE_SERVERKEY:
|
||||
if (*optvallen_ == CURVE_KEYSIZE) {
|
||||
memcpy (optval_, curve_server_key, CURVE_KEYSIZE);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "tcp_address.hpp"
|
||||
#include "../include/zmq.h"
|
||||
|
||||
#define CURVE_KEYSIZE 32
|
||||
|
||||
namespace zmq
|
||||
{
|
||||
struct options_t
|
||||
@ -125,6 +127,7 @@ namespace zmq
|
||||
|
||||
// Security mechanism for all connections on this socket
|
||||
int mechanism;
|
||||
|
||||
// If peer is acting as server for PLAIN or CURVE mechanisms
|
||||
int as_server;
|
||||
|
||||
@ -132,14 +135,10 @@ namespace zmq
|
||||
std::string plain_username;
|
||||
std::string plain_password;
|
||||
|
||||
unsigned char public_key_size;
|
||||
unsigned char public_key [32];
|
||||
|
||||
unsigned char secret_key_size;
|
||||
unsigned char secret_key [32];
|
||||
|
||||
unsigned char server_key_size;
|
||||
unsigned char server_key [32];
|
||||
// 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];
|
||||
|
||||
// ID of the socket.
|
||||
int socket_id;
|
||||
|
47
tools/curve_keygen.c
Normal file
47
tools/curve_keygen.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file
|
||||
|
||||
This file is part of 0MQ.
|
||||
|
||||
0MQ is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
0MQ 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <sodium.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
# if crypto_box_PUBLICKEYBYTES != 32 \
|
||||
|| crypto_box_SECRETKEYBYTES != 32
|
||||
# error "libsodium not built correctly"
|
||||
# endif
|
||||
|
||||
uint8_t public_key [32];
|
||||
uint8_t secret_key [32];
|
||||
|
||||
int rc = crypto_box_keypair (public_key, secret_key);
|
||||
assert (rc == 0);
|
||||
int byte_nbr;
|
||||
printf ("public: ");
|
||||
for (byte_nbr = 0; byte_nbr < 32; byte_nbr++)
|
||||
printf ("%02X", public_key [byte_nbr]);
|
||||
printf ("\n");
|
||||
printf ("secret: ");
|
||||
for (byte_nbr = 0; byte_nbr < 32; byte_nbr++)
|
||||
printf ("%02X", secret_key [byte_nbr]);
|
||||
printf ("\n");
|
||||
exit (0);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user