aboutsummaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorDaniel P. Berrangé <berrange@redhat.com>2024-03-15 14:07:58 +0000
committerDaniel P. Berrangé <berrange@redhat.com>2024-07-24 10:39:10 +0100
commit57941c9c86357a6a642f9ee3279d881df4043b6d (patch)
tree5275e399ab1b5ac68197d3c30993882cea671e52 /crypto
parent305233349b471840b00068579d0ab0af50395852 (diff)
crypto: push error reporting into TLS session I/O APIs
The current TLS session I/O APIs just return a synthetic errno value on error, which has been translated from a gnutls error value. This looses a large amount of valuable information that distinguishes different scenarios. Pushing population of the "Error *errp" object into the TLS session I/O APIs gives more detailed error information. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Diffstat (limited to 'crypto')
-rw-r--r--crypto/tlssession.c60
1 files changed, 29 insertions, 31 deletions
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index 1e98f44e0d..926f19c115 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -441,23 +441,20 @@ qcrypto_tls_session_set_callbacks(QCryptoTLSSession *session,
ssize_t
qcrypto_tls_session_write(QCryptoTLSSession *session,
const char *buf,
- size_t len)
+ size_t len,
+ Error **errp)
{
ssize_t ret = gnutls_record_send(session->handle, buf, len);
if (ret < 0) {
- switch (ret) {
- case GNUTLS_E_AGAIN:
- errno = EAGAIN;
- break;
- case GNUTLS_E_INTERRUPTED:
- errno = EINTR;
- break;
- default:
- errno = EIO;
- break;
+ if (ret == GNUTLS_E_AGAIN) {
+ return QCRYPTO_TLS_SESSION_ERR_BLOCK;
+ } else {
+ error_setg(errp,
+ "Cannot write to TLS channel: %s",
+ gnutls_strerror(ret));
+ return -1;
}
- ret = -1;
}
return ret;
@@ -467,26 +464,24 @@ qcrypto_tls_session_write(QCryptoTLSSession *session,
ssize_t
qcrypto_tls_session_read(QCryptoTLSSession *session,
char *buf,
- size_t len)
+ size_t len,
+ bool gracefulTermination,
+ Error **errp)
{
ssize_t ret = gnutls_record_recv(session->handle, buf, len);
if (ret < 0) {
- switch (ret) {
- case GNUTLS_E_AGAIN:
- errno = EAGAIN;
- break;
- case GNUTLS_E_INTERRUPTED:
- errno = EINTR;
- break;
- case GNUTLS_E_PREMATURE_TERMINATION:
- errno = ECONNABORTED;
- break;
- default:
- errno = EIO;
- break;
+ if (ret == GNUTLS_E_AGAIN) {
+ return QCRYPTO_TLS_SESSION_ERR_BLOCK;
+ } else if ((ret == GNUTLS_E_PREMATURE_TERMINATION) &&
+ gracefulTermination){
+ return 0;
+ } else {
+ error_setg(errp,
+ "Cannot read from TLS channel: %s",
+ gnutls_strerror(ret));
+ return -1;
}
- ret = -1;
}
return ret;
@@ -605,9 +600,10 @@ qcrypto_tls_session_set_callbacks(
ssize_t
qcrypto_tls_session_write(QCryptoTLSSession *sess,
const char *buf,
- size_t len)
+ size_t len,
+ Error **errp)
{
- errno = -EIO;
+ error_setg(errp, "TLS requires GNUTLS support");
return -1;
}
@@ -615,9 +611,11 @@ qcrypto_tls_session_write(QCryptoTLSSession *sess,
ssize_t
qcrypto_tls_session_read(QCryptoTLSSession *sess,
char *buf,
- size_t len)
+ size_t len,
+ bool gracefulTermination,
+ Error **errp)
{
- errno = -EIO;
+ error_setg(errp, "TLS requires GNUTLS support");
return -1;
}