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