summaryrefslogtreecommitdiffstats
path: root/security/manager/tools/mach_commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'security/manager/tools/mach_commands.py')
-rw-r--r--security/manager/tools/mach_commands.py129
1 files changed, 129 insertions, 0 deletions
diff --git a/security/manager/tools/mach_commands.py b/security/manager/tools/mach_commands.py
new file mode 100644
index 0000000000..e543821dbe
--- /dev/null
+++ b/security/manager/tools/mach_commands.py
@@ -0,0 +1,129 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import os
+
+from mach.decorators import Command, CommandArgument
+from mach.util import UserError
+from mozpack.files import FileFinder
+from mozpack.path import basedir
+
+
+def run_module_main_on(module, input_filename, output_is_binary):
+ """Run the given module (pycert or pykey) on the given
+ file."""
+ # By convention, the specification files have names of the form
+ # "name.ext.*spec", where "ext" is some extension, and the "*" in
+ # "*spec" identifies what kind of specification it represents
+ # (certspec or keyspec). Taking off the ".*spec" part results in the
+ # desired filename for this file.
+ output_filename = os.path.splitext(input_filename)[0]
+ mode = "w"
+ encoding = "utf-8"
+ newline = "\n"
+ if output_is_binary:
+ mode = "wb"
+ encoding = None
+ newline = None
+ with open(output_filename, mode=mode, encoding=encoding, newline=newline) as output:
+ module.main(output, input_filename)
+
+
+def is_certspec_file(filename):
+ """Returns True if the given filename is a certificate
+ specification file (.certspec) and False otherwise."""
+ return filename.endswith(".certspec")
+
+
+def is_keyspec_file(filename):
+ """Returns True if the given filename is a key specification
+ file (.keyspec) and False otherwise."""
+ return filename.endswith(".keyspec")
+
+
+def is_pkcs12spec_file(filename):
+ """Returns True if the given filename is a pkcs12
+ specification file (.pkcs12spec) and False otherwise."""
+ return filename.endswith(".pkcs12spec")
+
+
+def is_specification_file(filename):
+ """Returns True if the given filename is a specification
+ file supported by this script, and False otherewise."""
+ return (
+ is_certspec_file(filename)
+ or is_keyspec_file(filename)
+ or is_pkcs12spec_file(filename)
+ )
+
+
+def is_excluded_directory(directory, exclusions):
+ """Returns True if the given directory is in or is a
+ subdirectory of a directory in the list of exclusions and
+ False otherwise."""
+
+ for exclusion in exclusions:
+ if directory.startswith(exclusion):
+ return True
+ return False
+
+
+@Command(
+ "generate-test-certs",
+ category="devenv",
+ description="Generate test certificates and keys from specifications.",
+)
+@CommandArgument(
+ "specifications",
+ nargs="*",
+ help="Specification files for test certs. If omitted, all certs are regenerated.",
+)
+def generate_test_certs(command_context, specifications):
+ """Generate test certificates and keys from specifications."""
+ import pycert
+ import pykey
+ import pypkcs12
+
+ if not specifications:
+ specifications = find_all_specifications(command_context)
+
+ for specification in specifications:
+ output_is_binary = False
+ if is_certspec_file(specification):
+ module = pycert
+ elif is_keyspec_file(specification):
+ module = pykey
+ elif is_pkcs12spec_file(specification):
+ module = pypkcs12
+ output_is_binary = True
+ else:
+ raise UserError(
+ "'{}' is not a .certspec, .keyspec, or .pkcs12spec file".format(
+ specification
+ )
+ )
+ run_module_main_on(module, os.path.abspath(specification), output_is_binary)
+ return 0
+
+
+def find_all_specifications(command_context):
+ """Searches the source tree for all specification files
+ and returns them as a list."""
+ specifications = []
+ inclusions = [
+ "netwerk/test/unit",
+ "security/manager/ssl/tests",
+ "services/settings/test/unit/test_remote_settings_signatures",
+ "testing/xpcshell/moz-http2",
+ "toolkit/mozapps/extensions/test/xpcshell/data/productaddons",
+ ]
+ exclusions = ["security/manager/ssl/tests/unit/test_signed_apps"]
+ finder = FileFinder(command_context.topsrcdir)
+ for inclusion_path in inclusions:
+ for f, _ in finder.find(inclusion_path):
+ if basedir(f, exclusions):
+ continue
+ if is_specification_file(f):
+ specifications.append(os.path.join(command_context.topsrcdir, f))
+ return specifications