It's either "GNU *Library* General Public License version 2" or "GNU Lesser General Public License version *2.1*", but there was no "version 2.0" of the "Lesser" license. So assume that version 2.1 is meant here. Signed-off-by: Thomas Huth <thuth@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
148 lines
4.7 KiB
C
148 lines
4.7 KiB
C
/*
|
|
* QEMU crypto secret support
|
|
*
|
|
* Copyright (c) 2015 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
*/
|
|
|
|
#ifndef QCRYPTO_SECRET_H
|
|
#define QCRYPTO_SECRET_H
|
|
|
|
#include "qapi/qapi-types-crypto.h"
|
|
#include "qom/object.h"
|
|
|
|
#define TYPE_QCRYPTO_SECRET "secret"
|
|
#define QCRYPTO_SECRET(obj) \
|
|
OBJECT_CHECK(QCryptoSecret, (obj), TYPE_QCRYPTO_SECRET)
|
|
|
|
typedef struct QCryptoSecret QCryptoSecret;
|
|
typedef struct QCryptoSecretClass QCryptoSecretClass;
|
|
|
|
/**
|
|
* 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 encryption keys, while the former is appropriate
|
|
* 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
|
|
* ad hoc developer testing only)
|
|
*
|
|
* $QEMU -object secret,id=sec0,data=letmein
|
|
*
|
|
* Providing data indirectly:
|
|
*
|
|
* # printf "letmein" > password.txt
|
|
* # $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=$(printf "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
|
|
*
|
|
* # printf "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.
|
|
*/
|
|
|
|
struct QCryptoSecret {
|
|
Object parent_obj;
|
|
uint8_t *rawdata;
|
|
size_t rawlen;
|
|
QCryptoSecretFormat format;
|
|
char *data;
|
|
char *file;
|
|
char *keyid;
|
|
char *iv;
|
|
};
|
|
|
|
|
|
struct QCryptoSecretClass {
|
|
ObjectClass parent_class;
|
|
};
|
|
|
|
|
|
extern int qcrypto_secret_lookup(const char *secretid,
|
|
uint8_t **data,
|
|
size_t *datalen,
|
|
Error **errp);
|
|
extern char *qcrypto_secret_lookup_as_utf8(const char *secretid,
|
|
Error **errp);
|
|
extern char *qcrypto_secret_lookup_as_base64(const char *secretid,
|
|
Error **errp);
|
|
|
|
#endif /* QCRYPTO_SECRET_H */
|