Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions pcs/pcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,16 @@ const (
TcbComponentStatusRevoked TcbComponentStatus = "Revoked"
)

// CollateralUpdate represents the `update` query parameter of the Intel PCS API service
type CollateralUpdate string

const (
// CollateralUpdateStandard represents the standard access channel to updated collateral provided as part of a TCB recovery event
CollateralUpdateStandard CollateralUpdate = "standard"
// CollateralUpdateEarly represents the early access channel to updated collaterals provided as part of a TCB recovery event
CollateralUpdateEarly CollateralUpdate = "early"
)

// UnmarshalJSON for TcbComponentStatus maps tcb status to corresponding valid strings
func (st *TcbComponentStatus) UnmarshalJSON(s []byte) error {
unquotedStatus, err := strconv.Unquote(string(s))
Expand Down Expand Up @@ -475,11 +485,11 @@ func PckCrlURL(ca string) string {
}

// TcbInfoURL returns the Intel PCS URL for retrieving TCB Info
func TcbInfoURL(fmspc string) string {
return fmt.Sprintf("%s/tcb?fmspc=%s", TdxBaseURL, fmspc)
func TcbInfoURL(fmspc string, update CollateralUpdate) string {
return fmt.Sprintf("%s/tcb?fmspc=%s&update=%s", TdxBaseURL, fmspc, update)
}

// QeIdentityURL returns the Intel PCS URL for retrieving QE identity
func QeIdentityURL() string {
return fmt.Sprintf("%s/qe/identity", TdxBaseURL)
func QeIdentityURL(update CollateralUpdate) string {
return fmt.Sprintf("%s/qe/identity?update=%s", TdxBaseURL, update)
}
53 changes: 47 additions & 6 deletions pcs/pcs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,58 @@ func TestPckCrlURL(t *testing.T) {
}

func TestTcbInfoURL(t *testing.T) {
want := TdxBaseURL + "/tcb?fmspc=50806f000000"
fmspcBytes := []byte{80, 128, 111, 0, 0, 0}
fmspc := hex.EncodeToString(fmspcBytes)
if got := TcbInfoURL(fmspc); got != want {
t.Errorf("TcbInfoURL(%q) = %q. Expected %q", fmspc, got, want)

testCases := []struct {
name string
updateChannel CollateralUpdate
wantUrl string
}{
{
name: "success with standard access",
updateChannel: CollateralUpdateStandard,
wantUrl: TdxBaseURL + "/tcb?fmspc=50806f000000&update=standard",
},
{
name: "success with early access",
updateChannel: CollateralUpdateEarly,
wantUrl: TdxBaseURL + "/tcb?fmspc=50806f000000&update=early",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if got := TcbInfoURL(fmspc, tc.updateChannel); got != tc.wantUrl {
t.Errorf("TcbInfoURL(%q) = %q. Expected %q", fmspc, got, tc.wantUrl)
}
})
}
}

func TestQeIdentityURL(t *testing.T) {
want := TdxBaseURL + "/qe/identity"
if got := QeIdentityURL(); got != want {
t.Errorf("QEIdentityURL() = %q. Expected %q", got, want)
testCases := []struct {
name string
updateChannel CollateralUpdate
wantUrl string
}{
{
name: "success with standard access",
updateChannel: CollateralUpdateStandard,
wantUrl: TdxBaseURL + "/qe/identity?update=standard",
},
{
name: "success with early access",
updateChannel: CollateralUpdateEarly,
wantUrl: TdxBaseURL + "/qe/identity?update=early",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if got := QeIdentityURL(tc.updateChannel); got != tc.wantUrl {
t.Errorf("QEIdentityURL() = %q. Expected %q", got, tc.wantUrl)
}
})
}
}
12 changes: 10 additions & 2 deletions testing/test_cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,19 @@ var QeIdentityHeader = map[string][]string{
// TestGetter is a local getter tied to the included sample quote
var TestGetter = &Getter{
Responses: map[string]HTTPResponse{
"https://api.trustedservices.intel.com/tdx/certification/v4/qe/identity": {
"https://api.trustedservices.intel.com/tdx/certification/v4/qe/identity?update=standard": {
Header: QeIdentityHeader,
Body: testdata.QeIdentityBody,
},
"https://api.trustedservices.intel.com/tdx/certification/v4/tcb?fmspc=50806f000000": {
"https://api.trustedservices.intel.com/tdx/certification/v4/qe/identity?update=early": {
Header: QeIdentityHeader,
Body: testdata.QeIdentityBody,
},
"https://api.trustedservices.intel.com/tdx/certification/v4/tcb?fmspc=50806f000000&update=standard": {
Header: TcbInfoHeader,
Body: testdata.TcbInfoBody,
},
"https://api.trustedservices.intel.com/tdx/certification/v4/tcb?fmspc=50806f000000&update=early": {
Header: TcbInfoHeader,
Body: testdata.TcbInfoBody,
},
Expand Down
18 changes: 12 additions & 6 deletions verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ type Options struct {
CheckRevocations bool
// GetCollateral set to true if the verifier should retrieve the collaterals from the network using PCS.
GetCollateral bool
// CollateralUpdate specifies the update channel used when retrieving the collaterals from PCS.
CollateralUpdate pcs.CollateralUpdate
// Getter takes a URL and returns the body of its contents. By default uses http.Get and returns the header and body
Getter trust.HTTPSGetter
// Now is a time set at which to verify the validity of certificates and collaterals. If unset, uses defaultTimeset().
Expand Down Expand Up @@ -389,8 +391,8 @@ func getPckCrl(ca string, getter trust.HTTPSGetter, collateral *Collateral) erro
return nil
}

func getTcbInfo(fmspc string, getter trust.HTTPSGetter, collateral *Collateral) error {
tcbInfoURL := pcs.TcbInfoURL(fmspc)
func getTcbInfo(fmspc string, update pcs.CollateralUpdate, getter trust.HTTPSGetter, collateral *Collateral) error {
tcbInfoURL := pcs.TcbInfoURL(fmspc, update)
logger.V(2).Info("Getting TCB Info: ", tcbInfoURL)
header, body, err := getter.Get(tcbInfoURL)
if err != nil {
Expand Down Expand Up @@ -425,8 +427,8 @@ func getTcbInfo(fmspc string, getter trust.HTTPSGetter, collateral *Collateral)
return nil
}

func getQeIdentity(getter trust.HTTPSGetter, collateral *Collateral) error {
qeIdentityURL := pcs.QeIdentityURL()
func getQeIdentity(update pcs.CollateralUpdate, getter trust.HTTPSGetter, collateral *Collateral) error {
qeIdentityURL := pcs.QeIdentityURL(update)
logger.V(2).Info("Getting QE Identity: ", qeIdentityURL)
header, body, err := getter.Get(qeIdentityURL)
if err != nil {
Expand Down Expand Up @@ -490,15 +492,19 @@ func obtainCollateral(fmspc string, ca string, options *Options) (*Collateral, e
if getter == nil {
getter = trust.DefaultHTTPSGetter()
}
update := options.CollateralUpdate
if update == "" {
update = pcs.CollateralUpdateStandard
}
collateral := &Collateral{}
logger.V(1).Info("Getting TCB Info API response from the Intel PCS")
if err := getTcbInfo(fmspc, getter, collateral); err != nil {
if err := getTcbInfo(fmspc, update, getter, collateral); err != nil {
return nil, fmt.Errorf("unable to receive tcbInfo: %v", err)
}
logger.V(1).Info("Successfully received TCB Info API response from the Intel PCS")

logger.V(1).Info("Getting QE Identity API response from the Intel PCS")
if err := getQeIdentity(getter, collateral); err != nil {
if err := getQeIdentity(update, getter, collateral); err != nil {
return nil, fmt.Errorf("unable to receive QeIdentity: %v", err)
}
logger.V(1).Info("Successfully received QE Identity API response from the Intel PCS")
Expand Down
63 changes: 51 additions & 12 deletions verify/verify_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,23 +379,62 @@ func TestGetTcbInfo(t *testing.T) {
fmspc := hex.EncodeToString(fmspcBytes)

collateral := &Collateral{}
if err := getTcbInfo(fmspc, getter, collateral); err != nil {
t.Error(err)

testCases := []struct {
name string
updateChannel pcs.CollateralUpdate
}{
{
name: "success with standard access",
updateChannel: pcs.CollateralUpdateStandard,
},
{
name: "success with early access",
updateChannel: pcs.CollateralUpdateEarly,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if err := getTcbInfo(fmspc, tc.updateChannel, getter, collateral); err != nil {
t.Error(err)
}
})
}
}

func TestGetQeIdentity(t *testing.T) {
getter := testcases.TestGetter
collateral := &Collateral{}
if err := getQeIdentity(getter, collateral); err != nil {
t.Error(err)

testCases := []struct {
name string
updateChannel pcs.CollateralUpdate
}{
{
name: "success with standard access",
updateChannel: pcs.CollateralUpdateStandard,
},
{
name: "success with early access",
updateChannel: pcs.CollateralUpdateEarly,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if err := getQeIdentity(tc.updateChannel, getter, collateral); err != nil {
t.Error(err)
}
})
}

}

func TestGetRootCRL(t *testing.T) {
getter := testcases.TestGetter
collateral := &Collateral{}
if err := getQeIdentity(getter, collateral); err != nil {
if err := getQeIdentity(pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}

Expand Down Expand Up @@ -474,7 +513,7 @@ func TestVerifyUsingTcbInfoV4(t *testing.T) {
fmspc := hex.EncodeToString(fmspcBytes)

collateral := &Collateral{}
if err := getTcbInfo(fmspc, getter, collateral); err != nil {
if err := getTcbInfo(fmspc, pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}
anyQuote, err := abi.QuoteToProto(testdata.RawQuote)
Expand Down Expand Up @@ -524,7 +563,7 @@ func TestNegativeVerifyUsingTcbInfoV4(t *testing.T) {
fmspc := hex.EncodeToString(fmspcBytes)

collateral := &Collateral{}
if err := getTcbInfo(fmspc, getter, collateral); err != nil {
if err := getTcbInfo(fmspc, pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}
anyQuote, err := abi.QuoteToProto(testdata.RawQuote)
Expand Down Expand Up @@ -580,7 +619,7 @@ func TestVerifyUsingQeIdentityV4(t *testing.T) {
getter := testcases.TestGetter

collateral := &Collateral{}
if err := getQeIdentity(getter, collateral); err != nil {
if err := getQeIdentity(pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}
anyQuote, err := abi.QuoteToProto(testdata.RawQuote)
Expand All @@ -604,7 +643,7 @@ func TestNegativeVerifyUsingQeIdentityV4(t *testing.T) {
getter := testcases.TestGetter

collateral := &Collateral{}
if err := getQeIdentity(getter, collateral); err != nil {
if err := getQeIdentity(pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}
anyQuote, err := abi.QuoteToProto(testdata.RawQuote)
Expand Down Expand Up @@ -657,7 +696,7 @@ func TestNegativeTcbInfoTcbStatusV4(t *testing.T) {
fmspc := hex.EncodeToString(fmspcBytes)

collateral := &Collateral{}
if err := getTcbInfo(fmspc, getter, collateral); err != nil {
if err := getTcbInfo(fmspc, pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}
anyQuote, err := abi.QuoteToProto(testdata.RawQuote)
Expand Down Expand Up @@ -706,7 +745,7 @@ func TestNegativeCheckQeStatusV4(t *testing.T) {
getter := testcases.TestGetter

collateral := &Collateral{}
if err := getQeIdentity(getter, collateral); err != nil {
if err := getQeIdentity(pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}
anyQuote, err := abi.QuoteToProto(testdata.RawQuote)
Expand Down Expand Up @@ -750,7 +789,7 @@ func TestValidateCRL(t *testing.T) {
if err := getPckCrl(ca, getter, collateral); err != nil {
t.Fatal(err)
}
if err := getQeIdentity(getter, collateral); err != nil {
if err := getQeIdentity(pcs.CollateralUpdateStandard, getter, collateral); err != nil {
t.Fatal(err)
}
if err := getRootCrl(getter, collateral); err != nil {
Expand Down