Compare commits
3 Commits
test-apach
...
ocsp-respo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d0f25df4b | ||
|
|
8f79859b10 | ||
|
|
3734ae7b04 |
@@ -1,5 +1,6 @@
|
||||
"""Certbot client interfaces."""
|
||||
import abc
|
||||
import enum
|
||||
|
||||
import six
|
||||
import zope.interface
|
||||
@@ -589,6 +590,43 @@ class RenewableCert(object):
|
||||
|
||||
"""
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta):
|
||||
class OCSPResponse(object):
|
||||
"""I'll have a real description someday."""
|
||||
|
||||
@abc.abstractproperty
|
||||
def certificate_status(self):
|
||||
"""Cert status
|
||||
|
||||
:rtype: OCSPCertStatus
|
||||
|
||||
"""
|
||||
|
||||
@abc.abstractproperty
|
||||
def next_update(self):
|
||||
"""Next update
|
||||
|
||||
:rtype: stdlib datetime thing
|
||||
|
||||
"""
|
||||
|
||||
@abc.abstractpoperty
|
||||
def raw_bytes(self):
|
||||
"""Raw bytes of the OCSP Response
|
||||
|
||||
:rtype: bytes
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class OCSPCertStatus(enum):
|
||||
GOOD = 1
|
||||
REVOKED = 2
|
||||
UNRECOGNIZED = 3
|
||||
"""There are other OCSP statuses, but we may not have code to recognize them yet."""
|
||||
|
||||
|
||||
# Updater interfaces
|
||||
#
|
||||
# When "certbot renew" is run, Certbot will iterate over each lineage and check
|
||||
|
||||
@@ -20,6 +20,7 @@ from acme.magic_typing import Optional
|
||||
from acme.magic_typing import Tuple
|
||||
from certbot import crypto_util
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot import util
|
||||
from certbot.compat.os import getenv
|
||||
from certbot.interfaces import RenewableCert # pylint: disable=unused-import
|
||||
@@ -29,19 +30,23 @@ try:
|
||||
# and signature_hash_algorithm attribute in OCSPResponse class
|
||||
from cryptography.x509 import ocsp # pylint: disable=ungrouped-imports
|
||||
getattr(ocsp.OCSPResponse, 'signature_hash_algorithm')
|
||||
CRYPTOGRAPHY_OCSP_AVAILABLE = True
|
||||
except (ImportError, AttributeError): # pragma: no cover
|
||||
ocsp = None # type: ignore
|
||||
CRYPTOGRAPHY_OCSP_AVAILABLE = False
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class _CryptographyOCSPResponse(interfaces.OCSPResponse):
|
||||
"""Cryptography implementation of given interface."""
|
||||
|
||||
class RevocationChecker(object):
|
||||
"""This class figures out OCSP checking on this system, and performs it."""
|
||||
|
||||
def __init__(self, enforce_openssl_binary_usage=False):
|
||||
self.broken = False
|
||||
self.use_openssl_binary = enforce_openssl_binary_usage or not ocsp
|
||||
self.use_openssl_binary = enforce_openssl_binary_usage or not CRYPTOGRAPHY_OCSP_AVAILABLE
|
||||
|
||||
if self.use_openssl_binary:
|
||||
if not util.exe_exists("openssl"):
|
||||
@@ -58,6 +63,29 @@ class RevocationChecker(object):
|
||||
else:
|
||||
self.host_args = lambda host: ["Host", host]
|
||||
|
||||
def ocsp_response_by_paths(self, cert_path, chain_path, timeout=10):
|
||||
"""Obtains a validated OCSP response.
|
||||
|
||||
The OCSP response could have any cert status, however, if an
|
||||
OCSP response is returned from this function, the caller knows
|
||||
it is properly timestamped, signed, etc.
|
||||
|
||||
.. note:: This function currently works when cryptography is
|
||||
used for OCSP. Whether a new enough version of crypography
|
||||
with OCSP support is available can be checked through
|
||||
CRYPTOGRAPHY_OCSP_AVAILABLE. If it is not available, None is
|
||||
always returned by this function for now.
|
||||
|
||||
:param str cert_path: Certificate filepath
|
||||
:param str chain_path: Certificate chain
|
||||
:param int timeout: Timeout (in seconds) for the OCSP query
|
||||
|
||||
:returns: The OCSP response if it could be obtained and
|
||||
validated, otherwise, None
|
||||
:rtype: interfaces.OCSPResponse or None
|
||||
|
||||
"""
|
||||
|
||||
def ocsp_revoked(self, cert):
|
||||
# type: (RenewableCert) -> bool
|
||||
"""Get revoked status for a particular cert version.
|
||||
|
||||
Reference in New Issue
Block a user