test_security_curve.cpp 28.2 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
#if defined (ZMQ_HAVE_WINDOWS)
33 34 35 36
#  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

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

48 49 50 51 52 53 54 55 56 57 58 59 60
const char large_identity[] = "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "012345678901234";

static void zap_handler_large_identity (void *ctx)
{
    zap_handler_generic (ctx, zap_ok, large_identity);
}

61 62 63 64 65
void expect_new_client_curve_bounce_fail (void *ctx,
                                          char *server_public,
                                          char *client_public,
                                          char *client_secret,
                                          char *my_endpoint,
66 67
                                          void *server,
                                          void **client_mon = NULL)
68
{
69 70
    curve_client_data_t curve_client_data = {server_public, client_public,
                                             client_secret};
71 72 73
    expect_new_client_bounce_fail (ctx, my_endpoint, server,
                                   socket_config_curve_client,
                                   &curve_client_data, client_mon);
74 75
}

76 77 78 79 80 81 82
void test_null_key (void *ctx,
                    void *server,
                    void *server_mon,
                    char *my_endpoint,
                    char *server_public,
                    char *client_public,
                    char *client_secret)
83 84 85
{
    expect_new_client_curve_bounce_fail (ctx, server_public, client_public,
                                         client_secret, my_endpoint, server);
86

87
#ifdef ZMQ_BUILD_DRAFT_API
88 89
    int handshake_failed_encryption_event_count =
      expect_monitor_event_multiple (server_mon,
90 91
                                     ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                     ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
92

93
    // handshake_failed_encryption_event_count should be at least two because 
94 95 96 97
    // expect_bounce_fail involves two exchanges
    // 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 
    // long)
98 99

    fprintf (stderr,
100 101 102
             "count of "
             "ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL/"
             "ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC events: %i\n",
103
             handshake_failed_encryption_event_count);
104 105 106 107 108 109
#endif
}

void test_curve_security_with_valid_credentials (
  void *ctx, char *my_endpoint, void *server, void *server_mon, int timeout)
{
110 111
    curve_client_data_t curve_client_data = {
      valid_server_public, valid_client_public, valid_client_secret};
112 113 114 115
    void *client_mon;
    void *client =
      create_and_connect_client (ctx, my_endpoint, socket_config_curve_client,
                                 &curve_client_data, &client_mon);
116
    bounce (server, client);
117
    int rc = zmq_close (client);
MinRK's avatar
MinRK committed
118
    assert (rc == 0);
119

120
#ifdef ZMQ_BUILD_DRAFT_API
121
    int event = get_monitor_event_with_timeout (server_mon, NULL, NULL, -1);
122 123 124
    assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);

    assert_no_more_monitor_events_with_timeout (server_mon, timeout);
125 126 127 128 129 130 131 132

    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);
    assert (rc == 0);
133
#endif
134
}
135

136 137 138
void test_curve_security_with_bogus_client_credentials (
  void *ctx, char *my_endpoint, void *server, void *server_mon, int timeout)
{
139 140
    LIBZMQ_UNUSED (timeout);

141
    //  This must be caught by the ZAP handler
142 143 144
    char bogus_public [41];
    char bogus_secret [41];
    zmq_curve_keypair (bogus_public, bogus_secret);
145

146
    void *client_mon;
147
    expect_new_client_curve_bounce_fail (ctx, valid_server_public, bogus_public,
148 149
                                         bogus_secret, my_endpoint, server,
                                         &client_mon);
150

151
    int server_event_count = 0; 
152
#ifdef ZMQ_BUILD_DRAFT_API
153
    server_event_count = expect_monitor_event_multiple (
154
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400);
155 156 157
    assert (server_event_count <= 1);

    int client_event_count = expect_monitor_event_multiple (
158 159 160 161
      client_mon, ZMQ_EVENT_HANDSHAKE_FAILED_AUTH, 400, true);
    // this should actually be client_event_count == 1, but this is not always
    // true, see https://github.com/zeromq/libzmq/issues/2705
    assert (client_event_count <= 1);
162 163 164

    int rc = zmq_close (client_mon);
    assert (rc == 0);
165
#endif
166 167

    // there may be more than one ZAP request due to repeated attempts by the client
168
    assert (0 == server_event_count
169
            || 1 <= zmq_atomic_counter_value (zap_requests_handled));
170
}
171

172 173 174 175
void expect_zmtp_mechanism_mismatch (void *client,
                                     char *my_endpoint,
                                     void *server,
                                     void *server_mon)
176
{
177
    //  This must be caught by the curve_server class, not passed to ZAP
178
    int rc = zmq_connect (client, my_endpoint);
179 180 181 182
    assert (rc == 0);
    expect_bounce_fail (server, client);
    close_zero_linger (client);

183
#ifdef ZMQ_BUILD_DRAFT_API
184 185 186
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
187
#endif
188 189

    assert (0 == zmq_atomic_counter_value (zap_requests_handled));
190
}
191

192 193 194 195 196 197 198 199
void test_curve_security_with_null_client_credentials (void *ctx,
                                                       char *my_endpoint,
                                                       void *server,
                                                       void *server_mon)
{
    void *client = zmq_socket (ctx, ZMQ_DEALER);
    assert (client);

200
    expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
201 202 203 204 205 206
}

void test_curve_security_with_plain_client_credentials (void *ctx,
                                                        char *my_endpoint,
                                                        void *server,
                                                        void *server_mon)
207 208
{
    void *client = zmq_socket (ctx, ZMQ_DEALER);
209
    assert (client);
210
    int rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5);
211 212 213
    assert (rc == 0);
    rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8);
    assert (rc == 0);
214

215
    expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
216
}
217

218
int connect_vanilla_socket (char *my_endpoint)
219
{
220
    int s;
221
    struct sockaddr_in ip4addr;
222

223
    unsigned short int port;
224
    int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port);
225 226
    assert (rc == 1);

227
    ip4addr.sin_family = AF_INET;
228
    ip4addr.sin_port = htons (port);
229
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
230 231
    ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
#else
232
    inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
233
#endif
234 235

    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
236
    rc = connect (s, (struct sockaddr *) &ip4addr, sizeof (ip4addr));
237
    assert (rc > -1);
238 239 240 241 242 243 244 245 246
    return s;
}

void test_curve_security_unauthenticated_message (char *my_endpoint,
                                                  void *server,
                                                  int timeout)
{
    // Unauthenticated messages from a vanilla socket shouldn't be received
    int s = connect_vanilla_socket(my_endpoint);
247 248 249 250
    // 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);
251

252 253
    zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
    char *buf = s_recv (server);
254 255 256 257
    if (buf != NULL) {
        printf ("Received unauthenticated message: %s\n", buf);
        assert (buf == NULL);
    }
258
    close (s);
259
}
260

261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
void send_all (int fd, const char *data, size_t size)
{
    while (size > 0) {
        int res = send (fd, data, size, 0);
        assert (res > 0);
        size -= res;
        data += res;
    }
}

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

void send_greeting(int s)
{
    send (s, "\xff\0\0\0\0\0\0\0\0\x7f"); // signature
    send (s, "\x03\x00"); // version 3.0
    send (s, "CURVE\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); // mechanism CURVE
    send (s, "\0"); // as-server == false
    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");
}

void test_curve_security_invalid_hello_wrong_length (char *my_endpoint,
                                                     void *server,
                                                     void *server_mon,
                                                     int timeout)
{
290 291 292
    LIBZMQ_UNUSED (server);
    LIBZMQ_UNUSED (timeout);

293 294 295 296 297 298
    int s = connect_vanilla_socket (my_endpoint);

    // send GREETING
    send_greeting (s);

    // send CURVE HELLO of wrong size
299
    send(s, "\x04\x06\x05HELLO");
300 301

#ifdef ZMQ_BUILD_DRAFT_API
302 303 304
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 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 365 366
#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])
{
  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);
}

void test_curve_security_invalid_hello_command_name (char *my_endpoint,
                                                     void *server,
                                                     void *server_mon,
                                                     int timeout)
{
367 368 369
    LIBZMQ_UNUSED (server);
    LIBZMQ_UNUSED (timeout);

370 371 372 373 374 375 376 377 378 379 380 381 382 383 384
    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);
    assert (rc == 0);
    hello[5] = 'X';

    send_command(s, hello);

#ifdef ZMQ_BUILD_DRAFT_API
385 386 387
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
388 389 390 391 392 393 394 395 396 397
#endif

    close (s);
}

void test_curve_security_invalid_hello_version (char *my_endpoint,
                                                void *server,
                                                void *server_mon,
                                                int timeout)
{
398 399 400
    LIBZMQ_UNUSED (server);
    LIBZMQ_UNUSED (timeout);

401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
    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);
    assert (rc == 0);
    hello[6] = 2;

    send_command (s, hello);

#ifdef ZMQ_BUILD_DRAFT_API
416 417 418
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454
#endif

    close (s);
}

void flush_read(int fd)
{
    int res;
    char buf[256];

    while ((res = recv (fd, buf, 256, 0)) == 256) {
    }
    assert (res != -1);
}

void recv_all(int fd, uint8_t *data, size_t len)
{
  size_t received = 0;
  while (received < len)
  {
    int res = recv(fd, (char*)data, len, 0);
    assert(res > 0);

    data += res;
    received += res;
  }
}

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,
455
                                              zmq::curve_client_tools_t &tools)
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475
{
    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);
    assert (rc == 0);

    send_command (s, hello);
    return s;
}

void test_curve_security_invalid_initiate_length (char *my_endpoint,
                                                  void *server,
                                                  void *server_mon,
                                                  int timeout)
{
476 477
    LIBZMQ_UNUSED (server);

478 479 480 481 482 483 484 485 486 487
    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);
    assert (res == -1);
488 489
#else
    LIBZMQ_UNUSED (timeout);
490 491
#endif

492
    send(s, "\x04\x09\x08INITIATE");
493 494

#ifdef ZMQ_BUILD_DRAFT_API
495 496 497
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
#endif

    close (s);
}

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

    // receive but ignore WELCOME
    uint8_t welcome[welcome_length + 2];
    recv_all (s, welcome, welcome_length + 2);
    
516 517
    uint8_t cn_precom [crypto_box_BEFORENMBYTES];
    int res = tools.process_welcome (welcome + 2, welcome_length, cn_precom);
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
    assert (res == 0);

#ifdef ZMQ_BUILD_DRAFT_API
    res = get_monitor_event_with_timeout (server_mon, NULL, NULL, timeout);
    assert (res == -1);
#endif

    return s;
}

void test_curve_security_invalid_initiate_command_name (char *my_endpoint,
                                                        void *server,
                                                        void *server_mon,
                                                        int timeout)
{
533 534
    LIBZMQ_UNUSED (server);

535 536 537 538 539 540 541 542 543 544 545 546
    zmq::curve_client_tools_t tools = make_curve_client_tools ();
    int s = connect_exchange_greeting_and_hello_welcome (
      my_endpoint, server_mon, timeout, tools);

    char initiate [257];
    tools.produce_initiate (initiate, 257, 1, NULL, 0);
    // modify command name
    initiate[5] = 'X';

    send_command (s, initiate);

#ifdef ZMQ_BUILD_DRAFT_API
547 548 549
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
550 551 552 553 554 555 556 557
#endif

    close (s);
}

void test_curve_security_invalid_initiate_command_encrypted_cookie (
  char *my_endpoint, void *server, void *server_mon, int timeout)
{
558 559
    LIBZMQ_UNUSED (server);

560 561 562 563 564 565 566 567 568 569 570 571
    zmq::curve_client_tools_t tools = make_curve_client_tools ();
    int s = connect_exchange_greeting_and_hello_welcome (
      my_endpoint, server_mon, timeout, tools);

    char initiate [257];
    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
572 573 574
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
575 576 577 578 579 580 581 582
#endif

    close (s);
}

void test_curve_security_invalid_initiate_command_encrypted_content (
  char *my_endpoint, void *server, void *server_mon, int timeout)
{
583 584
    LIBZMQ_UNUSED (server);

585 586 587 588 589 590 591 592 593 594 595 596
    zmq::curve_client_tools_t tools = make_curve_client_tools ();
    int s = connect_exchange_greeting_and_hello_welcome (
      my_endpoint, server_mon, timeout, tools);

    char initiate [257];
    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
597 598 599
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
600 601 602 603 604
#endif

    close (s);
}

605 606
void test_curve_security_invalid_keysize (void *ctx)
{
607
    //  Check return codes for invalid buffer sizes
608
    void *client = zmq_socket (ctx, ZMQ_DEALER);
609 610
    assert (client);
    errno = 0;
611
    int rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, valid_server_public, 123);
612 613
    assert (rc == -1 && errno == EINVAL);
    errno = 0;
614
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, valid_client_public, 123);
615 616
    assert (rc == -1 && errno == EINVAL);
    errno = 0;
617
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, valid_client_secret, 123);
618 619 620
    assert (rc == -1 && errno == EINVAL);
    rc = zmq_close (client);
    assert (rc == 0);
621
}
622

623 624 625 626 627 628 629
int main (void)
{
    if (!zmq_has ("curve")) {
        printf ("CURVE encryption not installed, skipping test\n");
        return 0;
    }

630 631
    zmq::random_open ();

632
    setup_testutil_security_curve ();
633

634 635 636 637 638 639 640 641 642 643 644
    int timeout = 250;

    setup_test_environment ();

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

645
    fprintf (stderr, "test_curve_security_with_valid_credentials\n");
646 647 648 649
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_with_valid_credentials (ctx, my_endpoint, server,
                                                server_mon, timeout);
650
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
651
                                      handler);
652

653
    char null_key[] = "0000000000000000000000000000000000000000";
654

655
    //  Check CURVE security with a null server key
656
    //  This will be caught by the curve_server class, not passed to ZAP
657
    fprintf (stderr, "test_null_key (server)\n");
658 659
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
660
    test_null_key (ctx, server, server_mon, my_endpoint, null_key,
661
                      valid_client_public, valid_client_secret);
662
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
663
                                      handler);
664

665
    //  Check CURVE security with a null client public key
666
    //  This will be caught by the curve_server class, not passed to ZAP
667
    fprintf (stderr, "test_null_key (client public)\n");
668 669
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
670 671
    test_null_key (ctx, server, server_mon, my_endpoint, valid_server_public,
                      null_key, valid_client_secret);
672
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
673
                                      handler);
674

675
    //  Check CURVE security with a null client secret key
676
    //  This will be caught by the curve_server class, not passed to ZAP
677
    fprintf (stderr, "test_null_key (client secret)\n");
678 679
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
680 681
    test_null_key (ctx, server, server_mon, my_endpoint, valid_server_public,
                      valid_client_public, null_key);
682
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
683
                                      handler);
684

685
    fprintf (stderr, "test_curve_security_with_bogus_client_credentials\n");
686 687 688 689
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_with_bogus_client_credentials (ctx, my_endpoint, server,
                                                       server_mon, timeout);
690
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
691
                                      handler);
692

693
    fprintf (stderr, "test_curve_security_with_null_client_credentials\n");
694 695 696 697
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_with_null_client_credentials (ctx, my_endpoint, server,
                                                      server_mon);
698
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
699
                                      handler);
700

701
    fprintf (stderr, "test_curve_security_with_plain_client_credentials\n");
702 703
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
704 705
    test_curve_security_with_plain_client_credentials (ctx, my_endpoint, server,
                                                       server_mon);
706
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
707
                                      handler);
708
    fprintf (stderr, "test_curve_security_unauthenticated_message\n");
709 710 711
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_unauthenticated_message (my_endpoint, server, timeout);
712
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
713
                                      handler);
714

715
    //  tests with misbehaving CURVE client
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770
    fprintf (stderr, "test_curve_security_invalid_hello_wrong_length\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_invalid_hello_wrong_length (my_endpoint, server,
                                                    server_mon, timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);
    fprintf (stderr, "test_curve_security_invalid_hello_command_name\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_invalid_hello_command_name (my_endpoint, server,
                                                    server_mon, timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);

    fprintf (stderr, "test_curve_security_invalid_hello_command_version\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_invalid_hello_version (my_endpoint, server, server_mon,
                                               timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);

    fprintf (stderr, "test_curve_security_invalid_initiate_command_length\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_invalid_initiate_length (my_endpoint, server,
                                                 server_mon, timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);

    fprintf (stderr, "test_curve_security_invalid_initiate_command_name\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_invalid_initiate_command_name (my_endpoint, server,
                                                       server_mon, timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);

    fprintf (stderr, "test_curve_security_invalid_initiate_command_encrypted_cookie\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_invalid_initiate_command_encrypted_cookie (
      my_endpoint, server, server_mon, timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);

    fprintf (stderr, "test_curve_security_invalid_initiate_command_encrypted_content\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_invalid_initiate_command_encrypted_content (
      my_endpoint, server, server_mon, timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
                                      handler);

771 772
    //  test with a large identity (resulting in large metadata)
    fprintf (stderr, "test_curve_security_with_valid_credentials (large identity)\n");
773 774
    setup_context_and_server_side (
      &ctx, &handler, &zap_thread, &server, &server_mon, my_endpoint,
775
      &zap_handler_large_identity, &socket_config_curve_server, &valid_server_secret,
776
      large_identity);
777 778 779 780 781
    test_curve_security_with_valid_credentials (ctx, my_endpoint, server,
                                                server_mon, timeout);
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
            handler);

782 783
    ctx = zmq_ctx_new ();
    test_curve_security_invalid_keysize (ctx);
784
    int rc = zmq_ctx_term (ctx);
785
    assert (rc == 0);
Ian Barber's avatar
Ian Barber committed
786

787 788
    zmq::random_close ();

Ian Barber's avatar
Ian Barber committed
789 790
    return 0;
}