Add a function to convert SSL_ERROR_* values to strings.
Unexpected SSL_ERROR_* values usually mean the caller didn't handle an
error case for some opt-in feature, but it still would be handy to
stringify them when logging.
Change-Id: If1c44a180b5c124a51ba61410ba02bd637f3429a
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/37188
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index d86ebf0..1ef9f84 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -560,6 +560,11 @@
#define SSL_ERROR_HANDOFF 17
#define SSL_ERROR_HANDBACK 18
+// SSL_error_description returns a string representation of |err|, where |err|
+// is one of the |SSL_ERROR_*| constants returned by |SSL_get_error|, or NULL
+// if the value is unrecognized.
+OPENSSL_EXPORT const char *SSL_error_description(int err);
+
// SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
// and zero on failure.
OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu);
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc
index 9cf14d5..1186312 100644
--- a/ssl/ssl_lib.cc
+++ b/ssl/ssl_lib.cc
@@ -1400,6 +1400,49 @@
return SSL_ERROR_SYSCALL;
}
+const char *SSL_error_description(int err) {
+ switch (err) {
+ case SSL_ERROR_NONE:
+ return "NONE";
+ case SSL_ERROR_SSL:
+ return "SSL";
+ case SSL_ERROR_WANT_READ:
+ return "WANT_READ";
+ case SSL_ERROR_WANT_WRITE:
+ return "WANT_WRITE";
+ case SSL_ERROR_WANT_X509_LOOKUP:
+ return "WANT_X509_LOOKUP";
+ case SSL_ERROR_SYSCALL:
+ return "SYSCALL";
+ case SSL_ERROR_ZERO_RETURN:
+ return "ZERO_RETURN";
+ case SSL_ERROR_WANT_CONNECT:
+ return "WANT_CONNECT";
+ case SSL_ERROR_WANT_ACCEPT:
+ return "WANT_ACCEPT";
+ case SSL_ERROR_WANT_CHANNEL_ID_LOOKUP:
+ return "WANT_CHANNEL_ID_LOOKUP";
+ case SSL_ERROR_PENDING_SESSION:
+ return "PENDING_SESSION";
+ case SSL_ERROR_PENDING_CERTIFICATE:
+ return "PENDING_CERTIFICATE";
+ case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION:
+ return "WANT_PRIVATE_KEY_OPERATION";
+ case SSL_ERROR_PENDING_TICKET:
+ return "PENDING_TICKET";
+ case SSL_ERROR_EARLY_DATA_REJECTED:
+ return "EARLY_DATA_REJECTED";
+ case SSL_ERROR_WANT_CERTIFICATE_VERIFY:
+ return "WANT_CERTIFICATE_VERIFY";
+ case SSL_ERROR_HANDOFF:
+ return "HANDOFF";
+ case SSL_ERROR_HANDBACK:
+ return "HANDBACK";
+ default:
+ return nullptr;
+ }
+}
+
uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
ctx->options |= options;
return ctx->options;
diff --git a/tool/transport_common.cc b/tool/transport_common.cc
index 8cc63d7..d04cb7d 100644
--- a/tool/transport_common.cc
+++ b/tool/transport_common.cc
@@ -661,7 +661,8 @@
fprintf(file, "%s: received close_notify\n", msg);
break;
default:
- fprintf(file, "%s: unknown error type (%d)\n", msg, ssl_err);
+ fprintf(file, "%s: unexpected error: %s\n", msg,
+ SSL_error_description(ssl_err));
}
ERR_print_errors_fp(file);
}