[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-block] [Qemu-devel] [PATCH WIP 01/30] crypto: add QCryptoSecre
From: |
Eric Blake |
Subject: |
Re: [Qemu-block] [Qemu-devel] [PATCH WIP 01/30] crypto: add QCryptoSecret object class for password/key handling |
Date: |
Fri, 20 Nov 2015 15:09:25 -0700 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 |
On 11/20/2015 11:04 AM, Daniel P. Berrange wrote:
> Introduce a new QCryptoSecret object class which will be used
> for providing passwords and keys to other objects which need
> sensitive credentials.
>
> The new object can provide secret values directly as properties,
> or indirectly via a file. The latter includes support for file
> descriptor passing syntax on UNIX platforms. Ordinarily passing
> secret values directly as properties is insecure, since they
> are visible in process listings, or in log files showing the
> CLI args / QMP commands. It is possible to use AES-256-CBC to
> encrypt the secret values though, in which case all that is
> visible is the ciphertext. For adhoc developer testing though,
> it is fine to provide the secrets directly without encryption
> so this is not explicitly forbidden.
>
> The anticipated scenario is that libvirtd will create a random
> master key per QEMU instance (eg /var/run/libvirt/qemu/$VMNAME.key)
> and will use that key to encrypt all passwords it provides to
> QEMU via '-object secret,....'. This avoids the need for libvirt
> (or other mgmt apps) to worry about file descriptor passing.
>
> It also makes life easier for people who are scripting the
> management of QEMU, for whom FD passing is significantly more
> complex.
>
> Providing data inline (insecure, only for adhoc dev tetsing)
s/tetsing/testing/
>
> $QEMU -object secret,id=sec0,data=letmein
>
> Providing data indirectly in raw format
>
> echo -n "letmein" > mypasswd.txt
'echo -n' is non-portable (just this month, there was a user complaining
that gentoo disables it on dash, even though upstream dash supports it).
Might be better as:
printf "letmein" > mypasswd.txt
> $QEMU -object secret,id=sec0,file=mypasswd.txt
>
> Providing data indirectly in base64 format
>
> $QEMU -object secret,id=sec0,file=mykey.b64,format=base64
>
> Providing data with encyption
s/encyption/encryption/
>
> $QEMU -object secret,id=master0,file=mykey.b64,format=base64 \
> -object secret,id=sec0,data=[base64 ciphertext],\
> keyid=master0,iv=[base64 IV],format=base64
>
> Note that 'format' here refers to the format of the ciphertext
> data. The decrypted data must always be in raw byte format.
>
> More examples are shown in the updated docs.
>
> Signed-off-by: Daniel P. Berrange <address@hidden>
> ---
> crypto/Makefile.objs | 1 +
> crypto/secret.c | 567
> +++++++++++++++++++++++++++++++++++++++++++++
> include/crypto/secret.h | 148 ++++++++++++
> qapi/crypto.json | 14 ++
> qemu-options.hx | 78 +++++++
> tests/.gitignore | 1 +
> tests/Makefile | 2 +
> tests/test-crypto-secret.c | 446 +++++++++++++++++++++++++++++++++++
> 8 files changed, 1257 insertions(+)
> create mode 100644 crypto/secret.c
> create mode 100644 include/crypto/secret.h
> create mode 100644 tests/test-crypto-secret.c
Just focusing on the interface on this pass:
> +
> +static const char *base64_valid_chars =
> + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
> +
> +static int
> +qcrypto_secret_validate_base64(const uint8_t *input,
> + size_t inputlen,
> + Error **errp)
Don't we already have base64 utility methods available?
> +++ b/include/crypto/secret.h
> +/**
> + * QCryptoSecret:
> + *
> + * The QCryptoSecret object provides storage of secrets,
> + * which may be user passwords, encryption keys or any
> + * other kind of sensitive data that is represented as
> + * a sequence of bytes.
> + *
> + * The sensitive data associated with the secret can
> + * be provided directly via the 'data' property, or
> + * indirectly via the 'file' property. In the latter
> + * case there is support for file descriptor passing
> + * via the usual /dev/fdset/NN syntax that QEMU uses.
> + *
> + * The data for a secret can be provided in two formats,
> + * either as a UTF-8 string (the default), or as base64
> + * encoded 8-bit binary data. The latter is appropriate
> + * for raw encrypton keys, while the former is appropriate
s/for raw/for raw/
s/encrypton/encryption/
> + * for user entered passwords.
> + *
> + * The data may be optionally encrypted with AES-256-CBC,
> + * and the decryption key provided by another
> + * QCryptoSecret instance identified by the 'keyid'
> + * property. When passing sensitive data directly
> + * via the 'data' property it is strongly recommended
> + * to use the AES encryption facility to prevent the
> + * sensitive data being exposed in the process listing
> + * or system log files.
> + *
> + * Providing data directly, insecurely (suitable for
> + * adhoc developer testing only)
> + *
> + * $QEMU -object secret,id=sec0,data=letmein
> + *
> + * Providing data indirectly:
> + *
> + * # echo -n "letmein" > password.txt
same comment as on commit message
> + * # $QEMU \
> + * -object secret,id=sec0,file=password.txt
> + *
> + * Using a master encryption key with data.
> + *
> + * The master key needs to be created as 32 secure
> + * random bytes (optionally base64 encoded)
> + *
> + * # openssl rand -base64 32 > key.b64
> + * # KEY=$(base64 -d key.b64 | hexdump -v -e '/1 "%02X"')
> + *
> + * Each secret to be encrypted needs to have a random
> + * initialization vector generated. These do not need
> + * to be kept secret
> + *
> + * # openssl rand -base64 16 > iv.b64
> + * # IV=$(base64 -d iv.b64 | hexdump -v -e '/1 "%02X"')
> + *
> + * A secret to be defined can now be encrypted
> + *
> + * # SECRET=$(echo -n "letmein" |
> + * openssl enc -aes-256-cbc -a -K $KEY -iv $IV)
> + *
> + * When launching QEMU, create a master secret pointing
> + * to key.b64 and specify that to be used to decrypt
> + * the user password
> + *
> + * # $QEMU \
> + * -object secret,id=secmaster0,format=base64,file=key.b64 \
> + * -object secret,id=sec0,keyid=secmaster0,format=base64,\
> + * data=$SECRET,iv=$(<iv.b64)
> + *
> + * When encrypting, the data can still be provided via an
> + * external file, in which case it is possible to use either
> + * raw binary data, or base64 encoded. This example uses
> + * raw format
> + *
> + * # echo -n "letmein" |
> + * openssl enc -aes-256-cbc -K $KEY -iv $IV -o pw.aes
> + * # $QEMU \
> + * -object secret,id=secmaster0,format=base64,file=key.b64 \
> + * -object secret,id=sec0,keyid=secmaster0,\
> + * file=pw.aes,iv=$(<iv.b64)
> + *
> + * Note that the ciphertext can be in either raw or base64
> + * format, as indicated by the 'format' parameter, but the
> + * plaintext resulting from decryption is expected to always
> + * be in raw format.
> + */
> +++ b/qapi/crypto.json
> @@ -19,3 +19,17 @@
> { 'enum': 'QCryptoTLSCredsEndpoint',
> 'prefix': 'QCRYPTO_TLS_CREDS_ENDPOINT',
> 'data': ['client', 'server']}
> +
> +
> +##
> +# QCryptoSecretFormat:
> +#
> +# The data format that the secret is provided in
> +#
> +# @raw: raw bytes. When encoded in JSON only valid UTF-8 sequences can be
> used
> +# @base64: arbitrary base64 encoded binary data
> +# Since: 2.5
You've missed 2.5. Probably need to tweak the whole series to call out 2.6.
> +##
> +{ 'enum': 'QCryptoSecretFormat',
> + 'prefix': 'QCRYPTO_SECRET_FORMAT',
> + 'data': ['raw', 'base64']}
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 0eea4ee..dd3f7f8 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -3670,6 +3670,7 @@ queue @var{all|rx|tx} is an option that can be applied
> to any netfilter.
> @option{tx}: the filter is attached to the transmit queue of the netdev,
> where it will receive packets sent by the netdev.
>
> +
> @item -object
> filter-dump,address@hidden,address@hidden,address@hidden,address@hidden
Why the added blank line here?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature
[Qemu-block] [PATCH WIP 03/30] qcow: add a 'keyid' parameter to qcow options, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 05/30] qom: add user_creatable_add & user_creatable_del methods, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 07/30] qemu-nbd: add support for --object command line arg, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 06/30] qemu-img: add support for --object command line arg, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 08/30] qemu-io: add support for --object command line arg, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 09/30] qemu-io: allow specifying image as a set of options args, Daniel P. Berrange, 2015/11/20
[Qemu-block] [PATCH WIP 16/30] crypto: add ability to query the cipher key, block & IV lens, Daniel P. Berrange, 2015/11/20