From 8424ea8c0380b57dd0dc0f8c79ecf23171072249 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 22 Apr 2009 14:35:43 -0400 Subject: A class for dealing with a temporary NSS certificate database --- ipapython/certdb.py | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 ipapython/certdb.py (limited to 'ipapython') diff --git a/ipapython/certdb.py b/ipapython/certdb.py new file mode 100644 index 000000000..15f6c16aa --- /dev/null +++ b/ipapython/certdb.py @@ -0,0 +1,150 @@ +# Authors: Rob Crittenden +# +# Copyright (C) 2009 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; version 2 only +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +from ipapython import ipautil +from ipapython import nsslib +import tempfile +import sha +import shutil +import os + +class CertDB(): + """ + To be used for temporary NSS databases only. If temporary is set then + this willcompletely remove the database it is working on when the + class is destroyed. + """ + def __init__(self, secdir, password=None, temporary=False): + if secdir is None: + secdir = tempfile.mkdtemp(prefix = "certdb-") + if password is None: + password = self.generate_random() + self.secdir = secdir + self.password = password + self.temporary = temporary + self.noise_file = secdir + "/noise" + self.pwd_file = secdir + "/pwd" + self.csr_file = secdir + "/csr.txt" + + f = open(self.pwd_file, "w") + f.write(self.password) + f.close() + + if not ipautil.file_exists(secdir + "/secmod.db"): + self.run_certutil(["-N", "-f", self.pwd_file]) + + def __del__(self): + if self.temporary: + shutil.rmtree(self.secdir) + else: + # clean up + if ipautil.file_exists(self.noise_file): + os.remove(self.noise_file) + + def run_certutil(self, args, stdin=None): + new_args = ["/usr/bin/certutil", "-d", self.secdir] + new_args = new_args + args + return ipautil.run(new_args, stdin) + + def generate_random(self): + return sha.sha(ipautil.ipa_generate_password()).hexdigest() + + def create_noise_file(self): + """ + Generate a noise file to be used when creating a key + """ + if ipautil.file_exists(self.noise_file): + os.remove(self.noise_file) + + f = open(self.noise_file, "w") + f.write(self.generate_random()) + f.close() + + return + + def generate_csr(self, subject, keysize=2048, keytype="rsa"): + """ + Generate a Certificate Signing Request (CSR) and return as a + string the base-64 result with the BEGIN/END block. + """ + self.create_noise_file() + args = ["-R", "-s", subject, + "-o", self.csr_file, + "-k", keytype, + "-g", str(keysize), + "-z", self.noise_file, + "-f", self.pwd_file, + "-a"] + self.run_certutil(args) + + # read in the CSR + f = open(self.csr_file, "r") + csr = f.readlines() + f.close() + csr = "".join(csr) + + # We just want the CSR bits, make sure there is nothing else + s = csr.find("-----BEGIN NEW CERTIFICATE REQUEST-----") + e = csr.find("-----END NEW CERTIFICATE REQUEST-----") + if e > 0: + e = e + 37 + if s >= 0: + csr = csr[s:] + + return csr + + def add_certificate(self, cert_file, nickname="Server-Cert", is_ca=False): + """ + Add a certificate to our NSS database. + + Only supports base64-encoded certificates, not DER-encoded. + """ + if is_ca: + trust_flag="CT,C,C" + else: + trust_flag="u,u,u" + + # Generate a CSR + args = ["-A", + "-n", nickname, + "-t", trust_flag, + "-i", cert_file, + "-f", self.pwd_file, + "-a"] + + self.run_certutil(args) + + def create_pkcs12(self, pkcs12_file, nickname="Server-Cert", password=None): + if password is None: + password = self.password + + p12pwd_file = self.secdir + "/pkcs12_pwd" + f = open(p12pwd_file, "w") + f.write(password) + f.close() + + args = ["/usr/bin/pk12util", + "-d", self.secdir, + "-o", pkcs12_file, + "-n", nickname, + "-k", self.pwd_file, + "-w", p12pwd_file] + ipautil.run(args) + + return password -- cgit