test/sslapitest.c
static int early_data_skip_helper(int testtype, int idx)
{
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;
    SSL_SESSION *sess = NULL;
    unsigned char buf[20];
    size_t readbytes, written;

    if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
                                        &serverssl, &sess, idx)))
        goto end;

    if (testtype == 1 || testtype == 2) {
        /* Force an HRR to occur */
        if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256")))
            goto end;
    } else if (idx == 2) {
        /*
         * We force early_data rejection by ensuring the PSK identity is
         * unrecognised
         */
        srvid = "Dummy Identity";
    } else {
        /*
         * Deliberately corrupt the creation time. We take 20 seconds off the
         * time. It could be any value as long as it is not within tolerance.
         * This should mean the ticket is rejected.
         */
        if (!TEST_true(SSL_SESSION_set_time(sess, (long)(time(NULL) - 20))))
            goto end;
    }

    if (testtype == 3
            && !TEST_true(SSL_set_recv_max_early_data(serverssl, 0)))
        goto end;

    /* Write some early data */
    if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
                                        &written))
            || !TEST_size_t_eq(written, strlen(MSG1)))
        goto end;

    /* Server should reject the early data */
    if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
                                         &readbytes),
                     SSL_READ_EARLY_DATA_FINISH)
            || !TEST_size_t_eq(readbytes, 0)
            || !TEST_int_eq(SSL_get_early_data_status(serverssl),
                            SSL_EARLY_DATA_REJECTED))
        goto end;

    switch (testtype) {
    case 0:
        /* Nothing to do */
        break;

    case 1:
        /*
         * Finish off the handshake. We perform the same writes and reads as
         * further down but we expect them to fail due to the incomplete
         * handshake.
         */
        if (!TEST_false(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
                || !TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
                               &readbytes)))
            goto end;
        break;

    case 2:
        {
            BIO *wbio = SSL_get_wbio(clientssl);
            /* A record that will appear as bad early_data */
            const unsigned char bad_early_data[] = {
                0x17, 0x03, 0x03, 0x00, 0x01, 0x00
            };

            /*
             * We force the client to attempt a write. This will fail because
             * we're still in the handshake. It will cause the second
             * ClientHello to be sent.
             */
            if (!TEST_false(SSL_write_ex(clientssl, MSG2, strlen(MSG2),
                                         &written)))
                goto end;

            /*
             * Inject some early_data after the second ClientHello. This should
             * cause the server to fail
             */
            if (!TEST_true(BIO_write_ex(wbio, bad_early_data,
                                        sizeof(bad_early_data), &written)))
                goto end;
        }
        /* fallthrough */

    case 3:
        /*
         * This client has sent more early_data than we are willing to skip
         * (case 3) or sent invalid early_data (case 2) so the connection should
         * abort.
         */
        if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
                || !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_SSL))
            goto end;

        /* Connection has failed - nothing more to do */
        testresult = 1;
        goto end;

    default:
        TEST_error("Invalid test type");
        goto end;
    }

    /*
     * Should be able to send normal data despite rejection of early data. The
     * early_data should be skipped.
     */
    if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
            || !TEST_size_t_eq(written, strlen(MSG2))
            || !TEST_int_eq(SSL_get_early_data_status(clientssl),
                            SSL_EARLY_DATA_REJECTED)
            || !TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
            || !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2)))
        goto end;

    testresult = 1;

 end:
    SSL_SESSION_free(clientpsk);
    SSL_SESSION_free(serverpsk);
    clientpsk = serverpsk = NULL;
    SSL_SESSION_free(sess);
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);
    return testresult;
}
/*
 * Helper function to test that a server attempting to read early data can
 * handle a connection from a client where the early data should be skipped.
 * testtype: 0 == No HRR
 * testtype: 1 == HRR
 * testtype: 2 == HRR, invalid early_data sent after HRR
 * testtype: 3 == recv_max_early_data set to 0
 */
Helper function to test that a server attempting to read early data can
handle a connection from a client where the early data should be skipped.
Helper function to test that a server attempting to read early data can handle a connection from a client where the early data should be skipped .
static int early_data_skip_helper(int testtype, int idx)
{
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;
    SSL_SESSION *sess = NULL;
    unsigned char buf[20];
    size_t readbytes, written;
    if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl,
                                        &serverssl, &sess, idx)))
        goto end;
    if (testtype == 1 || testtype == 2) {
        if (!TEST_true(SSL_set1_groups_list(serverssl, "P-256")))
            goto end;
    } else if (idx == 2) {
        srvid = "Dummy Identity";
    } else {
        if (!TEST_true(SSL_SESSION_set_time(sess, (long)(time(NULL) - 20))))
            goto end;
    }
    if (testtype == 3
            && !TEST_true(SSL_set_recv_max_early_data(serverssl, 0)))
        goto end;
    if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1),
                                        &written))
            || !TEST_size_t_eq(written, strlen(MSG1)))
        goto end;
    if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf),
                                         &readbytes),
                     SSL_READ_EARLY_DATA_FINISH)
            || !TEST_size_t_eq(readbytes, 0)
            || !TEST_int_eq(SSL_get_early_data_status(serverssl),
                            SSL_EARLY_DATA_REJECTED))
        goto end;
    switch (testtype) {
    case 0:
        break;
    case 1:
        if (!TEST_false(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
                || !TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf),
                               &readbytes)))
            goto end;
        break;
    case 2:
        {
            BIO *wbio = SSL_get_wbio(clientssl);
            const unsigned char bad_early_data[] = {
                0x17, 0x03, 0x03, 0x00, 0x01, 0x00
            };
            if (!TEST_false(SSL_write_ex(clientssl, MSG2, strlen(MSG2),
                                         &written)))
                goto end;
            if (!TEST_true(BIO_write_ex(wbio, bad_early_data,
                                        sizeof(bad_early_data), &written)))
                goto end;
        }
    case 3:
        if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
                || !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_SSL))
            goto end;
        testresult = 1;
        goto end;
    default:
        TEST_error("Invalid test type");
        goto end;
    }
    if (!TEST_true(SSL_write_ex(clientssl, MSG2, strlen(MSG2), &written))
            || !TEST_size_t_eq(written, strlen(MSG2))
            || !TEST_int_eq(SSL_get_early_data_status(clientssl),
                            SSL_EARLY_DATA_REJECTED)
            || !TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))
            || !TEST_mem_eq(buf, readbytes, MSG2, strlen(MSG2)))
        goto end;
    testresult = 1;
 end:
    SSL_SESSION_free(clientpsk);
    SSL_SESSION_free(serverpsk);
    clientpsk = serverpsk = NULL;
    SSL_SESSION_free(sess);
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);
    return testresult;
}
static int early_data_skip_helper ( int testtype , int idx ) { SSL_CTX * cctx = NULL , * sctx = NULL ; SSL * clientssl = NULL , * serverssl = NULL ; int testresult = 0 ; SSL_SESSION * sess = NULL ; unsigned char buf [ 20 ] ; size_t readbytes , written ; if ( ! TEST_true ( setupearly_data_test ( & cctx , & sctx , & clientssl , & serverssl , & sess , idx ) ) ) goto end ; if ( testtype == 1 || testtype == 2 ) { if ( ! TEST_true ( SSL_set1_groups_list ( serverssl , " " ) ) ) goto end ; } else if ( idx == 2 ) { srvid = " " ; } else { if ( ! TEST_true ( SSL_SESSION_set_time ( sess , ( long ) ( time ( NULL ) - 20 ) ) ) ) goto end ; } if ( testtype == 3 && ! TEST_true ( SSL_set_recv_max_early_data ( serverssl , 0 ) ) ) goto end ; if ( ! TEST_true ( SSL_write_early_data ( clientssl , MSG1 , strlen ( MSG1 ) , & written ) ) || ! TEST_size_t_eq ( written , strlen ( MSG1 ) ) ) goto end ; if ( ! TEST_int_eq ( SSL_read_early_data ( serverssl , buf , sizeof ( buf ) , & readbytes ) , SSL_READ_EARLY_DATA_FINISH ) || ! TEST_size_t_eq ( readbytes , 0 ) || ! TEST_int_eq ( SSL_get_early_data_status ( serverssl ) , SSL_EARLY_DATA_REJECTED ) ) goto end ; switch ( testtype ) { case 0 : break ; case 1 : if ( ! TEST_false ( SSL_write_ex ( clientssl , MSG2 , strlen ( MSG2 ) , & written ) ) || ! TEST_false ( SSL_read_ex ( serverssl , buf , sizeof ( buf ) , & readbytes ) ) ) goto end ; break ; case 2 : { BIO * wbio = SSL_get_wbio ( clientssl ) ; const unsigned char bad_early_data [ ] = { 0x17 , 0x03 , 0x03 , 0x00 , 0x01 , 0x00 } ; if ( ! TEST_false ( SSL_write_ex ( clientssl , MSG2 , strlen ( MSG2 ) , & written ) ) ) goto end ; if ( ! TEST_true ( BIO_write_ex ( wbio , bad_early_data , sizeof ( bad_early_data ) , & written ) ) ) goto end ; } case 3 : if ( ! TEST_false ( SSL_read_ex ( serverssl , buf , sizeof ( buf ) , & readbytes ) ) || ! TEST_int_eq ( SSL_get_error ( serverssl , 0 ) , SSL_ERROR_SSL ) ) goto end ; testresult = 1 ; goto end ; default : TEST_error ( " " ) ; goto end ; } if ( ! TEST_true ( SSL_write_ex ( clientssl , MSG2 , strlen ( MSG2 ) , & written ) ) || ! TEST_size_t_eq ( written , strlen ( MSG2 ) ) || ! TEST_int_eq ( SSL_get_early_data_status ( clientssl ) , SSL_EARLY_DATA_REJECTED ) || ! TEST_true ( SSL_read_ex ( serverssl , buf , sizeof ( buf ) , & readbytes ) ) || ! TEST_mem_eq ( buf , readbytes , MSG2 , strlen ( MSG2 ) ) ) goto end ; testresult = 1 ; end : SSL_SESSION_free ( clientpsk ) ; SSL_SESSION_free ( serverpsk ) ; clientpsk = serverpsk = NULL ; SSL_SESSION_free ( sess ) ; SSL_free ( serverssl ) ; SSL_free ( clientssl ) ; SSL_CTX_free ( sctx ) ; SSL_CTX_free ( cctx ) ; return testresult ; }
Helper function to test that a server attempting to read early data can
 handle a connection from a client where the early data should be skipped.
Helper function to test that a server attempting to read early data can handle a connection from a client where the early data should be skipped .
/* Force an HRR to occur */ /*
         * We force early_data rejection by ensuring the PSK identity is
         * unrecognised
         */ /*
         * Deliberately corrupt the creation time. We take 20 seconds off the
         * time. It could be any value as long as it is not within tolerance.
         * This should mean the ticket is rejected.
         */ /* Write some early data */ /* Server should reject the early data */ /* Nothing to do */ /*
         * Finish off the handshake. We perform the same writes and reads as
         * further down but we expect them to fail due to the incomplete
         * handshake.
         */ /* A record that will appear as bad early_data */ /*
             * We force the client to attempt a write. This will fail because
             * we're still in the handshake. It will cause the second
             * ClientHello to be sent.
             */ /*
             * Inject some early_data after the second ClientHello. This should
             * cause the server to fail
             */ /* fallthrough */ /*
         * This client has sent more early_data than we are willing to skip
         * (case 3) or sent invalid early_data (case 2) so the connection should
         * abort.
         */ /* Connection has failed - nothing more to do */ /*
     * Should be able to send normal data despite rejection of early data. The
     * early_data should be skipped.
     */