mirror of
https://github.com/certbot/certbot.git
synced 2026-06-03 13:59:02 -04:00
Merge remote-tracking branch 'github/letsencrypt/master' into acme-resource-json
Conflicts: acme/messages_test.py
This commit is contained in:
commit
bff89936af
7 changed files with 37 additions and 55 deletions
|
|
@ -540,21 +540,17 @@ class Client(object): # pylint: disable=too-many-instance-attributes
|
|||
else:
|
||||
return None
|
||||
|
||||
def revoke(self, certr, when=messages.Revocation.NOW):
|
||||
def revoke(self, cert):
|
||||
"""Revoke certificate.
|
||||
|
||||
:param certr: Certificate Resource
|
||||
:type certr: `.CertificateResource`
|
||||
|
||||
:param when: When should the revocation take place? Takes
|
||||
the same values as `.messages.Revocation.revoke`.
|
||||
:param .ComparableX509 cert: `M2Crypto.X509.X509` wrapped in
|
||||
`.ComparableX509`
|
||||
|
||||
:raises .ClientError: If revocation is unsuccessful.
|
||||
|
||||
"""
|
||||
rev = messages.Revocation(revoke=when, authorizations=tuple(
|
||||
authzr.uri for authzr in certr.authzrs))
|
||||
response = self._post(certr.uri, rev)
|
||||
response = self._post(messages.Revocation.url(self.new_reg_uri),
|
||||
messages.Revocation(certificate=cert))
|
||||
if response.status_code != httplib.OK:
|
||||
raise errors.ClientError(
|
||||
'Successful revocation must return HTTP OK status')
|
||||
|
|
|
|||
|
|
@ -509,8 +509,9 @@ class ClientTest(unittest.TestCase):
|
|||
|
||||
def test_revoke(self):
|
||||
self._mock_post_get()
|
||||
self.net.revoke(self.certr, when=messages.Revocation.NOW)
|
||||
self.post.assert_called_once_with(self.certr.uri, mock.ANY)
|
||||
self.net.revoke(self.certr.body)
|
||||
self.post.assert_called_once_with(messages.Revocation.url(
|
||||
self.net.new_reg_uri), mock.ANY)
|
||||
|
||||
def test_revoke_bad_status_raises_error(self):
|
||||
self.response.status_code = httplib.METHOD_NOT_ALLOWED
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
"""ACME protocol messages."""
|
||||
import urlparse
|
||||
|
||||
from acme import challenges
|
||||
from acme import fields
|
||||
from acme import jose
|
||||
|
|
@ -327,28 +329,22 @@ class CertificateResource(ResourceWithURI):
|
|||
class Revocation(jose.JSONObjectWithFields):
|
||||
"""Revocation message.
|
||||
|
||||
:ivar revoke: Either a `datetime.datetime` or `Revocation.NOW`.
|
||||
:ivar tuple authorizations: Same as `CertificateRequest.authorizations`
|
||||
:ivar .ComparableX509 certificate: `M2Crypto.X509.X509` wrapped in
|
||||
`.ComparableX509`
|
||||
|
||||
"""
|
||||
certificate = jose.Field(
|
||||
'certificate', decoder=jose.decode_cert, encoder=jose.encode_cert)
|
||||
|
||||
NOW = 'now'
|
||||
"""A possible value for `revoke`, denoting that certificate should
|
||||
be revoked now."""
|
||||
# TODO: acme-spec#138, this allows only one ACME server instance per domain
|
||||
PATH = '/acme/revoke-cert'
|
||||
"""Path to revocation URL, see `url`"""
|
||||
|
||||
revoke = jose.Field('revoke')
|
||||
authorizations = CertificateRequest._fields['authorizations']
|
||||
@classmethod
|
||||
def url(cls, base):
|
||||
"""Get revocation URL.
|
||||
|
||||
@revoke.decoder
|
||||
def revoke(value): # pylint: disable=missing-docstring,no-self-argument
|
||||
if value == Revocation.NOW:
|
||||
return value
|
||||
else:
|
||||
return fields.RFC3339Field.default_decoder(value)
|
||||
:param str base: New Registration Resource or server (root) URL.
|
||||
|
||||
@revoke.encoder
|
||||
def revoke(value): # pylint: disable=missing-docstring,no-self-argument
|
||||
if value == Revocation.NOW:
|
||||
return value
|
||||
else:
|
||||
return fields.RFC3339Field.default_encoder(value)
|
||||
"""
|
||||
return urlparse.urljoin(base, cls.PATH)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
"""Tests for acme.messages."""
|
||||
import datetime
|
||||
import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
|
@ -7,7 +6,6 @@ import unittest
|
|||
from Crypto.PublicKey import RSA
|
||||
import M2Crypto
|
||||
import mock
|
||||
import pytz
|
||||
|
||||
from acme import challenges
|
||||
from acme import jose
|
||||
|
|
@ -23,6 +21,9 @@ CSR = jose.ComparableX509(M2Crypto.X509.load_request_string(
|
|||
M2Crypto.X509.FORMAT_DER))
|
||||
KEY = jose.util.HashableRSAKey(RSA.importKey(pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
CERT = jose.ComparableX509(M2Crypto.X509.load_cert(
|
||||
format=M2Crypto.X509.FORMAT_DER, file=pkg_resources.resource_filename(
|
||||
'acme.jose', os.path.join('testdata', 'cert.der'))))
|
||||
|
||||
|
||||
class ErrorTest(unittest.TestCase):
|
||||
|
|
@ -318,27 +319,20 @@ class CertificateResourceTest(unittest.TestCase):
|
|||
class RevocationTest(unittest.TestCase):
|
||||
"""Tests for acme.messages.RevocationTest."""
|
||||
|
||||
def test_url(self):
|
||||
from acme.messages import Revocation
|
||||
url = 'https://letsencrypt-demo.org/acme/revoke-cert'
|
||||
self.assertEqual(url, Revocation.url('https://letsencrypt-demo.org'))
|
||||
self.assertEqual(
|
||||
url, Revocation.url('https://letsencrypt-demo.org/acme/new-reg'))
|
||||
|
||||
def setUp(self):
|
||||
from acme.messages import Revocation
|
||||
self.rev_now = Revocation(authorizations=(), revoke=Revocation.NOW)
|
||||
self.rev_date = Revocation(authorizations=(), revoke=datetime.datetime(
|
||||
2015, 3, 27, tzinfo=pytz.utc))
|
||||
self.jobj_now = {'authorizations': (), 'revoke': Revocation.NOW}
|
||||
self.jobj_date = {'authorizations': (),
|
||||
'revoke': '2015-03-27T00:00:00Z'}
|
||||
|
||||
def test_revoke_decoder(self):
|
||||
from acme.messages import Revocation
|
||||
self.assertEqual(self.rev_now, Revocation.from_json(self.jobj_now))
|
||||
self.assertEqual(self.rev_date, Revocation.from_json(self.jobj_date))
|
||||
|
||||
def test_revoke_encoder(self):
|
||||
self.assertEqual(self.jobj_now, self.rev_now.to_partial_json())
|
||||
self.assertEqual(self.jobj_date, self.rev_date.to_partial_json())
|
||||
self.rev = Revocation(certificate=CERT)
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from acme.messages import Revocation
|
||||
hash(Revocation.from_json(self.rev_now.to_json()))
|
||||
hash(Revocation.from_json(self.rev.to_json()))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -81,7 +81,3 @@ ACCOUNT_KEYS_DIR = "keys"
|
|||
REC_TOKEN_DIR = "recovery_tokens"
|
||||
"""Directory where all recovery tokens are saved (relative to
|
||||
IConfig.work_dir)."""
|
||||
|
||||
NETSTAT = "/bin/netstat"
|
||||
"""Location of netstat binary for checking whether a listener is already
|
||||
running on the specified port (Linux-specific)."""
|
||||
|
|
|
|||
|
|
@ -148,8 +148,7 @@ class IConfig(zope.interface.Interface):
|
|||
|
||||
"""
|
||||
server = zope.interface.Attribute(
|
||||
"CA hostname (and optionally :port). The server certificate must "
|
||||
"be trusted in order to avoid further modifications to the client.")
|
||||
"ACME new registration URI (including /acme/new-reg).")
|
||||
email = zope.interface.Attribute(
|
||||
"Email used for registration and recovery contact.")
|
||||
rsa_key_size = zope.interface.Attribute("Size of the RSA key.")
|
||||
|
|
|
|||
|
|
@ -253,7 +253,7 @@ class Revoker(object):
|
|||
raise errors.LetsEncryptRevokerError(
|
||||
"Corrupted backup key file: %s" % cert.backup_key_path)
|
||||
|
||||
return self.network.revoke(certr=None) # XXX
|
||||
return self.network.revoke(cert=None) # XXX
|
||||
|
||||
def _remove_certs_keys(self, cert_list): # pylint: disable=no-self-use
|
||||
"""Remove certificate and key.
|
||||
|
|
|
|||
Loading…
Reference in a new issue