summaryrefslogtreecommitdiff
path: root/chromium/net/data/ssl/root_stores/update_root_stores.py
blob: 8aca424fc36921192d74c6de706a47c5eb5e86f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Generator for a C++ file mapping known trust anchors to histogram values.

The generated structure will be sorted by SHA-256 hash of the
subjectPublicKeyInfo, to allow efficient lookup. The value '0' is reserved
as a sentinel value to indicate 'not found'.
"""

import json
import os.path
import platform
import sys
from subprocess import call

THIS_DIR = os.path.dirname(os.path.abspath(__file__))
SRC_DIR = os.path.normpath(os.path.join(THIS_DIR, '..', '..', '..', '..'))

ROOT_CERT_LIST_PATH = 'net/cert/root_cert_list_generated.h'
ROOT_STORE_FILE_PATH = 'net/data/ssl/root_stores/root_stores.json'

LICENSE_AND_HEADER = """\
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This file is generated by
// net/data/ssl/root_stores/update_root_stores.py
// It's formatted by clang-format using Chromium coding style:
//   clang-format -i -style=chromium filename
// DO NOT EDIT!
//

#ifndef NET_CERT_ROOT_CERT_LIST_GENERATED_H_
#define NET_CERT_ROOT_CERT_LIST_GENERATED_H_

#include <stdint.h>

namespace net {

namespace {

// The list of known trust anchors, sorted by sha256_spki_hash.
const struct RootCertData {
  // The SHA-256 hash of the associated certificate's subjectPublicKeyInfo.
  unsigned char sha256_spki_hash[32];

  // A value suitable for histograms using the NetTrustAnchors enum.
  int16_t histogram_id : 15;

  // If true, indicates the CA is considered a "Legacy" CA, formerly trusted
  // or not yet trusted.
  bool legacy_ca : 1;
} kRootCerts[] = {
"""

FOOTER = """\

};

}  // namespace

}  // namespace net

#endif  // NET_CERT_ROOT_CERT_LIST_GENERATED_H_
"""

def _GetInputFile(src_relative_file_path):
  """Converts a src/-relative path into a path that can be opened."""
  return os.path.join(SRC_DIR, src_relative_file_path)

def ClangFormat(filename):
  formatter = 'clang-format'
  if sys.platform == 'win32':
    formatter += '.bat'
  return call([formatter, '-i', '-style=chromium', filename])

def main():
  if len(sys.argv) > 1:
    print >>sys.stderr, 'No arguments expected!'
    sys.stderr.write(__doc__)
    return 1

  with open(_GetInputFile(ROOT_STORE_FILE_PATH), 'r') as root_store_file:
    root_stores = json.load(root_store_file)

  with open(_GetInputFile(ROOT_CERT_LIST_PATH), 'wb') as header_file:
    header_file.write(LICENSE_AND_HEADER)
    for spki, data in sorted(root_stores['spkis'].items()):
      cpp_str = ''.join('0x{:02X}, '.format(x) for x in bytearray.fromhex(spki))
      log_id = int(data['id'])
      legacy = 'legacy' in data and data['legacy']
      header_file.write('{ { %s },\n%d, %s }, ' %
                        (cpp_str, log_id, "true" if legacy else "false"))

    header_file.write(FOOTER)

  return ClangFormat(_GetInputFile(ROOT_CERT_LIST_PATH))

if __name__ == '__main__':
  sys.exit(main())