git: 14cf1cdf9a09 - stable/13 - pkg: pull rsa bits out of pkg.c
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 11 Jan 2025 02:49:01 UTC
The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=14cf1cdf9a099d47b8c80596b462696ebda1c11d commit 14cf1cdf9a099d47b8c80596b462696ebda1c11d 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: pull rsa bits out of pkg.c We'll eventually add a pkgsign abstraction over these similar to how we do in pkg(8), but start by isolating these parts. Reviewed by: bapt, emaste (cherry picked from commit 2629e90dd05fb69d767525f960101d7d055ffae0) --- usr.sbin/pkg/Makefile | 2 +- usr.sbin/pkg/pkg.c | 130 +----------------------------------------- usr.sbin/pkg/pkg.h | 50 ++++++++++++++++ usr.sbin/pkg/rsa.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 130 deletions(-) diff --git a/usr.sbin/pkg/Makefile b/usr.sbin/pkg/Makefile index 3e0e047382ca..af0a4d57ee90 100644 --- a/usr.sbin/pkg/Makefile +++ b/usr.sbin/pkg/Makefile @@ -22,7 +22,7 @@ CONFSNAME_${PKGCONF}= ${PKGCONF:C/\.conf.+$/.conf/} CONFSDIR= /etc/pkg CONFSMODE= 644 PROG= pkg -SRCS= pkg.c dns_utils.c config.c hash.c +SRCS= pkg.c rsa.c dns_utils.c config.c hash.c MAN= pkg.7 CFLAGS+=-I${SRCTOP}/contrib/libucl/include diff --git a/usr.sbin/pkg/pkg.c b/usr.sbin/pkg/pkg.c index 1915893af283..3e5e52751e0d 100644 --- a/usr.sbin/pkg/pkg.c +++ b/usr.sbin/pkg/pkg.c @@ -49,27 +49,12 @@ #include <string.h> #include <ucl.h> -#include <openssl/err.h> -#include <openssl/ssl.h> +#include "pkg.h" #include "dns_utils.h" #include "config.h" #include "hash.h" -struct sig_cert { - char *name; - unsigned char *sig; - int siglen; - unsigned char *cert; - int certlen; - bool trusted; -}; - -struct pubkey { - unsigned char *sig; - int siglen; -}; - typedef enum { HASH_UNKNOWN, HASH_SHA256, @@ -399,119 +384,6 @@ load_fingerprints(const char *path, int *count) return (fingerprints); } -static EVP_PKEY * -load_public_key_file(const char *file) -{ - EVP_PKEY *pkey; - BIO *bp; - char errbuf[1024]; - - bp = BIO_new_file(file, "r"); - if (!bp) - errx(EXIT_FAILURE, "Unable to read %s", file); - - if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) - warnx("ici: %s", ERR_error_string(ERR_get_error(), errbuf)); - - BIO_free(bp); - - return (pkey); -} - -static EVP_PKEY * -load_public_key_buf(const unsigned char *cert, int certlen) -{ - EVP_PKEY *pkey; - BIO *bp; - char errbuf[1024]; - - bp = BIO_new_mem_buf(__DECONST(void *, cert), certlen); - - if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - - BIO_free(bp); - - return (pkey); -} - -static bool -rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key, - int keylen, unsigned char *sig, int siglen) -{ - EVP_MD_CTX *mdctx; - EVP_PKEY *pkey; - char *sha256; - char errbuf[1024]; - bool ret; - - sha256 = NULL; - pkey = NULL; - mdctx = NULL; - ret = false; - - SSL_load_error_strings(); - - /* Compute SHA256 of the package. */ - if (lseek(fd, 0, 0) == -1) { - warn("lseek"); - goto cleanup; - } - if ((sha256 = sha256_fd(fd)) == NULL) { - warnx("Error creating SHA256 hash for package"); - goto cleanup; - } - - if (sigfile != NULL) { - if ((pkey = load_public_key_file(sigfile)) == NULL) { - warnx("Error reading public key"); - goto cleanup; - } - } else { - if ((pkey = load_public_key_buf(key, keylen)) == NULL) { - warnx("Error reading public key"); - goto cleanup; - } - } - - /* Verify signature of the SHA256(pkg) is valid. */ - if ((mdctx = EVP_MD_CTX_create()) == NULL) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - - if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - if (EVP_DigestVerifyUpdate(mdctx, sha256, strlen(sha256)) != 1) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - - if (EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) { - warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); - goto error; - } - - ret = true; - printf("done\n"); - goto cleanup; - -error: - printf("failed\n"); - -cleanup: - free(sha256); - if (pkey) - EVP_PKEY_free(pkey); - if (mdctx) - EVP_MD_CTX_destroy(mdctx); - ERR_free_strings(); - - return (ret); -} - static struct pubkey * read_pubkey(int fd) { diff --git a/usr.sbin/pkg/pkg.h b/usr.sbin/pkg/pkg.h new file mode 100644 index 000000000000..01f69f5a825b --- /dev/null +++ b/usr.sbin/pkg/pkg.h @@ -0,0 +1,50 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2012-2014 Baptiste Daroussin <bapt@FreeBSD.org> + * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _PKG_H +#define _PKG_H + +struct sig_cert { + char *name; + unsigned char *sig; + int siglen; + unsigned char *cert; + int certlen; + bool trusted; +}; + +struct pubkey { + unsigned char *sig; + int siglen; +}; + +bool rsa_verify_cert(int, const char *, const unsigned char *, int, + unsigned char *, int); + +#endif /* _PKG_H */ diff --git a/usr.sbin/pkg/rsa.c b/usr.sbin/pkg/rsa.c new file mode 100644 index 000000000000..afc446a6ad06 --- /dev/null +++ b/usr.sbin/pkg/rsa.c @@ -0,0 +1,155 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2012-2014 Baptiste Daroussin <bapt@FreeBSD.org> + * Copyright (c) 2013 Bryan Drewery <bdrewery@FreeBSD.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/types.h> + +#include <err.h> +#include <stdbool.h> + +#include <openssl/err.h> +#include <openssl/ssl.h> + +#include "pkg.h" + +#include "config.h" +#include "hash.h" + +static EVP_PKEY * +load_public_key_file(const char *file) +{ + EVP_PKEY *pkey; + BIO *bp; + char errbuf[1024]; + + bp = BIO_new_file(file, "r"); + if (!bp) + errx(EXIT_FAILURE, "Unable to read %s", file); + + if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) + warnx("ici: %s", ERR_error_string(ERR_get_error(), errbuf)); + + BIO_free(bp); + + return (pkey); +} + +static EVP_PKEY * +load_public_key_buf(const unsigned char *cert, int certlen) +{ + EVP_PKEY *pkey; + BIO *bp; + char errbuf[1024]; + + bp = BIO_new_mem_buf(__DECONST(void *, cert), certlen); + + if ((pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL)) == NULL) + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + + BIO_free(bp); + + return (pkey); +} + +bool +rsa_verify_cert(int fd, const char *sigfile, const unsigned char *key, + int keylen, unsigned char *sig, int siglen) +{ + EVP_MD_CTX *mdctx; + EVP_PKEY *pkey; + char *sha256; + char errbuf[1024]; + bool ret; + + sha256 = NULL; + pkey = NULL; + mdctx = NULL; + ret = false; + + SSL_load_error_strings(); + + /* Compute SHA256 of the package. */ + if (lseek(fd, 0, 0) == -1) { + warn("lseek"); + goto cleanup; + } + if ((sha256 = sha256_fd(fd)) == NULL) { + warnx("Error creating SHA256 hash for package"); + goto cleanup; + } + + if (sigfile != NULL) { + if ((pkey = load_public_key_file(sigfile)) == NULL) { + warnx("Error reading public key"); + goto cleanup; + } + } else { + if ((pkey = load_public_key_buf(key, keylen)) == NULL) { + warnx("Error reading public key"); + goto cleanup; + } + } + + /* Verify signature of the SHA256(pkg) is valid. */ + if ((mdctx = EVP_MD_CTX_create()) == NULL) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + + if (EVP_DigestVerifyInit(mdctx, NULL, EVP_sha256(), NULL, pkey) != 1) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + if (EVP_DigestVerifyUpdate(mdctx, sha256, strlen(sha256)) != 1) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + + if (EVP_DigestVerifyFinal(mdctx, sig, siglen) != 1) { + warnx("%s", ERR_error_string(ERR_get_error(), errbuf)); + goto error; + } + + ret = true; + printf("done\n"); + goto cleanup; + +error: + printf("failed\n"); + +cleanup: + free(sha256); + if (pkey) + EVP_PKEY_free(pkey); + if (mdctx) + EVP_MD_CTX_destroy(mdctx); + ERR_free_strings(); + + return (ret); +}