Drop --selfsign server functionality

Design: http://freeipa.org/page/V3/Drop_selfsign_functionality
Ticket: https://fedorahosted.org/freeipa/ticket/3494
This commit is contained in:
Petr Viktorin 2013-03-27 14:25:18 +01:00 committed by Rob Crittenden
parent 006ab23c6d
commit e736e75ce9
10 changed files with 133 additions and 801 deletions

View File

@ -112,7 +112,7 @@ def main():
api.bootstrap(in_server=True) api.bootstrap(in_server=True)
api.finalize() api.finalize()
if certs.ipa_self_signed(): if api.env.ra_plugin == 'selfsign':
sys.exit('A selfsign CA can not be added') sys.exit('A selfsign CA can not be added')
# get the directory manager password # get the directory manager password

View File

@ -1004,16 +1004,10 @@ def main():
ds = dsinstance.DsInstance(fstore=fstore) ds = dsinstance.DsInstance(fstore=fstore)
ds.init_info( ds.init_info(
realm_name, host_name, domain_name, dm_password, realm_name, host_name, domain_name, dm_password,
False, options.subject, 1101, 1100, None) options.subject, 1101, 1100, None)
if setup_ca: if setup_ca:
# Clean up any previous self-signed CA that may exist
try:
os.remove(certs.CA_SERIALNO)
except:
pass
if not dogtag.install_constants.SHARED_DB: if not dogtag.install_constants.SHARED_DB:
cs = cainstance.CADSInstance( cs = cainstance.CADSInstance(
host_name, realm_name, domain_name, dm_password) host_name, realm_name, domain_name, dm_password)

View File

@ -61,10 +61,9 @@ def subject_base():
return _subject_base return _subject_base
def valid_issuer(issuer): def valid_issuer(issuer):
# Handle all supported forms of issuer -- currently dogtag only.
if api.env.ra_plugin == 'dogtag': if api.env.ra_plugin == 'dogtag':
return DN(issuer) == DN(('CN', 'Certificate Authority'), subject_base()) return DN(issuer) == DN(('CN', 'Certificate Authority'), subject_base())
else:
return DN(issuer) == DN(('CN', '%s Certificate Authority' % api.env.realm))
def strip_header(pem): def strip_header(pem):
""" """
@ -238,7 +237,6 @@ def verify_cert_subject(ldap, hostname, dercert):
issuer = str(nsscert.issuer) issuer = str(nsscert.issuer)
del(nsscert) del(nsscert)
# Handle both supported forms of issuer, from selfsign and dogtag.
if (not valid_issuer(issuer)): if (not valid_issuer(issuer)):
raise errors.CertificateOperationError(error=_('Issuer "%(issuer)s" does not match the expected issuer') % \ raise errors.CertificateOperationError(error=_('Issuer "%(issuer)s" does not match the expected issuer') % \
{'issuer' : issuer}) {'issuer' : issuer})

View File

@ -17,20 +17,20 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
import os, stat, subprocess, re import os
import stat
import re
import sys import sys
import tempfile import tempfile
import shutil import shutil
from ipapython.ipa_log_manager import *
import xml.dom.minidom import xml.dom.minidom
import pwd import pwd
import fcntl
import base64 import base64
from hashlib import sha1 from hashlib import sha1
from ConfigParser import RawConfigParser, MissingSectionHeaderError
from nss import nss from nss import nss
from ipapython.ipa_log_manager import root_logger
from ipapython import dogtag from ipapython import dogtag
from ipapython import sysrestore from ipapython import sysrestore
from ipapython import ipautil from ipapython import ipautil
@ -46,32 +46,6 @@ from ipalib.text import _
# where apache can reach # where apache can reach
NSS_DIR = "/etc/httpd/alias" NSS_DIR = "/etc/httpd/alias"
CA_SERIALNO="/var/lib/ipa/ca_serialno"
def ipa_self_signed():
"""
Determine if the current IPA CA is self-signed or using another CA
We do this based on the CA plugin that is currently in use.
"""
if api.env.ra_plugin == 'selfsign':
return True
else:
return False
def ipa_self_signed_master():
"""
The selfsign backend is enabled only one a single master.
Return True/False whether this is that master.
Returns None if not a self-signed server.
"""
if ipa_self_signed():
return api.env.enable_ra
else:
return None
def find_cert_from_txt(cert, start=0): def find_cert_from_txt(cert, start=0):
""" """
Given a cert blob (str) which may or may not contian leading and Given a cert blob (str) which may or may not contian leading and
@ -106,90 +80,6 @@ def get_cert_nickname(cert):
return (str(dn[0]), dn) return (str(dn[0]), dn)
def next_serial(serial_file=CA_SERIALNO):
"""
Get the next serial number if we're using an NSS-based self-signed CA.
The file is an ini-like file with following properties:
lastvalue = the last serial number handed out
nextreplica = the serial number the next replica should start with
replicainterval = the number to add to nextreplica the next time a
replica is created
File locking is attempted so we have unique serial numbers.
"""
fp = None
parser = RawConfigParser()
if ipautil.file_exists(serial_file):
try:
fp = open(serial_file, "r+")
fcntl.flock(fp.fileno(), fcntl.LOCK_EX)
parser.readfp(fp)
serial = parser.getint('selfsign', 'lastvalue')
cur_serial = serial + 1
except IOError, e:
raise RuntimeError("Unable to determine serial number: %s" % str(e))
except MissingSectionHeaderError:
fcntl.flock(fp.fileno(), fcntl.LOCK_UN)
fp.close()
f=open(serial_file,"r")
r = f.readline()
f.close()
cur_serial = int(r) + 1
fp = open(serial_file, "w")
fcntl.flock(fp.fileno(), fcntl.LOCK_EX)
parser.add_section('selfsign')
parser.set('selfsign', 'nextreplica', 500000)
parser.set('selfsign', 'replicainterval', 500000)
else:
fp = open(serial_file, "w")
fcntl.flock(fp.fileno(), fcntl.LOCK_EX)
parser.add_section('selfsign')
parser.set('selfsign', 'nextreplica', 500000)
parser.set('selfsign', 'replicainterval', 500000)
cur_serial = 1000
try:
fp.seek(0)
parser.set('selfsign', 'lastvalue', cur_serial)
parser.write(fp)
fp.flush()
fcntl.flock(fp.fileno(), fcntl.LOCK_UN)
fp.close()
except IOError, e:
raise RuntimeError("Unable to increment serial number: %s" % str(e))
return str(cur_serial)
def next_replica(serial_file=CA_SERIALNO):
"""
Return the starting serial number for a new self-signed replica
"""
fp = None
parser = RawConfigParser()
if ipautil.file_exists(serial_file):
try:
fp = open(serial_file, "r+")
fcntl.flock(fp.fileno(), fcntl.LOCK_EX)
parser.readfp(fp)
serial = parser.getint('selfsign', 'nextreplica')
nextreplica = serial + parser.getint('selfsign', 'replicainterval')
except IOError, e:
raise RuntimeError("Unable to determine serial number: %s" % str(e))
else:
raise RuntimeError("%s does not exist, cannot create replica" % serial_file)
try:
fp.seek(0)
parser.set('selfsign', 'nextreplica', nextreplica)
parser.write(fp)
fp.flush()
fcntl.flock(fp.fileno(), fcntl.LOCK_UN)
fp.close()
except IOError, e:
raise RuntimeError("Unable to increment serial number: %s" % str(e))
return str(serial)
class NSSDatabase(object): class NSSDatabase(object):
"""A general-purpose wrapper around a NSS cert database """A general-purpose wrapper around a NSS cert database
@ -440,15 +330,10 @@ class CertDB(object):
except OSError, e: except OSError, e:
raise RuntimeError("Unable to determine the current directory: %s" % str(e)) raise RuntimeError("Unable to determine the current directory: %s" % str(e))
self.self_signed_ca = ipa_self_signed()
if not subject_base: if not subject_base:
self.subject_base = DN(('O', 'IPA')) self.subject_base = DN(('O', 'IPA'))
if self.self_signed_ca: self.cacert_name = get_ca_nickname(self.realm)
self.cacert_name = get_ca_nickname(self.realm, 'CN=%s Certificate Authority')
else:
self.cacert_name = get_ca_nickname(self.realm)
self.valid_months = "120" self.valid_months = "120"
self.keysize = "1024" self.keysize = "1024"
@ -495,22 +380,6 @@ class CertDB(object):
# sure we are in a unique place when this happens # sure we are in a unique place when this happens
os.chdir(self.reqdir) os.chdir(self.reqdir)
def set_serial_from_pkcs12(self):
"""A CA cert was loaded from a PKCS#12 file. Set up our serial file"""
cur_serial = self.find_cacert_serial()
try:
fp = open(CA_SERIALNO, "w")
parser = RawConfigParser()
parser.add_section('selfsign')
parser.set('selfsign', 'lastvalue', cur_serial)
parser.set('selfsign', 'nextreplica', 500000)
parser.set('selfsign', 'replicainterval', 500000)
parser.write(fp)
fp.close()
except IOError, e:
raise RuntimeError("Unable to increment serial number: %s" % str(e))
def set_perms(self, fname, write=False, uid=None): def set_perms(self, fname, write=False, uid=None):
if uid: if uid:
pent = pwd.getpwnam(uid) pent = pwd.getpwnam(uid)
@ -529,13 +398,10 @@ class CertDB(object):
return self.nssdb.run_certutil(args, stdin) return self.nssdb.run_certutil(args, stdin)
def run_signtool(self, args, stdin=None): def run_signtool(self, args, stdin=None):
if not self.self_signed_ca: with open(self.passwd_fname, "r") as f:
f = open(self.passwd_fname, "r")
password = f.readline() password = f.readline()
f.close() new_args = ["/usr/bin/signtool", "-d", self.secdir, "-p", password]
new_args = ["/usr/bin/signtool", "-d", self.secdir, "-p", password]
else:
new_args = ["/usr/bin/signtool", "-d", self.secdir]
new_args = new_args + args new_args = new_args + args
ipautil.run(new_args, stdin) ipautil.run(new_args, stdin)
@ -585,41 +451,6 @@ class CertDB(object):
return False return False
def create_ca_cert(self):
os.chdir(self.secdir)
subject = DN(('cn', '%s Certificate Authority' % self.realm))
p = subprocess.Popen(["/usr/bin/certutil",
"-d", self.secdir,
"-S", "-n", self.cacert_name,
"-s", str(subject),
"-x",
"-t", "CT,,C",
"-1",
"-2",
"-5",
"-m", next_serial(),
"-v", self.valid_months,
"-z", self.noise_fname,
"-f", self.passwd_fname],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# Create key usage extension
# 0 - Digital Signature
# 1 - Non-repudiation
# 5 - Cert signing key
# Is this a critical extension [y/N]? y
p.stdin.write("0\n1\n5\n9\ny\n")
# Create basic constraint extension
# Is this a CA certificate [y/N]? y
# Enter the path length constraint, enter to skip [<0 for unlimited pat
# Is this a critical extension [y/N]? y
# 5 6 7 9 n -> SSL, S/MIME, Object signing CA
p.stdin.write("y\n\ny\n")
p.stdin.write("5\n6\n7\n9\nn\n")
p.wait()
os.chdir(self.cwd)
def export_ca_cert(self, nickname, create_pkcs12=False): def export_ca_cert(self, nickname, create_pkcs12=False):
"""create_pkcs12 tells us whether we should create a PKCS#12 file """create_pkcs12 tells us whether we should create a PKCS#12 file
of the CA or not. If we are running on a replica then we won't of the CA or not. If we are running on a replica then we won't
@ -686,16 +517,6 @@ class CertDB(object):
except ipautil.CalledProcessError: except ipautil.CalledProcessError:
return '' return ''
def find_cacert_serial(self):
(out, err, returncode) = self.run_certutil(["-L", "-n", self.cacert_name])
data = out.split('\n')
for line in data:
x = re.match(r'\s+Serial Number: (\d+) .*', line)
if x is not None:
return x.group(1)
raise RuntimeError("Unable to find serial number")
def track_server_cert(self, nickname, principal, password_file=None, command=None): def track_server_cert(self, nickname, principal, password_file=None, command=None):
""" """
Tell certmonger to track the given certificate nickname. Tell certmonger to track the given certificate nickname.
@ -752,12 +573,7 @@ class CertDB(object):
def create_server_cert(self, nickname, hostname, other_certdb=None, subject=None): def create_server_cert(self, nickname, hostname, other_certdb=None, subject=None):
""" """
other_certdb can mean one of two things, depending on the context. If we are using a dogtag CA then other_certdb contains the RA agent key
If we are using a self-signed CA then other_certdb contains the
CA that will be signing our CSR.
If we are using a dogtag CA then it contains the RA agent key
that will issue our cert. that will issue our cert.
You can override the certificate Subject by specifying a subject. You can override the certificate Subject by specifying a subject.
@ -802,179 +618,117 @@ class CertDB(object):
"-k", certtype, "-k", certtype,
"-g", keysize, "-g", keysize,
"-z", self.noise_fname, "-z", self.noise_fname,
"-f", self.passwd_fname] "-f", self.passwd_fname,
if not self.self_signed_ca: "-a"]
args.append("-a")
(stdout, stderr, returncode) = self.run_certutil(args) (stdout, stderr, returncode) = self.run_certutil(args)
os.remove(self.noise_fname) os.remove(self.noise_fname)
return (stdout, stderr) return (stdout, stderr)
def issue_server_cert(self, certreq_fname, cert_fname): def issue_server_cert(self, certreq_fname, cert_fname):
self.setup_cert_request() self.setup_cert_request()
if self.self_signed_ca:
p = subprocess.Popen(["/usr/bin/certutil",
"-d", self.secdir,
"-C", "-c", self.cacert_name,
"-i", certreq_fname,
"-o", cert_fname,
"-m", next_serial(),
"-v", self.valid_months,
"-f", self.passwd_fname,
"-1", "-5"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
# Bah - this sucks, but I guess it isn't possible to fully if self.host_name is None:
# control this with command line arguments. raise RuntimeError("CA Host is not set.")
#
# What this is requesting is:
# -1 (Create key usage extension)
# 2 - Key encipherment
# 9 - done
# n - not critical
#
# -5 (Create netscape cert type extension)
# 1 - SSL Server
# 9 - done
# n - not critical
p.stdin.write("2\n9\nn\n1\n9\nn\n")
p.wait()
else:
if self.host_name is None:
raise RuntimeError("CA Host is not set.")
f = open(certreq_fname, "r") f = open(certreq_fname, "r")
csr = f.readlines() csr = f.readlines()
f.close() f.close()
csr = "".join(csr) csr = "".join(csr)
# We just want the CSR bits, make sure there is nothing else # We just want the CSR bits, make sure there is nothing else
csr = pkcs10.strip_header(csr) csr = pkcs10.strip_header(csr)
params = {'profileId': 'caIPAserviceCert', params = {'profileId': 'caIPAserviceCert',
'cert_request_type': 'pkcs10', 'cert_request_type': 'pkcs10',
'requestor_name': 'IPA Installer', 'requestor_name': 'IPA Installer',
'cert_request': csr, 'cert_request': csr,
'xmlOutput': 'true'} 'xmlOutput': 'true'}
# Send the request to the CA # Send the request to the CA
f = open(self.passwd_fname, "r") f = open(self.passwd_fname, "r")
password = f.readline() password = f.readline()
f.close() f.close()
result = dogtag.https_request( result = dogtag.https_request(
self.host_name, self.host_name,
api.env.ca_ee_install_port or api.env.ca_ee_install_port or
dogtag.configured_constants().EE_SECURE_PORT, dogtag.configured_constants().EE_SECURE_PORT,
"/ca/ee/ca/profileSubmitSSLClient", "/ca/ee/ca/profileSubmitSSLClient",
self.secdir, password, "ipaCert", **params) self.secdir, password, "ipaCert", **params)
http_status, http_reason_phrase, http_headers, http_body = result http_status, http_reason_phrase, http_headers, http_body = result
if http_status != 200: if http_status != 200:
raise CertificateOperationError( raise CertificateOperationError(
error=_('Unable to communicate with CMS (%s)') % error=_('Unable to communicate with CMS (%s)') %
http_reason_phrase) http_reason_phrase)
# The result is an XML blob. Pull the certificate out of that # The result is an XML blob. Pull the certificate out of that
doc = xml.dom.minidom.parseString(http_body) doc = xml.dom.minidom.parseString(http_body)
item_node = doc.getElementsByTagName("b64") item_node = doc.getElementsByTagName("b64")
try:
try: try:
try: cert = item_node[0].childNodes[0].data
cert = item_node[0].childNodes[0].data except IndexError:
except IndexError: raise RuntimeError("Certificate issuance failed")
raise RuntimeError("Certificate issuance failed") finally:
finally: doc.unlink()
doc.unlink()
# base64-decode the result for uniformity # base64-decode the result for uniformity
cert = base64.b64decode(cert) cert = base64.b64decode(cert)
# Write the certificate to a file. It will be imported in a later # Write the certificate to a file. It will be imported in a later
# step. This file will be read later to be imported. # step. This file will be read later to be imported.
f = open(cert_fname, "w") f = open(cert_fname, "w")
f.write(cert) f.write(cert)
f.close() f.close()
return
def issue_signing_cert(self, certreq_fname, cert_fname): def issue_signing_cert(self, certreq_fname, cert_fname):
self.setup_cert_request() self.setup_cert_request()
if self.self_signed_ca:
p = subprocess.Popen(["/usr/bin/certutil",
"-d", self.secdir,
"-C", "-c", self.cacert_name,
"-i", certreq_fname,
"-o", cert_fname,
"-m", next_serial(),
"-v", self.valid_months,
"-f", self.passwd_fname,
"-1", "-5"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
# Bah - this sucks, but I guess it isn't possible to fully if self.host_name is None:
# control this with command line arguments. raise RuntimeError("CA Host is not set.")
#
# What this is requesting is:
# -1 (Create key usage extension)
# 0 - Digital Signature
# 5 - Cert signing key
# 9 - done
# n - not critical
#
# -5 (Create netscape cert type extension)
# 3 - Object Signing
# 9 - done
# n - not critical
p.stdin.write("0\n5\n9\nn\n3\n9\nn\n")
p.wait()
else:
if self.host_name is None:
raise RuntimeError("CA Host is not set.")
f = open(certreq_fname, "r") f = open(certreq_fname, "r")
csr = f.readlines() csr = f.readlines()
f.close() f.close()
csr = "".join(csr) csr = "".join(csr)
# We just want the CSR bits, make sure there is no thing else # We just want the CSR bits, make sure there is no thing else
csr = pkcs10.strip_header(csr) csr = pkcs10.strip_header(csr)
params = {'profileId': 'caJarSigningCert', params = {'profileId': 'caJarSigningCert',
'cert_request_type': 'pkcs10', 'cert_request_type': 'pkcs10',
'requestor_name': 'IPA Installer', 'requestor_name': 'IPA Installer',
'cert_request': csr, 'cert_request': csr,
'xmlOutput': 'true'} 'xmlOutput': 'true'}
# Send the request to the CA # Send the request to the CA
f = open(self.passwd_fname, "r") f = open(self.passwd_fname, "r")
password = f.readline() password = f.readline()
f.close() f.close()
result = dogtag.https_request( result = dogtag.https_request(
self.host_name, self.host_name,
api.env.ca_ee_install_port or api.env.ca_ee_install_port or
dogtag.configured_constants().EE_SECURE_PORT, dogtag.configured_constants().EE_SECURE_PORT,
"/ca/ee/ca/profileSubmitSSLClient", "/ca/ee/ca/profileSubmitSSLClient",
self.secdir, password, "ipaCert", **params) self.secdir, password, "ipaCert", **params)
http_status, http_reason_phrase, http_headers, http_body = result http_status, http_reason_phrase, http_headers, http_body = result
if http_status != 200: if http_status != 200:
raise RuntimeError("Unable to submit cert request") raise RuntimeError("Unable to submit cert request")
# The result is an XML blob. Pull the certificate out of that # The result is an XML blob. Pull the certificate out of that
doc = xml.dom.minidom.parseString(http_body) doc = xml.dom.minidom.parseString(http_body)
item_node = doc.getElementsByTagName("b64") item_node = doc.getElementsByTagName("b64")
cert = item_node[0].childNodes[0].data cert = item_node[0].childNodes[0].data
doc.unlink() doc.unlink()
# base64-decode the cert for uniformity # base64-decode the cert for uniformity
cert = base64.b64decode(cert) cert = base64.b64decode(cert)
# Write the certificate to a file. It will be imported in a later # Write the certificate to a file. It will be imported in a later
# step. This file will be read later to be imported. # step. This file will be read later to be imported.
f = open(cert_fname, "w") f = open(cert_fname, "w")
f.write(cert) f.write(cert)
f.close() f.close()
return
def add_cert(self, cert_fname, nickname): def add_cert(self, cert_fname, nickname):
""" """
@ -1020,48 +774,11 @@ class CertDB(object):
""" """
root_nicknames = self.nssdb.get_trust_chain(nickname) root_nicknames = self.nssdb.get_trust_chain(nickname)
# Try to work around a change in the F-11 certutil where untrusted
# CA's are not shown in the chain. This will make a default IPA
# server installable.
if len(root_nicknames) == 0 and self.self_signed_ca:
return [self.cacert_name]
return root_nicknames return root_nicknames
def find_root_cert_from_pkcs12(self, pkcs12_fname, passwd_fname=None): def find_root_cert_from_pkcs12(self, pkcs12_fname, passwd_fname=None):
"""Given a PKCS#12 file, try to find any certificates that do return self.nssdb.find_root_cert_from_pkcs12(pkcs12_fname,
not have a key. The assumption is that these are the root CAs. passwd_fname=passwd_fname)
"""
args = ["/usr/bin/pk12util", "-d", self.secdir,
"-l", pkcs12_fname,
"-k", passwd_fname]
if passwd_fname:
args = args + ["-w", passwd_fname]
try:
(stdout, stderr, returncode) = ipautil.run(args)
except ipautil.CalledProcessError, e:
if e.returncode == 17:
raise RuntimeError("incorrect password")
else:
raise RuntimeError("unknown error using pkcs#12 file")
lines = stdout.split('\n')
# A simple state machine.
# 1 = looking for "Certificate:"
# 2 = looking for the Friendly name (nickname)
nicknames = []
state = 1
for line in lines:
if state == 2:
m = re.match("\W+Friendly Name: (.*)", line)
if m:
nicknames.append( m.groups(0)[0])
state = 1
if line == "Certificate:":
state = 2
return nicknames
def trust_root_cert(self, root_nickname): def trust_root_cert(self, root_nickname):
if root_nickname is None: if root_nickname is None:
@ -1097,14 +814,6 @@ class CertDB(object):
"-in", pem_fname, "-out", pkcs12_fname, "-in", pem_fname, "-out", pkcs12_fname,
"-passout", "file:" + pkcs12_pwd_fname]) "-passout", "file:" + pkcs12_pwd_fname])
def create_self_signed(self, passwd=None):
self.create_noise_file()
self.create_passwd_file(passwd)
self.create_certdbs()
self.create_ca_cert()
self.export_ca_cert(self.cacert_name, True)
self.create_pin_file()
def create_from_cacert(self, cacert_fname, passwd=None): def create_from_cacert(self, cacert_fname, passwd=None):
if ipautil.file_exists(self.certdb_fname): if ipautil.file_exists(self.certdb_fname):
# We already have a cert db, see if it is for the same CA. # We already have a cert db, see if it is for the same CA.
@ -1167,94 +876,6 @@ class CertDB(object):
self.create_pin_file() self.create_pin_file()
self.export_ca_cert(nickname, False) self.export_ca_cert(nickname, False)
self.self_signed_ca=False
# This file implies that we have our own self-signed CA. Ensure
# that it no longer exists (from previous installs, for example).
try:
os.remove(CA_SERIALNO)
except:
pass
def create_kdc_cert(self, nickname, hostname, destdir):
"""Create a new certificate with the spcial othername encoding needed
by a KDC certificate.
nickname: the CN name set in the certificate
destdir: the location where cert and key are to be installed
destdir will contain kdc.pem if the operation is successful
"""
reqcfg = "kdc_req.conf"
extcfg = ipautil.SHARE_DIR + "kdc_extensions.template"
key_fname = destdir + "/kdckey.pem"
cert_fname = destdir + "/kdccert.pem"
key_cert_fname = destdir + "/kdc.pem"
# Setup the temp dir
self.setup_cert_request()
# Copy the CA password file because openssl apparently can't use
# the same file twice within the same command and throws an error
ca_pwd_file = self.reqdir + "pwdfile.txt"
shutil.copyfile(self.passwd_fname, ca_pwd_file)
# Extract the cacert.pem file used by openssl to sign the certs
ipautil.run(["/usr/bin/openssl", "pkcs12",
"-in", self.pk12_fname,
"-passin", "file:" + self.passwd_fname,
"-passout", "file:" + ca_pwd_file,
"-out", "cacert.pem"])
# Create the kdc key
ipautil.run(["/usr/bin/openssl", "genrsa",
"-out", key_fname, "2048"])
# Prepare a simple cert request
req_dict = dict(PASSWORD=self.gen_password(),
SUBJBASE=self.subject_base,
CERTNAME=DN(('CN', nickname)))
req_template = ipautil.SHARE_DIR + reqcfg + ".template"
conf = ipautil.template_file(req_template, req_dict)
fd = open(reqcfg, "w+")
fd.write(conf)
fd.close()
base = str(self.subject_base).replace(",", "/")
esc_subject = DN(('CN', '%s/%s' % (nickname, base)))
ipautil.run(["/usr/bin/openssl", "req", "-new",
"-config", reqcfg,
"-subj", str(esc_subject),
"-key", key_fname,
"-out", "kdc.req"])
# Finally, sign the cert using the extensions file to set the
# special name
ipautil.run(["/usr/bin/openssl", "x509", "-req",
"-CA", "cacert.pem",
"-extfile", extcfg,
"-extensions", "kdc_cert",
"-passin", "file:" + ca_pwd_file,
"-set_serial", next_serial(),
"-in", "kdc.req",
"-out", cert_fname],
env = { 'REALM':self.realm, 'HOST_FQDN':hostname })
# Merge key and cert in a single file
fd = open(key_fname, "r")
key = fd.read()
fd.close()
fd = open(cert_fname, "r")
cert = fd.read()
fd.close()
fd = open(key_cert_fname, "w")
fd.write(key)
fd.write(cert)
fd.close()
os.unlink(key_fname)
os.unlink(cert_fname)
def install_pem_from_p12(self, p12_fname, p12_pwd_fname, pem_fname): def install_pem_from_p12(self, p12_fname, p12_pwd_fname, pem_fname):
ipautil.run(["/usr/bin/openssl", "pkcs12", "-nodes", ipautil.run(["/usr/bin/openssl", "pkcs12", "-nodes",

View File

@ -36,7 +36,7 @@ import certs
import ldap import ldap
from ipaserver.install import ldapupdate from ipaserver.install import ldapupdate
from ipaserver.install import replication from ipaserver.install import replication
from ipalib import errors, api from ipalib import errors
from ipapython.dn import DN from ipapython.dn import DN
SERVER_ROOT_64 = "/usr/lib64/dirsrv" SERVER_ROOT_64 = "/usr/lib64/dirsrv"
@ -228,8 +228,7 @@ class DsInstance(service.Service):
self.step("configuring directory to start on boot", self.__enable) self.step("configuring directory to start on boot", self.__enable)
def init_info(self, realm_name, fqdn, domain_name, dm_password, def init_info(self, realm_name, fqdn, domain_name, dm_password,
self_signed_ca, subject_base, idstart, idmax, pkcs12_info, subject_base, idstart, idmax, pkcs12_info, ca_file=None):
ca_file=None):
self.realm_name = realm_name.upper() self.realm_name = realm_name.upper()
self.serverid = realm_to_serverid(self.realm_name) self.serverid = realm_to_serverid(self.realm_name)
self.suffix = ipautil.realm_to_suffix(self.realm_name) self.suffix = ipautil.realm_to_suffix(self.realm_name)
@ -237,7 +236,6 @@ class DsInstance(service.Service):
self.dm_password = dm_password self.dm_password = dm_password
self.domain = domain_name self.domain = domain_name
self.principal = "ldap/%s@%s" % (self.fqdn, self.realm_name) self.principal = "ldap/%s@%s" % (self.fqdn, self.realm_name)
self.self_signed_ca = False
self.subject_base = subject_base self.subject_base = subject_base
self.idstart = idstart self.idstart = idstart
self.idmax = idmax self.idmax = idmax
@ -247,11 +245,11 @@ class DsInstance(service.Service):
self.__setup_sub_dict() self.__setup_sub_dict()
def create_instance(self, realm_name, fqdn, domain_name, def create_instance(self, realm_name, fqdn, domain_name,
dm_password, pkcs12_info=None, self_signed_ca=False, dm_password, pkcs12_info=None,
idstart=1100, idmax=999999, subject_base=None, idstart=1100, idmax=999999, subject_base=None,
hbac_allow=True, ca_file=None): hbac_allow=True, ca_file=None):
self.init_info( self.init_info(
realm_name, fqdn, domain_name, dm_password, self_signed_ca, realm_name, fqdn, domain_name, dm_password,
subject_base, idstart, idmax, pkcs12_info, ca_file=ca_file) subject_base, idstart, idmax, pkcs12_info, ca_file=ca_file)
self.__common_setup() self.__common_setup()
@ -282,7 +280,7 @@ class DsInstance(service.Service):
idmax = 1100 idmax = 1100
self.init_info( self.init_info(
realm_name, fqdn, domain_name, dm_password, None, None, realm_name, fqdn, domain_name, dm_password, None,
idstart, idmax, pkcs12_info, ca_file=ca_file) idstart, idmax, pkcs12_info, ca_file=ca_file)
self.master_fqdn = master_fqdn self.master_fqdn = master_fqdn
@ -545,30 +543,21 @@ class DsInstance(service.Service):
# We only handle one server cert # We only handle one server cert
nickname = server_certs[0][0] nickname = server_certs[0][0]
self.dercert = dsdb.get_cert_from_db(nickname, pem=False) self.dercert = dsdb.get_cert_from_db(nickname, pem=False)
if api.env.enable_ra: dsdb.track_server_cert(nickname, self.principal, dsdb.passwd_fname,
dsdb.track_server_cert( 'restart_dirsrv %s' % self.serverid)
nickname, self.principal, dsdb.passwd_fname,
'restart_dirsrv %s' % self.serverid)
else: else:
nickname = self.nickname nickname = self.nickname
cadb = certs.CertDB(self.realm_name, host_name=self.fqdn, subject_base=self.subject_base) cadb = certs.CertDB(self.realm_name, host_name=self.fqdn, subject_base=self.subject_base)
if self.self_signed_ca:
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None) # FIXME, need to set this nickname in the RA plugin
self.dercert = dsdb.create_server_cert(nickname, self.fqdn, cadb) cadb.export_ca_cert('ipaCert', False)
dsdb.track_server_cert( dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
nickname, self.principal, dsdb.passwd_fname, self.dercert = dsdb.create_server_cert(
'restart_dirsrv %s' % self.serverid) nickname, self.fqdn, cadb)
dsdb.create_pin_file() dsdb.track_server_cert(
else: nickname, self.principal, dsdb.passwd_fname,
# FIXME, need to set this nickname in the RA plugin 'restart_dirsrv %s' % self.serverid)
cadb.export_ca_cert('ipaCert', False) dsdb.create_pin_file()
dsdb.create_from_cacert(cadb.cacert_fname, passwd=None)
self.dercert = dsdb.create_server_cert(
nickname, self.fqdn, cadb)
dsdb.track_server_cert(
nickname, self.principal, dsdb.passwd_fname,
'restart_dirsrv %s' % self.serverid)
dsdb.create_pin_file()
conn = ipaldap.IPAdmin(self.fqdn) conn = ipaldap.IPAdmin(self.fqdn)
conn.do_simple_bind(DN(('cn', 'directory manager')), self.dm_password) conn.do_simple_bind(DN(('cn', 'directory manager')), self.dm_password)

View File

@ -63,15 +63,13 @@ class HTTPInstance(service.Service):
def create_instance(self, realm, fqdn, domain_name, dm_password=None, def create_instance(self, realm, fqdn, domain_name, dm_password=None,
autoconfig=True, pkcs12_info=None, autoconfig=True, pkcs12_info=None,
self_signed_ca=False, subject_base=None, subject_base=None, auto_redirect=True, ca_file=None):
auto_redirect=True, ca_file=None):
self.fqdn = fqdn self.fqdn = fqdn
self.realm = realm self.realm = realm
self.domain = domain_name self.domain = domain_name
self.dm_password = dm_password self.dm_password = dm_password
self.suffix = ipautil.realm_to_suffix(self.realm) self.suffix = ipautil.realm_to_suffix(self.realm)
self.pkcs12_info = pkcs12_info self.pkcs12_info = pkcs12_info
self.self_signed_ca = self_signed_ca
self.principal = "HTTP/%s@%s" % (self.fqdn, self.realm) self.principal = "HTTP/%s@%s" % (self.fqdn, self.realm)
self.dercert = None self.dercert = None
self.subject_base = subject_base self.subject_base = subject_base
@ -237,9 +235,7 @@ class HTTPInstance(service.Service):
print "Adding Include conf.d/ipa-rewrite to %s failed." % NSS_CONF print "Adding Include conf.d/ipa-rewrite to %s failed." % NSS_CONF
def __setup_ssl(self): def __setup_ssl(self):
fqdn = None fqdn = self.fqdn
if not self.self_signed_ca:
fqdn = self.fqdn
ca_db = certs.CertDB(self.realm, host_name=fqdn, subject_base=self.subject_base) ca_db = certs.CertDB(self.realm, host_name=fqdn, subject_base=self.subject_base)
@ -262,8 +258,6 @@ class HTTPInstance(service.Service):
self.__set_mod_nss_nickname(nickname) self.__set_mod_nss_nickname(nickname)
else: else:
if self.self_signed_ca:
db.create_from_cacert(ca_db.cacert_fname)
db.create_password_conf() db.create_password_conf()
self.dercert = db.create_server_cert(self.cert_nickname, self.fqdn, self.dercert = db.create_server_cert(self.cert_nickname, self.fqdn,
@ -288,13 +282,6 @@ class HTTPInstance(service.Service):
ipaservices.restore_context(certs.NSS_DIR + "/cert8.db") ipaservices.restore_context(certs.NSS_DIR + "/cert8.db")
ipaservices.restore_context(certs.NSS_DIR + "/key3.db") ipaservices.restore_context(certs.NSS_DIR + "/key3.db")
# In case this got generated as part of the install, reset the
# context
if ipautil.file_exists(certs.CA_SERIALNO):
ipaservices.restore_context(certs.CA_SERIALNO)
os.chown(certs.CA_SERIALNO, 0, pent.pw_gid)
os.chmod(certs.CA_SERIALNO, 0664)
def __setup_autoconfig(self): def __setup_autoconfig(self):
target_fname = '/usr/share/ipa/html/preferences.html' target_fname = '/usr/share/ipa/html/preferences.html'
ipautil.copy_template_file( ipautil.copy_template_file(

View File

@ -130,13 +130,6 @@ class ReplicaPrepare(admintool.AdminTool):
if api.env.host == self.replica_fqdn: if api.env.host == self.replica_fqdn:
raise admintool.ScriptError("You can't create a replica on itself") raise admintool.ScriptError("You can't create a replica on itself")
# FIXME: certs.ipa_self_signed_master return value can be
# True, False, None, with different meanings.
# So, we need to explicitly compare to False
if certs.ipa_self_signed_master() == False:
raise admintool.ScriptError("A selfsign CA backend can only "
"prepare on the original master")
if not api.env.enable_ra and not options.http_pkcs12: if not api.env.enable_ra and not options.http_pkcs12:
raise admintool.ScriptError( raise admintool.ScriptError(
"Cannot issue certificates: a CA is not installed. Use the " "Cannot issue certificates: a CA is not installed. Use the "
@ -227,8 +220,7 @@ class ReplicaPrepare(admintool.AdminTool):
options.reverse_zone, options.ip_address): options.reverse_zone, options.ip_address):
raise admintool.ScriptError("Invalid reverse zone") raise admintool.ScriptError("Invalid reverse zone")
if (not certs.ipa_self_signed() and if (not ipautil.file_exists(
not ipautil.file_exists(
dogtag.configured_constants().CS_CFG_PATH) and dogtag.configured_constants().CS_CFG_PATH) and
not options.dirsrv_pin): not options.dirsrv_pin):
self.log.info("If you installed IPA with your own certificates " self.log.info("If you installed IPA with your own certificates "
@ -281,17 +273,17 @@ class ReplicaPrepare(admintool.AdminTool):
options.dirsrv_pkcs12) options.dirsrv_pkcs12)
self.copy_info_file(options.dirsrv_pkcs12, "dscert.p12") self.copy_info_file(options.dirsrv_pkcs12, "dscert.p12")
else: else:
if not certs.ipa_self_signed(): if ipautil.file_exists(options.ca_file):
if ipautil.file_exists(options.ca_file): self.copy_info_file(options.ca_file, "cacert.p12")
self.copy_info_file(options.ca_file, "cacert.p12") else:
else: raise admintool.ScriptError("Root CA PKCS#12 not "
raise admintool.ScriptError("Root CA PKCS#12 not " "found in %s" % options.ca_file)
"found in %s" % options.ca_file)
self.log.info( self.log.info(
"Creating SSL certificate for the Directory Server") "Creating SSL certificate for the Directory Server")
self.export_certdb("dscert", passwd_fname) self.export_certdb("dscert", passwd_fname)
if not options.dirsrv_pkcs12 and not certs.ipa_self_signed(): if not options.dirsrv_pkcs12:
self.log.info( self.log.info(
"Creating SSL certificate for the dogtag Directory Server") "Creating SSL certificate for the dogtag Directory Server")
self.export_certdb("dogtagcert", passwd_fname) self.export_certdb("dogtagcert", passwd_fname)
@ -318,8 +310,7 @@ class ReplicaPrepare(admintool.AdminTool):
self.export_certdb("httpcert", passwd_fname) self.export_certdb("httpcert", passwd_fname)
self.log.info("Exporting RA certificate") self.log.info("Exporting RA certificate")
if not certs.ipa_self_signed(): self.export_ra_pkcs12()
self.export_ra_pkcs12()
def copy_pkinit_certificate(self): def copy_pkinit_certificate(self):
options = self.options options = self.options
@ -464,19 +455,14 @@ class ReplicaPrepare(admintool.AdminTool):
nickname = "Server-Cert" nickname = "Server-Cert"
try: try:
self_signed = certs.ipa_self_signed()
db = certs.CertDB( db = certs.CertDB(
api.env.realm, nssdir=self.dir, subject_base=subject_base) api.env.realm, nssdir=self.dir, subject_base=subject_base)
db.create_passwd_file() db.create_passwd_file()
ca_db = certs.CertDB( ca_db = certs.CertDB(
api.env.realm, host_name=api.env.host, api.env.realm, host_name=api.env.host,
subject_base=subject_base) subject_base=subject_base)
if is_kdc: db.create_from_cacert(ca_db.cacert_fname)
ca_db.create_kdc_cert("KDC-Cert", hostname, self.dir) db.create_server_cert(nickname, hostname, ca_db)
else:
db.create_from_cacert(ca_db.cacert_fname)
db.create_server_cert(nickname, hostname, ca_db)
pkcs12_fname = os.path.join(self.dir, fname + ".p12") pkcs12_fname = os.path.join(self.dir, fname + ".p12")

View File

@ -81,7 +81,6 @@ class KrbInstance(service.Service):
self.kdc_password = None self.kdc_password = None
self.sub_dict = None self.sub_dict = None
self.pkcs12_info = None self.pkcs12_info = None
self.self_signed_ca = None
if fstore: if fstore:
self.fstore = fstore self.fstore = fstore
@ -158,10 +157,9 @@ class KrbInstance(service.Service):
self.step("starting the KDC", self.__start_instance) self.step("starting the KDC", self.__start_instance)
self.step("configuring KDC to start on boot", self.__enable) self.step("configuring KDC to start on boot", self.__enable)
def create_instance(self, realm_name, host_name, domain_name, admin_password, master_password, setup_pkinit=False, pkcs12_info=None, self_signed_ca=False, subject_base=None): def create_instance(self, realm_name, host_name, domain_name, admin_password, master_password, setup_pkinit=False, pkcs12_info=None, subject_base=None):
self.master_password = master_password self.master_password = master_password
self.pkcs12_info = pkcs12_info self.pkcs12_info = pkcs12_info
self.self_signed_ca = self_signed_ca
self.subject_base = subject_base self.subject_base = subject_base
self.__common_setup(realm_name, host_name, domain_name, admin_password) self.__common_setup(realm_name, host_name, domain_name, admin_password)
@ -189,9 +187,8 @@ class KrbInstance(service.Service):
master_fqdn, host_name, master_fqdn, host_name,
domain_name, admin_password, domain_name, admin_password,
setup_pkinit=False, pkcs12_info=None, setup_pkinit=False, pkcs12_info=None,
self_signed_ca=False, subject_base=None): subject_base=None):
self.pkcs12_info = pkcs12_info self.pkcs12_info = pkcs12_info
self.self_signed_ca = self_signed_ca
self.subject_base = subject_base self.subject_base = subject_base
self.master_fqdn = master_fqdn self.master_fqdn = master_fqdn
@ -412,23 +409,15 @@ class KrbInstance(service.Service):
self.move_service_to_host(host_principal) self.move_service_to_host(host_principal)
def __setup_pkinit(self): def __setup_pkinit(self):
if self.self_signed_ca: ca_db = certs.CertDB(self.realm, host_name=self.fqdn,
ca_db = certs.CertDB(self.realm, subject_base=self.subject_base)
subject_base=self.subject_base)
else:
ca_db = certs.CertDB(self.realm, host_name=self.fqdn,
subject_base=self.subject_base)
if self.pkcs12_info: if self.pkcs12_info:
ca_db.install_pem_from_p12(self.pkcs12_info[0], ca_db.install_pem_from_p12(self.pkcs12_info[0],
self.pkcs12_info[1], self.pkcs12_info[1],
"/var/kerberos/krb5kdc/kdc.pem") "/var/kerberos/krb5kdc/kdc.pem")
else: else:
if self.self_signed_ca: raise RuntimeError("PKI not supported yet\n")
ca_db.create_kdc_cert("KDC-Cert", self.fqdn,
"/var/kerberos/krb5kdc")
else:
raise RuntimeError("PKI not supported yet\n")
# Finally copy the cacert in the krb directory so we don't # Finally copy the cacert in the krb directory so we don't
# have any selinux issues with the file context # have any selinux issues with the file context

View File

@ -44,11 +44,9 @@ class rabase(Backend):
if api.env.in_tree: if api.env.in_tree:
self.sec_dir = api.env.dot_ipa + os.sep + 'alias' self.sec_dir = api.env.dot_ipa + os.sep + 'alias'
self.pwd_file = self.sec_dir + os.sep + '.pwd' self.pwd_file = self.sec_dir + os.sep + '.pwd'
self.serial_file = self.sec_dir + os.sep + 'ca_serialno'
else: else:
self.sec_dir = "/etc/httpd/alias" self.sec_dir = "/etc/httpd/alias"
self.pwd_file = "/etc/httpd/alias/pwdfile.txt" self.pwd_file = "/etc/httpd/alias/pwdfile.txt"
self.serial_file = certs.CA_SERIALNO
super(rabase, self).__init__() super(rabase, self).__init__()

View File

@ -1,230 +0,0 @@
# Authors:
# Rob Crittenden <rcritten@@redhat.com>
# John Dennis <jdennis@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, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see <http://www.gnu.org/licenses/>.
"""
Backend plugin for RA activities.
The `ra` plugin provides access to the CA to issue, retrieve, and revoke
certificates via the following methods:
* `ra.check_request_status()` - check certificate request status.
* `ra.get_certificate()` - retrieve an existing certificate.
* `ra.request_certificate()` - request a new certificate.
* `ra.revoke_certificate()` - revoke a certificate.
* `ra.take_certificate_off_hold()` - take a certificate off hold.
"""
from ipalib import api, SkipPluginModule
if api.env.ra_plugin != 'selfsign':
# In this case, abort loading this plugin module...
raise SkipPluginModule(reason='selfsign is not selected as RA plugin, it is %s' % api.env.ra_plugin)
from ipalib import Backend
from ipalib import errors
from ipalib import x509
from ipalib import pkcs10
from ipapython.dn import DN, EditableDN, RDN
from ipapython.certdb import get_ca_nickname
import subprocess
import os
import re
from ipaserver.plugins import rabase
from ipaserver.install import certs
import tempfile
from ipalib import _
from ipalib import api
from ipalib.plugins.cert import get_csr_hostname
from nss.error import NSPRError
class ra(rabase.rabase):
"""
Request Authority backend plugin.
"""
def request_certificate(self, csr, request_type='pkcs10'):
"""
:param csr: The certificate signing request.
:param request_type: The request type (defaults to ``'pkcs10'``).
Submit certificate signing request.
The command returns a dict with these possible key/value pairs.
Some key/value pairs may be absent.
+---------------+---------------+---------------+
|result name |result type |comments |
+===============+===============+===============+
|serial_number |unicode [1]_ | |
+---------------+---------------+---------------+
|certificate |unicode [2]_ | |
+---------------+---------------+---------------+
|request_id |unicode | |
+---------------+---------------+---------------+
|subject |unicode | |
+---------------+---------------+---------------+
.. [1] Passed through XMLRPC as decimal string. Can convert to
optimal integer type (int or long) via int(serial_number)
.. [2] Base64 encoded
"""
try:
config = api.Command['config_show']()['result']
subject_base = EditableDN(config.get('ipacertificatesubjectbase')[0])
hostname = get_csr_hostname(csr)
subject_base.insert(0, RDN(('CN', hostname)))
request = pkcs10.load_certificate_request(csr)
# python-nss normalizes the request subject
request_subject = DN(str(pkcs10.get_subject(request)))
if subject_base != request_subject:
raise errors.CertificateOperationError(error=_('Request subject "%(request_subject)s" does not match the form "%(subject_base)s"') % \
{'request_subject' : request_subject, 'subject_base' : subject_base})
except errors.CertificateOperationError, e:
raise e
except NSPRError, e:
raise errors.CertificateOperationError(error=_('unable to decode csr: %s') % e)
# certutil wants the CSR to have have a header and footer. Add one
# if it isn't there.
s = csr.find('-----BEGIN NEW CERTIFICATE REQUEST-----')
if s == -1:
s = csr.find('-----BEGIN CERTIFICATE REQUEST-----')
if s == -1:
csr = '-----BEGIN NEW CERTIFICATE REQUEST-----\n' + csr + \
'\n-----END NEW CERTIFICATE REQUEST-----\n'
try:
(csr_fd, csr_name) = tempfile.mkstemp()
os.write(csr_fd, csr)
os.close(csr_fd)
except Exception, e:
try:
os.remove(csr_name)
except:
pass
self.log.error('unable to create temporary csr file: %s' % e)
raise errors.CertificateOperationError(error=_('file operation'))
try:
(cert_fd, cert_name) = tempfile.mkstemp()
os.close(cert_fd)
except Exception, e:
try:
os.remove(csr_name)
except:
pass
try:
os.remove(cert_name)
except:
pass
self.log.error('unable to create temporary certificate file: %s' % e)
raise errors.CertificateOperationError(error=_('file operation'))
try:
serialno = certs.next_serial(self.serial_file)
except Exception, e:
try:
os.remove(csr_name)
except:
pass
try:
os.remove(cert_name)
except:
pass
self.log.error('next_serial() failed: %s' % e)
raise errors.CertificateOperationError(error=_('cannot obtain next serial number'))
try:
args = [
"/usr/bin/certutil",
"-C",
"-d", self.sec_dir,
"-c", get_ca_nickname(api.env.realm),
"-i", csr_name,
"-o", cert_name,
"-m", str(serialno),
"-v", "60",
"-1",
"-5",
"-6",
"-a",
"-f", self.pwd_file]
self.log.debug("issue cert: %s" % str(args))
p = subprocess.Popen(args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)
p.stdin.write("0\n1\n2\n3\n9\ny\n")
p.stdin.write("0\n9\nn\n")
p.stdin.write("1\n9\nn\n")
(stdout, stderr) = p.communicate()
status = p.returncode
self.log.debug("stdout = %s" % stdout)
self.log.debug("stderr = %s" % stderr)
if status != 0:
try:
os.remove(cert_name)
except:
pass
self.log.error('certutil failed: %s' % stderr)
raise errors.CertificateOperationError(error=_('certutil failure'))
finally:
try:
os.remove(csr_name)
except:
pass
try:
cert_fd = open(cert_name)
cert = cert_fd.read()
cert_fd.close()
finally:
try:
os.remove(cert_name)
except:
pass
try:
subject = x509.get_subject(cert)
serial = x509.get_serial_number(cert)
except NSPRError, e:
self.log.error('Unable to decode certificate in entry: %s' % str(e))
raise errors.CertificateOperationError(
error=_('Unable to decode certificate in entry: %s') % str(e))
# To make it look like dogtag return just the base64 data.
cert = cert.replace('\n','')
cert = cert.replace('\r','')
s = cert.find('-----BEGIN CERTIFICATE-----')
e = cert.find('-----END CERTIFICATE-----')
s = s + 27
cert = cert[s:e]
cmd_result = {}
cmd_result['serial_number'] = unicode(serial) # convert long to decimal unicode string
cmd_result['serial_number_hex'] = u'0x%X' % serial
cmd_result['certificate'] = unicode(cert)
cmd_result['subject'] = unicode(subject)
return cmd_result
api.register(ra)