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 __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 load_certificate_set(filename): ''' Load list of concatenated PEM files, and return a list of parsed certificates. ''' with open(filename, 'rb') as f: data = f.read().decode('utf-8') return [load_certificate(None, content=cert) for cert in split_pem_list(data)]
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 get_info(self): result = dict() self.cert = load_certificate(self.path, content=self.content, backend=self.backend) result['signature_algorithm'] = self._get_signature_algorithm() subject = self._get_subject_ordered() issuer = self._get_issuer_ordered() result['subject'] = dict() for k, v in subject: result['subject'][k] = v result['subject_ordered'] = subject result['issuer'] = dict() for k, v in issuer: result['issuer'][k] = v result['issuer_ordered'] = issuer result['version'] = self._get_version() result['key_usage'], result['key_usage_critical'] = self._get_key_usage() result['extended_key_usage'], result['extended_key_usage_critical'] = self._get_extended_key_usage() result['basic_constraints'], result['basic_constraints_critical'] = self._get_basic_constraints() result['ocsp_must_staple'], result['ocsp_must_staple_critical'] = self._get_ocsp_must_staple() result['subject_alt_name'], result['subject_alt_name_critical'] = self._get_subject_alt_name() not_before = self._get_not_before() not_after = self._get_not_after() result['not_before'] = not_before.strftime(TIMESTAMP_FORMAT) result['not_after'] = not_after.strftime(TIMESTAMP_FORMAT) result['expired'] = not_after < datetime.datetime.utcnow() result['valid_at'] = dict() if self.valid_at: for k, v in self.valid_at.items(): result['valid_at'][k] = not_before <= v <= not_after 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() if self.backend != 'pyopenssl': ski = self._get_subject_key_identifier() if ski is not None: ski = to_native(binascii.hexlify(ski)) ski = ':'.join([ski[i:i + 2] for i in range(0, len(ski), 2)]) result['subject_key_identifier'] = ski aki, aci, acsn = self._get_authority_key_identifier() if aki is not None: aki = to_native(binascii.hexlify(aki)) aki = ':'.join([aki[i:i + 2] for i in range(0, len(aki), 2)]) result['authority_key_identifier'] = aki result['authority_cert_issuer'] = aci result['authority_cert_serial_number'] = acsn result['serial_number'] = self._get_serial_number() result['extensions_by_oid'] = self._get_all_extensions() result['ocsp_uri'] = self._get_ocsp_uri() return result
def __init__(self, module): self.path = module.params['path'] self.full_chain_path = module.params['full_chain_path'] self.force = module.params['force'] self.backup = module.params['backup'] self.request_type = module.params['request_type'] self.csr = module.params['csr'] self.certificate_profile = module.params['certificate_profile_name'] self.end_entity_profile = module.params['end_entity_profile_name'] self.certificate_authority = module.params['certificate_authority_name'] # All return values self.changed = False self.filename = None self.tracking_id = None self.cert_status = None self.serial_number = None self.cert_days = None self.cert_details = None self.backup_file = None self.backup_full_chain_file = None self.cert = None self.ejbca_client = None if self.path and os.path.exists(self.path): try: self.cert = load_certificate(self.path, backend='cryptography') except Exception as dummy: self.cert = None # Instantiate the EJBCA client and then try a no-op connection to verify credentials are valid try: self.ejbca_client = EJBCAClient( ejbca_api_url=module.params['ejbca_api_url'], ejbca_api_cert=module.params['ejbca_api_client_cert_path'], ejbca_api_cert_key=module.params['ejbca_api_client_cert_key_path'], ) except SessionConfigurationException as e: module.fail_json(msg='Failed to initialize EJBCA Provider: {0}'.format(to_native(e))) try: self.api_status = self.ejbca_client.GetStatus() self.status = self.api_status.get('status') self.api_ver = self.api_status.get('version') # This is the first REST API call to check connectivity, status and get version # Do a: https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/status #{ # "status": "OK", # "version": "1.0", # "revision": "EJBCA 7.5.0-Snapshot Enterprise (working copy)" #} # DEBUG #print ("STATUS: " + self.status) #print ("API VERSION: " + self.api_ver) if self.status != 'OK': raise RestOperationException({"status": self.status, "errors": [{"message": "API status is not OK: '" + self.status + ", " + self.api_ver + "'"}]}) except RestOperationException as e: module.fail_json(msg='Please verify credential information. Received exception when testing connection: {0}'.format(to_native(e.message)))
def _ensure_existing_certificate_loaded(self): """Load the existing certificate into self.existing_certificate.""" if self.existing_certificate is not None: return if self.existing_certificate_bytes is None: return self.existing_certificate = load_certificate( path=None, content=self.existing_certificate_bytes, backend=self.backend, )
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 __init__(self, module): self.path = module.params['path'] self.full_chain_path = module.params['full_chain_path'] self.force = module.params['force'] self.backup = module.params['backup'] self.request_type = module.params['request_type'] self.csr = module.params['csr'] # All return values self.changed = False self.filename = None self.tracking_id = None self.cert_status = None self.serial_number = None self.cert_days = None self.cert_details = None self.backup_file = None self.backup_full_chain_file = None self.cert = None self.ecs_client = None if self.path and os.path.exists(self.path): try: self.cert = load_certificate(self.path, backend='cryptography') except Exception as dummy: self.cert = None # Instantiate the ECS client and then try a no-op connection to verify credentials are valid try: self.ecs_client = ECSClient( entrust_api_user=module.params['entrust_api_user'], entrust_api_key=module.params['entrust_api_key'], entrust_api_cert=module.params['entrust_api_client_cert_path'], entrust_api_cert_key=module. params['entrust_api_client_cert_key_path'], entrust_api_specification_path=module. params['entrust_api_specification_path']) except SessionConfigurationException as e: module.fail_json( msg='Failed to initialize Entrust Provider: {0}'.format( to_native(e))) try: self.ecs_client.GetAppVersion() except RestOperationException as e: module.fail_json( msg= 'Please verify credential information. Received exception when testing ECS connection: {0}' .format(to_native(e.message)))
def generate_certificate(self): """(Re-)Generate certificate.""" body = {} # Read the CSR that was generated for us if self.csr_content is not None: # csr_content contains bytes body['csr'] = to_native(self.csr_content) else: with open(self.csr_path, 'r') as csr_file: body['csr'] = csr_file.read() body['certType'] = self.module.params['entrust_cert_type'] # Handle expiration (30 days if not specified) expiry = self.notAfter if not expiry: gmt_now = datetime.datetime.fromtimestamp( time.mktime(time.gmtime())) expiry = gmt_now + datetime.timedelta(days=365) expiry_iso3339 = expiry.strftime("%Y-%m-%dT%H:%M:%S.00Z") body['certExpiryDate'] = expiry_iso3339 body['org'] = self.csr_org body['tracking'] = { 'requesterName': self.module.params['entrust_requester_name'], 'requesterEmail': self.module.params['entrust_requester_email'], 'requesterPhone': self.module.params['entrust_requester_phone'], } try: result = self.ecs_client.NewCertRequest(Body=body) self.trackingId = result.get('trackingId') except RestOperationException as e: self.module.fail_json( msg= 'Failed to request new certificate from Entrust Certificate Services (ECS): {0}' .format(to_native(e.message))) self.cert_bytes = to_bytes(result.get('endEntityCert')) self.cert = load_certificate(path=None, content=self.cert_bytes, backend=self.backend)
def __init__(self, module, backend): super(Pkcs, self).__init__( module.params['path'], module.params['state'], module.params['force'], module.check_mode ) self.backend = backend self.action = module.params['action'] self.other_certificates = module.params['other_certificates'] self.other_certificates_parse_all = module.params['other_certificates_parse_all'] self.certificate_path = module.params['certificate_path'] self.friendly_name = module.params['friendly_name'] self.iter_size = module.params['iter_size'] or 2048 self.maciter_size = module.params['maciter_size'] or 1 self.passphrase = module.params['passphrase'] self.pkcs12 = None self.privatekey_passphrase = module.params['privatekey_passphrase'] self.privatekey_path = module.params['privatekey_path'] self.pkcs12_bytes = None self.return_content = module.params['return_content'] self.src = module.params['src'] if module.params['mode'] is None: module.params['mode'] = '0400' self.backup = module.params['backup'] self.backup_file = None if self.other_certificates: if self.other_certificates_parse_all: filenames = list(self.other_certificates) self.other_certificates = [] for other_cert_bundle in filenames: self.other_certificates.extend(load_certificate_set(other_cert_bundle, self.backend)) else: self.other_certificates = [ load_certificate(other_cert, backend=self.backend) for other_cert in self.other_certificates ]
def run(self): result = dict() try: with open(self.path, "rb") as f: _in = f.read() _signature = base64.b64decode(self.signature) certificate = load_certificate( path=self.certificate_path, content=self.certificate_content, backend=self.backend, ) try: OpenSSL.crypto.verify(certificate, _signature, _in, 'sha256') result['valid'] = True except Exception: result['valid'] = False return result except Exception as e: raise OpenSSLObjectError(e)
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() _signature = base64.b64decode(self.signature) certificate = load_certificate( path=self.certificate_path, content=self.certificate_content, backend=self.backend, ) public_key = certificate.public_key() verified = False valid = False if CRYPTOGRAPHY_HAS_DSA_SIGN: try: if isinstance( public_key, cryptography.hazmat.primitives. asymmetric.dsa.DSAPublicKey): public_key.verify(_signature, _in, _hash) verified = True valid = True except cryptography.exceptions.InvalidSignature: verified = True valid = False if CRYPTOGRAPHY_HAS_EC_SIGN: try: if isinstance( public_key, cryptography.hazmat.primitives. asymmetric.ec.EllipticCurvePublicKey): public_key.verify( _signature, _in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA( _hash)) verified = True valid = True except cryptography.exceptions.InvalidSignature: verified = True valid = False if CRYPTOGRAPHY_HAS_ED25519_SIGN: try: if isinstance( public_key, cryptography.hazmat.primitives. asymmetric.ed25519.Ed25519PublicKey): public_key.verify(_signature, _in) verified = True valid = True except cryptography.exceptions.InvalidSignature: verified = True valid = False if CRYPTOGRAPHY_HAS_ED448_SIGN: try: if isinstance( public_key, cryptography.hazmat.primitives. asymmetric.ed448.Ed448PublicKey): public_key.verify(_signature, _in) verified = True valid = True except cryptography.exceptions.InvalidSignature: verified = True valid = False if CRYPTOGRAPHY_HAS_RSA_SIGN: try: if isinstance( public_key, cryptography.hazmat.primitives. asymmetric.rsa.RSAPublicKey): public_key.verify(_signature, _in, _padding, _hash) verified = True valid = True except cryptography.exceptions.InvalidSignature: verified = True valid = False if not verified: self.module.fail_json( msg="Unsupported key type. Your cryptography version is {0}" .format(CRYPTOGRAPHY_VERSION)) result['valid'] = valid return result except Exception as e: raise OpenSSLObjectError(e)
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
def get_info(self, prefer_one_fingerprint=False): result = dict() self.cert = load_certificate(None, content=self.content, backend=self.backend) result['signature_algorithm'] = self._get_signature_algorithm() subject = self._get_subject_ordered() issuer = self._get_issuer_ordered() result['subject'] = dict() for k, v in subject: result['subject'][k] = v result['subject_ordered'] = subject result['issuer'] = dict() for k, v in issuer: result['issuer'][k] = v result['issuer_ordered'] = issuer result['version'] = self._get_version() result['key_usage'], result[ 'key_usage_critical'] = self._get_key_usage() result['extended_key_usage'], result[ 'extended_key_usage_critical'] = self._get_extended_key_usage() result['basic_constraints'], result[ 'basic_constraints_critical'] = self._get_basic_constraints() result['ocsp_must_staple'], result[ 'ocsp_must_staple_critical'] = self._get_ocsp_must_staple() result['subject_alt_name'], result[ 'subject_alt_name_critical'] = self._get_subject_alt_name() not_before = self.get_not_before() not_after = self.get_not_after() result['not_before'] = not_before.strftime(TIMESTAMP_FORMAT) result['not_after'] = not_after.strftime(TIMESTAMP_FORMAT) result['expired'] = not_after < datetime.datetime.utcnow() result['public_key'] = self._get_public_key_pem() public_key_info = get_publickey_info( self.module, self.backend, key=self._get_public_key_object(), prefer_one_fingerprint=prefer_one_fingerprint) result.update({ 'public_key_type': public_key_info['type'], 'public_key_data': public_key_info['public_data'], 'public_key_fingerprints': public_key_info['fingerprints'], }) result['fingerprints'] = get_fingerprint_of_bytes( self._get_der_bytes(), prefer_one=prefer_one_fingerprint) if self.backend != 'pyopenssl': ski = self._get_subject_key_identifier() if ski is not None: ski = to_native(binascii.hexlify(ski)) ski = ':'.join([ski[i:i + 2] for i in range(0, len(ski), 2)]) result['subject_key_identifier'] = ski aki, aci, acsn = self._get_authority_key_identifier() if aki is not None: aki = to_native(binascii.hexlify(aki)) aki = ':'.join([aki[i:i + 2] for i in range(0, len(aki), 2)]) result['authority_key_identifier'] = aki result['authority_cert_issuer'] = aci result['authority_cert_serial_number'] = acsn result['serial_number'] = self._get_serial_number() result['extensions_by_oid'] = self._get_all_extensions() result['ocsp_uri'] = self._get_ocsp_uri() return result