git: 082f3564f94d - stable/13 - pkg: abstract rsa out behind a pkgsign API
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 11 Jan 2025 02:49:03 UTC
The branch stable/13 has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=082f3564f94d85054aba8ef4d34fc375611e5387
commit 082f3564f94d85054aba8ef4d34fc375611e5387
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-01-01 21:10:27 +0000
Commit: Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-01-11 02:48:30 +0000
pkg: abstract rsa out behind a pkgsign API
This mirrors a change we made in pkg(8), and will be used to next add
another signer that does ECC.
Reviewed by: bapt, emaste
(cherry picked from commit 5862580ded35e23581291a2e1052f04428369ead)
---
usr.sbin/pkg/pkg.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
usr.sbin/pkg/pkg.h | 22 ++++++++++++--
usr.sbin/pkg/rsa.c | 11 +++++--
3 files changed, 110 insertions(+), 9 deletions(-)
diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c
index 56bced7b9c5f..5cc9c3b8dbfe 100644
--- a/usr.sbin/pkg/pkg.c
+++ b/usr.sbin/pkg/pkg.c
@@ -35,6 +35,7 @@
#include <archive.h>
#include <archive_entry.h>
+#include <assert.h>
#include <dirent.h>
#include <err.h>
#include <errno.h>
@@ -55,6 +56,16 @@
#include "config.h"
#include "hash.h"
+static const struct pkgsign_impl {
+ const char *pi_name;
+ const struct pkgsign_ops *pi_ops;
+} pkgsign_builtins[] = {
+ {
+ .pi_name = "rsa",
+ .pi_ops = &pkgsign_rsa,
+ },
+};
+
typedef enum {
HASH_UNKNOWN,
HASH_SHA256,
@@ -75,6 +86,61 @@ static const char *bootstrap_names [] = {
STAILQ_HEAD(fingerprint_list, fingerprint);
+static int
+pkgsign_new(const char *name, struct pkgsign_ctx **ctx)
+{
+ const struct pkgsign_impl *impl;
+ const struct pkgsign_ops *ops;
+ struct pkgsign_ctx *nctx;
+ size_t ctx_size;
+ int ret;
+
+ assert(*ctx == NULL);
+ ops = NULL;
+ for (size_t i = 0; i < nitems(pkgsign_builtins); i++) {
+ impl = &pkgsign_builtins[i];
+
+ if (strcmp(name, impl->pi_name) == 0) {
+ ops = impl->pi_ops;
+ break;
+ }
+ }
+
+ if (ops == NULL)
+ return (ENOENT);
+
+ ctx_size = ops->pkgsign_ctx_size;
+ if (ctx_size == 0)
+ ctx_size = sizeof(*nctx);
+ assert(ctx_size >= sizeof(*nctx));
+
+ nctx = calloc(1, ctx_size);
+ if (nctx == NULL)
+ err(EXIT_FAILURE, "calloc");
+ nctx->impl = impl;
+
+ ret = 0;
+ if (ops->pkgsign_new != NULL)
+ ret = (*ops->pkgsign_new)(name, nctx);
+
+ if (ret != 0) {
+ free(nctx);
+ return (ret);
+ }
+
+ *ctx = nctx;
+ return (0);
+}
+
+static bool
+pkgsign_verify_cert(const struct pkgsign_ctx *ctx, int fd, const char *sigfile,
+ const unsigned char *key, int keylen, unsigned char *sig, int siglen)
+{
+
+ return ((*ctx->impl->pi_ops->pkgsign_verify_cert)(ctx, fd, sigfile,
+ key, keylen, sig, siglen));
+}
+
static int
extract_pkg_static(int fd, char *p, int sz)
{
@@ -507,10 +573,12 @@ verify_pubsignature(int fd_pkg, int fd_sig)
{
struct pubkey *pk;
const char *pubkey;
+ struct pkgsign_ctx *sctx;
bool ret;
pk = NULL;
pubkey = NULL;
+ sctx = NULL;
ret = false;
if (config_string(PUBKEY, &pubkey) != 0) {
warnx("No CONFIG_PUBKEY defined");
@@ -522,9 +590,14 @@ verify_pubsignature(int fd_pkg, int fd_sig)
goto cleanup;
}
+ if (pkgsign_new("rsa", &sctx) != 0) {
+ warnx("Failed to fetch 'rsa' signer");
+ goto cleanup;
+ }
+
/* Verify the signature. */
printf("Verifying signature with public key %s... ", pubkey);
- if (rsa_verify_cert(fd_pkg, pubkey, NULL, 0, pk->sig,
+ if (pkgsign_verify_cert(sctx, fd_pkg, pubkey, NULL, 0, pk->sig,
pk->siglen) == false) {
fprintf(stderr, "Signature is not valid\n");
goto cleanup;
@@ -547,6 +620,7 @@ verify_signature(int fd_pkg, int fd_sig)
struct fingerprint_list *trusted, *revoked;
struct fingerprint *fingerprint;
struct sig_cert *sc;
+ struct pkgsign_ctx *sctx;
bool ret;
int trusted_count, revoked_count;
const char *fingerprints;
@@ -555,6 +629,7 @@ verify_signature(int fd_pkg, int fd_sig)
hash = NULL;
sc = NULL;
+ sctx = NULL;
trusted = revoked = NULL;
ret = false;
@@ -618,10 +693,15 @@ verify_signature(int fd_pkg, int fd_sig)
goto cleanup;
}
+ if (pkgsign_new("rsa", &sctx) != 0) {
+ fprintf(stderr, "Failed to fetch 'rsa' signer\n");
+ goto cleanup;
+ }
+
/* Verify the signature. */
printf("Verifying signature with trusted certificate %s... ", sc->name);
- if (rsa_verify_cert(fd_pkg, NULL, sc->cert, sc->certlen, sc->sig,
- sc->siglen) == false) {
+ if (pkgsign_verify_cert(sctx, fd_pkg, NULL, sc->cert, sc->certlen,
+ sc->sig, sc->siglen) == false) {
fprintf(stderr, "Signature is not valid\n");
goto cleanup;
}
diff --git a/usr.sbin/pkg/pkg.h b/usr.sbin/pkg/pkg.h
index faa2be6c8376..2d0dab96a20f 100644
--- a/usr.sbin/pkg/pkg.h
+++ b/usr.sbin/pkg/pkg.h
@@ -30,6 +30,25 @@
#ifndef _PKG_H
#define _PKG_H
+#include <stdbool.h>
+
+struct pkgsign_ctx {
+ const struct pkgsign_impl *impl;
+};
+
+/* Tentatively won't be needing to free any state, all allocated in the ctx. */
+typedef int pkgsign_new_cb(const char *, struct pkgsign_ctx *);
+typedef bool pkgsign_verify_cert_cb(const struct pkgsign_ctx *, int,
+ const char *, const unsigned char *, int, unsigned char *, int);
+
+struct pkgsign_ops {
+ size_t pkgsign_ctx_size;
+ pkgsign_new_cb *pkgsign_new;
+ pkgsign_verify_cert_cb *pkgsign_verify_cert;
+};
+
+extern const struct pkgsign_ops pkgsign_rsa;
+
struct sig_cert {
char *name;
unsigned char *sig;
@@ -44,9 +63,6 @@ struct pubkey {
int siglen;
};
-bool rsa_verify_cert(int, const char *, const unsigned char *, int,
- unsigned char *, int);
-
char *pkg_read_fd(int fd, size_t *osz);
#endif /* _PKG_H */
diff --git a/usr.sbin/pkg/rsa.c b/usr.sbin/pkg/rsa.c
index afc446a6ad06..b6345cdcecb8 100644
--- a/usr.sbin/pkg/rsa.c
+++ b/usr.sbin/pkg/rsa.c
@@ -77,9 +77,10 @@ load_public_key_buf(const unsigned char *cert, int certlen)
return (pkey);
}
-bool
-rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key,
- int keylen, unsigned char *sig, int siglen)
+static bool
+rsa_verify_cert(const struct pkgsign_ctx *ctx __unused, int fd,
+ const char *sigfile, const unsigned char *key, int keylen,
+ unsigned char *sig, int siglen)
{
EVP_MD_CTX *mdctx;
EVP_PKEY *pkey;
@@ -153,3 +154,7 @@ cleanup:
return (ret);
}
+
+const struct pkgsign_ops pkgsign_rsa = {
+ .pkgsign_verify_cert = rsa_verify_cert,
+};