-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
split-gpg2 [1] is the planned replacement for split-gpg1 [2]. It has
several advantages, such as much lower attack surface, support for all
of gpg(1)’s options, and support for key management operations.
However, the last is also a potential security concern.
Right now, a compromised frontend VM can sign or decrypt messages with
any key in the backend VM, but it *cannot* sign or revoke keys. This
limitation is also useful, since a mail client (for example) has no need
to perform these operations. However it is difficult for split-gpg2 to
enforce this restriction.
The technical reason for this restriction is that the “type” byte in an
OpenPGP signature of a message is always 0 or 1, but other signatures
use different types. The type of a signature is part of the signed
data, so it is not possible to pretend that a signature of one type is a
signature of another type. The type of a signature that GnuPG will
generate depends on the options passed to it, but split-gpg1 only allows
a subset of these options. The subset of options passed by split-gpg1
only allow signatures of type 0 or 1 to be created, and those are only
valid as signatures of messages.
Unfortunately, split-gpg2 does not see the data being signed! It only
sees the hash of that data. Therefore, split-gpg2 has no idea what type
of signature it is making: it could be a signature on a binary document,
a signature of a key and user ID, or even something that is not an
OpenPGP signature at all. For instance, gpgsm also uses gpg-agent, and
so is also supported by split-gpg2. It generates CMS (Cryptographic
Message Syntax, also known as S/MIME) signatures, which are different
than OpenPGP signatures.
The best solution that I have come up with is to not allow the frontend
to use any key it wishes, but only allow it to use a subset of keys.
Migrating from split-gpg1 to split-gpg2 would involve generating a
subkey that is capable of signing data, but is *not* capable of
certification (signing other keys, revoking keys, etc). split-gpg2
would then be configured to only allow the frontend to use this subkey,
*not* the main key. The frontend could still generate signatures of
other keys with this subkey, but these signatures are not valid. If a
program trusts these signatures, then either it has imported a key
controlled by the frontend (in which case the frontend could have just
generated its own key) or the program has a security vulnerability.
Sadly, split-gpg2 does not have support for this — yet. There is no
fundamental reason such support cannot be added, but right now
split-gpg2 (like split-gpg1) either allows all access or denies all
access. There are various workarounds, but all of them are more complex
than I would like.
What are people’s thoughts on this issue? In the short term, one option
is to use split-gpg2 as the backend for split-gpg1, which works fine.
However, split-gpg1 is a maintenance hog with a lot of attack surface,
so migrating entirely to split-gpg2 is definitely preferred.
[1]:
https://github.com/QubesOS/qubes-app-linux-split-gpg2
[2]:
https://github.com/QubesOS/qubes-app-linux-split-gpg
- --
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab
-----BEGIN PGP SIGNATURE-----
iQIzBAEBCgAdFiEEdodNnxM2uiJZBxxxsoi1X/+cIsEFAmLA9hgACgkQsoi1X/+c
IsE4QQ/+Mrou3OjktLirktp3QsSB6SuINxoY+oSUScecz10SnQkyMORkn+D3xGZq
Ed7xa8E1VIpws7KNHrqc01q5jW4OpccZSrHhnI2SMGdNGeo5r4BA+R7+YaSU40g2
iqJ1Blt15nT1QDl+fEwtO8bgWYrMiN5IYOiSKx+vrsBy83qnvWRp8CogO9Zr9JjW
Bsg8qrWklsUT3/VCA+9zosBtjXx749NBZpdHMw/kK7ulhHvNrtcSMFDIx8Fyl5XH
dMXV8Lj65zF/g70gOck/4EIfVuFzOFo3LmfiVXQgZFmn80q2hJe2Fr3G2N0troG5
V3+vg4+1ed1p3mPVhzZEfYkmBrEqKsma1CVTctmMMPLTdiHGojbjbd+U2zgqHM8w
8K/+aPL3/KCy6h9zIY0/aSyLgDueUfdgvsGwlA9GpumaX3lDjFF6SpnYPgrnysd/
3bMSwXejSWpNwqIR5zmAllR5l23k1Oz0Y2fRMaHTeMhj/jqn/X9g1nNpCRckFkpu
899ihnmHl+otpyLavRusfctGFmnngBcjNJhIPrXAry5ECioOcIHC38GXX3xuLt30
ss6lNgGrMxQU/6pd89rRWlVGHiC3h6rkHI5v67bcOD9KPWNQEeQADRXYHgc8eDOi
e5m7TFF/L1OGmZPwHChP4ae+pSXE7X791vOpnl9d7h3gfYQ3sKo=
=wpg3
-----END PGP SIGNATURE-----