/*
 * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <stdio.h>
#include <string.h>

#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/ssl.h>

#include "handshake_helper.h"
#include "ssl_test_ctx.h"
#include "testutil.h"
#include "test_main_custom.h"

static CONF *conf = NULL;

/* Currently the section names are of the form test-<number>, e.g. test-15. */
#define MAX_TESTCASE_NAME_LENGTH 100

static const char *print_alert(int alert)
{
    return alert ? SSL_alert_desc_string_long(alert) : "no alert";
}

static int check_result(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    if (result->result != test_ctx->expected_result) {
        fprintf(stderr, "ExpectedResult mismatch: expected %s, got %s.\n",
                ssl_test_result_name(test_ctx->expected_result),
                ssl_test_result_name(result->result));
        return 0;
    }
    return 1;
}

static int check_alerts(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    if (result->client_alert_sent != result->client_alert_received) {
        fprintf(stderr, "Client sent alert %s but server received %s\n.",
                print_alert(result->client_alert_sent),
                print_alert(result->client_alert_received));
        /*
         * We can't bail here because the peer doesn't always get far enough
         * to process a received alert. Specifically, in protocol version
         * negotiation tests, we have the following scenario.
         * Client supports TLS v1.2 only; Server supports TLS v1.1.
         * Client proposes TLS v1.2; server responds with 1.1;
         * Client now sends a protocol alert, using TLS v1.2 in the header.
         * The server, however, rejects the alert because of version mismatch
         * in the record layer; therefore, the server appears to never
         * receive the alert.
         */
        /* return 0; */
    }

    if (result->server_alert_sent != result->server_alert_received) {
        fprintf(stderr, "Server sent alert %s but client received %s\n.",
                print_alert(result->server_alert_sent),
                print_alert(result->server_alert_received));
        /* return 0; */
    }

    /* Tolerate an alert if one wasn't explicitly specified in the test. */
    if (test_ctx->expected_client_alert
        /*
         * The info callback alert value is computed as
         * (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]
         * where the low byte is the alert code and the high byte is other stuff.
         */
        && (result->client_alert_sent & 0xff) != test_ctx->expected_client_alert) {
        fprintf(stderr, "ClientAlert mismatch: expected %s, got %s.\n",
                print_alert(test_ctx->expected_client_alert),
                print_alert(result->client_alert_sent));
        return 0;
    }

    if (test_ctx->expected_server_alert
        && (result->server_alert_sent & 0xff) != test_ctx->expected_server_alert) {
        fprintf(stderr, "ServerAlert mismatch: expected %s, got %s.\n",
                print_alert(test_ctx->expected_server_alert),
                print_alert(result->server_alert_sent));
        return 0;
    }

    if (result->client_num_fatal_alerts_sent > 1) {
        fprintf(stderr, "Client sent %d fatal alerts.\n",
                result->client_num_fatal_alerts_sent);
        return 0;
    }
    if (result->server_num_fatal_alerts_sent > 1) {
        fprintf(stderr, "Server sent %d alerts.\n",
                result->server_num_fatal_alerts_sent);
        return 0;
    }
    return 1;
}

static int check_protocol(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    if (result->client_protocol != result->server_protocol) {
        fprintf(stderr, "Client has protocol %s but server has %s\n.",
                ssl_protocol_name(result->client_protocol),
                ssl_protocol_name(result->server_protocol));
        return 0;
    }

    if (test_ctx->expected_protocol) {
        if (result->client_protocol != test_ctx->expected_protocol) {
            fprintf(stderr, "Protocol mismatch: expected %s, got %s.\n",
                    ssl_protocol_name(test_ctx->expected_protocol),
                    ssl_protocol_name(result->client_protocol));
            return 0;
        }
    }
    return 1;
}

static int check_servername(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    if (result->servername != test_ctx->expected_servername) {
      fprintf(stderr, "Client ServerName mismatch, expected %s, got %s\n.",
              ssl_servername_name(test_ctx->expected_servername),
              ssl_servername_name(result->servername));
      return 0;
    }
  return 1;
}

static int check_session_ticket(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    if (test_ctx->session_ticket_expected == SSL_TEST_SESSION_TICKET_IGNORE)
        return 1;
    if (result->session_ticket != test_ctx->session_ticket_expected) {
        fprintf(stderr, "Client SessionTicketExpected mismatch, expected %s, got %s\n.",
                ssl_session_ticket_name(test_ctx->session_ticket_expected),
                ssl_session_ticket_name(result->session_ticket));
        return 0;
    }
    return 1;
}

static int check_compression(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    if (result->compression != test_ctx->compression_expected) {
        fprintf(stderr, "Client CompressionExpected mismatch, expected %d, got %d\n.",
                test_ctx->compression_expected,
                result->compression);
        return 0;
    }
    return 1;
}
#ifndef OPENSSL_NO_NEXTPROTONEG
static int check_npn(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    int ret = 1;
    ret &= strings_equal("NPN Negotiated (client vs server)",
                         result->client_npn_negotiated,
                         result->server_npn_negotiated);
    ret &= strings_equal("ExpectedNPNProtocol",
                         test_ctx->expected_npn_protocol,
                         result->client_npn_negotiated);
    return ret;
}
#endif

static int check_alpn(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    int ret = 1;
    ret &= strings_equal("ALPN Negotiated (client vs server)",
                         result->client_alpn_negotiated,
                         result->server_alpn_negotiated);
    ret &= strings_equal("ExpectedALPNProtocol",
                         test_ctx->expected_alpn_protocol,
                         result->client_alpn_negotiated);
    return ret;
}

static int check_resumption(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    if (result->client_resumed != result->server_resumed) {
        fprintf(stderr, "Resumption mismatch (client vs server): %d vs %d\n",
                result->client_resumed, result->server_resumed);
        return 0;
    }
    if (result->client_resumed != test_ctx->resumption_expected) {
        fprintf(stderr, "ResumptionExpected mismatch: %d vs %d\n",
                test_ctx->resumption_expected, result->client_resumed);
        return 0;
    }
    return 1;
}

static int check_nid(const char *name, int expected_nid, int nid)
{
    if (expected_nid == 0 || expected_nid == nid)
        return 1;
    fprintf(stderr, "%s type mismatch, %s vs %s\n",
            name, OBJ_nid2ln(expected_nid),
            nid == NID_undef ? "absent" : OBJ_nid2ln(nid));
    return 0;
}

static int check_tmp_key(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    return check_nid("Tmp key", test_ctx->expected_tmp_key_type,
                     result->tmp_key_type);
}

static int check_server_cert_type(HANDSHAKE_RESULT *result,
                                  SSL_TEST_CTX *test_ctx)
{
    return check_nid("Server certificate", test_ctx->expected_server_cert_type,
                     result->server_cert_type);
}

static int check_server_sign_hash(HANDSHAKE_RESULT *result,
                                  SSL_TEST_CTX *test_ctx)
{
    return check_nid("Server signing hash", test_ctx->expected_server_sign_hash,
                     result->server_sign_hash);
}

static int check_server_sign_type(HANDSHAKE_RESULT *result,
                                  SSL_TEST_CTX *test_ctx)
{
    return check_nid("Server signing", test_ctx->expected_server_sign_type,
                     result->server_sign_type);
}

static int check_client_cert_type(HANDSHAKE_RESULT *result,
                                  SSL_TEST_CTX *test_ctx)
{
    return check_nid("Client certificate", test_ctx->expected_client_cert_type,
                     result->client_cert_type);
}

static int check_client_sign_hash(HANDSHAKE_RESULT *result,
                                  SSL_TEST_CTX *test_ctx)
{
    return check_nid("Client signing hash", test_ctx->expected_client_sign_hash,
                     result->client_sign_hash);
}

static int check_client_sign_type(HANDSHAKE_RESULT *result,
                                  SSL_TEST_CTX *test_ctx)
{
    return check_nid("Client signing", test_ctx->expected_client_sign_type,
                     result->client_sign_type);
}

/*
 * This could be further simplified by constructing an expected
 * HANDSHAKE_RESULT, and implementing comparison methods for
 * its fields.
 */
static int check_test(HANDSHAKE_RESULT *result, SSL_TEST_CTX *test_ctx)
{
    int ret = 1;
    ret &= check_result(result, test_ctx);
    ret &= check_alerts(result, test_ctx);
    if (result->result == SSL_TEST_SUCCESS) {
        ret &= check_protocol(result, test_ctx);
        ret &= check_servername(result, test_ctx);
        ret &= check_session_ticket(result, test_ctx);
        ret &= check_compression(result, test_ctx);
        ret &= (result->session_ticket_do_not_call == 0);
#ifndef OPENSSL_NO_NEXTPROTONEG
        ret &= check_npn(result, test_ctx);
#endif
        ret &= check_alpn(result, test_ctx);
        ret &= check_resumption(result, test_ctx);
        ret &= check_tmp_key(result, test_ctx);
        ret &= check_server_cert_type(result, test_ctx);
        ret &= check_server_sign_hash(result, test_ctx);
        ret &= check_server_sign_type(result, test_ctx);
        ret &= check_client_cert_type(result, test_ctx);
        ret &= check_client_sign_hash(result, test_ctx);
        ret &= check_client_sign_type(result, test_ctx);
    }
    return ret;
}

static int test_handshake(int idx)
{
    int ret = 0;
    SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL,
        *resume_server_ctx = NULL, *resume_client_ctx = NULL;
    SSL_TEST_CTX *test_ctx = NULL;
    HANDSHAKE_RESULT *result = NULL;
    char test_app[MAX_TESTCASE_NAME_LENGTH];

    BIO_snprintf(test_app, sizeof(test_app), "test-%d", idx);

    test_ctx = SSL_TEST_CTX_create(conf, test_app);
    if (test_ctx == NULL)
        goto err;

#ifndef OPENSSL_NO_DTLS
    if (test_ctx->method == SSL_TEST_METHOD_DTLS) {
        server_ctx = SSL_CTX_new(DTLS_server_method());
        if (test_ctx->extra.server.servername_callback !=
            SSL_TEST_SERVERNAME_CB_NONE) {
            server2_ctx = SSL_CTX_new(DTLS_server_method());
            TEST_check(server2_ctx != NULL);
        }
        client_ctx = SSL_CTX_new(DTLS_client_method());
        if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) {
            resume_server_ctx = SSL_CTX_new(DTLS_server_method());
            resume_client_ctx = SSL_CTX_new(DTLS_client_method());
            TEST_check(resume_server_ctx != NULL);
            TEST_check(resume_client_ctx != NULL);
        }
    }
#endif
    if (test_ctx->method == SSL_TEST_METHOD_TLS) {
        server_ctx = SSL_CTX_new(TLS_server_method());
        /* SNI on resumption isn't supported/tested yet. */
        if (test_ctx->extra.server.servername_callback !=
            SSL_TEST_SERVERNAME_CB_NONE) {
            server2_ctx = SSL_CTX_new(TLS_server_method());
            TEST_check(server2_ctx != NULL);
        }
        client_ctx = SSL_CTX_new(TLS_client_method());

        if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) {
            resume_server_ctx = SSL_CTX_new(TLS_server_method());
            resume_client_ctx = SSL_CTX_new(TLS_client_method());
            TEST_check(resume_server_ctx != NULL);
            TEST_check(resume_client_ctx != NULL);
        }
    }

    TEST_check(server_ctx != NULL);
    TEST_check(client_ctx != NULL);

    TEST_check(CONF_modules_load(conf, test_app, 0) > 0);

    if (!SSL_CTX_config(server_ctx, "server")
        || !SSL_CTX_config(client_ctx, "client")) {
        goto err;
    }

    if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2"))
        goto err;
    if (resume_server_ctx != NULL
        && !SSL_CTX_config(resume_server_ctx, "resume-server"))
        goto err;
    if (resume_client_ctx != NULL
        && !SSL_CTX_config(resume_client_ctx, "resume-client"))
        goto err;

    result = do_handshake(server_ctx, server2_ctx, client_ctx,
                          resume_server_ctx, resume_client_ctx, test_ctx);

    ret = check_test(result, test_ctx);

err:
    CONF_modules_unload(0);
    SSL_CTX_free(server_ctx);
    SSL_CTX_free(server2_ctx);
    SSL_CTX_free(client_ctx);
    SSL_CTX_free(resume_server_ctx);
    SSL_CTX_free(resume_client_ctx);
    SSL_TEST_CTX_free(test_ctx);
    HANDSHAKE_RESULT_free(result);
    return ret;
}

int test_main(int argc, char **argv)
{
    int result = 0;
    long num_tests;

    if (argc != 2)
        return 1;

    conf = NCONF_new(NULL);
    TEST_check(conf != NULL);

    /* argv[1] should point to the test conf file */
    TEST_check(NCONF_load(conf, argv[1], NULL) > 0);

    TEST_check(NCONF_get_number_e(conf, NULL, "num_tests", &num_tests));

    ADD_ALL_TESTS(test_handshake, (int)(num_tests));
    result = run_tests(argv[0]);

    NCONF_free(conf);
    return result;
}
