1 / 36

Constraint Logic Programming for Verifying Security Protocols a gzipped tutorial

Constraint Logic Programming for Verifying Security Protocols a gzipped tutorial. Sandro Etalle Ricardo Corin University of Twente. Why another talk. Addressing the (old) problem of verifying security protocols. Against e.g., man-in-the-middle attacks.

lanza
Télécharger la présentation

Constraint Logic Programming for Verifying Security Protocols a gzipped tutorial

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Constraint Logic Programming for Verifying Security Protocolsa gzipped tutorial Sandro Etalle Ricardo Corin University of Twente

  2. Why another talk • Addressing the (old) problem of verifying security protocols. • Against e.g., man-in-the-middle attacks. • use constraint solvingto model efficiently the intruder. • It works lazily. • We have a very fast tool. • Based on: Millen & Shmatikov.

  3. Index • How to specify a protocol. • The intruder model. • The constraint-solving algorithm. • Conclusions.

  4. Preliminaries: Prolog’s notation • variables: begin with uppercase or with _ • Complex terms can be built using predicate (function) symbols: • pk(b) • Nb*pk(B) is the same as *(Nb,pk(B)): * is an infix-operator. • send(Nb*pk(B)) • Lists: [t1,…,tn]

  5. The same, old example: Needham-Schroeder A->B : [A,Na]*pk(B) B->A : [Na,Nb]*pk(A) A->B : [Nb]*pk(B) • Notation • msg*k: asymmetric encryption • Na, Nb: nonces • A, B: Agents (Alice and Bob) • pk(A): public key of A • First, we want to model it.

  6. Roles • Here we have 2 roles: initiator & responder. • A role is specified as a sequence of events: • send(t) • recv(t) • t is a term (a message) • initiator(A,B,Na,Nb) = [ send([A,Na]*pk(B)), recv([Na,Nb]*pk(A)), send(Nb*pk(B))].

  7. The Responder • Just exchange “send” and “recv” responder(A,B,Na,Nb) = [ recv([A,Na]*pk(B)), send([Na,Nb]*pk(A)), recv(Nb*pk(B))]). • Notice the variables. • names & nonces are not fixed • roles are parametric • We still need to: • fix some parameters • determine how many agents are there, what they know etc. • We do this by specifying a session.

  8. Session (scenario) • session: set of (instantiated) roles • {initiator(a,B,na,Nb), responder(A,b,Na,nb)} • Notice the variables • Freshness nonces = new terms (ground terms that don’t occur elsewhere ). • We can add more agents etc. • next: network model & constraint-solving

  9. The network model • Dolev-Yao • Constraint Solving: to see what the intruder can generate. Scenario Agent Role Role Role Role Role send(t) recv(t) Network/Intruder

  10. Constraints • A constraint is a pair: m:T • m is a message term, T is a list of terms. • is called simple if m is a variable. • intuitive meaning: “m is generable from T” • The Constraint Store (CS) is a set of constraints.

  11. the Verification Algorithm • S: scenario • CS: constraint store (initially empty) • K: intruder’s knowledge (K0 is provided by the user) • A step of the verification algorithm: • choose the first event e from a non-empty role of S • case 1) e = send(t) • K := K U {t}; proceed • case 2) e = recv(t) • CS := CS U {t:K } • if CS can be solved to CS’ with solution , • S := S; K:= K; CS := CS’; • proceed • otherwise, stop

  12. What is solvable? • CS can be solved to CS’ with solution  if we can apply reduction rules to CS until we obtain CS’, where • CS’ is empty or • CS’ contains only simple constraints. • Two kind of rules • synthesis. • analysis.

  13. Synthesis reduction rules • :rewriting step yielding substitution  •  is the empty substitution • Local rules: • Pair: [m1,m2]:T  m1:T , m2:T • hash: h(m):T  m:T • penc: m*pk(a) :T  m:T, a:T • senc: m+k :T  m:T, k:T • sig: m*sk(e)  m:T • Global rule • unify: {m:T,C1,…,Cn} {C1,…,Cn} • provided that =mgu(m,t), tT

  14. Analysis reduction rules (2) • Affect the other side of the constraint. • Local rules • split: m:{[t1,t2]} T  m:{t1,t2} T • pdec: m:{t*pk(e)}  :T  m:{t}  T • sdec: m:T{t+k}  k:T{t-k}, m:T{t,k} • forget about this one • used only for constructed symmetric keys • Global rule • ksub: {m:{t*k}T, C1, …, Cn}  {m:({t*k}T), C1, …, Cn} • where =mgu(k,pk(e)), kpk(e)

  15. the Result • CS0 1 CS1 2… n CSn • each time a constraint in CS is selected and a rule is applied to it • The rewriting stops when • CSn is empty or made of simple constraints • CS is solved • the composition of the substitutions is the result of the simplification:  := 1 2 … n • a constraint is selected that cannot be simplified • CS is unsolvable • there is no result (failure)

  16. Properties • Is it Confluent? • No. • Different reduction sequences are possible: • in total: 4 sources of nondeterminism • choice of the event in the algorithm. • choice of the constraint to be reduced. • choice of the rule to be applied. • in the the analysis rules and in the unify rule there is the additional choice of the term in T to which the rule is applied. • Full backtracking to preserve completeness. • Local analysis reduction rules preserve confluence, and this can be used for optimization.

  17. Finding Secrecy flaws • What is a secrecy flaw? • To check if na remains secret, one just has to add to the scenario the singleton role [recv(na)] • na remains secret <=> the intruder cannot output it! • in practice we define a special role • secrecy(X) = [recv(X)].

  18. Finding Authentication Flaws • More complex than checking secrecy. • What is an authentication flaw? • Various definitions. • Basically: an input event recv(t) without corresponding preceding output event send(t). • Can be checked by e.g., running the responder strand without an initiator role. • Presently: a pain in the neck. • We are working on it.

  19. An Example for Laziness • send(na*pk(b)), recv(X), recv(X*pk(b)) • two constraints are generated: • X : {a,b,e} • X*pk(b) : {a,b,e,na*pk(b)} • by rule (unify): • na : {a,b,e} • not solvable! • we did not know this after the first step.

  20. Bibliography Remark • The system is strongly based on that of Millen and Shmatikov [MS01] • Various differences: • Constraints checked “on the fly” • Consider run also with unfinished roles (very important in practice) • Few other minor things.

  21. Part 3 Example

  22. Example • Consider the scenario for NS with OA: {initiator(a,B,na,Nb),responder(A,b,Na,nb), {recv(nb)}} • A possible interleaving: recv([A,B]), send([a,na]*pk(B)) recv([A,Na]*pk(b)), send([Na,nb]*pk(A)) recv( [na,Nb]*pk(a)), send([Nb]*pk(B)), recv(nb) ... • We omit the events after recv(nb)

  23. Example (cont) recv([A,B]), send([a,na]*pk(B)) recv([A,Na]*pk(b)), send([Na,nb]*pk(A)) recv( [na,Nb]*pk(a)), send([Nb]*pk(B)), recv(nb) ... • find out what happens to the CS • T = {a,b,e} (intruder knowledge) • CS = {}

  24. The run (1) recv([A,B]), send([a,na]*pk(B)), recv([A,Na]*pk(b)), send([Na,nb]*pk(A)), recv( [na,Nb]*pk(a)), send([Nb]*pk(B)), recv(nb) ... • Before the step • T = {a,b,e} • CS = {} • After (T does not change) • CS = {[A,B]:{a,b,e}} • By applying pair • CS’ = {A:{a,b,e}, B:{a,b,e}}

  25. The run (2) send([a,na]*pk(B)), recv([A,Na]*pk(b)), send([Na,nb]*pk(A)), recv( [na,Nb]*pk(a)), send([Nb]*pk(B)), recv(nb) ... • Before the step • T = T0 = {a,b,e} • CS = {A:{a,b,e}, B:{a,b,e}} • After • T = T1 = {a,b,e,[a,na]*pk(B)}

  26. The run (3) recv([A,Na]*pk(b)), send([Na,nb]*pk(A)), recv( [na,Nb]*pk(a)), send([Nb]*pk(B)), recv(nb) ... • Before the step • T = T1 = {a,b,e,[a,na]*pk(B)} (T0 = {a,b,e}) • CS = {A:{a,b,e}, B:{a,b,e}} • After • CS = {A:T0, B:T0, [A,Na]*pk(b):T1} • by penc + pair • CS = {A:T0, B:T0, A:T1, Na:T1, b:T1} • by nif • CS = {A:T0, B:T0, A:T1, Na:T1}

  27. The run (4) send([Na,nb]*pk(A)), recv( [na,Nb]*pk(a)), send([Nb]*pk(B)), recv(nb) ... • Before the step • T = T1 = {a,b,e,[a,na]*pk(B)} • T0 = {a,b,e} • CS = {A:T0, B:T0, A:T1, Na:T1} • After • T = T2 = T1 U {[Na,nb]*pk(A) • T1 = {a,b,e,[a,na]*pk(B)} • T0 = {a,b,e} • CS is unchanged

  28. The run (5) recv( [na,Nb]*pk(a)), send([Nb]*pk(B)), recv(nb) ... • Before • T = T2 = T1 U {[Na,nb]*pk(A) • T1 = {a,b,e,[a,na]*pk(B)} • T0 = {a,b,e} • CS = {A:T0, B:T0, A:T1, Na:T1} • After • CS= {A:T0, B:T0, A:T1, Na:T1,[na,Nb]*pk(a):T2} • unify! (Na-> na , Nb -> nb and A-> a) • The unification has to be applied to the rest…

  29. The run (5.1) recv([na,b]*pk(a)), send([nb]*pk(B)), recv(nb) ... • After the unification: • T = T2 = T1 U {[na,nb]*pk(a) • T1 = {a,b,e,[a,na]*pk(B)} • T0 = {a,b,e} • CS= {a:T0, B:T0, a:T1, na:T1} • Unify • CS= {B:{a,b,e}, na: {a,b,e,[a,na]*pk(B)}}

  30. The run (5.2) recv([na,b]*pk(a)), send([nb]*pk(e)), recv(nb) ... • After the unification: • CS= {B:{a,b,e}, na: {a,b,e,[a,na]*pk(B)}} • ksub (unification B -> e) + split • CS= {e:{a,b,e}, na: {a,b,e,a,na}} • unify twice, with empty answer • CS = {} • T = {[na,nb]*pk(a), a,b,e,[a,na]*pk(e)}

  31. The run (5.3) send([nb]*pk(e)), recv(nb) ... • Before • CS = {} • T = {[na,nb]*pk(a), a,b,e,[a,na]*pk(e)} • After • CS = {} • T = {[na,nb]*pk(a), a,b,e,[a,na]*pk(e), [nb]*pk(e)}

  32. The run (5.4) recv(nb) ... • Before • CS = {} • T = {[na,nb]*pk(a), a,b,e,[a,na]*pk(e), [nb]*pk(e)} • After • CS = {nb:{[na,nb]*pk(a), a,b,e,[a,na]*pk(e), [nb]*pk(e)}} • pdec • CS = {nb:{[na,nb]*pk(a), a,b,e,[a,na]*pk(e),nb}} • unify (empty substitution) • CS = {} !!!

  33. The solution substitution • We ended up with an empty CS • => the system has a solution • in the process, reduction rules gave us the `solution substitution’  = {A->a,Na->na,Nb->b, B->e}

  34. Part 3 Considerations

  35. Laziness • We stop simplifying a constraint when the lhs is a variable. • This enforces a call-by-need mechanism. • As long as the lhs is a variable the constraint is trivially solvable. • If subsequent unification step instantiate the lhs of a constraint, then I check further if it can be solved. • It would be silly to guess.

  36. An Example for Laziness • Consider two roles: roleA(X,A) = { recv(X), recv(X*pk(A)) } roleB(Na,A) = { send(Na*pk(A)) } • and this scenario:{roleA(X, b), roleB(na,b)} • initial intruder knowledge: {a,b,e} • there’s only one possible order: send(na*pk(b)), recv(X), recv(X*pk(b))

More Related