def dump(self, check_mode=False): result = { 'changed': self.changed, 'filename': self.path, 'privatekey': self.privatekey_path, 'last_update': None, 'next_update': None, 'digest': None, 'issuer_ordered': None, 'issuer': None, 'revoked_certificates': [], } if self.backup_file: result['backup_file'] = self.backup_file if check_mode: result['last_update'] = self.last_update.strftime(TIMESTAMP_FORMAT) result['next_update'] = self.next_update.strftime(TIMESTAMP_FORMAT) # result['digest'] = crypto_utils.cryptography_oid_to_name(self.crl.signature_algorithm_oid) result['digest'] = self.module.params['digest'] result['issuer_ordered'] = self.issuer result['issuer'] = {} for k, v in self.issuer: result['issuer'][k] = v result['revoked_certificates'] = [] for entry in self.revoked_certificates: result['revoked_certificates'].append(self._dump_revoked(entry)) elif self.crl: result['last_update'] = self.crl.last_update.strftime(TIMESTAMP_FORMAT) result['next_update'] = self.crl.next_update.strftime(TIMESTAMP_FORMAT) try: result['digest'] = crypto_utils.cryptography_oid_to_name(self.crl.signature_algorithm_oid) except AttributeError: # Older cryptography versions don't have signature_algorithm_oid yet dotted = crypto_utils._obj2txt( self.crl._backend._lib, self.crl._backend._ffi, self.crl._x509_crl.sig_alg.algorithm ) oid = x509.oid.ObjectIdentifier(dotted) result['digest'] = crypto_utils.cryptography_oid_to_name(oid) issuer = [] for attribute in self.crl.issuer: issuer.append([crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value]) result['issuer_ordered'] = issuer result['issuer'] = {} for k, v in issuer: result['issuer'][k] = v result['revoked_certificates'] = [] for cert in self.crl: entry = crypto_utils.cryptography_decode_revoked_certificate(cert) result['revoked_certificates'].append(self._dump_revoked(entry)) if self.return_content: result['crl'] = self.crl_content return result
def _get_extended_key_usage(self): try: ext_keyusage_ext = self.cert.extensions.get_extension_for_class(x509.ExtendedKeyUsage) return sorted([ crypto_utils.cryptography_oid_to_name(eku) for eku in ext_keyusage_ext.value ]), ext_keyusage_ext.critical except cryptography.x509.ExtensionNotFound: return None, False
def _get_subject_ordered(self): result = [] for attribute in self.csr.subject: result.append([ crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value ]) return result
def _get_issuer_ordered(self): result = [] for attribute in self.cert.issuer: result.append([ crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value ]) return result
def get_info(self): result = { 'changed': False, 'last_update': None, 'next_update': None, 'digest': None, 'issuer_ordered': None, 'issuer': None, 'revoked_certificates': [], } result['last_update'] = self.crl.last_update.strftime(TIMESTAMP_FORMAT) result['next_update'] = self.crl.next_update.strftime(TIMESTAMP_FORMAT) try: result['digest'] = crypto_utils.cryptography_oid_to_name( self.crl.signature_algorithm_oid) except AttributeError: # Older cryptography versions don't have signature_algorithm_oid yet dotted = crypto_utils._obj2txt( self.crl._backend._lib, self.crl._backend._ffi, self.crl._x509_crl.sig_alg.algorithm) oid = x509.oid.ObjectIdentifier(dotted) result['digest'] = crypto_utils.cryptography_oid_to_name(oid) issuer = [] for attribute in self.crl.issuer: issuer.append([ crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value ]) result['issuer_ordered'] = issuer result['issuer'] = {} for k, v in issuer: result['issuer'][k] = v result['revoked_certificates'] = [] for cert in self.crl: entry = crypto_utils.cryptography_decode_revoked_certificate(cert) result['revoked_certificates'].append(self._dump_revoked(entry)) return result
def main(): module = AnsibleModule(argument_spec=dict( ca_cert=dict(type='path'), host=dict(type='str', required=True), port=dict(type='int', required=True), proxy_host=dict(type='str'), proxy_port=dict(type='int', default=8080), timeout=dict(type='int', default=10), select_crypto_backend=dict( type='str', choices=['auto', 'pyopenssl', 'cryptography'], default='auto'), ), ) ca_cert = module.params.get('ca_cert') host = module.params.get('host') port = module.params.get('port') proxy_host = module.params.get('proxy_host') proxy_port = module.params.get('proxy_port') timeout = module.params.get('timeout') backend = module.params.get('select_crypto_backend') if backend == 'auto': # Detection what is possible can_use_cryptography = CRYPTOGRAPHY_FOUND and CRYPTOGRAPHY_VERSION >= LooseVersion( MINIMAL_CRYPTOGRAPHY_VERSION) can_use_pyopenssl = PYOPENSSL_FOUND and PYOPENSSL_VERSION >= LooseVersion( MINIMAL_PYOPENSSL_VERSION) # First try cryptography, then pyOpenSSL if can_use_cryptography: backend = 'cryptography' elif can_use_pyopenssl: backend = 'pyopenssl' # Success? if backend == 'auto': module.fail_json(msg=( "Can't detect any of the required Python libraries " "cryptography (>= {0}) or PyOpenSSL (>= {1})" ).format(MINIMAL_CRYPTOGRAPHY_VERSION, MINIMAL_PYOPENSSL_VERSION)) if backend == 'pyopenssl': if not PYOPENSSL_FOUND: module.fail_json(msg=missing_required_lib( 'pyOpenSSL >= {0}'.format(MINIMAL_PYOPENSSL_VERSION)), exception=PYOPENSSL_IMP_ERR) module.deprecate( 'The module is using the PyOpenSSL backend. This backend has been deprecated', version='2.13') elif backend == 'cryptography': if not CRYPTOGRAPHY_FOUND: module.fail_json(msg=missing_required_lib( 'cryptography >= {0}'.format(MINIMAL_CRYPTOGRAPHY_VERSION)), exception=CRYPTOGRAPHY_IMP_ERR) result = dict(changed=False, ) if not PYOPENSSL_FOUND: module.fail_json(msg=missing_required_lib('pyOpenSSL >= 0.15'), exception=PYOPENSSL_IMP_ERR) if timeout: setdefaulttimeout(timeout) if ca_cert: if not isfile(ca_cert): module.fail_json(msg="ca_cert file does not exist") if proxy_host: if not HAS_CREATE_DEFAULT_CONTEXT: module.fail_json( msg= 'To use proxy_host, you must run the get_certificate module with Python 2.7 or newer.', exception=CREATE_DEFAULT_CONTEXT_IMP_ERR) try: connect = "CONNECT %s:%s HTTP/1.0\r\n\r\n" % (host, port) sock = socket() atexit.register(sock.close) sock.connect((proxy_host, proxy_port)) sock.send(connect.encode()) sock.recv(8192) ctx = create_default_context() ctx.check_hostname = False ctx.verify_mode = CERT_NONE if ca_cert: ctx.verify_mode = CERT_OPTIONAL ctx.load_verify_locations(cafile=ca_cert) cert = ctx.wrap_socket(sock, server_hostname=host).getpeercert(True) cert = DER_cert_to_PEM_cert(cert) except Exception as e: module.fail_json( msg="Failed to get cert from port with error: {0}".format(e)) else: try: cert = get_server_certificate((host, port), ca_certs=ca_cert) except Exception as e: module.fail_json( msg="Failed to get cert from port with error: {0}".format(e)) result['cert'] = cert if backend == 'pyopenssl': x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert) result['subject'] = {} for component in x509.get_subject().get_components(): result['subject'][component[0]] = component[1] result['expired'] = x509.has_expired() result['extensions'] = [] extension_count = x509.get_extension_count() for index in range(0, extension_count): extension = x509.get_extension(index) result['extensions'].append({ 'critical': extension.get_critical(), 'asn1_data': extension.get_data(), 'name': extension.get_short_name(), }) result['issuer'] = {} for component in x509.get_issuer().get_components(): result['issuer'][component[0]] = component[1] result['not_after'] = x509.get_notAfter() result['not_before'] = x509.get_notBefore() result['serial_number'] = x509.get_serial_number() result['signature_algorithm'] = x509.get_signature_algorithm() result['version'] = x509.get_version() elif backend == 'cryptography': x509 = cryptography.x509.load_pem_x509_certificate( to_bytes(cert), cryptography_backend()) result['subject'] = {} for attribute in x509.subject: result['subject'][crypto_utils.cryptography_oid_to_name( attribute.oid, short=True)] = attribute.value result['expired'] = x509.not_valid_after < datetime.datetime.utcnow() result['extensions'] = [] for dotted_number, entry in crypto_utils.cryptography_get_extensions_from_cert( x509).items(): oid = cryptography.x509.oid.ObjectIdentifier(dotted_number) result['extensions'].append({ 'critical': entry['critical'], 'asn1_data': base64.b64decode(entry['value']), 'name': crypto_utils.cryptography_oid_to_name(oid, short=True), }) result['issuer'] = {} for attribute in x509.issuer: result['issuer'][crypto_utils.cryptography_oid_to_name( attribute.oid, short=True)] = attribute.value result['not_after'] = x509.not_valid_after.strftime('%Y%m%d%H%M%SZ') result['not_before'] = x509.not_valid_before.strftime('%Y%m%d%H%M%SZ') result['serial_number'] = x509.serial_number result['signature_algorithm'] = crypto_utils.cryptography_oid_to_name( x509.signature_algorithm_oid) # We need the -1 offset to get the same values as pyOpenSSL if x509.version == cryptography.x509.Version.v1: result['version'] = 1 - 1 elif x509.version == cryptography.x509.Version.v3: result['version'] = 3 - 1 else: result['version'] = "unknown" module.exit_json(**result)
def _get_signature_algorithm(self): return crypto_utils.cryptography_oid_to_name(self.cert.signature_algorithm_oid)
def _get_subject(self): result = dict() for attribute in self.csr.subject: result[crypto_utils.cryptography_oid_to_name( attribute.oid)] = attribute.value return result
def _get_issuer(self): result = dict() for attribute in self.cert.issuer: result[crypto_utils.cryptography_oid_to_name( attribute.oid)] = attribute.value return result