diff --git a/pcs/pcs.go b/pcs/pcs.go index c991641..87ef512 100644 --- a/pcs/pcs.go +++ b/pcs/pcs.go @@ -75,6 +75,8 @@ var ( OidPCEID = asn1.ObjectIdentifier([]int{1, 2, 840, 113741, 1, 13, 1, 3}) // OidFMSPC is the x509v3 extension for PCK certificate's SGX Extensions FMSPC value. OidFMSPC = asn1.ObjectIdentifier([]int{1, 2, 840, 113741, 1, 13, 1, 4}) + // OidSGXType is the x509v3 extension for PCK certificate's SGX Extensions SGX Type value. + OidSGXType = asn1.ObjectIdentifier([]int{1, 2, 840, 113741, 1, 13, 1, 5}) // ErrPckExtInvalid error returned when parsing PCK certificate's extension returns leftover bytes ErrPckExtInvalid = errors.New("unexpected leftover bytes for PCK certificate's extension") @@ -176,14 +178,27 @@ type PckCertTCB struct { } // PckExtensions represents the information stored in the x509 extensions of a PCK certificate which -// will be required for verification +// will be required for verification/validation type PckExtensions struct { - PPID string - TCB PckCertTCB - PCEID string - FMSPC string + PPID string + TCB PckCertTCB + PCEID string + FMSPC string + SGXType SGXType } +// SGXType represents the type of the platform for which the PCK certificate was created +type SGXType int + +const ( + // SGXTypeStandard represents a standard (non-scalable) platform. + SGXTypeStandard SGXType = iota + // SGXTypeScalable represents a scalable platform with logical integrity protection. + SGXTypeScalable + // SGXTypeScalableWithIntegrity represents a scalable platform with cryptographic integrity protection. + SGXTypeScalableWithIntegrity +) + // HexBytes struct contains hex decoded string to bytes value type HexBytes struct { Bytes []byte @@ -394,6 +409,15 @@ func extractAsn1OctetStringExtension(name string, extension asn1.RawValue, size return hex.EncodeToString(val), nil } +// attributeTypeAndEnumerated is a specialized version of +// pkix.AttributeTypeAndValue to work around a bug where Go's ASN.1 parser +// fails to unmarshal `asn1.Enumerated` values into the `any` field in +// `AttributeTypeAndValue`: https://github.com/golang/go/pull/69727 +type attributeTypeAndEnumerated struct { + Type asn1.ObjectIdentifier + Value asn1.Enumerated +} + func extractSgxExtensions(extensions []asn1.RawValue) (*PckExtensions, error) { pckExtension := &PckExtensions{} if len(extensions) < sgxExtensionMinSize { @@ -434,6 +458,14 @@ func extractSgxExtensions(extensions []asn1.RawValue) (*PckExtensions, error) { return nil, err } } + if sExtension.Type.Equal(OidSGXType) { + var sExtension attributeTypeAndEnumerated + _, err := asn1.Unmarshal(ext.FullBytes, &sExtension) + if err != nil { + return nil, fmt.Errorf("could not parse SGX extension's in PCK certificate: %v", err) + } + pckExtension.SGXType = SGXType(sExtension.Value) + } } return pckExtension, nil } @@ -448,7 +480,7 @@ func findMatchingExtension(extns []pkix.Extension, oid asn1.ObjectIdentifier) (* } // PckCertificateExtensions returns only those x509v3 extensions from the PCK certificate into a -// struct type which will be required in verification purpose. +// struct type which will be required for verification or validation purposes. func PckCertificateExtensions(cert *x509.Certificate) (*PckExtensions, error) { if len(cert.Extensions) != pckCertExtensionSize { return nil, fmt.Errorf("PCK certificate extensions length found %d. Expected %d", len(cert.Extensions), pckCertExtensionSize) diff --git a/proto/checkconfig.proto b/proto/checkconfig.proto index fed75d9..fd69a8b 100644 --- a/proto/checkconfig.proto +++ b/proto/checkconfig.proto @@ -30,6 +30,8 @@ message Policy { // TDQuoteBodyPolicy is representation of TdQuoteBody of an attestation quote // validation policy. TDQuoteBodyPolicy td_quote_body_policy = 2; // should be 528 bytes + + PCKPolicy pck_policy = 3; } message HeaderPolicy { @@ -55,6 +57,16 @@ message TDQuoteBodyPolicy { bool enable_td_debug_check = 12; // if true, check that the DEBUG bit is 0 in TDAttributes. } +message PCKPolicy { + optional SGXType sgx_type = 1; +} + +enum SGXType { + Standard = 0; + Scalable = 1; + ScalableWithIntegrity = 2; +} + // RootOfTrust represents configuration for which hardware root of trust // certificates to use for verifying attestation quote. message RootOfTrust { diff --git a/proto/checkconfig/checkconfig.pb.go b/proto/checkconfig/checkconfig.pb.go index 29cc93c..39b93a3 100644 --- a/proto/checkconfig/checkconfig.pb.go +++ b/proto/checkconfig/checkconfig.pb.go @@ -36,6 +36,55 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type SGXType int32 + +const ( + SGXType_Standard SGXType = 0 + SGXType_Scalable SGXType = 1 + SGXType_ScalableWithIntegrity SGXType = 2 +) + +// Enum value maps for SGXType. +var ( + SGXType_name = map[int32]string{ + 0: "Standard", + 1: "Scalable", + 2: "ScalableWithIntegrity", + } + SGXType_value = map[string]int32{ + "Standard": 0, + "Scalable": 1, + "ScalableWithIntegrity": 2, + } +) + +func (x SGXType) Enum() *SGXType { + p := new(SGXType) + *p = x + return p +} + +func (x SGXType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (SGXType) Descriptor() protoreflect.EnumDescriptor { + return file_checkconfig_proto_enumTypes[0].Descriptor() +} + +func (SGXType) Type() protoreflect.EnumType { + return &file_checkconfig_proto_enumTypes[0] +} + +func (x SGXType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use SGXType.Descriptor instead. +func (SGXType) EnumDescriptor() ([]byte, []int) { + return file_checkconfig_proto_rawDescGZIP(), []int{0} +} + // Policy is a representation of an attestation quote validation policy. // Each field corresponds to a field on validate.Options. This format // is useful for providing programmatic inputs to the `check` CLI tool. @@ -50,6 +99,7 @@ type Policy struct { // TDQuoteBodyPolicy is representation of TdQuoteBody of an attestation quote // validation policy. TdQuoteBodyPolicy *TDQuoteBodyPolicy `protobuf:"bytes,2,opt,name=td_quote_body_policy,json=tdQuoteBodyPolicy,proto3" json:"td_quote_body_policy,omitempty"` // should be 528 bytes + PckPolicy *PCKPolicy `protobuf:"bytes,3,opt,name=pck_policy,json=pckPolicy,proto3" json:"pck_policy,omitempty"` } func (x *Policy) Reset() { @@ -98,6 +148,13 @@ func (x *Policy) GetTdQuoteBodyPolicy() *TDQuoteBodyPolicy { return nil } +func (x *Policy) GetPckPolicy() *PCKPolicy { + if x != nil { + return x.PckPolicy + } + return nil +} + type HeaderPolicy struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -297,6 +354,53 @@ func (x *TDQuoteBodyPolicy) GetEnableTdDebugCheck() bool { return false } +type PCKPolicy struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + SgxType *SGXType `protobuf:"varint,1,opt,name=sgx_type,json=sgxType,proto3,enum=checkconfig.SGXType,oneof" json:"sgx_type,omitempty"` +} + +func (x *PCKPolicy) Reset() { + *x = PCKPolicy{} + if protoimpl.UnsafeEnabled { + mi := &file_checkconfig_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PCKPolicy) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PCKPolicy) ProtoMessage() {} + +func (x *PCKPolicy) ProtoReflect() protoreflect.Message { + mi := &file_checkconfig_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PCKPolicy.ProtoReflect.Descriptor instead. +func (*PCKPolicy) Descriptor() ([]byte, []int) { + return file_checkconfig_proto_rawDescGZIP(), []int{3} +} + +func (x *PCKPolicy) GetSgxType() SGXType { + if x != nil && x.SgxType != nil { + return *x.SgxType + } + return SGXType_Standard +} + // RootOfTrust represents configuration for which hardware root of trust // certificates to use for verifying attestation quote. type RootOfTrust struct { @@ -321,7 +425,7 @@ type RootOfTrust struct { func (x *RootOfTrust) Reset() { *x = RootOfTrust{} if protoimpl.UnsafeEnabled { - mi := &file_checkconfig_proto_msgTypes[3] + mi := &file_checkconfig_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -334,7 +438,7 @@ func (x *RootOfTrust) String() string { func (*RootOfTrust) ProtoMessage() {} func (x *RootOfTrust) ProtoReflect() protoreflect.Message { - mi := &file_checkconfig_proto_msgTypes[3] + mi := &file_checkconfig_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -347,7 +451,7 @@ func (x *RootOfTrust) ProtoReflect() protoreflect.Message { // Deprecated: Use RootOfTrust.ProtoReflect.Descriptor instead. func (*RootOfTrust) Descriptor() ([]byte, []int) { - return file_checkconfig_proto_rawDescGZIP(), []int{3} + return file_checkconfig_proto_rawDescGZIP(), []int{4} } func (x *RootOfTrust) GetCabundlePaths() []string { @@ -395,7 +499,7 @@ type Config struct { func (x *Config) Reset() { *x = Config{} if protoimpl.UnsafeEnabled { - mi := &file_checkconfig_proto_msgTypes[4] + mi := &file_checkconfig_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -408,7 +512,7 @@ func (x *Config) String() string { func (*Config) ProtoMessage() {} func (x *Config) ProtoReflect() protoreflect.Message { - mi := &file_checkconfig_proto_msgTypes[4] + mi := &file_checkconfig_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -421,7 +525,7 @@ func (x *Config) ProtoReflect() protoreflect.Message { // Deprecated: Use Config.ProtoReflect.Descriptor instead. func (*Config) Descriptor() ([]byte, []int) { - return file_checkconfig_proto_rawDescGZIP(), []int{4} + return file_checkconfig_proto_rawDescGZIP(), []int{5} } func (x *Config) GetPolicy() *Policy { @@ -443,7 +547,7 @@ var File_checkconfig_proto protoreflect.FileDescriptor var file_checkconfig_proto_rawDesc = []byte{ 0x0a, 0x11, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0b, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, - 0x22, 0x99, 0x01, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x3e, 0x0a, 0x0d, 0x68, + 0x22, 0xd0, 0x01, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x3e, 0x0a, 0x0d, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0c, 0x68, @@ -452,61 +556,74 @@ var file_checkconfig_proto_rawDesc = []byte{ 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x54, 0x44, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x11, 0x74, 0x64, 0x51, 0x75, 0x6f, - 0x74, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, 0x7e, 0x0a, 0x0c, - 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x24, 0x0a, 0x0e, - 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x71, 0x65, 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x51, 0x65, 0x53, - 0x76, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x70, 0x63, - 0x65, 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x69, 0x6e, - 0x69, 0x6d, 0x75, 0x6d, 0x50, 0x63, 0x65, 0x53, 0x76, 0x6e, 0x12, 0x20, 0x0a, 0x0c, 0x71, 0x65, - 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0a, 0x71, 0x65, 0x56, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x49, 0x64, 0x22, 0x94, 0x03, 0x0a, - 0x11, 0x54, 0x44, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x74, 0x65, - 0x65, 0x5f, 0x74, 0x63, 0x62, 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x10, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x54, 0x65, 0x65, 0x54, 0x63, 0x62, 0x53, 0x76, - 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x72, 0x5f, 0x73, 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x72, 0x53, 0x65, 0x61, 0x6d, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x64, - 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0c, 0x74, 0x64, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x78, 0x66, 0x61, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x78, - 0x66, 0x61, 0x6d, 0x12, 0x13, 0x0a, 0x05, 0x6d, 0x72, 0x5f, 0x74, 0x64, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x04, 0x6d, 0x72, 0x54, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x6d, 0x72, 0x5f, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, - 0x6d, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x72, - 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x72, - 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x72, 0x5f, 0x6f, 0x77, 0x6e, 0x65, - 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, - 0x6d, 0x72, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, - 0x05, 0x72, 0x74, 0x6d, 0x72, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x74, - 0x6d, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, - 0x44, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x09, 0x61, 0x6e, 0x79, 0x5f, 0x6d, 0x72, 0x5f, 0x74, - 0x64, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x61, 0x6e, 0x79, 0x4d, 0x72, 0x54, 0x64, - 0x12, 0x31, 0x0a, 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x64, 0x5f, 0x64, 0x65, - 0x62, 0x75, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x64, 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x22, 0x96, 0x01, 0x0a, 0x0b, 0x52, 0x6f, 0x6f, 0x74, 0x4f, 0x66, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x61, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, - 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x61, 0x62, - 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x61, - 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, - 0x61, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x5f, 0x63, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x43, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6c, - 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x67, - 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x22, 0x73, 0x0a, 0x06, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x12, 0x3c, 0x0a, 0x0d, 0x72, 0x6f, 0x6f, 0x74, 0x5f, 0x6f, 0x66, 0x5f, 0x74, - 0x72, 0x75, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x68, 0x65, - 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x52, 0x6f, 0x6f, 0x74, 0x4f, 0x66, 0x54, - 0x72, 0x75, 0x73, 0x74, 0x52, 0x0b, 0x72, 0x6f, 0x6f, 0x74, 0x4f, 0x66, 0x54, 0x72, 0x75, 0x73, - 0x74, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x74, 0x64, 0x78, 0x2d, 0x67, 0x75, - 0x65, 0x73, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x65, 0x42, 0x6f, 0x64, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x35, 0x0a, 0x0a, + 0x70, 0x63, 0x6b, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, + 0x43, 0x4b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x09, 0x70, 0x63, 0x6b, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x22, 0x7e, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x71, + 0x65, 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x69, 0x6e, + 0x69, 0x6d, 0x75, 0x6d, 0x51, 0x65, 0x53, 0x76, 0x6e, 0x12, 0x26, 0x0a, 0x0f, 0x6d, 0x69, 0x6e, + 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x70, 0x63, 0x65, 0x5f, 0x73, 0x76, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x50, 0x63, 0x65, 0x53, 0x76, + 0x6e, 0x12, 0x20, 0x0a, 0x0c, 0x71, 0x65, 0x5f, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x71, 0x65, 0x56, 0x65, 0x6e, 0x64, 0x6f, + 0x72, 0x49, 0x64, 0x22, 0x94, 0x03, 0x0a, 0x11, 0x54, 0x44, 0x51, 0x75, 0x6f, 0x74, 0x65, 0x42, + 0x6f, 0x64, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2d, 0x0a, 0x13, 0x6d, 0x69, 0x6e, + 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x74, 0x65, 0x65, 0x5f, 0x74, 0x63, 0x62, 0x5f, 0x73, 0x76, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x54, + 0x65, 0x65, 0x54, 0x63, 0x62, 0x53, 0x76, 0x6e, 0x12, 0x17, 0x0a, 0x07, 0x6d, 0x72, 0x5f, 0x73, + 0x65, 0x61, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x72, 0x53, 0x65, 0x61, + 0x6d, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x64, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x74, 0x64, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x78, 0x66, 0x61, 0x6d, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x78, 0x66, 0x61, 0x6d, 0x12, 0x13, 0x0a, 0x05, 0x6d, 0x72, + 0x5f, 0x74, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x6d, 0x72, 0x54, 0x64, 0x12, + 0x20, 0x0a, 0x0c, 0x6d, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6d, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49, + 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6d, 0x72, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6d, 0x72, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0f, + 0x6d, 0x72, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x6d, 0x72, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x74, 0x6d, 0x72, 0x73, 0x18, 0x09, 0x20, + 0x03, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x74, 0x6d, 0x72, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, + 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x09, 0x61, + 0x6e, 0x79, 0x5f, 0x6d, 0x72, 0x5f, 0x74, 0x64, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, + 0x61, 0x6e, 0x79, 0x4d, 0x72, 0x54, 0x64, 0x12, 0x31, 0x0a, 0x15, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x74, 0x64, 0x5f, 0x64, 0x65, 0x62, 0x75, 0x67, 0x5f, 0x63, 0x68, 0x65, 0x63, 0x6b, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x64, + 0x44, 0x65, 0x62, 0x75, 0x67, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x22, 0x4e, 0x0a, 0x09, 0x50, 0x43, + 0x4b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x34, 0x0a, 0x08, 0x73, 0x67, 0x78, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x53, 0x47, 0x58, 0x54, 0x79, 0x70, 0x65, 0x48, + 0x00, 0x52, 0x07, 0x73, 0x67, 0x78, 0x54, 0x79, 0x70, 0x65, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, + 0x09, 0x5f, 0x73, 0x67, 0x78, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x96, 0x01, 0x0a, 0x0b, 0x52, + 0x6f, 0x6f, 0x74, 0x4f, 0x66, 0x54, 0x72, 0x75, 0x73, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x61, + 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0d, 0x63, 0x61, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x50, 0x61, 0x74, 0x68, + 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x61, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x62, 0x75, 0x6e, 0x64, 0x6c, 0x65, 0x73, 0x12, + 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x5f, 0x63, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x43, 0x72, 0x6c, 0x12, 0x25, 0x0a, 0x0e, + 0x67, 0x65, 0x74, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6c, 0x61, 0x74, 0x65, + 0x72, 0x61, 0x6c, 0x22, 0x73, 0x0a, 0x06, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2b, 0x0a, + 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, + 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x3c, 0x0a, 0x0d, 0x72, 0x6f, + 0x6f, 0x74, 0x5f, 0x6f, 0x66, 0x5f, 0x74, 0x72, 0x75, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2e, + 0x52, 0x6f, 0x6f, 0x74, 0x4f, 0x66, 0x54, 0x72, 0x75, 0x73, 0x74, 0x52, 0x0b, 0x72, 0x6f, 0x6f, + 0x74, 0x4f, 0x66, 0x54, 0x72, 0x75, 0x73, 0x74, 0x2a, 0x40, 0x0a, 0x07, 0x53, 0x47, 0x58, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x10, + 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x63, 0x61, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x01, 0x12, + 0x19, 0x0a, 0x15, 0x53, 0x63, 0x61, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x57, 0x69, 0x74, 0x68, 0x49, + 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x10, 0x02, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x67, 0x6f, 0x2d, 0x74, 0x64, 0x78, 0x2d, 0x67, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -521,24 +638,29 @@ func file_checkconfig_proto_rawDescGZIP() []byte { return file_checkconfig_proto_rawDescData } -var file_checkconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_checkconfig_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_checkconfig_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_checkconfig_proto_goTypes = []interface{}{ - (*Policy)(nil), // 0: checkconfig.Policy - (*HeaderPolicy)(nil), // 1: checkconfig.HeaderPolicy - (*TDQuoteBodyPolicy)(nil), // 2: checkconfig.TDQuoteBodyPolicy - (*RootOfTrust)(nil), // 3: checkconfig.RootOfTrust - (*Config)(nil), // 4: checkconfig.Config + (SGXType)(0), // 0: checkconfig.SGXType + (*Policy)(nil), // 1: checkconfig.Policy + (*HeaderPolicy)(nil), // 2: checkconfig.HeaderPolicy + (*TDQuoteBodyPolicy)(nil), // 3: checkconfig.TDQuoteBodyPolicy + (*PCKPolicy)(nil), // 4: checkconfig.PCKPolicy + (*RootOfTrust)(nil), // 5: checkconfig.RootOfTrust + (*Config)(nil), // 6: checkconfig.Config } var file_checkconfig_proto_depIdxs = []int32{ - 1, // 0: checkconfig.Policy.header_policy:type_name -> checkconfig.HeaderPolicy - 2, // 1: checkconfig.Policy.td_quote_body_policy:type_name -> checkconfig.TDQuoteBodyPolicy - 0, // 2: checkconfig.Config.policy:type_name -> checkconfig.Policy - 3, // 3: checkconfig.Config.root_of_trust:type_name -> checkconfig.RootOfTrust - 4, // [4:4] is the sub-list for method output_type - 4, // [4:4] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 2, // 0: checkconfig.Policy.header_policy:type_name -> checkconfig.HeaderPolicy + 3, // 1: checkconfig.Policy.td_quote_body_policy:type_name -> checkconfig.TDQuoteBodyPolicy + 4, // 2: checkconfig.Policy.pck_policy:type_name -> checkconfig.PCKPolicy + 0, // 3: checkconfig.PCKPolicy.sgx_type:type_name -> checkconfig.SGXType + 1, // 4: checkconfig.Config.policy:type_name -> checkconfig.Policy + 5, // 5: checkconfig.Config.root_of_trust:type_name -> checkconfig.RootOfTrust + 6, // [6:6] is the sub-list for method output_type + 6, // [6:6] is the sub-list for method input_type + 6, // [6:6] is the sub-list for extension type_name + 6, // [6:6] is the sub-list for extension extendee + 0, // [0:6] is the sub-list for field type_name } func init() { file_checkconfig_proto_init() } @@ -584,7 +706,7 @@ func file_checkconfig_proto_init() { } } file_checkconfig_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RootOfTrust); i { + switch v := v.(*PCKPolicy); i { case 0: return &v.state case 1: @@ -596,6 +718,18 @@ func file_checkconfig_proto_init() { } } file_checkconfig_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RootOfTrust); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_checkconfig_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Config); i { case 0: return &v.state @@ -608,18 +742,20 @@ func file_checkconfig_proto_init() { } } } + file_checkconfig_proto_msgTypes[3].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_checkconfig_proto_rawDesc, - NumEnums: 0, - NumMessages: 5, + NumEnums: 1, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, GoTypes: file_checkconfig_proto_goTypes, DependencyIndexes: file_checkconfig_proto_depIdxs, + EnumInfos: file_checkconfig_proto_enumTypes, MessageInfos: file_checkconfig_proto_msgTypes, }.Build() File_checkconfig_proto = out.File diff --git a/tools/check/check.go b/tools/check/check.go index 403804a..32e2cee 100644 --- a/tools/check/check.go +++ b/tools/check/check.go @@ -109,6 +109,8 @@ var ( minqesvn = flag.String("minimum_qe_svn", "", "The minimum acceptable value for QE_SVN field.") minpcesvn = flag.String("minimum_pce_svn", "", "The minimum acceptable value for PCE_SVN field.") + sgxtype = flag.String("sgx_type", "", "An acceptable value for SGXType field.") + // Optional Bool checkcrl = flag.String("check_crl", "", "Download and check the CRL for revoked certificates. -get_collateral must be true.") getcollateral = flag.String("get_collateral", "", "If true, then permitted to download necessary collaterals for additional checks.") @@ -119,7 +121,7 @@ var ( // Assign the values of the flags to the corresponding proto fields config = &ccpb.Config{ RootOfTrust: &ccpb.RootOfTrust{}, - Policy: &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}}, + Policy: &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}, PckPolicy: &ccpb.PCKPolicy{}}, } ) @@ -232,7 +234,7 @@ func parseConfig(path string) error { config.RootOfTrust = &ccpb.RootOfTrust{} } if config.Policy == nil { - config.Policy = &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}} + config.Policy = &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}, PckPolicy: &ccpb.PCKPolicy{}} } return nil } @@ -355,6 +357,17 @@ func populateConfig() error { } return nil } + setSGXType := func(dest **ccpb.SGXType, flag string) error { + if flag != "" { + val, ok := ccpb.SGXType_value[flag] + if !ok { + return fmt.Errorf("invalid -sgx_type=%s: expected one of Standard, Scalable, or ScalableWithIntegrity", flag) + } + sgxType := ccpb.SGXType(val) + *dest = &sgxType + } + return nil + } setNonNil(&policy.HeaderPolicy.QeVendorId, *qevendorid) setNonNil(&policy.TdQuoteBodyPolicy.MinimumTeeTcbSvn, *minteetcbsvn) @@ -370,6 +383,7 @@ func populateConfig() error { return multierr.Combine( setUint32(&policy.HeaderPolicy.MinimumQeSvn, "minimum_qe_svn", *minqesvn, defaultMinQeSvn), setUint32(&policy.HeaderPolicy.MinimumPceSvn, "minimum_pce_svn", *minpcesvn, defaultMinPceSvn), + setSGXType(&policy.PckPolicy.SgxType, *sgxtype), setRtmrs(&policy.TdQuoteBodyPolicy.Rtmrs, *rtmrs), ) } diff --git a/tools/check/check_test.go b/tools/check/check_test.go index 18f5fe8..e15847e 100644 --- a/tools/check/check_test.go +++ b/tools/check/check_test.go @@ -90,6 +90,11 @@ func setField(p *ccpb.Policy, policy string, name string, value any) { r := s.ProtoReflect() ty := r.Descriptor() r.Set(ty.Fields().ByName(protoreflect.Name(name)), protoreflect.ValueOf(value)) + } else if policy == "pck_policy" { + s := p.PckPolicy + r := s.ProtoReflect() + ty := r.Descriptor() + r.Set(ty.Fields().ByName(protoreflect.Name(name)), protoreflect.ValueOf(value)) } } @@ -115,6 +120,13 @@ func uint32setter(name string, policy string) setterFn { } } +func enumSetter(name string, policy string, values map[string]int32) setterFn { + return func(p *ccpb.Policy, value string, _ *testing.T) bool { + setField(p, policy, name, protoreflect.EnumNumber(values[value])) + return false + } +} + func testCases() []testCase { return []testCase{ { @@ -200,6 +212,16 @@ func testCases() []testCase { bad: []string{"6c62dec1b8191749a31dab490be532a35944dea47caef1f980863993d9899545eb7406a38d1eed313b987a467dacead6f0c87a6d766c66f6f29f8acb281f2213"}, setter: bytesSetter("report_data", "td_quote_body_policy"), }, + { + flag: "sgx_type", + good: "Scalable", + bad: []string{ + "Standard", + "ScalableWithIntegrity", + "non-existing type", + }, + setter: enumSetter("sgx_type", "pck_policy", ccpb.SGXType_value), + }, } } @@ -288,7 +310,7 @@ func TestRtmrs(t *testing.T) { func TestCheckGoodFields(t *testing.T) { for _, tc := range testCases() { t.Run(tc.flag, func(t *testing.T) { - p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}} + p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}, PckPolicy: &ccpb.PCKPolicy{}} if tc.setter(p, tc.good, t) { t.Fatal("unexpected parse failure") } @@ -306,7 +328,7 @@ func TestCheckBadFields(t *testing.T) { for _, tc := range testCases() { for i, bad := range tc.bad { t.Run(fmt.Sprintf("%s_bad[%d]", tc.flag, i+1), func(t *testing.T) { - p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}} + p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}, PckPolicy: &ccpb.PCKPolicy{}} if tc.setter(p, bad, t) { return } @@ -325,7 +347,7 @@ func TestCheckGoodFlagOverridesBadField(t *testing.T) { for _, tc := range testCases() { for i, bad := range tc.bad { t.Run(fmt.Sprintf("%s_bad[%d]", tc.flag, i+1), func(t *testing.T) { - p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}} + p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}, PckPolicy: &ccpb.PCKPolicy{}} if tc.setter(p, bad, t) { return } @@ -344,7 +366,7 @@ func TestCheckBadFlagOverridesGoodField(t *testing.T) { for _, tc := range testCases() { for i, bad := range tc.bad { t.Run(fmt.Sprintf("%s_bad[%d]", tc.flag, i+1), func(t *testing.T) { - p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}} + p := &ccpb.Policy{HeaderPolicy: &ccpb.HeaderPolicy{}, TdQuoteBodyPolicy: &ccpb.TDQuoteBodyPolicy{}, PckPolicy: &ccpb.PCKPolicy{}} if tc.setter(p, tc.good, t) { t.Fatal("unexpected parse failure") } diff --git a/validate/validate.go b/validate/validate.go index 5fb1572..19a67ea 100644 --- a/validate/validate.go +++ b/validate/validate.go @@ -17,11 +17,15 @@ package validate import ( "bytes" + "crypto/x509" "encoding/binary" "encoding/hex" + "encoding/pem" + "errors" "fmt" "github.com/google/go-tdx-guest/abi" + "github.com/google/go-tdx-guest/pcs" ccpb "github.com/google/go-tdx-guest/proto/checkconfig" pb "github.com/google/go-tdx-guest/proto/tdx" vr "github.com/google/go-tdx-guest/verify" @@ -51,6 +55,7 @@ const ( type Options struct { HeaderOptions HeaderOptions TdQuoteBodyOptions TdQuoteBodyOptions + PCKOptions PCKOptions } // HeaderOptions represents validation options for a TDX attestation Quote Header. @@ -92,6 +97,12 @@ type TdQuoteBodyOptions struct { EnableTdDebugCheck bool } +// PCKOptions represents validation options for the PCK certificate in side a TDX attestation. +type PCKOptions struct { + // SgxType is the expected SGXType. Not checked if nil. + SgxType *pcs.SGXType +} + func lengthCheck(name string, length int, value []byte) error { if value != nil && len(value) != length { return fmt.Errorf("option %q length is %d. Want %d", name, len(value), length) @@ -169,6 +180,10 @@ func PolicyToOptions(policy *ccpb.Policy) (*Options, error) { }, } + if policy.PckPolicy != nil && policy.PckPolicy.SgxType != nil { + value := pcs.SGXType(*policy.PckPolicy.SgxType) + opts.PCKOptions.SgxType = &value + } if err := checkOptionsLengths(opts); err != nil { return nil, err } @@ -328,6 +343,32 @@ func validateTdAttributes(value []byte, fixed1, fixed0 uint64, enableTdDebugChec return nil } +func validatePck(quote *pb.QuoteV4, opts *PCKOptions) error { + // Extract the PCK + certChainBytes := quote.GetSignedData().GetCertificationData().GetQeReportCertificationData().GetPckCertificateChainData().GetPckCertChain() + if certChainBytes == nil { + return errors.New("PCK certificate chain is empty") + } + pck, rem := pem.Decode(certChainBytes) + if pck == nil || len(rem) == 0 || pck.Type != "CERTIFICATE" { + return errors.New("incomplete PCK Certificate chain found, should contain 3 concatenated PEM-formatted 'CERTIFICATE'-type block (PCK Leaf Cert||Intermediate CA Cert||Root CA Cert)") + } + pckCert, err := x509.ParseCertificate(pck.Bytes) + if err != nil { + return fmt.Errorf("could not interpret PCK leaf certificate DER bytes: %v", err) + } + + // Validate the PCK. + exts, err := pcs.PckCertificateExtensions(pckCert) + if err != nil { + return fmt.Errorf("could not get PCK certificate extensions: %v", err) + } + if opts.SgxType != nil && *opts.SgxType != exts.SGXType { + return fmt.Errorf("PCK extension SGXType is %d. Expect %d", *opts.SgxType, exts.SGXType) + } + return nil +} + // TdxQuote validates fields of the protobuf representation of an attestation Quote // against expectations depending on supported quote formats - QuoteV4. // Does not check the attestation certificates or signature. @@ -355,6 +396,7 @@ func tdxQuoteV4(quote *pb.QuoteV4, options *Options) error { minVersionCheck(quote, options), validateXfam(quote.GetTdQuoteBody().GetXfam(), xfamFixed1, xfamFixed0), validateTdAttributes(quote.GetTdQuoteBody().GetTdAttributes(), tdAttributesFixed1, tdAttributesFixed0, options.TdQuoteBodyOptions.EnableTdDebugCheck), + validatePck(quote, &options.PCKOptions), ) } diff --git a/validate/validate_test.go b/validate/validate_test.go index 83d6f15..f1419f8 100644 --- a/validate/validate_test.go +++ b/validate/validate_test.go @@ -18,6 +18,7 @@ import ( "strings" "testing" + "github.com/google/go-tdx-guest/pcs" pb "github.com/google/go-tdx-guest/proto/tdx" vr "github.com/google/go-tdx-guest/verify" @@ -73,6 +74,7 @@ func TestTdxQuote(t *testing.T) { 0x59, 0x44, 0xde, 0xa4, 0x7c, 0xae, 0xf1, 0xf9, 0x80, 0x86, 0x39, 0x93, 0xd9, 0x89, 0x95, 0x45, 0xeb, 0x74, 0x6, 0xa3, 0x8d, 0x1e, 0xed, 0x31, 0x3b, 0x98, 0x7a, 0x46, 0x7d, 0xac, 0xea, 0xd6, 0xf0, 0xc8, 0x7a, 0x6d, 0x76, 0x6c, 0x66, 0xf6, 0xf2, 0x9f, 0x8a, 0xcb, 0x28, 0x1f, 0x11, 0x13} + sgxType := pcs.SGXTypeScalable mknonce := func(front []byte) []byte { result := make([]byte, 64) @@ -140,6 +142,9 @@ func TestTdxQuote(t *testing.T) { ReportData: reportData, EnableTdDebugCheck: true, }, + PCKOptions: PCKOptions{ + SgxType: &sgxType, + }, }, }, { @@ -295,6 +300,14 @@ func TestTdxQuote(t *testing.T) { }, wantErr: "TD_ATTRIBUTES DEBUG bit is set, but debug is not allowed", }, + { + name: "Test incorrect SGXType", + quote: quote12345, + opts: &Options{ + PCKOptions: PCKOptions{SgxType: new(pcs.SGXType)}, + }, + wantErr: "PCK extension SGXType", + }, } for _, tc := range tests { diff --git a/verify/verify_test.go b/verify/verify_test.go index 0350611..78b29ec 100644 --- a/verify/verify_test.go +++ b/verify/verify_test.go @@ -105,6 +105,7 @@ func TestPckCertificateExtensions(t *testing.T) { pckExt.PPID = hex.EncodeToString(ppidBytes) pckExt.FMSPC = hex.EncodeToString(fmspcBytes) pckExt.PCEID = hex.EncodeToString(pceIDBytes) + pckExt.SGXType = pcs.SGXTypeScalable pckExtTcb := &pcs.PckCertTCB{ PCESvn: 11, CPUSvn: []byte{3, 3, 2, 2, 2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0},