int main (void) { 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 ( "is a base-85 format that is described in 0MQ RFC 32, and which has an"); puts ("implementation in the z85_codec.h source used by this tool. The " "keypair"); 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."); char public_key[41]; char secret_key[41]; if (zmq_curve_keypair (public_key, secret_key)) { if (zmq_errno () == ENOTSUP) puts ("To use curve_keygen, please install libsodium and then " "rebuild libzmq."); exit (1); } puts ("\n== CURVE PUBLIC KEY =="); puts (public_key); puts ("\n== CURVE SECRET KEY =="); puts (secret_key); exit (0); }
JNIEXPORT jobject JNICALL Java_org_zeromq_ZMQ_00024Curve_generateKeyPair(JNIEnv *env, jclass cls) { #if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4,0,0) char public_key [41]; char secret_key [41]; int rc = zmq_curve_keypair (public_key, secret_key); int err = zmq_errno (); if (0 != rc) { raise_exception (env, err); return NULL; } jstring pk = env->NewStringUTF (public_key); assert (pk); jstring sk = env->NewStringUTF (secret_key); assert (sk); jclass clz = env->FindClass ("org/zeromq/ZMQ$Curve$KeyPair"); assert (clz); jmethodID midInit = env->GetMethodID (clz, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V"); assert (midInit); jobject result = env->NewObject (clz, midInit, pk, sk); assert (result); return result; #else raise_exception (env, ENOTSUP); return NULL; #endif }
// There is no way to test for correctness because of the embedded RNG. void test__zmq_curve_keypair__always__success (void) { errno = 0; char public_key[41] = {0}; char secret_key[41] = {0}; const int rc = zmq_curve_keypair (public_key, secret_key); #if defined(ZMQ_HAVE_CURVE) assert (rc == 0); #else assert (rc == -1); assert (zmq_errno () == ENOTSUP); #endif }
zcert_t * zcert_new (void) { byte public_key [32] = { 0 }; byte secret_key [32] = { 0 }; #if (ZMQ_VERSION_MAJOR == 4) if (zsys_has_curve ()) { char public_txt [41]; char secret_txt [41]; int rc = zmq_curve_keypair (public_txt, secret_txt); if (rc != 0) return NULL; zmq_z85_decode (public_key, public_txt); zmq_z85_decode (secret_key, secret_txt); } #endif return zcert_new_from (public_key, secret_key); }
zcert_t * zcert_new (void) { zcert_t *self = (zcert_t *) zmalloc (sizeof (zcert_t)); assert (self); // Initialize metadata, even if keys aren't working self->metadata = zhash_new (); zhash_autofree (self->metadata); #if (ZMQ_VERSION_MAJOR == 4) int rc = zmq_curve_keypair (self->public_txt, self->secret_txt); assert (rc == 0); zmq_z85_decode (self->public_key, self->public_txt); zmq_z85_decode (self->secret_key, self->secret_txt); #else strcpy (self->public_txt, "0000000000000000000000000000000000000000"); strcpy (self->secret_txt, "0000000000000000000000000000000000000000"); #endif return self; }
int main (void) { #ifndef HAVE_LIBSODIUM printf ("libsodium not installed, skipping CURVE test\n"); return 0; #endif // Generate new keypairs for this test int rc = zmq_curve_keypair (client_public, client_secret); assert (rc == 0); rc = zmq_curve_keypair (server_public, server_secret); assert (rc == 0); setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler // We create and bind ZAP socket in main thread to avoid case // where child thread does not start up fast enough. void *handler = zmq_socket (ctx, ZMQ_REP); assert (handler); rc = zmq_bind (handler, "inproc://zeromq.zap.01"); assert (rc == 0); void *zap_thread = zmq_threadstart (&zap_handler, handler); // Server socket will accept connections void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); int as_server = 1; rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 40); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9998"); assert (rc == 0); // 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); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); bounce (server, client); rc = zmq_close (client); assert (rc == 0); // Check CURVE security with a garbage server key // This will be caught by the curve_server class, not passed to ZAP char garbage_key [] = "0000111122223333444455556666777788889999"; client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client public key // 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); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client secret key // 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); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with bogus client credentials // This must be caught by the ZAP handler char bogus_public [40]; char bogus_secret [40]; zmq_curve_keypair (bogus_public, bogus_secret); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 40); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 40); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with NULL client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with PLAIN client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Shutdown rc = zmq_close (server); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }
int main(int argc, char** argv) { if (argc == 1) { fprintf(stderr, "Generate a random key for dabInputZMQ and save it to two files.\n\n"); fprintf(stderr, "Usage: %s <name>\n", argv[0]); return 1; } const char* keyname = argv[1]; if (strlen(keyname) > 2048) { fprintf(stderr, "name too long\n"); return 1; } char pubkeyfile[strlen(keyname) + 10]; char seckeyfile[strlen(keyname) + 10]; sprintf(pubkeyfile, "%s.pub", keyname); sprintf(seckeyfile, "%s.sec", keyname); char public_key [41]; char secret_key [41]; int rc = zmq_curve_keypair(public_key, secret_key); if (rc != 0) { fprintf(stderr, "key generation failed\n"); } int fdpub = creat(pubkeyfile, S_IRUSR | S_IWUSR); if (fdpub < 0) { perror("File creation failed"); return 1; } int fdsec = creat(seckeyfile, S_IRUSR | S_IWUSR); if (fdsec < 0) { perror("File creation failed"); return 1; } int r = write(fdpub, public_key, 41); int ret = 0; if (r < 0) { perror("write failed"); ret = 1; } else if (r != 41) { fprintf(stderr, "Not enough key data written to file\n"); ret = 1; } close(fdpub); if (ret == 0) { r = write(fdsec, secret_key, 41); if (r < 0) { perror("write failed"); ret = 1; } else if (r != 41) { fprintf(stderr, "Not enough key data written to file\n"); ret = 1; } } close(fdsec); return ret; }
int main (void) { #ifndef HAVE_LIBSODIUM printf ("libsodium not installed, skipping CURVE test\n"); return 0; #endif // Generate new keypairs for this test int rc = zmq_curve_keypair (client_public, client_secret); assert (rc == 0); rc = zmq_curve_keypair (server_public, server_secret); assert (rc == 0); setup_test_environment (); void *ctx = zmq_ctx_new (); assert (ctx); // Spawn ZAP handler // We create and bind ZAP socket in main thread to avoid case // where child thread does not start up fast enough. void *handler = zmq_socket (ctx, ZMQ_REP); assert (handler); rc = zmq_bind (handler, "inproc://zeromq.zap.01"); assert (rc == 0); void *zap_thread = zmq_threadstart (&zap_handler, handler); // Server socket will accept connections void *server = zmq_socket (ctx, ZMQ_DEALER); assert (server); int as_server = 1; rc = zmq_setsockopt (server, ZMQ_CURVE_SERVER, &as_server, sizeof (int)); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_CURVE_SECRETKEY, server_secret, 41); assert (rc == 0); rc = zmq_setsockopt (server, ZMQ_IDENTITY, "IDENT", 6); assert (rc == 0); rc = zmq_bind (server, "tcp://127.0.0.1:9998"); assert (rc == 0); // Check CURVE security with valid credentials void *client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); bounce (server, client); rc = zmq_close (client); assert (rc == 0); // Check CURVE security with a garbage server key // This will be caught by the curve_server class, not passed to ZAP char garbage_key [] = "0000111122223333444455556666777788889999"; client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, garbage_key, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client public key // 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, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, garbage_key, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with a garbage client secret key // 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, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, garbage_key, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with bogus client credentials // This must be caught by the ZAP handler char bogus_public [41]; char bogus_secret [41]; zmq_curve_keypair (bogus_public, bogus_secret); client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, bogus_public, 41); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, bogus_secret, 41); assert (rc == 0); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with NULL client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_connect (client, "tcp://localhost:9998"); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Check CURVE security with PLAIN client credentials // This must be caught by the curve_server class, not passed to ZAP client = zmq_socket (ctx, ZMQ_DEALER); assert (client); rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5); assert (rc == 0); rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8); assert (rc == 0); expect_bounce_fail (server, client); close_zero_linger (client); // Unauthenticated messages from a vanilla socket shouldn't be received struct sockaddr_in ip4addr; int s; ip4addr.sin_family = AF_INET; ip4addr.sin_port = htons (9998); #if (_WIN32_WINNT < 0x0600) ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1"); #else inet_pton(AF_INET, "127.0.0.1", &ip4addr.sin_addr); #endif s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); rc = connect (s, (struct sockaddr*) &ip4addr, sizeof (ip4addr)); assert (rc > -1); // send anonymous ZMTP/1.0 greeting send (s, "\x01\x00", 2, 0); // send sneaky message that shouldn't be received send (s, "\x08\x00sneaky\0", 9, 0); int timeout = 250; zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); char *buf = s_recv (server); if (buf != NULL) { printf ("Received unauthenticated message: %s\n", buf); assert (buf == NULL); } close (s); // Check return codes for invalid buffer sizes client = zmq_socket (ctx, ZMQ_DEALER); assert (client); errno = 0; rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 123); assert (rc == -1 && errno == EINVAL); errno = 0; rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 123); assert (rc == -1 && errno == EINVAL); errno = 0; rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 123); assert (rc == -1 && errno == EINVAL); rc = zmq_close (client); assert (rc == 0); // Shutdown rc = zmq_close (server); assert (rc == 0); rc = zmq_ctx_term (ctx); assert (rc == 0); // Wait until ZAP handler terminates zmq_threadclose (zap_thread); return 0; }