Skip to content

Commit

Permalink
Rust Binary Checks SHA256 (#449)
Browse files Browse the repository at this point in the history
* add shasum check of init payload
* fix path to rust injector in workflow
* update zarf-ijector to version that checks sha
* switch to govcloud KMS
* update rust injector cargo version
* add cosign annotations
* include github url in release-engineer annotation

Co-authored-by: Jeff McCoy <[email protected]>
  • Loading branch information
YrrepNoj and jeff-mccoy authored Apr 20, 2022
1 parent d806d8b commit 6bf8992
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 22 deletions.
18 changes: 13 additions & 5 deletions .github/workflows/build-rust-injector.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
name: Build Rust Binary

env:
zarfInjectorPath: 'src/injector/stage1/target/x86_64-unknown-linux-musl/release/zarf-injector'

on:
workflow_dispatch:
inputs:
Expand Down Expand Up @@ -29,13 +33,13 @@ jobs:
args: cargo build --target x86_64-unknown-linux-musl --release --manifest-path src/injector/stage1/Cargo.toml

- name: "Strip The Binary Down"
run: sudo strip src/injector/stage1/target/x86_64-unknown-linux-musl/release/zarf-injector
run: sudo strip ${{ env.zarfInjectorPath }}

- name: "Upload Rust Binary"
uses: actions/upload-artifact@v2
with:
name: zarf-injector
path: src/injector/stage1/target/x86_64-unknown-linux-musl/release/zarf-injector
path: ${{ env.zarfInjectorPath }}

- name: Login to Docker Hub
uses: docker/login-action@v1
Expand All @@ -44,9 +48,13 @@ jobs:
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: "Upload Binary To DockerHub"
run: cosign upload blob -f zarf-injector defenseunicorns/zarf-injector:${{ github.event.inputs.versionTag }}
run: cosign upload blob -f ${{ env.zarfInjectorPath }} defenseunicorns/zarf-injector:${{ github.event.inputs.versionTag }}

- name: "Sign the binary"
run: cosign sign --key ${{ secrets.COSIGN_SIGNING_KEY }} defenseunicorns/zarf-injector:${{ github.event.inputs.versionTag }}
run: cosign sign --key awskms:///${{ secrets.COSIGN_AWS_KMS_KEY }} -a release-engineer=https://github.com/${{ github.actor }} -a version=${{ github.event.inputs.versionTag }} defenseunicorns/zarf-injector:${{ github.event.inputs.versionTag }}
env:
COSIGN_EXPERIMENTAL: 1
COSIGN_EXPERIMENTAL: 1
AWS_REGION: ${{ secrets.COSIGN_AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.COSIGN_AWS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.COSIGN_AWS_ACCESS_KEY }}

16 changes: 13 additions & 3 deletions cosign.pub
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEkK3glLLNDKX7ny8wRzrh/G04huzV
QaiLEEMlVHpdzfwqkspAWxzbcUaTj5SPyaLT5TLDEXiOt4AS4D/Q3twxfw==
-----END PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9u472y/wY0tjIiR2T6rY
zOG1q4qwx5ZdmnoGsiG0Zc3rYo2DMiuKciG0MI4opCf4IID7kfYOD4aWILymwFID
xW0L6pEbxknHRQacWZSf/qfA+aAcjbKOY3ZWU8/uLJJeq37Y4OLc17ThJ7ZOj1Yf
Uvj81Uz9ZWVW7kYY31vWCruJh4VxZLsUAmFc6CsQUtzSGordLhh1b1rDP6ZRAaIP
mQnniULogwIBqnUTkIVwxiRYG+V2a3IC5vqlBLQRQ3UOWQ9mgZcfcXuTA6Fh8bwO
2lG768UfI1RBYioXAgXbPwXK+kM3Idvjcr+X2F3VpYWhHTscMIQF0ERzK7BkRqRI
x9l/RRm5lP+9a1kt6giYtvX2OqEsWaG3lTen3ocwblaHRlmqnaiVBtAnVny6QDHX
9p1HPMD/NjWjZucxWMjtdL5FZxBywbJVlxhe7sFByMoBZYhea9vGGSn2M2Q9kPiq
Bgl6bKZdeYIhaKQ7wrNkS6YVHMIqqpCIUI6/YGYwnu0hodbjR0yA2LFx4TgFZAuY
uGEiRP4Oi7WEOPkjRjP7kPXGpEBB7ulZ/Wohq1B6pB1Odo8WlfJRAek319F2aqqh
J1c3YdZ/w3EvCLKd+Inp1UNbamb79UN6jtwhqwKw72YbZh/yP0rim49lQ++umwPX
JWqG8iY/UzGB/3ch4/Wb09UCAwEAAQ==
-----END PUBLIC KEY-----
2 changes: 1 addition & 1 deletion packages/zarf-injector/zarf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ components:
cosignKeyPath: ../../cosign.pub
files:
# Rust Injector Binary
- source: sget://defenseunicorns/zarf-injector:0.1.0
- source: sget://defenseunicorns/zarf-injector:0.4.3
target: "###ZARF_TEMP###/zarf-injector"
executable: true
# Go Registry Binary
Expand Down
7 changes: 7 additions & 0 deletions src/injector/stage1/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/injector/stage1/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ panic = "abort"

[package]
name = "zarf-injector"
version = "0.1.0"
version = "0.4.3"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand All @@ -16,3 +16,4 @@ glob = "0.3.0"
flate2 = "1.0.22"
tar = "0.4.38"
sha2 = "0.10.2"
hex = "0.4.3"
5 changes: 3 additions & 2 deletions src/injector/stage1/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
use tar::Archive;
use hex::ToHex;

// Inspired by https://medium.com/@nlauchande/rust-coding-up-a-simple-concatenate-files-tool-and-first-impressions-a8cbe680e887

Expand Down Expand Up @@ -69,8 +70,8 @@ fn main() {

// read hash digest and consume hasher
let result = hasher.finalize();

assert_eq!(result[..], sha_sum.as_bytes()[..]);
let result_string = result.encode_hex::<String>();
assert_eq!(*sha_sum, result_string);
}

let tar = GzDecoder::new(&contents[..]);
Expand Down
27 changes: 17 additions & 10 deletions src/internal/packager/injector.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package packager

import (
"crypto/sha256"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -31,6 +32,7 @@ func runInjectionMadness(tempPath tempPaths) {
var images []string
var envVars []corev1.EnvVar
var payloadConfigmaps []string
var sha256sum string

// Try to create the zarf namespace
spinner.Updatef("Creating the Zarf namespace")
Expand Down Expand Up @@ -62,7 +64,7 @@ func runInjectionMadness(tempPath tempPaths) {
}

spinner.Updatef("Loading the seed registry configmaps")
if payloadConfigmaps, err = createPayloadConfigmaps(tempPath, spinner); err != nil {
if payloadConfigmaps, sha256sum, err = createPayloadConfigmaps(tempPath, spinner); err != nil {
message.Fatal(err, "Unable to generate the injector payload configmaps")
}

Expand All @@ -82,7 +84,7 @@ func runInjectionMadness(tempPath tempPaths) {
_ = k8s.DeletePod(k8s.ZarfNamespace, "injector")

// Update the podspec image path
pod := buildInjectionPod(image, envVars, payloadConfigmaps)
pod := buildInjectionPod(image, envVars, payloadConfigmaps, sha256sum)

// Create the pod in the cluster
pod, err = k8s.CreatePod(pod)
Expand All @@ -103,13 +105,14 @@ func runInjectionMadness(tempPath tempPaths) {
spinner.Fatalf(nil, "Unable to perform the injection")
}

func createPayloadConfigmaps(tempPath tempPaths, spinner *message.Spinner) ([]string, error) {
func createPayloadConfigmaps(tempPath tempPaths, spinner *message.Spinner) ([]string, string, error) {
message.Debugf("packager.tryInjectorPayloadDeploy(%v)", tempPath)
var (
err error
tarFile []byte
chunks [][]byte
configMaps []string
sha256sum string
)

// Chunk size has to accomdate base64 encoding & etcd 1MB limit
Expand All @@ -125,14 +128,19 @@ func createPayloadConfigmaps(tempPath tempPaths, spinner *message.Spinner) ([]st
spinner.Updatef("Creating the seed registry archive to send to the cluster")
// Create a tar archive of the injector payload
if err = archiver.Archive(tarFileList, tarPath); err != nil {
return configMaps, err
return configMaps, "", err
}

archiver.Archive(tarFileList, "/home/user/payload.tgz")

// Open the created archive for io.Copy
if tarFile, err = ioutil.ReadFile(tarPath); err != nil {
return configMaps, err
return configMaps, "", err
}

//Calculate the sha256sum of the tarFile before we split it up
sha256sum = fmt.Sprintf("%x", sha256.Sum256(tarFile))

spinner.Updatef("Splitting the archive into binary configmaps")
// Loop over the tarball breaking it into chunks based on the payloadChunkSize
for {
Expand Down Expand Up @@ -165,7 +173,7 @@ func createPayloadConfigmaps(tempPath tempPaths, spinner *message.Spinner) ([]st

// Attempt to create the configmap in the cluster
if _, err = k8s.ReplaceConfigmap(k8s.ZarfNamespace, fileName, labels, configData); err != nil {
return configMaps, err
return configMaps, "", err
}

// Add the configmap to the configmaps slice for later usage in the pod
Expand All @@ -175,7 +183,7 @@ func createPayloadConfigmaps(tempPath tempPaths, spinner *message.Spinner) ([]st
time.Sleep(100 * time.Millisecond)
}

return configMaps, nil
return configMaps, sha256sum, nil
}

func hasSeedImages(spinner *message.Spinner) bool {
Expand Down Expand Up @@ -295,21 +303,20 @@ func buildEnvVars(tempPath tempPaths) ([]corev1.EnvVar, error) {
}

// buildInjectionPod return a pod for injection with the appropriate containers to perform the injection
func buildInjectionPod(image string, envVars []corev1.EnvVar, payloadConfigmaps []string) *corev1.Pod {
func buildInjectionPod(image string, envVars []corev1.EnvVar, payloadConfigmaps []string, payloadShasum string) *corev1.Pod {
pod := k8s.GeneratePod("injector", k8s.ZarfNamespace)
executeMode := int32(0777)
seedImage := config.GetSeedImage()

pod.Labels["app"] = "zarf-injector"

pod.Spec.RestartPolicy = corev1.RestartPolicyNever

pod.Spec.InitContainers = []corev1.Container{
{
Name: "init-injector",
Image: image,
WorkingDir: "/zarf-stage1",
Command: []string{"/zarf-stage1/zarf-injector"},
Command: []string{"/zarf-stage1/zarf-injector", payloadShasum},

VolumeMounts: []corev1.VolumeMount{
{
Expand Down

0 comments on commit 6bf8992

Please sign in to comment.