def _read_pem_cert_from_data(f, password, key_converter, cert_converter): def PEM_SSLError(err): # Shorthand from _socket import SSLError, SSL_ERROR_SSL return SSLError(SSL_ERROR_SSL, "PEM lib ({})".format(err)) certs = [] private_key = None if key_converter is None: key_converter = JcaPEMKeyConverter().setProvider("BC") if cert_converter is None: cert_converter = JcaX509CertificateConverter().setProvider("BC") for br in _extract_readers(f): while True: try: obj = PEMParser(br).readObject() except PEMException as err: raise PEM_SSLError(err) except DecoderException as err: raise PEM_SSLError(err) if obj is None: break if isinstance(obj, PEMKeyPair): private_key = key_converter.getKeyPair(obj).getPrivate() elif isinstance(obj, PrivateKeyInfo): private_key = key_converter.getPrivateKey(obj) elif isinstance(obj, X509CertificateHolder): certs.append(cert_converter.getCertificate(obj)) elif isinstance(obj, PEMEncryptedKeyPair): provider = JcePEMDecryptorProviderBuilder().build( _parse_password(password)) try: key_pair = key_converter.getKeyPair( obj.decryptKeyPair(provider)) except EncryptionException as err: raise PEM_SSLError(err) private_key = key_pair.getPrivate() else: raise NotImplementedError( "Jython does not implement PEM object {!r}".format(obj)) return certs, private_key
def _extract_certs_for_paths(paths, password=None): # Go from Bouncy Castle API to Java's; a bit heavyweight for the Python dev ;) key_converter = JcaPEMKeyConverter().setProvider("BC") cert_converter = JcaX509CertificateConverter().setProvider("BC") certs = [] private_key = None for path in paths: err = None with open(path) as f: # try to load the file as keystore file first try: _certs = _extract_certs_from_keystore_file(f, password) certs.extend(_certs) except IOException as err: pass # reported as 'Invalid keystore format' if err is not None: # try loading pem version instead with open(path) as f: _certs, _private_key = _extract_cert_from_data(f, password, key_converter, cert_converter) private_key = _private_key if _private_key else private_key certs.extend(_certs) return certs, private_key