/*
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <string.h>
#include <openssl/opensslconf.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/ocsp.h>
#include "ssltestlib.h"
#include "testutil.h"
static char *cert = NULL;
static char *privkey = NULL;
static const unsigned char orespder[] = "Dummy OCSP Response";
static int ocsp_server_called = 0;
static int ocsp_client_called = 0;
static int cdummyarg = 1;
static X509 *ocspcert = NULL;
#define NUM_EXTRA_CERTS 40
static int execute_test_large_message(const SSL_METHOD *smeth,
const SSL_METHOD *cmeth, int read_ahead)
{
SSL_CTX *cctx = NULL, *sctx = NULL;
SSL *clientssl = NULL, *serverssl = NULL;
int testresult = 0;
int i;
BIO *certbio = BIO_new_file(cert, "r");
X509 *chaincert = NULL;
int certlen;
if (certbio == NULL) {
printf("Can't load the certficate file\n");
goto end;
}
chaincert = PEM_read_bio_X509(certbio, NULL, NULL, NULL);
BIO_free(certbio);
certbio = NULL;
if (chaincert == NULL) {
printf("Unable to load certificate for chain\n");
goto end;
}
if (!create_ssl_ctx_pair(smeth, cmeth, &sctx,
&cctx, cert, privkey)) {
printf("Unable to create SSL_CTX pair\n");
goto end;
}
if(read_ahead) {
/*
* Test that read_ahead works correctly when dealing with large
* records
*/
SSL_CTX_set_read_ahead(cctx, 1);
}
/*
* We assume the supplied certificate is big enough so that if we add
* NUM_EXTRA_CERTS it will make the overall message large enough. The
* default buffer size is requested to be 16k, but due to the way BUF_MEM
* works, it ends up allocing a little over 21k (16 * 4/3). So, in this test
* we need to have a message larger than that.
*/
certlen = i2d_X509(chaincert, NULL);
OPENSSL_assert((certlen * NUM_EXTRA_CERTS)
> ((SSL3_RT_MAX_PLAIN_LENGTH * 4) / 3));
for (i = 0; i < NUM_EXTRA_CERTS; i++) {
if (!X509_up_ref(chaincert)) {
printf("Unable to up ref cert\n");
goto end;
}
if (!SSL_CTX_add_extra_chain_cert(sctx, chaincert)) {
printf("Unable to add extra chain cert %d\n", i);
X509_free(chaincert);
goto end;
}
}
if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) {
printf("Unable to create SSL objects\n");
goto end;
}
if (!create_ssl_connection(serverssl, clientssl)) {
printf("Unable to create SSL connection\n");
goto end;
}
testresult = 1;
end:
X509_free(chaincert);
SSL_free(serverssl);
SSL_free(clientssl);
SSL_CTX_free(sctx);
SSL_CTX_free(cctx);
return testresult;
}
static int test_large_message_tls(void)
{
return execute_test_large_message(TLS_server_method(), TLS_client_method(),
0);
}
static int test_large_message_tls_read_ahead(void)
{
return execute_test_large_message(TLS_server_method(), TLS_client_method(),
1);
}
#ifndef OPENSSL_NO_DTLS
static int test_large_message_dtls(void)
{
/*
* read_ahead is not relevant to DTLS because DTLS always acts as if
* read_ahead is set.
*/
return execute_test_large_message(DTLS_server_method(),
DTLS_client_method(), 0);
}
#endif
static int ocsp_server_cb(SSL *s, void *arg)
{
int *argi = (int *)arg;
unsigned char *orespdercopy = NULL;
STACK_OF(OCSP_RESPID) *ids = NULL;
OCSP_RESPID *id = NULL;
if (*argi == 2) {
/* In this test we are expecting exactly 1 OCSP_RESPID */
SSL_get_tlsext_status_ids(s, &ids);
if (ids == NULL || sk_OCSP_RESPID_num(ids) != 1)
return SSL_TLSEXT_ERR_ALERT_FATAL;
id = sk_OCSP_RESPID_value(ids, 0);
if (id == NULL || !OCSP_RESPID_match(id, ocspcert))
return SSL_TLSEXT_ERR_ALERT_FATAL;
} else if (*argi != 1) {
return