Example #1
0
int FuzzerTestOneInput(const uint8_t *buf, size_t len)
{
    SSL *server;
    BIO *in;
    BIO *out;
#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DSA)
    BIO *bio_buf;
#endif
    SSL_CTX *ctx;
    int ret;
    RSA *privkey;
    const uint8_t *bufp;
    EVP_PKEY *pkey;
    X509 *cert;
#ifndef OPENSSL_NO_EC
    EC_KEY *ecdsakey = NULL;
#endif
#ifndef OPENSSL_NO_DSA
    DSA *dsakey = NULL;
#endif
    uint8_t opt;

    if (len < 2)
        return 0;

    /*
     * TODO: use the ossltest engine (optionally?) to disable crypto checks.
     */

    /* This only fuzzes the initial flow from the client so far. */
    ctx = SSL_CTX_new(SSLv23_method());

    ret = SSL_CTX_set_min_proto_version(ctx, 0);
    OPENSSL_assert(ret == 1);
    ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:@SECLEVEL=0");
    OPENSSL_assert(ret == 1);

    /* RSA */
    bufp = kRSAPrivateKeyDER;
    privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER));
    OPENSSL_assert(privkey != NULL);
    pkey = EVP_PKEY_new();
    EVP_PKEY_assign_RSA(pkey, privkey);
    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
    OPENSSL_assert(ret == 1);
    EVP_PKEY_free(pkey);

    bufp = kCertificateDER;
    cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER));
    OPENSSL_assert(cert != NULL);
    ret = SSL_CTX_use_certificate(ctx, cert);
    OPENSSL_assert(ret == 1);
    X509_free(cert);

#ifndef OPENSSL_NO_EC
    /* ECDSA */
    bio_buf = BIO_new(BIO_s_mem());
    OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSAPrivateKeyPEM, sizeof(ECDSAPrivateKeyPEM)) == sizeof(ECDSAPrivateKeyPEM));
    ecdsakey = PEM_read_bio_ECPrivateKey(bio_buf, NULL, NULL, NULL);
    ERR_print_errors_fp(stderr);
    OPENSSL_assert(ecdsakey != NULL);
    BIO_free(bio_buf);
    pkey = EVP_PKEY_new();
    EVP_PKEY_assign_EC_KEY(pkey, ecdsakey);
    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
    OPENSSL_assert(ret == 1);
    EVP_PKEY_free(pkey);

    bio_buf = BIO_new(BIO_s_mem());
    OPENSSL_assert((size_t)BIO_write(bio_buf, ECDSACertPEM, sizeof(ECDSACertPEM)) == sizeof(ECDSACertPEM));
    cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL);
    OPENSSL_assert(cert != NULL);
    BIO_free(bio_buf);
    ret = SSL_CTX_use_certificate(ctx, cert);
    OPENSSL_assert(ret == 1);
    X509_free(cert);
#endif

#ifndef OPENSSL_NO_DSA
    /* DSA */
    bio_buf = BIO_new(BIO_s_mem());
    OPENSSL_assert((size_t)BIO_write(bio_buf, DSAPrivateKeyPEM, sizeof(DSAPrivateKeyPEM)) == sizeof(DSAPrivateKeyPEM));
    dsakey = PEM_read_bio_DSAPrivateKey(bio_buf, NULL, NULL, NULL);
    ERR_print_errors_fp(stderr);
    OPENSSL_assert(dsakey != NULL);
    BIO_free(bio_buf);
    pkey = EVP_PKEY_new();
    EVP_PKEY_assign_DSA(pkey, dsakey);
    ret = SSL_CTX_use_PrivateKey(ctx, pkey);
    OPENSSL_assert(ret == 1);
    EVP_PKEY_free(pkey);

    bio_buf = BIO_new(BIO_s_mem());
    OPENSSL_assert((size_t)BIO_write(bio_buf, DSACertPEM, sizeof(DSACertPEM)) == sizeof(DSACertPEM));
    cert = PEM_read_bio_X509(bio_buf, NULL, NULL, NULL);
    OPENSSL_assert(cert != NULL);
    BIO_free(bio_buf);
    ret = SSL_CTX_use_certificate(ctx, cert);
    OPENSSL_assert(ret == 1);
    X509_free(cert);
#endif

    /* TODO: Set up support for SRP and PSK */

    server = SSL_new(ctx);
    in = BIO_new(BIO_s_mem());
    out = BIO_new(BIO_s_mem());
    SSL_set_bio(server, in, out);
    SSL_set_accept_state(server);

    opt = (uint8_t)buf[len-1];
    len--;

    OPENSSL_assert((size_t)BIO_write(in, buf, len) == len);

    if ((opt & 0x01) != 0)
    {
        do {
            char early_buf[16384];
            size_t early_len;
            ret = SSL_read_early_data(server, early_buf, sizeof(early_buf), &early_len);

            if (ret != SSL_READ_EARLY_DATA_SUCCESS)
                break;
        } while (1);
    }

    if (SSL_do_handshake(server) == 1) {
        /* Keep reading application data until error or EOF. */
        uint8_t tmp[1024];
        for (;;) {
            if (SSL_read(server, tmp, sizeof(tmp)) <= 0) {
                break;
            }
        }
    }
    SSL_free(server);
    ERR_clear_error();
    SSL_CTX_free(ctx);

    return 0;
}
Example #2
0
static int test_tls13ccs(int tst)
{
    SSL_CTX *sctx = NULL, *cctx = NULL;
    SSL *sssl = NULL, *cssl = NULL;
    int ret = 0;
    const char msg[] = "Dummy data";
    char buf[80];
    size_t written, readbytes;
    SSL_SESSION *sess = NULL;

    chseen = shseen = sccsseen = ccsaftersh = ccsbeforesh = 0;
    sappdataseen = cappdataseen = badccs = badvers = badsessid = 0;
    chsessidlen = 0;

    if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(),
                                       TLS1_VERSION, 0,
                                       &sctx, &cctx, cert, privkey))
        || !TEST_true(SSL_CTX_set_max_early_data(sctx,
                                                 SSL3_RT_MAX_PLAIN_LENGTH)))
        goto err;

    /*
     * Test 0: Simple Handshake
     * Test 1: Simple Handshake, client middlebox compat mode disabled
     * Test 2: Simple Handshake, server middlebox compat mode disabled
     * Test 3: HRR Handshake
     * Test 4: HRR Handshake, client middlebox compat mode disabled
     * Test 5: HRR Handshake, server middlebox compat mode disabled
     * Test 6: Early data handshake
     * Test 7: Early data handshake, client middlebox compat mode disabled
     * Test 8: Early data handshake, server middlebox compat mode disabled
     * Test 9: Early data then HRR
     * Test 10: Early data then HRR, client middlebox compat mode disabled
     * Test 11: Early data then HRR, server middlebox compat mode disabled
     */
    switch (tst) {
    case 0:
    case 3:
    case 6:
    case 9:
        break;
    case 1:
    case 4:
    case 7:
    case 10:
        SSL_CTX_clear_options(cctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
        break;
    case 2:
    case 5:
    case 8:
    case 11:
        SSL_CTX_clear_options(sctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT);
        break;
    default:
        TEST_error("Invalid test value");
        goto err;
    }

    if (tst >= 6) {
        /* Get a session suitable for early_data */
        if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))
                || !TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE)))
            goto err;
        sess = SSL_get1_session(cssl);
        if (!TEST_ptr(sess))
            goto err;
        SSL_shutdown(cssl);
        SSL_shutdown(sssl);
        SSL_free(sssl);
        SSL_free(cssl);
        sssl = cssl = NULL;
    }

    if ((tst >= 3 && tst <= 5) || tst >= 9) {
        /* HRR handshake */
        if (!TEST_true(SSL_CTX_set1_groups_list(sctx, "P-256")))
            goto err;
    }

    s_to_c_fbio = BIO_new(bio_f_watchccs_filter());
    c_to_s_fbio = BIO_new(bio_f_watchccs_filter());
    if (!TEST_ptr(s_to_c_fbio)
            || !TEST_ptr(c_to_s_fbio)) {
        BIO_free(s_to_c_fbio);
        BIO_free(c_to_s_fbio);
        goto err;
    }

    /* BIOs get freed on error */
    if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, s_to_c_fbio,
                                      c_to_s_fbio)))
        goto err;

    if (tst >= 6) {
        /* Early data */
        if (!TEST_true(SSL_set_session(cssl, sess))
                || !TEST_true(SSL_write_early_data(cssl, msg, strlen(msg),
                                                   &written))
                || (tst <= 8
                    && !TEST_int_eq(SSL_read_early_data(sssl, buf,  sizeof(buf),
                                                &readbytes),
                                                SSL_READ_EARLY_DATA_SUCCESS)))
            goto err;
        if (tst <= 8) {
            if (!TEST_int_gt(SSL_connect(cssl), 0))
                goto err;
        } else {
            if (!TEST_int_le(SSL_connect(cssl), 0))
                goto err;
        }
        if (!TEST_int_eq(SSL_read_early_data(sssl, buf,  sizeof(buf),
                                             &readbytes),
                         SSL_READ_EARLY_DATA_FINISH))
            goto err;
    }

    /* Perform handshake (or complete it if doing early data ) */
    if (!TEST_true(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE)))
        goto err;

    /*
     * Check there were no unexpected CCS messages, all record versions
     * were as expected, and that the session ids were reflected by the server
     * correctly.
     */
    if (!TEST_false(badccs) || !TEST_false(badvers) || !TEST_false(badsessid))
        goto err;

    switch (tst) {
    case 0:
        if (!TEST_true(sccsseen)
                || !TEST_true(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    case 1:
        if (!TEST_true(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_eq(chsessidlen, 0))
            goto err;
        break;

    case 2:
        if (!TEST_false(sccsseen)
                || !TEST_true(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    case 3:
        if (!TEST_true(sccsseen)
                || !TEST_true(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    case 4:
        if (!TEST_true(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_eq(chsessidlen, 0))
            goto err;
        break;

    case 5:
        if (!TEST_false(sccsseen)
                || !TEST_true(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    case 6:
        if (!TEST_true(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_true(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    case 7:
        if (!TEST_true(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_eq(chsessidlen, 0))
            goto err;
        break;

    case 8:
        if (!TEST_false(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_true(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    case 9:
        if (!TEST_true(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_true(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    case 10:
        if (!TEST_true(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_false(ccsbeforesh)
                || !TEST_size_t_eq(chsessidlen, 0))
            goto err;
        break;

    case 11:
        if (!TEST_false(sccsseen)
                || !TEST_false(ccsaftersh)
                || !TEST_true(ccsbeforesh)
                || !TEST_size_t_gt(chsessidlen, 0))
            goto err;
        break;

    default:
        TEST_error("Invalid test value");
        goto err;
    }

    ret = 1;
 err:
    SSL_SESSION_free(sess);
    SSL_free(sssl);
    SSL_free(cssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);

    return ret;
}