test_security_curve.cpp 27.9 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
const char large_identity[] = "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "0123456789012345678901234567890123456789"
                              "012345678901234";

56
#ifdef ZMQ_BUILD_DRAFT_API
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
// assert_* are macros rather than functions, to allow assertion failures be
// attributed to the causing source code line
#define assert_no_more_monitor_events_with_timeout(monitor, timeout)           \
    {                                                                          \
        int event_count = 0;                                                   \
        int event, err;                                                        \
        while ((event = get_monitor_event_with_timeout ((monitor), &err, NULL, \
                                                        (timeout)))            \
               != -1) {                                                        \
            ++event_count;                                                     \
            fprintf (stderr, "Unexpected event: %x (err = %i)\n", event, err); \
        }                                                                      \
        assert (event_count == 0);                                             \
    }

#endif
73

74 75 76 77 78
static void zap_handler_large_identity (void *ctx)
{
    zap_handler_generic (ctx, zap_ok, large_identity);
}

79 80 81 82 83 84 85
void expect_new_client_curve_bounce_fail (void *ctx,
                                          char *server_public,
                                          char *client_public,
                                          char *client_secret,
                                          char *my_endpoint,
                                          void *server)
{
86 87 88 89
    curve_client_data_t curve_client_data = {server_public, client_public,
                                             client_secret};
    expect_new_client_bounce_fail (
      ctx, my_endpoint, server, socket_config_curve_client, &curve_client_data);
90 91 92 93 94 95 96 97 98 99 100 101
}

void test_garbage_key(void *ctx,
                       void *server,
                       void *server_mon,
                       char *my_endpoint,
                       char *server_public,
                       char *client_public,
                       char *client_secret)
{
    expect_new_client_curve_bounce_fail (ctx, server_public, client_public,
                                         client_secret, my_endpoint, server);
102

103
#ifdef ZMQ_BUILD_DRAFT_API
104 105
    int handshake_failed_encryption_event_count =
      expect_monitor_event_multiple (server_mon,
106 107
                                     ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                     ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
108

109
    // handshake_failed_encryption_event_count should be at least two because 
110 111 112 113
    // 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)
114 115 116 117

    fprintf (stderr,
             "count of ZMQ_EVENT_HANDSHAKE_FAILED_ENCRYPTION events: %i\n",
             handshake_failed_encryption_event_count);
118 119 120 121 122 123
#endif
}

void test_curve_security_with_valid_credentials (
  void *ctx, char *my_endpoint, void *server, void *server_mon, int timeout)
{
124 125 126 127
    curve_client_data_t curve_client_data = {
      valid_server_public, valid_client_public, valid_client_secret};
    void *client = create_and_connect_client (
      ctx, my_endpoint, socket_config_curve_client, &curve_client_data);
128
    bounce (server, client);
129
    int rc = zmq_close (client);
MinRK's avatar
MinRK committed
130
    assert (rc == 0);
131

132
#ifdef ZMQ_BUILD_DRAFT_API
133
    int event = get_monitor_event_with_timeout (server_mon, NULL, NULL, -1);
134 135 136
    assert (event == ZMQ_EVENT_HANDSHAKE_SUCCEEDED);

    assert_no_more_monitor_events_with_timeout (server_mon, timeout);
137
#endif
138
}
139

140 141 142
void test_curve_security_with_bogus_client_credentials (
  void *ctx, char *my_endpoint, void *server, void *server_mon, int timeout)
{
143
    //  This must be caught by the ZAP handler
144 145 146
    char bogus_public [41];
    char bogus_secret [41];
    zmq_curve_keypair (bogus_public, bogus_secret);
147

148 149
    expect_new_client_curve_bounce_fail (ctx, valid_server_public, bogus_public,
                                         bogus_secret, my_endpoint, server);
150

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

    // there may be more than one ZAP request due to repeated attempts by the client
159 160
    assert (0 == event_count
            || 1 <= zmq_atomic_counter_value (zap_requests_handled));
161
}
162

163 164 165 166
void expect_zmtp_mechanism_mismatch (void *client,
                                     char *my_endpoint,
                                     void *server,
                                     void *server_mon)
167
{
168
    //  This must be caught by the curve_server class, not passed to ZAP
169
    int rc = zmq_connect (client, my_endpoint);
170 171 172 173
    assert (rc == 0);
    expect_bounce_fail (server, client);
    close_zero_linger (client);

174
#ifdef ZMQ_BUILD_DRAFT_API
175 176 177
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_MECHANISM_MISMATCH);
178
#endif
179 180

    assert (0 == zmq_atomic_counter_value (zap_requests_handled));
181
}
182

183 184 185 186 187 188 189 190
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);

191
    expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
192 193 194 195 196 197
}

void test_curve_security_with_plain_client_credentials (void *ctx,
                                                        char *my_endpoint,
                                                        void *server,
                                                        void *server_mon)
198 199
{
    void *client = zmq_socket (ctx, ZMQ_DEALER);
200
    assert (client);
201
    int rc = zmq_setsockopt (client, ZMQ_PLAIN_USERNAME, "admin", 5);
202 203 204
    assert (rc == 0);
    rc = zmq_setsockopt (client, ZMQ_PLAIN_PASSWORD, "password", 8);
    assert (rc == 0);
205

206
    expect_zmtp_mechanism_mismatch (client, my_endpoint, server, server_mon);
207
}
208

209
int connect_vanilla_socket (char *my_endpoint)
210
{
211
    int s;
212
    struct sockaddr_in ip4addr;
213

214
    unsigned short int port;
215
    int rc = sscanf (my_endpoint, "tcp://127.0.0.1:%hu", &port);
216 217
    assert (rc == 1);

218
    ip4addr.sin_family = AF_INET;
219
    ip4addr.sin_port = htons (port);
220
#if defined(ZMQ_HAVE_WINDOWS) && (_WIN32_WINNT < 0x0600)
221 222
    ip4addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
#else
223
    inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr);
224
#endif
225 226

    s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
227
    rc = connect (s, (struct sockaddr *) &ip4addr, sizeof (ip4addr));
228
    assert (rc > -1);
229 230 231 232 233 234 235 236 237
    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);
238 239 240 241
    // 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);
242

243 244
    zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout));
    char *buf = s_recv (server);
245 246 247 248
    if (buf != NULL) {
        printf ("Received unauthenticated message: %s\n", buf);
        assert (buf == NULL);
    }
249
    close (s);
250
}
251

252 253 254 255 256 257 258 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
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)
{
    int s = connect_vanilla_socket (my_endpoint);

    // send GREETING
    send_greeting (s);

    // send CURVE HELLO of wrong size
287
    send(s, "\x04\x06\x05HELLO");
288 289

#ifdef ZMQ_BUILD_DRAFT_API
290 291 292
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
293 294 295 296 297 298 299 300 301 302 303 304 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 367 368 369
#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)
{
    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
370 371 372
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 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)
{
    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
398 399 400
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_HELLO);
401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 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 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
#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,
                                     zmq::curve_client_tools_t &tools)
{
    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)
{
    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);
#endif

470
    send(s, "\x04\x09\x08INITIATE");
471 472

#ifdef ZMQ_BUILD_DRAFT_API
473 474 475
    expect_monitor_event_multiple (
      server_mon, ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
      ZMQ_PROTOCOL_ERROR_ZMTP_MALFORMED_COMMAND_INITIATE);
476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
#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);
    
494 495
    uint8_t cn_precom [crypto_box_BEFORENMBYTES];
    int res = tools.process_welcome (welcome + 2, welcome_length, cn_precom);
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522
    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)
{
    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
523 524 525
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_UNEXPECTED_COMMAND);
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
#endif

    close (s);
}

void test_curve_security_invalid_initiate_command_encrypted_cookie (
  char *my_endpoint, void *server, void *server_mon, int timeout)
{
    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
546 547 548
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
#endif

    close (s);
}

void test_curve_security_invalid_initiate_command_encrypted_content (
  char *my_endpoint, void *server, void *server_mon, int timeout)
{
    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
569 570 571
    expect_monitor_event_multiple (server_mon,
                                   ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL,
                                   ZMQ_PROTOCOL_ERROR_ZMTP_CRYPTOGRAPHIC);
572 573 574 575 576
#endif

    close (s);
}

577 578
void test_curve_security_invalid_keysize (void *ctx)
{
579
    //  Check return codes for invalid buffer sizes
580
    void *client = zmq_socket (ctx, ZMQ_DEALER);
581 582
    assert (client);
    errno = 0;
583
    int rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, valid_server_public, 123);
584 585
    assert (rc == -1 && errno == EINVAL);
    errno = 0;
586
    rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, valid_client_public, 123);
587 588
    assert (rc == -1 && errno == EINVAL);
    errno = 0;
589
    rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, valid_client_secret, 123);
590 591 592
    assert (rc == -1 && errno == EINVAL);
    rc = zmq_close (client);
    assert (rc == 0);
593
}
594

595 596 597 598 599 600 601
int main (void)
{
    if (!zmq_has ("curve")) {
        printf ("CURVE encryption not installed, skipping test\n");
        return 0;
    }

602 603
    zmq::random_open ();

604
    setup_testutil_security_curve ();
605

606 607 608 609 610 611 612 613 614 615 616
    int timeout = 250;

    setup_test_environment ();

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

617
    fprintf (stderr, "test_curve_security_with_valid_credentials\n");
618 619 620 621
    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);
622
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
623
                                      handler);
624

625
    char garbage_key[] = "0000000000000000000000000000000000000000";
626 627 628 629 630 631 632

    //  Check CURVE security with a garbage server key
    //  This will be caught by the curve_server class, not passed to ZAP
    fprintf (stderr, "test_garbage_server_key\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_garbage_key (ctx, server, server_mon, my_endpoint, garbage_key,
633
                      valid_client_public, valid_client_secret);
634
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
635
                                      handler);
636 637 638 639 640 641

    //  Check CURVE security with a garbage client public key
    //  This will be caught by the curve_server class, not passed to ZAP
    fprintf (stderr, "test_garbage_client_public_key\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
642 643
    test_garbage_key (ctx, server, server_mon, my_endpoint, valid_server_public,
                      garbage_key, valid_client_secret);
644
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
645
                                      handler);
646 647 648 649 650 651

    //  Check CURVE security with a garbage client secret key
    //  This will be caught by the curve_server class, not passed to ZAP
    fprintf (stderr, "test_garbage_client_secret_key\n");
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
652 653
    test_garbage_key (ctx, server, server_mon, my_endpoint, valid_server_public,
                      valid_client_public, garbage_key);
654
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
655
                                      handler);
656

657
    fprintf (stderr, "test_curve_security_with_bogus_client_credentials\n");
658 659 660 661
    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);
662
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
663
                                      handler);
664
    fprintf (stderr, "test_curve_security_with_null_client_credentials\n");
665 666 667 668
    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);
669
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
670
                                      handler);
671

672
    fprintf (stderr, "test_curve_security_with_plain_client_credentials\n");
673 674
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
675 676
    test_curve_security_with_plain_client_credentials (ctx, my_endpoint, server,
                                                       server_mon);
677
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
678
                                      handler);
679
    fprintf (stderr, "test_curve_security_unauthenticated_message\n");
680 681 682
    setup_context_and_server_side (&ctx, &handler, &zap_thread, &server,
                                   &server_mon, my_endpoint);
    test_curve_security_unauthenticated_message (my_endpoint, server, timeout);
683
    shutdown_context_and_server_side (ctx, zap_thread, server, server_mon,
684
                                      handler);
685

686
    //  tests with misbehaving CURVE client
687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 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
    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);

742 743
    //  test with a large identity (resulting in large metadata)
    fprintf (stderr, "test_curve_security_with_valid_credentials (large identity)\n");
744 745
    setup_context_and_server_side (
      &ctx, &handler, &zap_thread, &server, &server_mon, my_endpoint,
746
      &zap_handler_large_identity, &socket_config_curve_server, &valid_server_secret,
747
      large_identity);
748 749 750 751 752
    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);

753 754
    ctx = zmq_ctx_new ();
    test_curve_security_invalid_keysize (ctx);
755
    int rc = zmq_ctx_term (ctx);
756
    assert (rc == 0);
Ian Barber's avatar
Ian Barber committed
757

758 759
    zmq::random_close ();

Ian Barber's avatar
Ian Barber committed
760 761
    return 0;
}