diff --git a/acme/acme/challenges_test.py b/acme/acme/challenges_test.py index f7d25a4b4..4e3bfa8e0 100644 --- a/acme/acme/challenges_test.py +++ b/acme/acme/challenges_test.py @@ -136,7 +136,7 @@ class SimpleHTTPResponseTest(unittest.TestCase): jose.JWS.sign(payload=bad_resource.json_dumps().encode('utf-8'), alg=jose.RS256, key=account_key) for bad_resource in (resource.update(tls=True), - resource.update(token=b'x'*20)) + resource.update(token=(b'x' * 20))) ) for validation in validations: self.assertFalse(self.resp_http.check_validation( @@ -320,7 +320,7 @@ class DVSNIResponseTest(unittest.TestCase): def test_simple_verify_wrong_token(self): msg = self.msg.update(validation=jose.JWS.sign( - payload=self.chall.update(token=b'b'*20).json_dumps().encode(), + payload=self.chall.update(token=(b'b' * 20)).json_dumps().encode(), key=self.key, alg=jose.RS256)) self.assertFalse(msg.simple_verify( self.chall, self.domain, self.key.public_key())) diff --git a/acme/acme/client_test.py b/acme/acme/client_test.py index dcc0832e3..12589217f 100644 --- a/acme/acme/client_test.py +++ b/acme/acme/client_test.py @@ -379,11 +379,14 @@ class ClientNetworkTest(unittest.TestCase): # pylint: disable=missing-docstring def __init__(self, value): self.value = value + def to_partial_json(self): return {'foo': self.value} + @classmethod def from_json(cls, value): pass # pragma: no cover + # pylint: disable=protected-access jws_dump = self.net._wrap_in_jws( MockJSONDeSerializable('foo'), nonce=b'Tg') @@ -487,6 +490,7 @@ class ClientNetworkWithMockedResponseTest(unittest.TestCase): self.all_nonces = [jose.b64encode(b'Nonce'), jose.b64encode(b'Nonce2')] self.available_nonces = self.all_nonces[:] + def send_request(*args, **kwargs): # pylint: disable=unused-argument,missing-docstring if self.available_nonces: diff --git a/acme/acme/jose/json_util.py b/acme/acme/jose/json_util.py index 51d55ebd9..7b95e3fce 100644 --- a/acme/acme/jose/json_util.py +++ b/acme/acme/jose/json_util.py @@ -307,6 +307,7 @@ def encode_b64jose(data): # b64encode produces ASCII characters only return b64.b64encode(data).decode('ascii') + def decode_b64jose(data, size=None, minimum=False): """Decode JOSE Base-64 field. @@ -324,13 +325,14 @@ def decode_b64jose(data, size=None, minimum=False): except error_cls as error: raise errors.DeserializationError(error) - if size is not None and ((not minimum and len(decoded) != size) - or (minimum and len(decoded) < size)): + if size is not None and ((not minimum and len(decoded) != size) or + (minimum and len(decoded) < size)): raise errors.DeserializationError( "Expected at least or exactly {0} bytes".format(size)) return decoded + def encode_hex16(value): """Hexlify. @@ -340,6 +342,7 @@ def encode_hex16(value): """ return binascii.hexlify(value).decode() + def decode_hex16(value, size=None, minimum=False): """Decode hexlified field. @@ -352,8 +355,8 @@ def decode_hex16(value, size=None, minimum=False): """ value = value.encode() - if size is not None and ((not minimum and len(value) != size * 2) - or (minimum and len(value) < size * 2)): + if size is not None and ((not minimum and len(value) != size * 2) or + (minimum and len(value) < size * 2)): raise errors.DeserializationError() error_cls = TypeError if six.PY2 else binascii.Error try: @@ -361,6 +364,7 @@ def decode_hex16(value, size=None, minimum=False): except error_cls as error: raise errors.DeserializationError(error) + def encode_cert(cert): """Encode certificate as JOSE Base-64 DER. @@ -371,6 +375,7 @@ def encode_cert(cert): return encode_b64jose(OpenSSL.crypto.dump_certificate( OpenSSL.crypto.FILETYPE_ASN1, cert)) + def decode_cert(b64der): """Decode JOSE Base-64 DER-encoded certificate. @@ -384,6 +389,7 @@ def decode_cert(b64der): except OpenSSL.crypto.Error as error: raise errors.DeserializationError(error) + def encode_csr(csr): """Encode CSR as JOSE Base-64 DER. @@ -394,6 +400,7 @@ def encode_csr(csr): return encode_b64jose(OpenSSL.crypto.dump_certificate_request( OpenSSL.crypto.FILETYPE_ASN1, csr)) + def decode_csr(b64der): """Decode JOSE Base-64 DER-encoded CSR. diff --git a/acme/acme/jose/json_util_test.py b/acme/acme/jose/json_util_test.py index 313282e67..a055f3bf7 100644 --- a/acme/acme/jose/json_util_test.py +++ b/acme/acme/jose/json_util_test.py @@ -52,6 +52,7 @@ class FieldTest(unittest.TestCase): # pylint: disable=missing-docstring def to_partial_json(self): return 'foo' # pragma: no cover + @classmethod def from_json(cls, jobj): pass # pragma: no cover @@ -93,14 +94,18 @@ class JSONObjectWithFieldsMetaTest(unittest.TestCase): self.field2 = Field('Baz2') # pylint: disable=invalid-name,missing-docstring,too-few-public-methods # pylint: disable=blacklisted-name + @six.add_metaclass(JSONObjectWithFieldsMeta) class A(object): __slots__ = ('bar',) baz = self.field + class B(A): pass + class C(A): baz = self.field2 + self.a_cls = A self.b_cls = B self.c_cls = C diff --git a/acme/acme/jose/jwa.py b/acme/acme/jose/jwa.py index 0c84905df..4ce5ca3f5 100644 --- a/acme/acme/jose/jwa.py +++ b/acme/acme/jose/jwa.py @@ -21,7 +21,7 @@ from acme.jose import jwk logger = logging.getLogger(__name__) -class JWA(interfaces.JSONDeSerializable): # pylint: disable=abstract-method +class JWA(interfaces.JSONDeSerializable): # pylint: disable=abstract-method # pylint: disable=too-few-public-methods # for some reason disable=abstract-method has to be on the line # above... @@ -159,7 +159,7 @@ class _JWAES(JWASignature): # pylint: disable=abstract-class-not-used def sign(self, key, msg): # pragma: no cover raise NotImplementedError() - def verify(self, key, msg, sig): # pragma: no cover + def verify(self, key, msg, sig): # pragma: no cover raise NotImplementedError() diff --git a/acme/acme/jose/jwk.py b/acme/acme/jose/jwk.py index d9b903eb0..7a976f189 100644 --- a/acme/acme/jose/jwk.py +++ b/acme/acme/jose/jwk.py @@ -231,7 +231,7 @@ class JWKRSA(JWK): 'n': numbers.n, 'e': numbers.e, } - else: # rsa.RSAPrivateKey + else: # rsa.RSAPrivateKey private = self.key.private_numbers() public = self.key.public_key().public_numbers() params = { diff --git a/acme/acme/jose/jws.py b/acme/acme/jose/jws.py index 392a2f074..9a9a7621f 100644 --- a/acme/acme/jose/jws.py +++ b/acme/acme/jose/jws.py @@ -294,10 +294,10 @@ class JWS(json_util.JSONObjectWithFields): # ... it must be in protected return ( - b64.b64encode(self.signature.protected.encode('utf-8')) - + b'.' + - b64.b64encode(self.payload) - + b'.' + + b64.b64encode(self.signature.protected.encode('utf-8')) + + b'.' + + b64.b64encode(self.payload) + + b'.' + b64.b64encode(self.signature.signature)) @classmethod @@ -345,6 +345,7 @@ class JWS(json_util.JSONObjectWithFields): signatures=tuple(cls.signature_cls.from_json(sig) for sig in jobj['signatures'])) + class CLI(object): """JWS CLI.""" diff --git a/acme/acme/messages.py b/acme/acme/messages.py index 970cf4e6e..7b9702278 100644 --- a/acme/acme/messages.py +++ b/acme/acme/messages.py @@ -216,16 +216,19 @@ class Registration(ResourceBody): """All emails found in the ``contact`` field.""" return self._filter_contact(self.email_prefix) + class NewRegistration(Registration): """New registration.""" resource_type = 'new-reg' resource = fields.Resource(resource_type) + class UpdateRegistration(Registration): """Update registration.""" resource_type = 'reg' resource = fields.Resource(resource_type) + class RegistrationResource(ResourceWithURI): """Registration Resource. @@ -328,11 +331,13 @@ class Authorization(ResourceBody): return tuple(tuple(self.challenges[idx] for idx in combo) for combo in self.combinations) + class NewAuthorization(Authorization): """New authorization.""" resource_type = 'new-authz' resource = fields.Resource(resource_type) + class AuthorizationResource(ResourceWithURI): """Authorization Resource. diff --git a/acme/acme/messages_test.py b/acme/acme/messages_test.py index 481c2e2a3..fc3e3c97e 100644 --- a/acme/acme/messages_test.py +++ b/acme/acme/messages_test.py @@ -60,6 +60,7 @@ class ConstantTest(unittest.TestCase): def setUp(self): from acme.messages import _Constant + class MockConstant(_Constant): # pylint: disable=missing-docstring POSSIBLE_NAMES = {} @@ -211,7 +212,6 @@ class ChallengeBodyTest(unittest.TestCase): 'detail': 'Unable to communicate with DNS server', } - def test_to_partial_json(self): self.assertEqual(self.jobj_to, self.challb.to_partial_json()) diff --git a/acme/acme/test_util.py b/acme/acme/test_util.py index 8ad118e17..d6fe7d11d 100644 --- a/acme/acme/test_util.py +++ b/acme/acme/test_util.py @@ -20,12 +20,14 @@ def vector_path(*names): return pkg_resources.resource_filename( __name__, os.path.join('testdata', *names)) + def load_vector(*names): """Load contents of a test vector.""" # luckily, resource_string opens file in binary mode return pkg_resources.resource_string( __name__, os.path.join('testdata', *names)) + def _guess_loader(filename, loader_pem, loader_der): _, ext = os.path.splitext(filename) if ext.lower() == '.pem': @@ -35,6 +37,7 @@ def _guess_loader(filename, loader_pem, loader_der): else: # pragma: no cover raise ValueError("Loader could not be recognized based on extension") + def load_cert(*names): """Load certificate.""" loader = _guess_loader( @@ -42,6 +45,7 @@ def load_cert(*names): return jose.ComparableX509(OpenSSL.crypto.load_certificate( loader, load_vector(*names))) + def load_csr(*names): """Load certificate request.""" loader = _guess_loader( @@ -49,6 +53,7 @@ def load_csr(*names): return jose.ComparableX509(OpenSSL.crypto.load_certificate_request( loader, load_vector(*names))) + def load_rsa_private_key(*names): """Load RSA private key.""" loader = _guess_loader(names[-1], serialization.load_pem_private_key, @@ -56,6 +61,7 @@ def load_rsa_private_key(*names): return jose.ComparableRSAKey(loader( load_vector(*names), password=None, backend=default_backend())) + def load_pyopenssl_private_key(*names): """Load pyOpenSSL private key.""" loader = _guess_loader(