# Copyright 2021 The Pigweed Authors
#
# 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
#
#     https://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.
"""Facilities for keys generation, importing, signing and verification.

IMPORTANT: THESE FACILITIES ARE FOR LOCAL NON-PRODUCTION USE ONLY!!

These are not suited for production use because:

1. The private keys are not generated without ANY supervision or authorization.
2. The private keys are not stored securely.
3. The underlying crypto library is not audited.
"""

import argparse
import hashlib
from pathlib import Path

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.utils import (
    decode_dss_signature, encode_dss_signature)
from cryptography.hazmat.primitives.serialization import (
    Encoding, NoEncryption, PrivateFormat, PublicFormat, load_pem_private_key,
    load_pem_public_key)

from pw_software_update.tuf_pb2 import (Key, KeyMapping, KeyScheme, KeyType,
                                        Signature)


def parse_args():
    """Parse CLI arguments."""
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-o',
                        '--out',
                        type=Path,
                        required=True,
                        help='Output path for the generated key')
    return parser.parse_args()


def gen_ecdsa_keypair(out: Path) -> None:
    """Generates and writes to disk a NIST-P256 EC key pair.

    Args:
      out: The path to write the private key to. The public key is written
        to the same path as the private key using the suffix '.pub'.
    """
    private_key = ec.generate_private_key(ec.SECP256R1())
    public_key = private_key.public_key()
    private_pem = private_key.private_bytes(
        encoding=Encoding.PEM,
        format=PrivateFormat.PKCS8,
        encryption_algorithm=NoEncryption())
    public_pem = public_key.public_bytes(
        encoding=Encoding.PEM, format=PublicFormat.SubjectPublicKeyInfo)

    out.write_bytes(private_pem)
    public_out = (out.parent / f'{out.name}.pub')
    public_out.write_bytes(public_pem)


def gen_key_id(key: Key) -> bytes:
    """Computes the key ID of a Key object."""
    sha = hashlib.sha256()
    sha.update(key.key_type.to_bytes(1, 'big'))
    sha.update(key.scheme.to_bytes(1, 'big'))
    sha.update(key.keyval)
    return sha.digest()


def import_ecdsa_public_key(pem: bytes) -> KeyMapping:
    """Imports an EC NIST-P256 public key in pem format."""
    ec_key = load_pem_public_key(pem)

    if not isinstance(ec_key, ec.EllipticCurvePublicKey):
        raise TypeError(
            f'Not an elliptic curve public key type: {type(ec_key)}.'
            'Try generate a key with gen_ecdsa_keypair()?')

    # pylint: disable=no-member
    if not (ec_key.curve.name == 'secp256r1' and ec_key.key_size == 256):
        raise TypeError(f'Unsupported curve: {ec_key.curve.name}.'
                        'Try generate a key with gen_ecdsa_keypair()?')
    # pylint: enable=no-member

    tuf_key = Key(key_type=KeyType.ECDSA_SHA2_NISTP256,
                  scheme=KeyScheme.ECDSA_SHA2_NISTP256_SCHEME,
                  keyval=ec_key.public_bytes(Encoding.X962,
                                             PublicFormat.UncompressedPoint))
    return KeyMapping(key_id=gen_key_id(tuf_key), key=tuf_key)


def create_ecdsa_signature(data: bytes, key: bytes) -> Signature:
    """Creates an ECDSA-SHA2-NISTP256 signature."""
    ec_key = load_pem_private_key(key, password=None)
    if not isinstance(ec_key, ec.EllipticCurvePrivateKey):
        raise TypeError(f'Not an elliptic curve private key: {type(ec_key)}.'
                        'Try generate a key with gen_ecdsa_keypair()?')

    tuf_key = Key(key_type=KeyType.ECDSA_SHA2_NISTP256,
                  scheme=KeyScheme.ECDSA_SHA2_NISTP256_SCHEME,
                  keyval=ec_key.public_key().public_bytes(
                      Encoding.X962, PublicFormat.UncompressedPoint))

    der_signature = ec_key.sign(data, ec.ECDSA(hashes.SHA256()))  # pylint: disable=no-value-for-parameter
    int_r, int_s = decode_dss_signature(der_signature)
    sig_bytes = int_r.to_bytes(32, 'big') + int_s.to_bytes(32, 'big')

    return Signature(key_id=gen_key_id(tuf_key), sig=sig_bytes)


def verify_ecdsa_signature(sig: bytes, data: bytes, key: Key) -> bool:
    """Verifies an ECDSA-SHA2-NISTP256 signature with a given public key.

    Args:
      sig: the ECDSA signature as raw bytes (r||s).
      data: the message as plain text.
      key: the ECDSA-NISTP256 public key.

    Returns:
      True if the signature is verified. False otherwise.
    """
    ec_key = ec.EllipticCurvePublicKey.from_encoded_point(
        ec.SECP256R1(), key.keyval)
    try:
        dss_sig = encode_dss_signature(int.from_bytes(sig[:32], 'big'),
                                       int.from_bytes(sig[-32:], 'big'))
        ec_key.verify(dss_sig, data, ec.ECDSA(hashes.SHA256()))
    except:  # pylint: disable=bare-except
        return False

    return True


def main(out: Path) -> None:
    """Generates and writes to disk key pairs for development use."""

    # Currently only supports the "ecdsa-sha2-nistp256" key scheme.
    #
    # TODO(alizhang): Add support for "rsassa-pss-sha256" and "ed25519" key
    # schemes.
    gen_ecdsa_keypair(out)


if __name__ == '__main__':
    main(**vars(parse_args()))
