diff options
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/rpki/resource_set.py | 74 | ||||
-rw-r--r-- | scripts/test-pow.py | 74 |
2 files changed, 102 insertions, 46 deletions
diff --git a/scripts/rpki/resource_set.py b/scripts/rpki/resource_set.py index a0e71566..2309bafe 100644 --- a/scripts/rpki/resource_set.py +++ b/scripts/rpki/resource_set.py @@ -15,8 +15,9 @@ class resource_range(object): def __cmp__(self, other): c = self.min - other.min - if c == 0: - c = self.max - other.max + if c == 0: c = self.max - other.max + if c < 0: c = -1 + if c > 0: c = 1 return c class resource_range_as(resource_range): @@ -67,13 +68,15 @@ class resource_set(list): You probably don't want to use this type directly. """ - def __init__(self, s): - if s: - self.extend(map(self.parse, s.split(","))) - self.sort() - if __debug__: - for i in range(0, len(self) - 1): - assert self[i].max < self[i + 1].min, 'Resource overlap "%s"' % (s) + def __init__(self, ini=None): + if isinstance(ini, str) and len(ini): + self.extend(map(self.parse_str, ini.split(","))) + if isinstance(ini, tuple): + self.parse_tuple(ini) + self.sort() + if __debug__: + for i in range(0, len(self) - 1): + assert self[i].max < self[i + 1].min, 'Resource overlap "%s"' % (s) def __str__(self): return ",".join(map(str, self)) @@ -83,20 +86,31 @@ class resource_set_as(resource_set): ASN resource set. """ - def parse(self, x): + def parse_str(self, x): r = re.match("^([0-9]+)-([0-9]+)$", x) if r: return resource_range_as(long(r.group(1)), long(r.group(2))) else: return resource_range_as(long(x), long(x)) + def parse_tuple(self, x): + assert x[0] == "asIdsOrRanges" # Not handling "inherit" yet + for aor in x[1]: + if aor[0] == "range": + min = aor[1][0] + max = aor[1][1] + else: + min = aor[1] + max = min + self.append(resource_range_as(min, max)) + class resource_set_ip(resource_set): """ (Generic) IP address resource set. You probably don't want to use this type directly. """ - def parse(self, x): + def parse_str(self, x): r = re.match("^([0-9:.a-fA-F]+)-([0-9:.a-fA-F]+)$", x) if r: return self.range_type(self.addr_type(r.group(1)), self.addr_type(r.group(2))) @@ -110,6 +124,20 @@ class resource_set_ip(resource_set): return self.range_type(min, max) raise RuntimeError, 'Bad IP resource "%s"' % (x) + def parse_tuple(self, x): + assert x[0] == "addressesOrRanges" # Not handling "inherit" yet + for aor in x[1]: + if aor[0] == "addressRange": + min = bs2long(aor[1][0]) << (self.addr_type.bits - len(aor[1][0])) + max = bs2long(aor[1][1]) << (self.addr_type.bits - len(aor[1][1])) + mask = (1L << (self.addr_type.bits - len(aor[1][1]))) - 1 + else: + min = bs2long(aor[1]) << (self.addr_type.bits - len(aor[1])) + mask = (1L << (self.addr_type.bits - len(aor[1]))) - 1 + assert (min & mask) == 0, "Resource not in canonical form: %s" % (str(x)) + max = min | mask + self.append(self.range_type(self.addr_type(min), self.addr_type(max))) + class resource_set_ipv4(resource_set_ip): """ IPv4 address resource set. @@ -125,3 +153,27 @@ class resource_set_ipv6(resource_set_ip): addr_type = ipaddrs.v6addr range_type = resource_range_ipv6 + +def bs2long(bs): + """ + Convert a bitstring (tuple representation) into a long. + """ + + return reduce(lambda x, y: (x << 1) | y, bs, 0L) + +def parse_extensions(exts): + """ + Parse RFC 3779 extensions out of the tuple encoding returned by + POW.pkix.cert.getExtensions(). + """ + + res = resource_set() + for x in exts: + if x[0] == (1, 3, 6, 1, 5, 5, 7, 1, 8): # sbgp-autonomousSysNum + assert x[2][1] is None, "RDI not implemented: %s" % (str(x)) + res.extend(resource_set_as(x[2][0])) + elif x[0] == (1, 3, 6, 1, 5, 5, 7, 1, 7): # sbgp-ipAddrBlock + for fam in x[2]: + res.extend(({ "\x00\x01" : resource_set_ipv4, + "\x00\x02" : resource_set_ipv6 }[fam[0]])(fam[1])) + return res diff --git a/scripts/test-pow.py b/scripts/test-pow.py index 542cf715..d2b2d9fa 100644 --- a/scripts/test-pow.py +++ b/scripts/test-pow.py @@ -1,6 +1,6 @@ # $Id$ -import POW, POW.pkix, base64, rpki.ipaddrs +import POW, POW.pkix, base64, rpki.ipaddrs, rpki.resource_set Alice_EE = """ MIIDGDCCAgCgAwIBAgIJANkdU8+R7K3dMA0GCSqGSIb3DQEBBQUAMCQxIjAgBgNV @@ -78,37 +78,41 @@ for der in (alice, apnic): print " OID: ", oid, POW.pkix.oid2obj(oid) print " Val:", val print - val = [x[2] for x in cert.getExtensions() if x[0] == POW.pkix.obj2oid("sbgp-ipAddrBlock")] - if val: - for fam in val[0]: - afi = (ord(fam[0][0]) << 8) + ord(fam[0][1]) - addrlen = { 1 : 32, 2 : 128 }[afi] - addrtype = { 1 : rpki.ipaddrs.v4addr, 2 : rpki.ipaddrs.v6addr }[afi] - if len(fam[0]) > 2: - safi = ord(fam[0][2]) - else: - safi = None - if fam[1][0] == 'inherit': - vals = None - else: - vals = [] - for aor in fam[1][1]: - def b2l(x, y): return (x << 1) | y - if aor[0] == 'addressRange': - min = reduce(b2l, aor[1][0], 0L) - max = reduce(b2l, aor[1][1], 0L) - min <<= addrlen - len(aor[1][0]) - max <<= addrlen - len(aor[1][1]) - max |= (1 << (addrlen - len(aor[1][1]))) - 1 - min = addrtype(min) - max = addrtype(max) - txt = "%s-%s" % (min, max) - vals.append((txt, min, max)) - else: - prefix = reduce(b2l, aor[1], 0L) - prefix <<= addrlen - len(aor[1]) - prefixlen = len(aor[1]) - prefix = addrtype(prefix) - txt = "%s/%d" % (prefix, prefixlen) - vals.append((txt, prefix, prefixlen)) - print afi, safi, vals + if False: + val = [x[2] for x in cert.getExtensions() if x[0] == POW.pkix.obj2oid("sbgp-ipAddrBlock")] + if val: + for fam in val[0]: + afi = (ord(fam[0][0]) << 8) + ord(fam[0][1]) + addrlen = { 1 : 32, 2 : 128 }[afi] + addrtype = { 1 : rpki.ipaddrs.v4addr, 2 : rpki.ipaddrs.v6addr }[afi] + if len(fam[0]) > 2: + safi = ord(fam[0][2]) + else: + safi = None + if fam[1][0] == 'inherit': + vals = None + else: + vals = [] + for aor in fam[1][1]: + def b2l(x, y): return (x << 1) | y + if aor[0] == 'addressRange': + min = reduce(b2l, aor[1][0], 0L) + max = reduce(b2l, aor[1][1], 0L) + min <<= addrlen - len(aor[1][0]) + max <<= addrlen - len(aor[1][1]) + max |= (1 << (addrlen - len(aor[1][1]))) - 1 + min = addrtype(min) + max = addrtype(max) + txt = "%s-%s" % (min, max) + vals.append((txt, min, max)) + else: + prefix = reduce(b2l, aor[1], 0L) + prefix <<= addrlen - len(aor[1]) + prefixlen = len(aor[1]) + prefix = addrtype(prefix) + txt = "%s/%d" % (prefix, prefixlen) + vals.append((txt, prefix, prefixlen)) + print afi, safi, vals + else: + rs = rpki.resource_set.parse_extensions(cert.getExtensions()) + print rs |