qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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 --]

  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).