Commit ead6826c authored by Pieter Hintjens's avatar Pieter Hintjens

Merge pull request #691 from minrk/curve_keygen

Expose zmq_curve_keypair via zmq_utils
parents 30d34888 45779569
...@@ -88,6 +88,10 @@ ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size); ...@@ -88,6 +88,10 @@ ZMQ_EXPORT char *zmq_z85_encode (char *dest, uint8_t *data, size_t size);
/* Decode data with Z85 encoding. Returns decoded data */ /* Decode data with Z85 encoding. Returns decoded data */
ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string); ZMQ_EXPORT uint8_t *zmq_z85_decode (uint8_t *dest, char *string);
/* Generate z85-encoded public and private keypair with libsodium. */
/* Returns 0 on success. */
ZMQ_EXPORT int zmq_curve_keypair (char* z85_public_key, char *z85_secret_key);
#undef ZMQ_EXPORT #undef ZMQ_EXPORT
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -30,6 +30,10 @@ ...@@ -30,6 +30,10 @@
#else #else
#include "windows.hpp" #include "windows.hpp"
#endif #endif
#ifdef HAVE_LIBSODIUM
# include <sodium.h>
#endif
void zmq_sleep (int seconds_) void zmq_sleep (int seconds_)
{ {
...@@ -100,10 +104,14 @@ static uint8_t decoder [96] = { ...@@ -100,10 +104,14 @@ static uint8_t decoder [96] = {
// Encode a binary frame as a string; destination string MUST be at least // Encode a binary frame as a string; destination string MUST be at least
// size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns // size * 5 / 4 bytes long plus 1 byte for the null terminator. Returns
// dest. Size must be a multiple of 4. // dest. Size must be a multiple of 4.
// Returns NULL and sets errno = EINVAL for invalid input.
char *zmq_z85_encode (char *dest, uint8_t *data, size_t size) char *zmq_z85_encode (char *dest, uint8_t *data, size_t size)
{ {
assert (size % 4 == 0); if (size % 4 != 0) {
errno = EINVAL;
return NULL;
}
unsigned int char_nbr = 0; unsigned int char_nbr = 0;
unsigned int byte_nbr = 0; unsigned int byte_nbr = 0;
uint32_t value = 0; uint32_t value = 0;
...@@ -125,15 +133,20 @@ char *zmq_z85_encode (char *dest, uint8_t *data, size_t size) ...@@ -125,15 +133,20 @@ char *zmq_z85_encode (char *dest, uint8_t *data, size_t size)
return dest; return dest;
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Decode an encoded string into a binary frame; dest must be at least // Decode an encoded string into a binary frame; dest must be at least
// strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string) // strlen (string) * 4 / 5 bytes long. Returns dest. strlen (string)
// must be a multiple of 5. // must be a multiple of 5.
// Returns NULL and sets errno = EINVAL for invalid input.
uint8_t *zmq_z85_decode (uint8_t *dest, char *string) uint8_t *zmq_z85_decode (uint8_t *dest, char *string)
{ {
assert (strlen (string) % 5 == 0);
if (strlen (string) % 5 != 0) {
errno = EINVAL;
return NULL;
}
unsigned int byte_nbr = 0; unsigned int byte_nbr = 0;
unsigned int char_nbr = 0; unsigned int char_nbr = 0;
uint32_t value = 0; uint32_t value = 0;
...@@ -153,3 +166,34 @@ uint8_t *zmq_z85_decode (uint8_t *dest, char *string) ...@@ -153,3 +166,34 @@ uint8_t *zmq_z85_decode (uint8_t *dest, char *string)
assert (byte_nbr == strlen (string) * 4 / 5); assert (byte_nbr == strlen (string) * 4 / 5);
return dest; return dest;
} }
// --------------------------------------------------------------------------
// Generate a public/private keypair with libsodium.
// Generated keys will be 40 byte z85-encoded strings.
// Returns 0 on success, -1 on failure, setting errno.
// Sets errno = ENOTSUP in the absence of libsodium.
int zmq_curve_keypair (char* z85_public_key, char *z85_secret_key)
{
#ifdef HAVE_LIBSODIUM
# 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);
// is there a sensible errno to set here?
if (rc) return rc;
zmq_z85_encode (z85_public_key, public_key, 32);
zmq_z85_encode (z85_secret_key, secret_key, 32);
return 0;
#else // requires libsodium
errno = ENOTSUP;
return -1;
#endif
}
...@@ -26,19 +26,11 @@ ...@@ -26,19 +26,11 @@
#include <assert.h> #include <assert.h>
#include <platform.hpp> #include <platform.hpp>
#include <zmq.h>
#include <zmq_utils.h> #include <zmq_utils.h>
#ifdef HAVE_LIBSODIUM
# include <sodium.h>
#endif
int main (void) int main (void)
{ {
#ifdef HAVE_LIBSODIUM
# if crypto_box_PUBLICKEYBYTES != 32 \
|| crypto_box_SECRETKEYBYTES != 32
# error "libsodium not built correctly"
# endif
puts ("This tool generates a CurveZMQ keypair, as two printable strings you can"); puts ("This tool generates a CurveZMQ keypair, as two printable strings you can");
puts ("use in configuration files or source code. The encoding uses Z85, which"); puts ("use in configuration files or source code. The encoding uses Z85, which");
puts ("is a base-85 format that is described in 0MQ RFC 32, and which has an"); puts ("is a base-85 format that is described in 0MQ RFC 32, and which has an");
...@@ -46,23 +38,21 @@ int main (void) ...@@ -46,23 +38,21 @@ int main (void)
puts ("always works with the secret key held by one party and the public key"); puts ("always works with the secret key held by one party and the public key");
puts ("distributed (securely!) to peers wishing to connect to it."); puts ("distributed (securely!) to peers wishing to connect to it.");
uint8_t public_key [32]; char public_key [41];
uint8_t secret_key [32]; char secret_key [41];
int rc = zmq_curve_keypair (public_key, secret_key);
if (rc != 0) {
if (zmq_errno () == ENOTSUP) {
puts ("To use curve_keygen, please install libsodium and then rebuild libzmq.");
}
exit (1);
}
int rc = crypto_box_keypair (public_key, secret_key);
assert (rc == 0);
char encoded [41];
zmq_z85_encode (encoded, public_key, 32);
puts ("\n== CURVE PUBLIC KEY =="); puts ("\n== CURVE PUBLIC KEY ==");
puts (encoded); puts (public_key);
zmq_z85_encode (encoded, secret_key, 32);
puts ("\n== CURVE SECRET KEY =="); puts ("\n== CURVE SECRET KEY ==");
puts (encoded); puts (secret_key);
#else
puts ("To build curve_keygen, please install libsodium and then rebuild libzmq.");
#endif
exit (0); exit (0);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment