feat: add security state resource
Add security state resource that describes the state of Talos SecureBoot and PCR signing key fingerprints. The UKI fingerprint is currently not populated. Fixes: #7514 Signed-off-by: Noel Georgi <git@frezbo.dev>
This commit is contained in:
parent
209c34801e
commit
68e6b98f7d
@ -85,6 +85,13 @@ message PlatformMetadataSpec {
|
||||
bool spot = 8;
|
||||
}
|
||||
|
||||
// SecurityStateSpec describes the security state resource properties.
|
||||
message SecurityStateSpec {
|
||||
bool secure_boot = 1;
|
||||
string uki_signing_key_fingerprint = 2;
|
||||
string pcr_signing_key_fingerprint = 3;
|
||||
}
|
||||
|
||||
// UnmetCondition is a failure which prevents machine from being ready at the stage.
|
||||
message UnmetCondition {
|
||||
string name = 1;
|
||||
|
@ -325,6 +325,8 @@ function validate_rlimit_nofile {
|
||||
|
||||
function validate_booted_secureboot {
|
||||
${TALOSCTL} dmesg | grep "Secure boot enabled"
|
||||
${TALOSCTL} get securitystate -o json
|
||||
${TALOSCTL} get securitystate -o json | jq -e '.spec.secureBoot == true'
|
||||
}
|
||||
|
||||
function install_and_run_cilium_cni_tests {
|
||||
|
110
internal/app/machined/pkg/controllers/runtime/security_state.go
Normal file
110
internal/app/machined/pkg/controllers/runtime/security_state.go
Normal file
@ -0,0 +1,110 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/cosi-project/runtime/pkg/controller"
|
||||
"github.com/cosi-project/runtime/pkg/safe"
|
||||
"github.com/foxboron/go-uefi/efi"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||
runtimeres "github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
||||
)
|
||||
|
||||
// SecurityStateController is a controller that updates the security state of Talos.
|
||||
type SecurityStateController struct{}
|
||||
|
||||
// Name implements controller.Controller interface.
|
||||
func (ctrl *SecurityStateController) Name() string {
|
||||
return "runtime.SecurityStateController"
|
||||
}
|
||||
|
||||
// Inputs implements controller.Controller interface.
|
||||
func (ctrl *SecurityStateController) Inputs() []controller.Input {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Outputs implements controller.Controller interface.
|
||||
func (ctrl *SecurityStateController) Outputs() []controller.Output {
|
||||
return []controller.Output{
|
||||
{
|
||||
Type: runtimeres.SecurityStateType,
|
||||
Kind: controller.OutputExclusive,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Run implements controller.Controller interface.
|
||||
// nolint:gocyclo
|
||||
func (ctrl *SecurityStateController) Run(ctx context.Context, r controller.Runtime, logger *zap.Logger) error {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case <-r.EventCh():
|
||||
}
|
||||
|
||||
var secureBootState bool
|
||||
|
||||
if efi.GetSecureBoot() && !efi.GetSetupMode() {
|
||||
secureBootState = true
|
||||
}
|
||||
|
||||
if err := safe.WriterModify(ctx, r, runtimeres.NewSecurityStateSpec(runtimeres.NamespaceName), func(state *runtimeres.SecurityState) error {
|
||||
state.TypedSpec().SecureBoot = secureBootState
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if pcrPublicKeyData, err := os.ReadFile(constants.PCRPublicKey); err == nil {
|
||||
block, _ := pem.Decode(pcrPublicKeyData)
|
||||
if block == nil {
|
||||
return fmt.Errorf("failed to decode PEM block for PCR public key")
|
||||
}
|
||||
|
||||
cert := x509.Certificate{
|
||||
Raw: block.Bytes,
|
||||
}
|
||||
|
||||
if err := safe.WriterModify(ctx, r, runtimeres.NewSecurityStateSpec(runtimeres.NamespaceName), func(state *runtimeres.SecurityState) error {
|
||||
state.TypedSpec().PCRSigningKeyFingerprint = x509CertFingerprint(cert)
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// terminating the controller here, as we need to only populate securitystate once
|
||||
return nil
|
||||
}
|
||||
|
||||
func x509CertFingerprint(cert x509.Certificate) string {
|
||||
hash := sha256.Sum256(cert.Raw)
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
for i, b := range hex.EncodeToString(hash[:]) {
|
||||
if i > 0 && i%2 == 0 {
|
||||
buf.WriteByte(':')
|
||||
}
|
||||
|
||||
buf.WriteString(strings.ToUpper(string(b)))
|
||||
}
|
||||
|
||||
return buf.String()
|
||||
}
|
@ -278,6 +278,7 @@ func (ctrl *Controller) Run(ctx context.Context, drainer *runtime.Drainer) error
|
||||
&runtimecontrollers.MachineStatusPublisherController{
|
||||
V1Alpha1Events: ctrl.v1alpha1Runtime.Events(),
|
||||
},
|
||||
&runtimecontrollers.SecurityStateController{},
|
||||
&secrets.APICertSANsController{},
|
||||
&secrets.APIController{},
|
||||
&secrets.EtcdController{},
|
||||
|
@ -182,6 +182,7 @@ func NewState() (*State, error) {
|
||||
&runtime.MetaKey{},
|
||||
&runtime.MountStatus{},
|
||||
&runtime.PlatformMetadata{},
|
||||
&runtime.SecurityState{},
|
||||
&secrets.API{},
|
||||
&secrets.CertSAN{},
|
||||
&secrets.Etcd{},
|
||||
|
@ -744,6 +744,70 @@ func (x *PlatformMetadataSpec) GetSpot() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SecurityStateSpec describes the security state resource properties.
|
||||
type SecurityStateSpec struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
SecureBoot bool `protobuf:"varint,1,opt,name=secure_boot,json=secureBoot,proto3" json:"secure_boot,omitempty"`
|
||||
UkiSigningKeyFingerprint string `protobuf:"bytes,2,opt,name=uki_signing_key_fingerprint,json=ukiSigningKeyFingerprint,proto3" json:"uki_signing_key_fingerprint,omitempty"`
|
||||
PcrSigningKeyFingerprint string `protobuf:"bytes,3,opt,name=pcr_signing_key_fingerprint,json=pcrSigningKeyFingerprint,proto3" json:"pcr_signing_key_fingerprint,omitempty"`
|
||||
}
|
||||
|
||||
func (x *SecurityStateSpec) Reset() {
|
||||
*x = SecurityStateSpec{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *SecurityStateSpec) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*SecurityStateSpec) ProtoMessage() {}
|
||||
|
||||
func (x *SecurityStateSpec) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12]
|
||||
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 SecurityStateSpec.ProtoReflect.Descriptor instead.
|
||||
func (*SecurityStateSpec) Descriptor() ([]byte, []int) {
|
||||
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *SecurityStateSpec) GetSecureBoot() bool {
|
||||
if x != nil {
|
||||
return x.SecureBoot
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (x *SecurityStateSpec) GetUkiSigningKeyFingerprint() string {
|
||||
if x != nil {
|
||||
return x.UkiSigningKeyFingerprint
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (x *SecurityStateSpec) GetPcrSigningKeyFingerprint() string {
|
||||
if x != nil {
|
||||
return x.PcrSigningKeyFingerprint
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// UnmetCondition is a failure which prevents machine from being ready at the stage.
|
||||
type UnmetCondition struct {
|
||||
state protoimpl.MessageState
|
||||
@ -757,7 +821,7 @@ type UnmetCondition struct {
|
||||
func (x *UnmetCondition) Reset() {
|
||||
*x = UnmetCondition{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12]
|
||||
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@ -770,7 +834,7 @@ func (x *UnmetCondition) String() string {
|
||||
func (*UnmetCondition) ProtoMessage() {}
|
||||
|
||||
func (x *UnmetCondition) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[12]
|
||||
mi := &file_resource_definitions_runtime_runtime_proto_msgTypes[13]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@ -783,7 +847,7 @@ func (x *UnmetCondition) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use UnmetCondition.ProtoReflect.Descriptor instead.
|
||||
func (*UnmetCondition) Descriptor() ([]byte, []int) {
|
||||
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{12}
|
||||
return file_resource_definitions_runtime_runtime_proto_rawDescGZIP(), []int{13}
|
||||
}
|
||||
|
||||
func (x *UnmetCondition) GetName() string {
|
||||
@ -895,16 +959,28 @@ var file_resource_definitions_runtime_runtime_proto_rawDesc = []byte{
|
||||
0x63, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x18, 0x08, 0x20,
|
||||
0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x22, 0x3c, 0x0a, 0x0e, 0x55, 0x6e, 0x6d,
|
||||
0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e,
|
||||
0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x6c, 0x61, 0x62, 0x73,
|
||||
0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x6d, 0x61, 0x63, 0x68, 0x69,
|
||||
0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x72, 0x75,
|
||||
0x6e, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x01, 0x28, 0x08, 0x52, 0x04, 0x73, 0x70, 0x6f, 0x74, 0x22, 0xb2, 0x01, 0x0a, 0x11, 0x53, 0x65,
|
||||
0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12,
|
||||
0x1f, 0x0a, 0x0b, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x42, 0x6f, 0x6f, 0x74,
|
||||
0x12, 0x3d, 0x0a, 0x1b, 0x75, 0x6b, 0x69, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f,
|
||||
0x6b, 0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x75, 0x6b, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
|
||||
0x67, 0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x12,
|
||||
0x3d, 0x0a, 0x1b, 0x70, 0x63, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x6b,
|
||||
0x65, 0x79, 0x5f, 0x66, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x18, 0x70, 0x63, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67,
|
||||
0x4b, 0x65, 0x79, 0x46, 0x69, 0x6e, 0x67, 0x65, 0x72, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x22, 0x3c,
|
||||
0x0a, 0x0e, 0x55, 0x6e, 0x6d, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x42, 0x4c, 0x5a, 0x4a,
|
||||
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72,
|
||||
0x6f, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2f, 0x70, 0x6b, 0x67, 0x2f,
|
||||
0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x72, 0x79, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x73, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -919,7 +995,7 @@ func file_resource_definitions_runtime_runtime_proto_rawDescGZIP() []byte {
|
||||
return file_resource_definitions_runtime_runtime_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
|
||||
var file_resource_definitions_runtime_runtime_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
|
||||
var file_resource_definitions_runtime_runtime_proto_goTypes = []interface{}{
|
||||
(*DevicesStatusSpec)(nil), // 0: talos.resource.definitions.runtime.DevicesStatusSpec
|
||||
(*EventSinkConfigSpec)(nil), // 1: talos.resource.definitions.runtime.EventSinkConfigSpec
|
||||
@ -933,17 +1009,18 @@ var file_resource_definitions_runtime_runtime_proto_goTypes = []interface{}{
|
||||
(*MetaKeySpec)(nil), // 9: talos.resource.definitions.runtime.MetaKeySpec
|
||||
(*MountStatusSpec)(nil), // 10: talos.resource.definitions.runtime.MountStatusSpec
|
||||
(*PlatformMetadataSpec)(nil), // 11: talos.resource.definitions.runtime.PlatformMetadataSpec
|
||||
(*UnmetCondition)(nil), // 12: talos.resource.definitions.runtime.UnmetCondition
|
||||
(*common.URL)(nil), // 13: common.URL
|
||||
(enums.RuntimeMachineStage)(0), // 14: talos.resource.definitions.enums.RuntimeMachineStage
|
||||
(*common.NetIP)(nil), // 15: common.NetIP
|
||||
(*SecurityStateSpec)(nil), // 12: talos.resource.definitions.runtime.SecurityStateSpec
|
||||
(*UnmetCondition)(nil), // 13: talos.resource.definitions.runtime.UnmetCondition
|
||||
(*common.URL)(nil), // 14: common.URL
|
||||
(enums.RuntimeMachineStage)(0), // 15: talos.resource.definitions.enums.RuntimeMachineStage
|
||||
(*common.NetIP)(nil), // 16: common.NetIP
|
||||
}
|
||||
var file_resource_definitions_runtime_runtime_proto_depIdxs = []int32{
|
||||
13, // 0: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL
|
||||
14, // 1: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage
|
||||
14, // 0: talos.resource.definitions.runtime.KmsgLogConfigSpec.destinations:type_name -> common.URL
|
||||
15, // 1: talos.resource.definitions.runtime.MachineStatusSpec.stage:type_name -> talos.resource.definitions.enums.RuntimeMachineStage
|
||||
7, // 2: talos.resource.definitions.runtime.MachineStatusSpec.status:type_name -> talos.resource.definitions.runtime.MachineStatusStatus
|
||||
12, // 3: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition
|
||||
15, // 4: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec.reachable_addresses:type_name -> common.NetIP
|
||||
13, // 3: talos.resource.definitions.runtime.MachineStatusStatus.unmet_conditions:type_name -> talos.resource.definitions.runtime.UnmetCondition
|
||||
16, // 4: talos.resource.definitions.runtime.MaintenanceServiceConfigSpec.reachable_addresses:type_name -> common.NetIP
|
||||
5, // [5:5] is the sub-list for method output_type
|
||||
5, // [5:5] is the sub-list for method input_type
|
||||
5, // [5:5] is the sub-list for extension type_name
|
||||
@ -1102,6 +1179,18 @@ func file_resource_definitions_runtime_runtime_proto_init() {
|
||||
}
|
||||
}
|
||||
file_resource_definitions_runtime_runtime_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*SecurityStateSpec); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_resource_definitions_runtime_runtime_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UnmetCondition); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@ -1120,7 +1209,7 @@ func file_resource_definitions_runtime_runtime_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_resource_definitions_runtime_runtime_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 13,
|
||||
NumMessages: 14,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
@ -691,6 +691,63 @@ func (m *PlatformMetadataSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error)
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *SecurityStateSpec) MarshalVT() (dAtA []byte, err error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
size := m.SizeVT()
|
||||
dAtA = make([]byte, size)
|
||||
n, err := m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dAtA[:n], nil
|
||||
}
|
||||
|
||||
func (m *SecurityStateSpec) MarshalToVT(dAtA []byte) (int, error) {
|
||||
size := m.SizeVT()
|
||||
return m.MarshalToSizedBufferVT(dAtA[:size])
|
||||
}
|
||||
|
||||
func (m *SecurityStateSpec) MarshalToSizedBufferVT(dAtA []byte) (int, error) {
|
||||
if m == nil {
|
||||
return 0, nil
|
||||
}
|
||||
i := len(dAtA)
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if m.unknownFields != nil {
|
||||
i -= len(m.unknownFields)
|
||||
copy(dAtA[i:], m.unknownFields)
|
||||
}
|
||||
if len(m.PcrSigningKeyFingerprint) > 0 {
|
||||
i -= len(m.PcrSigningKeyFingerprint)
|
||||
copy(dAtA[i:], m.PcrSigningKeyFingerprint)
|
||||
i = encodeVarint(dAtA, i, uint64(len(m.PcrSigningKeyFingerprint)))
|
||||
i--
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
if len(m.UkiSigningKeyFingerprint) > 0 {
|
||||
i -= len(m.UkiSigningKeyFingerprint)
|
||||
copy(dAtA[i:], m.UkiSigningKeyFingerprint)
|
||||
i = encodeVarint(dAtA, i, uint64(len(m.UkiSigningKeyFingerprint)))
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
if m.SecureBoot {
|
||||
i--
|
||||
if m.SecureBoot {
|
||||
dAtA[i] = 1
|
||||
} else {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x8
|
||||
}
|
||||
return len(dAtA) - i, nil
|
||||
}
|
||||
|
||||
func (m *UnmetCondition) MarshalVT() (dAtA []byte, err error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
@ -1004,6 +1061,27 @@ func (m *PlatformMetadataSpec) SizeVT() (n int) {
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *SecurityStateSpec) SizeVT() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
if m.SecureBoot {
|
||||
n += 2
|
||||
}
|
||||
l = len(m.UkiSigningKeyFingerprint)
|
||||
if l > 0 {
|
||||
n += 1 + l + sov(uint64(l))
|
||||
}
|
||||
l = len(m.PcrSigningKeyFingerprint)
|
||||
if l > 0 {
|
||||
n += 1 + l + sov(uint64(l))
|
||||
}
|
||||
n += len(m.unknownFields)
|
||||
return n
|
||||
}
|
||||
|
||||
func (m *UnmetCondition) SizeVT() (n int) {
|
||||
if m == nil {
|
||||
return 0
|
||||
@ -2541,6 +2619,141 @@ func (m *PlatformMetadataSpec) UnmarshalVT(dAtA []byte) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *SecurityStateSpec) UnmarshalVT(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
for iNdEx < l {
|
||||
preIndex := iNdEx
|
||||
var wire uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
wire |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
fieldNum := int32(wire >> 3)
|
||||
wireType := int(wire & 0x7)
|
||||
if wireType == 4 {
|
||||
return fmt.Errorf("proto: SecurityStateSpec: wiretype end group for non-group")
|
||||
}
|
||||
if fieldNum <= 0 {
|
||||
return fmt.Errorf("proto: SecurityStateSpec: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||
}
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field SecureBoot", wireType)
|
||||
}
|
||||
var v int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
v |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.SecureBoot = bool(v != 0)
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field UkiSigningKeyFingerprint", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.UkiSigningKeyFingerprint = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field PcrSigningKeyFingerprint", wireType)
|
||||
}
|
||||
var stringLen uint64
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflow
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
stringLen |= uint64(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
intStringLen := int(stringLen)
|
||||
if intStringLen < 0 {
|
||||
return ErrInvalidLength
|
||||
}
|
||||
postIndex := iNdEx + intStringLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLength
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.PcrSigningKeyFingerprint = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skip(dAtA[iNdEx:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLength
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...)
|
||||
iNdEx += skippy
|
||||
}
|
||||
}
|
||||
|
||||
if iNdEx > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *UnmetCondition) UnmarshalVT(dAtA []byte) error {
|
||||
l := len(dAtA)
|
||||
iNdEx := 0
|
||||
|
@ -2,7 +2,7 @@
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// Code generated by "deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
|
||||
// Code generated by "deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
|
||||
|
||||
package runtime
|
||||
|
||||
@ -112,3 +112,9 @@ func (o PlatformMetadataSpec) DeepCopy() PlatformMetadataSpec {
|
||||
var cp PlatformMetadataSpec = o
|
||||
return cp
|
||||
}
|
||||
|
||||
// DeepCopy generates a deep copy of SecurityStateSpec.
|
||||
func (o SecurityStateSpec) DeepCopy() SecurityStateSpec {
|
||||
var cp SecurityStateSpec = o
|
||||
return cp
|
||||
}
|
||||
|
@ -5,4 +5,4 @@
|
||||
package runtime
|
||||
|
||||
//nolint:lll
|
||||
//go:generate deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
||||
//go:generate deep-copy -type DevicesStatusSpec -type EventSinkConfigSpec -type KernelModuleSpecSpec -type KernelParamSpecSpec -type KernelParamStatusSpec -type KmsgLogConfigSpec -type MaintenanceServiceConfigSpec -type MaintenanceServiceRequestSpec -type MachineStatusSpec -type MetaKeySpec -type MountStatusSpec -type PlatformMetadataSpec -type SecurityStateSpec -header-file ../../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
||||
|
@ -38,6 +38,7 @@ func TestRegisterResource(t *testing.T) {
|
||||
&runtime.MetaKey{},
|
||||
&runtime.MountStatus{},
|
||||
&runtime.PlatformMetadata{},
|
||||
&runtime.SecurityState{},
|
||||
} {
|
||||
assert.NoError(t, resourceRegistry.Register(ctx, resource))
|
||||
}
|
||||
|
74
pkg/machinery/resources/runtime/security_status.go
Normal file
74
pkg/machinery/resources/runtime/security_status.go
Normal file
@ -0,0 +1,74 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"github.com/cosi-project/runtime/pkg/resource"
|
||||
"github.com/cosi-project/runtime/pkg/resource/meta"
|
||||
"github.com/cosi-project/runtime/pkg/resource/protobuf"
|
||||
"github.com/cosi-project/runtime/pkg/resource/typed"
|
||||
|
||||
"github.com/siderolabs/talos/pkg/machinery/proto"
|
||||
)
|
||||
|
||||
// SecurityStateType is the type of the security state resource.
|
||||
const SecurityStateType = resource.Type("SecurityStates.talos.dev")
|
||||
|
||||
// SecurityStateID is the ID of the security state resource.
|
||||
const SecurityStateID = resource.ID("securitystate")
|
||||
|
||||
// SecurityState is the security state resource.
|
||||
type SecurityState = typed.Resource[SecurityStateSpec, SecurityStateExtension]
|
||||
|
||||
// SecurityStateSpec describes the security state resource properties.
|
||||
//
|
||||
//gotagsrewrite:gen
|
||||
type SecurityStateSpec struct {
|
||||
SecureBoot bool `yaml:"secureBoot" protobuf:"1"`
|
||||
UKISigningKeyFingerprint string `yaml:"ukiSigningKeyFingerprint,omitempty" protobuf:"2"`
|
||||
PCRSigningKeyFingerprint string `yaml:"pcrSigningKeyFingerprint,omitempty" protobuf:"3"`
|
||||
}
|
||||
|
||||
// NewSecurityStateSpec initializes a security state resource.
|
||||
func NewSecurityStateSpec(namespace resource.Namespace) *SecurityState {
|
||||
return typed.NewResource[SecurityStateSpec, SecurityStateExtension](
|
||||
resource.NewMetadata(namespace, SecurityStateType, SecurityStateID, resource.VersionUndefined),
|
||||
SecurityStateSpec{},
|
||||
)
|
||||
}
|
||||
|
||||
// SecurityStateExtension provides auxiliary methods for SecurityState.
|
||||
type SecurityStateExtension struct{}
|
||||
|
||||
// ResourceDefinition implements [typed.Extension] interface.
|
||||
func (SecurityStateExtension) ResourceDefinition() meta.ResourceDefinitionSpec {
|
||||
return meta.ResourceDefinitionSpec{
|
||||
Type: SecurityStateType,
|
||||
DefaultNamespace: NamespaceName,
|
||||
PrintColumns: []meta.PrintColumn{
|
||||
{
|
||||
Name: "SecureBoot",
|
||||
JSONPath: `{.secureBoot}`,
|
||||
},
|
||||
{
|
||||
Name: "UKISigningKeyFingerprint",
|
||||
JSONPath: `{.ukiSigningKeyFingerprint}`,
|
||||
},
|
||||
{
|
||||
Name: "PCRSigningKeyFingerprint",
|
||||
JSONPath: `{.pcrSigningKeyFingerprint}`,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterDefaultTypes()
|
||||
|
||||
err := protobuf.RegisterDynamic[SecurityStateSpec](SecurityStateType, &SecurityState{})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
@ -200,6 +200,7 @@ description: Talos gRPC API reference.
|
||||
- [MetaKeySpec](#talos.resource.definitions.runtime.MetaKeySpec)
|
||||
- [MountStatusSpec](#talos.resource.definitions.runtime.MountStatusSpec)
|
||||
- [PlatformMetadataSpec](#talos.resource.definitions.runtime.PlatformMetadataSpec)
|
||||
- [SecurityStateSpec](#talos.resource.definitions.runtime.SecurityStateSpec)
|
||||
- [UnmetCondition](#talos.resource.definitions.runtime.UnmetCondition)
|
||||
|
||||
- [resource/definitions/secrets/secrets.proto](#resource/definitions/secrets/secrets.proto)
|
||||
@ -3643,6 +3644,23 @@ PlatformMetadataSpec describes platform metadata properties.
|
||||
|
||||
|
||||
|
||||
<a name="talos.resource.definitions.runtime.SecurityStateSpec"></a>
|
||||
|
||||
### SecurityStateSpec
|
||||
SecurityStateSpec describes the security state resource properties.
|
||||
|
||||
|
||||
| Field | Type | Label | Description |
|
||||
| ----- | ---- | ----- | ----------- |
|
||||
| secure_boot | [bool](#bool) | | |
|
||||
| uki_signing_key_fingerprint | [string](#string) | | |
|
||||
| pcr_signing_key_fingerprint | [string](#string) | | |
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<a name="talos.resource.definitions.runtime.UnmetCondition"></a>
|
||||
|
||||
### UnmetCondition
|
||||
|
Loading…
x
Reference in New Issue
Block a user