def test(self): intermediate_path = os.path.join( os.path.dirname(__file__), '..', 'utils', 'DigiCertSHA2ExtendedValidationServerCA.pem') with open(intermediate_path) as intermediate_file: intermediate_pem = intermediate_file.read().encode('ascii') leaf_path = os.path.join(os.path.dirname(__file__), '..', 'utils', 'github.com.pem') with open(leaf_path) as leaf_file: leaf_pem = leaf_file.read().encode('ascii') certificate_chain = [ load_pem_x509_certificate(leaf_pem, default_backend()), load_pem_x509_certificate(intermediate_pem, default_backend()) ] found_mozilla = False for trust_store in TrustStoresRepository.get_default().get_all_stores( ): verified_chain = trust_store.build_verified_certificate_chain( certificate_chain) self.assertTrue(verified_chain) if trust_store.name == 'Mozilla': found_mozilla = True # The GH certificate is EV self.assertTrue( trust_store.is_extended_validation(certificate_chain[0])) self.assertTrue(found_mozilla)
def _compute_subject_certificate_dict(path: str) -> Dict[Name, Certificate]: cert_dict = {} with io.open(path, encoding='utf-8') as store_file: store_content = store_file.read() # Each certificate is separated by -----BEGIN CERTIFICATE----- pem_cert_list = store_content.split('-----BEGIN CERTIFICATE-----')[1::] pem_cert_nb = 0 for pem_split in pem_cert_list: # Remove PEM comments as they may cause Unicode errors final_pem = '-----BEGIN CERTIFICATE-----{}-----END CERTIFICATE-----'.format( pem_split.split('-----END CERTIFICATE-----')[0] ).strip() cert = load_pem_x509_certificate(final_pem.encode(encoding='ascii'), default_backend()) # Store a dictionary of subject->certificate for easy lookup try: cert_dict[cert.subject] = cert except ValueError: if pem_cert_nb == 311: # Cert number 311 in the Mozilla store can't be parsed by cryptography continue raise pem_cert_nb += 1 return cert_dict
def _compute_subject_certificate_dict(path): # type: (Text) -> Dict[Name, Certificate] cert_dict = {} with io.open(path, encoding='utf-8') as store_file: store_content = store_file.read() # Each certificate is separated by -----BEGIN CERTIFICATE----- pem_cert_list = store_content.split( '-----BEGIN CERTIFICATE-----')[1::] pem_cert_nb = 0 for pem_split in pem_cert_list: # Remove PEM comments as they may cause Unicode errors final_pem = '-----BEGIN CERTIFICATE-----{}-----END CERTIFICATE-----'.format( pem_split.split('-----END CERTIFICATE-----')[0]).strip() cert = load_pem_x509_certificate( final_pem.encode(encoding='ascii'), default_backend()) # Store a dictionary of subject->certificate for easy lookup try: cert_dict[cert.subject] = cert except ValueError: if pem_cert_nb == 311: # Cert number 311 in the Mozilla store can't be parsed by cryptography continue raise pem_cert_nb += 1 return cert_dict
def process_apk(self, data, name): """ Processes Android application :param data: :param name: :return: """ from cryptography.x509.base import load_pem_x509_certificate from apk_parse.apk import APK try: apkf = APK(data, process_now=False, process_file_types=False, raw=True, temp_dir=self.args.tmp_dir) apkf.process() self.num_apk += 1 pem = apkf.cert_pem aux = {'subtype': 'apk'} x509 = load_pem_x509_certificate(pem, self.get_backend()) self.process_x509(x509, name=name, idx=0, data=data, pem=True, source='apk-pem-cert', aux=aux) except Exception as e: logger.debug('Exception in processing JSON %s : %s' % (name, e)) self.trace_logger.log(e)
def load_pem(self, entity_type=None, path=None, pem_text=None, password=None): """ Load pem encoded entity Attributes: entity_type (str): certificate|key|csr. path (str): Absolute path to file containing pem encoded entity. pem_text (str): String object with pem encoded entity password (str): Password to use in case entity is protected """ if path and pem_text: raise ValueError("Path and pem_text are mutually exclusive") if path: with open(path, "rb") as f: pem_text = f.read() if entity_type == "certificate": return load_pem_x509_certificate(pem_text, backend=default_backend()) elif entity_type == "csr": return load_pem_x509_csr(pem_text, backend=default_backend()) elif entity_type == "key": return load_pem_private_key( pem_text, password=password, backend=default_backend(), ) else: raise ValueError("Unsupported entity_type {}".format(entity_type))
def add_peer_cert(self, cert: str) -> bool: try: self.peer_cert = load_pem_x509_certificate(str.encode(cert), default_backend()) Encrypt.verify_key_chain(self.peer_cert) return True except: traceback.print_exc() return False
def test(self): intermediate_path = os.path.join(os.path.dirname(__file__), '..', 'utils', 'DigiCertSHA2ExtendedValidationServerCA.pem') with open(intermediate_path) as intermediate_file: intermediate_pem = intermediate_file.read().encode('ascii') leaf_path = os.path.join(os.path.dirname(__file__), '..', 'utils', 'github.com.pem') with open(leaf_path) as leaf_file: leaf_pem = leaf_file.read().encode('ascii') certificate_chain = [load_pem_x509_certificate(leaf_pem, default_backend()), load_pem_x509_certificate(intermediate_pem, default_backend())] found_mozilla = False for trust_store in TrustStoresRepository.get_default().get_all_stores(): verified_chain = trust_store.build_verified_certificate_chain(certificate_chain) self.assertTrue(verified_chain) if trust_store.name == 'Mozilla': found_mozilla = True # The GH certificate is EV self.assertTrue(trust_store.is_extended_validation(certificate_chain[0])) self.assertTrue(found_mozilla)
def process_pem_cert(self, data, name, idx): """ Processes PEM encoded certificate :param data: :param name: :param idx: :return: """ from cryptography.x509.base import load_pem_x509_certificate try: x509 = load_pem_x509_certificate(data, self.get_backend()) self.num_pem_certs += 1 self.process_x509(x509, name=name, idx=idx, data=data, pem=True, source='pem-cert') except Exception as e: logger.debug('PEM processing failed: ' % e) self.trace_logger.log(e)
def validate_signing_keys(signing_key_pem, certificate_pem): # type: (str, str) -> Tuple[EllipticCurvePrivateKey, RSAPrivateKey, Certificate] """Validates the attestation signing key and certificates specified. :param str signing_key_pem: PEM encoded EC or RSA signing key. :param str certificate_pem: PEM encoded X.509 certificate. :return: Returns the decoded signing key and certificate :rtype: RSAPrivateKey or ElilipticCurvePrivateKey, Certificate The validate_signing_keys method decodes the signing key and certificate and verifies that the public key associated with the certificate and the signing key are the same key. """ # Start by making sure that both signing key and certificate are present. if signing_key_pem and not certificate_pem: raise ValueError( "signing_key cannot be specified without signing_certificate.") if certificate_pem and not signing_key_pem: raise ValueError( "signing_certificate cannot be specified without signing_key.") # Verify that the key and certificate are validly PEM encoded. signing_key = serialization.load_pem_private_key( signing_key_pem.encode("utf-8"), password=None, backend=default_backend()) certificate = load_pem_x509_certificate(certificate_pem.encode("utf-8"), backend=default_backend()) # We only support ECDS and RSA keys in the MAA service. if not isinstance(signing_key, RSAPrivateKey) and not isinstance( signing_key, EllipticCurvePrivateKey): raise ValueError("Signing keys must be either ECDS or RSA keys.") # Ensure that the public key in the certificate matches the public key of the key. cert_public_key = certificate.public_key().public_bytes( Encoding.PEM, PublicFormat.SubjectPublicKeyInfo) key_public_key = signing_key.public_key().public_bytes( Encoding.PEM, PublicFormat.SubjectPublicKeyInfo) if cert_public_key != key_public_key: raise ValueError("Signing key must match certificate public key") return signing_key, certificate
def work(self): """ Entry point after argument processing. :return: """ roots = self.load_roots() logger.info('Roots loaded') # 1 - load all CAs, roots from Mozilla. roots = roots.split('-----END CERTIFICATE-----') for root in roots: if len(root.strip()) == 0: continue try: root += '-----END CERTIFICATE-----' root_cert = load_certificate(FILETYPE_PEM, root) crypt_cert = load_pem_x509_certificate(root, get_backend()) self.root_store.add_cert(root_cert) self.cur_store.add_cert(root_cert) self.all_certs.append(root_cert) root_fprint = binascii.hexlify( crypt_cert.fingerprint(hashes.SHA1())) self.assigned_fprints.add(root_fprint) self.test_cert(crypt_cert) logger.info('Root: %s' % root_fprint) except Exception as e: logger.error('Exception in processing root cert %s' % e) self.trace_logger.log(e) logger.info('Roots[%s] %s' % (len(self.all_certs), self.root_store)) root_files = [] for tlsdir in self.args.tlsdir: root_files += sorted([ os.path.join(tlsdir, f) for f in os.listdir(tlsdir) if (os.path.isfile(os.path.join(tlsdir, f)) and '.cr.json' in f ) ]) for alexa in self.args.alexa: root_files += sorted([ os.path.join(alexa, f) for f in os.listdir(alexa) if (os.path.isfile(os.path.join(alexa, f)) and '.cr.json' in f) ]) for sonar in self.args.sonar: root_files += sorted([ os.path.join(sonar, f) for f in os.listdir(sonar) if (os.path.isfile(os.path.join(sonar, f)) and '_certs.uniq.json' in f) ]) for sonar in self.args.sonar_snap: root_files += sorted([ os.path.join(sonar, f) for f in os.listdir(sonar) if (os.path.isfile(os.path.join(sonar, f)) and '_merge_certs.uniq.json' in f) ]) for fl in root_files: logger.debug('File: %s' % fl) # BFS on CA tree for cdepth in range(1, 10): logger.info('New depth level: %d' % cdepth) self.cur_depth = cdepth self.interms[cdepth] = [] self.chain_cert_db = set() for fidx, fname in enumerate(root_files): logger.info('Reading file[%02d][%02d/%02d] %s' % (self.cur_depth, fidx + 1, len(root_files), fname)) self.roots(fname) self.cur_store = self.new_store() for crt in self.all_certs: try: self.cur_store.add_cert(crt) except: pass ln = len(self.interms[self.cur_depth]) if ln == 0: logger.info('No more certs added, exiting') break logger.info('New certificates added: %s' % ln) dpath = os.path.join(self.args.data_dir, 'interm-lvl%02d.json' % cdepth) with open(dpath, 'w') as fh: for rec in self.interms[cdepth]: fh.write('%s\n' % json.dumps(rec))
def test_september_2018(self): # Given a certificate chain issued by a Symantec CA that will be distrusted in September 2018 cert_chain = [ # invalid-expected-sct.badssl.com load_pem_x509_certificate( """-----BEGIN CERTIFICATE----- MIIFGDCCBACgAwIBAgIQGkTSlT8/2bAURo/J1C2/STANBgkqhkiG9w0BAQsFADBC MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMS UmFwaWRTU0wgU0hBMjU2IENBMB4XDTE2MTExNzAwMDAwMFoXDTE4MTExNzIzNTk1 OVowKjEoMCYGA1UEAwwfaW52YWxpZC1leHBlY3RlZC1zY3QuYmFkc3NsLmNvbTCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMIE7PiM7gTCs9hQ1XBYzJMY 61yoaEmwIrX5lZ6xKyx2PmzAS2BMTOqytMAPgLaw+XLJhgL5XEFdEyt/ccRLvOmU LlA3pmccYYz2QULFRtMWhyefdOsKnRFSJiFzbIRMeVXk0WvoBj1IFVKtsyjbqv9u /2CVSndrOfEk0TG23U3AxPxTuW1CrbV8/q71FdIzSOciccfCFHpsKOo3St/qbLVy tH5aohbcabFXRNsKEqveww9HdFxBIuGa+RuT5q0iBikusbpJHAwnnqP7i/dAcgCs kgjZjFeEU4EFy+b+a1SYQCeFxxC7c3DvaRhBB0VVfPlkPz0sw6l865MaTIbRyoUC AwEAAaOCAiAwggIcMCoGA1UdEQQjMCGCH2ludmFsaWQtZXhwZWN0ZWQtc2N0LmJh ZHNzbC5jb20wCQYDVR0TBAIwADArBgNVHR8EJDAiMCCgHqAchhpodHRwOi8vZ3Au c3ltY2IuY29tL2dwLmNybDBvBgNVHSAEaDBmMGQGBmeBDAECATBaMCoGCCsGAQUF BwIBFh5odHRwczovL3d3dy5yYXBpZHNzbC5jb20vbGVnYWwwLAYIKwYBBQUHAgIw IAweaHR0cHM6Ly93d3cucmFwaWRzc2wuY29tL2xlZ2FsMB8GA1UdIwQYMBaAFJfC J1CewsnsDIgyyHyt4qYBT9pvMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggr BgEFBQcDAQYIKwYBBQUHAwIwVwYIKwYBBQUHAQEESzBJMB8GCCsGAQUFBzABhhNo dHRwOi8vZ3Auc3ltY2QuY29tMCYGCCsGAQUFBzAChhpodHRwOi8vZ3Auc3ltY2Iu Y29tL2dwLmNydDAPBgMrZU0ECDAGAgEBAgEBMIGKBgorBgEEAdZ5AgQCBHwEegB4 AHYAp85KTmIH4K3e5f2qSx+GdodntdACpV1HMQ5+ZwqV6rIAAAFYb//OtAAABAMA RzBFAiEAuAOtNPb8Dyz/hKCG5dfPWvAKB2Jqf7OmRGTxlaRIRRECIC9hjVMbb0q4 CmeyB+GPba3RBEpes4nvfGDCaFP5PR9tMA0GCSqGSIb3DQEBCwUAA4IBAQBIMHww vuW8XOBdxw0Mq0z3NFsAW2XvkcXtTGmB5savCpRJ6LN0ub6NJX+KiFmDo9voMDro YL7o9i+BrSAFo3hr8QNxLLJaXD54h8lJ0oCkzyZtzezM8p2PWsEjouePtdE0AIHn RK0SnKBk9w0b3CMSbzObc1Cu8ATqZnE51d7xurim7qTZMhJM2hi9HeLPLVdEBiuC zmYtNpRMMQqbQvvrXftAohq/W90rK42Ss8kYIf8FsVTa5VaqXW7lIh/3JmBNLZ1D Aw5rmaztWlYO64YS7z4am5d9h2rrF1rfgv9Mc3caxAUO3sJZDRyhYaj+7BUgv8HR otJHkjr2ASPp31Yf -----END CERTIFICATE----- """.encode(encoding="ascii"), default_backend(), ), # RapidSSL SHA 256 load_pem_x509_certificate( """-----BEGIN CERTIFICATE----- MIIETTCCAzWgAwIBAgIDAjpxMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i YWwgQ0EwHhcNMTMxMjExMjM0NTUxWhcNMjIwNTIwMjM0NTUxWjBCMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSUmFwaWRTU0wg U0hBMjU2IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1jBEgEu l9h9GKrIwuWF4hdsYC7JjTEFORoGmFbdVNcRjFlbPbFUrkshhTIWX1SG5tmx2GCJ a1i+ctqgAEJ2sSdZTM3jutRc2aZ/uyt11UZEvexAXFm33Vmf8Wr3BvzWLxmKlRK6 msrVMNI4/Bk7WxU7NtBDTdFlodSLwWBBs9ZwF8w5wJwMoD23ESJOztmpetIqYpyg C04q18NhWoXdXBC5VD0tA/hJ8LySt7ecMcfpuKqCCwW5Mc0IW7siC/acjopVHHZD dvDibvDfqCl158ikh4tq8bsIyTYYZe5QQ7hdctUoOeFTPiUs2itP3YqeUFDgb5rE 1RkmiQF1cwmbOwIDAQABo4IBSjCCAUYwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwR fap9ZbjKzE4wHQYDVR0OBBYEFJfCJ1CewsnsDIgyyHyt4qYBT9pvMBIGA1UdEwEB /wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgEGMDYGA1UdHwQvMC0wK6ApoCeGJWh0 dHA6Ly9nMS5zeW1jYi5jb20vY3Jscy9ndGdsb2JhbC5jcmwwLwYIKwYBBQUHAQEE IzAhMB8GCCsGAQUFBzABhhNodHRwOi8vZzIuc3ltY2IuY29tMEwGA1UdIARFMEMw QQYKYIZIAYb4RQEHNjAzMDEGCCsGAQUFBwIBFiVodHRwOi8vd3d3Lmdlb3RydXN0 LmNvbS9yZXNvdXJjZXMvY3BzMCkGA1UdEQQiMCCkHjAcMRowGAYDVQQDExFTeW1h bnRlY1BLSS0xLTU2OTANBgkqhkiG9w0BAQsFAAOCAQEANevhiyBWlLp6vXmp9uP+ bji0MsGj21hWID59xzqxZ2nVeRQb9vrsYPJ5zQoMYIp0TKOTKqDwUX/N6fmS/Zar RfViPT9gRlATPSATGC6URq7VIf5Dockj/lPEvxrYrDrK3maXI67T30pNcx9vMaJR BBZqAOv5jUOB8FChH6bKOvMoPF9RrNcKRXdLDlJiG9g4UaCSLT+Qbsh+QJ8gRhVd 4FB84XavXu0R0y8TubglpK9YCa81tGJUheNI3rzSkHp6pIQNo0LyUcDUrVNlXWz4 Px8G8k/Ll6BKWcZ40egDuYVtLLrhX7atKz4lecWLVtXjCYDqwSfC2Q7sRwrp0Mr8 2A== -----END CERTIFICATE----- """.encode(encoding="ascii"), default_backend(), ), # GeoTrust Global CA load_pem_x509_certificate( self._GEOTRUST_GLOBAL_CA_CERT.encode(encoding="ascii"), default_backend()), ] # The class to check for Symantec CAs returns the right result assert SymantecDistructTester.get_distrust_timeline( cert_chain) == SymantecDistrustTimelineEnum.SEPTEMBER_2018
async def remove_policy_management_certificate( self, *args: str, **kwargs: Any) -> AttestationPolicyManagementCertificateResult: """Removes a policy management certificate from the set of policy management certificates for the instance. :param str certificate_to_remove: Required PEM encoded X.509 certificate to remove from the list of attestation policy management certificates. :keyword str signing_key: PEM encoded signing Key representing the key associated with one of the *existing* attestation signing certificates. :keyword str signing_certificate: PEM encoded signing certificate which is one of the *existing* attestation signing certificates. :keyword bool validate_token: If True, validate the token, otherwise return the token unvalidated. :keyword validation_callback: Function callback to allow clients to perform custom validation of the token. if the token is invalid, the `validation_callback` function should throw an exception. :paramtype validation_callback: ~typing.Callable[[~azure.security.attestation.AttestationToken, ~azure.security.attestation.AttestationSigner], None] :keyword bool validate_signature: If True, validate the signature of the token being validated. :keyword bool validate_expiration: If True, validate the expiration time of the token being validated. :keyword str issuer: Expected issuer, used if `validate_issuer` is true. :keyword float validation_slack: Slack time for validation - tolerance applied to help account for clock drift between the issuer and the current machine. :keyword bool validate_issuer: If True, validate that the issuer of the token matches the expected issuer. :keyword bool validate_not_before_time: If true, validate the "Not Before" time in the token. :return: Result describing the outcome of the certificate removal. :rtype: Tuple[~azure.security.attestation.AttestationPolicyCertificateResult, ~azure.security.attestation.AttestationToken] The :class:`AttestationPolicyCertificateResult` response to the :meth:`remove_policy_management_certificate` API contains two attributes of interest. The first is `certificate_resolution`, which indicates whether the certificate in question is present in the set of policy management certificates after the operation has completed, or if it is absent. The second is the `thumbprint` of the certificate added. The `thumbprint` for the certificate is the SHA1 hash of the DER encoding of the certificate. .. admonition:: Example: Removing an added policy management certificate for an isolated attestation instance. .. literalinclude:: ../samples/sample_get_set_policy_async.py :start-after: [BEGIN remove_policy_management_certificate] :end-before: [END remove_policy_management_certificate] :language: python :dedent: 8 :caption: Removing a policy management certificate. """ if len(args) != 1: raise TypeError( "remove_policy_management_certificate takes a single positional parameter. found {}" .format(len(args))) certificate_to_remove = args[0] signing_key = kwargs.pop("signing_key", None) signing_certificate = kwargs.pop("signing_certificate", None) if signing_key or signing_certificate: signing_key, signing_certificate = validate_signing_keys( signing_key, signing_certificate) if not signing_key: signing_key = self._signing_key if not signing_certificate: signing_certificate = self._signing_certificate if not signing_key or not signing_certificate: raise ValueError( "A signing certificate and key must be provided to remove_policy_management_certificate." ) # Verify that the provided certificate is a valid PEM encoded X.509 certificate certificate_to_remove = load_pem_x509_certificate( certificate_to_remove.encode("ascii")) jwk = JSONWebKey( kty="RSA", x5_c=[ base64.b64encode( certificate_to_remove.public_bytes( serialization.Encoding.DER)).decode("ascii") ], ) add_body = AttestationCertificateManagementBody(policy_certificate=jwk) cert_add_token = AttestationToken( body=add_body, signing_key=signing_key, signing_certificate=signing_certificate, body_type=AttestationCertificateManagementBody, ) # Merge our existing config options with the options for this API call. # Note that this must be done before calling into the implementation # layer because the implementation layer doesn't like keyword args that # it doesn't expect :(. options = merge_validation_args(self._config._kwargs, kwargs) cert_response = await self._client.policy_certificates.remove( cert_add_token.to_jwt_string(), **kwargs) token = AttestationToken( token=cert_response.token, body_type=GeneratedPolicyCertificatesModificationResult, ) if options.get("validate_token", True): token._validate_token(await self._get_signers(**kwargs), **options) return ( AttestationPolicyCertificateResult._from_generated( token._get_body()), token, )
def test_good(self): # Given a certificate chain unaffected by the Symantec deprecation cert_chain = [ # www.google.com load_pem_x509_certificate( """-----BEGIN CERTIFICATE----- MIIDxzCCAq+gAwIBAgIIPiCtWLuXgJ8wDQYJKoZIhvcNAQELBQAwVDELMAkGA1UE BhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczElMCMGA1UEAxMc R29vZ2xlIEludGVybmV0IEF1dGhvcml0eSBHMzAeFw0xODAyMjgyMzA0MTVaFw0x ODA1MjMyMjA5MDBaMGgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh MRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKDApHb29nbGUgSW5jMRcw FQYDVQQDDA53d3cuZ29vZ2xlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IA BNCoAa9TTYk7XhYNVADCSHNELcCGiHZyWA1PIUaanBwW2xAh+unTNrqJwPPoh2MI 9fs1TRvSHfq2Q3yOlIQm/g2jggFSMIIBTjATBgNVHSUEDDAKBggrBgEFBQcDATAO BgNVHQ8BAf8EBAMCB4AwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB BQUHAQEEXDBaMC0GCCsGAQUFBzAChiFodHRwOi8vcGtpLmdvb2cvZ3NyMi9HVFNH SUFHMy5jcnQwKQYIKwYBBQUHMAGGHWh0dHA6Ly9vY3NwLnBraS5nb29nL0dUU0dJ QUczMB0GA1UdDgQWBBRlhs6xDR5Yuw6s3r6v51JLBx4L8zAMBgNVHRMBAf8EAjAA MB8GA1UdIwQYMBaAFHfCuFCaZ3Z2sS3ChtCDoH6mfrpLMCEGA1UdIAQaMBgwDAYK KwYBBAHWeQIFAzAIBgZngQwBAgIwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2Ny bC5wa2kuZ29vZy9HVFNHSUFHMy5jcmwwDQYJKoZIhvcNAQELBQADggEBAH4jN7GJ /akcN6Uj2v9k8LlxdG0XZihpfDoQz1T3GPGe3ouzvx5bihV9VntljEywiSXLM6dy unjmXZzqywdk1Z3ss8Phkc1IoUB5fGo9Uslmqp1dhGns4jp9rnonIWb5STT64zBH NEZl8uL0Zel5MaYLdmtPESRC7a4/Bg4yxrITVvYsMBGbOUPj7g9FkQTyfK7jNccF F+IhhneyYPrtg+e1S8y7+qTdGVN40E6ByQfwCWcsngcW9zyuNY+cYQMr4DFoIZO/ t0IQ6jGEq2FeTREHAqcP0vRah5+GBwRDrUURBZOhE0AOuzuNhIANAd6STqRJdg3w R7vu2UObYzI35CU= -----END CERTIFICATE----- """.encode(encoding="ascii"), default_backend(), ), # Google Internet Authority G3 load_pem_x509_certificate( """-----BEGIN CERTIFICATE----- MIIEXDCCA0SgAwIBAgINAeOpMBz8cgY4P5pTHTANBgkqhkiG9w0BAQsFADBMMSAw HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy MTUwMDAwNDJaMFQxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg U2VydmljZXMxJTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzMw ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKUkvqHv/OJGuo2nIYaNVW XQ5IWi01CXZaz6TIHLGp/lOJ+600/4hbn7vn6AAB3DVzdQOts7G5pH0rJnnOFUAK 71G4nzKMfHCGUksW/mona+Y2emJQ2N+aicwJKetPKRSIgAuPOB6Aahh8Hb2XO3h9 RUk2T0HNouB2VzxoMXlkyW7XUR5mw6JkLHnA52XDVoRTWkNty5oCINLvGmnRsJ1z ouAqYGVQMc/7sy+/EYhALrVJEA8KbtyX+r8snwU5C1hUrwaW6MWOARa8qBpNQcWT kaIeoYvy/sGIJEmjR0vFEwHdp1cSaWIr6/4g72n7OqXwfinu7ZYW97EfoOSQJeAz AgMBAAGjggEzMIIBLzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUH AwEGCCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFHfCuFCa Z3Z2sS3ChtCDoH6mfrpLMB8GA1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYu MDUGCCsGAQUFBwEBBCkwJzAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdv b2cvZ3NyMjAyBgNVHR8EKzApMCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dz cjIvZ3NyMi5jcmwwPwYDVR0gBDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYc aHR0cHM6Ly9wa2kuZ29vZy9yZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEA HLeJluRT7bvs26gyAZ8so81trUISd7O45skDUmAge1cnxhG1P2cNmSxbWsoiCt2e ux9LSD+PAj2LIYRFHW31/6xoic1k4tbWXkDCjir37xTTNqRAMPUyFRWSdvt+nlPq wnb8Oa2I/maSJukcxDjNSfpDh/Bd1lZNgdd/8cLdsE3+wypufJ9uXO1iQpnh9zbu FIwsIONGl1p3A8CgxkqI/UAih3JaGOqcpcdaCIzkBaR9uYQ1X4k2Vg5APRLouzVy 7a8IVk6wuy6pm+T7HT4LY8ibS5FEZlfAFLSW8NwsVz9SBK2Vqn1N0PIMn5xA6NZV c7o835DLAFshEWfC7TIe3g== -----END CERTIFICATE----- """.encode(encoding="ascii"), default_backend(), ), # GlobalSign Root CA load_pem_x509_certificate( """-----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- """.encode(encoding="ascii"), default_backend(), ), ] # The class to check for Symantec CAs returns the right result assert SymantecDistructTester.get_distrust_timeline(cert_chain) is None
def ensure_certificate_valid(body: str): """Attempt loading of a PEM-encoded certificate""" load_pem_x509_certificate(body.encode("utf-8"), default_backend()) return body
args = parser.parse_args() for file_name in args.files: with open(file_name, 'rb') as hnd: crt = hnd.read() is_pem = file_name.endswith('.pem') or crt.startswith('-----BEGIN') if is_pem or args.pem: parts = re.split('-{5,}BEGIN', crt) if len(parts) == 0: continue if len(parts[0]) == 0: parts.pop(0) crt_arr = ['-----BEGIN' + x for x in parts] for key in crt_arr: try: x509 = load_pem_x509_certificate(key, get_backend()) print_mod_hex(x509, print_e=args.exponent) except Exception as e: traceback.print_exc() sys.stderr.write('Exception in parsing key: %s\n' % e) if not is_pem or args.der: try: x509 = load_der_x509_certificate(crt, get_backend()) print_mod_hex(x509, print_e=args.exponent) except Exception as e: traceback.print_exc() sys.stderr.write('Exception in parsing key: %s\n' % e)
def load_x509(data, backend=None): backend = get_backend(backend) return load_pem_x509_certificate(data, backend)
def test_march_2018(self): # Given a certificate chain issued by a Symantec CA that will be distrusted in March 2018 cert_chain = [ # www.careergame.com load_pem_x509_certificate( """-----BEGIN CERTIFICATE----- MIIF6zCCBNOgAwIBAgIDAgP0MA0GCSqGSIb3DQEBCwUAMGYxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMR0wGwYDVQQLExREb21haW4gVmFsaWRh dGVkIFNTTDEgMB4GA1UEAxMXR2VvVHJ1c3QgRFYgU1NMIENBIC0gRzQwHhcNMTUw ODI1MTc1NDE0WhcNMTgwOTI1MDcwNjE0WjCBljETMBEGA1UECxMKR1Q4NDM0MzI1 MzExMC8GA1UECxMoU2VlIHd3dy5nZW90cnVzdC5jb20vcmVzb3VyY2VzL2NwcyAo YykxNTEvMC0GA1UECxMmRG9tYWluIENvbnRyb2wgVmFsaWRhdGVkIC0gUXVpY2tT U0woUikxGzAZBgNVBAMTEnd3dy5jYXJlZXJnYW1lLmNvbTCCAiIwDQYJKoZIhvcN AQEBBQADggIPADCCAgoCggIBAO2G7lKIgIpkCO673Xe6c3uO/GW6GX7TxTsBh1iw +hGkefBs4dccMb6nynGb/nYEYwWj6vuQ/bxvZp7yBpEHpDvM9qxwaPeU3eOqEU8E 8iNNO0uL2t04r3tbkTK5eGh4/cCITta9fZzDeoqQ3Shpb5mRaAEsgPMurXoeBH3+ ZQDuAlsqHtOSG2leGf2moKnKbJzu/tLiNGsukjHfhdHtyePcBbmCg8mt5sru/5Jx d66A5CtbMaLlME2VOzAaePT9HL397Wss9HiIwRdiMTpMm/Hgr6clSYIdsHXCZ9/V 8HmjXMgSLQzBIB/ntervBkZmmfEz/+tt8OUU7bG5RhJf2PGacu/VszgXia5ymhia lIW+T2qdFjYwFHtKuPo33HeK03qiD9Q7RIIXzPUWkCiL1GNdZtKET3CPF/mL+tbr zMa1cghPtSYP8URdaV1B0VsCFPlB930pTr104k59ogj099sXZI/Q5tqA+vOry3MH 9kvAul5sb8XW2zJ/Hvnmb3cuI+EWCKkUlHnYmvPvjvrt6jTCbYyG1toZ2CvWLJit 49Xh5CKMyN7STjAyeJ5qAGwZaJaHyUPlymT8g6SmtXoaf4XqyL29y+gbyZ/a3+If ync1j3BDqoSvX6+7dXvsfPSJb8n85PSVQDYAlNKJN2Hb4uKbxvKnz9A5SFir32n8 H01rAgMBAAGjggFvMIIBazAfBgNVHSMEGDAWgBQLUOx37yqb/+wDoQr/rcbkKhjH PjBXBggrBgEFBQcBAQRLMEkwHwYIKwYBBQUHMAGGE2h0dHA6Ly9ndS5zeW1jZC5j b20wJgYIKwYBBQUHMAKGGmh0dHA6Ly9ndS5zeW1jYi5jb20vZ3UuY3J0MA4GA1Ud DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwLQYDVR0R BCYwJIISd3d3LmNhcmVlcmdhbWUuY29tgg5jYXJlZXJnYW1lLmNvbTArBgNVHR8E JDAiMCCgHqAchhpodHRwOi8vZ3Uuc3ltY2IuY29tL2d1LmNybDAMBgNVHRMBAf8E AjAAMFYGA1UdIARPME0wSwYGZ4EMAQIBMEEwPwYIKwYBBQUHAgEWM2h0dHBzOi8v d3d3Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeS9sZWdhbDANBgkq hkiG9w0BAQsFAAOCAQEAb3zs0ONhor2xgIvPEYklqGaO2Do3C1a74+tNMOREqW9G kH5EPQu/w+tbzlpIaEihtenHLStTI+tHSimuGTeF0jm03t6J/bhgR2zgp6lmhQzv k6babANTO4IyQckh9qtIKQ9RGUzva+YtKe3LauS6lxl3dQvytClZy36PX4TaV59i EyCN38LY+4mzkddqNV4hm6+ON/7q9WG2zVoxFzDX8Kv/FogP4ivspFJUWtF5xZ2X QzQuVEXo8FVfMP9wqDEQe1IeOePcYMFEBt4/evEneUvEX2MNLc+wMt8qf44pxryp 8NIYplnoidK7+W1YRQcFUhx/3xbyoBB2fEHCsvyYGw== -----END CERTIFICATE----- """.encode(encoding="ascii"), default_backend(), ), # GeoTrust DV SSL load_pem_x509_certificate( """-----BEGIN CERTIFICATE----- MIIERDCCAyygAwIBAgIDAjp4MA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i YWwgQ0EwHhcNMTQwODI5MjIyNDU4WhcNMjIwNTIwMjIyNDU4WjBmMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UECxMURG9tYWluIFZh bGlkYXRlZCBTU0wxIDAeBgNVBAMTF0dlb1RydXN0IERWIFNTTCBDQSAtIEc0MIIB IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA30GUetr35DFDtuoBG1zOY+r6 baPZau4tmnX51ZxbvTTf2BzJbdgEiNputbe18DCuQNZd+sRTwdQinQROEaaV1UV8 QQVY4Ezd+e5VvV9G3K0TCJ0s5PeC5gcrng6MNKHOxKHggXCGAAY/Lep8myiuGyiL OQnT5/BFpLG6EWeQVXuP3u04XKHh44PEw3KRT5juHMKAqmSlPoNiHMzgnvhawBMS faKni6PnnyrXm8rL7ZcBnCiEUQRQQby0/HjpG88U6h8P/C4BMo22NcsKGDvsWj48 G9OZQx4v973zWxK5B17tPtGph8x3cifU2XWiY0uTNr3lXNe/X3kNszKnC7JjIwID AQABo4IBHTCCARkwHwYDVR0jBBgwFoAUwHqYaI2J+6sFZAwRfap9ZbjKzE4wHQYD VR0OBBYEFAtQ7HfvKpv/7AOhCv+txuQqGMc+MBIGA1UdEwEB/wQIMAYBAf8CAQAw DgYDVR0PAQH/BAQDAgEGMDUGA1UdHwQuMCwwKqAooCaGJGh0dHA6Ly9nLnN5bWNi LmNvbS9jcmxzL2d0Z2xvYmFsLmNybDAuBggrBgEFBQcBAQQiMCAwHgYIKwYBBQUH MAGGEmh0dHA6Ly9nLnN5bWNkLmNvbTBMBgNVHSAERTBDMEEGCmCGSAGG+EUBBzYw MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nZW90cnVzdC5jb20vcmVzb3VyY2Vz L2NwczANBgkqhkiG9w0BAQsFAAOCAQEAMyTVkKopDDW5L8PHQpPAxhBLAwh2hBCi 4OdTEifyCtp/Otz9XHlajxd0Q1Ox1dFdWbmmhGTK8ToKWZYQv6mBV4tch9x/4+S7 BXqgMgkTThCBKB+cA2K89AG1KYNGB7nnuF3I6dHdrTv4NNvB0ZWpkRjtPCw3EU3M /lM+UEP5w1ZBrFObbAWymuLgWVcwMrYmThMlzfpIcA91VWAR9TvVXlo8i1sPD2JC SGGFixD0wYi/f1+KwtfNK5RcHzRKCK/rromoSHVVlR27wJoBufQDIj7U5lIwDWe5 wJH9LUwwjr2MpQSRu6Srfw/Yb/BmAMmjXPWwj4PmnFrmtrnFvL7kAg== -----END CERTIFICATE----- """.encode(encoding="ascii"), default_backend(), ), # GeoTrust Global CA load_pem_x509_certificate( self._GEOTRUST_GLOBAL_CA_CERT.encode(encoding="ascii"), default_backend()), ] # The class to check for Symantec CAs returns the right result assert SymantecDistructTester.get_distrust_timeline( cert_chain) == SymantecDistrustTimelineEnum.MARCH_2018