Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: net/data/verify_certificate_chain_unittest/common.py

Issue 2036033002: Add CertIssuerSourceAia: authorityInfoAccess fetching for CertPathBuilder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert-parsing-path-building
Patch Set: remove orphaned kw_args change, remove g_cur_path_id change from this cl Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/data/update_net_gypi.py ('k') | net/net.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2015 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Set of helpers to generate signed X.509v3 certificates. 6 """Set of helpers to generate signed X.509v3 certificates.
7 7
8 This works by shelling out calls to the 'openssl req' and 'openssl ca' 8 This works by shelling out calls to the 'openssl req' and 'openssl ca'
9 commands, and passing the appropriate command line flags and configuration file 9 commands, and passing the appropriate command line flags and configuration file
10 (.cnf). 10 (.cnf).
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 71
72 class Certificate(object): 72 class Certificate(object):
73 """Helper for building an X.509 certificate.""" 73 """Helper for building an X.509 certificate."""
74 74
75 def __init__(self, name, cert_type, issuer): 75 def __init__(self, name, cert_type, issuer):
76 # The name will be used for the subject's CN, and also as a component of 76 # The name will be used for the subject's CN, and also as a component of
77 # the temporary filenames to help with debugging. 77 # the temporary filenames to help with debugging.
78 self.name = name 78 self.name = name
79 self.path_id = GetUniquePathId(name) 79 self.path_id = GetUniquePathId(name)
80 80
81 # If specified, use the key from this path instead of generating a new one.
82 self.key_path = None
83
81 # The issuer is also a Certificate object. Passing |None| means it is a 84 # The issuer is also a Certificate object. Passing |None| means it is a
82 # self-signed certificate. 85 # self-signed certificate.
83 self.issuer = issuer 86 self.issuer = issuer
84 if issuer is None: 87 if issuer is None:
85 self.issuer = self 88 self.issuer = self
86 89
87 # The config contains all the OpenSSL options that will be passed via a 90 # The config contains all the OpenSSL options that will be passed via a
88 # .cnf file. Set up defaults. 91 # .cnf file. Set up defaults.
89 self.config = openssl_conf.Config() 92 self.config = openssl_conf.Config()
90 self.init_config() 93 self.init_config()
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 128
126 # Initialize any files that will be needed if this certificate is used to 129 # Initialize any files that will be needed if this certificate is used to
127 # sign other certificates. Starts off serial numbers at 1, and will 130 # sign other certificates. Starts off serial numbers at 1, and will
128 # increment them for each signed certificate. 131 # increment them for each signed certificate.
129 write_string_to_file('01\n', self.get_serial_path()) 132 write_string_to_file('01\n', self.get_serial_path())
130 write_string_to_file('', self.get_database_path()) 133 write_string_to_file('', self.get_database_path())
131 134
132 135
133 def generate_rsa_key(self, size_bits): 136 def generate_rsa_key(self, size_bits):
134 """Generates an RSA private key for the certificate.""" 137 """Generates an RSA private key for the certificate."""
138 assert self.key_path is None
135 subprocess.check_call( 139 subprocess.check_call(
136 ['openssl', 'genrsa', '-out', self.get_key_path(), str(size_bits)]) 140 ['openssl', 'genrsa', '-out', self.get_key_path(), str(size_bits)])
137 141
138 142
139 def generate_ec_key(self, named_curve): 143 def generate_ec_key(self, named_curve):
140 """Generates an EC private key for the certificate. |named_curve| can be 144 """Generates an EC private key for the certificate. |named_curve| can be
141 something like secp384r1""" 145 something like secp384r1"""
146 assert self.key_path is None
142 subprocess.check_call( 147 subprocess.check_call(
143 ['openssl', 'ecparam', '-out', self.get_key_path(), 148 ['openssl', 'ecparam', '-out', self.get_key_path(),
144 '-name', named_curve, '-genkey']) 149 '-name', named_curve, '-genkey'])
145 150
146 151
147 def set_validity_range(self, start_date, end_date): 152 def set_validity_range(self, start_date, end_date):
148 """Sets the Validity notBefore and notAfter properties for the 153 """Sets the Validity notBefore and notAfter properties for the
149 certificate""" 154 certificate"""
150 self.validity_flags = ['-startdate', start_date, '-enddate', end_date] 155 self.validity_flags = ['-startdate', start_date, '-enddate', end_date]
151 156
152 157
153 def set_signature_hash(self, md): 158 def set_signature_hash(self, md):
154 """Sets the hash function that will be used when signing this certificate. 159 """Sets the hash function that will be used when signing this certificate.
155 Can be sha1, sha256, sha512, md5, etc.""" 160 Can be sha1, sha256, sha512, md5, etc."""
156 self.md_flags = ['-md', md] 161 self.md_flags = ['-md', md]
157 162
158 163
159 def get_extensions(self): 164 def get_extensions(self):
160 return self.config.get_section('req_ext') 165 return self.config.get_section('req_ext')
161 166
162 167
163 def get_path(self, suffix): 168 def get_path(self, suffix):
164 """Forms a path to an output file for this certificate, containing the 169 """Forms a path to an output file for this certificate, containing the
165 indicated suffix. The certificate's name will be used as its basis.""" 170 indicated suffix. The certificate's name will be used as its basis."""
166 return os.path.join(g_out_dir, '%s%s' % (self.path_id, suffix)) 171 return os.path.join(g_out_dir, '%s%s' % (self.path_id, suffix))
167 172
168 173
174 def set_key_path(self, path):
175 """Uses the key from the given path instead of generating a new one."""
176 self.key_path = path
177 section = self.config.get_section('root_ca')
178 section.set_property('private_key', self.get_key_path())
179
180
169 def get_key_path(self): 181 def get_key_path(self):
182 if self.key_path is not None:
183 return self.key_path
170 return self.get_path('.key') 184 return self.get_path('.key')
171 185
172 186
173 def get_cert_path(self): 187 def get_cert_path(self):
174 return self.get_path('.pem') 188 return self.get_path('.pem')
175 189
176 190
177 def get_serial_path(self): 191 def get_serial_path(self):
178 return self.get_path('.serial') 192 return self.get_path('.serial')
179 193
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 section = self.config.get_section('crl_ext') 358 section = self.config.get_section('crl_ext')
345 section.set_property('authorityKeyIdentifier', 'keyid:always') 359 section.set_property('authorityKeyIdentifier', 'keyid:always')
346 section.set_property('authorityInfoAccess', '@issuer_info') 360 section.set_property('authorityInfoAccess', '@issuer_info')
347 361
348 362
349 def data_to_pem(block_header, block_data): 363 def data_to_pem(block_header, block_data):
350 return '-----BEGIN %s-----\n%s\n-----END %s-----\n' % (block_header, 364 return '-----BEGIN %s-----\n%s\n-----END %s-----\n' % (block_header,
351 base64.b64encode(block_data), block_header) 365 base64.b64encode(block_data), block_header)
352 366
353 367
354 def write_test_file(description, chain, trusted_certs, utc_time, verify_result): 368 def write_test_file(description, chain, trusted_certs, utc_time, verify_result,
369 out_pem=None):
355 """Writes a test file that contains all the inputs necessary to run a 370 """Writes a test file that contains all the inputs necessary to run a
356 verification on a certificate chain""" 371 verification on a certificate chain"""
357 372
358 # Prepend the script name that generated the file to the description. 373 # Prepend the script name that generated the file to the description.
359 test_data = '[Created by: %s]\n\n%s\n' % (sys.argv[0], description) 374 test_data = '[Created by: %s]\n\n%s\n' % (sys.argv[0], description)
360 375
361 # Write the certificate chain to the output file. 376 # Write the certificate chain to the output file.
362 for cert in chain: 377 for cert in chain:
363 test_data += '\n' + cert.get_cert_pem() 378 test_data += '\n' + cert.get_cert_pem()
364 379
365 # Write the trust store. 380 # Write the trust store.
366 for cert in trusted_certs: 381 for cert in trusted_certs:
367 cert_data = cert.get_cert_pem() 382 cert_data = cert.get_cert_pem()
368 # Use a different block type in the .pem file. 383 # Use a different block type in the .pem file.
369 cert_data = cert_data.replace('CERTIFICATE', 'TRUSTED_CERTIFICATE') 384 cert_data = cert_data.replace('CERTIFICATE', 'TRUSTED_CERTIFICATE')
370 test_data += '\n' + cert_data 385 test_data += '\n' + cert_data
371 386
372 test_data += '\n' + data_to_pem('TIME', utc_time) 387 test_data += '\n' + data_to_pem('TIME', utc_time)
373 388
374 verify_result_string = 'SUCCESS' if verify_result else 'FAIL' 389 verify_result_string = 'SUCCESS' if verify_result else 'FAIL'
375 test_data += '\n' + data_to_pem('VERIFY_RESULT', verify_result_string) 390 test_data += '\n' + data_to_pem('VERIFY_RESULT', verify_result_string)
376 391
377 write_string_to_file(test_data, g_out_pem) 392 write_string_to_file(test_data, out_pem if out_pem else g_out_pem)
378 393
379 394
380 def write_string_to_file(data, path): 395 def write_string_to_file(data, path):
381 with open(path, 'w') as f: 396 with open(path, 'w') as f:
382 f.write(data) 397 f.write(data)
383 398
384 399
385 def init(invoking_script_path): 400 def init(invoking_script_path):
386 """Creates an output directory to contain all the temporary files that may be 401 """Creates an output directory to contain all the temporary files that may be
387 created, as well as determining the path for the final output. These paths 402 created, as well as determining the path for the final output. These paths
(...skipping 26 matching lines...) Expand all
414 429
415 430
416 def create_intermediary_certificate(name, issuer): 431 def create_intermediary_certificate(name, issuer):
417 return Certificate(name, TYPE_CA, issuer) 432 return Certificate(name, TYPE_CA, issuer)
418 433
419 434
420 def create_end_entity_certificate(name, issuer): 435 def create_end_entity_certificate(name, issuer):
421 return Certificate(name, TYPE_END_ENTITY, issuer) 436 return Certificate(name, TYPE_END_ENTITY, issuer)
422 437
423 init(sys.argv[0]) 438 init(sys.argv[0])
OLDNEW
« no previous file with comments | « net/data/update_net_gypi.py ('k') | net/net.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698