import prelude;
public and : Word;
public sending : Word;
public to : Word;
pattern Msg (a:Host,b:Host,c:Host)
= ( text:Private, c ) [!begun (a and b sending text to c)];
pattern SignRequest (b:Host)
= ( c:Host, Private(b,c) );
tag msg (Msg(a,b,c)) : Auth (a:Host,b:Host,c:Host);
tag signRequest (SignRequest(b)) : Auth (a:Host,b:Host);
fun lkupPubKey (p:Any) : PublicKey(p);
fun lkupAuthKey (p:Any) : AuthKey(p);
fun lkupSharedKey (p:Any,q:Any) : SharedKey(p,q);
client Initiator
(a:Host, b:Host, c:Host, sA:SignKey(a), kAB:SharedKey(a,b))
at a is
{
establish Intermediary at b is (socket : Socket);
new (text : Private);
begin!(a and b sending text to c);
output socket is ( a, { signRequest(c, {| msg(text,c) |}sA) }kAB );
}
server Intermediary
(b:Host, sB:SignKey(b))
at b is (socket : Socket)
{
input socket is (a:Un, ctext:Un);
let kAB:SharedKey(a,b) = lkupSharedKey(a,b);
let sA:AuthKey(a) = lkupAuthKey(a);
match ctext is { signRequest(c:Host, signedtext:Private(b,c)) }kAB;
match signedtext is {| msg(text:Private, c) |}sA^-1;
establish Receiver at c is (socketC : Socket);
let pC:PublicKey(c) = lkupPubKey(c);
output socketC is (a, b, {| {| signedtext |}sB |}pC);
}
server Receiver
(c:Host, pC:PrivateKey(c))
at c is (socket : Socket)
{
input socket is (a:Un, b:Un, {| signedtext:Tainted |}pC^-1);
let sB:AuthKey(b) = lkupAuthKey(b);
let sA:AuthKey(a) = lkupAuthKey(a);
match signedtext is {| {| msg(text:Private, c) |}sA^-1 |}sB^-1
[ !begun(a and b sending text to c) ];
end(a and b sending text to c);
}
|