ce7756b
From 6c16b978fd33f3611e9f7aaf4f9c44bce1679485 Mon Sep 17 00:00:00 2001
c81bb39
From: Peter Jones <pjones@redhat.com>
c81bb39
Date: Mon, 6 Jul 2020 13:54:35 -0400
ce7756b
Subject: [PATCH] Move most of macros.pesign to pesign-rpmbuild-helper
c81bb39
c81bb39
Signed-off-by: Peter Jones <pjones@redhat.com>
c81bb39
---
c81bb39
 Make.defaults                 |   1 +
c81bb39
 src/Makefile                  |   8 +-
ce7756b
 src/macros.pesign             |  74 ++++--------
c81bb39
 src/pesign-rpmbuild-helper.in | 222 ++++++++++++++++++++++++++++++++++
ce7756b
 4 files changed, 252 insertions(+), 53 deletions(-)
c81bb39
 create mode 100644 src/pesign-rpmbuild-helper.in
c81bb39
c81bb39
diff --git a/Make.defaults b/Make.defaults
c81bb39
index 0bacafe0d01..d4cd626c11e 100644
c81bb39
--- a/Make.defaults
c81bb39
+++ b/Make.defaults
c81bb39
@@ -16,6 +16,7 @@ INSTALLROOT = $(DESTDIR)
c81bb39
 
c81bb39
 INSTALL	?= install
c81bb39
 CROSS_COMPILE	?=
c81bb39
+EFI_ARCHES ?= aa64 ia32 x64
c81bb39
 
c81bb39
 PKG_CONFIG = $(CROSS_COMPILE)pkg-config
c81bb39
 CC	:= $(if $(filter default,$(origin CC)),$(CROSS_COMPILE)gcc,$(CC))
c81bb39
diff --git a/src/Makefile b/src/Makefile
c81bb39
index 74327ba13f3..a7ca89159c6 100644
c81bb39
--- a/src/Makefile
c81bb39
+++ b/src/Makefile
c81bb39
@@ -5,7 +5,7 @@ include $(TOPDIR)/Make.version
c81bb39
 include $(TOPDIR)/Make.rules
c81bb39
 include $(TOPDIR)/Make.defaults
c81bb39
 
c81bb39
-BINTARGETS=authvar client efikeygen efisiglist pesigcheck pesign
c81bb39
+BINTARGETS=authvar client efikeygen efisiglist pesigcheck pesign pesign-rpmbuild-helper
c81bb39
 SVCTARGETS=pesign.sysvinit pesign.service
c81bb39
 TARGETS=$(BINTARGETS) $(SVCTARGETS)
c81bb39
 
c81bb39
@@ -49,6 +49,11 @@ pesign : $(call objects-of,$(PESIGN_SOURCES) $(COMMON_SOURCES) $(COMMON_PE_SOURC
c81bb39
 pesign : LDLIBS+=$(TOPDIR)/libdpe/libdpe.a
c81bb39
 pesign : PKGS=efivar nss nspr popt
c81bb39
 
c81bb39
+pesign-rpmbuild-helper: pesign-rpmbuild-helper.in
c81bb39
+	sed \
c81bb39
+		-e "s/@@EFI_ARCHES@@/$(EFI_ARCHES)/g" \
c81bb39
+		$^ > $@
c81bb39
+
c81bb39
 deps : PKGS=efivar nss nspr popt uuid
c81bb39
 deps : $(ALL_SOURCES)
c81bb39
 	$(MAKE) -f $(TOPDIR)/Make.deps \
c81bb39
@@ -94,6 +99,7 @@ install :
c81bb39
 	$(INSTALL) -m 644 macros.pesign $(INSTALLROOT)/etc/rpm/
c81bb39
 	$(INSTALL) -d -m 755 $(INSTALLROOT)$(libexecdir)/pesign/
c81bb39
 	$(INSTALL) -m 750 pesign-authorize $(INSTALLROOT)$(libexecdir)/pesign/
c81bb39
+	$(INSTALL) -m 755 pesign-rpmbuild-helper $(INSTALLROOT)$(libexecdir)/pesign/
c81bb39
 	$(INSTALL) -d -m 700 $(INSTALLROOT)/etc/pesign
c81bb39
 	$(INSTALL) -m 600 pesign-users $(INSTALLROOT)/etc/pesign/users
c81bb39
 	$(INSTALL) -m 600 pesign-groups $(INSTALLROOT)/etc/pesign/groups
c81bb39
diff --git a/src/macros.pesign b/src/macros.pesign
ce7756b
index 5a6da1c6809..2e984b4eeb3 100644
c81bb39
--- a/src/macros.pesign
c81bb39
+++ b/src/macros.pesign
ce7756b
@@ -6,7 +6,7 @@
c81bb39
 # %pesign -s -i shim.orig -o shim.efi
c81bb39
 # And magically get the right thing.
c81bb39
 
c81bb39
-%__pesign_token %{nil}%{?pe_signing_token:-t "%{pe_signing_token}"}
c81bb39
+%__pesign_token %{nil}%{?pe_signing_token:--token "%{pe_signing_token}"}
c81bb39
 %__pesign_cert %{!?pe_signing_cert:"Red Hat Test Certificate"}%{?pe_signing_cert:"%{pe_signing_cert}"}
c81bb39
 
c81bb39
 %__pesign_client_token %{!?pe_signing_token:"OpenSC Card (Fedora Signer)"}%{?pe_signing_token:"%{pe_signing_token}"}
c81bb39
@@ -24,54 +24,24 @@
c81bb39
 # -a <input ca cert filename>		# rhel only
c81bb39
 # -s 					# perform signing
c81bb39
 %pesign(i:o:C:e:c:n:a:s)						\
c81bb39
-  _pesign_nssdir=/etc/pki/pesign					\
c81bb39
-  if [ %{__pesign_cert} = "Red Hat Test Certificate" ]; then		\
c81bb39
-    _pesign_nssdir=/etc/pki/pesign-rh-test				\
c81bb39
-  fi									\
c81bb39
-  if [ -x %{_pesign} ] &&  						\\\
c81bb39
-       [ "%{_target_cpu}" == "x86_64" -o 				\\\
c81bb39
-         "%{_target_cpu}" == "aarch64" ]; then				\
c81bb39
-    if [ "0%{?rhel}" -ge "7" -a -f /usr/bin/rpm-sign ]; then		\
c81bb39
-      nss=$(mktemp -p $PWD -d)						\
c81bb39
-      echo > ${nss}/pwfile						\
c81bb39
-      certutil -N -d ${nss} -f ${nss}/pwfile				\
c81bb39
-      certutil -A -n "ca" -t "CT,C," -i %{-a*} -d ${nss}		\
c81bb39
-      certutil -A -n "signer" -t ",c," -i %{-c*} -d ${nss}		\
c81bb39
-      sattrs=$(mktemp -p $PWD --suffix=.der)				\
c81bb39
-      %{_pesign} %{-i} -E ${sattrs} --certdir ${nss} --force		\
c81bb39
-      rpm-sign --key "%{-n*}" --rsadgstsign ${sattrs}			\
c81bb39
-      %{_pesign} -R ${sattrs}.sig -I ${sattrs} %{-i}			\\\
c81bb39
-                 --certdir ${nss} -c signer %{-o}			\
c81bb39
-      rm -rf ${sattrs} ${sattrs}.sig ${nss}				\
c81bb39
-    elif [ "$(id -un)" == "kojibuilder" -a				\\\
c81bb39
-           grep -q ID=fedora /etc/os-release -a				\\\
c81bb39
-           ! -S /run/pesign/socket ]; then				\
c81bb39
-      echo "No socket even though this is kojibuilder" 1>&2		\
c81bb39
-      ls -ld /run/pesign 1>&2					\
c81bb39
-      ls -l /run/pesign/socket 1>&2					\
c81bb39
-      getfacl /run/pesign 1>&2					\
c81bb39
-      getfacl /run/pesign/socket 1>&2				\
c81bb39
-      exit 1								\
c81bb39
-    elif [ -S /run/pesign/socket ]; then				\
c81bb39
-      %{_pesign_client} -t %{__pesign_client_token}			\\\
c81bb39
-                        -c %{__pesign_client_cert}			\\\
c81bb39
-                        %{-i} %{-o} %{-e} %{-s} %{-C}			\
c81bb39
-    else								\
c81bb39
-      %{_pesign} %{__pesign_token} -c %{__pesign_cert}			\\\
c81bb39
-                 --certdir ${_pesign_nssdir}				\\\
c81bb39
-                 %{-i} %{-o} %{-e} %{-s} %{-C}				\
c81bb39
-    fi									\
c81bb39
-  else									\
c81bb39
-    if [ -n "%{-i*}" -a -n "%{-o*}" ]; then				\
c81bb39
-      mv %{-i*} %{-o*}							\
c81bb39
-    elif [ -n "%{-i*}" -a -n "%{-e*}" ]; then				\
c81bb39
-      touch %{-e*}							\
c81bb39
-    fi									\
c81bb39
-  fi									\
c81bb39
-  if [ ! -s %{-o} ]; then						\
c81bb39
-    if [ -e "%{-o*}" ]; then						\
c81bb39
-      rm -f %{-o*}							\
c81bb39
-    fi									\
c81bb39
-    exit 1								\
c81bb39
-  fi ;
c81bb39
-
c81bb39
+  %{_libexecdir}/pesign/pesign-rpmbuild-helper				\\\
c81bb39
+    "%{_target_cpu}"							\\\
c81bb39
+    "%{_pesign}"							\\\
c81bb39
+    "%{_pesign_client}"							\\\
c81bb39
+    %{?__pesign_client_token:--client-token %{__pesign_client_token}}	\\\
c81bb39
+    %{?__pesign_client_cert:--client-cert %{__pesign_client_cert}}	\\\
c81bb39
+    %{?__pesign_token:%{__pesign_token}}				\\\
c81bb39
+    %{?__pesign_cert:--cert %{__pesign_cert}}				\\\
c81bb39
+    %{?_buildhost:--hostname "%{_buildhost}"}				\\\
c81bb39
+    %{?vendor:--vendor "%{vendor}"}					\\\
c81bb39
+    %{?_rhel:--rhelver "%{_rhel}"}					\\\
ce7756b
+    %{?-n:--rhelcert %{-n*}}%{?!-n:--rhelcert %{__pesign_cert}}	\\\
c81bb39
+    %{?-a:--rhelcafile "%{-a*}"}					\\\
c81bb39
+    %{?-c:--rhelcertfile "%{-c*}"}					\\\
c81bb39
+    %{?-C:--certout "%{-C*}"}						\\\
c81bb39
+    %{?-e:--sattrout "%{-e*}"}						\\\
c81bb39
+    %{?-i:--in "%{-i*}"}						\\\
c81bb39
+    %{?-o:--out "%{-o*}"}						\\\
c81bb39
+    %{?-s:--sign}							\\\
c81bb39
+    ;									\
c81bb39
+%{nil}
c81bb39
diff --git a/src/pesign-rpmbuild-helper.in b/src/pesign-rpmbuild-helper.in
c81bb39
new file mode 100644
c81bb39
index 00000000000..c5287c27e0c
c81bb39
--- /dev/null
c81bb39
+++ b/src/pesign-rpmbuild-helper.in
c81bb39
@@ -0,0 +1,222 @@
c81bb39
+#!/bin/bash
c81bb39
+# shellcheck shell=bash
c81bb39
+
c81bb39
+set -eu
c81bb39
+set -x
c81bb39
+
c81bb39
+usage() {
c81bb39
+    local status="${1}" && shift
c81bb39
+    local out
c81bb39
+    if [[ "${status}" -eq 0 ]] ; then
c81bb39
+	out=/dev/stdout
c81bb39
+    else
c81bb39
+	out=/dev/stderr
c81bb39
+    fi
c81bb39
+
c81bb39
+    if [[ $# -gt 0 ]] ; then
c81bb39
+	echo "${0}: error: $*" >>"${out}"
c81bb39
+    fi
c81bb39
+    echo "usage: ${0} TARGET_CPU PESIGN_BINARY PESIGN_CLIENT_BINARY [OPTIONS]" >>"${out}"
c81bb39
+    exit "${status}"
c81bb39
+}
c81bb39
+
c81bb39
+is_efi_arch() {
c81bb39
+    local arch="${1}"
c81bb39
+    local arches=(@@EFI_ARCHES@@)
c81bb39
+    local x
c81bb39
+    for x in "${arches[@]}" ; do
c81bb39
+	if [[ "${arch}" = "${x}" ]] ; then
c81bb39
+	    return 0
c81bb39
+	fi
c81bb39
+    done
c81bb39
+    return 1
c81bb39
+}
c81bb39
+
c81bb39
+error_on_empty() {
c81bb39
+    local f="${1}"
c81bb39
+    if [[ ! -s "${f}" ]] ; then
c81bb39
+	if [[ -e "${f}" ]] ; then
c81bb39
+	    rm -f "${f}"
c81bb39
+	fi
c81bb39
+	echo "${0}: error: empty result file \"${f}\"">>/dev/stderr
c81bb39
+	exit 1
c81bb39
+    fi
c81bb39
+}
c81bb39
+
c81bb39
+main() {
c81bb39
+    if [[ $# -lt 3 ]] ; then
c81bb39
+	usage 1 not enough arguments
c81bb39
+    fi
c81bb39
+    local target_cpu="${1}" && shift
c81bb39
+    local bin="${1}" && shift
c81bb39
+    local client="${1}" && shift
c81bb39
+
c81bb39
+    local rhelcafile="" || :
c81bb39
+    local rhelcertfile="" || :
c81bb39
+
c81bb39
+    local certout=() || :
c81bb39
+    local sattrout=() || :
c81bb39
+    local input=() || :
c81bb39
+    local output=() || :
c81bb39
+    local client_token=() || :
c81bb39
+    local client_cert=() || :
c81bb39
+    local token=() || :
c81bb39
+    local cert=() || :
c81bb39
+    local rhelcert=() || :
c81bb39
+    local rhelver=0 || :
c81bb39
+    local sign="" || :
c81bb39
+    local arch="" || :
c81bb39
+    local vendor="" || :
c81bb39
+    local HOSTNAME="" || :
c81bb39
+
c81bb39
+    while [[ $# -ge 2 ]] ; do
c81bb39
+	case " ${1} " in
c81bb39
+	" --rhelcafile ")
c81bb39
+	    rhelcafile="${2}"
c81bb39
+	    ;;
c81bb39
+	" --rhelcertfile ")
c81bb39
+	    rhelcertfile="${2}"
c81bb39
+	    ;;
c81bb39
+	" --hostname ")
c81bb39
+	    HOSTNAME="${2}"
c81bb39
+	    ;;
c81bb39
+	" --certout ")
c81bb39
+	    certout[0]=-C
c81bb39
+	    certout[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --sattrout ")
c81bb39
+	    sattrout[0]=-e
c81bb39
+	    sattrout[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --client-token ")
c81bb39
+	    client_token[0]=-t
c81bb39
+	    client_token[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --client-cert ")
c81bb39
+	    client_cert[0]=-c
c81bb39
+	    client_cert[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --token ")
c81bb39
+	    token[0]=-t
c81bb39
+	    token[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --cert ")
c81bb39
+	    cert[0]=-c
c81bb39
+	    cert[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --rhelcert ")
c81bb39
+	    rhelcert[0]=-c
c81bb39
+	    rhelcert[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --in ")
c81bb39
+	    input[0]=-i
c81bb39
+	    input[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --out ")
c81bb39
+	    output[0]=-o
c81bb39
+	    output[1]="${2}"
c81bb39
+	    ;;
c81bb39
+	" --rhelver ")
c81bb39
+	    rhelver="${2}"
c81bb39
+	    ;;
c81bb39
+	" --vendor ")
c81bb39
+	    vendor="${2}"
c81bb39
+	    ;;
c81bb39
+	*)
c81bb39
+	    break
c81bb39
+	    ;;
c81bb39
+	esac
c81bb39
+	shift
c81bb39
+	shift
c81bb39
+    done
c81bb39
+    if [[ $# -ge 1 ]] && [[ "${1}" = --sign ]] ; then
c81bb39
+	sign=-s
c81bb39
+	shift
c81bb39
+    fi
c81bb39
+
c81bb39
+    if [[ -z "${target_cpu}" ]] ; then
c81bb39
+	target_cpu="$(uname -m)"
c81bb39
+    fi
c81bb39
+
c81bb39
+    target_cpu="${target_cpu/i?86/ia32}"
c81bb39
+    target_cpu="${target_cpu/x86_64/x64}"
c81bb39
+    target_cpu="${target_cpu/aarch64/aa64}"
c81bb39
+    target_cpu="${target_cpu/arm*/arm/}"
c81bb39
+
c81bb39
+    local nssdir=/etc/pki/pesign
c81bb39
+    if [[ "${#cert[@]}" -eq 2 ]] &&
c81bb39
+       [[ "${cert[1]}" == "Red Hat Test Certificate" ]] ; then
c81bb39
+	nssdir=/etc/pki/pesign-rh-test
c81bb39
+    fi
c81bb39
+
c81bb39
+    # is_efi_arch is ultimately returning "is pesign configured to sign these
c81bb39
+    # using the rpm macro", so if it isn't, we're just copying the input to
c81bb39
+    # the output
c81bb39
+    if [[ -x "${bin}" ]] && ! is_efi_arch "${target_cpu}" ; then
c81bb39
+	if [[ -n "${input[*]}" ]] && [[ -n "${output[*]}" ]] ; then
c81bb39
+	    cp -v "${input[1]}" "${output[1]}"
c81bb39
+	elif [[ -n "${input[*]}" ]] && [[ -n "${sattrout[*]}" ]] ; then
c81bb39
+	    touch "${sattrout[1]}"
c81bb39
+	fi
c81bb39
+
c81bb39
+	# if there's a 0-sized output file, delete it and error out
c81bb39
+	error_on_empty "${output[1]}"
c81bb39
+	return 0
c81bb39
+    fi
c81bb39
+
c81bb39
+    USERNAME="${USERNAME:-$(id -un)}"
c81bb39
+
c81bb39
+    local socket="" || :
c81bb39
+    if grep -q ID=fedora /etc/os-release \
c81bb39
+       && [[ "${rhelver}" -lt 7 ]] \
c81bb39
+       && [[ "${USERNAME}" = "mockbuild" ]] \
c81bb39
+       && [[ "${vendor}" = "Fedora Project" ]] \
c81bb39
+       && [[ "${HOSTNAME}" =~ bkernel.* ]]
c81bb39
+    then
c81bb39
+	if [[ -S /run/pesign/socket ]] ; then
c81bb39
+	    socket=/run/pesign/socket
c81bb39
+	elif [[ -S /var/run/pesign/socket ]]; then
c81bb39
+	    socket=/var/run/pesign/socket
c81bb39
+	else
c81bb39
+	    echo "Warning: no pesign socket even though user is ${USERNAME}" 1>&2
c81bb39
+	    echo "Warning: if this is a non-scratch koji build, this is wrong" 1>&2
c81bb39
+	    ls -ld /run/pesign /var/run/pesign 1>&2 ||:
c81bb39
+	    ls -l /run/pesign/socket /var/run/pesign/socket 1>&2 ||:
c81bb39
+	    getfacl /run/pesign /run/pesign/socket /var/run/pesign /var/run/pesign/socket 1>&2 ||:
c81bb39
+	    getfacl -n /run/pesign /run/pesign/socket /var/run/pesign /var/run/pesign/socket 1>&2 ||:
c81bb39
+	fi
c81bb39
+    fi
c81bb39
+
c81bb39
+    if [[ "${rhelver}" -ge 7 ]] ; then
c81bb39
+	nssdir="$(mktemp -p "${PWD}" -d)"
c81bb39
+	echo > "${nssdir}/pwfile"
c81bb39
+	certutil -N -d "${nssdir}" -f "${nssdir}/pwfile"
c81bb39
+	certutil -A -n "ca" -t "CTu,CTu,CTu" -i "${rhelcafile}" -d "${nssdir}"
c81bb39
+	certutil -A -n "signer" -t "CTu,CTu,CTu" -i "${rhelcertfile}" -d "${nssdir}"
c81bb39
+	sattrs="$(mktemp -p "${PWD}" --suffix=.der)"
c81bb39
+	"${bin}" -E "${sattrs}" --certdir "${nssdir}" \
c81bb39
+	    "${input[@]}" --force
c81bb39
+	rpm-sign --key "${rhelcert[1]}" --rsadgstsign "${sattrs}"
c81bb39
+	"${bin}" -R "${sattrs}.sig" -I "${sattrs}" \
c81bb39
+	    --certdir "${nssdir}" -c signer \
c81bb39
+	    "${input[@]}" "${output[@]}"
c81bb39
+	rm -rf "${sattrs}" "${sattrs}.sig" "${nssdir}"
c81bb39
+    elif [[ -n "${socket}" ]] ; then
c81bb39
+	"${client}" "${client_token[@]}" "${client_cert[@]}"    \
c81bb39
+	    "${sattrout[@]}" "${certout[@]}"	\
c81bb39
+	    ${sign} "${input[@]}" "${output[@]}"
c81bb39
+    else
c81bb39
+	"${bin}" --certdir "${nssdir}" "${token[@]}"	\
c81bb39
+	    "${cert[@]}" ${sign} "${sattrout[@]}"	\
c81bb39
+	    "${certout[@]}"    "${input[@]}" "${output[@]}"
c81bb39
+    fi
c81bb39
+
c81bb39
+    # if there's a 0-sized output file, delete it and error out
c81bb39
+    if [[ "${#output[@]}" -eq 2 ]] ; then
c81bb39
+	error_on_empty "${output[1]}"
c81bb39
+    fi
c81bb39
+}
c81bb39
+
c81bb39
+main "${@}"
c81bb39
+
c81bb39
+# vim:filetype=sh:fenc=utf-8:tw=78:sts=4:sw=4
c81bb39
-- 
c81bb39
2.26.2
c81bb39