Don't use SSL_want_* macros internally.
Reduce the amount of boilerplate needed to add more of these. Also tidy
things up a little.
Change-Id: I90ea7f70dba5a2b38a1fb716faff97eb4f6afafc
Reviewed-on: https://boringssl-review.googlesource.com/12687
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 6c8d8ec..c5f8d35 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -877,18 +877,25 @@
return ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
}
-int SSL_get_error(const SSL *ssl, int ret_code) {
- int reason;
- uint32_t err;
- BIO *bio;
+static int bio_retry_reason_to_error(int reason) {
+ switch (reason) {
+ case BIO_RR_CONNECT:
+ return SSL_ERROR_WANT_CONNECT;
+ case BIO_RR_ACCEPT:
+ return SSL_ERROR_WANT_ACCEPT;
+ default:
+ return SSL_ERROR_SYSCALL;
+ }
+}
+int SSL_get_error(const SSL *ssl, int ret_code) {
if (ret_code > 0) {
return SSL_ERROR_NONE;
}
/* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
* where we do encode the error */
- err = ERR_peek_error();
+ uint32_t err = ERR_peek_error();
if (err != 0) {
if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
return SSL_ERROR_SYSCALL;
@@ -906,79 +913,59 @@
return SSL_ERROR_SYSCALL;
}
- if (SSL_want_session(ssl)) {
- return SSL_ERROR_PENDING_SESSION;
- }
+ switch (ssl->rwstate) {
+ case SSL_PENDING_SESSION:
+ return SSL_ERROR_PENDING_SESSION;
- if (SSL_want_certificate(ssl)) {
- return SSL_ERROR_PENDING_CERTIFICATE;
- }
+ case SSL_CERTIFICATE_SELECTION_PENDING:
+ return SSL_ERROR_PENDING_CERTIFICATE;
- if (SSL_want_read(ssl)) {
- bio = SSL_get_rbio(ssl);
- if (BIO_should_read(bio)) {
- return SSL_ERROR_WANT_READ;
- }
-
- if (BIO_should_write(bio)) {
- /* This one doesn't make too much sense ... We never try to write to the
- * rbio, and an application program where rbio and wbio are separate
- * couldn't even know what it should wait for. However if we ever set
- * ssl->rwstate incorrectly (so that we have SSL_want_read(ssl) instead of
- * SSL_want_write(ssl)) and rbio and wbio *are* the same, this test works
- * around that bug; so it might be safer to keep it. */
- return SSL_ERROR_WANT_WRITE;
- }
-
- if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT) {
- return SSL_ERROR_WANT_CONNECT;
+ case SSL_READING: {
+ BIO *bio = SSL_get_rbio(ssl);
+ if (BIO_should_read(bio)) {
+ return SSL_ERROR_WANT_READ;
}
- if (reason == BIO_RR_ACCEPT) {
- return SSL_ERROR_WANT_ACCEPT;
+ if (BIO_should_write(bio)) {
+ /* TODO(davidben): OpenSSL historically checked for writes on the read
+ * BIO. Can this be removed? */
+ return SSL_ERROR_WANT_WRITE;
}
- return SSL_ERROR_SYSCALL; /* unknown */
- }
- }
-
- if (SSL_want_write(ssl)) {
- bio = SSL_get_wbio(ssl);
- if (BIO_should_write(bio)) {
- return SSL_ERROR_WANT_WRITE;
- }
-
- if (BIO_should_read(bio)) {
- /* See above (SSL_want_read(ssl) with BIO_should_write(bio)) */
- return SSL_ERROR_WANT_READ;
- }
-
- if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT) {
- return SSL_ERROR_WANT_CONNECT;
+ if (BIO_should_io_special(bio)) {
+ return bio_retry_reason_to_error(BIO_get_retry_reason(bio));
}
- if (reason == BIO_RR_ACCEPT) {
- return SSL_ERROR_WANT_ACCEPT;
+ break;
+ }
+
+ case SSL_WRITING: {
+ BIO *bio = SSL_get_wbio(ssl);
+ if (BIO_should_write(bio)) {
+ return SSL_ERROR_WANT_WRITE;
}
- return SSL_ERROR_SYSCALL;
+ if (BIO_should_read(bio)) {
+ /* TODO(davidben): OpenSSL historically checked for reads on the write
+ * BIO. Can this be removed? */
+ return SSL_ERROR_WANT_READ;
+ }
+
+ if (BIO_should_io_special(bio)) {
+ return bio_retry_reason_to_error(BIO_get_retry_reason(bio));
+ }
+
+ break;
}
- }
- if (SSL_want_x509_lookup(ssl)) {
- return SSL_ERROR_WANT_X509_LOOKUP;
- }
+ case SSL_X509_LOOKUP:
+ return SSL_ERROR_WANT_X509_LOOKUP;
- if (SSL_want_channel_id_lookup(ssl)) {
- return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
- }
+ case SSL_CHANNEL_ID_LOOKUP:
+ return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
- if (SSL_want_private_key_operation(ssl)) {
- return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
+ case SSL_PRIVATE_KEY_OPERATION:
+ return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
}
return SSL_ERROR_SYSCALL;