util: Introduce virCryptoGenerateRandom

Move the logic from qemuDomainGenerateRandomKey into this new
function, altering the comments, variable names, and error messages
to keep things more generic.

NB: Although perhaps more reasonable to add soemthing to virrandom.c.
    The virrandom.c was included in the setuid_rpc_client, so I chose
    placement in vircrypto.
This commit is contained in:
John Ferlan 2016-05-19 13:05:36 -04:00
parent 1ce9c08ab3
commit 238032505f
4 changed files with 46 additions and 51 deletions

View File

@ -1395,6 +1395,7 @@ virConfWriteMem;
# util/vircrypto.h
virCryptoEncryptData;
virCryptoGenerateRandom;
virCryptoHashString;
virCryptoHaveCipher;

View File

@ -45,15 +45,8 @@
#include "virthreadjob.h"
#include "viratomic.h"
#include "virprocess.h"
#include "virrandom.h"
#include "vircrypto.h"
#include "secret_util.h"
#include "base64.h"
#ifdef WITH_GNUTLS
# include <gnutls/gnutls.h>
# if HAVE_GNUTLS_CRYPTO_H
# include <gnutls/crypto.h>
# endif
#endif
#include "logging/log_manager.h"
#include "locking/domain_lock.h"
@ -630,48 +623,6 @@ qemuDomainMasterKeyReadFile(qemuDomainObjPrivatePtr priv)
}
/* qemuDomainGenerateRandomKey
* @nbytes: Size in bytes of random key to generate
*
* Generate a random key of nbytes length and return it.
*
* Since the gnutls_rnd could be missing, provide an alternate less
* secure mechanism to at least have something.
*
* Returns pointer memory containing key on success, NULL on failure
*/
static uint8_t *
qemuDomainGenerateRandomKey(size_t nbytes)
{
uint8_t *key;
int ret;
if (VIR_ALLOC_N(key, nbytes) < 0)
return NULL;
#if HAVE_GNUTLS_RND
/* Generate a master key using gnutls_rnd() if possible */
if ((ret = gnutls_rnd(GNUTLS_RND_RANDOM, key, nbytes)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to generate master key, ret=%d"), ret);
VIR_FREE(key);
return NULL;
}
#else
/* If we don't have gnutls_rnd(), we will generate a less cryptographically
* strong master key from /dev/urandom.
*/
if ((ret = virRandomBytes(key, nbytes)) < 0) {
virReportSystemError(ret, "%s", _("failed to generate master key"));
VIR_FREE(key);
return NULL;
}
#endif
return key;
}
/* qemuDomainMasterKeyRemove:
* @priv: Pointer to the domain private object
*
@ -718,7 +669,7 @@ qemuDomainMasterKeyCreate(virDomainObjPtr vm)
return 0;
if (!(priv->masterKey =
qemuDomainGenerateRandomKey(QEMU_DOMAIN_MASTER_KEY_LEN)))
virCryptoGenerateRandom(QEMU_DOMAIN_MASTER_KEY_LEN)))
return -1;
priv->masterKeyLen = QEMU_DOMAIN_MASTER_KEY_LEN;

View File

@ -268,3 +268,44 @@ virCryptoEncryptData(virCryptoCipher algorithm,
_("algorithm=%d is not supported"), algorithm);
return -1;
}
/* virCryptoGenerateRandom:
* @nbytes: Size in bytes of random byte stream to generate
*
* Generate a random stream of nbytes length and return it.
*
* Since the gnutls_rnd could be missing, provide an alternate less
* secure mechanism to at least have something.
*
* Returns pointer memory containing byte stream on success, NULL on failure
*/
uint8_t *
virCryptoGenerateRandom(size_t nbytes)
{
uint8_t *buf;
int ret;
if (VIR_ALLOC_N(buf, nbytes) < 0)
return NULL;
#if HAVE_GNUTLS_RND
/* Generate the byte stream using gnutls_rnd() if possible */
if ((ret = gnutls_rnd(GNUTLS_RND_RANDOM, buf, nbytes)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to generate byte stream, ret=%d"), ret);
VIR_FREE(buf);
return NULL;
}
#else
/* If we don't have gnutls_rnd(), we will generate a less cryptographically
* strong master buf from /dev/urandom.
*/
if ((ret = virRandomBytes(buf, nbytes)) < 0) {
virReportSystemError(ret, "%s", _("failed to generate byte stream"));
VIR_FREE(buf);
return NULL;
}
#endif
return buf;
}

View File

@ -55,4 +55,6 @@ int virCryptoEncryptData(virCryptoCipher algorithm,
ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6)
ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(9) ATTRIBUTE_RETURN_CHECK;
uint8_t *virCryptoGenerateRandom(size_t nbytes);
#endif /* __VIR_CRYPTO_H__ */