test_security_curve.cpp 21.7 KB
Newer Older
Ian Barber's avatar
Ian Barber committed
1
/*
2
    Copyright (c) 2007-2017 Contributors as noted in the AUTHORS file
Ian Barber's avatar
Ian Barber committed
3

4
    This file is part of libzmq, the ZeroMQ core engine in C++.
Ian Barber's avatar
Ian Barber committed
5

6 7 8
    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
Ian Barber's avatar
Ian Barber committed
9 10
    (at your option) any later version.

11 12 13 14 15 16 17 18 19 20 21 22 23 24
    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.
Ian Barber's avatar
Ian Barber committed
25 26 27 28 29 30

    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 "testutil.hpp"
31
#include "testutil_security.hpp"
32 33 34 35 36
#if defined(ZMQ_HAVE_WINDOWS)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdexcept>
#define close closesocket
37
#else
38 39 40 41
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
42
#endif
43
#include <unity.h>
44

45 46 47 48
#include "../src/tweetnacl.h"
#include "../src/curve_client_tools.hpp"
#include "../src/random.hpp"

49 50
char error_message_buffer[256];

51 52 53 54
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
#endif

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
const char *zmq_errno_message ()
{
    snprintf (error_message_buffer, sizeof (error_message_buffer),
              "errno=%i (%s)", zmq_errno (), zmq_strerror (zmq_errno ()));
    return error_message_buffer;
}

#define TEST_ASSERT_ZMQ_ERRNO(condition)                                       \
    TEST_ASSERT_MESSAGE ((condition), zmq_errno_message ())

void *ctx;
void *handler;
void *zap_thread;
void *server;
void *server_mon;
char my_endpoint[MAX_SOCKET_STRING];

void setUp ()
{
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
}

void tearDown ()
{
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);
}

const int timeout = 250;

86
const char large_routing_id[] = "0123456789012345678901234567890123456789"
87 88 89 90 91 92
                                "0123456789012345678901234567890123456789"
                                "0123456789012345678901234567890123456789"
                                "0123456789012345678901234567890123456789"
                                "0123456789012345678901234567890123456789"
                                "0123456789012345678901234567890123456789"
                                "012345678901234";
93

94
static void zap_handler_large_routing_id (void *ctx)
95
{
96
    zap_handler_generic (ctx, zap_ok, large_routing_id);
97 98
}

99 100 101 102 103
void expect_new_client_curve_bounce_fail (void *ctx,
                                          char *server_public,
                                          char *client_public,
                                          char *client_secret,
                                          char *my_endpoint,
104
                                          void *server,
105 106 107
                                          void **client_mon = NULL,
                                          int expected_client_event = 0,
                                          int expected_client_value = 0)
108
{
109 110
    curve_client_data_t curve_client_data = {server_public, client_public,
                                             client_secret};
111 112 113
    expect_new_client_bounce_fail (
      ctx, my_endpoint, server, socket_config_curve_client, &curve_client_data,
      client_mon, expected_client_event, expected_client_value);
114 115
}

116 117 118 119 120 121 122
void test_null_key (void *ctx,
                    void *server,
                    void *server_mon,
                    char *my_endpoint,
                    char *server_public,
                    char *client_public,
                    char *client_secret)
123 124 125
{
    expect_new_client_curve_bounce_fail (ctx, server_public, client_public,
                                         client_secret, my_endpoint, server);
126

127
#ifdef ZMQ_BUILD_DRAFT_API
128 129
    int handshake_failed_encryption_event_count =
      expect_monitor_event_multiple (server_mon,
130 131
                                     ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                     ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
132

133
    // handshake_failed_encryption_event_count should be at least two because
134
    // expect_bounce_fail involves two exchanges
135 136
    // however, with valgrind we see only one event (maybe the next one takes
    // very long, or does not happen at all because something else takes very
137
    // long)
138 139

    fprintf (stderr,
140 141 142
             "count of "
             "ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL/"
             "ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC events: %i\n",
143
             handshake_failed_encryption_event_count);
144 145 146
#endif
}

147
void test_curve_security_with_valid_credentials ()
148
{
149 150
    curve_client_data_t curve_client_data = {
      valid_server_public, valid_client_public, valid_client_secret};
151 152 153 154
    void *client_mon;
    void *client =
      create_and_connect_client (ctx, my_endpoint, socket_config_curve_client,
                                 &curve_client_data, &client_mon);
155
    bounce (server, client);
156
    int rc = zmq_close (client);
157
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
158

159
#ifdef ZMQ_BUILD_DRAFT_API
160
    int event = get_monitor_event_with_timeout (server_mon, NULL, NULL, -1);
161 162 163
    assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);

    assert_no_more_monitor_events_with_timeout (server_mon, timeout);
164 165 166 167 168 169 170

    event = get_monitor_event_with_timeout (client_mon, NULL, NULL, -1);
    assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);

    assert_no_more_monitor_events_with_timeout (client_mon, timeout);

    rc = zmq_close (client_mon);
171
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
172
#endif
173
}
174

175
void test_curve_security_with_bogus_client_credentials ()
176
{
177
    //  This must be caught by the ZAP handler
178 179
    char bogus_public[41];
    char bogus_secret[41];
180
    zmq_curve_keypair (bogus_public, bogus_secret);
181

182
    expect_new_client_curve_bounce_fail (ctx, valid_server_public, bogus_public,
183
                                         bogus_secret, my_endpoint, server,
184 185 186 187 188 189 190
                                         NULL,
#ifdef ZMQ_BUILD_DRAFT_API
                                         ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400
#else
                                         0, 0
#endif
    );
191

192
    int server_event_count = 0;
193
#ifdef ZMQ_BUILD_DRAFT_API
194
    server_event_count = expect_monitor_event_multiple (
195
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400);
196
    TEST_ASSERT_LESS_OR_EQUAL_INT (1, server_event_count);
197
#endif
198 199

    // there may be more than one ZAP request due to repeated attempts by the client
200 201
    TEST_ASSERT (0 == server_event_count
                 || 1 <= zmq_atomic_counter_value (zap_requests_handled));
202
}
203

204 205 206 207
void expect_zmtp_mechanism_mismatch (void *client,
                                     char *my_endpoint,
                                     void *server,
                                     void *server_mon)
208
{
209
    //  This must be caught by the curve_server class, not passed to ZAP
210
    int rc = zmq_connect (client, my_endpoint);
211
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
212 213 214
    expect_bounce_fail (server, client);
    close_zero_linger (client);

215
#ifdef ZMQ_BUILD_DRAFT_API
216 217 218
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
219
#endif
220

221
    TEST_ASSERT_EQUAL_INT (0, zmq_atomic_counter_value (zap_requests_handled));
222
}
223

224
void test_curve_security_with_null_client_credentials ()
225 226
{
    void *client = zmq_socket (ctx, ZMQ_DEALER);
227
    TEST_ASSERT_NOT_NULL (client);
228

229
    expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
230 231
}

232
void test_curve_security_with_plain_client_credentials ()
233 234
{
    void *client = zmq_socket (ctx, ZMQ_DEALER);
235
    TEST_ASSERT_NOT_NULL (client);
236
    int rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5);
237
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
238
    rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8);
239
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
240

241
    expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
242
}
243

244
int connect_vanilla_socket (char *my_endpoint)
245
{
246
    int s;
247
    struct sockaddr_in ip4addr;
248

249
    unsigned short int port;
250
    int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port);
251
    TEST_ASSERT_EQUAL_INT (1, rc);
252

253
    ip4addr.sin_family = AF_INET;
254
    ip4addr.sin_port = htons (port);
255
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
256 257
    ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
#else
258
    inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
259
#endif
260 261

    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
262
    rc = connect (s, (struct sockaddr *) &ip4addr, sizeof (ip4addr));
263
    TEST_ASSERT_GREATER_THAN_INT (-1, rc);
264 265 266
    return s;
}

267
void test_curve_security_unauthenticated_message ()
268 269
{
    // Unauthenticated messages from a vanilla socket shouldn't be received
270
    int s = connect_vanilla_socket (my_endpoint);
271 272 273 274
    // 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);
275

276 277
    zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
    char *buf = s_recv (server);
278
    TEST_ASSERT_NULL_MESSAGE (buf, "Received unauthenticated message");
279
    close (s);
280
}
281

282 283 284 285
void send_all (int fd, const char *data, size_t size)
{
    while (size > 0) {
        int res = send (fd, data, size, 0);
286
        TEST_ASSERT_GREATER_THAN_INT (0, res);
287 288 289 290 291
        size -= res;
        data += res;
    }
}

292
template <size_t N> void send (int fd, const char (&data)[N])
293 294 295 296
{
    send_all (fd, data, N - 1);
}

297
void send_greeting (int s)
298
{
299 300
    send (s, "\xff\0\0\0\0\0\0\0\0\x7f");            // signature
    send (s, "\x03\x00");                            // version 3.0
301
    send (s, "CURVE\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); // mechanism CURVE
302
    send (s, "\0");                                  // as-server == false
303 304 305
    send (s, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
}

306
void test_curve_security_invalid_hello_wrong_length ()
307 308 309 310 311 312 313
{
    int s = connect_vanilla_socket (my_endpoint);

    // send GREETING
    send_greeting (s);

    // send CURVE HELLO of wrong size
314
    send (s, "\x04\x06\x05HELLO");
315 316

#ifdef ZMQ_BUILD_DRAFT_API
317 318 319
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
#endif

    close (s);
}

const size_t hello_length = 200;
const size_t welcome_length = 168;

zmq::curve_client_tools_t make_curve_client_tools ()
{
    uint8_t valid_client_secret_decoded[32];
    uint8_t valid_client_public_decoded[32];

    zmq_z85_decode (valid_client_public_decoded, valid_client_public);
    zmq_z85_decode (valid_client_secret_decoded, valid_client_secret);

    uint8_t valid_server_public_decoded[32];
    zmq_z85_decode (valid_server_public_decoded, valid_server_public);

    return zmq::curve_client_tools_t (valid_client_public_decoded,
                                      valid_client_secret_decoded,
                                      valid_server_public_decoded);
}

#ifndef htonll
uint64_t htonll (uint64_t value)
{
    // The answer is 42
    static const int num = 42;

    // Check the endianness
    if (*reinterpret_cast<const char *> (&num) == num) {
        const uint32_t high_part = htonl (static_cast<uint32_t> (value >> 32));
        const uint32_t low_part =
          htonl (static_cast<uint32_t> (value & 0xFFFFFFFFLL));

        return (static_cast<uint64_t> (low_part) << 32) | high_part;
    } else {
        return value;
    }
}
#endif

template <size_t N> void send_command (int s, char (&command)[N])
{
365 366 367 368 369 370 371 372 373 374
    if (N < 256) {
        send (s, "\x04");
        char len = (char) N;
        send_all (s, &len, 1);
    } else {
        send (s, "\x06");
        uint64_t len = htonll (N);
        send_all (s, (char *) &len, 8);
    }
    send_all (s, command, N);
375 376
}

377
void test_curve_security_invalid_hello_command_name ()
378 379 380 381 382 383 384 385 386 387
{
    int s = connect_vanilla_socket (my_endpoint);

    send_greeting (s);

    zmq::curve_client_tools_t tools = make_curve_client_tools ();

    // send CURVE HELLO with a misspelled command name (but otherwise correct)
    char hello[hello_length];
    int rc = tools.produce_hello (hello, 0);
388
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
389 390
    hello[5] = 'X';

391
    send_command (s, hello);
392 393

#ifdef ZMQ_BUILD_DRAFT_API
394 395 396
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
397 398 399 400 401
#endif

    close (s);
}

402
void test_curve_security_invalid_hello_version ()
403 404 405 406 407 408 409 410 411 412
{
    int s = connect_vanilla_socket (my_endpoint);

    send_greeting (s);

    zmq::curve_client_tools_t tools = make_curve_client_tools ();

    // send CURVE HELLO with a wrong version number (but otherwise correct)
    char hello[hello_length];
    int rc = tools.produce_hello (hello, 0);
413
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
414 415 416 417 418
    hello[6] = 2;

    send_command (s, hello);

#ifdef ZMQ_BUILD_DRAFT_API
419 420 421
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
422 423 424 425 426
#endif

    close (s);
}

427
void flush_read (int fd)
428 429 430 431 432 433
{
    int res;
    char buf[256];

    while ((res = recv (fd, buf, 256, 0)) == 256) {
    }
434
    TEST_ASSERT_NOT_EQUAL (-1, res);
435 436
}

437
void recv_all (int fd, uint8_t *data, size_t len)
438
{
439 440 441
    size_t received = 0;
    while (received < len) {
        int res = recv (fd, (char *) data, len, 0);
442
        TEST_ASSERT_GREATER_THAN_INT (0, res);
443 444 445 446

        data += res;
        received += res;
    }
447 448 449 450 451 452 453 454 455 456
}

void recv_greeting (int fd)
{
    uint8_t greeting[64];
    recv_all (fd, greeting, 64);
    //  TODO assert anything about the greeting received from the server?
}

int connect_exchange_greeting_and_send_hello (char *my_endpoint,
457
                                              zmq::curve_client_tools_t &tools)
458 459 460 461 462 463 464 465 466
{
    int s = connect_vanilla_socket (my_endpoint);

    send_greeting (s);
    recv_greeting (s);

    // send valid CURVE HELLO
    char hello[hello_length];
    int rc = tools.produce_hello (hello, 0);
467
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
468 469 470 471 472

    send_command (s, hello);
    return s;
}

473
void test_curve_security_invalid_initiate_wrong_length ()
474 475 476 477 478 479 480 481 482 483
{
    zmq::curve_client_tools_t tools = make_curve_client_tools ();

    int s = connect_exchange_greeting_and_send_hello (my_endpoint, tools);

    // receive but ignore WELCOME
    flush_read (s);

#ifdef ZMQ_BUILD_DRAFT_API
    int res = get_monitor_event_with_timeout (server_mon, NULL, NULL, timeout);
484
    TEST_ASSERT_EQUAL_INT (-1, res);
485 486
#else
    LIBZMQ_UNUSED (timeout);
487 488
#endif

489
    send (s, "\x04\x09\x08INITIATE");
490 491

#ifdef ZMQ_BUILD_DRAFT_API
492 493 494
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
495 496 497 498 499 500 501 502 503 504 505
#endif

    close (s);
}

int connect_exchange_greeting_and_hello_welcome (
  char *my_endpoint,
  void *server_mon,
  int timeout,
  zmq::curve_client_tools_t &tools)
{
506
    int s = connect_exchange_greeting_and_send_hello (my_endpoint, tools);
507 508 509 510

    // receive but ignore WELCOME
    uint8_t welcome[welcome_length + 2];
    recv_all (s, welcome, welcome_length + 2);
511 512

    uint8_t cn_precom[crypto_box_BEFORENMBYTES];
513
    int res = tools.process_welcome (welcome + 2, welcome_length, cn_precom);
514
    TEST_ASSERT_ZMQ_ERRNO (res == 0);
515 516 517

#ifdef ZMQ_BUILD_DRAFT_API
    res = get_monitor_event_with_timeout (server_mon, NULL, NULL, timeout);
518
    TEST_ASSERT_EQUAL_INT (-1, res);
519 520 521 522 523
#endif

    return s;
}

524
void test_curve_security_invalid_initiate_command_name ()
525 526 527 528 529
{
    zmq::curve_client_tools_t tools = make_curve_client_tools ();
    int s = connect_exchange_greeting_and_hello_welcome (
      my_endpoint, server_mon, timeout, tools);

530
    char initiate[257];
531 532 533 534 535 536 537
    tools.produce_initiate (initiate, 257, 1, NULL, 0);
    // modify command name
    initiate[5] = 'X';

    send_command (s, initiate);

#ifdef ZMQ_BUILD_DRAFT_API
538 539 540
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
541 542 543 544 545
#endif

    close (s);
}

546
void test_curve_security_invalid_initiate_command_encrypted_cookie ()
547 548 549 550 551
{
    zmq::curve_client_tools_t tools = make_curve_client_tools ();
    int s = connect_exchange_greeting_and_hello_welcome (
      my_endpoint, server_mon, timeout, tools);

552
    char initiate[257];
553 554 555 556 557 558 559
    tools.produce_initiate (initiate, 257, 1, NULL, 0);
    // make garbage from encrypted cookie
    initiate[30] = !initiate[30];

    send_command (s, initiate);

#ifdef ZMQ_BUILD_DRAFT_API
560 561 562
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
563 564 565 566 567
#endif

    close (s);
}

568
void test_curve_security_invalid_initiate_command_encrypted_content ()
569 570 571 572 573
{
    zmq::curve_client_tools_t tools = make_curve_client_tools ();
    int s = connect_exchange_greeting_and_hello_welcome (
      my_endpoint, server_mon, timeout, tools);

574
    char initiate[257];
575 576 577 578 579 580 581
    tools.produce_initiate (initiate, 257, 1, NULL, 0);
    // make garbage from encrypted content
    initiate[150] = !initiate[150];

    send_command (s, initiate);

#ifdef ZMQ_BUILD_DRAFT_API
582 583 584
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
585 586 587 588 589
#endif

    close (s);
}

590 591
void test_curve_security_invalid_keysize (void *ctx)
{
592
    //  Check return codes for invalid buffer sizes
593
    void *client = zmq_socket (ctx, ZMQ_DEALER);
594
    TEST_ASSERT_NOT_NULL (client);
595
    errno = 0;
596 597
    int rc =
      zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, valid_server_public, 123);
598 599
    assert (rc == -1 && errno == EINVAL);
    errno = 0;
600
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, valid_client_public, 123);
601 602
    assert (rc == -1 && errno == EINVAL);
    errno = 0;
603
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, valid_client_secret, 123);
604 605
    assert (rc == -1 && errno == EINVAL);
    rc = zmq_close (client);
606
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
607
}
608

609 610
// TODO why isn't this const?
char null_key[] = "0000000000000000000000000000000000000000";
611

612 613
void test_null_server_key ()
{
614
    //  Check CURVE security with a null server key
615
    //  This will be caught by the curve_server class, not passed to ZAP
616
    test_null_key (ctx, server, server_mon, my_endpoint, null_key,
617
                   valid_client_public, valid_client_secret);
618
}
619

620 621
void test_null_client_public_key ()
{
622
    //  Check CURVE security with a null client public key
623
    //  This will be caught by the curve_server class, not passed to ZAP
624
    test_null_key (ctx, server, server_mon, my_endpoint, valid_server_public,
625
                   null_key, valid_client_secret);
626
}
627

628 629 630
void test_null_client_secret_key ()
{
    //  Check CURVE security with a null client public key
631
    //  This will be caught by the curve_server class, not passed to ZAP
632
    test_null_key (ctx, server, server_mon, my_endpoint, valid_server_public,
633
                   valid_client_public, null_key);
634
}
635

636

637 638 639 640 641 642
int main (void)
{
    if (!zmq_has ("curve")) {
        printf ("CURVE encryption not installed, skipping test\n");
        return 0;
    }
643

644
    zmq::random_open ();
645

646
    setup_testutil_security_curve ();
647 648


649
    setup_test_environment ();
650

651 652 653 654 655 656 657 658 659
    UNITY_BEGIN ();
    RUN_TEST (test_curve_security_with_valid_credentials);
    RUN_TEST (test_null_server_key);
    RUN_TEST (test_null_client_public_key);
    RUN_TEST (test_null_client_secret_key);
    RUN_TEST (test_curve_security_with_bogus_client_credentials);
    RUN_TEST (test_curve_security_with_null_client_credentials);
    RUN_TEST (test_curve_security_with_plain_client_credentials);
    RUN_TEST (test_curve_security_unauthenticated_message);
660

661 662 663 664 665 666 667 668 669 670
    //  tests with misbehaving CURVE client
    RUN_TEST (test_curve_security_invalid_hello_wrong_length);
    RUN_TEST (test_curve_security_invalid_hello_command_name);
    RUN_TEST (test_curve_security_invalid_hello_version);
    RUN_TEST (test_curve_security_invalid_initiate_wrong_length);
    RUN_TEST (test_curve_security_invalid_initiate_command_name);
    RUN_TEST (test_curve_security_invalid_initiate_command_encrypted_cookie);
    RUN_TEST (test_curve_security_invalid_initiate_command_encrypted_content);

    // TODO this requires a deviating test setup, must be moved to a separate executable/fixture
671
    //  test with a large routing id (resulting in large metadata)
672
    fprintf (stderr,
673
             "test_curve_security_with_valid_credentials (large routing id)\n");
674 675
    setup_context_and_server_side (
      &ctx, &handler, &zap_thread, &server, &server_mon, my_endpoint,
676 677
      &zap_handler_large_routing_id, &socket_config_curve_server,
      &valid_server_secret, large_routing_id);
678
    test_curve_security_with_valid_credentials ();
679
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
680
                                      handler);
681

682 683
    ctx = zmq_ctx_new ();
    test_curve_security_invalid_keysize (ctx);
684
    int rc = zmq_ctx_term (ctx);
685
    TEST_ASSERT_ZMQ_ERRNO (rc == 0);
Ian Barber's avatar
Ian Barber committed
686

687 688
    zmq::random_close ();

689
    return UNITY_END ();
Ian Barber's avatar
Ian Barber committed
690
}