Blame test/sslbuffertest.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL licenses, (the "License");
Packit c4476c
 * you may not use this file except in compliance with the License.
Packit c4476c
 * You may obtain a copy of the License at
Packit c4476c
 * https://www.openssl.org/source/license.html
Packit c4476c
 * or in the file LICENSE in the source distribution.
Packit c4476c
 */
Packit c4476c
Packit c4476c
#include <string.h>
Packit c4476c
#include <openssl/ssl.h>
Packit c4476c
#include <openssl/bio.h>
Packit c4476c
#include <openssl/err.h>
Packit c4476c
Packit c4476c
#include "../ssl/packet_local.h"
Packit c4476c
Packit c4476c
#include "ssltestlib.h"
Packit c4476c
#include "testutil.h"
Packit c4476c
Packit c4476c
struct async_ctrs {
Packit c4476c
    unsigned int rctr;
Packit c4476c
    unsigned int wctr;
Packit c4476c
};
Packit c4476c
Packit c4476c
static SSL_CTX *serverctx = NULL;
Packit c4476c
static SSL_CTX *clientctx = NULL;
Packit c4476c
Packit c4476c
#define MAX_ATTEMPTS    100
Packit c4476c
Packit c4476c
Packit c4476c
/*
Packit c4476c
 * There are 9 passes in the tests
Packit c4476c
 * 0 = control test
Packit c4476c
 * tests during writes
Packit c4476c
 * 1 = free buffers
Packit c4476c
 * 2 = + allocate buffers after free
Packit c4476c
 * 3 = + allocate buffers again
Packit c4476c
 * 4 = + free buffers after allocation
Packit c4476c
 * tests during reads
Packit c4476c
 * 5 = + free buffers
Packit c4476c
 * 6 = + free buffers again
Packit c4476c
 * 7 = + allocate buffers after free
Packit c4476c
 * 8 = + free buffers after allocation
Packit c4476c
 */
Packit c4476c
static int test_func(int test)
Packit c4476c
{
Packit c4476c
    int result = 0;
Packit c4476c
    SSL *serverssl = NULL, *clientssl = NULL;
Packit c4476c
    int ret;
Packit c4476c
    size_t i, j;
Packit c4476c
    const char testdata[] = "Test data";
Packit c4476c
    char buf[sizeof(testdata)];
Packit c4476c
Packit c4476c
    if (!TEST_true(create_ssl_objects(serverctx, clientctx, &serverssl, &clientssl,
Packit c4476c
                                      NULL, NULL))) {
Packit c4476c
        TEST_error("Test %d failed: Create SSL objects failed\n", test);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) {
Packit c4476c
        TEST_error("Test %d failed: Create SSL connection failed\n", test);
Packit c4476c
        goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    /*
Packit c4476c
     * Send and receive some test data. Do the whole thing twice to ensure
Packit c4476c
     * we hit at least one async event in both reading and writing
Packit c4476c
     */
Packit c4476c
    for (j = 0; j < 2; j++) {
Packit c4476c
        int len;
Packit c4476c
Packit c4476c
        /*
Packit c4476c
Packit c4476c
         * Write some test data. It should never take more than 2 attempts
Packit c4476c
         * (the first one might be a retryable fail).
Packit c4476c
         */
Packit c4476c
        for (ret = -1, i = 0, len = 0; len != sizeof(testdata) && i < 2;
Packit c4476c
             i++) {
Packit c4476c
            /* test == 0 mean to free/allocate = control */
Packit c4476c
            if (test >= 1 && !TEST_true(SSL_free_buffers(clientssl)))
Packit c4476c
                goto end;
Packit c4476c
            if (test >= 2 && !TEST_true(SSL_alloc_buffers(clientssl)))
Packit c4476c
                goto end;
Packit c4476c
            /* allocate a second time */
Packit c4476c
            if (test >= 3 && !TEST_true(SSL_alloc_buffers(clientssl)))
Packit c4476c
                goto end;
Packit c4476c
            if (test >= 4 && !TEST_true(SSL_free_buffers(clientssl)))
Packit c4476c
                goto end;
Packit c4476c
Packit c4476c
            ret = SSL_write(clientssl, testdata + len,
Packit c4476c
                            sizeof(testdata) - len);
Packit c4476c
            if (ret > 0) {
Packit c4476c
                len += ret;
Packit c4476c
            } else {
Packit c4476c
                int ssl_error = SSL_get_error(clientssl, ret);
Packit c4476c
Packit c4476c
                if (ssl_error == SSL_ERROR_SYSCALL ||
Packit c4476c
                    ssl_error == SSL_ERROR_SSL) {
Packit c4476c
                    TEST_error("Test %d failed: Failed to write app data\n", test);
Packit c4476c
                    goto end;
Packit c4476c
                }
Packit c4476c
            }
Packit c4476c
        }
Packit c4476c
        if (!TEST_size_t_eq(len, sizeof(testdata)))
Packit c4476c
            goto end;
Packit c4476c
        /*
Packit c4476c
         * Now read the test data. It may take more attempts here because
Packit c4476c
         * it could fail once for each byte read, including all overhead
Packit c4476c
         * bytes from the record header/padding etc.
Packit c4476c
         */
Packit c4476c
        for (ret = -1, i = 0, len = 0; len != sizeof(testdata) &&
Packit c4476c
                 i < MAX_ATTEMPTS; i++)
Packit c4476c
        {
Packit c4476c
            if (test >= 5 && !TEST_true(SSL_free_buffers(serverssl)))
Packit c4476c
                goto end;
Packit c4476c
            /* free a second time */
Packit c4476c
            if (test >= 6 && !TEST_true(SSL_free_buffers(serverssl)))
Packit c4476c
                goto end;
Packit c4476c
            if (test >= 7 && !TEST_true(SSL_alloc_buffers(serverssl)))
Packit c4476c
                goto end;
Packit c4476c
            if (test >= 8 && !TEST_true(SSL_free_buffers(serverssl)))
Packit c4476c
                goto end;
Packit c4476c
Packit c4476c
            ret = SSL_read(serverssl, buf + len, sizeof(buf) - len);
Packit c4476c
            if (ret > 0) {
Packit c4476c
                len += ret;
Packit c4476c
            } else {
Packit c4476c
                int ssl_error = SSL_get_error(serverssl, ret);
Packit c4476c
Packit c4476c
                if (ssl_error == SSL_ERROR_SYSCALL ||
Packit c4476c
                    ssl_error == SSL_ERROR_SSL) {
Packit c4476c
                    TEST_error("Test %d failed: Failed to read app data\n", test);
Packit c4476c
                    goto end;
Packit c4476c
                }
Packit c4476c
            }
Packit c4476c
        }
Packit c4476c
        if (!TEST_mem_eq(buf, len, testdata, sizeof(testdata)))
Packit c4476c
            goto end;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    result = 1;
Packit c4476c
 end:
Packit c4476c
    if (!result)
Packit c4476c
        ERR_print_errors_fp(stderr);
Packit c4476c
Packit c4476c
    SSL_free(clientssl);
Packit c4476c
    SSL_free(serverssl);
Packit c4476c
Packit c4476c
    return result;
Packit c4476c
}
Packit c4476c
Packit c4476c
int global_init(void)
Packit c4476c
{
Packit c4476c
    CRYPTO_set_mem_debug(1);
Packit c4476c
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
int setup_tests(void)
Packit c4476c
{
Packit c4476c
    char *cert, *pkey;
Packit c4476c
Packit c4476c
    if (!TEST_ptr(cert = test_get_argument(0))
Packit c4476c
            || !TEST_ptr(pkey = test_get_argument(1)))
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
Packit c4476c
                             TLS1_VERSION, TLS_MAX_VERSION,
Packit c4476c
                             &serverctx, &clientctx, cert, pkey)) {
Packit c4476c
        TEST_error("Failed to create SSL_CTX pair\n");
Packit c4476c
        return 0;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    ADD_ALL_TESTS(test_func, 9);
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
void cleanup_tests(void)
Packit c4476c
{
Packit c4476c
    SSL_CTX_free(clientctx);
Packit c4476c
    SSL_CTX_free(serverctx);
Packit c4476c
}