mirror of
https://github.com/certbot/certbot.git
synced 2026-08-01 19:02:52 +02:00
acme: M2Crypto -> pyOpenSSL
This commit is contained in:
@@ -5,8 +5,8 @@ import unittest
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
import M2Crypto
|
||||
import mock
|
||||
import OpenSSL
|
||||
import requests
|
||||
import urlparse
|
||||
|
||||
@@ -14,8 +14,8 @@ from acme import jose
|
||||
from acme import other
|
||||
|
||||
|
||||
CERT = jose.ComparableX509(M2Crypto.X509.load_cert(
|
||||
pkg_resources.resource_filename(
|
||||
CERT = jose.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, pkg_resources.resource_string(
|
||||
'letsencrypt.tests', os.path.join('testdata', 'cert.pem'))))
|
||||
KEY = jose.ComparableRSAKey(serialization.load_pem_private_key(
|
||||
pkg_resources.resource_string(
|
||||
@@ -370,7 +370,8 @@ class ProofOfPossessionHintsTest(unittest.TestCase):
|
||||
self.jmsg_to = {
|
||||
'jwk': jwk,
|
||||
'certFingerprints': cert_fingerprints,
|
||||
'certs': (jose.b64encode(CERT.as_der()),),
|
||||
'certs': (jose.b64encode(OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, CERT)),),
|
||||
'subjectKeyIdentifiers': subject_key_identifiers,
|
||||
'serialNumbers': serial_numbers,
|
||||
'issuers': issuers,
|
||||
|
||||
+9
-9
@@ -5,7 +5,7 @@ import httplib
|
||||
import logging
|
||||
import time
|
||||
|
||||
import M2Crypto
|
||||
import OpenSSL
|
||||
import requests
|
||||
import werkzeug
|
||||
|
||||
@@ -256,7 +256,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes
|
||||
"""Request issuance.
|
||||
|
||||
:param csr: CSR
|
||||
:type csr: `M2Crypto.X509.Request` wrapped in `.ComparableX509`
|
||||
:type csr: `OpenSSL.crypto.X509Req` wrapped in `.ComparableX509`
|
||||
|
||||
:param authzrs: `list` of `.AuthorizationResource`
|
||||
|
||||
@@ -287,8 +287,8 @@ class Client(object): # pylint: disable=too-many-instance-attributes
|
||||
|
||||
return messages.CertificateResource(
|
||||
uri=uri, authzrs=authzrs, cert_chain_uri=cert_chain_uri,
|
||||
body=jose.ComparableX509(
|
||||
M2Crypto.X509.load_cert_der_string(response.content)))
|
||||
body=jose.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, response.content)))
|
||||
|
||||
def poll_and_request_issuance(self, csr, authzrs, mintime=5):
|
||||
"""Poll and request issuance.
|
||||
@@ -300,7 +300,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes
|
||||
.. todo:: add `max_attempts` or `timeout`
|
||||
|
||||
:param csr: CSR.
|
||||
:type csr: `M2Crypto.X509.Request` wrapped in `.ComparableX509`
|
||||
:type csr: `OpenSSL.crypto.X509Req` wrapped in `.ComparableX509`
|
||||
|
||||
:param authzrs: `list` of `.AuthorizationResource`
|
||||
|
||||
@@ -359,8 +359,8 @@ class Client(object): # pylint: disable=too-many-instance-attributes
|
||||
content_type = self.DER_CONTENT_TYPE # TODO: make it a param
|
||||
response = self.net.get(uri, headers={'Accept': content_type},
|
||||
content_type=content_type)
|
||||
return response, jose.ComparableX509(
|
||||
M2Crypto.X509.load_cert_der_string(response.content))
|
||||
return response, jose.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, response.content))
|
||||
|
||||
def check_cert(self, certr):
|
||||
"""Check for new cert.
|
||||
@@ -403,7 +403,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes
|
||||
:type certr: `.CertificateResource`
|
||||
|
||||
:returns: Certificate chain, or `None` if no "up" Link was provided.
|
||||
:rtype: `M2Crypto.X509.X509` wrapped in `.ComparableX509`
|
||||
:rtype: `OpenSSL.crypto.X509` wrapped in `.ComparableX509`
|
||||
|
||||
"""
|
||||
if certr.cert_chain_uri is not None:
|
||||
@@ -414,7 +414,7 @@ class Client(object): # pylint: disable=too-many-instance-attributes
|
||||
def revoke(self, cert):
|
||||
"""Revoke certificate.
|
||||
|
||||
:param .ComparableX509 cert: `M2Crypto.X509.X509` wrapped in
|
||||
:param .ComparableX509 cert: `OpenSSL.crypto.X509` wrapped in
|
||||
`.ComparableX509`
|
||||
|
||||
:raises .ClientError: If revocation is unsuccessful.
|
||||
|
||||
+6
-4
@@ -16,6 +16,8 @@ from acme import messages
|
||||
from acme import messages_test
|
||||
|
||||
|
||||
CERT_DER = pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'cert.der'))
|
||||
KEY = jose.JWKRSA.load(pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'rsa512_key.pem')))
|
||||
KEY2 = jose.JWKRSA.load(pkg_resources.resource_string(
|
||||
@@ -204,7 +206,7 @@ class ClientTest(unittest.TestCase):
|
||||
errors.UnexpectedUpdate, self.client.poll, self.authzr)
|
||||
|
||||
def test_request_issuance(self):
|
||||
self.response.content = messages_test.CERT.as_der()
|
||||
self.response.content = CERT_DER
|
||||
self.response.headers['Location'] = self.certr.uri
|
||||
self.response.links['up'] = {'url': self.certr.cert_chain_uri}
|
||||
self.assertEqual(self.certr, self.client.request_issuance(
|
||||
@@ -212,7 +214,7 @@ class ClientTest(unittest.TestCase):
|
||||
# TODO: check POST args
|
||||
|
||||
def test_request_issuance_missing_up(self):
|
||||
self.response.content = messages_test.CERT.as_der()
|
||||
self.response.content = CERT_DER
|
||||
self.response.headers['Location'] = self.certr.uri
|
||||
self.assertEqual(
|
||||
self.certr.update(cert_chain_uri=None),
|
||||
@@ -306,7 +308,7 @@ class ClientTest(unittest.TestCase):
|
||||
|
||||
def test_check_cert(self):
|
||||
self.response.headers['Location'] = self.certr.uri
|
||||
self.response.content = messages_test.CERT.as_der()
|
||||
self.response.content = CERT_DER
|
||||
self.assertEqual(self.certr.update(body=messages_test.CERT),
|
||||
self.client.check_cert(self.certr))
|
||||
|
||||
@@ -316,7 +318,7 @@ class ClientTest(unittest.TestCase):
|
||||
errors.UnexpectedUpdate, self.client.check_cert, self.certr)
|
||||
|
||||
def test_check_cert_missing_location(self):
|
||||
self.response.content = messages_test.CERT.as_der()
|
||||
self.response.content = CERT_DER
|
||||
self.assertRaises(
|
||||
errors.ClientError, self.client.check_cert, self.certr)
|
||||
|
||||
|
||||
+11
-9
@@ -10,7 +10,7 @@ import abc
|
||||
import binascii
|
||||
import logging
|
||||
|
||||
import M2Crypto
|
||||
import OpenSSL
|
||||
|
||||
from acme.jose import b64
|
||||
from acme.jose import errors
|
||||
@@ -321,26 +321,28 @@ def encode_cert(cert):
|
||||
:type cert: :class:`acme.jose.util.ComparableX509`
|
||||
|
||||
"""
|
||||
return b64.b64encode(cert.as_der())
|
||||
return b64.b64encode(OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, cert))
|
||||
|
||||
def decode_cert(b64der):
|
||||
"""Decode JOSE Base-64 DER-encoded certificate."""
|
||||
try:
|
||||
return util.ComparableX509(M2Crypto.X509.load_cert_der_string(
|
||||
decode_b64jose(b64der)))
|
||||
except M2Crypto.X509.X509Error as error:
|
||||
return util.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, decode_b64jose(b64der)))
|
||||
except OpenSSL.crypto.Error as error:
|
||||
raise errors.DeserializationError(error)
|
||||
|
||||
def encode_csr(csr):
|
||||
"""Encode CSR as JOSE Base-64 DER."""
|
||||
return encode_cert(csr)
|
||||
return b64.b64encode(OpenSSL.crypto.dump_certificate_request(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, csr))
|
||||
|
||||
def decode_csr(b64der):
|
||||
"""Decode JOSE Base-64 DER-encoded CSR."""
|
||||
try:
|
||||
return util.ComparableX509(M2Crypto.X509.load_request_der_string(
|
||||
decode_b64jose(b64der)))
|
||||
except M2Crypto.X509.X509Error as error:
|
||||
return util.ComparableX509(OpenSSL.crypto.load_certificate_request(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, decode_b64jose(b64der)))
|
||||
except OpenSSL.crypto.Error as error:
|
||||
raise errors.DeserializationError(error)
|
||||
|
||||
|
||||
|
||||
@@ -4,18 +4,20 @@ import os
|
||||
import pkg_resources
|
||||
import unittest
|
||||
|
||||
import M2Crypto
|
||||
import mock
|
||||
import OpenSSL
|
||||
|
||||
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.tests', os.path.join('testdata', 'cert.pem')))
|
||||
CSR = M2Crypto.X509.load_request(pkg_resources.resource_filename(
|
||||
'letsencrypt.tests', os.path.join('testdata', 'csr.pem')))
|
||||
CERT = OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, pkg_resources.resource_string(
|
||||
'letsencrypt.tests', os.path.join('testdata', 'cert.pem')))
|
||||
CSR = OpenSSL.crypto.load_certificate_request(
|
||||
OpenSSL.crypto.FILETYPE_PEM, pkg_resources.resource_string(
|
||||
'letsencrypt.tests', os.path.join('testdata', 'csr.pem')))
|
||||
|
||||
|
||||
class FieldTest(unittest.TestCase):
|
||||
@@ -280,7 +282,7 @@ class DeEncodersTest(unittest.TestCase):
|
||||
|
||||
def test_encode_csr(self):
|
||||
from acme.jose.json_util import encode_csr
|
||||
self.assertEqual(self.b64_cert, encode_csr(CERT))
|
||||
self.assertEqual(self.b64_csr, encode_csr(CSR))
|
||||
|
||||
def test_decode_csr(self):
|
||||
from acme.jose.json_util import decode_csr
|
||||
|
||||
+6
-4
@@ -3,7 +3,7 @@ import argparse
|
||||
import base64
|
||||
import sys
|
||||
|
||||
import M2Crypto
|
||||
import OpenSSL
|
||||
|
||||
from acme.jose import b64
|
||||
from acme.jose import errors
|
||||
@@ -122,14 +122,16 @@ class Header(json_util.JSONObjectWithFields):
|
||||
|
||||
@x5c.encoder
|
||||
def x5c(value): # pylint: disable=missing-docstring,no-self-argument
|
||||
return [base64.b64encode(cert.as_der()) for cert in value]
|
||||
return [base64.b64encode(OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, cert)) for cert in value]
|
||||
|
||||
@x5c.decoder
|
||||
def x5c(value): # pylint: disable=missing-docstring,no-self-argument
|
||||
try:
|
||||
return tuple(util.ComparableX509(M2Crypto.X509.load_cert_der_string(
|
||||
return tuple(util.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1,
|
||||
base64.b64decode(cert))) for cert in value)
|
||||
except M2Crypto.X509.X509Error as error:
|
||||
except OpenSSL.crypto.Error as error:
|
||||
raise errors.DeserializationError(error)
|
||||
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@ import unittest
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
import M2Crypto
|
||||
import mock
|
||||
import OpenSSL
|
||||
|
||||
from acme.jose import b64
|
||||
from acme.jose import errors
|
||||
@@ -16,8 +16,8 @@ from acme.jose import jwk
|
||||
from acme.jose import util
|
||||
|
||||
|
||||
CERT = util.ComparableX509(M2Crypto.X509.load_cert(
|
||||
pkg_resources.resource_filename(
|
||||
CERT = util.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_PEM, pkg_resources.resource_string(
|
||||
'letsencrypt.tests', 'testdata/cert.pem')))
|
||||
RSA512_KEY = util.ComparableRSAKey(serialization.load_pem_private_key(
|
||||
pkg_resources.resource_string(
|
||||
@@ -76,10 +76,13 @@ class HeaderTest(unittest.TestCase):
|
||||
from acme.jose.jws import Header
|
||||
header = Header(x5c=(CERT, CERT))
|
||||
jobj = header.to_partial_json()
|
||||
cert_b64 = base64.b64encode(CERT.as_der())
|
||||
cert_b64 = base64.b64encode(OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, CERT))
|
||||
self.assertEqual(jobj, {'x5c': [cert_b64, cert_b64]})
|
||||
self.assertEqual(header, Header.from_json(jobj))
|
||||
jobj['x5c'][0] = base64.b64encode('xxx' + CERT.as_der())
|
||||
jobj['x5c'][0] = base64.b64encode(
|
||||
'xxx' + OpenSSL.crypto.dump_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, CERT))
|
||||
self.assertRaises(errors.DeserializationError, Header.from_json, jobj)
|
||||
|
||||
def test_find_key(self):
|
||||
|
||||
+21
-4
@@ -2,6 +2,7 @@
|
||||
import collections
|
||||
|
||||
from cryptography.hazmat.primitives.asymmetric import rsa
|
||||
import OpenSSL
|
||||
|
||||
|
||||
class abstractclassmethod(classmethod):
|
||||
@@ -25,12 +26,12 @@ class abstractclassmethod(classmethod):
|
||||
|
||||
|
||||
class ComparableX509(object): # pylint: disable=too-few-public-methods
|
||||
"""Wrapper for M2Crypto.X509.* objects that supports __eq__.
|
||||
"""Wrapper for OpenSSL.crypto.X509** objects that supports __eq__.
|
||||
|
||||
Wraps around:
|
||||
|
||||
- :class:`M2Crypto.X509.X509`
|
||||
- :class:`M2Crypto.X509.Request`
|
||||
- :class:`OpenSSL.crypto.X509`
|
||||
- :class:`OpenSSL.crypto.X509Req`
|
||||
|
||||
"""
|
||||
def __init__(self, wrapped):
|
||||
@@ -40,7 +41,23 @@ class ComparableX509(object): # pylint: disable=too-few-public-methods
|
||||
return getattr(self._wrapped, name)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.as_der() == other.as_der()
|
||||
filetype = OpenSSL.crypto.FILETYPE_ASN1
|
||||
def as_der(obj):
|
||||
# pylint: disable=missing-docstring,protected-access
|
||||
if isinstance(obj, type(self)):
|
||||
obj = obj._wrapped
|
||||
if isinstance(obj, OpenSSL.crypto.X509):
|
||||
func = OpenSSL.crypto.dump_certificate
|
||||
elif isinstance(obj, OpenSSL.crypto.X509Req):
|
||||
func = OpenSSL.crypto.dump_certificate_request
|
||||
else:
|
||||
raise TypeError(
|
||||
"Equality for {0} not provided".format(obj.__class__))
|
||||
return func(filetype, obj)
|
||||
return as_der(self) == as_der(other)
|
||||
|
||||
def __repr__(self):
|
||||
return '<{0}({1!r})>'.format(self.__class__.__name__, self._wrapped)
|
||||
|
||||
|
||||
class ComparableRSAKey(object): # pylint: disable=too-few-public-methods
|
||||
|
||||
@@ -6,6 +6,38 @@ import unittest
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
import OpenSSL
|
||||
|
||||
|
||||
class ComparableX509Test(unittest.TestCase):
|
||||
"""Tests for acme.jose.util.ComparableX509."""
|
||||
|
||||
def setUp(self):
|
||||
from acme.jose.util import ComparableX509
|
||||
def load_cert(): # pylint: disable=missing-docstring
|
||||
return ComparableX509(OpenSSL.crypto.load_certificate_request(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, pkg_resources.resource_string(
|
||||
__name__, os.path.join('testdata', 'csr.der'))))
|
||||
self.cert = load_cert()
|
||||
self.cert_same = load_cert()
|
||||
self.cert2 = ComparableX509(OpenSSL.crypto.load_certificate_request(
|
||||
OpenSSL.crypto.FILETYPE_PEM, pkg_resources.resource_string(
|
||||
'letsencrypt.tests', os.path.join('testdata', 'csr-san.pem'))))
|
||||
|
||||
def test_eq(self):
|
||||
self.assertEqual(self.cert, self.cert_same)
|
||||
|
||||
def test_not_eq(self):
|
||||
self.assertNotEqual(self.cert, self.cert2)
|
||||
|
||||
def test_eq_wrong_types(self):
|
||||
from acme.jose.util import ComparableX509
|
||||
self.assertRaises(
|
||||
TypeError, ComparableX509(5).__eq__, ComparableX509(5))
|
||||
|
||||
def test_repr(self):
|
||||
self.assertTrue(repr(self.cert).startswith(
|
||||
'<ComparableX509(<OpenSSL.crypto.X509'))
|
||||
|
||||
|
||||
class ComparableRSAKeyTest(unittest.TestCase):
|
||||
|
||||
+3
-3
@@ -312,7 +312,7 @@ class CertificateRequest(jose.JSONObjectWithFields):
|
||||
"""ACME new-cert request.
|
||||
|
||||
:ivar acme.jose.util.ComparableX509 csr:
|
||||
`M2Crypto.X509.Request` wrapped in `.ComparableX509`
|
||||
`OpenSSL.crypto.X509Req` wrapped in `.ComparableX509`
|
||||
:ivar tuple authorizations: `tuple` of URIs (`str`)
|
||||
|
||||
"""
|
||||
@@ -324,7 +324,7 @@ class CertificateResource(ResourceWithURI):
|
||||
"""Certificate Resource.
|
||||
|
||||
:ivar acme.jose.util.ComparableX509 body:
|
||||
`M2Crypto.X509.X509` wrapped in `.ComparableX509`
|
||||
`OpenSSL.crypto.X509` wrapped in `.ComparableX509`
|
||||
:ivar str cert_chain_uri: URI found in the 'up' ``Link`` header
|
||||
:ivar tuple authzrs: `tuple` of `AuthorizationResource`.
|
||||
|
||||
@@ -336,7 +336,7 @@ class CertificateResource(ResourceWithURI):
|
||||
class Revocation(jose.JSONObjectWithFields):
|
||||
"""Revocation message.
|
||||
|
||||
:ivar .ComparableX509 certificate: `M2Crypto.X509.X509` wrapped in
|
||||
:ivar .ComparableX509 certificate: `OpenSSL.crypto.X509` wrapped in
|
||||
`.ComparableX509`
|
||||
|
||||
"""
|
||||
|
||||
+9
-11
@@ -5,27 +5,25 @@ import unittest
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
import M2Crypto
|
||||
import mock
|
||||
import OpenSSL
|
||||
|
||||
from acme import challenges
|
||||
from acme import jose
|
||||
|
||||
|
||||
CERT = jose.ComparableX509(M2Crypto.X509.load_cert_string(
|
||||
pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'cert.der')),
|
||||
M2Crypto.X509.FORMAT_DER))
|
||||
CSR = jose.ComparableX509(M2Crypto.X509.load_request_string(
|
||||
pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'csr.der')),
|
||||
M2Crypto.X509.FORMAT_DER))
|
||||
CERT = jose.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'cert.der'))))
|
||||
CSR = jose.ComparableX509(OpenSSL.crypto.load_certificate_request(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'csr.der'))))
|
||||
KEY = jose.util.ComparableRSAKey(serialization.load_pem_private_key(
|
||||
pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'rsa512_key.pem')),
|
||||
password=None, backend=default_backend()))
|
||||
CERT = jose.ComparableX509(M2Crypto.X509.load_cert(
|
||||
format=M2Crypto.X509.FORMAT_DER, file=pkg_resources.resource_filename(
|
||||
CERT = jose.ComparableX509(OpenSSL.crypto.load_certificate(
|
||||
OpenSSL.crypto.FILETYPE_ASN1, pkg_resources.resource_string(
|
||||
'acme.jose', os.path.join('testdata', 'cert.der'))))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user