# Copyright 2020 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy of # the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. # # Lint as: python3 """Generates known_test_values.h from dumped test values. This program generates the known_test_values.h file used for unit tests. This is useful to correct the baseline test values based on dumps from the tests. Use this after fixing a bug in the code, not to 'fix' test breakage not well understood. Usage: $ cd out $ python ../generate_test_values.py > ../include/dice/known_test_values.h Prerequisites: pip install absl-py """ from __future__ import print_function import re import subprocess import textwrap from absl import app from absl import flags FLAGS = flags.FLAGS _FILE_HEADER = textwrap.dedent("""\ // Copyright 2020 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); you may not // use this file except in compliance with the License. You may obtain a copy of // the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations under // the License. // !!! GENERATED - DO NOT MODIFY !!! // To update this file, use generate_test_values.py. #ifndef DICE_KNOWN_TEST_VALUES_H_ #define DICE_KNOWN_TEST_VALUES_H_ #include namespace dice { namespace test { """) _FILE_FOOTER = textwrap.dedent("""\ } // namespace test } // namespace dice #endif // DICE_KNOWN_TEST_VALUES_H_ """) def _to_camel_case(s): return ''.join(tmp.capitalize() for tmp in s.split('_')) def _read_file(name): try: with open(name, 'rb') as f: return f.read() except OSError: return '' def _generate_array(name, data): return 'constexpr uint8_t %s[%d] = {%s};\n\n' % ( name, len(data), ', '.join('0x%02x' % tmp for tmp in data)) def _generate_cert_comment(data): return re.sub('^', '// ', subprocess.run([ 'openssl', 'x509', '-inform', 'DER', '-noout', '-text', '-certopt', 'ext_parse' ], input=data, capture_output=True, check=True).stdout.decode(), flags=re.MULTILINE)[:-3] def _generate_c(name): """Generates C declarations from dumps identified by |name|.""" content = '' attest_cdi_data = _read_file('_attest_cdi_%s.bin' % name) content += _generate_array('kExpectedCdiAttest_%s' % _to_camel_case(name), attest_cdi_data) seal_cdi_data = _read_file('_seal_cdi_%s.bin' % name) content += _generate_array('kExpectedCdiSeal_%s' % _to_camel_case(name), seal_cdi_data) for cert_type in ('X509', 'CBOR'): for key_type in ('Ed25519', 'P256', 'P384'): var_name = 'kExpected%s%sCert_%s' % (_to_camel_case(cert_type), _to_camel_case(key_type), _to_camel_case(name)) cert_data = _read_file('_%s_%s_cert_%s.cert' % (cert_type, key_type, name)) if cert_type == 'X509' and key_type != 'P384': content += ( '// $ openssl x509 -inform DER -noout -text -certopt ' 'ext_parse\n') content += _generate_cert_comment(cert_data) content += _generate_array(var_name, cert_data) return content def main(argv): if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') content = _FILE_HEADER content += _generate_c('zero_input') content += _generate_c('hash_only_input') content += _generate_c('descriptor_input') content += _FILE_FOOTER subprocess.run(['clang-format', '--style=file'], input=content.encode(), check=True) if __name__ == '__main__': app.run(main)