age: Add testkit test files from reference impl

Source: eaa4e03cfe
This commit is contained in:
Jack Grigg 2022-06-18 15:36:13 +00:00
parent 16376f4f2b
commit 26a105a394
50 changed files with 692 additions and 0 deletions

2
.gitattributes vendored Normal file
View file

@ -0,0 +1,2 @@
*.age binary
age/tests/testdata/testkit/* binary

30
Cargo.lock generated
View file

@ -58,6 +58,7 @@ dependencies = [
"curve25519-dalek",
"futures",
"futures-test",
"hex",
"hkdf",
"hmac",
"i18n-embed",
@ -79,6 +80,7 @@ dependencies = [
"sha2 0.10.2",
"sha2 0.9.9",
"subtle",
"test-case",
"web-sys",
"which",
"wsl",
@ -1044,6 +1046,12 @@ dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hkdf"
version = "0.12.3"
@ -2315,6 +2323,28 @@ dependencies = [
"winapi",
]
[[package]]
name = "test-case"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "196e8a70562e252cc51eaaaee3ecddc39803d9b7fd4a772b7c7dae7cdf42a859"
dependencies = [
"test-case-macros",
]
[[package]]
name = "test-case-macros"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dd461f47ade621665c9f4e44b20449341769911c253275dc5cb03726cbb852c"
dependencies = [
"cfg-if",
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "textwrap"
version = "0.11.0"

View file

@ -93,9 +93,11 @@ wsl = { version = "0.1", optional = true }
criterion = "0.3"
criterion-cycles-per-byte = "0.1"
futures-test = "0.3"
hex = "0.4"
i18n-embed = { version = "0.13", features = ["desktop-requester", "fluent-system"] }
quickcheck = "1"
quickcheck_macros = "1"
test-case = "2"
[target.'cfg(unix)'.dev-dependencies]
pprof = { version = "0.8", features = ["criterion", "flamegraph"] }

10
age/tests/testdata/testkit/header_crlf vendored Normal file
View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
comment: lines in the header end with CRLF instead of LF
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- 2KIGb7ye32MWtUuEVWkO3MP6qCDLzOvT9wF06lelBSI
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

9
age/tests/testdata/testkit/hmac_bad vendored Normal file
View file

@ -0,0 +1,9 @@
expect: HMAC failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- 8McE3ix9R34E/vLrQv3yepsHjo/LXhfs22Ab3UyInmg
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- WyJp9F/9FOZh7gJdheq2WIJcwHgYc8NIVh3ddwhrcNg
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- WyJp9F/9FOZh7gJdheq2WIJcwHgYc8NIVh3ddwhrcNgAAA
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
---
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
---WyJp9F/9FOZh7gJdheq2WIJcwHgYc8NIVh3ddwhrcNg
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
comment: the base64 encoding of the HMAC is not canonical
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- WyJp9F/9FOZh7gJdheq2WIJcwHgYc8NIVh3ddwhrcNh
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- WyJp9F/9FOZh7gJdheq2WIJcwHgYc8NIVh3ddwhrcNg
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- WyJp
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

BIN
age/tests/testdata/testkit/scrypt vendored Normal file

Binary file not shown.

View 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Ú¦�âRùÛL

Binary file not shown.

Binary file not shown.

View 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ŠóÎ|

View file

@ -0,0 +1,11 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-- stanza
--- lpxzkyQGe/sA7F1yh4c6KVZV7//jANm5lYefTToioXs
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,12 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza
QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
QUE=
--- OtG7IuNHaf2SHZuowmxg/fhbhtz0/DI5g5OGd7WH7S0
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,11 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza argument
--- bosBxVRBzKF9emyxQ9BERq7+D5JKU+lvbEsL8UHJ/SA
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,12 @@
expect: success
payload: 013f54400c82da08037759ada907a8b864e97de81c088a182062c4b5622fd2ab
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> empty
--- 697zSC9pa/ZLNIaXGtuwcUobmxv+Dpx48Hv0papk5c0
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,14 @@
expect: success
payload: 013f54400c82da08037759ada907a8b864e97de81c088a182062c4b5622fd2ab
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza
QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
--- cb4SqtunSJzXKDGjqeYxuva9Be80QXEDKDn2aKBaCsw
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,11 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza è
--- sTIB/0Fc74rhpjC4RAxoR3E01eVTTnWruaD+c5QWjKI
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,13 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: a body line is longer than 64 columns
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
--- tnRUR2vmmU92czsjnioF5ujgXUetUhzUoQPPGT9wmug
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,11 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: every stanza must end with a short body line, even if empty
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> empty
--- CDgFIIJ1wE4CpW6zG+LVZ6/G/RCNTH6ZUVGp2NbeIkU
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,12 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: every stanza must end with a short body line
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
--- GRjUy1ShNhFoV3cQikdtUZqDeDEZSrbtNXUgDtDbwC8
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,13 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: a short body line ends the stanza
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
--- ct87HSIMoTC4nUsQva+8AeKc2bK2q8b9sPjRhjuf1us
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,11 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
->
--- B0qjnUjVajTa8I4Uia49g1c4DMQQN6u9m9QOSS1HLks
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,12 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza
QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB
QUF
--- nQM2VCzmNLPrUurNWN+SW9wVp/9uTMQ/6CTUM7l8c84
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,11 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> stanza
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
--- MZaFAh8ldzU0F88NJjLx5yd7fnd57XS5COowmgvQtXQ
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,14 @@
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
--- x538z9xJq9XEK1aTTTv80aWDVvVdROvaXn2tpqXPC8g
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: success
payload: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇΑ´3'NhÔòùL­.OÏ>RŠA0Þ«ïC6åU

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1234
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- 38AL8Mr4VwmS6CNbM4bc7u3WwGBDqsMTRHOuYJ9ckqs
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

10
age/tests/testdata/testkit/x25519 vendored Normal file
View file

@ -0,0 +1,10 @@
expect: success
payload: 013f54400c82da08037759ada907a8b864e97de81c088a182062c4b5622fd2ab
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- Vn+54jqiiUCE+WZcEVY3f1sqHjlu/z1LCQ/T7Xm7qI0
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: the ChaCha20Poly1305 authentication tag on the body of the X25519 stanza is wrong
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw0o
--- tG0k9bg4iIuBdMWb13n7FFYDzoBbtsLppNLhbh22aKg
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: the base64 encoding of the share is not canonical
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc 1234
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- hQQySEUXL8pOuIOuw0qXzi66RphDJP9IKMNEChNJIPk
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,14 @@
expect: success
payload: 013f54400c82da08037759ada907a8b864e97de81c088a182062c4b5622fd2ab
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
age-encryption.org/v1
-> grease
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
-> grease
--- 7NLrfbRUZt6qK0pdtARUf59dHwo12ReldjJKjMlbE3I
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
comment: the X25519 share is a low-order point, so the shared secret is the disallowed all-zero value
age-encryption.org/v1
-> X25519 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
W3E/OCRme9TiTY97JoK31Z71arNur77WIIdB90XnN3M
--- Pne3IPMDvBj7wRbPMcNViffpVZAx814tgMxp8AwyMhs
¬]?7åPqÓ¦ F—¹ •Â÷õÛ®è zŒ(rŠóÎ|

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 41204c4f4e4745522059454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
comment: the file key must be checked to be 16 bytes before decrypting it
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
nlObGn0CSA4pxiaG3W6nLlaFFuHmqW+bFC6sJmbsJ9yFesgSok1K0AI
--- C49Jo3+j4I6jWB2tldSs1jVAXbv0mOTAnwdT+5vOiBg
îÏbÇΑ´3'NhÔòùLc÷(­çñ ÐtÿÇ�P²)€x1

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
comment: a trailing zero is missing from the X25519 share
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCcA
hjabGXwSLQ9c3S6Lw2i+S2Tu2fiwQHHslbBN6B41FLE
--- QbEwdWirchS37UUOPh7uVddRiOaWjFwRUpaQ4Q+Z1RE
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
comment: the X25519 share is a low-order point, so the shared secretis the disallowed all-zero value
age-encryption.org/v1
-> X25519 X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEdc
3E0NpFans/m0WLWF7+54ZBdNj3iqQqpraGDFiaRkvBA
--- sXw327YMT1/ULXe+ZyRMbMY0Z2jnWHGgI9j1we6yQ8A
¬]?7åPqÓ¦ F—¹ •Â÷õÛ®è zŒ(rŠóÎ|

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: the first argument in the X25519 stanza is lowercase
age-encryption.org/v1
-> x25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- SwXKO3dXLh9l5QiSgMWgPhCkwstT8oB4jLDv7aBgC+c
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View 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

View file

@ -0,0 +1,9 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-143WN7DCXU4G8R5AXQSSYD9AEPYDNT3HXSLWSPK36CDU6E8M59SSSAGZ3KG
age-encryption.org/v1
-> X25519 ajtqAvDEkVNr2B7zUOtq2mAQXDSBlNrVAuM/dKb5sT4
HUKtz0R2j5Bl2ER7HhAZrURikCFpiIjNa0KjHcjbAGU
--- rrpTlvKEKrK3EqhoOPJeP1KE8O1d2arrRez77mwekRc
ÝßrÐo¼«Wß= 1$–­!Œ×ýo€x»ø�-ØyG^·½^ˆ

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: the base64 encoding of the share is not canonical
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCc
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7V
--- eSjjCjQyp30yHDPwCztKS+1txs+aoCa5ERz8jeEp+9A
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1XMWWC06LY3EE5RYTXM9MFLAZ2U56JJJ36S0MYPDRWSVLUL66MV4QX3S7F6
comment: the base64 encoding of the share is not canonical
age-encryption.org/v1
-> X25519 TEiF0ypqr+bpvcqXNyCVJpL7OuwPdVwPL7KQEbFDOCd
EmECAEcKN+n/Vs9SbWiV+Hu0r+E8R77DdWYyd83nw7U
--- AO6haEGU6BGJ8Tzeqnr2fSLEo31JrWodGtZuCZmijI8
îÏbÇΑ´3'NhÔòùL·L[þ÷¾ªRÈð¼™,ƒ1ûf

View file

@ -0,0 +1,10 @@
expect: header failure
file key: 59454c4c4f57205355424d4152494e45
identity: AGE-SECRET-KEY-1EGTZVFFV20835NWYV6270LXYVK2VKNX2MMDKWYKLMGR48UAWX40Q2P2LM0
comment: a trailing zero is missing from the X25519 share
age-encryption.org/v1
-> X25519 l7o4oTX9X5E3/KODa/7CQ0CrA9fKMWsm9IJjYzSlJg
yUGP5aPob6YJ+vzRfBtDT9D1K/wmyheZE/Xl/mDSKA4
--- Zn1/VRtHpD93HtIXSv1S++POXeKcQF7w1+hpXhMiAbk
¬]?7åPqÓ¦ F—¹ •Â÷õÛ®è zŒ(rŠóÎ|

222
age/tests/testkit.rs Normal file
View file

@ -0,0 +1,222 @@
use std::{
fs::File,
io::{self, BufRead, BufReader, Read},
str::FromStr,
};
use age::{x25519, DecryptError, Decryptor, Identity};
use sha2::{Digest, Sha256};
use test_case::test_case;
#[test_case("header_crlf")]
#[test_case("hmac_bad")]
#[test_case("hmac_extra_space")]
#[test_case("hmac_garbage")]
#[test_case("hmac_missing")]
#[test_case("hmac_no_space")]
#[test_case("hmac_not_canonical")]
#[test_case("hmac_trailing_space")]
#[test_case("hmac_truncated")]
#[test_case("scrypt")]
#[test_case("scrypt_and_x25519")]
#[test_case("scrypt_long_file_key")]
#[test_case("scrypt_no_match")]
#[test_case("scrypt_work_factor_23")]
#[test_case("stanza_bad_start")]
#[test_case("stanza_base64_padding")]
#[test_case("stanza_empty_argument")]
#[test_case("stanza_empty_body")]
#[test_case("stanza_empty_last_line")]
#[test_case("stanza_invalid_character")]
#[test_case("stanza_long_line")]
#[test_case("stanza_missing_body")]
#[test_case("stanza_missing_final_line")]
#[test_case("stanza_multiple_short_lines")]
#[test_case("stanza_no_arguments")]
#[test_case("stanza_not_canonical")]
#[test_case("stanza_spurious_cr")]
#[test_case("stanza_valid_characters")]
#[test_case("stream_empty_payload")]
#[test_case("stream_last_chunk_empty")]
#[test_case("stream_last_chunk_full")]
#[test_case("version_unsupported")]
#[test_case("x25519")]
#[test_case("x25519_bad_tag")]
#[test_case("x25519_extra_argument")]
#[test_case("x25519_grease")]
#[test_case("x25519_identity")]
#[test_case("x25519_long_file_key")]
#[test_case("x25519_long_share")]
#[test_case("x25519_lowercase")]
#[test_case("x25519_low_order")]
#[test_case("x25519_multiple_recipients")]
#[test_case("x25519_no_match")]
#[test_case("x25519_not_canonical_body")]
#[test_case("x25519_not_canonical_share")]
#[test_case("x25519_short_share")]
fn testkit(filename: &str) {
let testfile = TestFile::parse(filename);
let comment = testfile
.comment
.map(|c| format!(" ({})", c))
.unwrap_or_default();
match Decryptor::new(&testfile.age_file[..]).and_then(|d| match d {
Decryptor::Recipients(d) => {
assert_eq!(testfile.passphrases.len(), 0);
let identities: Vec<x25519::Identity> = testfile
.identities
.iter()
.map(|s| s.as_str())
.map(x25519::Identity::from_str)
.collect::<Result<_, _>>()
.unwrap();
d.decrypt(identities.iter().map(|i| i as &dyn Identity))
}
Decryptor::Passphrase(d) => {
assert_eq!(testfile.identities.len(), 0);
match testfile.passphrases.len() {
0 => panic!("Test file is missing passphrase{}", comment),
1 => d.decrypt(
&testfile.passphrases.get(0).cloned().unwrap().into(),
Some(16),
),
n => panic!("Too many passphrases ({}){}", n, comment),
}
}
}) {
Ok(mut r) => {
let mut payload = vec![];
let res = r.read_to_end(&mut payload);
match (res, testfile.expect) {
(Ok(_), Expect::Success { payload_sha256 }) => {
assert_eq!(Sha256::digest(&payload)[..], payload_sha256);
}
// These testfile failures are expected, because we maintains support for
// parsing legacy age stanzas without an explicit short final line.
(Ok(_), Expect::HeaderFailure)
if ["stanza_missing_body", "stanza_missing_final_line"].contains(&filename) => {
}
(Err(e), Expect::PayloadFailure) => {
assert_eq!(e.kind(), io::ErrorKind::InvalidData)
}
(actual, expected) => panic!(
"Expected {:?}, got {}{}",
expected,
if actual.is_ok() {
format!("payload '{}'", String::from_utf8_lossy(&payload))
} else {
format!("{:?}", actual)
},
comment,
),
}
}
Err(e) => match e {
DecryptError::DecryptionFailed
| DecryptError::ExcessiveWork { .. }
| DecryptError::InvalidHeader
| DecryptError::Io(_)
| DecryptError::UnknownFormat => {
assert_eq!(testfile.expect, Expect::HeaderFailure)
}
// Temporary workaround for the testkit test files not distinguishing header
// failures from "no matching keys".
DecryptError::NoMatchingKeys
if ["x25519_bad_tag", "x25519_no_match", "x25519_lowercase"]
.contains(&filename) =>
{
assert_eq!(testfile.expect, Expect::HeaderFailure)
}
DecryptError::InvalidMac => assert_eq!(testfile.expect, Expect::HmacFailure),
DecryptError::KeyDecryptionFailed => todo!(),
#[cfg(feature = "plugin")]
DecryptError::MissingPlugin { .. } => todo!(),
DecryptError::NoMatchingKeys => todo!(),
#[cfg(feature = "plugin")]
DecryptError::Plugin(_) => todo!(),
},
}
}
#[derive(Debug, PartialEq, Eq)]
enum Expect {
Success { payload_sha256: [u8; 32] },
HeaderFailure,
HmacFailure,
PayloadFailure,
}
struct TestFile {
expect: Expect,
identities: Vec<String>,
passphrases: Vec<String>,
comment: Option<String>,
age_file: Vec<u8>,
}
impl TestFile {
fn parse(filename: &str) -> Self {
let file = File::open(format!("./tests/testdata/testkit/{}", filename)).unwrap();
let mut r = BufReader::new(file);
let mut line = String::new();
fn data<'l>(line: &'l str, prefix: &str) -> &'l str {
line.strip_prefix(prefix).unwrap().trim()
}
let expect = {
r.read_line(&mut line).unwrap();
match data(&line, "expect:") {
"success" => {
line.clear();
r.read_line(&mut line).unwrap();
let payload = data(&line, "payload:");
Expect::Success {
payload_sha256: hex::decode(payload).unwrap().try_into().unwrap(),
}
}
"header failure" => Expect::HeaderFailure,
"payload failure" => Expect::PayloadFailure,
"HMAC failure" => Expect::HmacFailure,
e => panic!("Unknown testkit failure '{}'", e),
}
};
let _file_key = {
line.clear();
r.read_line(&mut line).unwrap();
hex::decode(data(&line, "file key: ")).unwrap()
};
let mut identities = vec![];
let mut passphrases = vec![];
let mut comment = None;
loop {
line.clear();
r.read_line(&mut line).unwrap();
if line.trim().is_empty() {
break;
}
let (prefix, data) = line.trim().split_once(": ").unwrap();
match prefix {
"identity" => identities.push(data.to_owned()),
"passphrase" => passphrases.push(data.to_owned()),
"comment" => comment = Some(data.to_owned()),
_ => panic!("Unknown testkit metadata '{}'", prefix),
}
}
let mut age_file = vec![];
r.read_to_end(&mut age_file).unwrap();
Self {
expect,
identities,
passphrases,
comment,
age_file,
}
}
}