Skip to content

Commit

Permalink
Fix key to card failing with invalid time when moving keys to smartca…
Browse files Browse the repository at this point in the history
…rd on master (Opt: Authenticated Heads)

- Revert gnupg toolstack version bump to prior of linuxboot#1661 merge (2.4.2 -> 2.4.0). Version bump not needed for reproducibility.
  - Investigation and upstream discussions will take their time resolving invalid time issue introduced by between 2.4.0 and latest gnupg, fix regression first under master)

- oem-factory-reset
  - Adding DO_WITH_DEBUG to oem-factory-reset for all its gpg calls. If failing in debug mode, /tmp/debug.txt contains calls and errors
  - Wipe keyrings only (*.gpg, *.kbx)  not conf files under gpg homedir (keep initrd/.gnupg/*.conf)

- flake.nix
  - switch build derivative from qemu and qemu_kvm to qemu_full to have qemu-img tool which was missing to run qemu boards (v0.1.8 docker)
  - add gnupg so that qemu boards can call inject_gpg to inject public key in absence of flashrom+pflash support for internal flashing

- flake.lock: Updated nix pinned package list under flake.lock with 'nix flake update' so qemu_full builds

- README.md: have consistent docker testing + release (push) notes

- .circleci/config.yml: depend on docker v0.1.8 (qemu_full built with canokey-qemu lib support, diffoscopeMinimal and gnupg for proper qemu testing)

TODO:
- some fd2 instead of fd1?!
- oem-factory-resest has whiptail_or_die which sets whiptail box to HEIGHT 0. This doesn't show a scrolling window on gpg errors which is problematic with fbwhiptail, not whiptail

Signed-off-by: Thierry Laurion <[email protected]>
  • Loading branch information
tlaurion authored and mdrobnak committed May 27, 2024
1 parent 8d6f89a commit dec64ec
Show file tree
Hide file tree
Showing 16 changed files with 73 additions and 108 deletions.
8 changes: 4 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ commands:
jobs:
prep_env:
docker:
- image: tlaurion/heads-dev-env:v0.1.6
- image: tlaurion/heads-dev-env:v0.1.8
resource_class: large
working_directory: ~/heads
steps:
Expand Down Expand Up @@ -111,7 +111,7 @@ jobs:

build_and_persist:
docker:
- image: tlaurion/heads-dev-env:v0.1.6
- image: tlaurion/heads-dev-env:v0.1.8
resource_class: large
working_directory: ~/heads
parameters:
Expand Down Expand Up @@ -139,7 +139,7 @@ jobs:

build:
docker:
- image: tlaurion/heads-dev-env:v0.1.6
- image: tlaurion/heads-dev-env:v0.1.8
resource_class: large
working_directory: ~/heads
parameters:
Expand All @@ -160,7 +160,7 @@ jobs:

save_cache:
docker:
- image: tlaurion/heads-dev-env:v0.1.6
- image: tlaurion/heads-dev-env:v0.1.8
resource_class: large
working_directory: ~/heads
steps:
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ Maintenance notes on docker image
Redo the steps above in case the flake.nix or nix.lock changes. Then publish on docker hub:

```
docker tag linuxboot/heads:dev-env tlaurion/heads-dev-env:vx.y.z
docker push tlaurion/heads-dev-env:vx.y.z
#test against CircleCI in PR. Merge.
#make last version the latest
docker tag tlaurion/heads-dev-env:vx.y.z tlaurion/heads-dev-env:latest
docker push tlaurion/heads-dev-env:latest
```
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@
canokeySupport = true; # This override enables Canokey support in QEMU, resulting in -device canokey being available.
})
# Packages for qemu support with Canokey integration from previous override
#qemu_full #Heavier but contains qemu-img, kvm and everything else needed to do development cycles under docker
qemu # To test make BOARD=qemu-coreboot-* boards and then call make BOARD=qemu-coreboot-* with inject_gpg statement, and then run statement.
qemu_kvm # kvm additional support for qemu without all the qemu-img and everything else under qemu_full
qemu_full #Heavier but contains qemu-img, kvm and everything else needed to do development cycles under docker
#qemu # To test make BOARD=qemu-coreboot-* boards and then call make BOARD=qemu-coreboot-* with inject_gpg statement, and then run statement.
#qemu_kvm # kvm additional support for qemu without all the qemu-img and everything else under qemu_full
] ++ [
# Additional tools for debugging/editing/testing.
vim # Mostly used amongst us, sorry if you'd like something else, open issue.
swtpm # QEMU requirement to emulate tpm1/tpm2.
dosfstools # QEMU requirement to produce valid fs to store exported public key to be fused through inject_key on qemu (so qemu flashrom emulated SPI support).
diffoscopeMinimal # Not sure exactly what is packed here, let's try.
gnupg #to inject public key inside of qemu create rom through inject_gpg target of targets/qemu.mk TODO: remove when pflash supported by flashrom
#diffoscope #should we include it? Massive:11 GB uncompressed. Wow?!?!
] ++ [
# Tools for handling binary blobs in their compressed state. (blobs/xx30/vbios_[tw]530.sh)
Expand Down
60 changes: 23 additions & 37 deletions initrd/bin/oem-factory-reset
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ MAX_HOTP_GPG_PIN_LENGTH=25
CUSTOM_PASS_AFFECTED_COMPONENTS=""

# Default GPG Algorithm is RSA
# p256 also supported (TODO: nk3 supports RSA 4096 in secure element in firmare v1.7.1. Switch!?
GPG_ALGO="RSA"
# Default RSA key length
# Default RSA key length is 3072 bits for OEM key gen. 4096 are way longer to generate in smartcard
RSA_KEY_LENGTH=3072

GPG_USER_NAME="OEM Key"
Expand Down Expand Up @@ -85,12 +86,11 @@ mount_boot() {
fi
}

#Generate a gpg master key: no expiration date, RSA 4096 bits
#Generate a gpg master key: no expiration date, ${RSA_KEY_LENGTH} bits
#This key will be used to sign 3 subkeys: encryption, authentication and signing
#The master key and subkeys will be copied to backup, and the subkeys moved from memory keyring to the smartcard
generate_inmemory_RSA_master_and_subkeys() {
TRACE_FUNC
echo "Generating GPG key material in memory:"

echo "Generating GPG RSA ${RSA_KEY_LENGTH} bits master key..."
# Generate GPG master key
Expand All @@ -104,7 +104,7 @@ generate_inmemory_RSA_master_and_subkeys() {
echo "Expire-Date: 0" # No expiration date
echo "Passphrase: ${ADMIN_PIN}" # Admin PIN
echo "%commit" # Commit changes
} | gpg --command-fd=0 --status-fd=1 --batch --gen-key >/tmp/gpg_card_edit_output 2>&1
} | DO_WITH_DEBUG gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key >/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "GPG Key generation failed!\n\n$ERROR"
Expand All @@ -120,7 +120,7 @@ generate_inmemory_RSA_master_and_subkeys() {
echo ${ADMIN_PIN} # Local keyring admin pin
echo y # confirm
echo save # save changes and commit to keyring
} | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand All @@ -137,7 +137,7 @@ generate_inmemory_RSA_master_and_subkeys() {
echo ${ADMIN_PIN} # Local keyring admin pin
echo y # confirm
echo save # save changes and commit to keyring
} | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand All @@ -161,26 +161,12 @@ generate_inmemory_RSA_master_and_subkeys() {
echo ${ADMIN_PIN} # Local keyring admin pin
echo y # confirm
echo save # save changes and commit to keyring
} | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --expert --edit-key "${GPG_USER_MAIL}" \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "GPG Key authentication subkey generation failed!\n\n$ERROR"
fi

DEBUG "Setting public key to ultimate trust..."
#Set the public key to the ultimate trust
{
echo trust # trust key in --edit-key mode
echo 5 # ultimate trust
echo y # confirm
echo save # save changes and commit to keyring
} | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "GPG Key setting public key to ultimate trust failed!\n\n$ERROR"
fi
}

#Generate a gpg master key: no expiration date, p256 key (ECC)
Expand All @@ -200,7 +186,7 @@ generate_inmemory_p256_master_and_subkeys() {
echo "Passphrase: ${ADMIN_PIN}" # Local keyring admin pin
echo "Expire-Date: 0" # No expiration date
echo "%commit" # Commit changes
} | gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key \
} | DO_WITH_DEBUG gpg --expert --batch --command-fd=0 --status-fd=1 --pinentry-mode=loopback --generate-key \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand All @@ -216,10 +202,10 @@ generate_inmemory_p256_master_and_subkeys() {
echo 11 # ECC own set capability
echo Q # sign already present, do not modify
echo 3 # P-256
echo 0 # no expiration
echo 0 # No validity/expiration date
echo ${ADMIN_PIN} # Local keyring admin pin
echo save # save changes and commit to keyring
} | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
} | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR_MSG=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "Failed to add ECC nistp256 signing key to master key\n\n${ERROR_MSG}"
Expand All @@ -231,10 +217,10 @@ generate_inmemory_p256_master_and_subkeys() {
echo 12 # ECC own set capability
echo Q # Quit
echo 3 # P-256
echo 0 # no expiration
echo 0 # No validity/expiration date
echo ${ADMIN_PIN} # Local keyring admin pin
echo save # save changes and commit to keyring
} | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
} | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR_MSG=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "Failed to add ECC nistp256 encryption key to master key\n\n${ERROR_MSG}"
Expand All @@ -251,7 +237,7 @@ generate_inmemory_p256_master_and_subkeys() {
echo 0 # no expiration
echo ${ADMIN_PIN} # Local keyring admin pin
echo save # save changes and commit to keyring
} | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
} | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key ${MASTER_KEY_FP} >/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR_MSG=$(cat /tmp/gpg_card_edit_output)
whiptail_error_die "Failed to add ECC nistp256 authentication key to master key\n\n${ERROR_MSG}"
Expand Down Expand Up @@ -297,7 +283,7 @@ keytocard_subkeys_to_smartcard() {
echo "${ADMIN_PIN_DEF}" #Smartcard Admin PIN
echo "key 3" #Toggle off Authentication key
echo "save" #Save changes and commit to keyring
} | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \
} | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --edit-key "${GPG_USER_MAIL}" \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand Down Expand Up @@ -488,7 +474,7 @@ gpg_key_factory_reset() {
echo factory-reset # factory reset smartcard
echo y # confirm
echo yes # confirm
} | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand All @@ -508,7 +494,7 @@ gpg_key_factory_reset() {
echo admin # admin menu
echo forcesig # toggle forcesig
echo ${ADMIN_PIN_DEF} # local keyring PIN
} | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand All @@ -529,7 +515,7 @@ gpg_key_factory_reset() {
echo 2 # ECC
echo 3 # P-256
echo ${ADMIN_PIN_DEF} # local keyring PIN
} | gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
} | DO_WITH_DEBUG gpg --expert --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand All @@ -551,7 +537,7 @@ gpg_key_factory_reset() {
echo 1 # RSA
echo ${RSA_KEY_LENGTH} #Authentication key size set to RSA_KEY_LENGTH
echo ${ADMIN_PIN_DEF} #Local keyring PIN
} | gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=1 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand Down Expand Up @@ -581,7 +567,7 @@ generate_OEM_gpg_keys() {
echo ${GPG_USER_MAIL} # User email
echo ${GPG_USER_COMMENT} # User comment
echo ${USER_PIN_DEF} # Default user PIN since we just factory reset
} | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output)
Expand All @@ -608,7 +594,7 @@ gpg_key_change_pin() {
echo ${PIN_NEW} # confirm new PIN
echo q # quit
echo q
} | gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
} | DO_WITH_DEBUG gpg --command-fd=0 --status-fd=2 --pinentry-mode=loopback --card-edit \
>/tmp/gpg_card_edit_output 2>&1
if [ $? -ne 0 ]; then
ERROR=$(cat /tmp/gpg_card_edit_output | fold -s)
Expand Down Expand Up @@ -686,7 +672,7 @@ generate_checksums() {
fi

DEBUG "Detach-signing boot files under kexec.sig: ${param_files}"
if sha256sum $param_files 2>/dev/null | gpg \
if sha256sum $param_files 2>/dev/null | DO_WITH_DEBUG gpg \
--pinentry-mode loopback \
--passphrase "${USER_PIN}" \
--digest-algo SHA256 \
Expand Down Expand Up @@ -1142,7 +1128,7 @@ assert_signable
# clear gpg-agent cache so that next gpg calls doesn't have past keyring in memory
killall gpg-agent >/dev/null 2>&1 || true
# clear local keyring
rm -rf /.gnupg/* >/dev/null 2>&1 || true
rm -rf /.gnupg/*.kbx /.gnupg/*.gpg >/dev/null 2>&1 || true

# detect and set /boot device
echo -e "\nDetecting and setting boot device...\n"
Expand Down Expand Up @@ -1242,7 +1228,7 @@ if [ "$GPG_EXPORT" != "0" ]; then
fi

# ensure key imported locally
if ! cat "$PUBKEY" | gpg --import >/dev/null 2>/tmp/error; then
if ! cat "$PUBKEY" | DO_WITH_DEBUG gpg --import >/dev/null 2>/tmp/error; then
ERROR=$(tail -n 1 /tmp/error | fold -s)
whiptail_error_die "Error importing GPG key:\n\n$ERROR"
fi
Expand Down
4 changes: 2 additions & 2 deletions modules/gpg2
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
modules-$(CONFIG_GPG2) += gpg2

gpg2_version := 2.4.2
gpg2_version := 2.4.0
gpg2_dir := gnupg-$(gpg2_version)
gpg2_tar := gnupg-$(gpg2_version).tar.bz2
gpg2_url := https://www.gnupg.org/ftp/gcrypt/gnupg/$(gpg2_tar)
gpg2_hash := 97eb47df8ae5a3ff744f868005a090da5ab45cb48ee9836dbf5ee739a4e5cf49
gpg2_hash := 1d79158dd01d992431dd2e3facb89fdac97127f89784ea2cb610c600fb0c1483
gpg2_depends := libgpg-error libgcrypt libksba libassuan npth libusb $(musl_dep)

# For reproducibility reasons we have to override the exec_prefix
Expand Down
6 changes: 3 additions & 3 deletions modules/libassuan
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
modules-$(CONFIG_GPG2) += libassuan

libassuan_version := 2.5.6
libassuan_version := 2.5.5
libassuan_dir := libassuan-$(libassuan_version)
libassuan_tar := libassuan-$(libassuan_version).tar.bz2
libassuan_url := https://gnupg.org/ftp/gcrypt/libassuan/$(libassuan_tar)
libassuan_hash := e9fd27218d5394904e4e39788f9b1742711c3e6b41689a31aa3380bd5aa4f426
libassuan_hash := 8e8c2fcc982f9ca67dcbb1d95e2dc746b1739a4668bc20b3a3c5be632edb34e4

libassuan_configure := \
CFLAGS="-Os" \
Expand All @@ -14,7 +14,7 @@ libassuan_configure := \
--prefix "/" \
--disable-doc \
--disable-static \
--with-libgpg-error-prefix="$(INSTALL)" \
--with-gpg-error-prefix="$(INSTALL)" \

libassuan_target := $(MAKE_JOBS) \
DESTDIR="$(INSTALL)" \
Expand Down
6 changes: 3 additions & 3 deletions modules/libgcrypt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
modules-$(CONFIG_GPG2) += libgcrypt

libgcrypt_version := 1.10.2
libgcrypt_version := 1.10.1
libgcrypt_dir := libgcrypt-$(libgcrypt_version)
libgcrypt_tar := libgcrypt-$(libgcrypt_version).tar.bz2
libgcrypt_url := https://gnupg.org/ftp/gcrypt/libgcrypt/$(libgcrypt_tar)
libgcrypt_hash := 3b9c02a004b68c256add99701de00b383accccf37177e0d6c58289664cce0c03
libgcrypt_hash := ef14ae546b0084cd84259f61a55e07a38c3b53afc0f546bffcef2f01baffe9de

libgcrypt_configure := \
$(CROSS_TOOLS) \
Expand All @@ -14,7 +14,7 @@ libgcrypt_configure := \
--prefix "/" \
--disable-doc \
--disable-static \
--with-libgpg-error-prefix="$(INSTALL)" \
--with-gpg-error-prefix="$(INSTALL)" \

libgcrypt_target := $(MAKE_JOBS) \
DESTDIR="$(INSTALL)" \
Expand Down
4 changes: 2 additions & 2 deletions modules/libgpg-error
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
modules-$(CONFIG_GPG2) += libgpg-error

libgpg-error_version := 1.47
libgpg-error_version := 1.46
libgpg-error_dir := libgpg-error-$(libgpg-error_version)
libgpg-error_tar := libgpg-error-$(libgpg-error_version).tar.bz2
libgpg-error_url := https://gnupg.org/ftp/gcrypt/libgpg-error/$(libgpg-error_tar)
libgpg-error_hash := 9e3c670966b96ecc746c28c2c419541e3bcb787d1a73930f5e5f5e1bcbbb9bdb
libgpg-error_hash := b7e11a64246bbe5ef37748de43b245abd72cfcd53c9ae5e7fc5ca59f1c81268d

libgpg-error_configure := \
$(CROSS_TOOLS) \
Expand Down
6 changes: 3 additions & 3 deletions modules/libksba
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
modules-$(CONFIG_GPG2) += libksba

libksba_version := 1.6.4
libksba_version := 1.6.3
libksba_dir := libksba-$(libksba_version)
libksba_tar := libksba-$(libksba_version).tar.bz2
libksba_url := https://gnupg.org/ftp/gcrypt/libksba/$(libksba_tar)
libksba_hash := bbb43f032b9164d86c781ffe42213a83bf4f2fee91455edfa4654521b8b03b6b
libksba_hash := 3f72c68db30971ebbf14367527719423f0a4d5f8103fc9f4a1c01a9fa440de5c

libksba_configure := \
$(CROSS_TOOLS) \
Expand All @@ -13,7 +13,7 @@ libksba_configure := \
--host $(MUSL_ARCH)-linux-musl \
--prefix "/" \
--disable-static \
--with-libgpg-error-prefix="$(INSTALL)" \
--with-gpg-error-prefix="$(INSTALL)" \

libksba_target := $(MAKE_JOBS) \
DESTDIR="$(INSTALL)" \
Expand Down
Loading

0 comments on commit dec64ec

Please sign in to comment.