From f4ea93f5f2b1d6339c9aa728de7e5f293579f244 Mon Sep 17 00:00:00 2001
From: Dimitri John Ledkov <dimitri.ledkov@surgut.co.uk>
Date: Mon, 29 Apr 2024 12:03:04 +0100
Subject: [PATCH] abuild-sign: add support for RSA256 signatures

Supported by apk-tools since v2.7.0 (2017).
---
 abuild-sign.in         | 20 ++++++++++++++++---
 tests/abuild_sign_test | 44 +++++++++++++++++++++++++++++++++++++++---
 2 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/abuild-sign.in b/abuild-sign.in
index c10c40f..5ead6ef 100644
--- a/abuild-sign.in
+++ b/abuild-sign.in
@@ -31,8 +31,8 @@ do_sign() {
 		trap 'die "failed to sign $i"' EXIT
 		set -e
 		cd "$repo"
-		sig=".SIGN.RSA.$keyname"
-		$openssl dgst -sha1 -sign "$privkey" -out "$sig" "$i"
+		sig=".SIGN.$type.$keyname"
+		$openssl dgst $dgstargs -sign "$privkey" -out "$sig" "$i"
 
 		if [ -n "$SOURCE_DATE_EPOCH" ]; then
 			touch -h -d "@$SOURCE_DATE_EPOCH" "$sig"
@@ -61,6 +61,7 @@ usage() {
 		  -k, --private KEY  The private key to use for signing
 		  -p, --public KEY   The name of public key. apk add will look for
 		                     /etc/apk/keys/KEY
+		  -t, --type TYPE    The signature type RSA or RSA256
 		  -q, --quiet
 		  -h, --help         Show this help
 
@@ -72,7 +73,7 @@ privkey="$PACKAGER_PRIVKEY"
 pubkey=
 quiet=
 
-args=$(getopt -o ek:p:qh --long installed,private:,public:,quiet,help -n "$program" -- "$@")
+args=$(getopt -o ek:p:t:qh --long installed,private:,public:,type:,quiet,help -n "$program" -- "$@")
 if [ $? -ne 0 ]; then
 	usage >&2
 	exit 2
@@ -83,6 +84,7 @@ while true; do
 		-e|--installed) check_installed=true;;
 		-k|--private) privkey=$2; shift;;
 		-p|--public) pubkey=$2; shift;;
+		-t|--type) type=$2; shift;;
 		-q|--quiet) quiet=1;; # suppresses msg
 		-h|--help) usage; exit;;
 		--) shift; break;;
@@ -112,6 +114,18 @@ if [ -z "$pubkey" ]; then
 	pubkey=${PACKAGER_PUBKEY:-"${privkey}.pub"}
 fi
 
+if [ -z "$type" ]; then
+	type=RSA
+fi
+
+case $type in
+	RSA) dgstargs="-sha1";;
+	RSA256) dgstargs="-sha256";;
+	*)
+		echo "$program: supported types are RSA and RSA256" >&2
+		exit 1
+		;;
+esac
 if $check_installed; then
 	if ! [ -e "$privkey" ]; then
 		echo "$program: $privkey: File not found" >&2
diff --git a/tests/abuild_sign_test b/tests/abuild_sign_test
index 9d2a6b2..2ce8df2 100755
--- a/tests/abuild_sign_test
+++ b/tests/abuild_sign_test
@@ -9,7 +9,10 @@ init_tests \
 	abuild_sign_installed_missing_pub \
 	abuild_sign_installed_missing_priv \
 	abuild_sign_installed \
-	abuild_sign_owner
+	abuild_sign_owner_type_invalid \
+	abuild_sign_owner_type_default \
+	abuild_sign_owner_type_rsa \
+	abuild_sign_owner_type_rsa256
 
 export ABUILD_SHAREDIR="$(atf_get_srcdir)/.."
 
@@ -63,7 +66,14 @@ abuild_sign_installed_body() {
 		abuild-sign --installed
 }
 
-abuild_sign_owner_body() {
+abuild_sign_owner_type_invalid_body() {
+	init_keys
+	atf_check -s exit:1 \
+		-e match:"abuild-sign: supported types are RSA and RSA256" \
+		abuild-sign -t DSA foo.tar.gz
+}
+
+abuild_sign_owner_type_default_body() {
 	init_keys
 	echo foo > .PKGINFO
 	tar -zcf foo.tar.gz .PKGINFO || atf_fail "Failed to create unsigned test archive"
@@ -73,6 +83,34 @@ abuild_sign_owner_body() {
 		abuild-sign foo.tar.gz
 
 	atf_check -s exit:0 \
-		-o match:"0/0.*\.SIGN\.RSA" \
+		-o match:"0/0.*\.SIGN\.RSA\." \
+		tar -ztvf foo.tar.gz
+}
+
+abuild_sign_owner_type_rsa_body() {
+	init_keys
+	echo foo > .PKGINFO
+	tar -zcf foo.tar.gz .PKGINFO || atf_fail "Failed to create unsigned test archive"
+
+	atf_check -s exit:0 \
+		-e match:"Signed" \
+		abuild-sign -t RSA foo.tar.gz
+
+	atf_check -s exit:0 \
+		-o match:"0/0.*\.SIGN\.RSA\." \
+		tar -ztvf foo.tar.gz
+}
+
+abuild_sign_owner_type_rsa256_body() {
+	init_keys
+	echo foo > .PKGINFO
+	tar -zcf foo.tar.gz .PKGINFO || atf_fail "Failed to create unsigned test archive"
+
+	atf_check -s exit:0 \
+		-e match:"Signed" \
+		abuild-sign -t RSA256 foo.tar.gz
+
+	atf_check -s exit:0 \
+		-o match:"0/0.*\.SIGN\.RSA256\." \
 		tar -ztvf foo.tar.gz
 }