mirror of
https://github.com/FiloSottile/age.git
synced 2025-12-23 05:25:14 +00:00
tests: add scrypt tests and move Go files from testdata
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +1,2 @@
|
||||
*.age binary
|
||||
*.test binary
|
||||
testdata/testkit/* binary
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
age-encryption.org/v1
|
||||
-> scrypt z8U9dYMQuK1fFdvtpQYLEQ 10
|
||||
5SVjw1bbFCZLdI1FR7RqfTd3yWo4KS1ikOjvz60Bpqhrv0W6o6/2oszxZEm1gEUC
|
||||
|
||||
--- YXxSwONGPBbV7woMuEFTYuA03qTYUF1k0Y8j/NDEu1o
|
||||
’Ì
|
||||
Å!í‡ i<7F>Þ.f¦æš{ŸdËIE]© ñn”$È!b®2
|
||||
BIN
cmd/age/testdata/fail_scrypt_and_x25519.age
vendored
BIN
cmd/age/testdata/fail_scrypt_and_x25519.age
vendored
Binary file not shown.
@@ -1,5 +0,0 @@
|
||||
age-encryption.org/v1
|
||||
-> scrypt 1Q6WlGmsRulbN7bmUw8A1Q 23
|
||||
GP2lnzFuk1dgEkcMPmK6KkmuOm5gIWJzLeuwGcRsvAY
|
||||
--- vXvOsVbDbMc0x5Js1FS6k1ViOJ3H2ZdSUZo9bfvbzmU
|
||||
=ñÅÙœ£¨v>¹vhKMû'ÕßúÙ½NeçS†Äñ\(_ó
|
||||
@@ -1,5 +0,0 @@
|
||||
age-encryption.org/v1
|
||||
-> scrypt qEa/WztCd2KJ4mKwNf1Yrw 10
|
||||
TQZ4GpAaH4aR4oSDWZTgeRT4wRby4jwmtB02dElWmVQ
|
||||
--- kOiEP6uoMyK9GKIsV77o4oaPuEr2Q0vdcu+1RKC3lLU
|
||||
hŸo²P¤V
w§\5~4ôënE½oÕd>rOš°mÒÛ¨
|
||||
@@ -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.
12
testdata/testkit/scrypt_and_x25519
vendored
Normal file
12
testdata/testkit/scrypt_and_x25519
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
expect: header failure
|
||||
file key: 59454c4c4f57205355424d4152494e45
|
||||
passphrase: password
|
||||
comment: scrypt stanzas must be alone in the header
|
||||
|
||||
age-encryption.org/v1
|
||||
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
|
||||
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
|
||||
-> scrypt 7s9ix86RtDMnTmjU8vkTTA 10
|
||||
0U4Pbxsl9pr9g4nHjPgkvtYkNrGiYJ43x1vbM5X5mhg
|
||||
--- f2AoyFXU2R5Cn7s38vH1pFkuKqzPh3ibwwHc/7y6RRU
|
||||
[æè.½Ó#ÈwÏ…=a×Yök×z©66Ú¦<01>âRùÛL
|
||||
BIN
testdata/testkit/scrypt_no_match
vendored
Normal file
BIN
testdata/testkit/scrypt_no_match
vendored
Normal file
Binary file not shown.
9
testdata/testkit/scrypt_work_factor_23
vendored
Normal file
9
testdata/testkit/scrypt_work_factor_23
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
expect: header failure
|
||||
file key: 59454c4c4f57205355424d4152494e45
|
||||
comment: work factor is very high, would take a long time to compute
|
||||
|
||||
age-encryption.org/v1
|
||||
-> scrypt rF0/NwblUHHTpgQgRpe5CQ 23
|
||||
qW9eVsT0NVb/Vswtw8kPIxUnaYmm9Px1dYmq2+4+qZA
|
||||
--- 38TpQMxQRRNMfmYYpBX6DDrPx4/QY5UmJnhPyVoX/cw
|
||||
¬]?7åPqÓ¦ F—¹ •Â÷õÛ®è
zŒ(rŠóÎ|
|
||||
Binary file not shown.
12
testdata/testkit/valid_characters
vendored
Normal file
12
testdata/testkit/valid_characters
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
expect: success
|
||||
payload: 013f54400c82da08037759ada907a8b864e97de81c088a182062c4b5622fd2ab
|
||||
file key: 59454c4c4f57205355424d4152494e45
|
||||
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
|
||||
|
||||
age-encryption.org/v1
|
||||
-> !"#$%&' ()*+,-./ 01234567 89:;<=>? @ABCDEFG HIJKLMNO PQRSTUVW XYZ[\]^_ `abcdefg hijklmno pqrstuvw xyz{|}~
|
||||
|
||||
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
|
||||
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
|
||||
--- XdSsgCFKtyPBxU0ard+ElUYUfOp6XQtDhzDGFUCLbjo
|
||||
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf
|
||||
12
testdata/testkit/x25519_multiple_recipients
vendored
Normal file
12
testdata/testkit/x25519_multiple_recipients
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
expect: success
|
||||
payload: 013f54400c82da08037759ada907a8b864e97de81c088a182062c4b5622fd2ab
|
||||
file key: 59454c4c4f57205355424d4152494e45
|
||||
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
|
||||
|
||||
age-encryption.org/v1
|
||||
-> X25519 ajtqAvDEkVNr2B7zUOtq2mAQXDSBlNrVAuM/dKb5sT4
|
||||
0evrK/HQXVsQ4YaDe+659l5OQzvAzD2ytLGHQLQiqxg
|
||||
-> X25519 0qC7u6AbLxuwnM8tPFOWVtWZn/ZZe7z7gcsP5kgA0FI
|
||||
T/PZg76MmVt2IaLntrxppzDnzeFDYHsHFcnTnhbRLQ8
|
||||
--- 7W07ef2PhsTAl74pn+9vSj/Xzukwa6SuTqMc16cdBk0
|
||||
ð¸¾5TB9™ €„–Ko•Ãm³^OYØøž<òo-¥B
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user