verify: use fixed user data

This commit is contained in:
Thomas Tendyck 2023-01-17 15:28:07 +01:00 committed by Thomas Tendyck
parent 85f33b2140
commit f0f109a1ea
8 changed files with 47 additions and 134 deletions

View File

@ -97,18 +97,12 @@ func (v *verifyCmd) verify(cmd *cobra.Command, fileHandler file.Handler, verifyC
return err return err
} }
v.log.Debugf("Generated random nonce: %x", nonce) v.log.Debugf("Generated random nonce: %x", nonce)
userData, err := crypto.GenerateRandomBytes(32)
if err != nil {
return err
}
v.log.Debugf("Generated random user data: %x", userData)
if err := verifyClient.Verify( if err := verifyClient.Verify(
cmd.Context(), cmd.Context(),
flags.endpoint, flags.endpoint,
&verifyproto.GetAttestationRequest{ &verifyproto.GetAttestationRequest{
Nonce: nonce, Nonce: nonce,
UserData: userData,
}, },
validators.V(cmd), validators.V(cmd),
); err != nil { ); err != nil {
@ -231,8 +225,8 @@ func (v *constellationVerifier) Verify(
return fmt.Errorf("validating attestation: %w", err) return fmt.Errorf("validating attestation: %w", err)
} }
if !bytes.Equal(signedData, req.UserData) { if !bytes.Equal(signedData, []byte(constants.ConstellationVerifyServiceUserData)) {
return errors.New("signed data in attestation does not match provided user data") return errors.New("signed data in attestation does not match expected user data")
} }
return nil return nil
} }

View File

@ -181,25 +181,22 @@ func TestVerify(t *testing.T) {
func TestVerifyClient(t *testing.T) { func TestVerifyClient(t *testing.T) {
testCases := map[string]struct { testCases := map[string]struct {
attestationDoc atls.FakeAttestationDoc attestationDoc atls.FakeAttestationDoc
userData []byte
nonce []byte nonce []byte
attestationErr error attestationErr error
wantErr bool wantErr bool
}{ }{
"success": { "success": {
attestationDoc: atls.FakeAttestationDoc{ attestationDoc: atls.FakeAttestationDoc{
UserData: []byte("user data"), UserData: []byte(constants.ConstellationVerifyServiceUserData),
Nonce: []byte("nonce"), Nonce: []byte("nonce"),
}, },
userData: []byte("user data"),
nonce: []byte("nonce"), nonce: []byte("nonce"),
}, },
"attestation error": { "attestation error": {
attestationDoc: atls.FakeAttestationDoc{ attestationDoc: atls.FakeAttestationDoc{
UserData: []byte("user data"), UserData: []byte(constants.ConstellationVerifyServiceUserData),
Nonce: []byte("nonce"), Nonce: []byte("nonce"),
}, },
userData: []byte("user data"),
nonce: []byte("nonce"), nonce: []byte("nonce"),
attestationErr: errors.New("error"), attestationErr: errors.New("error"),
wantErr: true, wantErr: true,
@ -209,16 +206,14 @@ func TestVerifyClient(t *testing.T) {
UserData: []byte("wrong user data"), UserData: []byte("wrong user data"),
Nonce: []byte("nonce"), Nonce: []byte("nonce"),
}, },
userData: []byte("user data"),
nonce: []byte("nonce"), nonce: []byte("nonce"),
wantErr: true, wantErr: true,
}, },
"nonce does not match": { "nonce does not match": {
attestationDoc: atls.FakeAttestationDoc{ attestationDoc: atls.FakeAttestationDoc{
UserData: []byte("user data"), UserData: []byte(constants.ConstellationVerifyServiceUserData),
Nonce: []byte("wrong nonce"), Nonce: []byte("wrong nonce"),
}, },
userData: []byte("user data"),
nonce: []byte("nonce"), nonce: []byte("nonce"),
wantErr: true, wantErr: true,
}, },
@ -248,7 +243,6 @@ func TestVerifyClient(t *testing.T) {
verifier := &constellationVerifier{dialer: dialer, log: logger.NewTest(t)} verifier := &constellationVerifier{dialer: dialer, log: logger.NewTest(t)}
request := &verifyproto.GetAttestationRequest{ request := &verifyproto.GetAttestationRequest{
UserData: tc.userData,
Nonce: tc.nonce, Nonce: tc.nonce,
} }

View File

@ -104,7 +104,7 @@ func getAttestation(ctx context.Context, addr string) ([]byte, error) {
} }
client := verifyproto.NewAPIClient(conn) client := verifyproto.NewAPIClient(conn)
res, err := client.GetAttestation(ctx, &verifyproto.GetAttestationRequest{Nonce: nonce, UserData: nonce}) res, err := client.GetAttestation(ctx, &verifyproto.GetAttestationRequest{Nonce: nonce})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -27,6 +27,8 @@ const (
ConstellationMasterSecretKey = "mastersecret" ConstellationMasterSecretKey = "mastersecret"
// ConstellationSaltKey is the name of the key for the salt in the master secret kubernetes secret. // ConstellationSaltKey is the name of the key for the salt in the master secret kubernetes secret.
ConstellationSaltKey = "salt" ConstellationSaltKey = "salt"
// ConstellationVerifyServiceUserData is the user data that the verification service includes in the attestation.
ConstellationVerifyServiceUserData = "VerifyService"
// //
// Ports. // Ports.

View File

@ -16,6 +16,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/logger" "github.com/edgelesssys/constellation/v2/internal/logger"
"github.com/edgelesssys/constellation/v2/verify/verifyproto" "github.com/edgelesssys/constellation/v2/verify/verifyproto"
"go.uber.org/zap" "go.uber.org/zap"
@ -107,13 +108,9 @@ func (s *Server) GetAttestation(ctx context.Context, req *verifyproto.GetAttesta
log.Errorf("Received attestation request with empty nonce") log.Errorf("Received attestation request with empty nonce")
return nil, status.Error(codes.InvalidArgument, "nonce is required to issue attestation") return nil, status.Error(codes.InvalidArgument, "nonce is required to issue attestation")
} }
if len(req.UserData) == 0 {
log.Errorf("Received attestation request with empty user data")
return nil, status.Error(codes.InvalidArgument, "user data is required to issue attestation")
}
log.Infof("Creating attestation") log.Infof("Creating attestation")
statement, err := s.issuer.Issue(req.UserData, req.Nonce) statement, err := s.issuer.Issue([]byte(constants.ConstellationVerifyServiceUserData), req.Nonce)
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "issuing attestation statement: %v", err) return nil, status.Errorf(codes.Internal, "issuing attestation statement: %v", err)
} }
@ -132,12 +129,6 @@ func (s *Server) getAttestationHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, "nonce parameter is required exactly once", http.StatusBadRequest) http.Error(w, "nonce parameter is required exactly once", http.StatusBadRequest)
return return
} }
userDataB64 := r.URL.Query()["userData"]
if len(userDataB64) != 1 || userDataB64[0] == "" {
log.Errorf("Received attestation request with empty or multiple user data parameter")
http.Error(w, "userData parameter is required exactly once", http.StatusBadRequest)
return
}
nonce, err := base64.URLEncoding.DecodeString(nonceB64[0]) nonce, err := base64.URLEncoding.DecodeString(nonceB64[0])
if err != nil { if err != nil {
@ -145,15 +136,9 @@ func (s *Server) getAttestationHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, fmt.Sprintf("invalid base64 encoding for nonce: %v", err), http.StatusBadRequest) http.Error(w, fmt.Sprintf("invalid base64 encoding for nonce: %v", err), http.StatusBadRequest)
return return
} }
userData, err := base64.URLEncoding.DecodeString(userDataB64[0])
if err != nil {
log.With(zap.Error(err)).Errorf("Received attestation request with invalid user data")
http.Error(w, fmt.Sprintf("invalid base64 encoding for userData: %v", err), http.StatusBadRequest)
return
}
log.Infof("Creating attestation") log.Infof("Creating attestation")
quote, err := s.issuer.Issue(userData, nonce) quote, err := s.issuer.Issue([]byte(constants.ConstellationVerifyServiceUserData), nonce)
if err != nil { if err != nil {
http.Error(w, fmt.Sprintf("issuing attestation statement: %v", err), http.StatusInternalServerError) http.Error(w, fmt.Sprintf("issuing attestation statement: %v", err), http.StatusInternalServerError)
return return

View File

@ -11,7 +11,6 @@ import (
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"io" "io"
"net" "net"
"net/http" "net/http"
@ -84,29 +83,18 @@ func TestGetAttestationGRPC(t *testing.T) {
issuer: stubIssuer{attestation: []byte("quote")}, issuer: stubIssuer{attestation: []byte("quote")},
request: &verifyproto.GetAttestationRequest{ request: &verifyproto.GetAttestationRequest{
Nonce: []byte("nonce"), Nonce: []byte("nonce"),
UserData: []byte("userData"),
}, },
}, },
"issuer fails": { "issuer fails": {
issuer: stubIssuer{issueErr: errors.New("issuer error")}, issuer: stubIssuer{issueErr: errors.New("issuer error")},
request: &verifyproto.GetAttestationRequest{ request: &verifyproto.GetAttestationRequest{
Nonce: []byte("nonce"), Nonce: []byte("nonce"),
UserData: []byte("userData"),
}, },
wantErr: true, wantErr: true,
}, },
"no nonce": { "no nonce": {
issuer: stubIssuer{attestation: []byte("quote")}, issuer: stubIssuer{attestation: []byte("quote")},
request: &verifyproto.GetAttestationRequest{ request: &verifyproto.GetAttestationRequest{},
UserData: []byte("userData"),
},
wantErr: true,
},
"no userData": {
issuer: stubIssuer{attestation: []byte("quote")},
request: &verifyproto.GetAttestationRequest{
Nonce: []byte("nonce"),
},
wantErr: true, wantErr: true,
}, },
} }
@ -138,67 +126,26 @@ func TestGetAttestationHTTP(t *testing.T) {
wantErr bool wantErr bool
}{ }{
"success": { "success": {
request: fmt.Sprintf( request: "?nonce=" + base64.URLEncoding.EncodeToString([]byte("nonce")),
"?nonce=%s&userData=%s",
base64.URLEncoding.EncodeToString([]byte("nonce")),
base64.URLEncoding.EncodeToString([]byte("userData")),
),
issuer: stubIssuer{attestation: []byte("quote")}, issuer: stubIssuer{attestation: []byte("quote")},
}, },
"invalid nonce in query": { "invalid nonce in query": {
request: fmt.Sprintf( request: "?nonce=not-base-64",
"?nonce=not-base-64&userData=%s",
base64.URLEncoding.EncodeToString([]byte("userData")),
),
issuer: stubIssuer{attestation: []byte("quote")}, issuer: stubIssuer{attestation: []byte("quote")},
wantErr: true, wantErr: true,
}, },
"no nonce in query": { "no nonce in query": {
request: fmt.Sprintf( request: "?foo=bar",
"?userData=%s",
base64.URLEncoding.EncodeToString([]byte("userData")),
),
issuer: stubIssuer{attestation: []byte("quote")}, issuer: stubIssuer{attestation: []byte("quote")},
wantErr: true, wantErr: true,
}, },
"empty nonce in query": { "empty nonce in query": {
request: fmt.Sprintf( request: "?nonce=",
"?nonce=&userData=%s",
base64.URLEncoding.EncodeToString([]byte("userData")),
),
issuer: stubIssuer{attestation: []byte("quote")},
wantErr: true,
},
"invalid userData in query": {
request: fmt.Sprintf(
"?nonce=%s&userData=not-base-64",
base64.URLEncoding.EncodeToString([]byte("nonce")),
),
issuer: stubIssuer{attestation: []byte("quote")},
wantErr: true,
},
"no userData in query": {
request: fmt.Sprintf(
"?nonce=%s",
base64.URLEncoding.EncodeToString([]byte("nonce")),
),
issuer: stubIssuer{attestation: []byte("quote")},
wantErr: true,
},
"empty userData in query": {
request: fmt.Sprintf(
"?nonce=%s&userData=",
base64.URLEncoding.EncodeToString([]byte("nonce")),
),
issuer: stubIssuer{attestation: []byte("quote")}, issuer: stubIssuer{attestation: []byte("quote")},
wantErr: true, wantErr: true,
}, },
"issuer fails": { "issuer fails": {
request: fmt.Sprintf( request: "?nonce=" + base64.URLEncoding.EncodeToString([]byte("nonce")),
"?nonce=%s&userData=%s",
base64.URLEncoding.EncodeToString([]byte("nonce")),
base64.URLEncoding.EncodeToString([]byte("userData")),
),
issuer: stubIssuer{issueErr: errors.New("errors")}, issuer: stubIssuer{issueErr: errors.New("errors")},
wantErr: true, wantErr: true,
}, },

View File

@ -25,7 +25,7 @@ type GetAttestationRequest struct {
sizeCache protoimpl.SizeCache sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
UserData []byte `protobuf:"bytes,1,opt,name=user_data,json=userData,proto3" json:"user_data,omitempty"` // bytes user_data = 1; removed
Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"` Nonce []byte `protobuf:"bytes,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
} }
@ -61,13 +61,6 @@ func (*GetAttestationRequest) Descriptor() ([]byte, []int) {
return file_verify_proto_rawDescGZIP(), []int{0} return file_verify_proto_rawDescGZIP(), []int{0}
} }
func (x *GetAttestationRequest) GetUserData() []byte {
if x != nil {
return x.UserData
}
return nil
}
func (x *GetAttestationRequest) GetNonce() []byte { func (x *GetAttestationRequest) GetNonce() []byte {
if x != nil { if x != nil {
return x.Nonce return x.Nonce
@ -126,25 +119,23 @@ var File_verify_proto protoreflect.FileDescriptor
var file_verify_proto_rawDesc = []byte{ var file_verify_proto_rawDesc = []byte{
0x0a, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x0a, 0x0c, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06,
0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x22, 0x4a, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x22, 0x2d, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74,
0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x1b, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05,
0x28, 0x0c, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x65,
0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x63, 0x65, 0x22, 0x3a, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x20, 0x0a, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x6e, 0x32, 0x56, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x4f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41,
0x0c, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x56, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x76, 0x65, 0x72,
0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x4f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x65, 0x69, 0x66, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69,
0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x65, 0x72, 0x69,
0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x66, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2e, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74,
0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3c, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2f, 0x76, 0x65, 0x72, 0x69,
0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x66, 0x79, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x32, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x2f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
} }
var ( var (

View File

@ -9,7 +9,7 @@ service API {
} }
message GetAttestationRequest { message GetAttestationRequest {
bytes user_data = 1; // bytes user_data = 1; removed
bytes nonce = 2; bytes nonce = 2;
} }