Reject unknown fields in d2i_SSL_SESSION.

The original OpenSSL implementation did the same. M_ASN1_D2I_Finish checks
this. Forwards compatibility with future sessions with unknown fields is
probably not desirable.

Change-Id: I116a8c482cbcc47c3fcc31515c4a3718f66cf268
Reviewed-on: https://boringssl-review.googlesource.com/4941
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2015-05-28 19:55:29 -04:00 committed by Adam Langley
parent 8a228f5bfe
commit f297e021f1
2 changed files with 32 additions and 1 deletions

View File

@ -477,7 +477,8 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
}
if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
kExtendedMasterSecretTag,
0 /* default to false */)) {
0 /* default to false */) ||
CBS_len(&session) != 0) {
OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, SSL_R_INVALID_SSL_SESSION);
goto err;
}

View File

@ -335,6 +335,18 @@ static const char kCustomSession[] =
"q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
"BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
// the final (optional) element of |kCustomSession| with tag number 30.
static const char kBadSessionExtraField[] =
"MIIBdgIBAQICAwMEAsAvBCAG5Q1ndq4Yfmbeo1zwLkNRKmCXGdNgWvGT3cskV0yQ"
"kAQwJlrlzkAWBOWiLj/jJ76D7l+UXoizP2KI2C7I2FccqMmIfFmmkUy32nIJ0mZH"
"IWoJoQYCBFRDO46iBAICASykAwQBAqUDAgEUphAEDnd3dy5nb29nbGUuY29tqAcE"
"BXdvcmxkqQUCAwGJwKqBpwSBpBwUQvoeOk0Kg36SYTcLEkXqKwOBfF9vE4KX0Nxe"
"LwjcDTpsuh3qXEaZ992r1N38VDcyS6P7I6HBYN9BsNHM362zZnY27GpTw+Kwd751"
"CLoXFPoaMOe57dbBpXoro6Pd3BTbf/Tzr88K06yEOTDKPNj3+inbMaVigtK4PLyP"
"q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
"BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBL4DBAEF";
static bool DecodeBase64(std::vector<uint8_t> *out, const char *in) {
size_t len;
if (!EVP_DecodedLength(&len, strlen(in))) {
@ -416,6 +428,23 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) {
return true;
}
static bool TestBadSSL_SESSIONEncoding(const char *input_b64) {
std::vector<uint8_t> input;
if (!DecodeBase64(&input, input_b64)) {
return false;
}
// Verify that the SSL_SESSION fails to decode.
const uint8_t *ptr = bssl::vector_data(&input);
ScopedSSL_SESSION session(d2i_SSL_SESSION(NULL, &ptr, input.size()));
if (session) {
fprintf(stderr, "d2i_SSL_SESSION unexpectedly succeeded\n");
return false;
}
ERR_clear_error();
return true;
}
static bool TestDefaultVersion(uint16_t version,
const SSL_METHOD *(*method)(void)) {
ScopedSSL_CTX ctx(SSL_CTX_new(method()));
@ -494,6 +523,7 @@ int main(void) {
if (!TestCipherRules() ||
!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
!TestSSL_SESSIONEncoding(kCustomSession) ||
!TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
!TestDefaultVersion(0, &TLS_method) ||
!TestDefaultVersion(SSL3_VERSION, &SSLv3_method) ||
!TestDefaultVersion(TLS1_VERSION, &TLSv1_method) ||