def _check_passphrase(self): try: crypto_utils.load_privatekey(self.path, self.passphrase) return True except crypto.Error: return False except crypto_utils.OpenSSLBadPassphraseError as exc: return False
def _check_pkey_passphrase(): if self.privatekey_passphrase: try: crypto_utils.load_privatekey(self.path, self.privatekey_passphrase) except crypto.Error: return False return True
def generate(self, module): """Generate PKCS#12 file archive.""" self.pkcs12 = crypto.PKCS12() if self.other_certificates: other_certs = [ crypto_utils.load_certificate(other_cert) for other_cert in self.other_certificates ] self.pkcs12.set_ca_certificates(other_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) return self.pkcs12.export(self.passphrase, self.iter_size, self.maciter_size)
def _ensure_private_key_loaded(self): """Make sure that the private key has been loaded.""" if self.privatekey is None: try: self.privatekey = privatekey = crypto_utils.load_privatekey(self.path, self.passphrase) except crypto_utils.OpenSSLBadPassphraseError as exc: raise PrivateKeyError(exc)
def _check_privatekey(): if not os.path.exists(self.privatekey_path): return False try: with open(self.path, 'rb') as public_key_fh: publickey_content = public_key_fh.read() if self.format == 'OpenSSH': current_publickey = crypto_serialization.load_ssh_public_key( publickey_content, backend=default_backend()) publickey_content = current_publickey.public_bytes( crypto_serialization.Encoding.PEM, crypto_serialization.PublicFormat.SubjectPublicKeyInfo) current_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto.load_publickey(crypto.FILETYPE_PEM, publickey_content)) except Exception as dummy: return False try: desired_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase)) except crypto_utils.OpenSSLBadPassphraseError as exc: raise PublicKeyError(exc) return current_publickey == desired_publickey
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 )
def run(self, terms, variables=None, **kwargs): if not PYOPENSSL_FOUND: raise AnsibleModuleError('ssl_key_text plugin requires pyOpenSSL') # lookups in general are expected to both take a list as input and output a list # this is done so they work with the looping construct 'with_'. ret = [] for term in terms: display.debug("key lookup term: %s" % term) # Find the file in the expected search path, using a class method # that implements the 'expected' search path for Ansible plugins. lookupfile = self.find_file_in_search_path(variables, 'files', term) # Don't use print or your own logging, the display class # takes care of it in a unified way. display.vvvv(u"key lookup using %s as file" % lookupfile) try: passphrase = kwargs.get('passphrase', None) if passphrase == '': passphrase = None if lookupfile: contents = crypto_utils.load_privatekey(lookupfile, passphrase) text_contents = crypto.dump_privatekey(crypto.FILETYPE_PEM, contents) ret.append(to_text(text_contents)) else: # Always use ansible error classes to throw 'final' exceptions, # so the Ansible engine will know how to deal with them. # The Parser error indicates invalid options passed raise AnsibleParserError() except AnsibleParserError: raise AnsibleError("could not locate file in lookup: %s" % term) return ret
def _check_privatekey(): if not os.path.exists(self.privatekey_path): return False try: publickey_content = open(self.path, 'rb').read() if self.format == 'OpenSSH': current_publickey = crypto_serialization.load_ssh_public_key( publickey_content, backend=default_backend()) publickey_content = current_publickey.public_bytes( crypto_serialization.Encoding.PEM, crypto_serialization.PublicFormat.SubjectPublicKeyInfo) current_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto.load_publickey(crypto.FILETYPE_PEM, publickey_content)) except (crypto.Error, ValueError): return False desired_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase)) return current_publickey == desired_publickey
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 check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(Certificate, self).check(module, perms_required) def _validate_privatekey(): if self.privatekey_path: ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_2_METHOD) ctx.use_privatekey(self.privatekey) ctx.use_certificate(self.cert) try: ctx.check_privatekey() return True except OpenSSL.SSL.Error: return False if not state_and_perms: return False self.cert = crypto_utils.load_certificate(self.path) if self.privatekey_path: self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase ) return _validate_privatekey() return True
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(Certificate, self).check(module, perms_required) def _validate_privatekey(): if self.privatekey_path: ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_2_METHOD) ctx.use_privatekey(self.privatekey) ctx.use_certificate(self.cert) try: ctx.check_privatekey() return True except OpenSSL.SSL.Error: return False if not state_and_perms: return False self.cert = crypto_utils.load_certificate(self.path) if self.privatekey_path: self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase ) return _validate_privatekey() return True
def __init__(self, module): super(SelfSignedCertificate, self).__init__(module) self.notBefore = module.params['selfsigned_notBefore'] self.notAfter = module.params['selfsigned_notAfter'] self.digest = module.params['selfsigned_digest'] self.version = module.params['selfsigned_version'] self.csr = crypto_utils.load_certificate_request(self.csr_path) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase)
def __init__(self, module): super(SelfSignedCertificate, self).__init__(module) self.serial_number = randint(1000, 99999) self.notBefore = module.params['selfsigned_notBefore'] self.notAfter = module.params['selfsigned_notAfter'] self.digest = module.params['selfsigned_digest'] self.csr = crypto_utils.load_certificate_request(self.csr_path) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase) self.cert = None
def _check_size_and_type(self): def _check_size(privatekey): return self.size == privatekey.bits() def _check_type(privatekey): return self.type == privatekey.type() privatekey = crypto_utils.load_privatekey(self.path, self.passphrase) return _check_size(privatekey) and _check_type(privatekey)
def __init__(self, module): super(SelfSignedCertificate, self).__init__(module) self.notBefore = self.get_relative_time_option(module.params['selfsigned_not_before'], 'selfsigned_not_before') self.notAfter = self.get_relative_time_option(module.params['selfsigned_not_after'], 'selfsigned_not_after') self.digest = module.params['selfsigned_digest'] self.version = module.params['selfsigned_version'] self.serial_number = randint(1000, 99999) self.csr = crypto_utils.load_certificate_request(self.csr_path) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase )
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(Certificate, self).check(module, perms_required) def _validate_privatekey(): if self.privatekey_path: ctx = OpenSSL.SSL.Context(OpenSSL.SSL.TLSv1_2_METHOD) ctx.use_privatekey(self.privatekey) ctx.use_certificate(self.cert) try: ctx.check_privatekey() return True except OpenSSL.SSL.Error: return False def _validate_csr(): try: self.csr.verify(self.cert.get_pubkey()) except OpenSSL.crypto.Error: return False if self.csr.get_subject() != self.cert.get_subject(): return False csr_extensions = self.csr.get_extensions() cert_extension_count = self.cert.get_extension_count() if len(csr_extensions) != cert_extension_count: return False for extension_number in range(0, cert_extension_count): cert_extension = self.cert.get_extension(extension_number) csr_extension = filter( lambda extension: extension.get_short_name() == cert_extension.get_short_name(), csr_extensions) if cert_extension.get_data() != list( csr_extension)[0].get_data(): return False return True if not state_and_perms: return False self.cert = crypto_utils.load_certificate(self.path) if self.privatekey_path: self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase) return _validate_privatekey() if self.csr_path: self.csr = crypto_utils.load_certificate_request(self.csr_path) if not _validate_csr(): return False return True
def __init__(self, module): super(SelfSignedCertificate, self).__init__(module) self.notBefore = module.params['selfsigned_notBefore'] self.notAfter = module.params['selfsigned_notAfter'] self.digest = module.params['selfsigned_digest'] self.version = module.params['selfsigned_version'] self.serial_number = randint(1000, 99999) self.csr = crypto_utils.load_certificate_request(self.csr_path) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase )
def _check_size_and_type(self): def _check_size(privatekey): return self.size == privatekey.bits() def _check_type(privatekey): return self.type == privatekey.type() try: privatekey = crypto_utils.load_privatekey(self.path, self.passphrase) except crypto_utils.OpenSSLBadPassphraseError as exc: raise PrivateKeyError(exc) return _check_size(privatekey) and _check_type(privatekey)
def __init__(self, module): super(SelfSignedCertificate, self).__init__(module) self.notBefore = module.params['selfsigned_notBefore'] self.notAfter = module.params['selfsigned_notAfter'] self.digest = module.params['selfsigned_digest'] self.version = module.params['selfsigned_version'] self.csr = crypto_utils.load_certificate_request(self.csr_path) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase) if module.params['provider'] == 'localsigned': self.cacert = crypto_utils.load_certificate( module.params['cacert_path']) else: self.cacert = None
def get_info(self): result = dict( can_load_key=False, can_parse_key=False, key_is_consistent=None, ) if self.content is not None: priv_key_detail = self.content.encode('utf-8') result['can_load_key'] = True else: try: with open(self.path, 'rb') as b_priv_key_fh: priv_key_detail = b_priv_key_fh.read() result['can_load_key'] = True except (IOError, OSError) as exc: self.module.fail_json(msg=to_native(exc), **result) try: self.key = crypto_utils.load_privatekey( path=None, content=priv_key_detail, passphrase=to_bytes(self.passphrase) if self.passphrase is not None else self.passphrase, backend=self.backend) result['can_parse_key'] = True except crypto_utils.OpenSSLObjectError as exc: self.module.fail_json(msg=to_native(exc), **result) result['public_key'] = self._get_public_key(binary=False) pk = self._get_public_key(binary=True) result[ 'public_key_fingerprints'] = crypto_utils.get_fingerprint_of_bytes( pk) if pk is not None else dict() key_type, key_public_data, key_private_data = self._get_key_info() result['type'] = key_type result['public_data'] = key_public_data if self.return_private_key_data: result['private_data'] = key_private_data result['key_is_consistent'] = self._is_key_consistent( key_public_data, key_private_data) if result['key_is_consistent'] is False: # Only fail when it is False, to avoid to fail on None (which means "we don't know") result['key_is_consistent'] = False self.module.fail_json( msg="Private key is not consistent! (See " "https://blog.hboeck.de/archives/888-How-I-tricked-Symantec-with-a-Fake-Private-Key.html)", **result) return result
def __init__(self, module): super(OwnCACertificate, self).__init__(module) self.notBefore = module.params['ownca_not_before'] self.notAfter = module.params['ownca_not_after'] self.digest = module.params['ownca_digest'] self.version = module.params['ownca_version'] self.serial_number = randint(1000, 99999) self.ca_cert_path = module.params['ownca_path'] self.ca_privatekey_path = module.params['ownca_privatekey_path'] self.ca_privatekey_passphrase = module.params['ownca_privatekey_passphrase'] self.csr = crypto_utils.load_certificate_request(self.csr_path) self.ca_cert = crypto_utils.load_certificate(self.ca_cert_path) self.ca_privatekey = crypto_utils.load_privatekey( self.ca_privatekey_path, self.ca_privatekey_passphrase )
def _check_privatekey(): if not os.path.exists(self.privatekey_path): return False current_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto.load_publickey(crypto.FILETYPE_PEM, open(self.path, 'rb').read()) ) desired_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase) ) return hashlib.md5(current_publickey).hexdigest() == hashlib.md5(desired_publickey).hexdigest()
def _check_privatekey(): if not os.path.exists(self.privatekey_path): return False current_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto.load_publickey(crypto.FILETYPE_PEM, open(self.path, 'rb').read())) desired_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase)) return hashlib.md5(current_publickey).hexdigest() == hashlib.md5( desired_publickey).hexdigest()
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) with open(self.path, 'wb') as publickey_file: publickey_file.write(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: self.remove(module) 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): """Generate PKCS#12 file archive.""" self.pkcs12 = crypto.PKCS12() try: self.remove(module) except PkcsError as exc: module.fail_json(msg=to_native(exc)) 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) try: pkcs12_file = os.open(self.path, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, self.mode) os.write( pkcs12_file, self.pkcs12.export(self.passphrase, self.iter_size, self.maciter_size)) os.close(pkcs12_file) except (IOError, OSError) as exc: self.remove(module) raise PkcsError(exc)
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': privatekey_content = open(self.privatekey_path, 'rb').read() key = crypto_serialization.load_pem_private_key(privatekey_content, password=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) with open(self.path, 'wb') as publickey_file: publickey_file.write(publickey_content) self.changed = True except (IOError, OSError) as exc: raise PublicKeyError(exc) except AttributeError as exc: self.remove() 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 _create_publickey(self, module): self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase, backend=self.backend) if self.backend == 'cryptography': if self.format == 'OpenSSH': return self.privatekey.public_key().public_bytes( crypto_serialization.Encoding.OpenSSH, crypto_serialization.PublicFormat.OpenSSH) else: return self.privatekey.public_key().public_bytes( crypto_serialization.Encoding.PEM, crypto_serialization.PublicFormat.SubjectPublicKeyInfo) else: try: return crypto.dump_publickey(crypto.FILETYPE_PEM, self.privatekey) except AttributeError as exc: raise PublicKeyError( 'You need to have PyOpenSSL>=16.0.0 to generate public keys' )
def generate(self, module): '''Generate the certificate signing request.''' if not os.path.exists(self.path) or self.force: req = crypto.X509Req() req.set_version(self.version) subject = req.get_subject() for (key, value) in self.subject.items(): if value is not None: setattr(subject, key, value) if self.subjectAltName is not None: req.add_extensions([ crypto.X509Extension(b"subjectAltName", False, self.subjectAltName.encode('ascii')) ]) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase) req.set_pubkey(self.privatekey) req.sign(self.privatekey, self.digest) self.request = req try: csr_file = open(self.path, 'wb') csr_file.write( crypto.dump_certificate_request(crypto.FILETYPE_PEM, self.request)) csr_file.close() except (IOError, OSError) as exc: raise CertificateSigningRequestError(exc) else: self.changed = False file_args = module.load_file_common_arguments(module.params) if module.set_fs_attributes_if_different(file_args, False): self.changed = True
def _check_privatekey(): if not os.path.exists(self.privatekey_path): return False try: publickey_content = open(self.path, 'rb').read() if self.format == 'OpenSSH': current_publickey = crypto_serialization.load_ssh_public_key(publickey_content, backend=default_backend()) publickey_content = current_publickey.public_bytes(crypto_serialization.Encoding.PEM, crypto_serialization.PublicFormat.SubjectPublicKeyInfo) current_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto.load_publickey(crypto.FILETYPE_PEM, publickey_content) ) except (crypto.Error, ValueError): return False desired_publickey = crypto.dump_publickey( crypto.FILETYPE_ASN1, crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase) ) return current_publickey == desired_publickey
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(PrivateKey, self).check(module, perms_required) def _check_size(privatekey): return self.size == privatekey.bits() def _check_type(privatekey): return self.type == privatekey.type() def _check_passphrase(): try: crypto_utils.load_privatekey(self.path, self.passphrase) return True except crypto.Error: return False if not state_and_perms or not _check_passphrase(): return False privatekey = crypto_utils.load_privatekey(self.path, self.passphrase) return _check_size(privatekey) and _check_type(privatekey)
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(PrivateKey, self).check(module, perms_required) def _check_size(privatekey): return self.size == privatekey.bits() def _check_type(privatekey): return self.type == privatekey.type() def _check_passphrase(): try: crypto_utils.load_privatekey(self.path, self.passphrase) return True except crypto.Error: return False if not state_and_perms or not _check_passphrase(): return False privatekey = crypto_utils.load_privatekey(self.path, self.passphrase) return _check_size(privatekey) and _check_type(privatekey)
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(CertificateSigningRequest, self).check(module, perms_required) self.privatekey = crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase) def _check_subject(csr): subject = csr.get_subject() for (key, value) in self.subject.items(): if getattr(subject, key, None) != value: return False return True def _check_subjectAltName(extensions): altnames_ext = next((ext for ext in extensions if ext.get_short_name() == b'subjectAltName'), '') altnames = [altname.strip() for altname in str(altnames_ext).split(',')] # apperently openssl returns 'IP address' not 'IP' as specifier when converting the subjectAltName to string # although it won't accept this specifier when generating the CSR. (https://github.com/openssl/openssl/issues/4004) altnames = [name if not name.startswith('IP Address:') else "IP:" + name.split(':', 1)[1] for name in altnames] if self.subjectAltName: if set(altnames) != set(self.subjectAltName) or altnames_ext.get_critical() != self.subjectAltName_critical: return False else: if altnames: return False return True def _check_keyUsage_(extensions, extName, expected, critical): usages_ext = [ext for ext in extensions if ext.get_short_name() == extName] if (not usages_ext and expected) or (usages_ext and not expected): return False elif not usages_ext and not expected: return True else: current = [OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage.strip())) for usage in str(usages_ext[0]).split(',')] expected = [OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage)) for usage in expected] return set(current) == set(expected) and usages_ext[0].get_critical() == critical def _check_keyUsage(extensions): return _check_keyUsage_(extensions, b'keyUsage', self.keyUsage, self.keyUsage_critical) def _check_extenededKeyUsage(extensions): return _check_keyUsage_(extensions, b'extendedKeyUsage', self.extendedKeyUsage, self.extendedKeyUsage_critical) def _check_extensions(csr): extensions = csr.get_extensions() return _check_subjectAltName(extensions) and _check_keyUsage(extensions) and _check_extenededKeyUsage(extensions) def _check_signature(csr): try: return csr.verify(self.privatekey) except crypto.Error: return False if not state_and_perms: return False csr = crypto_utils.load_certificate_request(self.path) return _check_subject(csr) and _check_extensions(csr) and _check_signature(csr)
def _check_passphrase(self): try: crypto_utils.load_privatekey(self.path, self.passphrase) return True except Exception as dummy: return False
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(CertificateSigningRequest, self).check(module, perms_required) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase) def _check_subject(csr): subject = [(OpenSSL._util.lib.OBJ_txt2nid(to_bytes(sub[0])), to_bytes(sub[1])) for sub in self.subject] current_subject = [ (OpenSSL._util.lib.OBJ_txt2nid(to_bytes(sub[0])), to_bytes(sub[1])) for sub in csr.get_subject().get_components() ] if not set(subject) == set(current_subject): return False return True def _check_subjectAltName(extensions): altnames_ext = next((ext for ext in extensions if ext.get_short_name() == b'subjectAltName'), '') altnames = [ altname.strip() for altname in str(altnames_ext).split(',') ] # apperently openssl returns 'IP address' not 'IP' as specifier when converting the subjectAltName to string # although it won't accept this specifier when generating the CSR. (https://github.com/openssl/openssl/issues/4004) altnames = [ name if not name.startswith('IP Address:') else "IP:" + name.split(':', 1)[1] for name in altnames ] if self.subjectAltName: if set(altnames) != set( self.subjectAltName) or altnames_ext.get_critical( ) != self.subjectAltName_critical: return False else: if altnames: return False return True def _check_keyUsage_(extensions, extName, expected, critical): usages_ext = [ ext for ext in extensions if ext.get_short_name() == extName ] if (not usages_ext and expected) or (usages_ext and not expected): return False elif not usages_ext and not expected: return True else: current = [ OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage.strip())) for usage in str(usages_ext[0]).split(',') ] expected = [ OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage)) for usage in expected ] return set(current) == set( expected) and usages_ext[0].get_critical() == critical def _check_keyUsage(extensions): return _check_keyUsage_(extensions, b'keyUsage', self.keyUsage, self.keyUsage_critical) def _check_extenededKeyUsage(extensions): return _check_keyUsage_(extensions, b'extendedKeyUsage', self.extendedKeyUsage, self.extendedKeyUsage_critical) def _check_basicConstraints(extensions): return _check_keyUsage_(extensions, b'basicConstraints', self.basicConstraints, self.basicConstraints_critical) def _check_ocspMustStaple(extensions): oms_ext = [ ext for ext in extensions if ext.get_short_name() == MUST_STAPLE_NAME and str(ext) == MUST_STAPLE_VALUE ] if OpenSSL.SSL.OPENSSL_VERSION_NUMBER < 0x10100000: # Older versions of libssl don't know about OCSP Must Staple oms_ext.extend([ ext for ext in extensions if ext.get_short_name() == b'UNDEF' and ext.get_data() == b'\x30\x03\x02\x01\x05' ]) if self.ocspMustStaple: return len(oms_ext) > 0 and oms_ext[0].get_critical( ) == self.ocspMustStaple_critical else: return len(oms_ext) == 0 def _check_extensions(csr): extensions = csr.get_extensions() return (_check_subjectAltName(extensions) and _check_keyUsage(extensions) and _check_extenededKeyUsage(extensions) and _check_basicConstraints(extensions) and _check_ocspMustStaple(extensions)) def _check_signature(csr): try: return csr.verify(self.privatekey) except crypto.Error: return False if not state_and_perms: return False csr = crypto_utils.load_certificate_request(self.path) return _check_subject(csr) and _check_extensions( csr) and _check_signature(csr)
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(CertificateSigningRequest, self).check(module, perms_required) self.privatekey = crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase) def _check_subject(csr): subject = [(OpenSSL._util.lib.OBJ_txt2nid(to_bytes(sub[0])), to_bytes(sub[1])) for sub in self.subject] current_subject = [(OpenSSL._util.lib.OBJ_txt2nid(to_bytes(sub[0])), to_bytes(sub[1])) for sub in csr.get_subject().get_components()] if not set(subject) == set(current_subject): return False return True def _check_subjectAltName(extensions): altnames_ext = next((ext for ext in extensions if ext.get_short_name() == b'subjectAltName'), '') altnames = [altname.strip() for altname in str(altnames_ext).split(',')] # apperently openssl returns 'IP address' not 'IP' as specifier when converting the subjectAltName to string # although it won't accept this specifier when generating the CSR. (https://github.com/openssl/openssl/issues/4004) altnames = [name if not name.startswith('IP Address:') else "IP:" + name.split(':', 1)[1] for name in altnames] if self.subjectAltName: if set(altnames) != set(self.subjectAltName) or altnames_ext.get_critical() != self.subjectAltName_critical: return False else: if altnames: return False return True def _check_keyUsage_(extensions, extName, expected, critical): usages_ext = [ext for ext in extensions if ext.get_short_name() == extName] if (not usages_ext and expected) or (usages_ext and not expected): return False elif not usages_ext and not expected: return True else: current = [OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage.strip())) for usage in str(usages_ext[0]).split(',')] expected = [OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage)) for usage in expected] return set(current) == set(expected) and usages_ext[0].get_critical() == critical def _check_keyUsage(extensions): return _check_keyUsage_(extensions, b'keyUsage', self.keyUsage, self.keyUsage_critical) def _check_extenededKeyUsage(extensions): return _check_keyUsage_(extensions, b'extendedKeyUsage', self.extendedKeyUsage, self.extendedKeyUsage_critical) def _check_basicConstraints(extensions): return _check_keyUsage_(extensions, b'basicConstraints', self.basicConstraints, self.basicConstraints_critical) def _check_ocspMustStaple(extensions): oms_ext = [ext for ext in extensions if ext.get_short_name() == MUST_STAPLE_NAME and str(ext) == MUST_STAPLE_VALUE] if OpenSSL.SSL.OPENSSL_VERSION_NUMBER < 0x10100000: # Older versions of libssl don't know about OCSP Must Staple oms_ext.extend([ext for ext in extensions if ext.get_short_name() == b'UNDEF' and ext.get_data() == b'\x30\x03\x02\x01\x05']) if self.ocspMustStaple: return len(oms_ext) > 0 and oms_ext[0].get_critical() == self.ocspMustStaple_critical else: return len(oms_ext) == 0 def _check_extensions(csr): extensions = csr.get_extensions() return (_check_subjectAltName(extensions) and _check_keyUsage(extensions) and _check_extenededKeyUsage(extensions) and _check_basicConstraints(extensions) and _check_ocspMustStaple(extensions)) def _check_signature(csr): try: return csr.verify(self.privatekey) except crypto.Error: return False if not state_and_perms: return False csr = crypto_utils.load_certificate_request(self.path) return _check_subject(csr) and _check_extensions(csr) and _check_signature(csr)
def _check_passphrase(): try: crypto_utils.load_privatekey(self.path, self.passphrase) return True except crypto.Error: return False
def _load_private_key(self): self.privatekey = crypto_utils.load_privatekey(self.privatekey_path, self.privatekey_passphrase)
def check(self, module, perms_required=True): """Ensure the resource is in its desired state.""" state_and_perms = super(CertificateSigningRequest, self).check(module, perms_required) self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase) def _check_subject(csr): subject = csr.get_subject() for (key, value) in self.subject.items(): if getattr(subject, key, None) != value: return False return True def _check_subjectAltName(extensions): altnames_ext = next((ext for ext in extensions if ext.get_short_name() == b'subjectAltName'), '') altnames = [ altname.strip() for altname in str(altnames_ext).split(',') ] # apperently openssl returns 'IP address' not 'IP' as specifier when converting the subjectAltName to string # although it won't accept this specifier when generating the CSR. (https://github.com/openssl/openssl/issues/4004) altnames = [ name if not name.startswith('IP Address:') else "IP:" + name.split(':', 1)[1] for name in altnames ] if self.subjectAltName: if set(altnames) != set( self.subjectAltName) or altnames_ext.get_critical( ) != self.subjectAltName_critical: return False else: if altnames: return False return True def _check_keyUsage_(extensions, extName, expected, critical): usages_ext = [ ext for ext in extensions if ext.get_short_name() == extName ] if (not usages_ext and expected) or (usages_ext and not expected): return False elif not usages_ext and not expected: return True else: current = [ OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage.strip())) for usage in str(usages_ext[0]).split(',') ] expected = [ OpenSSL._util.lib.OBJ_txt2nid(to_bytes(usage)) for usage in expected ] return set(current) == set( expected) and usages_ext[0].get_critical() == critical def _check_keyUsage(extensions): return _check_keyUsage_(extensions, b'keyUsage', self.keyUsage, self.keyUsage_critical) def _check_extenededKeyUsage(extensions): return _check_keyUsage_(extensions, b'extendedKeyUsage', self.extendedKeyUsage, self.extendedKeyUsage_critical) def _check_extensions(csr): extensions = csr.get_extensions() return _check_subjectAltName(extensions) and _check_keyUsage( extensions) and _check_extenededKeyUsage(extensions) def _check_signature(csr): try: return csr.verify(self.privatekey) except crypto.Error: return False if not state_and_perms: return False csr = crypto_utils.load_certificate_request(self.path) return _check_subject(csr) and _check_extensions( csr) and _check_signature(csr)
def _load_private_key(self): try: self.privatekey = crypto_utils.load_privatekey( self.privatekey_path, self.privatekey_passphrase) except crypto_utils.OpenSSLBadPassphraseError as exc: raise CertificateSigningRequestError(exc)