From: Eric Blake <eblake@redhat.com>
To: qemu-devel@nongnu.org
Cc: berrange@redhat.com, Markus Armbruster <armbru@redhat.com>,
qemu-block@nongnu.org
Subject: [PATCH 1/3] crypto: Add qcrypto_tls_shutdown()
Date: Fri, 27 Mar 2020 11:19:34 -0500 [thread overview]
Message-ID: <20200327161936.2225989-2-eblake@redhat.com> (raw)
In-Reply-To: <20200327161936.2225989-1-eblake@redhat.com>
Gnutls documents that applications that want to distinguish between a
clean end-of-communication and a malicious client abruptly tearing the
underlying transport out of under our feet need to use gnutls_bye().
Our channel code is already set up to allow shutdown requests, but we
weren't forwarding those to gnutls. To make that work, we first need
a new entry point that can isolate the rest of our code from the
gnutls interface.
Signed-off-by: Eric Blake <eblake@redhat.com>
---
qapi/crypto.json | 15 +++++++++++++++
include/crypto/tlssession.h | 24 ++++++++++++++++++++++++
crypto/tlssession.c | 27 +++++++++++++++++++++++++++
3 files changed, 66 insertions(+)
diff --git a/qapi/crypto.json b/qapi/crypto.json
index b2a4cff683ff..1df0f4502885 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -119,6 +119,21 @@
'prefix': 'QCRYPTO_IVGEN_ALG',
'data': ['plain', 'plain64', 'essiv']}
+##
+# @QCryptoShutdownMode:
+#
+# The supported modes for requesting shutdown of a crypto
+# communication channel.
+#
+# @shut-wr: No more writes will be sent, but the remote end can still send
+# data to be read.
+# @shut-rdwr: No more reads or writes should occur.
+# Since: 5.1
+##
+{ 'enum': 'QCryptoShutdownMode',
+ 'prefix': 'QCRYPTO',
+ 'data': ['shut-wr', 'shut-rdwr']}
+
##
# @QCryptoBlockFormat:
#
diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h
index 15b9cef086cc..10c670e3b6a2 100644
--- a/include/crypto/tlssession.h
+++ b/include/crypto/tlssession.h
@@ -321,4 +321,28 @@ int qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess,
*/
char *qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess);
+/**
+ * qcrypto_tls_shutdown:
+ * @sess: the TLS session object
+ * @how: the desired shutdown mode
+ *
+ * Prepare to terminate the session. If @how is QCRYPTO_SHUT_WR, this
+ * side will no longer write data, but should still process reads
+ * until EOF; if @how is QCRYPTO_SHUT_RDWR, then the entire session
+ * should shut down. Use of this function is optional, since closing
+ * the session implies QCRYPTO_SHUT_RDWR. However, using this
+ * function prior to terminating the underlying transport layer makes
+ * it possible for the remote endpoint to distinguish between a
+ * malicious party prematurely terminating the the connection and
+ * normal termination.
+ *
+ * This function should only be used after a successful
+ * qcrypto_tls_session_handshake().
+ *
+ * Returns: 0 for success, or -EAGAIN if more underlying I/O is
+ * required to finish proper session shutdown.
+ */
+int qcrypto_tls_session_shutdown(QCryptoTLSSession *sess,
+ QCryptoShutdownMode how);
+
#endif /* QCRYPTO_TLSSESSION_H */
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index 33203e8ca711..903301189069 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -521,6 +521,33 @@ qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *session)
}
+int qcrypto_tls_session_shutdown(QCryptoTLSSession *session,
+ QCryptoShutdownMode how)
+{
+ gnutls_close_request_t mode;
+ int ret;
+
+ assert(session->handshakeComplete);
+ switch (how) {
+ case QCRYPTO_SHUT_WR:
+ mode = GNUTLS_SHUT_WR;
+ break;
+ case QCRYPTO_SHUT_RDWR:
+ mode = GNUTLS_SHUT_RDWR;
+ break;
+ default:
+ abort();
+ }
+
+ ret = gnutls_bye(session->handle, mode);
+ if (ret == GNUTLS_E_INTERRUPTED ||
+ ret == GNUTLS_E_AGAIN) {
+ return -EAGAIN;
+ }
+ return 0;
+}
+
+
int
qcrypto_tls_session_get_key_size(QCryptoTLSSession *session,
Error **errp)
--
2.26.0.rc2
next prev parent reply other threads:[~2020-03-27 16:21 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-27 16:19 [PATCH 0/3] nbd: Try for cleaner TLS shutdown Eric Blake
2020-03-27 16:19 ` Eric Blake [this message]
2020-03-31 8:30 ` [PATCH 1/3] crypto: Add qcrypto_tls_shutdown() Markus Armbruster
2020-03-31 15:17 ` Eric Blake
2020-03-31 15:33 ` Daniel P. Berrangé
2020-03-27 16:19 ` [PATCH 2/3] io: Support shutdown of TLS channel Eric Blake
2020-03-27 16:40 ` Daniel P. Berrangé
2020-03-27 17:29 ` Eric Blake
2020-03-27 17:43 ` Daniel P. Berrangé
2020-03-27 18:46 ` Eric Blake
2020-03-27 16:19 ` [PATCH 3/3] nbd: Use shutdown(SHUT_WR) after last item sent Eric Blake
2020-03-27 16:35 ` Daniel P. Berrangé
2020-03-27 17:42 ` Eric Blake
2020-03-27 17:47 ` Daniel P. Berrangé
2020-03-27 18:44 ` [PATCH 0/3] nbd: Try for cleaner TLS shutdown no-reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200327161936.2225989-2-eblake@redhat.com \
--to=eblake@redhat.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).