summaryrefslogtreecommitdiffstats
path: root/comm/third_party/botan/src/scripts/oids.py
diff options
context:
space:
mode:
Diffstat (limited to 'comm/third_party/botan/src/scripts/oids.py')
-rwxr-xr-xcomm/third_party/botan/src/scripts/oids.py337
1 files changed, 337 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/scripts/oids.py b/comm/third_party/botan/src/scripts/oids.py
new file mode 100755
index 0000000000..323b6efb50
--- /dev/null
+++ b/comm/third_party/botan/src/scripts/oids.py
@@ -0,0 +1,337 @@
+#!/usr/bin/python
+
+"""
+(C) 2016 Jack Lloyd
+(C) 2017 Fabian Weissberg, Rohde & Schwarz Cybersecurity
+
+Botan is released under the Simplified BSD License (see license.txt)
+"""
+
+import sys
+import datetime
+import re
+from collections import defaultdict
+
+def format_oid(oid):
+ #return '"' + oid + '"'
+ return "{" + oid.replace('.', ',') + '}'
+
+def format_map(m, for_oid = False):
+ s = ''
+ for k in sorted(m.keys()):
+ v = m[k]
+
+ if len(s) > 0:
+ s += ' '
+
+ if for_oid:
+ s += '{ "%s", OID(%s) },\n' % (k,format_oid(v))
+ else:
+ s += '{ "%s", "%s" },\n' % (k,v)
+
+ s = s[:-2] # chomp last two chars
+
+ return s
+
+
+def format_as_map(oid2str, str2oid):
+ return """/*
+* OID maps
+*
+* This file was automatically generated by %s on %s
+*
+* All manual edits to this file will be lost. Edit the script
+* then regenerate this source file.
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/oids.h>
+#include <unordered_map>
+
+namespace Botan {
+
+std::unordered_map<std::string, std::string> OIDS::load_oid2str_map()
+ {
+ return std::unordered_map<std::string,std::string>{
+ %s
+ };
+ }
+
+std::unordered_map<std::string, OID> OIDS::load_str2oid_map()
+ {
+ return std::unordered_map<std::string,OID>{
+ %s
+ };
+ }
+
+}
+""" % (sys.argv[0], datetime.date.today().strftime("%Y-%m-%d"),
+ format_map(oid2str), format_map(str2oid, True))
+
+
+def format_if(m, nm,t=False):
+ s = ''
+ for k in sorted(m.keys()):
+ v = m[k]
+
+ if t:
+ s += ' if(%s == "%s") return OID(%s);\n' % (nm,k, format_oid(v))
+ else:
+ s += ' if(%s == "%s") return "%s";\n' % (nm,k, v)
+
+ s = s[:-1]
+
+ return s
+
+def format_as_ifs(oid2str, str2oid):
+ return """/*
+* OID maps
+*
+* This file was automatically generated by %s on %s
+*
+* All manual edits to this file will be lost. Edit the script
+* then regenerate this source file.
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/oids.h>
+
+namespace Botan {
+
+namespace OIDS {
+
+std::string lookup(const OID& oid)
+ {
+ const std::string oid_str = oid.to_string();
+%s
+
+ return std::string();
+ }
+
+OID lookup(const std::string& name)
+ {
+%s
+
+ return OID();
+ }
+
+}
+
+}
+""" % (sys.argv[0], datetime.date.today().strftime("%Y-%m-%d"),
+ format_if(oid2str,"oid_str"), format_if(str2oid, "name", True))
+
+
+def format_dn_ub_map(dn_ub, oid2str):
+ s = ''
+ for k in sorted(dn_ub.keys()):
+ v = dn_ub[k]
+
+ s += ' { Botan::OID({%s}), %s }, // %s\n' % (k.replace('.',','),v,oid2str[k])
+
+ # delete last ',' and \n
+ idx = s.rfind(',')
+ if idx != -1:
+ s = s[:idx] + s[idx+1:-1]
+
+ return s
+
+
+def format_dn_ub_as_map(dn_ub, oid2str):
+ return """/*
+* DN_UB maps: Upper bounds on the length of DN strings
+*
+* This file was automatically generated by %s on %s
+*
+* All manual edits to this file will be lost. Edit the script
+* then regenerate this source file.
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/x509_dn.h>
+#include <botan/asn1_oid.h>
+#include <map>
+
+namespace {
+
+/**
+ * Upper bounds for the length of distinguished name fields as given in RFC 5280, Appendix A.
+ * Only OIDS recognized by botan are considered, so far.
+ * Maps OID string representations instead of human readable strings in order
+ * to avoid an additional lookup.
+ */
+static const std::map<Botan::OID, size_t> DN_UB =
+ {
+%s
+ };
+}
+
+namespace Botan {
+
+//static
+size_t X509_DN::lookup_ub(const OID& oid)
+ {
+ auto ub_entry = DN_UB.find(oid);
+ if(ub_entry != DN_UB.end())
+ {
+ return ub_entry->second;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+}
+""" % (sys.argv[0], datetime.date.today().strftime("%Y-%m-%d"),
+ format_dn_ub_map(dn_ub,oid2str))
+
+
+def format_set_map(m):
+ s = ''
+ for k in sorted(m.keys()):
+ v = m[k]
+
+ if len(s) > 0:
+ s += ' '
+
+ s += '{ "%s", {' % k
+ for pad in v:
+ s += '"%s", ' % pad
+ if len(v) is not 0:
+ s = s[:-2]
+ s += '} },\n'
+ s = s[:-1]
+ return s
+
+
+def format_pads_as_map(sig_dict):
+ return """/*
+* Sets of allowed padding schemes for public key types
+*
+* This file was automatically generated by %s on %s
+*
+* All manual edits to this file will be lost. Edit the script
+* then regenerate this source file.
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/internal/padding.h>
+#include <unordered_map>
+#include <vector>
+#include <string>
+#include <algorithm>
+
+namespace Botan {
+
+namespace {
+
+const std::unordered_map<const std::string, std::vector<std::string>> allowed_signature_paddings =
+ {
+ %s
+ };
+
+}
+
+const std::vector<std::string> get_sig_paddings(const std::string algo)
+ {
+ auto i = allowed_signature_paddings.find(algo);
+ if(i != allowed_signature_paddings.end())
+ return i->second;
+ return {};
+ }
+
+bool sig_algo_and_pad_ok(const std::string algo, std::string padding)
+ {
+ const std::vector<std::string> pads = get_sig_paddings(algo);
+ return std::find(pads.begin(), pads.end(), padding) != pads.end();
+ }
+
+}
+""" % (sys.argv[0], datetime.date.today().strftime("%Y-%m-%d"),
+ format_set_map(sig_dict))
+
+
+def main(args = None):
+ """ Print header files (oids.cpp, dn_ub.cpp) depending on the first argument and on src/build-data/oids.txt
+
+ Choose 'oids' to print oids.cpp, needs to be written to src/lib/asn1/oids.cpp
+ Choose 'dn_ub' to print dn_ub.cpp, needs to be written to src/lib/x509/X509_dn_ub.cpp
+ Choose 'pads' to print padding.cpp, needs to be written to src/lib/pk_pad/padding.cpp
+ """
+ if args is None:
+ args = sys.argv
+ if len(args) < 2:
+ raise Exception("Use either 'oids', 'dn_ub', 'pads' as first argument")
+
+ oid_lines = open('./src/build-data/oids.txt').readlines()
+
+ oid_re = re.compile("^([0-9][0-9.]+) = ([A-Za-z0-9_\./\(\), -]+)(?: = )?([0-9]+)?$")
+ hdr_re = re.compile("^\[([a-z0-9_]+)\]$")
+ pad_re = re.compile("^([A-Za-z0-9_\., -]+)/([A-Za-z0-9_-]+)[A-Za-z0-9_\.\(\), -]*$")
+
+ oid2str = {}
+ str2oid = {}
+ dn_ub = {}
+ sig2pads = defaultdict(set)
+ cur_hdr = None
+
+ for line in oid_lines:
+ line = line.strip()
+ if len(line) == 0:
+ continue
+
+ if line[0] == '#':
+ continue
+
+ match = hdr_re.match(line)
+ if match is not None:
+ cur_hdr = match.group(1)
+ continue
+
+ match = oid_re.match(line)
+ if match is None:
+ raise Exception(line)
+
+ oid = match.group(1)
+ nam = match.group(2)
+
+ if oid in str2oid:
+ print("Duplicated OID", oid, name, oid2str[oid])
+ sys.exit() # hard error
+ else:
+ oid2str[oid] = nam
+
+ # parse upper bounds for DNs
+ if cur_hdr == "dn":
+ if match.lastindex < 3:
+ raise Exception("Could not find an upper bound for DN " + match.group(1))
+ dn_ub[oid] = match.group(3)
+ # parse signature paddings
+ elif cur_hdr == "signature":
+ pad_match = pad_re.search(nam)
+ if pad_match is not None:
+ sig2pads[pad_match.group(1)].add(pad_match.group(2))
+
+ if nam in str2oid:
+ #str2oid[nam] = oid
+ pass
+ else:
+ str2oid[nam] = oid
+
+ if args[1] == "oids":
+ print(format_as_map(oid2str, str2oid))
+ elif args[1] == "dn_ub":
+ print(format_dn_ub_as_map(dn_ub,oid2str))
+ elif args[1] == "pads":
+ print(format_pads_as_map(sig2pads))
+ else:
+ print("Unknown command: try oids, dn_ub, or pads")
+
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main())