Esempio n. 1
0
static int test_PACKET_move_funcs(PACKET *pkt, size_t start)
{
    unsigned char *byte;
    size_t bm;

    if (       !PACKET_goto_bookmark(pkt, start)
            ||  PACKET_back(pkt, 1)
            || !PACKET_forward(pkt, 1)
            || !PACKET_get_bytes(pkt, &byte, 1)
            ||  byte[0] != 4
            || !PACKET_get_bookmark(pkt, &bm)
            || !PACKET_forward(pkt, BUF_LEN - 2)
            ||  PACKET_forward(pkt, 1)
            || !PACKET_back(pkt, 1)
            || !PACKET_get_bytes(pkt, &byte, 1)
            ||  byte[0] != 0xfe
            || !PACKET_goto_bookmark(pkt, bm)
            || !PACKET_get_bytes(pkt, &byte, 1)
            ||  byte[0] != 6) {
        fprintf(stderr, "test_PACKET_move_funcs() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 2
0
static int test_PACKET_remaining(PACKET *pkt)
{
    if (        PACKET_remaining(pkt) != BUF_LEN
            || !PACKET_forward(pkt, BUF_LEN - 1)
            ||  PACKET_remaining(pkt) != 1
            || !PACKET_forward(pkt, 1)
            ||  PACKET_remaining(pkt) != 0) {
        fprintf(stderr, "test_PACKET_remaining() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 3
0
static int test_PACKET_remaining()
{
    PACKET pkt;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, sizeof(smbuf))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 1))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), 1)
            || !TEST_true(PACKET_forward(&pkt, 1))
            || !TEST_size_t_eq(PACKET_remaining(&pkt), 0)))
        return 0;

    return 1;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
static int test_PACKET_remaining(unsigned char buf[BUF_LEN])
{
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            ||  PACKET_remaining(&pkt) != BUF_LEN
            || !PACKET_forward(&pkt, BUF_LEN - 1)
            ||  PACKET_remaining(&pkt) != 1
            || !PACKET_forward(&pkt, 1)
            ||  PACKET_remaining(&pkt) != 0) {
        fprintf(stderr, "test_PACKET_remaining() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 6
0
static int test_PACKET_forward()
{
    const unsigned char *byte;
    PACKET pkt;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_forward(&pkt, 1))
            || !TEST_true(PACKET_get_bytes(&pkt, &byte, 1))
            || !TEST_uchar_eq(byte[0], 4)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 3))
            || !TEST_true(PACKET_get_bytes(&pkt, &byte, 1))
            || !TEST_uchar_eq(byte[0], 0xfe))
        return 0;

    return 1;
}
Esempio n. 7
0
static int test_PACKET_forward(unsigned char buf[BUF_LEN])
{
    unsigned char *byte;
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_forward(&pkt, 1)
            || !PACKET_get_bytes(&pkt, &byte, 1)
            ||  byte[0] != 4
            || !PACKET_forward(&pkt, BUF_LEN - 3)
            || !PACKET_get_bytes(&pkt, &byte, 1)
            ||  byte[0] != 0xfe) {
        fprintf(stderr, "test_PACKET_forward() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 8
0
static int test_PACKET_null_init()
{
    PACKET pkt;

    PACKET_null_init(&pkt);
    if (!TEST_size_t_eq(PACKET_remaining(&pkt), 0)
            || !TEST_false(PACKET_forward(&pkt, 1)))
        return 0;

    return 1;
}
Esempio n. 9
0
static int test_PACKET_get_4()
{
    unsigned long i;
    PACKET pkt;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_get_4(&pkt, &i))
            || !TEST_ulong_eq(i, 0x08060402UL)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
            || !TEST_true(PACKET_get_4(&pkt, &i))
            || !TEST_ulong_eq(i, 0xfefcfaf8UL)
            || !TEST_false(PACKET_get_4(&pkt, &i)))
        return 0;

    return 1;
}
Esempio n. 10
0
static int test_PACKET_get_net_2()
{
    unsigned int i;
    PACKET pkt;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_get_net_2(&pkt, &i))
            || !TEST_uint_eq(i, 0x0204)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 4))
            || !TEST_true(PACKET_get_net_2(&pkt, &i))
            || !TEST_uint_eq(i, 0xfcfe)
            || !TEST_false(PACKET_get_net_2(&pkt, &i)))
        return 0;

    return 1;
}
Esempio n. 11
0
static int test_PACKET_get_net_3()
{
    unsigned long i;
    PACKET pkt;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_get_net_3(&pkt, &i))
            || !TEST_ulong_eq(i, 0x020406UL)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 6))
            || !TEST_true(PACKET_get_net_3(&pkt, &i))
            || !TEST_ulong_eq(i, 0xfafcfeUL)
            || !TEST_false(PACKET_get_net_3(&pkt, &i)))
        return 0;

    return 1;
}
Esempio n. 12
0
static int test_PACKET_get_1(PACKET *pkt, size_t start)
{
    unsigned int i;

    if (       !PACKET_goto_bookmark(pkt, start)
            || !PACKET_get_1(pkt, &i)
            ||  i != 0x02
            || !PACKET_forward(pkt, BUF_LEN - 2)
            || !PACKET_get_1(pkt, &i)
            ||  i != 0xfe
            ||  PACKET_get_1(pkt, &i)) {
        fprintf(stderr, "test_PACKET_get_1() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 13
0
static int test_PACKET_get_4(PACKET *pkt, size_t start)
{
    unsigned long i;

    if (       !PACKET_goto_bookmark(pkt, start)
            || !PACKET_get_4(pkt, &i)
            ||  i != 0x08060402UL
            || !PACKET_forward(pkt, BUF_LEN - 8)
            || !PACKET_get_4(pkt, &i)
            ||  i != 0xfefcfaf8UL
            ||  PACKET_get_4(pkt, &i)) {
        fprintf(stderr, "test_PACKET_get_4() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 14
0
static int test_PACKET_get_net_3(PACKET *pkt, size_t start)
{
    unsigned long i;

    if (       !PACKET_goto_bookmark(pkt, start)
            || !PACKET_get_net_3(pkt, &i)
            ||  i != 0x020406UL
            || !PACKET_forward(pkt, BUF_LEN - 6)
            || !PACKET_get_net_3(pkt, &i)
            ||  i != 0xfafcfeUL
            ||  PACKET_get_net_3(pkt, &i)) {
        fprintf(stderr, "test_PACKET_get_net_3() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 15
0
static int test_PACKET_get_4(unsigned char buf[BUF_LEN])
{
    unsigned long i;
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_get_4(&pkt, &i)
            ||  i != 0x08060402UL
            || !PACKET_forward(&pkt, BUF_LEN - 8)
            || !PACKET_get_4(&pkt, &i)
            ||  i != 0xfefcfaf8UL
            ||  PACKET_get_4(&pkt, &i)) {
        fprintf(stderr, "test_PACKET_get_4() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 16
0
static int test_PACKET_get_net_3(unsigned char buf[BUF_LEN])
{
    unsigned long i;
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_get_net_3(&pkt, &i)
            ||  i != 0x020406UL
            || !PACKET_forward(&pkt, BUF_LEN - 6)
            || !PACKET_get_net_3(&pkt, &i)
            ||  i != 0xfafcfeUL
            ||  PACKET_get_net_3(&pkt, &i)) {
        fprintf(stderr, "test_PACKET_get_net_3() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 17
0
static int test_PACKET_get_1(unsigned char buf[BUF_LEN])
{
    unsigned int i;
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_get_1(&pkt, &i)
            ||  i != 0x02
            || !PACKET_forward(&pkt, BUF_LEN - 2)
            || !PACKET_get_1(&pkt, &i)
            ||  i != 0xfe
            ||  PACKET_get_1(&pkt, &i)) {
        fprintf(stderr, "test_PACKET_get_1() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 18
0
static int test_PACKET_copy_bytes(PACKET *pkt, size_t start)
{
    unsigned char bytes[4];

    if (       !PACKET_goto_bookmark(pkt, start)
            || !PACKET_copy_bytes(pkt, bytes, 4)
            ||  bytes[0] != 2 || bytes[1] != 4
            ||  bytes[2] != 6 || bytes[3] != 8
            ||  PACKET_remaining(pkt) != BUF_LEN - 4
            || !PACKET_forward(pkt, BUF_LEN - 8)
            || !PACKET_copy_bytes(pkt, bytes, 4)
            ||  bytes[0] != 0xf8 || bytes[1] != 0xfa
            ||  bytes[2] != 0xfc || bytes[3] != 0xfe
            ||  PACKET_remaining(pkt)) {
        fprintf(stderr, "test_PACKET_copy_bytes() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 19
0
static int test_PACKET_get_sub_packet()
{
    PACKET pkt, subpkt;
    unsigned long i;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_get_sub_packet(&pkt, &subpkt, 4))
            || !TEST_true(PACKET_get_net_4(&subpkt, &i))
            || !TEST_ulong_eq(i, 0x02040608UL)
            || !TEST_size_t_eq(PACKET_remaining(&subpkt), 0)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
            || !TEST_true(PACKET_get_sub_packet(&pkt, &subpkt, 4))
            || !TEST_true(PACKET_get_net_4(&subpkt, &i))
            || !TEST_ulong_eq(i, 0xf8fafcfeUL)
            || !TEST_size_t_eq(PACKET_remaining(&subpkt), 0)
            || !TEST_false(PACKET_get_sub_packet(&pkt, &subpkt, 4)))
        return 0;

    return 1;
}
Esempio n. 20
0
static int test_PACKET_copy_bytes(unsigned char buf[BUF_LEN])
{
    unsigned char bytes[4];
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_copy_bytes(&pkt, bytes, 4)
            ||  bytes[0] != 2 || bytes[1] != 4
            ||  bytes[2] != 6 || bytes[3] != 8
            ||  PACKET_remaining(&pkt) != BUF_LEN - 4
            || !PACKET_forward(&pkt, BUF_LEN - 8)
            || !PACKET_copy_bytes(&pkt, bytes, 4)
            ||  bytes[0] != 0xf8 || bytes[1] != 0xfa
            ||  bytes[2] != 0xfc || bytes[3] != 0xfe
            ||  PACKET_remaining(&pkt)) {
        fprintf(stderr, "test_PACKET_copy_bytes() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 21
0
static int test_PACKET_memdup()
{
    unsigned char *data = NULL;
    size_t len;
    PACKET pkt;
    int result = 0;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_memdup(&pkt, &data, &len))
            || !TEST_size_t_eq(len, BUF_LEN)
            || !TEST_mem_eq(data, len, PACKET_data(&pkt), len)
            || !TEST_true(PACKET_forward(&pkt, 10))
            || !TEST_true(PACKET_memdup(&pkt, &data, &len))
            || !TEST_size_t_eq(len, BUF_LEN - 10)
            || !TEST_mem_eq(data, len, PACKET_data(&pkt), len))
        goto end;
    result = 1;
end:
    OPENSSL_free(data);
    return result;
}
Esempio n. 22
0
static int test_PACKET_get_sub_packet(PACKET *pkt, size_t start)
{
    PACKET subpkt;
    unsigned long i;

    if (       !PACKET_goto_bookmark(pkt, start)
            || !PACKET_get_sub_packet(pkt, &subpkt, 4)
            || !PACKET_get_net_4(&subpkt, &i)
            ||  i != 0x02040608UL
            ||  PACKET_remaining(&subpkt)
            || !PACKET_forward(pkt, BUF_LEN - 8)
            || !PACKET_get_sub_packet(pkt, &subpkt, 4)
            || !PACKET_get_net_4(&subpkt, &i)
            ||  i != 0xf8fafcfeUL
            ||  PACKET_remaining(&subpkt)
            ||  PACKET_get_sub_packet(pkt, &subpkt, 4)) {
        fprintf(stderr, "test_PACKET_get_sub_packet() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 23
0
static int test_PACKET_memdup(unsigned char buf[BUF_LEN])
{
    unsigned char *data = NULL;
    size_t len;
    PACKET pkt;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_memdup(&pkt, &data, &len)
            ||  len != BUF_LEN
            ||  memcmp(data, PACKET_data(&pkt), len)
            || !PACKET_forward(&pkt, 10)
            || !PACKET_memdup(&pkt, &data, &len)
            ||  len != BUF_LEN - 10
            ||  memcmp(data, PACKET_data(&pkt), len)) {
        fprintf(stderr, "test_PACKET_memdup() failed\n");
        OPENSSL_free(data);
        return 0;
    }

    OPENSSL_free(data);
    return 1;
}
Esempio n. 24
0
static int test_PACKET_get_sub_packet(unsigned char buf[BUF_LEN])
{
    PACKET pkt, subpkt;
    unsigned long i;

    if (       !PACKET_buf_init(&pkt, buf, BUF_LEN)
            || !PACKET_get_sub_packet(&pkt, &subpkt, 4)
            || !PACKET_get_net_4(&subpkt, &i)
            ||  i != 0x02040608UL
            ||  PACKET_remaining(&subpkt)
            || !PACKET_forward(&pkt, BUF_LEN - 8)
            || !PACKET_get_sub_packet(&pkt, &subpkt, 4)
            || !PACKET_get_net_4(&subpkt, &i)
            ||  i != 0xf8fafcfeUL
            ||  PACKET_remaining(&subpkt)
            ||  PACKET_get_sub_packet(&pkt, &subpkt, 4)) {
        fprintf(stderr, "test_PACKET_get_sub_packet() failed\n");
        return 0;
    }

    return 1;
}
Esempio n. 25
0
static int test_PACKET_copy_bytes()
{
    unsigned char bytes[4];
    PACKET pkt;

    if (!TEST_true(PACKET_buf_init(&pkt, smbuf, BUF_LEN))
            || !TEST_true(PACKET_copy_bytes(&pkt, bytes, 4))
            || !TEST_char_eq(bytes[0], 2)
            || !TEST_char_eq(bytes[1], 4)
            || !TEST_char_eq(bytes[2], 6)
            || !TEST_char_eq(bytes[3], 8)
            || !TEST_size_t_eq(PACKET_remaining(&pkt), BUF_LEN - 4)
            || !TEST_true(PACKET_forward(&pkt, BUF_LEN - 8))
            || !TEST_true(PACKET_copy_bytes(&pkt, bytes, 4))
            || !TEST_uchar_eq(bytes[0], 0xf8)
            || !TEST_uchar_eq(bytes[1], 0xfa)
            || !TEST_uchar_eq(bytes[2], 0xfc)
            || !TEST_uchar_eq(bytes[3], 0xfe)
            || !TEST_false(PACKET_remaining(&pkt)))
        return 0;

    return 1;
}
Esempio n. 26
0
static int test_client_hello(int currtest)
{
    SSL_CTX *ctx;
    SSL *con = NULL;
    BIO *rbio;
    BIO *wbio;
    long len;
    unsigned char *data;
    PACKET pkt = {0}, pkt2 = {0}, pkt3 = {0};
    char *dummytick = "Hello World!";
    unsigned int type = 0;
    int testresult = 0;
    size_t msglen;
    BIO *sessbio = NULL;
    SSL_SESSION *sess = NULL;

#ifdef OPENSSL_NO_TLS1_3
    if (currtest == TEST_ADD_PADDING_AND_PSK)
        return 1;
#endif

    /*
     * For each test set up an SSL_CTX and SSL and see what ClientHello gets
     * produced when we try to connect
     */
    ctx = SSL_CTX_new(TLS_method());
    if (!TEST_ptr(ctx))
        goto end;

    switch(currtest) {
    case TEST_SET_SESSION_TICK_DATA_VER_NEG:
        /* Testing for session tickets <= TLS1.2; not relevant for 1.3 */
        if (!TEST_true(SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION)))
            goto end;
        break;

    case TEST_ADD_PADDING_AND_PSK:
    case TEST_ADD_PADDING:
    case TEST_PADDING_NOT_NEEDED:
        SSL_CTX_set_options(ctx, SSL_OP_TLSEXT_PADDING);
        /*
         * Add lots of ciphersuites so that the ClientHello is at least
         * F5_WORKAROUND_MIN_MSG_LEN bytes long - meaning padding will be
         * needed. Also add some dummy ALPN protocols in case we still don't
         * have enough.
         */
        if (currtest == TEST_ADD_PADDING
                && (!TEST_true(SSL_CTX_set_cipher_list(ctx, "ALL"))
                    || !TEST_false(SSL_CTX_set_alpn_protos(ctx,
                                               (unsigned char *)alpn_prots,
                                               sizeof(alpn_prots) - 1))))
            goto end;

        break;

    default:
        goto end;
    }

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

    if (currtest == TEST_ADD_PADDING_AND_PSK) {
        sessbio = BIO_new_file(sessionfile, "r");
        if (!TEST_ptr(sessbio)) {
            TEST_info("Unable to open session.pem");
            goto end;
        }
        sess = PEM_read_bio_SSL_SESSION(sessbio, NULL, NULL, NULL);
        if (!TEST_ptr(sess)) {
            TEST_info("Unable to load SSL_SESSION");
            goto end;
        }
        /*
         * We reset the creation time so that we don't discard the session as
         * too old.
         */
        if (!TEST_true(SSL_SESSION_set_time(sess, time(NULL)))
                || !TEST_true(SSL_set_session(con, sess)))
            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);

    if (currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {
        if (!TEST_true(SSL_set_session_ticket_ext(con, dummytick,
                                                  strlen(dummytick))))
            goto end;
    }

    if (!TEST_int_le(SSL_connect(con), 0)) {
        /* This shouldn't succeed because we don't have a server! */
        goto end;
    }

    len = BIO_get_mem_data(wbio, (char **)&data);
    if (!TEST_true(PACKET_buf_init(&pkt, data, len))
               /* Skip the record header */
            || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH))
        goto end;

    msglen = PACKET_remaining(&pkt);

    /* Skip the handshake message header */
    if (!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 */
    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_session_ticket) {
            if (currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) {
                if (TEST_true(PACKET_equal(&pkt3, dummytick,
                                           strlen(dummytick)))) {
                    /* Ticket data is as we expected */
                    testresult = 1;
                }
                goto end;
            }
        }
        if (type == TLSEXT_TYPE_padding) {
            if (!TEST_false(currtest == TEST_PADDING_NOT_NEEDED))
                goto end;
            else if (TEST_true(currtest == TEST_ADD_PADDING
                    || currtest == TEST_ADD_PADDING_AND_PSK))
                testresult = TEST_true(msglen == F5_WORKAROUND_MAX_MSG_LEN);
        }
    }

    if (currtest == TEST_PADDING_NOT_NEEDED)
        testresult = 1;

end:
    SSL_free(con);
    SSL_CTX_free(ctx);
    SSL_SESSION_free(sess);
    BIO_free(sessbio);

    return testresult;
}
Esempio n. 27
0
int DTLSv1_listen(SSL *s, BIO_ADDR *client)
{
    int next, n, ret = 0, clearpkt = 0;
    unsigned char cookie[DTLS1_COOKIE_LENGTH];
    unsigned char seq[SEQ_NUM_SIZE];
    const unsigned char *data;
    unsigned char *p, *buf;
    unsigned long reclen, fragoff, fraglen, msglen;
    unsigned int rectype, versmajor, msgseq, msgtype, clientvers, cookielen;
    BIO *rbio, *wbio;
    BUF_MEM *bufm;
    BIO_ADDR *tmpclient = NULL;
    PACKET pkt, msgpkt, msgpayload, session, cookiepkt;

    /* Ensure there is no state left over from a previous invocation */
    if (!SSL_clear(s))
        return -1;

    ERR_clear_error();

    rbio = SSL_get_rbio(s);
    wbio = SSL_get_wbio(s);

    if (!rbio || !wbio) {
        SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BIO_NOT_SET);
        return -1;
    }

    /*
     * We only peek at incoming ClientHello's until we're sure we are going to
     * to respond with a HelloVerifyRequest. If its a ClientHello with a valid
     * cookie then we leave it in the BIO for accept to handle.
     */
    BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);

    /*
     * Note: This check deliberately excludes DTLS1_BAD_VER because that version
     * requires the MAC to be calculated *including* the first ClientHello
     * (without the cookie). Since DTLSv1_listen is stateless that cannot be
     * supported. DTLS1_BAD_VER must use cookies in a stateful manner (e.g. via
     * SSL_accept)
     */
    if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) {
        SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNSUPPORTED_SSL_VERSION);
        return -1;
    }

    if (s->init_buf == NULL) {
        if ((bufm = BUF_MEM_new()) == NULL) {
            SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
            return -1;
        }

        if (!BUF_MEM_grow(bufm, SSL3_RT_MAX_PLAIN_LENGTH)) {
            BUF_MEM_free(bufm);
            SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
            return -1;
        }
        s->init_buf = bufm;
    }
    buf = (unsigned char *)s->init_buf->data;

    do {
        /* Get a packet */

        clear_sys_error();
        /*
         * Technically a ClientHello could be SSL3_RT_MAX_PLAIN_LENGTH
         * + DTLS1_RT_HEADER_LENGTH bytes long. Normally init_buf does not store
         * the record header as well, but we do here. We've set up init_buf to
         * be the standard size for simplicity. In practice we shouldn't ever
         * receive a ClientHello as long as this. If we do it will get dropped
         * in the record length check below.
         */
        n = BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);

        if (n <= 0) {
            if (BIO_should_retry(rbio)) {
                /* Non-blocking IO */
                goto end;
            }
            return -1;
        }

        /* If we hit any problems we need to clear this packet from the BIO */
        clearpkt = 1;

        if (!PACKET_buf_init(&pkt, buf, n)) {
            SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_INTERNAL_ERROR);
            return -1;
        }

        /*
         * Parse the received record. If there are any problems with it we just
         * dump it - with no alert. RFC6347 says this "Unlike TLS, DTLS is
         * resilient in the face of invalid records (e.g., invalid formatting,
         * length, MAC, etc.).  In general, invalid records SHOULD be silently
         * discarded, thus preserving the association; however, an error MAY be
         * logged for diagnostic purposes."
         */

        /* this packet contained a partial record, dump it */
        if (n < DTLS1_RT_HEADER_LENGTH) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_RECORD_TOO_SMALL);
            goto end;
        }

        if (s->msg_callback)
            s->msg_callback(0, 0, SSL3_RT_HEADER, buf,
                            DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);

        /* Get the record header */
        if (!PACKET_get_1(&pkt, &rectype)
            || !PACKET_get_1(&pkt, &versmajor)) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
            goto end;
        }

        if (rectype != SSL3_RT_HANDSHAKE) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
            goto end;
        }

        /*
         * Check record version number. We only check that the major version is
         * the same.
         */
        if (versmajor != DTLS1_VERSION_MAJOR) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
            goto end;
        }

        if (!PACKET_forward(&pkt, 1)
            /* Save the sequence number: 64 bits, with top 2 bytes = epoch */
            || !PACKET_copy_bytes(&pkt, seq, SEQ_NUM_SIZE)
            || !PACKET_get_length_prefixed_2(&pkt, &msgpkt)) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
            goto end;
        }
        /*
         * We allow data remaining at the end of the packet because there could
         * be a second record (but we ignore it)
         */

        /* This is an initial ClientHello so the epoch has to be 0 */
        if (seq[0] != 0 || seq[1] != 0) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
            goto end;
        }

        /* Get a pointer to the raw message for the later callback */
        data = PACKET_data(&msgpkt);

        /* Finished processing the record header, now process the message */
        if (!PACKET_get_1(&msgpkt, &msgtype)
            || !PACKET_get_net_3(&msgpkt, &msglen)
            || !PACKET_get_net_2(&msgpkt, &msgseq)
            || !PACKET_get_net_3(&msgpkt, &fragoff)
            || !PACKET_get_net_3(&msgpkt, &fraglen)
            || !PACKET_get_sub_packet(&msgpkt, &msgpayload, fraglen)
            || PACKET_remaining(&msgpkt) != 0) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
            goto end;
        }

        if (msgtype != SSL3_MT_CLIENT_HELLO) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_UNEXPECTED_MESSAGE);
            goto end;
        }

        /* Message sequence number can only be 0 or 1 */
        if (msgseq > 2) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_INVALID_SEQUENCE_NUMBER);
            goto end;
        }

        /*
         * We don't support fragment reassembly for ClientHellos whilst
         * listening because that would require server side state (which is
         * against the whole point of the ClientHello/HelloVerifyRequest
         * mechanism). Instead we only look at the first ClientHello fragment
         * and require that the cookie must be contained within it.
         */
        if (fragoff != 0 || fraglen > msglen) {
            /* Non initial ClientHello fragment (or bad fragment) */
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_FRAGMENTED_CLIENT_HELLO);
            goto end;
        }

        if (s->msg_callback)
            s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, data,
                            fraglen + DTLS1_HM_HEADER_LENGTH, s,
                            s->msg_callback_arg);

        if (!PACKET_get_net_2(&msgpayload, &clientvers)) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
            goto end;
        }

        /*
         * Verify client version is supported
         */
        if (DTLS_VERSION_LT(clientvers, (unsigned int)s->method->version) &&
            s->method->version != DTLS_ANY_VERSION) {
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_WRONG_VERSION_NUMBER);
            goto end;
        }

        if (!PACKET_forward(&msgpayload, SSL3_RANDOM_SIZE)
            || !PACKET_get_length_prefixed_1(&msgpayload, &session)
            || !PACKET_get_length_prefixed_1(&msgpayload, &cookiepkt)) {
            /*
             * Could be malformed or the cookie does not fit within the initial
             * ClientHello fragment. Either way we can't handle it.
             */
            SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_LENGTH_MISMATCH);
            goto end;
        }

        /*
         * Check if we have a cookie or not. If not we need to send a
         * HelloVerifyRequest.
         */
        if (PACKET_remaining(&cookiepkt) == 0) {
            next = LISTEN_SEND_VERIFY_REQUEST;
        } else {
            /*
             * We have a cookie, so lets check it.
             */
            if (s->ctx->app_verify_cookie_cb == NULL) {
                SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_NO_VERIFY_COOKIE_CALLBACK);
                /* This is fatal */
                return -1;
            }
            if (s->ctx->app_verify_cookie_cb(s, PACKET_data(&cookiepkt),
                                             PACKET_remaining(&cookiepkt)) ==
                0) {
                /*
                 * We treat invalid cookies in the same was as no cookie as
                 * per RFC6347
                 */
                next = LISTEN_SEND_VERIFY_REQUEST;
            } else {
                /* Cookie verification succeeded */
                next = LISTEN_SUCCESS;
            }
        }

        if (next == LISTEN_SEND_VERIFY_REQUEST) {
            /*
             * There was no cookie in the ClientHello so we need to send a
             * HelloVerifyRequest. If this fails we do not worry about trying
             * to resend, we just drop it.
             */

            /*
             * Dump the read packet, we don't need it any more. Ignore return
             * value
             */
            BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 0, NULL);
            BIO_read(rbio, buf, SSL3_RT_MAX_PLAIN_LENGTH);
            BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_PEEK_MODE, 1, NULL);

            /* Generate the cookie */
            if (s->ctx->app_gen_cookie_cb == NULL ||
                s->ctx->app_gen_cookie_cb(s, cookie, &cookielen) == 0 ||
                cookielen > 255) {
                SSLerr(SSL_F_DTLSV1_LISTEN, SSL_R_COOKIE_GEN_CALLBACK_FAILURE);
                /* This is fatal */
                return -1;
            }

            p = &buf[DTLS1_RT_HEADER_LENGTH];
            msglen = dtls_raw_hello_verify_request(p + DTLS1_HM_HEADER_LENGTH,
                                                   cookie, cookielen);

            *p++ = DTLS1_MT_HELLO_VERIFY_REQUEST;

            /* Message length */
            l2n3(msglen, p);

            /* Message sequence number is always 0 for a HelloVerifyRequest */
            s2n(0, p);

            /*
             * We never fragment a HelloVerifyRequest, so fragment offset is 0
             * and fragment length is message length
             */
            l2n3(0, p);
            l2n3(msglen, p);

            /* Set reclen equal to length of whole handshake message */
            reclen = msglen + DTLS1_HM_HEADER_LENGTH;

            /* Add the record header */
            p = buf;

            *(p++) = SSL3_RT_HANDSHAKE;
            /*
             * Special case: for hello verify request, client version 1.0 and we
             * haven't decided which version to use yet send back using version
             * 1.0 header: otherwise some clients will ignore it.
             */
            if (s->method->version == DTLS_ANY_VERSION) {
                *(p++) = DTLS1_VERSION >> 8;
                *(p++) = DTLS1_VERSION & 0xff;
            } else {
                *(p++) = s->version >> 8;
                *(p++) = s->version & 0xff;
            }

            /*
             * Record sequence number is always the same as in the received
             * ClientHello
             */
            memcpy(p, seq, SEQ_NUM_SIZE);
            p += SEQ_NUM_SIZE;

            /* Length */
            s2n(reclen, p);

            /*
             * Set reclen equal to length of whole record including record
             * header
             */
            reclen += DTLS1_RT_HEADER_LENGTH;

            if (s->msg_callback)
                s->msg_callback(1, 0, SSL3_RT_HEADER, buf,
                                DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);

            if ((tmpclient = BIO_ADDR_new()) == NULL) {
                SSLerr(SSL_F_DTLSV1_LISTEN, ERR_R_MALLOC_FAILURE);
                goto end;
            }

            /*
             * This is unnecessary if rbio and wbio are one and the same - but
             * maybe they're not. We ignore errors here - some BIOs do not
             * support this.
             */
            if (BIO_dgram_get_peer(rbio, tmpclient) > 0) {
                (void)BIO_dgram_set_peer(wbio, tmpclient);
            }
            BIO_ADDR_free(tmpclient);
            tmpclient = NULL;

            if (BIO_write(wbio, buf, reclen) < (int)reclen) {
                if (BIO_should_retry(wbio)) {
                    /*
                     * Non-blocking IO...but we're stateless, so we're just
                     * going to drop this packet.
                     */
                    goto end;
                }
                return -1;
            }

            if (BIO_flush(wbio) <= 0) {
                if (BIO_should_retry(wbio)) {
                    /*
                     * Non-blocking IO...but we're stateless, so we're just
                     * going to drop this packet.
                     */
                    goto end;
                }
                return -1;
            }
        }
Esempio n. 28
0
int tls_parse_ctos_use_srtp(SSL *s, PACKET *pkt, unsigned int context, X509 *x,
                            size_t chainidx, int *al)
{
    STACK_OF(SRTP_PROTECTION_PROFILE) *srvr;
    unsigned int ct, mki_len, id;
    int i, srtp_pref;
    PACKET subpkt;

    /* Ignore this if we have no SRTP profiles */
    if (SSL_get_srtp_profiles(s) == NULL)
        return 1;

    /* Pull off the length of the cipher suite list  and check it is even */
    if (!PACKET_get_net_2(pkt, &ct) || (ct & 1) != 0
            || !PACKET_get_sub_packet(pkt, &subpkt, ct)) {
        SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP,
               SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    srvr = SSL_get_srtp_profiles(s);
    s->srtp_profile = NULL;
    /* Search all profiles for a match initially */
    srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr);

    while (PACKET_remaining(&subpkt)) {
        if (!PACKET_get_net_2(&subpkt, &id)) {
            SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP,
                   SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
            *al = SSL_AD_DECODE_ERROR;
            return 0;
        }

        /*
         * Only look for match in profiles of higher preference than
         * current match.
         * If no profiles have been have been configured then this
         * does nothing.
         */
        for (i = 0; i < srtp_pref; i++) {
            SRTP_PROTECTION_PROFILE *sprof =
                sk_SRTP_PROTECTION_PROFILE_value(srvr, i);

            if (sprof->id == id) {
                s->srtp_profile = sprof;
                srtp_pref = i;
                break;
            }
        }
    }

    /* Now extract the MKI value as a sanity check, but discard it for now */
    if (!PACKET_get_1(pkt, &mki_len)) {
        SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP,
               SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    if (!PACKET_forward(pkt, mki_len)
        || PACKET_remaining(pkt)) {
        SSLerr(SSL_F_TLS_PARSE_CTOS_USE_SRTP, SSL_R_BAD_SRTP_MKI_VALUE);
        *al = SSL_AD_DECODE_ERROR;
        return 0;
    }

    return 1;
}
Esempio n. 29
0
static int watchccs_write(BIO *bio, const char *in, int inl)
{
    int ret = 0;
    BIO *next = BIO_next(bio);
    PACKET pkt, msg, msgbody, sessionid;
    unsigned int rectype, recvers, msgtype, expectedrecvers;

    if (inl <= 0)
        return 0;
    if (next == NULL)
        return 0;

    BIO_clear_retry_flags(bio);

    if (!PACKET_buf_init(&pkt, (const unsigned char *)in, inl))
        return 0;

    /* We assume that we always write complete records each time */
    while (PACKET_remaining(&pkt)) {
        if (!PACKET_get_1(&pkt, &rectype)
                || !PACKET_get_net_2(&pkt, &recvers)
                || !PACKET_get_length_prefixed_2(&pkt, &msg))
            return 0;

        expectedrecvers = TLS1_2_VERSION;

        if (rectype == SSL3_RT_HANDSHAKE) {
            if (!PACKET_get_1(&msg, &msgtype)
                    || !PACKET_get_length_prefixed_3(&msg, &msgbody))
                return 0;
            if (msgtype == SSL3_MT_CLIENT_HELLO) {
                chseen++;

                /*
                 * Skip legacy_version (2 bytes) and Random (32 bytes) to read
                 * session_id.
                 */
                if (!PACKET_forward(&msgbody, 34)
                        || !PACKET_get_length_prefixed_1(&msgbody, &sessionid))
                    return 0;

                if (chseen == 1) {
                    expectedrecvers = TLS1_VERSION;

                    /* Save the session id for later */
                    chsessidlen = PACKET_remaining(&sessionid);
                    if (!PACKET_copy_bytes(&sessionid, chsessid, chsessidlen))
                        return 0;
                } else {
                    /*
                     * Check the session id for the second ClientHello is the
                     * same as the first one.
                     */
                    if (PACKET_remaining(&sessionid) != chsessidlen
                            || (chsessidlen > 0
                                && memcmp(chsessid, PACKET_data(&sessionid),
                                          chsessidlen) != 0))
                        badsessid = 1;
                }
            } else if (msgtype == SSL3_MT_SERVER_HELLO) {
                shseen++;
                /*
                 * Skip legacy_version (2 bytes) and Random (32 bytes) to read
                 * session_id.
                 */
                if (!PACKET_forward(&msgbody, 34)
                        || !PACKET_get_length_prefixed_1(&msgbody, &sessionid))
                    return 0;

                /*
                 * Check the session id is the same as the one in the
                 * ClientHello
                 */
                if (PACKET_remaining(&sessionid) != chsessidlen
                        || (chsessidlen > 0
                            && memcmp(chsessid, PACKET_data(&sessionid),
                                      chsessidlen) != 0))
                    badsessid = 1;
            }
        } else if (rectype == SSL3_RT_CHANGE_CIPHER_SPEC) {
            if (bio == s_to_c_fbio) {
                /*
                 * Server writing. We shouldn't have written any app data
                 * yet, and we should have seen both the ClientHello and the
                 * ServerHello
                 */
                if (!sappdataseen
                        && chseen == 1
                        && shseen == 1
                        && !sccsseen)
                    sccsseen = 1;
                else
                    badccs = 1;
            } else if (!cappdataseen) {
                /*
                 * Client writing. We shouldn't have written any app data
                 * yet, and we should have seen the ClientHello
                 */
                if (shseen == 1 && !ccsaftersh)
                    ccsaftersh = 1;
                else if (shseen == 0 && !ccsbeforesh)
                    ccsbeforesh = 1;
                else
                    badccs = 1;
            } else {
                badccs = 1;
            }
        } else if(rectype == SSL3_RT_APPLICATION_DATA) {
            if (bio == s_to_c_fbio)
                sappdataseen = 1;
            else
                cappdataseen = 1;
        }
        if (recvers != expectedrecvers)
            badvers = 1;
    }

    ret = BIO_write(next, in, inl);
    if (ret <= 0 && BIO_should_write(next))
        BIO_set_retry_write(bio);

    return ret;
}