Skip to content

Commit

Permalink
refactor: cleanup verifier demo
Browse files Browse the repository at this point in the history
  • Loading branch information
natesales committed Jan 16, 2025
1 parent a65e748 commit 8e587c8
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 97 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ https://tinfoilanalytics.github.io/verifier

```bash
go run cmd/main.go \
-u https://inference-enclave.tinfoil.sh/.well-known/tinfoil-attestation \
-e inference-enclave.tinfoil.sh \
-r tinfoilanalytics/nitro-enclave-build-demo
```
94 changes: 18 additions & 76 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,54 @@ package main

import (
_ "embed"
"encoding/json"
"flag"
"fmt"
"io"
"log"
"net/http"
"regexp"

"github.com/tinfoilanalytics/verifier/pkg/attestation"
"github.com/tinfoilanalytics/verifier/pkg/github"
"github.com/tinfoilanalytics/verifier/pkg/sigstore"
)

var (
attestationDoc = flag.String("u", "", "Attestation document URL")
repo = flag.String("r", "", "Attested repo (e.g. tinfoilanalytics/nitro-private-inference-image)")
enclaveHost = flag.String("e", "", "Enclave hostname")
repo = flag.String("r", "", "Source repo (e.g. tinfoilanalytics/nitro-private-inference-image)")
)

func fetchLatestRelease(repo string) (string, string, error) {
url := "https://api.github.com/repos/" + repo + "/releases/latest"
log.Printf("Fetching latest release for %s", repo)
releaseResponse, err := http.Get(url)
if err != nil {
return "", "", err
}
if releaseResponse.StatusCode != 200 {
return "", "", fmt.Errorf("failed to fetch latest release: %s", releaseResponse.Status)
}

var responseJSON struct {
TagName string `json:"tag_name"`
Body string `json:"body"`
}
if err := json.NewDecoder(releaseResponse.Body).Decode(&responseJSON); err != nil {
return "", "", err
}

eifRegex := regexp.MustCompile(`EIF hash: ([a-fA-F0-9]{64})`)
eifHash := eifRegex.FindStringSubmatch(responseJSON.Body)[1]

return responseJSON.TagName, eifHash, nil
}

func gitHubAttestation(digest string) ([]byte, error) {
url := "https://api.github.com/repos/" + *repo + "/attestations/sha256:" + digest
log.Printf("Fetching sigstore bundle from %s for EIF %s", *repo, digest)
bundleResponse, err := http.Get(url)
if err != nil {
return nil, err
}
if bundleResponse.StatusCode != 200 {
return nil, fmt.Errorf("failed to fetch sigstore bundle: %s", bundleResponse.Status)
}

var responseJSON struct {
Attestations []struct {
Bundle json.RawMessage `json:"bundle"`
} `json:"attestations"`
}
if err := json.NewDecoder(bundleResponse.Body).Decode(&responseJSON); err != nil {
return nil, err
}

return responseJSON.Attestations[0].Bundle, nil
}

func main() {
flag.Parse()

if *repo == "" || *enclaveHost == "" {
log.Fatal("Missing required arguments")
}

var codeMeasurements, enclaveMeasurements *attestation.Measurement

latestTag, eifHash, err := fetchLatestRelease(*repo)
latestTag, eifHash, err := github.FetchLatestRelease(*repo)
if err != nil {
log.Fatalf("Failed to fetch latest release: %v", err)
}

log.Printf("Latest release: %s", latestTag)
log.Printf("EIF hash: %s", eifHash)

if *repo == "" {
log.Fatal("Missing repo")
}

bundleBytes, err := gitHubAttestation(eifHash)
bundleBytes, err := github.FetchAttestationBundle(*repo, eifHash)
if err != nil {
panic(err)
log.Fatal(err)
}

sigstoreResponse, err := http.Get("https://tuf-repo-cdn.sigstore.dev/targets/4364d7724c04cc912ce2a6c45ed2610e8d8d1c4dc857fb500292738d4d9c8d2c.trusted_root.json")
if err != nil {
panic(err)
log.Fatal(err)
}
sigstoreRootBytes, err := io.ReadAll(sigstoreResponse.Body)
if err != nil {
panic(err)
log.Fatal(err)
}

log.Println("Verifying code measurements")
codeMeasurements, err = sigstore.VerifyAttestedMeasurements(
codeMeasurements, err = sigstore.VerifyMeasurementAttestation(
sigstoreRootBytes,
bundleBytes,
eifHash,
Expand All @@ -109,24 +59,16 @@ func main() {
log.Fatalf("Failed to verify source measurements: %v", err)
}

if *attestationDoc != "" {
var attDocJSON []byte
var err error
log.Printf("Fetching attestation doc from %s", *attestationDoc)
resp, err := http.Get(*attestationDoc)
if err != nil {
panic(err)
}
defer resp.Body.Close()

attDocJSON, err = io.ReadAll(resp.Body)
if *enclaveHost != "" {
log.Printf("Fetching attestation doc from %s", *enclaveHost)
remoteAttestation, err := attestation.Fetch(*enclaveHost)
if err != nil {
panic(err)
log.Fatal(err)
}

log.Println("Verifying enclave measurements")
var tlsPubkey []byte
enclaveMeasurements, tlsPubkey, err = attestation.VerifyAttestationJSON(attDocJSON)
enclaveMeasurements, tlsPubkey, err = remoteAttestation.Verify()
if err != nil {
log.Fatalf("Failed to parse enclave attestation doc: %v", err)
}
Expand Down
32 changes: 32 additions & 0 deletions pkg/attestation/fetch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package attestation

import (
"encoding/json"
"log"
"net/http"
"net/url"
)

const (
attestationEndpoint = "/.well-known/tinfoil-attestation"
)

// Fetch retrieves the attestation document from a given enclave hostname
func Fetch(host string) (*Document, error) {
var u url.URL
u.Host = host
u.Scheme = "https"
u.Path = attestationEndpoint

resp, err := http.Get(u.String())
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()

var doc Document
if err := json.NewDecoder(resp.Body).Decode(&doc); err != nil {
return nil, err
}
return &doc, nil
}
59 changes: 59 additions & 0 deletions pkg/github/github.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package github

import (
"encoding/json"
"fmt"
"log"
"net/http"
"regexp"
)

// FetchLatestRelease gets the latest release and EIF hash of a repo
func FetchLatestRelease(repo string) (string, string, error) {
url := "https://api.github.com/repos/" + repo + "/releases/latest"
log.Printf("Fetching latest release for %s", repo)
releaseResponse, err := http.Get(url)
if err != nil {
return "", "", err
}
if releaseResponse.StatusCode != 200 {
return "", "", fmt.Errorf("failed to fetch latest release: %s", releaseResponse.Status)
}

var responseJSON struct {
TagName string `json:"tag_name"`
Body string `json:"body"`
}
if err := json.NewDecoder(releaseResponse.Body).Decode(&responseJSON); err != nil {
return "", "", err
}

eifRegex := regexp.MustCompile(`EIF hash: ([a-fA-F0-9]{64})`)
eifHash := eifRegex.FindStringSubmatch(responseJSON.Body)[1]

return responseJSON.TagName, eifHash, nil
}

// FetchAttestationBundle fetches the sigstore bundle from a repo for a given repo and EIF hash
func FetchAttestationBundle(repo, digest string) ([]byte, error) {
url := "https://api.github.com/repos/" + repo + "/attestations/sha256:" + digest
log.Printf("Fetching sigstore bundle from %s for EIF %s", repo, digest)
bundleResponse, err := http.Get(url)
if err != nil {
return nil, err
}
if bundleResponse.StatusCode != 200 {
return nil, fmt.Errorf("failed to fetch sigstore bundle: %s", bundleResponse.Status)
}

var responseJSON struct {
Attestations []struct {
Bundle json.RawMessage `json:"bundle"`
} `json:"attestations"`
}
if err := json.NewDecoder(bundleResponse.Body).Decode(&responseJSON); err != nil {
return nil, err
}

return responseJSON.Attestations[0].Bundle, nil
}
26 changes: 7 additions & 19 deletions pkg/sigstore/sigstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package sigstore
import (
"encoding/hex"
"fmt"
"os"

protobundle "github.com/sigstore/protobuf-specs/gen/pb-go/bundle/v1"
"github.com/sigstore/sigstore-go/pkg/bundle"
"github.com/sigstore/sigstore-go/pkg/root"
Expand All @@ -18,9 +16,9 @@ const (
OidcIssuer = "https://token.actions.githubusercontent.com"
)

// VerifyAttestedMeasurements verifies the attested measurements of an EIF measurement
// VerifyMeasurementAttestation verifies the attested measurements of an EIF measurement
// against a trusted root (Sigstore) and returns the measurement payload contained in the DSSE.
func VerifyAttestedMeasurements(
func VerifyMeasurementAttestation(
trustedRootJSON, bundleJSON []byte,
hexDigest, repo string,
) (*attestation.Measurement, error) {
Expand Down Expand Up @@ -87,22 +85,12 @@ func VerifyAttestedMeasurements(
}
}

// FetchTrustRoot downloads the Sigstore trust root configuration and saves it as a JSON file
func FetchTrustRoot() error {
opts := tuf.DefaultOptions()
client, err := tuf.New(opts)
if err != nil {
return err
}

rootJSON, err := client.GetTarget("trusted_root.json")
// FetchTrustRoot fetches the trust root from the Sigstore TUF repo
func FetchTrustRoot() ([]byte, error) {
client, err := tuf.New(tuf.DefaultOptions())
if err != nil {
return err
}

if err := os.WriteFile("trusted_root.json", rootJSON, 0644); err != nil {
return err
return nil, err
}

return nil
return client.GetTarget("trusted_root.json")
}
2 changes: 1 addition & 1 deletion wasm/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ func verifySigstore() js.Func {
bundleBytes := []byte(args[1].String())
repo := args[2].String()

sigstoreMeasurements, err := sigstore.VerifyAttestedMeasurements(
sigstoreMeasurements, err := sigstore.VerifyMeasurementAttestation(
trustedRootBytes,
bundleBytes,
digest,
Expand Down

0 comments on commit 8e587c8

Please sign in to comment.