mirror of
https://github.com/FiloSottile/age.git
synced 2026-03-11 08:55:41 +00:00
tests: add scrypt tests and move Go files from testdata
This commit is contained in:
parent
787044bdb6
commit
92713afd1e
45 changed files with 186 additions and 14 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -1,2 +1,2 @@
|
|||
*.age binary
|
||||
*.test binary
|
||||
testdata/testkit/* binary
|
||||
|
|
|
|||
BIN
cmd/age/testdata/fail_large_filekey_scrypt.age
vendored
BIN
cmd/age/testdata/fail_large_filekey_scrypt.age
vendored
Binary file not shown.
BIN
cmd/age/testdata/fail_scrypt_and_x25519.age
vendored
BIN
cmd/age/testdata/fail_scrypt_and_x25519.age
vendored
Binary file not shown.
BIN
cmd/age/testdata/fail_scrypt_work_factor_23.age
vendored
BIN
cmd/age/testdata/fail_scrypt_work_factor_23.age
vendored
Binary file not shown.
BIN
cmd/age/testdata/good_scrypt_work_factor_10.age
vendored
BIN
cmd/age/testdata/good_scrypt_work_factor_10.age
vendored
Binary file not shown.
|
|
@ -12,6 +12,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"filippo.io/age/internal/bech32"
|
||||
|
|
@ -19,6 +20,7 @@ import (
|
|||
"golang.org/x/crypto/chacha20poly1305"
|
||||
"golang.org/x/crypto/curve25519"
|
||||
"golang.org/x/crypto/hkdf"
|
||||
"golang.org/x/crypto/scrypt"
|
||||
)
|
||||
|
||||
var TestFileKey = []byte("YELLOW SUBMARINE")
|
||||
|
|
@ -32,13 +34,14 @@ type TestFile struct {
|
|||
Buf bytes.Buffer
|
||||
Rand func(n int) []byte
|
||||
|
||||
fileKey []byte
|
||||
streamKey []byte
|
||||
nonce [12]byte
|
||||
payload bytes.Buffer
|
||||
expect string
|
||||
comment string
|
||||
identities []string
|
||||
fileKey []byte
|
||||
streamKey []byte
|
||||
nonce [12]byte
|
||||
payload bytes.Buffer
|
||||
expect string
|
||||
comment string
|
||||
identities []string
|
||||
passphrases []string
|
||||
}
|
||||
|
||||
func NewTestFile() *TestFile {
|
||||
|
|
@ -117,6 +120,23 @@ func (f *TestFile) X25519NoRecordIdentity(identity []byte) {
|
|||
f.AEADBody(key, f.fileKey)
|
||||
}
|
||||
|
||||
func (f *TestFile) Scrypt(passphrase string, workFactor int) {
|
||||
f.ScryptRecordPassphrase(passphrase)
|
||||
f.ScryptNoRecordPassphrase(passphrase, workFactor)
|
||||
}
|
||||
|
||||
func (f *TestFile) ScryptRecordPassphrase(passphrase string) {
|
||||
f.passphrases = append(f.passphrases, passphrase)
|
||||
}
|
||||
|
||||
func (f *TestFile) ScryptNoRecordPassphrase(passphrase string, workFactor int) {
|
||||
salt := f.Rand(16)
|
||||
f.ArgsLine("scrypt", b64(salt), strconv.Itoa(workFactor))
|
||||
key, _ := scrypt.Key([]byte(passphrase), append([]byte("age-encryption.org/v1/scrypt"), salt...),
|
||||
1<<workFactor, 8, 1, 32)
|
||||
f.AEADBody(key, f.fileKey)
|
||||
}
|
||||
|
||||
func (f *TestFile) HMACLine(h []byte) {
|
||||
f.TextLine("--- " + b64(h))
|
||||
}
|
||||
|
|
@ -176,6 +196,9 @@ func (f *TestFile) Generate() {
|
|||
for _, id := range f.identities {
|
||||
fmt.Printf("identity: %s\n", id)
|
||||
}
|
||||
for _, p := range f.passphrases {
|
||||
fmt.Printf("passphrase: %s\n", p)
|
||||
}
|
||||
if f.comment != "" {
|
||||
fmt.Printf("comment: %s\n", f.comment)
|
||||
}
|
||||
|
|
|
|||
BIN
testdata/testkit/long_file_key_scrypt
vendored
Normal file
BIN
testdata/testkit/long_file_key_scrypt
vendored
Normal file
Binary file not shown.
BIN
testdata/testkit/scrypt
vendored
Normal file
BIN
testdata/testkit/scrypt
vendored
Normal file
Binary file not shown.
BIN
testdata/testkit/scrypt_and_x25519
vendored
Normal file
BIN
testdata/testkit/scrypt_and_x25519
vendored
Normal file
Binary file not shown.
BIN
testdata/testkit/scrypt_no_match
vendored
Normal file
BIN
testdata/testkit/scrypt_no_match
vendored
Normal file
Binary file not shown.
BIN
testdata/testkit/scrypt_work_factor_23
vendored
Normal file
BIN
testdata/testkit/scrypt_work_factor_23
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
testdata/testkit/valid_characters
vendored
Normal file
BIN
testdata/testkit/valid_characters
vendored
Normal file
Binary file not shown.
BIN
testdata/testkit/x25519_multiple_recipients
vendored
Normal file
BIN
testdata/testkit/x25519_multiple_recipients
vendored
Normal file
Binary file not shown.
|
|
@ -27,19 +27,20 @@ func TestMain(m *testing.M) {
|
|||
flag.Parse()
|
||||
if *genFlag {
|
||||
log.SetFlags(0)
|
||||
tests, err := filepath.Glob("testdata/*.test")
|
||||
tests, err := filepath.Glob("testdata/testkit/*")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, test := range tests {
|
||||
os.Remove(test)
|
||||
}
|
||||
generators, err := filepath.Glob("testdata/*.go")
|
||||
generators, err := filepath.Glob("tests/*.go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, generator := range generators {
|
||||
vector := strings.TrimSuffix(generator, ".go") + ".test"
|
||||
vector := strings.TrimSuffix(generator, ".go")
|
||||
vector = "testdata/testkit/" + strings.TrimPrefix(vector, "tests/")
|
||||
log.Printf("%s -> %s\n", generator, vector)
|
||||
out, err := exec.Command("go", "run", generator).Output()
|
||||
if err != nil {
|
||||
|
|
@ -56,7 +57,7 @@ func TestMain(m *testing.M) {
|
|||
}
|
||||
|
||||
func TestVectors(t *testing.T) {
|
||||
tests, err := filepath.Glob("testdata/*.test")
|
||||
tests, err := filepath.Glob("testdata/testkit/*")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
@ -65,8 +66,7 @@ func TestVectors(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
name := strings.TrimPrefix(test, "testdata/")
|
||||
name = strings.TrimSuffix(name, ".test")
|
||||
name := strings.TrimPrefix(test, "testdata/testkit/")
|
||||
t.Run(name, func(t *testing.T) {
|
||||
testVector(t, contents)
|
||||
})
|
||||
|
|
@ -114,6 +114,12 @@ func testVector(t *testing.T, test []byte) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
identities = append(identities, i)
|
||||
case "passphrase":
|
||||
i, err := age.NewScryptIdentity(value)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
identities = append(identities, i)
|
||||
case "file key":
|
||||
// Ignored.
|
||||
case "comment":
|
||||
|
|
|
|||
21
tests/long_file_key_scrypt.go
Normal file
21
tests/long_file_key_scrypt.go
Normal file
|
|
@ -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([]byte("A LONGER YELLOW SUBMARINE"))
|
||||
f.VersionLine("v1")
|
||||
f.Scrypt("password", 10)
|
||||
f.HMAC()
|
||||
f.Payload("age")
|
||||
f.ExpectHeaderFailure()
|
||||
f.Comment("the file key must be checked to be 16 bytes before decrypting it")
|
||||
f.Generate()
|
||||
}
|
||||
18
tests/scrypt.go
Normal file
18
tests/scrypt.go
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// 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.Scrypt("password", 10)
|
||||
f.HMAC()
|
||||
f.Payload("age")
|
||||
f.Generate()
|
||||
}
|
||||
21
tests/scrypt_and_x25519.go
Normal file
21
tests/scrypt_and_x25519.go
Normal file
|
|
@ -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.X25519NoRecordIdentity(testkit.TestX25519Identity)
|
||||
f.Scrypt("password", 10)
|
||||
f.HMAC()
|
||||
f.Payload("age")
|
||||
f.ExpectHeaderFailure()
|
||||
f.Comment("scrypt stanzas must be alone in the header")
|
||||
f.Generate()
|
||||
}
|
||||
20
tests/scrypt_no_match.go
Normal file
20
tests/scrypt_no_match.go
Normal file
|
|
@ -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.ScryptRecordPassphrase("wrong")
|
||||
f.ScryptNoRecordPassphrase("password", 10)
|
||||
f.HMAC()
|
||||
f.Payload("age")
|
||||
f.ExpectHeaderFailure()
|
||||
f.Generate()
|
||||
}
|
||||
23
tests/scrypt_work_factor_23.go
Normal file
23
tests/scrypt_work_factor_23.go
Normal file
|
|
@ -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")
|
||||
// Hardcoded because it would be too slow to regenerate every time.
|
||||
// f.Scrypt("password", 23)
|
||||
f.ArgsLine("scrypt", "rF0/NwblUHHTpgQgRpe5CQ", "23")
|
||||
f.TextLine("qW9eVsT0NVb/Vswtw8kPIxUnaYmm9Px1dYmq2+4+qZA")
|
||||
f.HMAC()
|
||||
f.Payload("age")
|
||||
f.ExpectHeaderFailure()
|
||||
f.Comment("work factor is very high, would take a long time to compute")
|
||||
f.Generate()
|
||||
}
|
||||
21
tests/valid_characters.go
Normal file
21
tests/valid_characters.go
Normal file
|
|
@ -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.ArgsLine("!\"#$%&'", "()*+,-./", "01234567", "89:;<=>?", "@ABCDEFG",
|
||||
"HIJKLMNO", "PQRSTUVW", "XYZ[\\]^_", "`abcdefg", "hijklmno", "pqrstuvw", "xyz{|}~")
|
||||
f.Body([]byte(""))
|
||||
f.X25519(testkit.TestX25519Recipient)
|
||||
f.HMAC()
|
||||
f.Payload("age")
|
||||
f.Generate()
|
||||
}
|
||||
19
tests/x25519_multiple_recipients.go
Normal file
19
tests/x25519_multiple_recipients.go
Normal file
|
|
@ -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.X25519NoRecordIdentity(f.Rand(32))
|
||||
f.X25519(testkit.TestX25519Recipient)
|
||||
f.HMAC()
|
||||
f.Payload("age")
|
||||
f.Generate()
|
||||
}
|
||||
Loading…
Reference in a new issue