From cb20155b1e7802f15b14a1a71a7409b291fa71b5 Mon Sep 17 00:00:00 2001 From: Jared Allard Date: Sat, 1 Mar 2025 11:45:43 -0800 Subject: [PATCH] pull out client reduce replay attack surface --- cmd/klefkictl/klefkictl_requests.go | 39 +- docs/DESIGN.md | 6 +- internal/db/ent/migrate/schema.go | 2 +- .../generated/go/rgst/klefki/v1/kelfki.pb.go | 605 +++++++++--------- .../go/rgst/klefki/v1/kelfki_grpc.pb.go | 36 +- .../grpc/proto/rgst/klefki/v1/kelfki.proto | 22 +- internal/server/server.go | 47 +- pkg/client/client.go | 41 ++ 8 files changed, 412 insertions(+), 386 deletions(-) create mode 100644 pkg/client/client.go diff --git a/cmd/klefkictl/klefkictl_requests.go b/cmd/klefkictl/klefkictl_requests.go index cf2f2eb..64c29b2 100644 --- a/cmd/klefkictl/klefkictl_requests.go +++ b/cmd/klefkictl/klefkictl_requests.go @@ -25,12 +25,12 @@ import ( "text/tabwriter" pbgrpcv1 "git.rgst.io/homelab/klefki/internal/server/grpc/generated/go/rgst/klefki/v1" + "git.rgst.io/homelab/klefki/pkg/client" "git.rgst.io/homelab/klefki/internal/machines" "git.rgst.io/homelab/sigtool/v3/sign" + "github.com/google/uuid" "github.com/spf13/cobra" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" ) // newRequestsCommand creates a requests [cobra.Command] @@ -43,6 +43,8 @@ func newRequestsCommand() *cobra.Command { newGetKeyRequestCommand(), newListSessionsCommand(), ) + flags := cmd.Flags() + flags.String("hostname", "127.0.0.1:5300", "hostname of the klefki server to connect to") return cmd } @@ -54,6 +56,7 @@ func newGetKeyRequestCommand() *cobra.Command { Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { privKeyPath := cmd.Flag("priv-key").Value.String() + hostname := cmd.Parent().Flag("hostname").Value.String() privKeyByt, err := os.ReadFile(privKeyPath) if err != nil { @@ -77,40 +80,36 @@ func newGetKeyRequestCommand() *cobra.Command { fmt.Printf("Sending GetKeyRequest: machine_id=%s\n", machineID) - // TODO(jaredallard): Make a client - conn, err := grpc.NewClient("127.0.0.1:5300", grpc.WithTransportCredentials(insecure.NewCredentials())) + kc, kcclose, err := client.Dial(hostname) if err != nil { - return fmt.Errorf("failed to connect to klefki server: %w", err) + return err } - defer conn.Close() + defer kcclose() //nolint:errcheck // Why: Best effort - client := pbgrpcv1.NewKlefkiServiceClient(conn) - - req := &pbgrpcv1.CreateSessionRequest{} + req := &pbgrpcv1.GetKeyRequest{} req.SetMachineId(machineID) - req.SetNonce("FIXME") + req.SetNonce(uuid.New().String()) req.SetSignature(ed25519.Sign(pk, []byte(req.GetNonce()))) - resp, err := client.CreateSession(cmd.Context(), req) + resp, err := kc.GetKey(cmd.Context(), req) if err != nil { return fmt.Errorf("failed to get key from server: %w", err) } - encSessionID := resp.GetEncSessionId() - dec, err := sign.NewDecryptor(bytes.NewReader(encSessionID)) + dec, err := sign.NewDecryptor(bytes.NewReader(resp.GetEncKey())) if err != nil { return fmt.Errorf("failed to create decryptor: %w", err) } if err := dec.SetPrivateKey(spk, nil); err != nil { return fmt.Errorf("failed to set private key on decryptor: %w", err) } + var buf bytes.Buffer if err := dec.Decrypt(&buf); err != nil { return fmt.Errorf("failed to decrypt session ID: %w", err) } - sessionID := buf.String() - fmt.Println(sessionID) + fmt.Println(buf.String()) return nil }, } @@ -126,15 +125,13 @@ func newListSessionsCommand() *cobra.Command { Short: "Return a list of all machines waiting for a key to be provided", Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { - // TODO(jaredallard): Make a client - conn, err := grpc.NewClient("127.0.0.1:5300", grpc.WithTransportCredentials(insecure.NewCredentials())) + kc, kcclose, err := client.Dial(cmd.Flag("hostname").Value.String()) if err != nil { - return fmt.Errorf("failed to connect to klefki server: %w", err) + return err } - defer conn.Close() + defer kcclose() //nolint:errcheck // Why: Best effort - client := pbgrpcv1.NewKlefkiServiceClient(conn) - resp, err := client.ListSessions(cmd.Context(), &pbgrpcv1.ListSessionsRequest{}) + resp, err := kc.ListSessions(cmd.Context(), &pbgrpcv1.ListSessionsRequest{}) if err != nil { return fmt.Errorf("failed to get key from server: %w", err) } diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 52aa293..bd78f5d 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -29,15 +29,13 @@ disk. ### Endpoints -- `CreateSession() string` - Creates a new session for the machineID and - returns it. -- `GetKey(sessionID string) string` - If connected to a client through +- `GetKey() string` - If connected to a client through `SubmitKey`, returns the key, otherwise waits for a period of time then the caller should retry the endpoint (polling). - `ListSessions() []MachineID` - Returns a list of machine IDs waiting for a key to be provided. - `SubmitKey(key []byte, machineID string)` - If a session is present - for the provided `machindID`, then the key is stored in memory on the + for the provided `machineID`, then the key is stored in memory on the server side and provided when `GetKey` is next called by the machine. Note that `key` is expected to be encrypted to the `machineID`'s public key, which is obtained through `ListSessions` beforehand. diff --git a/internal/db/ent/migrate/schema.go b/internal/db/ent/migrate/schema.go index 7548ae9..7940e4e 100644 --- a/internal/db/ent/migrate/schema.go +++ b/internal/db/ent/migrate/schema.go @@ -13,7 +13,7 @@ var ( {Name: "id", Type: field.TypeString}, {Name: "name", Type: field.TypeString, Unique: true}, {Name: "public_key", Type: field.TypeBytes}, - {Name: "created_at", Type: field.TypeString, Default: "2025-03-01T18:59:51Z"}, + {Name: "created_at", Type: field.TypeString, Default: "2025-03-01T23:41:53Z"}, } // MachinesTable holds the schema information for the "machines" table. MachinesTable = &schema.Table{ diff --git a/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki.pb.go b/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki.pb.go index baea617..90a5c45 100644 --- a/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki.pb.go +++ b/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki.pb.go @@ -21,29 +21,26 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -type GetKeyRequest struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_SessionId *string `protobuf:"bytes,1,opt,name=session_id,json=sessionId"` - XXX_raceDetectHookData protoimpl.RaceDetectHookData - XXX_presence [1]uint32 - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache +type GetTimeRequest struct { + state protoimpl.MessageState `protogen:"opaque.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -func (x *GetKeyRequest) Reset() { - *x = GetKeyRequest{} +func (x *GetTimeRequest) Reset() { + *x = GetTimeRequest{} mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *GetKeyRequest) String() string { +func (x *GetTimeRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*GetKeyRequest) ProtoMessage() {} +func (*GetTimeRequest) ProtoMessage() {} -func (x *GetKeyRequest) ProtoReflect() protoreflect.Message { +func (x *GetTimeRequest) ProtoReflect() protoreflect.Message { mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -55,46 +52,269 @@ func (x *GetKeyRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -func (x *GetKeyRequest) GetSessionId() string { +type GetTimeRequest_builder struct { + _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. + +} + +func (b0 GetTimeRequest_builder) Build() *GetTimeRequest { + m0 := &GetTimeRequest{} + b, x := &b0, m0 + _, _ = b, x + return m0 +} + +type GetTimeResponse struct { + state protoimpl.MessageState `protogen:"opaque.v1"` + xxx_hidden_Time *string `protobuf:"bytes,1,opt,name=time"` + XXX_raceDetectHookData protoimpl.RaceDetectHookData + XXX_presence [1]uint32 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetTimeResponse) Reset() { + *x = GetTimeResponse{} + mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetTimeResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetTimeResponse) ProtoMessage() {} + +func (x *GetTimeResponse) ProtoReflect() protoreflect.Message { + mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[1] if x != nil { - if x.xxx_hidden_SessionId != nil { - return *x.xxx_hidden_SessionId + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +func (x *GetTimeResponse) GetTime() string { + if x != nil { + if x.xxx_hidden_Time != nil { + return *x.xxx_hidden_Time } return "" } return "" } -func (x *GetKeyRequest) SetSessionId(v string) { - x.xxx_hidden_SessionId = &v +func (x *GetTimeResponse) SetTime(v string) { + x.xxx_hidden_Time = &v protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 1) } -func (x *GetKeyRequest) HasSessionId() bool { +func (x *GetTimeResponse) HasTime() bool { if x == nil { return false } return protoimpl.X.Present(&(x.XXX_presence[0]), 0) } -func (x *GetKeyRequest) ClearSessionId() { +func (x *GetTimeResponse) ClearTime() { protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0) - x.xxx_hidden_SessionId = nil + x.xxx_hidden_Time = nil +} + +type GetTimeResponse_builder struct { + _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. + + Time *string +} + +func (b0 GetTimeResponse_builder) Build() *GetTimeResponse { + m0 := &GetTimeResponse{} + b, x := &b0, m0 + _, _ = b, x + if b.Time != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 1) + x.xxx_hidden_Time = b.Time + } + return m0 +} + +type GetKeyRequest struct { + state protoimpl.MessageState `protogen:"opaque.v1"` + xxx_hidden_MachineId *string `protobuf:"bytes,1,opt,name=machine_id,json=machineId"` + xxx_hidden_Signature []byte `protobuf:"bytes,2,opt,name=signature"` + xxx_hidden_Nonce *string `protobuf:"bytes,3,opt,name=nonce"` + xxx_hidden_SignedAt *string `protobuf:"bytes,4,opt,name=signed_at,json=signedAt"` + XXX_raceDetectHookData protoimpl.RaceDetectHookData + XXX_presence [1]uint32 + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *GetKeyRequest) Reset() { + *x = GetKeyRequest{} + mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *GetKeyRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetKeyRequest) ProtoMessage() {} + +func (x *GetKeyRequest) ProtoReflect() protoreflect.Message { + mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +func (x *GetKeyRequest) GetMachineId() string { + if x != nil { + if x.xxx_hidden_MachineId != nil { + return *x.xxx_hidden_MachineId + } + return "" + } + return "" +} + +func (x *GetKeyRequest) GetSignature() []byte { + if x != nil { + return x.xxx_hidden_Signature + } + return nil +} + +func (x *GetKeyRequest) GetNonce() string { + if x != nil { + if x.xxx_hidden_Nonce != nil { + return *x.xxx_hidden_Nonce + } + return "" + } + return "" +} + +func (x *GetKeyRequest) GetSignedAt() string { + if x != nil { + if x.xxx_hidden_SignedAt != nil { + return *x.xxx_hidden_SignedAt + } + return "" + } + return "" +} + +func (x *GetKeyRequest) SetMachineId(v string) { + x.xxx_hidden_MachineId = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 4) +} + +func (x *GetKeyRequest) SetSignature(v []byte) { + if v == nil { + v = []byte{} + } + x.xxx_hidden_Signature = v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 4) +} + +func (x *GetKeyRequest) SetNonce(v string) { + x.xxx_hidden_Nonce = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 2, 4) +} + +func (x *GetKeyRequest) SetSignedAt(v string) { + x.xxx_hidden_SignedAt = &v + protoimpl.X.SetPresent(&(x.XXX_presence[0]), 3, 4) +} + +func (x *GetKeyRequest) HasMachineId() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 0) +} + +func (x *GetKeyRequest) HasSignature() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 1) +} + +func (x *GetKeyRequest) HasNonce() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 2) +} + +func (x *GetKeyRequest) HasSignedAt() bool { + if x == nil { + return false + } + return protoimpl.X.Present(&(x.XXX_presence[0]), 3) +} + +func (x *GetKeyRequest) ClearMachineId() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0) + x.xxx_hidden_MachineId = nil +} + +func (x *GetKeyRequest) ClearSignature() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 1) + x.xxx_hidden_Signature = nil +} + +func (x *GetKeyRequest) ClearNonce() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 2) + x.xxx_hidden_Nonce = nil +} + +func (x *GetKeyRequest) ClearSignedAt() { + protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 3) + x.xxx_hidden_SignedAt = nil } type GetKeyRequest_builder struct { _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - SessionId *string + MachineId *string + Signature []byte + Nonce *string + SignedAt *string } func (b0 GetKeyRequest_builder) Build() *GetKeyRequest { m0 := &GetKeyRequest{} b, x := &b0, m0 _, _ = b, x - if b.SessionId != nil { - protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 1) - x.xxx_hidden_SessionId = b.SessionId + if b.MachineId != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 4) + x.xxx_hidden_MachineId = b.MachineId + } + if b.Signature != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 4) + x.xxx_hidden_Signature = b.Signature + } + if b.Nonce != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 2, 4) + x.xxx_hidden_Nonce = b.Nonce + } + if b.SignedAt != nil { + protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 3, 4) + x.xxx_hidden_SignedAt = b.SignedAt } return m0 } @@ -110,7 +330,7 @@ type GetKeyResponse struct { func (x *GetKeyResponse) Reset() { *x = GetKeyResponse{} - mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[1] + mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -122,7 +342,7 @@ func (x *GetKeyResponse) String() string { func (*GetKeyResponse) ProtoMessage() {} func (x *GetKeyResponse) ProtoReflect() protoreflect.Message { - mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[1] + mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[3] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -177,228 +397,6 @@ func (b0 GetKeyResponse_builder) Build() *GetKeyResponse { return m0 } -type CreateSessionRequest struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_MachineId *string `protobuf:"bytes,1,opt,name=machine_id,json=machineId"` - xxx_hidden_Signature []byte `protobuf:"bytes,2,opt,name=signature"` - xxx_hidden_Nonce *string `protobuf:"bytes,3,opt,name=nonce"` - XXX_raceDetectHookData protoimpl.RaceDetectHookData - XXX_presence [1]uint32 - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *CreateSessionRequest) Reset() { - *x = CreateSessionRequest{} - mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CreateSessionRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateSessionRequest) ProtoMessage() {} - -func (x *CreateSessionRequest) ProtoReflect() protoreflect.Message { - mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *CreateSessionRequest) GetMachineId() string { - if x != nil { - if x.xxx_hidden_MachineId != nil { - return *x.xxx_hidden_MachineId - } - return "" - } - return "" -} - -func (x *CreateSessionRequest) GetSignature() []byte { - if x != nil { - return x.xxx_hidden_Signature - } - return nil -} - -func (x *CreateSessionRequest) GetNonce() string { - if x != nil { - if x.xxx_hidden_Nonce != nil { - return *x.xxx_hidden_Nonce - } - return "" - } - return "" -} - -func (x *CreateSessionRequest) SetMachineId(v string) { - x.xxx_hidden_MachineId = &v - protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 3) -} - -func (x *CreateSessionRequest) SetSignature(v []byte) { - if v == nil { - v = []byte{} - } - x.xxx_hidden_Signature = v - protoimpl.X.SetPresent(&(x.XXX_presence[0]), 1, 3) -} - -func (x *CreateSessionRequest) SetNonce(v string) { - x.xxx_hidden_Nonce = &v - protoimpl.X.SetPresent(&(x.XXX_presence[0]), 2, 3) -} - -func (x *CreateSessionRequest) HasMachineId() bool { - if x == nil { - return false - } - return protoimpl.X.Present(&(x.XXX_presence[0]), 0) -} - -func (x *CreateSessionRequest) HasSignature() bool { - if x == nil { - return false - } - return protoimpl.X.Present(&(x.XXX_presence[0]), 1) -} - -func (x *CreateSessionRequest) HasNonce() bool { - if x == nil { - return false - } - return protoimpl.X.Present(&(x.XXX_presence[0]), 2) -} - -func (x *CreateSessionRequest) ClearMachineId() { - protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0) - x.xxx_hidden_MachineId = nil -} - -func (x *CreateSessionRequest) ClearSignature() { - protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 1) - x.xxx_hidden_Signature = nil -} - -func (x *CreateSessionRequest) ClearNonce() { - protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 2) - x.xxx_hidden_Nonce = nil -} - -type CreateSessionRequest_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - MachineId *string - Signature []byte - Nonce *string -} - -func (b0 CreateSessionRequest_builder) Build() *CreateSessionRequest { - m0 := &CreateSessionRequest{} - b, x := &b0, m0 - _, _ = b, x - if b.MachineId != nil { - protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 3) - x.xxx_hidden_MachineId = b.MachineId - } - if b.Signature != nil { - protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 1, 3) - x.xxx_hidden_Signature = b.Signature - } - if b.Nonce != nil { - protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 2, 3) - x.xxx_hidden_Nonce = b.Nonce - } - return m0 -} - -type CreateSessionResponse struct { - state protoimpl.MessageState `protogen:"opaque.v1"` - xxx_hidden_EncSessionId []byte `protobuf:"bytes,1,opt,name=enc_session_id,json=encSessionId"` - XXX_raceDetectHookData protoimpl.RaceDetectHookData - XXX_presence [1]uint32 - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *CreateSessionResponse) Reset() { - *x = CreateSessionResponse{} - mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *CreateSessionResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateSessionResponse) ProtoMessage() {} - -func (x *CreateSessionResponse) ProtoReflect() protoreflect.Message { - mi := &file_rgst_klefki_v1_kelfki_proto_msgTypes[3] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -func (x *CreateSessionResponse) GetEncSessionId() []byte { - if x != nil { - return x.xxx_hidden_EncSessionId - } - return nil -} - -func (x *CreateSessionResponse) SetEncSessionId(v []byte) { - if v == nil { - v = []byte{} - } - x.xxx_hidden_EncSessionId = v - protoimpl.X.SetPresent(&(x.XXX_presence[0]), 0, 1) -} - -func (x *CreateSessionResponse) HasEncSessionId() bool { - if x == nil { - return false - } - return protoimpl.X.Present(&(x.XXX_presence[0]), 0) -} - -func (x *CreateSessionResponse) ClearEncSessionId() { - protoimpl.X.ClearPresent(&(x.XXX_presence[0]), 0) - x.xxx_hidden_EncSessionId = nil -} - -type CreateSessionResponse_builder struct { - _ [0]func() // Prevents comparability and use of unkeyed literals for the builder. - - EncSessionId []byte -} - -func (b0 CreateSessionResponse_builder) Build() *CreateSessionResponse { - m0 := &CreateSessionResponse{} - b, x := &b0, m0 - _, _ = b, x - if b.EncSessionId != nil { - protoimpl.X.SetPresentNonAtomic(&(x.XXX_presence[0]), 0, 1) - x.xxx_hidden_EncSessionId = b.EncSessionId - } - return m0 -} - type ListSessionsRequest struct { state protoimpl.MessageState `protogen:"opaque.v1"` unknownFields protoimpl.UnknownFields @@ -774,23 +772,21 @@ var file_rgst_klefki_v1_kelfki_proto_rawDesc = string([]byte{ 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x1a, 0x21, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x22, 0x2e, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x49, 0x64, - 0x22, 0x29, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x65, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x69, 0x0a, 0x14, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, - 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3d, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x24, 0x0a, 0x0e, 0x65, 0x6e, 0x63, 0x5f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x65, 0x6e, 0x63, 0x53, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, + 0x22, 0x10, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x22, 0x25, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x7f, 0x0a, 0x0d, 0x47, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6d, 0x61, + 0x63, 0x68, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x69, + 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x1b, 0x0a, + 0x09, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x41, 0x74, 0x22, 0x29, 0x0a, 0x0e, 0x47, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x17, 0x0a, 0x07, + 0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x65, + 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x38, 0x0a, 0x07, 0x4d, 0x61, 0x63, 0x68, 0x69, 0x6e, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, @@ -806,56 +802,55 @@ var file_rgst_klefki_v1_kelfki_proto_rawDesc = string([]byte{ 0x68, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x6e, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x65, 0x6e, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe3, 0x02, 0x0a, 0x0d, 0x4b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x5c, 0x0a, 0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, - 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, - 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x47, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1d, - 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, - 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, - 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, - 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x2e, - 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, - 0x69, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, + 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xd1, 0x02, 0x0a, 0x0d, 0x4b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x53, + 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, + 0x65, 0x12, 0x1e, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, + 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x47, 0x0a, 0x06, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x2e, 0x72, + 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, + 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x72, 0x67, + 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x0c, 0x4c, + 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x2e, 0x72, 0x67, + 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, + 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x24, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, + 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, + 0x4b, 0x65, 0x79, 0x12, 0x20, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, + 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x6b, - 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3f, 0x5a, 0x35, 0x67, 0x69, - 0x74, 0x2e, 0x72, 0x67, 0x73, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x64, 0x2f, 0x67, 0x6f, 0x2f, 0x72, 0x67, 0x73, 0x74, 0x2f, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, - 0x2f, 0x76, 0x31, 0x92, 0x03, 0x05, 0xd2, 0x3e, 0x02, 0x10, 0x03, 0x62, 0x08, 0x65, 0x64, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x70, 0xe8, 0x07, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x3f, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x2e, + 0x72, 0x67, 0x73, 0x74, 0x2e, 0x69, 0x6f, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x2f, + 0x67, 0x6f, 0x2f, 0x72, 0x67, 0x73, 0x74, 0x2f, 0x6b, 0x6c, 0x65, 0x66, 0x6b, 0x69, 0x2f, 0x76, + 0x31, 0x92, 0x03, 0x05, 0xd2, 0x3e, 0x02, 0x10, 0x03, 0x62, 0x08, 0x65, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x70, 0xe8, 0x07, }) var file_rgst_klefki_v1_kelfki_proto_msgTypes = make([]protoimpl.MessageInfo, 9) var file_rgst_klefki_v1_kelfki_proto_goTypes = []any{ - (*GetKeyRequest)(nil), // 0: rgst.klefki.v1.GetKeyRequest - (*GetKeyResponse)(nil), // 1: rgst.klefki.v1.GetKeyResponse - (*CreateSessionRequest)(nil), // 2: rgst.klefki.v1.CreateSessionRequest - (*CreateSessionResponse)(nil), // 3: rgst.klefki.v1.CreateSessionResponse - (*ListSessionsRequest)(nil), // 4: rgst.klefki.v1.ListSessionsRequest - (*Machine)(nil), // 5: rgst.klefki.v1.Machine - (*ListSessionsResponse)(nil), // 6: rgst.klefki.v1.ListSessionsResponse - (*SubmitKeyRequest)(nil), // 7: rgst.klefki.v1.SubmitKeyRequest - (*SubmitKeyResponse)(nil), // 8: rgst.klefki.v1.SubmitKeyResponse + (*GetTimeRequest)(nil), // 0: rgst.klefki.v1.GetTimeRequest + (*GetTimeResponse)(nil), // 1: rgst.klefki.v1.GetTimeResponse + (*GetKeyRequest)(nil), // 2: rgst.klefki.v1.GetKeyRequest + (*GetKeyResponse)(nil), // 3: rgst.klefki.v1.GetKeyResponse + (*ListSessionsRequest)(nil), // 4: rgst.klefki.v1.ListSessionsRequest + (*Machine)(nil), // 5: rgst.klefki.v1.Machine + (*ListSessionsResponse)(nil), // 6: rgst.klefki.v1.ListSessionsResponse + (*SubmitKeyRequest)(nil), // 7: rgst.klefki.v1.SubmitKeyRequest + (*SubmitKeyResponse)(nil), // 8: rgst.klefki.v1.SubmitKeyResponse } var file_rgst_klefki_v1_kelfki_proto_depIdxs = []int32{ 5, // 0: rgst.klefki.v1.ListSessionsResponse.machines:type_name -> rgst.klefki.v1.Machine - 2, // 1: rgst.klefki.v1.KlefkiService.CreateSession:input_type -> rgst.klefki.v1.CreateSessionRequest - 0, // 2: rgst.klefki.v1.KlefkiService.GetKey:input_type -> rgst.klefki.v1.GetKeyRequest + 0, // 1: rgst.klefki.v1.KlefkiService.GetTime:input_type -> rgst.klefki.v1.GetTimeRequest + 2, // 2: rgst.klefki.v1.KlefkiService.GetKey:input_type -> rgst.klefki.v1.GetKeyRequest 4, // 3: rgst.klefki.v1.KlefkiService.ListSessions:input_type -> rgst.klefki.v1.ListSessionsRequest 7, // 4: rgst.klefki.v1.KlefkiService.SubmitKey:input_type -> rgst.klefki.v1.SubmitKeyRequest - 3, // 5: rgst.klefki.v1.KlefkiService.CreateSession:output_type -> rgst.klefki.v1.CreateSessionResponse - 1, // 6: rgst.klefki.v1.KlefkiService.GetKey:output_type -> rgst.klefki.v1.GetKeyResponse + 1, // 5: rgst.klefki.v1.KlefkiService.GetTime:output_type -> rgst.klefki.v1.GetTimeResponse + 3, // 6: rgst.klefki.v1.KlefkiService.GetKey:output_type -> rgst.klefki.v1.GetKeyResponse 6, // 7: rgst.klefki.v1.KlefkiService.ListSessions:output_type -> rgst.klefki.v1.ListSessionsResponse 8, // 8: rgst.klefki.v1.KlefkiService.SubmitKey:output_type -> rgst.klefki.v1.SubmitKeyResponse 5, // [5:9] is the sub-list for method output_type diff --git a/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki_grpc.pb.go b/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki_grpc.pb.go index 647099c..bb96b0a 100644 --- a/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki_grpc.pb.go +++ b/internal/server/grpc/generated/go/rgst/klefki/v1/kelfki_grpc.pb.go @@ -19,17 +19,17 @@ import ( const _ = grpc.SupportPackageIsVersion9 const ( - KlefkiService_CreateSession_FullMethodName = "/rgst.klefki.v1.KlefkiService/CreateSession" - KlefkiService_GetKey_FullMethodName = "/rgst.klefki.v1.KlefkiService/GetKey" - KlefkiService_ListSessions_FullMethodName = "/rgst.klefki.v1.KlefkiService/ListSessions" - KlefkiService_SubmitKey_FullMethodName = "/rgst.klefki.v1.KlefkiService/SubmitKey" + KlefkiService_GetTime_FullMethodName = "/rgst.klefki.v1.KlefkiService/GetTime" + KlefkiService_GetKey_FullMethodName = "/rgst.klefki.v1.KlefkiService/GetKey" + KlefkiService_ListSessions_FullMethodName = "/rgst.klefki.v1.KlefkiService/ListSessions" + KlefkiService_SubmitKey_FullMethodName = "/rgst.klefki.v1.KlefkiService/SubmitKey" ) // KlefkiServiceClient is the client API for KlefkiService service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type KlefkiServiceClient interface { - CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error) + GetTime(ctx context.Context, in *GetTimeRequest, opts ...grpc.CallOption) (*GetTimeResponse, error) GetKey(ctx context.Context, in *GetKeyRequest, opts ...grpc.CallOption) (*GetKeyResponse, error) ListSessions(ctx context.Context, in *ListSessionsRequest, opts ...grpc.CallOption) (*ListSessionsResponse, error) SubmitKey(ctx context.Context, in *SubmitKeyRequest, opts ...grpc.CallOption) (*SubmitKeyResponse, error) @@ -43,10 +43,10 @@ func NewKlefkiServiceClient(cc grpc.ClientConnInterface) KlefkiServiceClient { return &klefkiServiceClient{cc} } -func (c *klefkiServiceClient) CreateSession(ctx context.Context, in *CreateSessionRequest, opts ...grpc.CallOption) (*CreateSessionResponse, error) { +func (c *klefkiServiceClient) GetTime(ctx context.Context, in *GetTimeRequest, opts ...grpc.CallOption) (*GetTimeResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(CreateSessionResponse) - err := c.cc.Invoke(ctx, KlefkiService_CreateSession_FullMethodName, in, out, cOpts...) + out := new(GetTimeResponse) + err := c.cc.Invoke(ctx, KlefkiService_GetTime_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -87,7 +87,7 @@ func (c *klefkiServiceClient) SubmitKey(ctx context.Context, in *SubmitKeyReques // All implementations must embed UnimplementedKlefkiServiceServer // for forward compatibility. type KlefkiServiceServer interface { - CreateSession(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error) + GetTime(context.Context, *GetTimeRequest) (*GetTimeResponse, error) GetKey(context.Context, *GetKeyRequest) (*GetKeyResponse, error) ListSessions(context.Context, *ListSessionsRequest) (*ListSessionsResponse, error) SubmitKey(context.Context, *SubmitKeyRequest) (*SubmitKeyResponse, error) @@ -101,8 +101,8 @@ type KlefkiServiceServer interface { // pointer dereference when methods are called. type UnimplementedKlefkiServiceServer struct{} -func (UnimplementedKlefkiServiceServer) CreateSession(context.Context, *CreateSessionRequest) (*CreateSessionResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateSession not implemented") +func (UnimplementedKlefkiServiceServer) GetTime(context.Context, *GetTimeRequest) (*GetTimeResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTime not implemented") } func (UnimplementedKlefkiServiceServer) GetKey(context.Context, *GetKeyRequest) (*GetKeyResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method GetKey not implemented") @@ -134,20 +134,20 @@ func RegisterKlefkiServiceServer(s grpc.ServiceRegistrar, srv KlefkiServiceServe s.RegisterService(&KlefkiService_ServiceDesc, srv) } -func _KlefkiService_CreateSession_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateSessionRequest) +func _KlefkiService_GetTime_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTimeRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(KlefkiServiceServer).CreateSession(ctx, in) + return srv.(KlefkiServiceServer).GetTime(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: KlefkiService_CreateSession_FullMethodName, + FullMethod: KlefkiService_GetTime_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KlefkiServiceServer).CreateSession(ctx, req.(*CreateSessionRequest)) + return srv.(KlefkiServiceServer).GetTime(ctx, req.(*GetTimeRequest)) } return interceptor(ctx, in, info, handler) } @@ -214,8 +214,8 @@ var KlefkiService_ServiceDesc = grpc.ServiceDesc{ HandlerType: (*KlefkiServiceServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "CreateSession", - Handler: _KlefkiService_CreateSession_Handler, + MethodName: "GetTime", + Handler: _KlefkiService_GetTime_Handler, }, { MethodName: "GetKey", diff --git a/internal/server/grpc/proto/rgst/klefki/v1/kelfki.proto b/internal/server/grpc/proto/rgst/klefki/v1/kelfki.proto index a4b4960..63dc9b7 100644 --- a/internal/server/grpc/proto/rgst/klefki/v1/kelfki.proto +++ b/internal/server/grpc/proto/rgst/klefki/v1/kelfki.proto @@ -7,24 +7,22 @@ import "google/protobuf/go_features.proto"; option features.(pb.go).api_level = API_OPAQUE; option go_package = "git.rgst.io/internal/grpc/generated/go/rgst/klefki/v1"; +message GetTimeRequest {} +message GetTimeResponse { + string time = 1; +} + message GetKeyRequest { - string session_id = 1; + string machine_id = 1; + bytes signature = 2; + string nonce = 3; + string signed_at = 4; } message GetKeyResponse { bytes enc_key = 1; } -message CreateSessionRequest { - string machine_id = 1; - bytes signature = 2; - string nonce = 3; -} - -message CreateSessionResponse { - bytes enc_session_id = 1; -} - message ListSessionsRequest {} message Machine { @@ -44,7 +42,7 @@ message SubmitKeyRequest { message SubmitKeyResponse {} service KlefkiService { - rpc CreateSession(CreateSessionRequest) returns (CreateSessionResponse); + rpc GetTime(GetTimeRequest) returns (GetTimeResponse); rpc GetKey(GetKeyRequest) returns (GetKeyResponse); rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse); rpc SubmitKey(SubmitKeyRequest) returns (SubmitKeyResponse); diff --git a/internal/server/server.go b/internal/server/server.go index f418889..a8a056a 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -19,12 +19,10 @@ package server import ( - "bytes" "context" "fmt" "io" "net" - "strings" "sync" "time" @@ -33,7 +31,6 @@ import ( "git.rgst.io/homelab/klefki/internal/machines" pbgrpcv1 "git.rgst.io/homelab/klefki/internal/server/grpc/generated/go/rgst/klefki/v1" "git.rgst.io/homelab/sigtool/v3/sign" - "github.com/google/uuid" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) @@ -53,13 +50,12 @@ func newNopWriteCloser(w io.Writer) *nopWriteCloser { return &nopWriteCloser{w} } +// Session represents a session where a machine is attempting to receive +// a private key from SubmitKey. type Session struct { - // CreatedAt is when the provided session was created. Should be in - // UTC. - CreatedAt time.Time - - // ID is the session ID, this is used as an authenticate gate. - ID uuid.UUID + // LastAsked is the last time the machine called GetKey without + // receiving a key. + LastAsked time.Time // EncKey is the encrypted provided by SubmitKey. If not set, no key // has been provided. @@ -101,11 +97,22 @@ func (s *Server) Run(ctx context.Context) error { return s.gs.Serve(lis) } -// CreateSession implements the CreateSession RPC -func (s *Server) CreateSession(ctx context.Context, req *pbgrpcv1.CreateSessionRequest) (*pbgrpcv1.CreateSessionResponse, error) { - resp := &pbgrpcv1.CreateSessionResponse{} +// GetTime implements the GetTime RPC +func (s *Server) GetTime(_ context.Context, req *pbgrpcv1.GetTimeRequest) (*pbgrpcv1.GetTimeResponse, error) { + resp := &pbgrpcv1.GetTimeResponse{} + resp.SetTime(time.Now().UTC().Format(time.RFC3339Nano)) + return resp, nil +} + +// GetKey implements the GetKey RPC +func (s *Server) GetKey(ctx context.Context, req *pbgrpcv1.GetKeyRequest) (*pbgrpcv1.GetKeyResponse, error) { + resp := &pbgrpcv1.GetKeyResponse{} nonce := req.GetNonce() + ts, err := time.Parse(time.RFC3339Nano, req.GetSignedAt()) + if err != nil || ts.IsZero() { + return nil, fmt.Errorf("failed to parsed signed at %q: %w", req.GetSignedAt(), err) + } sig := req.GetSignature() machine, err := s.db.Machine.Get(ctx, req.GetMachineId()) @@ -131,21 +138,11 @@ func (s *Server) CreateSession(ctx context.Context, req *pbgrpcv1.CreateSessionR return nil, fmt.Errorf("failed to add instance public key to encryptor: %w", err) } - sessionID := uuid.New() - var buf bytes.Buffer - if err := enc.Encrypt(strings.NewReader(sessionID.String()), newNopWriteCloser(&buf)); err != nil { - return nil, fmt.Errorf("failed to encrypt passphrase: %w", err) - } - resp.SetEncSessionId(buf.Bytes()) - - s.sesMu.Lock() - defer s.sesMu.Unlock() - - s.ses[machine.ID] = &Session{ - CreatedAt: time.Now().UTC(), - ID: sessionID, + if len(s.ses[machine.ID].EncKey) == 0 { + return nil, fmt.Errorf("key not available") } + resp.SetEncKey(s.ses[machine.ID].EncKey) return resp, nil } diff --git a/pkg/client/client.go b/pkg/client/client.go new file mode 100644 index 0000000..e2969b9 --- /dev/null +++ b/pkg/client/client.go @@ -0,0 +1,41 @@ +// Copyright (C) 2025 klefki contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +// SPDX-License-Identifier: AGPL-3.0 + +package client + +import ( + "fmt" + + pbgrpcv1 "git.rgst.io/homelab/klefki/internal/server/grpc/generated/go/rgst/klefki/v1" + "google.golang.org/grpc" + "google.golang.org/grpc/credentials/insecure" +) + +// Dial creates a new [pbgrpcv1.KlefkiServiceClient] at the given +// address with the provided options. Returned is the client and a +// closer function that can be used to close the underlying transport. +func Dial(address string, opts ...grpc.DialOption) (pbgrpcv1.KlefkiServiceClient, func() error, error) { + if opts == nil { + opts = []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())} + } + + conn, err := grpc.NewClient(address, opts...) + if err != nil { + return nil, nil, fmt.Errorf("failed to connect to klefki server: %w", err) + } + return pbgrpcv1.NewKlefkiServiceClient(conn), conn.Close, nil +}