@@ -585,6 +585,40 @@ qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *session)
}
}
+int
+qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp)
+{
+ int ret;
+
+ if (!session->handshakeComplete) {
+ return 0;
+ }
+
+ ret = gnutls_bye(session->handle, GNUTLS_SHUT_WR);
+
+ if (!ret) {
+ return QCRYPTO_TLS_BYE_COMPLETE;
+ }
+
+ if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
+ int direction = gnutls_record_get_direction(session->handle);
+ return direction ? QCRYPTO_TLS_BYE_SENDING : QCRYPTO_TLS_BYE_RECVING;
+ }
+
+ if (session->rerr || session->werr) {
+ error_setg(errp, "TLS termination failed: %s: %s", gnutls_strerror(ret),
+ error_get_pretty(session->rerr ?
+ session->rerr : session->werr));
+ } else {
+ error_setg(errp, "TLS termination failed: %s", gnutls_strerror(ret));
+ }
+
+ error_free(session->rerr);
+ error_free(session->werr);
+ session->rerr = session->werr = NULL;
+
+ return -1;
+}
int
qcrypto_tls_session_get_key_size(QCryptoTLSSession *session,
@@ -699,6 +733,13 @@ qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess)
}
+int
+qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp)
+{
+ return QCRYPTO_TLS_BYE_COMPLETE;
+}
+
+
int
qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess,
Error **errp)
@@ -323,6 +323,28 @@ typedef enum {
QCryptoTLSSessionHandshakeStatus
qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess);
+typedef enum {
+ QCRYPTO_TLS_BYE_COMPLETE,
+ QCRYPTO_TLS_BYE_SENDING,
+ QCRYPTO_TLS_BYE_RECVING,
+} QCryptoTLSSessionByeStatus;
+
+/**
+ * qcrypto_tls_session_bye:
+ * @session: the TLS session object
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Start, or continue, a TLS termination sequence. If the underlying
+ * data channel is non-blocking, then this method may return control
+ * before the termination is complete. The return value will indicate
+ * whether the termination has completed, or is waiting to send or
+ * receive data. In the latter cases, the caller should setup an event
+ * loop watch and call this method again once the underlying data
+ * channel is ready to read or write again.
+ */
+int
+qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp);
+
/**
* qcrypto_tls_session_get_key_size:
* @sess: the TLS session object