From bf789ce9905c72eb26bcdfde9093ccf428ac432f Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Fri, 2 May 2014 04:36:10 +0000 Subject: Switch all rp/utils/ programs to use the Python script versions instead of the nasty old C versions. C code retained in source tree for the moment, but will go away soon. svn path=/trunk/; revision=5825 --- rp/utils/Makefile.in | 41 +--------- rp/utils/find_roa | 160 ++++++++++++++++++++++++++++++++++++++++ rp/utils/find_roa.py | 160 ---------------------------------------- rp/utils/hashdir | 67 +++++++++++++++++ rp/utils/hashdir.py | 67 ----------------- rp/utils/print_roa | 75 +++++++++++++++++++ rp/utils/print_roa.py | 75 ------------------- rp/utils/print_rpki_manifest | 52 +++++++++++++ rp/utils/print_rpki_manifest.py | 52 ------------- rp/utils/scan_roas | 63 ++++++++++++++++ rp/utils/scan_roas.py | 63 ---------------- rp/utils/uri | 71 ++++++++++++++++++ rp/utils/uri.py | 71 ------------------ 13 files changed, 491 insertions(+), 526 deletions(-) create mode 100755 rp/utils/find_roa delete mode 100755 rp/utils/find_roa.py create mode 100755 rp/utils/hashdir delete mode 100755 rp/utils/hashdir.py create mode 100755 rp/utils/print_roa delete mode 100755 rp/utils/print_roa.py create mode 100755 rp/utils/print_rpki_manifest delete mode 100755 rp/utils/print_rpki_manifest.py create mode 100755 rp/utils/scan_roas delete mode 100755 rp/utils/scan_roas.py create mode 100755 rp/utils/uri delete mode 100755 rp/utils/uri.py (limited to 'rp/utils') diff --git a/rp/utils/Makefile.in b/rp/utils/Makefile.in index 1ff248e8..2e8a541f 100644 --- a/rp/utils/Makefile.in +++ b/rp/utils/Makefile.in @@ -1,11 +1,5 @@ # $Id$ -CFLAGS = @CFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ - -INSTALL = @INSTALL@ -m 555 - prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir = @datarootdir@ @@ -21,48 +15,19 @@ libdir = @libdir@ abs_top_srcdir = @abs_top_srcdir@ abs_top_builddir = @abs_top_builddir@ -BINS = find_roa hashdir print_rpki_manifest print_roa scan_roas uri - -all:: ${BINS} - -clean:: - rm -rf ${BINS} *.o *.dSYM - -install:: all - if test -d ${DESTDIR}${bindir} ; then :; else ${INSTALL} -d ${DESTDIR}${bindir}; fi - ${INSTALL} ${BINS} ${DESTDIR}${bindir} - -deinstall uninstall:: - for i in ${BINS}; do rm -f ${DESTDIR}${bindir}/$$i; done +all clean install einstall uninstall:: + @true distclean:: clean rm -f Makefile -find_roa: find_roa.c - ${CC} ${CFLAGS} -o $@ find_roa.c ${LDFLAGS} ${LIBS} - -hashdir: hashdir.c - ${CC} ${CFLAGS} -o $@ hashdir.c ${LDFLAGS} ${LIBS} - -print_roa: print_roa.c - ${CC} ${CFLAGS} -o $@ print_roa.c ${LDFLAGS} ${LIBS} - -print_rpki_manifest: print_rpki_manifest.c - ${CC} ${CFLAGS} -o $@ print_rpki_manifest.c ${LDFLAGS} ${LIBS} - -scan_roas: scan_roas.c - ${CC} ${CFLAGS} -o $@ scan_roas.c ${LDFLAGS} ${LIBS} - -uri: uri.c - ${CC} ${CFLAGS} -o $@ uri.c ${LDFLAGS} ${LIBS} - # Tests RSYNC_AUTH_DIR = ${abs_top_builddir}/rp/rcynic/rcynic-data/authenticated HASHDIR_OUTPUT = hashed-pem-dir TARGET_PREFIXES = 10.3.0.44 10.2.0.6 10.0.0.0/24 -test:: ${BINS} +test:: if test -d ${RSYNC_AUTH_DIR}; \ then \ rm -rf ${HASHDIR_OUTPUT} ; \ diff --git a/rp/utils/find_roa b/rp/utils/find_roa new file mode 100755 index 00000000..1fc0af3d --- /dev/null +++ b/rp/utils/find_roa @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Searches authenticated result tree from an rcynic run for ROAs +matching specified prefixes. +""" + +import os +import sys +import base64 +import argparse +import rpki.POW +import rpki.oids + + +def check_dir(s): + if os.path.isdir(s): + return os.path.abspath(s) + else: + raise argparse.ArgumentTypeError("%r is not a directory" % s) + + +def filename_to_uri(filename): + if not filename.startswith(args.rcynic_dir): + raise ValueError + return "rsync://" + filename[len(args.rcynic_dir):].lstrip("/") + +def uri_to_filename(uri): + if not uri.startswith("rsync://"): + raise ValueError + return os.path.join(args.rcynic_dir, uri[len("rsync://"):]) + + +class Prefix(object): + """ + One prefix parsed from the command line. + """ + + def __init__(self, val): + addr, length = val.split("/") + length, sep, maxlength = length.partition("-") + self.prefix = rpki.POW.IPAddress(addr) + self.length = int(length) + self.maxlength = int(maxlength) if maxlength else self.length + if self.maxlength < self.length or self.length < 0 or self.length > self.prefix.bits: + raise ValueError + if self.prefix & ((1 << (self.prefix.bits - self.length)) - 1) != 0: + raise ValueError + + def matches(self, roa): + return any(self.prefix == prefix and + self.length == length and + (not args.match_maxlength or + self.maxlength == maxlength or + (maxlength is None and + self.length == self.maxlength)) + for prefix, length, maxlength in roa.prefixes) + + +class ROA(rpki.POW.ROA): + """ + Aspects of a ROA that we care about. + """ + + @classmethod + def parse(cls, fn): + assert fn.startswith(args.rcynic_dir) + self = cls.derReadFile(fn) + self.fn = fn + self.extractWithoutVerifying() + v4, v6 = self.getPrefixes() + self.prefixes = (v4 or ()) + (v6 or ()) + return self + + @property + def uri(self): + return filename_to_uri(self.fn) + + @property + def formatted_prefixes(self): + for prefix in self.prefixes: + if prefix[2] is None or prefix[1] == prefix[2]: + yield "%s/%d" % (prefix[0], prefix[1]) + else: + yield "%s/%d-%d" % (prefix[0], prefix[1], prefix[2]) + + def __str__(self): + prefixes = " ".join(self.formatted_prefixes) + plural = "es" if " " in prefixes else "" + if args.show_inception: + return "signingTime %s ASN %s prefix%s %s" % (self.signingTime(), self.getASID(), plural, prefixes) + else: + return "ASN %s prefix%s %s" % (self.getASID(), plural, prefixes) + + def show(self): + print "%s %s" % (self, self.fn if args.show_filenames else self.uri) + + def show_expiration(self): + print self + x = self.certs()[0] + fn = self.fn + uri = self.uri + while uri is not None: + name = fn if args.show_filenames else uri + if args.show_inception: + print "notBefore", x.getNotBefore(), "notAfter", x.getNotAfter(), name + else: + print x.getNotAfter(), name + for uri in x.getAIA() or (): + if uri.startswith("rsync://"): + break + else: + break + fn = uri_to_filename(uri) + if not os.path.exists(fn): + print "***** MISSING ******", uri + break + x = rpki.POW.X509.derReadFile(fn) + print + + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("-a", "--all", action = "store_true", help = "show all ROAs, do no prefix matching at all") +parser.add_argument("-m", "--match-maxlength", action = "store_true", help = "pay attention to maxLength values") +parser.add_argument("-e", "--show-expiration", action = "store_true", help = "show ROA chain expiration dates") +parser.add_argument("-f", "--show-filenames", action = "store_true", help = "show filenames instead of URIs") +parser.add_argument("-i", "--show-inception", action = "store_true", help = "show inception dates") +parser.add_argument("rcynic_dir", type = check_dir, help = "rcynic authenticated output directory") +parser.add_argument("prefixes", type = Prefix, nargs = "*", help = "ROA prefix(es) to match") +args = parser.parse_args() + +# If there's some way to automate this in the parser, I don't know what it is, so just catch it here. +if args.all != (not args.prefixes): + parser.error("--all and prefix list are mutually exclusive") + +for root, dirs, files in os.walk(args.rcynic_dir): + for fn in files: + if fn.endswith(".roa"): + roa = ROA.parse(os.path.join(root, fn)) + if args.all or any(prefix.matches(roa) for prefix in args.prefixes): + if args.show_expiration: + roa.show_expiration() + else: + roa.show() diff --git a/rp/utils/find_roa.py b/rp/utils/find_roa.py deleted file mode 100755 index 1fc0af3d..00000000 --- a/rp/utils/find_roa.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# Copyright (C) 2014 Dragon Research Labs ("DRL") -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -""" -Searches authenticated result tree from an rcynic run for ROAs -matching specified prefixes. -""" - -import os -import sys -import base64 -import argparse -import rpki.POW -import rpki.oids - - -def check_dir(s): - if os.path.isdir(s): - return os.path.abspath(s) - else: - raise argparse.ArgumentTypeError("%r is not a directory" % s) - - -def filename_to_uri(filename): - if not filename.startswith(args.rcynic_dir): - raise ValueError - return "rsync://" + filename[len(args.rcynic_dir):].lstrip("/") - -def uri_to_filename(uri): - if not uri.startswith("rsync://"): - raise ValueError - return os.path.join(args.rcynic_dir, uri[len("rsync://"):]) - - -class Prefix(object): - """ - One prefix parsed from the command line. - """ - - def __init__(self, val): - addr, length = val.split("/") - length, sep, maxlength = length.partition("-") - self.prefix = rpki.POW.IPAddress(addr) - self.length = int(length) - self.maxlength = int(maxlength) if maxlength else self.length - if self.maxlength < self.length or self.length < 0 or self.length > self.prefix.bits: - raise ValueError - if self.prefix & ((1 << (self.prefix.bits - self.length)) - 1) != 0: - raise ValueError - - def matches(self, roa): - return any(self.prefix == prefix and - self.length == length and - (not args.match_maxlength or - self.maxlength == maxlength or - (maxlength is None and - self.length == self.maxlength)) - for prefix, length, maxlength in roa.prefixes) - - -class ROA(rpki.POW.ROA): - """ - Aspects of a ROA that we care about. - """ - - @classmethod - def parse(cls, fn): - assert fn.startswith(args.rcynic_dir) - self = cls.derReadFile(fn) - self.fn = fn - self.extractWithoutVerifying() - v4, v6 = self.getPrefixes() - self.prefixes = (v4 or ()) + (v6 or ()) - return self - - @property - def uri(self): - return filename_to_uri(self.fn) - - @property - def formatted_prefixes(self): - for prefix in self.prefixes: - if prefix[2] is None or prefix[1] == prefix[2]: - yield "%s/%d" % (prefix[0], prefix[1]) - else: - yield "%s/%d-%d" % (prefix[0], prefix[1], prefix[2]) - - def __str__(self): - prefixes = " ".join(self.formatted_prefixes) - plural = "es" if " " in prefixes else "" - if args.show_inception: - return "signingTime %s ASN %s prefix%s %s" % (self.signingTime(), self.getASID(), plural, prefixes) - else: - return "ASN %s prefix%s %s" % (self.getASID(), plural, prefixes) - - def show(self): - print "%s %s" % (self, self.fn if args.show_filenames else self.uri) - - def show_expiration(self): - print self - x = self.certs()[0] - fn = self.fn - uri = self.uri - while uri is not None: - name = fn if args.show_filenames else uri - if args.show_inception: - print "notBefore", x.getNotBefore(), "notAfter", x.getNotAfter(), name - else: - print x.getNotAfter(), name - for uri in x.getAIA() or (): - if uri.startswith("rsync://"): - break - else: - break - fn = uri_to_filename(uri) - if not os.path.exists(fn): - print "***** MISSING ******", uri - break - x = rpki.POW.X509.derReadFile(fn) - print - - -parser = argparse.ArgumentParser(description = __doc__) -parser.add_argument("-a", "--all", action = "store_true", help = "show all ROAs, do no prefix matching at all") -parser.add_argument("-m", "--match-maxlength", action = "store_true", help = "pay attention to maxLength values") -parser.add_argument("-e", "--show-expiration", action = "store_true", help = "show ROA chain expiration dates") -parser.add_argument("-f", "--show-filenames", action = "store_true", help = "show filenames instead of URIs") -parser.add_argument("-i", "--show-inception", action = "store_true", help = "show inception dates") -parser.add_argument("rcynic_dir", type = check_dir, help = "rcynic authenticated output directory") -parser.add_argument("prefixes", type = Prefix, nargs = "*", help = "ROA prefix(es) to match") -args = parser.parse_args() - -# If there's some way to automate this in the parser, I don't know what it is, so just catch it here. -if args.all != (not args.prefixes): - parser.error("--all and prefix list are mutually exclusive") - -for root, dirs, files in os.walk(args.rcynic_dir): - for fn in files: - if fn.endswith(".roa"): - roa = ROA.parse(os.path.join(root, fn)) - if args.all or any(prefix.matches(roa) for prefix in args.prefixes): - if args.show_expiration: - roa.show_expiration() - else: - roa.show() diff --git a/rp/utils/hashdir b/rp/utils/hashdir new file mode 100755 index 00000000..2f02cd3b --- /dev/null +++ b/rp/utils/hashdir @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Copies an authenticated result tree from an rcynic run into the format +expected by most OpenSSL-based programs: a collection of "PEM" format +files with names in the form that OpenSSL's -CApath lookup routines +expect. This can be useful for validating RPKI objects which are not +distributed as part of the repository system. +""" + +import os +import sys +import argparse +import rpki.POW + +def check_dir(s): + if os.path.isdir(s): + return os.path.abspath(s) + else: + raise argparse.ArgumentTypeError("%r is not a directory" % s) + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("-v", "--verbose", action = "store_true", help = "whistle while you work") +parser.add_argument("rcynic_dir", type = check_dir, help = "rcynic authenticated output directory") +parser.add_argument("output_dir", help = "name of output directory to create") +args = parser.parse_args() + +if not os.path.isdir(args.output_dir): + os.makedirs(args.output_dir) + +for root, dirs, files in os.walk(args.rcynic_dir): + for ifn in files: + ifn = os.path.join(root, ifn) + if ifn.endswith(".cer"): + obj = rpki.POW.X509.derReadFile(ifn) + fmt = "%08x.%%d" % obj.getSubjectHash() + elif ifn.endswith(".crl"): + obj = rpki.POW.CRL.derReadFile(ifn) + fmt = "%08x.r%%d" % obj.getIssuerHash() + else: + continue + for i in xrange(1000000): + ofn = os.path.join(args.output_dir, fmt % i) + if not os.path.exists(ofn): + with open(ofn, "w") as f: + f.write(obj.pemWrite()) + if args.verbose: + print ofn, "<=", ifn + break + else: + sys.exit("No path name available for %s (%s)" % (ifn, ofn)) diff --git a/rp/utils/hashdir.py b/rp/utils/hashdir.py deleted file mode 100755 index 2f02cd3b..00000000 --- a/rp/utils/hashdir.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# Copyright (C) 2014 Dragon Research Labs ("DRL") -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -""" -Copies an authenticated result tree from an rcynic run into the format -expected by most OpenSSL-based programs: a collection of "PEM" format -files with names in the form that OpenSSL's -CApath lookup routines -expect. This can be useful for validating RPKI objects which are not -distributed as part of the repository system. -""" - -import os -import sys -import argparse -import rpki.POW - -def check_dir(s): - if os.path.isdir(s): - return os.path.abspath(s) - else: - raise argparse.ArgumentTypeError("%r is not a directory" % s) - -parser = argparse.ArgumentParser(description = __doc__) -parser.add_argument("-v", "--verbose", action = "store_true", help = "whistle while you work") -parser.add_argument("rcynic_dir", type = check_dir, help = "rcynic authenticated output directory") -parser.add_argument("output_dir", help = "name of output directory to create") -args = parser.parse_args() - -if not os.path.isdir(args.output_dir): - os.makedirs(args.output_dir) - -for root, dirs, files in os.walk(args.rcynic_dir): - for ifn in files: - ifn = os.path.join(root, ifn) - if ifn.endswith(".cer"): - obj = rpki.POW.X509.derReadFile(ifn) - fmt = "%08x.%%d" % obj.getSubjectHash() - elif ifn.endswith(".crl"): - obj = rpki.POW.CRL.derReadFile(ifn) - fmt = "%08x.r%%d" % obj.getIssuerHash() - else: - continue - for i in xrange(1000000): - ofn = os.path.join(args.output_dir, fmt % i) - if not os.path.exists(ofn): - with open(ofn, "w") as f: - f.write(obj.pemWrite()) - if args.verbose: - print ofn, "<=", ifn - break - else: - sys.exit("No path name available for %s (%s)" % (ifn, ofn)) diff --git a/rp/utils/print_roa b/rp/utils/print_roa new file mode 100755 index 00000000..fd7308d1 --- /dev/null +++ b/rp/utils/print_roa @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Pretty-print the content of a ROA. Does NOT attempt to verify the +signature. +""" + +import os +import sys +import argparse +import rpki.POW + +class ROA(rpki.POW.ROA): + + @staticmethod + def _format_prefix(prefix): + if prefix[2] is None or prefix[1] == prefix[2]: + return "%s/%d" % (prefix[0], prefix[1]) + else: + return "%s/%d-%d" % (prefix[0], prefix[1], prefix[2]) + + def parse(self): + self.extractWithoutVerifying() + v4, v6 = self.getPrefixes() + self.v4_prefixes = [self._format_prefix(p) for p in (v4 or ())] + self.v6_prefixes = [self._format_prefix(p) for p in (v6 or ())] + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("-b", "--brief", action = "store_true", help = "show only ASN and prefix(es)") +parser.add_argument("-c", "--cms", action = "store_true", help = "print text representation of entire CMS blob") +parser.add_argument("-s", "--signing-time", action = "store_true", help = "show SigningTime in brief mode") +parser.add_argument("roas", nargs = "+", type = ROA.derReadFile, help = "ROA(s) to print") +args = parser.parse_args() + +for roa in args.roas: + roa.parse() + if args.brief: + if args.signing_time: + print roa.signingTime(), + print roa.getASID(), " ".join(roa.v4_prefixes + roa.v6_prefixes) + else: + print "ROA Version: ", roa.getVersion() + print "SigningTime: ", roa.signingTime() + print "asID: ", roa.getASID() + if roa.v4_prefixes: + print " addressFamily:", 1 + for p in roa.v4_prefixes: + print " IPAddress:", p + if roa.v6_prefixes: + print " addressFamily:", 2 + for p in roa.v6_prefixes: + print " IPAddress:", p + if args.cms: + print roa.pprint() + for cer in roa.certs(): + print cer.pprint() + for crl in roa.crls(): + print crl.pprint() + print diff --git a/rp/utils/print_roa.py b/rp/utils/print_roa.py deleted file mode 100755 index fd7308d1..00000000 --- a/rp/utils/print_roa.py +++ /dev/null @@ -1,75 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# Copyright (C) 2014 Dragon Research Labs ("DRL") -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -""" -Pretty-print the content of a ROA. Does NOT attempt to verify the -signature. -""" - -import os -import sys -import argparse -import rpki.POW - -class ROA(rpki.POW.ROA): - - @staticmethod - def _format_prefix(prefix): - if prefix[2] is None or prefix[1] == prefix[2]: - return "%s/%d" % (prefix[0], prefix[1]) - else: - return "%s/%d-%d" % (prefix[0], prefix[1], prefix[2]) - - def parse(self): - self.extractWithoutVerifying() - v4, v6 = self.getPrefixes() - self.v4_prefixes = [self._format_prefix(p) for p in (v4 or ())] - self.v6_prefixes = [self._format_prefix(p) for p in (v6 or ())] - -parser = argparse.ArgumentParser(description = __doc__) -parser.add_argument("-b", "--brief", action = "store_true", help = "show only ASN and prefix(es)") -parser.add_argument("-c", "--cms", action = "store_true", help = "print text representation of entire CMS blob") -parser.add_argument("-s", "--signing-time", action = "store_true", help = "show SigningTime in brief mode") -parser.add_argument("roas", nargs = "+", type = ROA.derReadFile, help = "ROA(s) to print") -args = parser.parse_args() - -for roa in args.roas: - roa.parse() - if args.brief: - if args.signing_time: - print roa.signingTime(), - print roa.getASID(), " ".join(roa.v4_prefixes + roa.v6_prefixes) - else: - print "ROA Version: ", roa.getVersion() - print "SigningTime: ", roa.signingTime() - print "asID: ", roa.getASID() - if roa.v4_prefixes: - print " addressFamily:", 1 - for p in roa.v4_prefixes: - print " IPAddress:", p - if roa.v6_prefixes: - print " addressFamily:", 2 - for p in roa.v6_prefixes: - print " IPAddress:", p - if args.cms: - print roa.pprint() - for cer in roa.certs(): - print cer.pprint() - for crl in roa.crls(): - print crl.pprint() - print diff --git a/rp/utils/print_rpki_manifest b/rp/utils/print_rpki_manifest new file mode 100755 index 00000000..778b4310 --- /dev/null +++ b/rp/utils/print_rpki_manifest @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Pretty-print the content of a manifest. Does NOT attempt to verify the +signature. +""" + +import os +import sys +import argparse +import rpki.POW +import rpki.oids + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("-c", "--cms", action = "store_true", help = "print text representation of entire CMS blob") +parser.add_argument("manifests", nargs = "+", type = rpki.POW.Manifest.derReadFile, help = "manifest(s) to print") +args = parser.parse_args() + +for mft in args.manifests: + mft.extractWithoutVerifying() + print "Manifest Version:", mft.getVersion() + print "SigningTime: ", mft.signingTime() + print "Number: ", mft.getManifestNumber() + print "thisUpdate: ", mft.getThisUpdate() + print "nextUpdate: ", mft.getNextUpdate() + print "fileHashAlg: ", rpki.oids.oid2name(mft.getAlgorithm()) + for i, fah in enumerate(mft.getFiles()): + name, hash = fah + print "fileList[%3d]: %s %s" % (i, ":".join(("%02X" % ord(h) for h in hash)), name) + if args.cms: + print mft.pprint() + for cer in mft.certs(): + print cer.pprint() + for crl in mft.crls(): + print crl.pprint() + print diff --git a/rp/utils/print_rpki_manifest.py b/rp/utils/print_rpki_manifest.py deleted file mode 100755 index 778b4310..00000000 --- a/rp/utils/print_rpki_manifest.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# Copyright (C) 2014 Dragon Research Labs ("DRL") -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -""" -Pretty-print the content of a manifest. Does NOT attempt to verify the -signature. -""" - -import os -import sys -import argparse -import rpki.POW -import rpki.oids - -parser = argparse.ArgumentParser(description = __doc__) -parser.add_argument("-c", "--cms", action = "store_true", help = "print text representation of entire CMS blob") -parser.add_argument("manifests", nargs = "+", type = rpki.POW.Manifest.derReadFile, help = "manifest(s) to print") -args = parser.parse_args() - -for mft in args.manifests: - mft.extractWithoutVerifying() - print "Manifest Version:", mft.getVersion() - print "SigningTime: ", mft.signingTime() - print "Number: ", mft.getManifestNumber() - print "thisUpdate: ", mft.getThisUpdate() - print "nextUpdate: ", mft.getNextUpdate() - print "fileHashAlg: ", rpki.oids.oid2name(mft.getAlgorithm()) - for i, fah in enumerate(mft.getFiles()): - name, hash = fah - print "fileList[%3d]: %s %s" % (i, ":".join(("%02X" % ord(h) for h in hash)), name) - if args.cms: - print mft.pprint() - for cer in mft.certs(): - print cer.pprint() - for crl in mft.crls(): - print crl.pprint() - print diff --git a/rp/utils/scan_roas b/rp/utils/scan_roas new file mode 100755 index 00000000..1f5746b1 --- /dev/null +++ b/rp/utils/scan_roas @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Search an authenticated result tree from an rcynic run for ROAs, and +prints out the signing time, ASN, and prefixes for each ROA, one ROA +per line. +""" + +import os +import argparse +import rpki.POW + +def check_dir(d): + if not os.path.isdir(d): + raise argparse.ArgumentTypeError("%r is not a directory" % d) + return d + +class ROA(rpki.POW.ROA): + + @classmethod + def parse(cls, fn): + self = cls.derReadFile(fn) + self.extractWithoutVerifying() + return self + + @property + def prefixes(self): + v4, v6 = self.getPrefixes() + for prefix, length, maxlength in (v4 or ()) + (v6 or ()): + if maxlength is None or length == maxlength: + yield "%s/%d" % (prefix, length) + else: + yield "%s/%d-%d" % (prefix, length, maxlength) + + def __str__(self): + return "%s %s %s" % (self.signingTime(), self.getASID(), " ".join(self.prefixes)) + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("rcynic_dir", nargs = "+", type = check_dir, + help = "rcynic authenticated output directory") +args = parser.parse_args() + +for rcynic_dir in args.rcynic_dir: + for root, dirs, files in os.walk(rcynic_dir): + for fn in files: + if fn.endswith(".roa"): + print ROA.parse(os.path.join(root, fn)) diff --git a/rp/utils/scan_roas.py b/rp/utils/scan_roas.py deleted file mode 100755 index 1f5746b1..00000000 --- a/rp/utils/scan_roas.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# Copyright (C) 2014 Dragon Research Labs ("DRL") -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -""" -Search an authenticated result tree from an rcynic run for ROAs, and -prints out the signing time, ASN, and prefixes for each ROA, one ROA -per line. -""" - -import os -import argparse -import rpki.POW - -def check_dir(d): - if not os.path.isdir(d): - raise argparse.ArgumentTypeError("%r is not a directory" % d) - return d - -class ROA(rpki.POW.ROA): - - @classmethod - def parse(cls, fn): - self = cls.derReadFile(fn) - self.extractWithoutVerifying() - return self - - @property - def prefixes(self): - v4, v6 = self.getPrefixes() - for prefix, length, maxlength in (v4 or ()) + (v6 or ()): - if maxlength is None or length == maxlength: - yield "%s/%d" % (prefix, length) - else: - yield "%s/%d-%d" % (prefix, length, maxlength) - - def __str__(self): - return "%s %s %s" % (self.signingTime(), self.getASID(), " ".join(self.prefixes)) - -parser = argparse.ArgumentParser(description = __doc__) -parser.add_argument("rcynic_dir", nargs = "+", type = check_dir, - help = "rcynic authenticated output directory") -args = parser.parse_args() - -for rcynic_dir in args.rcynic_dir: - for root, dirs, files in os.walk(rcynic_dir): - for fn in files: - if fn.endswith(".roa"): - print ROA.parse(os.path.join(root, fn)) diff --git a/rp/utils/uri b/rp/utils/uri new file mode 100755 index 00000000..891cd33a --- /dev/null +++ b/rp/utils/uri @@ -0,0 +1,71 @@ +#!/usr/bin/env python +# +# $Id$ +# +# Copyright (C) 2014 Dragon Research Labs ("DRL") +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. + +""" +Extract URIs from the SIA, AIA, and CRLDP extensions of one or more +X.509v3 certificates. + +Input files must be in DER format and may be either X.509v3 certificates +or CMS objects which contain X.509v3 certificates in the CMS wrapper. +""" + +import os +import argparse +import rpki.POW + +class Certificate(object): + + @staticmethod + def first_rsync(uris): + if uris is not None: + for uri in uris: + if uri.startswith("rsync://"): + return uri + return None + + def __init__(self, fn): + try: + x = rpki.POW.X509.derReadFile(fn) + except: + try: + cms = rpki.POW.CMS.derReadFile(fn) + cms.extractWithoutVerifying() + x = cms.getCerts()[0] + except: + raise ValueError + sia = x.getSIA() or (None, None, None) + self.fn = fn + self.uris = ( + ("AIA:caIssuers", self.first_rsync(x.getAIA())), + ("SIA:caRepository", self.first_rsync(sia[0])), + ("SIA:rpkiManifest", self.first_rsync(sia[1])), + ("SIA:signedObject", self.first_rsync(sia[2])), + ("CRLDP", self.first_rsync(x.getCRLDP()))) + + def __str__(self): + words = [self.fn] if args.single_line else ["File: " + self.fn] + words.extend(" %s: %s" % (tag, uri) for tag, uri in self.uris if uri is not None) + return ("" if args.single_line else "\n").join(words) + +parser = argparse.ArgumentParser(description = __doc__) +parser.add_argument("-s", "--single-line", action = "store_true", help = "single output line per object") +parser.add_argument("certs", nargs = "+", type = Certificate, help = "RPKI objects to examine") +args = parser.parse_args() + +for cert in args.certs: + print cert diff --git a/rp/utils/uri.py b/rp/utils/uri.py deleted file mode 100755 index 891cd33a..00000000 --- a/rp/utils/uri.py +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env python -# -# $Id$ -# -# Copyright (C) 2014 Dragon Research Labs ("DRL") -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND DRL DISCLAIMS ALL WARRANTIES WITH -# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS. IN NO EVENT SHALL DRL BE LIABLE FOR ANY SPECIAL, DIRECT, -# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE -# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. - -""" -Extract URIs from the SIA, AIA, and CRLDP extensions of one or more -X.509v3 certificates. - -Input files must be in DER format and may be either X.509v3 certificates -or CMS objects which contain X.509v3 certificates in the CMS wrapper. -""" - -import os -import argparse -import rpki.POW - -class Certificate(object): - - @staticmethod - def first_rsync(uris): - if uris is not None: - for uri in uris: - if uri.startswith("rsync://"): - return uri - return None - - def __init__(self, fn): - try: - x = rpki.POW.X509.derReadFile(fn) - except: - try: - cms = rpki.POW.CMS.derReadFile(fn) - cms.extractWithoutVerifying() - x = cms.getCerts()[0] - except: - raise ValueError - sia = x.getSIA() or (None, None, None) - self.fn = fn - self.uris = ( - ("AIA:caIssuers", self.first_rsync(x.getAIA())), - ("SIA:caRepository", self.first_rsync(sia[0])), - ("SIA:rpkiManifest", self.first_rsync(sia[1])), - ("SIA:signedObject", self.first_rsync(sia[2])), - ("CRLDP", self.first_rsync(x.getCRLDP()))) - - def __str__(self): - words = [self.fn] if args.single_line else ["File: " + self.fn] - words.extend(" %s: %s" % (tag, uri) for tag, uri in self.uris if uri is not None) - return ("" if args.single_line else "\n").join(words) - -parser = argparse.ArgumentParser(description = __doc__) -parser.add_argument("-s", "--single-line", action = "store_true", help = "single output line per object") -parser.add_argument("certs", nargs = "+", type = Certificate, help = "RPKI objects to examine") -args = parser.parse_args() - -for cert in args.certs: - print cert -- cgit v1.2.3