]> git.proxmox.com Git - mirror_qemu.git/blobdiff - crypto/secret.c
Merge remote-tracking branch 'remotes/kraxel/tags/ui-20200515-pull-request' into...
[mirror_qemu.git] / crypto / secret.c
index 30294b3229e8dac23a85b57c0215b0e774c9a116..3107aecb474f3728badafbb6bf3acd6ded4996ac 100644 (file)
@@ -6,7 +6,7 @@
  * 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
@@ -72,10 +72,12 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret,
                                    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;
@@ -83,27 +85,27 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret,
     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,
@@ -111,11 +113,11 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret,
                              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) {
@@ -124,7 +126,7 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret,
                                     &ciphertextlen,
                                     errp);
         if (!ciphertext) {
-            goto cleanup;
+            return;
         }
         plaintext = g_new0(uint8_t, ciphertextlen + 1);
     } else {
@@ -136,8 +138,7 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret,
                                plaintext,
                                ciphertextlen,
                                errp) < 0) {
-        plaintext = NULL;
-        goto cleanup;
+        return;
     }
 
     if (plaintext[ciphertextlen - 1] > 16 ||
@@ -145,9 +146,7 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret,
         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
@@ -156,14 +155,8 @@ static void qcrypto_secret_decrypt(QCryptoSecret *secret,
     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);
 }
 
 
@@ -211,7 +204,7 @@ qcrypto_secret_prop_set_loaded(Object *obj,
             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);
@@ -228,6 +221,7 @@ qcrypto_secret_prop_set_loaded(Object *obj,
         secret->rawlen = inputlen;
     } else {
         g_free(secret->rawdata);
+        secret->rawdata = NULL;
         secret->rawlen = 0;
     }
 }
@@ -238,7 +232,7 @@ qcrypto_secret_prop_get_loaded(Object *obj,
                                Error **errp G_GNUC_UNUSED)
 {
     QCryptoSecret *secret = QCRYPTO_SECRET(obj);
-    return secret->data != NULL;
+    return secret->rawdata != NULL;
 }
 
 
@@ -375,30 +369,24 @@ qcrypto_secret_class_init(ObjectClass *oc, void *data)
 
     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);
 }