mirror of
https://github.com/certbot/certbot.git
synced 2026-08-01 19:02:52 +02:00
Check_untyped_defs in mypy with clean output for acme (#5874)
* check_untyped_defs in mypy with clean output for acme * test entire acme module * Add typing as a dependency because it's only in the stdlib for 3.5+ * Add str_utils, modified for python2.7 compatibility * make mypy happy in acme * typing is needed in prod * we actually only need typing in acme so far * add tests and more docs for str_utils * pragma no cover * add magic_typing * s/from typing/from magic_typing/g * move typing to dev_extras * correctly set up imports * remove str_utils * only type: ignore for OpenSSL.SSL, not crypto * Since we only run mypy with python3 anyway and we're fine importing it when it's not actually there, there's no actual need for typing to be present as a dependency * comment magic_typing.py * disable wildcard-import im magic_typing * disable pylint errors * add magic_typing_test * make magic_typing tests work alongside other tests * make sure temp_typing is set * add typing as a dev dependency for python3.4 * run mypy with python3.4 on travis to get a little more testing with different environments * don't stick typing into sys.modules * reorder imports
This commit is contained in:
@@ -29,6 +29,8 @@ matrix:
|
|||||||
addons:
|
addons:
|
||||||
- python: "2.7"
|
- python: "2.7"
|
||||||
env: TOXENV=lint
|
env: TOXENV=lint
|
||||||
|
- python: "3.4"
|
||||||
|
env: TOXENV=mypy
|
||||||
- python: "3.5"
|
- python: "3.5"
|
||||||
env: TOXENV=mypy
|
env: TOXENV=mypy
|
||||||
- python: "2.7"
|
- python: "2.7"
|
||||||
|
|||||||
@@ -478,7 +478,7 @@ class TLSSNI01Response(KeyAuthorizationChallengeResponse):
|
|||||||
try:
|
try:
|
||||||
cert = self.probe_cert(domain=domain, **kwargs)
|
cert = self.probe_cert(domain=domain, **kwargs)
|
||||||
except errors.Error as error:
|
except errors.Error as error:
|
||||||
logger.debug(error, exc_info=True)
|
logger.debug(str(error), exc_info=True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
return self.verify_cert(cert)
|
return self.verify_cert(cert)
|
||||||
|
|||||||
+5
-4
@@ -9,7 +9,6 @@ import time
|
|||||||
|
|
||||||
import six
|
import six
|
||||||
from six.moves import http_client # pylint: disable=import-error
|
from six.moves import http_client # pylint: disable=import-error
|
||||||
|
|
||||||
import josepy as jose
|
import josepy as jose
|
||||||
import OpenSSL
|
import OpenSSL
|
||||||
import re
|
import re
|
||||||
@@ -20,6 +19,8 @@ from acme import crypto_util
|
|||||||
from acme import errors
|
from acme import errors
|
||||||
from acme import jws
|
from acme import jws
|
||||||
from acme import messages
|
from acme import messages
|
||||||
|
# pylint: disable=unused-import, no-name-in-module
|
||||||
|
from acme.magic_typing import Dict, List, Set, Text
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -415,7 +416,7 @@ class Client(ClientBase):
|
|||||||
"""
|
"""
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
assert max_attempts > 0
|
assert max_attempts > 0
|
||||||
attempts = collections.defaultdict(int)
|
attempts = collections.defaultdict(int) # type: Dict[messages.AuthorizationResource, int]
|
||||||
exhausted = set()
|
exhausted = set()
|
||||||
|
|
||||||
# priority queue with datetime.datetime (based on Retry-After) as key,
|
# priority queue with datetime.datetime (based on Retry-After) as key,
|
||||||
@@ -529,7 +530,7 @@ class Client(ClientBase):
|
|||||||
:rtype: `list` of `OpenSSL.crypto.X509` wrapped in `.ComparableX509`
|
:rtype: `list` of `OpenSSL.crypto.X509` wrapped in `.ComparableX509`
|
||||||
|
|
||||||
"""
|
"""
|
||||||
chain = []
|
chain = [] # type: List[jose.ComparableX509]
|
||||||
uri = certr.cert_chain_uri
|
uri = certr.cert_chain_uri
|
||||||
while uri is not None and len(chain) < max_length:
|
while uri is not None and len(chain) < max_length:
|
||||||
response, cert = self._get_cert(uri)
|
response, cert = self._get_cert(uri)
|
||||||
@@ -864,7 +865,7 @@ class ClientNetwork(object): # pylint: disable=too-many-instance-attributes
|
|||||||
self.account = account
|
self.account = account
|
||||||
self.alg = alg
|
self.alg = alg
|
||||||
self.verify_ssl = verify_ssl
|
self.verify_ssl = verify_ssl
|
||||||
self._nonces = set()
|
self._nonces = set() # type: Set[Text]
|
||||||
self.user_agent = user_agent
|
self.user_agent = user_agent
|
||||||
self.session = requests.Session()
|
self.session = requests.Session()
|
||||||
self._default_timeout = timeout
|
self._default_timeout = timeout
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ from acme import jws as acme_jws
|
|||||||
from acme import messages
|
from acme import messages
|
||||||
from acme import messages_test
|
from acme import messages_test
|
||||||
from acme import test_util
|
from acme import test_util
|
||||||
|
from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module
|
||||||
|
|
||||||
|
|
||||||
CERT_DER = test_util.load_vector('cert.der')
|
CERT_DER = test_util.load_vector('cert.der')
|
||||||
@@ -61,7 +62,8 @@ class ClientTestBase(unittest.TestCase):
|
|||||||
self.contact = ('mailto:cert-admin@example.com', 'tel:+12025551212')
|
self.contact = ('mailto:cert-admin@example.com', 'tel:+12025551212')
|
||||||
reg = messages.Registration(
|
reg = messages.Registration(
|
||||||
contact=self.contact, key=KEY.public_key())
|
contact=self.contact, key=KEY.public_key())
|
||||||
self.new_reg = messages.NewRegistration(**dict(reg))
|
the_arg = dict(reg) # type: Dict
|
||||||
|
self.new_reg = messages.NewRegistration(**the_arg) # pylint: disable=star-args
|
||||||
self.regr = messages.RegistrationResource(
|
self.regr = messages.RegistrationResource(
|
||||||
body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1')
|
body=reg, uri='https://www.letsencrypt-demo.org/acme/reg/1')
|
||||||
|
|
||||||
|
|||||||
+33
-30
@@ -6,11 +6,13 @@ import os
|
|||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
import OpenSSL
|
from OpenSSL import crypto
|
||||||
|
from OpenSSL import SSL # type: ignore # https://github.com/python/typeshed/issues/2052
|
||||||
import josepy as jose
|
import josepy as jose
|
||||||
|
|
||||||
|
|
||||||
from acme import errors
|
from acme import errors
|
||||||
|
# pylint: disable=unused-import, no-name-in-module
|
||||||
|
from acme.magic_typing import Callable, Text, Union
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -25,7 +27,7 @@ logger = logging.getLogger(__name__)
|
|||||||
# https://www.openssl.org/docs/ssl/SSLv23_method.html). _serve_sni
|
# https://www.openssl.org/docs/ssl/SSLv23_method.html). _serve_sni
|
||||||
# should be changed to use "set_options" to disable SSLv2 and SSLv3,
|
# should be changed to use "set_options" to disable SSLv2 and SSLv3,
|
||||||
# in case it's used for things other than probing/serving!
|
# in case it's used for things other than probing/serving!
|
||||||
_DEFAULT_TLSSNI01_SSL_METHOD = OpenSSL.SSL.SSLv23_METHOD # type: ignore
|
_DEFAULT_TLSSNI01_SSL_METHOD = SSL.SSLv23_METHOD # type: ignore
|
||||||
|
|
||||||
|
|
||||||
class SSLSocket(object): # pylint: disable=too-few-public-methods
|
class SSLSocket(object): # pylint: disable=too-few-public-methods
|
||||||
@@ -64,9 +66,9 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods
|
|||||||
logger.debug("Server name (%s) not recognized, dropping SSL",
|
logger.debug("Server name (%s) not recognized, dropping SSL",
|
||||||
server_name)
|
server_name)
|
||||||
return
|
return
|
||||||
new_context = OpenSSL.SSL.Context(self.method)
|
new_context = SSL.Context(self.method)
|
||||||
new_context.set_options(OpenSSL.SSL.OP_NO_SSLv2)
|
new_context.set_options(SSL.OP_NO_SSLv2)
|
||||||
new_context.set_options(OpenSSL.SSL.OP_NO_SSLv3)
|
new_context.set_options(SSL.OP_NO_SSLv3)
|
||||||
new_context.use_privatekey(key)
|
new_context.use_privatekey(key)
|
||||||
new_context.use_certificate(cert)
|
new_context.use_certificate(cert)
|
||||||
connection.set_context(new_context)
|
connection.set_context(new_context)
|
||||||
@@ -89,18 +91,18 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods
|
|||||||
def accept(self): # pylint: disable=missing-docstring
|
def accept(self): # pylint: disable=missing-docstring
|
||||||
sock, addr = self.sock.accept()
|
sock, addr = self.sock.accept()
|
||||||
|
|
||||||
context = OpenSSL.SSL.Context(self.method)
|
context = SSL.Context(self.method)
|
||||||
context.set_options(OpenSSL.SSL.OP_NO_SSLv2)
|
context.set_options(SSL.OP_NO_SSLv2)
|
||||||
context.set_options(OpenSSL.SSL.OP_NO_SSLv3)
|
context.set_options(SSL.OP_NO_SSLv3)
|
||||||
context.set_tlsext_servername_callback(self._pick_certificate_cb)
|
context.set_tlsext_servername_callback(self._pick_certificate_cb)
|
||||||
|
|
||||||
ssl_sock = self.FakeConnection(OpenSSL.SSL.Connection(context, sock))
|
ssl_sock = self.FakeConnection(SSL.Connection(context, sock))
|
||||||
ssl_sock.set_accept_state()
|
ssl_sock.set_accept_state()
|
||||||
|
|
||||||
logger.debug("Performing handshake with %s", addr)
|
logger.debug("Performing handshake with %s", addr)
|
||||||
try:
|
try:
|
||||||
ssl_sock.do_handshake()
|
ssl_sock.do_handshake()
|
||||||
except OpenSSL.SSL.Error as error:
|
except SSL.Error as error:
|
||||||
# _pick_certificate_cb might have returned without
|
# _pick_certificate_cb might have returned without
|
||||||
# creating SSL context (wrong server name)
|
# creating SSL context (wrong server name)
|
||||||
raise socket.error(error)
|
raise socket.error(error)
|
||||||
@@ -128,7 +130,7 @@ def probe_sni(name, host, port=443, timeout=300,
|
|||||||
:rtype: OpenSSL.crypto.X509
|
:rtype: OpenSSL.crypto.X509
|
||||||
|
|
||||||
"""
|
"""
|
||||||
context = OpenSSL.SSL.Context(method)
|
context = SSL.Context(method)
|
||||||
context.set_timeout(timeout)
|
context.set_timeout(timeout)
|
||||||
|
|
||||||
socket_kwargs = {'source_address': source_address}
|
socket_kwargs = {'source_address': source_address}
|
||||||
@@ -145,13 +147,13 @@ def probe_sni(name, host, port=443, timeout=300,
|
|||||||
raise errors.Error(error)
|
raise errors.Error(error)
|
||||||
|
|
||||||
with contextlib.closing(sock) as client:
|
with contextlib.closing(sock) as client:
|
||||||
client_ssl = OpenSSL.SSL.Connection(context, client)
|
client_ssl = SSL.Connection(context, client)
|
||||||
client_ssl.set_connect_state()
|
client_ssl.set_connect_state()
|
||||||
client_ssl.set_tlsext_host_name(name) # pyOpenSSL>=0.13
|
client_ssl.set_tlsext_host_name(name) # pyOpenSSL>=0.13
|
||||||
try:
|
try:
|
||||||
client_ssl.do_handshake()
|
client_ssl.do_handshake()
|
||||||
client_ssl.shutdown()
|
client_ssl.shutdown()
|
||||||
except OpenSSL.SSL.Error as error:
|
except SSL.Error as error:
|
||||||
raise errors.Error(error)
|
raise errors.Error(error)
|
||||||
return client_ssl.get_peer_certificate()
|
return client_ssl.get_peer_certificate()
|
||||||
|
|
||||||
@@ -164,18 +166,18 @@ def make_csr(private_key_pem, domains, must_staple=False):
|
|||||||
OCSP Must Staple: https://tools.ietf.org/html/rfc7633).
|
OCSP Must Staple: https://tools.ietf.org/html/rfc7633).
|
||||||
:returns: buffer PEM-encoded Certificate Signing Request.
|
:returns: buffer PEM-encoded Certificate Signing Request.
|
||||||
"""
|
"""
|
||||||
private_key = OpenSSL.crypto.load_privatekey(
|
private_key = crypto.load_privatekey(
|
||||||
OpenSSL.crypto.FILETYPE_PEM, private_key_pem)
|
crypto.FILETYPE_PEM, private_key_pem)
|
||||||
csr = OpenSSL.crypto.X509Req()
|
csr = crypto.X509Req()
|
||||||
extensions = [
|
extensions = [
|
||||||
OpenSSL.crypto.X509Extension(
|
crypto.X509Extension(
|
||||||
b'subjectAltName',
|
b'subjectAltName',
|
||||||
critical=False,
|
critical=False,
|
||||||
value=', '.join('DNS:' + d for d in domains).encode('ascii')
|
value=', '.join('DNS:' + d for d in domains).encode('ascii')
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
if must_staple:
|
if must_staple:
|
||||||
extensions.append(OpenSSL.crypto.X509Extension(
|
extensions.append(crypto.X509Extension(
|
||||||
b"1.3.6.1.5.5.7.1.24",
|
b"1.3.6.1.5.5.7.1.24",
|
||||||
critical=False,
|
critical=False,
|
||||||
value=b"DER:30:03:02:01:05"))
|
value=b"DER:30:03:02:01:05"))
|
||||||
@@ -183,8 +185,8 @@ def make_csr(private_key_pem, domains, must_staple=False):
|
|||||||
csr.set_pubkey(private_key)
|
csr.set_pubkey(private_key)
|
||||||
csr.set_version(2)
|
csr.set_version(2)
|
||||||
csr.sign(private_key, 'sha256')
|
csr.sign(private_key, 'sha256')
|
||||||
return OpenSSL.crypto.dump_certificate_request(
|
return crypto.dump_certificate_request(
|
||||||
OpenSSL.crypto.FILETYPE_PEM, csr)
|
crypto.FILETYPE_PEM, csr)
|
||||||
|
|
||||||
def _pyopenssl_cert_or_req_all_names(loaded_cert_or_req):
|
def _pyopenssl_cert_or_req_all_names(loaded_cert_or_req):
|
||||||
common_name = loaded_cert_or_req.get_subject().CN
|
common_name = loaded_cert_or_req.get_subject().CN
|
||||||
@@ -221,11 +223,12 @@ def _pyopenssl_cert_or_req_san(cert_or_req):
|
|||||||
parts_separator = ", "
|
parts_separator = ", "
|
||||||
prefix = "DNS" + part_separator
|
prefix = "DNS" + part_separator
|
||||||
|
|
||||||
if isinstance(cert_or_req, OpenSSL.crypto.X509):
|
if isinstance(cert_or_req, crypto.X509):
|
||||||
func = OpenSSL.crypto.dump_certificate
|
# pylint: disable=line-too-long
|
||||||
|
func = crypto.dump_certificate # type: Union[Callable[[int, crypto.X509Req], bytes], Callable[[int, crypto.X509], bytes]]
|
||||||
else:
|
else:
|
||||||
func = OpenSSL.crypto.dump_certificate_request
|
func = crypto.dump_certificate_request
|
||||||
text = func(OpenSSL.crypto.FILETYPE_TEXT, cert_or_req).decode("utf-8")
|
text = func(crypto.FILETYPE_TEXT, cert_or_req).decode("utf-8")
|
||||||
# WARNING: this function does not support multiple SANs extensions.
|
# WARNING: this function does not support multiple SANs extensions.
|
||||||
# Multiple X509v3 extensions of the same type is disallowed by RFC 5280.
|
# Multiple X509v3 extensions of the same type is disallowed by RFC 5280.
|
||||||
match = re.search(r"X509v3 Subject Alternative Name:(?: critical)?\s*(.*)", text)
|
match = re.search(r"X509v3 Subject Alternative Name:(?: critical)?\s*(.*)", text)
|
||||||
@@ -252,12 +255,12 @@ def gen_ss_cert(key, domains, not_before=None,
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
assert domains, "Must provide one or more hostnames for the cert."
|
assert domains, "Must provide one or more hostnames for the cert."
|
||||||
cert = OpenSSL.crypto.X509()
|
cert = crypto.X509()
|
||||||
cert.set_serial_number(int(binascii.hexlify(os.urandom(16)), 16))
|
cert.set_serial_number(int(binascii.hexlify(os.urandom(16)), 16))
|
||||||
cert.set_version(2)
|
cert.set_version(2)
|
||||||
|
|
||||||
extensions = [
|
extensions = [
|
||||||
OpenSSL.crypto.X509Extension(
|
crypto.X509Extension(
|
||||||
b"basicConstraints", True, b"CA:TRUE, pathlen:0"),
|
b"basicConstraints", True, b"CA:TRUE, pathlen:0"),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -266,7 +269,7 @@ def gen_ss_cert(key, domains, not_before=None,
|
|||||||
cert.set_issuer(cert.get_subject())
|
cert.set_issuer(cert.get_subject())
|
||||||
|
|
||||||
if force_san or len(domains) > 1:
|
if force_san or len(domains) > 1:
|
||||||
extensions.append(OpenSSL.crypto.X509Extension(
|
extensions.append(crypto.X509Extension(
|
||||||
b"subjectAltName",
|
b"subjectAltName",
|
||||||
critical=False,
|
critical=False,
|
||||||
value=b", ".join(b"DNS:" + d.encode() for d in domains)
|
value=b", ".join(b"DNS:" + d.encode() for d in domains)
|
||||||
@@ -281,7 +284,7 @@ def gen_ss_cert(key, domains, not_before=None,
|
|||||||
cert.sign(key, "sha256")
|
cert.sign(key, "sha256")
|
||||||
return cert
|
return cert
|
||||||
|
|
||||||
def dump_pyopenssl_chain(chain, filetype=OpenSSL.crypto.FILETYPE_PEM):
|
def dump_pyopenssl_chain(chain, filetype=crypto.FILETYPE_PEM):
|
||||||
"""Dump certificate chain into a bundle.
|
"""Dump certificate chain into a bundle.
|
||||||
|
|
||||||
:param list chain: List of `OpenSSL.crypto.X509` (or wrapped in
|
:param list chain: List of `OpenSSL.crypto.X509` (or wrapped in
|
||||||
@@ -298,7 +301,7 @@ def dump_pyopenssl_chain(chain, filetype=OpenSSL.crypto.FILETYPE_PEM):
|
|||||||
if isinstance(cert, jose.ComparableX509):
|
if isinstance(cert, jose.ComparableX509):
|
||||||
# pylint: disable=protected-access
|
# pylint: disable=protected-access
|
||||||
cert = cert.wrapped
|
cert = cert.wrapped
|
||||||
return OpenSSL.crypto.dump_certificate(filetype, cert)
|
return crypto.dump_certificate(filetype, cert)
|
||||||
|
|
||||||
# assumes that OpenSSL.crypto.dump_certificate includes ending
|
# assumes that OpenSSL.crypto.dump_certificate includes ending
|
||||||
# newline character
|
# newline character
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import OpenSSL
|
|||||||
|
|
||||||
from acme import errors
|
from acme import errors
|
||||||
from acme import test_util
|
from acme import test_util
|
||||||
|
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||||
|
|
||||||
|
|
||||||
class SSLSocketAndProbeSNITest(unittest.TestCase):
|
class SSLSocketAndProbeSNITest(unittest.TestCase):
|
||||||
@@ -165,7 +166,7 @@ class RandomSnTest(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.cert_count = 5
|
self.cert_count = 5
|
||||||
self.serial_num = []
|
self.serial_num = [] # type: List[int]
|
||||||
self.key = OpenSSL.crypto.PKey()
|
self.key = OpenSSL.crypto.PKey()
|
||||||
self.key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
|
self.key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
"""Shim class to not have to depend on typing module in prod."""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class TypingClass(object):
|
||||||
|
"""Ignore import errors by getting anything"""
|
||||||
|
def __getattr__(self, name):
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
# mypy doesn't respect modifying sys.modules
|
||||||
|
from typing import * # pylint: disable=wildcard-import, unused-wildcard-import
|
||||||
|
except ImportError:
|
||||||
|
sys.modules[__name__] = TypingClass()
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
"""Tests for acme.magic_typing."""
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
|
|
||||||
|
class MagicTypingTest(unittest.TestCase):
|
||||||
|
"""Tests for acme.magic_typing."""
|
||||||
|
def test_import_success(self):
|
||||||
|
try:
|
||||||
|
import typing as temp_typing
|
||||||
|
except ImportError: # pragma: no cover
|
||||||
|
temp_typing = None # pragma: no cover
|
||||||
|
typing_class_mock = mock.MagicMock()
|
||||||
|
text_mock = mock.MagicMock()
|
||||||
|
typing_class_mock.Text = text_mock
|
||||||
|
sys.modules['typing'] = typing_class_mock
|
||||||
|
if 'acme.magic_typing' in sys.modules:
|
||||||
|
del sys.modules['acme.magic_typing'] # pragma: no cover
|
||||||
|
from acme.magic_typing import Text # pylint: disable=no-name-in-module
|
||||||
|
self.assertEqual(Text, text_mock)
|
||||||
|
del sys.modules['acme.magic_typing']
|
||||||
|
sys.modules['typing'] = temp_typing
|
||||||
|
|
||||||
|
def test_import_failure(self):
|
||||||
|
try:
|
||||||
|
import typing as temp_typing
|
||||||
|
except ImportError: # pragma: no cover
|
||||||
|
temp_typing = None # pragma: no cover
|
||||||
|
sys.modules['typing'] = None
|
||||||
|
if 'acme.magic_typing' in sys.modules:
|
||||||
|
del sys.modules['acme.magic_typing'] # pragma: no cover
|
||||||
|
from acme.magic_typing import Text # pylint: disable=no-name-in-module
|
||||||
|
self.assertTrue(Text is None)
|
||||||
|
del sys.modules['acme.magic_typing']
|
||||||
|
sys.modules['typing'] = temp_typing
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main() # pragma: no cover
|
||||||
@@ -6,6 +6,7 @@ import mock
|
|||||||
|
|
||||||
from acme import challenges
|
from acme import challenges
|
||||||
from acme import test_util
|
from acme import test_util
|
||||||
|
from acme.magic_typing import Dict # pylint: disable=unused-import, no-name-in-module
|
||||||
|
|
||||||
|
|
||||||
CERT = test_util.load_comparable_cert('cert.der')
|
CERT = test_util.load_comparable_cert('cert.der')
|
||||||
@@ -85,7 +86,7 @@ class ConstantTest(unittest.TestCase):
|
|||||||
from acme.messages import _Constant
|
from acme.messages import _Constant
|
||||||
|
|
||||||
class MockConstant(_Constant): # pylint: disable=missing-docstring
|
class MockConstant(_Constant): # pylint: disable=missing-docstring
|
||||||
POSSIBLE_NAMES = {}
|
POSSIBLE_NAMES = {} # type: Dict
|
||||||
|
|
||||||
self.MockConstant = MockConstant # pylint: disable=invalid-name
|
self.MockConstant = MockConstant # pylint: disable=invalid-name
|
||||||
self.const_a = MockConstant('a')
|
self.const_a = MockConstant('a')
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import OpenSSL
|
|||||||
|
|
||||||
from acme import challenges
|
from acme import challenges
|
||||||
from acme import crypto_util
|
from acme import crypto_util
|
||||||
|
from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-module
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -66,8 +67,8 @@ class BaseDualNetworkedServers(object):
|
|||||||
|
|
||||||
def __init__(self, ServerClass, server_address, *remaining_args, **kwargs):
|
def __init__(self, ServerClass, server_address, *remaining_args, **kwargs):
|
||||||
port = server_address[1]
|
port = server_address[1]
|
||||||
self.threads = []
|
self.threads = [] # type: List[threading.Thread]
|
||||||
self.servers = []
|
self.servers = [] # type: List[ACMEServerMixin]
|
||||||
|
|
||||||
# Must try True first.
|
# Must try True first.
|
||||||
# Ubuntu, for example, will fail to bind to IPv4 if we've already bound
|
# Ubuntu, for example, will fail to bind to IPv4 if we've already bound
|
||||||
@@ -189,7 +190,7 @@ class HTTP01RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.simple_http_resources = kwargs.pop("simple_http_resources", set())
|
self.simple_http_resources = kwargs.pop("simple_http_resources", set())
|
||||||
socketserver.BaseRequestHandler.__init__(self, *args, **kwargs)
|
BaseHTTPServer.BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def log_message(self, format, *args): # pylint: disable=redefined-builtin
|
def log_message(self, format, *args): # pylint: disable=redefined-builtin
|
||||||
"""Log arbitrary message."""
|
"""Log arbitrary message."""
|
||||||
@@ -262,7 +263,7 @@ def simple_tls_sni_01_server(cli_args, forever=True):
|
|||||||
|
|
||||||
certs = {}
|
certs = {}
|
||||||
|
|
||||||
_, hosts, _ = next(os.walk('.'))
|
_, hosts, _ = next(os.walk('.')) # type: ignore # https://github.com/python/mypy/issues/465
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
with open(os.path.join(host, "cert.pem")) as cert_file:
|
with open(os.path.join(host, "cert.pem")) as cert_file:
|
||||||
cert_contents = cert_file.read()
|
cert_contents = cert_file.read()
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ from acme import challenges
|
|||||||
from acme import crypto_util
|
from acme import crypto_util
|
||||||
from acme import errors
|
from acme import errors
|
||||||
from acme import test_util
|
from acme import test_util
|
||||||
|
from acme.magic_typing import Set # pylint: disable=unused-import, no-name-in-module
|
||||||
|
|
||||||
|
|
||||||
class TLSServerTest(unittest.TestCase):
|
class TLSServerTest(unittest.TestCase):
|
||||||
@@ -72,7 +73,7 @@ class HTTP01ServerTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.account_key = jose.JWK.load(
|
self.account_key = jose.JWK.load(
|
||||||
test_util.load_vector('rsa1024_key.pem'))
|
test_util.load_vector('rsa1024_key.pem'))
|
||||||
self.resources = set()
|
self.resources = set() # type: Set
|
||||||
|
|
||||||
from acme.standalone import HTTP01Server
|
from acme.standalone import HTTP01Server
|
||||||
self.server = HTTP01Server(('', 0), resources=self.resources)
|
self.server = HTTP01Server(('', 0), resources=self.resources)
|
||||||
@@ -201,7 +202,7 @@ class HTTP01DualNetworkedServersTest(unittest.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.account_key = jose.JWK.load(
|
self.account_key = jose.JWK.load(
|
||||||
test_util.load_vector('rsa1024_key.pem'))
|
test_util.load_vector('rsa1024_key.pem'))
|
||||||
self.resources = set()
|
self.resources = set() # type: Set
|
||||||
|
|
||||||
from acme.standalone import HTTP01DualNetworkedServers
|
from acme.standalone import HTTP01DualNetworkedServers
|
||||||
self.servers = HTTP01DualNetworkedServers(('', 0), resources=self.resources)
|
self.servers = HTTP01DualNetworkedServers(('', 0), resources=self.resources)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import unittest
|
|||||||
from cryptography.hazmat.backends import default_backend
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
import josepy as jose
|
import josepy as jose
|
||||||
import OpenSSL
|
from OpenSSL import crypto
|
||||||
|
|
||||||
|
|
||||||
def vector_path(*names):
|
def vector_path(*names):
|
||||||
@@ -39,8 +39,8 @@ def _guess_loader(filename, loader_pem, loader_der):
|
|||||||
def load_cert(*names):
|
def load_cert(*names):
|
||||||
"""Load certificate."""
|
"""Load certificate."""
|
||||||
loader = _guess_loader(
|
loader = _guess_loader(
|
||||||
names[-1], OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.FILETYPE_ASN1)
|
names[-1], crypto.FILETYPE_PEM, crypto.FILETYPE_ASN1)
|
||||||
return OpenSSL.crypto.load_certificate(loader, load_vector(*names))
|
return crypto.load_certificate(loader, load_vector(*names))
|
||||||
|
|
||||||
|
|
||||||
def load_comparable_cert(*names):
|
def load_comparable_cert(*names):
|
||||||
@@ -51,8 +51,8 @@ def load_comparable_cert(*names):
|
|||||||
def load_csr(*names):
|
def load_csr(*names):
|
||||||
"""Load certificate request."""
|
"""Load certificate request."""
|
||||||
loader = _guess_loader(
|
loader = _guess_loader(
|
||||||
names[-1], OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.FILETYPE_ASN1)
|
names[-1], crypto.FILETYPE_PEM, crypto.FILETYPE_ASN1)
|
||||||
return OpenSSL.crypto.load_certificate_request(loader, load_vector(*names))
|
return crypto.load_certificate_request(loader, load_vector(*names))
|
||||||
|
|
||||||
|
|
||||||
def load_comparable_csr(*names):
|
def load_comparable_csr(*names):
|
||||||
@@ -71,8 +71,8 @@ def load_rsa_private_key(*names):
|
|||||||
def load_pyopenssl_private_key(*names):
|
def load_pyopenssl_private_key(*names):
|
||||||
"""Load pyOpenSSL private key."""
|
"""Load pyOpenSSL private key."""
|
||||||
loader = _guess_loader(
|
loader = _guess_loader(
|
||||||
names[-1], OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.FILETYPE_ASN1)
|
names[-1], crypto.FILETYPE_PEM, crypto.FILETYPE_ASN1)
|
||||||
return OpenSSL.crypto.load_privatekey(loader, load_vector(*names))
|
return crypto.load_privatekey(loader, load_vector(*names))
|
||||||
|
|
||||||
|
|
||||||
def skip_unless(condition, reason): # pragma: no cover
|
def skip_unless(condition, reason): # pragma: no cover
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
[mypy]
|
[mypy]
|
||||||
python_version = 2.7
|
python_version = 2.7
|
||||||
ignore_missing_imports = True
|
ignore_missing_imports = True
|
||||||
|
|
||||||
|
[mypy-acme.*]
|
||||||
|
check_untyped_defs = True
|
||||||
|
|||||||
Reference in New Issue
Block a user