Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 section = self.config.get_section('crl_ext') | 365 section = self.config.get_section('crl_ext') |
| 366 section.set_property('authorityKeyIdentifier', 'keyid:always') | 366 section.set_property('authorityKeyIdentifier', 'keyid:always') |
| 367 section.set_property('authorityInfoAccess', '@issuer_info') | 367 section.set_property('authorityInfoAccess', '@issuer_info') |
| 368 | 368 |
| 369 | 369 |
| 370 def data_to_pem(block_header, block_data): | 370 def data_to_pem(block_header, block_data): |
| 371 return '-----BEGIN %s-----\n%s\n-----END %s-----\n' % (block_header, | 371 return '-----BEGIN %s-----\n%s\n-----END %s-----\n' % (block_header, |
| 372 base64.b64encode(block_data), block_header) | 372 base64.b64encode(block_data), block_header) |
| 373 | 373 |
| 374 | 374 |
| 375 def write_test_file(description, chain, trusted_certs, utc_time, verify_result, | 375 class TrustAnchor(object): |
| 376 out_pem=None): | 376 """Structure that represents a trust anchor.""" |
| 377 """Writes a test file that contains all the inputs necessary to run a | |
| 378 verification on a certificate chain""" | |
| 379 | 377 |
| 380 # Prepend the script name that generated the file to the description. | 378 def __init__(self, cert, constrained=False): |
| 381 test_data = '[Created by: %s]\n\n%s\n' % (sys.argv[0], description) | 379 self.cert = cert |
| 380 self.constrained = constrained | |
| 382 | 381 |
| 383 # Write the certificate chain to the output file. | |
| 384 for cert in chain: | |
| 385 test_data += '\n' + cert.get_cert_pem() | |
| 386 | 382 |
| 387 # Write the trust store. | 383 class TestData(object): |
|
eroman
2016/08/11 01:02:30
Maybe this isn't idiomatic python.
But it felt a
eroman
2016/08/11 18:59:27
Quick update: I removed this unnecessary refactor
| |
| 388 for cert in trusted_certs: | 384 """Structure that represents the parameters of a test file.""" |
| 389 cert_data = cert.get_cert_pem() | 385 |
| 390 # Use a different block type in the .pem file. | 386 def __init__(self): |
| 391 cert_data = cert_data.replace('CERTIFICATE', 'TRUSTED_CERTIFICATE') | 387 # String describing the test. |
| 388 self.description = None | |
| 389 | |
| 390 # Ordered list of DER-encoded certificate bytes. | |
| 391 self.chain = None | |
| 392 | |
| 393 # An instance of TrustAnchor. | |
| 394 self.trust_anchor = None | |
| 395 | |
| 396 # A time when verification is to take place, encoded as UTCTime. | |
| 397 self.utc_time = None | |
| 398 | |
| 399 # Boolean for whether the chain is expected to pass verification. | |
| 400 self.verify_result = None | |
| 401 | |
| 402 | |
| 403 def write_to_file(self, path): | |
| 404 """Writes a test file that contains all the inputs necessary to run a | |
| 405 verification on a certificate chain""" | |
| 406 | |
| 407 # Prepend the script name that generated the file to the description. | |
| 408 test_data = '[Created by: %s]\n\n%s\n' % (sys.argv[0], self.description) | |
| 409 | |
| 410 # Write the certificate chain to the output file. | |
| 411 for cert in self.chain: | |
| 412 test_data += '\n' + cert.get_cert_pem() | |
| 413 | |
| 414 # Write the trust anchor. It is basicaly a certificate, but | |
| 415 # given a different block name depending on how it is to be | |
| 416 # interpreted. | |
| 417 cert_data = self.trust_anchor.cert.get_cert_pem() | |
| 418 block_name = 'TRUST_ANCHOR_' | |
| 419 if self.trust_anchor.constrained: | |
| 420 block_name += 'CONSTRAINED' | |
| 421 else: | |
| 422 block_name += 'UNCONSTRAINED' | |
| 423 cert_data = cert_data.replace('CERTIFICATE', 'TRUST_ANCHOR_UNCONSTRAINED') | |
| 392 test_data += '\n' + cert_data | 424 test_data += '\n' + cert_data |
| 393 | 425 |
| 394 test_data += '\n' + data_to_pem('TIME', utc_time) | 426 test_data += '\n' + data_to_pem('TIME', self.utc_time) |
| 395 | 427 |
| 396 verify_result_string = 'SUCCESS' if verify_result else 'FAIL' | 428 verify_result_string = 'SUCCESS' if self.verify_result else 'FAIL' |
| 397 test_data += '\n' + data_to_pem('VERIFY_RESULT', verify_result_string) | 429 test_data += '\n' + data_to_pem('VERIFY_RESULT', verify_result_string) |
| 398 | 430 |
| 399 write_string_to_file(test_data, out_pem if out_pem else g_out_pem) | 431 write_string_to_file(test_data, path) |
| 400 | 432 |
| 401 | 433 |
| 402 def write_string_to_file(data, path): | 434 def write_string_to_file(data, path): |
| 403 with open(path, 'w') as f: | 435 with open(path, 'w') as f: |
| 404 f.write(data) | 436 f.write(data) |
| 405 | 437 |
| 406 | 438 |
| 407 def init(invoking_script_path): | 439 def init(invoking_script_path): |
| 408 """Creates an output directory to contain all the temporary files that may be | 440 """Creates an output directory to contain all the temporary files that may be |
| 409 created, as well as determining the path for the final output. These paths | 441 created, as well as determining the path for the final output. These paths |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 435 return Certificate(name, TYPE_CA, None) | 467 return Certificate(name, TYPE_CA, None) |
| 436 | 468 |
| 437 | 469 |
| 438 def create_intermediate_certificate(name, issuer): | 470 def create_intermediate_certificate(name, issuer): |
| 439 return Certificate(name, TYPE_CA, issuer) | 471 return Certificate(name, TYPE_CA, issuer) |
| 440 | 472 |
| 441 | 473 |
| 442 def create_end_entity_certificate(name, issuer): | 474 def create_end_entity_certificate(name, issuer): |
| 443 return Certificate(name, TYPE_END_ENTITY, issuer) | 475 return Certificate(name, TYPE_END_ENTITY, issuer) |
| 444 | 476 |
| 477 | |
| 478 def get_default_pem_path(): | |
| 479 # TODO(eroman): remove this global. | |
| 480 return g_out_pem | |
| 481 | |
| 445 init(sys.argv[0]) | 482 init(sys.argv[0]) |
| OLD | NEW |