* 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 of the License, or (at your option) any later version.
+ * 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
#include "qapi/error.h"
#include "qom/object_interfaces.h"
#include "qemu/base64.h"
+#include "qemu/module.h"
#include "trace.h"
size_t *outputlen,
Error **errp)
{
- uint8_t *key = NULL, *ciphertext = NULL, *iv = NULL;
+ g_autofree uint8_t *key = NULL;
+ g_autofree uint8_t *ciphertext = NULL;
+ g_autofree uint8_t *iv = NULL;
size_t keylen, ciphertextlen, ivlen;
- QCryptoCipher *aes = NULL;
- uint8_t *plaintext = NULL;
+ g_autoptr(QCryptoCipher) aes = NULL;
+ g_autofree uint8_t *plaintext = NULL;
*output = NULL;
*outputlen = 0;
if (qcrypto_secret_lookup(secret->keyid,
&key, &keylen,
errp) < 0) {
- goto cleanup;
+ return;
}
if (keylen != 32) {
error_setg(errp, "Key should be 32 bytes in length");
- goto cleanup;
+ return;
}
if (!secret->iv) {
error_setg(errp, "IV is required to decrypt secret");
- goto cleanup;
+ return;
}
iv = qbase64_decode(secret->iv, -1, &ivlen, errp);
if (!iv) {
- goto cleanup;
+ return;
}
if (ivlen != 16) {
error_setg(errp, "IV should be 16 bytes in length not %zu",
ivlen);
- goto cleanup;
+ return;
}
aes = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_256,
key, keylen,
errp);
if (!aes) {
- goto cleanup;
+ return;
}
if (qcrypto_cipher_setiv(aes, iv, ivlen, errp) < 0) {
- goto cleanup;
+ return;
}
if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) {
&ciphertextlen,
errp);
if (!ciphertext) {
- goto cleanup;
+ return;
}
plaintext = g_new0(uint8_t, ciphertextlen + 1);
} else {
plaintext,
ciphertextlen,
errp) < 0) {
- plaintext = NULL;
- goto cleanup;
+ return;
}
if (plaintext[ciphertextlen - 1] > 16 ||
error_setg(errp, "Incorrect number of padding bytes (%d) "
"found on decrypted data",
(int)plaintext[ciphertextlen - 1]);
- g_free(plaintext);
- plaintext = NULL;
- goto cleanup;
+ return;
}
/* Even though plaintext may contain arbitrary NUL
ciphertextlen -= plaintext[ciphertextlen - 1];
plaintext[ciphertextlen] = '\0';
- *output = plaintext;
+ *output = g_steal_pointer(&plaintext);
*outputlen = ciphertextlen;
-
- cleanup:
- g_free(ciphertext);
- g_free(iv);
- g_free(key);
- qcrypto_cipher_free(aes);
}
input = output;
inputlen = outputlen;
} else {
- if (secret->format != QCRYPTO_SECRET_FORMAT_RAW) {
+ if (secret->format == QCRYPTO_SECRET_FORMAT_BASE64) {
qcrypto_secret_decode(input, inputlen,
&output, &outputlen, &local_err);
g_free(input);
secret->rawlen = inputlen;
} else {
g_free(secret->rawdata);
+ secret->rawdata = NULL;
secret->rawlen = 0;
}
}
Error **errp G_GNUC_UNUSED)
{
QCryptoSecret *secret = QCRYPTO_SECRET(obj);
- return secret->data != NULL;
+ return secret->rawdata != NULL;
}
object_class_property_add_bool(oc, "loaded",
qcrypto_secret_prop_get_loaded,
- qcrypto_secret_prop_set_loaded,
- NULL);
+ qcrypto_secret_prop_set_loaded);
object_class_property_add_enum(oc, "format",
"QCryptoSecretFormat",
&QCryptoSecretFormat_lookup,
qcrypto_secret_prop_get_format,
- qcrypto_secret_prop_set_format,
- NULL);
+ qcrypto_secret_prop_set_format);
object_class_property_add_str(oc, "data",
qcrypto_secret_prop_get_data,
- qcrypto_secret_prop_set_data,
- NULL);
+ qcrypto_secret_prop_set_data);
object_class_property_add_str(oc, "file",
qcrypto_secret_prop_get_file,
- qcrypto_secret_prop_set_file,
- NULL);
+ qcrypto_secret_prop_set_file);
object_class_property_add_str(oc, "keyid",
qcrypto_secret_prop_get_keyid,
- qcrypto_secret_prop_set_keyid,
- NULL);
+ qcrypto_secret_prop_set_keyid);
object_class_property_add_str(oc, "iv",
qcrypto_secret_prop_get_iv,
- qcrypto_secret_prop_set_iv,
- NULL);
+ qcrypto_secret_prop_set_iv);
}