# Copyright 2016 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import base64
import json
import os

from cryptography.hazmat.primitives.asymmetric import ec
import pytest

from google.auth import _helpers
from google.auth.crypt import base
from google.auth.crypt import es256


DATA_DIR = os.path.join(os.path.dirname(__file__), "..", "data")

# To generate es256_privatekey.pem, es256_privatekey.pub, and
# es256_public_cert.pem:
#   $ openssl ecparam -genkey -name prime256v1 -noout -out es256_privatekey.pem
#   $ openssl ec -in es256-private-key.pem -pubout -out es256-publickey.pem
#   $ openssl req -new -x509 -key es256_privatekey.pem -out \
#   >     es256_public_cert.pem

with open(os.path.join(DATA_DIR, "es256_privatekey.pem"), "rb") as fh:
    PRIVATE_KEY_BYTES = fh.read()
    PKCS1_KEY_BYTES = PRIVATE_KEY_BYTES

with open(os.path.join(DATA_DIR, "es256_publickey.pem"), "rb") as fh:
    PUBLIC_KEY_BYTES = fh.read()

with open(os.path.join(DATA_DIR, "es256_public_cert.pem"), "rb") as fh:
    PUBLIC_CERT_BYTES = fh.read()

SERVICE_ACCOUNT_JSON_FILE = os.path.join(DATA_DIR, "es256_service_account.json")

with open(SERVICE_ACCOUNT_JSON_FILE, "r") as fh:
    SERVICE_ACCOUNT_INFO = json.load(fh)


class TestES256Verifier(object):
    def test_verify_bytes_success(self):
        to_sign = b"foo"
        signer = es256.ES256Signer.from_string(PRIVATE_KEY_BYTES)
        actual_signature = signer.sign(to_sign)

        verifier = es256.ES256Verifier.from_string(PUBLIC_KEY_BYTES)
        assert verifier.verify(to_sign, actual_signature)

    def test_verify_text_success(self):
        to_sign = "foo"
        signer = es256.ES256Signer.from_string(PRIVATE_KEY_BYTES)
        actual_signature = signer.sign(to_sign)

        verifier = es256.ES256Verifier.from_string(PUBLIC_KEY_BYTES)
        assert verifier.verify(to_sign, actual_signature)

    def test_verify_failure(self):
        verifier = es256.ES256Verifier.from_string(PUBLIC_KEY_BYTES)
        bad_signature1 = b""
        assert not verifier.verify(b"foo", bad_signature1)
        bad_signature2 = b"a"
        assert not verifier.verify(b"foo", bad_signature2)

    def test_verify_failure_with_wrong_raw_signature(self):
        to_sign = b"foo"

        # This signature has a wrong "r" value in the "(r,s)" raw signature.
        wrong_signature = base64.urlsafe_b64decode(
            b"m7oaRxUDeYqjZ8qiMwo0PZLTMZWKJLFQREpqce1StMIa_yXQQ-C5WgeIRHW7OqlYSDL0XbUrj_uAw9i-QhfOJQ=="
        )

        verifier = es256.ES256Verifier.from_string(PUBLIC_KEY_BYTES)
        assert not verifier.verify(to_sign, wrong_signature)

    def test_from_string_pub_key(self):
        verifier = es256.ES256Verifier.from_string(PUBLIC_KEY_BYTES)
        assert isinstance(verifier, es256.ES256Verifier)
        assert isinstance(verifier._pubkey, ec.EllipticCurvePublicKey)

    def test_from_string_pub_key_unicode(self):
        public_key = _helpers.from_bytes(PUBLIC_KEY_BYTES)
        verifier = es256.ES256Verifier.from_string(public_key)
        assert isinstance(verifier, es256.ES256Verifier)
        assert isinstance(verifier._pubkey, ec.EllipticCurvePublicKey)

    def test_from_string_pub_cert(self):
        verifier = es256.ES256Verifier.from_string(PUBLIC_CERT_BYTES)
        assert isinstance(verifier, es256.ES256Verifier)
        assert isinstance(verifier._pubkey, ec.EllipticCurvePublicKey)

    def test_from_string_pub_cert_unicode(self):
        public_cert = _helpers.from_bytes(PUBLIC_CERT_BYTES)
        verifier = es256.ES256Verifier.from_string(public_cert)
        assert isinstance(verifier, es256.ES256Verifier)
        assert isinstance(verifier._pubkey, ec.EllipticCurvePublicKey)


class TestES256Signer(object):
    def test_from_string_pkcs1(self):
        signer = es256.ES256Signer.from_string(PKCS1_KEY_BYTES)
        assert isinstance(signer, es256.ES256Signer)
        assert isinstance(signer._key, ec.EllipticCurvePrivateKey)

    def test_from_string_pkcs1_unicode(self):
        key_bytes = _helpers.from_bytes(PKCS1_KEY_BYTES)
        signer = es256.ES256Signer.from_string(key_bytes)
        assert isinstance(signer, es256.ES256Signer)
        assert isinstance(signer._key, ec.EllipticCurvePrivateKey)

    def test_from_string_bogus_key(self):
        key_bytes = "bogus-key"
        with pytest.raises(ValueError):
            es256.ES256Signer.from_string(key_bytes)

    def test_from_service_account_info(self):
        signer = es256.ES256Signer.from_service_account_info(SERVICE_ACCOUNT_INFO)

        assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
        assert isinstance(signer._key, ec.EllipticCurvePrivateKey)

    def test_from_service_account_info_missing_key(self):
        with pytest.raises(ValueError) as excinfo:
            es256.ES256Signer.from_service_account_info({})

        assert excinfo.match(base._JSON_FILE_PRIVATE_KEY)

    def test_from_service_account_file(self):
        signer = es256.ES256Signer.from_service_account_file(SERVICE_ACCOUNT_JSON_FILE)

        assert signer.key_id == SERVICE_ACCOUNT_INFO[base._JSON_FILE_PRIVATE_KEY_ID]
        assert isinstance(signer._key, ec.EllipticCurvePrivateKey)
