Index: net/data/verify_name_match_unittest/scripts/generate-names.py |
diff --git a/net/data/verify_name_match_unittest/scripts/generate-names.py b/net/data/verify_name_match_unittest/scripts/generate-names.py |
new file mode 100755 |
index 0000000000000000000000000000000000000000..ea0e0fd14541988bf7c81f118b3e6773de497315 |
--- /dev/null |
+++ b/net/data/verify_name_match_unittest/scripts/generate-names.py |
@@ -0,0 +1,326 @@ |
+#!/usr/bin/env python |
+# Copyright 2015 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. |
+ |
+import base64 |
+import copy |
+import os |
+import subprocess |
+import tempfile |
+ |
+ |
+class RDN: |
+ def __init__(self): |
+ self.attrs = [] |
+ |
+ def add_attr(self, attr_type, attr_value_type, attr_value, |
+ attr_modifier=None): |
+ self.attrs.append((attr_type, attr_value_type, attr_value, attr_modifier)) |
+ return self |
+ |
+ def __str__(self): |
+ s = '' |
+ for n, attr in enumerate(self.attrs): |
+ s += 'attrTypeAndValue%i=SEQUENCE:attrTypeAndValueSequence%i_%i\n' % ( |
+ n, id(self), n) |
+ |
+ s += '\n' |
+ for n, attr in enumerate(self.attrs): |
+ attr_type, attr_value_type, attr_value, attr_modifier = attr |
+ s += '[attrTypeAndValueSequence%i_%i]\n' % (id(self), n) |
+ # Note the quotes around the string value here, which is necessary for |
+ # trailing whitespace to be included by openssl. |
+ s += 'type=OID:%s\n' % attr_type |
+ s += 'value=' |
+ if attr_modifier: |
+ s += attr_modifier + ',' |
+ s += '%s:"%s"\n' % (attr_value_type, attr_value) |
+ |
+ return s |
+ |
+ |
+class NameGenerator: |
+ def __init__(self): |
+ self.rdns = [] |
+ |
+ def add_rdn(self): |
+ rdn = RDN() |
+ self.rdns.append(rdn) |
+ return rdn |
+ |
+ def __str__(self): |
+ s = 'asn1 = SEQUENCE:rdnSequence\n\n[rdnSequence]\n' |
+ for n, rdn in enumerate(self.rdns): |
+ s += 'rdn%i = SET:rdnSet%i\n' % (n, n) |
+ |
+ s += '\n' |
+ |
+ for n, rdn in enumerate(self.rdns): |
+ s += '[rdnSet%i]\n%s\n' % (n, rdn) |
+ |
+ return s |
+ |
+ |
+def generate(s, fn): |
+ out_fn = os.path.join('..', 'names', fn + '.pem') |
+ conf_tempfile = tempfile.NamedTemporaryFile() |
+ conf_tempfile.write(str(s)) |
+ conf_tempfile.flush() |
+ der_tmpfile = tempfile.NamedTemporaryFile() |
+ description_tmpfile = tempfile.NamedTemporaryFile() |
+ subprocess.check_call(['openssl', 'asn1parse', '-genconf', conf_tempfile.name, |
+ '-i', '-out', der_tmpfile.name], |
+ stdout=description_tmpfile) |
+ conf_tempfile.close() |
+ |
+ output_file = open(out_fn, 'w') |
+ description_tmpfile.seek(0) |
+ output_file.write(description_tmpfile.read()) |
+ output_file.write('-----BEGIN NAME-----\n') |
+ output_file.write(base64.encodestring(der_tmpfile.read())) |
+ output_file.write('-----END NAME-----\n') |
+ output_file.close() |
+ |
+ |
+def unmangled(s): |
+ return s |
+ |
+ |
+def extra_whitespace(s): |
+ return ' ' + s.replace(' ', ' ') + ' ' |
+ |
+ |
+def case_swap(s): |
+ return s.swapcase() |
+ |
+ |
+def main(): |
+ for valuetype in ('PRINTABLESTRING', 'T61STRING', 'UTF8', 'BMPSTRING', |
+ 'UNIVERSALSTRING'): |
+ for string_mangler in (unmangled, extra_whitespace, case_swap): |
+ n=NameGenerator() |
+ n.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'US') |
+ n.add_rdn().add_attr('stateOrProvinceName', |
+ valuetype, |
+ string_mangler('New York')) |
+ n.add_rdn().add_attr('localityName', |
+ valuetype, |
+ string_mangler("ABCDEFGHIJKLMNOPQRSTUVWXYZ " |
+ "abcdefghijklmnopqrstuvwxyz " |
+ "0123456789 '()+,-./:=?")) |
+ |
+ n_extra_attr = copy.deepcopy(n) |
+ n_extra_attr.rdns[-1].add_attr('organizationName', |
+ valuetype, |
+ string_mangler('Name of company')) |
+ |
+ n_extra_rdn = copy.deepcopy(n) |
+ n_extra_rdn.add_rdn().add_attr('organizationName', |
+ valuetype, |
+ string_mangler('Name of company')) |
+ |
+ filename_base = 'ascii-' + valuetype + '-' + string_mangler.__name__ |
+ |
+ generate(n, filename_base) |
+ generate(n_extra_attr, filename_base + '-extra_attr') |
+ generate(n_extra_rdn, filename_base + '-extra_rdn') |
+ |
+ for valuetype in ('UTF8', 'BMPSTRING', 'UNIVERSALSTRING'): |
+ n=NameGenerator() |
+ n.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'JP') |
+ n.add_rdn().add_attr('localityName', |
+ valuetype, |
+ "\xe6\x9d\xb1\xe4\xba\xac", |
+ "FORMAT:UTF8") |
+ |
+ filename_base = 'unicode_bmp-' + valuetype + '-' + 'unmangled' |
+ generate(n, filename_base) |
+ |
+ for valuetype in ('UTF8', 'UNIVERSALSTRING'): |
+ n=NameGenerator() |
+ n.add_rdn().add_attr('countryName', 'PRINTABLESTRING', 'JP') |
+ n.add_rdn().add_attr('localityName', |
+ valuetype, |
+ "\xf0\x9d\x90\x80\xf0\x9d\x90\x99", |
+ "FORMAT:UTF8") |
+ |
+ filename_base = 'unicode_supplementary-' + valuetype + '-' + 'unmangled' |
+ generate(n, filename_base) |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+type=OID:countryName |
+value=PRINTABLESTRING:"US" |
+extra=PRINTABLESTRING:"hello world" |
+""", "invalid-AttributeTypeAndValue-extradata") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+type=OID:countryName |
+""", "invalid-AttributeTypeAndValue-onlyOneElement") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+""", "invalid-AttributeTypeAndValue-empty") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+type=PRINTABLESTRING:"hello world" |
+value=PRINTABLESTRING:"US" |
+""", "invalid-AttributeTypeAndValue-badAttributeType") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SET:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+type=OID:countryName |
+value=PRINTABLESTRING:"US" |
+""", "invalid-AttributeTypeAndValue-setNotSequence") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SEQUENCE:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+type=OID:countryName |
+value=PRINTABLESTRING:"US" |
+""", "invalid-RDN-sequenceInsteadOfSet") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+""", "invalid-RDN-empty") |
+ |
+ generate("""asn1 = SET:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+type=OID:countryName |
+value=PRINTABLESTRING:"US" |
+""", "invalid-Name-setInsteadOfSequence") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+""", "valid-Name-empty") |
+ |
+ # Certs with a RDN that is sorted differently due to length of the values, but |
+ # which should compare equal when normalized. |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 |
+[attrTypeAndValueSequence0_0] |
+type=OID:stateOrProvinceName |
+value=PRINTABLESTRING:" state" |
+[attrTypeAndValueSequence0_1] |
+type=OID:localityName |
+value=PRINTABLESTRING:"locality" |
+""", "ascii-PRINTABLESTRING-rdn_sorting_1") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 |
+[attrTypeAndValueSequence0_0] |
+type=OID:stateOrProvinceName |
+value=PRINTABLESTRING:"state" |
+[attrTypeAndValueSequence0_1] |
+type=OID:localityName |
+value=PRINTABLESTRING:" locality" |
+""", "ascii-PRINTABLESTRING-rdn_sorting_2") |
+ |
+ # Certs with a RDN that is sorted differently due to length of the values, and |
+ # also contains multiple values with the same type. |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 |
+attrTypeAndValue2=SEQUENCE:attrTypeAndValueSequence0_2 |
+attrTypeAndValue3=SEQUENCE:attrTypeAndValueSequence0_3 |
+attrTypeAndValue4=SEQUENCE:attrTypeAndValueSequence0_4 |
+[attrTypeAndValueSequence0_0] |
+type=OID:domainComponent |
+value=IA5STRING:" cOm" |
+[attrTypeAndValueSequence0_1] |
+type=OID:domainComponent |
+value=IA5STRING:"eXaMple" |
+[attrTypeAndValueSequence0_2] |
+type=OID:domainComponent |
+value=IA5STRING:"wWw" |
+[attrTypeAndValueSequence0_3] |
+type=OID:localityName |
+value=PRINTABLESTRING:"NEw" |
+[attrTypeAndValueSequence0_4] |
+type=OID:localityName |
+value=PRINTABLESTRING:" yORk " |
+""", "ascii-mixed-rdn_dupetype_sorting_1") |
+ |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+attrTypeAndValue1=SEQUENCE:attrTypeAndValueSequence0_1 |
+attrTypeAndValue2=SEQUENCE:attrTypeAndValueSequence0_2 |
+attrTypeAndValue3=SEQUENCE:attrTypeAndValueSequence0_3 |
+attrTypeAndValue4=SEQUENCE:attrTypeAndValueSequence0_4 |
+[attrTypeAndValueSequence0_0] |
+type=OID:domainComponent |
+value=IA5STRING:"cOM" |
+[attrTypeAndValueSequence0_1] |
+type=OID:domainComponent |
+value=IA5STRING:"eXampLE" |
+[attrTypeAndValueSequence0_2] |
+type=OID:domainComponent |
+value=IA5STRING:" Www " |
+[attrTypeAndValueSequence0_3] |
+type=OID:localityName |
+value=PRINTABLESTRING:" nEw " |
+[attrTypeAndValueSequence0_4] |
+type=OID:localityName |
+value=PRINTABLESTRING:"yoRK" |
+""", "ascii-mixed-rdn_dupetype_sorting_2") |
+ |
+ # Minimal valid config. Copy and modify this one when generating new invalid |
+ # configs. |
+ generate("""asn1 = SEQUENCE:rdnSequence |
+[rdnSequence] |
+rdn0 = SET:rdnSet0 |
+[rdnSet0] |
+attrTypeAndValue0=SEQUENCE:attrTypeAndValueSequence0_0 |
+[attrTypeAndValueSequence0_0] |
+type=OID:countryName |
+value=PRINTABLESTRING:"US" |
+""", "valid-minimal") |
+ |
+if __name__ == '__main__': |
+ main() |