-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add attestation only if nonce is provided.
The config endpoint isn't sensitive, so there's no need to always attest the response. This PR makes config attestation opportunistic: we do it if there's a nonce and otherwise we skip it.
- Loading branch information
1 parent
fcae61b
commit b70e5c4
Showing
7 changed files
with
217 additions
and
169 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package attestation | ||
|
||
import ( | ||
"crypto/sha256" | ||
|
||
"github.com/Amnesic-Systems/veil/internal/enclave" | ||
"github.com/Amnesic-Systems/veil/internal/nonce" | ||
) | ||
|
||
// Builder is an abstraction purpose-built for veil's HTTP handlers. It bundles | ||
// an attester with auxiliary fields because these two are always used together. | ||
// As a Builder is passed through the stack, its auxiliary fields are updated | ||
// and eventually used to create an attestation document. | ||
type Builder struct { | ||
enclave.Attester | ||
enclave.AuxInfo | ||
} | ||
|
||
type auxField func(*Builder) | ||
|
||
// NewBuilder returns a new Builder with the given attester and sets the given | ||
// auxiliary fields. | ||
func NewBuilder(attester enclave.Attester, opts ...auxField) *Builder { | ||
b := &Builder{Attester: attester} | ||
for _, opt := range opts { | ||
opt(b) | ||
} | ||
return b | ||
} | ||
|
||
// Update updates the builder with the given auxiliary fields. | ||
func (b *Builder) Update(opts ...auxField) { | ||
for _, opt := range opts { | ||
opt(b) | ||
} | ||
} | ||
|
||
// Attest returns an attestation document with the auxiliary fields that were | ||
// either already set, or are now passed in as options. | ||
func (b *Builder) Attest(opts ...auxField) (*enclave.RawDocument, error) { | ||
for _, opt := range opts { | ||
opt(b) | ||
} | ||
return b.Attester.Attest(&b.AuxInfo) | ||
} | ||
|
||
// WithHashes sets the given hashes in an auxiliary field. | ||
func WithHashes(h *Hashes) auxField { | ||
return func(b *Builder) { | ||
if h == nil { | ||
return | ||
} | ||
b.PublicKey = h.Serialize() | ||
} | ||
} | ||
|
||
// WithNonce sets the given nonce in an auxiliary field. | ||
func WithNonce(n *nonce.Nonce) auxField { | ||
return func(b *Builder) { | ||
if n == nil { | ||
return | ||
} | ||
b.Nonce = n.ToSlice() | ||
} | ||
} | ||
|
||
// WithSHA256 sets the given SHA256 hash in an auxiliary field. | ||
func WithSHA256(sha [sha256.Size]byte) auxField { | ||
return func(b *Builder) { | ||
b.UserData = sha[:] | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package attestation | ||
|
||
import ( | ||
"crypto/sha256" | ||
"testing" | ||
|
||
"github.com/Amnesic-Systems/veil/internal/addr" | ||
"github.com/Amnesic-Systems/veil/internal/enclave" | ||
"github.com/Amnesic-Systems/veil/internal/enclave/nitro" | ||
"github.com/Amnesic-Systems/veil/internal/enclave/noop" | ||
"github.com/Amnesic-Systems/veil/internal/nonce" | ||
"github.com/Amnesic-Systems/veil/internal/util" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestBuilder(t *testing.T) { | ||
attester := noop.NewAttester() | ||
if nitro.IsEnclave() { | ||
attester = nitro.NewAttester() | ||
} | ||
nonce1, nonce2 := util.Must(nonce.New()), util.Must(nonce.New()) | ||
sha1, sha2 := sha256.Sum256([]byte("foo")), sha256.Sum256([]byte("bar")) | ||
hashes1 := &Hashes{TlsKeyHash: addr.Of(sha256.Sum256([]byte("foo")))} | ||
hashes2 := &Hashes{TlsKeyHash: addr.Of(sha256.Sum256([]byte("bar")))} | ||
|
||
cases := []struct { | ||
name string | ||
initFields []auxField | ||
attestFields []auxField | ||
wantAux *enclave.AuxInfo | ||
}{ | ||
{ | ||
name: "empty", | ||
wantAux: &enclave.AuxInfo{}, | ||
}, | ||
{ | ||
name: "nonce at initialization", | ||
initFields: []auxField{WithNonce(nonce1)}, | ||
wantAux: &enclave.AuxInfo{Nonce: nonce1.ToSlice()}, | ||
}, | ||
{ | ||
name: "nonce at attestation", | ||
attestFields: []auxField{WithNonce(nonce1)}, | ||
wantAux: &enclave.AuxInfo{Nonce: nonce1.ToSlice()}, | ||
}, | ||
{ | ||
name: "nonce being overwritten", | ||
initFields: []auxField{WithNonce(nonce1)}, | ||
attestFields: []auxField{WithNonce(nonce2)}, | ||
wantAux: &enclave.AuxInfo{Nonce: nonce2.ToSlice()}, | ||
}, | ||
{ | ||
name: "everything overwritten", | ||
initFields: []auxField{WithHashes(hashes1), WithNonce(nonce1), WithSHA256(sha1)}, | ||
attestFields: []auxField{WithHashes(hashes2), WithNonce(nonce2), WithSHA256(sha2)}, | ||
wantAux: &enclave.AuxInfo{ | ||
Nonce: nonce2.ToSlice(), | ||
PublicKey: hashes2.Serialize(), | ||
UserData: sha2[:], | ||
}, | ||
}, | ||
} | ||
|
||
for _, c := range cases { | ||
t.Run(c.name, func(t *testing.T) { | ||
b := NewBuilder(attester, c.initFields...) | ||
rawDoc, err := b.Attest(c.attestFields...) | ||
require.NoError(t, err) | ||
|
||
// Verify the attestation document. We expect no error but if the | ||
// test is run inside a Nitro Enclave, we will get ErrDebugMode. | ||
doc, err := attester.Verify(rawDoc, nil) | ||
if err != nil { | ||
require.ErrorIs(t, err, nitro.ErrDebugMode) | ||
} | ||
require.Equal(t, c.wantAux, &doc.AuxInfo) | ||
}) | ||
} | ||
} |
This file contains 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
Oops, something went wrong.