# Copyright 2017 Google LLC. All Rights Reserved. import base64 import datetime import os import shutil import StringIO import tempfile import textwrap import unittest from cryptography import x509 from cryptography.hazmat import backends from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding from cryptography.x509 import oid import oem_certificate import oem_certificate_test_helper as oem_cert_test_helper class ArgParseObject(object): """A convenient object to allow adding arbitrary attribute to it.""" pass class OemCertificateTest(unittest.TestCase): def test_widevine_system_id(self): system_id = 1234567890123 self.assertEqual( oem_certificate.WidevineSystemId.from_int_value(system_id).int_value(), system_id) def test_generate_csr(self): args = oem_cert_test_helper.setup_csr_args() oem_certificate.generate_csr(args) # Verify CSR. csr = x509.load_pem_x509_csr(args.output_csr_file.getvalue(), backends.default_backend()) subject = csr.subject self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.COUNTRY_NAME)[0].value, args.country_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.STATE_OR_PROVINCE_NAME)[0] .value, args.state_or_province_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.LOCALITY_NAME)[0].value, args.locality_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.ORGANIZATION_NAME)[0].value, args.organization_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0] .value, args.organizational_unit_name) self.assertEqual( len(subject.get_attributes_for_oid(oid.NameOID.COMMON_NAME)), 0) private_key = serialization.load_der_private_key( args.output_private_key_file.getvalue(), args.passphrase, backend=backends.default_backend()) self.assertEqual(private_key.key_size, args.key_size) self.assertEqual(csr.public_key().key_size, args.key_size) # Verify csr and private key match. self.assertEqual(csr.public_key().public_numbers(), private_key.public_key().public_numbers()) def test_generate_csr_(self): args = oem_cert_test_helper.setup_csr_args(common_name='MyCommonName') oem_certificate.generate_csr(args) # Verify CSR. csr = x509.load_pem_x509_csr(args.output_csr_file.getvalue(), backends.default_backend()) subject = csr.subject self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.COUNTRY_NAME)[0].value, args.country_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.STATE_OR_PROVINCE_NAME)[0] .value, args.state_or_province_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.LOCALITY_NAME)[0].value, args.locality_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.ORGANIZATION_NAME)[0].value, args.organization_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0] .value, args.organizational_unit_name) self.assertEqual( subject.get_attributes_for_oid(oid.NameOID.COMMON_NAME)[0] .value, args.common_name) private_key = serialization.load_der_private_key( args.output_private_key_file.getvalue(), args.passphrase, backend=backends.default_backend()) self.assertEqual(private_key.key_size, args.key_size) self.assertEqual(csr.public_key().key_size, args.key_size) # Verify csr and private key match. self.assertEqual(csr.public_key().public_numbers(), private_key.public_key().public_numbers()) def test_generate_csr_with_keysize4096_and_passphrase(self): args = oem_cert_test_helper.setup_csr_args( key_size=4096, passphrase='passphrase_4096') oem_certificate.generate_csr(args) private_key = serialization.load_der_private_key( args.output_private_key_file.getvalue(), 'passphrase_4096', backend=backends.default_backend()) csr = x509.load_pem_x509_csr(args.output_csr_file.getvalue(), backends.default_backend()) self.assertEqual(private_key.key_size, 4096) self.assertEqual(csr.public_key().key_size, 4096) # Verify csr and private key match. self.assertEqual(csr.public_key().public_numbers(), private_key.public_key().public_numbers()) def test_generate_intermediate_certificate(self): csr_args = oem_cert_test_helper.setup_csr_args() oem_certificate.generate_csr(csr_args) csr_bytes = csr_args.output_csr_file.getvalue() csr = x509.load_pem_x509_csr(csr_bytes, backends.default_backend()) root_key, root_certificate = ( oem_cert_test_helper.create_root_certificate_and_key()) args = oem_cert_test_helper.setup_intermediate_cert_args( csr_bytes, root_key, root_certificate) oem_certificate.generate_intermediate_certificate(args) cert = x509.load_der_x509_certificate( args.output_certificate_file.getvalue(), backends.default_backend()) self.assertEqual(cert.issuer, root_certificate.subject) self.assertEqual(cert.subject, csr.subject) system_id_raw_bytes = cert.extensions.get_extension_for_oid( oem_certificate.WidevineSystemId.oid).value.value self.assertEqual( oem_certificate.WidevineSystemId(system_id_raw_bytes).int_value(), args.system_id) self.assertEqual(cert.not_valid_before, datetime.datetime(2001, 8, 9)) self.assertEqual(cert.not_valid_after, datetime.datetime(2001, 11, 17)) root_key.public_key().verify(cert.signature, cert.tbs_certificate_bytes, padding.PKCS1v15(), cert.signature_hash_algorithm) def test_generate_intermediate_with_cert_mismatch_root_cert_and_key(self): root_key1, _ = ( oem_cert_test_helper.create_root_certificate_and_key()) _, root_certificate2 = oem_cert_test_helper.create_root_certificate_and_key( ) args = oem_cert_test_helper.setup_intermediate_cert_args( 'some csr data', root_key1, root_certificate2) with self.assertRaises(ValueError) as context: oem_certificate.generate_intermediate_certificate(args) self.assertTrue('certificate does not match' in str(context.exception)) def test_generate_leaf_certificate_from_pem_intermediate_cert(self): intermediate_key_bytes, intermediate_certificate_bytes = ( oem_cert_test_helper.create_intermediate_certificate_and_key_bytes( pem_format=True)) args = oem_cert_test_helper.setup_leaf_cert_args( intermediate_key_bytes, intermediate_certificate_bytes) oem_certificate.generate_leaf_certificate(args) certificate_chain = oem_certificate.X509CertificateChain.load_der( args.output_certificate_file.getvalue()) certificates = list(certificate_chain) self.assertEqual(len(certificates), 2) intermediate_cert = certificates[1] leaf_cert = certificates[0] self.assertEqual( intermediate_cert.public_bytes(serialization.Encoding.PEM), intermediate_certificate_bytes) intermediate_cert.public_key().verify(leaf_cert.signature, leaf_cert.tbs_certificate_bytes, padding.PKCS1v15(), leaf_cert.signature_hash_algorithm) self.assertEqual(leaf_cert.not_valid_before, datetime.datetime(2001, 8, 9)) self.assertEqual(leaf_cert.not_valid_after, datetime.datetime(2023, 7, 5)) system_id_raw_bytes = leaf_cert.extensions.get_extension_for_oid( oem_certificate.WidevineSystemId.oid).value.value self.assertEqual( oem_certificate.WidevineSystemId(system_id_raw_bytes).int_value(), 2001) leaf_key = serialization.load_der_private_key( args.output_private_key_file.getvalue(), args.passphrase, backend=backends.default_backend()) self.assertEqual(leaf_key.key_size, args.key_size) self.assertEqual(leaf_cert.public_key().key_size, args.key_size) # Verify cert and private key match. self.assertEqual(leaf_cert.public_key().public_numbers(), leaf_key.public_key().public_numbers()) def test_generate_leaf_certificate_from_der_intermediate_cert(self): intermediate_key_bytes, intermediate_certificate_bytes = ( oem_cert_test_helper.create_intermediate_certificate_and_key_bytes( pem_format=False)) args = oem_cert_test_helper.setup_leaf_cert_args( intermediate_key_bytes, intermediate_certificate_bytes) oem_certificate.generate_leaf_certificate(args) certificate_chain = oem_certificate.X509CertificateChain.load_der( args.output_certificate_file.getvalue()) certificates = list(certificate_chain) self.assertEqual(len(certificates), 2) intermediate_cert = certificates[1] leaf_cert = certificates[0] self.assertEqual( intermediate_cert.public_bytes(serialization.Encoding.DER), intermediate_certificate_bytes) intermediate_cert.public_key().verify(leaf_cert.signature, leaf_cert.tbs_certificate_bytes, padding.PKCS1v15(), leaf_cert.signature_hash_algorithm) def test_generate_leaf_certificate_with_keysize4096_and_passphrase(self): intermediate_key_bytes, intermediate_certificate_bytes = ( oem_cert_test_helper.create_intermediate_certificate_and_key_bytes()) args = oem_cert_test_helper.setup_leaf_cert_args( intermediate_key_bytes, intermediate_certificate_bytes, key_size=4096, passphrase='leaf passphrase') oem_certificate.generate_leaf_certificate(args) leaf_key = serialization.load_der_private_key( args.output_private_key_file.getvalue(), 'leaf passphrase', backend=backends.default_backend()) self.assertEqual(4096, leaf_key.key_size) def test_get_csr_info(self): args = oem_cert_test_helper.setup_csr_args() oem_certificate.generate_csr(args) args.file = StringIO.StringIO(args.output_csr_file.getvalue()) output = StringIO.StringIO() oem_certificate.get_info(args, output) expected_info = """\ CSR Subject Name: , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Key Size: 4096""" self.assertEqual(output.getvalue(), textwrap.dedent(expected_info)) def test_get_pem_certificate_info(self): _, intermediate_certificate_bytes = ( oem_cert_test_helper.create_intermediate_certificate_and_key_bytes( pem_format=True)) args = ArgParseObject() args.file = StringIO.StringIO(intermediate_certificate_bytes) output = StringIO.StringIO() oem_certificate.get_info(args, output) expected_info = """\ Certificate Subject Name: , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Issuer Name: , value=u'root_cert')> Key Size: 4096 Widevine System Id: 2001 Not valid before: 2001-08-09 00:00:00 Not valid after: 2001-11-17 00:00:00""" self.assertEqual(output.getvalue(), textwrap.dedent(expected_info)) def test_get_der_certificate_info(self): _, intermediate_certificate_bytes = ( oem_cert_test_helper.create_intermediate_certificate_and_key_bytes( pem_format=False)) args = ArgParseObject() args.file = StringIO.StringIO(intermediate_certificate_bytes) output = StringIO.StringIO() oem_certificate.get_info(args, output) expected_info = """\ Certificate Subject Name: , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Issuer Name: , value=u'root_cert')> Key Size: 4096 Widevine System Id: 2001 Not valid before: 2001-08-09 00:00:00 Not valid after: 2001-11-17 00:00:00""" self.assertEqual(output.getvalue(), textwrap.dedent(expected_info)) def test_get_certificate_chain_info(self): intermediate_key_bytes, intermediate_certificate_bytes = ( oem_cert_test_helper.create_intermediate_certificate_and_key_bytes()) args = oem_cert_test_helper.setup_leaf_cert_args( intermediate_key_bytes, intermediate_certificate_bytes) oem_certificate.generate_leaf_certificate(args) args.file = StringIO.StringIO(args.output_certificate_file.getvalue()) output = StringIO.StringIO() oem_certificate.get_info(args, output) expected_info = """\ Certificate Subject Name: , value=u'2001-leaf')> , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Issuer Name: , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Key Size: 1024 Widevine System Id: 2001 Not valid before: 2001-08-09 00:00:00 Not valid after: 2023-07-05 00:00:00 Certificate Subject Name: , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Issuer Name: , value=u'root_cert')> Key Size: 4096 Widevine System Id: 2001 Not valid before: 2001-08-09 00:00:00 Not valid after: 2001-11-17 00:00:00""" self.assertEqual(output.getvalue(), textwrap.dedent(expected_info)) def test_get_certificate_chain_info_fixed_input(self): # This was generated from args.output_certificate_file in the test above. data_b64 = ( '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' 'vpWbEO7UpHHdfvWe9DEBODFbyXMxAA==') args = oem_cert_test_helper.ArgParseObject() args.file = StringIO.StringIO(base64.b64decode(data_b64)) output = StringIO.StringIO() oem_certificate.get_info(args, output) expected_info = """\ Certificate Subject Name: , value=u'2001-leaf')> , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Issuer Name: , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Key Size: 1024 Widevine System Id: 2001 Not valid before: 2001-08-09 00:00:00 Not valid after: 2023-07-05 00:00:00 Certificate Subject Name: , value=u'US')> , value=u'WA')> , value=u'Kirkland')> , value=u'CompanyXYZ')> , value=u'ContentProtection')> Issuer Name: , value=u'root_cert')> Key Size: 4096 Widevine System Id: 2001 Not valid before: 2001-08-09 00:00:00 Not valid after: 2001-11-17 00:00:00""" self.assertEqual(output.getvalue(), textwrap.dedent(expected_info)) def test_secure_erase(self): args = ArgParseObject() args.file = tempfile.NamedTemporaryFile(delete=False) args.passes = 2 self.assertTrue(os.path.exists(args.file.name)) oem_certificate.secure_erase(args) self.assertFalse(os.path.exists(args.file.name)) class OemCertificateArgParseTest(unittest.TestCase): def setUp(self): self.parser = oem_certificate.create_parser() self.test_dir = tempfile.mkdtemp() def tearDown(self): shutil.rmtree(self.test_dir) def test_generate_csr(self): cmds = ('generate_csr --key_size 4096 -C USA -ST WA ' '-L Kirkland -O Company -OU Widevine').split() output_private_key_file = os.path.join(self.test_dir, 'private_key') output_csr_file = os.path.join(self.test_dir, 'csr') cmds.extend([ '--output_csr_file', output_csr_file, '--output_private_key_file', output_private_key_file, '--passphrase', 'pass' ]) args = self.parser.parse_args(cmds) self.assertEqual(args.key_size, 4096) self.assertEqual(args.country_name, 'USA') self.assertEqual(args.state_or_province_name, 'WA') self.assertEqual(args.locality_name, 'Kirkland') self.assertEqual(args.organization_name, 'Company') self.assertEqual(args.organizational_unit_name, 'Widevine') self.assertEqual(args.output_csr_file.name, output_csr_file) self.assertEqual(args.output_csr_file.mode, 'wb') self.assertEqual(args.output_private_key_file.name, output_private_key_file) self.assertEqual(args.output_private_key_file.mode, 'wb') self.assertEqual(args.passphrase, 'pass') self.assertEqual(args.func, oem_certificate.generate_csr) self.assertIsNone(args.common_name) def test_generate_csr_with_cn(self): cmds = ('generate_csr --key_size 4096 -C USA -ST WA ' '-L Kirkland -O Company -OU Widevine -CN MyCommonName').split() output_private_key_file = os.path.join(self.test_dir, 'private_key') output_csr_file = os.path.join(self.test_dir, 'csr') cmds.extend([ '--output_csr_file', output_csr_file, '--output_private_key_file', output_private_key_file, '--passphrase', 'pass' ]) args = self.parser.parse_args(cmds) self.assertEqual(args.key_size, 4096) self.assertEqual(args.country_name, 'USA') self.assertEqual(args.state_or_province_name, 'WA') self.assertEqual(args.locality_name, 'Kirkland') self.assertEqual(args.organization_name, 'Company') self.assertEqual(args.organizational_unit_name, 'Widevine') self.assertEqual(args.output_csr_file.name, output_csr_file) self.assertEqual(args.output_csr_file.mode, 'wb') self.assertEqual(args.output_private_key_file.name, output_private_key_file) self.assertEqual(args.output_private_key_file.mode, 'wb') self.assertEqual(args.passphrase, 'pass') self.assertEqual(args.common_name, 'MyCommonName') self.assertEqual(args.func, oem_certificate.generate_csr) def _fill_file_with_dummy_contents(self, file_name): with open(file_name, 'wb') as f: f.write('dummy') def test_generate_csr_invalid_key_size(self): cmds = ('generate_csr --key_size unknown -C USA -ST WA ' '-L Kirkland -O Company -OU Widevine').split() output_private_key_file = os.path.join(self.test_dir, 'private_key') output_csr_file = os.path.join(self.test_dir, 'csr') cmds.extend([ '--output_csr_file', output_csr_file, '--output_private_key_file', output_private_key_file, '--passphrase', 'pass' ]) with self.assertRaises(SystemExit) as context: self.parser.parse_args(cmds) self.assertEqual(context.exception.code, 2) def test_generate_intermediate_cert(self): cmds = ( 'generate_intermediate_certificate --valid_duration 10 --system_id 100' ).split() csr_file = os.path.join(self.test_dir, 'csr') self._fill_file_with_dummy_contents(csr_file) root_certificate_file = os.path.join(self.test_dir, 'root_cert') self._fill_file_with_dummy_contents(root_certificate_file) root_private_key_file = os.path.join(self.test_dir, 'root_private_key') self._fill_file_with_dummy_contents(root_private_key_file) output_certificate_file = os.path.join(self.test_dir, 'cert') cmds.extend([ '--csr_file', csr_file, '--root_certificate_file', root_certificate_file, '--root_private_key_file', root_private_key_file, '--root_private_key_passphrase', 'root_key', '--output_certificate_file', output_certificate_file ]) args = self.parser.parse_args(cmds) self.assertAlmostEqual( args.not_valid_before, datetime.datetime.today(), delta=datetime.timedelta(seconds=60)) self.assertEqual(args.valid_duration, 10) self.assertEqual(args.system_id, 100) self.assertEqual(args.csr_file.name, csr_file) self.assertEqual(args.csr_file.mode, 'rb') self.assertEqual(args.root_certificate_file.name, root_certificate_file) self.assertEqual(args.root_certificate_file.mode, 'rb') self.assertEqual(args.root_private_key_file.name, root_private_key_file) self.assertEqual(args.root_private_key_file.mode, 'rb') self.assertEqual(args.root_private_key_passphrase, 'root_key') self.assertEqual(args.output_certificate_file.name, output_certificate_file) self.assertEqual(args.output_certificate_file.mode, 'wb') self.assertEqual(args.func, oem_certificate.generate_intermediate_certificate) def test_generate_leaf_cert(self): cmds = ('generate_leaf_certificate --not_valid_before 2016-01-02 ' '--valid_duration 10').split() intermediate_certificate_file = os.path.join(self.test_dir, 'intermediate_cert') self._fill_file_with_dummy_contents(intermediate_certificate_file) intermediate_private_key_file = os.path.join(self.test_dir, 'intermediate_private_key') self._fill_file_with_dummy_contents(intermediate_private_key_file) output_certificate_file = os.path.join(self.test_dir, 'cert') output_private_key_file = os.path.join(self.test_dir, 'key') cmds.extend([ '--intermediate_certificate_file', intermediate_certificate_file, '--intermediate_private_key_file', intermediate_private_key_file, '--intermediate_private_key_passphrase', 'intermediate_key', '--output_certificate_file', output_certificate_file, '--output_private_key_file', output_private_key_file, '--passphrase', 'leaf_key' ]) args = self.parser.parse_args(cmds) self.assertEqual(args.not_valid_before, datetime.datetime(2016, 1, 2)) self.assertEqual(args.valid_duration, 10) self.assertEqual(args.intermediate_certificate_file.name, intermediate_certificate_file) self.assertEqual(args.intermediate_certificate_file.mode, 'rb') self.assertEqual(args.intermediate_private_key_file.name, intermediate_private_key_file) self.assertEqual(args.intermediate_private_key_file.mode, 'rb') self.assertEqual(args.intermediate_private_key_passphrase, 'intermediate_key') self.assertEqual(args.output_certificate_file.name, output_certificate_file) self.assertEqual(args.output_certificate_file.mode, 'wb') self.assertEqual(args.output_private_key_file.name, output_private_key_file) self.assertEqual(args.output_private_key_file.mode, 'wb') self.assertEqual(args.passphrase, 'leaf_key') self.assertEqual(args.func, oem_certificate.generate_leaf_certificate) def test_generate_leaf_cert_invalid_date(self): cmds = ('generate_leaf_certificate --not_valid_before invaid-date ' '--valid_duration 10').split() intermediate_certificate_file = os.path.join(self.test_dir, 'intermediate_cert') self._fill_file_with_dummy_contents(intermediate_certificate_file) intermediate_private_key_file = os.path.join(self.test_dir, 'intermediate_private_key') self._fill_file_with_dummy_contents(intermediate_private_key_file) output_certificate_file = os.path.join(self.test_dir, 'cert') output_private_key_file = os.path.join(self.test_dir, 'key') cmds.extend([ '--intermediate_certificate_file', intermediate_certificate_file, '--intermediate_private_key_file', intermediate_private_key_file, '--intermediate_private_key_passphrase', 'intermediate_key', '--output_certificate_file', output_certificate_file, '--output_private_key_file', output_private_key_file, '--passphrase', 'leaf_key' ]) with self.assertRaises(SystemExit) as context: self.parser.parse_args(cmds) self.assertEqual(context.exception.code, 2) def test_secure_erase(self): file_path = os.path.join(self.test_dir, 'file') self._fill_file_with_dummy_contents(file_path) cmds = ['erase', '-F', file_path, '--passes', '2'] args = self.parser.parse_args(cmds) self.assertEqual(args.passes, 2) self.assertEqual(args.file.name, file_path) self.assertEqual(args.file.mode, 'a') self.assertEqual(args.func, oem_certificate.secure_erase) def test_get_info(self): file_path = os.path.join(self.test_dir, 'file') self._fill_file_with_dummy_contents(file_path) cmds = ['info', '-F', file_path] args = self.parser.parse_args(cmds) self.assertEqual(args.file.name, file_path) self.assertEqual(args.file.mode, 'rb') self.assertEqual(args.func, oem_certificate.get_info) def test_arbitrary_commands(self): with self.assertRaises(SystemExit) as context: self.parser.parse_args(['unsupport', '--commands']) self.assertEqual(context.exception.code, 2) def test_no_argument(self): with self.assertRaises(SystemExit) as context: self.parser.parse_args([]) self.assertEqual(context.exception.code, 2) if __name__ == '__main__': unittest.main()