diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2015-10-15 16:14:42 +0100 |
---|---|---|
committer | Daniel P. Berrange <berrange@redhat.com> | 2015-12-18 16:25:08 +0000 |
commit | 1d7b5b4afdcd76e24ec3678d5418b29d4ff06ad9 (patch) | |
tree | 403fca6a61c6ea4bac307c08434b0f0df1ea4b27 /crypto/tlscredsx509.c | |
parent | ac1d88784907c9603b3849b2c3043259f75ed2a5 (diff) |
crypto: add support for loading encrypted x509 keys
Make use of the QCryptoSecret object to support loading of
encrypted x509 keys. The optional 'passwordid' parameter
to the tls-creds-x509 object type, provides the ID of a
secret object instance that holds the decryption password
for the PEM file.
# printf "123456" > mypasswd.txt
# $QEMU \
-object secret,id=sec0,filename=mypasswd.txt \
-object tls-creds-x509,passwordid=sec0,id=creds0,\
dir=/home/berrange/.pki/qemu,endpoint=server \
-vnc :1,tls-creds=creds0
This requires QEMU to be linked to GNUTLS >= 3.1.11. If
GNUTLS is too old an error will be reported if an attempt
is made to pass a decryption password.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Diffstat (limited to 'crypto/tlscredsx509.c')
-rw-r--r-- | crypto/tlscredsx509.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c index 26f18cbb4a..d58fdea347 100644 --- a/crypto/tlscredsx509.c +++ b/crypto/tlscredsx509.c @@ -20,6 +20,7 @@ #include "crypto/tlscredsx509.h" #include "crypto/tlscredspriv.h" +#include "crypto/secret.h" #include "qom/object_interfaces.h" #include "trace.h" @@ -607,9 +608,30 @@ qcrypto_tls_creds_x509_load(QCryptoTLSCredsX509 *creds, } if (cert != NULL && key != NULL) { +#if GNUTLS_VERSION_NUMBER >= 0x030111 + char *password = NULL; + if (creds->passwordid) { + password = qcrypto_secret_lookup_as_utf8(creds->passwordid, + errp); + if (!password) { + goto cleanup; + } + } + ret = gnutls_certificate_set_x509_key_file2(creds->data, + cert, key, + GNUTLS_X509_FMT_PEM, + password, + 0); + g_free(password); +#else /* GNUTLS_VERSION_NUMBER < 0x030111 */ + if (creds->passwordid) { + error_setg(errp, "PKCS8 decryption requires GNUTLS >= 3.1.11"); + goto cleanup; + } ret = gnutls_certificate_set_x509_key_file(creds->data, cert, key, GNUTLS_X509_FMT_PEM); +#endif /* GNUTLS_VERSION_NUMBER < 0x030111 */ if (ret < 0) { error_setg(errp, "Cannot load certificate '%s' & key '%s': %s", cert, key, gnutls_strerror(ret)); @@ -737,6 +759,27 @@ qcrypto_tls_creds_x509_prop_set_sanity(Object *obj, } +static void +qcrypto_tls_creds_x509_prop_set_passwordid(Object *obj, + const char *value, + Error **errp G_GNUC_UNUSED) +{ + QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); + + creds->passwordid = g_strdup(value); +} + + +static char * +qcrypto_tls_creds_x509_prop_get_passwordid(Object *obj, + Error **errp G_GNUC_UNUSED) +{ + QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); + + return g_strdup(creds->passwordid); +} + + static bool qcrypto_tls_creds_x509_prop_get_sanity(Object *obj, Error **errp G_GNUC_UNUSED) @@ -769,6 +812,10 @@ qcrypto_tls_creds_x509_init(Object *obj) qcrypto_tls_creds_x509_prop_get_sanity, qcrypto_tls_creds_x509_prop_set_sanity, NULL); + object_property_add_str(obj, "passwordid", + qcrypto_tls_creds_x509_prop_get_passwordid, + qcrypto_tls_creds_x509_prop_set_passwordid, + NULL); } @@ -777,6 +824,7 @@ qcrypto_tls_creds_x509_finalize(Object *obj) { QCryptoTLSCredsX509 *creds = QCRYPTO_TLS_CREDS_X509(obj); + g_free(creds->passwordid); qcrypto_tls_creds_x509_unload(creds); } |