Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

10 роки тому
Add DTLS timeout and retransmit tests. This extends the packet adaptor protocol to send three commands: type command = | Packet of []byte | Timeout of time.Duration | TimeoutAck When the shim processes a Timeout in BIO_read, it sends TimeoutAck, fails the BIO_read, returns out of the SSL stack, advances the clock, calls DTLSv1_handle_timeout, and continues. If the Go side sends Timeout right between sending handshake flight N and reading flight N+1, the shim won't read the Timeout until it has sent flight N+1 (it only processes packet commands in BIO_read), so the TimeoutAck comes after N+1. Go then drops all packets before the TimeoutAck, thus dropping one transmit of flight N+1 without having to actually process the packets to determine the end of the flight. The shim then sees the updated clock, calls DTLSv1_handle_timeout, and re-sends flight N+1 for Go to process for real. When dropping packets, Go checks the epoch and increments sequence numbers so that we can continue to be strict here. This requires tracking the initial sequence number of the next epoch. The final Finished message takes an additional special-case to test. DTLS triggers retransmits on either a timeout or seeing a stale flight. OpenSSL only implements the former which should be sufficient (and is necessary) EXCEPT for the final Finished message. If the peer's final Finished message is lost, it won't be waiting for a message from us, so it won't time out anything. That retransmit must be triggered on stale message, so we retransmit the Finished message in Go. Change-Id: I3ffbdb1de525beb2ee831b304670a3387877634c Reviewed-on: https://boringssl-review.googlesource.com/3212 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Add DTLS timeout and retransmit tests. This extends the packet adaptor protocol to send three commands: type command = | Packet of []byte | Timeout of time.Duration | TimeoutAck When the shim processes a Timeout in BIO_read, it sends TimeoutAck, fails the BIO_read, returns out of the SSL stack, advances the clock, calls DTLSv1_handle_timeout, and continues. If the Go side sends Timeout right between sending handshake flight N and reading flight N+1, the shim won't read the Timeout until it has sent flight N+1 (it only processes packet commands in BIO_read), so the TimeoutAck comes after N+1. Go then drops all packets before the TimeoutAck, thus dropping one transmit of flight N+1 without having to actually process the packets to determine the end of the flight. The shim then sees the updated clock, calls DTLSv1_handle_timeout, and re-sends flight N+1 for Go to process for real. When dropping packets, Go checks the epoch and increments sequence numbers so that we can continue to be strict here. This requires tracking the initial sequence number of the next epoch. The final Finished message takes an additional special-case to test. DTLS triggers retransmits on either a timeout or seeing a stale flight. OpenSSL only implements the former which should be sufficient (and is necessary) EXCEPT for the final Finished message. If the peer's final Finished message is lost, it won't be waiting for a message from us, so it won't time out anything. That retransmit must be triggered on stale message, so we retransmit the Finished message in Go. Change-Id: I3ffbdb1de525beb2ee831b304670a3387877634c Reviewed-on: https://boringssl-review.googlesource.com/3212 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
10 роки тому
10 роки тому
10 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
10 роки тому
10 роки тому
Tighten up EMS resumption behaviour. The client and server both have to decide on behaviour when resuming a session where the EMS state of the session doesn't match the EMS state as exchanged in the handshake. Original handshake | No Yes ------+-------------------------------------------------------------- | R | Server: ok [1] Server: abort [3] e No | Client: ok [2] Client: abort [4] s | u | m | e | Yes | Server: don't resume No problem | Client: abort; server | shouldn't have resumed [1] Servers want to accept legacy clients. The draft[5] says that resumptions SHOULD be rejected so that Triple-Handshake can't be done, but we'll rather enforce that EMS was used when using tls-unique etc. [2] The draft[5] says that even the initial handshake should be aborted if the server doesn't support EMS, but we need to be able to talk to the world. [3] This is a very weird case where a client has regressed without flushing the session cache. Hopefully we can be strict and reject these. [4] This can happen when a server-farm shares a session cache but frontends are not all updated at once. If Chrome is strict here then hopefully we can prevent any servers from existing that will try to resume an EMS session that they don't understand. OpenSSL appears to be ok here: https://www.ietf.org/mail-archive/web/tls/current/msg16570.html [5] https://tools.ietf.org/html/draft-ietf-tls-session-hash-05#section-5.2 BUG=492200 Change-Id: Ie1225a3960d49117b05eefa5a36263d8e556e467 Reviewed-on: https://boringssl-review.googlesource.com/4981 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Add DTLS timeout and retransmit tests. This extends the packet adaptor protocol to send three commands: type command = | Packet of []byte | Timeout of time.Duration | TimeoutAck When the shim processes a Timeout in BIO_read, it sends TimeoutAck, fails the BIO_read, returns out of the SSL stack, advances the clock, calls DTLSv1_handle_timeout, and continues. If the Go side sends Timeout right between sending handshake flight N and reading flight N+1, the shim won't read the Timeout until it has sent flight N+1 (it only processes packet commands in BIO_read), so the TimeoutAck comes after N+1. Go then drops all packets before the TimeoutAck, thus dropping one transmit of flight N+1 without having to actually process the packets to determine the end of the flight. The shim then sees the updated clock, calls DTLSv1_handle_timeout, and re-sends flight N+1 for Go to process for real. When dropping packets, Go checks the epoch and increments sequence numbers so that we can continue to be strict here. This requires tracking the initial sequence number of the next epoch. The final Finished message takes an additional special-case to test. DTLS triggers retransmits on either a timeout or seeing a stale flight. OpenSSL only implements the former which should be sufficient (and is necessary) EXCEPT for the final Finished message. If the peer's final Finished message is lost, it won't be waiting for a message from us, so it won't time out anything. That retransmit must be triggered on stale message, so we retransmit the Finished message in Go. Change-Id: I3ffbdb1de525beb2ee831b304670a3387877634c Reviewed-on: https://boringssl-review.googlesource.com/3212 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Add DTLS timeout and retransmit tests. This extends the packet adaptor protocol to send three commands: type command = | Packet of []byte | Timeout of time.Duration | TimeoutAck When the shim processes a Timeout in BIO_read, it sends TimeoutAck, fails the BIO_read, returns out of the SSL stack, advances the clock, calls DTLSv1_handle_timeout, and continues. If the Go side sends Timeout right between sending handshake flight N and reading flight N+1, the shim won't read the Timeout until it has sent flight N+1 (it only processes packet commands in BIO_read), so the TimeoutAck comes after N+1. Go then drops all packets before the TimeoutAck, thus dropping one transmit of flight N+1 without having to actually process the packets to determine the end of the flight. The shim then sees the updated clock, calls DTLSv1_handle_timeout, and re-sends flight N+1 for Go to process for real. When dropping packets, Go checks the epoch and increments sequence numbers so that we can continue to be strict here. This requires tracking the initial sequence number of the next epoch. The final Finished message takes an additional special-case to test. DTLS triggers retransmits on either a timeout or seeing a stale flight. OpenSSL only implements the former which should be sufficient (and is necessary) EXCEPT for the final Finished message. If the peer's final Finished message is lost, it won't be waiting for a message from us, so it won't time out anything. That retransmit must be triggered on stale message, so we retransmit the Finished message in Go. Change-Id: I3ffbdb1de525beb2ee831b304670a3387877634c Reviewed-on: https://boringssl-review.googlesource.com/3212 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
Use TCP sockets rather than socketpairs in the SSL tests. This involves more synchronization with child exits as the kernel no longer closes the pre-created pipes for free, but it works on Windows. As long as TCP_NODELAY is set, the performance seems comparable. Though it does involve dealing with graceful socket shutdown. I couldn't get that to work on Windows without draining the socket; not even SO_LINGER worked. Current (untested) theory is that Windows refuses to gracefully shutdown a socket if the peer sends data after we've stopped reading. cmd.ExtraFiles doesn't work on Windows; it doesn't use fds natively, so you can't pass fds 4 and 5. (stdin/stdout/stderr are special slots in CreateProcess.) We can instead use the syscall module directly and mark handles as inheritable (and then pass the numerical values out-of-band), but that requires synchronizing all of our shim.Start() calls and assuming no other thread is spawning a process. PROC_THREAD_ATTRIBUTE_HANDLE_LIST fixes threading problems, but requires wrapping more syscalls. exec.Cmd also doesn't let us launch the process ourselves. Plus it still requires every handle in the list be marked inheritable, so it doesn't help if some other thread is launching a process with bInheritHandles TRUE but NOT using PROC_THREAD_ATTRIBUTE_HANDLE_LIST. (Like Go, though we can take syscall.ForkLock there.) http://blogs.msdn.com/b/oldnewthing/archive/2011/12/16/10248328.aspx The more natively Windows option seems to be named pipes, but that too requires wrapping more system calls. (To be fair, that isn't too painful.) They also involve a listening server, so we'd still have to synchronize with shim.Wait() a la net.TCPListener. Then there's DuplicateHandle, but then we need an out-of-band signal. All in all, one cross-platform implementation with a TCP sockets seems simplest. Change-Id: I38233e309a0fa6814baf61e806732138902347c0 Reviewed-on: https://boringssl-review.googlesource.com/3563 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
10 роки тому
Add DTLS timeout and retransmit tests. This extends the packet adaptor protocol to send three commands: type command = | Packet of []byte | Timeout of time.Duration | TimeoutAck When the shim processes a Timeout in BIO_read, it sends TimeoutAck, fails the BIO_read, returns out of the SSL stack, advances the clock, calls DTLSv1_handle_timeout, and continues. If the Go side sends Timeout right between sending handshake flight N and reading flight N+1, the shim won't read the Timeout until it has sent flight N+1 (it only processes packet commands in BIO_read), so the TimeoutAck comes after N+1. Go then drops all packets before the TimeoutAck, thus dropping one transmit of flight N+1 without having to actually process the packets to determine the end of the flight. The shim then sees the updated clock, calls DTLSv1_handle_timeout, and re-sends flight N+1 for Go to process for real. When dropping packets, Go checks the epoch and increments sequence numbers so that we can continue to be strict here. This requires tracking the initial sequence number of the next epoch. The final Finished message takes an additional special-case to test. DTLS triggers retransmits on either a timeout or seeing a stale flight. OpenSSL only implements the former which should be sufficient (and is necessary) EXCEPT for the final Finished message. If the peer's final Finished message is lost, it won't be waiting for a message from us, so it won't time out anything. That retransmit must be triggered on stale message, so we retransmit the Finished message in Go. Change-Id: I3ffbdb1de525beb2ee831b304670a3387877634c Reviewed-on: https://boringssl-review.googlesource.com/3212 Reviewed-by: Adam Langley <agl@google.com>
9 роки тому
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934
  1. package main
  2. import (
  3. "bytes"
  4. "crypto/ecdsa"
  5. "crypto/elliptic"
  6. "crypto/x509"
  7. "encoding/base64"
  8. "encoding/pem"
  9. "flag"
  10. "fmt"
  11. "io"
  12. "io/ioutil"
  13. "math/big"
  14. "net"
  15. "os"
  16. "os/exec"
  17. "path"
  18. "runtime"
  19. "strconv"
  20. "strings"
  21. "sync"
  22. "syscall"
  23. "time"
  24. )
  25. var (
  26. useValgrind = flag.Bool("valgrind", false, "If true, run code under valgrind")
  27. useGDB = flag.Bool("gdb", false, "If true, run BoringSSL code under gdb")
  28. flagDebug = flag.Bool("debug", false, "Hexdump the contents of the connection")
  29. mallocTest = flag.Int64("malloc-test", -1, "If non-negative, run each test with each malloc in turn failing from the given number onwards.")
  30. mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask bssl_shim to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.")
  31. jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
  32. pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.")
  33. testToRun = flag.String("test", "", "The name of a test to run, or empty to run all tests")
  34. numWorkers = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
  35. shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
  36. resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
  37. )
  38. const (
  39. rsaCertificateFile = "cert.pem"
  40. ecdsaCertificateFile = "ecdsa_cert.pem"
  41. )
  42. const (
  43. rsaKeyFile = "key.pem"
  44. ecdsaKeyFile = "ecdsa_key.pem"
  45. channelIDKeyFile = "channel_id_key.pem"
  46. )
  47. var rsaCertificate, ecdsaCertificate Certificate
  48. var channelIDKey *ecdsa.PrivateKey
  49. var channelIDBytes []byte
  50. var testOCSPResponse = []byte{1, 2, 3, 4}
  51. var testSCTList = []byte{5, 6, 7, 8}
  52. func initCertificates() {
  53. var err error
  54. rsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, rsaCertificateFile), path.Join(*resourceDir, rsaKeyFile))
  55. if err != nil {
  56. panic(err)
  57. }
  58. rsaCertificate.OCSPStaple = testOCSPResponse
  59. rsaCertificate.SignedCertificateTimestampList = testSCTList
  60. ecdsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, ecdsaCertificateFile), path.Join(*resourceDir, ecdsaKeyFile))
  61. if err != nil {
  62. panic(err)
  63. }
  64. ecdsaCertificate.OCSPStaple = testOCSPResponse
  65. ecdsaCertificate.SignedCertificateTimestampList = testSCTList
  66. channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
  67. if err != nil {
  68. panic(err)
  69. }
  70. channelIDDERBlock, _ := pem.Decode(channelIDPEMBlock)
  71. if channelIDDERBlock.Type != "EC PRIVATE KEY" {
  72. panic("bad key type")
  73. }
  74. channelIDKey, err = x509.ParseECPrivateKey(channelIDDERBlock.Bytes)
  75. if err != nil {
  76. panic(err)
  77. }
  78. if channelIDKey.Curve != elliptic.P256() {
  79. panic("bad curve")
  80. }
  81. channelIDBytes = make([]byte, 64)
  82. writeIntPadded(channelIDBytes[:32], channelIDKey.X)
  83. writeIntPadded(channelIDBytes[32:], channelIDKey.Y)
  84. }
  85. var certificateOnce sync.Once
  86. func getRSACertificate() Certificate {
  87. certificateOnce.Do(initCertificates)
  88. return rsaCertificate
  89. }
  90. func getECDSACertificate() Certificate {
  91. certificateOnce.Do(initCertificates)
  92. return ecdsaCertificate
  93. }
  94. type testType int
  95. const (
  96. clientTest testType = iota
  97. serverTest
  98. )
  99. type protocol int
  100. const (
  101. tls protocol = iota
  102. dtls
  103. )
  104. const (
  105. alpn = 1
  106. npn = 2
  107. )
  108. type testCase struct {
  109. testType testType
  110. protocol protocol
  111. name string
  112. config Config
  113. shouldFail bool
  114. expectedError string
  115. // expectedLocalError, if not empty, contains a substring that must be
  116. // found in the local error.
  117. expectedLocalError string
  118. // expectedVersion, if non-zero, specifies the TLS version that must be
  119. // negotiated.
  120. expectedVersion uint16
  121. // expectedResumeVersion, if non-zero, specifies the TLS version that
  122. // must be negotiated on resumption. If zero, expectedVersion is used.
  123. expectedResumeVersion uint16
  124. // expectedCipher, if non-zero, specifies the TLS cipher suite that
  125. // should be negotiated.
  126. expectedCipher uint16
  127. // expectChannelID controls whether the connection should have
  128. // negotiated a Channel ID with channelIDKey.
  129. expectChannelID bool
  130. // expectedNextProto controls whether the connection should
  131. // negotiate a next protocol via NPN or ALPN.
  132. expectedNextProto string
  133. // expectedNextProtoType, if non-zero, is the expected next
  134. // protocol negotiation mechanism.
  135. expectedNextProtoType int
  136. // expectedSRTPProtectionProfile is the DTLS-SRTP profile that
  137. // should be negotiated. If zero, none should be negotiated.
  138. expectedSRTPProtectionProfile uint16
  139. // messageLen is the length, in bytes, of the test message that will be
  140. // sent.
  141. messageLen int
  142. // messageCount is the number of test messages that will be sent.
  143. messageCount int
  144. // certFile is the path to the certificate to use for the server.
  145. certFile string
  146. // keyFile is the path to the private key to use for the server.
  147. keyFile string
  148. // resumeSession controls whether a second connection should be tested
  149. // which attempts to resume the first session.
  150. resumeSession bool
  151. // expectResumeRejected, if true, specifies that the attempted
  152. // resumption must be rejected by the client. This is only valid for a
  153. // serverTest.
  154. expectResumeRejected bool
  155. // resumeConfig, if not nil, points to a Config to be used on
  156. // resumption. Unless newSessionsOnResume is set,
  157. // SessionTicketKey, ServerSessionCache, and
  158. // ClientSessionCache are copied from the initial connection's
  159. // config. If nil, the initial connection's config is used.
  160. resumeConfig *Config
  161. // newSessionsOnResume, if true, will cause resumeConfig to
  162. // use a different session resumption context.
  163. newSessionsOnResume bool
  164. // noSessionCache, if true, will cause the server to run without a
  165. // session cache.
  166. noSessionCache bool
  167. // sendPrefix sends a prefix on the socket before actually performing a
  168. // handshake.
  169. sendPrefix string
  170. // shimWritesFirst controls whether the shim sends an initial "hello"
  171. // message before doing a roundtrip with the runner.
  172. shimWritesFirst bool
  173. // renegotiate indicates the the connection should be renegotiated
  174. // during the exchange.
  175. renegotiate bool
  176. // renegotiateCiphers is a list of ciphersuite ids that will be
  177. // switched in just before renegotiation.
  178. renegotiateCiphers []uint16
  179. // replayWrites, if true, configures the underlying transport
  180. // to replay every write it makes in DTLS tests.
  181. replayWrites bool
  182. // damageFirstWrite, if true, configures the underlying transport to
  183. // damage the final byte of the first application data write.
  184. damageFirstWrite bool
  185. // exportKeyingMaterial, if non-zero, configures the test to exchange
  186. // keying material and verify they match.
  187. exportKeyingMaterial int
  188. exportLabel string
  189. exportContext string
  190. useExportContext bool
  191. // flags, if not empty, contains a list of command-line flags that will
  192. // be passed to the shim program.
  193. flags []string
  194. // testTLSUnique, if true, causes the shim to send the tls-unique value
  195. // which will be compared against the expected value.
  196. testTLSUnique bool
  197. // sendEmptyRecords is the number of consecutive empty records to send
  198. // before and after the test message.
  199. sendEmptyRecords int
  200. // sendWarningAlerts is the number of consecutive warning alerts to send
  201. // before and after the test message.
  202. sendWarningAlerts int
  203. }
  204. var testCases []testCase
  205. func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
  206. var connDebug *recordingConn
  207. var connDamage *damageAdaptor
  208. if *flagDebug {
  209. connDebug = &recordingConn{Conn: conn}
  210. conn = connDebug
  211. defer func() {
  212. connDebug.WriteTo(os.Stdout)
  213. }()
  214. }
  215. if test.protocol == dtls {
  216. config.Bugs.PacketAdaptor = newPacketAdaptor(conn)
  217. conn = config.Bugs.PacketAdaptor
  218. if test.replayWrites {
  219. conn = newReplayAdaptor(conn)
  220. }
  221. }
  222. if test.damageFirstWrite {
  223. connDamage = newDamageAdaptor(conn)
  224. conn = connDamage
  225. }
  226. if test.sendPrefix != "" {
  227. if _, err := conn.Write([]byte(test.sendPrefix)); err != nil {
  228. return err
  229. }
  230. }
  231. var tlsConn *Conn
  232. if test.testType == clientTest {
  233. if test.protocol == dtls {
  234. tlsConn = DTLSServer(conn, config)
  235. } else {
  236. tlsConn = Server(conn, config)
  237. }
  238. } else {
  239. config.InsecureSkipVerify = true
  240. if test.protocol == dtls {
  241. tlsConn = DTLSClient(conn, config)
  242. } else {
  243. tlsConn = Client(conn, config)
  244. }
  245. }
  246. if err := tlsConn.Handshake(); err != nil {
  247. return err
  248. }
  249. // TODO(davidben): move all per-connection expectations into a dedicated
  250. // expectations struct that can be specified separately for the two
  251. // legs.
  252. expectedVersion := test.expectedVersion
  253. if isResume && test.expectedResumeVersion != 0 {
  254. expectedVersion = test.expectedResumeVersion
  255. }
  256. connState := tlsConn.ConnectionState()
  257. if vers := connState.Version; expectedVersion != 0 && vers != expectedVersion {
  258. return fmt.Errorf("got version %x, expected %x", vers, expectedVersion)
  259. }
  260. if cipher := connState.CipherSuite; test.expectedCipher != 0 && cipher != test.expectedCipher {
  261. return fmt.Errorf("got cipher %x, expected %x", cipher, test.expectedCipher)
  262. }
  263. if didResume := connState.DidResume; isResume && didResume == test.expectResumeRejected {
  264. return fmt.Errorf("didResume is %t, but we expected the opposite", didResume)
  265. }
  266. if test.expectChannelID {
  267. channelID := connState.ChannelID
  268. if channelID == nil {
  269. return fmt.Errorf("no channel ID negotiated")
  270. }
  271. if channelID.Curve != channelIDKey.Curve ||
  272. channelIDKey.X.Cmp(channelIDKey.X) != 0 ||
  273. channelIDKey.Y.Cmp(channelIDKey.Y) != 0 {
  274. return fmt.Errorf("incorrect channel ID")
  275. }
  276. }
  277. if expected := test.expectedNextProto; expected != "" {
  278. if actual := connState.NegotiatedProtocol; actual != expected {
  279. return fmt.Errorf("next proto mismatch: got %s, wanted %s", actual, expected)
  280. }
  281. }
  282. if test.expectedNextProtoType != 0 {
  283. if (test.expectedNextProtoType == alpn) != connState.NegotiatedProtocolFromALPN {
  284. return fmt.Errorf("next proto type mismatch")
  285. }
  286. }
  287. if p := connState.SRTPProtectionProfile; p != test.expectedSRTPProtectionProfile {
  288. return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
  289. }
  290. if test.exportKeyingMaterial > 0 {
  291. actual := make([]byte, test.exportKeyingMaterial)
  292. if _, err := io.ReadFull(tlsConn, actual); err != nil {
  293. return err
  294. }
  295. expected, err := tlsConn.ExportKeyingMaterial(test.exportKeyingMaterial, []byte(test.exportLabel), []byte(test.exportContext), test.useExportContext)
  296. if err != nil {
  297. return err
  298. }
  299. if !bytes.Equal(actual, expected) {
  300. return fmt.Errorf("keying material mismatch")
  301. }
  302. }
  303. if test.testTLSUnique {
  304. var peersValue [12]byte
  305. if _, err := io.ReadFull(tlsConn, peersValue[:]); err != nil {
  306. return err
  307. }
  308. expected := tlsConn.ConnectionState().TLSUnique
  309. if !bytes.Equal(peersValue[:], expected) {
  310. return fmt.Errorf("tls-unique mismatch: peer sent %x, but %x was expected", peersValue[:], expected)
  311. }
  312. }
  313. if test.shimWritesFirst {
  314. var buf [5]byte
  315. _, err := io.ReadFull(tlsConn, buf[:])
  316. if err != nil {
  317. return err
  318. }
  319. if string(buf[:]) != "hello" {
  320. return fmt.Errorf("bad initial message")
  321. }
  322. }
  323. for i := 0; i < test.sendEmptyRecords; i++ {
  324. tlsConn.Write(nil)
  325. }
  326. for i := 0; i < test.sendWarningAlerts; i++ {
  327. tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
  328. }
  329. if test.renegotiate {
  330. if test.renegotiateCiphers != nil {
  331. config.CipherSuites = test.renegotiateCiphers
  332. }
  333. if err := tlsConn.Renegotiate(); err != nil {
  334. return err
  335. }
  336. } else if test.renegotiateCiphers != nil {
  337. panic("renegotiateCiphers without renegotiate")
  338. }
  339. if test.damageFirstWrite {
  340. connDamage.setDamage(true)
  341. tlsConn.Write([]byte("DAMAGED WRITE"))
  342. connDamage.setDamage(false)
  343. }
  344. messageLen := test.messageLen
  345. if messageLen < 0 {
  346. if test.protocol == dtls {
  347. return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
  348. }
  349. // Read until EOF.
  350. _, err := io.Copy(ioutil.Discard, tlsConn)
  351. return err
  352. }
  353. if messageLen == 0 {
  354. messageLen = 32
  355. }
  356. messageCount := test.messageCount
  357. if messageCount == 0 {
  358. messageCount = 1
  359. }
  360. for j := 0; j < messageCount; j++ {
  361. testMessage := make([]byte, messageLen)
  362. for i := range testMessage {
  363. testMessage[i] = 0x42 ^ byte(j)
  364. }
  365. tlsConn.Write(testMessage)
  366. for i := 0; i < test.sendEmptyRecords; i++ {
  367. tlsConn.Write(nil)
  368. }
  369. for i := 0; i < test.sendWarningAlerts; i++ {
  370. tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
  371. }
  372. buf := make([]byte, len(testMessage))
  373. if test.protocol == dtls {
  374. bufTmp := make([]byte, len(buf)+1)
  375. n, err := tlsConn.Read(bufTmp)
  376. if err != nil {
  377. return err
  378. }
  379. if n != len(buf) {
  380. return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
  381. }
  382. copy(buf, bufTmp)
  383. } else {
  384. _, err := io.ReadFull(tlsConn, buf)
  385. if err != nil {
  386. return err
  387. }
  388. }
  389. for i, v := range buf {
  390. if v != testMessage[i]^0xff {
  391. return fmt.Errorf("bad reply contents at byte %d", i)
  392. }
  393. }
  394. }
  395. return nil
  396. }
  397. func valgrindOf(dbAttach bool, path string, args ...string) *exec.Cmd {
  398. valgrindArgs := []string{"--error-exitcode=99", "--track-origins=yes", "--leak-check=full"}
  399. if dbAttach {
  400. valgrindArgs = append(valgrindArgs, "--db-attach=yes", "--db-command=xterm -e gdb -nw %f %p")
  401. }
  402. valgrindArgs = append(valgrindArgs, path)
  403. valgrindArgs = append(valgrindArgs, args...)
  404. return exec.Command("valgrind", valgrindArgs...)
  405. }
  406. func gdbOf(path string, args ...string) *exec.Cmd {
  407. xtermArgs := []string{"-e", "gdb", "--args"}
  408. xtermArgs = append(xtermArgs, path)
  409. xtermArgs = append(xtermArgs, args...)
  410. return exec.Command("xterm", xtermArgs...)
  411. }
  412. type moreMallocsError struct{}
  413. func (moreMallocsError) Error() string {
  414. return "child process did not exhaust all allocation calls"
  415. }
  416. var errMoreMallocs = moreMallocsError{}
  417. // accept accepts a connection from listener, unless waitChan signals a process
  418. // exit first.
  419. func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error) {
  420. type connOrError struct {
  421. conn net.Conn
  422. err error
  423. }
  424. connChan := make(chan connOrError, 1)
  425. go func() {
  426. conn, err := listener.Accept()
  427. connChan <- connOrError{conn, err}
  428. close(connChan)
  429. }()
  430. select {
  431. case result := <-connChan:
  432. return result.conn, result.err
  433. case childErr := <-waitChan:
  434. waitChan <- childErr
  435. return nil, fmt.Errorf("child exited early: %s", childErr)
  436. }
  437. }
  438. func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
  439. if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
  440. panic("Error expected without shouldFail in " + test.name)
  441. }
  442. if test.expectResumeRejected && !test.resumeSession {
  443. panic("expectResumeRejected without resumeSession in " + test.name)
  444. }
  445. listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
  446. if err != nil {
  447. panic(err)
  448. }
  449. defer func() {
  450. if listener != nil {
  451. listener.Close()
  452. }
  453. }()
  454. flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
  455. if test.testType == serverTest {
  456. flags = append(flags, "-server")
  457. flags = append(flags, "-key-file")
  458. if test.keyFile == "" {
  459. flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
  460. } else {
  461. flags = append(flags, path.Join(*resourceDir, test.keyFile))
  462. }
  463. flags = append(flags, "-cert-file")
  464. if test.certFile == "" {
  465. flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
  466. } else {
  467. flags = append(flags, path.Join(*resourceDir, test.certFile))
  468. }
  469. }
  470. if test.protocol == dtls {
  471. flags = append(flags, "-dtls")
  472. }
  473. if test.resumeSession {
  474. flags = append(flags, "-resume")
  475. }
  476. if test.shimWritesFirst {
  477. flags = append(flags, "-shim-writes-first")
  478. }
  479. if test.exportKeyingMaterial > 0 {
  480. flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
  481. flags = append(flags, "-export-label", test.exportLabel)
  482. flags = append(flags, "-export-context", test.exportContext)
  483. if test.useExportContext {
  484. flags = append(flags, "-use-export-context")
  485. }
  486. }
  487. if test.expectResumeRejected {
  488. flags = append(flags, "-expect-session-miss")
  489. }
  490. if test.testTLSUnique {
  491. flags = append(flags, "-tls-unique")
  492. }
  493. flags = append(flags, test.flags...)
  494. var shim *exec.Cmd
  495. if *useValgrind {
  496. shim = valgrindOf(false, shimPath, flags...)
  497. } else if *useGDB {
  498. shim = gdbOf(shimPath, flags...)
  499. } else {
  500. shim = exec.Command(shimPath, flags...)
  501. }
  502. shim.Stdin = os.Stdin
  503. var stdoutBuf, stderrBuf bytes.Buffer
  504. shim.Stdout = &stdoutBuf
  505. shim.Stderr = &stderrBuf
  506. if mallocNumToFail >= 0 {
  507. shim.Env = os.Environ()
  508. shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
  509. if *mallocTestDebug {
  510. shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
  511. }
  512. shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
  513. }
  514. if err := shim.Start(); err != nil {
  515. panic(err)
  516. }
  517. waitChan := make(chan error, 1)
  518. go func() { waitChan <- shim.Wait() }()
  519. config := test.config
  520. if !test.noSessionCache {
  521. config.ClientSessionCache = NewLRUClientSessionCache(1)
  522. config.ServerSessionCache = NewLRUServerSessionCache(1)
  523. }
  524. if test.testType == clientTest {
  525. if len(config.Certificates) == 0 {
  526. config.Certificates = []Certificate{getRSACertificate()}
  527. }
  528. } else {
  529. // Supply a ServerName to ensure a constant session cache key,
  530. // rather than falling back to net.Conn.RemoteAddr.
  531. if len(config.ServerName) == 0 {
  532. config.ServerName = "test"
  533. }
  534. }
  535. conn, err := acceptOrWait(listener, waitChan)
  536. if err == nil {
  537. err = doExchange(test, &config, conn, false /* not a resumption */)
  538. conn.Close()
  539. }
  540. if err == nil && test.resumeSession {
  541. var resumeConfig Config
  542. if test.resumeConfig != nil {
  543. resumeConfig = *test.resumeConfig
  544. if len(resumeConfig.ServerName) == 0 {
  545. resumeConfig.ServerName = config.ServerName
  546. }
  547. if len(resumeConfig.Certificates) == 0 {
  548. resumeConfig.Certificates = []Certificate{getRSACertificate()}
  549. }
  550. if test.newSessionsOnResume {
  551. if !test.noSessionCache {
  552. resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1)
  553. resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1)
  554. }
  555. } else {
  556. resumeConfig.SessionTicketKey = config.SessionTicketKey
  557. resumeConfig.ClientSessionCache = config.ClientSessionCache
  558. resumeConfig.ServerSessionCache = config.ServerSessionCache
  559. }
  560. } else {
  561. resumeConfig = config
  562. }
  563. var connResume net.Conn
  564. connResume, err = acceptOrWait(listener, waitChan)
  565. if err == nil {
  566. err = doExchange(test, &resumeConfig, connResume, true /* resumption */)
  567. connResume.Close()
  568. }
  569. }
  570. // Close the listener now. This is to avoid hangs should the shim try to
  571. // open more connections than expected.
  572. listener.Close()
  573. listener = nil
  574. childErr := <-waitChan
  575. if exitError, ok := childErr.(*exec.ExitError); ok {
  576. if exitError.Sys().(syscall.WaitStatus).ExitStatus() == 88 {
  577. return errMoreMallocs
  578. }
  579. }
  580. stdout := string(stdoutBuf.Bytes())
  581. stderr := string(stderrBuf.Bytes())
  582. failed := err != nil || childErr != nil
  583. correctFailure := len(test.expectedError) == 0 || strings.Contains(stderr, test.expectedError)
  584. localError := "none"
  585. if err != nil {
  586. localError = err.Error()
  587. }
  588. if len(test.expectedLocalError) != 0 {
  589. correctFailure = correctFailure && strings.Contains(localError, test.expectedLocalError)
  590. }
  591. if failed != test.shouldFail || failed && !correctFailure {
  592. childError := "none"
  593. if childErr != nil {
  594. childError = childErr.Error()
  595. }
  596. var msg string
  597. switch {
  598. case failed && !test.shouldFail:
  599. msg = "unexpected failure"
  600. case !failed && test.shouldFail:
  601. msg = "unexpected success"
  602. case failed && !correctFailure:
  603. msg = "bad error (wanted '" + test.expectedError + "' / '" + test.expectedLocalError + "')"
  604. default:
  605. panic("internal error")
  606. }
  607. return fmt.Errorf("%s: local error '%s', child error '%s', stdout:\n%s\nstderr:\n%s", msg, localError, childError, stdout, stderr)
  608. }
  609. if !*useValgrind && !failed && len(stderr) > 0 {
  610. println(stderr)
  611. }
  612. return nil
  613. }
  614. var tlsVersions = []struct {
  615. name string
  616. version uint16
  617. flag string
  618. hasDTLS bool
  619. }{
  620. {"SSL3", VersionSSL30, "-no-ssl3", false},
  621. {"TLS1", VersionTLS10, "-no-tls1", true},
  622. {"TLS11", VersionTLS11, "-no-tls11", false},
  623. {"TLS12", VersionTLS12, "-no-tls12", true},
  624. }
  625. var testCipherSuites = []struct {
  626. name string
  627. id uint16
  628. }{
  629. {"3DES-SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},
  630. {"AES128-GCM", TLS_RSA_WITH_AES_128_GCM_SHA256},
  631. {"AES128-SHA", TLS_RSA_WITH_AES_128_CBC_SHA},
  632. {"AES128-SHA256", TLS_RSA_WITH_AES_128_CBC_SHA256},
  633. {"AES256-GCM", TLS_RSA_WITH_AES_256_GCM_SHA384},
  634. {"AES256-SHA", TLS_RSA_WITH_AES_256_CBC_SHA},
  635. {"AES256-SHA256", TLS_RSA_WITH_AES_256_CBC_SHA256},
  636. {"DHE-RSA-AES128-GCM", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
  637. {"DHE-RSA-AES128-SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},
  638. {"DHE-RSA-AES128-SHA256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},
  639. {"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
  640. {"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
  641. {"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
  642. {"DHE-RSA-CHACHA20-POLY1305", TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
  643. {"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  644. {"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
  645. {"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
  646. {"ECDHE-ECDSA-AES256-GCM", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},
  647. {"ECDHE-ECDSA-AES256-SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
  648. {"ECDHE-ECDSA-AES256-SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},
  649. {"ECDHE-ECDSA-CHACHA20-POLY1305", TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256},
  650. {"ECDHE-ECDSA-RC4-SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},
  651. {"ECDHE-RSA-AES128-GCM", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  652. {"ECDHE-RSA-AES128-SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  653. {"ECDHE-RSA-AES128-SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
  654. {"ECDHE-RSA-AES256-GCM", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},
  655. {"ECDHE-RSA-AES256-SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
  656. {"ECDHE-RSA-AES256-SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},
  657. {"ECDHE-RSA-CHACHA20-POLY1305", TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
  658. {"ECDHE-RSA-RC4-SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},
  659. {"PSK-AES128-CBC-SHA", TLS_PSK_WITH_AES_128_CBC_SHA},
  660. {"PSK-AES256-CBC-SHA", TLS_PSK_WITH_AES_256_CBC_SHA},
  661. {"ECDHE-PSK-AES128-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA},
  662. {"ECDHE-PSK-AES256-CBC-SHA", TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA},
  663. {"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA},
  664. {"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
  665. {"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
  666. }
  667. func hasComponent(suiteName, component string) bool {
  668. return strings.Contains("-"+suiteName+"-", "-"+component+"-")
  669. }
  670. func isTLS12Only(suiteName string) bool {
  671. return hasComponent(suiteName, "GCM") ||
  672. hasComponent(suiteName, "SHA256") ||
  673. hasComponent(suiteName, "SHA384") ||
  674. hasComponent(suiteName, "POLY1305")
  675. }
  676. func isDTLSCipher(suiteName string) bool {
  677. return !hasComponent(suiteName, "RC4")
  678. }
  679. func bigFromHex(hex string) *big.Int {
  680. ret, ok := new(big.Int).SetString(hex, 16)
  681. if !ok {
  682. panic("failed to parse hex number 0x" + hex)
  683. }
  684. return ret
  685. }
  686. func addBasicTests() {
  687. basicTests := []testCase{
  688. {
  689. name: "BadRSASignature",
  690. config: Config{
  691. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  692. Bugs: ProtocolBugs{
  693. InvalidSKXSignature: true,
  694. },
  695. },
  696. shouldFail: true,
  697. expectedError: ":BAD_SIGNATURE:",
  698. },
  699. {
  700. name: "BadECDSASignature",
  701. config: Config{
  702. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  703. Bugs: ProtocolBugs{
  704. InvalidSKXSignature: true,
  705. },
  706. Certificates: []Certificate{getECDSACertificate()},
  707. },
  708. shouldFail: true,
  709. expectedError: ":BAD_SIGNATURE:",
  710. },
  711. {
  712. testType: serverTest,
  713. name: "BadRSASignature-ClientAuth",
  714. config: Config{
  715. Bugs: ProtocolBugs{
  716. InvalidCertVerifySignature: true,
  717. },
  718. Certificates: []Certificate{getRSACertificate()},
  719. },
  720. shouldFail: true,
  721. expectedError: ":BAD_SIGNATURE:",
  722. flags: []string{"-require-any-client-certificate"},
  723. },
  724. {
  725. testType: serverTest,
  726. name: "BadECDSASignature-ClientAuth",
  727. config: Config{
  728. Bugs: ProtocolBugs{
  729. InvalidCertVerifySignature: true,
  730. },
  731. Certificates: []Certificate{getECDSACertificate()},
  732. },
  733. shouldFail: true,
  734. expectedError: ":BAD_SIGNATURE:",
  735. flags: []string{"-require-any-client-certificate"},
  736. },
  737. {
  738. name: "BadECDSACurve",
  739. config: Config{
  740. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  741. Bugs: ProtocolBugs{
  742. InvalidSKXCurve: true,
  743. },
  744. Certificates: []Certificate{getECDSACertificate()},
  745. },
  746. shouldFail: true,
  747. expectedError: ":WRONG_CURVE:",
  748. },
  749. {
  750. testType: serverTest,
  751. name: "BadRSAVersion",
  752. config: Config{
  753. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  754. Bugs: ProtocolBugs{
  755. RsaClientKeyExchangeVersion: VersionTLS11,
  756. },
  757. },
  758. shouldFail: true,
  759. expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
  760. },
  761. {
  762. name: "NoFallbackSCSV",
  763. config: Config{
  764. Bugs: ProtocolBugs{
  765. FailIfNotFallbackSCSV: true,
  766. },
  767. },
  768. shouldFail: true,
  769. expectedLocalError: "no fallback SCSV found",
  770. },
  771. {
  772. name: "SendFallbackSCSV",
  773. config: Config{
  774. Bugs: ProtocolBugs{
  775. FailIfNotFallbackSCSV: true,
  776. },
  777. },
  778. flags: []string{"-fallback-scsv"},
  779. },
  780. {
  781. name: "ClientCertificateTypes",
  782. config: Config{
  783. ClientAuth: RequestClientCert,
  784. ClientCertificateTypes: []byte{
  785. CertTypeDSSSign,
  786. CertTypeRSASign,
  787. CertTypeECDSASign,
  788. },
  789. },
  790. flags: []string{
  791. "-expect-certificate-types",
  792. base64.StdEncoding.EncodeToString([]byte{
  793. CertTypeDSSSign,
  794. CertTypeRSASign,
  795. CertTypeECDSASign,
  796. }),
  797. },
  798. },
  799. {
  800. name: "NoClientCertificate",
  801. config: Config{
  802. ClientAuth: RequireAnyClientCert,
  803. },
  804. shouldFail: true,
  805. expectedLocalError: "client didn't provide a certificate",
  806. },
  807. {
  808. name: "UnauthenticatedECDH",
  809. config: Config{
  810. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  811. Bugs: ProtocolBugs{
  812. UnauthenticatedECDH: true,
  813. },
  814. },
  815. shouldFail: true,
  816. expectedError: ":UNEXPECTED_MESSAGE:",
  817. },
  818. {
  819. name: "SkipCertificateStatus",
  820. config: Config{
  821. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  822. Bugs: ProtocolBugs{
  823. SkipCertificateStatus: true,
  824. },
  825. },
  826. flags: []string{
  827. "-enable-ocsp-stapling",
  828. },
  829. },
  830. {
  831. name: "SkipServerKeyExchange",
  832. config: Config{
  833. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  834. Bugs: ProtocolBugs{
  835. SkipServerKeyExchange: true,
  836. },
  837. },
  838. shouldFail: true,
  839. expectedError: ":UNEXPECTED_MESSAGE:",
  840. },
  841. {
  842. name: "SkipChangeCipherSpec-Client",
  843. config: Config{
  844. Bugs: ProtocolBugs{
  845. SkipChangeCipherSpec: true,
  846. },
  847. },
  848. shouldFail: true,
  849. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  850. },
  851. {
  852. testType: serverTest,
  853. name: "SkipChangeCipherSpec-Server",
  854. config: Config{
  855. Bugs: ProtocolBugs{
  856. SkipChangeCipherSpec: true,
  857. },
  858. },
  859. shouldFail: true,
  860. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  861. },
  862. {
  863. testType: serverTest,
  864. name: "SkipChangeCipherSpec-Server-NPN",
  865. config: Config{
  866. NextProtos: []string{"bar"},
  867. Bugs: ProtocolBugs{
  868. SkipChangeCipherSpec: true,
  869. },
  870. },
  871. flags: []string{
  872. "-advertise-npn", "\x03foo\x03bar\x03baz",
  873. },
  874. shouldFail: true,
  875. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  876. },
  877. {
  878. name: "FragmentAcrossChangeCipherSpec-Client",
  879. config: Config{
  880. Bugs: ProtocolBugs{
  881. FragmentAcrossChangeCipherSpec: true,
  882. },
  883. },
  884. shouldFail: true,
  885. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  886. },
  887. {
  888. testType: serverTest,
  889. name: "FragmentAcrossChangeCipherSpec-Server",
  890. config: Config{
  891. Bugs: ProtocolBugs{
  892. FragmentAcrossChangeCipherSpec: true,
  893. },
  894. },
  895. shouldFail: true,
  896. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  897. },
  898. {
  899. testType: serverTest,
  900. name: "FragmentAcrossChangeCipherSpec-Server-NPN",
  901. config: Config{
  902. NextProtos: []string{"bar"},
  903. Bugs: ProtocolBugs{
  904. FragmentAcrossChangeCipherSpec: true,
  905. },
  906. },
  907. flags: []string{
  908. "-advertise-npn", "\x03foo\x03bar\x03baz",
  909. },
  910. shouldFail: true,
  911. expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
  912. },
  913. {
  914. testType: serverTest,
  915. name: "Alert",
  916. config: Config{
  917. Bugs: ProtocolBugs{
  918. SendSpuriousAlert: alertRecordOverflow,
  919. },
  920. },
  921. shouldFail: true,
  922. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  923. },
  924. {
  925. protocol: dtls,
  926. testType: serverTest,
  927. name: "Alert-DTLS",
  928. config: Config{
  929. Bugs: ProtocolBugs{
  930. SendSpuriousAlert: alertRecordOverflow,
  931. },
  932. },
  933. shouldFail: true,
  934. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  935. },
  936. {
  937. testType: serverTest,
  938. name: "FragmentAlert",
  939. config: Config{
  940. Bugs: ProtocolBugs{
  941. FragmentAlert: true,
  942. SendSpuriousAlert: alertRecordOverflow,
  943. },
  944. },
  945. shouldFail: true,
  946. expectedError: ":BAD_ALERT:",
  947. },
  948. {
  949. protocol: dtls,
  950. testType: serverTest,
  951. name: "FragmentAlert-DTLS",
  952. config: Config{
  953. Bugs: ProtocolBugs{
  954. FragmentAlert: true,
  955. SendSpuriousAlert: alertRecordOverflow,
  956. },
  957. },
  958. shouldFail: true,
  959. expectedError: ":BAD_ALERT:",
  960. },
  961. {
  962. testType: serverTest,
  963. name: "EarlyChangeCipherSpec-server-1",
  964. config: Config{
  965. Bugs: ProtocolBugs{
  966. EarlyChangeCipherSpec: 1,
  967. },
  968. },
  969. shouldFail: true,
  970. expectedError: ":CCS_RECEIVED_EARLY:",
  971. },
  972. {
  973. testType: serverTest,
  974. name: "EarlyChangeCipherSpec-server-2",
  975. config: Config{
  976. Bugs: ProtocolBugs{
  977. EarlyChangeCipherSpec: 2,
  978. },
  979. },
  980. shouldFail: true,
  981. expectedError: ":CCS_RECEIVED_EARLY:",
  982. },
  983. {
  984. name: "SkipNewSessionTicket",
  985. config: Config{
  986. Bugs: ProtocolBugs{
  987. SkipNewSessionTicket: true,
  988. },
  989. },
  990. shouldFail: true,
  991. expectedError: ":CCS_RECEIVED_EARLY:",
  992. },
  993. {
  994. testType: serverTest,
  995. name: "FallbackSCSV",
  996. config: Config{
  997. MaxVersion: VersionTLS11,
  998. Bugs: ProtocolBugs{
  999. SendFallbackSCSV: true,
  1000. },
  1001. },
  1002. shouldFail: true,
  1003. expectedError: ":INAPPROPRIATE_FALLBACK:",
  1004. },
  1005. {
  1006. testType: serverTest,
  1007. name: "FallbackSCSV-VersionMatch",
  1008. config: Config{
  1009. Bugs: ProtocolBugs{
  1010. SendFallbackSCSV: true,
  1011. },
  1012. },
  1013. },
  1014. {
  1015. testType: serverTest,
  1016. name: "FragmentedClientVersion",
  1017. config: Config{
  1018. Bugs: ProtocolBugs{
  1019. MaxHandshakeRecordLength: 1,
  1020. FragmentClientVersion: true,
  1021. },
  1022. },
  1023. expectedVersion: VersionTLS12,
  1024. },
  1025. {
  1026. testType: serverTest,
  1027. name: "MinorVersionTolerance",
  1028. config: Config{
  1029. Bugs: ProtocolBugs{
  1030. SendClientVersion: 0x03ff,
  1031. },
  1032. },
  1033. expectedVersion: VersionTLS12,
  1034. },
  1035. {
  1036. testType: serverTest,
  1037. name: "MajorVersionTolerance",
  1038. config: Config{
  1039. Bugs: ProtocolBugs{
  1040. SendClientVersion: 0x0400,
  1041. },
  1042. },
  1043. expectedVersion: VersionTLS12,
  1044. },
  1045. {
  1046. testType: serverTest,
  1047. name: "VersionTooLow",
  1048. config: Config{
  1049. Bugs: ProtocolBugs{
  1050. SendClientVersion: 0x0200,
  1051. },
  1052. },
  1053. shouldFail: true,
  1054. expectedError: ":UNSUPPORTED_PROTOCOL:",
  1055. },
  1056. {
  1057. testType: serverTest,
  1058. name: "HttpGET",
  1059. sendPrefix: "GET / HTTP/1.0\n",
  1060. shouldFail: true,
  1061. expectedError: ":HTTP_REQUEST:",
  1062. },
  1063. {
  1064. testType: serverTest,
  1065. name: "HttpPOST",
  1066. sendPrefix: "POST / HTTP/1.0\n",
  1067. shouldFail: true,
  1068. expectedError: ":HTTP_REQUEST:",
  1069. },
  1070. {
  1071. testType: serverTest,
  1072. name: "HttpHEAD",
  1073. sendPrefix: "HEAD / HTTP/1.0\n",
  1074. shouldFail: true,
  1075. expectedError: ":HTTP_REQUEST:",
  1076. },
  1077. {
  1078. testType: serverTest,
  1079. name: "HttpPUT",
  1080. sendPrefix: "PUT / HTTP/1.0\n",
  1081. shouldFail: true,
  1082. expectedError: ":HTTP_REQUEST:",
  1083. },
  1084. {
  1085. testType: serverTest,
  1086. name: "HttpCONNECT",
  1087. sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
  1088. shouldFail: true,
  1089. expectedError: ":HTTPS_PROXY_REQUEST:",
  1090. },
  1091. {
  1092. testType: serverTest,
  1093. name: "Garbage",
  1094. sendPrefix: "blah",
  1095. shouldFail: true,
  1096. expectedError: ":UNKNOWN_PROTOCOL:",
  1097. },
  1098. {
  1099. name: "SkipCipherVersionCheck",
  1100. config: Config{
  1101. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  1102. MaxVersion: VersionTLS11,
  1103. Bugs: ProtocolBugs{
  1104. SkipCipherVersionCheck: true,
  1105. },
  1106. },
  1107. shouldFail: true,
  1108. expectedError: ":WRONG_CIPHER_RETURNED:",
  1109. },
  1110. {
  1111. name: "RSAEphemeralKey",
  1112. config: Config{
  1113. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  1114. Bugs: ProtocolBugs{
  1115. RSAEphemeralKey: true,
  1116. },
  1117. },
  1118. shouldFail: true,
  1119. expectedError: ":UNEXPECTED_MESSAGE:",
  1120. },
  1121. {
  1122. name: "DisableEverything",
  1123. flags: []string{"-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
  1124. shouldFail: true,
  1125. expectedError: ":WRONG_SSL_VERSION:",
  1126. },
  1127. {
  1128. protocol: dtls,
  1129. name: "DisableEverything-DTLS",
  1130. flags: []string{"-no-tls12", "-no-tls1"},
  1131. shouldFail: true,
  1132. expectedError: ":WRONG_SSL_VERSION:",
  1133. },
  1134. {
  1135. name: "NoSharedCipher",
  1136. config: Config{
  1137. CipherSuites: []uint16{},
  1138. },
  1139. shouldFail: true,
  1140. expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
  1141. },
  1142. {
  1143. protocol: dtls,
  1144. testType: serverTest,
  1145. name: "MTU",
  1146. config: Config{
  1147. Bugs: ProtocolBugs{
  1148. MaxPacketLength: 256,
  1149. },
  1150. },
  1151. flags: []string{"-mtu", "256"},
  1152. },
  1153. {
  1154. protocol: dtls,
  1155. testType: serverTest,
  1156. name: "MTUExceeded",
  1157. config: Config{
  1158. Bugs: ProtocolBugs{
  1159. MaxPacketLength: 255,
  1160. },
  1161. },
  1162. flags: []string{"-mtu", "256"},
  1163. shouldFail: true,
  1164. expectedLocalError: "dtls: exceeded maximum packet length",
  1165. },
  1166. {
  1167. name: "CertMismatchRSA",
  1168. config: Config{
  1169. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  1170. Certificates: []Certificate{getECDSACertificate()},
  1171. Bugs: ProtocolBugs{
  1172. SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  1173. },
  1174. },
  1175. shouldFail: true,
  1176. expectedError: ":WRONG_CERTIFICATE_TYPE:",
  1177. },
  1178. {
  1179. name: "CertMismatchECDSA",
  1180. config: Config{
  1181. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1182. Certificates: []Certificate{getRSACertificate()},
  1183. Bugs: ProtocolBugs{
  1184. SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
  1185. },
  1186. },
  1187. shouldFail: true,
  1188. expectedError: ":WRONG_CERTIFICATE_TYPE:",
  1189. },
  1190. {
  1191. name: "EmptyCertificateList",
  1192. config: Config{
  1193. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1194. Bugs: ProtocolBugs{
  1195. EmptyCertificateList: true,
  1196. },
  1197. },
  1198. shouldFail: true,
  1199. expectedError: ":DECODE_ERROR:",
  1200. },
  1201. {
  1202. name: "TLSFatalBadPackets",
  1203. damageFirstWrite: true,
  1204. shouldFail: true,
  1205. expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
  1206. },
  1207. {
  1208. protocol: dtls,
  1209. name: "DTLSIgnoreBadPackets",
  1210. damageFirstWrite: true,
  1211. },
  1212. {
  1213. protocol: dtls,
  1214. name: "DTLSIgnoreBadPackets-Async",
  1215. damageFirstWrite: true,
  1216. flags: []string{"-async"},
  1217. },
  1218. {
  1219. name: "AppDataAfterChangeCipherSpec",
  1220. config: Config{
  1221. Bugs: ProtocolBugs{
  1222. AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
  1223. },
  1224. },
  1225. shouldFail: true,
  1226. expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
  1227. },
  1228. {
  1229. protocol: dtls,
  1230. name: "AppDataAfterChangeCipherSpec-DTLS",
  1231. config: Config{
  1232. Bugs: ProtocolBugs{
  1233. AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
  1234. },
  1235. },
  1236. // BoringSSL's DTLS implementation will drop the out-of-order
  1237. // application data.
  1238. },
  1239. {
  1240. name: "AlertAfterChangeCipherSpec",
  1241. config: Config{
  1242. Bugs: ProtocolBugs{
  1243. AlertAfterChangeCipherSpec: alertRecordOverflow,
  1244. },
  1245. },
  1246. shouldFail: true,
  1247. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  1248. },
  1249. {
  1250. protocol: dtls,
  1251. name: "AlertAfterChangeCipherSpec-DTLS",
  1252. config: Config{
  1253. Bugs: ProtocolBugs{
  1254. AlertAfterChangeCipherSpec: alertRecordOverflow,
  1255. },
  1256. },
  1257. shouldFail: true,
  1258. expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
  1259. },
  1260. {
  1261. protocol: dtls,
  1262. name: "ReorderHandshakeFragments-Small-DTLS",
  1263. config: Config{
  1264. Bugs: ProtocolBugs{
  1265. ReorderHandshakeFragments: true,
  1266. // Small enough that every handshake message is
  1267. // fragmented.
  1268. MaxHandshakeRecordLength: 2,
  1269. },
  1270. },
  1271. },
  1272. {
  1273. protocol: dtls,
  1274. name: "ReorderHandshakeFragments-Large-DTLS",
  1275. config: Config{
  1276. Bugs: ProtocolBugs{
  1277. ReorderHandshakeFragments: true,
  1278. // Large enough that no handshake message is
  1279. // fragmented.
  1280. MaxHandshakeRecordLength: 2048,
  1281. },
  1282. },
  1283. },
  1284. {
  1285. protocol: dtls,
  1286. name: "MixCompleteMessageWithFragments-DTLS",
  1287. config: Config{
  1288. Bugs: ProtocolBugs{
  1289. ReorderHandshakeFragments: true,
  1290. MixCompleteMessageWithFragments: true,
  1291. MaxHandshakeRecordLength: 2,
  1292. },
  1293. },
  1294. },
  1295. {
  1296. name: "SendInvalidRecordType",
  1297. config: Config{
  1298. Bugs: ProtocolBugs{
  1299. SendInvalidRecordType: true,
  1300. },
  1301. },
  1302. shouldFail: true,
  1303. expectedError: ":UNEXPECTED_RECORD:",
  1304. },
  1305. {
  1306. protocol: dtls,
  1307. name: "SendInvalidRecordType-DTLS",
  1308. config: Config{
  1309. Bugs: ProtocolBugs{
  1310. SendInvalidRecordType: true,
  1311. },
  1312. },
  1313. shouldFail: true,
  1314. expectedError: ":UNEXPECTED_RECORD:",
  1315. },
  1316. {
  1317. name: "FalseStart-SkipServerSecondLeg",
  1318. config: Config{
  1319. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1320. NextProtos: []string{"foo"},
  1321. Bugs: ProtocolBugs{
  1322. SkipNewSessionTicket: true,
  1323. SkipChangeCipherSpec: true,
  1324. SkipFinished: true,
  1325. ExpectFalseStart: true,
  1326. },
  1327. },
  1328. flags: []string{
  1329. "-false-start",
  1330. "-handshake-never-done",
  1331. "-advertise-alpn", "\x03foo",
  1332. },
  1333. shimWritesFirst: true,
  1334. shouldFail: true,
  1335. expectedError: ":UNEXPECTED_RECORD:",
  1336. },
  1337. {
  1338. name: "FalseStart-SkipServerSecondLeg-Implicit",
  1339. config: Config{
  1340. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1341. NextProtos: []string{"foo"},
  1342. Bugs: ProtocolBugs{
  1343. SkipNewSessionTicket: true,
  1344. SkipChangeCipherSpec: true,
  1345. SkipFinished: true,
  1346. },
  1347. },
  1348. flags: []string{
  1349. "-implicit-handshake",
  1350. "-false-start",
  1351. "-handshake-never-done",
  1352. "-advertise-alpn", "\x03foo",
  1353. },
  1354. shouldFail: true,
  1355. expectedError: ":UNEXPECTED_RECORD:",
  1356. },
  1357. {
  1358. testType: serverTest,
  1359. name: "FailEarlyCallback",
  1360. flags: []string{"-fail-early-callback"},
  1361. shouldFail: true,
  1362. expectedError: ":CONNECTION_REJECTED:",
  1363. expectedLocalError: "remote error: access denied",
  1364. },
  1365. {
  1366. name: "WrongMessageType",
  1367. config: Config{
  1368. Bugs: ProtocolBugs{
  1369. WrongCertificateMessageType: true,
  1370. },
  1371. },
  1372. shouldFail: true,
  1373. expectedError: ":UNEXPECTED_MESSAGE:",
  1374. expectedLocalError: "remote error: unexpected message",
  1375. },
  1376. {
  1377. protocol: dtls,
  1378. name: "WrongMessageType-DTLS",
  1379. config: Config{
  1380. Bugs: ProtocolBugs{
  1381. WrongCertificateMessageType: true,
  1382. },
  1383. },
  1384. shouldFail: true,
  1385. expectedError: ":UNEXPECTED_MESSAGE:",
  1386. expectedLocalError: "remote error: unexpected message",
  1387. },
  1388. {
  1389. protocol: dtls,
  1390. name: "FragmentMessageTypeMismatch-DTLS",
  1391. config: Config{
  1392. Bugs: ProtocolBugs{
  1393. MaxHandshakeRecordLength: 2,
  1394. FragmentMessageTypeMismatch: true,
  1395. },
  1396. },
  1397. shouldFail: true,
  1398. expectedError: ":FRAGMENT_MISMATCH:",
  1399. },
  1400. {
  1401. protocol: dtls,
  1402. name: "FragmentMessageLengthMismatch-DTLS",
  1403. config: Config{
  1404. Bugs: ProtocolBugs{
  1405. MaxHandshakeRecordLength: 2,
  1406. FragmentMessageLengthMismatch: true,
  1407. },
  1408. },
  1409. shouldFail: true,
  1410. expectedError: ":FRAGMENT_MISMATCH:",
  1411. },
  1412. {
  1413. protocol: dtls,
  1414. name: "SplitFragments-Header-DTLS",
  1415. config: Config{
  1416. Bugs: ProtocolBugs{
  1417. SplitFragments: 2,
  1418. },
  1419. },
  1420. shouldFail: true,
  1421. expectedError: ":UNEXPECTED_MESSAGE:",
  1422. },
  1423. {
  1424. protocol: dtls,
  1425. name: "SplitFragments-Boundary-DTLS",
  1426. config: Config{
  1427. Bugs: ProtocolBugs{
  1428. SplitFragments: dtlsRecordHeaderLen,
  1429. },
  1430. },
  1431. shouldFail: true,
  1432. expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
  1433. },
  1434. {
  1435. protocol: dtls,
  1436. name: "SplitFragments-Body-DTLS",
  1437. config: Config{
  1438. Bugs: ProtocolBugs{
  1439. SplitFragments: dtlsRecordHeaderLen + 1,
  1440. },
  1441. },
  1442. shouldFail: true,
  1443. expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
  1444. },
  1445. {
  1446. protocol: dtls,
  1447. name: "SendEmptyFragments-DTLS",
  1448. config: Config{
  1449. Bugs: ProtocolBugs{
  1450. SendEmptyFragments: true,
  1451. },
  1452. },
  1453. },
  1454. {
  1455. name: "UnsupportedCipherSuite",
  1456. config: Config{
  1457. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  1458. Bugs: ProtocolBugs{
  1459. IgnorePeerCipherPreferences: true,
  1460. },
  1461. },
  1462. flags: []string{"-cipher", "DEFAULT:!RC4"},
  1463. shouldFail: true,
  1464. expectedError: ":WRONG_CIPHER_RETURNED:",
  1465. },
  1466. {
  1467. name: "UnsupportedCurve",
  1468. config: Config{
  1469. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1470. // BoringSSL implements P-224 but doesn't enable it by
  1471. // default.
  1472. CurvePreferences: []CurveID{CurveP224},
  1473. Bugs: ProtocolBugs{
  1474. IgnorePeerCurvePreferences: true,
  1475. },
  1476. },
  1477. shouldFail: true,
  1478. expectedError: ":WRONG_CURVE:",
  1479. },
  1480. {
  1481. name: "BadFinished",
  1482. config: Config{
  1483. Bugs: ProtocolBugs{
  1484. BadFinished: true,
  1485. },
  1486. },
  1487. shouldFail: true,
  1488. expectedError: ":DIGEST_CHECK_FAILED:",
  1489. },
  1490. {
  1491. name: "FalseStart-BadFinished",
  1492. config: Config{
  1493. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1494. NextProtos: []string{"foo"},
  1495. Bugs: ProtocolBugs{
  1496. BadFinished: true,
  1497. ExpectFalseStart: true,
  1498. },
  1499. },
  1500. flags: []string{
  1501. "-false-start",
  1502. "-handshake-never-done",
  1503. "-advertise-alpn", "\x03foo",
  1504. },
  1505. shimWritesFirst: true,
  1506. shouldFail: true,
  1507. expectedError: ":DIGEST_CHECK_FAILED:",
  1508. },
  1509. {
  1510. name: "NoFalseStart-NoALPN",
  1511. config: Config{
  1512. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1513. Bugs: ProtocolBugs{
  1514. ExpectFalseStart: true,
  1515. AlertBeforeFalseStartTest: alertAccessDenied,
  1516. },
  1517. },
  1518. flags: []string{
  1519. "-false-start",
  1520. },
  1521. shimWritesFirst: true,
  1522. shouldFail: true,
  1523. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1524. expectedLocalError: "tls: peer did not false start: EOF",
  1525. },
  1526. {
  1527. name: "NoFalseStart-NoAEAD",
  1528. config: Config{
  1529. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1530. NextProtos: []string{"foo"},
  1531. Bugs: ProtocolBugs{
  1532. ExpectFalseStart: true,
  1533. AlertBeforeFalseStartTest: alertAccessDenied,
  1534. },
  1535. },
  1536. flags: []string{
  1537. "-false-start",
  1538. "-advertise-alpn", "\x03foo",
  1539. },
  1540. shimWritesFirst: true,
  1541. shouldFail: true,
  1542. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1543. expectedLocalError: "tls: peer did not false start: EOF",
  1544. },
  1545. {
  1546. name: "NoFalseStart-RSA",
  1547. config: Config{
  1548. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  1549. NextProtos: []string{"foo"},
  1550. Bugs: ProtocolBugs{
  1551. ExpectFalseStart: true,
  1552. AlertBeforeFalseStartTest: alertAccessDenied,
  1553. },
  1554. },
  1555. flags: []string{
  1556. "-false-start",
  1557. "-advertise-alpn", "\x03foo",
  1558. },
  1559. shimWritesFirst: true,
  1560. shouldFail: true,
  1561. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1562. expectedLocalError: "tls: peer did not false start: EOF",
  1563. },
  1564. {
  1565. name: "NoFalseStart-DHE_RSA",
  1566. config: Config{
  1567. CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
  1568. NextProtos: []string{"foo"},
  1569. Bugs: ProtocolBugs{
  1570. ExpectFalseStart: true,
  1571. AlertBeforeFalseStartTest: alertAccessDenied,
  1572. },
  1573. },
  1574. flags: []string{
  1575. "-false-start",
  1576. "-advertise-alpn", "\x03foo",
  1577. },
  1578. shimWritesFirst: true,
  1579. shouldFail: true,
  1580. expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
  1581. expectedLocalError: "tls: peer did not false start: EOF",
  1582. },
  1583. {
  1584. testType: serverTest,
  1585. name: "NoSupportedCurves",
  1586. config: Config{
  1587. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  1588. Bugs: ProtocolBugs{
  1589. NoSupportedCurves: true,
  1590. },
  1591. },
  1592. },
  1593. {
  1594. testType: serverTest,
  1595. name: "NoCommonCurves",
  1596. config: Config{
  1597. CipherSuites: []uint16{
  1598. TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
  1599. TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
  1600. },
  1601. CurvePreferences: []CurveID{CurveP224},
  1602. },
  1603. expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
  1604. },
  1605. {
  1606. protocol: dtls,
  1607. name: "SendSplitAlert-Sync",
  1608. config: Config{
  1609. Bugs: ProtocolBugs{
  1610. SendSplitAlert: true,
  1611. },
  1612. },
  1613. },
  1614. {
  1615. protocol: dtls,
  1616. name: "SendSplitAlert-Async",
  1617. config: Config{
  1618. Bugs: ProtocolBugs{
  1619. SendSplitAlert: true,
  1620. },
  1621. },
  1622. flags: []string{"-async"},
  1623. },
  1624. {
  1625. protocol: dtls,
  1626. name: "PackDTLSHandshake",
  1627. config: Config{
  1628. Bugs: ProtocolBugs{
  1629. MaxHandshakeRecordLength: 2,
  1630. PackHandshakeFragments: 20,
  1631. PackHandshakeRecords: 200,
  1632. },
  1633. },
  1634. },
  1635. {
  1636. testType: serverTest,
  1637. protocol: dtls,
  1638. name: "NoRC4-DTLS",
  1639. config: Config{
  1640. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA},
  1641. Bugs: ProtocolBugs{
  1642. EnableAllCiphersInDTLS: true,
  1643. },
  1644. },
  1645. shouldFail: true,
  1646. expectedError: ":NO_SHARED_CIPHER:",
  1647. },
  1648. {
  1649. name: "SendEmptyRecords-Pass",
  1650. sendEmptyRecords: 32,
  1651. },
  1652. {
  1653. name: "SendEmptyRecords",
  1654. sendEmptyRecords: 33,
  1655. shouldFail: true,
  1656. expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
  1657. },
  1658. {
  1659. name: "SendEmptyRecords-Async",
  1660. sendEmptyRecords: 33,
  1661. flags: []string{"-async"},
  1662. shouldFail: true,
  1663. expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
  1664. },
  1665. {
  1666. name: "SendWarningAlerts-Pass",
  1667. sendWarningAlerts: 4,
  1668. },
  1669. {
  1670. protocol: dtls,
  1671. name: "SendWarningAlerts-DTLS-Pass",
  1672. sendWarningAlerts: 4,
  1673. },
  1674. {
  1675. name: "SendWarningAlerts",
  1676. sendWarningAlerts: 5,
  1677. shouldFail: true,
  1678. expectedError: ":TOO_MANY_WARNING_ALERTS:",
  1679. },
  1680. {
  1681. name: "SendWarningAlerts-Async",
  1682. sendWarningAlerts: 5,
  1683. flags: []string{"-async"},
  1684. shouldFail: true,
  1685. expectedError: ":TOO_MANY_WARNING_ALERTS:",
  1686. },
  1687. {
  1688. name: "EmptySessionID",
  1689. config: Config{
  1690. SessionTicketsDisabled: true,
  1691. },
  1692. noSessionCache: true,
  1693. flags: []string{"-expect-no-session"},
  1694. },
  1695. }
  1696. testCases = append(testCases, basicTests...)
  1697. }
  1698. func addCipherSuiteTests() {
  1699. for _, suite := range testCipherSuites {
  1700. const psk = "12345"
  1701. const pskIdentity = "luggage combo"
  1702. var cert Certificate
  1703. var certFile string
  1704. var keyFile string
  1705. if hasComponent(suite.name, "ECDSA") {
  1706. cert = getECDSACertificate()
  1707. certFile = ecdsaCertificateFile
  1708. keyFile = ecdsaKeyFile
  1709. } else {
  1710. cert = getRSACertificate()
  1711. certFile = rsaCertificateFile
  1712. keyFile = rsaKeyFile
  1713. }
  1714. var flags []string
  1715. if hasComponent(suite.name, "PSK") {
  1716. flags = append(flags,
  1717. "-psk", psk,
  1718. "-psk-identity", pskIdentity)
  1719. }
  1720. for _, ver := range tlsVersions {
  1721. if ver.version < VersionTLS12 && isTLS12Only(suite.name) {
  1722. continue
  1723. }
  1724. testCases = append(testCases, testCase{
  1725. testType: clientTest,
  1726. name: ver.name + "-" + suite.name + "-client",
  1727. config: Config{
  1728. MinVersion: ver.version,
  1729. MaxVersion: ver.version,
  1730. CipherSuites: []uint16{suite.id},
  1731. Certificates: []Certificate{cert},
  1732. PreSharedKey: []byte(psk),
  1733. PreSharedKeyIdentity: pskIdentity,
  1734. },
  1735. flags: flags,
  1736. resumeSession: true,
  1737. })
  1738. testCases = append(testCases, testCase{
  1739. testType: serverTest,
  1740. name: ver.name + "-" + suite.name + "-server",
  1741. config: Config{
  1742. MinVersion: ver.version,
  1743. MaxVersion: ver.version,
  1744. CipherSuites: []uint16{suite.id},
  1745. Certificates: []Certificate{cert},
  1746. PreSharedKey: []byte(psk),
  1747. PreSharedKeyIdentity: pskIdentity,
  1748. },
  1749. certFile: certFile,
  1750. keyFile: keyFile,
  1751. flags: flags,
  1752. resumeSession: true,
  1753. })
  1754. if ver.hasDTLS && isDTLSCipher(suite.name) {
  1755. testCases = append(testCases, testCase{
  1756. testType: clientTest,
  1757. protocol: dtls,
  1758. name: "D" + ver.name + "-" + suite.name + "-client",
  1759. config: Config{
  1760. MinVersion: ver.version,
  1761. MaxVersion: ver.version,
  1762. CipherSuites: []uint16{suite.id},
  1763. Certificates: []Certificate{cert},
  1764. PreSharedKey: []byte(psk),
  1765. PreSharedKeyIdentity: pskIdentity,
  1766. },
  1767. flags: flags,
  1768. resumeSession: true,
  1769. })
  1770. testCases = append(testCases, testCase{
  1771. testType: serverTest,
  1772. protocol: dtls,
  1773. name: "D" + ver.name + "-" + suite.name + "-server",
  1774. config: Config{
  1775. MinVersion: ver.version,
  1776. MaxVersion: ver.version,
  1777. CipherSuites: []uint16{suite.id},
  1778. Certificates: []Certificate{cert},
  1779. PreSharedKey: []byte(psk),
  1780. PreSharedKeyIdentity: pskIdentity,
  1781. },
  1782. certFile: certFile,
  1783. keyFile: keyFile,
  1784. flags: flags,
  1785. resumeSession: true,
  1786. })
  1787. }
  1788. }
  1789. }
  1790. testCases = append(testCases, testCase{
  1791. name: "WeakDH",
  1792. config: Config{
  1793. CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
  1794. Bugs: ProtocolBugs{
  1795. // This is a 1023-bit prime number, generated
  1796. // with:
  1797. // openssl gendh 1023 | openssl asn1parse -i
  1798. DHGroupPrime: bigFromHex("518E9B7930CE61C6E445C8360584E5FC78D9137C0FFDC880B495D5338ADF7689951A6821C17A76B3ACB8E0156AEA607B7EC406EBEDBB84D8376EB8FE8F8BA1433488BEE0C3EDDFD3A32DBB9481980A7AF6C96BFCF490A094CFFB2B8192C1BB5510B77B658436E27C2D4D023FE3718222AB0CA1273995B51F6D625A4944D0DD4B"),
  1799. },
  1800. },
  1801. shouldFail: true,
  1802. expectedError: "BAD_DH_P_LENGTH",
  1803. })
  1804. }
  1805. func addBadECDSASignatureTests() {
  1806. for badR := BadValue(1); badR < NumBadValues; badR++ {
  1807. for badS := BadValue(1); badS < NumBadValues; badS++ {
  1808. testCases = append(testCases, testCase{
  1809. name: fmt.Sprintf("BadECDSA-%d-%d", badR, badS),
  1810. config: Config{
  1811. CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
  1812. Certificates: []Certificate{getECDSACertificate()},
  1813. Bugs: ProtocolBugs{
  1814. BadECDSAR: badR,
  1815. BadECDSAS: badS,
  1816. },
  1817. },
  1818. shouldFail: true,
  1819. expectedError: "SIGNATURE",
  1820. })
  1821. }
  1822. }
  1823. }
  1824. func addCBCPaddingTests() {
  1825. testCases = append(testCases, testCase{
  1826. name: "MaxCBCPadding",
  1827. config: Config{
  1828. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1829. Bugs: ProtocolBugs{
  1830. MaxPadding: true,
  1831. },
  1832. },
  1833. messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
  1834. })
  1835. testCases = append(testCases, testCase{
  1836. name: "BadCBCPadding",
  1837. config: Config{
  1838. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1839. Bugs: ProtocolBugs{
  1840. PaddingFirstByteBad: true,
  1841. },
  1842. },
  1843. shouldFail: true,
  1844. expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
  1845. })
  1846. // OpenSSL previously had an issue where the first byte of padding in
  1847. // 255 bytes of padding wasn't checked.
  1848. testCases = append(testCases, testCase{
  1849. name: "BadCBCPadding255",
  1850. config: Config{
  1851. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1852. Bugs: ProtocolBugs{
  1853. MaxPadding: true,
  1854. PaddingFirstByteBadIf255: true,
  1855. },
  1856. },
  1857. messageLen: 12, // 20 bytes of SHA-1 + 12 == 0 % block size
  1858. shouldFail: true,
  1859. expectedError: "DECRYPTION_FAILED_OR_BAD_RECORD_MAC",
  1860. })
  1861. }
  1862. func addCBCSplittingTests() {
  1863. testCases = append(testCases, testCase{
  1864. name: "CBCRecordSplitting",
  1865. config: Config{
  1866. MaxVersion: VersionTLS10,
  1867. MinVersion: VersionTLS10,
  1868. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1869. },
  1870. messageLen: -1, // read until EOF
  1871. flags: []string{
  1872. "-async",
  1873. "-write-different-record-sizes",
  1874. "-cbc-record-splitting",
  1875. },
  1876. })
  1877. testCases = append(testCases, testCase{
  1878. name: "CBCRecordSplittingPartialWrite",
  1879. config: Config{
  1880. MaxVersion: VersionTLS10,
  1881. MinVersion: VersionTLS10,
  1882. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
  1883. },
  1884. messageLen: -1, // read until EOF
  1885. flags: []string{
  1886. "-async",
  1887. "-write-different-record-sizes",
  1888. "-cbc-record-splitting",
  1889. "-partial-write",
  1890. },
  1891. })
  1892. }
  1893. func addClientAuthTests() {
  1894. // Add a dummy cert pool to stress certificate authority parsing.
  1895. // TODO(davidben): Add tests that those values parse out correctly.
  1896. certPool := x509.NewCertPool()
  1897. cert, err := x509.ParseCertificate(rsaCertificate.Certificate[0])
  1898. if err != nil {
  1899. panic(err)
  1900. }
  1901. certPool.AddCert(cert)
  1902. for _, ver := range tlsVersions {
  1903. testCases = append(testCases, testCase{
  1904. testType: clientTest,
  1905. name: ver.name + "-Client-ClientAuth-RSA",
  1906. config: Config{
  1907. MinVersion: ver.version,
  1908. MaxVersion: ver.version,
  1909. ClientAuth: RequireAnyClientCert,
  1910. ClientCAs: certPool,
  1911. },
  1912. flags: []string{
  1913. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  1914. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  1915. },
  1916. })
  1917. testCases = append(testCases, testCase{
  1918. testType: serverTest,
  1919. name: ver.name + "-Server-ClientAuth-RSA",
  1920. config: Config{
  1921. MinVersion: ver.version,
  1922. MaxVersion: ver.version,
  1923. Certificates: []Certificate{rsaCertificate},
  1924. },
  1925. flags: []string{"-require-any-client-certificate"},
  1926. })
  1927. if ver.version != VersionSSL30 {
  1928. testCases = append(testCases, testCase{
  1929. testType: serverTest,
  1930. name: ver.name + "-Server-ClientAuth-ECDSA",
  1931. config: Config{
  1932. MinVersion: ver.version,
  1933. MaxVersion: ver.version,
  1934. Certificates: []Certificate{ecdsaCertificate},
  1935. },
  1936. flags: []string{"-require-any-client-certificate"},
  1937. })
  1938. testCases = append(testCases, testCase{
  1939. testType: clientTest,
  1940. name: ver.name + "-Client-ClientAuth-ECDSA",
  1941. config: Config{
  1942. MinVersion: ver.version,
  1943. MaxVersion: ver.version,
  1944. ClientAuth: RequireAnyClientCert,
  1945. ClientCAs: certPool,
  1946. },
  1947. flags: []string{
  1948. "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
  1949. "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
  1950. },
  1951. })
  1952. }
  1953. }
  1954. }
  1955. func addExtendedMasterSecretTests() {
  1956. const expectEMSFlag = "-expect-extended-master-secret"
  1957. for _, with := range []bool{false, true} {
  1958. prefix := "No"
  1959. var flags []string
  1960. if with {
  1961. prefix = ""
  1962. flags = []string{expectEMSFlag}
  1963. }
  1964. for _, isClient := range []bool{false, true} {
  1965. suffix := "-Server"
  1966. testType := serverTest
  1967. if isClient {
  1968. suffix = "-Client"
  1969. testType = clientTest
  1970. }
  1971. for _, ver := range tlsVersions {
  1972. test := testCase{
  1973. testType: testType,
  1974. name: prefix + "ExtendedMasterSecret-" + ver.name + suffix,
  1975. config: Config{
  1976. MinVersion: ver.version,
  1977. MaxVersion: ver.version,
  1978. Bugs: ProtocolBugs{
  1979. NoExtendedMasterSecret: !with,
  1980. RequireExtendedMasterSecret: with,
  1981. },
  1982. },
  1983. flags: flags,
  1984. shouldFail: ver.version == VersionSSL30 && with,
  1985. }
  1986. if test.shouldFail {
  1987. test.expectedLocalError = "extended master secret required but not supported by peer"
  1988. }
  1989. testCases = append(testCases, test)
  1990. }
  1991. }
  1992. }
  1993. for _, isClient := range []bool{false, true} {
  1994. for _, supportedInFirstConnection := range []bool{false, true} {
  1995. for _, supportedInResumeConnection := range []bool{false, true} {
  1996. boolToWord := func(b bool) string {
  1997. if b {
  1998. return "Yes"
  1999. }
  2000. return "No"
  2001. }
  2002. suffix := boolToWord(supportedInFirstConnection) + "To" + boolToWord(supportedInResumeConnection) + "-"
  2003. if isClient {
  2004. suffix += "Client"
  2005. } else {
  2006. suffix += "Server"
  2007. }
  2008. supportedConfig := Config{
  2009. Bugs: ProtocolBugs{
  2010. RequireExtendedMasterSecret: true,
  2011. },
  2012. }
  2013. noSupportConfig := Config{
  2014. Bugs: ProtocolBugs{
  2015. NoExtendedMasterSecret: true,
  2016. },
  2017. }
  2018. test := testCase{
  2019. name: "ExtendedMasterSecret-" + suffix,
  2020. resumeSession: true,
  2021. }
  2022. if !isClient {
  2023. test.testType = serverTest
  2024. }
  2025. if supportedInFirstConnection {
  2026. test.config = supportedConfig
  2027. } else {
  2028. test.config = noSupportConfig
  2029. }
  2030. if supportedInResumeConnection {
  2031. test.resumeConfig = &supportedConfig
  2032. } else {
  2033. test.resumeConfig = &noSupportConfig
  2034. }
  2035. switch suffix {
  2036. case "YesToYes-Client", "YesToYes-Server":
  2037. // When a session is resumed, it should
  2038. // still be aware that its master
  2039. // secret was generated via EMS and
  2040. // thus it's safe to use tls-unique.
  2041. test.flags = []string{expectEMSFlag}
  2042. case "NoToYes-Server":
  2043. // If an original connection did not
  2044. // contain EMS, but a resumption
  2045. // handshake does, then a server should
  2046. // not resume the session.
  2047. test.expectResumeRejected = true
  2048. case "YesToNo-Server":
  2049. // Resuming an EMS session without the
  2050. // EMS extension should cause the
  2051. // server to abort the connection.
  2052. test.shouldFail = true
  2053. test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
  2054. case "NoToYes-Client":
  2055. // A client should abort a connection
  2056. // where the server resumed a non-EMS
  2057. // session but echoed the EMS
  2058. // extension.
  2059. test.shouldFail = true
  2060. test.expectedError = ":RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION:"
  2061. case "YesToNo-Client":
  2062. // A client should abort a connection
  2063. // where the server didn't echo EMS
  2064. // when the session used it.
  2065. test.shouldFail = true
  2066. test.expectedError = ":RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION:"
  2067. }
  2068. testCases = append(testCases, test)
  2069. }
  2070. }
  2071. }
  2072. }
  2073. // Adds tests that try to cover the range of the handshake state machine, under
  2074. // various conditions. Some of these are redundant with other tests, but they
  2075. // only cover the synchronous case.
  2076. func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol) {
  2077. var tests []testCase
  2078. // Basic handshake, with resumption. Client and server,
  2079. // session ID and session ticket.
  2080. tests = append(tests, testCase{
  2081. name: "Basic-Client",
  2082. resumeSession: true,
  2083. })
  2084. tests = append(tests, testCase{
  2085. name: "Basic-Client-RenewTicket",
  2086. config: Config{
  2087. Bugs: ProtocolBugs{
  2088. RenewTicketOnResume: true,
  2089. },
  2090. },
  2091. flags: []string{"-expect-ticket-renewal"},
  2092. resumeSession: true,
  2093. })
  2094. tests = append(tests, testCase{
  2095. name: "Basic-Client-NoTicket",
  2096. config: Config{
  2097. SessionTicketsDisabled: true,
  2098. },
  2099. resumeSession: true,
  2100. })
  2101. tests = append(tests, testCase{
  2102. name: "Basic-Client-Implicit",
  2103. flags: []string{"-implicit-handshake"},
  2104. resumeSession: true,
  2105. })
  2106. tests = append(tests, testCase{
  2107. testType: serverTest,
  2108. name: "Basic-Server",
  2109. resumeSession: true,
  2110. })
  2111. tests = append(tests, testCase{
  2112. testType: serverTest,
  2113. name: "Basic-Server-NoTickets",
  2114. config: Config{
  2115. SessionTicketsDisabled: true,
  2116. },
  2117. resumeSession: true,
  2118. })
  2119. tests = append(tests, testCase{
  2120. testType: serverTest,
  2121. name: "Basic-Server-Implicit",
  2122. flags: []string{"-implicit-handshake"},
  2123. resumeSession: true,
  2124. })
  2125. tests = append(tests, testCase{
  2126. testType: serverTest,
  2127. name: "Basic-Server-EarlyCallback",
  2128. flags: []string{"-use-early-callback"},
  2129. resumeSession: true,
  2130. })
  2131. // TLS client auth.
  2132. tests = append(tests, testCase{
  2133. testType: clientTest,
  2134. name: "ClientAuth-Client",
  2135. config: Config{
  2136. ClientAuth: RequireAnyClientCert,
  2137. },
  2138. flags: []string{
  2139. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  2140. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  2141. },
  2142. })
  2143. if async {
  2144. tests = append(tests, testCase{
  2145. testType: clientTest,
  2146. name: "ClientAuth-Client-AsyncKey",
  2147. config: Config{
  2148. ClientAuth: RequireAnyClientCert,
  2149. },
  2150. flags: []string{
  2151. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  2152. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  2153. "-use-async-private-key",
  2154. },
  2155. })
  2156. tests = append(tests, testCase{
  2157. testType: serverTest,
  2158. name: "Basic-Server-RSAAsyncKey",
  2159. flags: []string{
  2160. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  2161. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  2162. "-use-async-private-key",
  2163. },
  2164. })
  2165. tests = append(tests, testCase{
  2166. testType: serverTest,
  2167. name: "Basic-Server-ECDSAAsyncKey",
  2168. flags: []string{
  2169. "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
  2170. "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
  2171. "-use-async-private-key",
  2172. },
  2173. })
  2174. }
  2175. tests = append(tests, testCase{
  2176. testType: serverTest,
  2177. name: "ClientAuth-Server",
  2178. config: Config{
  2179. Certificates: []Certificate{rsaCertificate},
  2180. },
  2181. flags: []string{"-require-any-client-certificate"},
  2182. })
  2183. // No session ticket support; server doesn't send NewSessionTicket.
  2184. tests = append(tests, testCase{
  2185. name: "SessionTicketsDisabled-Client",
  2186. config: Config{
  2187. SessionTicketsDisabled: true,
  2188. },
  2189. })
  2190. tests = append(tests, testCase{
  2191. testType: serverTest,
  2192. name: "SessionTicketsDisabled-Server",
  2193. config: Config{
  2194. SessionTicketsDisabled: true,
  2195. },
  2196. })
  2197. // Skip ServerKeyExchange in PSK key exchange if there's no
  2198. // identity hint.
  2199. tests = append(tests, testCase{
  2200. name: "EmptyPSKHint-Client",
  2201. config: Config{
  2202. CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
  2203. PreSharedKey: []byte("secret"),
  2204. },
  2205. flags: []string{"-psk", "secret"},
  2206. })
  2207. tests = append(tests, testCase{
  2208. testType: serverTest,
  2209. name: "EmptyPSKHint-Server",
  2210. config: Config{
  2211. CipherSuites: []uint16{TLS_PSK_WITH_AES_128_CBC_SHA},
  2212. PreSharedKey: []byte("secret"),
  2213. },
  2214. flags: []string{"-psk", "secret"},
  2215. })
  2216. if protocol == tls {
  2217. tests = append(tests, testCase{
  2218. name: "Renegotiate-Client",
  2219. renegotiate: true,
  2220. })
  2221. // NPN on client and server; results in post-handshake message.
  2222. tests = append(tests, testCase{
  2223. name: "NPN-Client",
  2224. config: Config{
  2225. NextProtos: []string{"foo"},
  2226. },
  2227. flags: []string{"-select-next-proto", "foo"},
  2228. expectedNextProto: "foo",
  2229. expectedNextProtoType: npn,
  2230. })
  2231. tests = append(tests, testCase{
  2232. testType: serverTest,
  2233. name: "NPN-Server",
  2234. config: Config{
  2235. NextProtos: []string{"bar"},
  2236. },
  2237. flags: []string{
  2238. "-advertise-npn", "\x03foo\x03bar\x03baz",
  2239. "-expect-next-proto", "bar",
  2240. },
  2241. expectedNextProto: "bar",
  2242. expectedNextProtoType: npn,
  2243. })
  2244. // TODO(davidben): Add tests for when False Start doesn't trigger.
  2245. // Client does False Start and negotiates NPN.
  2246. tests = append(tests, testCase{
  2247. name: "FalseStart",
  2248. config: Config{
  2249. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2250. NextProtos: []string{"foo"},
  2251. Bugs: ProtocolBugs{
  2252. ExpectFalseStart: true,
  2253. },
  2254. },
  2255. flags: []string{
  2256. "-false-start",
  2257. "-select-next-proto", "foo",
  2258. },
  2259. shimWritesFirst: true,
  2260. resumeSession: true,
  2261. })
  2262. // Client does False Start and negotiates ALPN.
  2263. tests = append(tests, testCase{
  2264. name: "FalseStart-ALPN",
  2265. config: Config{
  2266. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2267. NextProtos: []string{"foo"},
  2268. Bugs: ProtocolBugs{
  2269. ExpectFalseStart: true,
  2270. },
  2271. },
  2272. flags: []string{
  2273. "-false-start",
  2274. "-advertise-alpn", "\x03foo",
  2275. },
  2276. shimWritesFirst: true,
  2277. resumeSession: true,
  2278. })
  2279. // Client does False Start but doesn't explicitly call
  2280. // SSL_connect.
  2281. tests = append(tests, testCase{
  2282. name: "FalseStart-Implicit",
  2283. config: Config{
  2284. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2285. NextProtos: []string{"foo"},
  2286. },
  2287. flags: []string{
  2288. "-implicit-handshake",
  2289. "-false-start",
  2290. "-advertise-alpn", "\x03foo",
  2291. },
  2292. })
  2293. // False Start without session tickets.
  2294. tests = append(tests, testCase{
  2295. name: "FalseStart-SessionTicketsDisabled",
  2296. config: Config{
  2297. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  2298. NextProtos: []string{"foo"},
  2299. SessionTicketsDisabled: true,
  2300. Bugs: ProtocolBugs{
  2301. ExpectFalseStart: true,
  2302. },
  2303. },
  2304. flags: []string{
  2305. "-false-start",
  2306. "-select-next-proto", "foo",
  2307. },
  2308. shimWritesFirst: true,
  2309. })
  2310. // Server parses a V2ClientHello.
  2311. tests = append(tests, testCase{
  2312. testType: serverTest,
  2313. name: "SendV2ClientHello",
  2314. config: Config{
  2315. // Choose a cipher suite that does not involve
  2316. // elliptic curves, so no extensions are
  2317. // involved.
  2318. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  2319. Bugs: ProtocolBugs{
  2320. SendV2ClientHello: true,
  2321. },
  2322. },
  2323. })
  2324. // Client sends a Channel ID.
  2325. tests = append(tests, testCase{
  2326. name: "ChannelID-Client",
  2327. config: Config{
  2328. RequestChannelID: true,
  2329. },
  2330. flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
  2331. resumeSession: true,
  2332. expectChannelID: true,
  2333. })
  2334. // Server accepts a Channel ID.
  2335. tests = append(tests, testCase{
  2336. testType: serverTest,
  2337. name: "ChannelID-Server",
  2338. config: Config{
  2339. ChannelID: channelIDKey,
  2340. },
  2341. flags: []string{
  2342. "-expect-channel-id",
  2343. base64.StdEncoding.EncodeToString(channelIDBytes),
  2344. },
  2345. resumeSession: true,
  2346. expectChannelID: true,
  2347. })
  2348. } else {
  2349. tests = append(tests, testCase{
  2350. name: "SkipHelloVerifyRequest",
  2351. config: Config{
  2352. Bugs: ProtocolBugs{
  2353. SkipHelloVerifyRequest: true,
  2354. },
  2355. },
  2356. })
  2357. }
  2358. var suffix string
  2359. var flags []string
  2360. var maxHandshakeRecordLength int
  2361. if protocol == dtls {
  2362. suffix = "-DTLS"
  2363. }
  2364. if async {
  2365. suffix += "-Async"
  2366. flags = append(flags, "-async")
  2367. } else {
  2368. suffix += "-Sync"
  2369. }
  2370. if splitHandshake {
  2371. suffix += "-SplitHandshakeRecords"
  2372. maxHandshakeRecordLength = 1
  2373. }
  2374. for _, test := range tests {
  2375. test.protocol = protocol
  2376. test.name += suffix
  2377. test.config.Bugs.MaxHandshakeRecordLength = maxHandshakeRecordLength
  2378. test.flags = append(test.flags, flags...)
  2379. testCases = append(testCases, test)
  2380. }
  2381. }
  2382. func addDDoSCallbackTests() {
  2383. // DDoS callback.
  2384. for _, resume := range []bool{false, true} {
  2385. suffix := "Resume"
  2386. if resume {
  2387. suffix = "No" + suffix
  2388. }
  2389. testCases = append(testCases, testCase{
  2390. testType: serverTest,
  2391. name: "Server-DDoS-OK-" + suffix,
  2392. flags: []string{"-install-ddos-callback"},
  2393. resumeSession: resume,
  2394. })
  2395. failFlag := "-fail-ddos-callback"
  2396. if resume {
  2397. failFlag = "-fail-second-ddos-callback"
  2398. }
  2399. testCases = append(testCases, testCase{
  2400. testType: serverTest,
  2401. name: "Server-DDoS-Reject-" + suffix,
  2402. flags: []string{"-install-ddos-callback", failFlag},
  2403. resumeSession: resume,
  2404. shouldFail: true,
  2405. expectedError: ":CONNECTION_REJECTED:",
  2406. })
  2407. }
  2408. }
  2409. func addVersionNegotiationTests() {
  2410. for i, shimVers := range tlsVersions {
  2411. // Assemble flags to disable all newer versions on the shim.
  2412. var flags []string
  2413. for _, vers := range tlsVersions[i+1:] {
  2414. flags = append(flags, vers.flag)
  2415. }
  2416. for _, runnerVers := range tlsVersions {
  2417. protocols := []protocol{tls}
  2418. if runnerVers.hasDTLS && shimVers.hasDTLS {
  2419. protocols = append(protocols, dtls)
  2420. }
  2421. for _, protocol := range protocols {
  2422. expectedVersion := shimVers.version
  2423. if runnerVers.version < shimVers.version {
  2424. expectedVersion = runnerVers.version
  2425. }
  2426. suffix := shimVers.name + "-" + runnerVers.name
  2427. if protocol == dtls {
  2428. suffix += "-DTLS"
  2429. }
  2430. shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
  2431. clientVers := shimVers.version
  2432. if clientVers > VersionTLS10 {
  2433. clientVers = VersionTLS10
  2434. }
  2435. testCases = append(testCases, testCase{
  2436. protocol: protocol,
  2437. testType: clientTest,
  2438. name: "VersionNegotiation-Client-" + suffix,
  2439. config: Config{
  2440. MaxVersion: runnerVers.version,
  2441. Bugs: ProtocolBugs{
  2442. ExpectInitialRecordVersion: clientVers,
  2443. },
  2444. },
  2445. flags: flags,
  2446. expectedVersion: expectedVersion,
  2447. })
  2448. testCases = append(testCases, testCase{
  2449. protocol: protocol,
  2450. testType: clientTest,
  2451. name: "VersionNegotiation-Client2-" + suffix,
  2452. config: Config{
  2453. MaxVersion: runnerVers.version,
  2454. Bugs: ProtocolBugs{
  2455. ExpectInitialRecordVersion: clientVers,
  2456. },
  2457. },
  2458. flags: []string{"-max-version", shimVersFlag},
  2459. expectedVersion: expectedVersion,
  2460. })
  2461. testCases = append(testCases, testCase{
  2462. protocol: protocol,
  2463. testType: serverTest,
  2464. name: "VersionNegotiation-Server-" + suffix,
  2465. config: Config{
  2466. MaxVersion: runnerVers.version,
  2467. Bugs: ProtocolBugs{
  2468. ExpectInitialRecordVersion: expectedVersion,
  2469. },
  2470. },
  2471. flags: flags,
  2472. expectedVersion: expectedVersion,
  2473. })
  2474. testCases = append(testCases, testCase{
  2475. protocol: protocol,
  2476. testType: serverTest,
  2477. name: "VersionNegotiation-Server2-" + suffix,
  2478. config: Config{
  2479. MaxVersion: runnerVers.version,
  2480. Bugs: ProtocolBugs{
  2481. ExpectInitialRecordVersion: expectedVersion,
  2482. },
  2483. },
  2484. flags: []string{"-max-version", shimVersFlag},
  2485. expectedVersion: expectedVersion,
  2486. })
  2487. }
  2488. }
  2489. }
  2490. }
  2491. func addMinimumVersionTests() {
  2492. for i, shimVers := range tlsVersions {
  2493. // Assemble flags to disable all older versions on the shim.
  2494. var flags []string
  2495. for _, vers := range tlsVersions[:i] {
  2496. flags = append(flags, vers.flag)
  2497. }
  2498. for _, runnerVers := range tlsVersions {
  2499. protocols := []protocol{tls}
  2500. if runnerVers.hasDTLS && shimVers.hasDTLS {
  2501. protocols = append(protocols, dtls)
  2502. }
  2503. for _, protocol := range protocols {
  2504. suffix := shimVers.name + "-" + runnerVers.name
  2505. if protocol == dtls {
  2506. suffix += "-DTLS"
  2507. }
  2508. shimVersFlag := strconv.Itoa(int(versionToWire(shimVers.version, protocol == dtls)))
  2509. var expectedVersion uint16
  2510. var shouldFail bool
  2511. var expectedError string
  2512. var expectedLocalError string
  2513. if runnerVers.version >= shimVers.version {
  2514. expectedVersion = runnerVers.version
  2515. } else {
  2516. shouldFail = true
  2517. expectedError = ":UNSUPPORTED_PROTOCOL:"
  2518. if runnerVers.version > VersionSSL30 {
  2519. expectedLocalError = "remote error: protocol version not supported"
  2520. } else {
  2521. expectedLocalError = "remote error: handshake failure"
  2522. }
  2523. }
  2524. testCases = append(testCases, testCase{
  2525. protocol: protocol,
  2526. testType: clientTest,
  2527. name: "MinimumVersion-Client-" + suffix,
  2528. config: Config{
  2529. MaxVersion: runnerVers.version,
  2530. },
  2531. flags: flags,
  2532. expectedVersion: expectedVersion,
  2533. shouldFail: shouldFail,
  2534. expectedError: expectedError,
  2535. expectedLocalError: expectedLocalError,
  2536. })
  2537. testCases = append(testCases, testCase{
  2538. protocol: protocol,
  2539. testType: clientTest,
  2540. name: "MinimumVersion-Client2-" + suffix,
  2541. config: Config{
  2542. MaxVersion: runnerVers.version,
  2543. },
  2544. flags: []string{"-min-version", shimVersFlag},
  2545. expectedVersion: expectedVersion,
  2546. shouldFail: shouldFail,
  2547. expectedError: expectedError,
  2548. expectedLocalError: expectedLocalError,
  2549. })
  2550. testCases = append(testCases, testCase{
  2551. protocol: protocol,
  2552. testType: serverTest,
  2553. name: "MinimumVersion-Server-" + suffix,
  2554. config: Config{
  2555. MaxVersion: runnerVers.version,
  2556. },
  2557. flags: flags,
  2558. expectedVersion: expectedVersion,
  2559. shouldFail: shouldFail,
  2560. expectedError: expectedError,
  2561. expectedLocalError: expectedLocalError,
  2562. })
  2563. testCases = append(testCases, testCase{
  2564. protocol: protocol,
  2565. testType: serverTest,
  2566. name: "MinimumVersion-Server2-" + suffix,
  2567. config: Config{
  2568. MaxVersion: runnerVers.version,
  2569. },
  2570. flags: []string{"-min-version", shimVersFlag},
  2571. expectedVersion: expectedVersion,
  2572. shouldFail: shouldFail,
  2573. expectedError: expectedError,
  2574. expectedLocalError: expectedLocalError,
  2575. })
  2576. }
  2577. }
  2578. }
  2579. }
  2580. func addD5BugTests() {
  2581. testCases = append(testCases, testCase{
  2582. testType: serverTest,
  2583. name: "D5Bug-NoQuirk-Reject",
  2584. config: Config{
  2585. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  2586. Bugs: ProtocolBugs{
  2587. SSL3RSAKeyExchange: true,
  2588. },
  2589. },
  2590. shouldFail: true,
  2591. expectedError: ":TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG:",
  2592. })
  2593. testCases = append(testCases, testCase{
  2594. testType: serverTest,
  2595. name: "D5Bug-Quirk-Normal",
  2596. config: Config{
  2597. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  2598. },
  2599. flags: []string{"-tls-d5-bug"},
  2600. })
  2601. testCases = append(testCases, testCase{
  2602. testType: serverTest,
  2603. name: "D5Bug-Quirk-Bug",
  2604. config: Config{
  2605. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  2606. Bugs: ProtocolBugs{
  2607. SSL3RSAKeyExchange: true,
  2608. },
  2609. },
  2610. flags: []string{"-tls-d5-bug"},
  2611. })
  2612. }
  2613. func addExtensionTests() {
  2614. testCases = append(testCases, testCase{
  2615. testType: clientTest,
  2616. name: "DuplicateExtensionClient",
  2617. config: Config{
  2618. Bugs: ProtocolBugs{
  2619. DuplicateExtension: true,
  2620. },
  2621. },
  2622. shouldFail: true,
  2623. expectedLocalError: "remote error: error decoding message",
  2624. })
  2625. testCases = append(testCases, testCase{
  2626. testType: serverTest,
  2627. name: "DuplicateExtensionServer",
  2628. config: Config{
  2629. Bugs: ProtocolBugs{
  2630. DuplicateExtension: true,
  2631. },
  2632. },
  2633. shouldFail: true,
  2634. expectedLocalError: "remote error: error decoding message",
  2635. })
  2636. testCases = append(testCases, testCase{
  2637. testType: clientTest,
  2638. name: "ServerNameExtensionClient",
  2639. config: Config{
  2640. Bugs: ProtocolBugs{
  2641. ExpectServerName: "example.com",
  2642. },
  2643. },
  2644. flags: []string{"-host-name", "example.com"},
  2645. })
  2646. testCases = append(testCases, testCase{
  2647. testType: clientTest,
  2648. name: "ServerNameExtensionClientMismatch",
  2649. config: Config{
  2650. Bugs: ProtocolBugs{
  2651. ExpectServerName: "mismatch.com",
  2652. },
  2653. },
  2654. flags: []string{"-host-name", "example.com"},
  2655. shouldFail: true,
  2656. expectedLocalError: "tls: unexpected server name",
  2657. })
  2658. testCases = append(testCases, testCase{
  2659. testType: clientTest,
  2660. name: "ServerNameExtensionClientMissing",
  2661. config: Config{
  2662. Bugs: ProtocolBugs{
  2663. ExpectServerName: "missing.com",
  2664. },
  2665. },
  2666. shouldFail: true,
  2667. expectedLocalError: "tls: unexpected server name",
  2668. })
  2669. testCases = append(testCases, testCase{
  2670. testType: serverTest,
  2671. name: "ServerNameExtensionServer",
  2672. config: Config{
  2673. ServerName: "example.com",
  2674. },
  2675. flags: []string{"-expect-server-name", "example.com"},
  2676. resumeSession: true,
  2677. })
  2678. testCases = append(testCases, testCase{
  2679. testType: clientTest,
  2680. name: "ALPNClient",
  2681. config: Config{
  2682. NextProtos: []string{"foo"},
  2683. },
  2684. flags: []string{
  2685. "-advertise-alpn", "\x03foo\x03bar\x03baz",
  2686. "-expect-alpn", "foo",
  2687. },
  2688. expectedNextProto: "foo",
  2689. expectedNextProtoType: alpn,
  2690. resumeSession: true,
  2691. })
  2692. testCases = append(testCases, testCase{
  2693. testType: serverTest,
  2694. name: "ALPNServer",
  2695. config: Config{
  2696. NextProtos: []string{"foo", "bar", "baz"},
  2697. },
  2698. flags: []string{
  2699. "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
  2700. "-select-alpn", "foo",
  2701. },
  2702. expectedNextProto: "foo",
  2703. expectedNextProtoType: alpn,
  2704. resumeSession: true,
  2705. })
  2706. // Test that the server prefers ALPN over NPN.
  2707. testCases = append(testCases, testCase{
  2708. testType: serverTest,
  2709. name: "ALPNServer-Preferred",
  2710. config: Config{
  2711. NextProtos: []string{"foo", "bar", "baz"},
  2712. },
  2713. flags: []string{
  2714. "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
  2715. "-select-alpn", "foo",
  2716. "-advertise-npn", "\x03foo\x03bar\x03baz",
  2717. },
  2718. expectedNextProto: "foo",
  2719. expectedNextProtoType: alpn,
  2720. resumeSession: true,
  2721. })
  2722. testCases = append(testCases, testCase{
  2723. testType: serverTest,
  2724. name: "ALPNServer-Preferred-Swapped",
  2725. config: Config{
  2726. NextProtos: []string{"foo", "bar", "baz"},
  2727. Bugs: ProtocolBugs{
  2728. SwapNPNAndALPN: true,
  2729. },
  2730. },
  2731. flags: []string{
  2732. "-expect-advertised-alpn", "\x03foo\x03bar\x03baz",
  2733. "-select-alpn", "foo",
  2734. "-advertise-npn", "\x03foo\x03bar\x03baz",
  2735. },
  2736. expectedNextProto: "foo",
  2737. expectedNextProtoType: alpn,
  2738. resumeSession: true,
  2739. })
  2740. var emptyString string
  2741. testCases = append(testCases, testCase{
  2742. testType: clientTest,
  2743. name: "ALPNClient-EmptyProtocolName",
  2744. config: Config{
  2745. NextProtos: []string{""},
  2746. Bugs: ProtocolBugs{
  2747. // A server returning an empty ALPN protocol
  2748. // should be rejected.
  2749. ALPNProtocol: &emptyString,
  2750. },
  2751. },
  2752. flags: []string{
  2753. "-advertise-alpn", "\x03foo",
  2754. },
  2755. shouldFail: true,
  2756. expectedError: ":PARSE_TLSEXT:",
  2757. })
  2758. testCases = append(testCases, testCase{
  2759. testType: serverTest,
  2760. name: "ALPNServer-EmptyProtocolName",
  2761. config: Config{
  2762. // A ClientHello containing an empty ALPN protocol
  2763. // should be rejected.
  2764. NextProtos: []string{"foo", "", "baz"},
  2765. },
  2766. flags: []string{
  2767. "-select-alpn", "foo",
  2768. },
  2769. shouldFail: true,
  2770. expectedError: ":PARSE_TLSEXT:",
  2771. })
  2772. // Resume with a corrupt ticket.
  2773. testCases = append(testCases, testCase{
  2774. testType: serverTest,
  2775. name: "CorruptTicket",
  2776. config: Config{
  2777. Bugs: ProtocolBugs{
  2778. CorruptTicket: true,
  2779. },
  2780. },
  2781. resumeSession: true,
  2782. expectResumeRejected: true,
  2783. })
  2784. // Test the ticket callback, with and without renewal.
  2785. testCases = append(testCases, testCase{
  2786. testType: serverTest,
  2787. name: "TicketCallback",
  2788. resumeSession: true,
  2789. flags: []string{"-use-ticket-callback"},
  2790. })
  2791. testCases = append(testCases, testCase{
  2792. testType: serverTest,
  2793. name: "TicketCallback-Renew",
  2794. config: Config{
  2795. Bugs: ProtocolBugs{
  2796. ExpectNewTicket: true,
  2797. },
  2798. },
  2799. flags: []string{"-use-ticket-callback", "-renew-ticket"},
  2800. resumeSession: true,
  2801. })
  2802. // Resume with an oversized session id.
  2803. testCases = append(testCases, testCase{
  2804. testType: serverTest,
  2805. name: "OversizedSessionId",
  2806. config: Config{
  2807. Bugs: ProtocolBugs{
  2808. OversizedSessionId: true,
  2809. },
  2810. },
  2811. resumeSession: true,
  2812. shouldFail: true,
  2813. expectedError: ":DECODE_ERROR:",
  2814. })
  2815. // Basic DTLS-SRTP tests. Include fake profiles to ensure they
  2816. // are ignored.
  2817. testCases = append(testCases, testCase{
  2818. protocol: dtls,
  2819. name: "SRTP-Client",
  2820. config: Config{
  2821. SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
  2822. },
  2823. flags: []string{
  2824. "-srtp-profiles",
  2825. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2826. },
  2827. expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
  2828. })
  2829. testCases = append(testCases, testCase{
  2830. protocol: dtls,
  2831. testType: serverTest,
  2832. name: "SRTP-Server",
  2833. config: Config{
  2834. SRTPProtectionProfiles: []uint16{40, SRTP_AES128_CM_HMAC_SHA1_80, 42},
  2835. },
  2836. flags: []string{
  2837. "-srtp-profiles",
  2838. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2839. },
  2840. expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
  2841. })
  2842. // Test that the MKI is ignored.
  2843. testCases = append(testCases, testCase{
  2844. protocol: dtls,
  2845. testType: serverTest,
  2846. name: "SRTP-Server-IgnoreMKI",
  2847. config: Config{
  2848. SRTPProtectionProfiles: []uint16{SRTP_AES128_CM_HMAC_SHA1_80},
  2849. Bugs: ProtocolBugs{
  2850. SRTPMasterKeyIdentifer: "bogus",
  2851. },
  2852. },
  2853. flags: []string{
  2854. "-srtp-profiles",
  2855. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2856. },
  2857. expectedSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_80,
  2858. })
  2859. // Test that SRTP isn't negotiated on the server if there were
  2860. // no matching profiles.
  2861. testCases = append(testCases, testCase{
  2862. protocol: dtls,
  2863. testType: serverTest,
  2864. name: "SRTP-Server-NoMatch",
  2865. config: Config{
  2866. SRTPProtectionProfiles: []uint16{100, 101, 102},
  2867. },
  2868. flags: []string{
  2869. "-srtp-profiles",
  2870. "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32",
  2871. },
  2872. expectedSRTPProtectionProfile: 0,
  2873. })
  2874. // Test that the server returning an invalid SRTP profile is
  2875. // flagged as an error by the client.
  2876. testCases = append(testCases, testCase{
  2877. protocol: dtls,
  2878. name: "SRTP-Client-NoMatch",
  2879. config: Config{
  2880. Bugs: ProtocolBugs{
  2881. SendSRTPProtectionProfile: SRTP_AES128_CM_HMAC_SHA1_32,
  2882. },
  2883. },
  2884. flags: []string{
  2885. "-srtp-profiles",
  2886. "SRTP_AES128_CM_SHA1_80",
  2887. },
  2888. shouldFail: true,
  2889. expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
  2890. })
  2891. // Test OCSP stapling and SCT list.
  2892. testCases = append(testCases, testCase{
  2893. name: "OCSPStapling",
  2894. flags: []string{
  2895. "-enable-ocsp-stapling",
  2896. "-expect-ocsp-response",
  2897. base64.StdEncoding.EncodeToString(testOCSPResponse),
  2898. },
  2899. })
  2900. testCases = append(testCases, testCase{
  2901. name: "SignedCertificateTimestampList",
  2902. flags: []string{
  2903. "-enable-signed-cert-timestamps",
  2904. "-expect-signed-cert-timestamps",
  2905. base64.StdEncoding.EncodeToString(testSCTList),
  2906. },
  2907. })
  2908. testCases = append(testCases, testCase{
  2909. testType: clientTest,
  2910. name: "ClientHelloPadding",
  2911. config: Config{
  2912. Bugs: ProtocolBugs{
  2913. RequireClientHelloSize: 512,
  2914. },
  2915. },
  2916. // This hostname just needs to be long enough to push the
  2917. // ClientHello into F5's danger zone between 256 and 511 bytes
  2918. // long.
  2919. flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
  2920. })
  2921. }
  2922. func addResumptionVersionTests() {
  2923. for _, sessionVers := range tlsVersions {
  2924. for _, resumeVers := range tlsVersions {
  2925. protocols := []protocol{tls}
  2926. if sessionVers.hasDTLS && resumeVers.hasDTLS {
  2927. protocols = append(protocols, dtls)
  2928. }
  2929. for _, protocol := range protocols {
  2930. suffix := "-" + sessionVers.name + "-" + resumeVers.name
  2931. if protocol == dtls {
  2932. suffix += "-DTLS"
  2933. }
  2934. if sessionVers.version == resumeVers.version {
  2935. testCases = append(testCases, testCase{
  2936. protocol: protocol,
  2937. name: "Resume-Client" + suffix,
  2938. resumeSession: true,
  2939. config: Config{
  2940. MaxVersion: sessionVers.version,
  2941. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2942. },
  2943. expectedVersion: sessionVers.version,
  2944. expectedResumeVersion: resumeVers.version,
  2945. })
  2946. } else {
  2947. testCases = append(testCases, testCase{
  2948. protocol: protocol,
  2949. name: "Resume-Client-Mismatch" + suffix,
  2950. resumeSession: true,
  2951. config: Config{
  2952. MaxVersion: sessionVers.version,
  2953. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2954. },
  2955. expectedVersion: sessionVers.version,
  2956. resumeConfig: &Config{
  2957. MaxVersion: resumeVers.version,
  2958. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2959. Bugs: ProtocolBugs{
  2960. AllowSessionVersionMismatch: true,
  2961. },
  2962. },
  2963. expectedResumeVersion: resumeVers.version,
  2964. shouldFail: true,
  2965. expectedError: ":OLD_SESSION_VERSION_NOT_RETURNED:",
  2966. })
  2967. }
  2968. testCases = append(testCases, testCase{
  2969. protocol: protocol,
  2970. name: "Resume-Client-NoResume" + suffix,
  2971. resumeSession: true,
  2972. config: Config{
  2973. MaxVersion: sessionVers.version,
  2974. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2975. },
  2976. expectedVersion: sessionVers.version,
  2977. resumeConfig: &Config{
  2978. MaxVersion: resumeVers.version,
  2979. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2980. },
  2981. newSessionsOnResume: true,
  2982. expectResumeRejected: true,
  2983. expectedResumeVersion: resumeVers.version,
  2984. })
  2985. testCases = append(testCases, testCase{
  2986. protocol: protocol,
  2987. testType: serverTest,
  2988. name: "Resume-Server" + suffix,
  2989. resumeSession: true,
  2990. config: Config{
  2991. MaxVersion: sessionVers.version,
  2992. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2993. },
  2994. expectedVersion: sessionVers.version,
  2995. expectResumeRejected: sessionVers.version != resumeVers.version,
  2996. resumeConfig: &Config{
  2997. MaxVersion: resumeVers.version,
  2998. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
  2999. },
  3000. expectedResumeVersion: resumeVers.version,
  3001. })
  3002. }
  3003. }
  3004. }
  3005. testCases = append(testCases, testCase{
  3006. name: "Resume-Client-CipherMismatch",
  3007. resumeSession: true,
  3008. config: Config{
  3009. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  3010. },
  3011. resumeConfig: &Config{
  3012. CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
  3013. Bugs: ProtocolBugs{
  3014. SendCipherSuite: TLS_RSA_WITH_AES_128_CBC_SHA,
  3015. },
  3016. },
  3017. shouldFail: true,
  3018. expectedError: ":OLD_SESSION_CIPHER_NOT_RETURNED:",
  3019. })
  3020. }
  3021. func addRenegotiationTests() {
  3022. // Servers cannot renegotiate.
  3023. testCases = append(testCases, testCase{
  3024. testType: serverTest,
  3025. name: "Renegotiate-Server-Forbidden",
  3026. renegotiate: true,
  3027. flags: []string{"-reject-peer-renegotiations"},
  3028. shouldFail: true,
  3029. expectedError: ":NO_RENEGOTIATION:",
  3030. expectedLocalError: "remote error: no renegotiation",
  3031. })
  3032. // The server shouldn't echo the renegotiation extension unless
  3033. // requested by the client.
  3034. testCases = append(testCases, testCase{
  3035. testType: serverTest,
  3036. name: "Renegotiate-Server-NoExt",
  3037. config: Config{
  3038. Bugs: ProtocolBugs{
  3039. NoRenegotiationInfo: true,
  3040. RequireRenegotiationInfo: true,
  3041. },
  3042. },
  3043. shouldFail: true,
  3044. expectedLocalError: "renegotiation extension missing",
  3045. })
  3046. // The renegotiation SCSV should be sufficient for the server to echo
  3047. // the extension.
  3048. testCases = append(testCases, testCase{
  3049. testType: serverTest,
  3050. name: "Renegotiate-Server-NoExt-SCSV",
  3051. config: Config{
  3052. Bugs: ProtocolBugs{
  3053. NoRenegotiationInfo: true,
  3054. SendRenegotiationSCSV: true,
  3055. RequireRenegotiationInfo: true,
  3056. },
  3057. },
  3058. })
  3059. testCases = append(testCases, testCase{
  3060. name: "Renegotiate-Client",
  3061. config: Config{
  3062. Bugs: ProtocolBugs{
  3063. FailIfResumeOnRenego: true,
  3064. },
  3065. },
  3066. renegotiate: true,
  3067. })
  3068. testCases = append(testCases, testCase{
  3069. name: "Renegotiate-Client-EmptyExt",
  3070. renegotiate: true,
  3071. config: Config{
  3072. Bugs: ProtocolBugs{
  3073. EmptyRenegotiationInfo: true,
  3074. },
  3075. },
  3076. shouldFail: true,
  3077. expectedError: ":RENEGOTIATION_MISMATCH:",
  3078. })
  3079. testCases = append(testCases, testCase{
  3080. name: "Renegotiate-Client-BadExt",
  3081. renegotiate: true,
  3082. config: Config{
  3083. Bugs: ProtocolBugs{
  3084. BadRenegotiationInfo: true,
  3085. },
  3086. },
  3087. shouldFail: true,
  3088. expectedError: ":RENEGOTIATION_MISMATCH:",
  3089. })
  3090. testCases = append(testCases, testCase{
  3091. name: "Renegotiate-Client-NoExt",
  3092. config: Config{
  3093. Bugs: ProtocolBugs{
  3094. NoRenegotiationInfo: true,
  3095. },
  3096. },
  3097. shouldFail: true,
  3098. expectedError: ":UNSAFE_LEGACY_RENEGOTIATION_DISABLED:",
  3099. flags: []string{"-no-legacy-server-connect"},
  3100. })
  3101. testCases = append(testCases, testCase{
  3102. name: "Renegotiate-Client-NoExt-Allowed",
  3103. renegotiate: true,
  3104. config: Config{
  3105. Bugs: ProtocolBugs{
  3106. NoRenegotiationInfo: true,
  3107. },
  3108. },
  3109. })
  3110. testCases = append(testCases, testCase{
  3111. name: "Renegotiate-Client-SwitchCiphers",
  3112. renegotiate: true,
  3113. config: Config{
  3114. CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  3115. },
  3116. renegotiateCiphers: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3117. })
  3118. testCases = append(testCases, testCase{
  3119. name: "Renegotiate-Client-SwitchCiphers2",
  3120. renegotiate: true,
  3121. config: Config{
  3122. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3123. },
  3124. renegotiateCiphers: []uint16{TLS_RSA_WITH_RC4_128_SHA},
  3125. })
  3126. testCases = append(testCases, testCase{
  3127. name: "Renegotiate-Client-Forbidden",
  3128. renegotiate: true,
  3129. flags: []string{"-reject-peer-renegotiations"},
  3130. shouldFail: true,
  3131. expectedError: ":NO_RENEGOTIATION:",
  3132. expectedLocalError: "remote error: no renegotiation",
  3133. })
  3134. testCases = append(testCases, testCase{
  3135. name: "Renegotiate-SameClientVersion",
  3136. renegotiate: true,
  3137. config: Config{
  3138. MaxVersion: VersionTLS10,
  3139. Bugs: ProtocolBugs{
  3140. RequireSameRenegoClientVersion: true,
  3141. },
  3142. },
  3143. })
  3144. testCases = append(testCases, testCase{
  3145. name: "Renegotiate-FalseStart",
  3146. renegotiate: true,
  3147. config: Config{
  3148. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3149. NextProtos: []string{"foo"},
  3150. },
  3151. flags: []string{
  3152. "-false-start",
  3153. "-select-next-proto", "foo",
  3154. },
  3155. shimWritesFirst: true,
  3156. })
  3157. }
  3158. func addDTLSReplayTests() {
  3159. // Test that sequence number replays are detected.
  3160. testCases = append(testCases, testCase{
  3161. protocol: dtls,
  3162. name: "DTLS-Replay",
  3163. messageCount: 200,
  3164. replayWrites: true,
  3165. })
  3166. // Test the incoming sequence number skipping by values larger
  3167. // than the retransmit window.
  3168. testCases = append(testCases, testCase{
  3169. protocol: dtls,
  3170. name: "DTLS-Replay-LargeGaps",
  3171. config: Config{
  3172. Bugs: ProtocolBugs{
  3173. SequenceNumberMapping: func(in uint64) uint64 {
  3174. return in * 127
  3175. },
  3176. },
  3177. },
  3178. messageCount: 200,
  3179. replayWrites: true,
  3180. })
  3181. // Test the incoming sequence number changing non-monotonically.
  3182. testCases = append(testCases, testCase{
  3183. protocol: dtls,
  3184. name: "DTLS-Replay-NonMonotonic",
  3185. config: Config{
  3186. Bugs: ProtocolBugs{
  3187. SequenceNumberMapping: func(in uint64) uint64 {
  3188. return in ^ 31
  3189. },
  3190. },
  3191. },
  3192. messageCount: 200,
  3193. replayWrites: true,
  3194. })
  3195. }
  3196. var testHashes = []struct {
  3197. name string
  3198. id uint8
  3199. }{
  3200. {"SHA1", hashSHA1},
  3201. {"SHA224", hashSHA224},
  3202. {"SHA256", hashSHA256},
  3203. {"SHA384", hashSHA384},
  3204. {"SHA512", hashSHA512},
  3205. }
  3206. func addSigningHashTests() {
  3207. // Make sure each hash works. Include some fake hashes in the list and
  3208. // ensure they're ignored.
  3209. for _, hash := range testHashes {
  3210. testCases = append(testCases, testCase{
  3211. name: "SigningHash-ClientAuth-" + hash.name,
  3212. config: Config{
  3213. ClientAuth: RequireAnyClientCert,
  3214. SignatureAndHashes: []signatureAndHash{
  3215. {signatureRSA, 42},
  3216. {signatureRSA, hash.id},
  3217. {signatureRSA, 255},
  3218. },
  3219. },
  3220. flags: []string{
  3221. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  3222. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  3223. },
  3224. })
  3225. testCases = append(testCases, testCase{
  3226. testType: serverTest,
  3227. name: "SigningHash-ServerKeyExchange-Sign-" + hash.name,
  3228. config: Config{
  3229. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3230. SignatureAndHashes: []signatureAndHash{
  3231. {signatureRSA, 42},
  3232. {signatureRSA, hash.id},
  3233. {signatureRSA, 255},
  3234. },
  3235. },
  3236. })
  3237. }
  3238. // Test that hash resolution takes the signature type into account.
  3239. testCases = append(testCases, testCase{
  3240. name: "SigningHash-ClientAuth-SignatureType",
  3241. config: Config{
  3242. ClientAuth: RequireAnyClientCert,
  3243. SignatureAndHashes: []signatureAndHash{
  3244. {signatureECDSA, hashSHA512},
  3245. {signatureRSA, hashSHA384},
  3246. {signatureECDSA, hashSHA1},
  3247. },
  3248. },
  3249. flags: []string{
  3250. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  3251. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  3252. },
  3253. })
  3254. testCases = append(testCases, testCase{
  3255. testType: serverTest,
  3256. name: "SigningHash-ServerKeyExchange-SignatureType",
  3257. config: Config{
  3258. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3259. SignatureAndHashes: []signatureAndHash{
  3260. {signatureECDSA, hashSHA512},
  3261. {signatureRSA, hashSHA384},
  3262. {signatureECDSA, hashSHA1},
  3263. },
  3264. },
  3265. })
  3266. // Test that, if the list is missing, the peer falls back to SHA-1.
  3267. testCases = append(testCases, testCase{
  3268. name: "SigningHash-ClientAuth-Fallback",
  3269. config: Config{
  3270. ClientAuth: RequireAnyClientCert,
  3271. SignatureAndHashes: []signatureAndHash{
  3272. {signatureRSA, hashSHA1},
  3273. },
  3274. Bugs: ProtocolBugs{
  3275. NoSignatureAndHashes: true,
  3276. },
  3277. },
  3278. flags: []string{
  3279. "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
  3280. "-key-file", path.Join(*resourceDir, rsaKeyFile),
  3281. },
  3282. })
  3283. testCases = append(testCases, testCase{
  3284. testType: serverTest,
  3285. name: "SigningHash-ServerKeyExchange-Fallback",
  3286. config: Config{
  3287. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3288. SignatureAndHashes: []signatureAndHash{
  3289. {signatureRSA, hashSHA1},
  3290. },
  3291. Bugs: ProtocolBugs{
  3292. NoSignatureAndHashes: true,
  3293. },
  3294. },
  3295. })
  3296. // Test that hash preferences are enforced. BoringSSL defaults to
  3297. // rejecting MD5 signatures.
  3298. testCases = append(testCases, testCase{
  3299. testType: serverTest,
  3300. name: "SigningHash-ClientAuth-Enforced",
  3301. config: Config{
  3302. Certificates: []Certificate{rsaCertificate},
  3303. SignatureAndHashes: []signatureAndHash{
  3304. {signatureRSA, hashMD5},
  3305. // Advertise SHA-1 so the handshake will
  3306. // proceed, but the shim's preferences will be
  3307. // ignored in CertificateVerify generation, so
  3308. // MD5 will be chosen.
  3309. {signatureRSA, hashSHA1},
  3310. },
  3311. Bugs: ProtocolBugs{
  3312. IgnorePeerSignatureAlgorithmPreferences: true,
  3313. },
  3314. },
  3315. flags: []string{"-require-any-client-certificate"},
  3316. shouldFail: true,
  3317. expectedError: ":WRONG_SIGNATURE_TYPE:",
  3318. })
  3319. testCases = append(testCases, testCase{
  3320. name: "SigningHash-ServerKeyExchange-Enforced",
  3321. config: Config{
  3322. CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
  3323. SignatureAndHashes: []signatureAndHash{
  3324. {signatureRSA, hashMD5},
  3325. },
  3326. Bugs: ProtocolBugs{
  3327. IgnorePeerSignatureAlgorithmPreferences: true,
  3328. },
  3329. },
  3330. shouldFail: true,
  3331. expectedError: ":WRONG_SIGNATURE_TYPE:",
  3332. })
  3333. }
  3334. // timeouts is the retransmit schedule for BoringSSL. It doubles and
  3335. // caps at 60 seconds. On the 13th timeout, it gives up.
  3336. var timeouts = []time.Duration{
  3337. 1 * time.Second,
  3338. 2 * time.Second,
  3339. 4 * time.Second,
  3340. 8 * time.Second,
  3341. 16 * time.Second,
  3342. 32 * time.Second,
  3343. 60 * time.Second,
  3344. 60 * time.Second,
  3345. 60 * time.Second,
  3346. 60 * time.Second,
  3347. 60 * time.Second,
  3348. 60 * time.Second,
  3349. 60 * time.Second,
  3350. }
  3351. func addDTLSRetransmitTests() {
  3352. // Test that this is indeed the timeout schedule. Stress all
  3353. // four patterns of handshake.
  3354. for i := 1; i < len(timeouts); i++ {
  3355. number := strconv.Itoa(i)
  3356. testCases = append(testCases, testCase{
  3357. protocol: dtls,
  3358. name: "DTLS-Retransmit-Client-" + number,
  3359. config: Config{
  3360. Bugs: ProtocolBugs{
  3361. TimeoutSchedule: timeouts[:i],
  3362. },
  3363. },
  3364. resumeSession: true,
  3365. flags: []string{"-async"},
  3366. })
  3367. testCases = append(testCases, testCase{
  3368. protocol: dtls,
  3369. testType: serverTest,
  3370. name: "DTLS-Retransmit-Server-" + number,
  3371. config: Config{
  3372. Bugs: ProtocolBugs{
  3373. TimeoutSchedule: timeouts[:i],
  3374. },
  3375. },
  3376. resumeSession: true,
  3377. flags: []string{"-async"},
  3378. })
  3379. }
  3380. // Test that exceeding the timeout schedule hits a read
  3381. // timeout.
  3382. testCases = append(testCases, testCase{
  3383. protocol: dtls,
  3384. name: "DTLS-Retransmit-Timeout",
  3385. config: Config{
  3386. Bugs: ProtocolBugs{
  3387. TimeoutSchedule: timeouts,
  3388. },
  3389. },
  3390. resumeSession: true,
  3391. flags: []string{"-async"},
  3392. shouldFail: true,
  3393. expectedError: ":READ_TIMEOUT_EXPIRED:",
  3394. })
  3395. // Test that timeout handling has a fudge factor, due to API
  3396. // problems.
  3397. testCases = append(testCases, testCase{
  3398. protocol: dtls,
  3399. name: "DTLS-Retransmit-Fudge",
  3400. config: Config{
  3401. Bugs: ProtocolBugs{
  3402. TimeoutSchedule: []time.Duration{
  3403. timeouts[0] - 10*time.Millisecond,
  3404. },
  3405. },
  3406. },
  3407. resumeSession: true,
  3408. flags: []string{"-async"},
  3409. })
  3410. // Test that the final Finished retransmitting isn't
  3411. // duplicated if the peer badly fragments everything.
  3412. testCases = append(testCases, testCase{
  3413. testType: serverTest,
  3414. protocol: dtls,
  3415. name: "DTLS-Retransmit-Fragmented",
  3416. config: Config{
  3417. Bugs: ProtocolBugs{
  3418. TimeoutSchedule: []time.Duration{timeouts[0]},
  3419. MaxHandshakeRecordLength: 2,
  3420. },
  3421. },
  3422. flags: []string{"-async"},
  3423. })
  3424. }
  3425. func addExportKeyingMaterialTests() {
  3426. for _, vers := range tlsVersions {
  3427. if vers.version == VersionSSL30 {
  3428. continue
  3429. }
  3430. testCases = append(testCases, testCase{
  3431. name: "ExportKeyingMaterial-" + vers.name,
  3432. config: Config{
  3433. MaxVersion: vers.version,
  3434. },
  3435. exportKeyingMaterial: 1024,
  3436. exportLabel: "label",
  3437. exportContext: "context",
  3438. useExportContext: true,
  3439. })
  3440. testCases = append(testCases, testCase{
  3441. name: "ExportKeyingMaterial-NoContext-" + vers.name,
  3442. config: Config{
  3443. MaxVersion: vers.version,
  3444. },
  3445. exportKeyingMaterial: 1024,
  3446. })
  3447. testCases = append(testCases, testCase{
  3448. name: "ExportKeyingMaterial-EmptyContext-" + vers.name,
  3449. config: Config{
  3450. MaxVersion: vers.version,
  3451. },
  3452. exportKeyingMaterial: 1024,
  3453. useExportContext: true,
  3454. })
  3455. testCases = append(testCases, testCase{
  3456. name: "ExportKeyingMaterial-Small-" + vers.name,
  3457. config: Config{
  3458. MaxVersion: vers.version,
  3459. },
  3460. exportKeyingMaterial: 1,
  3461. exportLabel: "label",
  3462. exportContext: "context",
  3463. useExportContext: true,
  3464. })
  3465. }
  3466. testCases = append(testCases, testCase{
  3467. name: "ExportKeyingMaterial-SSL3",
  3468. config: Config{
  3469. MaxVersion: VersionSSL30,
  3470. },
  3471. exportKeyingMaterial: 1024,
  3472. exportLabel: "label",
  3473. exportContext: "context",
  3474. useExportContext: true,
  3475. shouldFail: true,
  3476. expectedError: "failed to export keying material",
  3477. })
  3478. }
  3479. func addTLSUniqueTests() {
  3480. for _, isClient := range []bool{false, true} {
  3481. for _, isResumption := range []bool{false, true} {
  3482. for _, hasEMS := range []bool{false, true} {
  3483. var suffix string
  3484. if isResumption {
  3485. suffix = "Resume-"
  3486. } else {
  3487. suffix = "Full-"
  3488. }
  3489. if hasEMS {
  3490. suffix += "EMS-"
  3491. } else {
  3492. suffix += "NoEMS-"
  3493. }
  3494. if isClient {
  3495. suffix += "Client"
  3496. } else {
  3497. suffix += "Server"
  3498. }
  3499. test := testCase{
  3500. name: "TLSUnique-" + suffix,
  3501. testTLSUnique: true,
  3502. config: Config{
  3503. Bugs: ProtocolBugs{
  3504. NoExtendedMasterSecret: !hasEMS,
  3505. },
  3506. },
  3507. }
  3508. if isResumption {
  3509. test.resumeSession = true
  3510. test.resumeConfig = &Config{
  3511. Bugs: ProtocolBugs{
  3512. NoExtendedMasterSecret: !hasEMS,
  3513. },
  3514. }
  3515. }
  3516. if isResumption && !hasEMS {
  3517. test.shouldFail = true
  3518. test.expectedError = "failed to get tls-unique"
  3519. }
  3520. testCases = append(testCases, test)
  3521. }
  3522. }
  3523. }
  3524. }
  3525. func addCustomExtensionTests() {
  3526. expectedContents := "custom extension"
  3527. emptyString := ""
  3528. for _, isClient := range []bool{false, true} {
  3529. suffix := "Server"
  3530. flag := "-enable-server-custom-extension"
  3531. testType := serverTest
  3532. if isClient {
  3533. suffix = "Client"
  3534. flag = "-enable-client-custom-extension"
  3535. testType = clientTest
  3536. }
  3537. testCases = append(testCases, testCase{
  3538. testType: testType,
  3539. name: "CustomExtensions-" + suffix,
  3540. config: Config{
  3541. Bugs: ProtocolBugs{
  3542. CustomExtension: expectedContents,
  3543. ExpectedCustomExtension: &expectedContents,
  3544. },
  3545. },
  3546. flags: []string{flag},
  3547. })
  3548. // If the parse callback fails, the handshake should also fail.
  3549. testCases = append(testCases, testCase{
  3550. testType: testType,
  3551. name: "CustomExtensions-ParseError-" + suffix,
  3552. config: Config{
  3553. Bugs: ProtocolBugs{
  3554. CustomExtension: expectedContents + "foo",
  3555. ExpectedCustomExtension: &expectedContents,
  3556. },
  3557. },
  3558. flags: []string{flag},
  3559. shouldFail: true,
  3560. expectedError: ":CUSTOM_EXTENSION_ERROR:",
  3561. })
  3562. // If the add callback fails, the handshake should also fail.
  3563. testCases = append(testCases, testCase{
  3564. testType: testType,
  3565. name: "CustomExtensions-FailAdd-" + suffix,
  3566. config: Config{
  3567. Bugs: ProtocolBugs{
  3568. CustomExtension: expectedContents,
  3569. ExpectedCustomExtension: &expectedContents,
  3570. },
  3571. },
  3572. flags: []string{flag, "-custom-extension-fail-add"},
  3573. shouldFail: true,
  3574. expectedError: ":CUSTOM_EXTENSION_ERROR:",
  3575. })
  3576. // If the add callback returns zero, no extension should be
  3577. // added.
  3578. skipCustomExtension := expectedContents
  3579. if isClient {
  3580. // For the case where the client skips sending the
  3581. // custom extension, the server must not “echo” it.
  3582. skipCustomExtension = ""
  3583. }
  3584. testCases = append(testCases, testCase{
  3585. testType: testType,
  3586. name: "CustomExtensions-Skip-" + suffix,
  3587. config: Config{
  3588. Bugs: ProtocolBugs{
  3589. CustomExtension: skipCustomExtension,
  3590. ExpectedCustomExtension: &emptyString,
  3591. },
  3592. },
  3593. flags: []string{flag, "-custom-extension-skip"},
  3594. })
  3595. }
  3596. // The custom extension add callback should not be called if the client
  3597. // doesn't send the extension.
  3598. testCases = append(testCases, testCase{
  3599. testType: serverTest,
  3600. name: "CustomExtensions-NotCalled-Server",
  3601. config: Config{
  3602. Bugs: ProtocolBugs{
  3603. ExpectedCustomExtension: &emptyString,
  3604. },
  3605. },
  3606. flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
  3607. })
  3608. }
  3609. func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
  3610. defer wg.Done()
  3611. for test := range c {
  3612. var err error
  3613. if *mallocTest < 0 {
  3614. statusChan <- statusMsg{test: test, started: true}
  3615. err = runTest(test, shimPath, -1)
  3616. } else {
  3617. for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
  3618. statusChan <- statusMsg{test: test, started: true}
  3619. if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs {
  3620. if err != nil {
  3621. fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
  3622. }
  3623. break
  3624. }
  3625. }
  3626. }
  3627. statusChan <- statusMsg{test: test, err: err}
  3628. }
  3629. }
  3630. type statusMsg struct {
  3631. test *testCase
  3632. started bool
  3633. err error
  3634. }
  3635. func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total int) {
  3636. var started, done, failed, lineLen int
  3637. testOutput := newTestOutput()
  3638. for msg := range statusChan {
  3639. if !*pipe {
  3640. // Erase the previous status line.
  3641. var erase string
  3642. for i := 0; i < lineLen; i++ {
  3643. erase += "\b \b"
  3644. }
  3645. fmt.Print(erase)
  3646. }
  3647. if msg.started {
  3648. started++
  3649. } else {
  3650. done++
  3651. if msg.err != nil {
  3652. fmt.Printf("FAILED (%s)\n%s\n", msg.test.name, msg.err)
  3653. failed++
  3654. testOutput.addResult(msg.test.name, "FAIL")
  3655. } else {
  3656. if *pipe {
  3657. // Print each test instead of a status line.
  3658. fmt.Printf("PASSED (%s)\n", msg.test.name)
  3659. }
  3660. testOutput.addResult(msg.test.name, "PASS")
  3661. }
  3662. }
  3663. if !*pipe {
  3664. // Print a new status line.
  3665. line := fmt.Sprintf("%d/%d/%d/%d", failed, done, started, total)
  3666. lineLen = len(line)
  3667. os.Stdout.WriteString(line)
  3668. }
  3669. }
  3670. doneChan <- testOutput
  3671. }
  3672. func main() {
  3673. flag.Parse()
  3674. *resourceDir = path.Clean(*resourceDir)
  3675. addBasicTests()
  3676. addCipherSuiteTests()
  3677. addBadECDSASignatureTests()
  3678. addCBCPaddingTests()
  3679. addCBCSplittingTests()
  3680. addClientAuthTests()
  3681. addDDoSCallbackTests()
  3682. addVersionNegotiationTests()
  3683. addMinimumVersionTests()
  3684. addD5BugTests()
  3685. addExtensionTests()
  3686. addResumptionVersionTests()
  3687. addExtendedMasterSecretTests()
  3688. addRenegotiationTests()
  3689. addDTLSReplayTests()
  3690. addSigningHashTests()
  3691. addDTLSRetransmitTests()
  3692. addExportKeyingMaterialTests()
  3693. addTLSUniqueTests()
  3694. addCustomExtensionTests()
  3695. for _, async := range []bool{false, true} {
  3696. for _, splitHandshake := range []bool{false, true} {
  3697. for _, protocol := range []protocol{tls, dtls} {
  3698. addStateMachineCoverageTests(async, splitHandshake, protocol)
  3699. }
  3700. }
  3701. }
  3702. var wg sync.WaitGroup
  3703. statusChan := make(chan statusMsg, *numWorkers)
  3704. testChan := make(chan *testCase, *numWorkers)
  3705. doneChan := make(chan *testOutput)
  3706. go statusPrinter(doneChan, statusChan, len(testCases))
  3707. for i := 0; i < *numWorkers; i++ {
  3708. wg.Add(1)
  3709. go worker(statusChan, testChan, *shimPath, &wg)
  3710. }
  3711. for i := range testCases {
  3712. if len(*testToRun) == 0 || *testToRun == testCases[i].name {
  3713. testChan <- &testCases[i]
  3714. }
  3715. }
  3716. close(testChan)
  3717. wg.Wait()
  3718. close(statusChan)
  3719. testOutput := <-doneChan
  3720. fmt.Printf("\n")
  3721. if *jsonOutput != "" {
  3722. if err := testOutput.writeTo(*jsonOutput); err != nil {
  3723. fmt.Fprintf(os.Stderr, "Error: %s\n", err)
  3724. }
  3725. }
  3726. if !testOutput.allPassed {
  3727. os.Exit(1)
  3728. }
  3729. }