1#!/usr/bin/env python
2# Copyright 2018 The Chromium Authors
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     https://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import sys
17sys.path += ['../..']
18
19import gencerts
20
21def add_excluded_name_constraints(cert, num_dns, num_ip, num_dirnames, num_uri):
22  cert.get_extensions().set_property('nameConstraints', '@nameConstraints_info')
23  constraints = cert.config.get_section('nameConstraints_info')
24  for i in range(num_dns):
25    constraints.set_property('excluded;DNS.%i' % (i + 1), 'x%i.test' % i)
26  for i in range(num_ip):
27    b,c = divmod(i, 256)
28    a,b = divmod(b, 256)
29    constraints.set_property('excluded;IP.%i' % (i + 1),
30                             '11.%i.%i.%i/255.255.255.255' % (a, b, c))
31  for i in range(num_dirnames):
32    section_name = 'nameConstraints_dirname_x%i' % (i + 1)
33    dirname = cert.config.get_section(section_name)
34    dirname.set_property('commonName', '"x%i' % i)
35    constraints.set_property('excluded;dirName.%i' % (i + 1), section_name)
36  for i in range(num_uri):
37    constraints.set_property('excluded;URI.%i' % (i + 1), 'http://xest/%i' % i)
38
39
40def add_permitted_name_constraints(
41    cert, num_dns, num_ip, num_dirnames, num_uri):
42  cert.get_extensions().set_property('nameConstraints', '@nameConstraints_info')
43  constraints = cert.config.get_section('nameConstraints_info')
44  for i in range(num_dns):
45    constraints.set_property('permitted;DNS.%i' % (i + 1), 't%i.test' % i)
46  for i in range(num_ip):
47    b,c = divmod(i, 256)
48    a,b = divmod(b, 256)
49    constraints.set_property('permitted;IP.%i' % (i + 1),
50                             '10.%i.%i.%i/255.255.255.255' % (a, b, c))
51  for i in range(num_dirnames):
52    section_name = 'nameConstraints_dirname_p%i' % (i + 1)
53    dirname = cert.config.get_section(section_name)
54    dirname.set_property('commonName', '"t%i' % i)
55    constraints.set_property('permitted;dirName.%i' % (i + 1), section_name)
56  for i in range(num_uri):
57    constraints.set_property('permitted;URI.%i' % (i + 1),
58                               'http://test/%i' % i)
59
60
61def add_sans(cert, num_dns, num_ip, num_dirnames, num_uri):
62  cert.get_extensions().set_property('subjectAltName', '@san_info')
63  sans = cert.config.get_section('san_info')
64  for i in range(num_dns):
65    sans.set_property('DNS.%i' % (i + 1), 't%i.test' % i)
66  for i in range(num_ip):
67    b,c = divmod(i, 256)
68    a,b = divmod(b, 256)
69    sans.set_property('IP.%i' % (i + 1), '10.%i.%i.%i' % (a, b, c))
70  for i in range(num_dirnames):
71    section_name = 'san_dirname%i' % (i + 1)
72    dirname = cert.config.get_section(section_name)
73    dirname.set_property('commonName', '"t%i' % i)
74    sans.set_property('dirName.%i' % (i + 1), section_name)
75  for i in range(num_uri):
76    sans.set_property('URI.%i' % (i + 1), 'http://test/%i' % i)
77
78
79# Self-signed root certificate.
80root = gencerts.create_self_signed_root_certificate('Root')
81
82# Use the same keys for all the chains. Fewer key files to check in, and also
83# gives stability against re-ordering of the calls to |make_chain|.
84intermediate_key = gencerts.get_or_generate_rsa_key(
85    2048, gencerts.create_key_path('Intermediate'))
86target_key = gencerts.get_or_generate_rsa_key(
87    2048, gencerts.create_key_path('t0'))
88
89def make_chain(name, doc, excluded, permitted, sans):
90  # Intermediate certificate.
91  intermediate = gencerts.create_intermediate_certificate('Intermediate', root)
92  intermediate.set_key(intermediate_key)
93  add_excluded_name_constraints(intermediate, **excluded)
94  add_permitted_name_constraints(intermediate, **permitted)
95
96  # Target certificate.
97  target = gencerts.create_end_entity_certificate('t0', intermediate)
98  target.set_key(target_key)
99  add_sans(target, **sans)
100
101  chain = [target, intermediate, root]
102  gencerts.write_chain(doc, chain, '%s.pem' % name)
103
104
105make_chain('ok-all-types',
106           "A chain containing a large number of name constraints and names,\n"
107           "but below the limit.",
108           excluded=dict(num_dns=170,
109                         num_ip=170,
110                         num_dirnames=170,
111                         num_uri=1025),
112           permitted=dict(num_dns=171,
113                          num_ip=171,
114                          num_dirnames=172,
115                          num_uri=1025),
116           sans=dict(num_dns=341, num_ip=341, num_dirnames=342, num_uri=1025))
117
118make_chain('toomany-all-types',
119           "A chain containing a large number of different types of name\n"
120           "constraints and names, above the limit.",
121           excluded=dict(num_dns=170, num_ip=170, num_dirnames=170, num_uri=0),
122           permitted=dict(num_dns=172, num_ip=171, num_dirnames=172, num_uri=0),
123           sans=dict(num_dns=342, num_ip=341, num_dirnames=341, num_uri=0))
124
125make_chain(
126    'toomany-dns-excluded',
127    "A chain containing a large number of excluded DNS name\n"
128    "constraints and DNS names, above the limit.",
129    excluded=dict(num_dns=1025, num_ip=0, num_dirnames=0, num_uri=0),
130    permitted=dict(num_dns=0, num_ip=0, num_dirnames=0, num_uri=0),
131    sans=dict(num_dns=1024, num_ip=0, num_dirnames=0, num_uri=0))
132make_chain(
133    'toomany-ips-excluded',
134    "A chain containing a large number of excluded IP name\n"
135    "constraints and IP names, above the limit.",
136    excluded=dict(num_dns=0, num_ip=1025, num_dirnames=0, num_uri=0),
137    permitted=dict(num_dns=0, num_ip=0, num_dirnames=0, num_uri=0),
138    sans=dict(num_dns=0, num_ip=1024, num_dirnames=0, num_uri=0))
139make_chain(
140    'toomany-dirnames-excluded',
141    "A chain containing a large number of excluded directory name\n"
142    "constraints and directory names, above the limit.",
143    excluded=dict(num_dns=0, num_ip=0, num_dirnames=1025, num_uri=0),
144    permitted=dict(num_dns=0, num_ip=0, num_dirnames=0, num_uri=0),
145    sans=dict(num_dns=0, num_ip=0, num_dirnames=1024, num_uri=0))
146
147make_chain(
148    'toomany-dns-permitted',
149    "A chain containing a large number of permitted DNS name\n"
150    "constraints and DNS names, above the limit.",
151    excluded=dict(num_dns=0, num_ip=0, num_dirnames=0, num_uri=0),
152    permitted=dict(num_dns=1025, num_ip=0, num_dirnames=0, num_uri=0),
153    sans=dict(num_dns=1024, num_ip=0, num_dirnames=0, num_uri=0))
154make_chain(
155    'toomany-ips-permitted',
156    "A chain containing a large number of permitted IP name\n"
157    "constraints and IP names, above the limit.",
158    excluded=dict(num_dns=0, num_ip=0, num_dirnames=0, num_uri=0),
159    permitted=dict(num_dns=0, num_ip=1025, num_dirnames=0, num_uri=0),
160    sans=dict(num_dns=0, num_ip=1024, num_dirnames=0, num_uri=0))
161make_chain(
162    'toomany-dirnames-permitted',
163    "A chain containing a large number of permitted directory name\n"
164    "constraints and directory names, above the limit.",
165    excluded=dict(num_dns=0, num_ip=0, num_dirnames=0, num_uri=0),
166    permitted=dict(num_dns=0, num_ip=0, num_dirnames=1025, num_uri=0),
167    sans=dict(num_dns=0, num_ip=0, num_dirnames=1024, num_uri=0))
168