Building GnuPG on Linux

Building GnuPG on Linux

I. Background

By default, GnuPG is shipped with Arch Linux’s default configuration: it is even one of the dependencies of pacman (pacman --> gpgme --> gnupg). On other distros, it is also possible to install GnuPG via some sort of package manager.

But that brings a problem. The PGP key used by me is a rsa16384 one, which is much larger than the maximum possible rsa4096 ones generated by GnuPG by default.

$ gpg -K
/home/lam/.gnupg/pubring.kbx
----------------------------
sec   rsa16384 2022-05-01 [SC]
      EF1CCBC4AD3BF5CC5E9769BCBE661106A1F3FA0B
uid           [ultimate] Eat-Swap <[email protected]>
ssb   rsa16384 2022-05-01 [E]

That caused my key could not be imported using the default gpg command. Hence a custom build is required.

(* The GnuPG shipped by MSYS2 on Windows works fine with 16384-bit RSA keys. Maybe it was pre-configured to accept them.)

II. Configuring

Set some optimisation flags first.

$ export CFLAGS="-Wall -O3 -ffast-math -fomit-frame-pointer -finline-functions -march=native -mtune=native -s -pipe"

$ export CXXFLAGS="-Wall -O3 -ffast-math -fomit-frame-pointer -finline-functions -march=native -mtune=native -s -pipe"

Then configure. Remember to add the required flags.

$ ../gnupg-2.3.6/configure --enable-large-secmem --enable-key-cache=16384 --prefix=/usr/local --sysconfdir=/etc --docdir=/usr/local/share/doc/gnupg-2.3.6

After configuration, the summary produced:

GnuPG v2.3.6 has been configured as follows:

Revision:  3a8164e69  (14977)
Platform:  GNU/Linux (x86_64-pc-linux-gnu)

OpenPGP:   yes
S/MIME:    yes
Agent:     yes
Smartcard: yes 
TPM:       yes (Intel)
G13:       no
Dirmngr:   yes
Keyboxd:   yes
Gpgtar:    yes
WKS tools: yes

Protect tool:       (default)
LDAP wrapper:       (default)
Default agent:      (default)
Default pinentry:   (default)
Default scdaemon:   (default)
Default keyboxd:    (default)
Default tpm2daemon: (default)
Default dirmngr:    (default)

Dirmngr auto start:  yes
Readline support:    yes
LDAP support:        yes
TLS support:         gnutls
TOFU support:        yes
Tor support:         yes

Warning: TPM support is compiled in but no software TPM
         for testing was discovered. TPM tests are disabled

III. Building

The building process is straightforward.

$ time make -j 20

It took 30 seconds to build on my machine. If you are trying to reporduce that, it should not take long.

Optionally, you may want to run a series of pre-defined tests: make check.

IV. Installing

As configured, the GnuPG 2.3.6 will be installed under /usr/local. However that brings a problem of package management. As the number of manually-built packages increases, it becomes impossible to find what package holds a specific file.

Here I will apply the timestamp-based method of package management, which comes from LFS (Linux From Scratch). It will be fine since we compile one package at a time (and soon you will find that you will never build multiple at a time: small packages finish before you are prepared to build another one, large ones occupies your entire CPU).

Save timestamp:

$ date +"%F %T" > _TS

… then install

$ make install

Create a list of installed files:

$ find /usr/local -type f -newermt "$(cat _TS)" > GnuPG-2.3.6.txt

… then you will be able to remove them whenever you want:

$ cat GnuPG-2.3.6.txt | xargs rm -v

V. Finishing

The installation has been finished. Verifying its version:

$ gpg --version

gpg (GnuPG) 2.3.6
libgcrypt 1.10.1-unknown
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/lam/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
AEAD: EAX, OCB
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

Looks fine.

VI. For Arch Linux users

The story has not ended yet.

When trying to import a LARGE key, gpg still complains that it could not handle that. But with some information this time:

gpg: WARNING: server 'gpg-agent' is older than us (2.2.35 < 2.3.6)

It keeps complaining even when gpg-agent was killed manually.

What caused this? By inspecting the journal it seems to be clear: systemd automatically starts the old gpg-agent immediately after killing. I have no choice but to modify the systemd unit file shipped by pacman.

$ <YOUR_EDITOR> /lib/systemd/user/gpg-agent.service

… and change /usr/ to /usr/local/ manually. Then perform a reboot since systemctl daemon-reload was not working.


Last modified on 2022-05-20