From nobody Wed Jan 01 21:11:40 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YNjFS5Z3sz5jCrY; Wed, 01 Jan 2025 21:11:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YNjFS3wnjz4k5F; Wed, 1 Jan 2025 21:11:40 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735765900; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BVu8xYGBgDENB5U7pY9YUvrvvWL1zfwgIAaMxyOfgQc=; b=Y0VZHTsvh4yck0ao32NVJVIbvkFtfyxnI3cLgqpREWJ0xU5ZE/5MtOUfmVPjyzzUttMNix NekZYt43fhTeArZHLbFHJ3+v/Hzw9ebGzIkcyXF/5Bceo01laBj2iOeGXk75V7gmUTwl3S jGpw5ci2cB+RwY9fbuCFJbpwdMpqgN27oFaMxRNQ+CmAhXPfzbO1mPhPtvlHZjgTZRmJgB IqTvLmY4dIREvmkTqHtZXJo7htV6zNRmcM2H04IQ33CHWP9+2+zgIw+5NzKH12R+3+uIhG ZcjpR5dWd9h+baYxrTgPe1Uj0o5yy56r8AKa35P0txZavyzfzxj+IPpAe4hDyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1735765900; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BVu8xYGBgDENB5U7pY9YUvrvvWL1zfwgIAaMxyOfgQc=; b=EPmkzwGpHmDoxHq65ZfwyqNRYO7M86rZL9dKiKdA/IDkpq9+6L5cg9OeYDkCpzuqUrBu7L KM5oVP+cOgP+2QDGPJaHNLPtDKPgsnF4jJJxkWxcwaqBtipM7xXXgGsJHcfuo6BM2KXpF1 3drH4Q9kBswvhjLrCnwqLcSLyOwgAq8BThB/zmRjiCaAH/dRLzjbiIwiXVk5Z/AgAB49uZ R3Sb0zPTCmh+jjw/EJk93FNBlrcgOVOGNzQwD/w+TiUEkDzu/Lr6s+qPMCKfxh0z/UvP6x CzEDniXEVYzMyY/OMEdhWfunJKqfMFAc9AOllaXXKvdCfZlzIxtqs0ExxwExeA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1735765900; a=rsa-sha256; cv=none; b=IstnByF/wKsn2kvAT6qI1t6gAz+iR2drSjbdOxVgA60t3W7YDODyBv7q5comLriRyzyoxQ sprwO20EpbaycpIrTKdZfQi170f6wgdNku/b85IjLME/wz2rxyrOF/ALxPpaAVdS/khl95 qSl0cZ5nmS82yk4V0kFMN8DRXt7u1dQnET6VtJ6O7DLobRRNKJgvfnqgOljqGjxPr3i9j+ /LzjZICDtb37LyEWnlrDRSZuUEQUq/RH5YvHqtW7sR0Kuq9g08rCI2ygUcBsqjGrWIm/DJ 6dcYVu+qYHYl3dnW7CC/JMa7iM96MasMjb44Z14nBcdhl01jsMgP8fCNgpRjww== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YNjFS3VR5zgVQ; Wed, 1 Jan 2025 21:11:40 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 501LBeOt080023; Wed, 1 Jan 2025 21:11:40 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 501LBeLI080020; Wed, 1 Jan 2025 21:11:40 GMT (envelope-from git) Date: Wed, 1 Jan 2025 21:11:40 GMT Message-Id: <202501012111.501LBeLI080020@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kyle Evans Subject: git: 2629e90dd05f - main - pkg: pull rsa bits out of pkg.c List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2629e90dd05fb69d767525f960101d7d055ffae0 Auto-Submitted: auto-generated The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=2629e90dd05fb69d767525f960101d7d055ffae0 commit 2629e90dd05fb69d767525f960101d7d055ffae0 Author: Kyle Evans AuthorDate: 2025-01-01 21:10:27 +0000 Commit: Kyle Evans CommitDate: 2025-01-01 21:11:22 +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 Differential Revision: https://reviews.freebsd.org/D48105 --- 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 27d607380006..c7ea68973041 100644 --- a/usr.sbin/pkg/Makefile +++ b/usr.sbin/pkg/Makefile @@ -21,7 +21,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 6138ca37e439..24a4f6516307 100644 --- a/usr.sbin/pkg/pkg.c +++ b/usr.sbin/pkg/pkg.c @@ -48,27 +48,12 @@ #include #include -#include -#include +#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, @@ -400,119 +385,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 + * Copyright (c) 2013 Bryan Drewery + * 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 + * Copyright (c) 2013 Bryan Drewery + * 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 +#include + +#include +#include + +#include +#include + +#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); +}