Add async certificate verification callback.
This also serves as a certificate verification callback for
CRYPTO_BUFFER-based consumers. Remove the silly
SSL_CTX_i_promise_to_verify_certs_after_the_handshake placeholder.
Bug: 54, chromium:347402
Change-Id: I4c6b445cb9cd7204218acb2e5d1625e6f37aff6f
Reviewed-on: https://boringssl-review.googlesource.com/17964
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 16aeaff..328ec1c 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -517,6 +517,13 @@
* used to reuse the underlying connection for the retry. */
#define SSL_ERROR_EARLY_DATA_REJECTED 15
+/* SSL_ERROR_WANT_CERTIFICATE_VERIFY indicates the operation failed because
+ * certificate verification was incomplete. The caller may retry the operation
+ * when certificate verification is complete.
+ *
+ * See also |SSL_CTX_set_custom_verify|. */
+#define SSL_ERROR_WANT_CERTIFICATE_VERIFY 16
+
/* 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);
@@ -2201,6 +2208,39 @@
int (*callback)(int ok,
X509_STORE_CTX *store_ctx));
+enum ssl_verify_result_t {
+ ssl_verify_ok,
+ ssl_verify_invalid,
+ ssl_verify_retry,
+};
+
+/* SSL_CTX_set_custom_verify configures certificate verification. |mode| is one
+ * of the |SSL_VERIFY_*| values defined above. |callback| performs the
+ * certificate verification.
+ *
+ * The callback may call |SSL_get0_peer_certificates| for the certificate chain
+ * to validate. The callback should return |ssl_verify_ok| if the certificate is
+ * valid. If the certificate is invalid, the callback should return
+ * |ssl_verify_invalid| and optionally set |*out_alert| to an alert to send to
+ * the peer. Some useful alerts include |SSL_AD_CERTIFICATE_EXPIRED|,
+ * |SSL_AD_CERTIFICATE_REVOKED|, |SSL_AD_UNKNOWN_CA|, |SSL_AD_BAD_CERTIFICATE|,
+ * |SSL_AD_CERTIFICATE_UNKNOWN|, and |SSL_AD_INTERNAL_ERROR|. See RFC 5246
+ * section 7.2.2 for their precise meanings. If unspecified,
+ * |SSL_AD_CERTIFICATE_UNKNOWN| will be sent by default.
+ *
+ * To verify a certificate asynchronously, the callback may return
+ * |ssl_verify_retry|. The handshake will then pause with |SSL_get_error|
+ * returning |SSL_ERROR_WANT_CERTIFICATE_VERIFY|. */
+OPENSSL_EXPORT void SSL_CTX_set_custom_verify(
+ SSL_CTX *ctx, int mode,
+ enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert));
+
+/* SSL_set_custom_verify behaves like |SSL_CTX_set_custom_verify| but configures
+ * an individual |SSL|. */
+OPENSSL_EXPORT void SSL_set_custom_verify(
+ SSL *ssl, int mode,
+ enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert));
+
/* SSL_CTX_get_verify_mode returns |ctx|'s verify mode, set by
* |SSL_CTX_set_verify|. */
OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
@@ -2320,13 +2360,6 @@
SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg),
void *arg);
-/* SSL_CTX_i_promise_to_verify_certs_after_the_handshake indicates that the
- * caller understands that the |CRYPTO_BUFFER|-based methods currently require
- * post-handshake verification of certificates and thus it's ok to accept any
- * certificates during the handshake. */
-OPENSSL_EXPORT void SSL_CTX_i_promise_to_verify_certs_after_the_handshake(
- SSL_CTX *ctx);
-
/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
* of a connection) to request SCTs from the server. See
* https://tools.ietf.org/html/rfc6962.
@@ -3748,6 +3781,7 @@
#define SSL_PRIVATE_KEY_OPERATION 9
#define SSL_PENDING_TICKET 10
#define SSL_EARLY_DATA_REJECTED 11
+#define SSL_CERTIFICATE_VERIFY 12
/* SSL_want returns one of the above values to determine what the most recent
* operation on |ssl| was blocked on. Use |SSL_get_error| instead. */
@@ -4194,6 +4228,9 @@
int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg);
void *app_verify_arg;
+ enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl,
+ uint8_t *out_alert);
+
/* Default password callback. */
pem_password_cb *default_passwd_callback;
@@ -4374,12 +4411,6 @@
* otherwise. */
unsigned grease_enabled:1;
- /* i_promise_to_verify_certs_after_the_handshake indicates that the
- * application is using the |CRYPTO_BUFFER|-based methods and understands
- * that this currently requires post-handshake verification of
- * certificates. */
- unsigned i_promise_to_verify_certs_after_the_handshake:1;
-
/* allow_unknown_alpn_protos is one if the client allows unsolicited ALPN
* protocols from the peer. */
unsigned allow_unknown_alpn_protos:1;