Test SSL_set_max_send_fragment.

This gives coverage over needing to fragment something over multiple
records.

Change-Id: I2373613608ef669358d48f4e12f68577fa5a40dc
Reviewed-on: https://boringssl-review.googlesource.com/13101
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2017-01-06 16:19:28 -05:00 committed by Adam Langley
parent 8b8d22c961
commit e3fbb36005
6 changed files with 59 additions and 5 deletions

View File

@ -1633,6 +1633,9 @@ static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
if (is_resume && config->retain_only_sha256_client_cert_resume) {
SSL_set_retain_only_sha256_of_client_certs(ssl.get(), 1);
}
if (config->max_send_fragment > 0) {
SSL_set_max_send_fragment(ssl.get(), config->max_send_fragment);
}
int sock = Connect(config->port);
if (sock == -1) {
@ -1796,12 +1799,15 @@ static bool DoExchange(bssl::UniquePtr<SSL_SESSION> *out_session,
}
if (!config->shim_shuts_down) {
for (;;) {
static const size_t kBufLen = 16384;
std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufLen]);
// Read only 512 bytes at a time in TLS to ensure records may be
// returned in multiple reads.
int n = DoRead(ssl.get(), buf.get(), config->is_dtls ? kBufLen : 512);
size_t read_size = config->is_dtls ? 16384 : 512;
if (config->read_size > 0) {
read_size = config->read_size;
}
std::unique_ptr<uint8_t[]> buf(new uint8_t[read_size]);
int n = DoRead(ssl.get(), buf.get(), read_size);
int err = SSL_get_error(ssl.get(), n);
if (err == SSL_ERROR_ZERO_RETURN ||
(n == 0 && err == SSL_ERROR_SYSCALL)) {

View File

@ -1253,6 +1253,10 @@ type ProtocolBugs struct {
// formats to send in ClientHello or ServerHello. If set to a non-nil
// empty slice, no extension will be sent.
SendSupportedPointFormats []byte
// MaxReceivePlaintext, if non-zero, is the maximum plaintext record
// length accepted from the peer.
MaxReceivePlaintext int
}
func (c *Config) serverInit() {

View File

@ -876,7 +876,11 @@ Again:
return err
}
data := b.data[b.off:]
if len(data) > maxPlaintext {
max := maxPlaintext
if c.config.Bugs.MaxReceivePlaintext != 0 {
max = c.config.Bugs.MaxReceivePlaintext
}
if len(data) > max {
err := c.sendAlert(alertRecordOverflow)
c.in.freeBlock(b)
return c.in.setErrorLocked(err)

View File

@ -2401,6 +2401,42 @@ func addBasicTests() {
},
},
},
{
// Test the server so there is a large certificate as
// well as application data.
testType: serverTest,
name: "MaxSendFragment",
config: Config{
Bugs: ProtocolBugs{
MaxReceivePlaintext: 512,
},
},
messageLen: 1024,
flags: []string{
"-max-send-fragment", "512",
"-read-size", "1024",
},
},
{
// Test the server so there is a large certificate as
// well as application data.
testType: serverTest,
name: "MaxSendFragment-TooLarge",
config: Config{
Bugs: ProtocolBugs{
// Ensure that some of the records are
// 512.
MaxReceivePlaintext: 511,
},
},
messageLen: 1024,
flags: []string{
"-max-send-fragment", "512",
"-read-size", "1024",
},
shouldFail: true,
expectedLocalError: "local error: record overflow",
},
}
testCases = append(testCases, basicTests...)

View File

@ -176,6 +176,8 @@ const Flag<int> kIntFlags[] = {
{ "-expect-cipher-aes", &TestConfig::expect_cipher_aes },
{ "-expect-cipher-no-aes", &TestConfig::expect_cipher_no_aes },
{ "-resumption-delay", &TestConfig::resumption_delay },
{ "-max-send-fragment", &TestConfig::max_send_fragment },
{ "-read-size", &TestConfig::read_size },
};
const Flag<std::vector<int>> kIntVectorFlags[] = {

View File

@ -129,6 +129,8 @@ struct TestConfig {
bool read_with_unfinished_write = false;
bool expect_secure_renegotiation = false;
bool expect_no_secure_renegotiation = false;
int max_send_fragment = 0;
int read_size = 0;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);