Created
September 3, 2022 14:12
Revisions
-
bobcallaway created this gist
Sep 3, 2022 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,82 @@ # 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