From a8f71d94b60af02d742d02919112a6cc66e1dfec Mon Sep 17 00:00:00 2001 From: Alex Wu Date: Wed, 17 Nov 2021 10:18:43 -0600 Subject: [PATCH 1/5] Add LinuxKernelState, with a command_line field We will use this message to parse the command line passed from the bootloader. --- proto/attest.proto | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/proto/attest.proto b/proto/attest.proto index 5c8509dd..7dee3e40 100644 --- a/proto/attest.proto +++ b/proto/attest.proto @@ -71,6 +71,14 @@ message GrubState { // and kernel modules. repeated string commands = 2; } + +// The state of the Linux kernel. +// At the moment, parsing LinuxKernelState relies on parsing the GrubState. +// To do so, use ParseOpts{Loader: GRUB} when calling ParseMachineState. +message LinuxKernelState { + // The kernel command line. + string command_line = 1; +} // A parsed event from the TCG event log message Event { @@ -189,7 +197,7 @@ message MachineState { GrubState grub = 5; - // LinuxKernelState linux_kernel = 6; + LinuxKernelState linux_kernel = 6; AttestedCosState cos = 7; } From fc372a0efa62576401b15db1bef9492cf1dfd6c6 Mon Sep 17 00:00:00 2001 From: Alex Wu Date: Wed, 17 Nov 2021 10:20:22 -0600 Subject: [PATCH 2/5] Regenerate the attest proto for Linux kernel state --- proto/attest/attest.pb.go | 514 ++++++++++++++++++++++---------------- 1 file changed, 297 insertions(+), 217 deletions(-) diff --git a/proto/attest/attest.pb.go b/proto/attest/attest.pb.go index 3426f93b..a6070992 100644 --- a/proto/attest/attest.pb.go +++ b/proto/attest/attest.pb.go @@ -582,6 +582,57 @@ func (x *GrubState) GetCommands() []string { return nil } +// The state of the Linux kernel. +// At the moment, parsing LinuxKernelState relies on parsing the GrubState. +// To do so, use ParseOpts{Loader: GRUB} when calling ParseMachineState. +type LinuxKernelState struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The kernel command line. + CommandLine string `protobuf:"bytes,1,opt,name=command_line,json=commandLine,proto3" json:"command_line,omitempty"` +} + +func (x *LinuxKernelState) Reset() { + *x = LinuxKernelState{} + if protoimpl.UnsafeEnabled { + mi := &file_attest_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LinuxKernelState) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LinuxKernelState) ProtoMessage() {} + +func (x *LinuxKernelState) ProtoReflect() protoreflect.Message { + mi := &file_attest_proto_msgTypes[5] + 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 LinuxKernelState.ProtoReflect.Descriptor instead. +func (*LinuxKernelState) Descriptor() ([]byte, []int) { + return file_attest_proto_rawDescGZIP(), []int{5} +} + +func (x *LinuxKernelState) GetCommandLine() string { + if x != nil { + return x.CommandLine + } + return "" +} + // A parsed event from the TCG event log type Event struct { state protoimpl.MessageState @@ -606,7 +657,7 @@ type Event struct { func (x *Event) Reset() { *x = Event{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[5] + mi := &file_attest_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -619,7 +670,7 @@ func (x *Event) String() string { func (*Event) ProtoMessage() {} func (x *Event) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[5] + mi := &file_attest_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -632,7 +683,7 @@ func (x *Event) ProtoReflect() protoreflect.Message { // Deprecated: Use Event.ProtoReflect.Descriptor instead. func (*Event) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{5} + return file_attest_proto_rawDescGZIP(), []int{6} } func (x *Event) GetPcrIndex() uint32 { @@ -688,7 +739,7 @@ type Certificate struct { func (x *Certificate) Reset() { *x = Certificate{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[6] + mi := &file_attest_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -701,7 +752,7 @@ func (x *Certificate) String() string { func (*Certificate) ProtoMessage() {} func (x *Certificate) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[6] + mi := &file_attest_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -714,7 +765,7 @@ func (x *Certificate) ProtoReflect() protoreflect.Message { // Deprecated: Use Certificate.ProtoReflect.Descriptor instead. func (*Certificate) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{6} + return file_attest_proto_rawDescGZIP(), []int{7} } func (m *Certificate) GetRepresentation() isCertificate_Representation { @@ -769,7 +820,7 @@ type Database struct { func (x *Database) Reset() { *x = Database{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[7] + mi := &file_attest_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -782,7 +833,7 @@ func (x *Database) String() string { func (*Database) ProtoMessage() {} func (x *Database) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[7] + mi := &file_attest_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -795,7 +846,7 @@ func (x *Database) ProtoReflect() protoreflect.Message { // Deprecated: Use Database.ProtoReflect.Descriptor instead. func (*Database) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{7} + return file_attest_proto_rawDescGZIP(), []int{8} } func (x *Database) GetCerts() []*Certificate { @@ -832,7 +883,7 @@ type SecureBootState struct { func (x *SecureBootState) Reset() { *x = SecureBootState{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[8] + mi := &file_attest_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -845,7 +896,7 @@ func (x *SecureBootState) String() string { func (*SecureBootState) ProtoMessage() {} func (x *SecureBootState) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[8] + mi := &file_attest_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -858,7 +909,7 @@ func (x *SecureBootState) ProtoReflect() protoreflect.Message { // Deprecated: Use SecureBootState.ProtoReflect.Descriptor instead. func (*SecureBootState) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{8} + return file_attest_proto_rawDescGZIP(), []int{9} } func (x *SecureBootState) GetEnabled() bool { @@ -913,7 +964,7 @@ type ContainerState struct { func (x *ContainerState) Reset() { *x = ContainerState{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[9] + mi := &file_attest_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -926,7 +977,7 @@ func (x *ContainerState) String() string { func (*ContainerState) ProtoMessage() {} func (x *ContainerState) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[9] + mi := &file_attest_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -939,7 +990,7 @@ func (x *ContainerState) ProtoReflect() protoreflect.Message { // Deprecated: Use ContainerState.ProtoReflect.Descriptor instead. func (*ContainerState) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{9} + return file_attest_proto_rawDescGZIP(), []int{10} } func (x *ContainerState) GetImageReference() string { @@ -1011,7 +1062,7 @@ type SemanticVersion struct { func (x *SemanticVersion) Reset() { *x = SemanticVersion{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[10] + mi := &file_attest_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1024,7 +1075,7 @@ func (x *SemanticVersion) String() string { func (*SemanticVersion) ProtoMessage() {} func (x *SemanticVersion) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[10] + mi := &file_attest_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1037,7 +1088,7 @@ func (x *SemanticVersion) ProtoReflect() protoreflect.Message { // Deprecated: Use SemanticVersion.ProtoReflect.Descriptor instead. func (*SemanticVersion) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{10} + return file_attest_proto_rawDescGZIP(), []int{11} } func (x *SemanticVersion) GetMajor() uint32 { @@ -1074,7 +1125,7 @@ type AttestedCosState struct { func (x *AttestedCosState) Reset() { *x = AttestedCosState{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[11] + mi := &file_attest_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1087,7 +1138,7 @@ func (x *AttestedCosState) String() string { func (*AttestedCosState) ProtoMessage() {} func (x *AttestedCosState) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[11] + mi := &file_attest_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1100,7 +1151,7 @@ func (x *AttestedCosState) ProtoReflect() protoreflect.Message { // Deprecated: Use AttestedCosState.ProtoReflect.Descriptor instead. func (*AttestedCosState) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{11} + return file_attest_proto_rawDescGZIP(), []int{12} } func (x *AttestedCosState) GetContainer() *ContainerState { @@ -1138,15 +1189,16 @@ type MachineState struct { // The hash algorithm used when verifying the Attestation. This indicates: // - which PCR bank was used for for quote validation and event log replay // - the hash algorithm used to calculate event digests - Hash tpm.HashAlgo `protobuf:"varint,4,opt,name=hash,proto3,enum=tpm.HashAlgo" json:"hash,omitempty"` - Grub *GrubState `protobuf:"bytes,5,opt,name=grub,proto3" json:"grub,omitempty"` - Cos *AttestedCosState `protobuf:"bytes,7,opt,name=cos,proto3" json:"cos,omitempty"` + Hash tpm.HashAlgo `protobuf:"varint,4,opt,name=hash,proto3,enum=tpm.HashAlgo" json:"hash,omitempty"` + Grub *GrubState `protobuf:"bytes,5,opt,name=grub,proto3" json:"grub,omitempty"` + LinuxKernel *LinuxKernelState `protobuf:"bytes,6,opt,name=linux_kernel,json=linuxKernel,proto3" json:"linux_kernel,omitempty"` + Cos *AttestedCosState `protobuf:"bytes,7,opt,name=cos,proto3" json:"cos,omitempty"` } func (x *MachineState) Reset() { *x = MachineState{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[12] + mi := &file_attest_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1159,7 +1211,7 @@ func (x *MachineState) String() string { func (*MachineState) ProtoMessage() {} func (x *MachineState) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[12] + mi := &file_attest_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1172,7 +1224,7 @@ func (x *MachineState) ProtoReflect() protoreflect.Message { // Deprecated: Use MachineState.ProtoReflect.Descriptor instead. func (*MachineState) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{12} + return file_attest_proto_rawDescGZIP(), []int{13} } func (x *MachineState) GetPlatform() *PlatformState { @@ -1210,6 +1262,13 @@ func (x *MachineState) GetGrub() *GrubState { return nil } +func (x *MachineState) GetLinuxKernel() *LinuxKernelState { + if x != nil { + return x.LinuxKernel + } + return nil +} + func (x *MachineState) GetCos() *AttestedCosState { if x != nil { return x.Cos @@ -1238,7 +1297,7 @@ type PlatformPolicy struct { func (x *PlatformPolicy) Reset() { *x = PlatformPolicy{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[13] + mi := &file_attest_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1251,7 +1310,7 @@ func (x *PlatformPolicy) String() string { func (*PlatformPolicy) ProtoMessage() {} func (x *PlatformPolicy) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[13] + mi := &file_attest_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1264,7 +1323,7 @@ func (x *PlatformPolicy) ProtoReflect() protoreflect.Message { // Deprecated: Use PlatformPolicy.ProtoReflect.Descriptor instead. func (*PlatformPolicy) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{13} + return file_attest_proto_rawDescGZIP(), []int{14} } func (x *PlatformPolicy) GetAllowedScrtmVersionIds() [][]byte { @@ -1300,7 +1359,7 @@ type Policy struct { func (x *Policy) Reset() { *x = Policy{} if protoimpl.UnsafeEnabled { - mi := &file_attest_proto_msgTypes[14] + mi := &file_attest_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1313,7 +1372,7 @@ func (x *Policy) String() string { func (*Policy) ProtoMessage() {} func (x *Policy) ProtoReflect() protoreflect.Message { - mi := &file_attest_proto_msgTypes[14] + mi := &file_attest_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1326,7 +1385,7 @@ func (x *Policy) ProtoReflect() protoreflect.Message { // Deprecated: Use Policy.ProtoReflect.Descriptor instead. func (*Policy) Descriptor() ([]byte, []int) { - return file_attest_proto_rawDescGZIP(), []int{14} + return file_attest_proto_rawDescGZIP(), []int{15} } func (x *Policy) GetPlatform() *PlatformPolicy { @@ -1395,144 +1454,151 @@ var file_attest_proto_rawDesc = []byte{ 0x32, 0x10, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x47, 0x72, 0x75, 0x62, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x6d, - 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, - 0x1b, 0x0a, 0x09, 0x70, 0x63, 0x72, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x08, 0x70, 0x63, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x25, 0x0a, 0x0e, - 0x75, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x75, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, - 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, - 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, - 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x22, 0x72, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74, - 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x64, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x64, 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x0a, 0x77, - 0x65, 0x6c, 0x6c, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x1c, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, - 0x77, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, - 0x09, 0x77, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x72, 0x65, - 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x4d, 0x0a, 0x08, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x05, 0x63, 0x65, 0x72, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, - 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x05, 0x63, 0x65, - 0x72, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x0f, - 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x02, 0x64, 0x62, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x02, 0x64, 0x62, 0x12, 0x22, 0x0a, 0x03, 0x64, - 0x62, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, - 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x03, 0x64, 0x62, 0x78, 0x12, - 0x2e, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x52, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, - 0x93, 0x04, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x65, - 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, - 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x44, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x3c, - 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0d, 0x72, - 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x19, 0x0a, 0x08, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, - 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x3e, 0x0a, 0x08, 0x65, - 0x6e, 0x76, 0x5f, 0x76, 0x61, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, - 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6f, - 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, - 0x41, 0x72, 0x67, 0x73, 0x12, 0x5d, 0x0a, 0x13, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, - 0x65, 0x6e, 0x5f, 0x65, 0x6e, 0x76, 0x5f, 0x76, 0x61, 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2d, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x35, 0x0a, 0x10, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4b, 0x65, + 0x72, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x6e, 0x65, 0x22, 0xa0, 0x01, 0x0a, + 0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x63, 0x72, 0x5f, 0x69, 0x6e, + 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x70, 0x63, 0x72, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x12, 0x25, 0x0a, 0x0e, 0x75, 0x6e, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, + 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x75, 0x6e, 0x74, + 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x16, + 0x0a, 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, + 0x5f, 0x76, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x64, 0x22, + 0x72, 0x0a, 0x0b, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x12, + 0x0a, 0x03, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x64, + 0x65, 0x72, 0x12, 0x3d, 0x0a, 0x0a, 0x77, 0x65, 0x6c, 0x6c, 0x5f, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x48, 0x00, 0x52, 0x09, 0x77, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, + 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x4d, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, + 0x29, 0x0a, 0x05, 0x63, 0x65, 0x72, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, + 0x61, 0x74, 0x65, 0x52, 0x05, 0x63, 0x65, 0x72, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x22, 0xa1, 0x01, 0x0a, 0x0f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x20, 0x0a, 0x02, 0x64, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, + 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x02, + 0x64, 0x62, 0x12, 0x22, 0x0a, 0x03, 0x64, 0x62, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x10, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x52, 0x03, 0x64, 0x62, 0x78, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, + 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x09, 0x61, 0x75, 0x74, + 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x22, 0x93, 0x04, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x64, 0x69, 0x67, 0x65, + 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x44, + 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x3c, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, + 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, + 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x52, 0x0d, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x49, 0x64, 0x12, 0x12, + 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, + 0x67, 0x73, 0x12, 0x3e, 0x0a, 0x08, 0x65, 0x6e, 0x76, 0x5f, 0x76, 0x61, 0x72, 0x73, 0x18, 0x06, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x76, + 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x56, 0x61, + 0x72, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, + 0x5f, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x6f, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x41, 0x72, 0x67, 0x73, 0x12, 0x5d, 0x0a, 0x13, 0x6f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x5f, 0x65, 0x6e, 0x76, 0x5f, 0x76, 0x61, + 0x72, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, + 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x45, 0x6e, 0x76, 0x56, 0x61, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x11, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, + 0x64, 0x65, 0x6e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, + 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, 0x0a, 0x16, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x11, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x45, 0x6e, 0x76, 0x56, - 0x61, 0x72, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x45, 0x6e, 0x76, 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, - 0x44, 0x0a, 0x16, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x45, 0x6e, 0x76, - 0x56, 0x61, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x53, 0x0a, 0x0f, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, - 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, - 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, - 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68, 0x22, 0xc6, 0x01, 0x0a, 0x10, 0x41, - 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, - 0x34, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x0b, 0x63, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x74, 0x74, - 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x73, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x42, 0x0a, 0x10, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x2e, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x0f, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0x9f, 0x02, 0x0a, 0x0c, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x70, - 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x38, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x75, 0x72, - 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, - 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, - 0x74, 0x12, 0x2c, 0x0a, 0x0a, 0x72, 0x61, 0x77, 0x5f, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x45, - 0x76, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x72, 0x61, 0x77, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, - 0x21, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, - 0x74, 0x70, 0x6d, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x41, 0x6c, 0x67, 0x6f, 0x52, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x12, 0x25, 0x0a, 0x04, 0x67, 0x72, 0x75, 0x62, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x47, 0x72, 0x75, 0x62, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x04, 0x67, 0x72, 0x75, 0x62, 0x12, 0x2a, 0x0a, 0x03, 0x63, 0x6f, 0x73, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, - 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x03, 0x63, 0x6f, 0x73, 0x22, 0xde, 0x01, 0x0a, 0x0e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, - 0x72, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x19, 0x61, 0x6c, 0x6c, 0x6f, - 0x77, 0x65, 0x64, 0x5f, 0x73, 0x63, 0x72, 0x74, 0x6d, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x16, 0x61, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x53, 0x63, 0x72, 0x74, 0x6d, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x49, 0x64, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x67, - 0x63, 0x65, 0x5f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x19, 0x6d, 0x69, 0x6e, 0x69, 0x6d, - 0x75, 0x6d, 0x47, 0x63, 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x12, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x5f, - 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x21, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x47, 0x43, 0x45, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, - 0x6f, 0x67, 0x79, 0x52, 0x11, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x54, 0x65, 0x63, 0x68, - 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x22, 0x3c, 0x0a, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x12, 0x32, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, - 0x66, 0x6f, 0x72, 0x6d, 0x2a, 0x42, 0x0a, 0x19, 0x47, 0x43, 0x45, 0x43, 0x6f, 0x6e, 0x66, 0x69, - 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, - 0x79, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x41, - 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, 0x41, 0x4d, 0x44, 0x5f, - 0x53, 0x45, 0x56, 0x5f, 0x45, 0x53, 0x10, 0x02, 0x2a, 0x62, 0x0a, 0x14, 0x57, 0x65, 0x6c, 0x6c, - 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1c, 0x0a, - 0x18, 0x4d, 0x53, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, 0x50, 0x52, 0x4f, 0x44, - 0x5f, 0x50, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, 0x31, 0x10, 0x01, 0x12, 0x1f, 0x0a, 0x1b, 0x4d, - 0x53, 0x5f, 0x54, 0x48, 0x49, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x59, 0x5f, 0x55, 0x45, - 0x46, 0x49, 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, 0x31, 0x10, 0x02, 0x2a, 0x35, 0x0a, 0x0d, - 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x0a, 0x0a, - 0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x4f, 0x6e, 0x46, - 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x4e, 0x65, 0x76, 0x65, - 0x72, 0x10, 0x02, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x74, 0x70, 0x6d, 0x2d, - 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x74, 0x74, 0x65, - 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x53, 0x0a, 0x0f, + 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, 0x69, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, + 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, + 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, + 0x68, 0x22, 0xc6, 0x01, 0x0a, 0x10, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6f, + 0x73, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x74, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x0b, + 0x63, 0x6f, 0x73, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, 0x6d, 0x61, 0x6e, + 0x74, 0x69, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x63, 0x6f, 0x73, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x42, 0x0a, 0x10, 0x6c, 0x61, 0x75, 0x6e, 0x63, 0x68, + 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, 0x6d, 0x61, 0x6e, 0x74, + 0x69, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x6c, 0x61, 0x75, 0x6e, 0x63, + 0x68, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xdc, 0x02, 0x0a, 0x0c, 0x4d, + 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x08, 0x70, + 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x38, + 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x65, 0x63, + 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0a, 0x73, 0x65, + 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74, 0x12, 0x2c, 0x0a, 0x0a, 0x72, 0x61, 0x77, 0x5f, + 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, + 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x72, 0x61, 0x77, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x74, 0x70, 0x6d, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x41, + 0x6c, 0x67, 0x6f, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x25, 0x0a, 0x04, 0x67, 0x72, 0x75, + 0x62, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, + 0x2e, 0x47, 0x72, 0x75, 0x62, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x04, 0x67, 0x72, 0x75, 0x62, + 0x12, 0x3b, 0x0a, 0x0c, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x0b, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x12, 0x2a, 0x0a, + 0x03, 0x63, 0x6f, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x74, 0x74, + 0x65, 0x73, 0x74, 0x2e, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x73, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x03, 0x63, 0x6f, 0x73, 0x22, 0xde, 0x01, 0x0a, 0x0e, 0x50, 0x6c, + 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x39, 0x0a, 0x19, + 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x73, 0x63, 0x72, 0x74, 0x6d, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x16, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x53, 0x63, 0x72, 0x74, 0x6d, 0x56, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x69, 0x6e, 0x69, 0x6d, + 0x75, 0x6d, 0x5f, 0x67, 0x63, 0x65, 0x5f, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x19, 0x6d, + 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x47, 0x63, 0x65, 0x46, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, + 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x12, 0x6d, 0x69, 0x6e, 0x69, + 0x6d, 0x75, 0x6d, 0x5f, 0x74, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x47, 0x43, + 0x45, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x11, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, + 0x54, 0x65, 0x63, 0x68, 0x6e, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x22, 0x3c, 0x0a, 0x06, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x12, 0x32, 0x0a, 0x08, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x2e, + 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x08, + 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2a, 0x42, 0x0a, 0x19, 0x47, 0x43, 0x45, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x54, 0x65, 0x63, 0x68, 0x6e, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, + 0x0b, 0x0a, 0x07, 0x41, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, 0x10, 0x01, 0x12, 0x0e, 0x0a, 0x0a, + 0x41, 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x56, 0x5f, 0x45, 0x53, 0x10, 0x02, 0x2a, 0x62, 0x0a, 0x14, + 0x57, 0x65, 0x6c, 0x6c, 0x4b, 0x6e, 0x6f, 0x77, 0x6e, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, + 0x00, 0x12, 0x1c, 0x0a, 0x18, 0x4d, 0x53, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x53, 0x5f, + 0x50, 0x52, 0x4f, 0x44, 0x5f, 0x50, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, 0x31, 0x10, 0x01, 0x12, + 0x1f, 0x0a, 0x1b, 0x4d, 0x53, 0x5f, 0x54, 0x48, 0x49, 0x52, 0x44, 0x5f, 0x50, 0x41, 0x52, 0x54, + 0x59, 0x5f, 0x55, 0x45, 0x46, 0x49, 0x5f, 0x43, 0x41, 0x5f, 0x32, 0x30, 0x31, 0x31, 0x10, 0x02, + 0x2a, 0x35, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x41, 0x6c, 0x77, 0x61, 0x79, 0x73, 0x10, 0x00, 0x12, 0x0d, 0x0a, + 0x09, 0x4f, 0x6e, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, + 0x4e, 0x65, 0x76, 0x65, 0x72, 0x10, 0x02, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6f, 0x2d, + 0x74, 0x70, 0x6d, 0x2d, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, + 0x61, 0x74, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1548,7 +1614,7 @@ func file_attest_proto_rawDescGZIP() []byte { } var file_attest_proto_enumTypes = make([]protoimpl.EnumInfo, 3) -var file_attest_proto_msgTypes = make([]protoimpl.MessageInfo, 17) +var file_attest_proto_msgTypes = make([]protoimpl.MessageInfo, 18) var file_attest_proto_goTypes = []interface{}{ (GCEConfidentialTechnology)(0), // 0: attest.GCEConfidentialTechnology (WellKnownCertificate)(0), // 1: attest.WellKnownCertificate @@ -1558,51 +1624,53 @@ var file_attest_proto_goTypes = []interface{}{ (*PlatformState)(nil), // 5: attest.PlatformState (*GrubFile)(nil), // 6: attest.GrubFile (*GrubState)(nil), // 7: attest.GrubState - (*Event)(nil), // 8: attest.Event - (*Certificate)(nil), // 9: attest.Certificate - (*Database)(nil), // 10: attest.Database - (*SecureBootState)(nil), // 11: attest.SecureBootState - (*ContainerState)(nil), // 12: attest.ContainerState - (*SemanticVersion)(nil), // 13: attest.SemanticVersion - (*AttestedCosState)(nil), // 14: attest.AttestedCosState - (*MachineState)(nil), // 15: attest.MachineState - (*PlatformPolicy)(nil), // 16: attest.PlatformPolicy - (*Policy)(nil), // 17: attest.Policy - nil, // 18: attest.ContainerState.EnvVarsEntry - nil, // 19: attest.ContainerState.OverriddenEnvVarsEntry - (*tpm.Quote)(nil), // 20: tpm.Quote - (tpm.HashAlgo)(0), // 21: tpm.HashAlgo + (*LinuxKernelState)(nil), // 8: attest.LinuxKernelState + (*Event)(nil), // 9: attest.Event + (*Certificate)(nil), // 10: attest.Certificate + (*Database)(nil), // 11: attest.Database + (*SecureBootState)(nil), // 12: attest.SecureBootState + (*ContainerState)(nil), // 13: attest.ContainerState + (*SemanticVersion)(nil), // 14: attest.SemanticVersion + (*AttestedCosState)(nil), // 15: attest.AttestedCosState + (*MachineState)(nil), // 16: attest.MachineState + (*PlatformPolicy)(nil), // 17: attest.PlatformPolicy + (*Policy)(nil), // 18: attest.Policy + nil, // 19: attest.ContainerState.EnvVarsEntry + nil, // 20: attest.ContainerState.OverriddenEnvVarsEntry + (*tpm.Quote)(nil), // 21: tpm.Quote + (tpm.HashAlgo)(0), // 22: tpm.HashAlgo } var file_attest_proto_depIdxs = []int32{ - 20, // 0: attest.Attestation.quotes:type_name -> tpm.Quote + 21, // 0: attest.Attestation.quotes:type_name -> tpm.Quote 3, // 1: attest.Attestation.instance_info:type_name -> attest.GCEInstanceInfo 0, // 2: attest.PlatformState.technology:type_name -> attest.GCEConfidentialTechnology 3, // 3: attest.PlatformState.instance_info:type_name -> attest.GCEInstanceInfo 6, // 4: attest.GrubState.files:type_name -> attest.GrubFile 1, // 5: attest.Certificate.well_known:type_name -> attest.WellKnownCertificate - 9, // 6: attest.Database.certs:type_name -> attest.Certificate - 10, // 7: attest.SecureBootState.db:type_name -> attest.Database - 10, // 8: attest.SecureBootState.dbx:type_name -> attest.Database - 10, // 9: attest.SecureBootState.authority:type_name -> attest.Database + 10, // 6: attest.Database.certs:type_name -> attest.Certificate + 11, // 7: attest.SecureBootState.db:type_name -> attest.Database + 11, // 8: attest.SecureBootState.dbx:type_name -> attest.Database + 11, // 9: attest.SecureBootState.authority:type_name -> attest.Database 2, // 10: attest.ContainerState.restart_policy:type_name -> attest.RestartPolicy - 18, // 11: attest.ContainerState.env_vars:type_name -> attest.ContainerState.EnvVarsEntry - 19, // 12: attest.ContainerState.overridden_env_vars:type_name -> attest.ContainerState.OverriddenEnvVarsEntry - 12, // 13: attest.AttestedCosState.container:type_name -> attest.ContainerState - 13, // 14: attest.AttestedCosState.cos_version:type_name -> attest.SemanticVersion - 13, // 15: attest.AttestedCosState.launcher_version:type_name -> attest.SemanticVersion + 19, // 11: attest.ContainerState.env_vars:type_name -> attest.ContainerState.EnvVarsEntry + 20, // 12: attest.ContainerState.overridden_env_vars:type_name -> attest.ContainerState.OverriddenEnvVarsEntry + 13, // 13: attest.AttestedCosState.container:type_name -> attest.ContainerState + 14, // 14: attest.AttestedCosState.cos_version:type_name -> attest.SemanticVersion + 14, // 15: attest.AttestedCosState.launcher_version:type_name -> attest.SemanticVersion 5, // 16: attest.MachineState.platform:type_name -> attest.PlatformState - 11, // 17: attest.MachineState.secure_boot:type_name -> attest.SecureBootState - 8, // 18: attest.MachineState.raw_events:type_name -> attest.Event - 21, // 19: attest.MachineState.hash:type_name -> tpm.HashAlgo + 12, // 17: attest.MachineState.secure_boot:type_name -> attest.SecureBootState + 9, // 18: attest.MachineState.raw_events:type_name -> attest.Event + 22, // 19: attest.MachineState.hash:type_name -> tpm.HashAlgo 7, // 20: attest.MachineState.grub:type_name -> attest.GrubState - 14, // 21: attest.MachineState.cos:type_name -> attest.AttestedCosState - 0, // 22: attest.PlatformPolicy.minimum_technology:type_name -> attest.GCEConfidentialTechnology - 16, // 23: attest.Policy.platform:type_name -> attest.PlatformPolicy - 24, // [24:24] is the sub-list for method output_type - 24, // [24:24] is the sub-list for method input_type - 24, // [24:24] is the sub-list for extension type_name - 24, // [24:24] is the sub-list for extension extendee - 0, // [0:24] is the sub-list for field type_name + 8, // 21: attest.MachineState.linux_kernel:type_name -> attest.LinuxKernelState + 15, // 22: attest.MachineState.cos:type_name -> attest.AttestedCosState + 0, // 23: attest.PlatformPolicy.minimum_technology:type_name -> attest.GCEConfidentialTechnology + 17, // 24: attest.Policy.platform:type_name -> attest.PlatformPolicy + 25, // [25:25] is the sub-list for method output_type + 25, // [25:25] is the sub-list for method input_type + 25, // [25:25] is the sub-list for extension type_name + 25, // [25:25] is the sub-list for extension extendee + 0, // [0:25] is the sub-list for field type_name } func init() { file_attest_proto_init() } @@ -1672,7 +1740,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Event); i { + switch v := v.(*LinuxKernelState); i { case 0: return &v.state case 1: @@ -1684,7 +1752,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Certificate); i { + switch v := v.(*Event); i { case 0: return &v.state case 1: @@ -1696,7 +1764,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Database); i { + switch v := v.(*Certificate); i { case 0: return &v.state case 1: @@ -1708,7 +1776,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SecureBootState); i { + switch v := v.(*Database); i { case 0: return &v.state case 1: @@ -1720,7 +1788,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ContainerState); i { + switch v := v.(*SecureBootState); i { case 0: return &v.state case 1: @@ -1732,7 +1800,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SemanticVersion); i { + switch v := v.(*ContainerState); i { case 0: return &v.state case 1: @@ -1744,7 +1812,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttestedCosState); i { + switch v := v.(*SemanticVersion); i { case 0: return &v.state case 1: @@ -1756,7 +1824,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MachineState); i { + switch v := v.(*AttestedCosState); i { case 0: return &v.state case 1: @@ -1768,7 +1836,7 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PlatformPolicy); i { + switch v := v.(*MachineState); i { case 0: return &v.state case 1: @@ -1780,6 +1848,18 @@ func file_attest_proto_init() { } } file_attest_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PlatformPolicy); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_attest_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Policy); i { case 0: return &v.state @@ -1796,7 +1876,7 @@ func file_attest_proto_init() { (*PlatformState_ScrtmVersionId)(nil), (*PlatformState_GceVersion)(nil), } - file_attest_proto_msgTypes[6].OneofWrappers = []interface{}{ + file_attest_proto_msgTypes[7].OneofWrappers = []interface{}{ (*Certificate_Der)(nil), (*Certificate_WellKnown)(nil), } @@ -1806,7 +1886,7 @@ func file_attest_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_attest_proto_rawDesc, NumEnums: 3, - NumMessages: 17, + NumMessages: 18, NumExtensions: 0, NumServices: 0, }, From 87f4276b10546a346843f5d0ff9fb896bc9cae2c Mon Sep 17 00:00:00 2001 From: Alex Wu Date: Thu, 30 Jun 2022 17:26:07 -0700 Subject: [PATCH 3/5] Parse LinuxKernelState/kernel cmdline from GRUB This supports reading the kernel cmdline from all of the GRUB commands. --- server/eventlog.go | 60 ++++++++++++++++++++++++++++++++++++++++++---- server/verify.go | 11 --------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/server/eventlog.go b/server/eventlog.go index 0a610de5..40f2722b 100644 --- a/server/eventlog.go +++ b/server/eventlog.go @@ -15,6 +15,19 @@ import ( "github.com/google/go-tpm/tpm2" ) +var ( + newGrubKernelCmdlinePrefix = []byte("kernel_cmdline: ") + oldGrubKernelCmdlinePrefix = []byte("grub_kernel_cmdline ") + // See https://www.gnu.org/software/grub/manual/grub/grub.html#Measured-Boot. + validPrefixes = [][]byte{[]byte("grub_cmd: "), + newGrubKernelCmdlinePrefix, + []byte("module_cmdline: "), + // Older style prefixes: + // https://src.fedoraproject.org/rpms/grub2/blob/c789522f7cfa19a10cd716a1db24dab5499c6e5c/f/0224-Rework-TPM-measurements.patch + oldGrubKernelCmdlinePrefix, + []byte("grub_cmd ")} +) + // parsePCClientEventLog parses a raw event log and replays the parsed event // log against the given PCR values. It returns the corresponding MachineState // containing the events verified by particular PCR indexes/digests. It returns @@ -48,19 +61,25 @@ func parsePCClientEventLog(rawEventLog []byte, pcrs *tpmpb.PCRs, loader Bootload } var grub *pb.GrubState + var kernel *pb.LinuxKernelState if loader == GRUB { grub, err = getGrubState(cryptoHash, rawEvents) if err != nil { errors = append(errors, err) } + kernel, err = getLinuxKernelStateFromGRUB(grub) + if err != nil { + errors = append(errors, err) + } } return &pb.MachineState{ - Platform: platform, - SecureBoot: sbState, - RawEvents: rawEvents, - Hash: pcrs.GetHash(), - Grub: grub, + Platform: platform, + SecureBoot: sbState, + RawEvents: rawEvents, + Hash: pcrs.GetHash(), + Grub: grub, + LinuxKernel: kernel, }, createGroupedError("failed to fully parse MachineState:", errors) } @@ -378,3 +397,34 @@ func getGrubState(hash crypto.Hash, events []*pb.Event) (*pb.GrubState, error) { } return &pb.GrubState{Files: files, Commands: commands}, nil } + +func getLinuxKernelStateFromGRUB(grub *pb.GrubState) (*pb.LinuxKernelState, error) { + var cmdline string + seen := false + + for _, command := range grub.GetCommands() { + // GRUB config is always in UTF-8: https://www.gnu.org/software/grub/manual/grub/html_node/Internationalisation.html. + cmdBytes := []byte(command) + suffixAt := getGrubKernelCmdlineSuffix(cmdBytes) + if suffixAt == -1 { + continue + } + + if seen { + return nil, fmt.Errorf("more than one kernel commandline in GRUB commands") + } + seen = true + cmdline = command[suffixAt:] + } + + return &pb.LinuxKernelState{CommandLine: cmdline}, nil +} + +func getGrubKernelCmdlineSuffix(grubCmd []byte) int { + for _, prefix := range [][]byte{oldGrubKernelCmdlinePrefix, newGrubKernelCmdlinePrefix} { + if bytes.HasPrefix(grubCmd, prefix) { + return len(prefix) + } + } + return -1 +} diff --git a/server/verify.go b/server/verify.go index 5df2381a..a3bade7c 100644 --- a/server/verify.go +++ b/server/verify.go @@ -48,17 +48,6 @@ type VerifyOpts struct { Loader Bootloader } -var ( - // See https://www.gnu.org/software/grub/manual/grub/grub.html#Measured-Boot. - validPrefixes = [][]byte{[]byte("grub_cmd: "), - []byte("kernel_cmdline: "), - []byte("module_cmdline: "), - // Older style prefixes: - // https://src.fedoraproject.org/rpms/grub2/blob/c789522f7cfa19a10cd716a1db24dab5499c6e5c/f/0224-Rework-TPM-measurements.patch - []byte("grub_kernel_cmdline "), - []byte("grub_cmd ")} -) - // Bootloader refers to the second-stage bootloader that loads and transfers // execution to the OS kernel. type Bootloader int From 9e6f7f6625cb2a91363213879de99c8cfa939510 Mon Sep 17 00:00:00 2001 From: Alex Wu Date: Thu, 30 Jun 2022 18:28:07 -0700 Subject: [PATCH 4/5] Add COS 101 event log on AMD SEV --- internal/test/eventlogs/cos-101-amd-sev.bin | Bin 0 -> 23050 bytes internal/test/test_data.go | 2 ++ 2 files changed, 2 insertions(+) create mode 100644 internal/test/eventlogs/cos-101-amd-sev.bin diff --git a/internal/test/eventlogs/cos-101-amd-sev.bin b/internal/test/eventlogs/cos-101-amd-sev.bin new file mode 100644 index 0000000000000000000000000000000000000000..193fa87805fe5743fdd9a1c02d4c9fd2d558a6c0 GIT binary patch literal 23050 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 e5MQPFfmp^Ef-mT*b%gn22`(@bUo Date: Wed, 6 Jul 2022 11:57:16 -0700 Subject: [PATCH 5/5] Test kernel command line event log parsing --- internal/test/test_data.go | 7 ++++ server/eventlog_test.go | 74 +++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/internal/test/test_data.go b/internal/test/test_data.go index 2d6536e0..043005aa 100644 --- a/internal/test/test_data.go +++ b/internal/test/test_data.go @@ -26,6 +26,13 @@ var ( Cos101AmdSevEventLog []byte ) +// Kernel command lines from event logs. +var ( + Cos85AmdSevCmdline = "/syslinux/vmlinuz.A init=/usr/lib/systemd/systemd boot=local rootwait ro noresume noswap loglevel=7 noinitrd console=ttyS0 security=apparmor virtio_net.napi_tx=1 systemd.unified_cgroup_hierarchy=false systemd.legacy_systemd_cgroup_controller=false csm.disabled=1 loadpin.exclude=kernel-module modules-load=loadpin_trigger module.sig_enforce=1 dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 i915.modeset=1 cros_efi root=/dev/dm-0 \"dm=1 vroot none ro 1,0 4077568 verity payload=PARTUUID=EF8ECEE2-2385-AE4F-A146-1ED93D8AC217 hashtree=PARTUUID=EF8ECEE2-2385-AE4F-A146-1ED93D8AC217 hashstart=4077568 alg=sha256 root_hexdigest=795872ee03859c10dfcc4d67b4b96c85094b340c2d8784783abc2fa12a6ed671 salt=40eb77fb9093cbff56a6f9c2214c4f7554817d079513b7c77de4953d6b8ffc16\"\x00" + Cos93AmdSevCmdline = "/syslinux/vmlinuz.A init=/usr/lib/systemd/systemd boot=local rootwait ro noresume loglevel=7 noinitrd console=ttyS0 security=apparmor virtio_net.napi_tx=1 systemd.unified_cgroup_hierarchy=false systemd.legacy_systemd_cgroup_controller=false csm.disabled=1 loadpin.exclude=kernel-module modules-load=loadpin_trigger module.sig_enforce=1 console=tty1 dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 i915.modeset=1 cros_efi root=/dev/dm-0 \"dm=1 vroot none ro 1,0 4077568 verity payload=PARTUUID=05CDEDEA-42C6-2248-B6B3-AB4CE3EA7501 hashtree=PARTUUID=05CDEDEA-42C6-2248-B6B3-AB4CE3EA7501 hashstart=4077568 alg=sha256 root_hexdigest=8db95edb446a7311634fc8409e6eab39c66886c4db16aeeef166bbd8fe4ff357 salt=3ec6b6fef69119253b9a5f79a5bb06bc7b12f177063b2466a04f08976375af44\"\x00" + Cos101AmdSevCmdline = "/syslinux/vmlinuz.A init=/usr/lib/systemd/systemd boot=local rootwait ro noresume loglevel=7 console=tty1 console=ttyS0 security=apparmor virtio_net.napi_tx=1 nmi_watchdog=0 csm.disabled=1 loadpin.exclude=kernel-module modules-load=loadpin_trigger module.sig_enforce=1 dm_verity.error_behavior=3 dm_verity.max_bios=-1 dm_verity.dev_wait=1 i915.modeset=1 cros_efi root=/dev/dm-0 \"dm=1 vroot none ro 1,0 4077568 verity payload=PARTUUID=1D70214B-9AB3-E542-8372-3CCD786534FA hashtree=PARTUUID=1D70214B-9AB3-E542-8372-3CCD786534FA hashstart=4077568 alg=sha256 root_hexdigest=48d436350a7e83bde985cd3f7e79fa443557743b42243803ce31104ca4719c5d salt=b323b014b6f463172fca758a1c5a6745a2c8e5872be0e175e2f4b40c8295b2ab\"\x00" +) + // Attestation .pb files. var ( //go:embed attestations/gce-cos-85-no-nonce.pb diff --git a/server/eventlog_test.go b/server/eventlog_test.go index 28299212..cc83cd93 100644 --- a/server/eventlog_test.go +++ b/server/eventlog_test.go @@ -316,6 +316,41 @@ var COS93AmdSev = eventLog{ }}, } +var COS101AmdSev = eventLog{ + RawLog: test.Cos101AmdSevEventLog, + Banks: []*pb.PCRs{{ + Hash: pb.HashAlgo_SHA1, + Pcrs: map[uint32][]byte{ + 0: decodeHex("c032c3b51dbb6f96b047421512fd4b4dfde496f3"), + 1: decodeHex("e3e9e1d9deacd95b289bbbd3a1717a57af7d211b"), + 2: decodeHex("b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236"), + 3: decodeHex("b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236"), + 4: decodeHex("1ebe08ea6c45e0dfbd2aad903d2e0d3ab69fd7ad"), + 5: decodeHex("1c7ca47e5c09a78a747b0e0f051cc8cad6431400"), + 6: decodeHex("b2a83b0ebf2f8374299a5b2bdfc31ea955ad7236"), + 7: decodeHex("6847f752ad1795c279f289e1eecf0040cd53c1d4"), + 8: decodeHex("a243d82bd1fa01ae487b7ba77dd73ebb7a17800a"), + 9: decodeHex("fbbb8a8f120369810e7e161504556f0080afadac"), + 14: decodeHex("1ba610b2d80967338649a8f88f45810448814bfc"), + }, + }, { + Hash: pb.HashAlgo_SHA256, + Pcrs: map[uint32][]byte{ + 0: decodeHex("0f35c214608d93c7a6e68ae7359b4a8be5a0e99eea9107ece427c4dea4e439cf"), + 1: decodeHex("6eb40f5b6bfafcb9914d486ce59404acd24bc13a6a3c45cda3b44c9d7053d638"), + 2: decodeHex("3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969"), + 3: decodeHex("3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969"), + 4: decodeHex("6d9f1a1d461cf77517e8d4c488c53f338a71c5a8e2b81ab7011c14f72cbc9a80"), + 5: decodeHex("d1a1ab23a5c3d98fbacff3891bad42d8e9257d61e1f683f42c6c9fa949bf96c5"), + 6: decodeHex("3d458cfe55cc03ea1f443f1562beec8df51c75e14a9fcf9a7234a13f198e7969"), + 7: decodeHex("2bc6edaa921f953cec0ffb28dad4f87114886603d6a782036502d28e69d97a48"), + 8: decodeHex("ebb7c847c4ade99849bcffca236d32331224a530087a7ae4cb9f7db4c2e571b5"), + 9: decodeHex("b5ad662e5eb9165825ee39ad66e851a67a193e0b87b27858f25ac58afa72ac57"), + 14: decodeHex("d0d95459205afae879514db7b85630f5d6b8272ed8c731bf92933dbc9fe99969"), + }, + }}, +} + func TestParseEventLogs(t *testing.T) { sbatErrorStr := "asn1: structure error: tags don't match (16 vs {class:0 tag:24 length:10 isCompound:true})" logs := []struct { @@ -338,6 +373,7 @@ func TestParseEventLogs(t *testing.T) { {ArchLinuxWorkstation, "ArchLinuxWorkstation", UnsupportedLoader, archLinuxBadSecureBoot}, {COS85AmdSev, "COS85AmdSev", GRUB, ""}, {COS93AmdSev, "COS93AmdSev", GRUB, ""}, + {COS101AmdSev, "COS101AmdSev", GRUB, ""}, } for _, log := range logs { @@ -633,6 +669,41 @@ func generateNonCosCelEvent(hashAlgoList []crypto.Hash) (cel.Record, error) { return randRecord, nil } +func TestParseLinuxKernelState(t *testing.T) { + logs := []struct { + eventLog + name string + expectedCmdline string + }{ + {COS85AmdSev, "COS85AmdSev", test.Cos85AmdSevCmdline}, + {COS93AmdSev, "COS93AmdSev", test.Cos93AmdSevCmdline}, + {COS101AmdSev, "COS101AmdSev", test.Cos101AmdSevCmdline}, + } + for _, log := range logs { + for _, bank := range log.Banks { + hashName := pb.HashAlgo_name[int32(bank.Hash)] + subtestName := fmt.Sprintf("%s-%s", log.name, hashName) + t.Run(subtestName, func(t *testing.T) { + msState, err := parsePCClientEventLog(log.RawLog, bank, GRUB) + if err != nil { + t.Errorf("failed to parse and replay log: %v", err) + } + + if msState.LinuxKernel == nil || len(msState.LinuxKernel.CommandLine) == 0 { + t.Errorf("expected %s to have a LinuxKernelState", log.name) + } + + if msState.LinuxKernel.CommandLine != log.expectedCmdline { + t.Errorf("kernel command line for log %s:\n'%s'\n did not match expected cmdline:\n'%s'", + log.name, + msState.LinuxKernel.CommandLine, + log.expectedCmdline) + } + }) + } + } +} + func TestParseGrubState(t *testing.T) { logs := []struct { eventLog @@ -640,11 +711,12 @@ func TestParseGrubState(t *testing.T) { }{ {COS85AmdSev, "COS85AmdSev"}, {COS93AmdSev, "COS93AmdSev"}, + {COS101AmdSev, "COS101AmdSev"}, } for _, log := range logs { for _, bank := range log.Banks { hashName := pb.HashAlgo_name[int32(bank.Hash)] - subtestName := fmt.Sprintf("COS85AmdSev-%s", hashName) + subtestName := fmt.Sprintf("%s-%s", log.name, hashName) t.Run(subtestName, func(t *testing.T) { msState, err := parsePCClientEventLog(log.RawLog, bank, GRUB) if err != nil {