| # 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 <stdint.h> |
| |
| 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'): |
| 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': |
| 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) |