Merge branch 'issues/7'

* issues/7:
  Add documentation on iPXE code signing
  Add copying of codesigning key pair
  Use and validate local codesigning key pair
  Add script to create new codesigning key pair
This commit is contained in:
David Runge 2021-05-16 13:59:28 +02:00
commit 34ad9f8756
No known key found for this signature in database
GPG Key ID: 7258734B41C31549
4 changed files with 144 additions and 9 deletions

View File

@ -25,6 +25,13 @@ shellcheck:
build:
after_script:
- mv -- output/metrics.txt .
before_script:
- |
if [[ -n "${SECRET_CODESIGNING_KEY_FILE}" && -n "${SECRET_CODESIGNING_CERT_FILE}" ]]; then
cp -- "${SECRET_CODESIGNING_CERT_FILE}" codesign.crt
cp -- "${SECRET_CODESIGNING_KEY_FILE}" codesign.key
fi
- pacman -Syu --needed --noconfirm qemu-headless
except:
- master@archlinux/releng
- schedules@archlinux/releng
@ -36,6 +43,13 @@ build:
secure_build:
after_script:
- mv -- "output/metrics.txt" .
before_script:
- |
if [[ -n "${SECRET_CODESIGNING_KEY_FILE}" && -n "${SECRET_CODESIGNING_CERT_FILE}" ]]; then
cp -- "${SECRET_CODESIGNING_CERT_FILE}" codesign.crt
cp -- "${SECRET_CODESIGNING_KEY_FILE}" codesign.key
fi
- pacman -Syu --needed --noconfirm qemu-headless
extends: .build
only:
- master@archlinux/releng

View File

@ -11,7 +11,7 @@
# * openssl
# * zsync
set -euo pipefail
set -eu
shopt -s extglob
readonly orig_pwd="${PWD}"
@ -208,6 +208,39 @@ create_ephemeral_codesigning_key() {
print_section_end "ephemeral_codesigning_key"
}
select_codesigning_key() {
local _codesigning_cert="${orig_pwd}/codesign.crt"
local _codesigning_key="${orig_pwd}/codesign.key"
if [[ -f "${_codesigning_key}" && -f "${_codesigning_cert}" ]]; then
print_section_start "select_codesigning_key" "Select codesigning key"
printf "Using local codesigning key pair!\n%s %s\n" "${_codesigning_cert}" "${_codesigning_key}"
codesigning_cert="${_codesigning_cert}"
codesigning_key="${_codesigning_key}"
print_section_end "select_codesigning_key"
else
create_ephemeral_codesigning_key
fi
}
check_codesigning_cert_validity() {
local _now _valid_until _ninety_days=7776000
printf -v _now "%(%s)T" '-1'
_valid_until="$(openssl x509 -noout -dates -in "${codesigning_cert}"| grep -Po 'notAfter=\K.*$' | date +%s -f -)"
print_section_start "check_codesigning_cert" "Check codesigning cert"
if (( ("$_now" + "$_ninety_days") > "$_valid_until" )); then
printf "The codesigning certificate is only valid for less than 90 days!\n" >&2
exit 1
fi
print_section_end "check_codesigning_cert"
}
copy_ipxe_binaries() {
# copy ipxe binaries to output dir
local _ipxe_base="/usr/share/ipxe"
@ -223,9 +256,6 @@ copy_ipxe_binaries() {
run_mkarchiso() {
# run mkarchiso
create_ephemeral_pgp_key
create_ephemeral_codesigning_key
print_section_start "mkarchiso" "Running mkarchiso"
mkdir -p "${output}/" "${tmpdir}/"
@ -247,16 +277,20 @@ run_mkarchiso() {
print_section_start "ownership" "Setting ownership on output"
if [[ -n "${SUDO_UID:-}" ]] && [[ -n "${SUDO_GID:-}" ]]; then
if [[ -n "${SUDO_UID:-}" && -n "${SUDO_GID:-}" ]]; then
chown -Rv "${SUDO_UID}:${SUDO_GID}" -- "${output}"
fi
print_section_end "ownership"
}
trap cleanup EXIT
if (( EUID != 0 )); then
printf "%s must be run as root.\n" "${app_name}" >&2
exit 1
fi
trap cleanup EXIT
create_ephemeral_pgp_key
select_codesigning_key
check_codesigning_cert_validity
run_mkarchiso

View File

@ -2,10 +2,47 @@
releng
======
This repository offers tools to create release artifacts for Arch Linux.
This repository is used to create release artifacts for Arch Linux.
Code Signing
============
``mkarchiso`` (`archiso <https://gitlab.archlinux.org/archlinux/archiso>`_) offers the export of server-side artifacts,
that allow for `iPXE <https://ipxe.org>`_ to use them. The artifacts can optionally be codesigned which can establish a
trust path between a client and the server-side files.
How to establish a code signing authority is explained in the `iPXE upstream documentation <https://ipxe.org/crypto>`_.
The server-side artifacts are signed using a codesigning certificate and key pair. The codesigning certificate is then
embedded in the iPXE binary and is used during boot to validate the codesigning signature when downloading the file.
Additionally, CA certificates are embedded in the iPXE binary to validate the TLS connection over which the data is
transmitted.
.. code:: sh
iPXE binary Server
xxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx
x CA cert(s) x =====> x Transport Layer Security x
xxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx
x Codesigning Certificate x =====> x Codesigning Signature x
xxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxx
Create a new Code Signing Key Pair
----------------------------------
1. Create a new code signing key pair using ``codesigning/create_codesigning_key_pair.sh``.
2. Embed the codesigning certificate in the binaries generated by `the ipxe
package <https://archlinux.org/packages/community/x86_64/ipxe/>`_ and release a new version of the package.
3. Add the codesigning certificate and key as `variables of type File
<https://docs.gitlab.com/ee/ci/variables/#project-cicd-variables>`_ to this repository
(``SECRET_CODESIGNING_CERT_FILE`` and ``SECRET_CODESIGNING_KEY_FILE``, respectively), so that they can be accessed
during build.
4. Build a new release with the respective artifacts being signed with the new codesigning key and make sure that the
release contains the iPXE binaries from the updated package (embedding the new codesigning certificate)
5. Once all official releases using the previous codesigning key pair have been removed, the previous codesigning
certificate can be removed from the ipxe package.
License
=======
Releng is licensed under the terms of the **GPL-3.0-or-later** (see `LICENSE
<LICENSE>`_).
Releng is licensed under the terms of the **GPL-3.0-or-later** (see `LICENSE <LICENSE>`_).

View File

@ -0,0 +1,50 @@
#!/usr/bin/env bash
#
# SPDX-License-Identifier: GPL-3.0-or-later
#
# This script creates a codesigning key pair and copies the resulting certificate and key to the directory specified by
# the first argument to this script (else $PWD)
set -euo pipefail
temp_dir="$(mktemp -d --tmpdir codesigning.XXXXXXXXXXXXX)"
readonly codesigning_subj="/C=DE/ST=Berlin/L=Berlin/O=Arch Linux/OU=Release Engineering/CN=archlinux.org"
readonly codesigning_cert="${temp_dir}/codesign.crt"
readonly codesigning_key="${temp_dir}/codesign.key"
readonly codesigning_conf="${temp_dir}/openssl.cnf"
readonly output_dir="${1:-$PWD}"
cleanup() {
rm -fr "${temp_dir}"
}
generate_ca() {
cp -- /etc/ssl/openssl.cnf "${codesigning_conf}"
printf "\n[codesigning]\nkeyUsage=digitalSignature\nextendedKeyUsage=codeSigning\n" >> "${codesigning_conf}"
openssl req \
-newkey rsa:4096 \
-keyout "${codesigning_key}" \
-nodes \
-sha256 \
-x509 \
-days 365 \
-out "${codesigning_cert}" \
-config "${codesigning_conf}" \
-subj "${codesigning_subj}" \
-extensions codesigning
}
copy_certs() {
local _output_dir
if [[ -d "${output_dir}" ]]; then
_output_dir="${output_dir}"
else
_output_dir="${PWD}"
fi
cp -- "${codesigning_cert}" "${codesigning_key}" "${_output_dir}"
}
trap cleanup EXIT
generate_ca
copy_certs