180 lines
4.6 KiB
Go
180 lines
4.6 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/AlecAivazis/survey/v2"
|
|
|
|
"github.com/safing/jess"
|
|
)
|
|
|
|
func newEnvelope(name string) (*jess.Envelope, error) {
|
|
// check name
|
|
name = strings.TrimSpace(name)
|
|
if name == "" {
|
|
return nil, errors.New("missing envelope name")
|
|
}
|
|
|
|
// start init process
|
|
envelope := jess.NewUnconfiguredEnvelope()
|
|
envelope.Name = name
|
|
|
|
// preset menu
|
|
var preset string
|
|
prompt := &survey.Select{
|
|
Message: "Select preset:",
|
|
Options: []string{
|
|
"Encrypt with password",
|
|
"Encrypt with key",
|
|
"Encrypt for someone and sign",
|
|
"Encrypt for someone but don't sign",
|
|
"Sign a file (wrapped)",
|
|
"Sign a file (separate sig)",
|
|
},
|
|
}
|
|
err := survey.AskOne(prompt, &preset, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch preset {
|
|
case "Encrypt with password":
|
|
envelope.SuiteID = jess.SuitePassword
|
|
err = selectSignets(envelope, "pw")
|
|
case "Encrypt with key":
|
|
envelope.SuiteID = jess.SuiteKey
|
|
err = selectSignets(envelope, "key")
|
|
case "Encrypt for someone and sign":
|
|
envelope.SuiteID = jess.SuiteComplete
|
|
err = selectSignets(envelope, "recipient")
|
|
if err == nil {
|
|
err = selectSignets(envelope, "sender")
|
|
}
|
|
case "Encrypt for someone but don't sign":
|
|
envelope.SuiteID = jess.SuiteRcptOnly
|
|
err = selectSignets(envelope, "recipient")
|
|
case "Sign a file (wrapped)":
|
|
envelope.SuiteID = jess.SuiteSign
|
|
err = selectSignets(envelope, "sender")
|
|
case "Sign a file (separate sig)":
|
|
envelope.SuiteID = jess.SuiteSignFile
|
|
err = selectSignets(envelope, "sender")
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return envelope, nil
|
|
}
|
|
|
|
func editEnvelope(envelope *jess.Envelope) error {
|
|
for {
|
|
// main menu
|
|
|
|
// print envelope status
|
|
envelope.SecurityLevel = 0 // reset
|
|
session, err := envelope.Correspondence(trustStore)
|
|
if err != nil {
|
|
fmt.Printf("Envelope status: %s\n", err)
|
|
} else {
|
|
fmt.Println("Envelope status: valid.")
|
|
envelope.SecurityLevel = session.SecurityLevel
|
|
}
|
|
|
|
// sub menu
|
|
var submenu string
|
|
prompt := &survey.Select{
|
|
Message: "Select to edit",
|
|
Options: formatColumns([][]string{
|
|
{"Done", "save and return"},
|
|
{""},
|
|
{"Suite", envelope.SuiteID},
|
|
{"", "provides " + formatRequirements(envelope.Suite().Provides)},
|
|
{"", "and " + formatSecurityLevel(envelope.Suite().SecurityLevel)},
|
|
{"Secrets", formatSignetNames(envelope.Secrets)},
|
|
{"Recipients", formatSignetNames(envelope.Recipients)},
|
|
{"Senders", formatSignetNames(envelope.Senders)},
|
|
{""},
|
|
{"Export", "export to text format"},
|
|
{"Abort", "discard changes and return"},
|
|
{"Delete", "delete and return"},
|
|
}),
|
|
PageSize: 15,
|
|
}
|
|
err = survey.AskOne(prompt, &submenu, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
switch {
|
|
case strings.HasPrefix(submenu, "Done"):
|
|
// Check if the envelope is valid.
|
|
if envelope.SecurityLevel == 0 {
|
|
fmt.Println("Envelope is invalid, please fix before saving.")
|
|
continue
|
|
}
|
|
// Remove and keys and save.
|
|
envelope.CleanSignets()
|
|
return trustStore.StoreEnvelope(envelope)
|
|
case strings.HasPrefix(submenu, "Export"):
|
|
// Check if the envelope is valid.
|
|
if envelope.SecurityLevel == 0 {
|
|
fmt.Println("Envelope is invalid, please fix before exporting.")
|
|
continue
|
|
}
|
|
// Remove keys and export.
|
|
envelope.CleanSignets()
|
|
text, err := envelope.Export(false)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to export: %w", err)
|
|
}
|
|
fmt.Println("Exported envelope:")
|
|
fmt.Println(text)
|
|
case strings.HasPrefix(submenu, "Abort"):
|
|
return nil
|
|
case strings.HasPrefix(submenu, "Delete"):
|
|
return trustStore.DeleteEnvelope(envelope.Name)
|
|
case strings.HasPrefix(submenu, "Suite"):
|
|
err = editEnvelopeSuite(envelope)
|
|
case strings.HasPrefix(submenu, "Secrets"):
|
|
err = selectSignets(envelope, "pw/key")
|
|
case strings.HasPrefix(submenu, "Recipients"):
|
|
err = selectSignets(envelope, "recipient")
|
|
case strings.HasPrefix(submenu, "Senders"):
|
|
err = selectSignets(envelope, "sender")
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
func editEnvelopeSuite(envelope *jess.Envelope) error {
|
|
all := jess.Suites()
|
|
suiteOptions := make([][]string, 0, len(all))
|
|
for _, suite := range all {
|
|
suiteOptions = append(suiteOptions, []string{
|
|
suite.ID,
|
|
"provides " + suite.Provides.ShortString(),
|
|
formatSecurityLevel(suite.SecurityLevel),
|
|
"uses " + strings.Join(suite.Tools, ", "),
|
|
formatSuiteStatus(suite),
|
|
})
|
|
}
|
|
|
|
var selectedSuite string
|
|
prompt := &survey.Select{
|
|
Message: "Select suite",
|
|
Options: formatColumns(suiteOptions),
|
|
PageSize: 10,
|
|
}
|
|
err := survey.AskOne(prompt, &selectedSuite, nil)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
envelope.SuiteID = strings.Fields(selectedSuite)[0]
|
|
return envelope.ReloadSuite()
|
|
}
|