You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

s3_both.cc 23 KiB

Move libssl's internals into the bssl namespace. This is horrible, but everything else I tried was worse. The goal with this CL is to take the extern "C" out of ssl/internal.h and move most symbols to namespace bssl, so we can start using C++ helpers and destructors without worry. Complications: - Public API functions must be extern "C" and match their declaration in ssl.h, which is unnamespaced. C++ really does not want you to interleave namespaced and unnamespaced things. One can actually write a namespaced extern "C" function, but this means, from C++'s perspective, the function is namespaced. Trying to namespace the public header would worked but ended up too deep a rabbithole. - Our STACK_OF macros do not work right in namespaces. - The typedefs for our exposed but opaque types are visible in the header files and copied into consuming projects as forward declarations. We ultimately want to give SSL a destructor, but clobbering an unnamespaced ssl_st::~ssl_st seems bad manners. - MSVC complains about ambiguous names if one typedefs SSL to bssl::SSL. This CL opts for: - ssl/*.cc must begin with #define BORINGSSL_INTERNAL_CXX_TYPES. This informs the public headers to create forward declarations which are compatible with our namespaces. - For now, C++-defined type FOO ends up at bssl::FOO with a typedef outside. Later I imagine we'll rename many of them. - Internal functions get namespace bssl, so we stop worrying about stomping the tls1_prf symbol. Exported C functions are stuck as they are. Rather than try anything weird, bite the bullet and reorder files which have a mix of public and private functions. I expect that over time, the public functions will become fairly small as we move logic to more idiomatic C++. Files without any public C functions can just be written normally. - To avoid MSVC troubles, some bssl types are renamed to CPlusPlusStyle in advance of them being made idiomatic C++. Bug: 132 Change-Id: Ic931895e117c38b14ff8d6e5a273e868796c7581 Reviewed-on: https://boringssl-review.googlesource.com/18124 Reviewed-by: David Benjamin <davidben@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
Don't use the buffer BIO in TLS. On the TLS side, we introduce a running buffer of ciphertext. Queuing up pending data consists of encrypting the record into the buffer. This effectively reimplements what the buffer BIO was doing previously, but this resizes to fit the whole flight. As part of this, rename all the functions to add to the pending flight to be more uniform. This CL proposes "add_foo" to add to the pending flight and "flush_flight" to drain it. We add an add_alert hook for alerts but, for now, only the SSL 3.0 warning alert (sent mid-handshake) uses this mechanism. Later work will push this down to the rest of the write path so closure alerts use it too, as in DTLS. The intended end state is that all the ssl_buffer.c and wpend_ret logic will only be used for application data and eventually optionally replaced by the in-place API, while all "incidental" data will be handled internally. For now, the two buffers are mutually exclusive. Moving closure alerts to "incidentals" will change this, but flushing application data early is tricky due to wpend_ret. (If we call ssl_write_buffer_flush, do_ssl3_write doesn't realize it still has a wpend_ret to replay.) That too is all left alone in this change. To keep the diff down, write_message is retained for now and will be removed from the state machines in a follow-up change. BUG=72 Change-Id: Ibce882f5f7196880648f25d5005322ca4055c71d Reviewed-on: https://boringssl-review.googlesource.com/13224 Reviewed-by: Adam Langley <agl@google.com>
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  2. * All rights reserved.
  3. *
  4. * This package is an SSL implementation written
  5. * by Eric Young (eay@cryptsoft.com).
  6. * The implementation was written so as to conform with Netscapes SSL.
  7. *
  8. * This library is free for commercial and non-commercial use as long as
  9. * the following conditions are aheared to. The following conditions
  10. * apply to all code found in this distribution, be it the RC4, RSA,
  11. * lhash, DES, etc., code; not just the SSL code. The SSL documentation
  12. * included with this distribution is covered by the same copyright terms
  13. * except that the holder is Tim Hudson (tjh@cryptsoft.com).
  14. *
  15. * Copyright remains Eric Young's, and as such any Copyright notices in
  16. * the code are not to be removed.
  17. * If this package is used in a product, Eric Young should be given attribution
  18. * as the author of the parts of the library used.
  19. * This can be in the form of a textual message at program startup or
  20. * in documentation (online or textual) provided with the package.
  21. *
  22. * Redistribution and use in source and binary forms, with or without
  23. * modification, are permitted provided that the following conditions
  24. * are met:
  25. * 1. Redistributions of source code must retain the copyright
  26. * notice, this list of conditions and the following disclaimer.
  27. * 2. Redistributions in binary form must reproduce the above copyright
  28. * notice, this list of conditions and the following disclaimer in the
  29. * documentation and/or other materials provided with the distribution.
  30. * 3. All advertising materials mentioning features or use of this software
  31. * must display the following acknowledgement:
  32. * "This product includes cryptographic software written by
  33. * Eric Young (eay@cryptsoft.com)"
  34. * The word 'cryptographic' can be left out if the rouines from the library
  35. * being used are not cryptographic related :-).
  36. * 4. If you include any Windows specific code (or a derivative thereof) from
  37. * the apps directory (application code) you must include an acknowledgement:
  38. * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
  39. *
  40. * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  41. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  42. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  43. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  44. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  45. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  46. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  47. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  48. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  49. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  50. * SUCH DAMAGE.
  51. *
  52. * The licence and distribution terms for any publically available version or
  53. * derivative of this code cannot be changed. i.e. this code cannot simply be
  54. * copied and put under another distribution licence
  55. * [including the GNU Public Licence.]
  56. */
  57. /* ====================================================================
  58. * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
  59. *
  60. * Redistribution and use in source and binary forms, with or without
  61. * modification, are permitted provided that the following conditions
  62. * are met:
  63. *
  64. * 1. Redistributions of source code must retain the above copyright
  65. * notice, this list of conditions and the following disclaimer.
  66. *
  67. * 2. Redistributions in binary form must reproduce the above copyright
  68. * notice, this list of conditions and the following disclaimer in
  69. * the documentation and/or other materials provided with the
  70. * distribution.
  71. *
  72. * 3. All advertising materials mentioning features or use of this
  73. * software must display the following acknowledgment:
  74. * "This product includes software developed by the OpenSSL Project
  75. * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
  76. *
  77. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  78. * endorse or promote products derived from this software without
  79. * prior written permission. For written permission, please contact
  80. * openssl-core@openssl.org.
  81. *
  82. * 5. Products derived from this software may not be called "OpenSSL"
  83. * nor may "OpenSSL" appear in their names without prior written
  84. * permission of the OpenSSL Project.
  85. *
  86. * 6. Redistributions of any form whatsoever must retain the following
  87. * acknowledgment:
  88. * "This product includes software developed by the OpenSSL Project
  89. * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
  90. *
  91. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  92. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  93. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  94. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  95. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  96. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  97. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  98. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  99. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  100. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  101. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  102. * OF THE POSSIBILITY OF SUCH DAMAGE.
  103. * ====================================================================
  104. *
  105. * This product includes cryptographic software written by Eric Young
  106. * (eay@cryptsoft.com). This product includes software written by Tim
  107. * Hudson (tjh@cryptsoft.com). */
  108. /* ====================================================================
  109. * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  110. * ECC cipher suite support in OpenSSL originally developed by
  111. * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
  112. #include <openssl/ssl.h>
  113. #include <assert.h>
  114. #include <limits.h>
  115. #include <string.h>
  116. #include <openssl/buf.h>
  117. #include <openssl/bytestring.h>
  118. #include <openssl/err.h>
  119. #include <openssl/evp.h>
  120. #include <openssl/mem.h>
  121. #include <openssl/md5.h>
  122. #include <openssl/nid.h>
  123. #include <openssl/rand.h>
  124. #include <openssl/sha.h>
  125. #include "../crypto/internal.h"
  126. #include "internal.h"
  127. BSSL_NAMESPACE_BEGIN
  128. static bool add_record_to_flight(SSL *ssl, uint8_t type,
  129. Span<const uint8_t> in) {
  130. // The caller should have flushed |pending_hs_data| first.
  131. assert(!ssl->s3->pending_hs_data);
  132. // We'll never add a flight while in the process of writing it out.
  133. assert(ssl->s3->pending_flight_offset == 0);
  134. if (ssl->s3->pending_flight == nullptr) {
  135. ssl->s3->pending_flight.reset(BUF_MEM_new());
  136. if (ssl->s3->pending_flight == nullptr) {
  137. return false;
  138. }
  139. }
  140. size_t max_out = in.size() + SSL_max_seal_overhead(ssl);
  141. size_t new_cap = ssl->s3->pending_flight->length + max_out;
  142. if (max_out < in.size() || new_cap < max_out) {
  143. OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
  144. return false;
  145. }
  146. size_t len;
  147. if (!BUF_MEM_reserve(ssl->s3->pending_flight.get(), new_cap) ||
  148. !tls_seal_record(ssl,
  149. (uint8_t *)ssl->s3->pending_flight->data +
  150. ssl->s3->pending_flight->length,
  151. &len, max_out, type, in.data(), in.size())) {
  152. return false;
  153. }
  154. ssl->s3->pending_flight->length += len;
  155. return true;
  156. }
  157. bool ssl3_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) {
  158. // Pick a modest size hint to save most of the |realloc| calls.
  159. if (!CBB_init(cbb, 64) ||
  160. !CBB_add_u8(cbb, type) ||
  161. !CBB_add_u24_length_prefixed(cbb, body)) {
  162. OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  163. CBB_cleanup(cbb);
  164. return false;
  165. }
  166. return true;
  167. }
  168. bool ssl3_finish_message(SSL *ssl, CBB *cbb, Array<uint8_t> *out_msg) {
  169. return CBBFinishArray(cbb, out_msg);
  170. }
  171. bool ssl3_add_message(SSL *ssl, Array<uint8_t> msg) {
  172. // Pack handshake data into the minimal number of records. This avoids
  173. // unnecessary encryption overhead, notably in TLS 1.3 where we send several
  174. // encrypted messages in a row. For now, we do not do this for the null
  175. // cipher. The benefit is smaller and there is a risk of breaking buggy
  176. // implementations. Additionally, we tie this to draft-28 as a sanity check,
  177. // on the off chance middleboxes have fixated on sizes.
  178. //
  179. // TODO(davidben): See if we can do this uniformly.
  180. Span<const uint8_t> rest = msg;
  181. if (ssl->ctx->quic_method == nullptr &&
  182. (ssl->s3->aead_write_ctx->is_null_cipher() ||
  183. ssl->version == TLS1_3_DRAFT23_VERSION)) {
  184. while (!rest.empty()) {
  185. Span<const uint8_t> chunk = rest.subspan(0, ssl->max_send_fragment);
  186. rest = rest.subspan(chunk.size());
  187. if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) {
  188. return false;
  189. }
  190. }
  191. } else {
  192. while (!rest.empty()) {
  193. // Flush if |pending_hs_data| is full.
  194. if (ssl->s3->pending_hs_data &&
  195. ssl->s3->pending_hs_data->length >= ssl->max_send_fragment &&
  196. !tls_flush_pending_hs_data(ssl)) {
  197. return false;
  198. }
  199. size_t pending_len =
  200. ssl->s3->pending_hs_data ? ssl->s3->pending_hs_data->length : 0;
  201. Span<const uint8_t> chunk =
  202. rest.subspan(0, ssl->max_send_fragment - pending_len);
  203. assert(!chunk.empty());
  204. rest = rest.subspan(chunk.size());
  205. if (!ssl->s3->pending_hs_data) {
  206. ssl->s3->pending_hs_data.reset(BUF_MEM_new());
  207. }
  208. if (!ssl->s3->pending_hs_data ||
  209. !BUF_MEM_append(ssl->s3->pending_hs_data.get(), chunk.data(),
  210. chunk.size())) {
  211. return false;
  212. }
  213. }
  214. }
  215. ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg);
  216. // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on
  217. // hs.
  218. if (ssl->s3->hs != NULL &&
  219. !ssl->s3->hs->transcript.Update(msg)) {
  220. return false;
  221. }
  222. return true;
  223. }
  224. bool tls_flush_pending_hs_data(SSL *ssl) {
  225. if (!ssl->s3->pending_hs_data || ssl->s3->pending_hs_data->length == 0) {
  226. return true;
  227. }
  228. UniquePtr<BUF_MEM> pending_hs_data = std::move(ssl->s3->pending_hs_data);
  229. auto data =
  230. MakeConstSpan(reinterpret_cast<const uint8_t *>(pending_hs_data->data),
  231. pending_hs_data->length);
  232. if (ssl->ctx->quic_method) {
  233. if (!ssl->ctx->quic_method->add_handshake_data(ssl, ssl->s3->write_level,
  234. data.data(), data.size())) {
  235. OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
  236. return false;
  237. }
  238. return true;
  239. }
  240. return add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, data);
  241. }
  242. bool ssl3_add_change_cipher_spec(SSL *ssl) {
  243. static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS};
  244. if (!tls_flush_pending_hs_data(ssl)) {
  245. return false;
  246. }
  247. if (!ssl->ctx->quic_method &&
  248. !add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC,
  249. kChangeCipherSpec)) {
  250. return false;
  251. }
  252. ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC,
  253. kChangeCipherSpec);
  254. return true;
  255. }
  256. int ssl3_flush_flight(SSL *ssl) {
  257. if (!tls_flush_pending_hs_data(ssl)) {
  258. return -1;
  259. }
  260. if (ssl->ctx->quic_method) {
  261. if (ssl->s3->write_shutdown != ssl_shutdown_none) {
  262. OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
  263. return -1;
  264. }
  265. if (!ssl->ctx->quic_method->flush_flight(ssl)) {
  266. OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
  267. return -1;
  268. }
  269. }
  270. if (ssl->s3->pending_flight == nullptr) {
  271. return 1;
  272. }
  273. if (ssl->s3->write_shutdown != ssl_shutdown_none) {
  274. OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
  275. return -1;
  276. }
  277. static_assert(INT_MAX <= 0xffffffff, "int is larger than 32 bits");
  278. if (ssl->s3->pending_flight->length > INT_MAX) {
  279. OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  280. return -1;
  281. }
  282. // If there is pending data in the write buffer, it must be flushed out before
  283. // any new data in pending_flight.
  284. if (!ssl->s3->write_buffer.empty()) {
  285. int ret = ssl_write_buffer_flush(ssl);
  286. if (ret <= 0) {
  287. ssl->s3->rwstate = SSL_WRITING;
  288. return ret;
  289. }
  290. }
  291. // Write the pending flight.
  292. while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) {
  293. int ret = BIO_write(
  294. ssl->wbio.get(),
  295. ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset,
  296. ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset);
  297. if (ret <= 0) {
  298. ssl->s3->rwstate = SSL_WRITING;
  299. return ret;
  300. }
  301. ssl->s3->pending_flight_offset += ret;
  302. }
  303. if (BIO_flush(ssl->wbio.get()) <= 0) {
  304. ssl->s3->rwstate = SSL_WRITING;
  305. return -1;
  306. }
  307. ssl->s3->pending_flight.reset();
  308. ssl->s3->pending_flight_offset = 0;
  309. return 1;
  310. }
  311. static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed,
  312. Span<const uint8_t> in) {
  313. *out_consumed = 0;
  314. assert(in.size() >= SSL3_RT_HEADER_LENGTH);
  315. // Determine the length of the V2ClientHello.
  316. size_t msg_length = ((in[0] & 0x7f) << 8) | in[1];
  317. if (msg_length > (1024 * 4)) {
  318. OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
  319. return ssl_open_record_error;
  320. }
  321. if (msg_length < SSL3_RT_HEADER_LENGTH - 2) {
  322. // Reject lengths that are too short early. We have already read
  323. // |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an
  324. // (invalid) V2ClientHello which would be shorter than that.
  325. OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH);
  326. return ssl_open_record_error;
  327. }
  328. // Ask for the remainder of the V2ClientHello.
  329. if (in.size() < 2 + msg_length) {
  330. *out_consumed = 2 + msg_length;
  331. return ssl_open_record_partial;
  332. }
  333. CBS v2_client_hello = CBS(ssl->s3->read_buffer.span().subspan(2, msg_length));
  334. // The V2ClientHello without the length is incorporated into the handshake
  335. // hash. This is only ever called at the start of the handshake, so hs is
  336. // guaranteed to be non-NULL.
  337. if (!ssl->s3->hs->transcript.Update(v2_client_hello)) {
  338. return ssl_open_record_error;
  339. }
  340. ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */,
  341. v2_client_hello);
  342. uint8_t msg_type;
  343. uint16_t version, cipher_spec_length, session_id_length, challenge_length;
  344. CBS cipher_specs, session_id, challenge;
  345. if (!CBS_get_u8(&v2_client_hello, &msg_type) ||
  346. !CBS_get_u16(&v2_client_hello, &version) ||
  347. !CBS_get_u16(&v2_client_hello, &cipher_spec_length) ||
  348. !CBS_get_u16(&v2_client_hello, &session_id_length) ||
  349. !CBS_get_u16(&v2_client_hello, &challenge_length) ||
  350. !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) ||
  351. !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) ||
  352. !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) ||
  353. CBS_len(&v2_client_hello) != 0) {
  354. OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
  355. return ssl_open_record_error;
  356. }
  357. // msg_type has already been checked.
  358. assert(msg_type == SSL2_MT_CLIENT_HELLO);
  359. // The client_random is the V2ClientHello challenge. Truncate or left-pad with
  360. // zeros as needed.
  361. size_t rand_len = CBS_len(&challenge);
  362. if (rand_len > SSL3_RANDOM_SIZE) {
  363. rand_len = SSL3_RANDOM_SIZE;
  364. }
  365. uint8_t random[SSL3_RANDOM_SIZE];
  366. OPENSSL_memset(random, 0, SSL3_RANDOM_SIZE);
  367. OPENSSL_memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge),
  368. rand_len);
  369. // Write out an equivalent TLS ClientHello directly to the handshake buffer.
  370. size_t max_v3_client_hello = SSL3_HM_HEADER_LENGTH + 2 /* version */ +
  371. SSL3_RANDOM_SIZE + 1 /* session ID length */ +
  372. 2 /* cipher list length */ +
  373. CBS_len(&cipher_specs) / 3 * 2 +
  374. 1 /* compression length */ + 1 /* compression */;
  375. ScopedCBB client_hello;
  376. CBB hello_body, cipher_suites;
  377. if (!ssl->s3->hs_buf) {
  378. ssl->s3->hs_buf.reset(BUF_MEM_new());
  379. }
  380. if (!ssl->s3->hs_buf ||
  381. !BUF_MEM_reserve(ssl->s3->hs_buf.get(), max_v3_client_hello) ||
  382. !CBB_init_fixed(client_hello.get(), (uint8_t *)ssl->s3->hs_buf->data,
  383. ssl->s3->hs_buf->max) ||
  384. !CBB_add_u8(client_hello.get(), SSL3_MT_CLIENT_HELLO) ||
  385. !CBB_add_u24_length_prefixed(client_hello.get(), &hello_body) ||
  386. !CBB_add_u16(&hello_body, version) ||
  387. !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) ||
  388. // No session id.
  389. !CBB_add_u8(&hello_body, 0) ||
  390. !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) {
  391. OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
  392. return ssl_open_record_error;
  393. }
  394. // Copy the cipher suites.
  395. while (CBS_len(&cipher_specs) > 0) {
  396. uint32_t cipher_spec;
  397. if (!CBS_get_u24(&cipher_specs, &cipher_spec)) {
  398. OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
  399. return ssl_open_record_error;
  400. }
  401. // Skip SSLv2 ciphers.
  402. if ((cipher_spec & 0xff0000) != 0) {
  403. continue;
  404. }
  405. if (!CBB_add_u16(&cipher_suites, cipher_spec)) {
  406. OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  407. return ssl_open_record_error;
  408. }
  409. }
  410. // Add the null compression scheme and finish.
  411. if (!CBB_add_u8(&hello_body, 1) ||
  412. !CBB_add_u8(&hello_body, 0) ||
  413. !CBB_finish(client_hello.get(), NULL, &ssl->s3->hs_buf->length)) {
  414. OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  415. return ssl_open_record_error;
  416. }
  417. *out_consumed = 2 + msg_length;
  418. ssl->s3->is_v2_hello = true;
  419. return ssl_open_record_success;
  420. }
  421. static bool parse_message(const SSL *ssl, SSLMessage *out,
  422. size_t *out_bytes_needed) {
  423. if (!ssl->s3->hs_buf) {
  424. *out_bytes_needed = 4;
  425. return false;
  426. }
  427. CBS cbs;
  428. uint32_t len;
  429. CBS_init(&cbs, reinterpret_cast<const uint8_t *>(ssl->s3->hs_buf->data),
  430. ssl->s3->hs_buf->length);
  431. if (!CBS_get_u8(&cbs, &out->type) ||
  432. !CBS_get_u24(&cbs, &len)) {
  433. *out_bytes_needed = 4;
  434. return false;
  435. }
  436. if (!CBS_get_bytes(&cbs, &out->body, len)) {
  437. *out_bytes_needed = 4 + len;
  438. return false;
  439. }
  440. CBS_init(&out->raw, reinterpret_cast<const uint8_t *>(ssl->s3->hs_buf->data),
  441. 4 + len);
  442. out->is_v2_hello = ssl->s3->is_v2_hello;
  443. return true;
  444. }
  445. bool ssl3_get_message(SSL *ssl, SSLMessage *out) {
  446. size_t unused;
  447. if (!parse_message(ssl, out, &unused)) {
  448. return false;
  449. }
  450. if (!ssl->s3->has_message) {
  451. if (!out->is_v2_hello) {
  452. ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw);
  453. }
  454. ssl->s3->has_message = true;
  455. }
  456. return true;
  457. }
  458. bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) {
  459. // If there is a complete message, the caller must have consumed it first.
  460. SSLMessage msg;
  461. size_t bytes_needed;
  462. if (parse_message(ssl, &msg, &bytes_needed)) {
  463. OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  464. *out_alert = SSL_AD_INTERNAL_ERROR;
  465. return false;
  466. }
  467. // Enforce the limit so the peer cannot force us to buffer 16MB.
  468. if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) {
  469. OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
  470. *out_alert = SSL_AD_ILLEGAL_PARAMETER;
  471. return false;
  472. }
  473. return true;
  474. }
  475. bool tls_has_unprocessed_handshake_data(const SSL *ssl) {
  476. size_t msg_len = 0;
  477. if (ssl->s3->has_message) {
  478. SSLMessage msg;
  479. size_t unused;
  480. if (parse_message(ssl, &msg, &unused)) {
  481. msg_len = CBS_len(&msg.raw);
  482. }
  483. }
  484. return ssl->s3->hs_buf && ssl->s3->hs_buf->length > msg_len;
  485. }
  486. bool tls_append_handshake_data(SSL *ssl, Span<const uint8_t> data) {
  487. // Re-create the handshake buffer if needed.
  488. if (!ssl->s3->hs_buf) {
  489. ssl->s3->hs_buf.reset(BUF_MEM_new());
  490. }
  491. return ssl->s3->hs_buf &&
  492. BUF_MEM_append(ssl->s3->hs_buf.get(), data.data(), data.size());
  493. }
  494. ssl_open_record_t ssl3_open_handshake(SSL *ssl, size_t *out_consumed,
  495. uint8_t *out_alert, Span<uint8_t> in) {
  496. *out_consumed = 0;
  497. // Bypass the record layer for the first message to handle V2ClientHello.
  498. if (ssl->server && !ssl->s3->v2_hello_done) {
  499. // Ask for the first 5 bytes, the size of the TLS record header. This is
  500. // sufficient to detect a V2ClientHello and ensures that we never read
  501. // beyond the first record.
  502. if (in.size() < SSL3_RT_HEADER_LENGTH) {
  503. *out_consumed = SSL3_RT_HEADER_LENGTH;
  504. return ssl_open_record_partial;
  505. }
  506. // Some dedicated error codes for protocol mixups should the application
  507. // wish to interpret them differently. (These do not overlap with
  508. // ClientHello or V2ClientHello.)
  509. const char *str = reinterpret_cast<const char*>(in.data());
  510. if (strncmp("GET ", str, 4) == 0 ||
  511. strncmp("POST ", str, 5) == 0 ||
  512. strncmp("HEAD ", str, 5) == 0 ||
  513. strncmp("PUT ", str, 4) == 0) {
  514. OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST);
  515. *out_alert = 0;
  516. return ssl_open_record_error;
  517. }
  518. if (strncmp("CONNE", str, 5) == 0) {
  519. OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST);
  520. *out_alert = 0;
  521. return ssl_open_record_error;
  522. }
  523. // Check for a V2ClientHello.
  524. if ((in[0] & 0x80) != 0 && in[2] == SSL2_MT_CLIENT_HELLO &&
  525. in[3] == SSL3_VERSION_MAJOR) {
  526. auto ret = read_v2_client_hello(ssl, out_consumed, in);
  527. if (ret == ssl_open_record_error) {
  528. *out_alert = 0;
  529. } else if (ret == ssl_open_record_success) {
  530. ssl->s3->v2_hello_done = true;
  531. }
  532. return ret;
  533. }
  534. ssl->s3->v2_hello_done = true;
  535. }
  536. uint8_t type;
  537. Span<uint8_t> body;
  538. auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in);
  539. if (ret != ssl_open_record_success) {
  540. return ret;
  541. }
  542. // WatchGuard's TLS 1.3 interference bug is very distinctive: they drop the
  543. // ServerHello and send the remaining encrypted application data records
  544. // as-is. This manifests as an application data record when we expect
  545. // handshake. Report a dedicated error code for this case.
  546. if (!ssl->server && type == SSL3_RT_APPLICATION_DATA &&
  547. ssl->s3->aead_read_ctx->is_null_cipher()) {
  548. OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE);
  549. *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
  550. return ssl_open_record_error;
  551. }
  552. if (type != SSL3_RT_HANDSHAKE) {
  553. OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
  554. *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
  555. return ssl_open_record_error;
  556. }
  557. // Append the entire handshake record to the buffer.
  558. if (!tls_append_handshake_data(ssl, body)) {
  559. *out_alert = SSL_AD_INTERNAL_ERROR;
  560. return ssl_open_record_error;
  561. }
  562. return ssl_open_record_success;
  563. }
  564. void ssl3_next_message(SSL *ssl) {
  565. SSLMessage msg;
  566. if (!ssl3_get_message(ssl, &msg) ||
  567. !ssl->s3->hs_buf ||
  568. ssl->s3->hs_buf->length < CBS_len(&msg.raw)) {
  569. assert(0);
  570. return;
  571. }
  572. OPENSSL_memmove(ssl->s3->hs_buf->data,
  573. ssl->s3->hs_buf->data + CBS_len(&msg.raw),
  574. ssl->s3->hs_buf->length - CBS_len(&msg.raw));
  575. ssl->s3->hs_buf->length -= CBS_len(&msg.raw);
  576. ssl->s3->is_v2_hello = false;
  577. ssl->s3->has_message = false;
  578. // Post-handshake messages are rare, so release the buffer after every
  579. // message. During the handshake, |on_handshake_complete| will release it.
  580. if (!SSL_in_init(ssl) && ssl->s3->hs_buf->length == 0) {
  581. ssl->s3->hs_buf.reset();
  582. }
  583. }
  584. BSSL_NAMESPACE_END