diff --git a/internal/stream/stream.go b/internal/stream/stream.go index f6d0602..7cf02c4 100644 --- a/internal/stream/stream.go +++ b/internal/stream/stream.go @@ -8,6 +8,7 @@ package stream import ( "crypto/cipher" "errors" + "fmt" "io" "golang.org/x/crypto/chacha20poly1305" @@ -66,7 +67,17 @@ func (r *Reader) Read(p []byte) (int, error) { r.unread = r.unread[n:] if last { - r.err = io.EOF + // Ensure there is an EOF after the last chunk as expected. In other + // words, check for trailing data after a full-length final chunk. + // Hopefully, the underlying reader supports returning EOF even if it + // had previously returned an EOF to ReadFull. + if _, err := r.src.Read(make([]byte, 1)); err == nil { + r.err = errors.New("trailing data after end of encrypted file") + } else if err != io.EOF { + r.err = fmt.Errorf("non-EOF error reading after end of encrypted file: %w", err) + } else { + r.err = io.EOF + } } return n, nil diff --git a/internal/testkit/testkit.go b/internal/testkit/testkit.go index ba03d50..ad7fc43 100644 --- a/internal/testkit/testkit.go +++ b/internal/testkit/testkit.go @@ -9,6 +9,7 @@ import ( "crypto/hmac" "crypto/sha256" "encoding/base64" + "encoding/hex" "fmt" "io" "os" @@ -30,6 +31,16 @@ var _, TestX25519Identity, _ = bech32.Decode( var TestX25519Recipient, _ = curve25519.X25519(TestX25519Identity, curve25519.Basepoint) +// These are the file key and nonce used to encrypt any full/multiple-chunk +// tests. They were generated by a previous iteration of this test suite. +// Reusing them across files and history makes the repository easier to pack and +// the test suite easier to compress. +var LargeTestFileKey, _ = hex.DecodeString("7aa5bdac0e6afeed3dd0a7eccb42af44") +var LargeTestNonce, _ = hex.DecodeString("c82f71eb82029b77136399e485e879f4") +var LargeTestFirstChunk = bytes.Repeat([]byte{0}, 64*1024) +var LargeTestSecondChunk = bytes.Repeat([]byte{1}, 64*1024) +var LargeTestThirdChunk = bytes.Repeat([]byte{2}, 64*1024) + func NotCanonicalBase64(s string) string { // Assuming there are spare zero bits at the end of the encoded bitstring, // the character immediately after in the alphabet compared to the last one @@ -222,6 +233,14 @@ func (f *TestFile) ExpectHeaderFailure() { func (f *TestFile) ExpectPayloadFailure() { f.expect = "payload failure" + f.payload.Reset() +} + +func (f *TestFile) ExpectPartialPayload(goodBytes int) { + f.expect = "payload failure" + payload := f.payload.Bytes() + f.payload.Reset() + f.payload.Write(payload[:goodBytes]) } func (f *TestFile) ExpectHMACFailure() { @@ -238,7 +257,7 @@ func (f *TestFile) Comment(c string) { func (f *TestFile) Generate() { fmt.Printf("expect: %s\n", f.expect) - if f.expect == "success" { + if f.expect == "success" || f.expect == "payload failure" { fmt.Printf("payload: %x\n", sha256.Sum256(f.payload.Bytes())) } fmt.Printf("file key: %x\n", f.fileKey) diff --git a/testdata/testkit/stream_bad_tag b/testdata/testkit/stream_bad_tag new file mode 100644 index 0000000..ce8189a Binary files /dev/null and b/testdata/testkit/stream_bad_tag differ diff --git a/testdata/testkit/stream_bad_tag_second_chunk b/testdata/testkit/stream_bad_tag_second_chunk new file mode 100644 index 0000000..21ec15e Binary files /dev/null and b/testdata/testkit/stream_bad_tag_second_chunk differ diff --git a/testdata/testkit/stream_bad_tag_second_chunk_full b/testdata/testkit/stream_bad_tag_second_chunk_full new file mode 100644 index 0000000..bcf23ad Binary files /dev/null and b/testdata/testkit/stream_bad_tag_second_chunk_full differ diff --git a/testdata/testkit/stream_last_chunk_empty b/testdata/testkit/stream_last_chunk_empty index 0795d14..b3a2a64 100644 Binary files a/testdata/testkit/stream_last_chunk_empty and b/testdata/testkit/stream_last_chunk_empty differ diff --git a/testdata/testkit/stream_last_chunk_full b/testdata/testkit/stream_last_chunk_full index bc4baae..5792b42 100644 Binary files a/testdata/testkit/stream_last_chunk_full and b/testdata/testkit/stream_last_chunk_full differ diff --git a/testdata/testkit/stream_last_chunk_full_second b/testdata/testkit/stream_last_chunk_full_second new file mode 100644 index 0000000..8e9936d Binary files /dev/null and b/testdata/testkit/stream_last_chunk_full_second differ diff --git a/testdata/testkit/stream_missing_tag b/testdata/testkit/stream_missing_tag new file mode 100644 index 0000000..87bf215 Binary files /dev/null and b/testdata/testkit/stream_missing_tag differ diff --git a/testdata/testkit/stream_no_chunks b/testdata/testkit/stream_no_chunks new file mode 100644 index 0000000..7d68f8b Binary files /dev/null and b/testdata/testkit/stream_no_chunks differ diff --git a/testdata/testkit/stream_no_final b/testdata/testkit/stream_no_final new file mode 100644 index 0000000..413187e Binary files /dev/null and b/testdata/testkit/stream_no_final differ diff --git a/testdata/testkit/stream_no_final_full b/testdata/testkit/stream_no_final_full new file mode 100644 index 0000000..f61cf07 Binary files /dev/null and b/testdata/testkit/stream_no_final_full differ diff --git a/testdata/testkit/stream_no_final_two_chunks b/testdata/testkit/stream_no_final_two_chunks new file mode 100644 index 0000000..ecdf769 Binary files /dev/null and b/testdata/testkit/stream_no_final_two_chunks differ diff --git a/testdata/testkit/stream_no_final_two_chunks_full b/testdata/testkit/stream_no_final_two_chunks_full new file mode 100644 index 0000000..88930ee Binary files /dev/null and b/testdata/testkit/stream_no_final_two_chunks_full differ diff --git a/testdata/testkit/stream_no_nonce b/testdata/testkit/stream_no_nonce new file mode 100644 index 0000000..62dcf36 Binary files /dev/null and b/testdata/testkit/stream_no_nonce differ diff --git a/testdata/testkit/stream_short_chunk b/testdata/testkit/stream_short_chunk new file mode 100644 index 0000000..13796de Binary files /dev/null and b/testdata/testkit/stream_short_chunk differ diff --git a/testdata/testkit/stream_short_nonce b/testdata/testkit/stream_short_nonce new file mode 100644 index 0000000..06dc835 Binary files /dev/null and b/testdata/testkit/stream_short_nonce differ diff --git a/testdata/testkit/stream_short_second_chunk b/testdata/testkit/stream_short_second_chunk new file mode 100644 index 0000000..c448186 Binary files /dev/null and b/testdata/testkit/stream_short_second_chunk differ diff --git a/testdata/testkit/stream_three_chunks b/testdata/testkit/stream_three_chunks new file mode 100644 index 0000000..734ed99 Binary files /dev/null and b/testdata/testkit/stream_three_chunks differ diff --git a/testdata/testkit/stream_trailing_garbage_long b/testdata/testkit/stream_trailing_garbage_long new file mode 100644 index 0000000..0862439 Binary files /dev/null and b/testdata/testkit/stream_trailing_garbage_long differ diff --git a/testdata/testkit/stream_trailing_garbage_short b/testdata/testkit/stream_trailing_garbage_short new file mode 100644 index 0000000..733e401 Binary files /dev/null and b/testdata/testkit/stream_trailing_garbage_short differ diff --git a/testdata/testkit/stream_two_chunks b/testdata/testkit/stream_two_chunks new file mode 100644 index 0000000..8e9936d Binary files /dev/null and b/testdata/testkit/stream_two_chunks differ diff --git a/testdata/testkit/stream_two_final_chunks b/testdata/testkit/stream_two_final_chunks new file mode 100644 index 0000000..ac2e7a7 Binary files /dev/null and b/testdata/testkit/stream_two_final_chunks differ diff --git a/testkit_test.go b/testkit_test.go index 5a2ea61..ea9d69d 100644 --- a/testkit_test.go +++ b/testkit_test.go @@ -155,6 +155,9 @@ func testVector(t *testing.T, test []byte) { if err != nil { if expect == "payload failure" { t.Log(err) + if payloadHash != nil && sha256.Sum256(out) != *payloadHash { + t.Error("partial payload hash mismatch") + } return } t.Fatalf("expected %s, got: %v", expect, err) diff --git a/tests/stream_bad_tag.go b/tests/stream_bad_tag.go new file mode 100644 index 0000000..822d731 --- /dev/null +++ b/tests/stream_bad_tag.go @@ -0,0 +1,23 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.VersionLine("v1") + f.X25519(testkit.TestX25519Recipient) + f.HMAC() + f.Payload("age") + file := f.Buf.Bytes() + f.Buf.Reset() + file[len(file)-1] ^= 0b0010_0000 + f.Buf.Write(file) + f.ExpectPayloadFailure() + f.Generate() +} diff --git a/tests/stream_bad_tag_second_chunk.go b/tests/stream_bad_tag_second_chunk.go new file mode 100644 index 0000000..f3b5059 --- /dev/null +++ b/tests/stream_bad_tag_second_chunk.go @@ -0,0 +1,26 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.PayloadChunkFinal([]byte("age")) + file := f.Buf.Bytes() + f.Buf.Reset() + file[len(file)-1] ^= 0b0010_0000 + f.Buf.Write(file) + f.ExpectPartialPayload(64 * 1024) + f.Generate() +} diff --git a/tests/stream_bad_tag_second_chunk_full.go b/tests/stream_bad_tag_second_chunk_full.go new file mode 100644 index 0000000..c3dfbd3 --- /dev/null +++ b/tests/stream_bad_tag_second_chunk_full.go @@ -0,0 +1,26 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.PayloadChunkFinal(testkit.LargeTestSecondChunk) + file := f.Buf.Bytes() + f.Buf.Reset() + file[len(file)-1] ^= 0b0010_0000 + f.Buf.Write(file) + f.ExpectPartialPayload(64 * 1024) + f.Generate() +} diff --git a/tests/stream_last_chunk_empty.go b/tests/stream_last_chunk_empty.go index 8cebe0e..ed33241 100644 --- a/tests/stream_last_chunk_empty.go +++ b/tests/stream_last_chunk_empty.go @@ -6,27 +6,18 @@ package main -import ( - "bytes" - "encoding/hex" - - "filippo.io/age/internal/testkit" -) +import "filippo.io/age/internal/testkit" func main() { f := testkit.NewTestFile() - // Reuse the file key and nonce from a previous test vector to avoid - // bloating the git history with two versions that can't be compressed. - fileKey, _ := hex.DecodeString("7aa5bdac0e6afeed3dd0a7eccb42af44") - f.FileKey(fileKey) + f.FileKey(testkit.LargeTestFileKey) f.VersionLine("v1") f.X25519(testkit.TestX25519Identity) f.HMAC() - nonce, _ := hex.DecodeString("c82f71eb82029b77136399e485e879f4") - f.Nonce(nonce) - f.PayloadChunk(bytes.Repeat([]byte{0}, 64*1024)) + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) f.PayloadChunkFinal([]byte{}) f.Comment("final STREAM chunk can't be empty unless whole payload is empty") - f.ExpectPayloadFailure() + f.ExpectPartialPayload(64 * 1024) f.Generate() } diff --git a/tests/stream_last_chunk_full.go b/tests/stream_last_chunk_full.go index a86efe7..db7807a 100644 --- a/tests/stream_last_chunk_full.go +++ b/tests/stream_last_chunk_full.go @@ -6,24 +6,15 @@ package main -import ( - "bytes" - "encoding/hex" - - "filippo.io/age/internal/testkit" -) +import "filippo.io/age/internal/testkit" func main() { f := testkit.NewTestFile() - // Reuse the file key and nonce from a previous test vector to avoid - // bloating the git history with two versions that can't be compressed. - fileKey, _ := hex.DecodeString("5085919e0d59b19d6cbd00330f03861c") - f.FileKey(fileKey) + f.FileKey(testkit.LargeTestFileKey) f.VersionLine("v1") f.X25519(testkit.TestX25519Identity) f.HMAC() - nonce, _ := hex.DecodeString("32521791a6f22e11637fb69ead3f2d5f") - f.Nonce(nonce) - f.PayloadChunkFinal(bytes.Repeat([]byte{0}, 64*1024)) + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunkFinal(testkit.LargeTestFirstChunk) f.Generate() } diff --git a/tests/stream_last_chunk_full_second.go b/tests/stream_last_chunk_full_second.go new file mode 100644 index 0000000..bb215ee --- /dev/null +++ b/tests/stream_last_chunk_full_second.go @@ -0,0 +1,21 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.PayloadChunkFinal(testkit.LargeTestSecondChunk) + f.Generate() +} diff --git a/tests/stream_missing_tag.go b/tests/stream_missing_tag.go new file mode 100644 index 0000000..b0e7843 --- /dev/null +++ b/tests/stream_missing_tag.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.VersionLine("v1") + f.X25519(testkit.TestX25519Recipient) + f.HMAC() + f.Payload("age") + file := f.Buf.Bytes() + f.Buf.Reset() + f.Buf.Write(file[:len(file)-16]) + f.ExpectPayloadFailure() + f.Generate() +} diff --git a/tests/stream_no_chunks.go b/tests/stream_no_chunks.go new file mode 100644 index 0000000..d682427 --- /dev/null +++ b/tests/stream_no_chunks.go @@ -0,0 +1,19 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.VersionLine("v1") + f.X25519(testkit.TestX25519Recipient) + f.HMAC() + f.Nonce(f.Rand(16)) + f.ExpectPayloadFailure() + f.Generate() +} diff --git a/tests/stream_no_final.go b/tests/stream_no_final.go new file mode 100644 index 0000000..a7021f7 --- /dev/null +++ b/tests/stream_no_final.go @@ -0,0 +1,20 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.VersionLine("v1") + f.X25519(testkit.TestX25519Recipient) + f.HMAC() + f.Nonce(f.Rand(16)) + f.PayloadChunk([]byte("age")) + f.ExpectPayloadFailure() + f.Generate() +} diff --git a/tests/stream_no_final_full.go b/tests/stream_no_final_full.go new file mode 100644 index 0000000..630dbdd --- /dev/null +++ b/tests/stream_no_final_full.go @@ -0,0 +1,21 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.ExpectPartialPayload(64 * 1024) + f.Generate() +} diff --git a/tests/stream_no_final_two_chunks.go b/tests/stream_no_final_two_chunks.go new file mode 100644 index 0000000..6745215 --- /dev/null +++ b/tests/stream_no_final_two_chunks.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.PayloadChunk([]byte("age")) + f.ExpectPartialPayload(64 * 1024) + f.Generate() +} diff --git a/tests/stream_no_final_two_chunks_full.go b/tests/stream_no_final_two_chunks_full.go new file mode 100644 index 0000000..a2b99dc --- /dev/null +++ b/tests/stream_no_final_two_chunks_full.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.PayloadChunk(testkit.LargeTestSecondChunk) + f.ExpectPartialPayload(64 * 1024 * 2) + f.Generate() +} diff --git a/tests/stream_no_nonce.go b/tests/stream_no_nonce.go new file mode 100644 index 0000000..56f8d53 --- /dev/null +++ b/tests/stream_no_nonce.go @@ -0,0 +1,20 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.VersionLine("v1") + f.X25519(testkit.TestX25519Recipient) + f.HMAC() + // Marked as header failure because we read the nonce while reading the + // header, before handing off to the STREAM implementation. + f.ExpectHeaderFailure() + f.Generate() +} diff --git a/tests/stream_short_chunk.go b/tests/stream_short_chunk.go new file mode 100644 index 0000000..982cfc9 --- /dev/null +++ b/tests/stream_short_chunk.go @@ -0,0 +1,20 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.VersionLine("v1") + f.X25519(testkit.TestX25519Recipient) + f.HMAC() + f.Nonce(f.Rand(16)) + f.Nonce(f.Rand(12)) // less than the length of a Poly1305 tag + f.ExpectPayloadFailure() + f.Generate() +} diff --git a/tests/stream_short_nonce.go b/tests/stream_short_nonce.go new file mode 100644 index 0000000..355fd16 --- /dev/null +++ b/tests/stream_short_nonce.go @@ -0,0 +1,21 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.VersionLine("v1") + f.X25519(testkit.TestX25519Recipient) + f.HMAC() + f.Nonce(f.Rand(12)) + // Marked as header failure because we read the nonce while reading the + // header, before handing off to the STREAM implementation. + f.ExpectHeaderFailure() + f.Generate() +} diff --git a/tests/stream_short_second_chunk.go b/tests/stream_short_second_chunk.go new file mode 100644 index 0000000..4aac7af --- /dev/null +++ b/tests/stream_short_second_chunk.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.Nonce(f.Rand(12)) // less than the length of a Poly1305 tag + f.ExpectPartialPayload(64 * 1024) + f.Generate() +} diff --git a/tests/stream_three_chunks.go b/tests/stream_three_chunks.go new file mode 100644 index 0000000..5529a21 --- /dev/null +++ b/tests/stream_three_chunks.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.PayloadChunk(testkit.LargeTestSecondChunk) + f.PayloadChunkFinal(testkit.LargeTestThirdChunk) + f.Generate() +} diff --git a/tests/stream_trailing_garbage_long.go b/tests/stream_trailing_garbage_long.go new file mode 100644 index 0000000..e9d6b10 --- /dev/null +++ b/tests/stream_trailing_garbage_long.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunkFinal(testkit.LargeTestFirstChunk) + f.Buf.Write(f.Rand(20)) + f.ExpectPartialPayload(64 * 1024) + f.Generate() +} diff --git a/tests/stream_trailing_garbage_short.go b/tests/stream_trailing_garbage_short.go new file mode 100644 index 0000000..73e7173 --- /dev/null +++ b/tests/stream_trailing_garbage_short.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunkFinal(testkit.LargeTestFirstChunk) + f.Buf.Write(f.Rand(12)) + f.ExpectPartialPayload(64 * 1024) + f.Generate() +} diff --git a/tests/stream_two_chunks.go b/tests/stream_two_chunks.go new file mode 100644 index 0000000..bb215ee --- /dev/null +++ b/tests/stream_two_chunks.go @@ -0,0 +1,21 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunk(testkit.LargeTestFirstChunk) + f.PayloadChunkFinal(testkit.LargeTestSecondChunk) + f.Generate() +} diff --git a/tests/stream_two_final_chunks.go b/tests/stream_two_final_chunks.go new file mode 100644 index 0000000..6099fe0 --- /dev/null +++ b/tests/stream_two_final_chunks.go @@ -0,0 +1,22 @@ +// Copyright 2022 The age Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +//go:build ignore + +package main + +import "filippo.io/age/internal/testkit" + +func main() { + f := testkit.NewTestFile() + f.FileKey(testkit.LargeTestFileKey) + f.VersionLine("v1") + f.X25519(testkit.TestX25519Identity) + f.HMAC() + f.Nonce(testkit.LargeTestNonce) + f.PayloadChunkFinal(testkit.LargeTestFirstChunk) + f.PayloadChunkFinal([]byte("age")) + f.ExpectPartialPayload(64 * 1024) + f.Generate() +}