예제 #1
0
    def generate(self, module):
        """Generate PKCS#12 file archive."""

        self.pkcs12 = crypto.PKCS12()

        if self.ca_certificates:
            ca_certs = [crypto_utils.load_certificate(ca_cert) for ca_cert
                        in self.ca_certificates]
            self.pkcs12.set_ca_certificates(ca_certs)

        if self.certificate_path:
            self.pkcs12.set_certificate(crypto_utils.load_certificate(
                                        self.certificate_path))

        if self.friendly_name:
            self.pkcs12.set_friendlyname(to_bytes(self.friendly_name))

        if self.privatekey_path:
            try:
                self.pkcs12.set_privatekey(crypto_utils.load_privatekey(
                                           self.privatekey_path,
                                           self.privatekey_passphrase)
                                           )
            except crypto_utils.OpenSSLBadPassphraseError as exc:
                raise PkcsError(exc)

        if self.backup:
            self.backup_file = module.backup_local(self.path)
        crypto_utils.write_file(
            module,
            self.pkcs12.export(self.passphrase, self.iter_size, self.maciter_size),
            0o600
        )
예제 #2
0
    def generate(self, module):
        """Generate a keypair."""

        if not self.check(module, perms_required=False,
                          ignore_conversion=True) or self.force:
            # Regenerate
            if self.backup:
                self.backup_file = module.backup_local(self.path)
            self._generate_private_key()
            privatekey_data = self._get_private_key_data()
            crypto_utils.write_file(module, privatekey_data, 0o600)
            self.changed = True
        elif not self.check(
                module, perms_required=False, ignore_conversion=False):
            # Convert
            if self.backup:
                self.backup_file = module.backup_local(self.path)
            privatekey_data = self._get_private_key_data()
            crypto_utils.write_file(module, privatekey_data, 0o600)
            self.changed = True

        self.fingerprint = self._get_fingerprint()
        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #3
0
 def write(self, module, content, mode=None):
     """Write the PKCS#12 file."""
     if self.backup:
         self.backup_file = module.backup_local(self.path)
     crypto_utils.write_file(module, content, mode)
     if self.return_content:
         self.pkcs12_bytes = content
예제 #4
0
    def generate(self, module):
        """Generate the public key."""

        if not os.path.exists(self.privatekey_path):
            raise PublicKeyError('The private key %s does not exist' %
                                 self.privatekey_path)

        if not self.check(module, perms_required=False) or self.force:
            try:
                publickey_content = self._create_publickey(module)

                if self.backup:
                    self.backup_file = module.backup_local(self.path)
                crypto_utils.write_file(module, publickey_content)

                self.changed = True
            except crypto_utils.OpenSSLBadPassphraseError as exc:
                raise PublicKeyError(exc)
            except (IOError, OSError) as exc:
                raise PublicKeyError(exc)

        self.fingerprint = crypto_utils.get_fingerprint(
            self.privatekey_path, self.privatekey_passphrase)
        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #5
0
    def generate(self, module):
        """Generate PKCS#12 file archive."""

        self.pkcs12 = crypto.PKCS12()

        if self.ca_certificates:
            ca_certs = [
                crypto_utils.load_certificate(
                    os.path.expanduser(os.path.expandvars(ca_cert)))
                for ca_cert in self.ca_certificates
            ]
            self.pkcs12.set_ca_certificates(ca_certs)

        if self.certificate_path:
            self.pkcs12.set_certificate(
                crypto_utils.load_certificate(self.certificate_path))

        if self.friendly_name:
            self.pkcs12.set_friendlyname(to_bytes(self.friendly_name))

        if self.privatekey_path:
            self.pkcs12.set_privatekey(
                crypto_utils.load_privatekey(self.privatekey_path,
                                             self.privatekey_passphrase))

        crypto_utils.write_file(
            module,
            self.pkcs12.export(self.passphrase, self.iter_size,
                               self.maciter_size), 0o600)
    def generate(self, module):
        """Generate a keypair."""

        if not self.check(module, perms_required=False) or self.force:
            self.privatekey = crypto.PKey()

            try:
                self.privatekey.generate_key(self.type, self.size)
            except (TypeError, ValueError) as exc:
                raise PrivateKeyError(exc)

            if self.cipher and self.passphrase:
                privatekey_data = crypto.dump_privatekey(
                    crypto.FILETYPE_PEM, self.privatekey, self.cipher,
                    to_bytes(self.passphrase))
            else:
                privatekey_data = crypto.dump_privatekey(
                    crypto.FILETYPE_PEM, self.privatekey)

            crypto_utils.write_file(module, privatekey_data, 0o600)
            self.changed = True

        self.fingerprint = crypto_utils.get_fingerprint(
            self.path, self.passphrase)
        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #7
0
    def generate(self, module):
        '''Generate the certificate signing request.'''

        if not self.check(module, perms_required=False) or self.force:
            req = crypto.X509Req()
            req.set_version(self.version - 1)
            subject = req.get_subject()
            for entry in self.subject:
                if entry[1] is not None:
                    # Workaround for https://github.com/pyca/pyopenssl/issues/165
                    nid = OpenSSL._util.lib.OBJ_txt2nid(to_bytes(entry[0]))
                    if nid == 0:
                        raise CertificateSigningRequestError('Unknown subject field identifier "{0}"'.format(entry[0]))
                    res = OpenSSL._util.lib.X509_NAME_add_entry_by_NID(subject._name, nid, OpenSSL._util.lib.MBSTRING_UTF8, to_bytes(entry[1]), -1, -1, 0)
                    if res == 0:
                        raise CertificateSigningRequestError('Invalid value for subject field identifier "{0}": {1}'.format(entry[0], entry[1]))

            extensions = []
            if self.subjectAltName:
                altnames = ', '.join(self.subjectAltName)
                try:
                    extensions.append(crypto.X509Extension(b"subjectAltName", self.subjectAltName_critical, altnames.encode('ascii')))
                except OpenSSL.crypto.Error as e:
                    raise CertificateSigningRequestError(
                        'Error while parsing Subject Alternative Names {0} (check for missing type prefix, such as "DNS:"!): {1}'.format(
                            ', '.join(["{0}".format(san) for san in self.subjectAltName]), str(e)
                        )
                    )

            if self.keyUsage:
                usages = ', '.join(self.keyUsage)
                extensions.append(crypto.X509Extension(b"keyUsage", self.keyUsage_critical, usages.encode('ascii')))

            if self.extendedKeyUsage:
                usages = ', '.join(self.extendedKeyUsage)
                extensions.append(crypto.X509Extension(b"extendedKeyUsage", self.extendedKeyUsage_critical, usages.encode('ascii')))

            if self.basicConstraints:
                usages = ', '.join(self.basicConstraints)
                extensions.append(crypto.X509Extension(b"basicConstraints", self.basicConstraints_critical, usages.encode('ascii')))

            if self.ocspMustStaple:
                extensions.append(crypto.X509Extension(MUST_STAPLE_NAME, self.ocspMustStaple_critical, MUST_STAPLE_VALUE))

            if extensions:
                req.add_extensions(extensions)

            req.set_pubkey(self.privatekey)
            req.sign(self.privatekey, self.digest)
            self.request = req

            result = crypto.dump_certificate_request(crypto.FILETYPE_PEM, self.request)
            crypto_utils.write_file(module, result)
            self.changed = True

        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #8
0
    def generate(self, module):
        '''Generate the certificate signing request.'''
        if not self.check(module, perms_required=False) or self.force:
            result = self._generate_csr()
            crypto_utils.write_file(module, result)
            self.changed = True

        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #9
0
    def generate(self):
        if not self.check(perms_required=False) or self.force:
            result = self._generate_crl()
            if self.return_content:
                self.crl_content = result
            if self.backup:
                self.backup_file = self.module.backup_local(self.path)
            crypto_utils.write_file(self.module, result)
            self.changed = True

        file_args = self.module.load_file_common_arguments(self.module.params)
        if self.module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #10
0
    def parse(self, module):
        """Read PKCS#12 file."""

        try:
            with open(self.src, 'rb') as pkcs12_fh:
                pkcs12_content = pkcs12_fh.read()
            p12 = crypto.load_pkcs12(pkcs12_content, self.passphrase)
            pkey = crypto.dump_privatekey(crypto.FILETYPE_PEM,
                                          p12.get_privatekey())
            crt = crypto.dump_certificate(crypto.FILETYPE_PEM,
                                          p12.get_certificate())

            crypto_utils.write_file(module, b'%s%s' % (pkey, crt))

        except IOError as exc:
            raise PkcsError(exc)
예제 #11
0
 def _do_generate(self, module):
     """Actually generate the DH params."""
     # Generate parameters
     params = cryptography.hazmat.primitives.asymmetric.dh.generate_parameters(
         generator=2,
         key_size=self.size,
         backend=self.crypto_backend,
     )
     # Serialize parameters
     result = params.parameter_bytes(
         encoding=cryptography.hazmat.primitives.serialization.Encoding.PEM,
         format=cryptography.hazmat.primitives.serialization.ParameterFormat.PKCS3,
     )
     # Write result
     if self.backup:
         self.backup_file = module.backup_local(self.path)
     crypto_utils.write_file(module, result)
    def generate(self, module):

        if not os.path.exists(self.ca_cert_path):
            raise CertificateError(
                'The CA certificate %s does not exist' % self.ca_cert_path
            )

        if not os.path.exists(self.ca_privatekey_path):
            raise CertificateError(
                'The CA private key %s does not exist' % self.ca_privatekey_path
            )

        if not os.path.exists(self.csr_path):
            raise CertificateError(
                'The certificate signing request file %s does not exist' % self.csr_path
            )

        if not self.check(module, perms_required=False) or self.force:
            cert = crypto.X509()
            cert.set_serial_number(self.serial_number)
            if self.notBefore:
                cert.set_notBefore(to_bytes(self.notBefore))
            else:
                cert.gmtime_adj_notBefore(0)
            if self.notAfter:
                cert.set_notAfter(to_bytes(self.notAfter))
            else:
                # If no NotAfter specified, expire in
                # 10 years. 315360000 is 10 years in seconds.
                cert.gmtime_adj_notAfter(315360000)
            cert.set_subject(self.csr.get_subject())
            cert.set_issuer(self.ca_cert.get_subject())
            cert.set_version(self.version - 1)
            cert.set_pubkey(self.csr.get_pubkey())
            cert.add_extensions(self.csr.get_extensions())

            cert.sign(self.ca_privatekey, self.digest)
            self.cert = cert

            crypto_utils.write_file(module, crypto.dump_certificate(crypto.FILETYPE_PEM, self.cert))
            self.changed = True

        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #13
0
    def generate(self, module):
        """Generate the public key."""

        if not os.path.exists(self.privatekey_path):
            raise PublicKeyError('The private key %s does not exist' %
                                 self.privatekey_path)

        if not self.check(module, perms_required=False) or self.force:
            try:
                if self.format == 'OpenSSH':
                    with open(self.privatekey_path, 'rb') as private_key_fh:
                        privatekey_content = private_key_fh.read()
                    key = crypto_serialization.load_pem_private_key(
                        privatekey_content,
                        password=None if self.privatekey_passphrase is None
                        else to_bytes(self.privatekey_passphrase),
                        backend=default_backend())
                    publickey_content = key.public_key().public_bytes(
                        crypto_serialization.Encoding.OpenSSH,
                        crypto_serialization.PublicFormat.OpenSSH)
                else:
                    self.privatekey = crypto_utils.load_privatekey(
                        self.privatekey_path, self.privatekey_passphrase)
                    publickey_content = crypto.dump_publickey(
                        crypto.FILETYPE_PEM, self.privatekey)

                if self.backup:
                    self.backup_file = module.backup_local(self.path)
                crypto_utils.write_file(module, publickey_content)

                self.changed = True
            except crypto_utils.OpenSSLBadPassphraseError as exc:
                raise PublicKeyError(exc)
            except (IOError, OSError) as exc:
                raise PublicKeyError(exc)
            except AttributeError as exc:
                raise PublicKeyError(
                    'You need to have PyOpenSSL>=16.0.0 to generate public keys'
                )

        self.fingerprint = crypto_utils.get_fingerprint(
            self.privatekey_path, self.privatekey_passphrase)
        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
    def generate(self, module):

        if not os.path.exists(self.privatekey_path):
            raise CertificateError(
                'The private key %s does not exist' % self.privatekey_path
            )

        if not os.path.exists(self.csr_path):
            raise CertificateError(
                'The certificate signing request file %s does not exist' % self.csr_path
            )

        if not os.path.exists(self.accountkey_path):
            raise CertificateError(
                'The account key %s does not exist' % self.accountkey_path
            )

        if not os.path.exists(self.challenge_path):
            raise CertificateError(
                'The challenge path %s does not exist' % self.challenge_path
            )

        if not self.check(module, perms_required=False) or self.force:
            acme_tiny_path = self.module.get_bin_path('acme-tiny', required=True)
            chain = ''
            if self.use_chain:
                chain = '--chain'

            try:
                crt = module.run_command("%s %s --account-key %s --csr %s "
                                         "--acme-dir %s" % (acme_tiny_path, chain,
                                                            self.accountkey_path,
                                                            self.csr_path,
                                                            self.challenge_path),
                                         check_rc=True)[1]
                crypto_utils.write_file(module, to_bytes(crt))
                self.changed = True
            except OSError as exc:
                raise CertificateError(exc)

        file_args = module.load_file_common_arguments(module.params)
        if module.set_fs_attributes_if_different(file_args, False):
            self.changed = True
예제 #15
0
    def request_cert(self, module):
        if not self.check(module) or self.force:
            body = {}

            # Read the CSR contents
            if self.csr and os.path.exists(self.csr):
                with open(self.csr, 'r') as csr_file:
                    body['csr'] = csr_file.read()

            # Check if the path is already a cert
            # tracking_id may be set as a parameter or by get_cert_details if an entrust cert is in 'path'. If tracking ID is null
            # We will be performing a reissue operation.
            if self.request_type != 'new' and not self.tracking_id:
                module.warn('No existing Entrust certificate found in path={0} and no tracking_id was provided, setting request_type to "new" for this task'
                            'run. Future playbook runs that point to the pathination file in {1} will use request_type={2}'
                            .format(self.path, self.path, self.request_type))
                self.request_type = 'new'
            elif self.request_type == 'new' and self.tracking_id:
                module.warn('Existing certificate being acted upon, but request_type is "new", so will be a new certificate issuance rather than a'
                            'reissue or renew')
            # Use cases where request type is new and no existing certificate, or where request type is reissue/renew and a valid
            # existing certificate is found, do not need warnings.

            body.update(self.convert_tracking_params(module))
            body.update(self.convert_cert_subject_params(module))
            body.update(self.convert_general_params(module))
            body.update(self.convert_expiry_params(module))

            if not module.check_mode:
                try:
                    if self.request_type == 'validate_only':
                        body['validateOnly'] = 'true'
                        result = self.ecs_client.NewCertRequest(Body=body)
                    if self.request_type == 'new':
                        result = self.ecs_client.NewCertRequest(Body=body)
                    elif self.request_type == 'renew':
                        result = self.ecs_client.RenewCertRequest(trackingId=self.tracking_id, Body=body)
                    elif self.request_type == 'reissue':
                        result = self.ecs_client.ReissueCertRequest(trackingId=self.tracking_id, Body=body)
                    self.tracking_id = result.get('trackingId')
                    self.set_cert_details(module)
                except RestOperationException as e:
                    module.fail_json(msg='Failed to request new certificate from Entrust (ECS) {0}'.format(e.message))

                if self.request_type != 'validate_only':
                    if self.backup:
                        self.backup_file = module.backup_local(self.path)
                    crypto_utils.write_file(module, to_bytes(self.cert_details.get('endEntityCert')))
                    if self.full_chain_path and self.cert_details.get('chainCerts'):
                        if self.backup:
                            self.backup_full_chain_file = module.backup_local(self.full_chain_path)
                        chain_string = '\n'.join(self.cert_details.get('chainCerts')) + '\n'
                        crypto_utils.write_file(module, to_bytes(chain_string), path=self.full_chain_path)
                    self.changed = True
        # If there is no certificate present in path but a tracking ID was specified, save it to disk
        elif not os.path.exists(self.path) and self.tracking_id:
            if not module.check_mode:
                crypto_utils.write_file(module, to_bytes(self.cert_details.get('endEntityCert')))
                if self.full_chain_path and self.cert_details.get('chainCerts'):
                    chain_string = '\n'.join(self.cert_details.get('chainCerts')) + '\n'
                    crypto_utils.write_file(module, to_bytes(chain_string), path=self.full_chain_path)
            self.changed = True