diff options
Diffstat (limited to 'crypto/tlssession.c')
-rw-r--r-- | crypto/tlssession.c | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/crypto/tlssession.c b/crypto/tlssession.c index 77286e2..6d8f8df 100644 --- a/crypto/tlssession.c +++ b/crypto/tlssession.c @@ -546,45 +546,69 @@ qcrypto_tls_session_handshake(QCryptoTLSSession *session, Error **errp) { int ret = gnutls_handshake(session->handle); - if (ret == 0) { + if (!ret) { session->handshakeComplete = true; + return QCRYPTO_TLS_HANDSHAKE_COMPLETE; + } + + if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { + int direction = gnutls_record_get_direction(session->handle); + return direction ? QCRYPTO_TLS_HANDSHAKE_SENDING : + QCRYPTO_TLS_HANDSHAKE_RECVING; + } + + if (session->rerr || session->werr) { + error_setg(errp, "TLS handshake failed: %s: %s", + gnutls_strerror(ret), + error_get_pretty(session->rerr ? + session->rerr : session->werr)); } else { - if (ret == GNUTLS_E_INTERRUPTED || - ret == GNUTLS_E_AGAIN) { - ret = 1; - } else { - if (session->rerr || session->werr) { - error_setg(errp, "TLS handshake failed: %s: %s", - gnutls_strerror(ret), - error_get_pretty(session->rerr ? - session->rerr : session->werr)); - } else { - error_setg(errp, "TLS handshake failed: %s", - gnutls_strerror(ret)); - } - ret = -1; - } + error_setg(errp, "TLS handshake failed: %s", + gnutls_strerror(ret)); } + error_free(session->rerr); error_free(session->werr); session->rerr = session->werr = NULL; - return ret; + return -1; } -QCryptoTLSSessionHandshakeStatus -qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *session) +int +qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp) { - if (session->handshakeComplete) { - return QCRYPTO_TLS_HANDSHAKE_COMPLETE; - } else if (gnutls_record_get_direction(session->handle) == 0) { - return QCRYPTO_TLS_HANDSHAKE_RECVING; + 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 { - return QCRYPTO_TLS_HANDSHAKE_SENDING; + 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, @@ -692,10 +716,10 @@ qcrypto_tls_session_handshake(QCryptoTLSSession *sess, } -QCryptoTLSSessionHandshakeStatus -qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess) +int +qcrypto_tls_session_bye(QCryptoTLSSession *session, Error **errp) { - return QCRYPTO_TLS_HANDSHAKE_COMPLETE; + return QCRYPTO_TLS_BYE_COMPLETE; } |