Fix memory leak when decoding corrupt tickets.
This is CVE-2014-3567 from upstream. See https://www.openssl.org/news/secadv_20141015.txt Change-Id: I9aad422bf1b8055cb251c7ff9346cf47a448a815 Reviewed-on: https://boringssl-review.googlesource.com/1970 Reviewed-by: David Benjamin <davidben@chromium.org> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
88333ef7d7
commit
3831173740
@ -2379,7 +2379,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen,
|
||||
HMAC_Final(&hctx, tick_hmac, NULL);
|
||||
HMAC_CTX_cleanup(&hctx);
|
||||
if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen))
|
||||
{
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
return 2;
|
||||
}
|
||||
/* Attempt to decrypt session data */
|
||||
/* Move p after IV to start of encrypted ticket, update length */
|
||||
p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
|
||||
|
@ -464,6 +464,14 @@ type ProtocolBugs struct {
|
||||
// AllowSessionVersionMismatch causes the server to resume sessions
|
||||
// regardless of the version associated with the session.
|
||||
AllowSessionVersionMismatch bool
|
||||
|
||||
// CorruptTicket causes a client to corrupt a session ticket before
|
||||
// sending it in a resume handshake.
|
||||
CorruptTicket bool
|
||||
|
||||
// OversizedSessionId causes the session id that is sent with a ticket
|
||||
// resumption attempt to be too large (33 bytes).
|
||||
OversizedSessionId bool
|
||||
}
|
||||
|
||||
func (c *Config) serverInit() {
|
||||
|
@ -148,10 +148,25 @@ NextCipherSuite:
|
||||
|
||||
if session != nil {
|
||||
hello.sessionTicket = session.sessionTicket
|
||||
if c.config.Bugs.CorruptTicket {
|
||||
hello.sessionTicket = make([]byte, len(session.sessionTicket))
|
||||
copy(hello.sessionTicket, session.sessionTicket)
|
||||
if len(hello.sessionTicket) > 0 {
|
||||
offset := 40
|
||||
if offset > len(hello.sessionTicket) {
|
||||
offset = len(hello.sessionTicket) - 1
|
||||
}
|
||||
hello.sessionTicket[offset] ^= 0x40
|
||||
}
|
||||
}
|
||||
// A random session ID is used to detect when the
|
||||
// server accepted the ticket and is resuming a session
|
||||
// (see RFC 5077).
|
||||
hello.sessionId = make([]byte, 16)
|
||||
sessionIdLen := 16
|
||||
if c.config.Bugs.OversizedSessionId {
|
||||
sessionIdLen = 33
|
||||
}
|
||||
hello.sessionId = make([]byte, sessionIdLen)
|
||||
if _, err := io.ReadFull(c.config.rand(), hello.sessionId); err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return errors.New("tls: short read from Rand: " + err.Error())
|
||||
|
@ -649,6 +649,10 @@ func openSocketPair() (shimEnd *os.File, conn net.Conn) {
|
||||
}
|
||||
|
||||
func runTest(test *testCase, buildDir string) error {
|
||||
if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
|
||||
panic("Error expected without shouldFail in " + test.name)
|
||||
}
|
||||
|
||||
shimEnd, conn := openSocketPair()
|
||||
shimEndResume, connResume := openSocketPair()
|
||||
|
||||
@ -1542,6 +1546,31 @@ func addExtensionTests() {
|
||||
expectedNextProtoType: alpn,
|
||||
resumeSession: true,
|
||||
})
|
||||
// Resume with a corrupt ticket.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: serverTest,
|
||||
name: "CorruptTicket",
|
||||
config: Config{
|
||||
Bugs: ProtocolBugs{
|
||||
CorruptTicket: true,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
flags: []string{"-expect-session-miss"},
|
||||
})
|
||||
// Resume with an oversized session id.
|
||||
testCases = append(testCases, testCase{
|
||||
testType: serverTest,
|
||||
name: "OversizedSessionId",
|
||||
config: Config{
|
||||
Bugs: ProtocolBugs{
|
||||
OversizedSessionId: true,
|
||||
},
|
||||
},
|
||||
resumeSession: true,
|
||||
shouldFail: true,
|
||||
expectedError: ":DECODE_ERROR:",
|
||||
})
|
||||
}
|
||||
|
||||
func addResumptionVersionTests() {
|
||||
|
Loading…
Reference in New Issue
Block a user