diff --git a/autoca/ca.py b/autoca/ca.py index 33ffefbedac54950425078afb3441419a0a7caa6..2e5818b4ade04d58b4c980160cdc4fbe20a27e56 100644 --- a/autoca/ca.py +++ b/autoca/ca.py @@ -57,6 +57,7 @@ class CA(object): self._generate_ca_cert() def renew_ca(self): + """Renew the CA certificate itself (keeping the private key).""" if not self.ca_key: log.error('CA private key not available') return @@ -64,14 +65,35 @@ class CA(object): self._generate_ca_cert() def get_ca(self): + """Return the CA certificate (PEM-encoded).""" return self.public_ca_pem def make_certificate(self, subject_attrs, days=7, server=False): + """Create a new certificate and private key. + + Args: + subject_attrs: dict of X509 Subject attributes + days: days of validity of the new certificate + server: if True, create a server certificate, otherwise a + client one. + Returns: + A (private_key, certificate) pair. + """ pkey = certutil.create_rsa_key_pair() csr = certutil.create_cert_request(pkey, **subject_attrs) return pkey, self.sign_certificate(csr, days, server) - def sign_certificate(self, req, days=365, server=False): + def sign_certificate(self, req, days=7, server=False): + """Sign a certificate request. + + Args: + req: CSR object + days: days of validity of the new certificate + server: if True, create a server certificate, otherwise a + client one. + Returns: + A X509 certificate, PEM-encoded. + """ cn = req.get_subject().CN log.info('sign request for cn=%s', cn) cert = self.get_certificate(cn) @@ -97,7 +119,12 @@ class CA(object): cn, crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) return cert - def _update_crl(self): + def update_crl(self): + """Update the CRL. + + This function will generate a newly signed CRL every time it + is called. + """ crl = crypto.CRL() for serial, stamp in self.storage.get_revoked(): revoked = crypto.Revoked() @@ -125,6 +152,7 @@ class CA(object): self.crl_data_der = pipe.communicate(self.crl_data_pem)[0] def get_crl(self, format='der'): + """Return the CRL (PEM- or DER-encoded).""" if format == 'der': return self.crl_data_der else: @@ -139,20 +167,27 @@ class CA(object): self.storage.delete_certificate(cn) self.storage.add_revoked(serial_num) - self._update_crl() + self.update_crl() def revoke_certificate(self, cn): + """Revoke a certificate.""" serial_num = self.get_serial(cn) if serial_num: self._revoke_certificate(cn, serial_num) def get_certificate(self, cn, raw=False): + """Return a certificate given its subject. + + If raw is True, the returned data will be in DER format, + otherwise it will be PEM-encoded. + """ data = self.storage.get_certificate(cn) if data and not raw: data = crypto.load_certificate(crypto.FILETYPE_PEM, data) return data def get_serial(self, cn): + """Return the serial number of the certificate given its subject.""" crt = self.get_certificate(cn, raw=False) if crt: return crt.get_serial_number() diff --git a/autoca/ca_tool.py b/autoca/ca_tool.py index 6b43af4a4097a6d95998811c0244a4dc7c7d3f81..7dc158a420999bf1210e8585a655a5ceed53e3fe 100644 --- a/autoca/ca_tool.py +++ b/autoca/ca_tool.py @@ -35,6 +35,9 @@ get-crl to request a specific output format by passing the desired format as second argument ("pem" or "der"). +update-crl + Update the CRL on a local CA (requires --ca-path). + sign Create a new certificate request and sign it. If the --server option is not specified, a client certificate will be @@ -126,6 +129,10 @@ separated by slashes ('/'), for example: parser.error('The "init" command is only valid with a local CA') # Nothing to do, actually. print 'Done.' + elif cmd == 'update-crl': + if not opts.ca_path: + parser.error('The "update-crl" command is only valid with a local CA') + client.update_crl() else: parser.error('Unknown command') diff --git a/debian/changelog b/debian/changelog index 8de6ff6a40e80d6574381de9155f1e5a4cb321e6..87b4263824e09d4fbff6ec260220c04747e110f5 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +autoca (0.3.1) unstable; urgency=low + + * Added command to update the CRL. + + -- Autistici/Inventati <debian@autistici.org> Sat, 19 Nov 2016 09:53:16 +0000 + autoca (0.3) unstable; urgency=low * Initial Release. diff --git a/setup.py b/setup.py index face0d1f22c5cc6dd9efd5776bb341ecc8180b4e..b6ee62ab36f27be18aba3d95e1c132deae3d4cd1 100755 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ from setuptools import setup, find_packages setup( name="autoca", - version="0.3", + version="0.3.1", description="Automated CA management.", author="Ale", author_email="ale@incal.net",