Skip to content

Commit c8c3735

Browse files
committed
feat(cmd/rofl): Add --verify to build to verify enclave identities
1 parent b163971 commit c8c3735

2 files changed

Lines changed: 85 additions & 1 deletion

File tree

cmd/rofl/build/build.go

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/base64"
66
"fmt"
7+
"maps"
78
"os"
89

910
"github.com/spf13/cobra"
@@ -14,7 +15,9 @@ import (
1415
"github.com/oasisprotocol/oasis-core/go/common/sgx"
1516
"github.com/oasisprotocol/oasis-core/go/common/version"
1617
"github.com/oasisprotocol/oasis-core/go/runtime/bundle"
18+
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/client"
1719
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/connection"
20+
"github.com/oasisprotocol/oasis-sdk/client-sdk/go/modules/rofl"
1821

1922
buildRofl "github.com/oasisprotocol/cli/build/rofl"
2023
"github.com/oasisprotocol/cli/cmd/common"
@@ -33,6 +36,7 @@ var (
3336
buildMode string
3437
offline bool
3538
doUpdate bool
39+
doVerify bool
3640
deploymentName string
3741

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

51+
if doVerify && doUpdate {
52+
cobra.CheckErr("only one of --verify and --update-manifest may be passed")
53+
}
54+
4755
fmt.Println("Building a ROFL application...")
4856
fmt.Printf("Deployment: %s\n", deploymentName)
4957
fmt.Printf("Network: %s\n", deployment.Network)
@@ -147,14 +155,83 @@ var (
147155

148156
runScript(manifest, buildRofl.ScriptBundlePost)
149157

158+
buildEnclaves := make(map[sgx.EnclaveIdentity]struct{})
159+
for _, eid := range eids {
160+
buildEnclaves[*eid] = struct{}{}
161+
}
162+
163+
manifestEnclaves := make(map[sgx.EnclaveIdentity]struct{})
164+
for _, eid := range deployment.Policy.Enclaves {
165+
manifestEnclaves[eid] = struct{}{}
166+
}
167+
168+
// Perform verification when requested.
169+
if doVerify {
170+
showIdentityDiff := func(build, other map[sgx.EnclaveIdentity]struct{}, otherName string) {
171+
fmt.Println("Built enclave identities:")
172+
for enclaveID := range build {
173+
data, _ := enclaveID.MarshalText()
174+
fmt.Printf(" - %s\n", string(data))
175+
}
176+
177+
fmt.Printf("%s enclave identities:\n", otherName)
178+
for enclaveID := range other {
179+
data, _ := enclaveID.MarshalText()
180+
fmt.Printf(" - %s\n", string(data))
181+
}
182+
}
183+
184+
if !maps.Equal(buildEnclaves, manifestEnclaves) {
185+
fmt.Println("Built enclave identities DIFFER from manifest enclave identities!")
186+
showIdentityDiff(buildEnclaves, manifestEnclaves, "Manifest")
187+
cobra.CheckErr(fmt.Errorf("enclave identity verification failed"))
188+
}
189+
190+
fmt.Println("Built enclave identities MATCH manifest enclave identities.")
191+
192+
// When not in offline mode, also verify on-chain enclave identities.
193+
if !offline {
194+
var conn connection.Connection
195+
ctx := context.Background()
196+
conn, err = connection.Connect(ctx, npa.Network)
197+
cobra.CheckErr(err)
198+
199+
var appID rofl.AppID
200+
_ = appID.UnmarshalText([]byte(deployment.AppID)) // Already verified.
201+
202+
var appCfg *rofl.AppConfig
203+
appCfg, err = conn.Runtime(npa.ParaTime).ROFL.App(ctx, client.RoundLatest, appID)
204+
cobra.CheckErr(err)
205+
206+
cfgEnclaves := make(map[sgx.EnclaveIdentity]struct{})
207+
for _, eid := range appCfg.Policy.Enclaves {
208+
cfgEnclaves[eid] = struct{}{}
209+
}
210+
211+
if !maps.Equal(manifestEnclaves, cfgEnclaves) {
212+
fmt.Println("Built enclave identities DIFFER from on-chain enclave identities!")
213+
showIdentityDiff(buildEnclaves, cfgEnclaves, "On-chain")
214+
cobra.CheckErr(fmt.Errorf("enclave identity verification failed"))
215+
}
216+
217+
fmt.Println("Built enclave identities MATCH on-chain enclave identities.")
218+
}
219+
return
220+
}
221+
150222
// Override the update manifest flag in case the policy does not exist.
151223
if deployment.Policy == nil {
152224
doUpdate = false
153225
}
154226

155227
switch doUpdate {
156228
case false:
157-
// Ask the user to update the manifest manually.
229+
// Ask the user to update the manifest manually (if the manifest has changed).
230+
if maps.Equal(buildEnclaves, manifestEnclaves) {
231+
fmt.Println("Built enclave identities already match manifest enclave identities.")
232+
break
233+
}
234+
158235
fmt.Println("Update the manifest with the following identities to use the new app:")
159236
fmt.Println()
160237
fmt.Printf("deployments:\n")
@@ -177,6 +254,8 @@ var (
177254
if err = manifest.Save(); err != nil {
178255
cobra.CheckErr(fmt.Errorf("failed to update manifest: %w", err))
179256
}
257+
258+
fmt.Printf("Run `oasis rofl update` to update your ROFL app's on-chain configuration.\n")
180259
}
181260
},
182261
}
@@ -258,6 +337,7 @@ func init() {
258337
buildFlags.BoolVar(&offline, "offline", false, "do not perform any operations requiring network access")
259338
buildFlags.StringVar(&outputFn, "output", "", "output bundle filename")
260339
buildFlags.BoolVar(&doUpdate, "update-manifest", false, "automatically update the manifest")
340+
buildFlags.BoolVar(&doVerify, "verify", false, "verify build against manifest and on-chain state")
261341
buildFlags.StringVar(&deploymentName, "deployment", buildRofl.DefaultDeploymentName, "deployment name")
262342

263343
Cmd.Flags().AddFlagSet(buildFlags)

cmd/rofl/mgmt.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ var (
264264
}
265265
}
266266
}
267+
268+
fmt.Printf("Run `oasis rofl build --update-manifest` to build your ROFL app.\n")
267269
},
268270
}
269271

@@ -577,6 +579,8 @@ var (
577579
if err = manifest.Save(); err != nil {
578580
cobra.CheckErr(fmt.Errorf("failed to update manifest: %w", err))
579581
}
582+
583+
fmt.Printf("Run `oasis rofl update` to update your ROFL app's on-chain configuration.\n")
580584
},
581585
}
582586

0 commit comments

Comments
 (0)