bdisk/bdisk/bSSL.py

100 lines
3.9 KiB
Python
Raw Normal View History

import OpenSSL
import os
import shutil
import datetime
import re
def verifyCert(cert, key, CA = None):
# Verify a given certificate against a certificate.
# Optionally verify against a CA certificate as well (Hopefully. If/when PyOpenSSL ever supports it.)
chk = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_METHOD)
chk.use_privatekey(key)
chk.use_certificate(cert)
try:
chk.check_privatekey()
except OpenSSL.SSL.Error:
exit(("{0}: Key does not match certificate!".format(datetime.datetime.now())))
else:
print("{0}: Key verified against certificate successfully.".format(datetime.datetime.now()))
# This is disabled because there doesn't seem to currently be any way
# to actually verify certificates against a given CA.
#if CA:
# try:
# magic stuff here
def sslCAKey():
key = OpenSSL.crypto.PKey()
print("{0}: Generating SSL CA key...".format(datetime.datetime.now()))
key.generate_key(OpenSSL.crypto.TYPE_RSA, 4096)
#print OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key)
return(key)
def sslCA(conf, key = None):
if not key:
try:
key = conf['ipxe']['ssl_cakey']
except:
exit("{0}: Cannot find a valid CA Key to use.".format(datetime.datetime.now()))
domain = (re.sub('^(https?|ftp)://([a-z0-9.-]+)/?.*$', '\g<2>',
conf['ipxe']['uri'],
flags=re.IGNORECASE)).lower()
# http://www.pyopenssl.org/en/stable/api/crypto.html#pkey-objects
# http://docs.ganeti.org/ganeti/2.14/html/design-x509-ca.html
ca = OpenSSL.crypto.X509()
ca.set_version(3)
ca.set_serial_number(1)
ca.get_subject().CN = domain
ca.gmtime_adj_notBefore(0)
# valid for ROUGHLY 10 years. years(ish) * days * hours * mins * secs.
# the paramater is in seconds, which is why we need to multiply them all together.
ca.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
ca.set_issuer(ca.get_subject())
ca.set_pubkey(key)
ca.add_extensions([
OpenSSL.crypto.X509Extension("basicConstraints",
True,
"CA:TRUE, pathlen:0"),
OpenSSL.crypto.X509Extension("keyUsage",
True,
"keyCertSign, cRLSign"),
OpenSSL.crypto.X509Extension("subjectKeyIdentifier",
False,
"hash",
subject = ca),])
ca.sign(key, "sha512")
#print OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, ca)
return(ca)
def sslCKey():
key = OpenSSL.crypto.PKey()
print("{0}: Generating SSL Client key...".format(datetime.datetime.now()))
key.generate_key(OpenSSL.crypto.TYPE_RSA, 4096)
#print OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key)
return(key)
def sslCSR(conf, key):
domain = (re.sub('^(https?|ftp)://([a-z0-9.-]+)/?.*$', '\g<2>',
conf['ipxe']['uri'],
flags=re.IGNORECASE)).lower()
csr = OpenSSL.crypto.X509Req()
csr.get_subject().CN = domain
csr.set_pubkey(key)
csr.sign(key, "sha512")
#print OpenSSL.crypto.dump_certificate_request(OpenSSL.crypto.FILETYPE_PEM, req)
return(csr)
def sslSign(ca, key, csr):
ca_cert = OpenSSL.crypto.load_certificate(ca)
ca_key = OpenSSL.crypto.load_privatekey(key)
req = OpenSSL.crypto.load_certificate_request(csr)
cert = OpenSSL.crypto.X509()
cert.set_subject(req.get_subject())
cert.set_serial_number(1)
cert.gmtime_adj_notBefore(0)
cert.gmtime_adj_notAfter(24 * 60 * 60)
cert.set_issuer(ca_cert.get_subject())
cert.set_pubkey(req.get_pubkey())
cert.sign(ca_key, "sha512")
#print OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
return(cert)