diff --git a/src/lib-ssl-iostream/iostream-openssl.c b/src/lib-ssl-iostream/iostream-openssl.c
index 2af3c001d26fdccf02c8b94294e27612e38a7a21..037fd0bae2fc303440e757f2ee5dad215be36b0a 100644
--- a/src/lib-ssl-iostream/iostream-openssl.c
+++ b/src/lib-ssl-iostream/iostream-openssl.c
@@ -343,8 +343,14 @@ static void openssl_iostream_unref(struct ssl_iostream *ssl_io)
 	openssl_iostream_free(ssl_io);
 }
 
-static void openssl_iostream_destroy(struct ssl_iostream *ssl_io)
+void openssl_iostream_shutdown(struct ssl_iostream *ssl_io)
 {
+	if (ssl_io->destroyed)
+		return;
+
+	i_assert(ssl_io->ssl_input != NULL);
+	i_assert(ssl_io->ssl_output != NULL);
+
 	ssl_io->destroyed = TRUE;
 	if (ssl_io->handshaked && SSL_shutdown(ssl_io->ssl) != 1) {
 		/* if bidirectional shutdown fails we need to clear
@@ -357,7 +363,11 @@ static void openssl_iostream_destroy(struct ssl_iostream *ssl_io)
 	   but we may still keep this ssl-iostream referenced until later. */
 	i_stream_close(ssl_io->plain_input);
 	o_stream_close(ssl_io->plain_output);
+}
 
+static void openssl_iostream_destroy(struct ssl_iostream *ssl_io)
+{
+	openssl_iostream_shutdown(ssl_io);
 	ssl_iostream_unref(&ssl_io);
 }
 
diff --git a/src/lib-ssl-iostream/iostream-openssl.h b/src/lib-ssl-iostream/iostream-openssl.h
index ca34fae62387ef0543ab369d6c5769a91c0a6623..edd4a86af24328f072dc707b490a6b04ddf72bf7 100644
--- a/src/lib-ssl-iostream/iostream-openssl.h
+++ b/src/lib-ssl-iostream/iostream-openssl.h
@@ -116,6 +116,9 @@ int openssl_iostream_handle_error(struct ssl_iostream *ssl_io, int ret,
 				  enum openssl_iostream_sync_type type,
 				  const char *func_name);
 
+/* Perform clean shutdown for the connection. */
+void openssl_iostream_shutdown(struct ssl_iostream *ssl_io);
+
 void openssl_iostream_set_error(struct ssl_iostream *ssl_io, const char *str);
 const char *openssl_iostream_error(void);
 const char *openssl_iostream_key_load_error(void);
diff --git a/src/lib-ssl-iostream/istream-openssl.c b/src/lib-ssl-iostream/istream-openssl.c
index 3bdfdb17ccc6ce163566c1f29bcf5381ad598f47..d23efd0a99fc5c6e63a5a65db629ef42d428aeb0 100644
--- a/src/lib-ssl-iostream/istream-openssl.c
+++ b/src/lib-ssl-iostream/istream-openssl.c
@@ -23,6 +23,7 @@ static void i_stream_ssl_destroy(struct iostream_private *stream)
 {
 	struct ssl_istream *sstream = (struct ssl_istream *)stream;
 
+	openssl_iostream_shutdown(sstream->ssl_io);
 	i_stream_free_buffer(&sstream->istream);
 	sstream->ssl_io->ssl_input = NULL;
 	ssl_iostream_unref(&sstream->ssl_io);
diff --git a/src/lib-ssl-iostream/ostream-openssl.c b/src/lib-ssl-iostream/ostream-openssl.c
index e6e8aa5686d5febc9c2c4ff665e935f759831c18..d1518bc5d7264115b90d9acb14e171e836e985e2 100644
--- a/src/lib-ssl-iostream/ostream-openssl.c
+++ b/src/lib-ssl-iostream/ostream-openssl.c
@@ -26,6 +26,7 @@ static void o_stream_ssl_destroy(struct iostream_private *stream)
 	struct ssl_ostream *sstream = (struct ssl_ostream *)stream;
 	struct istream *ssl_input = sstream->ssl_io->ssl_input;
 
+	openssl_iostream_shutdown(sstream->ssl_io);
 	sstream->ssl_io->ssl_output = NULL;
 	i_stream_unref(&ssl_input);
 	ssl_iostream_unref(&sstream->ssl_io);
