| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 #!/usr/bin/env python | 
|  | 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | 3 # Use of this source code is governed by a BSD-style license that can be | 
|  | 4 # found in the LICENSE file. | 
|  | 5 | 
|  | 6 import base64 | 
|  | 7 import copy | 
|  | 8 import os | 
|  | 9 import subprocess | 
|  | 10 import tempfile | 
|  | 11 | 
|  | 12 | 
|  | 13 class RDN: | 
|  | 14   def __init__(self): | 
|  | 15     self.attrs = [] | 
|  | 16 | 
|  | 17   def add_attr(self, attr_type, attr_value_type, attr_value, | 
|  | 18                attr_modifier=None): | 
|  | 19     self.attrs.append((attr_type, attr_value_type, attr_value, attr_modifier)) | 
|  | 20     return self | 
|  | 21 | 
|  | 22   def __str__(self): | 
|  | 23     s = '' | 
|  | 24     for n, attr in enumerate(self.attrs): | 
|  | 25       s += 'attrTypeAndValue%i=SEQUENCE:attrTypeAndValueSequence%i_%i\n' % ( | 
|  | 26           n, id(self), n) | 
|  | 27 | 
|  | 28     s += '\n' | 
|  | 29     for n, attr in enumerate(self.attrs): | 
|  | 30       attr_type, attr_value_type, attr_value, attr_modifier = attr | 
|  | 31       s += '[attrTypeAndValueSequence%i_%i]\n' % (id(self), n) | 
|  | 32       # Note the quotes around the string value here, which is necessary for | 
|  | 33       # trailing whitespace to be included by openssl. | 
|  | 34       s += 'type=OID:%s\n' % attr_type | 
|  | 35       s += 'value=' | 
|  | 36       if attr_modifier: | 
|  | 37         s += attr_modifier + ',' | 
|  | 38       s += '%s:"%s"\n' % (attr_value_type, attr_value) | 
|  | 39 | 
|  | 40     return s | 
|  | 41 | 
|  | 42 | 
|  | 43 class NameGenerator: | 
|  | 44   def __init__(self): | 
|  | 45     self.rdns = [] | 
|  | 46 | 
|  | 47   def add_rdn(self): | 
|  | 48     rdn = RDN() | 
|  | 49     self.rdns.append(rdn) | 
|  | 50     return rdn | 
|  | 51 | 
|  | 52   def __str__(self): | 
|  | 53     s = 'asn1 = SEQUENCE:rdnSequence\n\n[rdnSequence]\n' | 
|  | 54     for n, rdn in enumerate(self.rdns): | 
|  | 55       s += 'rdn%i = SET:rdnSet%i\n' % (n, n) | 
|  | 56 | 
|  | 57     s += '\n' | 
|  | 58 | 
|  | 59     for n, rdn in enumerate(self.rdns): | 
|  | 60       s += '[rdnSet%i]\n%s\n' % (n, rdn) | 
|  | 61 | 
|  | 62     return s | 
|  | 63 | 
|  | 64 | 
|  | 65 def generate(s, fn): | 
|  | 66   out_fn = os.path.join('..', 'names', fn + '.pem') | 
|  | 67   conf_tempfile = tempfile.NamedTemporaryFile() | 
|  | 68   conf_tempfile.write(str(s)) | 
|  | 69   conf_tempfile.flush() | 
|  | 70   der_tmpfile = tempfile.NamedTemporaryFile() | 
|  | 71   description_tmpfile = tempfile.NamedTemporaryFile() | 
|  | 72   subprocess.check_call(['openssl', 'asn1parse', '-genconf', conf_tempfile.name, | 
|  | 73                          '-i', '-out', der_tmpfile.name], | 
|  | 74                         stdout=description_tmpfile) | 
|  | 75   conf_tempfile.close() | 
|  | 76 | 
|  | 77   output_file = open(out_fn, 'w') | 
|  | 78   description_tmpfile.seek(0) | 
|  | 79   output_file.write(description_tmpfile.read()) | 
|  | 80   output_file.write('-----BEGIN NAME-----\n') | 
|  | 81   output_file.write(base64.encodestring(der_tmpfile.read())) | 
|  | 82   output_file.write('-----END NAME-----\n') | 
|  | 83   output_file.close() | 
|  | 84 | 
|  | 85 | 
|  | 86 def unmangled(s): | 
|  | 87   return s | 
|  | 88 | 
|  | 89 | 
|  | 90 def extra_whitespace(s): | 
|  | 91   return '  ' + s.replace(' ', '   ') + '  ' | 
|  | 92 | 
|  | 93 | 
|  | 94 def case_swap(s): | 
|  | 95   return s.swapcase() | 
|  | 96 | 
|  | 97 | 
|  | 98 def main(): | 
|  | 99   for valuetype in ('PRINTABLESTRING', 'T61STRING', 'UTF8', 'BMPSTRING', | 
|  | 100                     'UNIVERSALSTRING'): | 
|  | 101     for string_mangler in (unmangled, extra_whitespace, case_swap): | 
|  | 102       n=NameGenerator() | 
|  | 103       n.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'US') | 
|  | 104       n.add_rdn().add_attr('stateOrProvinceName', | 
|  | 105                            valuetype, | 
|  | 106                            string_mangler('New York')) | 
|  | 107       n.add_rdn().add_attr('localityName', | 
|  | 108                            valuetype, | 
|  | 109                            string_mangler("ABCDEFGHIJKLMNOPQRSTUVWXYZ " | 
|  | 110                                           "abcdefghijklmnopqrstuvwxyz " | 
|  | 111                                           "0123456789 '()+,-./:=?")) | 
|  | 112 | 
|  | 113       n_extra_attr = copy.deepcopy(n) | 
|  | 114       n_extra_attr.rdns[-1].add_attr('organizationName', | 
|  | 115                                      valuetype, | 
|  | 116                                      string_mangler('Name of company')) | 
|  | 117 | 
|  | 118       n_extra_rdn = copy.deepcopy(n) | 
|  | 119       n_extra_rdn.add_rdn().add_attr('organizationName', | 
|  | 120                                      valuetype, | 
|  | 121                                      string_mangler('Name of company')) | 
|  | 122 | 
|  | 123       filename_base = 'ascii-' + valuetype + '-' + string_mangler.__name__ | 
|  | 124 | 
|  | 125       generate(n, filename_base) | 
|  | 126       generate(n_extra_attr, filename_base + '-extra_attr') | 
|  | 127       generate(n_extra_rdn, filename_base + '-extra_rdn') | 
|  | 128 | 
|  | 129   for valuetype in ('UTF8', 'BMPSTRING', 'UNIVERSALSTRING'): | 
|  | 130     n=NameGenerator() | 
|  | 131     n.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'JP') | 
|  | 132     n.add_rdn().add_attr('localityName', | 
|  | 133                          valuetype, | 
|  | 134                          "\xe6\x9d\xb1\xe4\xba\xac", | 
|  | 135                          "FORMAT:UTF8") | 
|  | 136 | 
|  | 137     filename_base = 'unicode_bmp-' + valuetype + '-' + 'unmangled' | 
|  | 138     generate(n, filename_base) | 
|  | 139 | 
|  | 140   for valuetype in ('UTF8', 'UNIVERSALSTRING'): | 
|  | 141     n=NameGenerator() | 
|  | 142     n.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'JP') | 
|  | 143     n.add_rdn().add_attr('localityName', | 
|  | 144                          valuetype, | 
|  | 145                          "\xf0\x9d\x90\x80\xf0\x9d\x90\x99", | 
|  | 146                          "FORMAT:UTF8") | 
|  | 147 | 
|  | 148     filename_base = 'unicode_supplementary-' + valuetype + '-' + 'unmangled' | 
|  | 149     generate(n, filename_base) | 
|  | 150 | 
|  | 151   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 152 [rdnSequence] | 
|  | 153 rdn0 = SET:rdnSet0 | 
|  | 154 [rdnSet0] | 
|  | 155 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 156 [attrTypeAndValueSequence0_0] | 
|  | 157 type=OID:countryName | 
|  | 158 value=PRINTABLESTRING:"US" | 
|  | 159 extra=PRINTABLESTRING:"hello world" | 
|  | 160 """, "invalid-AttributeTypeAndValue-extradata") | 
|  | 161 | 
|  | 162   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 163 [rdnSequence] | 
|  | 164 rdn0 = SET:rdnSet0 | 
|  | 165 [rdnSet0] | 
|  | 166 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 167 [attrTypeAndValueSequence0_0] | 
|  | 168 type=OID:countryName | 
|  | 169 """, "invalid-AttributeTypeAndValue-onlyOneElement") | 
|  | 170 | 
|  | 171   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 172 [rdnSequence] | 
|  | 173 rdn0 = SET:rdnSet0 | 
|  | 174 [rdnSet0] | 
|  | 175 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 176 [attrTypeAndValueSequence0_0] | 
|  | 177 """, "invalid-AttributeTypeAndValue-empty") | 
|  | 178 | 
|  | 179   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 180 [rdnSequence] | 
|  | 181 rdn0 = SET:rdnSet0 | 
|  | 182 [rdnSet0] | 
|  | 183 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 184 [attrTypeAndValueSequence0_0] | 
|  | 185 type=PRINTABLESTRING:"hello world" | 
|  | 186 value=PRINTABLESTRING:"US" | 
|  | 187 """, "invalid-AttributeTypeAndValue-badAttributeType") | 
|  | 188 | 
|  | 189   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 190 [rdnSequence] | 
|  | 191 rdn0 = SET:rdnSet0 | 
|  | 192 [rdnSet0] | 
|  | 193 attrTypeAndValue0=SET:attrTypeAndValueSequence0_0 | 
|  | 194 [attrTypeAndValueSequence0_0] | 
|  | 195 type=OID:countryName | 
|  | 196 value=PRINTABLESTRING:"US" | 
|  | 197 """, "invalid-AttributeTypeAndValue-setNotSequence") | 
|  | 198 | 
|  | 199   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 200 [rdnSequence] | 
|  | 201 rdn0 = SEQUENCE:rdnSet0 | 
|  | 202 [rdnSet0] | 
|  | 203 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 204 [attrTypeAndValueSequence0_0] | 
|  | 205 type=OID:countryName | 
|  | 206 value=PRINTABLESTRING:"US" | 
|  | 207 """, "invalid-RDN-sequenceInsteadOfSet") | 
|  | 208 | 
|  | 209   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 210 [rdnSequence] | 
|  | 211 rdn0 = SET:rdnSet0 | 
|  | 212 [rdnSet0] | 
|  | 213 """, "invalid-RDN-empty") | 
|  | 214 | 
|  | 215   generate("""asn1 = SET:rdnSequence | 
|  | 216 [rdnSequence] | 
|  | 217 rdn0 = SET:rdnSet0 | 
|  | 218 [rdnSet0] | 
|  | 219 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 220 [attrTypeAndValueSequence0_0] | 
|  | 221 type=OID:countryName | 
|  | 222 value=PRINTABLESTRING:"US" | 
|  | 223 """, "invalid-Name-setInsteadOfSequence") | 
|  | 224 | 
|  | 225   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 226 [rdnSequence] | 
|  | 227 """, "valid-Name-empty") | 
|  | 228 | 
|  | 229   # Certs with a RDN that is sorted differently due to length of the values, but | 
|  | 230   # which should compare equal when normalized. | 
|  | 231   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 232 [rdnSequence] | 
|  | 233 rdn0 = SET:rdnSet0 | 
|  | 234 [rdnSet0] | 
|  | 235 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 236 attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 | 
|  | 237 [attrTypeAndValueSequence0_0] | 
|  | 238 type=OID:stateOrProvinceName | 
|  | 239 value=PRINTABLESTRING:"    state" | 
|  | 240 [attrTypeAndValueSequence0_1] | 
|  | 241 type=OID:localityName | 
|  | 242 value=PRINTABLESTRING:"locality" | 
|  | 243 """, "ascii-PRINTABLESTRING-rdn_sorting_1") | 
|  | 244 | 
|  | 245   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 246 [rdnSequence] | 
|  | 247 rdn0 = SET:rdnSet0 | 
|  | 248 [rdnSet0] | 
|  | 249 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 250 attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 | 
|  | 251 [attrTypeAndValueSequence0_0] | 
|  | 252 type=OID:stateOrProvinceName | 
|  | 253 value=PRINTABLESTRING:"state" | 
|  | 254 [attrTypeAndValueSequence0_1] | 
|  | 255 type=OID:localityName | 
|  | 256 value=PRINTABLESTRING:" locality" | 
|  | 257 """, "ascii-PRINTABLESTRING-rdn_sorting_2") | 
|  | 258 | 
|  | 259   # Certs with a RDN that is sorted differently due to length of the values, and | 
|  | 260   # also contains multiple values with the same type. | 
|  | 261   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 262 [rdnSequence] | 
|  | 263 rdn0 = SET:rdnSet0 | 
|  | 264 [rdnSet0] | 
|  | 265 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 266 attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 | 
|  | 267 attrTypeAndValue2=SEQUENCE:attrTypeAndValueSequence0_2 | 
|  | 268 attrTypeAndValue3=SEQUENCE:attrTypeAndValueSequence0_3 | 
|  | 269 attrTypeAndValue4=SEQUENCE:attrTypeAndValueSequence0_4 | 
|  | 270 [attrTypeAndValueSequence0_0] | 
|  | 271 type=OID:domainComponent | 
|  | 272 value=IA5STRING:"     cOm" | 
|  | 273 [attrTypeAndValueSequence0_1] | 
|  | 274 type=OID:domainComponent | 
|  | 275 value=IA5STRING:"eXaMple" | 
|  | 276 [attrTypeAndValueSequence0_2] | 
|  | 277 type=OID:domainComponent | 
|  | 278 value=IA5STRING:"wWw" | 
|  | 279 [attrTypeAndValueSequence0_3] | 
|  | 280 type=OID:localityName | 
|  | 281 value=PRINTABLESTRING:"NEw" | 
|  | 282 [attrTypeAndValueSequence0_4] | 
|  | 283 type=OID:localityName | 
|  | 284 value=PRINTABLESTRING:"   yORk    " | 
|  | 285 """, "ascii-mixed-rdn_dupetype_sorting_1") | 
|  | 286 | 
|  | 287   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 288 [rdnSequence] | 
|  | 289 rdn0 = SET:rdnSet0 | 
|  | 290 [rdnSet0] | 
|  | 291 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 292 attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 | 
|  | 293 attrTypeAndValue2=SEQUENCE:attrTypeAndValueSequence0_2 | 
|  | 294 attrTypeAndValue3=SEQUENCE:attrTypeAndValueSequence0_3 | 
|  | 295 attrTypeAndValue4=SEQUENCE:attrTypeAndValueSequence0_4 | 
|  | 296 [attrTypeAndValueSequence0_0] | 
|  | 297 type=OID:domainComponent | 
|  | 298 value=IA5STRING:"cOM" | 
|  | 299 [attrTypeAndValueSequence0_1] | 
|  | 300 type=OID:domainComponent | 
|  | 301 value=IA5STRING:"eXampLE" | 
|  | 302 [attrTypeAndValueSequence0_2] | 
|  | 303 type=OID:domainComponent | 
|  | 304 value=IA5STRING:"    Www  " | 
|  | 305 [attrTypeAndValueSequence0_3] | 
|  | 306 type=OID:localityName | 
|  | 307 value=PRINTABLESTRING:"   nEw            " | 
|  | 308 [attrTypeAndValueSequence0_4] | 
|  | 309 type=OID:localityName | 
|  | 310 value=PRINTABLESTRING:"yoRK" | 
|  | 311 """, "ascii-mixed-rdn_dupetype_sorting_2") | 
|  | 312 | 
|  | 313   # Minimal valid config. Copy and modify this one when generating new invalid | 
|  | 314   # configs. | 
|  | 315   generate("""asn1 = SEQUENCE:rdnSequence | 
|  | 316 [rdnSequence] | 
|  | 317 rdn0 = SET:rdnSet0 | 
|  | 318 [rdnSet0] | 
|  | 319 attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 | 
|  | 320 [attrTypeAndValueSequence0_0] | 
|  | 321 type=OID:countryName | 
|  | 322 value=PRINTABLESTRING:"US" | 
|  | 323 """, "valid-minimal") | 
|  | 324 | 
|  | 325 if __name__ == '__main__': | 
|  | 326   main() | 
| OLD | NEW | 
|---|