Compare commits

..

11 Commits

Author SHA1 Message Date
Aydin Mercan 962eed50db
crypto/signature: remove domain seperators for now 2022-08-24 10:16:01 +03:00
Aydin Mercan b4089b97b1
crypto/signature: remove tables
State unions and operation lists aren't really useful here.
For example, if someone wanted to have cute-only signatures, we would
need to have stubs that return unsupported only.
2022-08-24 10:15:59 +03:00
Aydin Mercan 0d59807471
extract/v2: simply finding the signature type 2022-08-24 10:15:58 +03:00
Aydin Mercan 1c54a3fbb4
trust: add draft seperate public/secret loading
It isn't clear where secret keys will be located at but this should at
least allow for cleaner seperation in lists.
2022-08-24 10:15:56 +03:00
Aydin Mercan 5b020ec9ef
crypto/signature: introduce domain seperation
It might seem a bit like unnecessary bikeshedding but it shouldn't hurt
anyone.
2022-08-24 10:15:54 +03:00
Aydin Mercan dea8ded23e
crypto/digest: simply state in oneshot calculation 2022-08-24 10:15:53 +03:00
Aydin Mercan 86da6dc599
apk: better messaging when crypto init fails 2022-08-24 10:15:46 +03:00
Aydin Mercan 0b7d6dfbf2
crypto: start seperating public/private key usage
Digests now use bearssl + libsodium instead of openssl + libsodium.
It fits better with the API looking more similar and I don't think it
will be that much of a bottleneck.

Instead of a apk_pkey that mimicks the EVP_PKEY semantics, have seperate
public and private key structures. However, apk is broken because of it
and needs fixing. The rest of the code might compile but won't work
as I haven't handled the cases where pkey corressponds to public/private
keys in codebase properly. Also, DSA signatures are removed.

Public and private keys impls' now use a static array of vtables
internally. The indicies correspond to the signature scheme version and
checking `< APK_*_MAX` should be enough? I tried to make so that higher
values correspond to more desirable constructs, this might come in handy.

Signing/verifying start is free from keys as it isn't used though it
might be brought back for domain seperated hashes, ability to get
timestamps involved with epheremal keys in the future etc.

`apk_crypto.h` is free from openssl includes although some headers still
use them for now.
2022-08-24 10:15:14 +03:00
Aydin Mercan 2727846361
crypto: start tinkering
Start working on "cute" signatures because why not? Cute signatures are
inspired/ripped of from the signify and minisign design:

Key (URL-Safe, padded base64):
- 2 bytes of version tag (specifies the algorithm)
- 16 bytes of key ID
- Public/Private key (size depending on the version tag)

Signature (raw):
- 2 bytes of version tag (specifies the algorithm)
- Signature depending (size depending on the version tag)

The new scheme uses libsodium and thus the work of
abstracting cryptographic operations from libcrypto should also be
completed. Also, since the key of the signature is provided in the
filename, there shouldn't be a need for ID

There is also the possibility of using epheremal keys for signatures and
sign the package's public key, signature and signing timestamp in the header
such as:

- 2 bytes of version tag
- signing timestamp
- epheremal public key used
- epheremal signature
- signature of the previous sections
2022-08-24 10:13:22 +03:00
Timo Teräs c21f61ddd8 db: fix change detection for symlinks
apk_fileinfo_get() special cases symlink digest calculation.
Convert apk_fsdir_ops.file_digest to .file_info to fix symlink
change detection.

fixes #10853
2022-08-17 21:13:40 +03:00
Felix Yan 1ababaa99d Correct a typo in Make.rules 2022-08-15 13:04:45 +00:00
5 changed files with 29 additions and 31 deletions

View File

@ -127,7 +127,7 @@ endif
PHONY += all compile install clean docs FORCE
# Convinient variables
# Convenient variables
comma := ,
squote := '
empty :=

View File

@ -42,7 +42,7 @@ struct apk_fsdir_ops {
int (*file_extract)(struct apk_ctx *, const struct apk_file_info *, struct apk_istream *, apk_progress_cb, void *, unsigned int, apk_blob_t);
int (*file_control)(struct apk_fsdir *, apk_blob_t, int);
int (*file_digest)(struct apk_fsdir *, apk_blob_t, uint8_t alg, struct apk_digest *);
int (*file_info)(struct apk_fsdir *, apk_blob_t, unsigned int, struct apk_file_info *);
};
#define APK_FSEXTRACTF_NO_CHOWN 0x0001
@ -72,8 +72,8 @@ static inline int apk_fsdir_update_perms(struct apk_fsdir *fs, mode_t mode, uid_
static inline int apk_fsdir_file_control(struct apk_fsdir *fs, apk_blob_t filename, int ctrl) {
return fs->ops->file_control(fs, filename, ctrl);
}
static inline int apk_fsdir_file_digest(struct apk_fsdir *fs, apk_blob_t filename, uint8_t alg, struct apk_digest *dgst) {
return fs->ops->file_digest(fs, filename, alg, dgst);
static inline int apk_fsdir_file_info(struct apk_fsdir *fs, apk_blob_t filename, unsigned int flags, struct apk_file_info *fi) {
return fs->ops->file_info(fs, filename, flags, fi);
}
#endif

View File

@ -2758,6 +2758,18 @@ static const struct apk_extract_ops extract_installer = {
.file = apk_db_install_file,
};
static int apk_db_audit_file(struct apk_fsdir *d, apk_blob_t filename, struct apk_db_file *dbf)
{
struct apk_file_info fi;
int r;
// Check file first
r = apk_fsdir_file_info(d, filename, APK_FI_NOFOLLOW | APK_FI_DIGEST(apk_dbf_digest(dbf)), &fi);
if (r != 0 || !dbf || dbf->csum.type == APK_CHECKSUM_NONE) return r != -ENOENT;
if (apk_digest_cmp_csum(&fi.digest, &dbf->csum) != 0) return 1;
return 0;
}
static void apk_db_purge_pkg(struct apk_database *db,
struct apk_installed_package *ipkg,
int is_installed)
@ -2767,7 +2779,6 @@ static void apk_db_purge_pkg(struct apk_database *db,
struct apk_db_file *file;
struct apk_db_file_hash_key key;
struct apk_fsdir d;
struct apk_digest dgst;
struct hlist_node *dc, *dn, *fc, *fn;
unsigned long hash;
int ctrl = is_installed ? APK_FS_CTRL_DELETE : APK_FS_CTRL_CANCEL;
@ -2786,9 +2797,7 @@ static void apk_db_purge_pkg(struct apk_database *db,
if (!is_installed ||
(diri->dir->protect_mode == APK_PROTECT_NONE) ||
(db->ctx->flags & APK_PURGE) ||
(file->csum.type != APK_CHECKSUM_NONE &&
apk_fsdir_file_digest(&d, key.filename, apk_dbf_digest(file), &dgst) == 0 &&
apk_digest_cmp_csum(&dgst, &file->csum) == 0))
apk_db_audit_file(&d, key.filename, file) == 0)
apk_fsdir_file_control(&d, key.filename, ctrl);
apk_dbg2(out, DIR_FILE_FMT, DIR_FILE_PRINTF(diri->dir, file));
@ -2814,7 +2823,6 @@ static uint8_t apk_db_migrate_files_for_priority(struct apk_database *db,
struct apk_db_file_hash_key key;
struct hlist_node *dc, *dn, *fc, *fn;
struct apk_fsdir d;
struct apk_digest dgst;
unsigned long hash;
apk_blob_t dirname;
int r, ctrl;
@ -2849,21 +2857,17 @@ static uint8_t apk_db_migrate_files_for_priority(struct apk_database *db,
// File was from overlay, delete the package's version
ctrl = APK_FS_CTRL_CANCEL;
} else if (diri->dir->protect_mode != APK_PROTECT_NONE &&
apk_fsdir_file_digest(&d, key.filename, apk_dbf_digest(ofile), &dgst) == 0 &&
(!ofile || ofile->csum.type == APK_CHECKSUM_NONE ||
apk_digest_cmp_csum(&dgst, &ofile->csum) != 0)) {
apk_db_audit_file(&d, key.filename, ofile) != 0) {
// Protected directory, and a file without db entry
// or with local modifications. Keep the filesystem file.
// Determine if the package's file should be kept as .apk-new
if ((db->ctx->flags & APK_CLEAN_PROTECTED) ||
(file->csum.type != APK_CHECKSUM_NONE &&
(apk_fsdir_file_digest(&d, key.filename, apk_dbf_digest(file), &dgst) == 0 &&
apk_digest_cmp_csum(&dgst, &file->csum) == 0))) {
apk_db_audit_file(&d, key.filename, file) == 0) {
// No .apk-new files allowed, or the file on disk has the same
// hash as the file from new package. Keep the on disk one.
ctrl = APK_FS_CTRL_CANCEL;
} else {
// All files difference. Use the package's file as .apk-new.
// All files differ. Use the package's file as .apk-new.
ctrl = APK_FS_CTRL_APKNEW;
}
}

View File

@ -12,6 +12,7 @@
#include "apk_fs.h"
#include "apk_xattr.h"
#include "apk_database.h" // for db->atoms
#define TMPNAME_MAX (PATH_MAX + 64)
@ -265,23 +266,16 @@ static int fsys_file_control(struct apk_fsdir *d, apk_blob_t filename, int ctrl)
return rc;
}
static int fsys_file_digest(struct apk_fsdir *d, apk_blob_t filename, uint8_t alg, struct apk_digest *dgst)
static int fsys_file_info(struct apk_fsdir *d, apk_blob_t filename,
unsigned int flags, struct apk_file_info *fi)
{
struct apk_ctx *ac = d->ac;
struct apk_istream *is;
apk_blob_t blob;
int n;
int n, r;
n = apk_pathbuilder_pushb(&d->pb, filename);
is = apk_istream_from_file(apk_ctx_fd_dest(ac), apk_pathbuilder_cstr(&d->pb));
r = apk_fileinfo_get(apk_ctx_fd_dest(ac), apk_pathbuilder_cstr(&d->pb), flags, fi, &ac->db->atoms);
apk_pathbuilder_pop(&d->pb, n);
if (IS_ERR(is)) return PTR_ERR(is);
apk_digest_ctx_reset(&ac->dctx, alg);
while (apk_istream_get_all(is, &blob) == 0)
apk_digest_ctx_update(&ac->dctx, blob.ptr, blob.len);
apk_digest_ctx_final(&ac->dctx, dgst);
return apk_istream_close(is);
return r;
}
static const struct apk_fsdir_ops fsdir_ops_fsys = {
@ -292,7 +286,7 @@ static const struct apk_fsdir_ops fsdir_ops_fsys = {
.dir_update_perms = fsys_dir_update_perms,
.file_extract = fsys_file_extract,
.file_control = fsys_file_control,
.file_digest = fsys_file_digest,
.file_info = fsys_file_info,
};
static const struct apk_fsdir_ops *apk_fsops_get(apk_blob_t dir)

View File

@ -150,7 +150,7 @@ static int uvol_file_control(struct apk_fsdir *d, apk_blob_t filename, int ctrl)
}
}
static int uvol_file_digest(struct apk_fsdir *d, apk_blob_t filename, uint8_t alg, struct apk_digest *dgst)
static int uvol_file_info(struct apk_fsdir *d, apk_blob_t filename, unsigned int flags, struct apk_file_info *fi)
{
return -APKE_UVOL_ERROR;
}
@ -163,5 +163,5 @@ const struct apk_fsdir_ops fsdir_ops_uvol = {
.dir_update_perms = uvol_dir_update_perms,
.file_extract = uvol_file_extract,
.file_control = uvol_file_control,
.file_digest = uvol_file_digest,
.file_info = uvol_file_info,
};