S27: HPKE-Base content wrap + public-key directory; reject xor on send
Some checks are pending
ci / python (push) Waiting to run
ci / go (push) Waiting to run

Routing/error fields stay clear. Content is X25519-HKDF-SHA256-ChaCha20.
This commit is contained in:
George Lambert 2026-09-15 23:43:01 -04:00
parent 9cdc64b185
commit 94919185a9
8 changed files with 364 additions and 13 deletions

View file

@ -7,6 +7,7 @@ import (
"log"
"net/http"
"net/url"
"os"
"strings"
"time"
@ -113,7 +114,8 @@ func (n *Node) handleSend(msg *nats.Msg) {
n.fail(msg, "SM-MISSING-TO", "mailbox", lid)
return
}
if alg != "" && alg != "npe" && alg != "lab-xor" && alg != "plain-lab" {
allowLab := os.Getenv("SM_ALLOW_LAB") == "1"
if alg != "npe" && !(allowLab && (alg == "lab-xor" || alg == "plain-lab")) {
n.fail(msg, "SM-BAD-ALG", "mailbox", lid)
return
}

View file

@ -56,7 +56,7 @@ func TestSMSubjectsAck(t *testing.T) {
t.Fatal(err)
}
defer n.Shutdown()
good := []byte(`{"to":"npe.inbox.x","alg":"lab-xor","ct":"abcd","from_lookup_id":"lid-good"}`)
good := []byte(`{"to":"npe.inbox.x","alg":"npe","ct":"abcd","enc":"00","from_lookup_id":"lid-good"}`)
msg, err := n.nc.Request("verae.sm.send", good, time.Second)
if err != nil {
t.Fatal(err)
@ -89,7 +89,7 @@ func TestSMSendRejectsMissingTo(t *testing.T) {
t.Fatal(err)
}
defer n.Shutdown()
msg, err := n.nc.Request("verae.sm.send", []byte(`{"alg":"lab-xor","ct":"ab"}`), time.Second)
msg, err := n.nc.Request("verae.sm.send", []byte(`{"alg":"npe","ct":"ab"}`), time.Second)
if err != nil {
t.Fatal(err)
}
@ -100,13 +100,30 @@ func TestSMSendRejectsMissingTo(t *testing.T) {
}
}
func TestSMSendRejectsXORContent(t *testing.T) {
n, err := Start("")
if err != nil {
t.Fatal(err)
}
defer n.Shutdown()
msg, err := n.nc.Request("verae.sm.send", []byte(`{"to":"npe.inbox.x","alg":"lab-xor","ct":"ab"}`), time.Second)
if err != nil {
t.Fatal(err)
}
var ack map[string]any
_ = json.Unmarshal(msg.Data, &ack)
if ack["error_code"] != "SM-BAD-ALG" {
t.Fatalf("%s", msg.Data)
}
}
func TestSMSendRejectsEmptyCiphertext(t *testing.T) {
n, err := Start("")
if err != nil {
t.Fatal(err)
}
defer n.Shutdown()
msg, err := n.nc.Request("verae.sm.send", []byte(`{"to":"npe.inbox.x","alg":"lab-xor","ct":""}`), time.Second)
msg, err := n.nc.Request("verae.sm.send", []byte(`{"to":"npe.inbox.x","alg":"npe","ct":""}`), time.Second)
if err != nil {
t.Fatal(err)
}