Do not depend on internals of the SSL state machine.

tlsdate has a "time_is_an_illusion" parameter which uses the server's
reported time (within some bounds) to check the certificate against. It
does this by configuring the time on the SSL's X509_VERIFY_PARAM when
one of the SSL3_ST_CR_SRVR_HELLO_A and SSL3_ST_CR_SRVR_HELLO_B states
passes.

In addition to depending on quirks of the OpenSSL state machine which
BoringSSL would otherwise need to emulate, this code is wrong. It needs
to run at a point after the server_random is filled in.  In the original
OpenSSL code, SSL3_ST_CR_SRVR_HELLO_A is when the message header is
read, so this is too early. The _B also wouldn't work in a non-blocking
socket because state mcahine might pause halfway through reading the
body. This probably only worked because it only uses blocking BIOs.

This also depends on OpenSSL's info_callback hacking the state
transitions so SSL_state returned the previous state during the
callback.

Rather than ossify all these bugs, use SSL_CTX_set_cert_verify_callback.
This overrides OpenSSL's call to X509_verify_cert. By looking up the
server random immediately before verification, we are guaranteed
server_random is filled in. At this point we also have an X509_STORE_CTX
available, so we may set the time on it directly.

(Cherry-picked from
https://android.googlesource.com/platform/external/tlsdate/+/c339766a51d2db711171cb704e30b7ae916a987f%5E%21/)

BUG=chromium:736453
TEST=Deploy, reboot, tlsdate correctly sets date.

Change-Id: I8512e083a50be55fffaa5d2bbcb66f3badb4a4ee
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/tlsdate/+/2203402
Tested-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Jorge Lucangeli Obes <jorgelo@chromium.org>
Reviewed-by: David Benjamin <davidben@chromium.org>
Reviewed-by: Pavol Marko <pmarko@chromium.org>
2 files changed