def encrypt_message(secret, topic, message): """Encrypt message.""" keylen = SecretBox.KEY_SIZE if isinstance(secret, dict): key = secret.get(topic) else: key = secret if key is None: _LOGGER.warning( "Unable to encrypt payload because no decryption key known " "for topic %s", topic, ) return None key = key.encode("utf-8") key = key[:keylen] key = key.ljust(keylen, b"\0") try: message = message.encode("utf-8") payload = SecretBox(key).encrypt(message, encoder=Base64Encoder) _LOGGER.debug("Encrypted message: %s to %s", message, payload) return payload.decode("utf-8") except ValueError: _LOGGER.warning("Unable to encrypt message for topic %s", topic) return None
async def test_registration_encryption(hass, hass_client): """Test that registrations happen.""" try: from nacl.encoding import Base64Encoder from nacl.secret import SecretBox except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) api_client = await hass_client() resp = await api_client.post("/api/mobile_app/registrations", json=REGISTER) assert resp.status == 201 register_json = await resp.json() keylen = SecretBox.KEY_SIZE key = register_json[CONF_SECRET].encode("utf-8") key = key[:keylen] key = key.ljust(keylen, b"\0") payload = json.dumps(RENDER_TEMPLATE["data"]).encode("utf-8") data = SecretBox(key).encrypt(payload, encoder=Base64Encoder).decode("utf-8") container = { "type": "render_template", "encrypted": True, "encrypted_data": data } resp = await api_client.post("/api/webhook/{}".format( register_json[CONF_WEBHOOK_ID]), json=container) assert resp.status == 200 webhook_json = await resp.json() assert "encrypted_data" in webhook_json decrypted_data = SecretBox(key).decrypt(webhook_json["encrypted_data"], encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") assert json.loads(decrypted_data) == {"one": "Hello world"}
def decrypt_payload(secret_key, encrypted_data): """Return a decrypted payload given a key and a string of encrypted data.""" try: from nacl.encoding import Base64Encoder from nacl.secret import SecretBox except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return import json prepped_key = unhexlify(secret_key) decrypted_data = SecretBox(prepped_key).decrypt(encrypted_data, encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") return json.loads(decrypted_data)
async def test_webhook_handle_decryption( webhook_client, # noqa: F811 create_registrations): # noqa: F401, F811, E501 """Test that we can encrypt/decrypt properly.""" try: # pylint: disable=unused-import from nacl.secret import SecretBox # noqa: F401 from nacl.encoding import Base64Encoder # noqa: F401 except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return import json keylen = SecretBox.KEY_SIZE key = create_registrations[0]['secret'].encode("utf-8") key = key[:keylen] key = key.ljust(keylen, b'\0') payload = json.dumps(RENDER_TEMPLATE['data']).encode("utf-8") data = SecretBox(key).encrypt(payload, encoder=Base64Encoder).decode("utf-8") container = { 'type': 'render_template', 'encrypted': True, 'encrypted_data': data, } resp = await webhook_client.post('/api/webhook/{}'.format( create_registrations[0]['webhook_id']), json=container) assert resp.status == 200 webhook_json = await resp.json() assert 'encrypted_data' in webhook_json decrypted_data = SecretBox(key).decrypt(webhook_json['encrypted_data'], encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") assert json.loads(decrypted_data) == {'one': 'Hello world'}
async def test_webhook_handle_decryption(webhook_client, # noqa: F811 create_registrations): # noqa: F401, F811, E501 """Test that we can encrypt/decrypt properly.""" try: # pylint: disable=unused-import from nacl.secret import SecretBox # noqa: F401 from nacl.encoding import Base64Encoder # noqa: F401 except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return import json keylen = SecretBox.KEY_SIZE key = create_registrations[0]['secret'].encode("utf-8") key = key[:keylen] key = key.ljust(keylen, b'\0') payload = json.dumps(RENDER_TEMPLATE['data']).encode("utf-8") data = SecretBox(key).encrypt(payload, encoder=Base64Encoder).decode("utf-8") container = { 'type': 'render_template', 'encrypted': True, 'encrypted_data': data, } resp = await webhook_client.post( '/api/webhook/{}'.format(create_registrations[0]['webhook_id']), json=container ) assert resp.status == 200 webhook_json = await resp.json() assert 'encrypted_data' in webhook_json decrypted_data = SecretBox(key).decrypt(webhook_json['encrypted_data'], encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") assert json.loads(decrypted_data) == {'one': 'Hello world'}
async def test_webhook_handle_decryption(webhook_client, create_registrations): """Test that we can encrypt/decrypt properly.""" try: # pylint: disable=unused-import from nacl.secret import SecretBox # noqa: F401 from nacl.encoding import Base64Encoder # noqa: F401 except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return import json keylen = SecretBox.KEY_SIZE key = create_registrations[0]["secret"].encode("utf-8") key = key[:keylen] key = key.ljust(keylen, b"\0") payload = json.dumps(RENDER_TEMPLATE["data"]).encode("utf-8") data = SecretBox(key).encrypt(payload, encoder=Base64Encoder).decode("utf-8") container = { "type": "render_template", "encrypted": True, "encrypted_data": data } resp = await webhook_client.post("/api/webhook/{}".format( create_registrations[0]["webhook_id"]), json=container) assert resp.status == 200 webhook_json = await resp.json() assert "encrypted_data" in webhook_json decrypted_data = SecretBox(key).decrypt(webhook_json["encrypted_data"], encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") assert json.loads(decrypted_data) == {"one": "Hello world"}
def decrypt_payload_legacy(secret_key, encrypted_data): """Return a decrypted payload given a key and a string of encrypted data.""" try: from nacl.encoding import Base64Encoder from nacl.secret import SecretBox except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return import json keylen = SecretBox.KEY_SIZE prepped_key = secret_key.encode("utf-8") prepped_key = prepped_key[:keylen] prepped_key = prepped_key.ljust(keylen, b"\0") decrypted_data = SecretBox(prepped_key).decrypt(encrypted_data, encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") return json.loads(decrypted_data)
async def test_registration(hass, hass_client): """Test that registrations happen.""" try: # pylint: disable=unused-import from nacl.secret import SecretBox # noqa: F401 from nacl.encoding import Base64Encoder # noqa: F401 except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return import json await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) api_client = await hass_client() resp = await api_client.post( '/api/mobile_app/registrations', json=REGISTER ) assert resp.status == 201 register_json = await resp.json() assert CONF_WEBHOOK_ID in register_json assert CONF_SECRET in register_json entries = hass.config_entries.async_entries(DOMAIN) assert entries[0].data['app_data'] == REGISTER['app_data'] assert entries[0].data['app_id'] == REGISTER['app_id'] assert entries[0].data['app_name'] == REGISTER['app_name'] assert entries[0].data['app_version'] == REGISTER['app_version'] assert entries[0].data['device_name'] == REGISTER['device_name'] assert entries[0].data['manufacturer'] == REGISTER['manufacturer'] assert entries[0].data['model'] == REGISTER['model'] assert entries[0].data['os_name'] == REGISTER['os_name'] assert entries[0].data['os_version'] == REGISTER['os_version'] assert entries[0].data['supports_encryption'] == \ REGISTER['supports_encryption'] keylen = SecretBox.KEY_SIZE key = register_json[CONF_SECRET].encode("utf-8") key = key[:keylen] key = key.ljust(keylen, b'\0') payload = json.dumps(RENDER_TEMPLATE['data']).encode("utf-8") data = SecretBox(key).encrypt(payload, encoder=Base64Encoder).decode("utf-8") container = { 'type': 'render_template', 'encrypted': True, 'encrypted_data': data, } resp = await api_client.post( '/api/webhook/{}'.format(register_json[CONF_WEBHOOK_ID]), json=container ) assert resp.status == 200 webhook_json = await resp.json() assert 'encrypted_data' in webhook_json decrypted_data = SecretBox(key).decrypt(webhook_json['encrypted_data'], encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") assert json.loads(decrypted_data) == {'one': 'Hello world'}
async def test_registration(hass, hass_client): # noqa: F811 """Test that registrations happen.""" try: # pylint: disable=unused-import from nacl.secret import SecretBox # noqa: F401 from nacl.encoding import Base64Encoder # noqa: F401 except (ImportError, OSError): pytest.skip("libnacl/libsodium is not installed") return import json await async_setup_component(hass, DOMAIN, {DOMAIN: {}}) api_client = await hass_client() resp = await api_client.post( '/api/mobile_app/registrations', json=REGISTER ) assert resp.status == 201 register_json = await resp.json() assert CONF_WEBHOOK_ID in register_json assert CONF_SECRET in register_json entries = hass.config_entries.async_entries(DOMAIN) assert entries[0].data['app_data'] == REGISTER['app_data'] assert entries[0].data['app_id'] == REGISTER['app_id'] assert entries[0].data['app_name'] == REGISTER['app_name'] assert entries[0].data['app_version'] == REGISTER['app_version'] assert entries[0].data['device_name'] == REGISTER['device_name'] assert entries[0].data['manufacturer'] == REGISTER['manufacturer'] assert entries[0].data['model'] == REGISTER['model'] assert entries[0].data['os_name'] == REGISTER['os_name'] assert entries[0].data['os_version'] == REGISTER['os_version'] assert entries[0].data['supports_encryption'] == \ REGISTER['supports_encryption'] keylen = SecretBox.KEY_SIZE key = register_json[CONF_SECRET].encode("utf-8") key = key[:keylen] key = key.ljust(keylen, b'\0') payload = json.dumps(RENDER_TEMPLATE['data']).encode("utf-8") data = SecretBox(key).encrypt(payload, encoder=Base64Encoder).decode("utf-8") container = { 'type': 'render_template', 'encrypted': True, 'encrypted_data': data, } resp = await api_client.post( '/api/webhook/{}'.format(register_json[CONF_WEBHOOK_ID]), json=container ) assert resp.status == 200 webhook_json = await resp.json() assert 'encrypted_data' in webhook_json decrypted_data = SecretBox(key).decrypt(webhook_json['encrypted_data'], encoder=Base64Encoder) decrypted_data = decrypted_data.decode("utf-8") assert json.loads(decrypted_data) == {'one': 'Hello world'}