From: Eric Blake <eblake@redhat.com>
To: "Daniel P. Berrange" <berrange@redhat.com>, qemu-devel@nongnu.org
Cc: qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH WIP 01/30] crypto: add QCryptoSecret object class for password/key handling
Date: Fri, 20 Nov 2015 15:09:25 -0700 [thread overview]
Message-ID: <564F9A15.8050109@redhat.com> (raw)
In-Reply-To: <1448042670-17433-2-git-send-email-berrange@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 8199 bytes --]
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 <berrange@redhat.com>
> ---
> 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,id=@var{id},netdev=@var{dev},file=@var{filename}][,maxlen=@var{len}]
Why the added blank line here?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]
next prev parent reply other threads:[~2015-11-20 22:09 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-20 18:04 [Qemu-devel] [PATCH WIP 00/30] Support for full disk encryption Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 01/30] crypto: add QCryptoSecret object class for password/key handling Daniel P. Berrange
2015-11-20 22:09 ` Eric Blake [this message]
2015-11-23 12:33 ` Daniel P. Berrange
2015-11-23 13:39 ` Markus Armbruster
2015-11-23 14:43 ` Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 02/30] crypto: add support for loading encrypted x509 keys Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 03/30] qcow: add a 'keyid' parameter to qcow options Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 04/30] qcow2: add a 'keyid' parameter to qcow2 options Daniel P. Berrange
2015-11-20 22:15 ` Eric Blake
2015-11-23 12:40 ` Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 05/30] qom: add user_creatable_add & user_creatable_del methods Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 06/30] qemu-img: add support for --object command line arg Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 07/30] qemu-nbd: " Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 08/30] qemu-io: " Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 09/30] qemu-io: allow specifying image as a set of options args Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 10/30] qemu-nbd: " Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 11/30] qemu-img: " Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 12/30] block: rip out all traces of password prompting Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 13/30] block: remove all encryption handling APIs Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 14/30] block: remove support for writing to qcow/qcow2 encrypted images Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 15/30] qcow2: make qcow2_encrypt_sectors encrypt in place Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 16/30] crypto: add ability to query the cipher key, block & IV lens Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 17/30] crypto: add method for querying hash digest size Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 18/30] crypto: move QCryptoHashAlgorithm enum definition into QAPI Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 19/30] crypto: move QCryptoCipherAlgorithm/Mode enum definitions " Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 20/30] crypto: ensure qapi/crypto.json is listed in qapi-modules Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 21/30] crypto: add cryptographic random byte source Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 22/30] crypto: add support for PBKDF2 algorithm Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 23/30] crypto: add support for generating initialization vectors Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 24/30] crypto: add support for anti-forensic split algorithm Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 25/30] crypto: fix transposed arguments in cipher error message Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 26/30] crypto: add block encryption framework Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 27/30] crypto: implement the LUKS block encryption format Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 28/30] block: add generic full disk encryption driver Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 29/30] qcow2: convert QCow2 to use QCryptoBlock for encryption Daniel P. Berrange
2015-11-20 18:04 ` [Qemu-devel] [PATCH WIP 30/30] qcow2: add LUKS full disk encryption support Daniel P. Berrange
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=564F9A15.8050109@redhat.com \
--to=eblake@redhat.com \
--cc=berrange@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).