mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 15:40:01 -06:00
A class for dealing with a temporary NSS certificate database
This commit is contained in:
parent
dfe9db5548
commit
8424ea8c03
@ -26,6 +26,15 @@ from ipalib import Command, Str, Int
|
|||||||
from ipalib import errors
|
from ipalib import errors
|
||||||
import krbV
|
import krbV
|
||||||
import os, subprocess
|
import os, subprocess
|
||||||
|
from ipapython import ipautil
|
||||||
|
from ipapython import certdb
|
||||||
|
from ipapython import dogtag
|
||||||
|
import tempfile
|
||||||
|
import sha
|
||||||
|
import httplib
|
||||||
|
import xml.dom.minidom
|
||||||
|
import stat
|
||||||
|
import shutil
|
||||||
|
|
||||||
def get_realm():
|
def get_realm():
|
||||||
krbctx = krbV.default_context()
|
krbctx = krbV.default_context()
|
||||||
@ -103,14 +112,43 @@ class join(Command):
|
|||||||
|
|
||||||
def __get_keytab(self, principal, stdin=None):
|
def __get_keytab(self, principal, stdin=None):
|
||||||
args = ["/usr/sbin/ipa-getkeytab", "-s", self.env.host, "-p", principal,"-k", "/tmp/kt"]
|
args = ["/usr/sbin/ipa-getkeytab", "-s", self.env.host, "-p", principal,"-k", "/tmp/kt"]
|
||||||
return self.__run(args, stdin)
|
return ipautil.run(args, stdin)
|
||||||
|
|
||||||
def __run(self, args, stdin=None):
|
def _generate_server_cert(self, hostname):
|
||||||
if stdin:
|
subject = "CN=%s,OU=pki-ipa,O=IPA" % hostname
|
||||||
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
|
cdb = certdb.CertDB(secdir=None, temporary=True)
|
||||||
stdout,stderr = p.communicate(stdin)
|
|
||||||
|
csr = cdb.generate_csr(subject, keysize=1024)
|
||||||
|
|
||||||
|
# Request a cert
|
||||||
|
try:
|
||||||
|
result = api.Command['cert_request'](unicode(csr), **{})
|
||||||
|
except KeyError:
|
||||||
|
return "Certificates are not supported"
|
||||||
|
|
||||||
|
# Load the cert into our temporary database
|
||||||
|
if result.get('certificate', False):
|
||||||
|
cert_file = cdb.secdir + "/cert.txt"
|
||||||
|
f = open(cert_file, "w")
|
||||||
|
f.write(result.get('certificate'))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
cdb.add_certificate(cert_file, "Server-Cert", is_ca=False)
|
||||||
|
|
||||||
|
ca_chain = dogtag.get_ca_certchain()
|
||||||
|
|
||||||
|
ca_file = cdb.secdir + "/ca.txt"
|
||||||
|
f = open(ca_file, "w")
|
||||||
|
f.write(ca_chain)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
cdb.add_certificate(ca_file, "caCert", is_ca=True)
|
||||||
|
|
||||||
|
result = cdb.create_pkcs12("/tmp/server.p12", "Server-Cert")
|
||||||
else:
|
else:
|
||||||
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True)
|
# Raise some error?
|
||||||
stdout,stderr = p.communicate()
|
pass
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
api.register(join)
|
api.register(join)
|
||||||
|
150
ipapython/certdb.py
Normal file
150
ipapython/certdb.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
# Authors: Rob Crittenden <rcritten@redhat.com>
|
||||||
|
#
|
||||||
|
# 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
|
Loading…
Reference in New Issue
Block a user