mach_commands.py (4634B)
1 # This Source Code Form is subject to the terms of the Mozilla Public 2 # License, v. 2.0. If a copy of the MPL was not distributed with this 3 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 import os 6 7 from mach.decorators import Command, CommandArgument 8 from mach.util import UserError 9 from mozpack.files import FileFinder 10 11 12 def run_module_main_on(module, input_filename, output_is_binary): 13 """Run the given module (pycert, pykey, etc.) on the given 14 file.""" 15 # By convention, the specification files have names of the form 16 # "name.ext.*spec", where "ext" is some extension, and the "*" in 17 # "*spec" identifies what kind of specification it represents 18 # (certspec, keyspec, etc.). Taking off the ".*spec" part results in 19 # the desired filename for this file. 20 output_filename = os.path.splitext(input_filename)[0] 21 mode = "w" 22 encoding = "utf-8" 23 newline = "\n" 24 if output_is_binary: 25 mode = "wb" 26 encoding = None 27 newline = None 28 with open(output_filename, mode=mode, encoding=encoding, newline=newline) as output: 29 module.main(output, input_filename) 30 31 32 def is_certspec_file(filename): 33 """Returns True if the given filename is a certificate 34 specification file (.certspec) and False otherwise.""" 35 return filename.endswith(".certspec") 36 37 38 def is_keyspec_file(filename): 39 """Returns True if the given filename is a key specification 40 file (.keyspec) and False otherwise.""" 41 return filename.endswith(".keyspec") 42 43 44 def is_pkcs12spec_file(filename): 45 """Returns True if the given filename is a pkcs12 46 specification file (.pkcs12spec) and False otherwise.""" 47 return filename.endswith(".pkcs12spec") 48 49 50 def is_sctspec_file(filename): 51 """Returns True if the given filename is an SCT 52 specification file (.sctspec) and False otherwise.""" 53 return filename.endswith(".sctspec") 54 55 56 def is_bindingspec_file(filename): 57 """Returns True if the given filename is a TLS certificate 58 binding specification file (.bindingspec) and False 59 otherwise.""" 60 return filename.endswith(".bindingspec") 61 62 63 def is_specification_file(filename): 64 """Returns True if the given filename is a specification 65 file supported by this script, and False otherewise.""" 66 return ( 67 is_certspec_file(filename) 68 or is_keyspec_file(filename) 69 or is_pkcs12spec_file(filename) 70 or is_sctspec_file(filename) 71 or is_bindingspec_file(filename) 72 ) 73 74 75 @Command( 76 "generate-test-certs", 77 category="devenv", 78 description="Generate test certificates and keys from specifications.", 79 ) 80 @CommandArgument( 81 "specifications", 82 nargs="*", 83 help="Specification files for test certs. If omitted, all certs are regenerated.", 84 ) 85 def generate_test_certs(command_context, specifications): 86 """Generate test certificates and keys from specifications.""" 87 import pycert 88 import pyct 89 import pykey 90 import pypkcs12 91 import pytlsbinding 92 93 if not specifications: 94 specifications = find_all_specifications(command_context) 95 96 for specification in specifications: 97 output_is_binary = False 98 if is_certspec_file(specification): 99 module = pycert 100 elif is_keyspec_file(specification): 101 module = pykey 102 elif is_pkcs12spec_file(specification): 103 module = pypkcs12 104 output_is_binary = True 105 elif is_sctspec_file(specification): 106 module = pyct 107 output_is_binary = True 108 elif is_bindingspec_file(specification): 109 module = pytlsbinding 110 else: 111 raise UserError( 112 f"'{specification}' is not a .certspec, .keyspec, .pkcs12spec, or .bindingspec file" 113 ) 114 run_module_main_on(module, os.path.abspath(specification), output_is_binary) 115 return 0 116 117 118 def find_all_specifications(command_context): 119 """Searches the source tree for all specification files 120 and returns them as a list.""" 121 specifications = [] 122 inclusions = [ 123 "browser/base/content/test/siteIdentity/", 124 "netwerk/test/unit", 125 "security/manager/ssl/tests", 126 "services/settings/test/unit/test_remote_settings_signatures", 127 "testing/xpcshell/moz-http2", 128 "toolkit/mozapps/extensions/test/xpcshell/data/productaddons", 129 ] 130 finder = FileFinder(command_context.topsrcdir) 131 for inclusion_path in inclusions: 132 for f, _ in finder.find(inclusion_path): 133 if is_specification_file(f): 134 specifications.append(os.path.join(command_context.topsrcdir, f)) 135 return specifications