From nobody Thu Feb 12 16:48:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1770906114; cv=none; d=zohomail.com; s=zohoarc; b=VsGDQIpvRk4zdBq8NffBsqRnGMwtfdhBMx3OceKu72w8+JvKVRuwFBM2MoNpQCNp3GEJr3CXlQA+0qgTxCrwaN25CAaZTRxXbml5IUP4Hkj+kv/+Z/6Nld7lB2YiXjaTQ8B/tt0gZlt274BmSLtvdNydexX5kwnJmV5eSocrsow= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770906114; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=8lx+wkL/wAUZywaI7GnDV5LAlwXs2qP3PnHSvN/W8wc=; b=co7muJhk3QGTNe1k63g/70u9/yIC4N562MbxUnCsAS0pNETyQ8VK1T5a6/7lTS2m4e6GzqO1bfZAN5vsrtZtiYYJkXde2Dfy2JFWeDkb0QPLZcWoK8XbWHyg9D9/1mNyaWESNNv+9/Gco8hnOK9Q2bTPegNEsGNjVaSNF67lL0M= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1770906114344195.39548244679827; Thu, 12 Feb 2026 06:21:54 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 10B604415A; Thu, 12 Feb 2026 09:21:53 -0500 (EST) Received: from [172.19.199.6] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id E455544FED; Thu, 12 Feb 2026 07:53:18 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 0B62D4555E; Thu, 12 Feb 2026 07:51:35 -0500 (EST) Received: from mx1.osci.io (unknown [8.43.85.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id F057D46300 for ; Thu, 12 Feb 2026 07:40:11 -0500 (EST) Received: by mx1.osci.io (Postfix, from userid 995) id 05EC328C7D; Tue, 10 Feb 2026 12:56:54 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx1.osci.io (Postfix) with ESMTPS id 2AF8B28C7B for ; Tue, 10 Feb 2026 12:56:53 -0500 (EST) Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-410-pmwheDxdNoO2LlbSzEjcvQ-1; Tue, 10 Feb 2026 12:56:51 -0500 Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-81f3c36dd2cso1178456b3a.2 for ; Tue, 10 Feb 2026 09:56:51 -0800 (PST) Received: from armenon-kvm.armenon-thinkpadp16vgen1.bengluru.csb ([49.36.106.234]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-824418a70fesm13782658b3a.45.2026.02.10.09.56.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 09:56:49 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746212; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8lx+wkL/wAUZywaI7GnDV5LAlwXs2qP3PnHSvN/W8wc=; b=bpyw51b1usoC3J1Z4zN6wnPmEe1+3gRtCeKi8O+C+6yafQz1vS2C2GMJ8glUg++S6XbCqS EqLGeVPbU96G1OsHRedBMsb4wDX+rBfjogyl8JZYAdm4vRopRfwW+E0pDVrjPoqTbhcZze GXg552WCNTdVgEseSmaxufGd43Tkniw= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746212; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8lx+wkL/wAUZywaI7GnDV5LAlwXs2qP3PnHSvN/W8wc=; b=bpyw51b1usoC3J1Z4zN6wnPmEe1+3gRtCeKi8O+C+6yafQz1vS2C2GMJ8glUg++S6XbCqS EqLGeVPbU96G1OsHRedBMsb4wDX+rBfjogyl8JZYAdm4vRopRfwW+E0pDVrjPoqTbhcZze GXg552WCNTdVgEseSmaxufGd43Tkniw= X-MC-Unique: pmwheDxdNoO2LlbSzEjcvQ-1 X-Mimecast-MFC-AGG-ID: pmwheDxdNoO2LlbSzEjcvQ_1770746210 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770746210; x=1771351010; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=8lx+wkL/wAUZywaI7GnDV5LAlwXs2qP3PnHSvN/W8wc=; b=rzmP3l5G/oBS6W87ZjnWYlIMeUn/MuJkOVf99vVPwoJsqjcOYidKyn5yybwqZx6+wi B994vaxQ5PiwaGUh/Z1s1o75Xt8Ok2KxO3XLsUIfyoK4QEkkHtmU2g+awcw+1isMAFm1 PvrvBQOKezYMR6nJelKBJRmUqZwpar0458OB8EYfKWPz7XY7M2/xy7g5hITtUaSesMjX whTXdmdsqNsgZ941Edt3kkDRPxmoGsFHAm0ERqbKj92nTsWy/GmztH0UWl4k/AvV2HsH +QJrgmEImyQqFvVlIC7fE4JZF5U2oJOR8/3quo123Gz/c1pFpFCICy0lsKb2OIRSV+O0 1Zhg== X-Gm-Message-State: AOJu0Yz+Dais5itcYinJFjK6HY+5B6qktv39AtxAfABuBvQ9Lz+O/7yn VxSUc21eru6P1awZW/gOlKquks3K1INkRO5QljTEucF/ISfAHdWTqbL/TMmrwprS4s0bHdz3vRt Y3iSXM1EdujywQPOW04jNJif876jI+JbtwHTJnYatl6cseG6s+YUoHqz+xaF7SnOvK8OHPoYADJ s/YAdSOFIoKeQq3wnQ1zki7utFJEltv9xr3Jlru6MqIA== X-Gm-Gg: AZuq6aJG+dbsN/DQuZZ8GO7rjz2tVRck2ecfR7TWP793AhSf/wwBalyRPKP7+NQAaDL JKstfzUUhGjzBbfebPf1p5yq374zl8xjAjxkjOq3O6mk++cR/WgheMwBoGnR4Mm6v4SjMhpijdr uu01NveMgG7X9oLqMu5Aym0qWVCiOYFGkXVmpH2B8OdACxIUWB6iAZHgnw04Ez4OWQlAv2bM55Y rjE53D4KcWQ1qw0AH+g1SfU0VxueyNAXsSIHFJ+yaMa9KD8tHJEClgjIICdfEu3Xhb/ytfhBsHu oMlMtiupPMLriq4Dzmx5xt7yWxv8IE1ZHCkQTcmVXtijDtYHy9st9uBvjL2nijp7h5afXmObaRM mJ/55rWPF5S8AJwycIISZJ9fZKfu0KQs6fsS1s+uHBo+grAHam4+Kwr1j/+OK40616hxwDQ== X-Received: by 2002:a05:6a00:ab86:b0:81f:9c54:65df with SMTP id d2e1a72fcca58-82441754f9bmr12479548b3a.50.1770746209960; Tue, 10 Feb 2026 09:56:49 -0800 (PST) X-Received: by 2002:a05:6a00:ab86:b0:81f:9c54:65df with SMTP id d2e1a72fcca58-82441754f9bmr12479534b3a.50.1770746209367; Tue, 10 Feb 2026 09:56:49 -0800 (PST) To: devel@lists.libvirt.org Subject: [PATCH v6 1/6] util: Add support for GnuTLS decryption Date: Tue, 10 Feb 2026 23:26:38 +0530 Message-ID: <20260210175643.23351-2-armenon@redhat.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20260210175643.23351-1-armenon@redhat.com> References: <20260210175643.23351-1-armenon@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: kTk_Ho-R3ZbEf4ZRm4QHZAuvMgYp1R2iH2UkD0HjKLY_1770746210 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: FVE4XUGZAVX53EERNAZL43MTB7IHDWWN X-Message-ID-Hash: FVE4XUGZAVX53EERNAZL43MTB7IHDWWN X-MailFrom: armenon@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Arun Menon X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Arun Menon via Devel Reply-To: Arun Menon X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1770906124896158500 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Arun Menon Adds `virCryptoDecryptDataAESgnutls` and `virCryptoDecryptData` as wrapper functions for GnuTLS decryption. These functions are the inverse of the existing GnuTLS encryption wrappers. This commit also includes a corresponding test case to validate data decryp= tion. Signed-off-by: Arun Menon Reviewed-by: Peter Krempa --- src/libvirt_private.syms | 1 + src/util/vircrypto.c | 126 ++++++++++++++++++++++++++++++++++++++- src/util/vircrypto.h | 8 +++ tests/vircryptotest.c | 65 ++++++++++++++++++++ 4 files changed, 199 insertions(+), 1 deletion(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d81b30f0b6..40af831070 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2248,6 +2248,7 @@ virConfWriteMem; =20 =20 # util/vircrypto.h +virCryptoDecryptData; virCryptoEncryptData; virCryptoHashBuf; virCryptoHashString; diff --git a/src/util/vircrypto.c b/src/util/vircrypto.c index 3ce23264ca..00f723bb75 100644 --- a/src/util/vircrypto.c +++ b/src/util/vircrypto.c @@ -98,7 +98,7 @@ virCryptoHashString(virCryptoHash hash, } =20 =20 -/* virCryptoEncryptDataAESgntuls: +/* virCryptoEncryptDataAESgnutls: * * Performs the AES gnutls encryption * @@ -233,3 +233,127 @@ virCryptoEncryptData(virCryptoCipher algorithm, _("algorithm=3D%1$d is not supported"), algorithm); return -1; } + +/* virCryptoDecryptDataAESgnutls: + * + * Performs the AES gnutls decryption + * + * Same input as virCryptoDecryptData, except the algorithm is replaced + * by the specific gnutls algorithm. + * + * Decrypts the @data buffer using the @deckey and if available the @iv + * + * Returns 0 on success with the plaintext being filled. It is the + * caller's responsibility to clear and free it. Returns -1 on failure + * w/ error set. + */ +static int +virCryptoDecryptDataAESgnutls(gnutls_cipher_algorithm_t gnutls_dec_alg, + uint8_t *deckey, + size_t deckeylen, + uint8_t *iv, + size_t ivlen, + uint8_t *data, + size_t datalen, + uint8_t **plaintextret, + size_t *plaintextlenret) +{ + int rc; + uint8_t padding_length; + gnutls_cipher_hd_t handle =3D NULL; + gnutls_datum_t dec_key =3D { .data =3D deckey, .size =3D deckeylen }; + gnutls_datum_t iv_buf =3D { .data =3D iv, .size =3D ivlen }; + g_autofree uint8_t *plaintext =3D NULL; + size_t plaintextlen; + + if ((rc =3D gnutls_cipher_init(&handle, gnutls_dec_alg, + &dec_key, &iv_buf)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to initialize cipher: '%1$s'"), + gnutls_strerror(rc)); + return -1; + } + + plaintext =3D g_memdup2(data, datalen); + plaintextlen =3D datalen; + if (plaintextlen =3D=3D 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("decrypted data has zero length")); + goto error; + } + rc =3D gnutls_cipher_decrypt(handle, plaintext, plaintextlen); + gnutls_cipher_deinit(handle); + if (rc < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("failed to decrypt the data: '%1$s'"), + gnutls_strerror(rc)); + goto error; + } + /* Before encryption, padding is added to the data. + * The last byte indicates the padding length, because in PKCS#7, all + * padding bytes are set to the padding length value. + */ + padding_length =3D plaintext[plaintextlen - 1]; + if (padding_length > plaintextlen) { + virReportError(VIR_ERR_INVALID_SECRET, "%s", + _("decrypted data has invalid padding")); + goto error; + } + *plaintextlenret =3D plaintextlen - padding_length; + *plaintextret =3D g_steal_pointer(&plaintext); + return 0; + error: + virSecureErase(plaintext, plaintextlen); + return -1; +} + +/* virCryptoDecryptData: + * @algorithm: algorithm desired for decryption + * @deckey: decryption key + * @deckeylen: decryption key length + * @iv: initialization vector + * @ivlen: length of initialization vector + * @data: data to decrypt + * @datalen: length of data + * @plaintext: stream of bytes allocated to store plaintext + * @plaintextlen: size of the stream of bytes + * Returns 0 on success, -1 on failure with error set + */ +int +virCryptoDecryptData(virCryptoCipher algorithm, + uint8_t *deckey, + size_t deckeylen, + uint8_t *iv, + size_t ivlen, + uint8_t *data, + size_t datalen, + uint8_t **plaintext, + size_t *plaintextlen) +{ + switch (algorithm) { + case VIR_CRYPTO_CIPHER_AES256CBC: + if (deckeylen !=3D 32) { + virReportError(VIR_ERR_INVALID_ARG, + _("AES256CBC decryption invalid keylen=3D%1$zu= "), + deckeylen); + return -1; + } + if (ivlen !=3D 16) { + virReportError(VIR_ERR_INVALID_ARG, + _("AES256CBC initialization vector invalid len= =3D%1$zu"), + ivlen); + return -1; + } + return virCryptoDecryptDataAESgnutls(GNUTLS_CIPHER_AES_256_CBC, + deckey, deckeylen, iv, ivlen, + data, datalen, + plaintext, plaintextlen); + case VIR_CRYPTO_CIPHER_NONE: + case VIR_CRYPTO_CIPHER_LAST: + break; + } + + virReportError(VIR_ERR_INVALID_ARG, + _("algorithm=3D%1$d is not supported"), algorithm); + return -1; +} diff --git a/src/util/vircrypto.h b/src/util/vircrypto.h index 5f079ac335..2e8557839d 100644 --- a/src/util/vircrypto.h +++ b/src/util/vircrypto.h @@ -61,3 +61,11 @@ int virCryptoEncryptData(virCryptoCipher algorithm, uint8_t **ciphertext, size_t *ciphertextlen) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6) ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(9) G_GNUC_WARN_UNUSED_RESULT; + +int virCryptoDecryptData(virCryptoCipher algorithm, + uint8_t *deckey, size_t deckeylen, + uint8_t *iv, size_t ivlen, + uint8_t *data, size_t datalen, + uint8_t **plaintext, size_t *plaintextlen) + ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(6) + ATTRIBUTE_NONNULL(8) ATTRIBUTE_NONNULL(9) G_GNUC_WARN_UNUSED_RESULT; diff --git a/tests/vircryptotest.c b/tests/vircryptotest.c index 9ffe70756e..864fa8838d 100644 --- a/tests/vircryptotest.c +++ b/tests/vircryptotest.c @@ -62,6 +62,14 @@ struct testCryptoEncryptData { size_t ciphertextlen; }; =20 +struct testCryptoDecryptData { + virCryptoCipher algorithm; + uint8_t *input; + size_t inputlen; + uint8_t *plaintext; + size_t plaintextlen; +}; + static int testCryptoEncrypt(const void *opaque) { @@ -101,6 +109,44 @@ testCryptoEncrypt(const void *opaque) return 0; } =20 +static int +testCryptoDecrypt(const void *opaque) +{ + const struct testCryptoDecryptData *data =3D opaque; + g_autofree uint8_t *deckey =3D NULL; + size_t deckeylen =3D 32; + g_autofree uint8_t *iv =3D NULL; + size_t ivlen =3D 16; + g_autofree uint8_t *plaintext =3D NULL; + size_t plaintextlen =3D 0; + + deckey =3D g_new0(uint8_t, deckeylen); + iv =3D g_new0(uint8_t, ivlen); + + if (virRandomBytes(deckey, deckeylen) < 0 || + virRandomBytes(iv, ivlen) < 0) { + fprintf(stderr, "Failed to generate random bytes\n"); + return -1; + } + + if (virCryptoDecryptData(data->algorithm, deckey, deckeylen, iv, ivlen, + data->input, data->inputlen, + &plaintext, &plaintextlen) < 0) + return -1; + + if (data->plaintextlen !=3D plaintextlen) { + fprintf(stderr, "Expected plaintexlen(%zu) doesn't match (%zu)\n", + data->plaintextlen, plaintextlen); + return -1; + } + + if (memcmp(data->plaintext, plaintext, plaintextlen)) { + fprintf(stderr, "Expected plaintext doesn't match\n"); + return -1; + } + + return 0; +} =20 static int mymain(void) @@ -155,7 +201,26 @@ mymain(void) =20 #undef VIR_CRYPTO_ENCRYPT =20 +#define VIR_CRYPTO_DECRYPT(a, n, i, il, c, cl) \ + do { \ + struct testCryptoDecryptData data =3D { \ + .algorithm =3D a, \ + .input =3D i, \ + .inputlen =3D il, \ + .plaintext =3D c, \ + .plaintextlen =3D cl, \ + }; \ + if (virTestRun("Decrypt " n, testCryptoDecrypt, &data) < 0) \ + ret =3D -1; \ + } while (0) + + VIR_CRYPTO_DECRYPT(VIR_CRYPTO_CIPHER_AES256CBC, "aes256cbc", + expected_ciphertext, 16, secretdata, 7); + +#undef VIR_CRYPTO_DECRYPT + return ret =3D=3D 0 ? EXIT_SUCCESS : EXIT_FAILURE; + } =20 /* Forces usage of not so random virRandomBytes */ --=20 2.51.1 From nobody Thu Feb 12 16:48:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1770902013; cv=none; d=zohomail.com; s=zohoarc; b=hmHi12xjfGs71+GwMgo+azdJ2rdzZJtJyixJyYQOO2O3gu40bwsN1U4UuZKlxn3LhafPHBzGJYO/gsULP4zVK6zN+JYvhgan9U7HC0UWdeTXMmomc0YJhcFOnx5bQO3B+Wu005ehyoXsg0DR3m503YAFgnojkes8291c1xE9KCA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770902013; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=jPF+25NsYehcHr5vrklk08W4cdaPdaFZNS1zeswPnos=; b=fEP48pzQPapACDOqV2SCE9gcuDtuxPHaKaF3iN4Y/Gv2nEnbUsK+dpD7HioHVXGpo8ODwSP4OG7DQE+ny3TzML0A9TuRPXj/GC7Qx9DJUGWTE/L9/A/N+hjjgR14VHGE695Z2Lg9godS7xxAUTvM3qsc4HfZq3zG/spTCC2O3/4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1770902013587130.79089378818685; Thu, 12 Feb 2026 05:13:33 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 14E17440B4; Thu, 12 Feb 2026 08:13:33 -0500 (EST) Received: from [172.19.199.6] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id C1A2445A64; Thu, 12 Feb 2026 07:52:33 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 9943D454A7; Thu, 12 Feb 2026 07:51:22 -0500 (EST) Received: from mx1.osci.io (unknown [8.43.85.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 33F9445B07 for ; Thu, 12 Feb 2026 07:39:37 -0500 (EST) Received: by mx1.osci.io (Postfix, from userid 995) id 304FD28C82; Tue, 10 Feb 2026 12:56:58 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx1.osci.io (Postfix) with ESMTPS id 6904328C80 for ; Tue, 10 Feb 2026 12:56:57 -0500 (EST) Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-517-XreAXhG4Ol-su63KTC4REg-1; Tue, 10 Feb 2026 12:56:52 -0500 Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-81f3f3af760so12699744b3a.1 for ; Tue, 10 Feb 2026 09:56:52 -0800 (PST) Received: from armenon-kvm.armenon-thinkpadp16vgen1.bengluru.csb ([49.36.106.234]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-824418a70fesm13782658b3a.45.2026.02.10.09.56.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 09:56:50 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746216; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jPF+25NsYehcHr5vrklk08W4cdaPdaFZNS1zeswPnos=; b=jFNRg9Mtn54/EEMjRW0ZgK1i6RQRMV/UZCzHKoixB8ihbAf3pj6LM8jc+pG06uZLEVbyoB m0y6MPLcdKendeAJMvC+yfB5a7K4oF9TiUIXebrbZfIyQ6KX0gtMER5BwMV2gnFXfb4v3J XGF/uSWeDzFycT6mJyQpaAQAzHBDgtg= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746217; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jPF+25NsYehcHr5vrklk08W4cdaPdaFZNS1zeswPnos=; b=Fbl13kUAi54gafO6C8iLQ5A+tXPxSbOc/nJf4s2WTVTjq2OWJAGIhf3x/4hSIswR3UouKo S3zPNJZ4mLxGUHmK0DJTtZrLIR9oB5U2I8Yl+rvReEjj1k3BR9Hrj93LHUviWAderv7aO1 a6V7fgki6IpzhOm1r2Bn7PFoTojqsMU= X-MC-Unique: XreAXhG4Ol-su63KTC4REg-1 X-Mimecast-MFC-AGG-ID: XreAXhG4Ol-su63KTC4REg_1770746212 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770746211; x=1771351011; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=jPF+25NsYehcHr5vrklk08W4cdaPdaFZNS1zeswPnos=; b=kYTIvAlulba6iXdrUGHd62dxwlCSG32tYi+XdOtkWgVDKjy1JCxv/NjyIuciv9MPrg SganiRd8ngvcQS9tlojFKiSZMD1Ayivvp0PsuejobpPm7Pwng0y2M+eJmeciaa2FYjIH C+eFK+4BsmCCPjLbo4W9d0cWHhl/uSYEXL7c+WnZQ0xQvILkh955bBnYbAPNYTSbNOc7 l8V1LKeJ/+wiOXUh5Grz04iADe/ANFjAWfCGe5odMrfGMvZ8rExgv/ik4975xiL1z47M ZOmFoOZ0pyS80NwRCPd5uhwyIsI8fdKimcwPrI5BgF/uVCOt44vCElLjgP3xgYWwlBTD YK3g== X-Gm-Message-State: AOJu0Yw8Ceap1OCCHZNh/seZoA0iqS/TKo6H6BMORLfoSJpBNBApCeME lc+JB7/XQE1Z48J+NNEHo2txUOnu8hEna8jsB4fbdzz+9/geTTC754KICzTdN3nAyuBGO9mn1Aq zJkyMPm6UBr4d4fVCRcn6tUj9pXwLL1jbXvLjlZOP/Q0qPYv1VQ9q32yLWBLzH2PepSn+6Q7vkf vXHg5CzGByE+9/Oj9Ly5Z16HbVso3WL33ynZo8WekVKQ== X-Gm-Gg: AZuq6aJeGbjNVYrO3Nq61cggw30YUGgEdFNWkB9t1ieI/W7AvMTFUX4J8KQbx6uxx68 2rlB/ZVgRLjRPzUVgj5RmZ+/7N1U02xWTvBWRfn1MRMggztYJcVVRtOjj/ZmjZmX/kvJFl7abrc E15unhhWarlPFUTuUNMrKSjXz+I+B1BUgpStLKtMGT7oNSliYZtgqofUJ9ZzMS3KBPkJDDyKQPH ZQSwio3XBQmCc9DJ3mH0DAJ5XN036EVrxhNblyE7jwubZVO0SQ6kwSrKyMpZNOECZTY0GGNf6jS fdTCwzw5o4B7dKuqq4cU1jHYYBVQXaNxavdApbkrUnd7GexJXsX3l9k8s2AZi3dpHyxnBornkCs yj2DkX+0bz6X2TNFWVE7j+zQRYFq01Mk9812qMwNfr8T+2bxv2wkJM762bqO8GI3NHIdHzw== X-Received: by 2002:aa7:8892:0:b0:823:bbb:76fb with SMTP id d2e1a72fcca58-82487ab3776mr3208785b3a.46.1770746211405; Tue, 10 Feb 2026 09:56:51 -0800 (PST) X-Received: by 2002:aa7:8892:0:b0:823:bbb:76fb with SMTP id d2e1a72fcca58-82487ab3776mr3208767b3a.46.1770746210916; Tue, 10 Feb 2026 09:56:50 -0800 (PST) To: devel@lists.libvirt.org Subject: [PATCH v6 2/6] secret: Set up default encryption secret key for the virtsecretd service Date: Tue, 10 Feb 2026 23:26:39 +0530 Message-ID: <20260210175643.23351-3-armenon@redhat.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20260210175643.23351-1-armenon@redhat.com> References: <20260210175643.23351-1-armenon@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: HD4IHUzVW0ZkOt6UlQAfKplafw7P0vj-3o9ep87w8Hs_1770746212 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: NMD6WLMD6AOQLIQQVUD7E74YLQZF733J X-Message-ID-Hash: NMD6WLMD6AOQLIQQVUD7E74YLQZF733J X-MailFrom: armenon@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Arun Menon X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Arun Menon via Devel Reply-To: Arun Menon X-ZohoMail-DKIM: fail (found 2 invalid signatures) X-ZM-MESSAGEID: 1770902024691154100 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Arun Menon This commit sets the foundation for encrypting the libvirt secrets by provi= ding a secure way to pass a secret encryption key to the virtsecretd service. A random secret key is generated using the new virt-secret-init-encryption service. This key can be consumed by the virtsecretd service. By using the "Before=3D" directive in the new virt-secret-init-encryption service and using "Requires=3D" directive in the virtsecretd service, we make sure that the daemon is run only after we have an encrypted secret key file generated and placed in /var/lib/libvirt/secrets. The virtsecretd service can then read the key from CREDENTIALS_DIRECTORY. [= 1] This setup therefore provides a default key out-of-the-box for initial use. A subsequent commit will introduce the logic for virtsecretd to access and use this key via the $CREDENTIALS_DIRECTORY environment varia= ble. [2] [1] https://www.freedesktop.org/software/systemd/man/latest/systemd-creds.h= tml [2] https://systemd.io/CREDENTIALS/ Signed-off-by: Arun Menon Reviewed-by: Peter Krempa --- libvirt.spec.in | 5 +++++ src/meson.build | 1 + src/remote/libvirtd.service.in | 4 ++++ src/secret/meson.build | 13 +++++++++++++ src/secret/virt-secret-init-encryption.service.in | 8 ++++++++ src/secret/virtsecretd.service.extra.in | 8 ++++++++ 6 files changed, 39 insertions(+) create mode 100644 src/secret/virt-secret-init-encryption.service.in diff --git a/libvirt.spec.in b/libvirt.spec.in index 22c9975d9f..34a47d689c 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -1891,13 +1891,16 @@ exit 0 %pre daemon-driver-secret %libvirt_sysconfig_pre virtsecretd %libvirt_systemd_unix_pre virtsecretd +%libvirt_systemd_oneshot_pre virt-secret-init-encryption =20 %posttrans daemon-driver-secret %libvirt_sysconfig_posttrans virtsecretd %libvirt_systemd_unix_posttrans virtsecretd +%libvirt_systemd_unix_posttrans virt-secret-init-encryption =20 %preun daemon-driver-secret %libvirt_systemd_unix_preun virtsecretd +%libvirt_systemd_unix_preun virt-secret-init-encryption =20 %pre daemon-driver-storage-core %libvirt_sysconfig_pre virtstoraged @@ -2249,11 +2252,13 @@ exit 0 %{_datadir}/augeas/lenses/virtsecretd.aug %{_datadir}/augeas/lenses/tests/test_virtsecretd.aug %{_unitdir}/virtsecretd.service +%{_unitdir}/virt-secret-init-encryption.service %{_unitdir}/virtsecretd.socket %{_unitdir}/virtsecretd-ro.socket %{_unitdir}/virtsecretd-admin.socket %attr(0755, root, root) %{_sbindir}/virtsecretd %dir %attr(0700, root, root) %{_sysconfdir}/libvirt/secrets/ +%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/secrets/ %ghost %dir %attr(0700, root, root) %{_rundir}/libvirt/secrets/ %{_libdir}/libvirt/connection-driver/libvirt_driver_secret.so %{_mandir}/man8/virtsecretd.8* diff --git a/src/meson.build b/src/meson.build index 16875622f4..cab52ce7a3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -833,6 +833,7 @@ if conf.has('WITH_LIBVIRTD') 'sbindir': sbindir, 'sysconfdir': sysconfdir, 'initconfdir': initconfdir, + 'localstatedir': localstatedir, 'name': unit['name'], 'service': unit['service'], 'SERVICE': unit['service'].to_upper(), diff --git a/src/remote/libvirtd.service.in b/src/remote/libvirtd.service.in index b0a062e885..7965010a0a 100644 --- a/src/remote/libvirtd.service.in +++ b/src/remote/libvirtd.service.in @@ -12,6 +12,8 @@ After=3Dlibvirtd.socket After=3Dlibvirtd-ro.socket After=3Dlibvirtd-admin.socket Requires=3Dvirtlogd.socket +Requires=3Dvirt-secret-init-encryption.service +After=3Dvirt-secret-init-encryption.service Wants=3Dvirtlockd.socket After=3Dvirtlogd.socket After=3Dvirtlockd.socket @@ -29,6 +31,8 @@ Conflicts=3Dxendomains.service Type=3Dnotify-reload Environment=3DLIBVIRTD_ARGS=3D"--timeout 120" EnvironmentFile=3D-@initconfdir@/libvirtd +Environment=3DSECRETS_ENCRYPTION_KEY=3D%d/secrets-encryption-key +LoadCredentialEncrypted=3Dsecrets-encryption-key:@localstatedir@/lib/libvi= rt/secrets/secrets-encryption-key ExecStart=3D@sbindir@/libvirtd $LIBVIRTD_ARGS ExecReload=3D/bin/kill -HUP $MAINPID KillMode=3Dprocess diff --git a/src/secret/meson.build b/src/secret/meson.build index 3b859ea7b4..b69abe32ab 100644 --- a/src/secret/meson.build +++ b/src/secret/meson.build @@ -31,6 +31,18 @@ if conf.has('WITH_SECRETS') 'name': 'virtsecretd', } =20 + virt_secret_init_encryption_conf =3D configuration_data() + + virt_secret_init_encryption_conf.set('localstatedir', localstatedir) + + configure_file( + input: 'virt-secret-init-encryption.service.in', + output: '@0@.service'.format('virt-secret-init-encryption'), + configuration: virt_secret_init_encryption_conf, + install: true, + install_dir: unitdir, + ) + virt_daemon_units +=3D { 'service': 'virtsecretd', 'name': 'secret', @@ -50,5 +62,6 @@ if conf.has('WITH_SECRETS') virt_install_dirs +=3D [ confdir / 'secrets', runstatedir / 'libvirt' / 'secrets', + localstatedir / 'lib' / 'libvirt' / 'secrets', ] endif diff --git a/src/secret/virt-secret-init-encryption.service.in b/src/secret= /virt-secret-init-encryption.service.in new file mode 100644 index 0000000000..8fd54002a0 --- /dev/null +++ b/src/secret/virt-secret-init-encryption.service.in @@ -0,0 +1,8 @@ +[Unit] +Before=3Dvirtsecretd.service +Before=3Dlibvirtd.service +ConditionPathExists=3D!@localstatedir@/lib/libvirt/secrets/secrets-encrypt= ion-key + +[Service] +Type=3Doneshot +ExecStart=3D/usr/bin/sh -c 'umask 0077 && (dd if=3D/dev/random status=3Dno= ne bs=3D32 count=3D1 | systemd-creds encrypt --name=3Dsecrets-encryption-ke= y - @localstatedir@/lib/libvirt/secrets/secrets-encryption-key)' diff --git a/src/secret/virtsecretd.service.extra.in b/src/secret/virtsecre= td.service.extra.in index 1fc8c672f7..116458b22a 100644 --- a/src/secret/virtsecretd.service.extra.in +++ b/src/secret/virtsecretd.service.extra.in @@ -1,2 +1,10 @@ # The contents of this unit will be merged into a base template. # Additional units might be merged as well. See meson.build for details. +# +[Unit] +Requires=3Dvirt-secret-init-encryption.service +After=3Dvirt-secret-init-encryption.service + +[Service] +LoadCredentialEncrypted=3Dsecrets-encryption-key:@localstatedir@/lib/libvi= rt/secrets/secrets-encryption-key +Environment=3DSECRETS_ENCRYPTION_KEY=3D%d/secrets-encryption-key --=20 2.51.1 From nobody Thu Feb 12 16:48:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1770905877; cv=none; d=zohomail.com; s=zohoarc; b=XGzk6TsjK78vFwfI436aQVa4nj3zrCOZaTHiQtQnvJuQu6eBKMRW7oG+eIz2Ax/fZFtuoJ0QIF4lmAscHYRM6hQ3hBwrs204JKkxBQeNRUiBZILK5Q9fBZXbSKoG6t0KCTb/zp0LRy2dJYyg0CgA6rXw0yXwBUYejyA2w0YlDoc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770905877; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=XiNQITEAlJ1YgCKKsP14FGv0FvEJpwQEEpEGzP5mK/0=; b=OFuUmpi812gK5PzVksnkza2qmiBWYO3ZzwLXbJ6rXkfH7FVlEjPQnMWsD+rfl3AZiwE5EjHBEcdEDftpR8QopLevtXLh9Qk7gUIWUUxYseXHGnVNRN1yoQmxTbRxxWnV8r51m/QXJaaIQIa17WfLt0ky2U5KI4EeqVlOpRRKWZs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1770905877221105.73159994012656; Thu, 12 Feb 2026 06:17:57 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 9E63B41AFD; Thu, 12 Feb 2026 09:17:56 -0500 (EST) Received: from [172.19.199.6] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 6E892446CB; Thu, 12 Feb 2026 07:53:15 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id DE4CE41837; Thu, 12 Feb 2026 07:51:43 -0500 (EST) Received: from mx1.osci.io (unknown [8.43.85.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id BCD4D463D4 for ; Thu, 12 Feb 2026 07:40:14 -0500 (EST) Received: by mx1.osci.io (Postfix, from userid 995) id 4CD2828C81; Tue, 10 Feb 2026 12:56:58 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx1.osci.io (Postfix) with ESMTPS id 1093528C7E for ; Tue, 10 Feb 2026 12:56:57 -0500 (EST) Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-661-9OWJG7fdOaeTBg-PfTZOiw-1; Tue, 10 Feb 2026 12:56:54 -0500 Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-c54e81eeab9so4045920a12.3 for ; Tue, 10 Feb 2026 09:56:54 -0800 (PST) Received: from armenon-kvm.armenon-thinkpadp16vgen1.bengluru.csb ([49.36.106.234]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-824418a70fesm13782658b3a.45.2026.02.10.09.56.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 09:56:52 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746216; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XiNQITEAlJ1YgCKKsP14FGv0FvEJpwQEEpEGzP5mK/0=; b=UoDawS62hw8MvZD3bjZmGnq8VWp8jKJ5+8udbLfS2Y2m/IYur/hpWUgZY1g+CcxgHeSGK6 3zKQFY3mx+hIz/5ckZSleVu5igVOgc6ZyMYTOFhyHZCOGNf0EN2cWHSVCXe/P0gizUVf+1 lqVgbdwRXENYUsyiWWykHK6jaiFUEjI= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746216; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=XiNQITEAlJ1YgCKKsP14FGv0FvEJpwQEEpEGzP5mK/0=; b=UoDawS62hw8MvZD3bjZmGnq8VWp8jKJ5+8udbLfS2Y2m/IYur/hpWUgZY1g+CcxgHeSGK6 3zKQFY3mx+hIz/5ckZSleVu5igVOgc6ZyMYTOFhyHZCOGNf0EN2cWHSVCXe/P0gizUVf+1 lqVgbdwRXENYUsyiWWykHK6jaiFUEjI= X-MC-Unique: 9OWJG7fdOaeTBg-PfTZOiw-1 X-Mimecast-MFC-AGG-ID: 9OWJG7fdOaeTBg-PfTZOiw_1770746213 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770746213; x=1771351013; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=XiNQITEAlJ1YgCKKsP14FGv0FvEJpwQEEpEGzP5mK/0=; b=SprJ9e670dTZJBJSnvd27e7b8P4D6CcfEvf/gHOQv6BmpNUg8xFWVTEDB5pmd1QJcT BAeKxhxErn77+qDJ/2bdtimiV+Cv/RUi0s82Vjw5hZ373+lJoPpB1o5kHa7txz7T9vtF W58HcZ4a88McPn5YpRC/bzNs+iP5gZAYh5Tj+WibVHEUKXhNrMY24R7ba+yFuYZfQZ+K rx4mNlz8MW1reYd83X3dpGURkrc9R/qFFXKWjAxRlw5FO9ikGEqo6eETQtMaqW+8UY32 WJdoyDE6V/M/QQdt2DcthWNJtqqPOqVQhND5zUfyrg3Zwibs/L1IGCTHlHrGP7EzsDv1 0tLg== X-Gm-Message-State: AOJu0YzQ3NdafWKotjLXyb7H+27r+fPabnnbzGQoLY3XKaqJHcBiBNsX KEs2hoKYDw1q/c9dLdQf9KW+4HS7JRoh90onsqrGBEn6gmmq4osIc+hpWhY1fdCMVIM9M9EKPkZ nM0Sbmc/b5DI2g9OmZ4N0j+4aHCxz4slCnC5A7w91Cp5BMafrstBqHghRoXHtrXoWMkrBeb4wS8 W8kkXGUfNcc9z4m0cXFLaoL72JHcaEojIKLA8qbIhBZw== X-Gm-Gg: AZuq6aLj9rX4yUNxzzqp/SOKF6XtuVjPIdEmlW6mtohr2tIhRyeRPAC/UhlWLmQVAlP gqeEQG0jgNp31RA1p1ouMkt9hQjKC0ZwwDPLhmDbW8Z4xjjey4Qa94xTYO6/LlNg1iNndTI3hKm MbokeP8bYSwj8BH792BLLx771yhN/SisugBm2TkOLI1mH+ue20d99qITlQuh/BTwHqfJ8wBTtTc WDuV+HGIYd4CyxBlfdXBryd0N5J1Pkt6ugkav6hpe8baEybDYDy7FOpJRh7G/9ol5fjNrqy7A6+ SGeTl+8okTHoN6qxYiEB4Fm3ZBvnJ3ZiD6RtBBYTmgT6aRmB7mkApnMxdxv/Vvbl+n9vTEvqG1Q S+gXAI5HcZSg5Vjy/Y5bvtFrooJOzRfigiXjBbz0tn/oWZHY3+/v3QjMAtlo2aL1jwn0uow== X-Received: by 2002:a05:6a20:5681:b0:38e:77ab:e7c5 with SMTP id adf61e73a8af0-393af0b9085mr14564669637.45.1770746213160; Tue, 10 Feb 2026 09:56:53 -0800 (PST) X-Received: by 2002:a05:6a20:5681:b0:38e:77ab:e7c5 with SMTP id adf61e73a8af0-393af0b9085mr14564642637.45.1770746212522; Tue, 10 Feb 2026 09:56:52 -0800 (PST) To: devel@lists.libvirt.org Subject: [PATCH v6 3/6] secret: Add secret.conf configuration file and parse it Date: Tue, 10 Feb 2026 23:26:40 +0530 Message-ID: <20260210175643.23351-4-armenon@redhat.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20260210175643.23351-1-armenon@redhat.com> References: <20260210175643.23351-1-armenon@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: Q71UogOimJuOufUYIf_1swiooc8BfbanlEjvrIDZUrE_1770746213 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: D2LEJ77LC2527E754W7PGU4O2QDU5NRN X-Message-ID-Hash: D2LEJ77LC2527E754W7PGU4O2QDU5NRN X-MailFrom: armenon@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Arun Menon X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Arun Menon via Devel Reply-To: Arun Menon X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1770905889817154100 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Arun Menon A new configuration file called secret.conf is introduced to let the user configure the path to the secrets encryption key. This key will be used to encrypt/decrypt the secrets in libvirt. By default the path is set to the runtime directory /run/libvirt/secrets, and it is commented in the config file. After parsing the file, the virtsecretd driver checks if an encryption key is present in the path and is valid. If no encryption key is present in the path, then the service will by default use the encryption key stored in the CREDENTIALS_DIRECTORY. Add logic to parse the encryption key file and store the key. It also checks for the encrypt_data attribute in the config file. The encryption and decryption logic will be added in the subsequent patches. Signed-off-by: Arun Menon Reviewed-by: Peter Krempa --- include/libvirt/virterror.h | 1 + libvirt.spec.in | 3 + po/POTFILES | 1 + src/secret/libvirt_secrets.aug | 40 ++++++ src/secret/meson.build | 19 +++ src/secret/secret.conf.in | 14 ++ src/secret/secret_config.c | 179 +++++++++++++++++++++++++ src/secret/secret_config.h | 40 ++++++ src/secret/secret_driver.c | 11 ++ src/secret/test_libvirt_secrets.aug.in | 6 + src/util/virerror.c | 3 + 11 files changed, 317 insertions(+) create mode 100644 src/secret/libvirt_secrets.aug create mode 100644 src/secret/secret.conf.in create mode 100644 src/secret/secret_config.c create mode 100644 src/secret/secret_config.h create mode 100644 src/secret/test_libvirt_secrets.aug.in diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index f02da046a3..c1cac7a3dd 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -353,6 +353,7 @@ typedef enum { command within timeout (Since: = 11.2.0) */ VIR_ERR_AGENT_COMMAND_FAILED =3D 113, /* guest agent responded with fa= ilure to a command (Since: 11.2.0) */ + VIR_ERR_INVALID_ENCR_KEY_SECRET =3D 114, /* encryption key is invalid = (Since: 12.1.0) */ =20 # ifdef VIR_ENUM_SENTINELS VIR_ERR_NUMBER_LAST /* (Since: 5.0.0) */ diff --git a/libvirt.spec.in b/libvirt.spec.in index 34a47d689c..0ba7bf4197 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -2251,6 +2251,9 @@ exit 0 %config(noreplace) %{_sysconfdir}/libvirt/virtsecretd.conf %{_datadir}/augeas/lenses/virtsecretd.aug %{_datadir}/augeas/lenses/tests/test_virtsecretd.aug +%{_datadir}/augeas/lenses/libvirt_secrets.aug +%{_datadir}/augeas/lenses/tests/test_libvirt_secrets.aug +%config(noreplace) %{_sysconfdir}/libvirt/secret.conf %{_unitdir}/virtsecretd.service %{_unitdir}/virt-secret-init-encryption.service %{_unitdir}/virtsecretd.socket diff --git a/po/POTFILES b/po/POTFILES index c78d2b8000..0042ddad08 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -232,6 +232,7 @@ src/rpc/virnetsshsession.c src/rpc/virnettlscert.c src/rpc/virnettlsconfig.c src/rpc/virnettlscontext.c +src/secret/secret_config.c src/secret/secret_driver.c src/security/security_apparmor.c src/security/security_dac.c diff --git a/src/secret/libvirt_secrets.aug b/src/secret/libvirt_secrets.aug new file mode 100644 index 0000000000..8dda373e62 --- /dev/null +++ b/src/secret/libvirt_secrets.aug @@ -0,0 +1,40 @@ +(* /etc/libvirt/secret.conf *) + +module Libvirt_secrets =3D + autoload xfm + + let eol =3D del /[ \t]*\n/ "\n" + let value_sep =3D del /[ \t]*=3D[ \t]*/ " =3D " + let indent =3D del /[ \t]*/ "" + + let array_sep =3D del /,[ \t\n]*/ ", " + let array_start =3D del /\[[ \t\n]*/ "[ " + let array_end =3D del /\]/ "]" + + let str_val =3D del /\"/ "\"" . store /[^\"]*/ . del /\"/ "\"" + let bool_val =3D store /0|1/ + let int_val =3D store /[0-9]+/ + let str_array_element =3D [ seq "el" . str_val ] . del /[ \t\n]*/ "" + let str_array_val =3D counter "el" . array_start . ( str_array_element = . ( array_sep . str_array_element ) * ) ? . array_end + + let str_entry (kw:string) =3D [ key kw . value_sep . str_val ] + let bool_entry (kw:string) =3D [ key kw . value_sep . bool_val ] + let int_entry (kw:string) =3D [ key kw . value_sep . int_val ] + let str_array_entry (kw:string) =3D [ key kw . value_sep . str_array_va= l ] + + let secrets_entry =3D str_entry "secrets_encryption_key" + | bool_entry "encrypt_data" + + (* Each entry in the config is one of the following three ... *) + let entry =3D secrets_entry + let comment =3D [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \= t\n][^\n]*)?/ . del /\n/ "\n" ] + let empty =3D [ label "#empty" . eol ] + + let record =3D indent . entry . eol + + let lns =3D ( record | comment | empty ) * + + let filter =3D incl "/etc/libvirt/secret.conf" + . Util.stdexcl + + let xfm =3D transform lns filter diff --git a/src/secret/meson.build b/src/secret/meson.build index b69abe32ab..cfcc861f4f 100644 --- a/src/secret/meson.build +++ b/src/secret/meson.build @@ -1,5 +1,6 @@ secret_driver_sources =3D [ 'secret_driver.c', + 'secret_config.c', ] =20 driver_source_files +=3D files(secret_driver_sources) @@ -27,6 +28,24 @@ if conf.has('WITH_SECRETS') ], } =20 + secret_conf =3D configure_file( + input: 'secret.conf.in', + output: 'secret.conf', + copy: true + ) + virt_conf_files +=3D secret_conf + + virt_aug_files +=3D files('libvirt_secrets.aug') + + virt_test_aug_files +=3D { + 'name': 'test_libvirt_secrets.aug', + 'aug': files('test_libvirt_secrets.aug.in'), + 'conf': files('secret.conf.in'), + 'test_name': 'libvirt_secrets', + 'test_srcdir': meson.current_source_dir(), + 'test_builddir': meson.current_build_dir(), + } + virt_daemon_confs +=3D { 'name': 'virtsecretd', } diff --git a/src/secret/secret.conf.in b/src/secret/secret.conf.in new file mode 100644 index 0000000000..a231c48f8d --- /dev/null +++ b/src/secret/secret.conf.in @@ -0,0 +1,14 @@ +# +# Configuration file for the secrets driver. +# +# The secret encryption key is used to override default encryption +# key path. The user can create an encryption key and set the secret_encry= ption_key +# to the path on which it resides. +# The key must be 32-bytes long. +#secrets_encryption_key =3D "/run/libvirt/secrets/secret-encryption-key" + +# The encrypt_data setting is used to indicate if the encryption is on or = off. +# 0 indicates off and 1 indicates on. By default it is on +# if secrets_encryption_key is set to a non-NULL +# path, or if a systemd credential named "secrets-encryption-key" exists. +#encrypt_data =3D 1 diff --git a/src/secret/secret_config.c b/src/secret/secret_config.c new file mode 100644 index 0000000000..4e11bca1b6 --- /dev/null +++ b/src/secret/secret_config.c @@ -0,0 +1,179 @@ +/* + * secret_config.c: secret.conf config file handling + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#include +#include +#include "configmake.h" +#include "datatypes.h" +#include "virlog.h" +#include "virerror.h" +#include "virfile.h" +#include "virutil.h" +#include "virsecureerase.h" +#include "secret_config.h" + + +#define VIR_FROM_THIS VIR_FROM_SECRET + +VIR_LOG_INIT("secret.secret_config"); + +static virClass *virSecretDaemonConfigClass; +static void virSecretDaemonConfigDispose(void *obj); + +static int +virSecretConfigOnceInit(void) +{ + if (!VIR_CLASS_NEW(virSecretDaemonConfig, virClassForObject())) + return -1; + + return 0; +} + + +VIR_ONCE_GLOBAL_INIT(virSecretConfig); + + +int +virSecretDaemonConfigFilePath(bool privileged, char **configfile) +{ + if (privileged) { + *configfile =3D g_strdup(SYSCONFDIR "/libvirt/secret.conf"); + } else { + g_autofree char *configdir =3D NULL; + + configdir =3D virGetUserConfigDirectory(); + + *configfile =3D g_strdup_printf("%s/secret.conf", configdir); + } + + return 0; +} + + +static int +virSecretLoadDaemonConfig(virSecretDaemonConfig *cfg, + const char *filename) +{ + g_autoptr(virConf) conf =3D NULL; + int res; + + if (virFileExists(filename)) { + conf =3D virConfReadFile(filename, 0); + if (!conf) + return -1; + res =3D virConfGetValueBool(conf, "encrypt_data", &cfg->encryptDat= a); + if (res < 0) { + return -1; + } else if (res =3D=3D 1) { + cfg->encryptDataWasSet =3D true; + } else { + cfg->encryptDataWasSet =3D false; + } + + if (virConfGetValueString(conf, "secrets_encryption_key", + &cfg->secretsEncryptionKeyPath) < 0) { + return -1; + } + } + return 0; +} + + +static int +virGetSecretsEncryptionKey(virSecretDaemonConfig *cfg, + uint8_t **secretsEncryptionKey, + size_t *secretsKeyLen) +{ + VIR_AUTOCLOSE fd =3D -1; + int encryptionKeyLength; + + if ((encryptionKeyLength =3D virFileReadAll(cfg->secretsEncryptionKeyP= ath, + VIR_SECRETS_ENCRYPTION_KEY_L= EN, + (char**)secretsEncryptionKey= )) < 0) { + return -1; + } + if (encryptionKeyLength !=3D VIR_SECRETS_ENCRYPTION_KEY_LEN) { + virReportError(VIR_ERR_INVALID_ENCR_KEY_SECRET, + _("Encryption key length must be '%1$d' '%2$s'"), + VIR_SECRETS_ENCRYPTION_KEY_LEN, + cfg->secretsEncryptionKeyPath); + return -1; + } + + *secretsKeyLen =3D (size_t)encryptionKeyLength; + return 0; +} + + +virSecretDaemonConfig * +virSecretDaemonConfigNew(bool privileged) +{ + g_autoptr(virSecretDaemonConfig) cfg =3D NULL; + g_autofree char *configdir =3D NULL; + g_autofree char *configfile =3D NULL; + g_autofree char *rundir =3D NULL; + const char *credentialsDirectory; + + if (virSecretConfigInitialize() < 0) + return NULL; + + if (!(cfg =3D virObjectNew(virSecretDaemonConfigClass))) + return NULL; + + if (virSecretDaemonConfigFilePath(privileged, &configfile) < 0) + return NULL; + + if (virSecretLoadDaemonConfig(cfg, configfile) < 0) + return NULL; + + credentialsDirectory =3D getenv("CREDENTIALS_DIRECTORY"); + + if (!cfg->secretsEncryptionKeyPath && credentialsDirectory) { + cfg->secretsEncryptionKeyPath =3D g_strdup_printf("%s/secrets-encr= yption-key", + credentialsDirecto= ry); + if (!virFileExists(cfg->secretsEncryptionKeyPath)) { + g_clear_pointer(&cfg->secretsEncryptionKeyPath, g_free); + } + } + + if (!cfg->encryptDataWasSet) { + if (!cfg->secretsEncryptionKeyPath) { + /* No path specified by user or environment, disable encryptio= n */ + cfg->encryptData =3D false; + } else { + cfg->encryptData =3D true; + } + } else { + if (cfg->encryptData) { + if (!cfg->secretsEncryptionKeyPath) { + /* Built-in default path must be used */ + rundir =3D virGetUserRuntimeDirectory(); + cfg->secretsEncryptionKeyPath =3D g_strdup_printf("%s/secr= ets/encryption-key", + rundir); + } + } + } + VIR_DEBUG("Secrets encryption key path: %s", NULLSTR(cfg->secretsEncry= ptionKeyPath)); + + if (cfg->encryptData) { + if (virGetSecretsEncryptionKey(cfg, + &cfg->secretsEncryptionKey, + &cfg->secretsKeyLen) < 0) { + return NULL; + } + } + return g_steal_pointer(&cfg); +} + + +static void +virSecretDaemonConfigDispose(void *obj) +{ + virSecretDaemonConfig *cfg =3D obj; + + virSecureErase(cfg->secretsEncryptionKey, cfg->secretsKeyLen); + g_free(cfg->secretsEncryptionKeyPath); +} diff --git a/src/secret/secret_config.h b/src/secret/secret_config.h new file mode 100644 index 0000000000..888acf272b --- /dev/null +++ b/src/secret/secret_config.h @@ -0,0 +1,40 @@ +/* + * secret_config.h: secret.conf config file handling + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#pragma once + +#include "internal.h" +#include "virinhibitor.h" +#include "secret_event.h" +#define VIR_SECRETS_ENCRYPTION_KEY_LEN 32 + +typedef struct _virSecretDaemonConfig virSecretDaemonConfig; +struct _virSecretDaemonConfig { + virObject parent; + /* secrets encryption key path from secret.conf file */ + char *secretsEncryptionKeyPath; + + /* Store the key to encrypt secrets on the disk */ + unsigned char *secretsEncryptionKey; + + size_t secretsKeyLen; + + /* Indicates if the newly written secrets are encrypted or not. + */ + bool encryptData; + + /* Indicates if the config file has encrypt_data set or not. + */ + bool encryptDataWasSet; +}; + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSecretDaemonConfig, virObjectUnref); + +int virSecretDaemonConfigFilePath(bool privileged, char **configfile); +virSecretDaemonConfig *virSecretDaemonConfigNew(bool privileged); +int virSecretDaemonConfigLoadFile(virSecretDaemonConfig *data, + const char *filename, + bool allow_missing); diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c index 04c3ca49f1..9b13772ad3 100644 --- a/src/secret/secret_driver.c +++ b/src/secret/secret_driver.c @@ -42,6 +42,7 @@ #include "secret_event.h" #include "virutil.h" #include "virinhibitor.h" +#include "secret_config.h" =20 #define VIR_FROM_THIS VIR_FROM_SECRET =20 @@ -70,6 +71,10 @@ struct _virSecretDriverState { =20 /* Immutable pointer, self-locking APIs */ virInhibitor *inhibitor; + + /* Require lock to get reference on 'config', + * then lockless thereafter */ + virSecretDaemonConfig *config; }; =20 static virSecretDriverState *driver; @@ -454,6 +459,7 @@ secretStateCleanupLocked(void) VIR_FREE(driver->configDir); =20 virObjectUnref(driver->secretEventState); + virObjectUnref(driver->config); virInhibitorFree(driver->inhibitor); =20 if (driver->lockFD !=3D -1) @@ -518,6 +524,8 @@ secretStateInitialize(bool privileged, driver->stateDir); goto error; } + if (!(driver->config =3D virSecretDaemonConfigNew(driver->privileged))) + goto error; =20 driver->inhibitor =3D virInhibitorNew( VIR_INHIBITOR_WHAT_NONE, @@ -553,6 +561,9 @@ secretStateReload(void) if (!driver) return -1; =20 + if (!(driver->config =3D virSecretDaemonConfigNew(driver->privileged))) + return -1; + ignore_value(virSecretLoadAllConfigs(driver->secrets, driver->configDi= r)); =20 return 0; diff --git a/src/secret/test_libvirt_secrets.aug.in b/src/secret/test_libvi= rt_secrets.aug.in new file mode 100644 index 0000000000..1bb205e0f2 --- /dev/null +++ b/src/secret/test_libvirt_secrets.aug.in @@ -0,0 +1,6 @@ +module Test_libvirt_secrets =3D + @CONFIG@ + + test Libvirt_secrets.lns get conf =3D +{ "secrets_encryption_key" =3D "/run/libvirt/secrets/secret-encryption-key= " } +{ "encrypt_data" =3D "1" } diff --git a/src/util/virerror.c b/src/util/virerror.c index abb014b522..b7d23f81c7 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -1296,6 +1296,9 @@ static const virErrorMsgTuple virErrorMsgStrings[] = =3D { [VIR_ERR_AGENT_COMMAND_FAILED] =3D { N_("guest agent command failed"), N_("guest agent command failed: %1$s") }, + [VIR_ERR_INVALID_ENCR_KEY_SECRET] =3D { + N_("Invalid encryption key for the secret"), + N_("Invalid encryption key for the secret: %1$s") }, }; =20 G_STATIC_ASSERT(G_N_ELEMENTS(virErrorMsgStrings) =3D=3D VIR_ERR_NUMBER_LAS= T); --=20 2.51.1 From nobody Thu Feb 12 16:48:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1770901680; cv=none; d=zohomail.com; s=zohoarc; b=DKH+U2+rXcmBB+L0Nqhk6LsCGn+sfdmT7NL0cJ75invXBliN2GGAXSIy7x0Y/u4YSc7Gc4A1aSr0rL7ecU/EM+i6+PiCX/13q5Isvc48wbJvyqoEfC6kk9bnq00ZuyJR1ndkuFq8GUQGEkoGXIyDScxFbQ+gQ3QDvql/hYQauF0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770901680; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=O3n+QCWxPpIV2SwlnCS2bkWl1FlSuZWAHGXiAJ7jc3k=; b=next8BZIq5d3Yj3xtLil9t8qAF5FjZTtsgxdAMjIxJAKsvv/ZreTLeJUWiYYI/gtuc/C/7MDGP3FaYIyVbrJJfiNlX/YH5ON5fXPb91r6qxqkWiF4yPnnLmv9kFOPboIO+oLtjRe7H5LwDg4KajA+JWYjrT0QKaFvIRh5Jrsw8U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1770901680417293.5724111685299; Thu, 12 Feb 2026 05:08:00 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 3A13D44FA6; Thu, 12 Feb 2026 08:07:59 -0500 (EST) Received: from [172.19.199.6] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 8C1D641902; Thu, 12 Feb 2026 07:51:38 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 8FA8B3F87A; Thu, 12 Feb 2026 07:50:44 -0500 (EST) Received: from mx1.osci.io (unknown [8.43.85.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id A0F0845249 for ; Thu, 12 Feb 2026 07:39:01 -0500 (EST) Received: by mx1.osci.io (Postfix, from userid 995) id C3FB028C7F; Tue, 10 Feb 2026 12:56:58 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx1.osci.io (Postfix) with ESMTPS id F290F28C83 for ; Tue, 10 Feb 2026 12:56:57 -0500 (EST) Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-288-s_-KKLYzOZ-W6kWP5fyp2Q-1; Tue, 10 Feb 2026 12:56:55 -0500 Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-81f3f3af760so12699866b3a.1 for ; Tue, 10 Feb 2026 09:56:55 -0800 (PST) Received: from armenon-kvm.armenon-thinkpadp16vgen1.bengluru.csb ([49.36.106.234]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-824418a70fesm13782658b3a.45.2026.02.10.09.56.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 09:56:53 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746217; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O3n+QCWxPpIV2SwlnCS2bkWl1FlSuZWAHGXiAJ7jc3k=; b=OmIlEirxfjUuHSpx+ZiMniGF09hG5nazCQmEuSKG2R/O5djmpUpn/9I+bOAYbVk5P4tDfJ J9J/ZRStIjQyVV6ErJPJbXOS1e8C2TTFzSf08kaNjAGSdmMuy4v/1B8zNLAtVZ+1VgQR0u bNj9Dckcpj5DWFgWIIhyLi+tBt4i0ps= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746217; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=O3n+QCWxPpIV2SwlnCS2bkWl1FlSuZWAHGXiAJ7jc3k=; b=OmIlEirxfjUuHSpx+ZiMniGF09hG5nazCQmEuSKG2R/O5djmpUpn/9I+bOAYbVk5P4tDfJ J9J/ZRStIjQyVV6ErJPJbXOS1e8C2TTFzSf08kaNjAGSdmMuy4v/1B8zNLAtVZ+1VgQR0u bNj9Dckcpj5DWFgWIIhyLi+tBt4i0ps= X-MC-Unique: s_-KKLYzOZ-W6kWP5fyp2Q-1 X-Mimecast-MFC-AGG-ID: s_-KKLYzOZ-W6kWP5fyp2Q_1770746215 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770746214; x=1771351014; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=O3n+QCWxPpIV2SwlnCS2bkWl1FlSuZWAHGXiAJ7jc3k=; b=iDaKmMeKYV594kJUf1gWLNdhNGKBxxFeWTwugfjrNeLJZCnJUvJgsvSZnOKa70ZMMc INyQumui8JPohNDzK0yFC85uCof07AgoXMMUvrfPPX+YrjFZVm3q1crsdQ8k7sWQgV9Z SyiSdVX+Ocmjx6wFKiKGh5T35DIL4rFKJCgz7lolHZnuzOV6Dur8LdEwmAvvACwXr6/0 uDfQBfyRvBmOPn4gFSHPaUZF1jV8HbL0Fq36LPGk2u0S+DLzp6QomtKtZXN/bAlTyEBa sAk0OoqI5NbwN+HiSQVUHAXAMIVm0wWMO80nbD40ct7OAJw6ZkbrUhi2J/ThOWimooVF 3Vhw== X-Gm-Message-State: AOJu0YyzWmCee+jk4PN4SmSRgYNhhKJS2XNjMGRZ10B/4FYDheWgQufW /fSOQTtCaDpG9hdnCcR8qeBuEdzTPJrlEenjwVrUqLyugGmaLajP+YypNI704gAPKYwVjr7bEvM YsbferrlovFd2ruyV727N8ZF5eoyXYT+WLrUwf1bqaz9Giypgqod9uoCL/LArlUCgkXaG1l9ONr pUDfUM5cZYducPPvvzBaFC/tgcq3Tq5+yqJl3MahXg9g== X-Gm-Gg: AZuq6aJTXG97alq1S/kLDMIAVxaLDDM6QFVyKB6kX67nEOqAE6d+NSjl0wNLbuaVllu 6A8VHvWYHlR3SjcJuFEWyFkep1D8PYMb0NFSqlqqbOnP1hK3XcO+Ig7teLEHvyUVWmPKUE4rGYk 5/QuVO/nUIZcd27SIORqVpSjTppRUGSwfyz0sdvjmVizbD708oSOsaUo0+oVdYsSQmtavaj2lV7 HrjwpepmdMU4q+ca9C/3tKUUlVIerdXa41ON564GsWRa/0CRU5Ik7F9ZGLQP80K8LYzwdjxfHU4 sjFNgEokzz+0uH6DNRzgbIKlJjIEGjWiuCjwMhgcX8XOFvFjB0R672eIVbgB+1/yfrfE3T5z+Pf CXyvTRd6OK14jSFptasqsLBq8YMHN7vom67sLYhRXee3AdnyBHyD/aXQ0VQKA41s0MDDS+A== X-Received: by 2002:a05:6a00:90a6:b0:823:244f:1fac with SMTP id d2e1a72fcca58-82487984688mr2648953b3a.6.1770746214645; Tue, 10 Feb 2026 09:56:54 -0800 (PST) X-Received: by 2002:a05:6a00:90a6:b0:823:244f:1fac with SMTP id d2e1a72fcca58-82487984688mr2648938b3a.6.1770746214199; Tue, 10 Feb 2026 09:56:54 -0800 (PST) To: devel@lists.libvirt.org Subject: [PATCH v6 4/6] secret: Rename virSecretObj structure attribute from base64File to secretValueFile Date: Tue, 10 Feb 2026 23:26:41 +0530 Message-ID: <20260210175643.23351-5-armenon@redhat.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20260210175643.23351-1-armenon@redhat.com> References: <20260210175643.23351-1-armenon@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: D-QfqHq0DcXoiRRGEVFE9hTWIYpCICVfOGyr-bg87Mg_1770746215 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: NZEXSOSUMIDZ3K23JIHK7RR42ALJZFSX X-Message-ID-Hash: NZEXSOSUMIDZ3K23JIHK7RR42ALJZFSX X-MailFrom: armenon@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Arun Menon X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Arun Menon via Devel Reply-To: Arun Menon X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1770901686590158500 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Arun Menon Change the attribute name of _virSecretObj because we want it to have a gen= eric name to indicate that secret values can be stored in it in both base64 and encrypted formats. Signed-off-by: Arun Menon Reviewed-by: Peter Krempa --- src/conf/virsecretobj.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c index 66270e2751..a3dd7983bb 100644 --- a/src/conf/virsecretobj.c +++ b/src/conf/virsecretobj.c @@ -39,7 +39,7 @@ VIR_LOG_INIT("conf.virsecretobj"); struct _virSecretObj { virObjectLockable parent; char *configFile; - char *base64File; + char *secretValueFile; virSecretDef *def; unsigned char *value; /* May be NULL */ size_t value_size; @@ -139,7 +139,7 @@ virSecretObjDispose(void *opaque) g_free(obj->value); } g_free(obj->configFile); - g_free(obj->base64File); + g_free(obj->secretValueFile); } =20 =20 @@ -378,11 +378,11 @@ virSecretObjListAdd(virSecretObjList *secrets, if (!(obj =3D virSecretObjNew())) goto cleanup; =20 - /* Generate the possible configFile and base64File strings + /* Generate the possible configFile and secretValueFile strings * using the configDir, uuidstr, and appropriate suffix */ if (!(obj->configFile =3D virFileBuildPath(configDir, uuidstr, ".x= ml")) || - !(obj->base64File =3D virFileBuildPath(configDir, uuidstr, ".b= ase64"))) + !(obj->secretValueFile =3D virFileBuildPath(configDir, uuidstr= , ".base64"))) goto cleanup; =20 if (virHashAddEntry(secrets->objs, uuidstr, obj) < 0) @@ -656,7 +656,7 @@ virSecretObjDeleteData(virSecretObj *obj) { /* The configFile will already be removed, so secret won't be * loaded again if this fails */ - unlink(obj->base64File); + unlink(obj->secretValueFile); } =20 =20 @@ -691,7 +691,7 @@ virSecretObjSaveData(virSecretObj *obj) =20 base64 =3D g_base64_encode(obj->value, obj->value_size); =20 - if (virFileRewriteStr(obj->base64File, S_IRUSR | S_IWUSR, base64) < 0) + if (virFileRewriteStr(obj->secretValueFile, S_IRUSR | S_IWUSR, base64)= < 0) return -1; =20 return 0; @@ -813,26 +813,26 @@ virSecretLoadValue(virSecretObj *obj) struct stat st; g_autofree char *contents =3D NULL; =20 - if ((fd =3D open(obj->base64File, O_RDONLY)) =3D=3D -1) { + if ((fd =3D open(obj->secretValueFile, O_RDONLY)) =3D=3D -1) { if (errno =3D=3D ENOENT) { ret =3D 0; goto cleanup; } virReportSystemError(errno, _("cannot open '%1$s'"), - obj->base64File); + obj->secretValueFile); goto cleanup; } =20 if (fstat(fd, &st) < 0) { virReportSystemError(errno, _("cannot stat '%1$s'"), - obj->base64File); + obj->secretValueFile); goto cleanup; } =20 if ((size_t)st.st_size !=3D st.st_size) { virReportError(VIR_ERR_INTERNAL_ERROR, _("'%1$s' file does not fit in memory"), - obj->base64File); + obj->secretValueFile); goto cleanup; } =20 @@ -845,7 +845,7 @@ virSecretLoadValue(virSecretObj *obj) =20 if (saferead(fd, contents, st.st_size) !=3D st.st_size) { virReportSystemError(errno, _("cannot read '%1$s'"), - obj->base64File); + obj->secretValueFile); goto cleanup; } contents[st.st_size] =3D '\0'; --=20 2.51.1 From nobody Thu Feb 12 16:48:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1770902517; cv=none; d=zohomail.com; s=zohoarc; b=Nap5eUtEiQvgTIF5kWH4X0r8PKlUypCbFDd46wWyigda4MH0Az5O3d0j0+cG2TpkDkHJcXgepLBlHNmbUDuYm/mJuYc5Z9j1GmilWQcTwPeovxgzZICaxRUghw1suLgDw+3OGNvbLV22XDUAS+g4yBN/2w7S0JT+bqggh3EYWnM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770902517; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=KFQf/F9jur7jcQTcAUEzJDn8vguzBRjzYM4SBRiWsEE=; b=QGEuxXbP+lYpoBxXASr4KsGu4z7ng28xBm91LUXuC4Ehne5AhNxZdei3jL8c1OQEdtI3IzHavOcGzXz6/8km9x4DkM9ftd0HVHi2ZgxdgrR+Uzb9eM6+QcC/8Cl8AQSBiCiMd/iKfuV12W5QxR5kAV7lqHmLyx9BZVSzLyG5pN0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1770902517126308.33921619344096; Thu, 12 Feb 2026 05:21:57 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 9A83F44DD3; Thu, 12 Feb 2026 08:21:56 -0500 (EST) Received: from [172.19.199.6] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 7467E45ADA; Thu, 12 Feb 2026 07:52:39 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id AEDD3454B7; Thu, 12 Feb 2026 07:51:23 -0500 (EST) Received: from mx1.osci.io (unknown [8.43.85.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id B495D45D99 for ; Thu, 12 Feb 2026 07:39:47 -0500 (EST) Received: by mx1.osci.io (Postfix, from userid 995) id 9244428C86; Tue, 10 Feb 2026 12:57:01 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx1.osci.io (Postfix) with ESMTPS id 22A5028C84 for ; Tue, 10 Feb 2026 12:57:00 -0500 (EST) Received: from mail-pf1-f199.google.com (mail-pf1-f199.google.com [209.85.210.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-248-cgBFbQrlM7yJ3dZSmv0G5A-1; Tue, 10 Feb 2026 12:56:58 -0500 Received: by mail-pf1-f199.google.com with SMTP id d2e1a72fcca58-81efa628efbso4560649b3a.1 for ; Tue, 10 Feb 2026 09:56:57 -0800 (PST) Received: from armenon-kvm.armenon-thinkpadp16vgen1.bengluru.csb ([49.36.106.234]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-824418a70fesm13782658b3a.45.2026.02.10.09.56.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 09:56:55 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746219; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KFQf/F9jur7jcQTcAUEzJDn8vguzBRjzYM4SBRiWsEE=; b=A9tNstuglCzQ+vEjAsZTiJRxGaYu4jOJgNa5cFPQ8dAhjpu8X9T8DPdOaf6I9booynAACf +WqT338UeC+VcZNlHfsZ99boo234hDwpV8HuerSjg97Xk6+nln8jsCaW1vraWM1A+mJ+hV 5tefagru766YTHI4rr1tXVVY9nX65mY= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746219; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=KFQf/F9jur7jcQTcAUEzJDn8vguzBRjzYM4SBRiWsEE=; b=A9tNstuglCzQ+vEjAsZTiJRxGaYu4jOJgNa5cFPQ8dAhjpu8X9T8DPdOaf6I9booynAACf +WqT338UeC+VcZNlHfsZ99boo234hDwpV8HuerSjg97Xk6+nln8jsCaW1vraWM1A+mJ+hV 5tefagru766YTHI4rr1tXVVY9nX65mY= X-MC-Unique: cgBFbQrlM7yJ3dZSmv0G5A-1 X-Mimecast-MFC-AGG-ID: cgBFbQrlM7yJ3dZSmv0G5A_1770746217 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770746216; x=1771351016; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=KFQf/F9jur7jcQTcAUEzJDn8vguzBRjzYM4SBRiWsEE=; b=EBU/1saaOomdjXLVkoqQaXDbGzIJQRzUs6gIyAGwPbomncMCNuFiCULwmr+3Prb4Ok 57KEa3UmcKYXWZs5dABuL7mxxLYiKm/adCSqPtlIJ7ZYWYLt4h5KssIMFPVHes2EyEBO bwTwyWnVF9p9b6vcMOkI3mTL/dUP2yl3XEnxJM4rBOO+a4Sq0Lu3kGnyAf+28O+wF1af /rQef/0ipdY326F5WzDb9c7k77oNRN7sILNpfJDWRzPn1lnSh/N8FZA876KshZ7fkmdN wJZqknzgcJvz6PwIUmf+SnuMaZqaUoniojVQvIqcvWuWBhovxDVpttOydaw6Dx48s0q2 PQ3Q== X-Gm-Message-State: AOJu0YwlM3Igcg+LgMoIOa4hkyNf8MZbAO+DqxA9BC6sVtAs2+r2+j/s ku9p8sODaVxmmsXhvOrS2j+F8yVWijrcAHstp2WDGlNlPs6t3WhZCDZF/WvMB33sdLojptSnST3 GYOQnTRcsmFCDz0/Hk0kCQHkhepi2PRqOjFiRUyTITAEnawjIqFWJqdo2vg1OxQC888yteJ1aG+ 4Iaa2xLvoIHL0UpYNvmIY19ZLq6aU5GYDfLlc/cDR+cA== X-Gm-Gg: AZuq6aKNhCAfd3ZB5uIyIdgisDmk5/AmTyjhX2cROcStZrUhS2OVY1or712KNUzstiI 6jp5aQO9AQ7pHklTAkiWCGD8wJguZxfpWahRfdO3gEdP80uPl5O1+NH8n7NfH8G9ib2mBf/f5Hg D0GV1WZ/73tGnw12chpcq2/VHV6yvpOcSFuW4uYUgvmEpW5Te4BriBWlzLpakhP4XkFajF9HI20 p8Xk4OdGyD82D/QYgwWWe6N0APn8Juba3FNSdVz4vblLklEDBQWmVy1OoMJpU2P0/QtI6ZmAqLH 7kkcrzK3O/FFYggqSux0WWlQ/lqlrQid+JyMaBMgmFLLceG6f0h+uIusLIiKqagnrvcMelnKdEw RbrBqW+27OLfs9alorxQ1G79ZLB2G85KZKNVeL0xFaHELwFbd+R0aMhjXUMO6lB2kfRFHdw== X-Received: by 2002:a05:6a00:198a:b0:823:1726:aedc with SMTP id d2e1a72fcca58-82441728212mr12459143b3a.50.1770746216529; Tue, 10 Feb 2026 09:56:56 -0800 (PST) X-Received: by 2002:a05:6a00:198a:b0:823:1726:aedc with SMTP id d2e1a72fcca58-82441728212mr12459123b3a.50.1770746215995; Tue, 10 Feb 2026 09:56:55 -0800 (PST) To: devel@lists.libvirt.org Subject: [PATCH v6 5/6] secret: Add functionality to load and save secrets in encrypted format Date: Tue, 10 Feb 2026 23:26:42 +0530 Message-ID: <20260210175643.23351-6-armenon@redhat.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20260210175643.23351-1-armenon@redhat.com> References: <20260210175643.23351-1-armenon@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: aHOEZ0UYxnrdM4G6xLt7nY8O1kJqYeyrpkNmLChKa_Y_1770746217 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 7DAI3NL2FPDUXUALBMLNR5EOG4GTXIZ2 X-Message-ID-Hash: 7DAI3NL2FPDUXUALBMLNR5EOG4GTXIZ2 X-MailFrom: armenon@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Arun Menon X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Arun Menon via Devel Reply-To: Arun Menon X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1770902528402154100 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Arun Menon Now that we have the functionality to provide the secrets driver with an encryption key through a configuration file or using system credentials, and the newly introduced array to iterate over the encryption schemes, we can use the key to save and load secrets. Encrypt all secrets that are going to be saved on the disk if the 'secrets_encryption_key' path is set in the secret.conf file OR if a valid systemd generated credential exists. While loading secrets, identify the decryption method by matching the file extension of the stored secret against the known array values. If no matching scheme is found, the secret is skipped. If the encryption key is changed across restarts, then also the secret driver will fail to lo= ad the secrets from the disk that were encrypted with the former key. Signed-off-by: Arun Menon Co-authored-by: Peter Krempa Reviewed-by: Peter Krempa --- src/conf/virsecretobj.c | 204 ++++++++++++++++++++++++++----------- src/conf/virsecretobj.h | 14 ++- src/secret/secret_driver.c | 18 +++- 3 files changed, 172 insertions(+), 64 deletions(-) diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c index a3dd7983bb..b448be493a 100644 --- a/src/conf/virsecretobj.c +++ b/src/conf/virsecretobj.c @@ -31,6 +31,10 @@ #include "virhash.h" #include "virlog.h" #include "virstring.h" +#include "virsecret.h" +#include "virrandom.h" +#include "vircrypto.h" +#include "virsecureerase.h" =20 #define VIR_FROM_THIS VIR_FROM_SECRET =20 @@ -45,6 +49,16 @@ struct _virSecretObj { size_t value_size; }; =20 +typedef struct _virSecretSchemeInfo { + const char *suffix; + virCryptoCipher cipher; +} virSecretSchemeInfo; + +virSecretSchemeInfo schemeInfo[] =3D { + { ".aes256cbc", VIR_CRYPTO_CIPHER_AES256CBC }, + { ".base64", -1 }, +}; + static virClass *virSecretObjClass; static virClass *virSecretObjListClass; static void virSecretObjDispose(void *obj); @@ -377,12 +391,14 @@ virSecretObjListAdd(virSecretObjList *secrets, =20 if (!(obj =3D virSecretObjNew())) goto cleanup; - /* Generate the possible configFile and secretValueFile strings - * using the configDir, uuidstr, and appropriate suffix + * using the configDir, uuidstr, and appropriate suffix. + * Note that secretValueFile extension is not set here. It is dete= rmined + * based on a) existing availability of secret file (virSecretLoad= Value) or + * b) target storage format (virSecretObjSaveData) */ if (!(obj->configFile =3D virFileBuildPath(configDir, uuidstr, ".x= ml")) || - !(obj->secretValueFile =3D virFileBuildPath(configDir, uuidstr= , ".base64"))) + !(obj->secretValueFile =3D virFileBuildPath(configDir, uuidstr= , NULL))) goto cleanup; =20 if (virHashAddEntry(secrets->objs, uuidstr, obj) < 0) @@ -654,9 +670,15 @@ virSecretObjDeleteConfig(virSecretObj *obj) void virSecretObjDeleteData(virSecretObj *obj) { + size_t i; + /* The configFile will already be removed, so secret won't be * loaded again if this fails */ - unlink(obj->secretValueFile); + for (i =3D 0; i < G_N_ELEMENTS(schemeInfo); i++) { + g_autofree char *deleteFile =3D g_strconcat(obj->secretValueFile, = schemeInfo[i].suffix, NULL); + + ignore_value(unlink(deleteFile)); + } } =20 =20 @@ -682,18 +704,69 @@ virSecretObjSaveConfig(virSecretObj *obj) =20 =20 int -virSecretObjSaveData(virSecretObj *obj) +virSecretObjSaveData(virSecretObj *obj, + bool encryptData, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen) { g_autofree char *base64 =3D NULL; + g_autofree char *filename =3D NULL; + size_t i; + g_autofree unsigned char *secretbuf =3D NULL; + const unsigned char *secret =3D NULL; + size_t secretLen =3D 0; =20 if (!obj->value) return 0; =20 - base64 =3D g_base64_encode(obj->value, obj->value_size); + /* Based on whether encryption is on/off, save the secret in either + * the latest encryption scheme or in base64 formats. + * Subsequently, delete the other formats of the same uuid on the disk. + */ + if (encryptData && secretsEncryptionKey) { + g_autofree uint8_t *encryptedValue =3D NULL; + size_t encryptedValueLen =3D 0; + const size_t ivlen =3D 16; + g_autofree unsigned char *ivbuf =3D g_new0(unsigned char, ivlen); + + filename =3D g_strconcat(obj->secretValueFile, schemeInfo[0].suffi= x, NULL); + + if (virRandomBytes(ivbuf, ivlen) < 0) + return -1; + + if (virCryptoEncryptData(schemeInfo[0].cipher, + secretsEncryptionKey, secretsKeyLen, + ivbuf, ivlen, + (uint8_t *)obj->value, obj->value_size, + &encryptedValue, &encryptedValueLen) < 0) + return -1; + + ivbuf =3D g_realloc(ivbuf, ivlen + encryptedValueLen); + memcpy(ivbuf + ivlen, encryptedValue, encryptedValueLen); + + secretbuf =3D g_steal_pointer(&ivbuf); + secret =3D secretbuf; + secretLen =3D ivlen + encryptedValueLen; + } else { + filename =3D g_strconcat(obj->secretValueFile, schemeInfo[G_N_ELEM= ENTS(schemeInfo) - 1].suffix, NULL); + secret =3D (unsigned char *) obj->value; + secretLen =3D obj->value_size; + } + + base64 =3D g_base64_encode(secret, secretLen); =20 - if (virFileRewriteStr(obj->secretValueFile, S_IRUSR | S_IWUSR, base64)= < 0) + if (virFileRewriteStr(filename, S_IRUSR | S_IWUSR, base64) < 0) return -1; =20 + for (i =3D 0; i < G_N_ELEMENTS(schemeInfo); i++) { + g_autofree char *deleteFile =3D g_strconcat(obj->secretValueFile, = schemeInfo[i].suffix, NULL); + + if (STREQ(filename, deleteFile)) + continue; + + ignore_value(unlink(deleteFile)); + } + return 0; } =20 @@ -737,7 +810,10 @@ virSecretObjGetValue(virSecretObj *obj) int virSecretObjSetValue(virSecretObj *obj, const unsigned char *value, - size_t value_size) + size_t value_size, + bool encryptData, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen) { virSecretDef *def =3D obj->def; g_autofree unsigned char *old_value =3D NULL; @@ -753,7 +829,10 @@ virSecretObjSetValue(virSecretObj *obj, obj->value =3D g_steal_pointer(&new_value); obj->value_size =3D value_size; =20 - if (!def->isephemeral && virSecretObjSaveData(obj) < 0) + if (!def->isephemeral && virSecretObjSaveData(obj, + encryptData, + secretsEncryptionKey, + secretsKeyLen) < 0) goto error; =20 /* Saved successfully - drop old value */ @@ -807,60 +886,65 @@ virSecretLoadValidateUUID(virSecretDef *def, =20 =20 static int -virSecretLoadValue(virSecretObj *obj) -{ - int ret =3D -1, fd =3D -1; - struct stat st; - g_autofree char *contents =3D NULL; +virSecretLoadValue(virSecretObj *obj, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen) +{ + const size_t secretFileMaxLen =3D 10 * 1024 * 1024; /* more won't fit = in the RPC buffer */ + size_t i; + + /* Find the file and match the storage scheme based on suffix. */ + for (i =3D 0; i < G_N_ELEMENTS(schemeInfo); i++) { + g_autofree char *filename =3D g_strconcat(obj->secretValueFile, + schemeInfo[i].suffix, NULL= ); + g_autofree char *filecontent =3D NULL; + int filelen =3D 0; + g_autofree unsigned char *decoded =3D NULL; + size_t decodedlen =3D 0; + + if (!virFileExists(filename)) + continue; =20 - if ((fd =3D open(obj->secretValueFile, O_RDONLY)) =3D=3D -1) { - if (errno =3D=3D ENOENT) { - ret =3D 0; - goto cleanup; - } - virReportSystemError(errno, _("cannot open '%1$s'"), - obj->secretValueFile); - goto cleanup; - } + if ((filelen =3D virFileReadAll(filename, secretFileMaxLen, &filec= ontent)) < 0) + return -1; =20 - if (fstat(fd, &st) < 0) { - virReportSystemError(errno, _("cannot stat '%1$s'"), - obj->secretValueFile); - goto cleanup; - } + filecontent =3D g_realloc(filecontent, filelen + 1); + filecontent[filelen] =3D '\0'; =20 - if ((size_t)st.st_size !=3D st.st_size) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("'%1$s' file does not fit in memory"), - obj->secretValueFile); - goto cleanup; - } + decoded =3D g_base64_decode(filecontent, &decodedlen); =20 - if (st.st_size < 1) { - ret =3D 0; - goto cleanup; - } + virSecureErase(filecontent, filelen); =20 - contents =3D g_new0(char, st.st_size + 1); + if (schemeInfo[i].cipher =3D=3D -1) { + obj->value =3D g_steal_pointer(&decoded); + obj->value_size =3D decodedlen; + } else { + size_t ivlen =3D 16; + int rc; =20 - if (saferead(fd, contents, st.st_size) !=3D st.st_size) { - virReportSystemError(errno, _("cannot read '%1$s'"), - obj->secretValueFile); - goto cleanup; - } - contents[st.st_size] =3D '\0'; + if (decodedlen < ivlen) { + virReportError(VIR_ERR_INVALID_SECRET, + _("Encrypted secret size '%1$zu' is invalid= "), + obj->value_size); =20 - VIR_FORCE_CLOSE(fd); + virSecureErase(decoded, decodedlen); + return -1; + } =20 - obj->value =3D g_base64_decode(contents, &obj->value_size); + rc =3D virCryptoDecryptData(schemeInfo[i].cipher, + secretsEncryptionKey, secretsKeyLen, + decoded, ivlen, /* initialization ve= ctor is stored at start of the buffer */ + decoded + ivlen, decodedlen - ivlen, + &obj->value, &obj->value_size); =20 - ret =3D 0; + virSecureErase(decoded, decodedlen); =20 - cleanup: - if (contents !=3D NULL) - memset(contents, 0, st.st_size); - VIR_FORCE_CLOSE(fd); - return ret; + if (rc < 0) + return -1; + } + } + + return 0; } =20 =20 @@ -868,7 +952,9 @@ static virSecretObj * virSecretLoad(virSecretObjList *secrets, const char *file, const char *path, - const char *configDir) + const char *configDir, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen) { g_autoptr(virSecretDef) def =3D NULL; virSecretObj *obj =3D NULL; @@ -882,7 +968,7 @@ virSecretLoad(virSecretObjList *secrets, if (!(obj =3D virSecretObjListAdd(secrets, &def, configDir, NULL))) return NULL; =20 - if (virSecretLoadValue(obj) < 0) { + if (virSecretLoadValue(obj, secretsEncryptionKey, secretsKeyLen) < 0) { virSecretObjListRemove(secrets, obj); g_clear_pointer(&obj, virObjectUnref); return NULL; @@ -894,7 +980,9 @@ virSecretLoad(virSecretObjList *secrets, =20 int virSecretLoadAllConfigs(virSecretObjList *secrets, - const char *configDir) + const char *configDir, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen) { g_autoptr(DIR) dir =3D NULL; struct dirent *de; @@ -915,7 +1003,9 @@ virSecretLoadAllConfigs(virSecretObjList *secrets, if (!(path =3D virFileBuildPath(configDir, de->d_name, NULL))) continue; =20 - if (!(obj =3D virSecretLoad(secrets, de->d_name, path, configDir))= ) { + if (!(obj =3D virSecretLoad(secrets, de->d_name, path, configDir, + secretsEncryptionKey, + secretsKeyLen))) { VIR_ERROR(_("Error reading secret: %1$s"), virGetLastErrorMessage()); continue; diff --git a/src/conf/virsecretobj.h b/src/conf/virsecretobj.h index 17897c5513..4e872f7b29 100644 --- a/src/conf/virsecretobj.h +++ b/src/conf/virsecretobj.h @@ -86,7 +86,10 @@ int virSecretObjSaveConfig(virSecretObj *obj); =20 int -virSecretObjSaveData(virSecretObj *obj); +virSecretObjSaveData(virSecretObj *obj, + bool encryptData, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen); =20 virSecretDef * virSecretObjGetDef(virSecretObj *obj); @@ -101,7 +104,10 @@ virSecretObjGetValue(virSecretObj *obj); int virSecretObjSetValue(virSecretObj *obj, const unsigned char *value, - size_t value_size); + size_t value_size, + bool encryptData, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen); =20 size_t virSecretObjGetValueSize(virSecretObj *obj); @@ -112,4 +118,6 @@ virSecretObjSetValueSize(virSecretObj *obj, =20 int virSecretLoadAllConfigs(virSecretObjList *secrets, - const char *configDir); + const char *configDir, + uint8_t *secretsEncryptionKey, + size_t secretsKeyLen); diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c index 9b13772ad3..2f4ac60f5a 100644 --- a/src/secret/secret_driver.c +++ b/src/secret/secret_driver.c @@ -229,7 +229,10 @@ secretDefineXML(virConnectPtr conn, =20 if (!objDef->isephemeral) { if (backup && backup->isephemeral) { - if (virSecretObjSaveData(obj) < 0) + if (virSecretObjSaveData(obj, + driver->configDir, + driver->config->secretsEncryptionKey, + driver->config->secretsKeyLen) < 0) goto restore_backup; } =20 @@ -333,7 +336,10 @@ secretSetValue(virSecretPtr secret, if (virSecretSetValueEnsureACL(secret->conn, def) < 0) goto cleanup; =20 - if (virSecretObjSetValue(obj, value, value_size) < 0) + if (virSecretObjSetValue(obj, value, value_size, + driver->configDir, + driver->config->secretsEncryptionKey, + driver->config->secretsKeyLen) < 0) goto cleanup; =20 event =3D virSecretEventValueChangedNew(def->uuid, @@ -542,7 +548,9 @@ secretStateInitialize(bool privileged, if (!(driver->secrets =3D virSecretObjListNew())) goto error; =20 - if (virSecretLoadAllConfigs(driver->secrets, driver->configDir) < 0) + if (virSecretLoadAllConfigs(driver->secrets, driver->configDir, + driver->config->secretsEncryptionKey, + driver->config->secretsKeyLen) < 0) goto error; =20 return VIR_DRV_STATE_INIT_COMPLETE; @@ -564,7 +572,9 @@ secretStateReload(void) if (!(driver->config =3D virSecretDaemonConfigNew(driver->privileged))) return -1; =20 - ignore_value(virSecretLoadAllConfigs(driver->secrets, driver->configDi= r)); + ignore_value(virSecretLoadAllConfigs(driver->secrets, driver->configDi= r, + driver->config->secretsEncryption= Key, + driver->config->secretsKeyLen)); =20 return 0; } --=20 2.51.1 From nobody Thu Feb 12 16:48:06 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1770905364; cv=none; d=zohomail.com; s=zohoarc; b=KtubzPuuFR0MCK7auNH2HaP7FLev+AOQvqSKx2z2uadGHWVWGsWxNWtvk6ye6xv1L9dGKnX7z9wwbZZglcLY+3od0fF/DD6Ym8D8zcCH11iSeQyXkMtGlX9w2kUr0qgU89jRWZF2po7fGfHagxRfpYiSBsGAkzSYFVaf23gYWR0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1770905364; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=dJcZUHhrukXBGbD8eA+ey/EfBNGFjfdiFuWobXTcpos=; b=Kaiqy+vUUAdGPOB/umoBnx2AGUAoDLWM/cL0iULs19No0CXBT5srVW6aiSO2UPwStDNDJl31k9SmQiwfiGG9EeQjLfaimx5yvMWaIRHaaaS/127qc39iInSRI96sTevRy7ghmQkLWbPmXnRJCeFMUBil9wqr0ZNCnQUlWTp12KU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1770905363945211.23952800210054; Thu, 12 Feb 2026 06:09:23 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id B7B9144F92; Thu, 12 Feb 2026 09:09:22 -0500 (EST) Received: from [172.19.199.6] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 93A4944EB8; Thu, 12 Feb 2026 07:50:28 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 324123F252; Thu, 12 Feb 2026 07:50:15 -0500 (EST) Received: from mx1.osci.io (unknown [8.43.85.229]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id BA87B446C3 for ; Thu, 12 Feb 2026 07:38:34 -0500 (EST) Received: by mx1.osci.io (Postfix, from userid 995) id CF89828C88; Tue, 10 Feb 2026 12:57:02 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-256) server-digest SHA256) (No client certificate requested) by mx1.osci.io (Postfix) with ESMTPS id 2F0DC28C85 for ; Tue, 10 Feb 2026 12:57:02 -0500 (EST) Received: from mail-pf1-f198.google.com (mail-pf1-f198.google.com [209.85.210.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-66-Mk-SNLi3N2CcXoRghEDWYw-1; Tue, 10 Feb 2026 12:56:59 -0500 Received: by mail-pf1-f198.google.com with SMTP id d2e1a72fcca58-82436a49592so3226115b3a.2 for ; Tue, 10 Feb 2026 09:56:59 -0800 (PST) Received: from armenon-kvm.armenon-thinkpadp16vgen1.bengluru.csb ([49.36.106.234]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-824418a70fesm13782658b3a.45.2026.02.10.09.56.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 10 Feb 2026 09:56:57 -0800 (PST) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dJcZUHhrukXBGbD8eA+ey/EfBNGFjfdiFuWobXTcpos=; b=Eg8xbzGvqDYEdkp5pjJqxY7bTlOalfvFmQ65wZo6JBtt2mFG1tDvyZrudvE8y56/UjmyLo a5Bf6WCPYazJLheoHXCtgbpOdfkMnmdtgrEscMjYXSslS/BrJIK5BqcRbVXwQdmMD5GFl7 sfn7PRTMBRg1ETwQZT3eXgIxxzMSN+g= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1770746221; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dJcZUHhrukXBGbD8eA+ey/EfBNGFjfdiFuWobXTcpos=; b=Eg8xbzGvqDYEdkp5pjJqxY7bTlOalfvFmQ65wZo6JBtt2mFG1tDvyZrudvE8y56/UjmyLo a5Bf6WCPYazJLheoHXCtgbpOdfkMnmdtgrEscMjYXSslS/BrJIK5BqcRbVXwQdmMD5GFl7 sfn7PRTMBRg1ETwQZT3eXgIxxzMSN+g= X-MC-Unique: Mk-SNLi3N2CcXoRghEDWYw-1 X-Mimecast-MFC-AGG-ID: Mk-SNLi3N2CcXoRghEDWYw_1770746218 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770746218; x=1771351018; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=dJcZUHhrukXBGbD8eA+ey/EfBNGFjfdiFuWobXTcpos=; b=GiGek12j4Paar+Lxghlox1wn9dj9jv3M6TQhMycznAvMo6UzoWfYu0TcqUiekCmyOH XKqcvHhRc9fpM6sgX1wB+FbCr8SCh9vofYc5moOBgZIPVqPvf6xUgETIDnx19qfo0shM t/RQ+jYpnc9i/VdcIVkLyDBise2Ft2vCHQaDZtR7R/Su6ZmFQp4tirPCnklJLIr/DGUH srM2al4Fp1X/hRBIJHLQRNFwGhiuuQcElXjRlzhWcULvCIz50THfAjf9G7XTtc57FBLx ri8pKDBOveW3HCT3iuxOrJje3FSZ/T3T/6v6E/FN9NK5Adpa2bWHOzV5/uU8GnRIT1o7 hxmw== X-Gm-Message-State: AOJu0YwYgUeLLpY8PJQDEPaWKn5JDrA0067joofRI8Aonpo5QXKxvZ38 exUxkZu+yb6vo0EoSz2oS9Ms4UbU7WX75+fSvrCK9k5oZg98f53uVdntJEtlSu53lVPaxY8l44R k8zYOW5QRhD13dgIhm8/eV8ip58t88toNq4kwV4vontYaYZdyC20P1o4NOHbPGUep/UHFUNw4SH +tuE9ReW47hPPCaucKRhlY0HKdsaizqBe/wLcSbx5LHg== X-Gm-Gg: AZuq6aIXH51NByHATUkDNyX8DOZ+M/MpgzNSdufMyzb3fD/hd27m3ktERbklhcIJVDT +PbC2rvhF3ZnhRMKNNjdHC3uuSe8qWdNHG19xY1lX/lmbiR3+oapsx0pQp5KdW2GqrD/Ff3z4Z7 0cM249KLu40x1QeDCdeYlAucKpXchZd9m/b3jDZjcd+4nhF9BBnI+S4BWWr4Fw+SAbmoyqSH6Rv 5r5WG2KC1jeizLKDSHEmF66FSsgxtdz1kDU6Xd/eoysZaYMmLbGhbwT/hyeLicA00VHEly3R4nm VAdXr/1yXjKeEQfa3e8ANw/AjHE0ykZJYW80KNSWnIAkdG1Xrnihef26mnWL6nJztNeD5F286Oe imzTROdGdXuxClZ5nEype6uKMJblzB8152gFtge0IvO6F8ZmEouiiCP6KRsT39zBLbrimWg== X-Received: by 2002:a05:6a00:909b:b0:822:7fd8:ffbd with SMTP id d2e1a72fcca58-82487ae8cc2mr2899713b3a.59.1770746218186; Tue, 10 Feb 2026 09:56:58 -0800 (PST) X-Received: by 2002:a05:6a00:909b:b0:822:7fd8:ffbd with SMTP id d2e1a72fcca58-82487ae8cc2mr2899693b3a.59.1770746217633; Tue, 10 Feb 2026 09:56:57 -0800 (PST) To: devel@lists.libvirt.org Subject: [PATCH v6 6/6] docs: secret: Add documentation of secret encryption feature Date: Tue, 10 Feb 2026 23:26:43 +0530 Message-ID: <20260210175643.23351-7-armenon@redhat.com> X-Mailer: git-send-email 2.51.1 In-Reply-To: <20260210175643.23351-1-armenon@redhat.com> References: <20260210175643.23351-1-armenon@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: XPuQ0Sublpqhi-si6ECIuYyITwTPavOCYggzSKJUotY_1770746218 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: YCFCSQWVVEFYCEDOW55QSEN2YCUTTLC6 X-Message-ID-Hash: YCFCSQWVVEFYCEDOW55QSEN2YCUTTLC6 X-MailFrom: armenon@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Arun Menon X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Arun Menon via Devel Reply-To: Arun Menon X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1770905374450158500 Content-Type: text/plain; charset="utf-8"; x-default="true" From: Arun Menon Document the new encryption of secrets feature in secretencryption.rst. Signed-off-by: Arun Menon Reviewed-by: Peter Krempa --- docs/drvsecret.rst | 4 ++ docs/meson.build | 1 + docs/secretencryption.rst | 105 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 docs/secretencryption.rst diff --git a/docs/drvsecret.rst b/docs/drvsecret.rst index 76a9097d2b..234551d5ae 100644 --- a/docs/drvsecret.rst +++ b/docs/drvsecret.rst @@ -63,3 +63,7 @@ the traditional system or session libvirt connections to = QEMU. Normal practice would be to open the secret driver in embedded mode any time one of the ot= her drivers is opened in embedded mode so that the two drivers can interact in-process. + +Further reading +---------------------------- +- `Secret Encryption `__ diff --git a/docs/meson.build b/docs/meson.build index 21e0b19c25..0e74f9c4bf 100644 --- a/docs/meson.build +++ b/docs/meson.build @@ -97,6 +97,7 @@ docs_rst_files =3D [ 'programming-languages', 'python', 'remote', + 'secretencryption', 'securityprocess', 'ssh-proxy', 'storage', diff --git a/docs/secretencryption.rst b/docs/secretencryption.rst new file mode 100644 index 0000000000..4908339f2d --- /dev/null +++ b/docs/secretencryption.rst @@ -0,0 +1,105 @@ +.. role:: since + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D +Secret storage and encryption +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D + +.. contents:: + +The secret objects can either be ephemeral or persistent. +Ephemeral secrets are only kept in memory, never stored persistently on th= e disk. +See `Secrets `__ + +:since:`Since 12.1.0` if a secret is defined as persistent, then it is sto= red **encrypted** on the disk. + + +Systemd Credentials Sealing +--------------------------- + +Out of the box, secrets are sealed using systemd credentials. This ties the +encrypted secret files to the specific host. + +The `virt-secret-init-encryption` service automatically generates a random +32-byte key and encrypts it using `systemd-creds`, storing the result in +`/var/lib/libvirt/secrets/secrets-encryption-key`. The `virtsecretd` servi= ce +then automatically loads this key securely via the systemd `LoadCredential= Encrypted` +mechanism. + +Disabling Systemd Credentials +----------------------------- + +You can control encryption behavior by editing the `secret.conf` configura= tion +file located in ``@SYSCONFDIR@/libvirt/secret.conf`` or ``$XDG_CONFIG_HOME= /libvirt/secret.conf`` +depending on how the daemon was started (system mode or session mode respe= ctively). + +To **disable encryption entirely** (which effectively disables the use of = any +systemd credentials for this purpose): + +:: + + encrypt_data =3D 0 + +Setting ``encrypt_data =3D 0`` takes precedence over any available systemd +credentials. If you have existing encrypted secrets, this setting will pre= vent +the secret driver from loading the encryption key, making those secrets +inaccessible. New or updated secrets will be stored in plain base64 format. + +To **use a custom encryption key** instead of the systemd credential. +Defining a custom key path takes precedence over the systemd credential + +:: + + secrets_encryption_key =3D "/path/to/custom/key" + +Configuring Encryption on Non-Systemd Hosts +------------------------------------------- + +On hosts without systemd, or if you prefer to manage the key manually, you= can +create a raw encryption key and configure libvirt to use it. + +Generate a random 32-byte key: + +:: + + dd if=3D/dev/random of=3D/path/to/key/file bs=3D32 count=3D1 + +Update `secret.conf` to point to this key: + +:: + + secrets_encryption_key =3D "/path/to/key/file" + +Manual Systemd Credential Creation +---------------------------------- + +If you want to use systemd credentials but need to customize the encryptio= n parameters +(for example, to specify which TPM PCRs to bind to), you can generate the +credential file manually. + +To create the default `/var/lib/libvirt/secrets/secrets-encryption-key` ma= nually +using `systemd-creds` (adjusting arguments to `systemd-creds encrypt` as n= eeded): + +:: + + dd if=3D/dev/random bs=3D32 count=3D1 | \ + systemd-creds encrypt --name=3Dsecrets-encryption-key - \ + /var/lib/libvirt/secrets/secrets-encryption-key + +You can pass extra arguments to `systemd-creds encrypt `__, +such as ``--tpm2-device=3D...`` or ``--tpm2-pcrs=3D...``, to customize the= sealing policy. + +Upgrading Libvirt for secret encryption +--------------------------------------- +Starting 12.1.0, secrets can be stored on the disk in an encrypted format,= rather than +the default base64 encoding. + +Any secret created before upgrading libvirt, remain stored in their origin= al base64 +format on the disk. +A pre-existing secret will only be encrypted if you explicitly update its = value using +**virsh secret-set-value** after the upgrade, provided that encryption is = enabled in +secret.conf configuration file. + +It is important to note that encrypted secrets are not backwards compatibl= e. In case of +a downgrade to an older version of libvirt, the encrypted secrets will not= be loaded from +the disk. Therefore, before reverting to an older version libvirt, make su= re that all the +secrets have been reverted to the standard base64 format, to avoid service= disruptions. --=20 2.51.1