def _check_pkey_passphrase(): if self.privatekey_passphrase: try: load_privatekey(self.privatekey_path, self.privatekey_passphrase, backend=self.backend) except OpenSSLObjectError: return False return True
def _check_passphrase(self): try: load_privatekey(None, self.passphrase, content=self.existing_private_key_bytes, backend=self.backend) return True except Exception as dummy: return False
def _check_pkey_passphrase(): if self.privatekey_passphrase: try: load_privatekey(self.privatekey_path, self.privatekey_passphrase) except crypto.Error: return False except OpenSSLBadPassphraseError: return False return True
def __init__(self, module): super(OwnCACertificateBackendCryptography, self).__init__(module, 'cryptography') self.create_subject_key_identifier = module.params['ownca_create_subject_key_identifier'] self.create_authority_key_identifier = module.params['ownca_create_authority_key_identifier'] self.notBefore = get_relative_time_option(module.params['ownca_not_before'], 'ownca_not_before', backend=self.backend) self.notAfter = get_relative_time_option(module.params['ownca_not_after'], 'ownca_not_after', backend=self.backend) self.digest = select_message_digest(module.params['ownca_digest']) self.version = module.params['ownca_version'] self.serial_number = x509.random_serial_number() self.ca_cert_path = module.params['ownca_path'] self.ca_cert_content = module.params['ownca_content'] if self.ca_cert_content is not None: self.ca_cert_content = self.ca_cert_content.encode('utf-8') self.ca_privatekey_path = module.params['ownca_privatekey_path'] self.ca_privatekey_content = module.params['ownca_privatekey_content'] if self.ca_privatekey_content is not None: self.ca_privatekey_content = self.ca_privatekey_content.encode('utf-8') self.ca_privatekey_passphrase = module.params['ownca_privatekey_passphrase'] if self.csr_content is None and self.csr_path is None: raise CertificateError( 'csr_path or csr_content is required for ownca provider' ) if self.csr_content is None and not os.path.exists(self.csr_path): raise CertificateError( 'The certificate signing request file {0} does not exist'.format(self.csr_path) ) if self.ca_cert_content is None and not os.path.exists(self.ca_cert_path): raise CertificateError( 'The CA certificate file {0} does not exist'.format(self.ca_cert_path) ) if self.ca_privatekey_content is None and not os.path.exists(self.ca_privatekey_path): raise CertificateError( 'The CA private key file {0} does not exist'.format(self.ca_privatekey_path) ) self._ensure_csr_loaded() self.ca_cert = load_certificate( path=self.ca_cert_path, content=self.ca_cert_content, backend=self.backend ) try: self.ca_private_key = load_privatekey( path=self.ca_privatekey_path, content=self.ca_privatekey_content, passphrase=self.ca_privatekey_passphrase, backend=self.backend ) except OpenSSLBadPassphraseError as exc: module.fail_json(msg=str(exc)) if cryptography_key_needs_digest_for_signing(self.ca_private_key): if self.digest is None: raise CertificateError( 'The digest %s is not supported with the cryptography backend' % module.params['ownca_digest'] ) else: self.digest = None
def generate_bytes(self, module): """Generate PKCS#12 file archive.""" pkey = None if self.privatekey_path: try: pkey = load_privatekey(self.privatekey_path, self.privatekey_passphrase, backend=self.backend) except OpenSSLBadPassphraseError as exc: raise PkcsError(exc) cert = None if self.certificate_path: cert = load_certificate(self.certificate_path, backend=self.backend) friendly_name = to_bytes(self.friendly_name) if self.friendly_name is not None else None # Store fake object which can be used to retrieve the components back self.pkcs12 = (pkey, cert, self.other_certificates, friendly_name) return serialize_key_and_certificates( friendly_name, pkey, cert, self.other_certificates, serialization.BestAvailableEncryption(to_bytes(self.passphrase)) if self.passphrase else serialization.NoEncryption(), )
def _ensure_private_key_loaded(self): """Make sure that the private key has been loaded.""" if self.privatekey is None: try: self.privatekey = privatekey = load_privatekey(self.path, self.passphrase) except OpenSSLBadPassphraseError as exc: raise PrivateKeyError(exc)
def generate(self, module): """Generate PKCS#12 file archive.""" self.pkcs12 = crypto.PKCS12() if self.other_certificates: other_certs = [ 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(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( load_privatekey(self.privatekey_path, self.privatekey_passphrase)) except OpenSSLBadPassphraseError as exc: raise PkcsError(exc) return self.pkcs12.export(self.passphrase, self.iter_size, self.maciter_size)
def _ensure_existing_private_key_loaded(self): if self.existing_private_key is None and self.has_existing(): try: self.existing_private_key = load_privatekey( None, self.passphrase, content=self.existing_private_key_bytes, backend=self.backend) except OpenSSLBadPassphraseError as exc: raise PrivateKeyError(exc)
def _ensure_private_key_loaded(self): """Load the provided private key into self.privatekey.""" if self.privatekey is not None: return try: self.privatekey = load_privatekey( path=self.privatekey_path, content=self.privatekey_content, passphrase=self.privatekey_passphrase, backend=self.backend, ) except OpenSSLBadPassphraseError as exc: raise CertificateSigningRequestError(exc)
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 = 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 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'] = 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(OwnCACertificateBackendPyOpenSSL, self).__init__(module, 'pyopenssl') self.notBefore = get_relative_time_option(self.module.params['ownca_not_before'], 'ownca_not_before', backend=self.backend) self.notAfter = get_relative_time_option(self.module.params['ownca_not_after'], 'ownca_not_after', backend=self.backend) self.digest = self.module.params['ownca_digest'] self.version = self.module.params['ownca_version'] self.serial_number = generate_serial_number() if self.module.params['ownca_create_subject_key_identifier'] != 'create_if_not_provided': self.module.fail_json(msg='ownca_create_subject_key_identifier cannot be used with the pyOpenSSL backend!') if self.module.params['ownca_create_authority_key_identifier']: self.module.warn('ownca_create_authority_key_identifier is ignored by the pyOpenSSL backend!') self.ca_cert_path = self.module.params['ownca_path'] self.ca_cert_content = self.module.params['ownca_content'] if self.ca_cert_content is not None: self.ca_cert_content = self.ca_cert_content.encode('utf-8') self.ca_privatekey_path = self.module.params['ownca_privatekey_path'] self.ca_privatekey_content = self.module.params['ownca_privatekey_content'] if self.ca_privatekey_content is not None: self.ca_privatekey_content = self.ca_privatekey_content.encode('utf-8') self.ca_privatekey_passphrase = self.module.params['ownca_privatekey_passphrase'] if self.csr_content is None and not os.path.exists(self.csr_path): raise CertificateError( 'The certificate signing request file {0} does not exist'.format(self.csr_path) ) if self.ca_cert_content is None and not os.path.exists(self.ca_cert_path): raise CertificateError( 'The CA certificate file {0} does not exist'.format(self.ca_cert_path) ) if self.ca_privatekey_content is None and not os.path.exists(self.ca_privatekey_path): raise CertificateError( 'The CA private key file {0} does not exist'.format(self.ca_privatekey_path) ) self._ensure_csr_loaded() self.ca_cert = load_certificate( path=self.ca_cert_path, content=self.ca_cert_content, ) try: self.ca_privatekey = load_privatekey( path=self.ca_privatekey_path, content=self.ca_privatekey_content, passphrase=self.ca_privatekey_passphrase ) except OpenSSLBadPassphraseError as exc: self.module.fail_json(msg=str(exc))
def run(self): result = dict() try: with open(self.path, "rb") as f: _in = f.read() private_key = load_privatekey( path=self.privatekey_path, content=self.privatekey_content, passphrase=self.privatekey_passphrase, backend=self.backend, ) signature = OpenSSL.crypto.sign(private_key, _in, "sha256") result['signature'] = base64.b64encode(signature) return result except Exception as e: raise OpenSSLObjectError(e)
def get_info(self, prefer_one_fingerprint=False): result = dict( can_parse_key=False, key_is_consistent=None, ) priv_key_detail = self.content try: self.key = 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 OpenSSLObjectError as exc: raise PrivateKeyParseError(to_native(exc), result) result['public_key'] = self._get_public_key(binary=False) pk = self._get_public_key(binary=True) result['public_key_fingerprints'] = get_fingerprint_of_bytes( pk, prefer_one=prefer_one_fingerprint) 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") msg = ( "Private key is not consistent! (See " "https://blog.hboeck.de/archives/888-How-I-tricked-Symantec-with-a-Fake-Private-Key.html)" ) raise PrivateKeyConsistencyError(msg, result) return result
def _create_publickey(self, module): self.privatekey = load_privatekey( path=self.privatekey_path, content=self.privatekey_content, passphrase=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 dummy: raise PublicKeyError( 'You need to have PyOpenSSL>=16.0.0 to generate public keys' )
def run(self): _padding = cryptography.hazmat.primitives.asymmetric.padding.PKCS1v15() _hash = cryptography.hazmat.primitives.hashes.SHA256() result = dict() try: with open(self.path, "rb") as f: _in = f.read() private_key = load_privatekey( path=self.privatekey_path, content=self.privatekey_content, passphrase=self.privatekey_passphrase, backend=self.backend, ) signature = None if CRYPTOGRAPHY_HAS_DSA_SIGN: if isinstance( private_key, cryptography.hazmat.primitives.asymmetric. dsa.DSAPrivateKey): signature = private_key.sign(_in, _hash) if CRYPTOGRAPHY_HAS_EC_SIGN: if isinstance( private_key, cryptography.hazmat.primitives.asymmetric. ec.EllipticCurvePrivateKey): signature = private_key.sign( _in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA( _hash)) if CRYPTOGRAPHY_HAS_ED25519_SIGN: if isinstance( private_key, cryptography.hazmat.primitives.asymmetric. ed25519.Ed25519PrivateKey): signature = private_key.sign(_in) if CRYPTOGRAPHY_HAS_ED448_SIGN: if isinstance( private_key, cryptography.hazmat.primitives.asymmetric. ed448.Ed448PrivateKey): signature = private_key.sign(_in) if CRYPTOGRAPHY_HAS_RSA_SIGN: if isinstance( private_key, cryptography.hazmat.primitives.asymmetric. rsa.RSAPrivateKey): signature = private_key.sign(_in, _padding, _hash) if signature is None: self.module.fail_json( msg="Unsupported key type. Your cryptography version is {0}" .format(CRYPTOGRAPHY_VERSION)) result['signature'] = base64.b64encode(signature) return result except Exception as e: raise OpenSSLObjectError(e)
def _check_passphrase(self): try: load_privatekey(self.path, self.passphrase) return True except Exception as dummy: return False
def __init__(self, module): super(CRL, self).__init__( module.params['path'], module.params['state'], module.params['force'], module.check_mode ) self.format = module.params['format'] self.update = module.params['mode'] == 'update' self.ignore_timestamps = module.params['ignore_timestamps'] self.return_content = module.params['return_content'] self.crl_content = None self.privatekey_path = module.params['privatekey_path'] self.privatekey_content = module.params['privatekey_content'] if self.privatekey_content is not None: self.privatekey_content = self.privatekey_content.encode('utf-8') self.privatekey_passphrase = module.params['privatekey_passphrase'] self.issuer = parse_name_field(module.params['issuer']) self.issuer = [(entry[0], entry[1]) for entry in self.issuer if entry[1]] self.last_update = get_relative_time_option(module.params['last_update'], 'last_update') self.next_update = get_relative_time_option(module.params['next_update'], 'next_update') self.digest = select_message_digest(module.params['digest']) if self.digest is None: raise CRLError('The digest "{0}" is not supported'.format(module.params['digest'])) self.revoked_certificates = [] for i, rc in enumerate(module.params['revoked_certificates']): result = { 'serial_number': None, 'revocation_date': None, 'issuer': None, 'issuer_critical': False, 'reason': None, 'reason_critical': False, 'invalidity_date': None, 'invalidity_date_critical': False, } path_prefix = 'revoked_certificates[{0}].'.format(i) if rc['path'] is not None or rc['content'] is not None: # Load certificate from file or content try: if rc['content'] is not None: rc['content'] = rc['content'].encode('utf-8') cert = load_certificate(rc['path'], content=rc['content'], backend='cryptography') result['serial_number'] = cryptography_serial_number_of_cert(cert) except OpenSSLObjectError as e: if rc['content'] is not None: module.fail_json( msg='Cannot parse certificate from {0}content: {1}'.format(path_prefix, to_native(e)) ) else: module.fail_json( msg='Cannot read certificate "{1}" from {0}path: {2}'.format(path_prefix, rc['path'], to_native(e)) ) else: # Specify serial_number (and potentially issuer) directly result['serial_number'] = rc['serial_number'] # All other options if rc['issuer']: result['issuer'] = [cryptography_get_name(issuer) for issuer in rc['issuer']] result['issuer_critical'] = rc['issuer_critical'] result['revocation_date'] = get_relative_time_option( rc['revocation_date'], path_prefix + 'revocation_date' ) if rc['reason']: result['reason'] = REVOCATION_REASON_MAP[rc['reason']] result['reason_critical'] = rc['reason_critical'] if rc['invalidity_date']: result['invalidity_date'] = get_relative_time_option( rc['invalidity_date'], path_prefix + 'invalidity_date' ) result['invalidity_date_critical'] = rc['invalidity_date_critical'] self.revoked_certificates.append(result) self.module = module self.backup = module.params['backup'] self.backup_file = None try: self.privatekey = load_privatekey( path=self.privatekey_path, content=self.privatekey_content, passphrase=self.privatekey_passphrase, backend='cryptography' ) except OpenSSLBadPassphraseError as exc: raise CRLError(exc) self.crl = None try: with open(self.path, 'rb') as f: data = f.read() self.actual_format = 'pem' if identify_pem_format(data) else 'der' if self.actual_format == 'pem': self.crl = x509.load_pem_x509_crl(data, default_backend()) if self.return_content: self.crl_content = data else: self.crl = x509.load_der_x509_crl(data, default_backend()) if self.return_content: self.crl_content = base64.b64encode(data) except Exception as dummy: self.crl_content = None self.actual_format = self.format