import prelude;
public contacting : Word;
public generating : Word;
public and : Word;
public for : Word;
type Challenge = SoshChall();
type ResponseToA(
a:Host, 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:Host,b:Host) = (
sessionKey : SharedKey(a,b),
sessionNonce : Challenge,
nonceA : ResponseToA(a,b,sessionKey,sessionNonce),
nonceB : Challenge
);
pattern Msg3(a:Host,b:Host) = ResponseToB(a,b);
tag msg1(Msg1) : Auth(a:Host,b:Host);
tag msg2(Msg2(a,b)) : Auth(a:Host,b:Host);
tag msg3(Msg3(a,b)) : Auth(a:Host,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(
sessionKey : SharedKey(a,b),
sessionNonce : Challenge,
nonceA,
nonceB : Challenge
) }kab [ begun(b generating sessionKey and sessionNonce for a),
fresh(sessionNonce:Challenge) ];
output socket is { msg3(nonceB) }kab;
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(sessionKey,sessionNonce,nonceA,nonceB) }kab;
input socket is { msg3(nonceB) }kab [ begun(a contacting b) ];
end(a contacting b);
}
|