(*************************************************************
 *                                                           *
 *  Cryptographic protocol verifier                          *
 *                                                           *
 *  Bruno Blanchet, Vincent Cheval, and Marc Sylvestre       *
 *                                                           *
 *  Copyright (C) INRIA, CNRS 2000-2020                      *
 *                                                           *
 *************************************************************)

(*

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details (in file LICENSE).

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

*)
(* Kerberos, modified by Gong et al,
   Version taken from Delaune, Jacquemard, LSV-04-1

   Here there is an obvious attack because message under the passwords
   are tuples that can be recognized. *)

free c.

(* Symmetric cryptography
   One does not know whether decryption succeeds or not
   For use with weak secrets *)

fun enc/2.
fun dec/2.
equation dec(enc(x,y),y) = x.
equation enc(dec(x,y),y) = x.

(* Symmetric cryptography
   One knows whether decryption succeeds or not *)

fun senc/2.
reduc sdec(senc(x,y),y) = x.

(* Public key cryptography *)

fun penc/2.
fun pk/1.
reduc pdec(penc(x,pk(y)),y) = x.

(* From passwd to host names, for host different from A and B *)

data host/1.

param verboseRules = yes.

(* PA = pw(A,S), PB = pw(B, S) *)

free hostA, hostB.
private free PA, PB.
weaksecret PA.
weaksecret PB.

let processA = 
	in(c, hostX);
	new N1;
	new N2;
	new Ca;
	new Ta;
	out(c, penc((hostA, hostX, N1, N2, Ca, enc(Ta, PA)), pkS));
	in(c, (m1, m2));
	let (=N1, m3) = dec(m1, PA) in
	let K = sdec(m3, N2) in
	out(c, m2).

let processB =
	in(c, m4);
	let (hostY, K, Ts) = dec(m4, PB) in
	0.

let pS = 
	 let Ta = dec(m6, pX) in
	 out(c, (enc((N1, senc(K, N2)), pX), enc((hostX, K, Ts), pY))).

let processS = 
	in(c, m5);
	let (hostX, hostY, N1, N2, Ca, m6) = pdec(m5, skS) in
	new K;
	new Ts;
	if hostX = hostA then
	    (let pX = PA in
	    if hostY = hostA then
		(let pY = PA in pS)
	    else if hostY = hostB then
		(let pY = PB in pS)
	    else
		(let host(pY) = hostY in pS))
	else if hostX = hostB then
	    (let pX = PB in
	    if hostY = hostA then
		(let pY = PA in pS)
	    else if hostY = hostB then
		(let pY = PB in pS)
	    else 
		(let host(pY) = hostY in pS))
	else
	    (let host(pX) = hostX in
	    if hostY = hostA then
		(let pY = PA in pS)
	    else if hostY = hostB then
		(let pY = PB in pS)
	    else 
		(let host(pY) = hostY in pS)).

	    
process new skS;
	let pkS = pk(skS) in
	out(c, pkS);
	(!processA) | (!processB) | (!processS)
