scyther/gui/mpa.py
ccremers 79e664c181 - Improved stuff for mpa attacks.
- Some todo addition.
2006-08-11 17:25:34 +00:00

142 lines
4.1 KiB
Python
Executable File

#!/usr/bin/python
"""
Example script to show how to perform large-scale tests using the
Scyther Python API (contained in the Scyther subdirectory)
In this example, multi-protocol attack analysis is performed on a small
test set.
"""
import Scyther.Scyther as Scyther
def MyScyther(protocollist,filter=None):
"""
Evaluate the composition of the protocols in protocollist.
If there is a filter, i.e. "ns3,I1" then only this specific claim
will be evaluated.
"""
s = Scyther.Scyther()
s.options = "--match=2"
if filter:
s.options += " --filter=%s" % (filter)
for protocol in protocollist:
s.addFile(protocol)
s.verify()
return s
def getCorrectIsolatedClaims(protocolset):
"""
Given a set of protocols, determine the correct claims when run in
isolation.
Returns a tuple, consisting of
- a list of compiling protocols
- a list of tuples (protocol,claimid) wich denote correct claims
"""
correctclaims = []
goodprotocols = []
for protocol in protocolset:
# verify protocol in isolation
s = MyScyther([protocol])
# investigate the results
if not s.errors:
goodprotocols.append(protocol)
for claim in s.claims:
if claim.okay:
correctclaims.append((protocol,claim.id))
return (goodprotocols,correctclaims)
def verifyMPAlist(mpalist,claimid):
"""
Verify the existence of an attack in this context
If an attack is found, we return False, otherwise True. This is
needed for the iteration later.
"""
# This should be a more restricted verification
s = MyScyther(mpalist,claimid)
claim = s.getClaim(claimid)
if claim:
if not claim.okay:
# This is an MPA attack!
print "I've found a multi-protocol attack on claim %s in the context %s." % (claimid,str(mpalist))
return False
else:
return True
def constructMPAlist(protocolset,claimid,mpalist,length,start,callback):
"""
Append a list of parallel protocols, without duplicates,
such that the added part is lexicographically ordered (from
index 'start' in the protocol list)
For each possible list, the function callback is called. If the
callback returns true, iteration proceeds (returning true in the
end), otherwise it aborts and returns false.
"""
if len(mpalist) < length:
# list is not long enough yet
for pn in range(start,len(protocolset)):
p = protocolset[pn]
if p not in mpalist:
if not constructMPAlist(protocolset,claimid,mpalist + [p],length,pn+1,callback):
return False
return True
else:
# list is long enough: callback
return callback(mpalist,claimid)
def findMPA(protocolset,protocol,claimid,maxcount=3):
"""
The protocol claim is assumed to be correct. When does it break?
"""
# First we examine 2-protocol attacks, and then increase the
# number of parallel protocols if we don't find any attacks on the
# claim.
count = 2
if len(protocolset) < maxcount:
# we cannot have more protocols in parallel than there are
# protocols.
maxcount = len(protocolset)
# the actual incremental search loop
while count <= maxcount:
constructMPAlist(protocolset,claimid,[protocol],count,0,verifyMPAlist)
count += 1
return None
def findAllMPA(protocolset,maxcount=3):
"""
Given a set of protocols, find multi-protocol attacks
"""
# Find all correct claims in each protocol
(protocolset,correct) = getCorrectIsolatedClaims(protocolset)
# For all these claims...
for (protocol,claimid) in correct:
# Try to find multi-protocol attacks
findMPA(protocolset,protocol,claimid,maxcount=3)
if __name__ == '__main__':
"""
Simple test case with a few protocols
"""
list = ['me.spdl','ns3.spdl','nsl3.spdl']
print "Performing multi-protocol analysis for the following protocols:", list
print
findAllMPA(list)
print
print "Analysis complete."