Repair noise session introduction
This commit is contained in:
parent
bfef60eaa9
commit
cbcd4b9ad9
|
@ -232,33 +232,90 @@ export function boot(ds = Dataspace.global, debug: boolean = false, WebSocketCon
|
||||||
if (!origin0 || !isEmbedded(origin0)) return;
|
if (!origin0 || !isEmbedded(origin0)) return;
|
||||||
const origin = origin0;
|
const origin = origin0;
|
||||||
|
|
||||||
const spec = Q.drop_lit(detailPatValue, N.toNoisePathStepDetail);
|
const spec0 = Q.drop_lit(detailPatValue, N.toNoisePathStepDetail);
|
||||||
if (!spec) return;
|
if (!spec0) return;
|
||||||
|
const spec = spec0;
|
||||||
|
|
||||||
const algorithms = SaltyCrypto.Noise_25519_ChaChaPoly_BLAKE2s;
|
const algorithms = SaltyCrypto.Noise_25519_ChaChaPoly_BLAKE2s;
|
||||||
const protocol =
|
const protocol =
|
||||||
spec.protocol._variant === "present" ? spec.protocol.protocol :
|
spec.protocol._variant === "present" ? spec.protocol.protocol :
|
||||||
spec.protocol._variant === "absent" ? N.fromDefaultProtocol(N.DefaultProtocol()) as string :
|
spec.protocol._variant === "absent" ? N.fromDefaultProtocol(N.DefaultProtocol()) as string :
|
||||||
(() => { throw new Error("Invalid noise protocol name"); })();
|
(() => { throw new Error("Invalid noise protocol name"); })();
|
||||||
const patternName = SaltyCrypto.matchPattern(algorithms, protocol);
|
|
||||||
if (patternName === null) throw new Error("Unsupported protocol " + protocol);
|
const patternName0 = SaltyCrypto.matchPattern(algorithms, protocol);
|
||||||
|
if (patternName0 === null) throw new Error("Unsupported protocol " + protocol);
|
||||||
|
const patternName = patternName0;
|
||||||
|
|
||||||
const preSharedKeys =
|
const preSharedKeys =
|
||||||
spec.preSharedKeys._variant === "present" ? spec.preSharedKeys.preSharedKeys :
|
spec.preSharedKeys._variant === "present" ? spec.preSharedKeys.preSharedKeys :
|
||||||
spec.preSharedKeys._variant === "absent" ? [] :
|
spec.preSharedKeys._variant === "absent" ? [] :
|
||||||
(() => { throw new Error("Invalid pre-shared keys"); })();
|
(() => { throw new Error("Invalid pre-shared keys"); })();
|
||||||
const prologue = underlying(canonicalEncode(spec.service));
|
const prologue = underlying(canonicalEncode(spec.service));
|
||||||
|
|
||||||
let H: SaltyCrypto.Handshake | null = null;
|
react {
|
||||||
let transportState: SaltyCrypto.TransportState | null = null;
|
at origin {
|
||||||
let responderSession: Ref | null = null;
|
assert G.Resolve({
|
||||||
let relay: Relay.Relay | null = null;
|
"step": G.Step({
|
||||||
|
"stepType": N.$noise,
|
||||||
function maybeTransition(s: SaltyCrypto.TransportState | null) {
|
"detail": fromJS(N.ServiceSelector(spec.service)),
|
||||||
if (transportState !== null) {
|
}),
|
||||||
throw new Error("Unexpected double-transition to transport state");
|
"observer": create assertionFacetObserver(e => {
|
||||||
|
const response = G.toResolved(e);
|
||||||
|
if (!response) return;
|
||||||
|
switch (response._variant) {
|
||||||
|
case "accepted":
|
||||||
|
runSession(response.responderSession);
|
||||||
|
break;
|
||||||
|
case "Rejected":
|
||||||
|
stop {
|
||||||
|
at ds {
|
||||||
|
assert G.ResolvedPathStep<Ref>({
|
||||||
|
"origin": origin,
|
||||||
|
"pathStep": G.PathStep({
|
||||||
|
"stepType": N.$noise,
|
||||||
|
"detail": fromJS(N.NoisePathStepDetail(spec)),
|
||||||
|
}),
|
||||||
|
"resolved": response,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
transportState = s;
|
}
|
||||||
if (transportState !== null) {
|
|
||||||
|
function runSession(responderSession: Ref) {
|
||||||
|
const H = new SaltyCrypto.Handshake(
|
||||||
|
algorithms,
|
||||||
|
patternName,
|
||||||
|
'initiator',
|
||||||
|
{
|
||||||
|
prologue,
|
||||||
|
remoteStaticPublicKey: underlying(spec.key),
|
||||||
|
preSharedKeys: preSharedKeys.map(underlying),
|
||||||
|
});
|
||||||
|
let transportState: SaltyCrypto.TransportState | null = null;
|
||||||
|
let relay: Relay.Relay | null = null;
|
||||||
|
|
||||||
|
const { packet, finished } = H.writeMessage(new Uint8Array());
|
||||||
|
at responderSession {
|
||||||
|
assert N.Initiator(create ({ message: handlePacket }));
|
||||||
|
send message Bytes.from(packet);
|
||||||
|
}
|
||||||
|
maybeTransition(finished);
|
||||||
|
|
||||||
|
function maybeTransition(s: SaltyCrypto.TransportState | null) {
|
||||||
|
if (transportState !== null) {
|
||||||
|
throw new Error("Unexpected double-transition to transport state");
|
||||||
|
}
|
||||||
|
transportState = s;
|
||||||
|
if (transportState !== null) {
|
||||||
|
actuallyTransition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function actuallyTransition() {
|
||||||
const noiseSessionFacet = Turn.activeFacet;
|
const noiseSessionFacet = Turn.activeFacet;
|
||||||
const peer = new Relay.Relay({
|
const peer = new Relay.Relay({
|
||||||
debug,
|
debug,
|
||||||
|
@ -283,74 +340,25 @@ export function boot(ds = Dataspace.global, debug: boolean = false, WebSocketCon
|
||||||
"resolved": G.Resolved.accepted(peer),
|
"resolved": G.Resolved.accepted(peer),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
react {
|
function handlePacket(body: Assertion) {
|
||||||
at origin {
|
const p = N.asPacket(body);
|
||||||
assert G.Resolve({
|
if (transportState) {
|
||||||
"step": G.Step({
|
const packet = transportState.recv.decrypt_large(
|
||||||
"stepType": N.$noise,
|
p._variant === 'complete'
|
||||||
"detail": fromJS(N.ServiceSelector(spec.service)),
|
? [underlying(p.value)]
|
||||||
}),
|
: p.value.map(underlying));
|
||||||
"observer": create ({
|
relay!.accept(packet);
|
||||||
... assertionFacetObserver(e => {
|
} else {
|
||||||
const response = G.toResolved(e);
|
if (p._variant !== 'complete') {
|
||||||
if (!response) return;
|
throw new Error("Unexpected fragmentation in handshake");
|
||||||
switch (response._variant) {
|
}
|
||||||
case "accepted":
|
const { message, finished } = H!.readMessage(underlying(p.value));
|
||||||
H = new SaltyCrypto.Handshake(
|
if (message.byteLength !== 0) {
|
||||||
algorithms,
|
throw new Error("Unexpected payload during handshake");
|
||||||
patternName,
|
}
|
||||||
'initiator',
|
maybeTransition(finished);
|
||||||
{
|
}
|
||||||
prologue,
|
|
||||||
remoteStaticPublicKey: underlying(spec.key),
|
|
||||||
preSharedKeys: preSharedKeys.map(underlying),
|
|
||||||
});
|
|
||||||
transportState = null;
|
|
||||||
responderSession = response.responderSession;
|
|
||||||
const { packet, finished } = H.writeMessage(new Uint8Array());
|
|
||||||
at responderSession {
|
|
||||||
send message Bytes.from(packet);
|
|
||||||
}
|
|
||||||
maybeTransition(finished);
|
|
||||||
break;
|
|
||||||
case "Rejected":
|
|
||||||
stop {
|
|
||||||
at ds {
|
|
||||||
assert G.ResolvedPathStep<Ref>({
|
|
||||||
"origin": origin,
|
|
||||||
"pathStep": G.PathStep({
|
|
||||||
"stepType": N.$noise,
|
|
||||||
"detail": fromJS(N.NoisePathStepDetail(spec)),
|
|
||||||
}),
|
|
||||||
"resolved": response,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
message(body: Assertion) {
|
|
||||||
const p = N.asPacket(body);
|
|
||||||
if (transportState) {
|
|
||||||
const packet = transportState.recv.decrypt_large(
|
|
||||||
p._variant === 'complete'
|
|
||||||
? [underlying(p.value)]
|
|
||||||
: p.value.map(underlying));
|
|
||||||
relay!.accept(packet);
|
|
||||||
} else {
|
|
||||||
if (p._variant !== 'complete') {
|
|
||||||
throw new Error("Unexpected fragmentation in handshake");
|
|
||||||
}
|
|
||||||
const { message, finished } = H!.readMessage(underlying(p.value));
|
|
||||||
if (message.byteLength !== 0) {
|
|
||||||
throw new Error("Unexpected payload during handshake");
|
|
||||||
}
|
|
||||||
maybeTransition(finished);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue