mirror of
https://github.com/google/go-attestation.git
synced 2024-12-19 04:57:59 +00:00
Remove proto/ & verifier/ (#111)
This commit is contained in:
parent
3381804469
commit
d029846083
570
proto/tpm.pb.go
570
proto/tpm.pb.go
@ -1,570 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: tpm.proto
|
||||
|
||||
package go_attestation
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type TpmVersion int32
|
||||
|
||||
const (
|
||||
TpmVersion_TPM_VERSION_UNSPECIFIED TpmVersion = 0
|
||||
TpmVersion_TPM_12 TpmVersion = 1
|
||||
TpmVersion_TPM_20 TpmVersion = 2
|
||||
)
|
||||
|
||||
var TpmVersion_name = map[int32]string{
|
||||
0: "TPM_VERSION_UNSPECIFIED",
|
||||
1: "TPM_12",
|
||||
2: "TPM_20",
|
||||
}
|
||||
|
||||
var TpmVersion_value = map[string]int32{
|
||||
"TPM_VERSION_UNSPECIFIED": 0,
|
||||
"TPM_12": 1,
|
||||
"TPM_20": 2,
|
||||
}
|
||||
|
||||
func (x TpmVersion) String() string {
|
||||
return proto.EnumName(TpmVersion_name, int32(x))
|
||||
}
|
||||
|
||||
func (TpmVersion) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{0}
|
||||
}
|
||||
|
||||
type TpmInterface int32
|
||||
|
||||
const (
|
||||
TpmInterface_TPM_INTERFACE_UNSPECIFIED TpmInterface = 0
|
||||
TpmInterface_DIRECT TpmInterface = 1
|
||||
TpmInterface_KERNEL_MANAGED TpmInterface = 2
|
||||
TpmInterface_DAEMON_MANAGED TpmInterface = 3
|
||||
)
|
||||
|
||||
var TpmInterface_name = map[int32]string{
|
||||
0: "TPM_INTERFACE_UNSPECIFIED",
|
||||
1: "DIRECT",
|
||||
2: "KERNEL_MANAGED",
|
||||
3: "DAEMON_MANAGED",
|
||||
}
|
||||
|
||||
var TpmInterface_value = map[string]int32{
|
||||
"TPM_INTERFACE_UNSPECIFIED": 0,
|
||||
"DIRECT": 1,
|
||||
"KERNEL_MANAGED": 2,
|
||||
"DAEMON_MANAGED": 3,
|
||||
}
|
||||
|
||||
func (x TpmInterface) String() string {
|
||||
return proto.EnumName(TpmInterface_name, int32(x))
|
||||
}
|
||||
|
||||
func (TpmInterface) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{1}
|
||||
}
|
||||
|
||||
type EndorsementKey_DataType int32
|
||||
|
||||
const (
|
||||
EndorsementKey_DATA_TYPE_UNSPECIFIED EndorsementKey_DataType = 0
|
||||
EndorsementKey_PUBLIC_BLOB EndorsementKey_DataType = 1
|
||||
EndorsementKey_X509_CERT_BLOB EndorsementKey_DataType = 2
|
||||
)
|
||||
|
||||
var EndorsementKey_DataType_name = map[int32]string{
|
||||
0: "DATA_TYPE_UNSPECIFIED",
|
||||
1: "PUBLIC_BLOB",
|
||||
2: "X509_CERT_BLOB",
|
||||
}
|
||||
|
||||
var EndorsementKey_DataType_value = map[string]int32{
|
||||
"DATA_TYPE_UNSPECIFIED": 0,
|
||||
"PUBLIC_BLOB": 1,
|
||||
"X509_CERT_BLOB": 2,
|
||||
}
|
||||
|
||||
func (x EndorsementKey_DataType) String() string {
|
||||
return proto.EnumName(EndorsementKey_DataType_name, int32(x))
|
||||
}
|
||||
|
||||
func (EndorsementKey_DataType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{1, 0}
|
||||
}
|
||||
|
||||
type ChallengeInfo_ChallengeType int32
|
||||
|
||||
const (
|
||||
ChallengeInfo_CHALLENGE_UNSPECIFIED ChallengeInfo_ChallengeType = 0
|
||||
ChallengeInfo_CHALLENGE_CA ChallengeInfo_ChallengeType = 1
|
||||
)
|
||||
|
||||
var ChallengeInfo_ChallengeType_name = map[int32]string{
|
||||
0: "CHALLENGE_UNSPECIFIED",
|
||||
1: "CHALLENGE_CA",
|
||||
}
|
||||
|
||||
var ChallengeInfo_ChallengeType_value = map[string]int32{
|
||||
"CHALLENGE_UNSPECIFIED": 0,
|
||||
"CHALLENGE_CA": 1,
|
||||
}
|
||||
|
||||
func (x ChallengeInfo_ChallengeType) String() string {
|
||||
return proto.EnumName(ChallengeInfo_ChallengeType_name, int32(x))
|
||||
}
|
||||
|
||||
func (ChallengeInfo_ChallengeType) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{5, 0}
|
||||
}
|
||||
|
||||
// TpmInfo encapsulates version / device information
|
||||
// about the TPM, and how the attestation client interfaces
|
||||
// with it.
|
||||
type TpmInfo struct {
|
||||
TpmVersion TpmVersion `protobuf:"varint,1,opt,name=tpm_version,json=tpmVersion,proto3,enum=go_attestation.TpmVersion" json:"tpm_version,omitempty"`
|
||||
Manufacturer string `protobuf:"bytes,2,opt,name=manufacturer,proto3" json:"manufacturer,omitempty"`
|
||||
TpmInterface TpmInterface `protobuf:"varint,3,opt,name=tpm_interface,json=tpmInterface,proto3,enum=go_attestation.TpmInterface" json:"tpm_interface,omitempty"`
|
||||
// This number represents the version of the support code which
|
||||
// interfaces with the TPM.
|
||||
TpmInterfaceVersion uint32 `protobuf:"varint,4,opt,name=tpm_interface_version,json=tpmInterfaceVersion,proto3" json:"tpm_interface_version,omitempty"` // Deprecated: Do not use.
|
||||
// This is the string provided by the TPM.
|
||||
TpmOpaqueInfo string `protobuf:"bytes,5,opt,name=tpm_opaque_info,json=tpmOpaqueInfo,proto3" json:"tpm_opaque_info,omitempty"`
|
||||
// This is set if challenges must be generated
|
||||
// in TrouSerS format for TPM 1.2 devices.
|
||||
TrousersFormat bool `protobuf:"varint,6,opt,name=trousers_format,json=trousersFormat,proto3" json:"trousers_format,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TpmInfo) Reset() { *m = TpmInfo{} }
|
||||
func (m *TpmInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*TpmInfo) ProtoMessage() {}
|
||||
func (*TpmInfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{0}
|
||||
}
|
||||
|
||||
func (m *TpmInfo) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_TpmInfo.Unmarshal(m, b)
|
||||
}
|
||||
func (m *TpmInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_TpmInfo.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *TpmInfo) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_TpmInfo.Merge(m, src)
|
||||
}
|
||||
func (m *TpmInfo) XXX_Size() int {
|
||||
return xxx_messageInfo_TpmInfo.Size(m)
|
||||
}
|
||||
func (m *TpmInfo) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_TpmInfo.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_TpmInfo proto.InternalMessageInfo
|
||||
|
||||
func (m *TpmInfo) GetTpmVersion() TpmVersion {
|
||||
if m != nil {
|
||||
return m.TpmVersion
|
||||
}
|
||||
return TpmVersion_TPM_VERSION_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (m *TpmInfo) GetManufacturer() string {
|
||||
if m != nil {
|
||||
return m.Manufacturer
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TpmInfo) GetTpmInterface() TpmInterface {
|
||||
if m != nil {
|
||||
return m.TpmInterface
|
||||
}
|
||||
return TpmInterface_TPM_INTERFACE_UNSPECIFIED
|
||||
}
|
||||
|
||||
// Deprecated: Do not use.
|
||||
func (m *TpmInfo) GetTpmInterfaceVersion() uint32 {
|
||||
if m != nil {
|
||||
return m.TpmInterfaceVersion
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *TpmInfo) GetTpmOpaqueInfo() string {
|
||||
if m != nil {
|
||||
return m.TpmOpaqueInfo
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *TpmInfo) GetTrousersFormat() bool {
|
||||
if m != nil {
|
||||
return m.TrousersFormat
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type EndorsementKey struct {
|
||||
Datatype EndorsementKey_DataType `protobuf:"varint,1,opt,name=datatype,proto3,enum=go_attestation.EndorsementKey_DataType" json:"datatype,omitempty"`
|
||||
Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EndorsementKey) Reset() { *m = EndorsementKey{} }
|
||||
func (m *EndorsementKey) String() string { return proto.CompactTextString(m) }
|
||||
func (*EndorsementKey) ProtoMessage() {}
|
||||
func (*EndorsementKey) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{1}
|
||||
}
|
||||
|
||||
func (m *EndorsementKey) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EndorsementKey.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EndorsementKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EndorsementKey.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EndorsementKey) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EndorsementKey.Merge(m, src)
|
||||
}
|
||||
func (m *EndorsementKey) XXX_Size() int {
|
||||
return xxx_messageInfo_EndorsementKey.Size(m)
|
||||
}
|
||||
func (m *EndorsementKey) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EndorsementKey.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EndorsementKey proto.InternalMessageInfo
|
||||
|
||||
func (m *EndorsementKey) GetDatatype() EndorsementKey_DataType {
|
||||
if m != nil {
|
||||
return m.Datatype
|
||||
}
|
||||
return EndorsementKey_DATA_TYPE_UNSPECIFIED
|
||||
}
|
||||
|
||||
func (m *EndorsementKey) GetData() []byte {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tpm20AikInfo describes an AIK using TPM 2.0 structures.
|
||||
type Tpm20AikInfo struct {
|
||||
// This is a TPMT_PUBLIC structure.
|
||||
PublicBlob []byte `protobuf:"bytes,1,opt,name=public_blob,json=publicBlob,proto3" json:"public_blob,omitempty"`
|
||||
// This is a TPMS_CREATION_DATA structure.
|
||||
CreationData []byte `protobuf:"bytes,2,opt,name=creation_data,json=creationData,proto3" json:"creation_data,omitempty"`
|
||||
// This is a TPMU_ATTEST structure, with the dynamic section
|
||||
// containing a CREATION_INFO structure.
|
||||
AttestationData []byte `protobuf:"bytes,3,opt,name=attestation_data,json=attestationData,proto3" json:"attestation_data,omitempty"`
|
||||
// This is a TPMT_SIGNATURE structure.
|
||||
SignatureData []byte `protobuf:"bytes,4,opt,name=signature_data,json=signatureData,proto3" json:"signature_data,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Tpm20AikInfo) Reset() { *m = Tpm20AikInfo{} }
|
||||
func (m *Tpm20AikInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*Tpm20AikInfo) ProtoMessage() {}
|
||||
func (*Tpm20AikInfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{2}
|
||||
}
|
||||
|
||||
func (m *Tpm20AikInfo) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Tpm20AikInfo.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Tpm20AikInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Tpm20AikInfo.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Tpm20AikInfo) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Tpm20AikInfo.Merge(m, src)
|
||||
}
|
||||
func (m *Tpm20AikInfo) XXX_Size() int {
|
||||
return xxx_messageInfo_Tpm20AikInfo.Size(m)
|
||||
}
|
||||
func (m *Tpm20AikInfo) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Tpm20AikInfo.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Tpm20AikInfo proto.InternalMessageInfo
|
||||
|
||||
func (m *Tpm20AikInfo) GetPublicBlob() []byte {
|
||||
if m != nil {
|
||||
return m.PublicBlob
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Tpm20AikInfo) GetCreationData() []byte {
|
||||
if m != nil {
|
||||
return m.CreationData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Tpm20AikInfo) GetAttestationData() []byte {
|
||||
if m != nil {
|
||||
return m.AttestationData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Tpm20AikInfo) GetSignatureData() []byte {
|
||||
if m != nil {
|
||||
return m.SignatureData
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Tpm12AikInfo describes an AIK using TPM 1.2 structures.
|
||||
type Tpm12AikInfo struct {
|
||||
// This is a TPM_PUBKEY structure.
|
||||
PublicBlob []byte `protobuf:"bytes,1,opt,name=public_blob,json=publicBlob,proto3" json:"public_blob,omitempty"`
|
||||
// This is auxillary data, provided for the purpose of debugging.
|
||||
// on Windows devices, this represents the contents of PCP_ID_BINDING.
|
||||
Aux []byte `protobuf:"bytes,2,opt,name=aux,proto3" json:"aux,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Tpm12AikInfo) Reset() { *m = Tpm12AikInfo{} }
|
||||
func (m *Tpm12AikInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*Tpm12AikInfo) ProtoMessage() {}
|
||||
func (*Tpm12AikInfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{3}
|
||||
}
|
||||
|
||||
func (m *Tpm12AikInfo) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Tpm12AikInfo.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Tpm12AikInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Tpm12AikInfo.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Tpm12AikInfo) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Tpm12AikInfo.Merge(m, src)
|
||||
}
|
||||
func (m *Tpm12AikInfo) XXX_Size() int {
|
||||
return xxx_messageInfo_Tpm12AikInfo.Size(m)
|
||||
}
|
||||
func (m *Tpm12AikInfo) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Tpm12AikInfo.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Tpm12AikInfo proto.InternalMessageInfo
|
||||
|
||||
func (m *Tpm12AikInfo) GetPublicBlob() []byte {
|
||||
if m != nil {
|
||||
return m.PublicBlob
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Tpm12AikInfo) GetAux() []byte {
|
||||
if m != nil {
|
||||
return m.Aux
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AikInfo describes the public key, parameters, and creation information
|
||||
// of an attestation identity key.
|
||||
type AikInfo struct {
|
||||
// Types that are valid to be assigned to TpmAikInfo:
|
||||
// *AikInfo_Tpm20
|
||||
// *AikInfo_Tpm12
|
||||
TpmAikInfo isAikInfo_TpmAikInfo `protobuf_oneof:"tpm_aik_info"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AikInfo) Reset() { *m = AikInfo{} }
|
||||
func (m *AikInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*AikInfo) ProtoMessage() {}
|
||||
func (*AikInfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{4}
|
||||
}
|
||||
|
||||
func (m *AikInfo) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_AikInfo.Unmarshal(m, b)
|
||||
}
|
||||
func (m *AikInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_AikInfo.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *AikInfo) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_AikInfo.Merge(m, src)
|
||||
}
|
||||
func (m *AikInfo) XXX_Size() int {
|
||||
return xxx_messageInfo_AikInfo.Size(m)
|
||||
}
|
||||
func (m *AikInfo) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_AikInfo.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_AikInfo proto.InternalMessageInfo
|
||||
|
||||
type isAikInfo_TpmAikInfo interface {
|
||||
isAikInfo_TpmAikInfo()
|
||||
}
|
||||
|
||||
type AikInfo_Tpm20 struct {
|
||||
Tpm20 *Tpm20AikInfo `protobuf:"bytes,1,opt,name=tpm20,proto3,oneof"`
|
||||
}
|
||||
|
||||
type AikInfo_Tpm12 struct {
|
||||
Tpm12 *Tpm12AikInfo `protobuf:"bytes,2,opt,name=tpm12,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*AikInfo_Tpm20) isAikInfo_TpmAikInfo() {}
|
||||
|
||||
func (*AikInfo_Tpm12) isAikInfo_TpmAikInfo() {}
|
||||
|
||||
func (m *AikInfo) GetTpmAikInfo() isAikInfo_TpmAikInfo {
|
||||
if m != nil {
|
||||
return m.TpmAikInfo
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AikInfo) GetTpm20() *Tpm20AikInfo {
|
||||
if x, ok := m.GetTpmAikInfo().(*AikInfo_Tpm20); ok {
|
||||
return x.Tpm20
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *AikInfo) GetTpm12() *Tpm12AikInfo {
|
||||
if x, ok := m.GetTpmAikInfo().(*AikInfo_Tpm12); ok {
|
||||
return x.Tpm12
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// XXX_OneofWrappers is for the internal use of the proto package.
|
||||
func (*AikInfo) XXX_OneofWrappers() []interface{} {
|
||||
return []interface{}{
|
||||
(*AikInfo_Tpm20)(nil),
|
||||
(*AikInfo_Tpm12)(nil),
|
||||
}
|
||||
}
|
||||
|
||||
// ChallengeInfo describes which challenge a nonce corresponds to.
|
||||
type ChallengeInfo struct {
|
||||
Type ChallengeInfo_ChallengeType `protobuf:"varint,1,opt,name=type,proto3,enum=go_attestation.ChallengeInfo_ChallengeType" json:"type,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ChallengeInfo) Reset() { *m = ChallengeInfo{} }
|
||||
func (m *ChallengeInfo) String() string { return proto.CompactTextString(m) }
|
||||
func (*ChallengeInfo) ProtoMessage() {}
|
||||
func (*ChallengeInfo) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_63ac7bc02f9d1279, []int{5}
|
||||
}
|
||||
|
||||
func (m *ChallengeInfo) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ChallengeInfo.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ChallengeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ChallengeInfo.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ChallengeInfo) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ChallengeInfo.Merge(m, src)
|
||||
}
|
||||
func (m *ChallengeInfo) XXX_Size() int {
|
||||
return xxx_messageInfo_ChallengeInfo.Size(m)
|
||||
}
|
||||
func (m *ChallengeInfo) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ChallengeInfo.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ChallengeInfo proto.InternalMessageInfo
|
||||
|
||||
func (m *ChallengeInfo) GetType() ChallengeInfo_ChallengeType {
|
||||
if m != nil {
|
||||
return m.Type
|
||||
}
|
||||
return ChallengeInfo_CHALLENGE_UNSPECIFIED
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("go_attestation.TpmVersion", TpmVersion_name, TpmVersion_value)
|
||||
proto.RegisterEnum("go_attestation.TpmInterface", TpmInterface_name, TpmInterface_value)
|
||||
proto.RegisterEnum("go_attestation.EndorsementKey_DataType", EndorsementKey_DataType_name, EndorsementKey_DataType_value)
|
||||
proto.RegisterEnum("go_attestation.ChallengeInfo_ChallengeType", ChallengeInfo_ChallengeType_name, ChallengeInfo_ChallengeType_value)
|
||||
proto.RegisterType((*TpmInfo)(nil), "go_attestation.TpmInfo")
|
||||
proto.RegisterType((*EndorsementKey)(nil), "go_attestation.EndorsementKey")
|
||||
proto.RegisterType((*Tpm20AikInfo)(nil), "go_attestation.Tpm20AikInfo")
|
||||
proto.RegisterType((*Tpm12AikInfo)(nil), "go_attestation.Tpm12AikInfo")
|
||||
proto.RegisterType((*AikInfo)(nil), "go_attestation.AikInfo")
|
||||
proto.RegisterType((*ChallengeInfo)(nil), "go_attestation.ChallengeInfo")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("tpm.proto", fileDescriptor_63ac7bc02f9d1279) }
|
||||
|
||||
var fileDescriptor_63ac7bc02f9d1279 = []byte{
|
||||
// 641 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0xdb, 0x6e, 0xda, 0x4a,
|
||||
0x14, 0x8d, 0x81, 0xdc, 0x36, 0xc6, 0x58, 0x73, 0x14, 0x1d, 0x72, 0x2e, 0x2a, 0x72, 0xd5, 0x86,
|
||||
0xa6, 0x12, 0x0a, 0xee, 0x45, 0xaa, 0x5a, 0xa9, 0x32, 0x66, 0x92, 0xb8, 0x21, 0x06, 0x4d, 0x9c,
|
||||
0xa8, 0x7d, 0xb2, 0x06, 0x32, 0xa4, 0x56, 0xf0, 0xa5, 0x66, 0xa8, 0x9a, 0x0f, 0xe8, 0x6b, 0x3f,
|
||||
0xa3, 0x7f, 0xd0, 0x7e, 0x5f, 0xe5, 0x31, 0x36, 0x86, 0xe6, 0xa1, 0x6f, 0xdb, 0x6b, 0xd6, 0xda,
|
||||
0xb3, 0xf6, 0x66, 0x0d, 0xb0, 0xcb, 0x23, 0xbf, 0x1d, 0xc5, 0x21, 0x0f, 0x91, 0x72, 0x13, 0xba,
|
||||
0x94, 0x73, 0x36, 0xe3, 0x94, 0x7b, 0x61, 0xa0, 0xfd, 0x2c, 0xc1, 0xb6, 0x13, 0xf9, 0x56, 0x30,
|
||||
0x09, 0xd1, 0x6b, 0xa8, 0xf2, 0xc8, 0x77, 0x3f, 0xb3, 0x78, 0xe6, 0x85, 0x41, 0x43, 0x6a, 0x4a,
|
||||
0x2d, 0x45, 0xff, 0xa7, 0xbd, 0xaa, 0x68, 0x3b, 0x91, 0x7f, 0x95, 0x32, 0x08, 0xf0, 0xbc, 0x46,
|
||||
0x1a, 0xc8, 0x3e, 0x0d, 0xe6, 0x13, 0x3a, 0xe6, 0xf3, 0x98, 0xc5, 0x8d, 0x52, 0x53, 0x6a, 0xed,
|
||||
0x92, 0x15, 0x0c, 0x19, 0x50, 0x4b, 0x2e, 0xf0, 0x02, 0xce, 0xe2, 0x09, 0x1d, 0xb3, 0x46, 0x59,
|
||||
0x5c, 0xf1, 0xdf, 0x3d, 0x57, 0x58, 0x19, 0x87, 0xc8, 0xbc, 0xf0, 0x85, 0x5e, 0xc2, 0xde, 0x4a,
|
||||
0x8b, 0xdc, 0x6d, 0xa5, 0x29, 0xb5, 0x6a, 0xdd, 0x52, 0x43, 0x22, 0x7f, 0x15, 0x05, 0x99, 0xbd,
|
||||
0xc7, 0x50, 0x4f, 0x74, 0x61, 0x44, 0x3f, 0xcd, 0x99, 0xeb, 0x05, 0x93, 0xb0, 0xb1, 0x29, 0x1c,
|
||||
0x26, 0x8e, 0x06, 0x02, 0x15, 0x3b, 0x38, 0x80, 0x3a, 0x8f, 0xc3, 0xf9, 0x8c, 0xc5, 0x33, 0x77,
|
||||
0x12, 0xc6, 0x3e, 0xe5, 0x8d, 0xad, 0xa6, 0xd4, 0xda, 0x21, 0x4a, 0x06, 0x1f, 0x0b, 0x54, 0xfb,
|
||||
0x21, 0x81, 0x82, 0x83, 0xeb, 0x30, 0x9e, 0x31, 0x9f, 0x05, 0xfc, 0x8c, 0xdd, 0x21, 0x13, 0x76,
|
||||
0xae, 0x29, 0xa7, 0xfc, 0x2e, 0x62, 0x8b, 0xe5, 0x1d, 0xac, 0x4f, 0xb6, 0xaa, 0x68, 0xf7, 0x28,
|
||||
0xa7, 0xce, 0x5d, 0xc4, 0x48, 0x2e, 0x44, 0x08, 0x2a, 0x49, 0x2d, 0xf6, 0x27, 0x13, 0x51, 0x6b,
|
||||
0xef, 0x60, 0x27, 0x63, 0xa2, 0x7d, 0xd8, 0xeb, 0x19, 0x8e, 0xe1, 0x3a, 0x1f, 0x86, 0xd8, 0xbd,
|
||||
0xb4, 0x2f, 0x86, 0xd8, 0xb4, 0x8e, 0x2d, 0xdc, 0x53, 0x37, 0x50, 0x1d, 0xaa, 0xc3, 0xcb, 0x6e,
|
||||
0xdf, 0x32, 0xdd, 0x6e, 0x7f, 0xd0, 0x55, 0x25, 0x84, 0x40, 0x79, 0xff, 0xe2, 0xe8, 0x95, 0x6b,
|
||||
0x62, 0xe2, 0xa4, 0x58, 0x49, 0xfb, 0x2e, 0x81, 0xec, 0x44, 0xbe, 0x7e, 0x64, 0x78, 0xb7, 0x62,
|
||||
0xe2, 0x07, 0x50, 0x8d, 0xe6, 0xa3, 0xa9, 0x37, 0x76, 0x47, 0xd3, 0x70, 0x24, 0x8c, 0xcb, 0x04,
|
||||
0x52, 0xa8, 0x3b, 0x0d, 0x47, 0xe8, 0x21, 0xd4, 0xc6, 0x31, 0x13, 0xfe, 0xdd, 0x82, 0x35, 0x39,
|
||||
0x03, 0x13, 0x6b, 0xe8, 0x09, 0xa8, 0x85, 0x39, 0x53, 0x5e, 0x59, 0xf0, 0xea, 0x05, 0x5c, 0x50,
|
||||
0x1f, 0x81, 0x32, 0xf3, 0x6e, 0x02, 0x9a, 0x64, 0x22, 0x25, 0x56, 0x04, 0xb1, 0x96, 0xa3, 0x09,
|
||||
0x4d, 0x33, 0x84, 0xcf, 0x8e, 0xfe, 0xc7, 0x3e, 0x55, 0x28, 0xd3, 0xf9, 0x97, 0x85, 0xbb, 0xa4,
|
||||
0xd4, 0xbe, 0x4a, 0xb0, 0x9d, 0xc9, 0x9f, 0xc3, 0x26, 0x4f, 0xc6, 0x16, 0xc2, 0xea, 0xbd, 0x99,
|
||||
0xcb, 0x77, 0x72, 0xba, 0x41, 0x52, 0xf2, 0x42, 0xd5, 0xd1, 0x45, 0xd7, 0xfb, 0x55, 0xb9, 0xc3,
|
||||
0x85, 0xaa, 0xa3, 0x77, 0x15, 0x48, 0x42, 0xeb, 0x52, 0xef, 0x56, 0x24, 0x4d, 0xfb, 0x26, 0x41,
|
||||
0xcd, 0xfc, 0x48, 0xa7, 0x53, 0x16, 0xdc, 0xa4, 0x31, 0x7b, 0x0b, 0x95, 0x42, 0x4c, 0x9e, 0xae,
|
||||
0xb7, 0x5d, 0x21, 0x2f, 0xbf, 0x44, 0x54, 0x84, 0x50, 0x7b, 0x53, 0xe8, 0x98, 0xe5, 0xc2, 0x3c,
|
||||
0x35, 0xfa, 0x7d, 0x6c, 0x9f, 0xac, 0xe7, 0x42, 0x05, 0x79, 0x79, 0x64, 0x1a, 0xaa, 0x74, 0x68,
|
||||
0x00, 0x2c, 0x9f, 0x31, 0xfa, 0x17, 0xfe, 0x76, 0x86, 0xe7, 0xee, 0x15, 0x26, 0x17, 0xd6, 0xc0,
|
||||
0x5e, 0x13, 0x03, 0x6c, 0x25, 0x87, 0x1d, 0x5d, 0x95, 0xb2, 0x5a, 0x3f, 0x52, 0x4b, 0x87, 0x54,
|
||||
0xfc, 0x3c, 0xcb, 0x87, 0xf9, 0x3f, 0xec, 0x27, 0x67, 0x96, 0xed, 0x60, 0x72, 0x6c, 0x98, 0xf8,
|
||||
0xf7, 0x36, 0x3d, 0x8b, 0x60, 0xd3, 0x49, 0x63, 0x79, 0x86, 0x89, 0x8d, 0xfb, 0xee, 0xb9, 0x61,
|
||||
0x1b, 0x27, 0xb8, 0xa7, 0x96, 0x12, 0xac, 0x67, 0xe0, 0xf3, 0x81, 0x9d, 0x63, 0xe5, 0xd1, 0x96,
|
||||
0xf8, 0xcb, 0x7a, 0xf6, 0x2b, 0x00, 0x00, 0xff, 0xff, 0xa5, 0x3e, 0xc2, 0xea, 0xbf, 0x04, 0x00,
|
||||
0x00,
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package go_attestation;
|
||||
|
||||
enum TpmVersion {
|
||||
TPM_VERSION_UNSPECIFIED = 0;
|
||||
TPM_12 = 1;
|
||||
TPM_20 = 2;
|
||||
}
|
||||
|
||||
enum TpmInterface {
|
||||
TPM_INTERFACE_UNSPECIFIED = 0;
|
||||
DIRECT = 1;
|
||||
KERNEL_MANAGED = 2;
|
||||
DAEMON_MANAGED = 3;
|
||||
}
|
||||
|
||||
// TpmInfo encapsulates version / device information
|
||||
// about the TPM, and how the attestation client interfaces
|
||||
// with it.
|
||||
message TpmInfo {
|
||||
TpmVersion tpm_version = 1;
|
||||
string manufacturer = 2;
|
||||
TpmInterface tpm_interface = 3;
|
||||
|
||||
// This number represents the version of the support code which
|
||||
// interfaces with the TPM.
|
||||
uint32 tpm_interface_version = 4 [deprecated = true];
|
||||
|
||||
// This is the string provided by the TPM.
|
||||
string tpm_opaque_info = 5;
|
||||
|
||||
// This is set if challenges must be generated
|
||||
// in TrouSerS format for TPM 1.2 devices.
|
||||
bool trousers_format = 6;
|
||||
}
|
||||
|
||||
message EndorsementKey {
|
||||
enum DataType {
|
||||
DATA_TYPE_UNSPECIFIED = 0;
|
||||
PUBLIC_BLOB = 1; // Indicates data is encoded as a PKCS1 public key.
|
||||
X509_CERT_BLOB = 2;
|
||||
};
|
||||
|
||||
DataType datatype = 1;
|
||||
bytes data = 2;
|
||||
}
|
||||
|
||||
// Tpm20AikInfo describes an AIK using TPM 2.0 structures.
|
||||
message Tpm20AikInfo {
|
||||
// This is a TPMT_PUBLIC structure.
|
||||
bytes public_blob = 1;
|
||||
// This is a TPMS_CREATION_DATA structure.
|
||||
bytes creation_data = 2;
|
||||
// This is a TPMU_ATTEST structure, with the dynamic section
|
||||
// containing a CREATION_INFO structure.
|
||||
bytes attestation_data = 3;
|
||||
// This is a TPMT_SIGNATURE structure.
|
||||
bytes signature_data = 4;
|
||||
}
|
||||
|
||||
// Tpm12AikInfo describes an AIK using TPM 1.2 structures.
|
||||
message Tpm12AikInfo {
|
||||
// This is a TPM_PUBKEY structure.
|
||||
bytes public_blob = 1;
|
||||
// This is auxillary data, provided for the purpose of debugging.
|
||||
// on Windows devices, this represents the contents of PCP_ID_BINDING.
|
||||
bytes aux = 2;
|
||||
}
|
||||
|
||||
// AikInfo describes the public key, parameters, and creation information
|
||||
// of an attestation identity key.
|
||||
message AikInfo {
|
||||
oneof tpm_aik_info {
|
||||
Tpm20AikInfo tpm20 = 1;
|
||||
Tpm12AikInfo tpm12 = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// ChallengeInfo describes which challenge a nonce corresponds to.
|
||||
message ChallengeInfo {
|
||||
enum ChallengeType {
|
||||
CHALLENGE_UNSPECIFIED = 0;
|
||||
CHALLENGE_CA = 1;
|
||||
};
|
||||
|
||||
ChallengeType type = 1;
|
||||
}
|
130
verifier/aik.go
130
verifier/aik.go
@ -1,130 +0,0 @@
|
||||
// Package verifier implements high-level logic to check information
|
||||
// provided by TPMs in client devices.
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
|
||||
tpb "github.com/google/go-attestation/proto"
|
||||
pb "github.com/google/go-attestation/verifier/proto"
|
||||
|
||||
tpm1 "github.com/google/go-tpm/tpm"
|
||||
"github.com/google/go-tpm/tpm2"
|
||||
)
|
||||
|
||||
const (
|
||||
tpmGeneratedMagic = 0xff544347
|
||||
)
|
||||
|
||||
// VerifyAIK examines properties of an AIK and a creation attestation, to determine
|
||||
// if it is suitable for use as an attestation key.
|
||||
func VerifyAIK(tpmVersion tpb.TpmVersion, aik *tpb.AikInfo) (*pb.AikVerificationResults, error) {
|
||||
switch tpmVersion {
|
||||
case tpb.TpmVersion_TPM_12:
|
||||
aik12 := aik.GetTpm12()
|
||||
return verifyAIK12(aik12.GetPublicBlob())
|
||||
|
||||
case tpb.TpmVersion_TPM_20:
|
||||
aik20 := aik.GetTpm20()
|
||||
return verifyAIK20(aik20.GetPublicBlob(), aik20.GetCreationData(), aik20.GetAttestationData(), aik20.GetSignatureData())
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("TPM version %d not supported", tpmVersion)
|
||||
}
|
||||
}
|
||||
|
||||
func verifyAIK12(public []byte) (*pb.AikVerificationResults, error) {
|
||||
pub, err := tpm1.UnmarshalPubRSAPublicKey(public)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out pb.AikVerificationResults
|
||||
out.RocaVulnerableKey = ROCAVulnerableKey(pub)
|
||||
out.Succeeded = !out.RocaVulnerableKey
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func verifyAIK20(public, creationData, attestationData, signature []byte) (*pb.AikVerificationResults, error) {
|
||||
if len(signature) < 8 {
|
||||
return nil, fmt.Errorf("signature is too short to be valid: only %d bytes", len(signature))
|
||||
}
|
||||
|
||||
pub, err := tpm2.DecodePublic(public)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, err = tpm2.DecodeCreationData(creationData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
att, err := tpm2.DecodeAttestationData(attestationData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if att.Type != tpm2.TagAttestCreation {
|
||||
return nil, fmt.Errorf("attestation does apply to creation data, got tag %x", att.Type)
|
||||
}
|
||||
var out pb.AikVerificationResults
|
||||
|
||||
switch pub.Type {
|
||||
case tpm2.AlgRSA:
|
||||
if pub.RSAParameters.KeyBits < 2048 {
|
||||
out.KeyTooSmall = true
|
||||
}
|
||||
out.RocaVulnerableKey = ROCAVulnerableKey(&rsa.PublicKey{N: pub.RSAParameters.Modulus()})
|
||||
default:
|
||||
return nil, fmt.Errorf("public key of alg 0x%x not supported", pub.Type)
|
||||
}
|
||||
|
||||
// Compute & verify that the creation data matches the digest in the
|
||||
// attestation structure.
|
||||
nameHashConstructor, err := pub.NameAlg.HashConstructor()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h := nameHashConstructor()
|
||||
h.Write(creationData)
|
||||
out.CreationAttestationMismatch = !bytes.Equal(att.AttestedCreationInfo.OpaqueDigest, h.Sum(nil))
|
||||
|
||||
// Make sure the AIK has sane key parameters (Attestation can be faked if an AIK
|
||||
// can be used for arbitrary signatures).
|
||||
// We verify the following:
|
||||
// - Key is TPM backed.
|
||||
// - Key is TPM generated.
|
||||
// - Key is a restricted key (means it cannot do arbitrary signing/decrypt ops).
|
||||
// - Key cannot be duplicated.
|
||||
// - Key was generated by a call to TPM_Create*.
|
||||
out.KeyNotTpmBound = (att.Magic != tpmGeneratedMagic) || ((pub.Attributes & tpm2.FlagFixedTPM) == 0)
|
||||
out.KeyUsageOverlyBroad = ((pub.Attributes & tpm2.FlagRestricted) == 0) || ((pub.Attributes & tpm2.FlagFixedParent) == 0) || ((pub.Attributes & tpm2.FlagSensitiveDataOrigin) == 0)
|
||||
|
||||
// Verify the attested creation name matches what is computed from
|
||||
// the public key.
|
||||
match, err := att.AttestedCreationInfo.Name.MatchesPublic(pub)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out.NameAttestationMismatch = !match
|
||||
|
||||
// Check the signature over the attestation data verifies correctly.
|
||||
p := rsa.PublicKey{E: int(pub.RSAParameters.Exponent()), N: pub.RSAParameters.Modulus()}
|
||||
signHashConstructor, err := pub.RSAParameters.Sign.Hash.HashConstructor()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hsh := signHashConstructor()
|
||||
hsh.Write(attestationData)
|
||||
|
||||
verifyHash, err := cryptoHash(pub.RSAParameters.Sign.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO(jsonp): Decode to tpm2.Signature & use that, once PR to expose DecodeSignature() is in.
|
||||
out.SignatureMismatch = rsa.VerifyPKCS1v15(&p, verifyHash, hsh.Sum(nil), signature[6:]) != nil
|
||||
|
||||
out.Succeeded = !(out.CreationAttestationMismatch || out.KeyTooSmall || out.KeyNotTpmBound || out.KeyUsageOverlyBroad || out.NameAttestationMismatch || out.SignatureMismatch)
|
||||
return &out, nil
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
|
||||
pb "github.com/google/go-attestation/verifier/proto"
|
||||
)
|
||||
|
||||
// EKVerifier verifies x509 EK certificates based on a pool of allowed
|
||||
// parent certificates.
|
||||
type EKVerifier struct {
|
||||
roots, intermediates *x509.CertPool
|
||||
}
|
||||
|
||||
// VerifyEKCert verifies the properties and provenance of a given EK certificate.
|
||||
func (v *EKVerifier) VerifyEKCert(certBytes []byte) (*pb.EkcertVerificationResults, error) {
|
||||
c, err := x509.ParseCertificate(certBytes)
|
||||
c.UnhandledCriticalExtensions = nil
|
||||
if err != nil && x509.IsFatal(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chains, verificationErr := c.Verify(x509.VerifyOptions{
|
||||
Roots: v.roots,
|
||||
Intermediates: v.intermediates,
|
||||
|
||||
// Disable checking extensions & key usages, as their application
|
||||
// appears to be inconsistent, and we only use the certificate
|
||||
// chains as a means to determine provenance.
|
||||
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
|
||||
})
|
||||
|
||||
out := &pb.EkcertVerificationResults{
|
||||
Succeeded: verificationErr == nil,
|
||||
ChainVerified: verificationErr == nil,
|
||||
}
|
||||
if verificationErr != nil {
|
||||
out.VerificationError = verificationErr.Error()
|
||||
} else {
|
||||
for _, cert := range chains[0] {
|
||||
out.Chain = append(out.Chain, &pb.EkcertVerificationResults_CertSummary{
|
||||
IssuerCn: cert.Issuer.CommonName,
|
||||
IssuerOrg: strings.Join(cert.Issuer.Organization, " "),
|
||||
Serial: cert.SerialNumber.String(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// NewEKVerifier returns an EKVerifier initialized using the certificates in the specified
|
||||
// directories. Directories are resolved recursively.
|
||||
// The specified directory should be structured in the forms:
|
||||
// <XXXX>/RootCA/<cert>.{der,cer,crt)
|
||||
// <XXXX>/IntermediateCA/<cert>.{der,cer,crt)
|
||||
func NewEKVerifier(certsPath []string) (*EKVerifier, error) {
|
||||
roots := x509.NewCertPool()
|
||||
intermediates := x509.NewCertPool()
|
||||
|
||||
for _, dir := range certsPath {
|
||||
root, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range root {
|
||||
if !f.IsDir() {
|
||||
continue
|
||||
}
|
||||
if err := readCertificates(filepath.Join(dir, f.Name()), roots, intermediates); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &EKVerifier{
|
||||
roots: roots,
|
||||
intermediates: intermediates,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func readCertificates(dir string, roots, intermediates *x509.CertPool) error {
|
||||
rootFiles, err := ioutil.ReadDir(filepath.Join(dir, "RootCA"))
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if err == nil {
|
||||
if err := parseCertsToPool(filepath.Join(dir, "RootCA"), rootFiles, roots); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
intermediateFiles, err := ioutil.ReadDir(filepath.Join(dir, "IntermediateCA"))
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
// Not all manufacturers use intermediates certificates.
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return parseCertsToPool(filepath.Join(dir, "IntermediateCA"), intermediateFiles, intermediates)
|
||||
}
|
||||
|
||||
func parseCertsToPool(path string, files []os.FileInfo, pool *x509.CertPool) error {
|
||||
for _, info := range files {
|
||||
if info.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
path := filepath.Join(path, info.Name())
|
||||
switch filepath.Ext(info.Name()) {
|
||||
case ".der":
|
||||
d, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, err := x509.ParseCertificate(d)
|
||||
if err != nil && x509.IsFatal(err) {
|
||||
return fmt.Errorf("%s parse failed: %v", info.Name(), err)
|
||||
}
|
||||
pool.AddCert(c)
|
||||
|
||||
case ".crt", ".cer":
|
||||
// Either DER or PEM.
|
||||
d, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c, err := x509.ParseCertificate(d)
|
||||
if err != nil && x509.IsFatal(err) && !pool.AppendCertsFromPEM(d) {
|
||||
return fmt.Errorf("%s parse failed: %v", info.Name(), err)
|
||||
}
|
||||
if err == nil {
|
||||
pool.AddCert(c)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,349 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: verification.proto
|
||||
|
||||
package go_attestation_verifier
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type AikVerificationResults struct {
|
||||
Succeeded bool `protobuf:"varint,1,opt,name=succeeded,proto3" json:"succeeded,omitempty"`
|
||||
KeyTooSmall bool `protobuf:"varint,2,opt,name=key_too_small,json=keyTooSmall,proto3" json:"key_too_small,omitempty"`
|
||||
CreationAttestationMismatch bool `protobuf:"varint,3,opt,name=creation_attestation_mismatch,json=creationAttestationMismatch,proto3" json:"creation_attestation_mismatch,omitempty"`
|
||||
KeyNotTpmBound bool `protobuf:"varint,4,opt,name=key_not_tpm_bound,json=keyNotTpmBound,proto3" json:"key_not_tpm_bound,omitempty"`
|
||||
KeyUsageOverlyBroad bool `protobuf:"varint,5,opt,name=key_usage_overly_broad,json=keyUsageOverlyBroad,proto3" json:"key_usage_overly_broad,omitempty"`
|
||||
NameAttestationMismatch bool `protobuf:"varint,6,opt,name=name_attestation_mismatch,json=nameAttestationMismatch,proto3" json:"name_attestation_mismatch,omitempty"`
|
||||
SignatureMismatch bool `protobuf:"varint,7,opt,name=signature_mismatch,json=signatureMismatch,proto3" json:"signature_mismatch,omitempty"`
|
||||
RocaVulnerableKey bool `protobuf:"varint,8,opt,name=roca_vulnerable_key,json=rocaVulnerableKey,proto3" json:"roca_vulnerable_key,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) Reset() { *m = AikVerificationResults{} }
|
||||
func (m *AikVerificationResults) String() string { return proto.CompactTextString(m) }
|
||||
func (*AikVerificationResults) ProtoMessage() {}
|
||||
func (*AikVerificationResults) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_69b5d5d3b04d10d4, []int{0}
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_AikVerificationResults.Unmarshal(m, b)
|
||||
}
|
||||
func (m *AikVerificationResults) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_AikVerificationResults.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *AikVerificationResults) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_AikVerificationResults.Merge(m, src)
|
||||
}
|
||||
func (m *AikVerificationResults) XXX_Size() int {
|
||||
return xxx_messageInfo_AikVerificationResults.Size(m)
|
||||
}
|
||||
func (m *AikVerificationResults) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_AikVerificationResults.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_AikVerificationResults proto.InternalMessageInfo
|
||||
|
||||
func (m *AikVerificationResults) GetSucceeded() bool {
|
||||
if m != nil {
|
||||
return m.Succeeded
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) GetKeyTooSmall() bool {
|
||||
if m != nil {
|
||||
return m.KeyTooSmall
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) GetCreationAttestationMismatch() bool {
|
||||
if m != nil {
|
||||
return m.CreationAttestationMismatch
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) GetKeyNotTpmBound() bool {
|
||||
if m != nil {
|
||||
return m.KeyNotTpmBound
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) GetKeyUsageOverlyBroad() bool {
|
||||
if m != nil {
|
||||
return m.KeyUsageOverlyBroad
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) GetNameAttestationMismatch() bool {
|
||||
if m != nil {
|
||||
return m.NameAttestationMismatch
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) GetSignatureMismatch() bool {
|
||||
if m != nil {
|
||||
return m.SignatureMismatch
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *AikVerificationResults) GetRocaVulnerableKey() bool {
|
||||
if m != nil {
|
||||
return m.RocaVulnerableKey
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type QuoteVerificationResults struct {
|
||||
Succeeded bool `protobuf:"varint,1,opt,name=succeeded,proto3" json:"succeeded,omitempty"`
|
||||
SignatureMismatch bool `protobuf:"varint,2,opt,name=signature_mismatch,json=signatureMismatch,proto3" json:"signature_mismatch,omitempty"`
|
||||
PcrDigest []byte `protobuf:"bytes,3,opt,name=pcr_digest,json=pcrDigest,proto3" json:"pcr_digest,omitempty"`
|
||||
PcrDigestMismatch bool `protobuf:"varint,4,opt,name=pcr_digest_mismatch,json=pcrDigestMismatch,proto3" json:"pcr_digest_mismatch,omitempty"`
|
||||
NonceMismatch bool `protobuf:"varint,5,opt,name=nonce_mismatch,json=nonceMismatch,proto3" json:"nonce_mismatch,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *QuoteVerificationResults) Reset() { *m = QuoteVerificationResults{} }
|
||||
func (m *QuoteVerificationResults) String() string { return proto.CompactTextString(m) }
|
||||
func (*QuoteVerificationResults) ProtoMessage() {}
|
||||
func (*QuoteVerificationResults) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_69b5d5d3b04d10d4, []int{1}
|
||||
}
|
||||
|
||||
func (m *QuoteVerificationResults) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_QuoteVerificationResults.Unmarshal(m, b)
|
||||
}
|
||||
func (m *QuoteVerificationResults) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_QuoteVerificationResults.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *QuoteVerificationResults) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_QuoteVerificationResults.Merge(m, src)
|
||||
}
|
||||
func (m *QuoteVerificationResults) XXX_Size() int {
|
||||
return xxx_messageInfo_QuoteVerificationResults.Size(m)
|
||||
}
|
||||
func (m *QuoteVerificationResults) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_QuoteVerificationResults.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_QuoteVerificationResults proto.InternalMessageInfo
|
||||
|
||||
func (m *QuoteVerificationResults) GetSucceeded() bool {
|
||||
if m != nil {
|
||||
return m.Succeeded
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *QuoteVerificationResults) GetSignatureMismatch() bool {
|
||||
if m != nil {
|
||||
return m.SignatureMismatch
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *QuoteVerificationResults) GetPcrDigest() []byte {
|
||||
if m != nil {
|
||||
return m.PcrDigest
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *QuoteVerificationResults) GetPcrDigestMismatch() bool {
|
||||
if m != nil {
|
||||
return m.PcrDigestMismatch
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *QuoteVerificationResults) GetNonceMismatch() bool {
|
||||
if m != nil {
|
||||
return m.NonceMismatch
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type EkcertVerificationResults struct {
|
||||
Succeeded bool `protobuf:"varint,1,opt,name=succeeded,proto3" json:"succeeded,omitempty"`
|
||||
ChainVerified bool `protobuf:"varint,2,opt,name=chain_verified,json=chainVerified,proto3" json:"chain_verified,omitempty"`
|
||||
Chain []*EkcertVerificationResults_CertSummary `protobuf:"bytes,3,rep,name=chain,proto3" json:"chain,omitempty"`
|
||||
VerificationError string `protobuf:"bytes,4,opt,name=verification_error,json=verificationError,proto3" json:"verification_error,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults) Reset() { *m = EkcertVerificationResults{} }
|
||||
func (m *EkcertVerificationResults) String() string { return proto.CompactTextString(m) }
|
||||
func (*EkcertVerificationResults) ProtoMessage() {}
|
||||
func (*EkcertVerificationResults) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_69b5d5d3b04d10d4, []int{2}
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EkcertVerificationResults.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EkcertVerificationResults) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EkcertVerificationResults.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EkcertVerificationResults) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EkcertVerificationResults.Merge(m, src)
|
||||
}
|
||||
func (m *EkcertVerificationResults) XXX_Size() int {
|
||||
return xxx_messageInfo_EkcertVerificationResults.Size(m)
|
||||
}
|
||||
func (m *EkcertVerificationResults) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EkcertVerificationResults.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EkcertVerificationResults proto.InternalMessageInfo
|
||||
|
||||
func (m *EkcertVerificationResults) GetSucceeded() bool {
|
||||
if m != nil {
|
||||
return m.Succeeded
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults) GetChainVerified() bool {
|
||||
if m != nil {
|
||||
return m.ChainVerified
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults) GetChain() []*EkcertVerificationResults_CertSummary {
|
||||
if m != nil {
|
||||
return m.Chain
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults) GetVerificationError() string {
|
||||
if m != nil {
|
||||
return m.VerificationError
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type EkcertVerificationResults_CertSummary struct {
|
||||
IssuerCn string `protobuf:"bytes,1,opt,name=issuer_cn,json=issuerCn,proto3" json:"issuer_cn,omitempty"`
|
||||
IssuerOrg string `protobuf:"bytes,2,opt,name=issuer_org,json=issuerOrg,proto3" json:"issuer_org,omitempty"`
|
||||
Serial string `protobuf:"bytes,3,opt,name=serial,proto3" json:"serial,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults_CertSummary) Reset() { *m = EkcertVerificationResults_CertSummary{} }
|
||||
func (m *EkcertVerificationResults_CertSummary) String() string { return proto.CompactTextString(m) }
|
||||
func (*EkcertVerificationResults_CertSummary) ProtoMessage() {}
|
||||
func (*EkcertVerificationResults_CertSummary) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_69b5d5d3b04d10d4, []int{2, 0}
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults_CertSummary) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_EkcertVerificationResults_CertSummary.Unmarshal(m, b)
|
||||
}
|
||||
func (m *EkcertVerificationResults_CertSummary) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_EkcertVerificationResults_CertSummary.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *EkcertVerificationResults_CertSummary) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_EkcertVerificationResults_CertSummary.Merge(m, src)
|
||||
}
|
||||
func (m *EkcertVerificationResults_CertSummary) XXX_Size() int {
|
||||
return xxx_messageInfo_EkcertVerificationResults_CertSummary.Size(m)
|
||||
}
|
||||
func (m *EkcertVerificationResults_CertSummary) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_EkcertVerificationResults_CertSummary.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_EkcertVerificationResults_CertSummary proto.InternalMessageInfo
|
||||
|
||||
func (m *EkcertVerificationResults_CertSummary) GetIssuerCn() string {
|
||||
if m != nil {
|
||||
return m.IssuerCn
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults_CertSummary) GetIssuerOrg() string {
|
||||
if m != nil {
|
||||
return m.IssuerOrg
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *EkcertVerificationResults_CertSummary) GetSerial() string {
|
||||
if m != nil {
|
||||
return m.Serial
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*AikVerificationResults)(nil), "go_attestation.verifier.AikVerificationResults")
|
||||
proto.RegisterType((*QuoteVerificationResults)(nil), "go_attestation.verifier.QuoteVerificationResults")
|
||||
proto.RegisterType((*EkcertVerificationResults)(nil), "go_attestation.verifier.EkcertVerificationResults")
|
||||
proto.RegisterType((*EkcertVerificationResults_CertSummary)(nil), "go_attestation.verifier.EkcertVerificationResults.CertSummary")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("verification.proto", fileDescriptor_69b5d5d3b04d10d4) }
|
||||
|
||||
var fileDescriptor_69b5d5d3b04d10d4 = []byte{
|
||||
// 494 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0x41, 0x6e, 0xdb, 0x3c,
|
||||
0x10, 0x85, 0x61, 0xfb, 0x8f, 0x7f, 0x6b, 0x5c, 0x1b, 0x30, 0x03, 0x38, 0x4a, 0xd3, 0x00, 0x81,
|
||||
0x81, 0x00, 0xe9, 0xa2, 0x5e, 0x34, 0xbb, 0x2e, 0x0a, 0xc4, 0x69, 0x56, 0x45, 0x1b, 0x54, 0x71,
|
||||
0xbd, 0x25, 0x68, 0x6a, 0xaa, 0x08, 0x92, 0x48, 0x63, 0x48, 0x19, 0xd0, 0x51, 0x7a, 0xa3, 0x5e,
|
||||
0xa2, 0x77, 0x29, 0x48, 0x29, 0xb6, 0x16, 0xf6, 0x22, 0x4b, 0xbd, 0xf7, 0xcd, 0x70, 0x86, 0x4f,
|
||||
0x04, 0xb6, 0x45, 0x4a, 0x7f, 0xa5, 0x52, 0xd8, 0x54, 0xab, 0xf9, 0x86, 0xb4, 0xd5, 0xec, 0x2c,
|
||||
0xd1, 0x5c, 0x58, 0x8b, 0xc6, 0xd6, 0x6a, 0x8d, 0x20, 0xcd, 0x7e, 0xf7, 0x60, 0x7a, 0x97, 0x66,
|
||||
0xab, 0x56, 0x49, 0x84, 0xa6, 0xcc, 0xad, 0x61, 0xef, 0x20, 0x30, 0xa5, 0x94, 0x88, 0x31, 0xc6,
|
||||
0x61, 0xe7, 0xaa, 0x73, 0x33, 0x88, 0xf6, 0x02, 0x9b, 0xc1, 0x28, 0xc3, 0x8a, 0x5b, 0xad, 0xb9,
|
||||
0x29, 0x44, 0x9e, 0x87, 0x5d, 0x4f, 0x0c, 0x33, 0xac, 0x96, 0x5a, 0x3f, 0x39, 0x89, 0x2d, 0xe0,
|
||||
0x52, 0x12, 0xfa, 0xa6, 0xed, 0xd3, 0x79, 0x91, 0x9a, 0x42, 0x58, 0xf9, 0x1c, 0xf6, 0x7c, 0xcd,
|
||||
0xc5, 0x0b, 0x74, 0xb7, 0x67, 0xbe, 0x35, 0x08, 0x7b, 0x0f, 0x13, 0x77, 0x8e, 0xd2, 0x96, 0xdb,
|
||||
0x4d, 0xc1, 0xd7, 0xba, 0x54, 0x71, 0xf8, 0x9f, 0xaf, 0x1b, 0x67, 0x58, 0x7d, 0xd7, 0x76, 0xb9,
|
||||
0x29, 0x16, 0x4e, 0x65, 0xb7, 0x30, 0x75, 0x68, 0x69, 0x44, 0x82, 0x5c, 0x6f, 0x91, 0xf2, 0x8a,
|
||||
0xaf, 0x49, 0x8b, 0x38, 0x3c, 0xf1, 0xfc, 0x69, 0x86, 0xd5, 0x4f, 0x67, 0x3e, 0x7a, 0x6f, 0xe1,
|
||||
0x2c, 0xf6, 0x09, 0xce, 0x95, 0x28, 0xf0, 0xf0, 0x7c, 0x7d, 0x5f, 0x77, 0xe6, 0x80, 0x43, 0xb3,
|
||||
0x7d, 0x00, 0x66, 0xd2, 0x44, 0x09, 0x5b, 0x12, 0xee, 0x8b, 0xfe, 0xf7, 0x45, 0x93, 0x9d, 0xb3,
|
||||
0xc3, 0xe7, 0x70, 0x4a, 0x5a, 0x0a, 0xbe, 0x2d, 0x73, 0x85, 0x24, 0xd6, 0x39, 0xf2, 0x0c, 0xab,
|
||||
0x70, 0x50, 0xf3, 0xce, 0x5a, 0xed, 0x9c, 0xaf, 0x58, 0xcd, 0xfe, 0x76, 0x20, 0xfc, 0x51, 0x6a,
|
||||
0x8b, 0xaf, 0x4f, 0xe7, 0xf0, 0x64, 0xdd, 0x63, 0x93, 0x5d, 0x02, 0x6c, 0x24, 0xf1, 0x38, 0x4d,
|
||||
0xd0, 0x58, 0x9f, 0xca, 0x9b, 0x28, 0xd8, 0x48, 0xfa, 0xe2, 0x05, 0x37, 0xf8, 0xde, 0xde, 0xb7,
|
||||
0xab, 0x53, 0x98, 0xec, 0xb8, 0x5d, 0xbb, 0x6b, 0x18, 0x2b, 0xad, 0x64, 0xeb, 0xe4, 0x3a, 0x80,
|
||||
0x91, 0x57, 0x5f, 0xb0, 0xd9, 0x9f, 0x2e, 0x9c, 0x3f, 0x64, 0x12, 0xc9, 0xbe, 0x7e, 0xc1, 0x6b,
|
||||
0x18, 0xcb, 0x67, 0x91, 0x2a, 0xde, 0xfc, 0xc9, 0x71, 0xb3, 0xdc, 0xc8, 0xab, 0xab, 0x46, 0x64,
|
||||
0x4b, 0x38, 0xf1, 0x42, 0xd8, 0xbb, 0xea, 0xdd, 0x0c, 0x3f, 0x7e, 0x9e, 0x1f, 0x79, 0x07, 0xf3,
|
||||
0xa3, 0x73, 0xcc, 0xef, 0x91, 0xec, 0x53, 0x59, 0x14, 0x82, 0xaa, 0xa8, 0x6e, 0xe6, 0x6e, 0xb7,
|
||||
0xfd, 0xc6, 0x38, 0x12, 0x69, 0xf2, 0xd7, 0x11, 0x44, 0x93, 0xb6, 0xf3, 0xe0, 0x8c, 0xb7, 0x02,
|
||||
0x86, 0xad, 0x26, 0xec, 0x02, 0x82, 0xd4, 0x98, 0x12, 0x89, 0x4b, 0xe5, 0x17, 0x0b, 0xa2, 0x41,
|
||||
0x2d, 0xdc, 0x2b, 0x97, 0x44, 0x63, 0x6a, 0x4a, 0xfc, 0x4e, 0x41, 0xd4, 0xe0, 0x8f, 0x94, 0xb0,
|
||||
0x29, 0xf4, 0x0d, 0x52, 0x2a, 0x72, 0x1f, 0x52, 0x10, 0x35, 0x5f, 0xeb, 0xbe, 0x7f, 0xe6, 0xb7,
|
||||
0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xeb, 0x1a, 0x1f, 0x6c, 0xfc, 0x03, 0x00, 0x00,
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package go_attestation.verifier;
|
||||
|
||||
message AikVerificationResults {
|
||||
bool succeeded = 1;
|
||||
|
||||
bool key_too_small = 2;
|
||||
bool creation_attestation_mismatch = 3;
|
||||
|
||||
bool key_not_tpm_bound = 4;
|
||||
bool key_usage_overly_broad = 5;
|
||||
|
||||
bool name_attestation_mismatch = 6;
|
||||
|
||||
bool signature_mismatch = 7;
|
||||
|
||||
bool roca_vulnerable_key = 8;
|
||||
}
|
||||
|
||||
message QuoteVerificationResults {
|
||||
bool succeeded = 1;
|
||||
bool signature_mismatch = 2;
|
||||
bytes pcr_digest = 3;
|
||||
bool pcr_digest_mismatch = 4;
|
||||
bool nonce_mismatch = 5;
|
||||
}
|
||||
|
||||
message EkcertVerificationResults {
|
||||
message CertSummary {
|
||||
string issuer_cn = 1;
|
||||
string issuer_org = 2;
|
||||
string serial = 3;
|
||||
}
|
||||
|
||||
bool succeeded = 1;
|
||||
bool chain_verified = 2;
|
||||
repeated CertSummary chain = 3;
|
||||
string verification_error = 4;
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
tpb "github.com/google/go-attestation/proto"
|
||||
pb "github.com/google/go-attestation/verifier/proto"
|
||||
tpm1 "github.com/google/go-tpm/tpm"
|
||||
"github.com/google/go-tpm/tpm2"
|
||||
"github.com/google/go-tpm/tpmutil"
|
||||
)
|
||||
|
||||
func cryptoHash(h tpm2.Algorithm) (crypto.Hash, error) {
|
||||
switch h {
|
||||
case tpm2.AlgSHA1:
|
||||
return crypto.SHA1, nil
|
||||
case tpm2.AlgSHA256:
|
||||
return crypto.SHA256, nil
|
||||
case tpm2.AlgSHA384:
|
||||
return crypto.SHA384, nil
|
||||
case tpm2.AlgSHA512:
|
||||
return crypto.SHA512, nil
|
||||
default:
|
||||
return crypto.Hash(0), fmt.Errorf("unsupported signature digest: %v", h)
|
||||
}
|
||||
}
|
||||
|
||||
// VerifyQuote returns information about the validity of a quote & signature.
|
||||
func VerifyQuote(tpmVersion tpb.TpmVersion, public, attestationData, signature []byte, pcrs map[uint32][]byte, nonce []byte) (*pb.QuoteVerificationResults, error) {
|
||||
var (
|
||||
pcrDigestMatched bool
|
||||
nonceMatched bool
|
||||
verifyErr error
|
||||
digest []byte
|
||||
)
|
||||
if len(signature) < 8 {
|
||||
return nil, fmt.Errorf("signature is too short to be valid: only %d bytes", len(signature))
|
||||
}
|
||||
|
||||
switch tpmVersion {
|
||||
case tpb.TpmVersion_TPM_20:
|
||||
var compositeHash crypto.Hash
|
||||
var verifyHash crypto.Hash
|
||||
pub, err := tpm2.DecodePublic(public)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
att, err := tpm2.DecodeAttestationData(attestationData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if att.Type != tpm2.TagAttestQuote {
|
||||
return nil, fmt.Errorf("attestation is tagged %x, want TagAttestQuote", att.Type)
|
||||
}
|
||||
digest = att.AttestedQuoteInfo.PCRDigest
|
||||
|
||||
// Compute the digest of PCR values based on the provided individual PCR values.
|
||||
compositeHash, err = cryptoHash(pub.RSAParameters.Sign.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var compositeData []byte
|
||||
for _, pcr := range att.AttestedQuoteInfo.PCRSelection.PCRs {
|
||||
digest, ok := pcrs[uint32(pcr)]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("PCR %d missing but used to compute PCR digest", pcr)
|
||||
}
|
||||
compositeData = append(compositeData, digest...)
|
||||
}
|
||||
compositeDigest := compositeHash.New()
|
||||
compositeDigest.Write(compositeData)
|
||||
pcrDigestMatched = bytes.Equal(compositeDigest.Sum(nil), digest)
|
||||
|
||||
// Check the signature over the attestation data verifies correctly.
|
||||
p := rsa.PublicKey{E: int(pub.RSAParameters.Exponent()), N: pub.RSAParameters.Modulus()}
|
||||
signHashConstructor, err := pub.RSAParameters.Sign.Hash.HashConstructor()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hsh := signHashConstructor()
|
||||
hsh.Write(attestationData)
|
||||
|
||||
verifyHash, err = cryptoHash(pub.RSAParameters.Sign.Hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nonceMatched = bytes.Equal(att.ExtraData, nonce)
|
||||
|
||||
//TODO(jsonp): Decode to tpm2.Signature & use that, once PR to expose DecodeSignature() is in.
|
||||
verifyErr = rsa.VerifyPKCS1v15(&p, verifyHash, hsh.Sum(nil), signature[6:])
|
||||
case tpb.TpmVersion_TPM_12:
|
||||
p, err := tpm1.UnmarshalPubRSAPublicKey(public)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
digest = attestationData
|
||||
pcrNums := sortPCRs(pcrs)
|
||||
compositeData := []byte{}
|
||||
for _, pcr := range pcrNums {
|
||||
compositeData = append(compositeData, pcrs[uint32(pcr)]...)
|
||||
}
|
||||
composite, err := tpmutil.Pack(&struct {
|
||||
Mask tpmutil.U16Bytes
|
||||
Data tpmutil.U32Bytes
|
||||
}{
|
||||
Mask: []byte{0xff, 0xff, 0xff},
|
||||
Data: compositeData,
|
||||
})
|
||||
|
||||
info := struct {
|
||||
Version [4]byte
|
||||
QUOT [4]byte
|
||||
Digest [20]byte
|
||||
Nonce [20]byte
|
||||
}{}
|
||||
if _, err = tpmutil.Unpack(attestationData, &info); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pcrDigestMatched = sha1.Sum(composite) == info.Digest
|
||||
nonceMatched = sha1.Sum(nonce) == info.Nonce
|
||||
|
||||
verifyErr = tpm1.VerifyQuote(p, nonce, signature, pcrNums, compositeData)
|
||||
default:
|
||||
return nil, fmt.Errorf("TPM version %d not supported", tpmVersion)
|
||||
}
|
||||
return &pb.QuoteVerificationResults{
|
||||
SignatureMismatch: verifyErr != nil,
|
||||
Succeeded: verifyErr == nil && pcrDigestMatched && nonceMatched,
|
||||
PcrDigest: digest,
|
||||
PcrDigestMismatch: !pcrDigestMatched,
|
||||
NonceMismatch: !nonceMatched,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func sortPCRs(pcrs map[uint32][]byte) []int {
|
||||
pcrNums := []int{}
|
||||
for pcr := range pcrs {
|
||||
pcrNums = append(pcrNums, int(pcr))
|
||||
}
|
||||
sort.Slice(pcrNums, func(i int, j int) bool {
|
||||
return pcrNums[i] < pcrNums[j]
|
||||
})
|
||||
return pcrNums
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
var (
|
||||
// Derived from resources published as:
|
||||
// "ROCA: Vulnerable RSA generation (CVE-2017-15361)".
|
||||
// Czech Republic: Centre for Research on Cryptography and Security, Faculty of Informatics, Masaryk University.
|
||||
|
||||
fingerprintPrimes = []int64{3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
|
||||
73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
|
||||
151, 157, 163, 167}
|
||||
fingerprintMasks = []string{
|
||||
"6",
|
||||
"30",
|
||||
"126",
|
||||
"1026",
|
||||
"5658",
|
||||
"107286",
|
||||
"199410",
|
||||
"8388606",
|
||||
"536870910",
|
||||
"2147483646",
|
||||
"67109890",
|
||||
"2199023255550",
|
||||
"8796093022206",
|
||||
"140737488355326",
|
||||
"5310023542746834",
|
||||
"576460752303423486",
|
||||
"1455791217086302986",
|
||||
"147573952589676412926",
|
||||
"20052041432995567486",
|
||||
"6041388139249378920330",
|
||||
"207530445072488465666",
|
||||
"9671406556917033397649406",
|
||||
"618970019642690137449562110",
|
||||
"79228162521181866724264247298",
|
||||
"2535301200456458802993406410750",
|
||||
"1760368345969468176824550810518",
|
||||
"50079290986288516948354744811034",
|
||||
"473022961816146413042658758988474",
|
||||
"10384593717069655257060992658440190",
|
||||
"144390480366845522447407333004847678774",
|
||||
"2722258935367507707706996859454145691646",
|
||||
"174224571863520493293247799005065324265470",
|
||||
"696898287454081973172991196020261297061886",
|
||||
"713623846352979940529142984724747568191373310",
|
||||
"1800793591454480341970779146165214289059119882",
|
||||
"126304807362733370595828809000324029340048915994",
|
||||
"11692013098647223345629478661730264157247460343806",
|
||||
"187072209578355573530071658587684226515959365500926",
|
||||
}
|
||||
)
|
||||
|
||||
// ROCAVulnerableKey returns true if the key is vulnerable to ROCA.
|
||||
func ROCAVulnerableKey(k *rsa.PublicKey) bool {
|
||||
for i := range fingerprintPrimes {
|
||||
n := &big.Int{}
|
||||
n.Mod(k.N, big.NewInt(fingerprintPrimes[i]))
|
||||
n.Lsh(big.NewInt(1), uint(n.Uint64()))
|
||||
|
||||
mask := &big.Int{}
|
||||
mask.SetString(fingerprintMasks[i], 10)
|
||||
n.And(n, mask)
|
||||
|
||||
if n.Cmp(big.NewInt(0)) == 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
@ -1,242 +0,0 @@
|
||||
package verifier
|
||||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
tpb "github.com/google/go-attestation/proto"
|
||||
"github.com/google/go-tpm-tools/simulator"
|
||||
"github.com/google/go-tpm/tpm2"
|
||||
"github.com/google/go-tpm/tpmutil"
|
||||
)
|
||||
|
||||
func decodeBase64(in string, t *testing.T) []byte {
|
||||
out, err := base64.StdEncoding.DecodeString(in)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func TestVerifyAIK(t *testing.T) {
|
||||
pub := decodeBase64("AAEACwAFBHIAIJ3/y/NsODrmmfuYaNxty4nXFTiEvigDkiwSQVi/rSKuABAAFAAECAAAAAAAAQC/08gj/04z4xGMIVTmr02lzhI5epufXgU831xEpf2qpXfvtNGUfqTcgWF2EUux2HDPqgcj59dtXRobQdlr4uCGNzfZIGAej4JusLa4MjpG6W2DtJPot6F1Mry63talzJ36U47niy9Iesd34CO2p9Xk3+86ZmBnQ6PQ2roUNK3l7bKz6cFLM9drOLwCqU0AUl6pHvzYPPz+xXsPl3iaA2cM97oneUiJNmJM7wtR9OcaKyIA4wVlX5TndB9NwWq5Iuj8q2Sp40Dg0noXXGSPliAtVD8flkXtAcuI9UHkQbzu9cGPRdSJPMn743GONg3bYalFtcgh2VpACXkPbXB32J7B", t)
|
||||
creation := decodeBase64("AAAAAAAg47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFUBAAsAIgALWI9hwDRB3zYSkannqM5z0J1coQNA1Jz/oCRxJQwTaNwAIgALmyFYBhHeIU3FUKIAPgXFD3NXyasP3siQviDEyH7avu4AAA==", t)
|
||||
attest := decodeBase64("/1RDR4AaACIAC41+jhmEOue1MZhJjIk79ENar6i15rBvamXLpQnGTBCOAAAAAAAAD3GRNfU4syzJ1jQGATDCDteFC5C4ACIAC3ToMYGy9GXxcf8A0HvOuLOHbU7HPEppM47C7CMcU8TtACBDmJFUFO1f5+BYevaYdd3VtfMCsxIuHhoTZJczzLP2BA==", t)
|
||||
sig := decodeBase64("ABQABAEALVzJSnKRJU39gHjETaI89/sM1L6HwBPGNekw6NojSW8bwD5/W1cLRDakCsYKUQu68mmbjs8xaIVBRvVM2YWP10tbTWNB0iJc9b8rERhkk3QIIFm/XsiVZsb0mysTxfeh8zygaAKQ/50sYyzp+raD0Ho0mYIRKJOEdQ6chsBflM3eB8mCXGTugUfrET80q3iu0gncaKWbfxQaQUb9ZTPSJrTN64HQ9tlOfnGT+8++WA3hV0NqKMnoAqiI9GZnI5MPXs6XxEncu/GJLJpAYZakBiS74Jvlr34Pur32B4xjm1M25AUGHEIgb6r49S0sV+hzaKu45858lQRMXj01GcyBhw==", t)
|
||||
|
||||
verificationResults, err := VerifyAIK(2, &tpb.AikInfo{
|
||||
TpmAikInfo: &tpb.AikInfo_Tpm20{
|
||||
Tpm20: &tpb.Tpm20AikInfo{
|
||||
PublicBlob: pub,
|
||||
CreationData: creation,
|
||||
AttestationData: attest,
|
||||
SignatureData: sig,
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("VerifyAIK() returned err: %v", err)
|
||||
}
|
||||
if !verificationResults.GetSucceeded() {
|
||||
t.Errorf("verification.Succeeded = %v, want true", verificationResults.GetSucceeded())
|
||||
}
|
||||
}
|
||||
|
||||
func setupSimulatedTPM(t *testing.T) *simulator.Simulator {
|
||||
t.Helper()
|
||||
tpm, err := simulator.Get()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return tpm
|
||||
}
|
||||
|
||||
func allPCRs(tpm io.ReadWriter, hash tpm2.Algorithm) (map[uint32][]byte, error) {
|
||||
numPCRs := 24
|
||||
out := map[uint32][]byte{}
|
||||
|
||||
// The TPM 2.0 spec says that the TPM can partially fulfill the
|
||||
// request. As such, we repeat the command up to 8 times to get all
|
||||
// 24 PCRs.
|
||||
for i := 0; i < numPCRs; i++ {
|
||||
// Build a selection structure, specifying all PCRs we do
|
||||
// not have the value for.
|
||||
sel := tpm2.PCRSelection{Hash: hash}
|
||||
for pcr := 0; pcr < numPCRs; pcr++ {
|
||||
if _, present := out[uint32(pcr)]; !present {
|
||||
sel.PCRs = append(sel.PCRs, pcr)
|
||||
}
|
||||
}
|
||||
|
||||
// Ask the TPM for those PCR values.
|
||||
ret, err := tpm2.ReadPCRs(tpm, sel)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("tpm2.ReadPCRs(%+v) failed with err: %v", sel, err)
|
||||
}
|
||||
// Keep track of the PCRs we were actually given.
|
||||
for pcr, digest := range ret {
|
||||
out[uint32(pcr)] = digest
|
||||
}
|
||||
if len(out) == numPCRs {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(out) != numPCRs {
|
||||
return nil, fmt.Errorf("failed to read all PCRs, only read %d", len(out))
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func TestVerifyQuoteTPM20(t *testing.T) {
|
||||
tpm := setupSimulatedTPM(t)
|
||||
defer tpm.Close()
|
||||
if err := tpm.ManufactureReset(); err != nil {
|
||||
t.Fatalf("Failed to reset TPM: %v", err)
|
||||
}
|
||||
|
||||
// Create the attestation key.
|
||||
keyHandle, pub, _, _, _, _, err := tpm2.CreatePrimaryEx(tpm, tpm2.HandleEndorsement, tpm2.PCRSelection{}, "", "", tpm2.Public{
|
||||
Type: tpm2.AlgRSA,
|
||||
NameAlg: tpm2.AlgSHA256,
|
||||
Attributes: tpm2.FlagSignerDefault | tpm2.FlagNoDA,
|
||||
RSAParameters: &tpm2.RSAParams{
|
||||
Sign: &tpm2.SigScheme{
|
||||
Alg: tpm2.AlgRSASSA,
|
||||
Hash: tpm2.AlgSHA256,
|
||||
},
|
||||
KeyBits: 2048,
|
||||
Modulus: big.NewInt(0),
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("CreatePrimaryEx() failed: %v", err)
|
||||
}
|
||||
defer tpm2.FlushContext(tpm, keyHandle)
|
||||
|
||||
for _, alg := range []tpm2.Algorithm{tpm2.AlgSHA1, tpm2.AlgSHA256} {
|
||||
t.Run(fmt.Sprintf("Alg %x", alg), func(t *testing.T) {
|
||||
// Generate the quote.
|
||||
sel := tpm2.PCRSelection{Hash: alg}
|
||||
numPCRs := 24
|
||||
for pcr := 0; pcr < numPCRs; pcr++ {
|
||||
sel.PCRs = append(sel.PCRs, pcr)
|
||||
}
|
||||
nonce := []byte{1, 2, 3, 4}
|
||||
quote, qSig, err := tpm2.Quote(tpm, keyHandle, "", "", nonce, sel, tpm2.AlgNull)
|
||||
if err != nil {
|
||||
t.Fatalf("tpm2.Quote() failed: %v", err)
|
||||
}
|
||||
sig, err := tpmutil.Pack(qSig.Alg, qSig.RSA.HashAlg, qSig.RSA.Signature)
|
||||
if err != nil {
|
||||
t.Fatalf("tpmutil.Pack() failed: %v", err)
|
||||
}
|
||||
|
||||
PCRs, err := allPCRs(tpm, alg)
|
||||
if err != nil {
|
||||
t.Fatalf("allPCRs() failed: %v", err)
|
||||
}
|
||||
|
||||
verificationResults, err := VerifyQuote(2, pub, quote, sig, PCRs, nonce)
|
||||
if err != nil {
|
||||
t.Errorf("VerifyQuote failed: %v", err)
|
||||
}
|
||||
if !verificationResults.Succeeded {
|
||||
t.Logf("Verification results: %+v", verificationResults)
|
||||
t.Errorf("verificationResults.succeeded = %v, expected true", verificationResults.Succeeded)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRoca(t *testing.T) {
|
||||
key := &rsa.PublicKey{N: &big.Int{}}
|
||||
key.N.SetString("944e13208a280c37efc31c3114485e590192adbb8e11c87cad60cdef0037ce99278330d3f471a2538fa667802ed2a3c44a8b7dea826e888d0aa341fd664f7fa7", 16)
|
||||
|
||||
if !ROCAVulnerableKey(key) {
|
||||
t.Errorf("ROCAVulnerableKey() = %v, wanted true", ROCAVulnerableKey(key))
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyQuoteTPM12(t *testing.T) {
|
||||
tcs := []struct {
|
||||
PublicHex string
|
||||
QuoteHex string
|
||||
SignatureHex string
|
||||
Nonce []byte
|
||||
PCRs map[int]string
|
||||
}{
|
||||
{
|
||||
PublicHex: "00000001000100020000000c00000800000000020000000000000100be855eadb504443ec1a85f5894cf9ae6b97fe75c39debe2376d13e49632ea34dc917c99f0ea29c52349eba9b1abfd2a92e814057568338ea68a32a45f92ae23944d0765805489414f9c588778220a3f384b7b2c4be8132515e276eefde7cb807303f7a7d57900f94dda27e6abe5e411026b8be7637483747073fa731643807e4c3d7e6fdad0ea297beaaeb208465aa4906447fcddf1955f5ac0a439295f7b43fbe38d018009456c17426e4ebf1581c99e3a97ff151a0c649335a46ec8189849b4efe932cb3a7d57e2ee45e67a7fcb64da5041604f24fd6153898fbe5d8432d95b2ad5d4b89088f6306f6b1a7d8c55c748838a96d106efc39ce119b11ac51211b",
|
||||
QuoteHex: "0101000051554f54d45a9b15807eac8d85cd467ec0060815cc687c18a8b93257fea90bba13ede78f0db2d81ae4173c19",
|
||||
SignatureHex: "33a4260f049c64f7539ab5a5f5adf1c87fc31d9ae5165340636ba96c88b82eb402b46902315c65d0d8b7a861ec8cd3f0d1bb7d264420cb7dca8e3d5862c5ecf5114f3bde50890cbf8c05b95fb0f2c70c816f9e86f247c4377aa58e84f24e6a910ea414664b9cdd1ff4a3522994ec1e1f419a2e1e3f503689e4eb0606c0b3e9a42f4f7b74c937d4d061161390e1790b6561b0d288e3534fd1b62af6a8c232174e1cb1586b863bd20e95e73e52e27a0781c7160672257831eb9b1d5192098495ad2170490c5e52693385e43aeab95069eecdd3f80529fdcc7ff2ef6086c24c06576e53b77e2f88eafb3e9b9fd40d954a7e0ab4c01e5b9a73d5d1841c49924beb64",
|
||||
Nonce: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
|
||||
PCRs: map[int]string{
|
||||
0: "b777654263752ed0bfe13b369cf512b4661eee04",
|
||||
1: "c2b93db7e6f705f98419a35cc6e46deb639c6a28",
|
||||
2: "b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
|
||||
3: "b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236",
|
||||
4: "8f3fe5e128e3f2186bfca0b804900ec9ded96e39",
|
||||
5: "45a323382bd933f08e7f0e256bc8249e4095b1ec",
|
||||
6: "ee1b0f997d7517b286bc9d73a4cf742c65a769be",
|
||||
7: "9d42f8fe8bfd73fba0274c7db891d91fb7861562",
|
||||
8: "0000000000000000000000000000000000000000",
|
||||
9: "0000000000000000000000000000000000000000",
|
||||
10: "0000000000000000000000000000000000000000",
|
||||
11: "ebb98df76613280f20dc38221143a9e727399486",
|
||||
12: "575e12d9ec16d6512648f25b65d38b4eb27a2d6d",
|
||||
13: "a9f1781a95d2e37970d1d73c463157fa016d9858",
|
||||
14: "fc76feaf714c844cc888ea454ddf97c0ed220b61",
|
||||
15: "0000000000000000000000000000000000000000",
|
||||
16: "0000000000000000000000000000000000000000",
|
||||
17: "ffffffffffffffffffffffffffffffffffffffff",
|
||||
18: "ffffffffffffffffffffffffffffffffffffffff",
|
||||
19: "ffffffffffffffffffffffffffffffffffffffff",
|
||||
20: "ffffffffffffffffffffffffffffffffffffffff",
|
||||
21: "ffffffffffffffffffffffffffffffffffffffff",
|
||||
22: "ffffffffffffffffffffffffffffffffffffffff",
|
||||
23: "0000000000000000000000000000000000000000",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, testcase := range tcs {
|
||||
tc := testcase
|
||||
t.Run(fmt.Sprintf("case %d", i), func(t *testing.T) {
|
||||
pub, err := hex.DecodeString(tc.PublicHex)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
quote, err := hex.DecodeString(tc.QuoteHex)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
sig, err := hex.DecodeString(tc.SignatureHex)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
pcrs := make(map[uint32][]byte)
|
||||
for idx, h := range tc.PCRs {
|
||||
pcrs[uint32(idx)], err = hex.DecodeString(h)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
verificationResults, err := VerifyQuote(1, pub, quote, sig, pcrs, tc.Nonce)
|
||||
if err != nil {
|
||||
t.Errorf("VerifyQuote failed: %v", err)
|
||||
}
|
||||
if !verificationResults.Succeeded {
|
||||
t.Errorf("verificationResults.Succeeded = %v, want %v", verificationResults.Succeeded, true)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user