Giter Site home page Giter Site logo

qubes-app-linux-split-gpg2's Introduction

split-gpg2

About split-gpg2

This software allows you to separate the handling of private key material from the rest of GnuPG's processing. This is similar to how smartcards work, except that in this case the handling of the private key is not put into some small microcontroller but into another Qubes domain.

Since GnuPG 2.1.0 the private gpg keys are handled by the gpg-agent. This allows to split gpg (the cmdline tool - handles public keys, etc.) and the gpg-agent which handles the private keys. This software implements this for Qubes. This mainly consists of a restrictive filter in front of gpg-agent, written in a memory safe language (python).

The server is the domain which runs the (real) gpg-agent and has access to your private key material. The client is the domain in which you run gpg and which accesses the server via Qubes RPC.

The server domain is generally considered more trustful then the client domain. This implies that the response from the server is not sanitized.

Requirements

  • Python 3.5 or newer
  • GnuPG 2.1 or newer

Building

Add it as a component to qubes-builder and built it.

For development you can also build the Debian packet in tree. Just run dpkg-buildpackage -us -uc at the top level.

Installation

Install the deb or the rpm on your TemplateVM(s).

Create/Edit /etc/qubes-rpc/policy/qubes.Gpg2 in dom0, it should contain something like:

gpg-client-vm gpg-server-vm allow

Configuration

Import/Generate your secret keys in the server domain. For example:

gpg-server-vm$ gpg --import /path/to/my/secret-keys-export
gpg-server-vm$ gpg --import-ownertrust /path/to/my/ownertrust-export

or

gpg-server-vm$ gpg --gen-key

Now configure which domain the client VM should use as server. Either:

  • Set the target for @default in qubes.Gpg2. or
  • Write SPLIT_GPG2_SERVER_DOMAIN=<gpg-server> into ~/.config/.split-gpg2-rc.

In dom0 enable the split-gpg2-client service in the client domain, for example via the command-line:

dom0$ qvm-service <SPLIT_GPG2_CLIENT_DOMAIN_NAME> split-gpg2-client on

To verify if this was done correctly:

dom0$ qvm-service <SPLIT_GPG2_CLIENT_DOMAIN_NAME>

Output should be:

split-gpg2-client on

Restart the client domain.

Export the public part of your keys and import them in the client domain. Also import/set proper "ownertrust" values. For example:

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

This should be enough to have it running:

gpg-client-vm$ gpg -K
/home/user/.gnupg/pubring.kbx
-----------------------------
sec#  rsa2048 2019-12-18 [SC] [expires: 2021-12-17]
      50C2035AF57B98CD6E4010F1B808E4BB07BA9EFB
uid           [ultimate] test
ssb#  rsa2048 2019-12-18 [E]

If you want change some server option copy /usr/share/doc/split-gpg2/examples/split-gpg2-rc.example to ~/.config/split-gpg2-rc and change it as desired.

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.

Advanced usage

There are a few option not described in this README. See the comments in the example config and the source code.

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.

Allow key generation

By setting SPLIT_GPG2_ALLOW_KEYGEN=yes in split-gpg2-rc 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!

Copyright

Copyright (C) 2014 HW42 [email protected]
Copyright (C) 2019 Marek Marczykowski-Górecki [email protected]

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.

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.

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.

qubes-app-linux-split-gpg2's People

Contributors

demimarie avatar hw42 avatar marmarek avatar pietrushnic avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar

qubes-app-linux-split-gpg2's Issues

Key generation does not work because of pinentry problem

If I try to generate a key, I run into a problem due to pinentry: pinentry tries to access the controlling terminal, but there is no such terminal, so it fails with a confusing error.

The simplest solution is to replace the pinentry program with a trivial script that always returns OK for every command. A better solution is to always set the pinentry mode to loopback, and respond to every passphrase request with an empty response.

Use a better configuration method

Right now configuration is done via sourcing shell scripts. This is rather fragile at best, and at worst can easily create misleading expectations regarding security. For instance, setting GNUPGHOME will sometimes change which keys are available via the agent, but it sometimes will not. It also prevents using socket-based qrexec for improved performance.

Command filtered: `pinentry-mode=loopback`

Looks like Mailpile relies on pinentry-mode=loopback; however, this is being filtered out by split-gpg2. This happening regardless of whether or not any secret key is protected by a password.

Is this something split-gpg2 could allow, or perhaps should Mailpile reevaluate the need for its use?

Log:

2018-02-11 23:00:30.485636939: 1180: connected 
2018-02-11 23:00:30.618741070: 1180: A >>> OK Pleased to meet you, process 1180
2018-02-11 23:00:30.619058294: 1180: C <<< OK Pleased to meet you, process 1180
2018-02-11 23:00:30.621540647: 1180: C >>> RESET
2018-02-11 23:00:30.621680104: 1180: A <<< RESET
2018-02-11 23:00:30.621822466: 1180: A >>> OK
2018-02-11 23:00:30.621886097: 1180: C <<< OK
2018-02-11 23:00:30.623717083: 1180: C >>> OPTION ttytype=xterm-256color
2018-02-11 23:00:30.623957721: 1180: C <<< OK
2018-02-11 23:00:30.625519086: 1180: C >>> OPTION display=:0
2018-02-11 23:00:30.625686597: 1180: A <<< OPTION display=:0
2018-02-11 23:00:30.626451342: 1180: A >>> OK
2018-02-11 23:00:30.626554322: 1180: C <<< OK
2018-02-11 23:00:30.627776613: 1180: C >>> OPTION putenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
2018-02-11 23:00:30.628066076: 1180: C <<< OK
2018-02-11 23:00:30.628655543: 1180: C >>> GETINFO version
2018-02-11 23:00:30.628777449: 1180: A <<< GETINFO version
2018-02-11 23:00:30.629661940: 1180: A >>> D 2.1.18
2018-02-11 23:00:30.629775343: 1180: C <<< D 2.1.18
2018-02-11 23:00:30.629863764: 1180: A >>> OK
2018-02-11 23:00:30.629924905: 1180: C <<< OK
2018-02-11 23:00:30.630263938: 1180: C >>> OPTION allow-pinentry-notify
2018-02-11 23:00:30.630395438: 1180: A <<< OPTION allow-pinentry-notify
2018-02-11 23:00:30.630883926: 1180: A >>> OK
2018-02-11 23:00:30.630944135: 1180: C <<< OK
2018-02-11 23:00:30.631328783: 1180: C >>> OPTION agent-awareness=2.1.0
2018-02-11 23:00:30.631472520: 1180: A <<< OPTION agent-awareness=2.1.0
2018-02-11 23:00:30.632166138: 1180: A >>> OK
2018-02-11 23:00:30.632252379: 1180: C <<< OK
2018-02-11 23:00:30.632931094: 1180: C >>> OPTION pinentry-mode=loopback
2018-02-11 23:00:30.645026328: 1180: C <<< ERR 67109888 Command filtered by split-gpg2.
2018-02-11 23:00:30.645747599: 1180: disconnected 

Should be a per-user systemd service

Services that should run in the context of a human user (which this does) should run under the user instance of systemd and be installed in /usr/lib/systemd/user. This also allows it to have a hard dependency on the GPG agent socket unit, which means it can avoid ever having to start the agent manually.

Being a per-user unit also allows one vault qube to expose a different set of GPG keys depending on the calling qube, by using qrexec policy to specify the user the command should run as. While this is suboptimal, there are cases where there is no good alternative ― the user may not have enough memory to run multiple vault qubes, for example.

[R4.0] QUBES_GPG_DOMAIN seems to be ignored

Seems like QUBES_GPG_DOMAIN setting is being ignored on QubesOS R4.0. Each time I run gpg2 --list-secret-keys I get a Qubes dialog box asking:

Do you want to allow the following operation?
Select the target domain and confirm with OK.
Source:
Operation: qubes.Gpg2
Target:

Not a huge problem (other than that all works as expected), but kind of annoying.

My .split-gpg2-rc from the client cube:

$ cat .split-gpg2-rc 
# put this file in ~user/.split-gpg2-rc and modify according your needs

#### Settings affecting the client (running gpg2) ####
export QUBES_GPG_DOMAIN=vault

...and from the server cube:

$ cat .split-gpg2-rc 
# put this file in ~user/.split-gpg2-rc and modify according your needs

#### Settings affecting the client (running gpg2) ####
export QUBES_GPG_DOMAIN=vault


##### Settings affecting the server (running gpg-agent) ####
export QUBES_SPLIT_GPG2_PKSIGN_AUTOACCEPT_TIME=no
export QUBES_SPLIT_GPG2_PKDECRYPT_AUTOACCEPT_TIME=300

# to enable verbose notifications comment the folloing line out:
export QUBES_SPLIT_GPG2_VERBOSE_NOTIFICATIONS=yes

Can't build Debian packages on Fedora

Building Debian packages on Fedora 25 (or a cube based on fedora-25 template) fails, since it's impossible to install a dependencies: dh-systemd and build-essential:native (no such packages available on Fedora).

Additionally, even after installing package debhelper, dpkg-buildpackage complains about it being unavailable.

Log:

$ dpkg-buildpackage -us -uc
dpkg-buildpackage: source package split-gpg2
dpkg-buildpackage: source version 0.1
dpkg-buildpackage: source distribution experimental
dpkg-buildpackage: source changed by HW42 <[email protected]>
dpkg-buildpackage: host architecture amd64
 dpkg-source --before-build split-gpg2
dpkg-source: info: using options from split-gpg2/debian/source/options: --tar-ignore=.git
dpkg-checkbuilddeps: Unmet build dependencies: build-essential:native debhelper (>= 9)
dpkg-buildpackage: warning: build dependencies/conflicts unsatisfied; aborting
dpkg-buildpackage: warning: (Use -d flag to override.)

Trying to override the dependency handling doesn't work, since debhelper plugin that would normally be provided by dh-systemd is not available:

$ dpkg-buildpackage -d -us -uc
dpkg-buildpackage: source package split-gpg2
dpkg-buildpackage: source version 0.1
dpkg-buildpackage: source distribution experimental
dpkg-buildpackage: source changed by HW42 <[email protected]>
dpkg-buildpackage: host architecture amd64
 dpkg-source --before-build split-gpg2
dpkg-source: info: using options from split-gpg2/debian/source/options: --tar-ignore=.git
 fakeroot debian/rules clean
dh clean --with=systemd
dh: unable to load addon systemd: Can't locate Debian/Debhelper/Sequence/systemd.pm in @INC (you may need to install the Debian::Debhelper::Sequence::systemd module) (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at (eval 15) line 2.
BEGIN failed--compilation aborted at (eval 15) line 2.

debian/rules:4: recipe for target 'clean' failed
make: *** [clean] Error 2
dpkg-buildpackage: error: fakeroot debian/rules clean gave error exit status 2

Building on Debian-based distros (or cubes based on debian-9 template) works flawlessly.

Command filtered: `GETINFO s2k_count`

Looks like Mailpile relies on GETINFO s2k_count; however, this is being filtered out by split-gpg2.

Is this something split-gpg2 could allow, or perhaps should Mailpile reevaluate the need for its use?

Relevant log:

2018-02-11 23:22:25.385615886: 1510: C >>> GETINFO s2k_count
2018-02-11 23:22:25.402996632: 1510: C <<< ERR 67109888 Command filtered by split-gpg2.

Zenity output confuses gpg

On my message, zenity displays an assertion failure error message, which somehow gets sent to GPG and interpreted as an invalid IPC command.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.