| #!/usr/bin/env python |
| # Copyright 2019 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """This script is called without any arguments to re-generate all of the *.pem |
| files in the script's directory. |
| |
| The https://github.com/google/der-ascii tools must be in the PATH. |
| """ |
| |
| import base64 |
| import subprocess |
| import os |
| |
| |
| HEADER = "Generated by %s. Do not edit." % os.path.split(__file__)[1] |
| |
| |
| def Ascii2Der(txt): |
| p = subprocess.Popen(['ascii2der'], |
| stdin=subprocess.PIPE, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE) |
| stdout_data, stderr_data = p.communicate(txt) |
| if p.returncode: |
| raise RuntimeError('ascii2der returned %i: %s' % (p.returncode, |
| stderr_data)) |
| return stdout_data |
| |
| |
| def MakePemBlock(text, der, name): |
| b64 = base64.b64encode(der) |
| wrapped = '\n'.join(b64[pos:pos + 64] for pos in xrange(0, len(b64), 64)) |
| return '%s\n\n%s\n-----BEGIN %s-----\n%s\n-----END %s-----' % ( |
| HEADER, text, name, wrapped, name) |
| |
| |
| def Generate(path, dertext): |
| der = Ascii2Der(dertext) |
| data = MakePemBlock(dertext, der, 'AUTHORITY_KEY_IDENTIFIER') |
| with open(path, "w") as f: |
| f.write(data) |
| |
| |
| Generate('empty_sequence.pem', 'SEQUENCE {}') |
| |
| Generate('key_identifier.pem', """ |
| SEQUENCE { |
| [0 PRIMITIVE] { `DEADB00F`} |
| } |
| """) |
| |
| Generate('issuer_and_serial.pem', """ |
| SEQUENCE { |
| [1] { |
| [4] { |
| SEQUENCE { |
| SET { |
| SEQUENCE { |
| # commonName |
| OBJECT_IDENTIFIER { 2.5.4.3 } |
| UTF8String { "Root" } |
| } |
| } |
| } |
| } |
| } |
| [2 PRIMITIVE] { `274f` } |
| } |
| """) |
| |
| Generate('url_issuer_and_serial.pem', """ |
| SEQUENCE { |
| [1] { |
| [6 PRIMITIVE] { "http://example.com" } |
| } |
| [2 PRIMITIVE] { `274f` } |
| } |
| """) |
| |
| Generate('key_identifier_and_issuer_and_serial.pem', """ |
| SEQUENCE { |
| [0 PRIMITIVE] { `DEADB00F`} |
| [1] { |
| [4] { |
| SEQUENCE { |
| SET { |
| SEQUENCE { |
| # commonName |
| OBJECT_IDENTIFIER { 2.5.4.3 } |
| UTF8String { "Root" } |
| } |
| } |
| } |
| } |
| } |
| [2 PRIMITIVE] { `274f` } |
| } |
| """) |
| |
| Generate('issuer_only.pem', """ |
| SEQUENCE { |
| [1] { |
| [4] { |
| SEQUENCE { |
| SET { |
| SEQUENCE { |
| # commonName |
| OBJECT_IDENTIFIER { 2.5.4.3 } |
| UTF8String { "Root" } |
| } |
| } |
| } |
| } |
| } |
| } |
| """) |
| |
| Generate('serial_only.pem', """ |
| SEQUENCE { |
| [2 PRIMITIVE] { `274f` } |
| } |
| """) |
| |
| Generate('invalid_contents.pem', """ |
| SEQUENCE { |
| INTEGER {`1234`} |
| } |
| """) |
| |
| Generate('invalid_key_identifier.pem', """ |
| SEQUENCE { |
| # Tag and Length for [0 PRIMITIVE], but no data. |
| `8004` |
| } |
| """) |
| |
| Generate('invalid_issuer.pem', """ |
| SEQUENCE { |
| [0 PRIMITIVE] { `DEADB00F`} |
| # Tag and Length for [1] {...}, but no data. |
| `a104` |
| } |
| """) |
| |
| Generate('invalid_serial.pem', """ |
| SEQUENCE { |
| [0 PRIMITIVE] { `DEADB00F`} |
| [1] {} |
| # Tag and Length for [2 PRIMITIVE], but no data. |
| `8204` |
| } |
| """) |
| |
| Generate('extra_contents_after_issuer_and_serial.pem', """ |
| SEQUENCE { |
| [1] { |
| [4] { |
| SEQUENCE { |
| SET { |
| SEQUENCE { |
| # commonName |
| OBJECT_IDENTIFIER { 2.5.4.3 } |
| UTF8String { "Root" } |
| } |
| } |
| } |
| } |
| } |
| [2 PRIMITIVE] { `274f` } |
| INTEGER {`1234`} |
| } |
| """) |
| |
| Generate('extra_contents_after_extension_sequence.pem', """ |
| SEQUENCE { |
| [0 PRIMITIVE] { `DEADB00F`} |
| } |
| INTEGER {`1234`} |
| """) |