Exemple #1
0
    def updatecrl(self, pwfile=None):
        """Update the Certificate Revocation List for this CA. It will return
        False if one of the following conditions is met:

        * pwfile was not found (for ca_type == CA_root or CA_INTERMEDIARY)
        * The configuration file could not be found

        :param pwfile:  Path to a file containing the password for the CA key
        :type  pwfile:  str
        :returns:       True if the CRL was created, else False
        :rtype:         bool
        """
        cfg = os.path.abspath(self.ca_data['cfg'])
        crl = os.path.abspath(self.ca_data['crl'])

        if self.ca_data['ca_type'] in [CA_ROOT, CA_INTERMEDIARY]:
            if not pwfile:
                log.warning('Need a password file')
                return False
            else:
                if not os.path.exists(pwfile):
                    return False
        if not os.path.exists(cfg):
            log.warning('{0} does not exist'.format(cfg))
            return False

        log.debug('Updating certificate revocation list for {0} CA'.format(
            self.ca_data['name']
        ))
        cmdline = 'openssl ca -gencrl -config {0} -out {1}'.format(cfg, crl)
        if pwfile:
            cmdline += ' -passin file:{0}'.format(pwfile)
        utils.run(cmdline)
        return os.path.exists(crl)
Exemple #2
0
    def sign_intermediary(self, csr, crt, pwfile, days):
        """Sign an intermediary certificate using this CA. This function will
        return False when:

        * The configuration file for this CA could not be found
        * The CSR could not be found
        * The certificate already exists
        * pwfile could not be found
        * days is not a number

        :param csr:     Path to a file containing the CSR for the intermediary
        :type  csr:     str
        :param crt:     Path to the output certificate
        :type  crt:     str
        :returns:       True if certificate was created, else False
        :rtype:         bool
        """
        cfg = os.path.abspath(self.ca_data['cfg'])

        if not os.path.exists(cfg):
            log.warning('{0} does not exist'.format(cfg))
            return False
        if not os.path.exists(csr):
            log.warning('{0} does not exist'.format(csr))
            return False
        if os.path.exists(crt):
            log.warning('{0} already exists'.format(crt))
            return False
        if not os.path.exists(pwfile):
            log.warning('{0} does not exist'.format(pwfile))
            return False
        try:
            int(days)
        except ValueError:
            log.warning('days needs to be a number')
            return False

        log.debug('Signing intermediary certificate using {0} CA'.format(
            self.ca_data['name']
        ))
        cmdline = 'openssl ca -config {0} -in {1} -out {2} -batch'.format(
            cfg, csr, crt
        )
        cmdline += ' -passin file:{0}'.format(pwfile)
        cmdline += ' -extensions intermediate_ca_ext -enddate {0}'.format(
            utils.gen_enddate(days)
        )
        utils.run(cmdline)
        self.update_cert_db()
        return os.path.exists(crt)
Exemple #3
0
    def genkey(self, cfg, name, pwfile=None):
        """Generate a new key and Certificate Signing Request. Cfg is a path
        pointing towards the configuration file which should be used for the
        CSR. The name is the name which will be used for this certificate. This
        function will return False if one of the following conditions is met:

        * The configuration file could not be found
        * The CSR or key already exists
        * pwfile is missing (if ca_type is CA_ROOT or CA_INTERMEDIARY)

        :param cfg:     Path to the configuration file to be used
        :type  cfg:     str
        :param name:    Name as mentioned in the CN
        :type  name:    str
        :param pwfile:  Path to the file containing the password for the key
        :type  pwfile:  str
        :returns:       True if the key + csr are generated, False if not
        :rtype:         bool
        """
        cfg = os.path.abspath(cfg)
        key = '{0}/private/{1}.key'.format(self.ca_data['basedir'], name)
        csr = '{0}/csr/{1}.csr'.format(self.ca_data['basedir'], name)

        if not os.path.exists(cfg):
            log.warning('{0} does not exist'.format(cfg))
            return False
        if os.path.exists(key):
            log.warning('{0} already exists'.format(key))
            return False
        if os.path.exists(csr):
            log.warning('{0} already exists'.format(csr))
            return False
        if self.ca_data['ca_type'] in [CA_ROOT, CA_INTERMEDIARY]:
            if not pwfile:
                log.warning('Need a password file')
                return False
            else:
                if not os.path.exists(pwfile):
                    return False

        log.debug('Generating key and csr for {0}'.format(name))
        cmdline = 'openssl req -new -config {0} -out {1} -keyout {2}'.format(
            cfg, csr, key
        )

        if pwfile:
            cmdline += ' -passout file:{0}'.format(pwfile)
        utils.run(cmdline)
        return os.path.exists(key)
Exemple #4
0
    def parse_certificate(self, crt):
        """Helper function which parses a certificate and returns the subject,
        fingerprint and serial in a dictionary. It will return False if the
        certificate does not exist.

        :param crt: Path to the certificate
        :type  crt: str
        :returns:   Dictionary containing the certificate details or False
        :rtype:     dict, bool
        """
        if not os.path.exists(crt):
            log.warning('{0} does not exist'.format(crt))
            return False

        cmdline = 'openssl x509 -in {0} -noout'.format(crt)
        cmdline += ' -subject -fingerprint -serial'

        data = {}
        for line in utils.run(cmdline).split('\n'):
            log.debug(line)
            if line.startswith('subject='):
                raw_subject = line.strip().replace('subject= ', '')
                data['subject'] = self.parse_subject(raw_subject)
            elif line.startswith('serial='):
                data['serial'] = line.strip().replace('serial=', '')
            elif line.startswith('SHA1'):
                data['fp'] = line.strip().replace('SHA1 Fingerprint=', '')
        return data
Exemple #5
0
    def selfsign(self, name, pwfile):
        """Self-sign a certificate. It expects the following conditions to be
        true. If one of them is not met, this function will return False:

        * The ca_type is not CA_ROOT
        * pwfile cannot be found
        * The CSR or configuration file cannot be found
        * The certificate already exists

        :param name:        Name as mentioned in the CN
        :type  name:        str
        :returns:           True if the certificate was signed, False if not
        :rtype:             bool
        """
        cfg = os.path.abspath(self.ca_data['cfg'])
        csr = '{0}/csr/{1}.csr'.format(self.ca_data['basedir'], name)
        crt = '{0}/certs/{1}.pem'.format(self.ca_data['basedir'], name)

        if self.ca_data['ca_type'] != CA_ROOT:
            log.warning('{0} CA cannot be self-signed'.format(
                self.ca_data['ca_type']
            ))
            return False
        try:
            open(pwfile, 'r')
        except (TypeError, EnvironmentError):
            log.warning('{0} cannot be read'.format(pwfile))
            return False
        if not os.path.exists(cfg):
            log.warning('{0} does not exist'.format(cfg))
            return False
        if not os.path.exists(csr):
            log.warning('{0} does not exist'.format(csr))
            return False
        if os.path.exists(crt):
            log.warning('{0} already exists'.format(crt))
            return False

        log.debug('Self-signing certificate for {0} CA'.format(name))
        cmdline = 'openssl ca -config {0} -in {1} -out {2} -batch'.format(
            cfg, csr, crt
        )
        cmdline += ' -selfsign -extensions root_ca_ext'
        cmdline += ' -passin file:{0}'.format(pwfile)
        utils.run(cmdline)
        self.update_cert_db()
        return os.path.exists(crt)
Exemple #6
0
    def sign(self, name):
        """Sign a certificate using this CA. Name must be a valid fqdn. This
        function will return False if one of the following conditions is met:

        * Name is invalid
        * The configuration file for this CA could not be found
        * The CSR for name could not be found
        * The certificate for name already exists

        :param name:    Name of the certificate to sign
        :type  name:    str
        :returns:       True if certificate was created, else False
        :rtype:         bool
        """
        cfg = os.path.abspath(self.ca_data['cfg'])
        csr = '{0}/csr/{1}.csr'.format(self.ca_data['basedir'], name)
        crt = '{0}/certs/{1}.pem'.format(self.ca_data['basedir'], name)

        if name is None:
            log.warning('Need a fqdn to sign a certificate for')
            return False
        if name == '':
            log.warning('Fqdn cannot be empty')
            return False
        if not os.path.exists(cfg):
            log.warning('{0} does not exist'.format(cfg))
            return False
        if not os.path.exists(csr):
            log.warning('{0} does not exist'.format(csr))
            return False
        if os.path.exists(crt):
            log.warning('{0} already exists'.format(crt))
            return False

        log.debug('Signing certificate using {0} CA'.format(
            self.ca_data['name']
        ))
        cmdline = 'openssl ca -config {0} -in {1} -out {2}'.format(
            cfg, csr, crt
        )
        cmdline += ' -batch -extensions server_ext'
        utils.run(cmdline)
        self.update_cert_db()
        return os.path.exists(crt)