0000-12-31 18:09:24 -05:50
# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com>
#
# Copyright (C) 2007 Red Hat
# see file 'COPYING' for use and warranty information
#
2010-12-09 06:59:11 -06:00
# 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.
0000-12-31 18:09:24 -05:50
#
# 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
2010-12-09 06:59:11 -06:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
0000-12-31 18:09:24 -05:50
#
0000-12-31 18:09:24 -05:50
import os , stat , subprocess , re
2008-02-05 11:23:53 -06:00
import errno
2008-08-14 17:36:35 -05:00
import tempfile
2008-08-19 15:39:33 -05:00
import shutil
2009-04-13 12:39:15 -05:00
import logging
import urllib
import xml . dom . minidom
2009-04-17 16:17:31 -05:00
import pwd
2009-09-10 15:15:14 -05:00
import fcntl
2009-12-07 22:17:00 -06:00
import base64
0000-12-31 18:09:24 -05:50
2009-04-13 12:39:15 -05:00
from ipapython import nsslib
2010-02-02 21:52:11 -06:00
from ipapython import dogtag
2009-02-05 14:03:08 -06:00
from ipapython import sysrestore
from ipapython import ipautil
2010-08-31 16:21:25 -05:00
from ipapython import certmonger
2010-11-01 12:51:14 -05:00
from ipapython . certdb import get_ca_nickname
2010-05-03 16:38:39 -05:00
from ipalib import pkcs10
2010-09-23 11:09:37 -05:00
from ConfigParser import RawConfigParser , MissingSectionHeaderError
2010-09-08 21:11:31 -05:00
import service
from ipalib import x509
2011-07-11 16:39:30 -05:00
from ipalib . dn import DN
2010-09-20 12:35:32 -05:00
from ipalib . errors import CertificateOperationError
0000-12-31 18:09:24 -05:50
2009-04-13 12:39:15 -05:00
from nss . error import NSPRError
import nss . nss as nss
2009-09-10 15:15:14 -05:00
from ipalib import api
2010-09-28 22:10:25 -05:00
from ipalib . compat import sha1
2009-07-23 15:58:21 -05:00
2010-12-08 15:35:12 -06:00
# Apache needs access to this database so we need to create it
# where apache can reach
NSS_DIR = " /etc/httpd/alias "
2008-07-24 13:34:43 -05:00
CA_SERIALNO = " /var/lib/ipa/ca_serialno "
2009-07-10 15:18:16 -05:00
def ipa_self_signed ( ) :
"""
Determine if the current IPA CA is self - signed or using another CA
2009-09-10 15:15:14 -05:00
We do this based on the CA plugin that is currently in use .
2009-07-10 15:18:16 -05:00
"""
2009-09-10 15:15:14 -05:00
if api . env . ra_plugin == ' selfsign ' :
2009-07-10 15:18:16 -05:00
return True
else :
return False
2009-09-10 15:15:14 -05:00
def find_cert_from_txt ( cert , start = 0 ) :
"""
Given a cert blob ( str ) which may or may not contian leading and
trailing text , pull out just the certificate part . This will return
the FIRST cert in a stream of data .
Returns a tuple ( certificate , last position in cert )
"""
s = cert . find ( ' -----BEGIN CERTIFICATE----- ' , start )
e = cert . find ( ' -----END CERTIFICATE----- ' , s )
if e > 0 : e = e + 25
if s < 0 or e < 0 :
raise RuntimeError ( " Unable to find certificate " )
cert = cert [ s : e ]
return ( cert , e )
2011-07-11 16:39:30 -05:00
def get_cert_nickname ( cert ) :
"""
Using the subject from cert come up with a nickname suitable
for NSS . The caller can decide whether to use just the RDN
or the whole subject .
2011-07-28 13:32:26 -05:00
Returns a tuple of ( rdn , subject_dn ) when rdn is the string
representation of the first RDN in the subject and subject_dn
is a DN object .
2011-07-11 16:39:30 -05:00
"""
nsscert = x509 . load_certificate ( cert )
subject = str ( nsscert . subject )
dn = DN ( subject )
2011-07-28 13:32:26 -05:00
return ( str ( dn [ 0 ] ) , dn )
2011-07-11 16:39:30 -05:00
2009-09-10 15:15:14 -05:00
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 ) )
2010-09-23 11:09:37 -05:00
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 )
2009-09-10 15:15:14 -05:00
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 )
0000-12-31 18:09:24 -05:50
class CertDB ( object ) :
2010-12-08 15:35:12 -06:00
def __init__ ( self , realm , nssdir = NSS_DIR , fstore = None , host_name = None , subject_base = None ) :
2009-04-13 12:39:15 -05:00
self . secdir = nssdir
2010-11-01 12:51:14 -05:00
self . realm = realm
0000-12-31 18:09:24 -05:50
self . noise_fname = self . secdir + " /noise.txt "
self . passwd_fname = self . secdir + " /pwdfile.txt "
self . certdb_fname = self . secdir + " /cert8.db "
self . keydb_fname = self . secdir + " /key3.db "
0000-12-31 18:09:24 -05:50
self . secmod_fname = self . secdir + " /secmod.db "
0000-12-31 18:09:24 -05:50
self . cacert_fname = self . secdir + " /cacert.asc "
self . pk12_fname = self . secdir + " /cacert.p12 "
self . pin_fname = self . secdir + " /pin.txt "
2009-04-13 12:39:15 -05:00
self . pwd_conf = " /etc/httpd/conf/password.conf "
2009-09-10 15:15:14 -05:00
self . reqdir = None
self . certreq_fname = None
self . certder_fname = None
2009-04-13 12:39:15 -05:00
self . host_name = host_name
2010-10-29 15:23:21 -05:00
self . subject_base = subject_base
2010-02-03 16:40:18 -06:00
try :
self . cwd = os . getcwd ( )
except OSError , e :
raise RuntimeError ( " Unable to determine the current directory: %s " % str ( e ) )
2009-04-13 12:39:15 -05:00
2009-07-10 15:18:16 -05:00
self . self_signed_ca = ipa_self_signed ( )
2010-10-29 15:23:21 -05:00
if not subject_base :
self . subject_base = " O=IPA "
self . subject_format = " CN= %% s, %s " % self . subject_base
0000-12-31 18:09:24 -05:50
2010-11-01 12:51:14 -05:00
self . cacert_name = get_ca_nickname ( self . realm )
0000-12-31 18:09:24 -05:50
self . valid_months = " 120 "
self . keysize = " 1024 "
0000-12-31 18:09:24 -05:50
# We are going to set the owner of all of the cert
# files to the owner of the containing directory
# instead of that of the process. This works when
# this is called by root for a daemon that runs as
# a normal user
mode = os . stat ( self . secdir )
self . uid = mode [ stat . ST_UID ]
self . gid = mode [ stat . ST_GID ]
2008-03-27 18:01:38 -05:00
if fstore :
self . fstore = fstore
else :
self . fstore = sysrestore . FileStore ( ' /var/lib/ipa/sysrestore ' )
2008-08-14 17:36:35 -05:00
def __del__ ( self ) :
2009-09-10 15:15:14 -05:00
if self . reqdir is not None :
shutil . rmtree ( self . reqdir , ignore_errors = True )
2010-01-20 10:26:20 -06:00
try :
os . chdir ( self . cwd )
except :
pass
2008-08-14 17:36:35 -05:00
2009-09-10 15:15:14 -05:00
def setup_cert_request ( self ) :
2009-04-13 12:39:15 -05:00
"""
2009-09-10 15:15:14 -05:00
Create a temporary directory to store certificate requests and
certificates . This should be called before requesting certificates .
2009-04-13 12:39:15 -05:00
2009-09-10 15:15:14 -05:00
This is set outside of __init__ to avoid creating a temporary
directory every time we open a cert DB .
"""
if self . reqdir is not None :
return
2009-04-13 12:39:15 -05:00
2009-09-10 15:15:14 -05:00
self . reqdir = tempfile . mkdtemp ( ' ' , ' ipa- ' , ' /var/lib/ipa ' )
self . certreq_fname = self . reqdir + " /tmpcertreq "
self . certder_fname = self . reqdir + " /tmpcert.der "
2009-04-13 12:39:15 -05:00
2010-01-20 10:26:20 -06:00
# When certutil makes a request it creates a file in the cwd, make
# sure we are in a unique place when this happens
os . chdir ( self . reqdir )
2008-02-05 11:23:53 -06:00
def set_serial_from_pkcs12 ( self ) :
""" A CA cert was loaded from a PKCS#12 file. Set up our serial file """
2009-09-10 15:15:14 -05:00
cur_serial = self . find_cacert_serial ( )
2008-02-05 11:23:53 -06:00
try :
2009-09-10 15:15:14 -05:00
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 ( )
2008-02-05 11:23:53 -06:00
except IOError , e :
raise RuntimeError ( " Unable to increment serial number: %s " % str ( e ) )
2009-04-17 16:17:31 -05:00
def set_perms ( self , fname , write = False , uid = None ) :
if uid :
pent = pwd . getpwnam ( uid )
os . chown ( fname , pent . pw_uid , pent . pw_gid )
else :
os . chown ( fname , self . uid , self . gid )
0000-12-31 18:09:24 -05:50
perms = stat . S_IRUSR
if write :
perms | = stat . S_IWUSR
os . chmod ( fname , perms )
def gen_password ( self ) :
2010-09-28 22:10:25 -05:00
return sha1 ( ipautil . ipa_generate_password ( ) ) . hexdigest ( )
0000-12-31 18:09:24 -05:50
def run_certutil ( self , args , stdin = None ) :
new_args = [ " /usr/bin/certutil " , " -d " , self . secdir ]
new_args = new_args + args
2008-02-05 11:23:53 -06:00
return ipautil . run ( new_args , stdin )
0000-12-31 18:09:24 -05:50
2007-12-12 08:36:32 -06:00
def run_signtool ( self , args , stdin = None ) :
2009-04-17 16:17:31 -05:00
if not self . self_signed_ca :
f = open ( self . passwd_fname , " r " )
password = f . readline ( )
f . close ( )
new_args = [ " /usr/bin/signtool " , " -d " , self . secdir , " -p " , password ]
else :
new_args = [ " /usr/bin/signtool " , " -d " , self . secdir ]
2007-12-12 08:36:32 -06:00
new_args = new_args + args
ipautil . run ( new_args , stdin )
0000-12-31 18:09:24 -05:50
def create_noise_file ( self ) :
2009-04-13 12:39:15 -05:00
if ipautil . file_exists ( self . noise_fname ) :
os . remove ( self . noise_fname )
0000-12-31 18:09:24 -05:50
f = open ( self . noise_fname , " w " )
f . write ( self . gen_password ( ) )
self . set_perms ( self . noise_fname )
2008-07-11 10:34:29 -05:00
def create_passwd_file ( self , passwd = None ) :
0000-12-31 18:09:24 -05:50
ipautil . backup_file ( self . passwd_fname )
f = open ( self . passwd_fname , " w " )
2008-07-11 10:34:29 -05:00
if passwd is not None :
f . write ( " %s \n " % passwd )
0000-12-31 18:09:24 -05:50
else :
2008-07-11 10:34:29 -05:00
f . write ( self . gen_password ( ) )
0000-12-31 18:09:24 -05:50
f . close ( )
self . set_perms ( self . passwd_fname )
def create_certdbs ( self ) :
ipautil . backup_file ( self . certdb_fname )
ipautil . backup_file ( self . keydb_fname )
0000-12-31 18:09:24 -05:50
ipautil . backup_file ( self . secmod_fname )
0000-12-31 18:09:24 -05:50
self . run_certutil ( [ " -N " ,
" -f " , self . passwd_fname ] )
self . set_perms ( self . passwd_fname , write = True )
2009-07-10 15:18:16 -05:00
def list_certs ( self ) :
"""
Return a tuple of tuples containing ( nickname , trust )
"""
p = subprocess . Popen ( [ " /usr/bin/certutil " , " -d " , self . secdir ,
" -L " ] , stdout = subprocess . PIPE )
certs = p . stdout . read ( )
certs = certs . split ( " \n " )
# FIXME, this relies on NSS never changing the formatting of certutil
certlist = [ ]
for cert in certs :
nickname = cert [ 0 : 61 ]
trust = cert [ 61 : ]
if re . match ( r ' \ w+, \ w+, \ w+ ' , trust ) :
certlist . append ( ( nickname . strip ( ) , trust ) )
return tuple ( certlist )
def has_nickname ( self , nickname ) :
"""
Returns True if nickname exists in the certdb , False otherwise .
This could also be done directly with :
certutil - L - d - n < nickname > . . .
"""
certs = self . list_certs ( )
for cert in certs :
if nickname == cert [ 0 ] :
return True
return False
0000-12-31 18:09:24 -05:50
def create_ca_cert ( self ) :
2010-02-03 16:40:18 -06:00
os . chdir ( self . secdir )
2010-11-01 12:51:14 -05:00
subject = " cn= %s Certificate Authority " % self . realm
2009-08-27 15:48:02 -05:00
p = subprocess . Popen ( [ " /usr/bin/certutil " ,
" -d " , self . secdir ,
" -S " , " -n " , self . cacert_name ,
2010-11-01 12:51:14 -05:00
" -s " , subject ,
2009-08-27 15:48:02 -05:00
" -x " ,
" -t " , " CT,,C " ,
2009-09-10 15:15:14 -05:00
" -1 " ,
2009-08-27 15:48:02 -05:00
" -2 " ,
2009-09-10 15:15:14 -05:00
" -5 " ,
" -m " , next_serial ( ) ,
2009-08-27 15:48:02 -05:00
" -v " , self . valid_months ,
" -z " , self . noise_fname ,
" -f " , self . passwd_fname ] ,
stdin = subprocess . PIPE ,
stdout = subprocess . PIPE ,
stderr = subprocess . PIPE )
2009-09-10 15:15:14 -05:00
# 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 \n 1 \n 5 \n 9 \n y \n " )
# Create basic constraint extension
2009-08-27 15:48:02 -05:00
# 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
2009-09-10 15:15:14 -05:00
# 5 6 7 9 n -> SSL, S/MIME, Object signing CA
p . stdin . write ( " y \n \n y \n " )
p . stdin . write ( " 5 \n 6 \n 7 \n 9 \n n \n " )
2009-08-27 15:48:02 -05:00
p . wait ( )
2010-02-03 16:40:18 -06:00
os . chdir ( self . cwd )
0000-12-31 18:09:24 -05:50
2008-07-11 10:34:29 -05:00
def export_ca_cert ( self , nickname , create_pkcs12 = False ) :
2008-02-14 19:39:06 -06:00
""" 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
have the private key to make a PKCS #12 file so we don't need to
do that step . """
0000-12-31 18:09:24 -05:50
# export the CA cert for use with other apps
ipautil . backup_file ( self . cacert_fname )
2009-09-10 15:15:14 -05:00
root_nicknames = self . find_root_cert ( nickname )
fd = open ( self . cacert_fname , " w " )
for root in root_nicknames :
2009-11-30 14:28:09 -06:00
( cert , stderr , returncode ) = self . run_certutil ( [ " -L " , " -n " , root , " -a " ] )
2009-09-10 15:15:14 -05:00
fd . write ( cert )
fd . close ( )
2009-04-17 16:17:31 -05:00
os . chmod ( self . cacert_fname , stat . S_IRUSR | stat . S_IRGRP | stat . S_IROTH )
2008-02-14 19:39:06 -06:00
if create_pkcs12 :
ipautil . backup_file ( self . pk12_fname )
ipautil . run ( [ " /usr/bin/pk12util " , " -d " , self . secdir ,
" -o " , self . pk12_fname ,
2008-07-11 10:34:29 -05:00
" -n " , self . cacert_name ,
2008-02-14 19:39:06 -06:00
" -w " , self . passwd_fname ,
" -k " , self . passwd_fname ] )
self . set_perms ( self . pk12_fname )
0000-12-31 18:09:24 -05:50
def load_cacert ( self , cacert_fname ) :
2009-09-10 15:15:14 -05:00
"""
Load all the certificates from a given file . It is assumed that
this file creates CA certificates .
"""
fd = open ( cacert_fname )
certs = fd . read ( )
fd . close ( )
2011-07-28 13:32:26 -05:00
ca_dn = DN ( ( ' CN ' , ' Certificate Authority ' ) , self . subject_base )
2009-09-10 15:15:14 -05:00
st = 0
while True :
try :
( cert , st ) = find_cert_from_txt ( certs , st )
2011-07-28 13:32:26 -05:00
( rdn , subject_dn ) = get_cert_nickname ( cert )
if subject_dn == ca_dn :
2011-07-11 16:39:30 -05:00
nick = get_ca_nickname ( self . realm )
2009-09-10 15:15:14 -05:00
else :
2011-07-28 13:32:26 -05:00
nick = str ( subject_dn )
2009-09-10 15:15:14 -05:00
self . run_certutil ( [ " -A " , " -n " , nick ,
" -t " , " CT,,C " ,
" -a " ] ,
stdin = cert )
except RuntimeError :
break
2008-02-05 11:23:53 -06:00
2011-06-08 09:54:41 -05:00
def get_cert_from_db ( self , nickname , pem = True ) :
"""
Retrieve a certificate from the current NSS database for nickname .
pem controls whether the value returned PEM or DER - encoded . The
default is the data straight from certutil - a .
"""
2009-04-13 12:39:15 -05:00
try :
args = [ " -L " , " -n " , nickname , " -a " ]
2009-11-30 14:28:09 -06:00
( cert , err , returncode ) = self . run_certutil ( args )
2011-06-08 09:54:41 -05:00
if pem :
return cert
else :
( cert , start ) = find_cert_from_txt ( cert , start = 0 )
2011-06-17 15:47:39 -05:00
cert = x509 . strip_header ( cert )
2011-06-08 09:54:41 -05:00
dercert = base64 . b64decode ( cert )
return dercert
2009-04-13 12:39:15 -05:00
except ipautil . CalledProcessError :
return ' '
2008-02-05 11:23:53 -06:00
def find_cacert_serial ( self ) :
2009-11-30 14:28:09 -06:00
( out , err , returncode ) = self . run_certutil ( [ " -L " , " -n " , self . cacert_name ] )
2008-02-05 11:23:53 -06:00
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 " )
2008-03-27 18:01:38 -05:00
2010-09-08 21:11:31 -05:00
def track_server_cert ( self , nickname , principal , password_file = None ) :
"""
Tell certmonger to track the given certificate nickname .
"""
service . chkconfig_on ( " certmonger " )
service . start ( " certmonger " )
try :
2010-08-31 16:21:25 -05:00
( stdout , stderr , rc ) = certmonger . start_tracking ( nickname , self . secdir , password_file )
except ( ipautil . CalledProcessError , RuntimeError ) , e :
logging . error ( " certmonger failed starting to track certificate: %s " % str ( e ) )
return
2010-09-08 21:11:31 -05:00
service . stop ( " certmonger " )
cert = self . get_cert_from_db ( nickname )
2011-06-17 15:47:39 -05:00
nsscert = x509 . load_certificate ( cert , dbdir = self . secdir )
subject = str ( nsscert . subject )
2010-09-08 21:11:31 -05:00
m = re . match ( ' New tracking request " ( \ d+) " added ' , stdout )
2010-08-31 16:21:25 -05:00
if not m :
logging . error ( ' Didn \' t get new certmonger request, got %s ' % stdout )
raise RuntimeError ( ' certmonger did not issue new tracking request for \' %s \' in \' %s \' . Use \' ipa-getcert list \' to list existing certificates. ' % ( nickname , self . secdir ) )
2010-09-08 21:11:31 -05:00
request_id = m . group ( 1 )
certmonger . add_principal ( request_id , principal )
certmonger . add_subject ( request_id , subject )
service . start ( " certmonger " )
def untrack_server_cert ( self , nickname ) :
"""
Tell certmonger to stop tracking the given certificate nickname .
"""
# Always start certmonger. We can't untrack something if it isn't
# running
service . start ( " certmonger " )
try :
2010-08-31 16:21:25 -05:00
certmonger . stop_tracking ( self . secdir , nickname = nickname )
except ( ipautil . CalledProcessError , RuntimeError ) , e :
logging . error ( " certmonger failed to stop tracking certificate: %s " % str ( e ) )
2010-09-08 21:11:31 -05:00
service . stop ( " certmonger " )
2009-07-10 15:18:16 -05:00
def create_server_cert ( self , nickname , hostname , other_certdb = None , subject = None ) :
2009-04-13 12:39:15 -05:00
"""
other_certdb can mean one of two things , depending on the context .
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 .
2009-07-10 15:18:16 -05:00
You can override the certificate Subject by specifying a subject .
2011-06-08 09:54:41 -05:00
Returns a certificate in DER format .
2009-04-13 12:39:15 -05:00
"""
0000-12-31 18:09:24 -05:50
cdb = other_certdb
if not cdb :
cdb = self
2009-07-10 15:18:16 -05:00
if subject is None :
subject = self . subject_format % hostname
2010-09-08 21:11:31 -05:00
self . request_cert ( subject )
2007-12-12 08:36:32 -06:00
cdb . issue_server_cert ( self . certreq_fname , self . certder_fname )
self . add_cert ( self . certder_fname , nickname )
2009-12-07 22:17:00 -06:00
fd = open ( self . certder_fname , " r " )
dercert = fd . read ( )
fd . close ( )
2007-12-12 08:36:32 -06:00
os . unlink ( self . certreq_fname )
os . unlink ( self . certder_fname )
2008-03-27 18:01:38 -05:00
2009-12-07 22:17:00 -06:00
return dercert
2009-07-10 15:18:16 -05:00
def create_signing_cert ( self , nickname , hostname , other_certdb = None , subject = None ) :
2007-12-12 08:36:32 -06:00
cdb = other_certdb
if not cdb :
cdb = self
2009-07-10 15:18:16 -05:00
if subject is None :
subject = self . subject_format % hostname
2009-04-17 16:17:31 -05:00
self . request_cert ( subject )
2007-12-12 08:36:32 -06:00
cdb . issue_signing_cert ( self . certreq_fname , self . certder_fname )
0000-12-31 18:09:24 -05:50
self . add_cert ( self . certder_fname , nickname )
os . unlink ( self . certreq_fname )
os . unlink ( self . certder_fname )
0000-12-31 18:09:24 -05:50
2009-04-13 12:39:15 -05:00
def request_cert ( self , subject , certtype = " rsa " , keysize = " 2048 " ) :
self . create_noise_file ( )
2009-09-10 15:15:14 -05:00
self . setup_cert_request ( )
2009-04-13 12:39:15 -05:00
args = [ " -R " , " -s " , subject ,
" -o " , self . certreq_fname ,
" -k " , certtype ,
" -g " , keysize ,
" -z " , self . noise_fname ,
" -f " , self . passwd_fname ]
if not self . self_signed_ca :
args . append ( " -a " )
2009-11-30 14:28:09 -06:00
( stdout , stderr , returncode ) = self . run_certutil ( args )
2009-04-13 12:39:15 -05:00
os . remove ( self . noise_fname )
return ( stdout , stderr )
0000-12-31 18:09:24 -05:50
2007-12-12 08:36:32 -06:00
def issue_server_cert ( self , certreq_fname , cert_fname ) :
2009-09-10 15:15:14 -05:00
self . setup_cert_request ( )
2009-04-13 12:39:15 -05:00
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 ,
2009-09-10 15:15:14 -05:00
" -m " , next_serial ( ) ,
2009-04-13 12:39:15 -05:00
" -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
# control this with command line arguments.
#
# 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 \n 9 \n n \n 1 \n 9 \n n \n " )
p . wait ( )
else :
if self . host_name is None :
raise RuntimeError ( " CA Host is not set. " )
0000-12-31 18:09:24 -05:50
2009-04-13 12:39:15 -05:00
f = open ( certreq_fname , " r " )
csr = f . readlines ( )
f . close ( )
csr = " " . join ( csr )
# We just want the CSR bits, make sure there is nothing else
2010-05-03 16:38:39 -05:00
csr = pkcs10 . strip_header ( csr )
2009-04-13 12:39:15 -05:00
2010-02-02 21:52:11 -06:00
params = { ' profileId ' : ' caRAserverCert ' ,
2009-04-13 12:39:15 -05:00
' cert_request_type ' : ' pkcs10 ' ,
' requestor_name ' : ' IPA Installer ' ,
' cert_request ' : csr ,
2010-02-02 21:52:11 -06:00
' xmlOutput ' : ' true ' }
2009-04-13 12:39:15 -05:00
2009-04-17 16:17:31 -05:00
# Send the request to the CA
f = open ( self . passwd_fname , " r " )
2009-04-13 12:39:15 -05:00
password = f . readline ( )
f . close ( )
2010-02-02 21:52:11 -06:00
http_status , http_reason_phrase , http_headers , http_body = \
2010-03-30 14:27:28 -05:00
dogtag . https_request ( self . host_name , api . env . ca_ee_port , " /ca/ee/ca/profileSubmitSSLClient " , self . secdir , password , " ipaCert " , * * params )
2010-02-02 21:52:11 -06:00
if http_status != 200 :
2011-01-25 11:46:26 -06:00
raise CertificateOperationError ( error = ' Unable to communicate with CMS ( %s ) ' % \
2010-02-02 21:52:11 -06:00
http_reason_phrase )
2009-04-13 12:39:15 -05:00
# The result is an XML blob. Pull the certificate out of that
2010-02-02 21:52:11 -06:00
doc = xml . dom . minidom . parseString ( http_body )
2009-04-13 12:39:15 -05:00
item_node = doc . getElementsByTagName ( " b64 " )
2009-09-10 15:15:14 -05:00
try :
try :
cert = item_node [ 0 ] . childNodes [ 0 ] . data
except IndexError :
raise RuntimeError ( " Certificate issuance failed " )
finally :
doc . unlink ( )
2009-04-13 12:39:15 -05:00
2010-02-01 13:00:28 -06:00
# base64-decode the result for uniformity
2010-01-20 10:26:20 -06:00
cert = base64 . b64decode ( cert )
2009-04-13 12:39:15 -05:00
# Write the certificate to a file. It will be imported in a later
2010-02-01 13:00:28 -06:00
# step. This file will be read later to be imported.
2009-04-13 12:39:15 -05:00
f = open ( cert_fname , " w " )
f . write ( cert )
f . close ( )
return
2007-12-12 08:36:32 -06:00
def issue_signing_cert ( self , certreq_fname , cert_fname ) :
2009-09-10 15:15:14 -05:00
self . setup_cert_request ( )
2009-04-17 16:17:31 -05:00
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 ,
2009-09-10 15:15:14 -05:00
" -m " , next_serial ( ) ,
2009-04-17 16:17:31 -05:00
" -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
# control this with command line arguments.
#
# 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 \n 5 \n 9 \n n \n 3 \n 9 \n n \n " )
p . wait ( )
else :
if self . host_name is None :
raise RuntimeError ( " CA Host is not set. " )
f = open ( certreq_fname , " r " )
csr = f . readlines ( )
f . close ( )
csr = " " . join ( csr )
# We just want the CSR bits, make sure there is no thing else
2010-05-03 16:38:39 -05:00
csr = pkcs10 . strip_header ( csr )
2009-04-17 16:17:31 -05:00
2010-02-02 21:52:11 -06:00
params = { ' profileId ' : ' caJarSigningCert ' ,
2009-04-17 16:17:31 -05:00
' cert_request_type ' : ' pkcs10 ' ,
' requestor_name ' : ' IPA Installer ' ,
' cert_request ' : csr ,
2010-02-02 21:52:11 -06:00
' xmlOutput ' : ' true ' }
2009-04-17 16:17:31 -05:00
# Send the request to the CA
f = open ( self . passwd_fname , " r " )
password = f . readline ( )
f . close ( )
2010-02-02 21:52:11 -06:00
http_status , http_reason_phrase , http_headers , http_body = \
2010-03-30 14:27:28 -05:00
dogtag . https_request ( self . host_name , api . env . ca_ee_port , " /ca/ee/ca/profileSubmitSSLClient " , self . secdir , password , " ipaCert " , * * params )
2010-02-02 21:52:11 -06:00
if http_status != 200 :
2009-04-17 16:17:31 -05:00
raise RuntimeError ( " Unable to submit cert request " )
# The result is an XML blob. Pull the certificate out of that
2010-02-02 21:52:11 -06:00
doc = xml . dom . minidom . parseString ( http_body )
2009-04-17 16:17:31 -05:00
item_node = doc . getElementsByTagName ( " b64 " )
cert = item_node [ 0 ] . childNodes [ 0 ] . data
doc . unlink ( )
2010-02-01 13:00:28 -06:00
# base64-decode the cert for uniformity
2010-01-20 10:26:20 -06:00
cert = base64 . b64decode ( cert )
2010-02-01 13:00:28 -06:00
# Write the certificate to a file. It will be imported in a later
# step. This file will be read later to be imported.
2009-04-17 16:17:31 -05:00
f = open ( cert_fname , " w " )
f . write ( cert )
f . close ( )
return
2007-12-12 08:36:32 -06:00
0000-12-31 18:09:24 -05:50
def add_cert ( self , cert_fname , nickname ) :
2009-09-10 15:15:14 -05:00
"""
Load a certificate from a PEM file and add minimal trust .
"""
2009-04-13 12:39:15 -05:00
args = [ " -A " , " -n " , nickname ,
" -t " , " u,u,u " ,
" -i " , cert_fname ,
2009-09-10 15:15:14 -05:00
" -f " , self . passwd_fname ]
2009-04-13 12:39:15 -05:00
self . run_certutil ( args )
0000-12-31 18:09:24 -05:50
def create_pin_file ( self ) :
2009-04-13 12:39:15 -05:00
"""
This is the format of Directory Server pin files .
"""
0000-12-31 18:09:24 -05:50
ipautil . backup_file ( self . pin_fname )
f = open ( self . pin_fname , " w " )
f . write ( " Internal (Software) Token: " )
2009-04-17 16:17:31 -05:00
pwdfile = open ( self . passwd_fname )
f . write ( pwdfile . read ( ) )
0000-12-31 18:09:24 -05:50
f . close ( )
2009-04-17 16:17:31 -05:00
pwdfile . close ( )
0000-12-31 18:09:24 -05:50
self . set_perms ( self . pin_fname )
2009-04-13 12:39:15 -05:00
def create_password_conf ( self ) :
"""
This is the format of mod_nss pin files .
"""
ipautil . backup_file ( self . pwd_conf )
f = open ( self . pwd_conf , " w " )
f . write ( " internal: " )
2009-04-17 16:17:31 -05:00
pwdfile = open ( self . passwd_fname )
f . write ( pwdfile . read ( ) )
2009-04-13 12:39:15 -05:00
f . close ( )
2009-04-17 16:17:31 -05:00
pwdfile . close ( )
self . set_perms ( self . pwd_conf , uid = " apache " )
2009-04-13 12:39:15 -05:00
2008-07-11 10:34:29 -05:00
def find_root_cert ( self , nickname ) :
2009-09-10 15:15:14 -05:00
"""
Given a nickname , return a list of the certificates that make up
the trust chain .
"""
root_nicknames = [ ]
0000-12-31 18:09:24 -05:50
p = subprocess . Popen ( [ " /usr/bin/certutil " , " -d " , self . secdir ,
" -O " , " -n " , nickname ] , stdout = subprocess . PIPE )
chain = p . stdout . read ( )
chain = chain . split ( " \n " )
2009-09-10 15:15:14 -05:00
for c in chain :
m = re . match ( ' \ s* " (.*) " \ [.* ' , c )
if m :
root_nicknames . append ( m . groups ( ) [ 0 ] )
if len ( root_nicknames ) > 1 :
# If you pass in the name of a CA to get the chain it may only
# return 1 (self-signed). Return that.
try :
root_nicknames . remove ( nickname )
except ValueError :
# The nickname wasn't in the list
pass
2009-07-23 11:16:56 -05:00
# 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.
2009-09-10 15:15:14 -05:00
if len ( root_nicknames ) == 0 and self . self_signed_ca :
return [ self . cacert_name ]
0000-12-31 18:09:24 -05:50
2009-09-10 15:15:14 -05:00
return root_nicknames
2008-07-11 10:34:29 -05:00
2009-07-27 20:23:31 -05:00
def find_root_cert_from_pkcs12 ( self , pkcs12_fname , passwd_fname = None ) :
""" Given a PKCS#12 file, try to find any certificates that do
not have a key . The assumption is that these are the root CAs .
"""
args = [ " /usr/bin/pk12util " , " -d " , self . secdir ,
" -l " , pkcs12_fname ,
" -k " , passwd_fname ]
if passwd_fname :
args = args + [ " -w " , passwd_fname ]
try :
2009-11-30 14:28:09 -06:00
( stdout , stderr , returncode ) = ipautil . run ( args )
2009-07-27 20:23:31 -05:00
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
2009-07-24 08:29:33 -05:00
def trust_root_cert ( self , root_nickname ) :
2009-07-23 11:16:56 -05:00
if root_nickname is None :
logging . debug ( " Unable to identify root certificate to trust. Continueing but things are likely to fail. " )
return
if root_nickname [ : 7 ] == " Builtin " :
logging . debug ( " No need to add trust for built-in root CA ' s, skipping %s " % root_nickname )
else :
2010-04-01 13:18:49 -05:00
try :
self . run_certutil ( [ " -M " , " -n " , root_nickname ,
" -t " , " CT,CT, " ] )
except ipautil . CalledProcessError , e :
logging . error ( " Setting trust on %s failed " % root_nickname )
0000-12-31 18:09:24 -05:50
def find_server_certs ( self ) :
p = subprocess . Popen ( [ " /usr/bin/certutil " , " -d " , self . secdir ,
" -L " ] , stdout = subprocess . PIPE )
certs = p . stdout . read ( )
certs = certs . split ( " \n " )
server_certs = [ ]
for cert in certs :
fields = cert . split ( )
if not len ( fields ) :
continue
flags = fields [ - 1 ]
if ' u ' in flags :
name = " " . join ( fields [ 0 : - 1 ] )
2008-07-25 16:06:51 -05:00
# NSS 3.12 added a header to the certutil output
if name == " Certificate Nickname Trust " :
continue
0000-12-31 18:09:24 -05:50
server_certs . append ( ( name , flags ) )
return server_certs
0000-12-31 18:09:24 -05:50
def import_pkcs12 ( self , pkcs12_fname , passwd_fname = None ) :
args = [ " /usr/bin/pk12util " , " -d " , self . secdir ,
" -i " , pkcs12_fname ,
" -k " , self . passwd_fname ]
if passwd_fname :
args = args + [ " -w " , passwd_fname ]
0000-12-31 18:09:24 -05:50
try :
0000-12-31 18:09:24 -05:50
ipautil . run ( args )
0000-12-31 18:09:24 -05:50
except ipautil . CalledProcessError , e :
if e . returncode == 17 :
raise RuntimeError ( " incorrect password " )
else :
raise RuntimeError ( " unknown error import pkcs#12 file " )
2010-11-01 12:51:14 -05:00
def export_pkcs12 ( self , pkcs12_fname , pkcs12_pwd_fname , nickname = None ) :
if nickname is None :
nickname = get_ca_nickname ( api . env . realm )
0000-12-31 18:09:24 -05:50
ipautil . run ( [ " /usr/bin/pk12util " , " -d " , self . secdir ,
" -o " , pkcs12_fname ,
" -n " , nickname ,
" -k " , self . passwd_fname ,
" -w " , pkcs12_pwd_fname ] )
2010-11-03 17:17:36 -05:00
def export_pem_p12 ( self , pkcs12_fname , pkcs12_pwd_fname ,
nickname , pem_fname ) :
ipautil . run ( [ " /usr/bin/openssl " , " pkcs12 " ,
" -export " , " -name " , nickname ,
" -in " , pem_fname , " -out " , pkcs12_fname ,
" -passout " , " file: " + pkcs12_pwd_fname ] )
2008-07-11 10:34:29 -05:00
def create_self_signed ( self , passwd = None ) :
0000-12-31 18:09:24 -05:50
self . create_noise_file ( )
self . create_passwd_file ( passwd )
self . create_certdbs ( )
self . create_ca_cert ( )
2008-07-11 10:34:29 -05:00
self . export_ca_cert ( self . cacert_name , True )
0000-12-31 18:09:24 -05:50
self . create_pin_file ( )
2011-07-17 11:55:54 -05:00
def create_from_cacert ( self , cacert_fname , passwd = None ) :
2009-04-13 12:39:15 -05:00
if ipautil . file_exists ( self . certdb_fname ) :
# We already have a cert db, see if it is for the same CA.
# If it is we leave things as they are.
f = open ( cacert_fname , " r " )
newca = f . readlines ( )
f . close ( )
newca = " " . join ( newca )
2009-09-10 15:15:14 -05:00
( newca , st ) = find_cert_from_txt ( newca )
2009-04-13 12:39:15 -05:00
cacert = self . get_cert_from_db ( self . cacert_name )
if cacert != ' ' :
2009-09-10 15:15:14 -05:00
( cacert , st ) = find_cert_from_txt ( cacert )
2009-04-13 12:39:15 -05:00
if newca == cacert :
return
# The CA certificates are different or something went wrong. Start with
# a new certificate database.
0000-12-31 18:09:24 -05:50
self . create_passwd_file ( passwd )
self . create_certdbs ( )
self . load_cacert ( cacert_fname )
0000-12-31 18:09:24 -05:50
2008-07-11 10:34:29 -05:00
def create_from_pkcs12 ( self , pkcs12_fname , pkcs12_pwd_fname , passwd = None ) :
""" Create a new NSS database using the certificates in a PKCS#12 file.
pkcs12_fname : the filename of the PKCS #12 file
pkcs12_pwd_fname : the file containing the pin for the PKCS #12 file
nickname : the nickname / friendly - name of the cert we are loading
passwd : The password to use for the new NSS database we are creating
2009-07-10 15:18:16 -05:00
The global CA may be added as well in case it wasn ' t included in the
PKCS #12 file. Extra certs won't hurt in any case.
2008-07-11 10:34:29 -05:00
"""
0000-12-31 18:09:24 -05:50
self . create_noise_file ( )
self . create_passwd_file ( passwd )
self . create_certdbs ( )
self . import_pkcs12 ( pkcs12_fname , pkcs12_pwd_fname )
2008-07-11 10:34:29 -05:00
server_certs = self . find_server_certs ( )
if len ( server_certs ) == 0 :
raise RuntimeError ( " Could not find a suitable server cert in import in %s " % pkcs12_fname )
# We only handle one server cert
nickname = server_certs [ 0 ] [ 0 ]
2009-07-24 08:29:33 -05:00
ca_names = self . find_root_cert_from_pkcs12 ( pkcs12_fname , pkcs12_pwd_fname )
if len ( ca_names ) == 0 :
raise RuntimeError ( " Could not find a CA cert in %s " % pkcs12_fname )
self . cacert_name = ca_names [ 0 ]
2009-09-10 15:15:14 -05:00
for ca in ca_names :
self . trust_root_cert ( ca )
2009-07-24 08:29:33 -05:00
0000-12-31 18:09:24 -05:50
self . create_pin_file ( )
2009-09-10 15:15:14 -05:00
self . export_ca_cert ( nickname , False )
2009-04-13 12:39:15 -05:00
self . self_signed_ca = False
2008-07-11 10:34:29 -05:00
# This file implies that we have our own self-signed CA. Ensure
# that it no longer exists (from previous installs, for example).
try :
2008-07-24 13:34:43 -05:00
os . remove ( CA_SERIALNO )
2008-07-11 10:34:29 -05:00
except :
pass
2008-01-14 11:43:26 -06:00
2010-10-29 15:23:21 -05:00
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 = " 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 = self . subject_base . replace ( " , " , " / " )
esc_subject = " CN= %s / %s " % ( nickname , base )
ipautil . run ( [ " /usr/bin/openssl " , " req " , " -new " ,
" -config " , reqcfg ,
" -subj " , 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 )
2010-11-03 17:17:36 -05:00
def install_pem_from_p12 ( self , p12_fname , p12_pwd_fname , pem_fname ) :
ipautil . run ( [ " /usr/bin/openssl " , " pkcs12 " , " -nodes " ,
" -in " , p12_fname , " -out " , pem_fname ,
" -passin " , " file: " + p12_pwd_fname ] )
2008-01-14 11:43:26 -06:00
def backup_files ( self ) :
2008-03-27 18:01:38 -05:00
self . fstore . backup_file ( self . noise_fname )
self . fstore . backup_file ( self . passwd_fname )
self . fstore . backup_file ( self . certdb_fname )
self . fstore . backup_file ( self . keydb_fname )
self . fstore . backup_file ( self . secmod_fname )
self . fstore . backup_file ( self . cacert_fname )
self . fstore . backup_file ( self . pk12_fname )
self . fstore . backup_file ( self . pin_fname )
self . fstore . backup_file ( self . certreq_fname )
self . fstore . backup_file ( self . certder_fname )
2010-12-08 15:35:12 -06:00
def publish_ca_cert ( self , location ) :
shutil . copy ( self . cacert_fname , location )
os . chmod ( location , 0444 )