mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-08-20 04:13:07 +02:00
Validate encryption using externally-generated data
This commit is contained in:
parent
17f5521ea4
commit
0af66fd6c8
9 changed files with 178 additions and 0 deletions
|
@ -317,4 +317,96 @@ mod test {
|
|||
let cryptor = Cryptor::new(client_key, &secret).unwrap();
|
||||
assert!(cryptor.unseal(sealed).is_err());
|
||||
}
|
||||
|
||||
mod externally_valid {
|
||||
// validate data generated by generate-test-data.py. The intent is to
|
||||
// validate that this format matches the specification by implementing
|
||||
// the specification in a second language
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
/// The values in generate-test-data.py
|
||||
fn defaults() -> (Uuid, Uuid, Vec<u8>) {
|
||||
(
|
||||
Uuid::parse_str("b0517957-f912-4d49-8330-f612e73030c4").unwrap(),
|
||||
Uuid::parse_str("0666d464-418a-4a08-ad53-6f15c78270cd").unwrap(),
|
||||
b"b4a4e6b7b811eda1dc1a2693ded".to_vec(),
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn good() {
|
||||
let (version_id, client_key, encryption_secret) = defaults();
|
||||
let sealed = Sealed {
|
||||
version_id,
|
||||
payload: include_bytes!("test-good.data").to_vec(),
|
||||
};
|
||||
|
||||
let cryptor = Cryptor::new(client_key, &Secret(encryption_secret)).unwrap();
|
||||
let unsealed = cryptor.unseal(sealed).unwrap();
|
||||
|
||||
assert_eq!(unsealed.payload, b"SUCCESS");
|
||||
assert_eq!(unsealed.version_id, version_id);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_version_id() {
|
||||
let (version_id, client_key, encryption_secret) = defaults();
|
||||
let sealed = Sealed {
|
||||
version_id,
|
||||
payload: include_bytes!("test-bad-version-id.data").to_vec(),
|
||||
};
|
||||
|
||||
let cryptor = Cryptor::new(client_key, &Secret(encryption_secret)).unwrap();
|
||||
assert!(cryptor.unseal(sealed).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_client_key() {
|
||||
let (version_id, client_key, encryption_secret) = defaults();
|
||||
let sealed = Sealed {
|
||||
version_id,
|
||||
payload: include_bytes!("test-bad-client-key.data").to_vec(),
|
||||
};
|
||||
|
||||
let cryptor = Cryptor::new(client_key, &Secret(encryption_secret)).unwrap();
|
||||
assert!(cryptor.unseal(sealed).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_secret() {
|
||||
let (version_id, client_key, encryption_secret) = defaults();
|
||||
let sealed = Sealed {
|
||||
version_id,
|
||||
payload: include_bytes!("test-bad-secret.data").to_vec(),
|
||||
};
|
||||
|
||||
let cryptor = Cryptor::new(client_key, &Secret(encryption_secret)).unwrap();
|
||||
assert!(cryptor.unseal(sealed).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_version() {
|
||||
let (version_id, client_key, encryption_secret) = defaults();
|
||||
let sealed = Sealed {
|
||||
version_id,
|
||||
payload: include_bytes!("test-bad-version.data").to_vec(),
|
||||
};
|
||||
|
||||
let cryptor = Cryptor::new(client_key, &Secret(encryption_secret)).unwrap();
|
||||
assert!(cryptor.unseal(sealed).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bad_app_id() {
|
||||
let (version_id, client_key, encryption_secret) = defaults();
|
||||
let sealed = Sealed {
|
||||
version_id,
|
||||
payload: include_bytes!("test-bad-app-id.data").to_vec(),
|
||||
};
|
||||
|
||||
let cryptor = Cryptor::new(client_key, &Secret(encryption_secret)).unwrap();
|
||||
assert!(cryptor.unseal(sealed).is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
77
taskchampion/src/server/generate-test-data.py
Normal file
77
taskchampion/src/server/generate-test-data.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
# This file generates test-encrypted.data. To run it:
|
||||
# - pip install cryptography pbkdf2
|
||||
# - python taskchampion/src/server/generate-test-data.py taskchampion/src/server/
|
||||
|
||||
import os
|
||||
import hashlib
|
||||
import pbkdf2
|
||||
import secrets
|
||||
import sys
|
||||
import uuid
|
||||
|
||||
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
|
||||
|
||||
# these values match values used in the rust tests
|
||||
client_key = "0666d464-418a-4a08-ad53-6f15c78270cd"
|
||||
encryption_secret = b"b4a4e6b7b811eda1dc1a2693ded"
|
||||
version_id = "b0517957-f912-4d49-8330-f612e73030c4"
|
||||
|
||||
def gen(
|
||||
version_id=version_id, client_key=client_key, encryption_secret=encryption_secret,
|
||||
app_id=1, version=1):
|
||||
# first, generate the encryption key
|
||||
salt = hashlib.sha256(uuid.UUID(client_key).bytes).digest()
|
||||
key = pbkdf2.PBKDF2(
|
||||
encryption_secret,
|
||||
salt,
|
||||
digestmodule=hashlib.sha256,
|
||||
iterations=100000,
|
||||
).read(32)
|
||||
|
||||
# create a nonce
|
||||
nonce = secrets.token_bytes(12)
|
||||
|
||||
assert len(b"\x01") == 1
|
||||
# create the AAD
|
||||
aad = b''.join([
|
||||
bytes([app_id]),
|
||||
uuid.UUID(version_id).bytes,
|
||||
])
|
||||
|
||||
# encrypt using AEAD
|
||||
chacha = ChaCha20Poly1305(key)
|
||||
ciphertext = chacha.encrypt(nonce, b"SUCCESS", aad)
|
||||
|
||||
# create the envelope
|
||||
envelope = b''.join([
|
||||
bytes([version]),
|
||||
nonce,
|
||||
ciphertext,
|
||||
])
|
||||
|
||||
return envelope
|
||||
|
||||
|
||||
def main():
|
||||
dir = sys.argv[1]
|
||||
|
||||
with open(os.path.join(dir, 'test-good.data'), "wb") as f:
|
||||
f.write(gen())
|
||||
|
||||
with open(os.path.join(dir, 'test-bad-version-id.data'), "wb") as f:
|
||||
f.write(gen(version_id=uuid.uuid4().hex))
|
||||
|
||||
with open(os.path.join(dir, 'test-bad-client-key.data'), "wb") as f:
|
||||
f.write(gen(client_key=uuid.uuid4().hex))
|
||||
|
||||
with open(os.path.join(dir, 'test-bad-secret.data'), "wb") as f:
|
||||
f.write(gen(encryption_secret=b"xxxxxxxxxxxxxxxxxxxxx"))
|
||||
|
||||
with open(os.path.join(dir, 'test-bad-version.data'), "wb") as f:
|
||||
f.write(gen(version=99))
|
||||
|
||||
with open(os.path.join(dir, 'test-bad-app-id.data'), "wb") as f:
|
||||
f.write(gen(app_id=99))
|
||||
|
||||
|
||||
main()
|
2
taskchampion/src/server/test-bad-app-id.data
Normal file
2
taskchampion/src/server/test-bad-app-id.data
Normal file
|
@ -0,0 +1,2 @@
|
|||
#§$á
|
||||
†—Õ^~B>n)j›i†¯1—î9™|µœÓ~
|
1
taskchampion/src/server/test-bad-client-key.data
Normal file
1
taskchampion/src/server/test-bad-client-key.data
Normal file
|
@ -0,0 +1 @@
|
|||
<01>ΝA4φ―Γθ
t;Δτ
υηp¦Ο¦x^Αύreό…<CF8C>JΤ¤<CEA4>
|
1
taskchampion/src/server/test-bad-secret.data
Normal file
1
taskchampion/src/server/test-bad-secret.data
Normal file
|
@ -0,0 +1 @@
|
|||
/}ådE°‡dIcÁXéè-‡!V°Û%è4îáòd]³ÃÇ}
|
1
taskchampion/src/server/test-bad-version-id.data
Normal file
1
taskchampion/src/server/test-bad-version-id.data
Normal file
|
@ -0,0 +1 @@
|
|||
lΰζδa|‚ο@Ο<>S_‚¬…γzέV9£q¦Ρ…‘)+¦…
|
1
taskchampion/src/server/test-bad-version.data
Normal file
1
taskchampion/src/server/test-bad-version.data
Normal file
|
@ -0,0 +1 @@
|
|||
c╙╤TH╗Гp>╔╚Ф╨╕m4О╧к~в1╣0P░IЖ╢W╒
|
2
taskchampion/src/server/test-bad-version_id.data
Normal file
2
taskchampion/src/server/test-bad-version_id.data
Normal file
|
@ -0,0 +1,2 @@
|
|||
B∙
|
||||
Ат-в3%╕jё,*ъ╨7Й╘√QьKЗO╕°FPZщ
|
1
taskchampion/src/server/test-good.data
Normal file
1
taskchampion/src/server/test-good.data
Normal file
|
@ -0,0 +1 @@
|
|||
pÑ¿µÒŸ½V²ûÝäToë"}cT·äY7Æ ˆÀ@ÙdLTý`Ò
|
Loading…
Add table
Add a link
Reference in a new issue