diff options
Diffstat (limited to 'security/manager/tools/mach_commands.py')
-rw-r--r-- | security/manager/tools/mach_commands.py | 129 |
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 |