diff options
Diffstat (limited to 'ipaserver/plugins/selfsign.py')
-rw-r--r-- | ipaserver/plugins/selfsign.py | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/ipaserver/plugins/selfsign.py b/ipaserver/plugins/selfsign.py new file mode 100644 index 000000000..4bec0665a --- /dev/null +++ b/ipaserver/plugins/selfsign.py @@ -0,0 +1,126 @@ +# 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 + +""" +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 +import subprocess +import os +from ipaserver.plugins import rabase +from ipaserver.install import certs +import tempfile +from OpenSSL import crypto + +class ra(rabase.rabase): + """ + Request Authority backend plugin. + """ + + def request_certificate(self, csr, request_type='pkcs10'): + """ + Submit certificate signing request. + + :param csr: The certificate signing request. + :param request_type: The request type (defaults to ``'pkcs10'``). + """ + (csr_fd, csr_name) = tempfile.mkstemp() + os.write(csr_fd, csr) + os.close(csr_fd) + (cert_fd, cert_name) = tempfile.mkstemp() + os.close(cert_fd) + + serialno = certs.next_serial(self.serial_file) + + try: + args = [ + "/usr/bin/certutil", + "-C", + "-d", self.sec_dir, + "-c", "CA certificate", + "-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() + self.log.debug("stdout = %s" % stdout) + self.log.debug("stderr = %s" % stderr) + finally: + os.remove(csr_name) + + try: + cert_fd = open(cert_name) + cert = cert_fd.read() + cert_fd.close() + finally: + os.remove(cert_name) + + try: + # Grab the subject, reverse it, combine it and return it + x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert) + sub = x509.get_subject().get_components() + sub.reverse() + subject = "" + for s in sub: + subject = subject + "%s=%s," % (s[0], s[1]) + subject = subject[:-1] + + serial = x509.get_serial_number() + except crypto.Error, e: + raise errors.GenericError(format='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] + + return {'status':0, 'subject': subject, 'certificate':cert, 'serial': "0x%x" % serial} + +api.register(ra) |