import prelude;
public contacting : Word;
public generating : Word;
public and : Word;
public for : Word;
type Challenge = SoshChall();
type ResponseToA(
a:Un, b:Host, sessionKey:SharedKey(a,b), sessionNonce:Challenge )
=
SoshResp(
begun(b generating sessionKey and sessionNonce for a),
fresh(sessionNonce:Challenge) );
type ResponseToB(a:Host,b:Host) = SoshResp ( begun(a contacting b) );
pattern Msg1 = Challenge;
pattern Msg2(
a:Un, b:Host, sessionKey:SharedKey(a,b), sessionNonce:Challenge )
=
( ResponseToA(a,b,sessionKey,sessionNonce), Challenge );
pattern Msg3(a:Host,b:Host) = ResponseToB(a,b);
pattern Msg4(a:Host,b:Host) = ( SharedKey(a,b), Challenge );
tag msg1(Msg1) : Auth(a:Host,b:Host);
tag msg2(Msg2(a,b)) : Auth(a:Un,b:Host);
tag msg3(Msg3(a,b)) : Auth(a:Host,b:Host);
tag msg4(Msg4(a,b)) : Auth(a:Un,b:Host);
fun lkupKey(a:Any,b:Any) : SharedKey(a,b);
client Initiator (a:Host, b:Host, kab:SharedKey(a,b)) at a is
{
establish responder at b is (socket:Socket);
begin(a contacting b);
new (nonceA : Challenge);
output socket is (a, { msg1(nonceA) }kab);
input socket is { msg2(nonceA,nonceB:Challenge) }kab;
output socket is { msg3(nonceB) }kab;
input socket is { msg4(
sessionKey:SharedKey(a,b),
sessionNonce:Challenge
) };
end(b generating sessionKey and sessionNonce for a);
}
server Responder (b:Host) at b is (socket:Socket)
{
input socket is (a:Un,ctext:Un);
let kab:SharedKey(a,b) = lkupKey(a,b);
match ctext is { msg1(nonceA:Challenge) }kab;
new (nonceB:Challenge);
new (sessionKey:SharedKey(a,b));
new (sessionNonce:Challenge);
begin(b generating sessionKey and sessionNonce for a);
output socket is { msg2(nonceA,nonceB) }kab;
input socket is { msg3(nonceB) }kab [ begun(a contacting b) ];
out socket is { msg4(sessionKey,sessionNonce) };
end(a contacting b);
}
|