1#!/usr/bin/env python 2# Copyright 2019 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"""This script is called without any arguments to re-generate all of the *.pem 6files in the script's directory. 7 8The https://github.com/google/der-ascii tools must be in the PATH. 9""" 10 11import base64 12import subprocess 13import os 14 15 16HEADER = "Generated by %s. Do not edit." % os.path.split(__file__)[1] 17 18 19def Ascii2Der(txt): 20 p = subprocess.Popen(['ascii2der'], 21 stdin=subprocess.PIPE, 22 stdout=subprocess.PIPE, 23 stderr=subprocess.PIPE) 24 stdout_data, stderr_data = p.communicate(txt) 25 if p.returncode: 26 raise RuntimeError('ascii2der returned %i: %s' % (p.returncode, 27 stderr_data)) 28 return stdout_data 29 30 31def MakePemBlock(text, der, name): 32 b64 = base64.b64encode(der) 33 wrapped = '\n'.join(b64[pos:pos + 64] for pos in xrange(0, len(b64), 64)) 34 return '%s\n\n%s\n-----BEGIN %s-----\n%s\n-----END %s-----' % ( 35 HEADER, text, name, wrapped, name) 36 37 38def Generate(path, dertext): 39 der = Ascii2Der(dertext) 40 data = MakePemBlock(dertext, der, 'AUTHORITY_KEY_IDENTIFIER') 41 with open(path, "w") as f: 42 f.write(data) 43 44 45Generate('empty_sequence.pem', 'SEQUENCE {}') 46 47Generate('key_identifier.pem', """ 48 SEQUENCE { 49 [0 PRIMITIVE] { `DEADB00F`} 50 } 51""") 52 53Generate('issuer_and_serial.pem', """ 54 SEQUENCE { 55 [1] { 56 [4] { 57 SEQUENCE { 58 SET { 59 SEQUENCE { 60 # commonName 61 OBJECT_IDENTIFIER { 2.5.4.3 } 62 UTF8String { "Root" } 63 } 64 } 65 } 66 } 67 } 68 [2 PRIMITIVE] { `274f` } 69 } 70""") 71 72Generate('url_issuer_and_serial.pem', """ 73 SEQUENCE { 74 [1] { 75 [6 PRIMITIVE] { "http://example.com" } 76 } 77 [2 PRIMITIVE] { `274f` } 78 } 79""") 80 81Generate('key_identifier_and_issuer_and_serial.pem', """ 82 SEQUENCE { 83 [0 PRIMITIVE] { `DEADB00F`} 84 [1] { 85 [4] { 86 SEQUENCE { 87 SET { 88 SEQUENCE { 89 # commonName 90 OBJECT_IDENTIFIER { 2.5.4.3 } 91 UTF8String { "Root" } 92 } 93 } 94 } 95 } 96 } 97 [2 PRIMITIVE] { `274f` } 98 } 99""") 100 101Generate('issuer_only.pem', """ 102 SEQUENCE { 103 [1] { 104 [4] { 105 SEQUENCE { 106 SET { 107 SEQUENCE { 108 # commonName 109 OBJECT_IDENTIFIER { 2.5.4.3 } 110 UTF8String { "Root" } 111 } 112 } 113 } 114 } 115 } 116 } 117""") 118 119Generate('serial_only.pem', """ 120 SEQUENCE { 121 [2 PRIMITIVE] { `274f` } 122 } 123""") 124 125Generate('invalid_contents.pem', """ 126 SEQUENCE { 127 INTEGER {`1234`} 128 } 129""") 130 131Generate('invalid_key_identifier.pem', """ 132 SEQUENCE { 133 # Tag and Length for [0 PRIMITIVE], but no data. 134 `8004` 135 } 136""") 137 138Generate('invalid_issuer.pem', """ 139 SEQUENCE { 140 [0 PRIMITIVE] { `DEADB00F`} 141 # Tag and Length for [1] {...}, but no data. 142 `a104` 143 } 144""") 145 146Generate('invalid_serial.pem', """ 147 SEQUENCE { 148 [0 PRIMITIVE] { `DEADB00F`} 149 [1] {} 150 # Tag and Length for [2 PRIMITIVE], but no data. 151 `8204` 152 } 153""") 154 155Generate('extra_contents_after_issuer_and_serial.pem', """ 156 SEQUENCE { 157 [1] { 158 [4] { 159 SEQUENCE { 160 SET { 161 SEQUENCE { 162 # commonName 163 OBJECT_IDENTIFIER { 2.5.4.3 } 164 UTF8String { "Root" } 165 } 166 } 167 } 168 } 169 } 170 [2 PRIMITIVE] { `274f` } 171 INTEGER {`1234`} 172 } 173""") 174 175Generate('extra_contents_after_extension_sequence.pem', """ 176 SEQUENCE { 177 [0 PRIMITIVE] { `DEADB00F`} 178 } 179 INTEGER {`1234`} 180""") 181