cmd/age: expand test vectors suite

This commit is contained in:
Filippo Valsorda
2021-02-02 13:51:35 +01:00
parent 5d96bfa9a9
commit 19e87b75b7
24 changed files with 146 additions and 26 deletions

View File

@@ -264,7 +264,6 @@ func encryptPass(pass string, in io.Reader, out io.Writer, armor bool) {
}
func encrypt(recipients []age.Recipient, in io.Reader, out io.Writer, withArmor bool) {
ageEncrypt := age.Encrypt
if withArmor {
a := armor.NewWriter(out)
defer func() {
@@ -274,7 +273,7 @@ func encrypt(recipients []age.Recipient, in io.Reader, out io.Writer, withArmor
}()
out = a
}
w, err := ageEncrypt(out, recipients...)
w, err := age.Encrypt(out, recipients...)
if err != nil {
logFatalf("Error: %v", err)
}

View File

@@ -7,6 +7,7 @@
package main
import (
"errors"
"io/ioutil"
"os"
"path/filepath"
@@ -17,24 +18,40 @@ import (
)
func TestVectors(t *testing.T) {
defaultIDs, err := parseIdentitiesFile("testdata/default_key.txt")
if err != nil {
t.Fatal(err)
}
password, err := ioutil.ReadFile("testdata/default_password.txt")
if err == nil {
p := strings.TrimSpace(string(password))
i, err := age.NewScryptIdentity(p)
if err != nil {
t.Fatal(err)
}
defaultIDs = append(defaultIDs, i)
}
files, _ := filepath.Glob("testdata/*.age")
for _, f := range files {
_, name := filepath.Split(f)
name = strings.TrimSuffix(name, ".age")
expectFailure := strings.HasPrefix(name, "fail_")
expectNoMatch := strings.HasPrefix(name, "nomatch_")
t.Run(name, func(t *testing.T) {
var identities []age.Identity
identities := defaultIDs
ids, err := parseIdentitiesFile("testdata/" + name + "_key.txt")
if err == nil {
identities = append(identities, ids...)
identities = ids
}
password, err := ioutil.ReadFile("testdata/" + name + "_password.txt")
if err == nil {
i, err := age.NewScryptIdentity(string(password))
p := strings.TrimSpace(string(password))
i, err := age.NewScryptIdentity(p)
if err != nil {
t.Fatal(err)
}
identities = append(identities, i)
identities = []age.Identity{i}
}
in, err := os.Open("testdata/" + name + ".age")
@@ -46,6 +63,16 @@ func TestVectors(t *testing.T) {
if err == nil {
t.Fatal("expected Decrypt failure")
}
if e := (&age.NoIdentityMatchError{}); errors.As(err, &e) {
t.Errorf("got ErrIncorrectIdentity, expected more specific error")
}
} else if expectNoMatch {
if err == nil {
t.Fatal("expected Decrypt failure")
}
if e := (&age.NoIdentityMatchError{}); !errors.As(err, &e) {
t.Errorf("expected ErrIncorrectIdentity, got %v", err)
}
} else {
if err != nil {
t.Fatal(err)

6
cmd/age/testdata/default_key.txt vendored Normal file
View File

@@ -0,0 +1,6 @@
# created: 2021-02-02T13:09:43+01:00
# public key: age1xmwwc06ly3ee5rytxm9mflaz2u56jjj36s0mypdrwsvlul66mv4q47ryef
AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
# TODO: regenerate empty_recipient_body.age
AGE-SECRET-KEY-1TRYTV7PQS5XPUYSTAQZCD7DQCWC7Q77YJD7UVFJRMW4J82Q6930QS70MRX

1
cmd/age/testdata/default_password.txt vendored Normal file
View File

@@ -0,0 +1 @@
now-major-idea-author-clerk-bronze-all-soul-uncover-glad

5
cmd/age/testdata/ed25519.age vendored Normal file
View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> ssh-ed25519 cp09gQ Kf5JDNFFDUaOvups2MDfP47PlrpJthnmz0WNMfGj+C8
hQ76lMAsG2pjR8GHTU+XU0giePyzE3prVmAw5MbMxSk
--- CjO8qf3vd83otqHSflgWP5gQoe2Roo9tf/zgWEy9t0U
<14>ٮ<EFBFBD>%J<><1D>nj<b<>:<3A>%UgZ4#<05><><EFBFBD>N<EFBFBD>

7
cmd/age/testdata/ed25519_key.txt vendored Normal file
View File

@@ -0,0 +1,7 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACB/aTuac9tiWRGrKEtixFlryYlGCPTOpdbmXN9RRmDF2gAAAKDgV/GC4Ffx
ggAAAAtzc2gtZWQyNTUxOQAAACB/aTuac9tiWRGrKEtixFlryYlGCPTOpdbmXN9RRmDF2g
AAAECvFoQXQzXgJLQ+Gz4PfEcfyZwC2gUjOiWTD//mTPyD8H9pO5pz22JZEasoS2LEWWvJ
iUYI9M6l1uZc31FGYMXaAAAAG2ZpbGlwcG9AQmlzdHJvbWF0aC1NMS5sb2NhbAEC
-----END OPENSSH PRIVATE KEY-----

1
cmd/age/testdata/ed25519_key.txt.pub vendored Normal file
View File

@@ -0,0 +1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH9pO5pz22JZEasoS2LEWWvJiUYI9M6l1uZc31FGYMXa

View File

@@ -1 +0,0 @@
AGE-SECRET-KEY-1TRYTV7PQS5XPUYSTAQZCD7DQCWC7Q77YJD7UVFJRMW4J82Q6930QS70MRX

View File

@@ -1,6 +1,7 @@
age-encryption.org/v1
-> scrypt qeKad+OgIkBbr/ndSa7J3Q 1
C2tmV7/uZjRafxqaQd1JhYkM2KxuHHBy3/d2dJNEZEh8rZCqYfvE/eJUXqiqZsZa
6kWgG1qa6Q6sXPz0vIIpYHGf4gzxG9oTVonMke2kHC4
--- FQeacPQobvFBd0tuIQnQDd/NEDR4G4MfylkXiq9ZqZ0
<EFBFBD><EFBFBD><EFBFBD>p<EFBFBD><EFBFBD>t<18>t<EFBFBD><74><EFBFBD>3q<33><71>)<29><><EFBFBD><EFBFBD>v<EFBFBD><0F>Q<EFBFBD>o̚K<CC9A><4B>7<EFBFBD><17>)<29>%a
-> scrypt z8U9dYMQuK1fFdvtpQYLEQ 10
5SVjw1bbFCZLdI1FR7RqfTd3yWo4KS1ikOjvz60Bpqhrv0W6o6/2oszxZEm1gEUC
--- YXxSwONGPBbV7woMuEFTYuA03qTYUF1k0Y8j/NDEu1o
<EFBFBD><EFBFBD>
<EFBFBD>!<21><> i<7F><69>.f<><66><EFBFBD>{<7B>d<EFBFBD>IE]<5D> <20>n<EFBFBD>$<24>!b<>2

View File

@@ -1 +0,0 @@
dog-old-little-breeze-novel-razor-battle-replace-lake-horse

View File

@@ -1,6 +1,6 @@
age-encryption.org/v1
-> X25519 /Gt0E6JT7yuYHlwsGW5LbpEEJawOc+QMeMAS+hoOIgw
XU/4Zkz4MksDhge0kosiMTJF8tHnOP0ZSi+6aaMqLMS1PlMIs95nKz3H7JGesTwA
tsxuQrj+TuoGouNB1O0VshA9vsHGurn0Dtw5e7bkw9Q
--- jQNSF6blozj2QFYJ/2iqy0wUcPuz/8vCS7RgKH8wjNI
<14>9<EFBFBD><39><EFBFBD>y<EFBFBD>_<><5F>R\<03><>m\<5C><><EFBFBD>Uv6Qȶ<51><15>mK<6D>a<EFBFBD><61><EFBFBD>v<EFBFBD><76><EFBFBD>2
-> X25519 UkSgrxSETNpdkHY8EwiiRivqks2QJLUzsNsVjUTDcmw
8yB9TqsBo4Ypchw07AtemV5TW4sGwyPDPMIfRg8Ve8rbDXt4tCwnnKcMq2K6aoqx
--- vUhLU0U9Dc8YhbKy4SxKuq0iSqqjBWGnHfZG+9+O4v4
<EFBFBD><EFBFBD><EFBFBD>g<EFBFBD><EFBFBD><EFBFBD><EFBFBD>h<15>W<EFBFBD><57><EFBFBD>SI<53><49>f<EFBFBD>ƆD<C686><44>Q;<3B>Rh<><68>w

View File

@@ -1,3 +0,0 @@
# created: 2020-09-19T18:42:11+02:00
# public key: age1uc8zlurjyjpenrslc2thyl28u7ylz6x8c2g9yphvjha6xm8ppf3slq0l25
AGE-SECRET-KEY-1D8JAD8SXNFVQEFHAUNNAX4QCE3K5CUKMT7YYHNGTUSSP97YGWL4STV89UH

Binary file not shown.

View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> scrypt 1Q6WlGmsRulbN7bmUw8A1Q 23
GP2lnzFuk1dgEkcMPmK6KkmuOm5gIWJzLeuwGcRsvAY
--- vXvOsVbDbMc0x5Js1FS6k1ViOJ3H2ZdSUZo9bfvbzmU
=<3D><><EFBFBD>œ<EFBFBD><C29C>v><3E>vhKM<4B>'<27><><EFBFBD><EFBFBD><1D>Ne<14>S<EFBFBD><53><EFBFBD>\(_<>

5
cmd/age/testdata/nomatch_scrypt.age vendored Normal file
View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> scrypt X6oOTRAjCR1xid0PlnNMFA 10
hszKAHhyFVpUgt9niYpdYXVhhN+r+oiCLPZukDdQZBQ
--- 7BRJPVjbIC1JntvHrA13PQrnsa3lkwhnNF/Pbo4BPs4
4|)<29>S|ۋҿD<D2BF><44><EFBFBD>}<01><1C>2<EFBFBD>%<25>e<EFBFBD>=<3D><>6<EFBFBD><36><EFBFBD>Z

5
cmd/age/testdata/nomatch_x25519.age vendored Normal file
View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> X25519 Rp86RQ3LgUJpQy4X2RMUhURlBP28tCaLQ2ssysJfRhg
83YXad/lj3/wFM4n7vlGIiBSgfhG8lfiP5U7ajjK3HM
--- O2+UpzetsP2+7BPyGQ4C6VMTY6zwp5TiNpVcFy4qdyM
 话g<0E>u(<28><>Q:|c<11><><EFBFBD>LɈ<><C988>=f<><66>6b<36>}!

13
cmd/age/testdata/rsa.age vendored Normal file
View File

@@ -0,0 +1,13 @@
age-encryption.org/v1
-> ssh-rsa jw/33g
xv12FD3f2d7snIcuXBznTOWAlgCovW1Dqttk9uljWKy3GtRZ3t8jEWkQEOYkOk0M
EHA6sHWfdPLdlS3DjQYjcaLFvwh3+XVKYNzP9MhLg8P8xvxVkn4aiCKd8ivEisp0
bKGi4g/TJz/JKUg1SGbqDg966to0P5AWrkwAD7OMykQToqo56flrKXgFPleSWVWu
umiwbxFYs7ltbRYvjzdpIj9l30lXkzrADP3RrrvTu/qT0IN3PMi3bOqm0kKz0vkd
p4NpxKmfqQXavU+YZiyQL637V3cbKIAEJ1qmpkd2Tr2oUhfD5IgAoT1nC5tCIzRb
DkPwM4k2FJgVX0KKvW3i0+k5tve4XWg82vq2OCj8+sl3A8cLX3g5zhh53DovUBVm
qDU2HWf++3q9kUy1al0sFb2es4ih+tK74nPjBJZtX0n+4lMngz557+XuYnzZ2OkW
QEq3b7Trdidw7Ak9S14tdXhj8oy7J1jdHsQ8/wehAc1v8MuBb1O7LxVIFxzBEBCA
--- QdCY4BN4vwp5jb+AFsyoHkvKW+EneZsZjPURH2tCF18
<EFBFBD>)KVMARsS<73>M<EFBFBD><06><><EFBFBD>؂K<D882>><3E><1A>ի`<60> ~T0n<30>

38
cmd/age/testdata/rsa_key.txt vendored Normal file
View File

@@ -0,0 +1,38 @@
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

1
cmd/age/testdata/rsa_key.txt.pub vendored Normal file
View File

@@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDULTit0KUehbigbhsQaZo2oXLgMug8nTfnzDhcf5cEzdOJZyF6i5aRQbqbXIOYeTS3Shpp/iE6d60qi93JBBfveAZqr76tK7lVK8fstvAAGgbo9L9Ru5nhWX0HTlZUOodUT2E0rgAeoFzfvcZTaajzPmikrESmuaJLcdJ3crbCIyovkTxc85KbSn+Ky5grntdVR7GXve0HuIgwuSXGNyO0/hEQyhCEco4w53LZDXl3Dlxgb52u0QCsFFiQJmZ3RWnbCz2mNjM9Vo5KRt2pJ4u74lVsfXCvAqG4GsDd5WXCNRNaQ7gUdw1eSnvvcy3hxeEqLNN9tHaFCjEuyPfXfTVd3t0SlXreyoNbV75rYvZ2F6aLxyMMys+5bpnX0tu2LSq4Bvj5xIsBokjgEd3UXyj1eErsQdUJ0gghAMpXOjVbISwPAGMvUsH2unGbjvfaxnK57S7KAXOYznjhBf5ayIleAc+4LVD/KeMtGbpkyXXozC9jwH9cZBbGU4BtElAbzh8=

View File

@@ -0,0 +1,5 @@
age-encryption.org/v1
-> scrypt qEa/WztCd2KJ4mKwNf1Yrw 10
TQZ4GpAaH4aR4oSDWZTgeRT4wRby4jwmtB02dElWmVQ
--- kOiEP6uoMyK9GKIsV77o4oaPuEr2Q0vdcu+1RKC3lLU
h<EFBFBD>o<EFBFBD>P<EFBFBD>V

View File

@@ -9,7 +9,7 @@ package age
import (
"crypto/hmac"
"crypto/sha256"
"fmt"
"errors"
"io"
"filippo.io/age/internal/format"
@@ -32,6 +32,8 @@ func aeadEncrypt(key, plaintext []byte) ([]byte, error) {
return aead.Seal(nil, nonce, plaintext, nil), nil
}
var errIncorrectCiphertextSize = errors.New("encrypted value has unexpected length")
// aeadDecrypt decrypts a message of an expected fixed size.
//
// The message size is limited to mitigate multi-key attacks, where a ciphertext
@@ -43,7 +45,7 @@ func aeadDecrypt(key []byte, size int, ciphertext []byte) ([]byte, error) {
return nil, err
}
if len(ciphertext) != size+aead.Overhead() {
return nil, fmt.Errorf("encrypted message has unexpected length")
return nil, errIncorrectCiphertextSize
}
nonce := make([]byte, chacha20poly1305.NonceSize)
return aead.Open(nil, nonce, ciphertext, nil)

View File

@@ -164,7 +164,9 @@ func (i *ScryptIdentity) unwrap(block *Stanza) ([]byte, error) {
// only one bit. This also does not bypass any scrypt work, although that work
// can be precomputed in an online oracle scenario.
fileKey, err := aeadDecrypt(k, fileKeySize, block.Body)
if err != nil {
if err == errIncorrectCiphertextSize {
return nil, errors.New("invalid scrypt recipient block: incorrect file key size")
} else if err != nil {
return nil, ErrIncorrectIdentity
}
return fileKey, nil

2
testdata/keys.txt vendored
View File

@@ -1,2 +1,2 @@
# Test key for ExampleParseX25519Identities.
# Test key for ExampleParseIdentities.
AGE-SECRET-KEY-184JMZMVQH3E6U0PSL869004Y3U2NYV7R30EU99CSEDNPH02YUVFSZW44VU

View File

@@ -188,7 +188,9 @@ func (i *X25519Identity) unwrap(block *Stanza) ([]byte, error) {
}
fileKey, err := aeadDecrypt(wrappingKey, fileKeySize, block.Body)
if err != nil {
if err == errIncorrectCiphertextSize {
return nil, errors.New("invalid X25519 recipient block: incorrect file key size")
} else if err != nil {
return nil, ErrIncorrectIdentity
}
return fileKey, nil