def test_read_file(tmpdir): fn = tmpdir / 'test.txt' fn.write(TEST_TEXT) assert read_file(str(fn), 't') == TEST_TEXT assert read_file(str(fn), 'b') == TEST_TEXT.encode('utf-8')
def main(): module = AnsibleModule( argument_spec=dict( challenge=dict(type='str', required=True, choices=['tls-alpn-01']), challenge_data=dict(type='dict', required=True), private_key_src=dict(type='path'), private_key_content=dict(type='str', no_log=True), ), required_one_of=(['private_key_src', 'private_key_content'], ), mutually_exclusive=(['private_key_src', 'private_key_content'], ), ) if not HAS_CRYPTOGRAPHY: module.fail_json(msg=missing_required_lib('cryptography >= 1.3'), exception=CRYPTOGRAPHY_IMP_ERR) try: # Get parameters challenge = module.params['challenge'] challenge_data = module.params['challenge_data'] # Get hold of private key private_key_content = module.params.get('private_key_content') if private_key_content is None: private_key_content = read_file(module.params['private_key_src']) else: private_key_content = to_bytes(private_key_content) try: private_key = cryptography.hazmat.primitives.serialization.load_pem_private_key( private_key_content, password=None, backend=_cryptography_backend) except Exception as e: raise ModuleFailException( 'Error while loading private key: {0}'.format(e)) # Some common attributes domain = to_text(challenge_data['resource']) identifier_type, identifier = to_text( challenge_data.get('resource_original', 'dns:' + challenge_data['resource'])).split( ':', 1) subject = issuer = cryptography.x509.Name([]) not_valid_before = datetime.datetime.utcnow() not_valid_after = datetime.datetime.utcnow() + datetime.timedelta( days=10) if identifier_type == 'dns': san = cryptography.x509.DNSName(identifier) elif identifier_type == 'ip': san = cryptography.x509.IPAddress(ipaddress.ip_address(identifier)) else: raise ModuleFailException( 'Unsupported identifier type "{0}"'.format(identifier_type)) # Generate regular self-signed certificate regular_certificate = cryptography.x509.CertificateBuilder( ).subject_name(subject).issuer_name(issuer).public_key( private_key.public_key()).serial_number( cryptography.x509.random_serial_number()).not_valid_before( not_valid_before).not_valid_after( not_valid_after).add_extension( cryptography.x509.SubjectAlternativeName([san]), critical=False, ).sign(private_key, cryptography.hazmat.primitives.hashes.SHA256(), _cryptography_backend) # Process challenge if challenge == 'tls-alpn-01': value = base64.b64decode(challenge_data['resource_value']) challenge_certificate = cryptography.x509.CertificateBuilder( ).subject_name(subject).issuer_name(issuer).public_key( private_key.public_key()).serial_number( cryptography.x509.random_serial_number()).not_valid_before( not_valid_before).not_valid_after( not_valid_after).add_extension( cryptography.x509.SubjectAlternativeName([san ]), critical=False, ).add_extension( cryptography.x509.UnrecognizedExtension( cryptography.x509.ObjectIdentifier( "1.3.6.1.5.5.7.1.31"), encode_octet_string(value), ), critical=True, ).sign( private_key, cryptography.hazmat.primitives.hashes.SHA256(), _cryptography_backend) module.exit_json( changed=True, domain=domain, identifier_type=identifier_type, identifier=identifier, challenge_certificate=challenge_certificate.public_bytes( cryptography.hazmat.primitives.serialization.Encoding.PEM), regular_certificate=regular_certificate.public_bytes( cryptography.hazmat.primitives.serialization.Encoding.PEM)) except ModuleFailException as e: e.do_fail(module)