170 lines
4.2 KiB
Go
170 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/safing/jess"
|
|
)
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(exportCmd)
|
|
rootCmd.AddCommand(backupCmd)
|
|
rootCmd.AddCommand(importCmd)
|
|
}
|
|
|
|
var (
|
|
exportCmdHelp = "usage: export <id>"
|
|
exportCmd = &cobra.Command{
|
|
Use: "export <id>",
|
|
Short: "export a signet or envelope",
|
|
Long: "export a signet (as a recipient - the public key only) or an envelope (configuration)",
|
|
RunE: handleExport,
|
|
}
|
|
|
|
backupCmdHelp = "usage: backup <id"
|
|
backupCmd = &cobra.Command{
|
|
Use: "backup <id>",
|
|
Short: "backup a signet",
|
|
Long: "backup a signet (the private key - do not share!)",
|
|
RunE: handleBackup,
|
|
}
|
|
|
|
importCmdHelp = "usage: import <text>"
|
|
importCmd = &cobra.Command{
|
|
Use: "import <text>",
|
|
Short: "import a signet or an enveleope",
|
|
Long: "import a signet (any kind) or an enveleope",
|
|
RunE: handleImport,
|
|
}
|
|
)
|
|
|
|
func handleExport(cmd *cobra.Command, args []string) error {
|
|
// Check args.
|
|
if len(args) != 1 {
|
|
return errors.New(exportCmdHelp)
|
|
}
|
|
id := args[0]
|
|
|
|
// Get Recipient.
|
|
recipient, err := trustStore.GetSignet(id, true)
|
|
if err == nil {
|
|
text, err := recipient.Export(false)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to export recipient %s: %w", id, err)
|
|
}
|
|
fmt.Println(text)
|
|
return nil
|
|
}
|
|
|
|
// Check if there is a signet instead.
|
|
signet, err := trustStore.GetSignet(id, false)
|
|
if err == nil {
|
|
recipient, err := signet.AsRecipient()
|
|
if err != nil {
|
|
return fmt.Errorf("failed convert signet %s to recipient for export: %w", id, err)
|
|
}
|
|
text, err := recipient.Export(false)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to export recipient %s: %w", id, err)
|
|
}
|
|
fmt.Println(text)
|
|
return nil
|
|
}
|
|
|
|
// Check for an envelope.
|
|
env, err := trustStore.GetEnvelope(id)
|
|
if err == nil {
|
|
text, err := env.Export(false)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to export envelope %s: %w", id, err)
|
|
}
|
|
fmt.Println(text)
|
|
return nil
|
|
}
|
|
|
|
return errors.New("no recipient or envelope found with the given ID")
|
|
}
|
|
|
|
func handleBackup(cmd *cobra.Command, args []string) error {
|
|
// Check args.
|
|
if len(args) != 1 {
|
|
return errors.New(backupCmdHelp)
|
|
}
|
|
id := args[0]
|
|
|
|
// Check if there is a signet instead.
|
|
signet, err := trustStore.GetSignet(id, false)
|
|
if err != nil {
|
|
text, err := signet.Backup(false)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to backup signet %s: %w", id, err)
|
|
}
|
|
fmt.Println(text)
|
|
return nil
|
|
}
|
|
|
|
return errors.New("no signet found with the given ID")
|
|
}
|
|
|
|
func handleImport(cmd *cobra.Command, args []string) error {
|
|
// Check args.
|
|
if len(args) != 1 {
|
|
return errors.New(importCmdHelp)
|
|
}
|
|
text := args[0]
|
|
|
|
// First, check if it's an envelope.
|
|
if strings.HasPrefix(text, jess.ExportEnvelopePrefix) {
|
|
env, err := jess.EnvelopeFromTextFormat(text)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse envelope: %w", err)
|
|
}
|
|
err = trustStore.StoreEnvelope(env)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to import envelope into trust store: %w", err)
|
|
}
|
|
fmt.Printf("imported envelope %q intro trust store\n", env.Name)
|
|
return nil
|
|
}
|
|
|
|
// Then handle all signet types together.
|
|
var (
|
|
signetType string
|
|
parseFunc func(textFormat string) (*jess.Signet, error)
|
|
)
|
|
switch {
|
|
case strings.HasPrefix(text, jess.ExportSenderPrefix):
|
|
signetType = jess.ExportSenderKeyword
|
|
parseFunc = jess.SenderFromTextFormat
|
|
case strings.HasPrefix(text, jess.ExportRecipientPrefix):
|
|
signetType = jess.ExportRecipientKeyword
|
|
parseFunc = jess.RecipientFromTextFormat
|
|
case strings.HasPrefix(text, jess.ExportKeyPrefix):
|
|
signetType = jess.ExportKeyKeyword
|
|
parseFunc = jess.KeyFromTextFormat
|
|
default:
|
|
return fmt.Errorf(
|
|
"invalid format or unknown type, expected one of %s, %s, %s, %s",
|
|
jess.ExportKeyKeyword,
|
|
jess.ExportSenderKeyword,
|
|
jess.ExportRecipientKeyword,
|
|
jess.ExportEnvelopeKeyword,
|
|
)
|
|
}
|
|
// Parse and import
|
|
signet, err := parseFunc(text)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to parse %s: %w", signetType, err)
|
|
}
|
|
err = trustStore.StoreSignet(signet)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to import %s into trust store: %w", signetType, err)
|
|
}
|
|
fmt.Printf("imported %s %s intro trust store\n", signetType, signet.ID)
|
|
|
|
return nil
|
|
}
|