/*
 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright 2017 BaishanCloud. 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 <string.h>

#include <openssl/opensslconf.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/evp.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <time.h>

#include "../ssl/packet_locl.h"

#include "testutil.h"
#include "internal/nelem.h"

#define CLIENT_VERSION_LEN      2

static const char *host = "dummy-host";

static int get_sni_from_client_hello(BIO *bio, char **sni)
{
    long len;
    unsigned char *data;
    PACKET pkt = {0}, pkt2 = {0}, pkt3 = {0}, pkt4 = {0}, pkt5 = {0};
    unsigned int servname_type = 0, type = 0;
    int ret = 0;

    len = BIO_get_mem_data(bio, (char **)&data);
    if (!TEST_true(PACKET_buf_init(&pkt, data, len))
               /* Skip the record header */
            || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH)
               /* Skip the handshake message header */
            || !TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH))
               /* Skip client version and random */
            || !TEST_true(PACKET_forward(&pkt, CLIENT_VERSION_LEN
                                               + SSL3_RANDOM_SIZE))
               /* Skip session id */
            || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2))
               /* Skip ciphers */
            || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &pkt2))
               /* Skip compression */
            || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2))
               /* Extensions len */
            || !TEST_true(PACKET_as_length_prefixed_2(&pkt, &pkt2)))
        goto end;

    /* Loop through all extensions for SNI */
    while (PACKET_remaining(&pkt2)) {
        if (!TEST_true(PACKET_get_net_2(&pkt2, &type))
                || !TEST_true(PACKET_get_length_prefixed_2(&pkt2, &pkt3)))
            goto end;
        if (type == TLSEXT_TYPE_server_name) {
            if (!TEST_true(PACKET_get_length_prefixed_2(&pkt3, &pkt4))
                    || !TEST_uint_ne(PACKET_remaining(&pkt4), 0)
                    || !TEST_true(PACKET_get_1(&pkt4, &servname_type))
                    || !TEST_uint_eq(servname_type, TLSEXT_NAMETYPE_host_name)
                    || !TEST_true(PACKET_get_length_prefixed_2(&pkt4, &pkt5))
                    || !TEST_uint_le(PACKET_remaining(&pkt5), TLSEXT_MAXLEN_host_name)
                    || !TEST_false(PACKET_contains_zero_byte(&pkt5))
                    || !TEST_true(PACKET_strndup(&pkt5, sni)))
                goto end;
            ret = 1;
            goto end;
        }
    }
end:
    return ret;
}

static int client_setup_sni_before_state(void)
{
    SSL_CTX *ctx;
    SSL *con = NULL;
    BIO *rbio;
    BIO *wbio;
    char *hostname = NULL;
    int ret = 0;

    /* use TLS_method to blur 'side' */
    ctx = SSL_CTX_new(TLS_method());
    if (!TEST_ptr(ctx))
        goto end;

    con = SSL_new(ctx);
    if (!TEST_ptr(con))
        goto end;

    /* set SNI before 'client side' is set */
    SSL_set_tlsext_host_name(con, host);

    rbio = BIO_new(BIO_s_mem());
    wbio = BIO_new(BIO_s_mem());
    if (!TEST_ptr(rbio)|| !TEST_ptr(wbio)) {
        BIO_free(rbio);
        BIO_free(wbio);
        goto end;
    }

    SSL_set_bio(con, rbio, wbio);

    if (!TEST_int_le(SSL_connect(con), 0))
        /* This shouldn't succeed because we don't have a server! */
        goto end;
    if (!TEST_true(get_sni_from_client_hello(wbio, &hostname)))
        /* no SNI in client hello */
        goto end;
    if (!TEST_str_eq(hostname, host))
        /* incorrect SNI value */
        goto end;
    ret = 1;
end:
    OPENSSL_free(hostname);
    SSL_free(con);
    SSL_CTX_free(ctx);
    return ret;
}

static int client_setup_sni_after_state(void)
{
    SSL_CTX *ctx;
    SSL *con = NULL;
    BIO *rbio;
    BIO *wbio;
    char *hostname = NULL;
    int ret = 0;

    /* use TLS_method to blur 'side' */
    ctx = SSL_CTX_new(TLS_method());
    if (!TEST_ptr(ctx))
        goto end;

    con = SSL_new(ctx);
    if (!TEST_ptr(con))
        goto end;

    rbio = BIO_new(BIO_s_mem());
    wbio = BIO_new(BIO_s_mem());
    if (!TEST_ptr(rbio)|| !TEST_ptr(wbio)) {
        BIO_free(rbio);
        BIO_free(wbio);
        goto end;
    }

    SSL_set_bio(con, rbio, wbio);
    SSL_set_connect_state(con);

    /* set SNI after 'client side' is set */
    SSL_set_tlsext_host_name(con, host);

    if (!TEST_int_le(SSL_connect(con), 0))
        /* This shouldn't succeed because we don't have a server! */
        goto end;
    if (!TEST_true(get_sni_from_client_hello(wbio, &hostname)))
        /* no SNI in client hello */
        goto end;
    if (!TEST_str_eq(hostname, host))
        /* incorrect SNI value */
        goto end;
    ret = 1;
end:
    OPENSSL_free(hostname);
    SSL_free(con);
    SSL_CTX_free(ctx);
    return ret;
}

static int server_setup_sni(void)
{
    SSL_CTX *ctx;
    SSL *con = NULL;
    BIO *rbio;
    BIO *wbio;
    int ret = 0;

    /* use TLS_server_method to choose 'server-side' */
    ctx = SSL_CTX_new(TLS_server_method());
    if (!TEST_ptr(ctx))
        goto end;

    con = SSL_new(ctx);
    if (!TEST_ptr(con))
        goto end;

    rbio = BIO_new(BIO_s_mem());
    wbio = BIO_new(BIO_s_mem());
    if (!TEST_ptr(rbio)|| !TEST_ptr(wbio)) {
        BIO_free(rbio);
        BIO_free(wbio);
        goto end;
    }

    SSL_set_bio(con, rbio, wbio);

    /* set SNI at server side */
    SSL_set_tlsext_host_name(con, host);

    if (!TEST_int_le(SSL_accept(con), 0))
        /* This shouldn't succeed because we have nothing to listen on */
        goto end;
    if (!TEST_ptr_null(SSL_get_servername(con, TLSEXT_NAMETYPE_host_name)))
        /* SNI should be cleared by SSL_accpet */
        goto end;
    ret = 1;
end:
    SSL_free(con);
    SSL_CTX_free(ctx);
    return ret;
}

typedef int (*sni_test_fn)(void);

static sni_test_fn sni_test_fns[3] = {
    client_setup_sni_before_state,
    client_setup_sni_after_state,
    server_setup_sni
};

static int test_servername(int test)
{
    /*
     * For each test set up an SSL_CTX and SSL and see
     * what SNI behaves.
     */
    return sni_test_fns[test]();
}

int setup_tests(void)
{
    ADD_ALL_TESTS(test_servername, OSSL_NELEM(sni_test_fns));
    return 1;
}
