summaryrefslogtreecommitdiffstats
path: root/ipapython/certdb.py
diff options
context:
space:
mode:
Diffstat (limited to 'ipapython/certdb.py')
-rw-r--r--ipapython/certdb.py93
1 files changed, 92 insertions, 1 deletions
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index 948132633..08b8391b1 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -17,7 +17,11 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+import binascii
import os
+import io
+import pwd
+import grp
import re
import tempfile
import shutil
@@ -26,6 +30,7 @@ from cryptography.hazmat.primitives import serialization
from nss import nss
from nss.error import NSPRError
+from ipaplatform.tasks import tasks
from ipapython.dn import DN
from ipapython.ipa_log_manager import root_logger
from ipapython import ipautil
@@ -45,6 +50,8 @@ else:
CA_NICKNAME_FMT = "%s IPA CA"
+NSS_FILES = ("cert8.db", "key3.db", "secmod.db", "pwdfile.txt")
+
def get_ca_nickname(realm, format=CA_NICKNAME_FMT):
return format % realm
@@ -106,13 +113,63 @@ class NSSDatabase(object):
new_args = new_args + args
return ipautil.run(new_args, stdin, **kwargs)
- def create_db(self, password_filename):
+ def create_db(self, password_filename=None, user=None, group=None,
+ mode=None, backup=False):
"""Create cert DB
:param password_filename: Name of file containing the database password
+ :param user: User owner the secdir
+ :param group: Group owner of the secdir
+ :param mode: Mode of the secdir
+ :param backup: Backup the sedir files
"""
+ dirmode = 0o750
+ filemode = 0o640
+ if mode is not None:
+ dirmode = mode
+ filemode = mode & 0o666
+
+ uid = -1
+ gid = -1
+ if user is not None:
+ uid = pwd.getpwnam(user).pw_uid
+ if group is not None:
+ gid = grp.getgrnam(group).gr_gid
+
+ if backup:
+ for filename in NSS_FILES:
+ path = os.path.join(self.secdir, filename)
+ ipautil.backup_file(path)
+
+ if not os.path.exists(self.secdir):
+ os.makedirs(self.secdir, dirmode)
+
+ if password_filename is None:
+ password_filename = os.path.join(self.secdir, 'pwdfile.txt')
+
+ if not os.path.exists(password_filename):
+ # Create the password file for this db
+ hex_str = binascii.hexlify(os.urandom(10))
+ with io.open(os.open(password_filename,
+ os.O_CREAT | os.O_WRONLY,
+ filemode), 'wb', closefd=True) as f:
+ f.write(hex_str)
+ f.flush()
+
self.run_certutil(["-N", "-f", password_filename])
+ # Finally fix up perms
+ os.chown(self.secdir, uid, gid)
+ os.chmod(self.secdir, dirmode)
+ tasks.restore_context(self.secdir)
+ for filename in NSS_FILES:
+ path = os.path.join(self.secdir, filename)
+ if os.path.exists(path):
+ if uid != -1 or gid != -1:
+ os.chown(path, uid, gid)
+ os.chmod(path, filemode)
+ tasks.restore_context(path)
+
def list_certs(self):
"""Return nicknames and cert flags for all certs in the database
@@ -161,6 +218,31 @@ class NSSDatabase(object):
return root_nicknames
+ def export_pkcs12(self, nickname, pkcs12_filename, db_password_filename,
+ pkcs12_passwd=None):
+ args = [PK12UTIL, "-d", self.secdir,
+ "-o", pkcs12_filename,
+ "-n", nickname,
+ "-k", db_password_filename]
+ pkcs12_password_file = None
+ if pkcs12_passwd is not None:
+ pkcs12_password_file = ipautil.write_tmp_file(pkcs12_passwd + '\n')
+ args = args + ["-w", pkcs12_password_file.name]
+ try:
+ ipautil.run(args)
+ except ipautil.CalledProcessError as e:
+ if e.returncode == 17:
+ raise RuntimeError("incorrect password for pkcs#12 file %s" %
+ pkcs12_filename)
+ elif e.returncode == 10:
+ raise RuntimeError("Failed to open %s" % pkcs12_filename)
+ else:
+ raise RuntimeError("unknown error exporting pkcs#12 file %s" %
+ pkcs12_filename)
+ finally:
+ if pkcs12_password_file is not None:
+ pkcs12_password_file.close()
+
def import_pkcs12(self, pkcs12_filename, db_password_filename,
pkcs12_passwd=None):
args = [PK12UTIL, "-d", self.secdir,
@@ -508,3 +590,12 @@ class NSSDatabase(object):
finally:
del certdb, cert
nss.nss_shutdown()
+
+ def publish_ca_cert(self, canickname, location):
+ args = ["-L", "-n", canickname, "-a"]
+ result = self.run_certutil(args, capture_output=True)
+ cert = result.output
+ fd = open(location, "w+")
+ fd.write(cert)
+ fd.close()
+ os.chmod(location, 0o444)