I want to pull my ssl certificate and key from environment variables and not store them on the filesystem. But I am running into a road block with twisted ssl
from io import StringIO
from twisted.internet import reactor, task, threads, ssl
key = StringIO()
key.write(os.environ['SSLKEY'])
cert = StringIO()
cert.write(os.environ['SSLCERT'])
contextFactory = ssl.DefaultOpenSSLContextFactory(key, cert)
gives me the following exception
2018-04-03 16:01:28-0500 [-] TypeError: Path must be represented as bytes or unicode string
or
contextFactory = ssl.DefaultOpenSSLContextFactory(key.getvalue(), cert.getvalue())
gives me the following exception.
2018-04-03 16:02:44-0500 [-] OpenSSL.SSL.Error: [('system library', 'fopen', 'File name too long'), ('BIO routines', 'file_ctrl', 'system lib'), ('SSL routines', 'SSL_CTX_use_certificate_file', 'system lib')]
twisted.internet.ssl is looking for a string or bytes object of the filename and io.StringIO gives me a io.StringIO object.
Is there anyway to accomplish this?
Twisted uses OpenSSL to actually implement TLS. Twisted merely provides a wrapper around OpenSSL's APIs to make them easier to use.
The DefaultOpenSSLContextFactory
initializer takes certificate and key filenames, not certificate and key themselves. So, you cannot accomplish what you want with this API.
twisted.internet.ssl.CertificateOptions
, however, will accept key and certificate objects to its initializer:
from os import environb
from twisted.internet.ssl import (
CertificateOptions,
PrivateCertificate,
)
cert = PrivateCertificate.loadPEM(
environb['SSLKEY'] + b'\n' + environb['SSLCERT'],
)
key = cert.privateKey
contextFactory = CertificateOptions(
privateKey=key.original,
certificate=cert.original,
)
There is probably also a better way to load the certificates using the cryptography
library (which will hopefully supplant a lot of twisted.internet.ssl
key and certificate management APIs in the near future).
Also note that putting your private key into an environment variable in your process exposes it to all other users and processes on the same host. This is a pretty bad idea (it's not very private, after all). So you should probably put your key somewhere else.