Index: net/data/ssl/scripts/crlsetutil.py |
diff --git a/net/data/ssl/scripts/crlsetutil.py b/net/data/ssl/scripts/crlsetutil.py |
deleted file mode 100755 |
index 49a1a860cdfaa81e83b4ffa4a5155cebfe46d08a..0000000000000000000000000000000000000000 |
--- a/net/data/ssl/scripts/crlsetutil.py |
+++ /dev/null |
@@ -1,200 +0,0 @@ |
-#!/usr/bin/env python |
-# Copyright (c) 2014 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 utility takes a JSON input that describes a CRLSet and produces a |
-CRLSet from it. |
- |
-The input is taken on stdin and is a dict with the following keys: |
- - BlockedBySPKI: An array of strings, where each string is a filename |
- containing a PEM certificate, from which an SPKI will be extracted. |
- - BlockedByHash: A dict of string to an array of ints, where the string is |
- a filename containing a PEM format certificate, and the ints are the |
- serial numbers. The listed serial numbers will be blocked when issued by |
- the given certificate. |
- |
-For example: |
- |
-{ |
- "BlockedBySPKI": ["/tmp/blocked-certificate"], |
- "BlockedByHash": { |
- "/tmp/intermediate-certificate": [1, 2, 3] |
- } |
-} |
-""" |
- |
-import hashlib |
-import json |
-import optparse |
-import struct |
-import sys |
- |
- |
-def _pem_cert_to_binary(pem_filename): |
- """Decodes the first PEM-encoded certificate in a given file into binary |
- |
- Args: |
- pem_filename: A filename that contains a PEM-encoded certificate. It may |
- contain additional data (keys, textual representation) which will be |
- ignored |
- |
- Returns: |
- A byte array containing the decoded certificate data |
- """ |
- base64 = "" |
- started = False |
- |
- with open(pem_filename, 'r') as pem_file: |
- for line in pem_file: |
- if not started: |
- if line.startswith('-----BEGIN CERTIFICATE'): |
- started = True |
- else: |
- if line.startswith('-----END CERTIFICATE'): |
- break |
- base64 += line[:-1].strip() |
- |
- return base64.decode('base64') |
- |
- |
-def _parse_asn1_element(der_bytes): |
- """Parses a DER-encoded tag/Length/Value into its component parts |
- |
- Args: |
- der_bytes: A DER-encoded ASN.1 data type |
- |
- Returns: |
- A tuple of the ASN.1 tag value, the length of the ASN.1 header that was |
- read, the sequence of bytes for the value, and then any data from der_bytes |
- that was not part of the tag/Length/Value. |
- """ |
- tag = ord(der_bytes[0]) |
- length = ord(der_bytes[1]) |
- header_length = 2 |
- |
- if length & 0x80: |
- num_length_bytes = length & 0x7f |
- length = 0 |
- for i in xrange(2, 2 + num_length_bytes): |
- length <<= 8 |
- length += ord(der_bytes[i]) |
- header_length = 2 + num_length_bytes |
- |
- contents = der_bytes[:header_length + length] |
- rest = der_bytes[header_length + length:] |
- |
- return (tag, header_length, contents, rest) |
- |
- |
-class ASN1Iterator(object): |
- """Iterator that parses and iterates through a ASN.1 DER structure""" |
- |
- def __init__(self, contents): |
- self._tag = 0 |
- self._header_length = 0 |
- self._rest = None |
- self._contents = contents |
- self.step_into() |
- |
- def step_into(self): |
- """Begins processing the inner contents of the next ASN.1 element""" |
- (self._tag, self._header_length, self._contents, self._rest) = ( |
- _parse_asn1_element(self._contents[self._header_length:])) |
- |
- def step_over(self): |
- """Skips/ignores the next ASN.1 element""" |
- (self._tag, self._header_length, self._contents, self._rest) = ( |
- _parse_asn1_element(self._rest)) |
- |
- def tag(self): |
- """Returns the ASN.1 tag of the current element""" |
- return self._tag |
- |
- def contents(self): |
- """Returns the raw data of the current element""" |
- return self._contents |
- |
- |
-def _der_cert_to_spki(der_bytes): |
- """Returns the subjectPublicKeyInfo of a DER-encoded certificate |
- |
- Args: |
- der_bytes: A DER-encoded certificate (RFC 5280) |
- |
- Returns: |
- A byte array containing the subjectPublicKeyInfo |
- """ |
- iterator = ASN1Iterator(der_bytes) |
- iterator.step_into() # enter certificate structure |
- iterator.step_into() # enter TBSCertificate |
- iterator.step_over() # over version |
- iterator.step_over() # over serial |
- iterator.step_over() # over signature algorithm |
- iterator.step_over() # over issuer name |
- iterator.step_over() # over validity |
- iterator.step_over() # over subject name |
- return iterator.contents() |
- |
- |
-def pem_cert_file_to_spki_hash(pem_filename): |
- """Gets the SHA-256 hash of the subjectPublicKeyInfo of a cert in a file |
- |
- Args: |
- pem_filename: A file containing a PEM-encoded certificate. |
- |
- Returns: |
- The SHA-256 hash of the first certificate in the file, as a byte sequence |
- """ |
- return hashlib.sha256( |
- _der_cert_to_spki(_pem_cert_to_binary(pem_filename))).digest() |
- |
- |
-def main(): |
- parser = optparse.OptionParser(description=sys.modules[__name__].__doc__) |
- parser.add_option('-o', '--output', |
- help='Specifies the output file. The default is stdout.') |
- options, _ = parser.parse_args() |
- outfile = sys.stdout |
- if options.output and options.output != '-': |
- outfile = open(options.output, 'wb') |
- |
- config = json.load(sys.stdin) |
- blocked_spkis = [ |
- pem_cert_file_to_spki_hash(pem_file).encode('base64').strip() |
- for pem_file in config.get('BlockedBySPKI', [])] |
- parents = { |
- pem_cert_file_to_spki_hash(pem_file): serials |
- for pem_file, serials in config.get('BlockedByHash', {}).iteritems() |
- } |
- header_json = { |
- 'Version': 0, |
- 'ContentType': 'CRLSet', |
- 'Sequence': 0, |
- 'DeltaFrom': 0, |
- 'NumParents': len(parents), |
- 'BlockedSPKIs': blocked_spkis, |
- } |
- header = json.dumps(header_json) |
- outfile.write(struct.pack('<H', len(header))) |
- outfile.write(header) |
- for spki, serials in sorted(parents.iteritems()): |
- outfile.write(spki) |
- outfile.write(struct.pack('<I', len(serials))) |
- for serial in serials: |
- raw_serial = [] |
- if not serial: |
- raw_serial = ['\x00'] |
- else: |
- while serial: |
- raw_serial.insert(0, chr(serial & 0xff)) |
- serial >>= 8 |
- |
- outfile.write(struct.pack('<B', len(raw_serial))) |
- outfile.write(''.join(raw_serial)) |
- return 0 |
- |
- |
-if __name__ == '__main__': |
- sys.exit(main()) |