diff --git a/package/system/apk/Makefile b/package/system/apk/Makefile new file mode 100644 index 0000000000..912ddc253e --- /dev/null +++ b/package/system/apk/Makefile @@ -0,0 +1,87 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=apk +PKG_RELEASE:=1 + +PKG_SOURCE_URL=https://gitlab.alpinelinux.org/alpine/apk-tools.git +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2024-04-16 +PKG_SOURCE_VERSION:=ba6c31a5469ef74fb85119508e55de9631ffef41 +PKG_MIRROR_HASH:=3455d5799481add9ece3db685576d58be6303f3a13140133979b965cbd3c9966 + +PKG_VERSION=3.0.0_pre$(subst -,,$(PKG_SOURCE_DATE)) + +PKG_MAINTAINER:=Paul Spooren +PKG_LICENSE:=GPL-2.0-only +PKG_LICENSE_FILES:=LICENSE +PKG_INSTALL:=1 + +HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST) +HOST_BUILD_DEPENDS:=lua/host +PKG_BUILD_DEPENDS:=$(HOST_BUILD_DEPENDS) + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/host-build.mk +include $(INCLUDE_DIR)/meson.mk + +define Package/apk/default + SECTION:=base + CATEGORY:=Base system + TITLE:=apk package manager + DEPENDS:=+zlib + URL:=$(PKG_SOURCE_URL) +endef + +define Package/apk-mbedtls + $(Package/apk/default) + TITLE += (mbedtls) + DEPENDS +=+libmbedtls + VARIANT:=mbedtls + DEFAULT_VARIANT:=1 + CONFLICTS:=apk-openssl +endef + +define Package/apk-openssl + $(Package/apk/default) + TITLE += (openssl) + DEPENDS +=+libopenssl + VARIANT:=openssl +endef + +MESON_HOST_VARS+=VERSION=$(PKG_VERSION) +MESON_VARS+=VERSION=$(PKG_VERSION) + +MESON_HOST_ARGS += \ + -Dlua_version=5.1 \ + -Dcompressed-help=false \ + -Ddocs=disabled \ + -Dcrypto_backend=openssl \ + -Dzstd=false + +MESON_ARGS += \ + -Dlua_version=5.1 \ + -Dcompressed-help=false \ + -Ddocs=disabled \ + -Durl_backend=wget \ + -Dcrypto_backend=$(BUILD_VARIANT) \ + -Dzstd=false + +HOST_LDFLAGS += \ + -Wl,-rpath $(STAGING_DIR_HOST)/lib + +define Package/apk/default/install + $(INSTALL_DIR) $(1)/lib/apk/db + + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/apk $(1)/usr/bin/apk + + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libapk.so.* $(1)/usr/lib/ +endef + +Package/apk-mbedtls/install = $(Package/apk/default/install) +Package/apk-openssl/install = $(Package/apk/default/install) + +$(eval $(call BuildPackage,apk-mbedtls)) +$(eval $(call BuildPackage,apk-openssl)) +$(eval $(call HostBuild)) diff --git a/package/system/apk/patches/0001-openwrt-move-layer-db-to-temp-folder.patch b/package/system/apk/patches/0001-openwrt-move-layer-db-to-temp-folder.patch new file mode 100644 index 0000000000..eac8a965e5 --- /dev/null +++ b/package/system/apk/patches/0001-openwrt-move-layer-db-to-temp-folder.patch @@ -0,0 +1,21 @@ +From 9918c683fcc2f148328332d58d030ec5750a1473 Mon Sep 17 00:00:00 2001 +From: Paul Spooren +Date: Sat, 19 Feb 2022 17:20:37 +0100 +Subject: [PATCH 1/4] openwrt: move layer db to temp folder + +Signed-off-by: Paul Spooren +--- + src/database.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/src/database.c ++++ b/src/database.c +@@ -1604,7 +1604,7 @@ const char *apk_db_layer_name(int layer) + { + switch (layer) { + case APK_DB_LAYER_ROOT: return "lib/apk/db"; +- case APK_DB_LAYER_UVOL: return "lib/apk/db-uvol"; ++ case APK_DB_LAYER_UVOL: return "tmp/run/uvol/.meta/apk"; + default: + assert("invalid layer"); + return 0; diff --git a/package/system/apk/patches/0002-mbedtls-support.patch b/package/system/apk/patches/0002-mbedtls-support.patch new file mode 100644 index 0000000000..62b3ab81d3 --- /dev/null +++ b/package/system/apk/patches/0002-mbedtls-support.patch @@ -0,0 +1,917 @@ +From 74ea482102e1a7c1845b3eec19cbdb21264836d4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +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 ++ * Copyright (C) 2008-2011 Timo Teräs ++ * All rights reserved. ++ * ++ * SPDX-License-Identifier: GPL-2.0-only ++ */ ++ ++#include ++#include ++#include ++#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(&act); ++ posix_spawn_file_actions_adddup2(&act, pipefds[1], STDOUT_FILENO); ++ r = posix_spawnp(pid, "wget", &act, 0, argv, environ); ++ posix_spawn_file_actions_destroy(&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->pid == 0) return apk_istream_error(&wis->is, 0); ++ if (waitpid(wis->pid, &status, 0) == wis->pid) { ++ wis->pid = 0; ++ return apk_istream_error(&wis->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->fd, ptr, size); ++ if (r < 0) return -errno; ++ if (r == 0) return wget_check_exit(wis); ++ return r; ++} ++ ++static int wget_close(struct apk_istream *is) ++{ ++ int r = is->err; ++ struct apk_wget_istream *wis = container_of(is, struct apk_wget_istream, is); ++ ++ while (wis->pid != 0) ++ wget_check_exit(wis); ++ ++ close(wis->fd); ++ free(wis); ++ return r < 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 = &wget_istream_ops, ++ .is.buf = (uint8_t *)(wis + 1), ++ .is.buf_size = apk_io_bufsize, ++ }; ++ r = wget_spawn(url, &wis->pid, &wis->fd); ++ if (r != 0) { ++ free(wis); ++ return ERR_PTR(r); ++ } ++ ++ return &wis->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 +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 +--- + 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 +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 +Signed-off-by: Christian Marangi +Signed-off-by: Jonas Jelonek +--- + 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: '>=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 ++#include ++#include ++#include ++ ++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 < 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 ++#include ++ ++#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 + #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 ++#include ++#include ++ ++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 ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#ifdef MBEDTLS_PSA_CRYPTO_C ++#include ++#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->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->alg = alg; ++ ++ mbedtls_md_init(&dctx->mdctx); ++ if (alg == APK_DIGEST_NONE) return 0; ++ if (mbedtls_md_setup(&dctx->mdctx, apk_digest_alg_to_mdinfo(alg), 0) || ++ mbedtls_md_starts(&dctx->mdctx)) ++ return -APKE_CRYPTO_ERROR; ++ ++ return 0; ++} ++ ++int apk_digest_ctx_reset(struct apk_digest_ctx *dctx) ++{ ++ if (dctx->alg == APK_DIGEST_NONE) return 0; ++ if (mbedtls_md_starts(&dctx->mdctx)) return -APKE_CRYPTO_ERROR; ++ return 0; ++} ++ ++int apk_digest_ctx_reset_alg(struct apk_digest_ctx *dctx, uint8_t alg) ++{ ++ mbedtls_md_free(&dctx->mdctx); ++ ++ dctx->alg = alg; ++ if (alg == APK_DIGEST_NONE) return 0; ++ if (mbedtls_md_setup(&dctx->mdctx, apk_digest_alg_to_mdinfo(alg), 0) || ++ mbedtls_md_starts(&dctx->mdctx)) ++ return -APKE_CRYPTO_ERROR; ++ ++ return 0; ++} ++ ++void apk_digest_ctx_free(struct apk_digest_ctx *dctx) ++{ ++ mbedtls_md_free(&dctx->mdctx); ++} ++ ++int apk_digest_ctx_update(struct apk_digest_ctx *dctx, const void *ptr, size_t sz) ++{ ++ if (dctx->alg == APK_DIGEST_NONE) return 0; ++ return mbedtls_md_update(&dctx->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(&dctx->mdctx, d->data)) { ++ apk_digest_reset(d); ++ return -APKE_CRYPTO_ERROR; ++ } ++ ++ d->alg = dctx->alg; ++ d->len = apk_digest_alg_len(d->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)) < 0) ++ return -errno; ++ ++ if (fstat(fd, &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(&c, pub, &pkey->key)) < 0) return -APKE_CRYPTO_ERROR; ++ if (!mbedtls_md(apk_digest_alg_to_mdinfo(APK_DIGEST_SHA512), c, len, dig)) { ++ memcpy(pkey->id, dig, sizeof pkey->id); ++ r = 0; ++ } ++ ++ return r; ++} ++ ++void apk_pkey_free(struct apk_pkey *pkey) ++{ ++ mbedtls_pk_free(&pkey->key); ++} ++ ++static int apk_random(void *ctx, unsigned char *out, size_t len) ++{ ++ return (int)getrandom(out, len, 0); ++} ++ ++#if MBEDTLS_VERSION_NUMBER >= 0x03000000 ++static inline int apk_mbedtls_parse_privkey(struct apk_pkey *pkey, const unsigned char *buf, size_t blen) ++{ ++ return mbedtls_pk_parse_key(&pkey->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(&dctx->sigver_key->key, apk_digest_alg_to_mbedtls_type(dctx->alg), ++ (const unsigned char *)&dig->data, dig->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(&pkey->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(&dctx->sigver_key->key, apk_digest_alg_to_mbedtls_type(dctx->alg), ++ (const unsigned char *)&dig->data, dig->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, &buf, &blen)) ++ return -APKE_CRYPTO_ERROR; ++ ++ mbedtls_pk_init(&pkey->key); ++ if ((ret = mbedtls_pk_parse_public_key(&pkey->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->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, &dig)) ++ return -APKE_SIGNATURE_GEN_FAILURE; ++ ++ if (apk_mbedtls_sign(dctx, &dig, sig, len)) ++ r = -APKE_SIGNATURE_GEN_FAILURE; ++ ++ dctx->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->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, &dig)) ++ return -APKE_SIGNATURE_GEN_FAILURE; ++ ++ if (mbedtls_pk_verify(&dctx->sigver_key->key, apk_digest_alg_to_mbedtls_type(dctx->alg), ++ (const unsigned char *)&dig.data, dig.len, sig, len)) ++ r = -APKE_SIGNATURE_INVALID; ++ ++ dctx->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 +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 +--- + 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