crypto: add support for TLS priority string override
The gnutls default priority is either "NORMAL" (most historical versions of gnutls) which is a built-in label in gnutls code, or "@SYSTEM" (latest gnutls on Fedora at least) which refers to an admin customizable entry in a gnutls config file. Regardless of which default is used by a distro, they are both global defaults applying to all applications using gnutls. If a single application on the system needs to use a weaker set of crypto priorities, this potentially forces the weakness onto all applications. Or conversely if a single application wants a strong default than all others, it can't do this via the global config file. This adds an extra parameter to the tls credential object which allows the mgmt app / user to explicitly provide a priority string to QEMU when configuring TLS. For example, to use the "NORMAL" priority, but disable SSL 3.0 one can now configure QEMU thus: $QEMU -object tls-creds-x509,id=tls0,dir=/home/berrange/qemutls,\ priority="NORMAL:-VERS-SSL3.0" \ ..other args... If creating tls-creds-anon, whatever priority the user specifies will always have "+ANON-DH" appended to it, since that's mandatory to make the anonymous credentials work. Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
parent
9164b89762
commit
13f12430d4
@ -178,6 +178,27 @@ qcrypto_tls_creds_prop_get_dir(Object *obj,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
qcrypto_tls_creds_prop_set_priority(Object *obj,
|
||||||
|
const char *value,
|
||||||
|
Error **errp G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
|
||||||
|
|
||||||
|
creds->priority = g_strdup(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char *
|
||||||
|
qcrypto_tls_creds_prop_get_priority(Object *obj,
|
||||||
|
Error **errp G_GNUC_UNUSED)
|
||||||
|
{
|
||||||
|
QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
|
||||||
|
|
||||||
|
return g_strdup(creds->priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qcrypto_tls_creds_prop_set_endpoint(Object *obj,
|
qcrypto_tls_creds_prop_set_endpoint(Object *obj,
|
||||||
int value,
|
int value,
|
||||||
@ -216,6 +237,10 @@ qcrypto_tls_creds_class_init(ObjectClass *oc, void *data)
|
|||||||
qcrypto_tls_creds_prop_get_endpoint,
|
qcrypto_tls_creds_prop_get_endpoint,
|
||||||
qcrypto_tls_creds_prop_set_endpoint,
|
qcrypto_tls_creds_prop_set_endpoint,
|
||||||
NULL);
|
NULL);
|
||||||
|
object_class_property_add_str(oc, "priority",
|
||||||
|
qcrypto_tls_creds_prop_get_priority,
|
||||||
|
qcrypto_tls_creds_prop_set_priority,
|
||||||
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -234,6 +259,7 @@ qcrypto_tls_creds_finalize(Object *obj)
|
|||||||
QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
|
QCryptoTLSCreds *creds = QCRYPTO_TLS_CREDS(obj);
|
||||||
|
|
||||||
g_free(creds->dir);
|
g_free(creds->dir);
|
||||||
|
g_free(creds->priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,14 +132,22 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
|
|||||||
if (object_dynamic_cast(OBJECT(creds),
|
if (object_dynamic_cast(OBJECT(creds),
|
||||||
TYPE_QCRYPTO_TLS_CREDS_ANON)) {
|
TYPE_QCRYPTO_TLS_CREDS_ANON)) {
|
||||||
QCryptoTLSCredsAnon *acreds = QCRYPTO_TLS_CREDS_ANON(creds);
|
QCryptoTLSCredsAnon *acreds = QCRYPTO_TLS_CREDS_ANON(creds);
|
||||||
|
char *prio;
|
||||||
|
|
||||||
ret = gnutls_priority_set_direct(session->handle,
|
if (creds->priority != NULL) {
|
||||||
"NORMAL:+ANON-DH", NULL);
|
prio = g_strdup_printf("%s:+ANON-DH", creds->priority);
|
||||||
|
} else {
|
||||||
|
prio = g_strdup("NORMAL:+ANON-DH");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gnutls_priority_set_direct(session->handle, prio, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "Unable to set TLS session priority: %s",
|
error_setg(errp, "Unable to set TLS session priority %s: %s",
|
||||||
gnutls_strerror(ret));
|
prio, gnutls_strerror(ret));
|
||||||
|
g_free(prio);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
g_free(prio);
|
||||||
if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
|
if (creds->endpoint == QCRYPTO_TLS_CREDS_ENDPOINT_SERVER) {
|
||||||
ret = gnutls_credentials_set(session->handle,
|
ret = gnutls_credentials_set(session->handle,
|
||||||
GNUTLS_CRD_ANON,
|
GNUTLS_CRD_ANON,
|
||||||
@ -157,11 +165,15 @@ qcrypto_tls_session_new(QCryptoTLSCreds *creds,
|
|||||||
} else if (object_dynamic_cast(OBJECT(creds),
|
} else if (object_dynamic_cast(OBJECT(creds),
|
||||||
TYPE_QCRYPTO_TLS_CREDS_X509)) {
|
TYPE_QCRYPTO_TLS_CREDS_X509)) {
|
||||||
QCryptoTLSCredsX509 *tcreds = QCRYPTO_TLS_CREDS_X509(creds);
|
QCryptoTLSCredsX509 *tcreds = QCRYPTO_TLS_CREDS_X509(creds);
|
||||||
|
const char *prio = creds->priority;
|
||||||
|
if (!prio) {
|
||||||
|
prio = "NORMAL";
|
||||||
|
}
|
||||||
|
|
||||||
ret = gnutls_set_default_priority(session->handle);
|
ret = gnutls_priority_set_direct(session->handle, prio, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "Cannot set default TLS session priority: %s",
|
error_setg(errp, "Cannot set default TLS session priority %s: %s",
|
||||||
gnutls_strerror(ret));
|
prio, gnutls_strerror(ret));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
ret = gnutls_credentials_set(session->handle,
|
ret = gnutls_credentials_set(session->handle,
|
||||||
|
@ -54,6 +54,7 @@ struct QCryptoTLSCreds {
|
|||||||
gnutls_dh_params_t dh_params;
|
gnutls_dh_params_t dh_params;
|
||||||
#endif
|
#endif
|
||||||
bool verifyPeer;
|
bool verifyPeer;
|
||||||
|
char *priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user