Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clean up for ubuntu 14.04 #1

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions NDprotector/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignore
*.pyc

# Keep
!.gitignore
2 changes: 2 additions & 0 deletions NDprotector/Address.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ def __init__(self,interface=None,\
self.__sec = ord(socket.inet_pton(\
socket.AF_INET6,self.__address)[8]) >> 5

print "About to invoke CGAverify in Address.py, check 1" # jochoi: debug
if not CGAverify(self.__address, CGAParams(modifier=modifier, prefix=self.__prefix, \
ccount = self.__collcount, pubkey = self.__pubkey, \
ext = ext)):
Expand Down Expand Up @@ -341,6 +342,7 @@ def do_dad(self):
if packet.haslayer(ICMPv6ND_NS) and address == "::":
address = packet.tgt
# CGA address check
print "About to invoke CGAverify in Address.py, check 2" # jochoi: debug
if not CGAverify(address,packet[CGAParams]):
warn("one packet with an invalid CGA address was received during the DAD procedure\n")
continue
Expand Down
1 change: 1 addition & 0 deletions NDprotector/Config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
load_plugins, \
find_plugins
from NDprotector.Log import warn
from NDprotector.Address import Address


def readconfig(config_file):
Expand Down
38 changes: 36 additions & 2 deletions NDprotector/In.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"""this module processes all the in-going packets by using nfqueue"""
from socket import AF_INET6
import sys
import ctypes # jochoi: import to use if_indextoname
import ctypes.util # jochoi: import to use if_indextoname

libc = ctypes.CDLL(ctypes.util.find_library('c')) # jochoi: needed for if_indextoname

from NDprotector.Log import warn

Expand All @@ -21,6 +25,18 @@
except ImportError:
pass

# jochoi: begin if_indextoname to replace get_if_list function
def if_indextoname(index):
if not isinstance(index, int):
raise TypeError ('provided index should be an int value');
libc.if_indextoname.argtypes = [ctypes.c_uint32, ctypes.c_char_p]
libc.if_indextoname.restype = ctypes.c_char_p
ifname = ctypes.create_string_buffer(32)
ifname = libc.if_indextoname (index, ifname)
if not ifname:
raise RuntimeError ("Invalid index")
return ifname
# jochoi: end if_indextoname

def callback(i, payload):
"""a callback function called on each ingoing packets"""
Expand All @@ -36,21 +52,36 @@ def callback(i, payload):
signalgs = []
verifalgs = []

print "In.py | Interface index is : %s" % payload.get_indev() # jochoi: debug
print "In.py | Interface name is : %s" % if_indextoname(payload.get_indev()) # jochoi: debug

# may be buggy due to the order of get_if_list()
# (in that case, we could use the if_nametoindex() )
interface = get_if_list()[ payload.get_indev() - 1]
# interface = get_if_list()[ payload.get_indev() - 1]
interface = if_indextoname(payload.get_indev()) # jochoi: edit

nc = NeighCache()

if packet.haslayer(ICMPv6ND_NS) \
or packet.haslayer(ICMPv6ND_NA):

# jochoi: begin debug to match arpsec02 printout
if packet.haslayer(ICMPv6ND_NS):
print "In.py | Received NS message"
else:
print "In.py | Received NA message"

print "In.py | Source address: %s" % packet[IPv6].src
print "In.py | Target address: %s" % packet[IPv6].tgt
# jochoi: end debug to match arpsec02

secured = False
try:
address = packet[IPv6].src
# we can receive messages from other node performing a DAD
if address == "::":
address = packet.tgt
print "In.py | About to invoke CGAverify, check 1" # jochoi: debug
cga_prop = CGAverify(address,packet.getlayer(CGAParams))
if not cga_prop:
warn("an ingoing packet has failed CGA verification test\n")
Expand All @@ -60,6 +91,7 @@ def callback(i, payload):
# Timestamp and Nonce verification are performed in the NC
# FIXME: this is not "good", we are subject to a DoS attack here

print "In.py | CGAverify successful" # jochoi: debug
list_of_pubkeys = CGAPKExtListtoPubKeyList(packet[CGAParams].ext)
list_of_pubkeys.insert(0,packet[CGAParams].pubkey)
pubkey = list_of_pubkeys[packet[ICMPv6NDOptUSSig].pos]
Expand All @@ -79,6 +111,7 @@ def callback(i, payload):
warn("an ingoing packet has failed Universal Signature verification\n")
else:
secured = True
print "In.py | Set secured to TRUE" # jochoi: debug

except AttributeError:
warn("An unsecured packet passed\n")
Expand Down Expand Up @@ -200,7 +233,8 @@ def callback(i, payload):
and pubkey.modulusLen <= NDprotector.max_RSA_key_size))\
or\
(NDprotector.ECCsupport and isinstance(pubkey, ECCkey)):


print "About to invoke CGAverify in In.py, check 2" # jochoi: debug
if CGAverify(packet[IPv6].src,packet.getlayer(CGAParams)) and \
packet[ICMPv6NDOptUSSig].keyh == pkhash and \
packet[ICMPv6NDOptUSSig].verify_sig(pubkey):
Expand Down
58 changes: 33 additions & 25 deletions NDprotector/Out.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,33 @@ def callback(i,payload):
or packet.haslayer(ICMPv6ND_NA):

for addr in configured_addresses:
print "Out.py | addr in config %s" % str(addr) # jochoi: debug
print "Out.py | source address %s" % packet[IPv6].src # jochoi: debug
if str(addr) == packet[IPv6].src:
print "Out.py | addr in config matches packet source address" # jochoi: debug
if packet.haslayer(ICMPv6ND_NS):
nonce = "".join([ chr(random.randrange(255)) for i in range(6)])
nc.record_nonce_out(packet[IPv6].src,packet[IPv6].dst,nonce)
else:
nonce = nc.pop_nonce_out(packet[IPv6].src,packet[IPv6].dst)
data = addr.sign(data,nonce=nonce)
warn("signing a NS or NA message\n")
# jochoi: split warning for NS and NA messages
# warn("signing a NS or NA message\n")
if packet.haslayer(ICMPv6ND_NS):
warn("signing a NS message\n")
else:
warn("signing a NA message\n")
payload.set_verdict_modified(nfqueue.NF_ACCEPT,str(data),len(str(data)))
return 0
else:
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecured packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return
else:
warn("dropping one unsecured packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecured packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0 # added return 0
else:
warn("dropping one unsecured packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
elif packet.haslayer(ICMPv6ND_RS):
if NDprotector.is_router == False:
if packet[IPv6].src == "::" :
Expand All @@ -69,15 +77,15 @@ def callback(i,payload):
data = addr.sign(data,nonce=nonce)
payload.set_verdict_modified(nfqueue.NF_ACCEPT, str(data), len(str(data)))
return 0
else:
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RS packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
else:
# a router does not send this kind of messages
payload.set_verdict(nfqueue.NF_DROP)
Expand All @@ -97,15 +105,15 @@ def callback(i,payload):
data = addr.sign(data,nonce=nonce)
payload.set_verdict_modified(nfqueue.NF_ACCEPT,str(data),len(str(data)))
return 0
else:
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
if NDprotector.mixed_mode:
warn("letting go one outgoing unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_ACCEPT)
return 0
else:
warn("dropping one unsecure RA packet\n")
payload.set_verdict(nfqueue.NF_DROP)
return 0
else:
# a host does not send RA messages
payload.set_verdict(nfqueue.NF_DROP)
Expand Down
92 changes: 89 additions & 3 deletions bench/benchCGA.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
from scapy6send.cert import *
from scapy6send.scapy6 import *
from NDprotector.Tool import PubKeyListtoCGAPKExtList
from math import * # cynthiao

sigtypeID = 9
extrakeynum =3

key_gen_time = []
cga_gen_time = []
cga_verif_time = []
sign_gen_time = []
Expand Down Expand Up @@ -73,15 +75,21 @@ def signature_verify(data,k):
return IPv6(data)[ICMPv6NDOptUSSig].verify_sig(k)

def compute_key():
return ECCkey(NID_secp256k1)
return ECCkey(NID_secp256k1) # jochoi: (observation) key is being generated with 256 bits?

def gen_cga(key):
return CGAgen("fe80::", key, 1,
ext = PubKeyListtoCGAPKExtList([ key for i in range(extrakeynum)]) )

def bench_single_ecc():
for i in range(10000):
for i in range(100):
before = time.time()
k = compute_key()
# print "key computed, %s" % k # jochoi: debug / should time tthe key generation
after = time.time()
# print "key generation took: %s" % str(after - before)
key_gen_time.append(after - before)

# computes a CGA address
before = time.time()
(address, params) = gen_cga(k)
Expand Down Expand Up @@ -109,6 +117,16 @@ def bench_single_ecc():

print "loop #%d computed, message size: %d" % (i, len(m))

def computeMdev(data, avg):
'''
Compute the mean deviation given the list and the average value
'''
num = len(data)
sum = 0.0
for d in data:
sum += abs(d - avg)

return(sum/num)

if __name__ == "__main__":

Expand All @@ -121,17 +139,85 @@ def bench_single_ecc():

f = open("%d-key-ecc-duration" % extrakeynum, "w")

f.write("key_gen_time = " + repr(key_gen_time) + "\n")
f.write("cga_gen_time = " + repr(cga_gen_time) + "\n")
f.write("cga_verif_time = " + repr(cga_verif_time) + "\n")
f.write("sign_gen_time = " + repr(sign_gen_time) + "\n")
f.write("sign_verif_time = " + repr(sign_verif_time) + "\n")

f.close()

# cynthiao additions :: added min, max, standard deviation

print "==KEY GENERATION TIMES=="
print "min KEY Generation time: " + str(min(key_gen_time))
print "max KEY generation time: " + str(max(key_gen_time))
print "mean KEY generation time: " + str(sum(key_gen_time) / len(key_gen_time))

def average(key_gen_time): return sum(key_gen_time) * 1.0 / len(key_gen_time)
avg = average(key_gen_time)
variance = map(lambda x: (x - avg)**2, key_gen_time)
average(variance)
stdGenDev = math.sqrt(average(variance))
print "deviation of KEY generation time: " + str(stdGenDev)
mdev = computeMdev(key_gen_time, avg)
print "mean deviation of KEY generation time: " + str(mdev)

print "==CGA GENERATION TIMES=="
print "min CGA generation time: " + str(min(cga_gen_time))
print "max CGA generation time: " + str(max(cga_gen_time))
print "mean CGA generation time: " + str(sum(cga_gen_time) / len(cga_gen_time))

def average(cga_gen_time): return sum(cga_gen_time) * 1.0 / len(cga_gen_time)
avg = average(cga_gen_time)
variance = map(lambda x: (x - avg)**2, cga_gen_time)
average(variance)
stdGenDev = math.sqrt(average(variance))
print "deviation of CGA generation time: " + str(stdGenDev)
mdev = computeMdev(cga_gen_time, avg)
print "mean deviation of KEY generation time: " + str(mdev)

print "==CGA VERIFICATION TIMES=="
print "min CGA verification time: " + str(min(cga_verif_time))
print "max CGA verification time: " + str(max(cga_verif_time))
print "mean CGA verification time: " + str(sum(cga_verif_time) / len(cga_verif_time))

def average(cga_verif_time): return sum(cga_verif_time) * 1.0 / len(cga_verif_time)
avg = average(cga_verif_time)
variance = map(lambda x: (x - avg)**2, cga_verif_time)
average(variance)
stdVerDev = math.sqrt(average(variance))
print "deviation of CGA verification time: " + str(stdVerDev)
mdev = computeMdev(cga_verif_time, avg)
print "mean deviation of KEY generation time: " + str(mdev)

print "==SIGNATURE GENERATION TIMES=="
print "min Signature generation time: " + str(min(sign_gen_time))
print "max Signature generation time: " + str(max(sign_gen_time))
print "mean Signature generation time: " + str(sum(sign_gen_time) / len(sign_gen_time))

def average(sign_gen_time): return sum(sign_gen_time) * 1.0 / len(sign_gen_time)
avg = average(sign_gen_time)
variance = map(lambda x: (x - avg)**2, sign_gen_time)
average(variance)
stdSigDev = math.sqrt(average(variance))
print "deviation of Signature generation time: " + str(stdSigDev)
mdev = computeMdev(sign_gen_time, avg)
print "mean deviation of KEY generation time: " + str(mdev)

print "==SIGNATURE VERIFICATION TIMES=="
print "min Signature verification time: " + str(min(sign_verif_time))
print "max Signature verification time: " + str(max(sign_verif_time))
print "mean Signature verification time: " + str(sum(sign_verif_time) / len(sign_verif_time))

def average(sign_verif_time): return sum(sign_verif_time) * 1.0 / len(sign_verif_time)
avg = average(sign_verif_time)
variance = map(lambda x: (x - avg)**2, sign_verif_time)
average(variance)
stdSigVerDev = math.sqrt(average(variance))
print "deviation of Signature verification time: " + str(stdSigVerDev)
mdev = computeMdev(sign_verif_time, avg)
print "mean deviation of KEY generation time: " + str(mdev)

# prof = cProfile.run("bench_single_ecc()","%d-key-ecc.prof" % extrakeynum)


Expand Down
14 changes: 8 additions & 6 deletions examples/sendd.conf.host
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ NDprotector.mixed_mode = False

# allow NDprotector to flush all the IPv6 addresses on all interfaces
# (so that only CGA are on the interfaces)
NDprotector.flush_interfaces = True
NDprotector.flush_interfaces = False

# /!\ Beware:
# force test on X.509 IP Address extension
Expand All @@ -53,7 +53,7 @@ NDprotector.default_sec_value = 1
# If True, the programm automotaticlally assign addresses on the interfaces
# the program will also clean up and destroy unused addresses
# If set to False, the user must to the address assignement manually
NDprotector.assign_addresses = True
NDprotector.assign_addresses = False


# Default key size for RSA keys
Expand All @@ -70,7 +70,7 @@ NDprotector.max_RSA_key_size = 2048

# Path to the default Public Key used for Stateless Address Autoconfiguration
# if None is provided, generate a new RSA Public Key for new addresses
NDprotector.default_publickey = None
NDprotector.default_publickey = "/root/git/NDprotector/publicKeyB.pem"
# NDprotector.default_publickey = "/etc/NDprotector/mypublickey.pem"

# Path to the trust anchor
Expand Down Expand Up @@ -107,9 +107,11 @@ NDprotector.configured_addresses = \
# ext = None ),

# list of configured prefixes where autoconfiguration will be applied
Address(interface = "eth0",
prefix = "fe80::",
key = "/etc/NDprotector/key.pem"), # if ommited, uses the key pointed by default_publickey
# Address(interface = "eth0",
Address(interface = "eth1",
prefix = "2001:db8:0:100::",
key = "/root/git/NDprotector/privateKeyB.pem",
modifier = 50), # if ommited, uses the key pointed by default_publickey
# or fallback (when default_publickey is None) and the program will compute a new RSA key
# Address(interface = "eth0", # for example this one will build it's own key
# prefix = "2001::",
Expand Down
Loading