index
:
riscv-gnu-toolchain/qemu.git
block
master
stable-0.10
stable-0.11
stable-0.12
stable-0.13
stable-0.14
stable-0.15
stable-1.0
stable-1.1
stable-1.2
stable-1.3
stable-1.4
stable-1.5
stable-1.6
stable-1.7
stable-2.0
stable-2.1
stable-2.10
stable-2.11
stable-2.12
stable-2.2
stable-2.3
stable-2.4
stable-2.5
stable-2.6
stable-2.7
stable-2.8
stable-2.9
stable-3.0
stable-3.1
stable-4.0
stable-4.1
stable-4.2
stable-5.0
stable-6.0
stable-6.1
stable-7.2
stable-8.0
stable-8.1
stable-8.2
stable-9.0
stable-9.1
stable-9.2
staging
staging-7.2
staging-8.0
staging-8.1
staging-8.2
staging-9.0
staging-9.1
staging-9.2
Unnamed repository; edit this file 'description' to name the repository.
root
about
summary
refs
log
tree
commit
diff
log msg
author
committer
range
path:
root
/
net
/
vhost-user-stub.c
diff options
context:
1
2
3
4
5
6
7
8
9
10
15
20
25
30
35
40
space:
include
ignore
mode:
unified
ssdiff
stat only
Diffstat
(limited to 'net/vhost-user-stub.c')
0 files changed, 0 insertions, 0 deletions
ename(OBJECT(creds))); goto error; } gnutls_transport_set_ptr(session->handle, session); gnutls_transport_set_push_function(session->handle, qcrypto_tls_session_push); gnutls_transport_set_pull_function(session->handle, qcrypto_tls_session_pull); return session; error: qcrypto_tls_session_free(session); return NULL; } static int qcrypto_tls_session_check_certificate(QCryptoTLSSession *session, Error **errp) { int ret; unsigned int status; const gnutls_datum_t *certs; unsigned int nCerts, i; time_t now; gnutls_x509_crt_t cert = NULL; Error *err = NULL; now = time(NULL); if (now == ((time_t)-1)) { error_setg_errno(errp, errno, "Cannot get current time"); return -1; } ret = gnutls_certificate_verify_peers2(session->handle, &status); if (ret < 0) { error_setg(errp, "Verify failed: %s", gnutls_strerror(ret)); return -1; } if (status != 0) { const char *reason = "Invalid certificate"; if (status & GNUTLS_CERT_INVALID) { reason = "The certificate is not trusted"; } if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { reason = "The certificate hasn't got a known issuer"; } if (status & GNUTLS_CERT_REVOKED) { reason = "The certificate has been revoked"; } if (status & GNUTLS_CERT_INSECURE_ALGORITHM) { reason = "The certificate uses an insecure algorithm"; } error_setg(errp, "%s", reason); return -1; } certs = gnutls_certificate_get_peers(session->handle, &nCerts); if (!certs) { error_setg(errp, "No certificate peers"); return -1; } for (i = 0; i < nCerts; i++) { ret = gnutls_x509_crt_init(&cert); if (ret < 0) { error_setg(errp, "Cannot initialize certificate: %s", gnutls_strerror(ret)); return -1; } ret = gnutls_x509_crt_import(cert, &certs[i], GNUTLS_X509_FMT_DER); if (ret < 0) { error_setg(errp, "Cannot import certificate: %s", gnutls_strerror(ret)); goto error; } if (gnutls_x509_crt_get_expiration_time(cert) < now) { error_setg(errp, "The certificate has expired"); goto error; } if (gnutls_x509_crt_get_activation_time(cert) > now) { error_setg(errp, "The certificate is not yet activated"); goto error; } if (gnutls_x509_crt_get_activation_time(cert) > now) { error_setg(errp, "The certificate is not yet activated"); goto error; } if (i == 0) { size_t dnameSize = 1024; session->peername = g_malloc(dnameSize); requery: ret = gnutls_x509_crt_get_dn(cert, session->peername, &dnameSize); if (ret < 0) { if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { session->peername = g_realloc(session->peername, dnameSize); goto requery; } error_setg(errp, "Cannot get client distinguished name: %s", gnutls_strerror(ret)); goto error; } if (session->authzid) { bool allow; allow = qauthz_is_allowed_by_id(session->authzid, session->peername, &err); if (err) { error_propagate(errp, err); goto error; } if (!allow) { error_setg(errp, "TLS x509 authz check for %s is denied", session->peername); goto error; } } if (session->hostname) { if (!gnutls_x509_crt_check_hostname(cert, session->hostname)) { error_setg(errp, "Certificate does not match the hostname %s", session->hostname); goto error; } } } gnutls_x509_crt_deinit(cert); } return 0; error: gnutls_x509_crt_deinit(cert); return -1; } int qcrypto_tls_session_check_credentials(QCryptoTLSSession *session, Error **errp) { if (object_dynamic_cast(OBJECT(session->creds), TYPE_QCRYPTO_TLS_CREDS_ANON)) { trace_qcrypto_tls_session_check_creds(session, "nop"); return 0; } else if (object_dynamic_cast(OBJECT(session->creds), TYPE_QCRYPTO_TLS_CREDS_PSK)) { trace_qcrypto_tls_session_check_creds(session, "nop"); return 0; } else if (object_dynamic_cast(OBJECT(session->creds), TYPE_QCRYPTO_TLS_CREDS_X509)) { if (session->creds->verifyPeer) { int ret = qcrypto_tls_session_check_certificate(session, errp); trace_qcrypto_tls_session_check_creds(session, ret == 0 ? "pass" : "fail"); return ret; } else { trace_qcrypto_tls_session_check_creds(session, "skip"); return 0; } } else { trace_qcrypto_tls_session_check_creds(session, "error"); error_setg(errp, "Unexpected credential type %s", object_get_typename(OBJECT(session->creds))); return -1; } } void qcrypto_tls_session_set_callbacks(QCryptoTLSSession *session, QCryptoTLSSessionWriteFunc writeFunc, QCryptoTLSSessionReadFunc readFunc, void *opaque) { session->writeFunc = writeFunc; session->readFunc = readFunc; session->opaque = opaque; } ssize_t qcrypto_tls_session_write(QCryptoTLSSession *session, const char *buf, size_t len) { 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; } ret = -1; } return ret; } ssize_t qcrypto_tls_session_read(QCryptoTLSSession *session, char *buf, size_t len) { 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; } ret = -1; } return ret; } int qcrypto_tls_session_handshake(QCryptoTLSSession *session, Error **errp) { int ret = gnutls_handshake(session->handle); if (ret == 0) { session->handshakeComplete = true; } else { if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { ret = 1; } else { error_setg(errp, "TLS handshake failed: %s", gnutls_strerror(ret)); ret = -1; } } return ret; } QCryptoTLSSessionHandshakeStatus qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *session) { if (session->handshakeComplete) { return QCRYPTO_TLS_HANDSHAKE_COMPLETE; } else if (gnutls_record_get_direction(session->handle) == 0) { return QCRYPTO_TLS_HANDSHAKE_RECVING; } else { return QCRYPTO_TLS_HANDSHAKE_SENDING; } } int qcrypto_tls_session_get_key_size(QCryptoTLSSession *session, Error **errp) { gnutls_cipher_algorithm_t cipher; int ssf; cipher = gnutls_cipher_get(session->handle); ssf = gnutls_cipher_get_key_size(cipher); if (!ssf) { error_setg(errp, "Cannot get TLS cipher key size"); return -1; } return ssf; } char * qcrypto_tls_session_get_peer_name(QCryptoTLSSession *session) { if (session->peername) { return g_strdup(session->peername); } return NULL; } #else /* ! CONFIG_GNUTLS */ QCryptoTLSSession * qcrypto_tls_session_new(QCryptoTLSCreds *creds G_GNUC_UNUSED, const char *hostname G_GNUC_UNUSED, const char *authzid G_GNUC_UNUSED, QCryptoTLSCredsEndpoint endpoint G_GNUC_UNUSED, Error **errp) { error_setg(errp, "TLS requires GNUTLS support"); return NULL; } void qcrypto_tls_session_free(QCryptoTLSSession *sess G_GNUC_UNUSED) { } int qcrypto_tls_session_check_credentials(QCryptoTLSSession *sess G_GNUC_UNUSED, Error **errp) { error_setg(errp, "TLS requires GNUTLS support"); return -1; } void qcrypto_tls_session_set_callbacks( QCryptoTLSSession *sess G_GNUC_UNUSED, QCryptoTLSSessionWriteFunc writeFunc G_GNUC_UNUSED, QCryptoTLSSessionReadFunc readFunc G_GNUC_UNUSED, void *opaque G_GNUC_UNUSED) { } ssize_t qcrypto_tls_session_write(QCryptoTLSSession *sess, const char *buf, size_t len) { errno = -EIO; return -1; } ssize_t qcrypto_tls_session_read(QCryptoTLSSession *sess, char *buf, size_t len) { errno = -EIO; return -1; } int qcrypto_tls_session_handshake(QCryptoTLSSession *sess, Error **errp) { error_setg(errp, "TLS requires GNUTLS support"); return -1; } QCryptoTLSSessionHandshakeStatus qcrypto_tls_session_get_handshake_status(QCryptoTLSSession *sess) { return QCRYPTO_TLS_HANDSHAKE_COMPLETE; } int qcrypto_tls_session_get_key_size(QCryptoTLSSession *sess, Error **errp) { error_setg(errp, "TLS requires GNUTLS support"); return -1; } char * qcrypto_tls_session_get_peer_name(QCryptoTLSSession *sess) { return NULL; } #endif