Package: ocspresponder
RFC 6960 compliant OCSP Responder framework written in Python 3.5+.It is based on theocspbuilderandasn1cryptolibraries. The HTTP
server is implemented usingBottle.Current status: Alpha. Don’t use for production yet.FeaturesGoalsSimple: Don’t overwhelm the user with a gazillion options.Flexible: Configurable using Python code.Supported extensionsNonce (RFC 6960 Section 4.4.1)Not (yet) implementedMultiple certificates per request / responseUsageRight now,ocspresponderassumes the usage of a custom keypair just for
signing OCSP responses.To be able to instantiate theOCSPResponderserver, you need to provide
this keypair as well as the certificate of the issueing CA.ISSUER_CERT='path/to/issuer_cert.pem'OCSP_CERT='path/to/responder_cert.pem'OCSP_KEY='path/to/responder_key.pem'Furthermore you need to provide two custom functions:A function that – given a certificate serial – will return the appropriateCertificateStatusand - depending on the status - a revocation
datetime.A function that – given a certificate serial – will return the corresponding
certificate as a string.You’re expected to implement these functions yourself. In the future, drop-in
libraries for typical use cases could be provided.Example implementations:fromocspresponderimportOCSPResponder,CertificateStatusdefvalidate(serial:int)->(CertificateStatus,Optional[datetime]):ifcertificate_is_valid(serial):return(CertificateStatus.good,None)elifcertificate_is_expired(serial):expired_at=get_expiration_date(serial)return(CertificateStatus.revoked,expired_at)elifcertificate_is_revoked(serial):revoked_at=get_revocation_date(serial)return(CertificateStatus.revoked,revoked_at)else:return(CertificateStatus.unknown,None)defget_cert(serial:int)->str:"""
    Assume the certificates are stored in the ``certs`` directory with the
    serial as base filename.
    """withopen('certs/%s.cert.pem'%serial,'r')asf:returnf.read().strip()If an exception occurs in either of the two functions, an OCSP response with
theresponse_statusset tointernal_errorwill be returned.Now you can instantiate theOCSPResponderand launch the development server:print('Initializing OCSP responder')app=OCSPResponder(ISSUER_CERT,OCSP_CERT,OCSP_KEY,validate_func=validate,cert_retrieve_func=get_cert,)print('Starting OCSP responder')app.serve(port=8080,debug=True)Type hintsThis library uses the optional type hints as defined inPEP484. Thetypingmodule is only provided in Python 3.5+, but older versions of Python could run
the code as well if thetypingmodule is installed from PyPI.TestingTo run the test, installrequirements-dev.txtusing pip and run pytest:py.test -vRelease processUpdate version number insetup.pyandCHANGELOG.md:vim -p setup.py CHANGELOG.mdDo a commit and signed tag of the release:export VERSION={VERSION}
git add setup.py CHANGELOG.md
git commit -m "Release v${VERSION}"
git tag -u C75D77C8 -m "Release v${VERSION}" v${VERSION}Build source and binary distributions:python3 setup.py sdist
python3 setup.py bdist_wheelSign files:gpg --detach-sign -u C75D77C8 -a dist/ocspresponder-${VERSION}.tar.gz
gpg --detach-sign -u C75D77C8 -a dist/ocspresponder-${VERSION}-py3-none-any.whlRegister package on PyPI:twine3 register -r pypi-threema dist/ocspresponder-${VERSION}.tar.gzUpload package:twine3 upload -r pypi-threema dist/ocspresponder-${VERSION}*
git push
git push --tagsLicenseCopyright 2016 Threema GmbH

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.