<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">From 74ea482102e1a7c1845b3eec19cbdb21264836d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timo=20Ter=C3=A4s?= &lt;timo.teras@iki.fi&gt;
Date: Fri, 5 Apr 2024 12:06:56 +0300
Subject: [PATCH 1/4] add alternate url wget implementation

---
 .gitlab-ci.yml    |  16 ++++-
 meson.build       |   6 +-
 meson_options.txt |   1 +
 src/io_url_wget.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++
 src/meson.build   |   4 +-
 5 files changed, 173 insertions(+), 4 deletions(-)
 create mode 100644 src/io_url_wget.c

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 7fc86563..b7e00008 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -24,7 +24,19 @@ test:alpine:
     script:
         - apk update
         - apk add make gcc git musl-dev openssl-dev linux-headers zlib-dev zstd-dev lua5.3-dev lua5.3-lzlib meson zlib-static zstd-static openssl-libs-static
-        - meson build
+        - meson setup build -Dstatic_apk=true
+        - ninja -C build
+    tags:
+        - docker-alpine
+        - x86_64
+
+test:alpine-alt-config:
+    image: alpine
+    stage: test
+    script:
+        - apk update
+        - apk add make gcc git musl-dev openssl-dev linux-headers zlib-dev lua5.3-dev lua5.3-lzlib meson
+        - meson setup build -Durl_backend=wget -Dzstd=false
         - ninja -C build
     tags:
         - docker-alpine
@@ -38,7 +50,7 @@ test:debian:
         - apt-get install -y make gcc git libssl-dev zlib1g-dev libzstd-dev lua5.3-dev lua5.2 lua-zlib-dev sudo meson
         - unlink /bin/sh
         - ln -s /bin/bash /bin/sh
-        - meson build
+        - meson setup build
         - ninja -C build
     tags:
         - docker-alpine
diff --git a/meson.build b/meson.build
index 1a44c11f..9a14cac0 100644
--- a/meson.build
+++ b/meson.build
@@ -33,6 +33,10 @@ subproject = meson.is_subproject()
 
 subdir('doc')
 subdir('portability')
-subdir('libfetch')
+if get_option('url_backend') == 'libfetch'
+	subdir('libfetch')
+else
+	libfetch_dep = dependency('', required: false)
+endif
 subdir('src')
 subdir('tests')
diff --git a/meson_options.txt b/meson_options.txt
index 693f46ec..940fe9a4 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -5,5 +5,6 @@ option('help', description: 'Build help into apk binaries, needs lua', type: 'fe
 option('lua', description: 'Build luaapk (lua bindings)', type: 'feature', value: 'auto')
 option('lua_version', description: 'Lua version to build against', type: 'string', value: '5.3')
 option('static_apk', description: 'Also build apk.static', type: 'boolean', value: false)
+option('url_backend', description: 'URL backend', type: 'combo', choices: ['libfetch', 'wget'], value: 'libfetch')
 option('uvol_db_target', description: 'Default target for uvol database layer', type: 'string')
 option('zstd', description: 'Build with zstd support', type: 'boolean', value: true)
diff --git a/src/io_url_wget.c b/src/io_url_wget.c
new file mode 100644
index 00000000..9a929222
--- /dev/null
+++ b/src/io_url_wget.c
@@ -0,0 +1,150 @@
+/* io_url_wget.c - Alpine Package Keeper (APK)
+ *
+ * Copyright (C) 2005-2008 Natanael Copa &lt;n@tanael.org&gt;
+ * Copyright (C) 2008-2011 Timo TerÃƒÂ¤s &lt;timo.teras@iki.fi&gt;
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include &lt;spawn.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;sys/wait.h&gt;
+#include "apk_io.h"
+
+static char wget_timeout[16];
+static char wget_no_check_certificate;
+
+static int wget_translate_status(int status)
+{
+	if (!WIFEXITED(status)) return -EFAULT;
+	switch (WEXITSTATUS(status)) {
+	case 0: return 0;
+	case 3: return -EIO;
+	case 4: return -ENETUNREACH;
+	case 5: return -EACCES;
+	case 6: return -EACCES;
+	case 7: return -EPROTO;
+	default: return -APKE_REMOTE_IO;
+	}
+}
+
+struct apk_wget_istream {
+	struct apk_istream is;
+	int fd;
+	pid_t pid;
+};
+
+static int wget_spawn(const char *url, pid_t *pid, int *fd)
+{
+	int i = 0, r, pipefds[2];
+	posix_spawn_file_actions_t act;
+	char *argv[16];
+
+	argv[i++] = "wget";
+	argv[i++] = "-q";
+	argv[i++] = "-T";
+	argv[i++] = wget_timeout;
+	if (wget_no_check_certificate) argv[i++] = "--no-check-certificate";
+	argv[i++] = (char *) url;
+	argv[i++] = "-O";
+	argv[i++] = "-";
+	argv[i++] = 0;
+
+	if (pipe2(pipefds, O_CLOEXEC) != 0) return -errno;
+
+	posix_spawn_file_actions_init(&amp;act);
+	posix_spawn_file_actions_adddup2(&amp;act, pipefds[1], STDOUT_FILENO);
+	r = posix_spawnp(pid, "wget", &amp;act, 0, argv, environ);
+	posix_spawn_file_actions_destroy(&amp;act);
+	if (r != 0) return -r;
+	close(pipefds[1]);
+	*fd = pipefds[0];
+	return 0;
+}
+
+static int wget_check_exit(struct apk_wget_istream *wis)
+{
+	int status;
+
+	if (wis-&gt;pid == 0) return apk_istream_error(&amp;wis-&gt;is, 0);
+	if (waitpid(wis-&gt;pid, &amp;status, 0) == wis-&gt;pid) {
+		wis-&gt;pid = 0;
+		return apk_istream_error(&amp;wis-&gt;is, wget_translate_status(status));
+	}
+	return 0;
+}
+
+static void wget_get_meta(struct apk_istream *is, struct apk_file_meta *meta)
+{
+}
+
+static ssize_t wget_read(struct apk_istream *is, void *ptr, size_t size)
+{
+	struct apk_wget_istream *wis = container_of(is, struct apk_wget_istream, is);
+	ssize_t r;
+
+	r = read(wis-&gt;fd, ptr, size);
+	if (r &lt; 0) return -errno;
+	if (r == 0) return wget_check_exit(wis);
+	return r;
+}
+
+static int wget_close(struct apk_istream *is)
+{
+	int r = is-&gt;err;
+	struct apk_wget_istream *wis = container_of(is, struct apk_wget_istream, is);
+
+	while (wis-&gt;pid != 0)
+		wget_check_exit(wis);
+
+	close(wis-&gt;fd);
+	free(wis);
+	return r &lt; 0 ? r : 0;
+}
+
+static const struct apk_istream_ops wget_istream_ops = {
+	.get_meta = wget_get_meta,
+	.read = wget_read,
+	.close = wget_close,
+};
+
+struct apk_istream *apk_io_url_istream(const char *url, time_t since)
+{
+	struct apk_wget_istream *wis;
+	int r;
+
+	wis = malloc(sizeof(*wis) + apk_io_bufsize);
+	if (wis == NULL) return ERR_PTR(-ENOMEM);
+
+	*wis = (struct apk_wget_istream) {
+		.is.ops = &amp;wget_istream_ops,
+		.is.buf = (uint8_t *)(wis + 1),
+		.is.buf_size = apk_io_bufsize,
+	};
+	r = wget_spawn(url, &amp;wis-&gt;pid, &amp;wis-&gt;fd);
+	if (r != 0) {
+		free(wis);
+		return ERR_PTR(r);
+	}
+
+	return &amp;wis-&gt;is;
+}
+
+void apk_io_url_no_check_certificate(void)
+{
+	wget_no_check_certificate = 1;
+}
+
+void apk_io_url_set_timeout(int timeout)
+{
+	snprintf(wget_timeout, sizeof wget_timeout, "%d", timeout);
+}
+
+void apk_io_url_set_redirect_callback(void (*cb)(int, const char *))
+{
+}
+
+void apk_io_url_init(void)
+{
+}
diff --git a/src/meson.build b/src/meson.build
index c1aae550..38e9d3b0 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,3 +1,5 @@
+url_backend = get_option('url_backend')
+
 libapk_so_version = '2.99.0'
 libapk_src = [
 	'adb.c',
@@ -22,8 +24,8 @@ libapk_src = [
 	'fs_uvol.c',
 	'hash.c',
 	'io.c',
-	'io_url_libfetch.c',
 	'io_gunzip.c',
+	'io_url_@0@.c'.format(url_backend),
 	'package.c',
 	'pathbuilder.c',
 	'print.c',
-- 
GitLab


From b9fe78fbf19bb10e1d0b8eb1cb1de123bee2ed7e Mon Sep 17 00:00:00 2001
From: Christian Marangi &lt;ansuelsmth@gmail.com&gt;
Date: Tue, 16 Apr 2024 17:55:15 +0200
Subject: [PATCH 2/4] add option to configure url backend in legacy make build
 system

Can be configured by setting URL_BACKEND. If not set libfetch is
selected by default.

Signed-off-by: Christian Marangi &lt;ansuelsmth@gmail.com&gt;
---
 src/Makefile | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index f7873cb1..efdc68df 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -9,8 +9,8 @@ else
 $(error Lua interpreter not found. Please specify LUA interpreter, or use LUA=no to build without help.)
 endif
 
-OPENSSL_CFLAGS		:= $(shell $(PKG_CONFIG) --cflags openssl)
-OPENSSL_LIBS		:= $(shell $(PKG_CONFIG) --libs openssl)
+OPENSSL_CFLAGS         := $(shell $(PKG_CONFIG) --cflags openssl)
+OPENSSL_LIBS           := $(shell $(PKG_CONFIG) --libs openssl)
 
 ZLIB_CFLAGS		:= $(shell $(PKG_CONFIG) --cflags zlib)
 ZLIB_LIBS		:= $(shell $(PKG_CONFIG) --libs zlib)
@@ -21,10 +21,18 @@ libapk_so		:= $(obj)/libapk.so.$(libapk_soname)
 libapk.so.$(libapk_soname)-objs := \
 	adb.o adb_comp.o adb_walk_adb.o adb_walk_genadb.o adb_walk_gentext.o adb_walk_text.o apk_adb.o \
 	atom.o blob.o commit.o common.o context.o crypto.o crypto_openssl.o ctype.o database.o hash.o \
-	extract_v2.o extract_v3.o fs_fsys.o fs_uvol.o io.o io_gunzip.o io_url_libfetch.o \
-	tar.o package.o pathbuilder.o print.o solver.o trust.o version.o
+	extract_v2.o extract_v3.o fs_fsys.o fs_uvol.o io.o io_gunzip.o tar.o package.o pathbuilder.o \
+	print.o solver.o trust.o version.o
 
-libapk.so.$(libapk_soname)-libs := libfetch/libfetch.a
+libapk.so.$(libapk_soname)-libs :=
+
+ifeq ($(URL_BACKEND),wget)
+libapk.so.$(libapk_soname)-objs += io_url_wget.o
+else
+CFLAGS_ALL += -Ilibfetch
+libapk.so.$(libapk_soname)-objs += io_url_libfetch.o
+libapk.so.$(libapk_soname)-libs += libfetch/libfetch.a
+endif
 
 # ZSTD support can be disabled
 ifneq ($(ZSTD),no)
@@ -79,7 +87,7 @@ LIBS_apk		:= -lapk
 LIBS_apk-test		:= -lapk
 LIBS_apk.so		:= -L$(obj) -lapk
 
-CFLAGS_ALL		+= -D_ATFILE_SOURCE -Ilibfetch -Iportability
+CFLAGS_ALL		+= -D_ATFILE_SOURCE -Iportability
 CFLAGS_apk.o		:= -DAPK_VERSION=\"$(VERSION)\"
 CFLAGS_apk-static.o	:= -DAPK_VERSION=\"$(VERSION)\" -DOPENSSL_NO_ENGINE
 CFLAGS_apk-test.o	:= -DAPK_VERSION=\"$(VERSION)\" -DOPENSSL_NO_ENGINE -DTEST_MODE
-- 
GitLab


From 0418b684898403c49905c1f0e4b7c5ca522b2d50 Mon Sep 17 00:00:00 2001
From: Jonas Jelonek &lt;jelonek.jonas@gmail.com&gt;
Date: Sun, 14 Apr 2024 00:20:14 +0200
Subject: [PATCH 3/4] crypto: add support for mbedtls as backend

backend is selected at compile-time with crypto_backend option

Co-developed-by: Christian Marangi &lt;ansuelsmth@gmail.com&gt;
Signed-off-by: Christian Marangi &lt;ansuelsmth@gmail.com&gt;
Signed-off-by: Jonas Jelonek &lt;jelonek.jonas@gmail.com&gt;
---
 libfetch/meson.build     |   2 +-
 meson.build              |  14 +-
 meson_options.txt        |   1 +
 portability/getrandom.c  |  19 +++
 portability/meson.build  |   3 +-
 portability/sys/random.h |   6 +
 src/apk_crypto.h         |   5 +
 src/apk_crypto_mbedtls.h |  30 +++++
 src/crypto_mbedtls.c     | 285 +++++++++++++++++++++++++++++++++++++++
 src/meson.build          |  21 ++-
 10 files changed, 373 insertions(+), 13 deletions(-)
 create mode 100644 portability/getrandom.c
 create mode 100644 portability/sys/random.h
 create mode 100644 src/apk_crypto_mbedtls.h
 create mode 100644 src/crypto_mbedtls.c

diff --git a/libfetch/meson.build b/libfetch/meson.build
index 431ba197..e24f95eb 100644
--- a/libfetch/meson.build
+++ b/libfetch/meson.build
@@ -40,7 +40,7 @@ libfetch = static_library(
 	c_args: libfetch_cargs,
 	dependencies: [
 		libportability_dep.partial_dependency(compile_args: true, includes: true),
-		openssl_dep.partial_dependency(compile_args: true, includes: true)
+		crypto_dep.partial_dependency(compile_args: true, includes: true)
 	],
 )
 
diff --git a/meson.build b/meson.build
index 9a14cac0..3a83f4e1 100644
--- a/meson.build
+++ b/meson.build
@@ -13,15 +13,21 @@ apk_libdir = get_option('libdir')
 lua_bin = find_program('lua' + get_option('lua_version'), required: get_option('help'))
 lua_dep = dependency('lua' + get_option('lua_version'), required: get_option('lua'))
 scdoc_dep = dependency('scdoc', version: '&gt;=1.10', required: get_option('docs'))
-openssl_dep = dependency('openssl')
-openssl_static_dep = dependency('openssl', static: true)
 zlib_dep = dependency('zlib')
 zlib_static_dep = dependency('zlib', static: true)
 libzstd_dep = dependency('libzstd', required: get_option('zstd'))
 libzstd_static_dep = dependency('libzstd', required: get_option('zstd'), static: true)
 
-shared_deps = [ openssl_dep, zlib_dep, libzstd_dep ]
-static_deps = [ openssl_static_dep, zlib_static_dep, libzstd_static_dep ]
+if get_option('crypto_backend') == 'openssl'
+	crypto_dep = dependency('openssl')
+	crypto_static_dep = dependency('openssl', static: true)
+elif get_option('crypto_backend') == 'mbedtls'
+	crypto_dep = [ dependency('mbedtls'), dependency('mbedcrypto') ]
+	crypto_static_dep = [ dependency('mbedtls', static: true), dependency('mbedcrypto', static: true) ]
+endif
+
+shared_deps = [ crypto_dep, zlib_dep, libzstd_dep ]
+static_deps = [ crypto_static_dep, zlib_static_dep, libzstd_static_dep ]
 
 add_project_arguments('-D_GNU_SOURCE', language: 'c')
 
diff --git a/meson_options.txt b/meson_options.txt
index 940fe9a4..df0b07dc 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,4 +1,5 @@
 option('arch_prefix', description: 'Define a custom arch prefix for default arch', type: 'string')
+option('crypto_backend', description: 'Crypto backend', type: 'combo', choices: ['openssl', 'mbedtls'], value: 'openssl')
 option('compressed-help', description: 'Compress help database, needs lua-zlib', type: 'boolean', value: true)
 option('docs', description: 'Build manpages with scdoc', type: 'feature', value: 'auto')
 option('help', description: 'Build help into apk binaries, needs lua', type: 'feature', value: 'auto')
diff --git a/portability/getrandom.c b/portability/getrandom.c
new file mode 100644
index 00000000..b2f4a07c
--- /dev/null
+++ b/portability/getrandom.c
@@ -0,0 +1,19 @@
+#include &lt;sys/random.h&gt;
+#include &lt;sys/types.h&gt;
+#include &lt;unistd.h&gt;
+#include &lt;fcntl.h&gt;
+
+ssize_t getrandom(void *buf, size_t buflen, unsigned int flags)
+{
+	int fd;
+	ssize_t ret;
+
+	fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC);
+	if (fd &lt; 0)
+		return -1;
+
+	ret = read(fd, buf, buflen);
+	close(fd);
+	return ret;
+}
+
diff --git a/portability/meson.build b/portability/meson.build
index 89957c3c..3172044e 100644
--- a/portability/meson.build
+++ b/portability/meson.build
@@ -3,7 +3,8 @@ cc = meson.get_compiler('c')
 libportability_src = []
 
 check_symbols = [
-	['memrchr', 'memrchr.c', 'NEED_MEMRCHR', 'string.h'],
+	['getrandom', 'getrandom.c', 'NEED_GETRANDOM', 'sys/random.h'],
+        ['memrchr', 'memrchr.c', 'NEED_MEMRCHR', 'string.h'],
 	['mknodat', 'mknodat.c', 'NEED_MKNODAT', 'sys/stat.h'],
 	['pipe2', 'pipe2.c', 'NEED_PIPE2', 'unistd.h'],
 	['qsort_r', 'qsort_r.c', 'NEED_QSORT_R', 'stdlib.h'],
diff --git a/portability/sys/random.h b/portability/sys/random.h
new file mode 100644
index 00000000..02d5b1ca
--- /dev/null
+++ b/portability/sys/random.h
@@ -0,0 +1,6 @@
+#include_next &lt;sys/random.h&gt;
+#include &lt;sys/types.h&gt;
+
+#ifdef NEED_GETRANDOM
+ssize_t getrandom(void *buf, size_t buflen, unsigned int flags);
+#endif
diff --git a/src/apk_crypto.h b/src/apk_crypto.h
index 7de88dfc..5cae3bfe 100644
--- a/src/apk_crypto.h
+++ b/src/apk_crypto.h
@@ -12,7 +12,12 @@
 #include &lt;string.h&gt;
 #include "apk_defines.h"
 #include "apk_blob.h"
+
+#if defined(CRYPTO_USE_OPENSSL)
 #include "apk_crypto_openssl.h"
+#elif defined(CRYPTO_USE_MBEDTLS)
+#include "apk_crypto_mbedtls.h"
+#endif
 
 // Digest
 
diff --git a/src/apk_crypto_mbedtls.h b/src/apk_crypto_mbedtls.h
new file mode 100644
index 00000000..5481d149
--- /dev/null
+++ b/src/apk_crypto_mbedtls.h
@@ -0,0 +1,30 @@
+/* apk_crypto_mbedtls.h - Alpine Package Keeper (APK)
+ *
+ * Copyright (C) 2024
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#ifndef APK_CRYPTO_MBEDTLS_H
+#define APK_CRYPTO_MBEDTLS_H
+
+#include &lt;mbedtls/md.h&gt;
+#include &lt;mbedtls/pk.h&gt;
+#include &lt;mbedtls/bignum.h&gt;
+
+struct apk_pkey {
+	uint8_t id[16];
+	mbedtls_pk_context key;
+};
+
+struct apk_digest_ctx {
+	mbedtls_md_context_t mdctx;
+	struct apk_pkey *sigver_key;
+	uint8_t alg;
+};
+
+/* based on mbedtls' internal pkwrite.h calculations */
+#define APK_ENC_KEY_MAX_LENGTH          (38 + 2 * MBEDTLS_MPI_MAX_SIZE)
+
+#endif
diff --git a/src/crypto_mbedtls.c b/src/crypto_mbedtls.c
new file mode 100644
index 00000000..73d60e9d
--- /dev/null
+++ b/src/crypto_mbedtls.c
@@ -0,0 +1,285 @@
+#include &lt;errno.h&gt;
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;fcntl.h&gt;
+#include &lt;sys/random.h&gt;
+#include &lt;sys/stat.h&gt;
+#include &lt;unistd.h&gt;
+
+#include &lt;mbedtls/platform.h&gt;
+#include &lt;mbedtls/md.h&gt;
+#include &lt;mbedtls/pk.h&gt;
+#include &lt;mbedtls/entropy.h&gt;
+
+#ifdef MBEDTLS_PSA_CRYPTO_C
+#include &lt;psa/crypto.h&gt;
+#endif
+
+#include "apk_crypto.h"
+
+static inline const mbedtls_md_type_t apk_digest_alg_to_mbedtls_type(uint8_t alg) {
+	switch (alg) {
+	case APK_DIGEST_NONE:	return MBEDTLS_MD_NONE;
+	case APK_DIGEST_MD5:	return MBEDTLS_MD_MD5;
+	case APK_DIGEST_SHA1:	return MBEDTLS_MD_SHA1;
+	case APK_DIGEST_SHA256_160:
+	case APK_DIGEST_SHA256:	return MBEDTLS_MD_SHA256;
+	case APK_DIGEST_SHA512:	return MBEDTLS_MD_SHA512;
+	default:
+		assert(alg);
+		return MBEDTLS_MD_NONE;
+	}
+}
+
+static inline const mbedtls_md_info_t *apk_digest_alg_to_mdinfo(uint8_t alg)
+{
+	return mbedtls_md_info_from_type(
+		apk_digest_alg_to_mbedtls_type(alg)
+	);
+}
+
+int apk_digest_calc(struct apk_digest *d, uint8_t alg, const void *ptr, size_t sz)
+{
+	if (mbedtls_md(apk_digest_alg_to_mdinfo(alg), ptr, sz, d-&gt;data))
+		return -APKE_CRYPTO_ERROR;
+
+	apk_digest_set(d, alg);
+	return 0;
+}
+
+int apk_digest_ctx_init(struct apk_digest_ctx *dctx, uint8_t alg)
+{
+	dctx-&gt;alg = alg;
+
+	mbedtls_md_init(&amp;dctx-&gt;mdctx);
+	if (alg == APK_DIGEST_NONE) return 0;
+	if (mbedtls_md_setup(&amp;dctx-&gt;mdctx, apk_digest_alg_to_mdinfo(alg), 0) ||
+		mbedtls_md_starts(&amp;dctx-&gt;mdctx))
+		return -APKE_CRYPTO_ERROR;
+
+	return 0;
+}
+
+int apk_digest_ctx_reset(struct apk_digest_ctx *dctx)
+{
+	if (dctx-&gt;alg == APK_DIGEST_NONE) return 0;
+	if (mbedtls_md_starts(&amp;dctx-&gt;mdctx)) return -APKE_CRYPTO_ERROR;
+	return 0;
+}
+
+int apk_digest_ctx_reset_alg(struct apk_digest_ctx *dctx, uint8_t alg)
+{
+	mbedtls_md_free(&amp;dctx-&gt;mdctx);
+
+	dctx-&gt;alg = alg;
+	if (alg == APK_DIGEST_NONE) return 0;
+	if (mbedtls_md_setup(&amp;dctx-&gt;mdctx, apk_digest_alg_to_mdinfo(alg), 0) ||
+		mbedtls_md_starts(&amp;dctx-&gt;mdctx))
+		return -APKE_CRYPTO_ERROR;
+
+	return 0;
+}
+
+void apk_digest_ctx_free(struct apk_digest_ctx *dctx)
+{
+	mbedtls_md_free(&amp;dctx-&gt;mdctx);
+}
+
+int apk_digest_ctx_update(struct apk_digest_ctx *dctx, const void *ptr, size_t sz)
+{
+	if (dctx-&gt;alg == APK_DIGEST_NONE) return 0;
+	return mbedtls_md_update(&amp;dctx-&gt;mdctx, ptr, sz) == 0 ? 0 : -APKE_CRYPTO_ERROR;
+}
+
+int apk_digest_ctx_final(struct apk_digest_ctx *dctx, struct apk_digest *d)
+{
+	if (mbedtls_md_finish(&amp;dctx-&gt;mdctx, d-&gt;data)) {
+		apk_digest_reset(d);
+		return -APKE_CRYPTO_ERROR;
+	}
+
+	d-&gt;alg = dctx-&gt;alg;
+	d-&gt;len = apk_digest_alg_len(d-&gt;alg);
+	return 0;
+}
+
+static int apk_load_file_at(int dirfd, const char *fn, unsigned char **buf, size_t *n)
+{
+	struct stat stats;
+	size_t size;
+	int fd;
+
+	if ((fd = openat(dirfd, fn, O_RDONLY|O_CLOEXEC)) &lt; 0)
+		return -errno;
+
+	if (fstat(fd, &amp;stats)) {
+		close(fd);
+		return -errno;
+	}
+
+	size = (size_t)stats.st_size;
+	*n = size;
+
+	if (size == 0 || (*buf = mbedtls_calloc(1, size + 1)) == NULL)
+		return MBEDTLS_ERR_PK_ALLOC_FAILED;
+
+	if (read(fd, *buf, size) != size) {
+		close(fd);
+
+		mbedtls_platform_zeroize(*buf, size);
+		mbedtls_free(*buf);
+
+		return MBEDTLS_ERR_PK_FILE_IO_ERROR;
+	}
+	close(fd);
+
+	(*buf)[size] = '\0';
+
+	if (strstr((const char *) *buf, "-----BEGIN ") != NULL) {
+		++*n;
+	}
+
+	return 0;
+}
+
+static int apk_pkey_init(struct apk_pkey *pkey)
+{
+	unsigned char dig[APK_DIGEST_MAX_LENGTH];
+	unsigned char pub[APK_ENC_KEY_MAX_LENGTH] = {};
+	unsigned char *c;
+	int len, r = -APKE_CRYPTO_ERROR;
+
+	c = pub + APK_ENC_KEY_MAX_LENGTH;
+
+	// key is written backwards into pub starting at c!
+	if ((len = mbedtls_pk_write_pubkey(&amp;c, pub, &amp;pkey-&gt;key)) &lt; 0) return -APKE_CRYPTO_ERROR;
+	if (!mbedtls_md(apk_digest_alg_to_mdinfo(APK_DIGEST_SHA512), c, len, dig)) {
+		memcpy(pkey-&gt;id, dig, sizeof pkey-&gt;id);
+		r = 0;
+	}
+
+	return r;
+}
+
+void apk_pkey_free(struct apk_pkey *pkey)
+{
+	mbedtls_pk_free(&amp;pkey-&gt;key);
+}
+
+static int apk_random(void *ctx, unsigned char *out, size_t len)
+{
+	return (int)getrandom(out, len, 0);
+}
+
+#if MBEDTLS_VERSION_NUMBER &gt;= 0x03000000
+static inline int apk_mbedtls_parse_privkey(struct apk_pkey *pkey, const unsigned char *buf, size_t blen)
+{
+	return mbedtls_pk_parse_key(&amp;pkey-&gt;key, buf, blen, NULL, 0, apk_random, NULL);
+}
+static inline int apk_mbedtls_sign(struct apk_digest_ctx *dctx, struct apk_digest *dig,
+				   unsigned char *sig, size_t *sig_len)
+{
+	return mbedtls_pk_sign(&amp;dctx-&gt;sigver_key-&gt;key, apk_digest_alg_to_mbedtls_type(dctx-&gt;alg),
+			       (const unsigned char *)&amp;dig-&gt;data, dig-&gt;len, sig, sizeof *sig, sig_len,
+			       apk_random, NULL);
+}
+#else
+static inline int apk_mbedtls_parse_privkey(struct apk_pkey *pkey, const unsigned char *buf, size_t blen)
+{
+	return mbedtls_pk_parse_key(&amp;pkey-&gt;key, buf, blen, NULL, 0);
+}
+static inline int apk_mbedtls_sign(struct apk_digest_ctx *dctx, struct apk_digest *dig,
+				   unsigned char *sig, size_t *sig_len)
+{
+	return mbedtls_pk_sign(&amp;dctx-&gt;sigver_key-&gt;key, apk_digest_alg_to_mbedtls_type(dctx-&gt;alg),
+			       (const unsigned char *)&amp;dig-&gt;data, dig-&gt;len, sig, sig_len, apk_random, NULL);
+}
+#endif
+
+int apk_pkey_load(struct apk_pkey *pkey, int dirfd, const char *fn)
+{
+	unsigned char *buf = NULL;
+	size_t blen = 0;
+	int ret;
+
+	if (apk_load_file_at(dirfd, fn, &amp;buf, &amp;blen))
+		return -APKE_CRYPTO_ERROR;
+
+	mbedtls_pk_init(&amp;pkey-&gt;key);
+	if ((ret = mbedtls_pk_parse_public_key(&amp;pkey-&gt;key, buf, blen)) != 0)
+		ret = apk_mbedtls_parse_privkey(pkey, buf, blen);
+
+	mbedtls_platform_zeroize(buf, blen);
+	mbedtls_free(buf);
+	if (ret != 0)
+		return -APKE_CRYPTO_KEY_FORMAT;
+
+	return apk_pkey_init(pkey);
+}
+
+int apk_sign_start(struct apk_digest_ctx *dctx, uint8_t alg, struct apk_pkey *pkey)
+{
+	if (apk_digest_ctx_reset_alg(dctx, alg))
+		return -APKE_CRYPTO_ERROR;
+
+	dctx-&gt;sigver_key = pkey;
+
+	return 0;
+}
+
+int apk_sign(struct apk_digest_ctx *dctx, void *sig, size_t *len)
+{
+	struct apk_digest dig;
+	int r = 0;
+
+	if (apk_digest_ctx_final(dctx, &amp;dig))
+		return -APKE_SIGNATURE_GEN_FAILURE;
+
+	if (apk_mbedtls_sign(dctx, &amp;dig, sig, len))
+		r = -APKE_SIGNATURE_GEN_FAILURE;
+
+	dctx-&gt;sigver_key = NULL;
+	return r;
+}
+
+int apk_verify_start(struct apk_digest_ctx *dctx, uint8_t alg, struct apk_pkey *pkey)
+{
+	if (apk_digest_ctx_reset_alg(dctx, alg))
+		return -APKE_CRYPTO_ERROR;
+
+	dctx-&gt;sigver_key = pkey;
+
+	return 0;
+}
+
+int apk_verify(struct apk_digest_ctx *dctx, void *sig, size_t len)
+{
+	struct apk_digest dig;
+	int r = 0;
+
+	if (apk_digest_ctx_final(dctx, &amp;dig))
+		return -APKE_SIGNATURE_GEN_FAILURE;
+
+	if (mbedtls_pk_verify(&amp;dctx-&gt;sigver_key-&gt;key, apk_digest_alg_to_mbedtls_type(dctx-&gt;alg),
+			      (const unsigned char *)&amp;dig.data, dig.len, sig, len))
+		r = -APKE_SIGNATURE_INVALID;
+
+	dctx-&gt;sigver_key = NULL;
+	return r;
+}
+
+static void apk_crypto_cleanup(void)
+{
+#ifdef MBEDTLS_PSA_CRYPTO_C
+	mbedtls_psa_crypto_free();
+#endif
+}
+
+void apk_crypto_init(void)
+{
+	atexit(apk_crypto_cleanup);
+	
+#ifdef MBEDTLS_PSA_CRYPTO_C
+	psa_crypto_init();
+#endif
+}
diff --git a/src/meson.build b/src/meson.build
index 38e9d3b0..e1204fc0 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,3 +1,4 @@
+crypto_backend = get_option('crypto_backend')
 url_backend = get_option('url_backend')
 
 libapk_so_version = '2.99.0'
@@ -15,7 +16,7 @@ libapk_src = [
 	'common.c',
 	'context.c',
 	'crypto.c',
-	'crypto_openssl.c',
+        'crypto_@0@.c'.format(crypto_backend),
 	'ctype.c',
 	'database.c',
 	'extract_v2.c',
@@ -40,7 +41,7 @@ libapk_headers = [
 	'apk_atom.h',
 	'apk_blob.h',
 	'apk_crypto.h',
-	'apk_crypto_openssl.h',
+        'apk_crypto_@0@.h'.format(crypto_backend),
 	'apk_ctype.h',
 	'apk_database.h',
 	'apk_defines.h',
@@ -89,6 +90,17 @@ apk_src = [
 	'applet.c',
 ]
 
+apk_cargs = [
+	'-DAPK_VERSION="' + meson.project_version() + '"',
+	'-D_ATFILE_SOURCE',
+]
+
+if crypto_backend == 'openssl'
+	apk_cargs += [ '-DCRYPTO_USE_OPENSSL' ]
+elif crypto_backend == 'mbedtls'
+	apk_cargs += [ '-DCRYPTO_USE_MBEDTLS' ]
+endif
+
 if lua_bin.found()
 	genhelp_script = files('genhelp.lua')
 	genhelp_args = [lua_bin, genhelp_script, '@INPUT@']
@@ -115,11 +127,6 @@ endif
 
 apk_src += [ generated_help ]
 
-apk_cargs = [
-	'-DAPK_VERSION="' + meson.project_version() + '"',
-	'-D_ATFILE_SOURCE',
-]
-
 apk_arch_prefix = get_option('arch_prefix')
 if apk_arch_prefix != ''
 	apk_cargs += ['-DAPK_ARCH_PREFIX="@0@"'.format(apk_arch_prefix)]
-- 
GitLab


From 34bb1021284dccbf97f02b0a0bb9e751b8887cad Mon Sep 17 00:00:00 2001
From: Christian Marangi &lt;ansuelsmth@gmail.com&gt;
Date: Tue, 16 Apr 2024 17:56:45 +0200
Subject: [PATCH 4/4] add option to configure crypto backend in legacy make
 build system

Define CRYPTO to select mbedtls as alternative crypto backend. By
default openssl is used.

Signed-off-by: Christian Marangi &lt;ansuelsmth@gmail.com&gt;
---
 src/Makefile | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index efdc68df..97db0e72 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -20,9 +20,9 @@ libapk_soname		:= 2.99.0
 libapk_so		:= $(obj)/libapk.so.$(libapk_soname)
 libapk.so.$(libapk_soname)-objs := \
 	adb.o adb_comp.o adb_walk_adb.o adb_walk_genadb.o adb_walk_gentext.o adb_walk_text.o apk_adb.o \
-	atom.o blob.o commit.o common.o context.o crypto.o crypto_openssl.o ctype.o database.o hash.o \
-	extract_v2.o extract_v3.o fs_fsys.o fs_uvol.o io.o io_gunzip.o tar.o package.o pathbuilder.o \
-	print.o solver.o trust.o version.o
+	atom.o blob.o commit.o common.o context.o crypto.o ctype.o database.o hash.o extract_v2.o \
+	extract_v3.o fs_fsys.o fs_uvol.o io.o io_gunzip.o tar.o package.o pathbuilder.o print.o \
+	solver.o trust.o version.o
 
 libapk.so.$(libapk_soname)-libs :=
 
@@ -34,6 +34,16 @@ libapk.so.$(libapk_soname)-objs += io_url_libfetch.o
 libapk.so.$(libapk_soname)-libs += libfetch/libfetch.a
 endif
 
+ifeq ($(CRYPTO),mbedtls)
+CRYPTO_CFLAGS		:= $(shell $(PKG_CONFIG) --cflags mbedtls mbedcrypto) -DCRYPTO_USE_MBEDTLS
+CRYPTO_LIBS		:= $(shell $(PKG_CONFIG) --libs mbedtls mbedcrypto)
+libapk.so.$(libapk_soname)-objs += crypto_mbedtls.o
+else
+CRYPTO_CFLAGS		:= $(shell $(PKG_CONFIG) --cflags openssl) -DCRYPTO_USE_OPENSSL
+CRYPTO_LIBS		:= $(shell $(PKG_CONFIG) --libs openssl)
+libapk.so.$(libapk_soname)-objs += crypto_openssl.o
+endif
+
 # ZSTD support can be disabled
 ifneq ($(ZSTD),no)
 ZSTD_CFLAGS		:= $(shell $(PKG_CONFIG) --cflags libzstd)
@@ -100,9 +110,9 @@ LIBS_apk.static		:= -Wl,--as-needed -ldl -Wl,--no-as-needed
 LDFLAGS_apk		+= -L$(obj)
 LDFLAGS_apk-test	+= -L$(obj)
 
-CFLAGS_ALL		+= $(OPENSSL_CFLAGS) $(ZLIB_CFLAGS) $(ZSTD_CFLAGS)
+CFLAGS_ALL		+= $(CRYPTO_CFLAGS) $(ZLIB_CFLAGS) $(ZSTD_CFLAGS)
 LIBS			:= -Wl,--as-needed \
-				$(OPENSSL_LIBS) $(ZLIB_LIBS) $(ZSTD_LIBS) \
+				$(CRYPTO_LIBS) $(ZLIB_LIBS) $(ZSTD_LIBS) \
 			   -Wl,--no-as-needed
 
 # Help generation
-- 
GitLab
</pre></body></html>