Blame test/dtlsv1listentest.c

Packit c4476c
/*
Packit c4476c
 * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
Packit c4476c
 *
Packit c4476c
 * Licensed under the OpenSSL license (the "License").  You may not use
Packit c4476c
 * this file except in compliance with the License.  You can obtain a copy
Packit c4476c
 * in the file LICENSE in the source distribution or at
Packit c4476c
 * https://www.openssl.org/source/license.html
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
#include <openssl/conf.h>
Packit c4476c
#include "internal/nelem.h"
Packit c4476c
#include "testutil.h"
Packit c4476c
Packit c4476c
#ifndef OPENSSL_NO_SOCK
Packit c4476c
Packit c4476c
/* Just a ClientHello without a cookie */
Packit c4476c
static const unsigned char clienthello_nocookie[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x3A, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x2E, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x2E, /* Fragment length */
Packit c4476c
    0xFE, 0xFD, /* DTLSv1.2 */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00, /* Session id len */
Packit c4476c
    0x00, /* Cookie len */
Packit c4476c
    0x00, 0x04, /* Ciphersuites len */
Packit c4476c
    0x00, 0x2f, /* AES128-SHA */
Packit c4476c
    0x00, 0xff, /* Empty reneg info SCSV */
Packit c4476c
    0x01, /* Compression methods len */
Packit c4476c
    0x00, /* Null compression */
Packit c4476c
    0x00, 0x00 /* Extensions len */
Packit c4476c
};
Packit c4476c
Packit c4476c
/* First fragment of a ClientHello without a cookie */
Packit c4476c
static const unsigned char clienthello_nocookie_frag[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x30, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x2E, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x24, /* Fragment length */
Packit c4476c
    0xFE, 0xFD, /* DTLSv1.2 */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00, /* Session id len */
Packit c4476c
    0x00 /* Cookie len */
Packit c4476c
};
Packit c4476c
Packit c4476c
/* First fragment of a ClientHello which is too short */
Packit c4476c
static const unsigned char clienthello_nocookie_short[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x2F, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x2E, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x23, /* Fragment length */
Packit c4476c
    0xFE, 0xFD, /* DTLSv1.2 */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00 /* Session id len */
Packit c4476c
};
Packit c4476c
Packit c4476c
/* Second fragment of a ClientHello */
Packit c4476c
static const unsigned char clienthello_2ndfrag[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x38, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x2E, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x02, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x2C, /* Fragment length */
Packit c4476c
    /* Version skipped - sent in first fragment */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00, /* Session id len */
Packit c4476c
    0x00, /* Cookie len */
Packit c4476c
    0x00, 0x04, /* Ciphersuites len */
Packit c4476c
    0x00, 0x2f, /* AES128-SHA */
Packit c4476c
    0x00, 0xff, /* Empty reneg info SCSV */
Packit c4476c
    0x01, /* Compression methods len */
Packit c4476c
    0x00, /* Null compression */
Packit c4476c
    0x00, 0x00 /* Extensions len */
Packit c4476c
};
Packit c4476c
Packit c4476c
/* A ClientHello with a good cookie */
Packit c4476c
static const unsigned char clienthello_cookie[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x4E, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x42, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x42, /* Fragment length */
Packit c4476c
    0xFE, 0xFD, /* DTLSv1.2 */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00, /* Session id len */
Packit c4476c
    0x14, /* Cookie len */
Packit c4476c
    0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
Packit c4476c
    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
Packit c4476c
    0x00, 0x04, /* Ciphersuites len */
Packit c4476c
    0x00, 0x2f, /* AES128-SHA */
Packit c4476c
    0x00, 0xff, /* Empty reneg info SCSV */
Packit c4476c
    0x01, /* Compression methods len */
Packit c4476c
    0x00, /* Null compression */
Packit c4476c
    0x00, 0x00 /* Extensions len */
Packit c4476c
};
Packit c4476c
Packit c4476c
/* A fragmented ClientHello with a good cookie */
Packit c4476c
static const unsigned char clienthello_cookie_frag[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x44, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x42, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x38, /* Fragment length */
Packit c4476c
    0xFE, 0xFD, /* DTLSv1.2 */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00, /* Session id len */
Packit c4476c
    0x14, /* Cookie len */
Packit c4476c
    0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
Packit c4476c
    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
Packit c4476c
};
Packit c4476c
Packit c4476c
Packit c4476c
/* A ClientHello with a bad cookie */
Packit c4476c
static const unsigned char clienthello_badcookie[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x4E, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x42, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x42, /* Fragment length */
Packit c4476c
    0xFE, 0xFD, /* DTLSv1.2 */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00, /* Session id len */
Packit c4476c
    0x14, /* Cookie len */
Packit c4476c
    0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
Packit c4476c
    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */
Packit c4476c
    0x00, 0x04, /* Ciphersuites len */
Packit c4476c
    0x00, 0x2f, /* AES128-SHA */
Packit c4476c
    0x00, 0xff, /* Empty reneg info SCSV */
Packit c4476c
    0x01, /* Compression methods len */
Packit c4476c
    0x00, /* Null compression */
Packit c4476c
    0x00, 0x00 /* Extensions len */
Packit c4476c
};
Packit c4476c
Packit c4476c
/* A fragmented ClientHello with the fragment boundary mid cookie */
Packit c4476c
static const unsigned char clienthello_cookie_short[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x43, /* Record Length */
Packit c4476c
    0x01, /* ClientHello */
Packit c4476c
    0x00, 0x00, 0x42, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x37, /* Fragment length */
Packit c4476c
    0xFE, 0xFD, /* DTLSv1.2 */
Packit c4476c
    0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90,
Packit c4476c
    0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56,
Packit c4476c
    0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */
Packit c4476c
    0x00, /* Session id len */
Packit c4476c
    0x14, /* Cookie len */
Packit c4476c
    0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
Packit c4476c
    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie */
Packit c4476c
};
Packit c4476c
Packit c4476c
/* Bad record - too short */
Packit c4476c
static const unsigned char record_short[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */
Packit c4476c
};
Packit c4476c
Packit c4476c
static const unsigned char verify[] = {
Packit c4476c
    0x16, /* Handshake */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x00, 0x00, /* Epoch */
Packit c4476c
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */
Packit c4476c
    0x00, 0x23, /* Record Length */
Packit c4476c
    0x03, /* HelloVerifyRequest */
Packit c4476c
    0x00, 0x00, 0x17, /* Message length */
Packit c4476c
    0x00, 0x00, /* Message sequence */
Packit c4476c
    0x00, 0x00, 0x00, /* Fragment offset */
Packit c4476c
    0x00, 0x00, 0x17, /* Fragment length */
Packit c4476c
    0xFE, 0xFF, /* DTLSv1.0 */
Packit c4476c
    0x14, /* Cookie len */
Packit c4476c
    0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
Packit c4476c
    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13 /* Cookie */
Packit c4476c
};
Packit c4476c
Packit c4476c
typedef struct {
Packit c4476c
    const unsigned char *in;
Packit c4476c
    unsigned int inlen;
Packit c4476c
    /*
Packit c4476c
     * GOOD == positive return value from DTLSv1_listen, no output yet
Packit c4476c
     * VERIFY == 0 return value, HelloVerifyRequest sent
Packit c4476c
     * DROP == 0 return value, no output
Packit c4476c
     */
Packit c4476c
    enum {GOOD, VERIFY, DROP} outtype;
Packit c4476c
} tests;
Packit c4476c
Packit c4476c
static tests testpackets[9] = {
Packit c4476c
    { clienthello_nocookie, sizeof(clienthello_nocookie), VERIFY },
Packit c4476c
    { clienthello_nocookie_frag, sizeof(clienthello_nocookie_frag), VERIFY },
Packit c4476c
    { clienthello_nocookie_short, sizeof(clienthello_nocookie_short), DROP },
Packit c4476c
    { clienthello_2ndfrag, sizeof(clienthello_2ndfrag), DROP },
Packit c4476c
    { clienthello_cookie, sizeof(clienthello_cookie), GOOD },
Packit c4476c
    { clienthello_cookie_frag, sizeof(clienthello_cookie_frag), GOOD },
Packit c4476c
    { clienthello_badcookie, sizeof(clienthello_badcookie), VERIFY },
Packit c4476c
    { clienthello_cookie_short, sizeof(clienthello_cookie_short), DROP },
Packit c4476c
    { record_short, sizeof(record_short), DROP }
Packit c4476c
};
Packit c4476c
Packit c4476c
# define COOKIE_LEN  20
Packit c4476c
Packit c4476c
static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len)
Packit c4476c
{
Packit c4476c
    unsigned int i;
Packit c4476c
Packit c4476c
    for (i = 0; i < COOKIE_LEN; i++, cookie++)
Packit c4476c
        *cookie = i;
Packit c4476c
    *cookie_len = COOKIE_LEN;
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int cookie_verify(SSL *ssl, const unsigned char *cookie,
Packit c4476c
                         unsigned int cookie_len)
Packit c4476c
{
Packit c4476c
    unsigned int i;
Packit c4476c
Packit c4476c
    if (cookie_len != COOKIE_LEN)
Packit c4476c
        return 0;
Packit c4476c
Packit c4476c
    for (i = 0; i < COOKIE_LEN; i++, cookie++) {
Packit c4476c
        if (*cookie != i)
Packit c4476c
            return 0;
Packit c4476c
    }
Packit c4476c
Packit c4476c
    return 1;
Packit c4476c
}
Packit c4476c
Packit c4476c
static int dtls_listen_test(int i)
Packit c4476c
{
Packit c4476c
    SSL_CTX *ctx = NULL;
Packit c4476c
    SSL *ssl = NULL;
Packit c4476c
    BIO *outbio = NULL;
Packit c4476c
    BIO *inbio = NULL;
Packit c4476c
    BIO_ADDR *peer = NULL;
Packit c4476c
    tests *tp = &testpackets[i];
Packit c4476c
    char *data;
Packit c4476c
    long datalen;
Packit c4476c
    int ret, success = 0;
Packit c4476c
Packit c4476c
    if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))
Packit c4476c
            || !TEST_ptr(peer = BIO_ADDR_new()))
Packit c4476c
        goto err;
Packit c4476c
    SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen);
Packit c4476c
    SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify);
Packit c4476c
Packit c4476c
    /* Create an SSL object and set the BIO */
Packit c4476c
    if (!TEST_ptr(ssl = SSL_new(ctx))
Packit c4476c
            || !TEST_ptr(outbio = BIO_new(BIO_s_mem())))
Packit c4476c
        goto err;
Packit c4476c
    SSL_set0_wbio(ssl, outbio);
Packit c4476c
Packit c4476c
    /* Set Non-blocking IO behaviour */
Packit c4476c
    if (!TEST_ptr(inbio = BIO_new_mem_buf((char *)tp->in, tp->inlen)))
Packit c4476c
        goto err;
Packit c4476c
    BIO_set_mem_eof_return(inbio, -1);
Packit c4476c
    SSL_set0_rbio(ssl, inbio);
Packit c4476c
Packit c4476c
    /* Process the incoming packet */
Packit c4476c
    if (!TEST_int_ge(ret = DTLSv1_listen(ssl, peer), 0))
Packit c4476c
        goto err;
Packit c4476c
    datalen = BIO_get_mem_data(outbio, &data);
Packit c4476c
Packit c4476c
    if (tp->outtype == VERIFY) {
Packit c4476c
        if (!TEST_int_eq(ret, 0)
Packit c4476c
                || !TEST_mem_eq(data, datalen, verify, sizeof(verify)))
Packit c4476c
            goto err;
Packit c4476c
    } else if (datalen == 0) {
Packit c4476c
        if (!TEST_true((ret == 0 && tp->outtype == DROP)
Packit c4476c
                || (ret == 1 && tp->outtype == GOOD)))
Packit c4476c
            goto err;
Packit c4476c
    } else {
Packit c4476c
        TEST_info("Test %d: unexpected data output", i);
Packit c4476c
        goto err;
Packit c4476c
    }
Packit c4476c
    (void)BIO_reset(outbio);
Packit c4476c
    inbio = NULL;
Packit c4476c
    SSL_set0_rbio(ssl, NULL);
Packit c4476c
    success = 1;
Packit c4476c
Packit c4476c
 err:
Packit c4476c
    /* Also frees up outbio */
Packit c4476c
    SSL_free(ssl);
Packit c4476c
    SSL_CTX_free(ctx);
Packit c4476c
    BIO_free(inbio);
Packit c4476c
    OPENSSL_free(peer);
Packit c4476c
    return success;
Packit c4476c
}
Packit c4476c
#endif
Packit c4476c
Packit c4476c
int setup_tests(void)
Packit c4476c
{
Packit c4476c
#ifndef OPENSSL_NO_SOCK
Packit c4476c
    ADD_ALL_TESTS(dtls_listen_test, (int)OSSL_NELEM(testpackets));
Packit c4476c
#endif
Packit c4476c
    return 1;
Packit c4476c
}