carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package maintenance
2
3import (
4 "bytes"
5 "crypto/ecdh"
6 "crypto/rand"
7 "encoding/binary"
8 "reflect"
9 "strings"
10 "testing"
11)
12
13func TestInputExactSignedBytes(t *testing.T) {
14 in := Input{Arguments: []string{"operator-v1", "", "space value", "$(not-a-shell)"}, Stdin: []byte(" \n{\"signed\": \"\\u003c\", \"n\": 1e0} \n")}
15 frame, err := EncodeInput(in)
16 if err != nil {
17 t.Fatal(err)
18 }
19 got, err := DecodeInput(frame)
20 if err != nil || !reflect.DeepEqual(in, got) {
21 t.Fatalf("round trip: %v", err)
22 }
23 clear(frame)
24 if !reflect.DeepEqual(in, got) {
25 t.Fatal("decoded input aliases frame")
26 }
27 priv, err := ecdh.P256().GenerateKey(rand.Reader)
28 if err != nil {
29 t.Fatal(err)
30 }
31 fingerprint, _ := RecipientFingerprint(priv.PublicKey())
32 binding := Binding{Version: 1, Direction: DirectionInput, Account: "account", App: "home", Host: "test.example", RequestID: "request", AttemptID: "attempt", Recipient: fingerprint}
33 sealed, err := SealInput(priv.PublicKey(), binding, in)
34 if err != nil {
35 t.Fatal(err)
36 }
37 opened, err := OpenInput(priv, binding, sealed)
38 if err != nil || !reflect.DeepEqual(in, opened) {
39 t.Fatalf("sealed round trip: %v", err)
40 }
41 for _, direction := range []Direction{DirectionResult, DirectionEnvironment} {
42 wrong := binding
43 wrong.Direction = direction
44 if _, err := SealInput(priv.PublicKey(), wrong, in); err != ErrInput {
45 t.Fatal("accepted wrong sealing direction")
46 }
47 // An otherwise valid envelope of the wrong purpose must also be refused.
48 frame, _ := EncodeInput(in)
49 ciphertext, err := Seal(priv.PublicKey(), wrong, frame)
50 if err != nil {
51 t.Fatal(err)
52 }
53 if _, err := OpenInput(priv, wrong, ciphertext); err != ErrInput {
54 t.Fatal("accepted wrong opening direction")
55 }
56 }
57}
58
59func TestInputLimitsAndRefusals(t *testing.T) {
60 maxJSON := []byte(`"` + strings.Repeat("x", MaxInputBytes-2) + `"`)
61 args := make([]string, MaxArguments)
62 args[0] = strings.Repeat("x", MaxArgumentBytes)
63 boundary := Input{Arguments: args, Stdin: maxJSON}
64 frame, err := EncodeInput(boundary)
65 if err != nil {
66 t.Fatal(err)
67 }
68 if _, err := DecodeInput(frame); err != nil {
69 t.Fatal(err)
70 }
71 bad := []Input{
72 {nil, []byte(`{}`)},
73 {make([]string, MaxArguments+1), []byte(`{}`)},
74 {[]string{strings.Repeat("x", MaxArgumentBytes), "x"}, []byte(`{}`)},
75 {[]string{"ok\x00bad"}, []byte(`{}`)},
76 {[]string{string([]byte{255})}, []byte(`{}`)},
77 {[]string{"ok"}, append(bytes.Clone(maxJSON), ' ')},
78 {[]string{"ok"}, nil},
79 {[]string{"ok"}, []byte(`{} {}`)},
80 {[]string{"ok"}, []byte{'"', 255, '"'}},
81 }
82 for i, in := range bad {
83 if _, err := EncodeInput(in); err != ErrInput {
84 t.Fatalf("case %d encode accepted", i)
85 }
86 // Construct unchecked frames so decoder limits cannot rely on the encoder.
87 raw := binary.BigEndian.AppendUint32([]byte(inputPrefix), uint32(len(in.Arguments)))
88 for _, arg := range in.Arguments {
89 raw = appendField(raw, []byte(arg))
90 }
91 raw = appendField(raw, in.Stdin)
92 if _, err := DecodeInput(raw); err != ErrInput {
93 t.Fatalf("case %d decode accepted", i)
94 }
95 }
96}
97
98func TestInputMalformedFrames(t *testing.T) {
99 frame, _ := EncodeInput(Input{[]string{"operator-v1", "argument"}, []byte(`{"ok":true}`)})
100 for n := 0; n < len(frame); n++ {
101 if _, err := DecodeInput(frame[:n]); err != ErrInput {
102 t.Fatalf("accepted truncation %d", n)
103 }
104 }
105 for _, offset := range []int{0, 4, 8, 8 + 4 + len("operator-v1"), 8 + 4 + len("operator-v1") + 4 + len("argument")} {
106 broken := bytes.Clone(frame)
107 binary.BigEndian.PutUint32(broken[offset:offset+4], ^uint32(0))
108 if _, err := DecodeInput(broken); err != ErrInput {
109 t.Fatalf("accepted corrupt frame at %d", offset)
110 }
111 }
112 if _, err := DecodeInput(append(bytes.Clone(frame), 0)); err != ErrInput {
113 t.Fatal("accepted trailing bytes")
114 }
115 if _, err := DecodeInput(make([]byte, maxInputFrame+1)); err != ErrInput {
116 t.Fatal("accepted oversized frame")
117 }
118}
119