You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
DateKeys/capsule/interop_test.go

100 lines
3.1 KiB

//go:build interop
// Interoperability with third-party tools (plan §7.9): SEALED_CONTROL and
// PAYLOAD_AGE of an official fixture are standard age files, opened here by
// the official age and tle command-line tools.
//
// go install filippo.io/age/cmd/age@v1.3.2
// go install github.com/drand/tlock/cmd/tle@v1.2.0
// go test -tags interop ./capsule -run Interop
//
// DATEKEYS_AGE and DATEKEYS_TLE may point at the binaries. The tle part
// fetches round 1000 from the public drand relay.
package capsule_test
import (
"bytes"
"encoding/hex"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"filippo.io/age"
"github.com/datekeys/datekeys-go/agewrap"
"github.com/datekeys/datekeys-go/internal/testkit"
)
func tool(t *testing.T, env, name string) string {
t.Helper()
if p := os.Getenv(env); p != "" {
return p
}
p, err := exec.LookPath(name)
if err != nil {
t.Skipf("%s not found; install it or set %s", name, env)
}
return p
}
func TestInteropAgeOpensPayload(t *testing.T) {
bin := tool(t, "DATEKEYS_AGE", "age")
f := loadFixture(t, "time_only")
parts, _ := testkit.Split(f.dkc)
raw, _ := hex.DecodeString(f.PayloadIdentity)
id, err := agewrap.X25519IdentityFromRaw(raw)
if err != nil {
t.Fatal(err)
}
dir := t.TempDir()
os.WriteFile(filepath.Join(dir, "payload.age"), parts.Payload, 0o600)
os.WriteFile(filepath.Join(dir, "id.txt"), []byte(id.String()+"\n"), 0o600)
out := filepath.Join(dir, "plain")
cmd := exec.Command(bin, "-d", "-i", filepath.Join(dir, "id.txt"), "-o", out, filepath.Join(dir, "payload.age"))
if b, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("age: %v\n%s", err, b)
}
if got, _ := os.ReadFile(out); !bytes.Equal(got, f.plaintext) {
t.Fatal("age produced a different plaintext")
}
}
func TestInteropAgeEncryptsPayloadWeOpen(t *testing.T) {
bin := tool(t, "DATEKEYS_AGE", "age")
id, _ := age.GenerateX25519Identity()
dir := t.TempDir()
os.WriteFile(filepath.Join(dir, "in"), []byte("written by age"), 0o600)
out := filepath.Join(dir, "out.age")
if b, err := exec.Command(bin, "-r", id.Recipient().String(), "-o", out, filepath.Join(dir, "in")).CombinedOutput(); err != nil {
t.Fatalf("age: %v\n%s", err, b)
}
file, _ := os.ReadFile(out)
raw, _ := agewrap.RawX25519Identity(id)
pid, _ := agewrap.NewPayloadIdentity(raw)
if got := decryptAge(t, file, pid); string(got) != "written by age" {
t.Fatal("plaintext differs")
}
}
func TestInteropTleOpensSealedControl(t *testing.T) {
bin := tool(t, "DATEKEYS_TLE", "tle")
f := loadFixture(t, "time_only")
parts, _ := testkit.Split(f.dkc)
dir := t.TempDir()
in := filepath.Join(dir, "sealed.age")
os.WriteFile(in, parts.Sealed, 0o600)
out := filepath.Join(dir, "control.cbor")
cmd := exec.Command(bin, "-d", "-o", out, in)
if b, err := cmd.CombinedOutput(); err != nil {
if strings.Contains(string(b), "dial") || strings.Contains(string(b), "no such host") {
t.Skipf("tle needs network access: %s", b)
}
t.Fatalf("tle: %v\n%s", err, b)
}
if got, _ := os.ReadFile(out); hex.EncodeToString(got) != f.ControlCBOR {
t.Fatal("tle produced a different CONTROL_CBOR")
}
}

Powered by TurnKey Linux.