Skip to content

Commit

Permalink
Merge pull request #353 from oasisprotocol/kostko/feature/rofl-build-…
Browse files Browse the repository at this point in the history
…verify

feat(cmd/rofl): Add --verify to build to verify enclave identities
  • Loading branch information
kostko authored Jan 28, 2025
2 parents b163971 + c8c3735 commit a668c36
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 1 deletion.
82 changes: 81 additions & 1 deletion cmd/rofl/build/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/base64"
"fmt"
"maps"
"os"

"github.com/spf13/cobra"
Expand All @@ -14,7 +15,9 @@ import (
"github.com/oasisprotocol/oasis-core/go/common/sgx"
"github.com/oasisprotocol/oasis-core/go/common/version"
"github.com/oasisprotocol/oasis-core/go/runtime/bundle"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/client"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"

buildRofl "github.com/oasisprotocol/cli/build/rofl"
"github.com/oasisprotocol/cli/cmd/common"
Expand All @@ -33,6 +36,7 @@ var (
buildMode string
offline bool
doUpdate bool
doVerify bool
deploymentName string

Cmd = &cobra.Command{
Expand All @@ -44,6 +48,10 @@ var (
npa := common.GetNPASelection(cfg)
manifest, deployment := roflCommon.LoadManifestAndSetNPA(cfg, npa, deploymentName, true)

if doVerify && doUpdate {
cobra.CheckErr("only one of --verify and --update-manifest may be passed")
}

fmt.Println("Building a ROFL application...")
fmt.Printf("Deployment: %s\n", deploymentName)
fmt.Printf("Network: %s\n", deployment.Network)
Expand Down Expand Up @@ -147,14 +155,83 @@ var (

runScript(manifest, buildRofl.ScriptBundlePost)

buildEnclaves := make(map[sgx.EnclaveIdentity]struct{})
for _, eid := range eids {
buildEnclaves[*eid] = struct{}{}
}

manifestEnclaves := make(map[sgx.EnclaveIdentity]struct{})
for _, eid := range deployment.Policy.Enclaves {
manifestEnclaves[eid] = struct{}{}
}

// Perform verification when requested.
if doVerify {
showIdentityDiff := func(build, other map[sgx.EnclaveIdentity]struct{}, otherName string) {
fmt.Println("Built enclave identities:")
for enclaveID := range build {
data, _ := enclaveID.MarshalText()
fmt.Printf(" - %s\n", string(data))
}

fmt.Printf("%s enclave identities:\n", otherName)
for enclaveID := range other {
data, _ := enclaveID.MarshalText()
fmt.Printf(" - %s\n", string(data))
}
}

if !maps.Equal(buildEnclaves, manifestEnclaves) {
fmt.Println("Built enclave identities DIFFER from manifest enclave identities!")
showIdentityDiff(buildEnclaves, manifestEnclaves, "Manifest")
cobra.CheckErr(fmt.Errorf("enclave identity verification failed"))
}

fmt.Println("Built enclave identities MATCH manifest enclave identities.")

// When not in offline mode, also verify on-chain enclave identities.
if !offline {
var conn connection.Connection
ctx := context.Background()
conn, err = connection.Connect(ctx, npa.Network)
cobra.CheckErr(err)

var appID rofl.AppID
_ = appID.UnmarshalText([]byte(deployment.AppID)) // Already verified.

var appCfg *rofl.AppConfig
appCfg, err = conn.Runtime(npa.ParaTime).ROFL.App(ctx, client.RoundLatest, appID)
cobra.CheckErr(err)

cfgEnclaves := make(map[sgx.EnclaveIdentity]struct{})
for _, eid := range appCfg.Policy.Enclaves {
cfgEnclaves[eid] = struct{}{}
}

if !maps.Equal(manifestEnclaves, cfgEnclaves) {
fmt.Println("Built enclave identities DIFFER from on-chain enclave identities!")
showIdentityDiff(buildEnclaves, cfgEnclaves, "On-chain")
cobra.CheckErr(fmt.Errorf("enclave identity verification failed"))
}

fmt.Println("Built enclave identities MATCH on-chain enclave identities.")
}
return
}

// Override the update manifest flag in case the policy does not exist.
if deployment.Policy == nil {
doUpdate = false
}

switch doUpdate {
case false:
// Ask the user to update the manifest manually.
// Ask the user to update the manifest manually (if the manifest has changed).
if maps.Equal(buildEnclaves, manifestEnclaves) {
fmt.Println("Built enclave identities already match manifest enclave identities.")
break
}

fmt.Println("Update the manifest with the following identities to use the new app:")
fmt.Println()
fmt.Printf("deployments:\n")
Expand All @@ -177,6 +254,8 @@ var (
if err = manifest.Save(); err != nil {
cobra.CheckErr(fmt.Errorf("failed to update manifest: %w", err))
}

fmt.Printf("Run `oasis rofl update` to update your ROFL app's on-chain configuration.\n")
}
},
}
Expand Down Expand Up @@ -258,6 +337,7 @@ func init() {
buildFlags.BoolVar(&offline, "offline", false, "do not perform any operations requiring network access")
buildFlags.StringVar(&outputFn, "output", "", "output bundle filename")
buildFlags.BoolVar(&doUpdate, "update-manifest", false, "automatically update the manifest")
buildFlags.BoolVar(&doVerify, "verify", false, "verify build against manifest and on-chain state")
buildFlags.StringVar(&deploymentName, "deployment", buildRofl.DefaultDeploymentName, "deployment name")

Cmd.Flags().AddFlagSet(buildFlags)
Expand Down
4 changes: 4 additions & 0 deletions cmd/rofl/mgmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ var (
}
}
}

fmt.Printf("Run `oasis rofl build --update-manifest` to build your ROFL app.\n")
},
}

Expand Down Expand Up @@ -577,6 +579,8 @@ var (
if err = manifest.Save(); err != nil {
cobra.CheckErr(fmt.Errorf("failed to update manifest: %w", err))
}

fmt.Printf("Run `oasis rofl update` to update your ROFL app's on-chain configuration.\n")
},
}

Expand Down

0 comments on commit a668c36

Please sign in to comment.