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 test-dirs-chmods
Conflicts: letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/foo.conf letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/nginx.conf letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/nginx.new.conf letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/server.conf letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/sites-enabled/default letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/sites-enabled/example.com letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/fastcgi_params letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-utf letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-win letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/mime.types letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi-ui.conf.1.4.1 letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi.rules letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi_core.rules letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/nginx.conf letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/proxy_params letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/scgi_params letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-available/default letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-enabled/default letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/uwsgi_params letsencrypt/client/plugins/nginx/tests/testdata/etc_nginx/ubuntu_nginx_1_4_6/default_vhost/nginx/win-utf letsencrypt/client/plugins/nginx/tests/testdata/foo.conf letsencrypt/client/plugins/nginx/tests/testdata/nginx.conf letsencrypt/client/plugins/nginx/tests/testdata/nginx.new.conf letsencrypt/client/plugins/nginx/tests/testdata/server.conf letsencrypt/client/plugins/nginx/tests/testdata/sites-enabled/default letsencrypt/client/plugins/nginx/tests/testdata/sites-enabled/example.com letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/fastcgi_params letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-utf letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-win letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/mime.types letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi-ui.conf.1.4.1 letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi.rules letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi_core.rules letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/nginx.conf letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/proxy_params letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/scgi_params letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-available/default letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-enabled/default letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/uwsgi_params letsencrypt/client/plugins/nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/win-utf letsencrypt_apache/tests/util.py letsencrypt_nginx/tests/testdata/foo.conf letsencrypt_nginx/tests/testdata/nginx.conf letsencrypt_nginx/tests/testdata/nginx.new.conf letsencrypt_nginx/tests/testdata/server.conf letsencrypt_nginx/tests/testdata/sites-enabled/default letsencrypt_nginx/tests/testdata/sites-enabled/example.com letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/fastcgi_params letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-utf letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/koi-win letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/mime.types letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi-ui.conf.1.4.1 letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi.rules letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/naxsi_core.rules letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/nginx.conf letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/proxy_params letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/scgi_params letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-available/default letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/sites-enabled/default letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/uwsgi_params letsencrypt_nginx/tests/testdata/ubuntu_nginx_1_4_6/default_vhost/nginx/win-utf letsencrypt_nginx/tests/util.py
This commit is contained in:
commit
bb94952830
282 changed files with 3834 additions and 2526 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -10,4 +10,4 @@ m3
|
|||
*~
|
||||
.vagrant
|
||||
*.swp
|
||||
\#*#
|
||||
\#*#
|
||||
12
MANIFEST.in
12
MANIFEST.in
|
|
@ -3,6 +3,14 @@ include CHANGES.rst
|
|||
include CONTRIBUTING.md
|
||||
include linter_plugin.py
|
||||
include letsencrypt/EULA
|
||||
recursive-include letsencrypt *.json
|
||||
recursive-include letsencrypt *.conf
|
||||
|
||||
recursive-include letsencrypt/client/tests/testdata *
|
||||
|
||||
recursive-include acme/schemata *.json
|
||||
recursive-include acme/jose/testdata *
|
||||
|
||||
recursive-include letsencrypt_apache/tests/testdata *
|
||||
include letsencrypt_apache/options-ssl.conf
|
||||
|
||||
recursive-include letsencrypt_nginx/tests/testdata *
|
||||
include letsencrypt_nginx/options-ssl.conf
|
||||
|
|
|
|||
15
README.rst
15
README.rst
|
|
@ -17,11 +17,15 @@ It's all automated:
|
|||
* If domain control has been proven, a certificate will get issued and the tool
|
||||
will automatically install it.
|
||||
|
||||
All you need to do is:
|
||||
All you need to do is::
|
||||
|
||||
::
|
||||
user@www:~$ sudo letsencrypt -d www.example.org auth
|
||||
|
||||
user@www:~$ sudo letsencrypt -d www.example.org
|
||||
and if you have a compatbile web server (Apache or Nginx), Let's Encrypt can
|
||||
not only get a new certificate, but also deploy it and configure your
|
||||
server automatically!::
|
||||
|
||||
user@www:~$ sudo letsencrypt -d www.example.org run
|
||||
|
||||
|
||||
**Encrypt ALL the things!**
|
||||
|
|
@ -56,7 +60,8 @@ Current Features
|
|||
|
||||
* web servers supported:
|
||||
|
||||
- apache2.x (tested and working on Ubuntu Linux)
|
||||
- apache/2.x (tested and working on Ubuntu Linux)
|
||||
- nginx/0.8.48+ (tested and mostly working on Ubuntu Linux)
|
||||
- standalone (runs its own webserver to prove you control the domain)
|
||||
|
||||
* the private key is generated locally on your system
|
||||
|
|
@ -66,7 +71,7 @@ Current Features
|
|||
* can revoke certificates
|
||||
* adjustable RSA key bitlength (2048 (default), 4096, ...)
|
||||
* optionally can install a http->https redirect, so your site effectively
|
||||
runs https only
|
||||
runs https only (Apache only)
|
||||
* fully automated
|
||||
* configuration changes are logged and can be reverted using the CLI
|
||||
* text and ncurses UI
|
||||
|
|
|
|||
2
Vagrantfile
vendored
2
Vagrantfile
vendored
|
|
@ -10,7 +10,7 @@ cd /vagrant
|
|||
sudo ./bootstrap/ubuntu.sh
|
||||
if [ ! -d "venv" ]; then
|
||||
virtualenv --no-site-packages -p python2 venv
|
||||
./venv/bin/python setup.py dev
|
||||
./venv/bin/pip install -r requirements.txt -e .[dev,docs,testing]
|
||||
fi
|
||||
SETUP_SCRIPT
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import hashlib
|
|||
|
||||
import Crypto.Random
|
||||
|
||||
from letsencrypt.acme import jose
|
||||
from letsencrypt.acme import other
|
||||
from acme import jose
|
||||
from acme import other
|
||||
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
|
@ -186,8 +186,8 @@ class ProofOfPossession(ContinuityChallenge):
|
|||
class Hints(jose.JSONObjectWithFields):
|
||||
"""Hints for "proofOfPossession" challenge.
|
||||
|
||||
:ivar jwk: JSON Web Key (:class:`letsencrypt.acme.jose.JWK`)
|
||||
:ivar list certs: List of :class:`letsencrypt.acme.jose.ComparableX509`
|
||||
:ivar jwk: JSON Web Key (:class:`acme.jose.JWK`)
|
||||
:ivar list certs: List of :class:`acme.jose.ComparableX509`
|
||||
certificates.
|
||||
|
||||
"""
|
||||
|
|
@ -221,7 +221,7 @@ class ProofOfPossessionResponse(ChallengeResponse):
|
|||
"""ACME "proofOfPossession" challenge response.
|
||||
|
||||
:ivar str nonce: Random data, **not** base64-encoded.
|
||||
:ivar signature: :class:`~letsencrypt.acme.other.Signature` of this message.
|
||||
:ivar signature: :class:`~acme.other.Signature` of this message.
|
||||
|
||||
"""
|
||||
typ = "proofOfPossession"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.challenges."""
|
||||
"""Tests for acme.challenges."""
|
||||
import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
|
@ -6,23 +6,22 @@ import unittest
|
|||
import Crypto.PublicKey.RSA
|
||||
import M2Crypto
|
||||
|
||||
from letsencrypt.acme import jose
|
||||
from letsencrypt.acme import other
|
||||
from acme import jose
|
||||
from acme import other
|
||||
|
||||
|
||||
CERT = jose.ComparableX509(M2Crypto.X509.load_cert(
|
||||
pkg_resources.resource_filename(
|
||||
'letsencrypt.client.tests', os.path.join('testdata', 'cert.pem'))))
|
||||
'letsencrypt.tests', os.path.join('testdata', 'cert.pem'))))
|
||||
KEY = jose.HashableRSAKey(Crypto.PublicKey.RSA.importKey(
|
||||
pkg_resources.resource_string(
|
||||
'letsencrypt.acme.jose',
|
||||
os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
'acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
|
||||
|
||||
class SimpleHTTPSTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import SimpleHTTPS
|
||||
from acme.challenges import SimpleHTTPS
|
||||
self.msg = SimpleHTTPS(
|
||||
token='evaGxfADs6pSRb2LAv9IZf17Dt3juxGJ+PCt92wr+oA')
|
||||
self.jmsg = {
|
||||
|
|
@ -34,18 +33,18 @@ class SimpleHTTPSTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import SimpleHTTPS
|
||||
from acme.challenges import SimpleHTTPS
|
||||
self.assertEqual(self.msg, SimpleHTTPS.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import SimpleHTTPS
|
||||
from acme.challenges import SimpleHTTPS
|
||||
hash(SimpleHTTPS.from_json(self.jmsg))
|
||||
|
||||
|
||||
class SimpleHTTPSResponseTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import SimpleHTTPSResponse
|
||||
from acme.challenges import SimpleHTTPSResponse
|
||||
self.msg = SimpleHTTPSResponse(path='6tbIMBC5Anhl5bOlWT5ZFA')
|
||||
self.jmsg = {
|
||||
'type': 'simpleHttps',
|
||||
|
|
@ -60,19 +59,19 @@ class SimpleHTTPSResponseTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import SimpleHTTPSResponse
|
||||
from acme.challenges import SimpleHTTPSResponse
|
||||
self.assertEqual(
|
||||
self.msg, SimpleHTTPSResponse.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import SimpleHTTPSResponse
|
||||
from acme.challenges import SimpleHTTPSResponse
|
||||
hash(SimpleHTTPSResponse.from_json(self.jmsg))
|
||||
|
||||
|
||||
class DVSNITest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import DVSNI
|
||||
from acme.challenges import DVSNI
|
||||
self.msg = DVSNI(
|
||||
r="O*\xb4-\xad\xec\x95>\xed\xa9\r0\x94\xe8\x97\x9c&6"
|
||||
"\xbf'\xb3\xed\x9a9nX\x0f'\\m\xe7\x12",
|
||||
|
|
@ -91,21 +90,21 @@ class DVSNITest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import DVSNI
|
||||
from acme.challenges import DVSNI
|
||||
self.assertEqual(self.msg, DVSNI.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import DVSNI
|
||||
from acme.challenges import DVSNI
|
||||
hash(DVSNI.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_invalid_r_length(self):
|
||||
from letsencrypt.acme.challenges import DVSNI
|
||||
from acme.challenges import DVSNI
|
||||
self.jmsg['r'] = 'abcd'
|
||||
self.assertRaises(
|
||||
jose.DeserializationError, DVSNI.from_json, self.jmsg)
|
||||
|
||||
def test_from_json_invalid_nonce_length(self):
|
||||
from letsencrypt.acme.challenges import DVSNI
|
||||
from acme.challenges import DVSNI
|
||||
self.jmsg['nonce'] = 'abcd'
|
||||
self.assertRaises(
|
||||
jose.DeserializationError, DVSNI.from_json, self.jmsg)
|
||||
|
|
@ -114,7 +113,7 @@ class DVSNITest(unittest.TestCase):
|
|||
class DVSNIResponseTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import DVSNIResponse
|
||||
from acme.challenges import DVSNIResponse
|
||||
self.msg = DVSNIResponse(
|
||||
s='\xf5\xd6\xe3\xb2]\xe0L\x0bN\x9cKJ\x14I\xa1K\xa3#\xf9\xa8'
|
||||
'\xcd\x8c7\x0e\x99\x19)\xdc\xb7\xf3\x9bw')
|
||||
|
|
@ -124,7 +123,7 @@ class DVSNIResponseTest(unittest.TestCase):
|
|||
}
|
||||
|
||||
def test_z_and_domain(self):
|
||||
from letsencrypt.acme.challenges import DVSNI
|
||||
from acme.challenges import DVSNI
|
||||
challenge = DVSNI(
|
||||
r="O*\xb4-\xad\xec\x95>\xed\xa9\r0\x94\xe8\x97\x9c&6"
|
||||
"\xbf'\xb3\xed\x9a9nX\x0f'\\m\xe7\x12",
|
||||
|
|
@ -140,18 +139,18 @@ class DVSNIResponseTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import DVSNIResponse
|
||||
from acme.challenges import DVSNIResponse
|
||||
self.assertEqual(self.msg, DVSNIResponse.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import DVSNIResponse
|
||||
from acme.challenges import DVSNIResponse
|
||||
hash(DVSNIResponse.from_json(self.jmsg))
|
||||
|
||||
|
||||
class RecoveryContactTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import RecoveryContact
|
||||
from acme.challenges import RecoveryContact
|
||||
self.msg = RecoveryContact(
|
||||
activation_url='https://example.ca/sendrecovery/a5bd99383fb0',
|
||||
success_url='https://example.ca/confirmrecovery/bb1b9928932',
|
||||
|
|
@ -167,11 +166,11 @@ class RecoveryContactTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import RecoveryContact
|
||||
from acme.challenges import RecoveryContact
|
||||
self.assertEqual(self.msg, RecoveryContact.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import RecoveryContact
|
||||
from acme.challenges import RecoveryContact
|
||||
hash(RecoveryContact.from_json(self.jmsg))
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
|
|
@ -179,7 +178,7 @@ class RecoveryContactTest(unittest.TestCase):
|
|||
del self.jmsg['successURL']
|
||||
del self.jmsg['contact']
|
||||
|
||||
from letsencrypt.acme.challenges import RecoveryContact
|
||||
from acme.challenges import RecoveryContact
|
||||
msg = RecoveryContact.from_json(self.jmsg)
|
||||
|
||||
self.assertTrue(msg.activation_url is None)
|
||||
|
|
@ -191,7 +190,7 @@ class RecoveryContactTest(unittest.TestCase):
|
|||
class RecoveryContactResponseTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import RecoveryContactResponse
|
||||
from acme.challenges import RecoveryContactResponse
|
||||
self.msg = RecoveryContactResponse(token='23029d88d9e123e')
|
||||
self.jmsg = {'type': 'recoveryContact', 'token': '23029d88d9e123e'}
|
||||
|
||||
|
|
@ -199,18 +198,18 @@ class RecoveryContactResponseTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import RecoveryContactResponse
|
||||
from acme.challenges import RecoveryContactResponse
|
||||
self.assertEqual(
|
||||
self.msg, RecoveryContactResponse.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import RecoveryContactResponse
|
||||
from acme.challenges import RecoveryContactResponse
|
||||
hash(RecoveryContactResponse.from_json(self.jmsg))
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
del self.jmsg['token']
|
||||
|
||||
from letsencrypt.acme.challenges import RecoveryContactResponse
|
||||
from acme.challenges import RecoveryContactResponse
|
||||
msg = RecoveryContactResponse.from_json(self.jmsg)
|
||||
|
||||
self.assertTrue(msg.token is None)
|
||||
|
|
@ -220,7 +219,7 @@ class RecoveryContactResponseTest(unittest.TestCase):
|
|||
class RecoveryTokenTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import RecoveryToken
|
||||
from acme.challenges import RecoveryToken
|
||||
self.msg = RecoveryToken()
|
||||
self.jmsg = {'type': 'recoveryToken'}
|
||||
|
||||
|
|
@ -228,18 +227,18 @@ class RecoveryTokenTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import RecoveryToken
|
||||
from acme.challenges import RecoveryToken
|
||||
self.assertEqual(self.msg, RecoveryToken.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import RecoveryToken
|
||||
from acme.challenges import RecoveryToken
|
||||
hash(RecoveryToken.from_json(self.jmsg))
|
||||
|
||||
|
||||
class RecoveryTokenResponseTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import RecoveryTokenResponse
|
||||
from acme.challenges import RecoveryTokenResponse
|
||||
self.msg = RecoveryTokenResponse(token='23029d88d9e123e')
|
||||
self.jmsg = {'type': 'recoveryToken', 'token': '23029d88d9e123e'}
|
||||
|
||||
|
|
@ -247,18 +246,18 @@ class RecoveryTokenResponseTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import RecoveryTokenResponse
|
||||
from acme.challenges import RecoveryTokenResponse
|
||||
self.assertEqual(
|
||||
self.msg, RecoveryTokenResponse.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import RecoveryTokenResponse
|
||||
from acme.challenges import RecoveryTokenResponse
|
||||
hash(RecoveryTokenResponse.from_json(self.jmsg))
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
del self.jmsg['token']
|
||||
|
||||
from letsencrypt.acme.challenges import RecoveryTokenResponse
|
||||
from acme.challenges import RecoveryTokenResponse
|
||||
msg = RecoveryTokenResponse.from_json(self.jmsg)
|
||||
|
||||
self.assertTrue(msg.token is None)
|
||||
|
|
@ -282,7 +281,7 @@ class ProofOfPossessionHintsTest(unittest.TestCase):
|
|||
authorized_for = ('www.example.com', 'example.net')
|
||||
serial_numbers = (34234239832, 23993939911, 17)
|
||||
|
||||
from letsencrypt.acme.challenges import ProofOfPossession
|
||||
from acme.challenges import ProofOfPossession
|
||||
self.msg = ProofOfPossession.Hints(
|
||||
jwk=jwk, issuers=issuers, cert_fingerprints=cert_fingerprints,
|
||||
certs=(CERT,), subject_key_identifiers=subject_key_identifiers,
|
||||
|
|
@ -304,12 +303,12 @@ class ProofOfPossessionHintsTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg_to, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import ProofOfPossession
|
||||
from acme.challenges import ProofOfPossession
|
||||
self.assertEqual(
|
||||
self.msg, ProofOfPossession.Hints.from_json(self.jmsg_from))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import ProofOfPossession
|
||||
from acme.challenges import ProofOfPossession
|
||||
hash(ProofOfPossession.Hints.from_json(self.jmsg_from))
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
|
|
@ -318,7 +317,7 @@ class ProofOfPossessionHintsTest(unittest.TestCase):
|
|||
del self.jmsg_from[optional]
|
||||
del self.jmsg_to[optional]
|
||||
|
||||
from letsencrypt.acme.challenges import ProofOfPossession
|
||||
from acme.challenges import ProofOfPossession
|
||||
msg = ProofOfPossession.Hints.from_json(self.jmsg_from)
|
||||
|
||||
self.assertEqual(msg.cert_fingerprints, ())
|
||||
|
|
@ -334,7 +333,7 @@ class ProofOfPossessionHintsTest(unittest.TestCase):
|
|||
class ProofOfPossessionTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import ProofOfPossession
|
||||
from acme.challenges import ProofOfPossession
|
||||
hints = ProofOfPossession.Hints(
|
||||
jwk=jose.JWKRSA(key=KEY.publickey()), cert_fingerprints=(),
|
||||
certs=(), serial_numbers=(), subject_key_identifiers=(),
|
||||
|
|
@ -360,12 +359,12 @@ class ProofOfPossessionTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg_to, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import ProofOfPossession
|
||||
from acme.challenges import ProofOfPossession
|
||||
self.assertEqual(
|
||||
self.msg, ProofOfPossession.from_json(self.jmsg_from))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import ProofOfPossession
|
||||
from acme.challenges import ProofOfPossession
|
||||
hash(ProofOfPossession.from_json(self.jmsg_from))
|
||||
|
||||
|
||||
|
|
@ -384,7 +383,7 @@ class ProofOfPossessionResponseTest(unittest.TestCase):
|
|||
nonce='\x99\xc7Q\xb3f2\xbc\xdci\xfe\xd6\x98k\xc67\xdf',
|
||||
)
|
||||
|
||||
from letsencrypt.acme.challenges import ProofOfPossessionResponse
|
||||
from acme.challenges import ProofOfPossessionResponse
|
||||
self.msg = ProofOfPossessionResponse(
|
||||
nonce='xD\xf9\xb9\xdbU\xed\xaa\x17\xf1y|\x81\x88\x99 ',
|
||||
signature=signature)
|
||||
|
|
@ -407,19 +406,19 @@ class ProofOfPossessionResponseTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg_to, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import ProofOfPossessionResponse
|
||||
from acme.challenges import ProofOfPossessionResponse
|
||||
self.assertEqual(
|
||||
self.msg, ProofOfPossessionResponse.from_json(self.jmsg_from))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import ProofOfPossessionResponse
|
||||
from acme.challenges import ProofOfPossessionResponse
|
||||
hash(ProofOfPossessionResponse.from_json(self.jmsg_from))
|
||||
|
||||
|
||||
class DNSTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import DNS
|
||||
from acme.challenges import DNS
|
||||
self.msg = DNS(token='17817c66b60ce2e4012dfad92657527a')
|
||||
self.jmsg = {'type': 'dns', 'token': '17817c66b60ce2e4012dfad92657527a'}
|
||||
|
||||
|
|
@ -427,18 +426,18 @@ class DNSTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import DNS
|
||||
from acme.challenges import DNS
|
||||
self.assertEqual(self.msg, DNS.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import DNS
|
||||
from acme.challenges import DNS
|
||||
hash(DNS.from_json(self.jmsg))
|
||||
|
||||
|
||||
class DNSResponseTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.challenges import DNSResponse
|
||||
from acme.challenges import DNSResponse
|
||||
self.msg = DNSResponse()
|
||||
self.jmsg = {'type': 'dns'}
|
||||
|
||||
|
|
@ -446,13 +445,13 @@ class DNSResponseTest(unittest.TestCase):
|
|||
self.assertEqual(self.jmsg, self.msg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.challenges import DNSResponse
|
||||
from acme.challenges import DNSResponse
|
||||
self.assertEqual(self.msg, DNSResponse.from_json(self.jmsg))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.challenges import DNSResponse
|
||||
from acme.challenges import DNSResponse
|
||||
hash(DNSResponse.from_json(self.jmsg))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
"""ACME errors."""
|
||||
from letsencrypt.acme.jose import errors as jose_errors
|
||||
from acme.jose import errors as jose_errors
|
||||
|
||||
class Error(Exception):
|
||||
"""Generic ACME error."""
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
"""ACME JSON fields."""
|
||||
import pyrfc3339
|
||||
|
||||
from letsencrypt.acme import jose
|
||||
from acme import jose
|
||||
|
||||
|
||||
class RFC3339Field(jose.Field):
|
||||
|
|
@ -1,35 +1,39 @@
|
|||
"""Tests for letsencrypt.acme.fields."""
|
||||
"""Tests for acme.fields."""
|
||||
import datetime
|
||||
import unittest
|
||||
|
||||
import pytz
|
||||
|
||||
from letsencrypt.acme import jose
|
||||
from acme import jose
|
||||
|
||||
|
||||
class RFC3339FieldTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.fields.RFC3339Field."""
|
||||
"""Tests for acme.fields.RFC3339Field."""
|
||||
|
||||
def setUp(self):
|
||||
self.decoded = datetime.datetime(2015, 3, 27, tzinfo=pytz.utc)
|
||||
self.encoded = '2015-03-27T00:00:00Z'
|
||||
|
||||
def test_default_encoder(self):
|
||||
from letsencrypt.acme.fields import RFC3339Field
|
||||
from acme.fields import RFC3339Field
|
||||
self.assertEqual(
|
||||
self.encoded, RFC3339Field.default_encoder(self.decoded))
|
||||
|
||||
def test_default_encoder_naive_fails(self):
|
||||
from letsencrypt.acme.fields import RFC3339Field
|
||||
from acme.fields import RFC3339Field
|
||||
self.assertRaises(
|
||||
ValueError, RFC3339Field.default_encoder, datetime.datetime.now())
|
||||
|
||||
def test_default_decoder(self):
|
||||
from letsencrypt.acme.fields import RFC3339Field
|
||||
from acme.fields import RFC3339Field
|
||||
self.assertEqual(
|
||||
self.decoded, RFC3339Field.default_decoder(self.encoded))
|
||||
|
||||
def test_default_decoder_raises_deserialization_error(self):
|
||||
from letsencrypt.acme.fields import RFC3339Field
|
||||
from acme.fields import RFC3339Field
|
||||
self.assertRaises(
|
||||
jose.DeserializationError, RFC3339Field.default_decoder, '')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -22,21 +22,21 @@ particular the following RFCs:
|
|||
https://datatracker.ietf.org/doc/draft-ietf-jose-json-web-signature/
|
||||
|
||||
"""
|
||||
from letsencrypt.acme.jose.b64 import (
|
||||
from acme.jose.b64 import (
|
||||
b64decode,
|
||||
b64encode,
|
||||
)
|
||||
|
||||
from letsencrypt.acme.jose.errors import (
|
||||
from acme.jose.errors import (
|
||||
DeserializationError,
|
||||
SerializationError,
|
||||
Error,
|
||||
UnrecognizedTypeError,
|
||||
)
|
||||
|
||||
from letsencrypt.acme.jose.interfaces import JSONDeSerializable
|
||||
from acme.jose.interfaces import JSONDeSerializable
|
||||
|
||||
from letsencrypt.acme.jose.json_util import (
|
||||
from acme.jose.json_util import (
|
||||
Field,
|
||||
JSONObjectWithFields,
|
||||
TypedJSONObjectWithFields,
|
||||
|
|
@ -48,7 +48,7 @@ from letsencrypt.acme.jose.json_util import (
|
|||
encode_csr,
|
||||
)
|
||||
|
||||
from letsencrypt.acme.jose.jwa import (
|
||||
from acme.jose.jwa import (
|
||||
HS256,
|
||||
HS384,
|
||||
HS512,
|
||||
|
|
@ -61,14 +61,14 @@ from letsencrypt.acme.jose.jwa import (
|
|||
RS512,
|
||||
)
|
||||
|
||||
from letsencrypt.acme.jose.jwk import (
|
||||
from acme.jose.jwk import (
|
||||
JWK,
|
||||
JWKRSA,
|
||||
)
|
||||
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
|
||||
from letsencrypt.acme.jose.util import (
|
||||
from acme.jose.util import (
|
||||
ComparableX509,
|
||||
HashableRSAKey,
|
||||
ImmutableMap,
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.jose.b64."""
|
||||
"""Tests for acme.jose.b64."""
|
||||
import unittest
|
||||
|
||||
|
||||
|
|
@ -19,11 +19,11 @@ B64_URL_UNSAFE_EXAMPLES = {
|
|||
|
||||
|
||||
class B64EncodeTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.b64.b64encode."""
|
||||
"""Tests for acme.jose.b64.b64encode."""
|
||||
|
||||
@classmethod
|
||||
def _call(cls, data):
|
||||
from letsencrypt.acme.jose.b64 import b64encode
|
||||
from acme.jose.b64 import b64encode
|
||||
return b64encode(data)
|
||||
|
||||
def test_unsafe_url(self):
|
||||
|
|
@ -39,11 +39,11 @@ class B64EncodeTest(unittest.TestCase):
|
|||
|
||||
|
||||
class B64DecodeTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.b64.b64decode."""
|
||||
"""Tests for acme.jose.b64.b64decode."""
|
||||
|
||||
@classmethod
|
||||
def _call(cls, data):
|
||||
from letsencrypt.acme.jose.b64 import b64decode
|
||||
from acme.jose.b64 import b64decode
|
||||
return b64decode(data)
|
||||
|
||||
def test_unsafe_url(self):
|
||||
|
|
@ -69,4 +69,4 @@ class B64DecodeTest(unittest.TestCase):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
"""Tests for letsencrypt.acme.jose.errors."""
|
||||
"""Tests for acme.jose.errors."""
|
||||
import unittest
|
||||
|
||||
|
||||
class UnrecognizedTypeErrorTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.errors import UnrecognizedTypeError
|
||||
from acme.jose.errors import UnrecognizedTypeError
|
||||
self.error = UnrecognizedTypeError('foo', {'type': 'foo'})
|
||||
|
||||
def test_str(self):
|
||||
|
|
@ -14,4 +14,4 @@ class UnrecognizedTypeErrorTest(unittest.TestCase):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -3,7 +3,7 @@ import abc
|
|||
import collections
|
||||
import json
|
||||
|
||||
from letsencrypt.acme.jose import util
|
||||
from acme.jose import util
|
||||
|
||||
# pylint: disable=no-self-argument,no-method-argument,no-init,inherit-non-class
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
|
@ -110,7 +110,7 @@ class JSONDeSerializable(object):
|
|||
# in particular...
|
||||
assert Bar().to_partial_json() != ['foo', 'foo']
|
||||
|
||||
:raises letsencrypt.acme.jose.errors.SerializationError:
|
||||
:raises acme.jose.errors.SerializationError:
|
||||
in case of any serialization error.
|
||||
:returns: Partially serializable object.
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ class JSONDeSerializable(object):
|
|||
|
||||
assert Bar().to_json() == ['foo', 'foo']
|
||||
|
||||
:raises letsencrypt.acme.jose.errors.SerializationError:
|
||||
:raises acme.jose.errors.SerializationError:
|
||||
in case of any serialization error.
|
||||
:returns: Fully serialized object.
|
||||
|
||||
|
|
@ -157,7 +157,7 @@ class JSONDeSerializable(object):
|
|||
types, as decoded from JSON document. Not necessarily
|
||||
:class:`dict` (as decoded from "JSON object" document).
|
||||
|
||||
:raises letsencrypt.acme.jose.errors.DeserializationError:
|
||||
:raises acme.jose.errors.DeserializationError:
|
||||
if decoding was unsuccessful, e.g. in case of unparseable
|
||||
X509 certificate, or wrong padding in JOSE base64 encoded
|
||||
string, etc.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.jose.interfaces."""
|
||||
"""Tests for acme.jose.interfaces."""
|
||||
import unittest
|
||||
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ class JSONDeSerializableTest(unittest.TestCase):
|
|||
# pylint: disable=too-many-instance-attributes
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.interfaces import JSONDeSerializable
|
||||
from acme.jose.interfaces import JSONDeSerializable
|
||||
|
||||
# pylint: disable=missing-docstring,invalid-name
|
||||
|
||||
|
|
@ -44,8 +44,7 @@ class JSONDeSerializableTest(unittest.TestCase):
|
|||
|
||||
@classmethod
|
||||
def from_json(cls, jobj):
|
||||
return cls(Basic.from_json(jobj.keys()[0]),
|
||||
Basic.from_json(jobj.values()[0]))
|
||||
pass # pragma: no cover
|
||||
|
||||
self.basic1 = Basic('foo1')
|
||||
self.basic2 = Basic('foo2')
|
||||
|
|
@ -76,7 +75,7 @@ class JSONDeSerializableTest(unittest.TestCase):
|
|||
self.assertEqual(self.tuple.to_json(), (('foo', )))
|
||||
|
||||
def test_from_json_not_implemented(self):
|
||||
from letsencrypt.acme.jose.interfaces import JSONDeSerializable
|
||||
from acme.jose.interfaces import JSONDeSerializable
|
||||
self.assertRaises(TypeError, JSONDeSerializable.from_json, 'xxx')
|
||||
|
||||
def test_json_loads(self):
|
||||
|
|
@ -95,7 +94,7 @@ class JSONDeSerializableTest(unittest.TestCase):
|
|||
self.seq.json_dumps_pretty(), '[\n "foo1",\n "foo2"\n]')
|
||||
|
||||
def test_json_dump_default(self):
|
||||
from letsencrypt.acme.jose.interfaces import JSONDeSerializable
|
||||
from acme.jose.interfaces import JSONDeSerializable
|
||||
|
||||
self.assertEqual(
|
||||
'foo1', JSONDeSerializable.json_dump_default(self.basic1))
|
||||
|
|
@ -106,10 +105,10 @@ class JSONDeSerializableTest(unittest.TestCase):
|
|||
self.assertTrue(jobj[1] is self.basic2)
|
||||
|
||||
def test_json_dump_default_type_error(self):
|
||||
from letsencrypt.acme.jose.interfaces import JSONDeSerializable
|
||||
from acme.jose.interfaces import JSONDeSerializable
|
||||
self.assertRaises(
|
||||
TypeError, JSONDeSerializable.json_dump_default, object())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -12,10 +12,10 @@ import logging
|
|||
|
||||
import M2Crypto
|
||||
|
||||
from letsencrypt.acme.jose import b64
|
||||
from letsencrypt.acme.jose import errors
|
||||
from letsencrypt.acme.jose import interfaces
|
||||
from letsencrypt.acme.jose import util
|
||||
from acme.jose import b64
|
||||
from acme.jose import errors
|
||||
from acme.jose import interfaces
|
||||
from acme.jose import util
|
||||
|
||||
|
||||
class Field(object):
|
||||
|
|
@ -27,8 +27,8 @@ class Field(object):
|
|||
``encoder`` (``decoder``) is a callable that accepts a single
|
||||
parameter, i.e. a value to be encoded (decoded), and returns the
|
||||
serialized (deserialized) value. In case of errors it should raise
|
||||
:class:`~letsencrypt.acme.jose.errors.SerializationError`
|
||||
(:class:`~letsencrypt.acme.jose.errors.DeserializationError`).
|
||||
:class:`~acme.jose.errors.SerializationError`
|
||||
(:class:`~acme.jose.errors.DeserializationError`).
|
||||
|
||||
Note, that ``decoder`` should perform partial serialization only.
|
||||
|
||||
|
|
@ -96,7 +96,7 @@ class Field(object):
|
|||
"""Default decoder.
|
||||
|
||||
Recursively deserialize into immutable types (
|
||||
:class:`letsencrypt.acme.jose.util.frozendict` instead of
|
||||
:class:`acme.jose.util.frozendict` instead of
|
||||
:func:`dict`, :func:`tuple` instead of :func:`list`).
|
||||
|
||||
"""
|
||||
|
|
@ -304,7 +304,7 @@ def encode_cert(cert):
|
|||
"""Encode certificate as JOSE Base-64 DER.
|
||||
|
||||
:param cert: Certificate.
|
||||
:type cert: :class:`letsencrypt.acme.jose.util.ComparableX509`
|
||||
:type cert: :class:`acme.jose.util.ComparableX509`
|
||||
|
||||
"""
|
||||
return b64.b64encode(cert.as_der())
|
||||
|
|
@ -381,7 +381,7 @@ class TypedJSONObjectWithFields(JSONObjectWithFields):
|
|||
|
||||
:returns: Serializable JSON object representing ACME typed object.
|
||||
:meth:`validate` will almost certainly not work, due to reasons
|
||||
explained in :class:`letsencrypt.acme.interfaces.IJSONSerializable`.
|
||||
explained in :class:`acme.interfaces.IJSONSerializable`.
|
||||
:rtype: dict
|
||||
|
||||
"""
|
||||
|
|
@ -393,7 +393,7 @@ class TypedJSONObjectWithFields(JSONObjectWithFields):
|
|||
def from_json(cls, jobj):
|
||||
"""Deserialize ACME object from valid JSON object.
|
||||
|
||||
:raises letsencrypt.acme.errors.UnrecognizedTypeError: if type
|
||||
:raises acme.errors.UnrecognizedTypeError: if type
|
||||
of the ACME object has not been registered.
|
||||
|
||||
"""
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.jose.json_util."""
|
||||
"""Tests for acme.jose.json_util."""
|
||||
import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
|
@ -6,19 +6,19 @@ import unittest
|
|||
import M2Crypto
|
||||
import mock
|
||||
|
||||
from letsencrypt.acme.jose import errors
|
||||
from letsencrypt.acme.jose import interfaces
|
||||
from letsencrypt.acme.jose import util
|
||||
from acme.jose import errors
|
||||
from acme.jose import interfaces
|
||||
from acme.jose import util
|
||||
|
||||
|
||||
CERT = M2Crypto.X509.load_cert(pkg_resources.resource_filename(
|
||||
'letsencrypt.client.tests', os.path.join('testdata', 'cert.pem')))
|
||||
'letsencrypt.tests', os.path.join('testdata', 'cert.pem')))
|
||||
CSR = M2Crypto.X509.load_request(pkg_resources.resource_filename(
|
||||
'letsencrypt.client.tests', os.path.join('testdata', 'csr.pem')))
|
||||
'letsencrypt.tests', os.path.join('testdata', 'csr.pem')))
|
||||
|
||||
|
||||
class FieldTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.json_util.Field."""
|
||||
"""Tests for acme.jose.json_util.Field."""
|
||||
|
||||
def test_descriptors(self):
|
||||
mock_value = mock.MagicMock()
|
||||
|
|
@ -31,7 +31,7 @@ class FieldTest(unittest.TestCase):
|
|||
def encoder(unused_value):
|
||||
return 'e'
|
||||
|
||||
from letsencrypt.acme.jose.json_util import Field
|
||||
from acme.jose.json_util import Field
|
||||
field = Field('foo')
|
||||
|
||||
field = field.encoder(encoder)
|
||||
|
|
@ -45,45 +45,45 @@ class FieldTest(unittest.TestCase):
|
|||
class MockField(interfaces.JSONDeSerializable):
|
||||
# pylint: disable=missing-docstring
|
||||
def to_partial_json(self):
|
||||
return 'foo'
|
||||
return 'foo' # pragma: no cover
|
||||
@classmethod
|
||||
def from_json(cls, jobj):
|
||||
pass
|
||||
pass # pragma: no cover
|
||||
mock_field = MockField()
|
||||
|
||||
from letsencrypt.acme.jose.json_util import Field
|
||||
from acme.jose.json_util import Field
|
||||
self.assertTrue(Field.default_encoder(mock_field) is mock_field)
|
||||
# in particular...
|
||||
self.assertNotEqual('foo', Field.default_encoder(mock_field))
|
||||
|
||||
def test_default_encoder_passthrough(self):
|
||||
mock_value = mock.MagicMock()
|
||||
from letsencrypt.acme.jose.json_util import Field
|
||||
from acme.jose.json_util import Field
|
||||
self.assertTrue(Field.default_encoder(mock_value) is mock_value)
|
||||
|
||||
def test_default_decoder_list_to_tuple(self):
|
||||
from letsencrypt.acme.jose.json_util import Field
|
||||
from acme.jose.json_util import Field
|
||||
self.assertEqual((1, 2, 3), Field.default_decoder([1, 2, 3]))
|
||||
|
||||
def test_default_decoder_dict_to_frozendict(self):
|
||||
from letsencrypt.acme.jose.json_util import Field
|
||||
from acme.jose.json_util import Field
|
||||
obj = Field.default_decoder({'x': 2})
|
||||
self.assertTrue(isinstance(obj, util.frozendict))
|
||||
self.assertEqual(obj, util.frozendict(x=2))
|
||||
|
||||
def test_default_decoder_passthrough(self):
|
||||
mock_value = mock.MagicMock()
|
||||
from letsencrypt.acme.jose.json_util import Field
|
||||
from acme.jose.json_util import Field
|
||||
self.assertTrue(Field.default_decoder(mock_value) is mock_value)
|
||||
|
||||
|
||||
class JSONObjectWithFieldsTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.json_util.JSONObjectWithFields."""
|
||||
"""Tests for acme.jose.json_util.JSONObjectWithFields."""
|
||||
# pylint: disable=protected-access
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.json_util import JSONObjectWithFields
|
||||
from letsencrypt.acme.jose.json_util import Field
|
||||
from acme.jose.json_util import JSONObjectWithFields
|
||||
from acme.jose.json_util import Field
|
||||
|
||||
class MockJSONObjectWithFields(JSONObjectWithFields):
|
||||
# pylint: disable=invalid-name,missing-docstring,no-self-argument
|
||||
|
|
@ -185,11 +185,11 @@ class DeEncodersTest(unittest.TestCase):
|
|||
)
|
||||
|
||||
def test_decode_b64_jose_padding_error(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_b64jose
|
||||
from acme.jose.json_util import decode_b64jose
|
||||
self.assertRaises(errors.DeserializationError, decode_b64jose, 'x')
|
||||
|
||||
def test_decode_b64_jose_size(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_b64jose
|
||||
from acme.jose.json_util import decode_b64jose
|
||||
self.assertEqual('foo', decode_b64jose('Zm9v', size=3))
|
||||
self.assertRaises(
|
||||
errors.DeserializationError, decode_b64jose, 'Zm9v', size=2)
|
||||
|
|
@ -197,44 +197,44 @@ class DeEncodersTest(unittest.TestCase):
|
|||
errors.DeserializationError, decode_b64jose, 'Zm9v', size=4)
|
||||
|
||||
def test_decode_b64_jose_minimum_size(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_b64jose
|
||||
from acme.jose.json_util import decode_b64jose
|
||||
self.assertEqual('foo', decode_b64jose('Zm9v', size=3, minimum=True))
|
||||
self.assertEqual('foo', decode_b64jose('Zm9v', size=2, minimum=True))
|
||||
self.assertRaises(errors.DeserializationError, decode_b64jose,
|
||||
'Zm9v', size=4, minimum=True)
|
||||
|
||||
def test_decode_hex16(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_hex16
|
||||
from acme.jose.json_util import decode_hex16
|
||||
self.assertEqual('foo', decode_hex16('666f6f'))
|
||||
|
||||
def test_decode_hex16_minimum_size(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_hex16
|
||||
from acme.jose.json_util import decode_hex16
|
||||
self.assertEqual('foo', decode_hex16('666f6f', size=3, minimum=True))
|
||||
self.assertEqual('foo', decode_hex16('666f6f', size=2, minimum=True))
|
||||
self.assertRaises(errors.DeserializationError, decode_hex16,
|
||||
'666f6f', size=4, minimum=True)
|
||||
|
||||
def test_decode_hex16_odd_length(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_hex16
|
||||
from acme.jose.json_util import decode_hex16
|
||||
self.assertRaises(errors.DeserializationError, decode_hex16, 'x')
|
||||
|
||||
def test_encode_cert(self):
|
||||
from letsencrypt.acme.jose.json_util import encode_cert
|
||||
from acme.jose.json_util import encode_cert
|
||||
self.assertEqual(self.b64_cert, encode_cert(CERT))
|
||||
|
||||
def test_decode_cert(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_cert
|
||||
from acme.jose.json_util import decode_cert
|
||||
cert = decode_cert(self.b64_cert)
|
||||
self.assertTrue(isinstance(cert, util.ComparableX509))
|
||||
self.assertEqual(cert, CERT)
|
||||
self.assertRaises(errors.DeserializationError, decode_cert, '')
|
||||
|
||||
def test_encode_csr(self):
|
||||
from letsencrypt.acme.jose.json_util import encode_csr
|
||||
from acme.jose.json_util import encode_csr
|
||||
self.assertEqual(self.b64_cert, encode_csr(CERT))
|
||||
|
||||
def test_decode_csr(self):
|
||||
from letsencrypt.acme.jose.json_util import decode_csr
|
||||
from acme.jose.json_util import decode_csr
|
||||
csr = decode_csr(self.b64_csr)
|
||||
self.assertTrue(isinstance(csr, util.ComparableX509))
|
||||
self.assertEqual(csr, CSR)
|
||||
|
|
@ -244,7 +244,7 @@ class DeEncodersTest(unittest.TestCase):
|
|||
class TypedJSONObjectWithFieldsTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.json_util import TypedJSONObjectWithFields
|
||||
from acme.jose.json_util import TypedJSONObjectWithFields
|
||||
|
||||
# pylint: disable=missing-docstring,abstract-method
|
||||
# pylint: disable=too-few-public-methods
|
||||
|
|
@ -294,4 +294,4 @@ class TypedJSONObjectWithFieldsTest(unittest.TestCase):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -13,9 +13,9 @@ from Crypto.Hash import SHA512
|
|||
from Crypto.Signature import PKCS1_PSS
|
||||
from Crypto.Signature import PKCS1_v1_5
|
||||
|
||||
from letsencrypt.acme.jose import errors
|
||||
from letsencrypt.acme.jose import interfaces
|
||||
from letsencrypt.acme.jose import jwk
|
||||
from acme.jose import errors
|
||||
from acme.jose import interfaces
|
||||
from acme.jose import jwk
|
||||
|
||||
|
||||
class JWA(interfaces.JSONDeSerializable): # pylint: disable=abstract-method
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
"""Tests for letsencrypt.acme.jose.jwa."""
|
||||
"""Tests for acme.jose.jwa."""
|
||||
import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
from letsencrypt.acme.jose import errors
|
||||
from acme.jose import errors
|
||||
|
||||
|
||||
RSA256_KEY = RSA.importKey(pkg_resources.resource_string(
|
||||
|
|
@ -17,19 +17,19 @@ RSA1024_KEY = RSA.importKey(pkg_resources.resource_string(
|
|||
|
||||
|
||||
class JWASignatureTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.jwa.JWASignature."""
|
||||
"""Tests for acme.jose.jwa.JWASignature."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.jwa import JWASignature
|
||||
from acme.jose.jwa import JWASignature
|
||||
|
||||
class MockSig(JWASignature):
|
||||
# pylint: disable=missing-docstring,too-few-public-methods
|
||||
# pylint: disable=abstract-class-not-used
|
||||
def sign(self, key, msg):
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError() # pragma: no cover
|
||||
|
||||
def verify(self, key, msg, sig):
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError() # pragma: no cover
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
self.Sig1 = MockSig('Sig1')
|
||||
|
|
@ -48,15 +48,15 @@ class JWASignatureTest(unittest.TestCase):
|
|||
self.assertEqual(self.Sig2.to_partial_json(), 'Sig2')
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.jose.jwa import JWASignature
|
||||
from letsencrypt.acme.jose.jwa import RS256
|
||||
from acme.jose.jwa import JWASignature
|
||||
from acme.jose.jwa import RS256
|
||||
self.assertTrue(JWASignature.from_json('RS256') is RS256)
|
||||
|
||||
|
||||
class JWAHSTest(unittest.TestCase): # pylint: disable=too-few-public-methods
|
||||
|
||||
def test_it(self):
|
||||
from letsencrypt.acme.jose.jwa import HS256
|
||||
from acme.jose.jwa import HS256
|
||||
sig = (
|
||||
"\xceR\xea\xcd\x94\xab\xcf\xfb\xe0\xacA.:\x1a'\x08i\xe2\xc4"
|
||||
"\r\x85+\x0e\x85\xaeUZ\xd4\xb3\x97zO"
|
||||
|
|
@ -69,19 +69,19 @@ class JWAHSTest(unittest.TestCase): # pylint: disable=too-few-public-methods
|
|||
class JWARSTest(unittest.TestCase):
|
||||
|
||||
def test_sign_no_private_part(self):
|
||||
from letsencrypt.acme.jose.jwa import RS256
|
||||
from acme.jose.jwa import RS256
|
||||
self.assertRaises(
|
||||
errors.Error, RS256.sign, RSA512_KEY.publickey(), 'foo')
|
||||
|
||||
def test_sign_key_too_small(self):
|
||||
from letsencrypt.acme.jose.jwa import RS256
|
||||
from letsencrypt.acme.jose.jwa import PS256
|
||||
from acme.jose.jwa import RS256
|
||||
from acme.jose.jwa import PS256
|
||||
self.assertRaises(errors.Error, RS256.sign, RSA256_KEY, 'foo')
|
||||
self.assertRaises(errors.Error, PS256.sign, RSA256_KEY, 'foo')
|
||||
self.assertRaises(errors.Error, PS256.sign, RSA512_KEY, 'foo')
|
||||
|
||||
def test_rs(self):
|
||||
from letsencrypt.acme.jose.jwa import RS256
|
||||
from acme.jose.jwa import RS256
|
||||
sig = (
|
||||
'|\xc6\xb2\xa4\xab(\x87\x99\xfa*:\xea\xf8\xa0N&}\x9f\x0f\xc0O'
|
||||
'\xc6t\xa3\xe6\xfa\xbb"\x15Y\x80Y\xe0\x81\xb8\x88)\xba\x0c\x9c'
|
||||
|
|
@ -95,11 +95,11 @@ class JWARSTest(unittest.TestCase):
|
|||
self.assertFalse(RS256.verify(RSA512_KEY, 'foo', sig + '!') is False)
|
||||
|
||||
def test_ps(self):
|
||||
from letsencrypt.acme.jose.jwa import PS256
|
||||
from acme.jose.jwa import PS256
|
||||
sig = PS256.sign(RSA1024_KEY, 'foo')
|
||||
self.assertTrue(PS256.verify(RSA1024_KEY, 'foo', sig) is True)
|
||||
self.assertTrue(PS256.verify(RSA1024_KEY, 'foo', sig + '!') is False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -4,10 +4,10 @@ import binascii
|
|||
|
||||
import Crypto.PublicKey.RSA
|
||||
|
||||
from letsencrypt.acme.jose import b64
|
||||
from letsencrypt.acme.jose import errors
|
||||
from letsencrypt.acme.jose import json_util
|
||||
from letsencrypt.acme.jose import util
|
||||
from acme.jose import b64
|
||||
from acme.jose import errors
|
||||
from acme.jose import json_util
|
||||
from acme.jose import util
|
||||
|
||||
|
||||
class JWK(json_util.TypedJSONObjectWithFields):
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
"""Tests for letsencrypt.acme.jose.jwk."""
|
||||
"""Tests for acme.jose.jwk."""
|
||||
import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
from letsencrypt.acme.jose import errors
|
||||
from letsencrypt.acme.jose import util
|
||||
from acme.jose import errors
|
||||
from acme.jose import util
|
||||
|
||||
|
||||
RSA256_KEY = util.HashableRSAKey(RSA.importKey(pkg_resources.resource_string(
|
||||
|
|
@ -16,10 +16,10 @@ RSA512_KEY = util.HashableRSAKey(RSA.importKey(pkg_resources.resource_string(
|
|||
|
||||
|
||||
class JWKOctTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.jwk.JWKOct."""
|
||||
"""Tests for acme.jose.jwk.JWKOct."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.jwk import JWKOct
|
||||
from acme.jose.jwk import JWKOct
|
||||
self.jwk = JWKOct(key='foo')
|
||||
self.jobj = {'kty': 'oct', 'k': 'foo'}
|
||||
|
||||
|
|
@ -27,15 +27,15 @@ class JWKOctTest(unittest.TestCase):
|
|||
self.assertEqual(self.jwk.to_partial_json(), self.jobj)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.jose.jwk import JWKOct
|
||||
from acme.jose.jwk import JWKOct
|
||||
self.assertEqual(self.jwk, JWKOct.from_json(self.jobj))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.jose.jwk import JWKOct
|
||||
from acme.jose.jwk import JWKOct
|
||||
hash(JWKOct.from_json(self.jobj))
|
||||
|
||||
def test_load(self):
|
||||
from letsencrypt.acme.jose.jwk import JWKOct
|
||||
from acme.jose.jwk import JWKOct
|
||||
self.assertEqual(self.jwk, JWKOct.load('foo'))
|
||||
|
||||
def test_public(self):
|
||||
|
|
@ -43,10 +43,10 @@ class JWKOctTest(unittest.TestCase):
|
|||
|
||||
|
||||
class JWKRSATest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.jwk.JWKRSA."""
|
||||
"""Tests for acme.jose.jwk.JWKRSA."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.jwk import JWKRSA
|
||||
from acme.jose.jwk import JWKRSA
|
||||
self.jwk256 = JWKRSA(key=RSA256_KEY.publickey())
|
||||
self.jwk256_private = JWKRSA(key=RSA256_KEY)
|
||||
self.jwk256json = {
|
||||
|
|
@ -71,7 +71,7 @@ class JWKRSATest(unittest.TestCase):
|
|||
self.assertNotEqual(self.jwk512, self.jwk256)
|
||||
|
||||
def test_load(self):
|
||||
from letsencrypt.acme.jose.jwk import JWKRSA
|
||||
from acme.jose.jwk import JWKRSA
|
||||
self.assertEqual(
|
||||
JWKRSA(key=util.HashableRSAKey(RSA256_KEY)), JWKRSA.load(
|
||||
pkg_resources.resource_string(
|
||||
|
|
@ -85,18 +85,18 @@ class JWKRSATest(unittest.TestCase):
|
|||
self.assertEqual(self.jwk512.to_partial_json(), self.jwk512json)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.jose.jwk import JWK
|
||||
from acme.jose.jwk import JWK
|
||||
self.assertEqual(self.jwk256, JWK.from_json(self.jwk256json))
|
||||
# TODO: fix schemata to allow RSA512
|
||||
#self.assertEqual(self.jwk512, JWK.from_json(self.jwk512json))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.jose.jwk import JWK
|
||||
from acme.jose.jwk import JWK
|
||||
hash(JWK.from_json(self.jwk256json))
|
||||
|
||||
def test_from_json_non_schema_errors(self):
|
||||
# valid against schema, but still failing
|
||||
from letsencrypt.acme.jose.jwk import JWK
|
||||
from acme.jose.jwk import JWK
|
||||
self.assertRaises(errors.DeserializationError, JWK.from_json,
|
||||
{'kty': 'RSA', 'e': 'AQAB', 'n': ''})
|
||||
self.assertRaises(errors.DeserializationError, JWK.from_json,
|
||||
|
|
@ -104,4 +104,4 @@ class JWKRSATest(unittest.TestCase):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -5,12 +5,12 @@ import sys
|
|||
|
||||
import M2Crypto
|
||||
|
||||
from letsencrypt.acme.jose import b64
|
||||
from letsencrypt.acme.jose import errors
|
||||
from letsencrypt.acme.jose import json_util
|
||||
from letsencrypt.acme.jose import jwa
|
||||
from letsencrypt.acme.jose import jwk
|
||||
from letsencrypt.acme.jose import util
|
||||
from acme.jose import b64
|
||||
from acme.jose import errors
|
||||
from acme.jose import json_util
|
||||
from acme.jose import jwa
|
||||
from acme.jose import jwk
|
||||
from acme.jose import util
|
||||
|
||||
|
||||
class MediaType(object):
|
||||
|
|
@ -103,9 +103,9 @@ class Header(json_util.JSONObjectWithFields):
|
|||
.. todo:: Supports only "jwk" header parameter lookup.
|
||||
|
||||
:returns: (Public) key found in the header.
|
||||
:rtype: :class:`letsencrypt.acme.jose.jwk.JWK`
|
||||
:rtype: :class:`acme.jose.jwk.JWK`
|
||||
|
||||
:raises letsencrypt.acme.jose.errors.Error: if key could not be found
|
||||
:raises acme.jose.errors.Error: if key could not be found
|
||||
|
||||
"""
|
||||
if self.jwk is None:
|
||||
|
|
@ -180,7 +180,7 @@ class Signature(json_util.JSONObjectWithFields):
|
|||
"""Verify.
|
||||
|
||||
:param key: Key used for verification.
|
||||
:type key: :class:`letsencrypt.acme.jose.jwk.JWK`
|
||||
:type key: :class:`acme.jose.jwk.JWK`
|
||||
|
||||
"""
|
||||
key = self.combined.find_key() if key is None else key
|
||||
|
|
@ -195,7 +195,7 @@ class Signature(json_util.JSONObjectWithFields):
|
|||
"""Sign.
|
||||
|
||||
:param key: Key for signature.
|
||||
:type key: :class:`letsencrypt.acme.jose.jwk.JWK`
|
||||
:type key: :class:`acme.jose.jwk.JWK`
|
||||
|
||||
"""
|
||||
assert isinstance(key, alg.kty)
|
||||
|
|
@ -241,8 +241,6 @@ class Signature(json_util.JSONObjectWithFields):
|
|||
class JWS(json_util.JSONObjectWithFields):
|
||||
"""JSON Web Signature.
|
||||
|
||||
from letsencrypt.acme.jose import interfaces
|
||||
|
||||
:ivar str payload: JWS Payload.
|
||||
:ivar str signaturea: JWS Signatures.
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.jose.jws."""
|
||||
"""Tests for acme.jose.jws."""
|
||||
import base64
|
||||
import os
|
||||
import pkg_resources
|
||||
|
|
@ -8,49 +8,49 @@ import Crypto.PublicKey.RSA
|
|||
import M2Crypto
|
||||
import mock
|
||||
|
||||
from letsencrypt.acme.jose import b64
|
||||
from letsencrypt.acme.jose import errors
|
||||
from letsencrypt.acme.jose import jwa
|
||||
from letsencrypt.acme.jose import jwk
|
||||
from letsencrypt.acme.jose import util
|
||||
from acme.jose import b64
|
||||
from acme.jose import errors
|
||||
from acme.jose import jwa
|
||||
from acme.jose import jwk
|
||||
from acme.jose import util
|
||||
|
||||
|
||||
CERT = util.ComparableX509(M2Crypto.X509.load_cert(
|
||||
pkg_resources.resource_filename(
|
||||
'letsencrypt.client.tests', 'testdata/cert.pem')))
|
||||
'letsencrypt.tests', 'testdata/cert.pem')))
|
||||
RSA512_KEY = Crypto.PublicKey.RSA.importKey(pkg_resources.resource_string(
|
||||
__name__, os.path.join('testdata', 'rsa512_key.pem')))
|
||||
|
||||
|
||||
class MediaTypeTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.jws.MediaType."""
|
||||
"""Tests for acme.jose.jws.MediaType."""
|
||||
|
||||
def test_decode(self):
|
||||
from letsencrypt.acme.jose.jws import MediaType
|
||||
from acme.jose.jws import MediaType
|
||||
self.assertEqual('application/app', MediaType.decode('application/app'))
|
||||
self.assertEqual('application/app', MediaType.decode('app'))
|
||||
self.assertRaises(
|
||||
errors.DeserializationError, MediaType.decode, 'app;foo')
|
||||
|
||||
def test_encode(self):
|
||||
from letsencrypt.acme.jose.jws import MediaType
|
||||
from acme.jose.jws import MediaType
|
||||
self.assertEqual('app', MediaType.encode('application/app'))
|
||||
self.assertEqual('application/app;foo',
|
||||
MediaType.encode('application/app;foo'))
|
||||
|
||||
|
||||
class HeaderTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.jws.Header."""
|
||||
"""Tests for acme.jose.jws.Header."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.jws import Header
|
||||
from acme.jose.jws import Header
|
||||
self.header1 = Header(jwk='foo')
|
||||
self.header2 = Header(jwk='bar')
|
||||
self.crit = Header(crit=('a', 'b'))
|
||||
self.empty = Header()
|
||||
|
||||
def test_add_non_empty(self):
|
||||
from letsencrypt.acme.jose.jws import Header
|
||||
from acme.jose.jws import Header
|
||||
self.assertEqual(Header(jwk='foo', crit=('a', 'b')),
|
||||
self.header1 + self.crit)
|
||||
|
||||
|
|
@ -65,12 +65,12 @@ class HeaderTest(unittest.TestCase):
|
|||
self.assertRaises(TypeError, self.header1.__add__, 'xxx')
|
||||
|
||||
def test_crit_decode_always_errors(self):
|
||||
from letsencrypt.acme.jose.jws import Header
|
||||
from acme.jose.jws import Header
|
||||
self.assertRaises(errors.DeserializationError, Header.from_json,
|
||||
{'crit': ['a', 'b']})
|
||||
|
||||
def test_x5c_decoding(self):
|
||||
from letsencrypt.acme.jose.jws import Header
|
||||
from acme.jose.jws import Header
|
||||
header = Header(x5c=(CERT, CERT))
|
||||
jobj = header.to_partial_json()
|
||||
cert_b64 = base64.b64encode(CERT.as_der())
|
||||
|
|
@ -86,30 +86,30 @@ class HeaderTest(unittest.TestCase):
|
|||
|
||||
|
||||
class SignatureTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.jws.Signature."""
|
||||
"""Tests for acme.jose.jws.Signature."""
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.jose.jws import Header
|
||||
from letsencrypt.acme.jose.jws import Signature
|
||||
from acme.jose.jws import Header
|
||||
from acme.jose.jws import Signature
|
||||
self.assertEqual(
|
||||
Signature(signature='foo', header=Header(alg=jwa.RS256)),
|
||||
Signature.from_json(
|
||||
{'signature': 'Zm9v', 'header': {'alg': 'RS256'}}))
|
||||
|
||||
def test_from_json_no_alg_error(self):
|
||||
from letsencrypt.acme.jose.jws import Signature
|
||||
from acme.jose.jws import Signature
|
||||
self.assertRaises(errors.DeserializationError,
|
||||
Signature.from_json, {'signature': 'foo'})
|
||||
|
||||
|
||||
class JWSTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.jws.JWS."""
|
||||
"""Tests for acme.jose.jws.JWS."""
|
||||
|
||||
def setUp(self):
|
||||
self.privkey = jwk.JWKRSA(key=RSA512_KEY)
|
||||
self.pubkey = self.privkey.public()
|
||||
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
self.unprotected = JWS.sign(
|
||||
payload='foo', key=self.privkey, alg=jwa.RS256)
|
||||
self.protected = JWS.sign(
|
||||
|
|
@ -140,7 +140,7 @@ class JWSTest(unittest.TestCase):
|
|||
'_893n1zQjpim_eLS5J1F61lkvrCrCDErTEJnBGOGesJ72M7b6Ve1cAJA',
|
||||
compact)
|
||||
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
mixed = JWS.from_compact(compact)
|
||||
|
||||
self.assertNotEqual(self.mixed, mixed)
|
||||
|
|
@ -148,7 +148,7 @@ class JWSTest(unittest.TestCase):
|
|||
set(['alg']), set(mixed.signature.combined.not_omitted()))
|
||||
|
||||
def test_from_compact_missing_components(self):
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
self.assertRaises(errors.DeserializationError, JWS.from_compact, '.')
|
||||
|
||||
def test_json_omitempty(self):
|
||||
|
|
@ -160,7 +160,7 @@ class JWSTest(unittest.TestCase):
|
|||
|
||||
unprotected_jobj['header'] = unprotected_jobj['header'].to_json()
|
||||
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
self.assertEqual(JWS.from_json(protected_jobj), self.protected)
|
||||
self.assertEqual(JWS.from_json(unprotected_jobj), self.unprotected)
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ class JWSTest(unittest.TestCase):
|
|||
jobj_from['header'] = jobj_from['header'].to_json()
|
||||
|
||||
self.assertEqual(self.mixed.to_partial_json(flat=True), jobj_to)
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
self.assertEqual(self.mixed, JWS.from_json(jobj_from))
|
||||
|
||||
def test_json_not_flat(self):
|
||||
|
|
@ -187,16 +187,16 @@ class JWSTest(unittest.TestCase):
|
|||
jobj_from['signatures'] = [jobj_to['signatures'][0].to_json()]
|
||||
|
||||
self.assertEqual(self.mixed.to_partial_json(flat=False), jobj_to)
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
self.assertEqual(self.mixed, JWS.from_json(jobj_from))
|
||||
|
||||
def test_from_json_mixed_flat(self):
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
self.assertRaises(errors.DeserializationError, JWS.from_json,
|
||||
{'signatures': (), 'signature': 'foo'})
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.jose.jws import JWS
|
||||
from acme.jose.jws import JWS
|
||||
hash(JWS.from_json(self.mixed.to_json()))
|
||||
|
||||
|
||||
|
|
@ -207,14 +207,14 @@ class CLITest(unittest.TestCase):
|
|||
__name__, os.path.join('testdata', 'rsa512_key.pem'))
|
||||
|
||||
def test_unverified(self):
|
||||
from letsencrypt.acme.jose.jws import CLI
|
||||
from acme.jose.jws import CLI
|
||||
with mock.patch('sys.stdin') as sin:
|
||||
sin.read.return_value = '{"payload": "foo", "signature": "xxx"}'
|
||||
with mock.patch('sys.stdout'):
|
||||
self.assertEqual(-1, CLI.run(['verify']))
|
||||
|
||||
def test_json(self):
|
||||
from letsencrypt.acme.jose.jws import CLI
|
||||
from acme.jose.jws import CLI
|
||||
|
||||
with mock.patch('sys.stdin') as sin:
|
||||
sin.read.return_value = 'foo'
|
||||
|
|
@ -225,7 +225,7 @@ class CLITest(unittest.TestCase):
|
|||
self.assertEqual(0, CLI.run(['verify']))
|
||||
|
||||
def test_compact(self):
|
||||
from letsencrypt.acme.jose.jws import CLI
|
||||
from acme.jose.jws import CLI
|
||||
|
||||
with mock.patch('sys.stdin') as sin:
|
||||
sin.read.return_value = 'foo'
|
||||
|
|
@ -238,4 +238,4 @@ class CLITest(unittest.TestCase):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -4,7 +4,7 @@ The following command has been used to generate test keys:
|
|||
|
||||
and for the CSR:
|
||||
|
||||
python -c from 'letsencrypt.client.crypto_util import make_csr;
|
||||
python -c from 'letsencrypt.crypto_util import make_csr;
|
||||
import pkg_resources; open("csr2.pem",
|
||||
"w").write(make_csr(pkg_resources.resource_string("letsencrypt.client.tests",
|
||||
"w").write(make_csr(pkg_resources.resource_string("letsencrypt.tests",
|
||||
"testdata/rsa512_key.pem"), ["example2.com"])[0])'
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.jose.util."""
|
||||
"""Tests for acme.jose.util."""
|
||||
import functools
|
||||
import os
|
||||
import pkg_resources
|
||||
|
|
@ -8,10 +8,10 @@ import Crypto.PublicKey.RSA
|
|||
|
||||
|
||||
class HashableRSAKeyTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.util.HashableRSAKey."""
|
||||
"""Tests for acme.jose.util.HashableRSAKey."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.util import HashableRSAKey
|
||||
from acme.jose.util import HashableRSAKey
|
||||
self.key = HashableRSAKey(Crypto.PublicKey.RSA.importKey(
|
||||
pkg_resources.resource_string(
|
||||
__name__, os.path.join('testdata', 'rsa256_key.pem'))))
|
||||
|
|
@ -28,17 +28,17 @@ class HashableRSAKeyTest(unittest.TestCase):
|
|||
self.assertTrue(isinstance(hash(self.key), int))
|
||||
|
||||
def test_publickey(self):
|
||||
from letsencrypt.acme.jose.util import HashableRSAKey
|
||||
from acme.jose.util import HashableRSAKey
|
||||
self.assertTrue(isinstance(self.key.publickey(), HashableRSAKey))
|
||||
|
||||
|
||||
class ImmutableMapTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.jose.util.ImmutableMap."""
|
||||
"""Tests for acme.jose.util.ImmutableMap."""
|
||||
|
||||
def setUp(self):
|
||||
# pylint: disable=invalid-name,too-few-public-methods
|
||||
# pylint: disable=missing-docstring
|
||||
from letsencrypt.acme.jose.util import ImmutableMap
|
||||
from acme.jose.util import ImmutableMap
|
||||
|
||||
class A(ImmutableMap):
|
||||
__slots__ = ('x', 'y')
|
||||
|
|
@ -101,18 +101,18 @@ class ImmutableMapTest(unittest.TestCase):
|
|||
|
||||
|
||||
class frozendictTest(unittest.TestCase): # pylint: disable=invalid-name
|
||||
"""Tests for letsencrypt.acme.jose.util.frozendict."""
|
||||
"""Tests for acme.jose.util.frozendict."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.jose.util import frozendict
|
||||
from acme.jose.util import frozendict
|
||||
self.fdict = frozendict(x=1, y='2')
|
||||
|
||||
def test_init_dict(self):
|
||||
from letsencrypt.acme.jose.util import frozendict
|
||||
from acme.jose.util import frozendict
|
||||
self.assertEqual(self.fdict, frozendict({'x': 1, 'y': '2'}))
|
||||
|
||||
def test_init_other_raises_type_error(self):
|
||||
from letsencrypt.acme.jose.util import frozendict
|
||||
from acme.jose.util import frozendict
|
||||
# specifically fail for generators...
|
||||
self.assertRaises(TypeError, frozendict, {'a': 'b'}.iteritems())
|
||||
|
||||
|
|
@ -137,4 +137,4 @@ class frozendictTest(unittest.TestCase): # pylint: disable=invalid-name
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -22,11 +22,11 @@
|
|||
"""
|
||||
import jsonschema
|
||||
|
||||
from letsencrypt.acme import challenges
|
||||
from letsencrypt.acme import errors
|
||||
from letsencrypt.acme import jose
|
||||
from letsencrypt.acme import other
|
||||
from letsencrypt.acme import util
|
||||
from acme import challenges
|
||||
from acme import errors
|
||||
from acme import jose
|
||||
from acme import other
|
||||
from acme import util
|
||||
|
||||
|
||||
class Message(jose.TypedJSONObjectWithFields):
|
||||
|
|
@ -41,7 +41,7 @@ class Message(jose.TypedJSONObjectWithFields):
|
|||
|
||||
Subclasses must overrride it with a value that is acceptable by
|
||||
:func:`jsonschema.validate`, most probably using
|
||||
:func:`letsencrypt.acme.util.load_schema`.
|
||||
:func:`acme.util.load_schema`.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -53,10 +53,10 @@ class Message(jose.TypedJSONObjectWithFields):
|
|||
|
||||
:param jobj: JSON object.
|
||||
|
||||
:raises letsencrypt.acme.errors.SchemaValidationError: if the input
|
||||
:raises acme.errors.SchemaValidationError: if the input
|
||||
JSON object could not be validated against JSON schema specified
|
||||
in :attr:`schema`.
|
||||
:raises letsencrypt.acme.jose.errors.DeserializationError: for any
|
||||
:raises acme.jose.errors.DeserializationError: for any
|
||||
other generic error in decoding.
|
||||
|
||||
:returns: instance of the class
|
||||
|
|
@ -79,7 +79,7 @@ class Challenge(Message):
|
|||
|
||||
:ivar str nonce: Random data, **not** base64-encoded.
|
||||
:ivar list challenges: List of
|
||||
:class:`~letsencrypt.acme.challenges.Challenge` objects.
|
||||
:class:`~acme.challenges.Challenge` objects.
|
||||
|
||||
.. todo::
|
||||
1. can challenges contain two challenges of the same type?
|
||||
|
|
@ -121,7 +121,7 @@ class ChallengeRequest(Message):
|
|||
class Authorization(Message):
|
||||
"""ACME "authorization" message.
|
||||
|
||||
:ivar jwk: :class:`letsencrypt.acme.jose.JWK`
|
||||
:ivar jwk: :class:`acme.jose.JWK`
|
||||
|
||||
"""
|
||||
typ = "authorization"
|
||||
|
|
@ -139,8 +139,8 @@ class AuthorizationRequest(Message):
|
|||
:ivar str nonce: Random data from the corresponding
|
||||
:attr:`Challenge.nonce`, **not** base64-encoded.
|
||||
:ivar list responses: List of completed challenges (
|
||||
:class:`letsencrypt.acme.challenges.ChallengeResponse`).
|
||||
:ivar signature: Signature (:class:`letsencrypt.acme.other.Signature`).
|
||||
:class:`acme.challenges.ChallengeResponse`).
|
||||
:ivar signature: Signature (:class:`acme.other.Signature`).
|
||||
|
||||
"""
|
||||
typ = "authorizationRequest"
|
||||
|
|
@ -184,7 +184,7 @@ class AuthorizationRequest(Message):
|
|||
"""Verify signature.
|
||||
|
||||
.. warning:: Caller must check that the public key encoded in the
|
||||
:attr:`signature`'s :class:`letsencrypt.acme.jose.JWK` object
|
||||
:attr:`signature`'s :class:`acme.jose.JWK` object
|
||||
is the correct key for a given context.
|
||||
|
||||
:param str name: Hostname
|
||||
|
|
@ -202,10 +202,10 @@ class Certificate(Message):
|
|||
"""ACME "certificate" message.
|
||||
|
||||
:ivar certificate: The certificate (:class:`M2Crypto.X509.X509`
|
||||
wrapped in :class:`letsencrypt.acme.util.ComparableX509`).
|
||||
wrapped in :class:`acme.util.ComparableX509`).
|
||||
|
||||
:ivar list chain: Chain of certificates (:class:`M2Crypto.X509.X509`
|
||||
wrapped in :class:`letsencrypt.acme.util.ComparableX509` ).
|
||||
wrapped in :class:`acme.util.ComparableX509` ).
|
||||
|
||||
"""
|
||||
typ = "certificate"
|
||||
|
|
@ -230,8 +230,8 @@ class CertificateRequest(Message):
|
|||
"""ACME "certificateRequest" message.
|
||||
|
||||
:ivar csr: Certificate Signing Request (:class:`M2Crypto.X509.Request`
|
||||
wrapped in :class:`letsencrypt.acme.util.ComparableX509`.
|
||||
:ivar signature: Signature (:class:`letsencrypt.acme.other.Signature`).
|
||||
wrapped in :class:`acme.util.ComparableX509`.
|
||||
:ivar signature: Signature (:class:`acme.other.Signature`).
|
||||
|
||||
"""
|
||||
typ = "certificateRequest"
|
||||
|
|
@ -262,7 +262,7 @@ class CertificateRequest(Message):
|
|||
"""Verify signature.
|
||||
|
||||
.. warning:: Caller must check that the public key encoded in the
|
||||
:attr:`signature`'s :class:`letsencrypt.acme.jose.JWK` object
|
||||
:attr:`signature`'s :class:`acme.jose.JWK` object
|
||||
is the correct key for a given context.
|
||||
|
||||
:returns: True iff ``signature`` can be verified, False otherwise.
|
||||
|
|
@ -316,8 +316,8 @@ class RevocationRequest(Message):
|
|||
"""ACME "revocationRequest" message.
|
||||
|
||||
:ivar certificate: Certificate (:class:`M2Crypto.X509.X509`
|
||||
wrapped in :class:`letsencrypt.acme.util.ComparableX509`).
|
||||
:ivar signature: Signature (:class:`letsencrypt.acme.other.Signature`).
|
||||
wrapped in :class:`acme.util.ComparableX509`).
|
||||
:ivar signature: Signature (:class:`acme.other.Signature`).
|
||||
|
||||
"""
|
||||
typ = "revocationRequest"
|
||||
|
|
@ -348,7 +348,7 @@ class RevocationRequest(Message):
|
|||
"""Verify signature.
|
||||
|
||||
.. warning:: Caller must check that the public key encoded in the
|
||||
:attr:`signature`'s :class:`letsencrypt.acme.jose.JWK` object
|
||||
:attr:`signature`'s :class:`acme.jose.JWK` object
|
||||
is the correct key for a given context.
|
||||
|
||||
:returns: True iff ``signature`` can be verified, False otherwise.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
"""ACME protocol messages."""
|
||||
from letsencrypt.acme import challenges
|
||||
from letsencrypt.acme import fields
|
||||
from letsencrypt.acme import jose
|
||||
from acme import challenges
|
||||
from acme import fields
|
||||
from acme import jose
|
||||
|
||||
|
||||
class Error(jose.JSONObjectWithFields, Exception):
|
||||
|
|
@ -46,6 +46,11 @@ class Error(jose.JSONObjectWithFields, Exception):
|
|||
"""Hardcoded error description based on its type."""
|
||||
return self.ERROR_TYPE_DESCRIPTIONS[self.typ]
|
||||
|
||||
def __str__(self):
|
||||
if self.typ is not None:
|
||||
return ' :: '.join([self.typ, self.description, self.detail])
|
||||
else:
|
||||
return str(self.detail)
|
||||
|
||||
class _Constant(jose.JSONDeSerializable):
|
||||
"""ACME constant."""
|
||||
|
|
@ -96,7 +101,7 @@ IDENTIFIER_FQDN = IdentifierType('dns') # IdentifierDNS in Boulder
|
|||
class Identifier(jose.JSONObjectWithFields):
|
||||
"""ACME identifier.
|
||||
|
||||
:ivar letsencrypt.acme.messages2.IdentifierType typ:
|
||||
:ivar acme.messages2.IdentifierType typ:
|
||||
|
||||
"""
|
||||
typ = jose.Field('type', decoder=IdentifierType.from_json)
|
||||
|
|
@ -106,7 +111,7 @@ class Identifier(jose.JSONObjectWithFields):
|
|||
class Resource(jose.ImmutableMap):
|
||||
"""ACME Resource.
|
||||
|
||||
:ivar letsencrypt.acme.messages2.ResourceBody body: Resource body.
|
||||
:ivar acme.messages2.ResourceBody body: Resource body.
|
||||
:ivar str uri: Location of the resource.
|
||||
|
||||
"""
|
||||
|
|
@ -120,7 +125,7 @@ class ResourceBody(jose.JSONObjectWithFields):
|
|||
class RegistrationResource(Resource):
|
||||
"""Registration Resource.
|
||||
|
||||
:ivar letsencrypt.acme.messages2.Registration body:
|
||||
:ivar acme.messages2.Registration body:
|
||||
:ivar str new_authzr_uri: URI found in the 'next' ``Link`` header
|
||||
:ivar str terms_of_service: URL for the CA TOS.
|
||||
|
||||
|
|
@ -131,7 +136,7 @@ class RegistrationResource(Resource):
|
|||
class Registration(ResourceBody):
|
||||
"""Registration Resource Body.
|
||||
|
||||
:ivar letsencrypt.acme.jose.jwk.JWK key: Public key.
|
||||
:ivar acme.jose.jwk.JWK key: Public key.
|
||||
:ivar tuple contact: Contact information following ACME spec
|
||||
|
||||
"""
|
||||
|
|
@ -146,7 +151,7 @@ class Registration(ResourceBody):
|
|||
class ChallengeResource(Resource, jose.JSONObjectWithFields):
|
||||
"""Challenge Resource.
|
||||
|
||||
:ivar letsencrypt.acme.messages2.ChallengeBody body:
|
||||
:ivar acme.messages2.ChallengeBody body:
|
||||
:ivar str authzr_uri: URI found in the 'up' ``Link`` header.
|
||||
|
||||
"""
|
||||
|
|
@ -168,10 +173,10 @@ class ChallengeBody(ResourceBody):
|
|||
such as ``challb`` to distinguish instances of this class from
|
||||
``achall``.
|
||||
|
||||
:ivar letsencrypt.acme.challenges.Challenge: Wrapped challenge.
|
||||
:ivar acme.challenges.Challenge: Wrapped challenge.
|
||||
Conveniently, all challenge fields are proxied, i.e. you can
|
||||
call ``challb.x`` to get ``challb.chall.x`` contents.
|
||||
:ivar letsencrypt.acme.messages2.Status status:
|
||||
:ivar acme.messages2.Status status:
|
||||
:ivar datetime.datetime validated:
|
||||
|
||||
"""
|
||||
|
|
@ -198,7 +203,7 @@ class ChallengeBody(ResourceBody):
|
|||
class AuthorizationResource(Resource):
|
||||
"""Authorization Resource.
|
||||
|
||||
:ivar letsencrypt.acme.messages2.Authorization body:
|
||||
:ivar acme.messages2.Authorization body:
|
||||
:ivar str new_cert_uri: URI found in the 'next' ``Link`` header
|
||||
|
||||
"""
|
||||
|
|
@ -208,13 +213,13 @@ class AuthorizationResource(Resource):
|
|||
class Authorization(ResourceBody):
|
||||
"""Authorization Resource Body.
|
||||
|
||||
:ivar letsencrypt.acme.messages2.Identifier identifier:
|
||||
:ivar acme.messages2.Identifier identifier:
|
||||
:ivar list challenges: `list` of `.ChallengeBody`
|
||||
:ivar tuple combinations: Challenge combinations (`tuple` of `tuple`
|
||||
of `int`, as opposed to `list` of `list` from the spec).
|
||||
:ivar letsencrypt.acme.jose.jwk.JWK key: Public key.
|
||||
:ivar acme.jose.jwk.JWK key: Public key.
|
||||
:ivar tuple contact:
|
||||
:ivar letsencrypt.acme.messages2.Status status:
|
||||
:ivar acme.messages2.Status status:
|
||||
:ivar datetime.datetime expires:
|
||||
|
||||
"""
|
||||
|
|
@ -247,7 +252,7 @@ class Authorization(ResourceBody):
|
|||
class CertificateRequest(jose.JSONObjectWithFields):
|
||||
"""ACME new-cert request.
|
||||
|
||||
:ivar letsencrypt.acme.jose.util.ComparableX509 csr:
|
||||
:ivar acme.jose.util.ComparableX509 csr:
|
||||
`M2Crypto.X509.Request` wrapped in `.ComparableX509`
|
||||
:ivar tuple authorizations: `tuple` of URIs (`str`)
|
||||
|
||||
|
|
@ -259,7 +264,7 @@ class CertificateRequest(jose.JSONObjectWithFields):
|
|||
class CertificateResource(Resource):
|
||||
"""Certificate Resource.
|
||||
|
||||
:ivar letsencrypt.acme.jose.util.ComparableX509 body:
|
||||
:ivar acme.jose.util.ComparableX509 body:
|
||||
`M2Crypto.X509.X509` wrapped in `.ComparableX509`
|
||||
:ivar str cert_chain_uri: URI found in the 'up' ``Link`` header
|
||||
:ivar tuple authzrs: `tuple` of `AuthorizationResource`.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.messages2."""
|
||||
"""Tests for acme.messages2."""
|
||||
import datetime
|
||||
import os
|
||||
import pkg_resources
|
||||
|
|
@ -8,19 +8,19 @@ import mock
|
|||
import pytz
|
||||
from Crypto.PublicKey import RSA
|
||||
|
||||
from letsencrypt.acme import challenges
|
||||
from letsencrypt.acme import jose
|
||||
from acme import challenges
|
||||
from acme import jose
|
||||
|
||||
|
||||
KEY = jose.util.HashableRSAKey(RSA.importKey(pkg_resources.resource_string(
|
||||
'letsencrypt.acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
'acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
|
||||
|
||||
class ErrorTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages2.Error."""
|
||||
"""Tests for acme.messages2.Error."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages2 import Error
|
||||
from acme.messages2 import Error
|
||||
self.error = Error(detail='foo', typ='malformed')
|
||||
|
||||
def test_typ_prefix(self):
|
||||
|
|
@ -31,14 +31,14 @@ class ErrorTest(unittest.TestCase):
|
|||
'malformed', self.error.from_json(self.error.to_partial_json()).typ)
|
||||
|
||||
def test_typ_decoder_missing_prefix(self):
|
||||
from letsencrypt.acme.messages2 import Error
|
||||
from acme.messages2 import Error
|
||||
self.assertRaises(jose.DeserializationError, Error.from_json,
|
||||
{'detail': 'foo', 'type': 'malformed'})
|
||||
self.assertRaises(jose.DeserializationError, Error.from_json,
|
||||
{'detail': 'foo', 'type': 'not valid bare type'})
|
||||
|
||||
def test_typ_decoder_not_recognized(self):
|
||||
from letsencrypt.acme.messages2 import Error
|
||||
from acme.messages2 import Error
|
||||
self.assertRaises(jose.DeserializationError, Error.from_json,
|
||||
{'detail': 'foo', 'type': 'urn:acme:error:baz'})
|
||||
|
||||
|
|
@ -47,15 +47,21 @@ class ErrorTest(unittest.TestCase):
|
|||
'The request message was malformed', self.error.description)
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.messages2 import Error
|
||||
from acme.messages2 import Error
|
||||
hash(Error.from_json(self.error.to_json()))
|
||||
|
||||
def test_str(self):
|
||||
self.assertEqual(
|
||||
'malformed :: The request message was malformed :: foo',
|
||||
str(self.error))
|
||||
self.assertEqual('foo', str(self.error.update(typ=None)))
|
||||
|
||||
|
||||
class ConstantTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages2._Constant."""
|
||||
"""Tests for acme.messages2._Constant."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages2 import _Constant
|
||||
from acme.messages2 import _Constant
|
||||
class MockConstant(_Constant): # pylint: disable=missing-docstring
|
||||
POSSIBLE_NAMES = {}
|
||||
|
||||
|
|
@ -88,7 +94,7 @@ class ConstantTest(unittest.TestCase):
|
|||
self.assertFalse(self.const_a != const_a_prime)
|
||||
|
||||
class RegistrationTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages2.Registration."""
|
||||
"""Tests for acme.messages2.Registration."""
|
||||
|
||||
def setUp(self):
|
||||
key = jose.jwk.JWKRSA(key=KEY.publickey())
|
||||
|
|
@ -96,7 +102,7 @@ class RegistrationTest(unittest.TestCase):
|
|||
recovery_token = 'XYZ'
|
||||
agreement = 'https://letsencrypt.org/terms'
|
||||
|
||||
from letsencrypt.acme.messages2 import Registration
|
||||
from acme.messages2 import Registration
|
||||
self.reg = Registration(
|
||||
key=key, contact=contact, recovery_token=recovery_token,
|
||||
agreement=agreement)
|
||||
|
|
@ -114,31 +120,31 @@ class RegistrationTest(unittest.TestCase):
|
|||
self.assertEqual(self.jobj_to, self.reg.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages2 import Registration
|
||||
from acme.messages2 import Registration
|
||||
self.assertEqual(self.reg, Registration.from_json(self.jobj_from))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.messages2 import Registration
|
||||
from acme.messages2 import Registration
|
||||
hash(Registration.from_json(self.jobj_from))
|
||||
|
||||
|
||||
class ChallengeResourceTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages2.ChallengeResource."""
|
||||
"""Tests for acme.messages2.ChallengeResource."""
|
||||
|
||||
def test_uri(self):
|
||||
from letsencrypt.acme.messages2 import ChallengeResource
|
||||
from acme.messages2 import ChallengeResource
|
||||
self.assertEqual('http://challb', ChallengeResource(body=mock.MagicMock(
|
||||
uri='http://challb'), authzr_uri='http://authz').uri)
|
||||
|
||||
|
||||
class ChallengeBodyTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages2.ChallengeBody."""
|
||||
"""Tests for acme.messages2.ChallengeBody."""
|
||||
|
||||
def setUp(self):
|
||||
self.chall = challenges.DNS(token='foo')
|
||||
|
||||
from letsencrypt.acme.messages2 import ChallengeBody
|
||||
from letsencrypt.acme.messages2 import STATUS_VALID
|
||||
from acme.messages2 import ChallengeBody
|
||||
from acme.messages2 import STATUS_VALID
|
||||
self.status = STATUS_VALID
|
||||
self.challb = ChallengeBody(
|
||||
uri='http://challb', chall=self.chall, status=self.status)
|
||||
|
|
@ -156,20 +162,23 @@ class ChallengeBodyTest(unittest.TestCase):
|
|||
self.assertEqual(self.jobj_to, self.challb.to_partial_json())
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages2 import ChallengeBody
|
||||
from acme.messages2 import ChallengeBody
|
||||
self.assertEqual(self.challb, ChallengeBody.from_json(self.jobj_from))
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.messages2 import ChallengeBody
|
||||
from acme.messages2 import ChallengeBody
|
||||
hash(ChallengeBody.from_json(self.jobj_from))
|
||||
|
||||
def test_proxy(self):
|
||||
self.assertEqual('foo', self.challb.token)
|
||||
|
||||
|
||||
class AuthorizationTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages2.Authorization."""
|
||||
"""Tests for acme.messages2.Authorization."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages2 import ChallengeBody
|
||||
from letsencrypt.acme.messages2 import STATUS_VALID
|
||||
from acme.messages2 import ChallengeBody
|
||||
from acme.messages2 import STATUS_VALID
|
||||
self.challbs = (
|
||||
ChallengeBody(
|
||||
uri='http://challb1', status=STATUS_VALID,
|
||||
|
|
@ -181,9 +190,9 @@ class AuthorizationTest(unittest.TestCase):
|
|||
)
|
||||
combinations = ((0, 2), (1, 2))
|
||||
|
||||
from letsencrypt.acme.messages2 import Authorization
|
||||
from letsencrypt.acme.messages2 import Identifier
|
||||
from letsencrypt.acme.messages2 import IDENTIFIER_FQDN
|
||||
from acme.messages2 import Authorization
|
||||
from acme.messages2 import Identifier
|
||||
from acme.messages2 import IDENTIFIER_FQDN
|
||||
identifier = Identifier(typ=IDENTIFIER_FQDN, value='example.com')
|
||||
self.authz = Authorization(
|
||||
identifier=identifier, combinations=combinations,
|
||||
|
|
@ -196,11 +205,11 @@ class AuthorizationTest(unittest.TestCase):
|
|||
}
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages2 import Authorization
|
||||
from acme.messages2 import Authorization
|
||||
Authorization.from_json(self.jobj_from)
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.messages2 import Authorization
|
||||
from acme.messages2 import Authorization
|
||||
hash(Authorization.from_json(self.jobj_from))
|
||||
|
||||
def test_resolved_combinations(self):
|
||||
|
|
@ -211,10 +220,10 @@ class AuthorizationTest(unittest.TestCase):
|
|||
|
||||
|
||||
class RevocationTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages2.RevocationTest."""
|
||||
"""Tests for acme.messages2.RevocationTest."""
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages2 import Revocation
|
||||
from acme.messages2 import Revocation
|
||||
self.rev_now = Revocation(authorizations=(), revoke=Revocation.NOW)
|
||||
self.rev_date = Revocation(authorizations=(), revoke=datetime.datetime(
|
||||
2015, 3, 27, tzinfo=pytz.utc))
|
||||
|
|
@ -223,7 +232,7 @@ class RevocationTest(unittest.TestCase):
|
|||
'revoke': '2015-03-27T00:00:00Z'}
|
||||
|
||||
def test_revoke_decoder(self):
|
||||
from letsencrypt.acme.messages2 import Revocation
|
||||
from acme.messages2 import Revocation
|
||||
self.assertEqual(self.rev_now, Revocation.from_json(self.jobj_now))
|
||||
self.assertEqual(self.rev_date, Revocation.from_json(self.jobj_date))
|
||||
|
||||
|
|
@ -232,9 +241,9 @@ class RevocationTest(unittest.TestCase):
|
|||
self.assertEqual(self.jobj_date, self.rev_date.to_partial_json())
|
||||
|
||||
def test_from_json_hashable(self):
|
||||
from letsencrypt.acme.messages2 import Revocation
|
||||
from acme.messages2 import Revocation
|
||||
hash(Revocation.from_json(self.rev_now.to_json()))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
"""Tests for letsencrypt.acme.messages."""
|
||||
"""Tests for acme.messages."""
|
||||
import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
|
@ -6,32 +6,32 @@ import unittest
|
|||
import Crypto.PublicKey.RSA
|
||||
import M2Crypto
|
||||
|
||||
from letsencrypt.acme import challenges
|
||||
from letsencrypt.acme import errors
|
||||
from letsencrypt.acme import jose
|
||||
from letsencrypt.acme import other
|
||||
from acme import challenges
|
||||
from acme import errors
|
||||
from acme import jose
|
||||
from acme import other
|
||||
|
||||
|
||||
KEY = jose.HashableRSAKey(Crypto.PublicKey.RSA.importKey(
|
||||
pkg_resources.resource_string(
|
||||
'letsencrypt.acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
'acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
CERT = jose.ComparableX509(M2Crypto.X509.load_cert(
|
||||
pkg_resources.resource_filename(
|
||||
'letsencrypt.client.tests', os.path.join('testdata', 'cert.pem'))))
|
||||
'letsencrypt.tests', os.path.join('testdata', 'cert.pem'))))
|
||||
CSR = jose.ComparableX509(M2Crypto.X509.load_request(
|
||||
pkg_resources.resource_filename(
|
||||
'letsencrypt.client.tests', os.path.join('testdata', 'csr.pem'))))
|
||||
'letsencrypt.tests', os.path.join('testdata', 'csr.pem'))))
|
||||
CSR2 = jose.ComparableX509(M2Crypto.X509.load_request(
|
||||
pkg_resources.resource_filename(
|
||||
'letsencrypt.acme.jose', os.path.join('testdata', 'csr2.pem'))))
|
||||
'acme.jose', os.path.join('testdata', 'csr2.pem'))))
|
||||
|
||||
|
||||
class MessageTest(unittest.TestCase):
|
||||
"""Tests for letsencrypt.acme.messages.Message."""
|
||||
"""Tests for acme.messages.Message."""
|
||||
|
||||
def setUp(self):
|
||||
# pylint: disable=missing-docstring,too-few-public-methods
|
||||
from letsencrypt.acme.messages import Message
|
||||
from acme.messages import Message
|
||||
|
||||
class MockParentMessage(Message):
|
||||
# pylint: disable=abstract-method
|
||||
|
|
@ -69,7 +69,7 @@ class ChallengeTest(unittest.TestCase):
|
|||
)
|
||||
combinations = ((0, 2), (1, 2))
|
||||
|
||||
from letsencrypt.acme.messages import Challenge
|
||||
from acme.messages import Challenge
|
||||
self.msg = Challenge(
|
||||
session_id='aefoGaavieG9Wihuk2aufai3aeZ5EeW4',
|
||||
nonce='\xec\xd6\xf2oYH\xeb\x13\xd5#q\xe0\xdd\xa2\x92\xa9',
|
||||
|
|
@ -107,14 +107,14 @@ class ChallengeTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg_to)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import Challenge
|
||||
from acme.messages import Challenge
|
||||
self.assertEqual(Challenge.from_json(self.jmsg_from), self.msg)
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
del self.jmsg_from['combinations']
|
||||
del self.jmsg_to['combinations']
|
||||
|
||||
from letsencrypt.acme.messages import Challenge
|
||||
from acme.messages import Challenge
|
||||
msg = Challenge.from_json(self.jmsg_from)
|
||||
|
||||
self.assertEqual(msg.combinations, ())
|
||||
|
|
@ -124,7 +124,7 @@ class ChallengeTest(unittest.TestCase):
|
|||
class ChallengeRequestTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages import ChallengeRequest
|
||||
from acme.messages import ChallengeRequest
|
||||
self.msg = ChallengeRequest(identifier='example.com')
|
||||
|
||||
self.jmsg = {
|
||||
|
|
@ -136,7 +136,7 @@ class ChallengeRequestTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import ChallengeRequest
|
||||
from acme.messages import ChallengeRequest
|
||||
self.assertEqual(ChallengeRequest.from_json(self.jmsg), self.msg)
|
||||
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ class AuthorizationTest(unittest.TestCase):
|
|||
def setUp(self):
|
||||
jwk = jose.JWKRSA(key=KEY.publickey())
|
||||
|
||||
from letsencrypt.acme.messages import Authorization
|
||||
from acme.messages import Authorization
|
||||
self.msg = Authorization(recovery_token='tok', jwk=jwk,
|
||||
identifier='example.com')
|
||||
|
||||
|
|
@ -162,7 +162,7 @@ class AuthorizationTest(unittest.TestCase):
|
|||
def test_from_json(self):
|
||||
self.jmsg['jwk'] = self.jmsg['jwk'].to_partial_json()
|
||||
|
||||
from letsencrypt.acme.messages import Authorization
|
||||
from acme.messages import Authorization
|
||||
self.assertEqual(Authorization.from_json(self.jmsg), self.msg)
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
|
|
@ -170,7 +170,7 @@ class AuthorizationTest(unittest.TestCase):
|
|||
del self.jmsg['identifier']
|
||||
del self.jmsg['jwk']
|
||||
|
||||
from letsencrypt.acme.messages import Authorization
|
||||
from acme.messages import Authorization
|
||||
msg = Authorization.from_json(self.jmsg)
|
||||
|
||||
self.assertTrue(msg.recovery_token is None)
|
||||
|
|
@ -196,7 +196,7 @@ class AuthorizationRequestTest(unittest.TestCase):
|
|||
'\x92\xe9\x96\x11\xc2\xefx\x0bR',
|
||||
nonce='\xab?\x08o\xe6\x81$\x9f\xa1\xc9\x025\x1c\x1b\xa5+')
|
||||
|
||||
from letsencrypt.acme.messages import AuthorizationRequest
|
||||
from acme.messages import AuthorizationRequest
|
||||
self.msg = AuthorizationRequest(
|
||||
session_id='aefoGaavieG9Wihuk2aufai3aeZ5EeW4',
|
||||
nonce='\xec\xd6\xf2oYH\xeb\x13\xd5#q\xe0\xdd\xa2\x92\xa9',
|
||||
|
|
@ -226,7 +226,7 @@ class AuthorizationRequestTest(unittest.TestCase):
|
|||
}
|
||||
|
||||
def test_create(self):
|
||||
from letsencrypt.acme.messages import AuthorizationRequest
|
||||
from acme.messages import AuthorizationRequest
|
||||
self.assertEqual(self.msg, AuthorizationRequest.create(
|
||||
name='example.com', key=KEY, responses=self.responses,
|
||||
nonce='\xec\xd6\xf2oYH\xeb\x13\xd5#q\xe0\xdd\xa2\x92\xa9',
|
||||
|
|
@ -241,7 +241,7 @@ class AuthorizationRequestTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg_to)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import AuthorizationRequest
|
||||
from acme.messages import AuthorizationRequest
|
||||
self.assertEqual(
|
||||
self.msg, AuthorizationRequest.from_json(self.jmsg_from))
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ class AuthorizationRequestTest(unittest.TestCase):
|
|||
del self.jmsg_from['contact']
|
||||
del self.jmsg_to['contact']
|
||||
|
||||
from letsencrypt.acme.messages import AuthorizationRequest
|
||||
from acme.messages import AuthorizationRequest
|
||||
msg = AuthorizationRequest.from_json(self.jmsg_from)
|
||||
|
||||
self.assertEqual(msg.contact, ())
|
||||
|
|
@ -261,7 +261,7 @@ class CertificateTest(unittest.TestCase):
|
|||
def setUp(self):
|
||||
refresh = 'https://example.com/refresh/Dr8eAwTVQfSS/'
|
||||
|
||||
from letsencrypt.acme.messages import Certificate
|
||||
from acme.messages import Certificate
|
||||
self.msg = Certificate(
|
||||
certificate=CERT, chain=(CERT,), refresh=refresh)
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ class CertificateTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg_to)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import Certificate
|
||||
from acme.messages import Certificate
|
||||
self.assertEqual(Certificate.from_json(self.jmsg_from), self.msg)
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
|
|
@ -288,7 +288,7 @@ class CertificateTest(unittest.TestCase):
|
|||
del self.jmsg_to['chain']
|
||||
del self.jmsg_to['refresh']
|
||||
|
||||
from letsencrypt.acme.messages import Certificate
|
||||
from acme.messages import Certificate
|
||||
msg = Certificate.from_json(self.jmsg_from)
|
||||
|
||||
self.assertEqual(msg.chain, ())
|
||||
|
|
@ -307,7 +307,7 @@ class CertificateRequestTest(unittest.TestCase):
|
|||
'k\xfe\xee\xb4\xe4\xc8\x05\x9a\x08\xa7',
|
||||
nonce='\xec\xd6\xf2oYH\xeb\x13\xd5#q\xe0\xdd\xa2\x92\xa9')
|
||||
|
||||
from letsencrypt.acme.messages import CertificateRequest
|
||||
from acme.messages import CertificateRequest
|
||||
self.msg = CertificateRequest(csr=CSR, signature=signature)
|
||||
|
||||
self.jmsg_to = {
|
||||
|
|
@ -319,7 +319,7 @@ class CertificateRequestTest(unittest.TestCase):
|
|||
self.jmsg_from['signature'] = self.jmsg_from['signature'].to_json()
|
||||
|
||||
def test_create(self):
|
||||
from letsencrypt.acme.messages import CertificateRequest
|
||||
from acme.messages import CertificateRequest
|
||||
self.assertEqual(self.msg, CertificateRequest.create(
|
||||
csr=CSR, key=KEY,
|
||||
sig_nonce='\xec\xd6\xf2oYH\xeb\x13\xd5#q\xe0\xdd\xa2\x92\xa9'))
|
||||
|
|
@ -331,14 +331,14 @@ class CertificateRequestTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg_to)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import CertificateRequest
|
||||
from acme.messages import CertificateRequest
|
||||
self.assertEqual(self.msg, CertificateRequest.from_json(self.jmsg_from))
|
||||
|
||||
|
||||
class DeferTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages import Defer
|
||||
from acme.messages import Defer
|
||||
self.msg = Defer(
|
||||
token='O7-s9MNq1siZHlgrMzi9_A', interval=60,
|
||||
message='Warming up the HSM')
|
||||
|
|
@ -354,14 +354,14 @@ class DeferTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import Defer
|
||||
from acme.messages import Defer
|
||||
self.assertEqual(Defer.from_json(self.jmsg), self.msg)
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
del self.jmsg['interval']
|
||||
del self.jmsg['message']
|
||||
|
||||
from letsencrypt.acme.messages import Defer
|
||||
from acme.messages import Defer
|
||||
msg = Defer.from_json(self.jmsg)
|
||||
|
||||
self.assertTrue(msg.interval is None)
|
||||
|
|
@ -372,7 +372,7 @@ class DeferTest(unittest.TestCase):
|
|||
class ErrorTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages import Error
|
||||
from acme.messages import Error
|
||||
self.msg = Error(
|
||||
error='badCSR', message='RSA keys must be at least 2048 bits long',
|
||||
more_info='https://ca.example.com/documentation/csr-requirements')
|
||||
|
|
@ -388,14 +388,14 @@ class ErrorTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import Error
|
||||
from acme.messages import Error
|
||||
self.assertEqual(Error.from_json(self.jmsg), self.msg)
|
||||
|
||||
def test_json_without_optionals(self):
|
||||
del self.jmsg['message']
|
||||
del self.jmsg['moreInfo']
|
||||
|
||||
from letsencrypt.acme.messages import Error
|
||||
from acme.messages import Error
|
||||
msg = Error.from_json(self.jmsg)
|
||||
|
||||
self.assertTrue(msg.message is None)
|
||||
|
|
@ -406,7 +406,7 @@ class ErrorTest(unittest.TestCase):
|
|||
class RevocationTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages import Revocation
|
||||
from acme.messages import Revocation
|
||||
self.msg = Revocation()
|
||||
self.jmsg = {'type': 'revocation'}
|
||||
|
||||
|
|
@ -414,7 +414,7 @@ class RevocationTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import Revocation
|
||||
from acme.messages import Revocation
|
||||
self.assertEqual(Revocation.from_json(self.jmsg), self.msg)
|
||||
|
||||
|
||||
|
|
@ -431,7 +431,7 @@ class RevocationRequestTest(unittest.TestCase):
|
|||
's\xd9\xd0\xe7',
|
||||
nonce=self.sig_nonce)
|
||||
|
||||
from letsencrypt.acme.messages import RevocationRequest
|
||||
from acme.messages import RevocationRequest
|
||||
self.msg = RevocationRequest(certificate=CERT, signature=signature)
|
||||
|
||||
self.jmsg_to = {
|
||||
|
|
@ -443,7 +443,7 @@ class RevocationRequestTest(unittest.TestCase):
|
|||
self.jmsg_from['signature'] = self.jmsg_from['signature'].to_json()
|
||||
|
||||
def test_create(self):
|
||||
from letsencrypt.acme.messages import RevocationRequest
|
||||
from acme.messages import RevocationRequest
|
||||
self.assertEqual(self.msg, RevocationRequest.create(
|
||||
certificate=CERT, key=KEY, sig_nonce=self.sig_nonce))
|
||||
|
||||
|
|
@ -454,14 +454,14 @@ class RevocationRequestTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg_to)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import RevocationRequest
|
||||
from acme.messages import RevocationRequest
|
||||
self.assertEqual(self.msg, RevocationRequest.from_json(self.jmsg_from))
|
||||
|
||||
|
||||
class StatusRequestTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
from letsencrypt.acme.messages import StatusRequest
|
||||
from acme.messages import StatusRequest
|
||||
self.msg = StatusRequest(token=u'O7-s9MNq1siZHlgrMzi9_A')
|
||||
self.jmsg = {
|
||||
'type': 'statusRequest',
|
||||
|
|
@ -472,9 +472,9 @@ class StatusRequestTest(unittest.TestCase):
|
|||
self.assertEqual(self.msg.to_partial_json(), self.jmsg)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.messages import StatusRequest
|
||||
from acme.messages import StatusRequest
|
||||
self.assertEqual(StatusRequest.from_json(self.jmsg), self.msg)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -5,7 +5,7 @@ import logging
|
|||
import Crypto.Random
|
||||
import Crypto.PublicKey.RSA
|
||||
|
||||
from letsencrypt.acme import jose
|
||||
from acme import jose
|
||||
|
||||
|
||||
class Signature(jose.JSONObjectWithFields):
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
"""Tests for letsencrypt.acme.sig."""
|
||||
"""Tests for acme.sig."""
|
||||
import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
||||
import Crypto.PublicKey.RSA
|
||||
|
||||
from letsencrypt.acme import jose
|
||||
from acme import jose
|
||||
|
||||
|
||||
KEY = jose.HashableRSAKey(Crypto.PublicKey.RSA.importKey(
|
||||
pkg_resources.resource_string(
|
||||
'letsencrypt.acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
'acme.jose', os.path.join('testdata', 'rsa512_key.pem'))))
|
||||
|
||||
|
||||
class SignatureTest(unittest.TestCase):
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
"""Tests for letsencrypt.acme.sig.Signature."""
|
||||
"""Tests for acme.sig.Signature."""
|
||||
|
||||
def setUp(self):
|
||||
self.msg = 'message'
|
||||
|
|
@ -45,7 +45,7 @@ class SignatureTest(unittest.TestCase):
|
|||
'sig': b64sig,
|
||||
}
|
||||
|
||||
from letsencrypt.acme.other import Signature
|
||||
from acme.other import Signature
|
||||
self.signature = Signature(
|
||||
alg=self.alg, sig=self.sig, nonce=self.nonce, jwk=self.jwk)
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ class SignatureTest(unittest.TestCase):
|
|||
|
||||
@classmethod
|
||||
def _from_msg(cls, *args, **kwargs):
|
||||
from letsencrypt.acme.other import Signature
|
||||
from acme.other import Signature
|
||||
return Signature.from_msg(*args, **kwargs)
|
||||
|
||||
def test_create_from_msg(self):
|
||||
|
|
@ -80,12 +80,12 @@ class SignatureTest(unittest.TestCase):
|
|||
self.assertEqual(self.signature.to_partial_json(), self.jsig_to)
|
||||
|
||||
def test_from_json(self):
|
||||
from letsencrypt.acme.other import Signature
|
||||
from acme.other import Signature
|
||||
self.assertEqual(
|
||||
self.signature, Signature.from_json(self.jsig_from))
|
||||
|
||||
def test_from_json_non_schema_errors(self):
|
||||
from letsencrypt.acme.other import Signature
|
||||
from acme.other import Signature
|
||||
jwk = self.jwk.to_partial_json()
|
||||
self.assertRaises(
|
||||
jose.DeserializationError, Signature.from_json, {
|
||||
|
|
@ -96,4 +96,4 @@ class SignatureTest(unittest.TestCase):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main() # pragma: no cover
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
"type": "string"
|
||||
},
|
||||
"jwk": {
|
||||
"$ref": "file:letsencrypt/acme/schemata/jwk.json"
|
||||
"$ref": "file:acme/schemata/jwk.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,14 +15,14 @@
|
|||
"type": "string"
|
||||
},
|
||||
"signature" : {
|
||||
"$ref": "file:letsencrypt/acme/schemata/signature.json"
|
||||
"$ref": "file:acme/schemata/signature.json"
|
||||
},
|
||||
"responses": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{ "$ref": "file:letsencrypt/acme/schemata/responseobject.json" },
|
||||
{ "$ref": "file:acme/schemata/responseobject.json" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
"pattern": "^[-_=0-9A-Za-z]+$"
|
||||
},
|
||||
"signature" : {
|
||||
"$ref": "file:letsencrypt/acme/schemata/signature.json"
|
||||
"$ref": "file:acme/schemata/signature.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "file:letsencrypt/acme/schemata/challengeobject.json"
|
||||
"$ref": "file:acme/schemata/challengeobject.json"
|
||||
}
|
||||
},
|
||||
"combinations": {
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
"pattern": "^[-_=0-9A-Za-z]+$"
|
||||
},
|
||||
"signature": {
|
||||
"$ref": "file:letsencrypt/acme/schemata/signature.json"
|
||||
"$ref": "file:acme/schemata/signature.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
"type" : "string"
|
||||
},
|
||||
"signature" : {
|
||||
"$ref": "file:letsencrypt/acme/schemata/signature.json"
|
||||
"$ref": "file:acme/schemata/signature.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
5
docs/api/account.rst
Normal file
5
docs/api/account.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.account`
|
||||
--------------------------
|
||||
|
||||
.. automodule:: letsencrypt.account
|
||||
:members:
|
||||
5
docs/api/achallenges.rst
Normal file
5
docs/api/achallenges.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.achallenges`
|
||||
------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.achallenges
|
||||
:members:
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
:mod:`letsencrypt.acme`
|
||||
=======================
|
||||
|
||||
.. contents::
|
||||
|
||||
.. automodule:: letsencrypt.acme
|
||||
:members:
|
||||
|
||||
|
||||
Messages
|
||||
--------
|
||||
|
||||
v00
|
||||
~~~
|
||||
|
||||
.. automodule:: letsencrypt.acme.messages
|
||||
:members:
|
||||
|
||||
v02
|
||||
~~~
|
||||
|
||||
.. automodule:: letsencrypt.acme.messages2
|
||||
:members:
|
||||
|
||||
|
||||
Challenges
|
||||
----------
|
||||
|
||||
.. automodule:: letsencrypt.acme.challenges
|
||||
:members:
|
||||
|
||||
|
||||
Other ACME objects
|
||||
------------------
|
||||
|
||||
.. automodule:: letsencrypt.acme.other
|
||||
:members:
|
||||
|
||||
|
||||
Fields
|
||||
------
|
||||
|
||||
.. automodule:: letsencrypt.acme.fields
|
||||
:members:
|
||||
|
||||
|
||||
Errors
|
||||
------
|
||||
|
||||
.. automodule:: letsencrypt.acme.errors
|
||||
:members:
|
||||
|
||||
|
||||
:members:
|
||||
|
||||
|
||||
Utilities
|
||||
---------
|
||||
|
||||
.. automodule:: letsencrypt.acme.util
|
||||
:members:
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
:mod:`letsencrypt.acme.jose`
|
||||
============================
|
||||
|
||||
.. contents::
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose
|
||||
:members:
|
||||
|
||||
|
||||
JSON Web Algorithms
|
||||
-------------------
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.jwa
|
||||
:members:
|
||||
|
||||
|
||||
JSON Web Key
|
||||
------------
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.jwk
|
||||
:members:
|
||||
|
||||
|
||||
JSON Web Signature
|
||||
------------------
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.jws
|
||||
:members:
|
||||
|
||||
|
||||
Implementation details
|
||||
----------------------
|
||||
|
||||
|
||||
Interfaces
|
||||
~~~~~~~~~~
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.interfaces
|
||||
:members:
|
||||
|
||||
|
||||
Errors
|
||||
~~~~~~
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.errors
|
||||
:members:
|
||||
|
||||
|
||||
JSON utilities
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.json_util
|
||||
:members:
|
||||
|
||||
|
||||
JOSE Base64
|
||||
~~~~~~~~~~~
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.b64
|
||||
:members:
|
||||
|
||||
|
||||
Utilities
|
||||
~~~~~~~~~
|
||||
|
||||
.. automodule:: letsencrypt.acme.jose.util
|
||||
:members:
|
||||
5
docs/api/augeas_configurator.rst
Normal file
5
docs/api/augeas_configurator.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.augeas_configurator`
|
||||
--------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.augeas_configurator
|
||||
:members:
|
||||
5
docs/api/auth_handler.rst
Normal file
5
docs/api/auth_handler.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.auth_handler`
|
||||
-------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.auth_handler
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.account`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.account
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.achallenges`
|
||||
-------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.achallenges
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.augeas_configurator`
|
||||
---------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.augeas_configurator
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.auth_handler`
|
||||
--------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.auth_handler
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.client`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.client
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.configuration`
|
||||
---------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.configuration
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.constants`
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.constants
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.continuity_auth`
|
||||
-----------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.continuity_auth
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.crypto_util`
|
||||
-------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.crypto_util
|
||||
:members:
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
:mod:`letsencrypt.client.display`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.display
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.display.util`
|
||||
======================================
|
||||
|
||||
.. automodule:: letsencrypt.client.display.util
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.display.ops`
|
||||
=====================================
|
||||
|
||||
.. automodule:: letsencrypt.client.display.ops
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.display.enhancements`
|
||||
==============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.display.enhancements
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.display.revocation`
|
||||
============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.display.revocation
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.errors`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.errors
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.interfaces`
|
||||
------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.interfaces
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.le_util`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.le_util
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.log`
|
||||
-----------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.log
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.network`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.network
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.network2`
|
||||
----------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.network2
|
||||
:members:
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
:mod:`letsencrypt.client.plugins.apache`
|
||||
----------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.apache
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.apache.configurator`
|
||||
=====================================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.apache.configurator
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.apache.dvsni`
|
||||
==============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.apache.dvsni
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.apache.obj`
|
||||
============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.apache.obj
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.apache.parser`
|
||||
===============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.apache.parser
|
||||
:members:
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
:mod:`letsencrypt.client.plugins.nginx`
|
||||
----------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.nginx
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.nginx.configurator`
|
||||
=====================================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.nginx.configurator
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.nginx.dvsni`
|
||||
==============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.nginx.dvsni
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.nginx.obj`
|
||||
============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.nginx.obj
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.nginx.parser`
|
||||
===============================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.nginx.parser
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.nginx.nginxparser`
|
||||
====================================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.nginx.nginxparser
|
||||
:members:
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
:mod:`letsencrypt.client.plugins.standalone`
|
||||
--------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.standalone
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.client.plugins.standalone.authenticator`
|
||||
==========================================================
|
||||
|
||||
.. automodule:: letsencrypt.client.plugins.standalone.authenticator
|
||||
:members:
|
||||
5
docs/api/client/proof_of_possession.rst
Normal file
5
docs/api/client/proof_of_possession.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.client.proof_of_possession`
|
||||
--------------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.proof_of_possession
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.recovery_token`
|
||||
--------------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.recovery_token
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.reverter`
|
||||
----------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.reverter
|
||||
:members:
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
:mod:`letsencrypt.client.revoker`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.client.revoker
|
||||
:members:
|
||||
5
docs/api/configuration.rst
Normal file
5
docs/api/configuration.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.configuration`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.configuration
|
||||
:members:
|
||||
5
docs/api/constants.rst
Normal file
5
docs/api/constants.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.constants`
|
||||
-----------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.constants
|
||||
:members:
|
||||
5
docs/api/continuity_auth.rst
Normal file
5
docs/api/continuity_auth.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.continuity_auth`
|
||||
----------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.continuity_auth
|
||||
:members:
|
||||
5
docs/api/crypto_util.rst
Normal file
5
docs/api/crypto_util.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.crypto_util`
|
||||
------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.crypto_util
|
||||
:members:
|
||||
29
docs/api/display.rst
Normal file
29
docs/api/display.rst
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
:mod:`letsencrypt.display`
|
||||
--------------------------
|
||||
|
||||
.. automodule:: letsencrypt.display
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.display.util`
|
||||
===============================
|
||||
|
||||
.. automodule:: letsencrypt.display.util
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.display.ops`
|
||||
==============================
|
||||
|
||||
.. automodule:: letsencrypt.display.ops
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.display.enhancements`
|
||||
=======================================
|
||||
|
||||
.. automodule:: letsencrypt.display.enhancements
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.display.revocation`
|
||||
=====================================
|
||||
|
||||
.. automodule:: letsencrypt.display.revocation
|
||||
:members:
|
||||
5
docs/api/errors.rst
Normal file
5
docs/api/errors.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.errors`
|
||||
-------------------------
|
||||
|
||||
.. automodule:: letsencrypt.errors
|
||||
:members:
|
||||
5
docs/api/index.rst
Normal file
5
docs/api/index.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt`
|
||||
------------------
|
||||
|
||||
.. automodule:: letsencrypt
|
||||
:members:
|
||||
5
docs/api/interfaces.rst
Normal file
5
docs/api/interfaces.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.interfaces`
|
||||
-----------------------------
|
||||
|
||||
.. automodule:: letsencrypt.interfaces
|
||||
:members:
|
||||
5
docs/api/le_util.rst
Normal file
5
docs/api/le_util.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.le_util`
|
||||
--------------------------
|
||||
|
||||
.. automodule:: letsencrypt.le_util
|
||||
:members:
|
||||
5
docs/api/log.rst
Normal file
5
docs/api/log.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.log`
|
||||
----------------------
|
||||
|
||||
.. automodule:: letsencrypt.log
|
||||
:members:
|
||||
5
docs/api/network.rst
Normal file
5
docs/api/network.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.network`
|
||||
--------------------------
|
||||
|
||||
.. automodule:: letsencrypt.network
|
||||
:members:
|
||||
5
docs/api/network2.rst
Normal file
5
docs/api/network2.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.network2`
|
||||
---------------------------
|
||||
|
||||
.. automodule:: letsencrypt.network2
|
||||
:members:
|
||||
5
docs/api/plugins/common.rst
Normal file
5
docs/api/plugins/common.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.plugins.common`
|
||||
---------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.plugins.common
|
||||
:members:
|
||||
5
docs/api/plugins/disco.rst
Normal file
5
docs/api/plugins/disco.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.plugins.disco`
|
||||
--------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.plugins.disco
|
||||
:members:
|
||||
11
docs/api/plugins/standalone.rst
Normal file
11
docs/api/plugins/standalone.rst
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
:mod:`letsencrypt.plugins.standalone`
|
||||
-------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.plugins.standalone
|
||||
:members:
|
||||
|
||||
:mod:`letsencrypt.plugins.standalone.authenticator`
|
||||
===================================================
|
||||
|
||||
.. automodule:: letsencrypt.plugins.standalone.authenticator
|
||||
:members:
|
||||
5
docs/api/recovery_token.rst
Normal file
5
docs/api/recovery_token.rst
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
:mod:`letsencrypt.recovery_token`
|
||||
--------------------------------------------------
|
||||
|
||||
.. automodule:: letsencrypt.recovery_token
|
||||
:members:
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue