def monkeypatch_extension_oids(): oid.ExtensionOID.SZOID_CERTIFICATE_TEMPLATE = ( oid.ObjectIdentifier("1.3.6.1.4.1.311.21.7")) oid.ExtensionOID.SZOID_APPLICATION_CERT_POLICIES = ( oid.ObjectIdentifier("1.3.6.1.4.1.311.21.10")) oid.ExtensionOID.SMIME_CAPABILITIES = ( oid.ObjectIdentifier("1.2.840.113549.1.9.15"))
def test_load_der_x509_cert_ok_prueba_sii(self) -> None: cert_der_bytes = utils.read_test_file_bytes( 'test_data/sii-crypto/prueba-sii-cert.der') x509_cert = load_der_x509_cert(cert_der_bytes) self.assertIsInstance(x509_cert, X509Cert) ####################################################################### # main properties ####################################################################### self.assertEqual(x509_cert.version, cryptography.x509.Version.v3) self.assertIsInstance(x509_cert.signature_hash_algorithm, cryptography.hazmat.primitives.hashes.MD5) self.assertEqual(x509_cert.signature_algorithm_oid, oid.SignatureAlgorithmOID.RSA_WITH_MD5) self.assertEqual(x509_cert.serial_number, 131466) self.assertEqual(x509_cert.not_valid_after, datetime(2003, 10, 2, 0, 0)) self.assertEqual(x509_cert.not_valid_before, datetime(2002, 10, 2, 19, 11, 59)) ####################################################################### # issuer ####################################################################### self.assertEqual(len(x509_cert.issuer.rdns), 6) self.assertEqual( x509_cert.issuer.rfc4514_string(), 'ST=Region Metropolitana,' 'L=Santiago,' 'CN=E-Certchile CA Intermedia,' 'OU=Empresa Nacional de Certificacion Electronica,' 'O=E-CERTCHILE,' 'C=CL') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.STATE_OR_PROVINCE_NAME)[0].value, 'Region Metropolitana') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.LOCALITY_NAME)[0].value, 'Santiago') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'E-CERTCHILE') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Empresa Nacional de Certificacion Electronica') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'E-Certchile CA Intermedia') ####################################################################### # subject ####################################################################### self.assertEqual(len(x509_cert.subject.rdns), 7) self.assertEqual( x509_cert.subject.rfc4514_string(), 'ST=Region Metropolitana,' 'OU=Servicio de Impuestos Internos,' 'O=Servicio de Impuestos Internos,' 'L=Santiago,' '[email protected],' 'CN=Wilibaldo Gonzalez Cabrera,' 'C=CL') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.STATE_OR_PROVINCE_NAME)[0].value, 'Region Metropolitana') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.LOCALITY_NAME)[0].value, 'Santiago') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'Servicio de Impuestos Internos') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Servicio de Impuestos Internos') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'Wilibaldo Gonzalez Cabrera') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.EMAIL_ADDRESS)[0].value, '*****@*****.**') ####################################################################### # extensions ####################################################################### cert_extensions = x509_cert.extensions self.assertEqual(len(cert_extensions._extensions), 5) # KEY_USAGE key_usage_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.KeyUsage) self.assertEqual(key_usage_ext.critical, False) self.assertEqual(key_usage_ext.value.content_commitment, True) self.assertEqual(key_usage_ext.value.crl_sign, False) self.assertEqual(key_usage_ext.value.data_encipherment, True) self.assertEqual(key_usage_ext.value.digital_signature, True) self.assertEqual(key_usage_ext.value.key_agreement, False) self.assertEqual(key_usage_ext.value.key_cert_sign, False) self.assertEqual(key_usage_ext.value.key_encipherment, True) # ISSUER_ALTERNATIVE_NAME issuer_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.IssuerAlternativeName) self.assertEqual(issuer_alt_name_ext.critical, False) self.assertEqual( len(issuer_alt_name_ext.value._general_names._general_names), 1) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].type_id, _SII_CERT_CERTIFICADORA_EMISORA_RUT_OID) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].value, b'\x16\n96928180-5') # SUBJECT_ALTERNATIVE_NAME subject_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.SubjectAlternativeName) self.assertEqual(subject_alt_name_ext.critical, False) self.assertEqual( len(subject_alt_name_ext.value._general_names._general_names), 1) # TODO: find out where did OID '1.3.6.1.4.1.8658.1' come from. # Shouldn't it have been equal to '_SII_CERT_TITULAR_RUT_OID'? self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0]. type_id, oid.ObjectIdentifier("1.3.6.1.4.1.8658.1")) self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0].value, b'\x16\n07880442-4') # CERTIFICATE_POLICIES certificate_policies_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CertificatePolicies) self.assertEqual(certificate_policies_ext.critical, False) self.assertEqual(len(certificate_policies_ext.value._policies), 1) # TODO: find out where did OID '1.3.6.1.4.1.8658.0' come from. # Perhaps it was '1.3.6.1.4.1.8658'? # https://oidref.com/1.3.6.1.4.1.8658 self.assertEqual( certificate_policies_ext.value._policies[0].policy_identifier, oid.ObjectIdentifier("1.3.6.1.4.1.8658.0")) self.assertEqual( len(certificate_policies_ext.value._policies[0].policy_qualifiers), 2) self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[0], "http://www.e-certchile.cl/politica/cps.htm") self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[1]. explicit_text, "El titular ha sido validado en forma presencial, quedando habilitado el Certificado " "para uso tributario, pagos, comercio u otros") # CRL_DISTRIBUTION_POINTS crl_distribution_points_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CRLDistributionPoints) self.assertEqual(crl_distribution_points_ext.critical, False) self.assertEqual( len(crl_distribution_points_ext.value._distribution_points), 1) self.assertEqual( crl_distribution_points_ext.value._distribution_points[0]. full_name[0].value, 'http://crl.e-certchile.cl/EcertchileCAI.crl') self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. crl_issuer, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0].reasons, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. relative_name, None)
def test_load_der_x509_cert_ok_cert_real_dte(self) -> None: cert_der_bytes = utils.read_test_file_bytes( 'test_data/sii-crypto/DTE--76354771-K--33--170-cert.der') x509_cert = load_der_x509_cert(cert_der_bytes) self.assertIsInstance(x509_cert, X509Cert) ####################################################################### # main properties ####################################################################### self.assertEqual(x509_cert.version, cryptography.x509.Version.v3) self.assertIsInstance(x509_cert.signature_hash_algorithm, cryptography.hazmat.primitives.hashes.SHA1) self.assertEqual(x509_cert.signature_algorithm_oid, oid.SignatureAlgorithmOID.RSA_WITH_SHA1) self.assertEqual(x509_cert.serial_number, 232680798042554446173213) self.assertEqual(x509_cert.not_valid_after, datetime(2020, 9, 3, 21, 11, 12)) self.assertEqual(x509_cert.not_valid_before, datetime(2017, 9, 4, 21, 11, 12)) ####################################################################### # issuer ####################################################################### self.assertEqual(len(x509_cert.issuer.rdns), 7) self.assertEqual( x509_cert.issuer.rfc4514_string(), 'C=CL,ST=Region Metropolitana,' 'L=Santiago,' 'O=E-CERTCHILE,' 'OU=Autoridad Certificadora,' 'CN=E-CERTCHILE CA FIRMA ELECTRONICA SIMPLE,' '[email protected]') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.STATE_OR_PROVINCE_NAME)[0].value, 'Region Metropolitana') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.LOCALITY_NAME)[0].value, 'Santiago') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'E-CERTCHILE') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Autoridad Certificadora') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'E-CERTCHILE CA FIRMA ELECTRONICA SIMPLE') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.EMAIL_ADDRESS)[0].value, '*****@*****.**') ####################################################################### # subject ####################################################################### self.assertEqual(len(x509_cert.subject.rdns), 7) self.assertEqual( x509_cert.subject.rfc4514_string(), 'C=CL,' 'ST=VALPARAISO\\ ,' 'L=Quillota,' 'O=Servicios Bonilla y Lopez y Cia. Ltda.,' 'OU=Ingeniería y Construcción,' 'CN=Ramon humberto Lopez Jara,' '[email protected]') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.STATE_OR_PROVINCE_NAME)[0].value, 'VALPARAISO ') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.LOCALITY_NAME)[0].value, 'Quillota') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'Servicios Bonilla y Lopez y Cia. Ltda.') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Ingeniería y Construcción') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'Ramon humberto Lopez Jara') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.EMAIL_ADDRESS)[0].value, '*****@*****.**') ####################################################################### # extensions ####################################################################### cert_extensions = x509_cert.extensions self.assertEqual(len(cert_extensions._extensions), 9) # KEY_USAGE key_usage_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.KeyUsage) self.assertEqual(key_usage_ext.critical, False) self.assertEqual(key_usage_ext.value.content_commitment, True) self.assertEqual(key_usage_ext.value.crl_sign, False) self.assertEqual(key_usage_ext.value.data_encipherment, True) self.assertEqual(key_usage_ext.value.digital_signature, True) self.assertEqual(key_usage_ext.value.key_agreement, False) self.assertEqual(key_usage_ext.value.key_cert_sign, False) self.assertEqual(key_usage_ext.value.key_encipherment, True) # ISSUER_ALTERNATIVE_NAME issuer_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.IssuerAlternativeName) self.assertEqual(issuer_alt_name_ext.critical, False) self.assertEqual( len(issuer_alt_name_ext.value._general_names._general_names), 1) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].type_id, _SII_CERT_CERTIFICADORA_EMISORA_RUT_OID) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].value, b'\x16\n96928180-5') # SUBJECT_ALTERNATIVE_NAME subject_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.SubjectAlternativeName) self.assertEqual(subject_alt_name_ext.critical, False) self.assertEqual( len(subject_alt_name_ext.value._general_names._general_names), 1) self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0]. type_id, _SII_CERT_TITULAR_RUT_OID) self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0].value, b'\x16\n13185095-6') # AUTHORITY_INFORMATION_ACCESS authority_information_access_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.AuthorityInformationAccess) self.assertEqual(authority_information_access_ext.critical, False) self.assertEqual( len(authority_information_access_ext.value._descriptions), 1) self.assertEqual( authority_information_access_ext.value._descriptions[0]. access_location.value, 'http://ocsp.ecertchile.cl/ocsp') self.assertEqual( authority_information_access_ext.value._descriptions[0]. access_method, oid.AuthorityInformationAccessOID.OCSP) # SUBJECT_KEY_IDENTIFIER subject_key_identifier_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.SubjectKeyIdentifier) self.assertEqual(subject_key_identifier_ext.critical, False) self.assertEqual( subject_key_identifier_ext.value.digest, b'\xd5\xd5G\x84]\x14U\xee\xd1\\\x8c\xf8r9w\xfdW\xb0\xfa\xaa') # AUTHORITY_KEY_IDENTIFIER authority_key_identifier_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.AuthorityKeyIdentifier) self.assertEqual(authority_key_identifier_ext.critical, False) self.assertIs(authority_key_identifier_ext.value.authority_cert_issuer, None) self.assertIs( authority_key_identifier_ext.value.authority_cert_serial_number, None) self.assertEqual( authority_key_identifier_ext.value.key_identifier, b'x\xe1>\x9f\xd2\x12\xb3z<\x8d\xcd0\x0eS\xb3C)\x07\xb3U') # CERTIFICATE_POLICIES certificate_policies_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CertificatePolicies) self.assertEqual(certificate_policies_ext.critical, False) self.assertEqual(len(certificate_policies_ext.value._policies), 1) # TODO: find out where did OID '1.3.6.1.4.1.8658.5' come from. # Perhaps it was '1.3.6.1.4.1.8658'? # https://oidref.com/1.3.6.1.4.1.8658 self.assertEqual( certificate_policies_ext.value._policies[0].policy_identifier, oid.ObjectIdentifier("1.3.6.1.4.1.8658.5")) self.assertEqual( len(certificate_policies_ext.value._policies[0].policy_qualifiers), 2) self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[0], "http://www.e-certchile.cl/CPS.htm") self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[1]. explicit_text, "Certificado Firma Simple. Ha sido validado en forma presencial, quedando habilitado " "el Certificado para uso tributario") # CRL_DISTRIBUTION_POINTS crl_distribution_points_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CRLDistributionPoints) self.assertEqual(crl_distribution_points_ext.critical, False) self.assertEqual( len(crl_distribution_points_ext.value._distribution_points), 1) self.assertEqual( crl_distribution_points_ext.value._distribution_points[0]. full_name[0].value, 'http://crl.e-certchile.cl/ecertchilecaFES.crl') self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. crl_issuer, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0].reasons, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. relative_name, None) ####################################################################### # extra extensions ####################################################################### # "Microsoft" / "Microsoft CertSrv Infrastructure" / "szOID_CERTIFICATE_TEMPLATE" # See: # http://oidref.com/1.3.6.1.4.1.311.21.7 # https://support.microsoft.com/en-ae/help/287547/object-ids-associated-with-microsoft-cryptography some_microsoft_extension_oid = oid.ObjectIdentifier( "1.3.6.1.4.1.311.21.7") some_microsoft_ext = cert_extensions.get_extension_for_oid( some_microsoft_extension_oid) self.assertEqual(some_microsoft_ext.critical, False) self.assertTrue(isinstance(some_microsoft_ext.value.value, bytes))
from . import utils # TODO: get fake certificates, keys, and all the variations from # https://github.com/urllib3/urllib3/tree/1.24.2/dummyserver/certs # TODO: move me into 'cl_sii/crypto/constants.py' # - Organismo: MINISTERIO DE ECONOMÍA / SUBSECRETARIA DE ECONOMIA # - Decreto 181 (Julio-Agosto 2002) # "APRUEBA REGLAMENTO DE LA LEY 19.799 SOBRE DOCUMENTOS ELECTRONICOS, FIRMA ELECTRONICA # Y LA CERTIFICACION DE DICHA FIRMA" # - ref: https://www.leychile.cl/Consulta/m/norma_plana?org=&idNorma=201668 # dice: # > RUT del titular del certificado : 1.3.6.1.4.1.8321.1 # > RUT de la certificadora emisora : 1.3.6.1.4.1.8321.2 _SII_CERT_CERTIFICADORA_EMISORA_RUT_OID = oid.ObjectIdentifier( "1.3.6.1.4.1.8321.2") _SII_CERT_TITULAR_RUT_OID = oid.ObjectIdentifier("1.3.6.1.4.1.8321.1") class FunctionsTest(unittest.TestCase): def test_add_pem_cert_header_footer(self) -> None: # TODO: implement for function 'add_pem_cert_header_footer'. pass def test_remove_pem_cert_header_footer(self) -> None: # TODO: implement for function 'remove_pem_cert_header_footer'. pass class LoadPemX509CertTest(unittest.TestCase): def test_load_der_x509_cert_ok(self) -> None:
def test_load_der_x509_cert_ok_cert_real_dte_3(self) -> None: cert_der_bytes = utils.read_test_file_bytes( 'test_data/sii-crypto/DTE--60910000-1--33--2336600-cert.der') x509_cert = load_der_x509_cert(cert_der_bytes) self.assertIsInstance(x509_cert, X509Cert) ####################################################################### # main properties ####################################################################### self.assertEqual(x509_cert.version, cryptography.x509.Version.v3) self.assertIsInstance(x509_cert.signature_hash_algorithm, cryptography.hazmat.primitives.hashes.SHA256) self.assertEqual(x509_cert.signature_algorithm_oid, oid.SignatureAlgorithmOID.RSA_WITH_SHA256) self.assertEqual(x509_cert.serial_number, 6504844188525727926) self.assertEqual(x509_cert.not_valid_after, datetime(2019, 9, 6, 21, 13, 0)) self.assertEqual(x509_cert.not_valid_before, datetime(2018, 9, 6, 21, 13, 0)) ####################################################################### # issuer ####################################################################### self.assertEqual(len(x509_cert.issuer.rdns), 5) self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'E-Sign S.A.') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Terms of use at www.esign-la.com/acuerdoterceros') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'E-Sign Class 2 Firma Tributaria CA') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.EMAIL_ADDRESS)[0].value, '*****@*****.**') ####################################################################### # subject ####################################################################### self.assertEqual(len(x509_cert.subject.rdns), 5) self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'E-Sign S.A.') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Terms of use at www.esign-la.com/acuerdoterceros') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'Jorge Enrique Cabello Ortiz') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.EMAIL_ADDRESS)[0].value, '*****@*****.**') ####################################################################### # extensions ####################################################################### cert_extensions = x509_cert.extensions self.assertEqual(len(cert_extensions._extensions), 10) # KEY_USAGE key_usage_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.KeyUsage) self.assertEqual(key_usage_ext.critical, True) self.assertEqual(key_usage_ext.value.content_commitment, False) self.assertEqual(key_usage_ext.value.crl_sign, False) self.assertEqual(key_usage_ext.value.data_encipherment, False) self.assertEqual(key_usage_ext.value.digital_signature, True) self.assertEqual(key_usage_ext.value.key_agreement, False) self.assertEqual(key_usage_ext.value.key_cert_sign, False) self.assertEqual(key_usage_ext.value.key_encipherment, True) # ISSUER_ALTERNATIVE_NAME issuer_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.IssuerAlternativeName) self.assertEqual(issuer_alt_name_ext.critical, False) self.assertEqual( len(issuer_alt_name_ext.value._general_names._general_names), 1) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].type_id, _SII_CERT_CERTIFICADORA_EMISORA_RUT_OID) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].value, b'\x16\n99551740-K') # SUBJECT_ALTERNATIVE_NAME subject_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.SubjectAlternativeName) self.assertEqual(subject_alt_name_ext.critical, False) self.assertEqual( len(subject_alt_name_ext.value._general_names._general_names), 1) self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0]. type_id, _SII_CERT_TITULAR_RUT_OID) self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0].value, b'\x16\t8480437-1') # AUTHORITY_INFORMATION_ACCESS authority_information_access_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.AuthorityInformationAccess) self.assertEqual(authority_information_access_ext.critical, False) self.assertEqual( len(authority_information_access_ext.value._descriptions), 2) self.assertEqual( authority_information_access_ext.value._descriptions[0]. access_location.value, 'http://pki.esign-la.com/cacerts/pkiClass2FirmaTributariaCA.crt') self.assertEqual( authority_information_access_ext.value._descriptions[0]. access_method, oid.AuthorityInformationAccessOID.CA_ISSUERS) self.assertEqual( authority_information_access_ext.value._descriptions[1]. access_location.value, 'http://ocsp.esign-la.com') self.assertEqual( authority_information_access_ext.value._descriptions[1]. access_method, oid.AuthorityInformationAccessOID.OCSP) # SUBJECT_KEY_IDENTIFIER subject_key_identifier_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.SubjectKeyIdentifier) self.assertEqual(subject_key_identifier_ext.critical, False) self.assertEqual( subject_key_identifier_ext.value.digest, a2b_hex( 'E9:FE:44:7A:91:0A:F0:40:F2:9D:86:B4:E2:4C:F6:FA:1D:07:5B:C7'. replace(':', ''))) # AUTHORITY_KEY_IDENTIFIER authority_key_identifier_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.AuthorityKeyIdentifier) self.assertEqual(authority_key_identifier_ext.critical, False) self.assertIs(authority_key_identifier_ext.value.authority_cert_issuer, None) self.assertIs( authority_key_identifier_ext.value.authority_cert_serial_number, None) self.assertEqual( authority_key_identifier_ext.value.key_identifier, a2b_hex( 'F9:4A:FA:C2:C7:6E:C2:E7:12:9C:57:45:35:84:1A:6D:28:E9:4A:A4'. replace(':', ''))) # CERTIFICATE_POLICIES certificate_policies_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CertificatePolicies) self.assertEqual(certificate_policies_ext.critical, False) self.assertEqual(len(certificate_policies_ext.value._policies), 1) # note: parent of OID '1.3.6.1.4.1.42346.1.4.1.2' is '1.3.6.1.4.1.42346' ("E-SIGN S.A."). # http://oidref.com/1.3.6.1.4.1.42346 # http://oid-info.com/get/1.3.6.1.4.1.42346 self.assertEqual( certificate_policies_ext.value._policies[0].policy_identifier, oid.ObjectIdentifier("1.3.6.1.4.1.42346.1.4.1.2")) self.assertEqual( len(certificate_policies_ext.value._policies[0].policy_qualifiers), 2) self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[0], cryptography.x509.extensions.UserNotice( notice_reference=None, explicit_text= 'Certificado para uso Tributario, Comercio, Pagos y Otros')) self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[1], "http://www.esign-la.com/cps") # CRL_DISTRIBUTION_POINTS crl_distribution_points_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CRLDistributionPoints) self.assertEqual(crl_distribution_points_ext.critical, False) self.assertEqual( len(crl_distribution_points_ext.value._distribution_points), 1) self.assertEqual( crl_distribution_points_ext.value._distribution_points[0]. full_name[0].value, 'http://pki.esign-la.com/crl/pkiClass2FirmaTributaria/enduser.crl') self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. crl_issuer, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0].reasons, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. relative_name, None)
def test_load_der_x509_cert_ok_cert_real_dte_1(self) -> None: cert_der_bytes = utils.read_test_file_bytes( 'test_data/sii-crypto/DTE--76354771-K--33--170-cert.der') x509_cert = load_der_x509_cert(cert_der_bytes) self.assertIsInstance(x509_cert, X509Cert) ####################################################################### # main properties ####################################################################### self.assertEqual(x509_cert.version, cryptography.x509.Version.v3) self.assertIsInstance(x509_cert.signature_hash_algorithm, cryptography.hazmat.primitives.hashes.SHA1) self.assertEqual(x509_cert.signature_algorithm_oid, oid.SignatureAlgorithmOID.RSA_WITH_SHA1) self.assertEqual(x509_cert.serial_number, 232680798042554446173213) self.assertEqual(x509_cert.not_valid_after, datetime(2020, 9, 3, 21, 11, 12)) self.assertEqual(x509_cert.not_valid_before, datetime(2017, 9, 4, 21, 11, 12)) ####################################################################### # issuer ####################################################################### self.assertEqual(len(x509_cert.issuer.rdns), 7) self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.STATE_OR_PROVINCE_NAME)[0].value, 'Region Metropolitana') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.LOCALITY_NAME)[0].value, 'Santiago') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'E-CERTCHILE') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Autoridad Certificadora') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'E-CERTCHILE CA FIRMA ELECTRONICA SIMPLE') self.assertEqual( x509_cert.issuer.get_attributes_for_oid( oid.NameOID.EMAIL_ADDRESS)[0].value, '*****@*****.**') ####################################################################### # subject ####################################################################### self.assertEqual(len(x509_cert.subject.rdns), 7) self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COUNTRY_NAME)[0].value, 'CL') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.STATE_OR_PROVINCE_NAME)[0].value, 'VALPARAISO ') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.LOCALITY_NAME)[0].value, 'Quillota') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATION_NAME)[0].value, 'Servicios Bonilla y Lopez y Cia. Ltda.') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.ORGANIZATIONAL_UNIT_NAME)[0].value, 'Ingeniería y Construcción') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.COMMON_NAME)[0].value, 'Ramon humberto Lopez Jara') self.assertEqual( x509_cert.subject.get_attributes_for_oid( oid.NameOID.EMAIL_ADDRESS)[0].value, '*****@*****.**') ####################################################################### # extensions ####################################################################### cert_extensions = x509_cert.extensions self.assertEqual(len(cert_extensions._extensions), 9) # KEY_USAGE key_usage_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.KeyUsage) self.assertEqual(key_usage_ext.critical, False) self.assertEqual(key_usage_ext.value.content_commitment, True) self.assertEqual(key_usage_ext.value.crl_sign, False) self.assertEqual(key_usage_ext.value.data_encipherment, True) self.assertEqual(key_usage_ext.value.digital_signature, True) self.assertEqual(key_usage_ext.value.key_agreement, False) self.assertEqual(key_usage_ext.value.key_cert_sign, False) self.assertEqual(key_usage_ext.value.key_encipherment, True) # ISSUER_ALTERNATIVE_NAME issuer_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.IssuerAlternativeName) self.assertEqual(issuer_alt_name_ext.critical, False) self.assertEqual( len(issuer_alt_name_ext.value._general_names._general_names), 1) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].type_id, _SII_CERT_CERTIFICADORA_EMISORA_RUT_OID) self.assertEqual( issuer_alt_name_ext.value._general_names._general_names[0].value, b'\x16\n96928180-5') # SUBJECT_ALTERNATIVE_NAME subject_alt_name_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.SubjectAlternativeName) self.assertEqual(subject_alt_name_ext.critical, False) self.assertEqual( len(subject_alt_name_ext.value._general_names._general_names), 1) self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0]. type_id, _SII_CERT_TITULAR_RUT_OID) self.assertEqual( subject_alt_name_ext.value._general_names._general_names[0].value, b'\x16\n13185095-6') # AUTHORITY_INFORMATION_ACCESS authority_information_access_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.AuthorityInformationAccess) self.assertEqual(authority_information_access_ext.critical, False) self.assertEqual( len(authority_information_access_ext.value._descriptions), 1) self.assertEqual( authority_information_access_ext.value._descriptions[0]. access_location.value, 'http://ocsp.ecertchile.cl/ocsp') self.assertEqual( authority_information_access_ext.value._descriptions[0]. access_method, oid.AuthorityInformationAccessOID.OCSP) # SUBJECT_KEY_IDENTIFIER subject_key_identifier_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.SubjectKeyIdentifier) self.assertEqual(subject_key_identifier_ext.critical, False) self.assertEqual( subject_key_identifier_ext.value.digest, a2b_hex( 'D5:D5:47:84:5D:14:55:EE:D1:5C:8C:F8:72:39:77:FD:57:B0:FA:AA'. replace(':', ''))) # AUTHORITY_KEY_IDENTIFIER authority_key_identifier_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.AuthorityKeyIdentifier) self.assertEqual(authority_key_identifier_ext.critical, False) self.assertIs(authority_key_identifier_ext.value.authority_cert_issuer, None) self.assertIs( authority_key_identifier_ext.value.authority_cert_serial_number, None) self.assertEqual( authority_key_identifier_ext.value.key_identifier, a2b_hex( '78:E1:3E:9F:D2:12:B3:7A:3C:8D:CD:30:0E:53:B3:43:29:07:B3:55'. replace(':', ''))) # CERTIFICATE_POLICIES certificate_policies_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CertificatePolicies) self.assertEqual(certificate_policies_ext.critical, False) self.assertEqual(len(certificate_policies_ext.value._policies), 1) # note: parent of OID '1.3.6.1.4.1.8658.5' is '1.3.6.1.4.1.42346' # ("Empresa Nacional de Certificacion Electronica "). # http://oidref.com/1.3.6.1.4.1.8658 # http://oid-info.com/get/1.3.6.1.4.1.8658 self.assertEqual( certificate_policies_ext.value._policies[0].policy_identifier, oid.ObjectIdentifier("1.3.6.1.4.1.8658.5")) self.assertEqual( len(certificate_policies_ext.value._policies[0].policy_qualifiers), 2) self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[0], "http://www.e-certchile.cl/CPS.htm") self.assertEqual( certificate_policies_ext.value._policies[0].policy_qualifiers[1], cryptography.x509.extensions.UserNotice( notice_reference=None, explicit_text= "Certificado Firma Simple. Ha sido validado en forma presencial, " "quedando habilitado el Certificado para uso tributario")) # CRL_DISTRIBUTION_POINTS crl_distribution_points_ext = cert_extensions.get_extension_for_class( cryptography.x509.extensions.CRLDistributionPoints) self.assertEqual(crl_distribution_points_ext.critical, False) self.assertEqual( len(crl_distribution_points_ext.value._distribution_points), 1) self.assertEqual( crl_distribution_points_ext.value._distribution_points[0]. full_name[0].value, 'http://crl.e-certchile.cl/ecertchilecaFES.crl') self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. crl_issuer, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0].reasons, None) self.assertIs( crl_distribution_points_ext.value._distribution_points[0]. relative_name, None) ####################################################################### # extra extensions ####################################################################### # "Microsoft" / "Microsoft CertSrv Infrastructure" / "szOID_CERTIFICATE_TEMPLATE" # See: # http://oidref.com/1.3.6.1.4.1.311.21.7 # https://support.microsoft.com/en-ae/help/287547/object-ids-associated-with-microsoft-cryptography some_microsoft_extension_oid = oid.ObjectIdentifier( "1.3.6.1.4.1.311.21.7") some_microsoft_ext = cert_extensions.get_extension_for_oid( some_microsoft_extension_oid) self.assertEqual(some_microsoft_ext.critical, False) self.assertTrue(isinstance(some_microsoft_ext.value.value, bytes))
from cryptography import x509 from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.x509 import oid from ipalib.errors import AuthorizationError, NotFound from ipalib.krb_utils import krb5_format_service_principal_name import six from custodia.plugin import CSStore, CSStoreError, PluginOption, REQUIRED from .interface import IPAInterface TLS_SERVERAUTH = oid.ObjectIdentifier('2.5.29.37.1') @six.add_metaclass(abc.ABCMeta) class _CSRGenerator(object): """Build and sign certificate signing request """ TEMPLATE = textwrap.dedent("""\ Issuer: {issuer} Subject: {subject} Serial Number: {cert.serial_number} Validity: Not Before: {cert.not_valid_before} Not After: {cert.not_valid_after} {pem}\ """)