package cmd import ( "fmt" "github.com/portainer/kubesolo-os/update/pkg/signing" ) // Sign creates Ed25519 signatures for update artifacts. // Used during the build process, not on the target device. // // Usage: // // kubesolo-update sign --key [file...] func Sign(args []string) error { var keyPath string var files []string for i := 0; i < len(args); i++ { switch args[i] { case "--key": if i+1 < len(args) { keyPath = args[i+1] i++ } default: // Non-flag args are files to sign if args[i] != "" && args[i][0] != '-' { files = append(files, args[i]) } } } if keyPath == "" { return fmt.Errorf("--key is required (path to Ed25519 private key hex file)") } if len(files) == 0 { return fmt.Errorf("at least one file to sign is required") } signer, err := signing.NewSignerFromFile(keyPath) if err != nil { return fmt.Errorf("loading private key: %w", err) } for _, f := range files { sigPath := f + ".sig" if err := signer.SignFile(f, sigPath); err != nil { return fmt.Errorf("signing %s: %w", f, err) } fmt.Printf("Signed: %s → %s\n", f, sigPath) } return nil } // GenKey generates a new Ed25519 key pair for signing updates. // // Usage: // // kubesolo-update genkey func GenKey(args []string) error { pub, priv, err := signing.GenerateKeyPair() if err != nil { return err } fmt.Printf("Public key (hex): %s\n", pub) fmt.Printf("Private key (hex): %s\n", priv) fmt.Println() fmt.Println("Save the public key to /etc/kubesolo/update-pubkey.hex on the device.") fmt.Println("Keep the private key secure and offline — use it only for signing updates.") return nil }