Created
September 3, 2022 14:12
-
-
Save bobcallaway/dbb9b13ce71dc92ecdebde36c41f6505 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# used in OpenSSF EU 22 presentation: | |
#!/bin/sh | |
#set -X | |
#doitlive commentecho: true | |
### start second demo | |
#!/bin/sh | |
#set -x | |
#doitlive commentecho: true | |
# Requires yubico-piv-tool, step (https://github.com/smallstep/cli), jq, curl | |
## SETUP | |
# reset yubikey to factory defaults | |
ykman piv reset | |
ykman piv keys generate --algorithm ECCP256 9c pubkey.pem | |
# generate a sBOM* (silly bill of materials) | |
echo "insert dad joke here" > /tmp/sBOM | |
# let's sign the sBOM | |
yubico-piv-tool -a verify-pin --sign -s 9c -H SHA256 -A ECCP256 -i /tmp/sBOM -o /tmp/sBOM.sig | |
# let's upload the information to rekor | |
~/go/bin/rekor-cli upload --pki-format=x509 --artifact /tmp/sBOM --public-key pubkey.pem --signature /tmp/sBOM.sig | |
## FULCIO | |
# use step to get ID token from Fulcio OIDC IdP (note this token only lasts 60 sec - TYPE QUICKLY!) | |
~/go/bin/step oauth --provider=https://oauth2.sigstore.dev/auth --client-id=sigstore --listen localhost:0 --oidc --bare 2>/dev/null > id_token | |
# extract email from ID token | |
~/go/bin/step crypto jwt inspect --insecure < id_token |jq -r .payload.email | tr -d '\n' > /tmp/email | |
# sign email address from inside OIDC token with yubikey | |
yubico-piv-tool -a verify-pin --sign -s 9c -H SHA256 -A ECCP256 -i /tmp/email -o /tmp/email.sig | |
base64 /tmp/email.sig |tr -d '\n' > /tmp/email.sigb64 | |
# submit to fulcio via curl (need to sign email address with private key) | |
curl -s https://fulcio.sigstore.dev/api/v1/signingCert -H "Authorization: Bearer $(cat id_token)" -H "Accept: application/pem-certificate-chain" -H "Content-Type: application/json" -o signingCertChain.pem --data-binary "{ \"publicKey\": { \"algorithm\": \"ecdsa\", \"content\": \"$(base64 pubkey.pem | tr -d '\n')\" }, \"signedEmailAddress\": \"$(base64 /tmp/email.sig|tr -d '\n')\" }" | |
# inspect OIDC ID token | |
step crypto jwt inspect --insecure < id_token | egrep -v "sub|user_id" | |
# inspect signing cert chain | |
openssl crl2pkcs7 -nocrl -certfile signingCertChain.pem | openssl pkcs7 -print_certs -text -noout | |
# verify signed email address using pub key in signing cert | |
openssl x509 -pubkey -noout -in signingCertChain.pem > signingPubKey.pem | |
openssl dgst -sha256 -verify signingPubKey.pem -signature email.sig email | |
diff signingPubKey.pem ec_public.pem || echo "pub key from signing cert does not match generated one" | |
## COSIGN or SWISS-ARMY-KNIFE TOOL | |
# generate & sign artifact and generate detached signature | |
head -c 128 < /dev/urandom > artifact | |
openssl dgst -sha256 -sign ec_private.pem artifact > artifact.sig | |
openssl dgst -sha256 -verify signingPubKey.pem -signature artifact.sig artifact | |
# generate timestamp request | |
openssl ts -query -data artifact.sig -cert -sha256 -no_nonce -out request.tsq | |
# send to Rekor Timestamping authority to make entry into log for this signature | |
# -- note that the index for the timestamp entry in the log is returned as a response HTTP header | |
curl -sSH "Content-Type: application/timestamp-query" --data-binary @request.tsq https://rekor.sigstore.dev/api/v1/timestamp -o response.tsr | |
# fetch timestamping certificate chain for verification | |
curl -sSo ts_chain.pem https://rekor.sigstore.dev/api/v1/timestamp/certchain | |
# verify timestamp response | |
openssl ts -verify -in response.tsr -queryfile request.tsq -CAfile ts_chain.pem | |
# ensure timestamp is during validity period of code signing certificate | |
openssl ts -reply -in response.tsr -text | grep "Time stamp"; openssl crl2pkcs7 -nocrl -certfile signingCertChain.pem | openssl pkcs7 -print_certs -text -noout|grep -A2 -m1 Validity | |
## REKOR | |
# submit signature for & signing cert to rekor | |
curl -s https://rekor.sigstore.dev/api/v1/log/entries -H "Accept: application/json" -H "Content-Type: application/json" -o rekor_output --data-binary " { \"apiVersion\": \"0.0.1\", \"kind\": \"rekord\", \"spec\": { \"signature\": { \"format\": \"x509\", \"content\": \"$(base64 -w0 artifact.sig)\", \"publicKey\": { \"content\": \"$(base64 -w0 signingCertChain.pem)\" } }, \"data\": { \"content\": \"$(base64 -w0 artifact)\" } } }" | |
jq '.[keys[0]].body |= (@base64d|fromjson)' rekor_output | |
# print inclusion proof for entry | |
# curl -s -H "Accept: application/json" https://rekor.sigstore.dev/api/v1/log/entries/$(jq -r -c 'keys[0]' rekor_output) | jq . | |
rekor-cli verify --artifact artifact --signature artifact.sig --public-key signingCertChain.pem --pki-format x509 | |
# delete private key - since all we need to verify signature is stored in Rekor | |
rm -rf ec_private.pem |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment