S27: HPKE-Base content wrap + public-key directory; reject xor on send
Routing/error fields stay clear. Content is X25519-HKDF-SHA256-ChaCha20.
This commit is contained in:
parent
9cdc64b185
commit
94919185a9
8 changed files with 364 additions and 13 deletions
|
|
@ -93,23 +93,65 @@ class HistoryTests(unittest.TestCase):
|
|||
h.append_change(actor="", prev_text="", new_text="x")
|
||||
|
||||
|
||||
class HpkeDirTests(unittest.TestCase):
|
||||
def test_roundtrip_and_router_cannot_see_body(self):
|
||||
from secure_messaging.content import routing_view, unwrap_content, wrap_content
|
||||
from secure_messaging.pubkey_dir import PubKeyDir
|
||||
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
d = PubKeyDir(Path(td))
|
||||
d.create_endpoint("alice")
|
||||
d.create_endpoint("pfc-repl")
|
||||
avail = d.available()
|
||||
self.assertIn("pfc-repl", avail["handles"])
|
||||
self.assertTrue(all("sk" not in json.dumps(k) for k in avail["keys"]))
|
||||
env = wrap_content(
|
||||
to_handle="pfc-repl",
|
||||
sender="alice",
|
||||
body={"bytes_hex": "ab", "note": "secret-phi"},
|
||||
directory=d,
|
||||
)
|
||||
self.assertEqual(env["alg"], "npe")
|
||||
rv = routing_view(env)
|
||||
self.assertNotIn("ct", rv)
|
||||
blob = json.dumps(env)
|
||||
self.assertNotIn("secret-phi", blob)
|
||||
self.assertNotIn("bytes_hex", routing_view(env))
|
||||
pt = unwrap_content(env, handle="pfc-repl", directory=d)
|
||||
self.assertEqual(pt["note"], "secret-phi")
|
||||
with self.assertRaises(Exception):
|
||||
unwrap_content(env, handle="alice", directory=d)
|
||||
|
||||
|
||||
class RouterTests(unittest.TestCase):
|
||||
def test_good_passthrough(self):
|
||||
from secure_messaging.envelope import seal
|
||||
from secure_messaging.router import handle_send
|
||||
|
||||
env = seal(to="npe.inbox.abc", sender="alice", body={"note": "hello"}, mode="lab-xor", lab_key=b"lab")
|
||||
r = handle_send(json.dumps(env.wire()).encode())
|
||||
env = {
|
||||
"to": "npe.inbox.abc",
|
||||
"to_handle": "pfc-repl",
|
||||
"alg": "npe",
|
||||
"ct": "abcd",
|
||||
"enc": "00",
|
||||
"from_lookup_id": "lid-npe",
|
||||
}
|
||||
r = handle_send(json.dumps(env).encode())
|
||||
self.assertTrue(r.accepted)
|
||||
self.assertEqual(r.ack()["lookup_id"], env.from_lookup_id)
|
||||
self.assertEqual(r.ack()["lookup_id"], "lid-npe")
|
||||
self.assertNotIn("ct", r.ack())
|
||||
self.assertEqual(r.events, [])
|
||||
|
||||
def test_xor_rejected_for_content(self):
|
||||
from secure_messaging.router import handle_send
|
||||
|
||||
r = handle_send(b'{"to":"npe.inbox.x","alg":"lab-xor","ct":"ab"}')
|
||||
self.assertEqual(r.error_code, "SM-BAD-ALG")
|
||||
|
||||
def test_missing_to_failure_path(self):
|
||||
from secure_messaging.router import handle_send
|
||||
from secure_messaging.error_bundle import open_sender, open_system
|
||||
|
||||
r = handle_send(b'{"alg":"lab-xor","ct":"ab","from_lookup_id":"lid-x"}')
|
||||
r = handle_send(b'{"alg":"npe","ct":"ab","from_lookup_id":"lid-x"}')
|
||||
self.assertFalse(r.accepted)
|
||||
self.assertEqual(r.error_code, "SM-MISSING-TO")
|
||||
subjects = [e["subject"] for e in r.events]
|
||||
|
|
@ -125,9 +167,9 @@ class RouterTests(unittest.TestCase):
|
|||
def test_empty_ct_and_plaintext_body(self):
|
||||
from secure_messaging.router import handle_send
|
||||
|
||||
r = handle_send(b'{"to":"npe.inbox.x","alg":"lab-xor","ct":""}')
|
||||
r = handle_send(b'{"to":"npe.inbox.x","alg":"npe","ct":""}')
|
||||
self.assertEqual(r.error_code, "SM-EMPTY-CT")
|
||||
r2 = handle_send(b'{"to":"npe.inbox.x","alg":"lab-xor","ct":"ab","body":{"secret":1}}')
|
||||
r2 = handle_send(b'{"to":"npe.inbox.x","alg":"npe","ct":"ab","body":{"secret":1}}')
|
||||
self.assertEqual(r2.error_code, "SM-PLAINTEXT-BODY")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue