From 2402e810534f87124b5e279a781823a7f3b2d15e Mon Sep 17 00:00:00 2001 From: parulin <161326115+parulin@users.noreply.github.com> Date: Tue, 12 Aug 2025 13:29:35 -0400 Subject: [PATCH 1/4] Rewrite Split GPG-2 tutorial I am not very convinced by my own edits. I tried to keep the old version as much as possible while trying to reorganize the content structure. I don't really understand Split GPG-2, so I only provided instructions from my own experience. * limit references to smart cards and go straight up to the point * insert instructions about installation * follow the documentation style guide as much as possible * detail the configuration options in "Advanced usage" This piece of software merits better documentation! --- .../split-gpg2/client-qube-settings.png | Bin 0 -> 40533 bytes index.rst | 3 +- user/security-in-qubes/split-gpg-2.rst | 216 +++++++++++++----- user/security-in-qubes/split-gpg.rst | 3 +- 4 files changed, 160 insertions(+), 62 deletions(-) create mode 100644 attachment/split-gpg2/client-qube-settings.png diff --git a/attachment/split-gpg2/client-qube-settings.png b/attachment/split-gpg2/client-qube-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..95bd2db9b93f4441f0e83a8b2678221efae6474d GIT binary patch literal 40533 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 + user/security-in-qubes/split-gpg-2 user/security-in-qubes/mfa user/security-in-qubes/ctap-proxy diff --git a/user/security-in-qubes/split-gpg-2.rst b/user/security-in-qubes/split-gpg-2.rst index 734097b7..0c4e5574 100644 --- a/user/security-in-qubes/split-gpg-2.rst +++ b/user/security-in-qubes/split-gpg-2.rst @@ -2,91 +2,142 @@ Split GPG-2 =========== +Split GPG-2 allows less trusted qubes to delegate GPG operations to another trusted qube (i.e. a network-isolated qube). The encryption, decryption and signing operations are handled by the trusted qube. -Split GPG implements a concept similar to having a smart card with your private GPG keys, except that the role of the “smart card” is played by another Qubes app qube. This way one not-so-trusted domain, e.g. the one where Thunderbird is running, can delegate all crypto operations – such as encryption/decryption and signing – to another, more trusted, network-isolated domain. This way the compromise of your domain where Thunderbird or another client app is running – arguably a not-so-unthinkable scenario – does not allow the attacker to automatically also steal all your keys. (We should make a rather obvious comment here that the so-often-used passphrases on private keys are pretty meaningless because the attacker can easily set up a simple backdoor which would wait until the user enters the passphrase and steal the key then.) +With Split GPG-2, you can use the Thunderbird mail client in one qube, and hold your GPG secret keys in another qube. This way the compromise of your qube where Thunderbird is running does not allow the attacker to automatically also steal all your keys. -|split-gpg-diagram.png| +.. figure:: /attachment/doc/split-gpg-diagram.png + :alt: -This diagram presents an overview of the Split GPG architecture. + Example of the Split GPG-2 architecture -Advantages of Split GPG vs. traditional GPG with a smart card -------------------------------------------------------------- + In a qube called *work-email* (with a green level of trust), ``qubes-gpg-client`` pretends to be a standard ``/usr/bin/gpg`` to other apps, here with Thunderbird. + In the *work-email* qube, ``qubes-gpg-client`` is communicating with ``qubes-gpg-server`` located in the *work-gpg* qube (with a black level of trust). The communication is made through the ``qubes.Gpg2`` remote procedure call using the ``qrexec`` protocol. -It is often thought that the use of smart cards for private key storage guarantees ultimate safety. While this might be true (unless the attacker can find a usually-very-expensive-and-requiring-physical-presence way to extract the key from the smart card) but only with regards to the safety of the private key itself. However, there is usually nothing that could stop the attacker from requesting the smart card to perform decryption of all the user documents the attacker has found or need to decrypt. In other words, while protecting the user’s private key is an important task, we should not forget that ultimately it is the user data that are to be protected and that the smart card chip has no way of knowing the requests to decrypt documents are now coming from the attacker’s script and not from the user sitting in front of the monitor. (Similarly the smart card doesn’t make the process of digitally signing a document or a transaction in any way more secure – the user cannot know what the chip is really signing. Unfortunately this problem of signing reliability is not solvable by Split GPG.) + Inside the *work-gpg* qube, ``qubes-gpg-server`` has access to the GPG key, through ``/usr/bin/gpg``. -With Qubes Split GPG this problem is drastically minimized, because each time the key is to be used the user is asked for consent (with a definable time out, 5 minutes by default), plus is always notified each time the key is used via a tray notification from the domain where GPG backend is running. This way it would be easy to spot unexpected requests to decrypt documents. +The following page will setup Split GPG-2 with two qubes: -Configuration -------------- +* one qube holding the private keys, called **server-qube** (in the previous example, it is the role of *work-gpg*) +* the other qube using the keys, called **client-qube** (in the previous example, it *work-email*, where Thunderbird is used) +Installation of Split GPG-2 +--------------------------- -Create/Edit ``/etc/qubes/policy.d/30-user-gpg2.policy`` in dom0, and add a line like this: +In the template(s) qube(s) used by *server-qube* and *client-qube*, install ``split-gpg2``: -.. code:: bash +* **with Fedora**: - qubes.Gpg2 + gpg-client-vm @default allow target=gpg-server-vm + .. code:: console + [root@fedora-template] # dnf install split-gpg2 +* **with Debian**: -Import/Generate your secret keys in the server domain. For example: + .. code:: console -.. code:: bash + [root@debian-template] # apt install split-gpg2 - gpg-server-vm$ gpg --import /path/to/my/secret-keys-export - gpg-server-vm$ gpg --import-ownertrust /path/to/my/ownertrust-export +.. note:: If you use a minimal template, make sure to install ``zenity`` +Configuration of Split GPG-2 +---------------------------- +Create a new policy in dom0 +^^^^^^^^^^^^^^^^^^^^^^^^^^^ -or +**In dom0**, create or edit a RPC policy. Use either the *Qubes OS Policy Editor* program or the ``qubes-policy-editor`` command. You can call is :file:`{30-user-gpg2}.policy` or something else. Add a line like the following and make sure to replace :samp:`{client-qube}` and :samp:`{server-qube}` by the appropriate values. -.. code:: bash +.. code:: text - gpg-server-vm$ gpg --gen-key + qubes.Gpg2 + client-qube @default allow target=server-qube +Generate or import the secret keys in the server qube +""""""""""""""""""""""""""""""""""""""""""""""""""""" +**In server-qube**: -In dom0 enable the ``split-gpg2-client`` service in the client domain, for example via the command-line: +* generate your secret keys, like this: -.. code:: bash + .. code:: console - dom0$ qvm-service split-gpg2-client on + [user@server-qube] $ gpg --gen-key + In that case, you have to export the public part of your keys and the "ownertrust" values in the client qube: -To verify if this was done correctly: + .. code:: console -.. code:: bash + [user@server-qube] $ gpg --export > public-keys-export + [user@server-qube] $ gpg --export-ownertrust > ownertrust-export + [user@server-qube] $ qvm-copy public-keys-export ownertrust-export - dom0$ qvm-service + .. warning:: do not export the private keys ! +* or import your secret keys, like the following example. Make sure to replace :file:`/path/to/my/{name-of-the-file}` by the path of the expected file: -Output should be: + .. code:: console -.. code:: bash + [user@server-qube] $ gpg --import /path/to/my/secret-keys-export + [user@server-qube] $ gpg --import-ownertrust /path/to/my/ownertrust-export - split-gpg2-client on +Set up the client qube +^^^^^^^^^^^^^^^^^^^^^^ +The first step is to enable the ``split-gpg2-client`` service. There is two options to do it, with the client qube's settings or with the ``qvm-service`` command. -Restart the client domain. +Enable ``split-gpg2-client`` with the qube's settings +""""""""""""""""""""""""""""""""""""""""""""""""""""" -Export the **public** part of your keys and import them in the client domain. Also import/set proper “ownertrust” values. For example: +Follow these steps: -.. code:: bash +1. Open the *client-qube*'s settings +2. Select the :guilabel:`Services` tab +3. At the top, in :guilabel:`Select a service`, select :guilabel:`split-gpg2-client` +4. Click on the :guilabel:`Add` button +5. Click on :guilabel:`Apply` or :guilabel:`Ok` to validate - gpg-server-vm$ gpg --export > public-keys-export - gpg-server-vm$ gpg --export-ownertrust > ownertrust-export - gpg-server-vm$ qvm-copy public-keys-export ownertrust-export - - gpg-client-vm$ gpg --import ~/QubesIncoming/gpg-server-vm/public-keys-export - gpg-client-vm$ gpg --import-ownertrust ~/QubesIncoming/gpg-server-vm/ownertrust-export +.. figure:: /attachment/split-gpg2/client-qube-settings.png + :alt: + :guilabel:`split-gpg2-client` should be listed and the checkbox in front of this service should be checked. +Enable ``split-gpg2-client`` with ``qvm-service`` +""""""""""""""""""""""""""""""""""""""""""""""""" + +Enable the service in the *client-qube*: + +.. code:: console + + [user@dom0] $ qvm-service client-qube split-gpg2-client on + +To verify if this was done correctly type the following command and check that the output on the second line is ``on``: + +.. code:: console + + [user@dom0] $ qvm-service client-qube split-gpg2-client + on + +If *client-qube* is running, restart it. + +Import the public keys and ownertrust +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +You have previously exported the public keys and the "ownertrust" values from *server-qube*. Now, you have to import them in the client qube. Replace the following paths by the correct values. + +.. code:: console + + [user@client-qube] $ gpg --import /home/user/QubesIncoming/server-qube/public-keys-export + [user@client-qube] $ gpg --import-ownertrust /home/user/QubesIncoming/server-qube/ownertrust-export + +Check that Split GPG-2 works +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This should be enough to have it running: -.. code:: bash +.. code:: console - gpg-client-vm$ gpg -K + [user@client-qube] $ gpg -K /home/user/.gnupg/pubring.kbx ----------------------------- sec# rsa2048 2019-12-18 [SC] [expires: 2021-12-17] @@ -94,50 +145,97 @@ This should be enough to have it running: uid [ultimate] test ssb# rsa2048 2019-12-18 [E] +Troubleshooting +--------------- - -If you want change some server option copy ``/usr/share/doc/split-gpg2/examples/qubes-split-gpg2.conf.example`` to ``~/.config/qubes-split-gpg2/qubes-split-gpg2.conf`` and change it as desired, it will take precedence over other loaded files, such as the drop-in configuration files with the suffix ``.conf`` in ``~/.config/qubes-split-gpg2/conf.d/``. +``gpg-agent`` only shows the "keygrip" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If you have a passphrase on your keys and ``gpg-agent`` only shows the “keygrip” (something like the fingerprint of the private key) when asking for the passphrase, then make sure that you have imported the public key part in the server domain. Subkeys vs primary keys ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ +Split GPG-2 only knows a hash of the data being signed. Therefore, it cannot differentiate between e.g. signatures of a piece of data or signatures of another key. This means that a client can use Split GPG-2 to sign other keys, which :doc:`split-gpg` did not allow. -split-gpg2 only knows a hash of the data being signed. Therefore, it cannot differentiate between e.g. signatures of a piece of data or signatures of another key. This means that a client can use split-gpg2 to sign other keys, which split-gpg1 did not allow. - -To prevent this, split-gpg2 creates a new GnuPG home directory and imports the secret subkeys (**not** the primary key!) to it. Clients will be able to use the secret parts of the subkeys, but not of the primary key. If your primary key is able to sign data and certify other keys, and your only subkey can only perform encryption, this means that all signing will fail. To make signing work again, generate a subkey that is capable of signing but **not** certification. split-gpg2 does not generate this key for you, so you need to generate it yourself. If you want to generate a key in software, use the ``addkey`` command of ``gpg2 --edit-key``. If you want to generate a key on a smartcard or other hardware token, use ``addcardkey`` instead. +To prevent this, Split GPG-2 creates a new GnuPG home directory and imports the secret subkeys (**not** the primary key!) to it. Clients will be able to use the secret parts of the subkeys, but not of the primary key. If your primary key is able to sign data and certify other keys, and your only subkey can only perform encryption, this means that all signing will fail. To make signing work again, generate a subkey that is capable of signing but **not** certification. Split GPG-2 does not generate this key for you, so you need to generate it yourself. If you want to generate a key in software, use the ``addkey`` command of ``gpg2 --edit-key``. If you want to generate a key on a smartcard or other hardware token, use ``addcardkey`` instead. You will need to import your public keys again. Advanced usage -------------- +If you want change some server option copy :file:`/usr/share/doc/split-gpg2/examples/qubes-split-gpg2.conf.example` to :file:`/home/user/.config/qubes-split-gpg2/qubes-split-gpg2.conf` and change it as desired, it will take precedence over other loaded files, such as the drop-in configuration files with the suffix ``.conf`` in `/home/user/.config/qubes-split-gpg2/conf.d/`. -There are a few option not described in this README. See the comments in the example `config and the source code `__. +By setting up some values in the configuration file, you can change some parameters. The configurations files are INI files, you can set global options in the ``DEFAULT`` section, or provide some client specific options in their own :samp:`client:{QUBE_NAME}` section (where ``QUBE_NAME`` is the name of the client). The following configuration is an example where no qube is automatically accepted besides *personal* qube: -Similar to a smartcard, split-gpg2 only tries to protect the private key. For advanced usages, consider if a specialized RPC service would be better. It could do things like checking what data is singed, detailed logging, exposing the encrypted content only to a VM without network, etc. +.. code:: ini -Using split-gpg2 as the “backend” for split-gpg1 is known to work. + [DEFAULT] + autoaccept = no + + [client:personal] + autoaccept = yes + +Automatically accept requests +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +By default, all requests made to the *server-qube* need to be confirmed. If you already use a RPC policy to ask confirmation, you can tell Split GPG-2 to automatically accept all requests, always or during a period of time after a successful request. You have to put something like this in you configuration file: + +.. code:: ini + + autoaccept = yes + +To accept all requests following a successful one during one minute (60 seconds), use this: + +.. code:: ini + + autoaccept = 60 + +This option has two alternatives: + +``pksign_autoaccept`` + same as ``autoaccept`` but only for signing requests + +``pkdecrypt_autoaccept`` + same as ``autoaccept`` but only for decrypt requests + +Notifications +^^^^^^^^^^^^^ + +Setting ``verbose_notifications`` to ``yes`` will provide more notifications. + +Edit GnuPG home +^^^^^^^^^^^^^^^ + +You can set up a different GnuPG home from the default :file:`/home/user/gpg-home`, using ``gnupghome``. + +If you store different keys for different client qubes in the same server qube, you can isolate each GnuPG home, by setting ``isolated_gnupghome``. The value points at a directory where each client will get its own subdirectory. For example when this option is set to :file:`/home/user/gpg-home`, then the qube *personal* will use :file:`/home/user/gpg-home/{personal}` as GnuPG home. + +If you do this, don't forget to use the option ``--gnupg-home`` or the environment variable ``GNUPGHOME`` when using ``gpg`` commands. Allow key generation --------------------- +^^^^^^^^^^^^^^^^^^^^ +.. warning:: This feature is new and not much tested. Therefore it’s not security supported! By setting ``allow_keygen = yes`` in ``qubes-split-gpg2.conf`` you can allow the client to generate new keys. Normal usage should not need this. -**Warning**: This feature is new and not much tested. Therefore it’s not security supported! +Notes +----- -Copyright ---------- +Using Split GPG-2 with Split GPG-1 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -| Copyright (C) 2014 HW42 `hw42@ipsumj.de `__ -| Copyright (C) 2019 Marek Marczykowski-Górecki `marmarek@invisiblethingslab.com `__ +Using Split GPG-2 as the “backend” for :doc:`split-gpg` is known to work. +Advanced usage: checking what is signed, etc. +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. +Similar to a smartcard, Split GPG-2 only tries to protect the private key. For advanced usages, consider if a specialized RPC service would be better. It could do things like checking what data is singed, detailed logging, exposing the encrypted content only to a VM without network, etc. -This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +Advantages of Split GPG vs. traditional GPG with a smart card +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +It is often thought that the use of smart cards for private key storage guarantees ultimate safety. While this might be true (unless the attacker can find a usually-very-expensive-and-requiring-physical-presence way to extract the key from the smart card) but only with regards to the safety of the private key itself. However, there is usually nothing that could stop the attacker from requesting the smart card to perform decryption of all the user documents the attacker has found or need to decrypt. In other words, while protecting the user’s private key is an important task, we should not forget that ultimately it is the user data that are to be protected and that the smart card chip has no way of knowing the requests to decrypt documents are now coming from the attacker’s script and not from the user sitting in front of the monitor. (Similarly the smart card doesn't make the process of digitally signing a document or a transaction in any way more secure – the user cannot know what the chip is really signing. Unfortunately this problem of signing reliability is not solvable by Split GPG.) + +With Qubes Split GPG-2 this problem is drastically minimized, because each time the key is to be used the user is asked for consent (with a definable time out, 5 minutes by default), plus is always notified each time the key is used via a tray notification from the domain where GPG backend is running. This way it would be easy to spot unexpected requests to decrypt documents. -.. |split-gpg-diagram.png| image:: /attachment/doc/split-gpg-diagram.png - diff --git a/user/security-in-qubes/split-gpg.rst b/user/security-in-qubes/split-gpg.rst index 70d1a349..94dcad4c 100644 --- a/user/security-in-qubes/split-gpg.rst +++ b/user/security-in-qubes/split-gpg.rst @@ -2,10 +2,9 @@ Split GPG ========= - .. warning:: - **Note:** This information concerns split-gpg. The implementation has been updated to provide more features in split-gpg-2. Some incomplete information on split-gpg-2 is available :doc:`here `. + The implementation has been updated to provide more features in :doc:`split-gpg-2`. Split GPG implements a concept similar to having a smart card with your private GPG keys, except that the role of the “smart card” is played by another Qubes app qube. This way one not-so-trusted domain, e.g. the one where Thunderbird is running, can delegate all crypto operations – such as encryption/decryption and signing – to another, more trusted, network-isolated domain. This way the compromise of your domain where Thunderbird or another client app is running – arguably a not-so-unthinkable scenario – does not allow the attacker to automatically also steal all your keys. (We should make a rather obvious comment here that the so-often-used passphrases on private keys are pretty meaningless because the attacker can easily set up a simple backdoor which would wait until the user enters the passphrase and steal the key then.) From 67ee0781716e3aa7dd57c7315b8d8b90b5fc4f47 Mon Sep 17 00:00:00 2001 From: parulin <161326115+parulin@users.noreply.github.com> Date: Thu, 21 Aug 2025 06:04:48 -0400 Subject: [PATCH 2/4] Simplify Split GPG-2 I came across the diataxis approach and used it to get a better understanding of this page. Additionnaly, I did this: * move instructions to edit a policy and to enable a service qube to the related pages * clean the structure of the server options and make them cross-referenceable using `:confval:` role --- .../split-gpg2/client-qube-settings.png | Bin 40533 -> 0 bytes user/security-in-qubes/split-gpg-2.rst | 226 ++++++++---------- 2 files changed, 105 insertions(+), 121 deletions(-) delete mode 100644 attachment/split-gpg2/client-qube-settings.png diff --git a/attachment/split-gpg2/client-qube-settings.png b/attachment/split-gpg2/client-qube-settings.png deleted file mode 100644 index 95bd2db9b93f4441f0e83a8b2678221efae6474d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 40533 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. .. note:: If you use a minimal template, make sure to install ``zenity`` -Configuration of Split GPG-2 ----------------------------- +Create a policy for Split GPG-2 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Create a new policy in dom0 -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -**In dom0**, create or edit a RPC policy. Use either the *Qubes OS Policy Editor* program or the ``qubes-policy-editor`` command. You can call is :file:`{30-user-gpg2}.policy` or something else. Add a line like the following and make sure to replace :samp:`{client-qube}` and :samp:`{server-qube}` by the appropriate values. +**In dom0**, :doc:`create or edit a RPC policy `. Add a line like the following and make sure to replace :samp:`{client-qube}` and :samp:`{server-qube}` by the appropriate values. .. code:: text qubes.Gpg2 + client-qube @default allow target=server-qube Generate or import the secret keys in the server qube -""""""""""""""""""""""""""""""""""""""""""""""""""""" +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -**In server-qube**: +**In server-qube**, you have two options: -* generate your secret keys, like this: +* either generate your secret keys, like this: .. code:: console [user@server-qube] $ gpg --gen-key - In that case, you have to export the public part of your keys and the "ownertrust" values in the client qube: +* or, if you want to use some old keys, previously generated in an other qube, import them and the ownertrust. Make sure to replace :file:`/home/user/QubesIncoming/{}/{[...]}` by the path of the expected file: .. code:: console - [user@server-qube] $ gpg --export > public-keys-export - [user@server-qube] $ gpg --export-ownertrust > ownertrust-export - [user@server-qube] $ qvm-copy public-keys-export ownertrust-export + [user@server-qube] $ gpg --import /home/user/QubesIncoming//secret-keys-export + [user@server-qube] $ gpg --import-ownertrust /home/user/QubesIncoming//ownertrust-export - .. warning:: do not export the private keys ! +In both situations, you have to export the public part of your keys and the "ownertrust" values in the client qube: -* or import your secret keys, like the following example. Make sure to replace :file:`/path/to/my/{name-of-the-file}` by the path of the expected file: +.. code:: console - .. code:: console + [user@server-qube] $ gpg --export > public-keys-export + [user@server-qube] $ gpg --export-ownertrust > ownertrust-export + [user@server-qube] $ qvm-copy public-keys-export ownertrust-export - [user@server-qube] $ gpg --import /path/to/my/secret-keys-export - [user@server-qube] $ gpg --import-ownertrust /path/to/my/ownertrust-export +.. warning:: do not export the private keys ! -Set up the client qube -^^^^^^^^^^^^^^^^^^^^^^ +Set up the *client qube* +^^^^^^^^^^^^^^^^^^^^^^^^ -The first step is to enable the ``split-gpg2-client`` service. There is two options to do it, with the client qube's settings or with the ``qvm-service`` command. - -Enable ``split-gpg2-client`` with the qube's settings +Enable ``split-gpg2-client`` service in *client qube* """"""""""""""""""""""""""""""""""""""""""""""""""""" -Follow these steps: - -1. Open the *client-qube*'s settings -2. Select the :guilabel:`Services` tab -3. At the top, in :guilabel:`Select a service`, select :guilabel:`split-gpg2-client` -4. Click on the :guilabel:`Add` button -5. Click on :guilabel:`Apply` or :guilabel:`Ok` to validate - -.. figure:: /attachment/split-gpg2/client-qube-settings.png - :alt: - - :guilabel:`split-gpg2-client` should be listed and the checkbox in front of this service should be checked. - -Enable ``split-gpg2-client`` with ``qvm-service`` -""""""""""""""""""""""""""""""""""""""""""""""""" - -Enable the service in the *client-qube*: - -.. code:: console - - [user@dom0] $ qvm-service client-qube split-gpg2-client on - -To verify if this was done correctly type the following command and check that the output on the second line is ``on``: - -.. code:: console - - [user@dom0] $ qvm-service client-qube split-gpg2-client - on - -If *client-qube* is running, restart it. +The first step is to :doc:`enable the qube service ` called ``split-gpg2-client``. Import the public keys and ownertrust -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +""""""""""""""""""""""""""""""""""""" -You have previously exported the public keys and the "ownertrust" values from *server-qube*. Now, you have to import them in the client qube. Replace the following paths by the correct values. +If you have previously exported the public keys and the "ownertrust" values from *server-qube*. Now, you have to import them in the client qube. Replace the following paths by the correct values. .. code:: console @@ -133,7 +81,7 @@ You have previously exported the public keys and the "ownertrust" values from *s Check that Split GPG-2 works ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This should be enough to have it running: +You should be able to run ``gpg -K`` in the *client qube*: .. code:: console @@ -146,24 +94,24 @@ This should be enough to have it running: ssb# rsa2048 2019-12-18 [E] Troubleshooting ---------------- +^^^^^^^^^^^^^^^ ``gpg-agent`` only shows the "keygrip" -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""""""""""""""""""" If you have a passphrase on your keys and ``gpg-agent`` only shows the “keygrip” (something like the fingerprint of the private key) when asking for the passphrase, then make sure that you have imported the public key part in the server domain. Subkeys vs primary keys -^^^^^^^^^^^^^^^^^^^^^^^ +""""""""""""""""""""""" Split GPG-2 only knows a hash of the data being signed. Therefore, it cannot differentiate between e.g. signatures of a piece of data or signatures of another key. This means that a client can use Split GPG-2 to sign other keys, which :doc:`split-gpg` did not allow. To prevent this, Split GPG-2 creates a new GnuPG home directory and imports the secret subkeys (**not** the primary key!) to it. Clients will be able to use the secret parts of the subkeys, but not of the primary key. If your primary key is able to sign data and certify other keys, and your only subkey can only perform encryption, this means that all signing will fail. To make signing work again, generate a subkey that is capable of signing but **not** certification. Split GPG-2 does not generate this key for you, so you need to generate it yourself. If you want to generate a key in software, use the ``addkey`` command of ``gpg2 --edit-key``. If you want to generate a key on a smartcard or other hardware token, use ``addcardkey`` instead. You will need to import your public keys again. -Advanced usage +Server options -------------- -If you want change some server option copy :file:`/usr/share/doc/split-gpg2/examples/qubes-split-gpg2.conf.example` to :file:`/home/user/.config/qubes-split-gpg2/qubes-split-gpg2.conf` and change it as desired, it will take precedence over other loaded files, such as the drop-in configuration files with the suffix ``.conf`` in `/home/user/.config/qubes-split-gpg2/conf.d/`. +If you want change some server option, copy :file:`/usr/share/doc/split-gpg2/examples/qubes-split-gpg2.conf.example` to :file:`/home/user/.config/qubes-split-gpg2/qubes-split-gpg2.conf` and change it as desired, it will take precedence over other loaded files, such as the drop-in configuration files with the suffix ``.conf`` in `/home/user/.config/qubes-split-gpg2/conf.d/`. By setting up some values in the configuration file, you can change some parameters. The configurations files are INI files, you can set global options in the ``DEFAULT`` section, or provide some client specific options in their own :samp:`client:{QUBE_NAME}` section (where ``QUBE_NAME`` is the name of the client). The following configuration is an example where no qube is automatically accepted besides *personal* qube: @@ -175,52 +123,88 @@ By setting up some values in the configuration file, you can change some paramet [client:personal] autoaccept = yes -Automatically accept requests -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. confval:: autoaccept -By default, all requests made to the *server-qube* need to be confirmed. If you already use a RPC policy to ask confirmation, you can tell Split GPG-2 to automatically accept all requests, always or during a period of time after a successful request. You have to put something like this in you configuration file: + :type: text + :default: ``no`` + :allowed values: ``no``, ``yes`` or any integer -.. code:: ini - - autoaccept = yes - -To accept all requests following a successful one during one minute (60 seconds), use this: - -.. code:: ini - - autoaccept = 60 + By default, all requests made to the *server-qube* need to be confirmed. You can tell Split GPG-2 to accept requests: never (``no``), always (``yes``) or during a period of time after a successful request. To accept all requests following a successful one during one minute, use a value of ``60`` seconds. This option has two alternatives: -``pksign_autoaccept`` - same as ``autoaccept`` but only for signing requests +.. confval:: pksign_autoaccept -``pkdecrypt_autoaccept`` - same as ``autoaccept`` but only for decrypt requests + :type: boolean or integer + :default: ``no`` + :allowed values: ``no``, ``yes`` or any integer -Notifications -^^^^^^^^^^^^^ + same as :confval:`autoaccept` but only for signing requests -Setting ``verbose_notifications`` to ``yes`` will provide more notifications. +.. confval:: pkdecrypt_autoaccept -Edit GnuPG home -^^^^^^^^^^^^^^^ + :type: boolean or integer + :default: ``no`` + :allowed values: ``no``, ``yes`` or any integer -You can set up a different GnuPG home from the default :file:`/home/user/gpg-home`, using ``gnupghome``. + same as :confval:`autoaccept` but only for decrypt requests -If you store different keys for different client qubes in the same server qube, you can isolate each GnuPG home, by setting ``isolated_gnupghome``. The value points at a directory where each client will get its own subdirectory. For example when this option is set to :file:`/home/user/gpg-home`, then the qube *personal* will use :file:`/home/user/gpg-home/{personal}` as GnuPG home. +.. confval:: verbose_notifications -If you do this, don't forget to use the option ``--gnupg-home`` or the environment variable ``GNUPGHOME`` when using ``gpg`` commands. + :type: boolean + :default: ``no`` + :allowed values: ``no`` or ``yes`` -Allow key generation -^^^^^^^^^^^^^^^^^^^^ + Setting ``verbose_notifications`` to ``yes`` will provide more notifications. -.. warning:: This feature is new and not much tested. Therefore it’s not security supported! +.. confval:: allow_keygen -By setting ``allow_keygen = yes`` in ``qubes-split-gpg2.conf`` you can allow the client to generate new keys. Normal usage should not need this. + :type: boolean + :default: ``no`` + :allowed values: ``no`` or ``yes`` -Notes ------ + .. warning:: This feature is new and not much tested. Therefore it’s not security supported! + + By setting :confval:`allow_keygen` to ``yes``, you can allow the client to generate new keys. Normal usage should not need this. + +.. confval:: gnupghome + + :type: full path + :default: empty + + You can set up a different GnuPG home from the default :file:`/home/user/gpg-home`, using :confval:`gnupghome`. + +.. confval:: isolated_gnupghome + + :type: full path + :default: empty + + If you store different keys for different client qubes in the same server qube, you can isolate each GnuPG home, by setting :confval:`isolated_gnupghome`. The value points at a directory where each client will get its own subdirectory. For example, when this option is set to :file:`/home/user/gpg-home`, then the qube *personal* will use :file:`/home/user/gpg-home/{personal}` as GnuPG home. + + If you do this, don't forget to use the option ``--gnupg-home`` or the environment variable ``GNUPGHOME`` when using :program:`gpg` commands. + +.. confval:: debug_log + + :type: path + :default: empty + + Enable debug logging and set the debug log path. + + .. warning:: This is for debugging purpose only, **everything will be logged** including potentially confidential data/keys/etc + +Notes about Split GPG-2 +----------------------- + +.. figure:: /attachment/doc/split-gpg-diagram.png + :alt: + + Example of the Split GPG-2 architecture + + In a qube called *work-email* (with a green level of trust), ``qubes-gpg-client`` pretends to be a standard ``/usr/bin/gpg`` to other apps, here with Thunderbird. + + In the *work-email* qube, ``qubes-gpg-client`` is communicating with ``qubes-gpg-server`` located in the *work-gpg* qube (with a black level of trust). The communication is made through the ``qubes.Gpg2`` remote procedure call using the ``qrexec`` protocol. + + Inside the *work-gpg* qube, ``qubes-gpg-server`` has access to the GPG key, through ``/usr/bin/gpg``. Using Split GPG-2 with Split GPG-1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -230,7 +214,7 @@ Using Split GPG-2 as the “backend” for :doc:`split-gpg` is known to work. Advanced usage: checking what is signed, etc. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Similar to a smartcard, Split GPG-2 only tries to protect the private key. For advanced usages, consider if a specialized RPC service would be better. It could do things like checking what data is singed, detailed logging, exposing the encrypted content only to a VM without network, etc. +Similar to a smartcard, Split GPG-2 only tries to protect the private key. For advanced usages, consider if a specialized RPC service would be better. It could do things like checking what data is signed, detailed logging, exposing the encrypted content only to a VM without network, etc. Advantages of Split GPG vs. traditional GPG with a smart card ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 4f6f82029a4e4c87578e4a33be3b2a154c7fad42 Mon Sep 17 00:00:00 2001 From: parulin <161326115+parulin@users.noreply.github.com> Date: Thu, 11 Dec 2025 03:40:26 -0500 Subject: [PATCH 3/4] Note about passphrase and consistent naming Use "client qube" and "server qube" as much as possible. --- user/security-in-qubes/split-gpg-2.rst | 32 ++++++++++++++------------ 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/user/security-in-qubes/split-gpg-2.rst b/user/security-in-qubes/split-gpg-2.rst index a2bcfac7..967e1e2c 100644 --- a/user/security-in-qubes/split-gpg-2.rst +++ b/user/security-in-qubes/split-gpg-2.rst @@ -11,33 +11,33 @@ This way the compromise of your less trusted qube does not allow the attacker to How-to split your GPG keys between two qubes -------------------------------------------- -The following how-to will setup Split GPG-2 with two qubes: +The following how-to will set up Split GPG-2 with two qubes: * one qube holding the private keys, called **server-qube**. This qube is offline and should be trusted. * the other qube using the keys, called **client-qube**. This qube doesn't have to be trusted as much as the server. -Each time you want to do something with a GPG key, the *client-qube* will delegate the operation to the *server-qube*. This qube will ask you to confirm the operation. +Each time you want to do something with a GPG key, the *client qube* will delegate the operation to the *server qube*. This qube will ask you to confirm the operation. Install Split GPG-2 ^^^^^^^^^^^^^^^^^^^ -In the template(s) qube(s) used by *server-qube* and *client-qube*, :ref:`install the split-gpg2 package `. +In the template(s) qube(s) used by the *server qube* and the *client qube*, :ref:`install the split-gpg2 package `. .. note:: If you use a minimal template, make sure to install ``zenity`` Create a policy for Split GPG-2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -**In dom0**, :doc:`create or edit a RPC policy `. Add a line like the following and make sure to replace :samp:`{client-qube}` and :samp:`{server-qube}` by the appropriate values. +**In dom0**, :doc:`create or edit an RPC policy `. Add a line like the following and make sure to replace :samp:`{client-qube}` and :samp:`{server-qube}` by the appropriate values. .. code:: text qubes.Gpg2 + client-qube @default allow target=server-qube -Generate or import the secret keys in the server qube -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Generate or import the secret keys in the *server qube* +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -**In server-qube**, you have two options: +**In the server qube**, you have two options: * either generate your secret keys, like this: @@ -45,14 +45,16 @@ Generate or import the secret keys in the server qube [user@server-qube] $ gpg --gen-key -* or, if you want to use some old keys, previously generated in an other qube, import them and the ownertrust. Make sure to replace :file:`/home/user/QubesIncoming/{}/{[...]}` by the path of the expected file: +* or, if you want to use some old keys, previously generated in another qube, import them and the ownertrust. Make sure to replace :file:`/home/user/QubesIncoming/{}/{[...]}` by the path of the expected file: .. code:: console [user@server-qube] $ gpg --import /home/user/QubesIncoming//secret-keys-export [user@server-qube] $ gpg --import-ownertrust /home/user/QubesIncoming//ownertrust-export -In both situations, you have to export the public part of your keys and the "ownertrust" values in the client qube: +.. note:: Ensure your key doesn't have a passphrase set. + +In both situations, you have to export the public part of your keys and the "ownertrust" values in the *client qube*: .. code:: console @@ -65,15 +67,15 @@ In both situations, you have to export the public part of your keys and the "own Set up the *client qube* ^^^^^^^^^^^^^^^^^^^^^^^^ -Enable ``split-gpg2-client`` service in *client qube* -""""""""""""""""""""""""""""""""""""""""""""""""""""" +Enable the ``split-gpg2-client`` service in the *client qube* +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -The first step is to :doc:`enable the qube service ` called ``split-gpg2-client``. +The first step is to :doc:`enable the qube service ` called ``split-gpg2-client``. Restarting the *client qube* is needed. Import the public keys and ownertrust """"""""""""""""""""""""""""""""""""" -If you have previously exported the public keys and the "ownertrust" values from *server-qube*. Now, you have to import them in the client qube. Replace the following paths by the correct values. +If you have previously exported the public keys and the "ownertrust" values from the *server qube*. Now, you have to import them in the *client qube*. Replace the following paths by the correct values. .. code:: console @@ -131,7 +133,7 @@ By setting up some values in the configuration file, you can change some paramet :default: ``no`` :allowed values: ``no``, ``yes`` or any integer - By default, all requests made to the *server-qube* need to be confirmed. You can tell Split GPG-2 to accept requests: never (``no``), always (``yes``) or during a period of time after a successful request. To accept all requests following a successful one during one minute, use a value of ``60`` seconds. + By default, all requests made to the *server qube* need to be confirmed. You can tell Split GPG-2 to accept requests: never (``no``), always (``yes``) or during a period of time after a successful request. To accept all requests following a successful one during one minute, use a value of ``60`` seconds. This option has two alternatives: @@ -181,7 +183,7 @@ This option has two alternatives: :type: full path :default: empty - If you store different keys for different client qubes in the same server qube, you can isolate each GnuPG home, by setting :confval:`isolated_gnupghome`. The value points at a directory where each client will get its own subdirectory. For example, when this option is set to :file:`/home/user/gpg-home`, then the qube *personal* will use :file:`/home/user/gpg-home/{personal}` as GnuPG home. + If you store different keys for different *client qubes* in the same *server qube*, you can isolate each GnuPG home, by setting :confval:`isolated_gnupghome`. The value points at a directory where each client will get its own subdirectory. For example, when this option is set to :file:`/home/user/gpg-home`, then the qube *personal* will use :file:`/home/user/gpg-home/{personal}` as GnuPG home. If you do this, don't forget to use the option ``--gnupg-home`` or the environment variable ``GNUPGHOME`` when using :program:`gpg` commands. From f6587a90248059cc58e5378415f88c553c3db34b Mon Sep 17 00:00:00 2001 From: parulin <161326115+parulin@users.noreply.github.com> Date: Sun, 14 Dec 2025 04:15:50 -0500 Subject: [PATCH 4/4] Minor corrections on Split GPG 2 As suggested by @rapenne-s. Thanks. --- user/security-in-qubes/split-gpg-2.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/user/security-in-qubes/split-gpg-2.rst b/user/security-in-qubes/split-gpg-2.rst index 967e1e2c..160093a8 100644 --- a/user/security-in-qubes/split-gpg-2.rst +++ b/user/security-in-qubes/split-gpg-2.rst @@ -23,7 +23,7 @@ Install Split GPG-2 In the template(s) qube(s) used by the *server qube* and the *client qube*, :ref:`install the split-gpg2 package `. -.. note:: If you use a minimal template, make sure to install ``zenity`` +.. note:: If you use a minimal template, make sure to install ``zenity`` package. Create a policy for Split GPG-2 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -62,7 +62,7 @@ In both situations, you have to export the public part of your keys and the "own [user@server-qube] $ gpg --export-ownertrust > ownertrust-export [user@server-qube] $ qvm-copy public-keys-export ownertrust-export -.. warning:: do not export the private keys ! +.. warning:: Do not export the private keys! Set up the *client qube* ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -115,7 +115,7 @@ To prevent this, Split GPG-2 creates a new GnuPG home directory and imports the Server options -------------- -If you want change some server option, copy :file:`/usr/share/doc/split-gpg2/examples/qubes-split-gpg2.conf.example` to :file:`/home/user/.config/qubes-split-gpg2/qubes-split-gpg2.conf` and change it as desired, it will take precedence over other loaded files, such as the drop-in configuration files with the suffix ``.conf`` in `/home/user/.config/qubes-split-gpg2/conf.d/`. +If you want to change some server option, copy :file:`/usr/share/doc/split-gpg2/examples/qubes-split-gpg2.conf.example` to :file:`/home/user/.config/qubes-split-gpg2/qubes-split-gpg2.conf` and change it as desired, it will take precedence over other loaded files, such as the drop-in configuration files with the suffix ``.conf`` in `/home/user/.config/qubes-split-gpg2/conf.d/`. By setting up some values in the configuration file, you can change some parameters. The configurations files are INI files, you can set global options in the ``DEFAULT`` section, or provide some client specific options in their own :samp:`client:{QUBE_NAME}` section (where ``QUBE_NAME`` is the name of the client). The following configuration is an example where no qube is automatically accepted besides *personal* qube: @@ -129,7 +129,7 @@ By setting up some values in the configuration file, you can change some paramet .. confval:: autoaccept - :type: text + :type: boolean or integer :default: ``no`` :allowed values: ``no``, ``yes`` or any integer