# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.

from __future__ import absolute_import, division, print_function

import binascii

import pytest

from cryptography.exceptions import (
    AlreadyFinalized, InvalidKey, _Reasons
)
from cryptography.hazmat.backends.interfaces import HashBackend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.x963kdf import X963KDF

from ...utils import raises_unsupported_algorithm


@pytest.mark.requires_backend_interface(interface=HashBackend)
class TestX963KDF(object):
    def test_length_limit(self, backend):
        big_length = hashes.SHA256().digest_size * (2 ** 32 - 1) + 1

        with pytest.raises(ValueError):
            X963KDF(hashes.SHA256(), big_length, None, backend)

    def test_already_finalized(self, backend):
        xkdf = X963KDF(hashes.SHA256(), 16, None, backend)

        xkdf.derive(b"\x01" * 16)

        with pytest.raises(AlreadyFinalized):
            xkdf.derive(b"\x02" * 16)

    def test_derive(self, backend):
        key = binascii.unhexlify(
            b"96c05619d56c328ab95fe84b18264b08725b85e33fd34f08"
        )

        derivedkey = binascii.unhexlify(b"443024c3dae66b95e6f5670601558f71")

        xkdf = X963KDF(hashes.SHA256(), 16, None, backend)

        assert xkdf.derive(key) == derivedkey

    def test_buffer_protocol(self, backend):
        key = bytearray(binascii.unhexlify(
            b"96c05619d56c328ab95fe84b18264b08725b85e33fd34f08"
        ))

        derivedkey = binascii.unhexlify(b"443024c3dae66b95e6f5670601558f71")

        xkdf = X963KDF(hashes.SHA256(), 16, None, backend)

        assert xkdf.derive(key) == derivedkey

    def test_verify(self, backend):
        key = binascii.unhexlify(
            b"22518b10e70f2a3f243810ae3254139efbee04aa57c7af7d"
        )

        sharedinfo = binascii.unhexlify(b"75eef81aa3041e33b80971203d2c0c52")

        derivedkey = binascii.unhexlify(
            b"c498af77161cc59f2962b9a713e2b215152d139766ce34a776df11866a69bf2e"
            b"52a13d9c7c6fc878c50c5ea0bc7b00e0da2447cfd874f6cf92f30d0097111485"
            b"500c90c3af8b487872d04685d14c8d1dc8d7fa08beb0ce0ababc11f0bd496269"
            b"142d43525a78e5bc79a17f59676a5706dc54d54d4d1f0bd7e386128ec26afc21"
        )

        xkdf = X963KDF(hashes.SHA256(), 128, sharedinfo, backend)

        assert xkdf.verify(key, derivedkey) is None

    def test_invalid_verify(self, backend):
        key = binascii.unhexlify(
            b"96c05619d56c328ab95fe84b18264b08725b85e33fd34f08"
        )

        xkdf = X963KDF(hashes.SHA256(), 16, None, backend)

        with pytest.raises(InvalidKey):
            xkdf.verify(key, b"wrong derived key")

    def test_unicode_typeerror(self, backend):
        with pytest.raises(TypeError):
            X963KDF(
                hashes.SHA256(),
                16,
                sharedinfo=u"foo",
                backend=backend
            )

        with pytest.raises(TypeError):
            xkdf = X963KDF(
                hashes.SHA256(),
                16,
                sharedinfo=None,
                backend=backend
            )

            xkdf.derive(u"foo")

        with pytest.raises(TypeError):
            xkdf = X963KDF(
                hashes.SHA256(),
                16,
                sharedinfo=None,
                backend=backend
            )

            xkdf.verify(u"foo", b"bar")

        with pytest.raises(TypeError):
            xkdf = X963KDF(
                hashes.SHA256(),
                16,
                sharedinfo=None,
                backend=backend
            )

            xkdf.verify(b"foo", u"bar")


def test_invalid_backend():
    pretend_backend = object()

    with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
        X963KDF(hashes.SHA256(), 16, None, pretend_backend)
