xref: /aosp_15_r20/external/cronet/net/data/ssl/root_stores/update_root_stores.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1#!/usr/bin/env python3
2# Copyright 2017 The Chromium Authors
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Generator for a C++ file mapping known trust anchors to histogram values.
7
8The generated structure will be sorted by SHA-256 hash of the
9subjectPublicKeyInfo, to allow efficient lookup. The value '0' is reserved
10as a sentinel value to indicate 'not found'.
11"""
12
13import json
14import os.path
15import platform
16import sys
17from subprocess import call
18
19THIS_DIR = os.path.dirname(os.path.abspath(__file__))
20SRC_DIR = os.path.normpath(os.path.join(THIS_DIR, '..', '..', '..', '..'))
21
22ROOT_CERT_LIST_PATH = 'net/cert/root_cert_list_generated.h'
23ROOT_STORE_FILE_PATH = 'net/data/ssl/root_stores/root_stores.json'
24
25LICENSE_AND_HEADER = b"""\
26// Copyright 2017 The Chromium Authors
27// Use of this source code is governed by a BSD-style license that can be
28// found in the LICENSE file.
29//
30// This file is generated by
31// net/data/ssl/root_stores/update_root_stores.py
32// It's formatted by clang-format using Chromium coding style:
33//   clang-format -i -style=chromium filename
34// DO NOT EDIT!
35//
36
37#ifndef NET_CERT_ROOT_CERT_LIST_GENERATED_H_
38#define NET_CERT_ROOT_CERT_LIST_GENERATED_H_
39
40#include <stdint.h>
41
42namespace net {
43
44namespace {
45
46// The list of known trust anchors, sorted by sha256_spki_hash.
47const struct RootCertData {
48  // The SHA-256 hash of the associated certificate's subjectPublicKeyInfo.
49  unsigned char sha256_spki_hash[32];
50
51  // A value suitable for histograms using the NetTrustAnchors enum.
52  int16_t histogram_id : 15;
53
54  // If true, indicates the CA is considered a "Legacy" CA, formerly trusted
55  // or not yet trusted.
56  bool legacy_ca : 1;
57} kRootCerts[] = {
58"""
59
60FOOTER = b"""\
61
62};
63
64}  // namespace
65
66}  // namespace net
67
68#endif  // NET_CERT_ROOT_CERT_LIST_GENERATED_H_
69"""
70
71def _GetInputFile(src_relative_file_path):
72  """Converts a src/-relative path into a path that can be opened."""
73  return os.path.join(SRC_DIR, src_relative_file_path)
74
75def ClangFormat(filename):
76  formatter = 'clang-format'
77  if sys.platform == 'win32':
78    formatter += '.bat'
79  return call([formatter, '-i', '-style=chromium', filename])
80
81def main():
82  if len(sys.argv) > 1:
83    print >>sys.stderr, 'No arguments expected!'
84    sys.stderr.write(__doc__)
85    return 1
86
87  with open(_GetInputFile(ROOT_STORE_FILE_PATH), 'r') as root_store_file:
88    root_stores = json.load(root_store_file)
89
90  with open(_GetInputFile(ROOT_CERT_LIST_PATH), 'wb') as header_file:
91    header_file.write(LICENSE_AND_HEADER)
92    for spki, data in sorted(root_stores['spkis'].items()):
93      cpp_str = ''.join('0x{:02X}, '.format(x) for x in bytearray.fromhex(spki))
94      log_id = int(data['id'])
95      legacy = 'legacy' in data and data['legacy']
96      header_file.write(
97          ('{ { %s },\n%d, %s }, ' %
98           (cpp_str, log_id, "true" if legacy else "false")).encode('utf-8'))
99
100    header_file.write(FOOTER)
101
102  return ClangFormat(_GetInputFile(ROOT_CERT_LIST_PATH))
103
104if __name__ == '__main__':
105  sys.exit(main())
106