Commit 545f0ecd authored by ale's avatar ale

fix CRL handling and generation

parent 951f622b
......@@ -18,7 +18,7 @@ class CA(object):
self.digest = digest
self.storage = ca_storage.FileStorage(root)
self._init_ca()
self._update_crl()
self._load_crl()
def _init_ca(self):
key_str, crt_str = self.storage.get_ca()
......@@ -79,32 +79,42 @@ class CA(object):
return cert
def _update_crl(self):
self.crl_data_der = ''
self.crl_data_pem = self.storage.get_crl() or ''
if self.crl_data_pem:
# Re-read the CRL data in DER and PEM formats.
pipe = subprocess.Popen(
['openssl', 'crl', '-inform', 'PEM', '-outform', 'DER'],
stdout=subprocess.PIPE)
self.crl_data_der = pipe.communicate(self.crl_data_pem)[0]
crl = crypto.CRL()
for serial, stamp in self.storage.get_revoked():
revoked = crypto.Revoked()
revoked.set_serial(str(serial))
revoked.set_rev_date(
time.strftime('%Y%m%d%H%M%SZ', time.gmtime(stamp)))
crl.add_revoked(revoked)
self.storage.set_crl(
crl.export(self.ca_crt, self.ca_key, crypto.FILETYPE_PEM, 30))
self._load_crl()
def _load_crl(self):
self.crl_data_pem = self.storage.get_crl()
if not self.crl_data_pem:
# Create an empty CRL.
crl = crypto.CRL()
self.crl_data_pem = crl.export(self.ca_crt, self.ca_key,
crypto.FILETYPE_PEM, 30)
self.storage.set_crl(self.crl_data_pem)
log.debug('CRL PEM data: %s', self.crl_data_pem)
# Re-read the CRL data in DER and PEM formats.
pipe = subprocess.Popen(
['openssl', 'crl', '-inform', 'PEM', '-outform', 'DER'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
self.crl_data_der = pipe.communicate(self.crl_data_pem)[0]
def _revoke_certificate(self, cn, serial_num):
log.debug('revoking certificate: cn=%s, serial=%s', cn, serial_num)
if self.crl_data_pem:
crl = crypto.load_crl(crypto.FILETYPE_PEM, self.crl_data_pem)
else:
crl = crypto.CRL()
revoked_set = set(x.get_serial() for x in crl.get_revoked())
if serial_num in revoked_set:
return
r = crypto.Revoked()
r.set_serial(str(serial_num))
crl.add_revoked(r)
#serial_hex = '%X' % int(serial_num)
revoked = self.storage.get_revoked()
if serial_num in revoked:
return
self.storage.delete_certificate(cn)
self.storage.set_crl(crl.export(self.ca_crt, self.ca_key,
crypto.FILETYPE_PEM, 7))
self.storage.add_revoked(serial_num)
self._update_crl()
def revoke_certificate(self, cn):
......
......@@ -5,6 +5,24 @@ import time
import certutil
class LockedFile(object):
def __init__(self, path):
self._path = path
def __enter__(self):
try:
self._fd = open(self._path, 'r+')
except IOError:
self._fd = open(self._path, 'w+')
fcntl.lockf(self._fd, fcntl.LOCK_EX)
return self._fd
def __exit__(self, type, value, traceback):
fcntl.lockf(self._fd, fcntl.LOCK_UN)
self._fd.close()
class FileStorage(object):
def __init__(self, root):
......@@ -17,6 +35,7 @@ class FileStorage(object):
# Special files.
self.serial_path = os.path.join(root, 'serial')
self.revoked_path = os.path.join(root, 'revoked')
self.ca_crt_path = os.path.join(root, 'ca.pem')
self.ca_key_path = os.path.join(self.key_dir, 'ca.key')
self.crl_path = os.path.join(root, 'crl.pem')
......@@ -43,6 +62,7 @@ class FileStorage(object):
return certutil.readfrom(self.crl_path)
def set_crl(self, crl_str):
print 'setting CRL:', crl_str
certutil.writeto(self.crl_path, crl_str)
def get_certificate(self, cn):
......@@ -57,12 +77,7 @@ class FileStorage(object):
os.unlink(self._cert_path(cn))
def get_next_serial(self):
try:
fd = open(self.serial_path, 'r+')
except IOError:
fd = open(self.serial_path, 'w+')
fcntl.lockf(fd, fcntl.LOCK_EX)
try:
with LockedFile(self.serial_path) as fd:
contents = fd.read()
fd.seek(0)
if contents:
......@@ -72,6 +87,16 @@ class FileStorage(object):
serial = int(time.time())
fd.write('%d\n' % serial)
return serial
finally:
fcntl.lockf(fd, fcntl.LOCK_UN)
fd.close()
def get_revoked(self):
with LockedFile(self.revoked_path) as fd:
revoked = [map(int, x.strip().split()) for x in fd if x]
print 'get_revoked():', revoked
return revoked
def add_revoked(self, serial):
print 'add_revoked(%s)' % serial
with LockedFile(self.revoked_path) as fd:
fd.seek(0, 2)
fd.write('%s %i\n' % (serial, time.time()))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment