// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file

package main

import (
	"crypto/ecdsa"
	"crypto/md5"
	"crypto/x509"
	"encoding"
	"errors"
	"fmt"
)

// hash identifies a cryptographic hash function approved for use in signature algorithms.
type hash string

const (
	sha1Hash   = hash("SHA1")   // sha1 cryptographic hash function defined in RFC3174.
	sha256Hash = hash("SHA256") // sha256 cryptographic hash function defined  in FIPS 180-4.
	sha384Hash = hash("SHA384") // sha384 cryptographic hash function defined in FIPS 180-2.
	sha512Hash = hash("SHA512") // sha512 cryptographic hash function defined in FIPS 180-2.
)

// publicKey represents a public key using an unspecified algorithm.
//
// MarshalBinary returns the DER-encoded PKIX representation of the public key,
// while UnmarshalPublicKey creates a PublicKey object from the marshaled bytes.
//
// String returns a human-readable representation of the public key.
type publicKey interface {
	encoding.BinaryMarshaler
	fmt.Stringer

	// hashFn returns a cryptographic hash function whose security strength is
	// appropriate for creating message digests to sign with this public key.
	// For example, an ECDSA public key with a 512-bit curve would require a
	// 512-bit hash function, whilst a key with a 256-bit curve would be
	// happy with a 256-bit hash function.
	hashFn() hash
	implementationsOnlyInThisPackage()
}

type ecdsaPublicKey struct {
	key *ecdsa.PublicKey
}

func (pk *ecdsaPublicKey) MarshalBinary() ([]byte, error)    { return x509.MarshalPKIXPublicKey(pk.key) }
func (pk *ecdsaPublicKey) String() string                    { return publicKeyString(pk) }
func (pk *ecdsaPublicKey) implementationsOnlyInThisPackage() {}
func (pk *ecdsaPublicKey) hashFn() hash {
	if nbits := pk.key.Curve.Params().BitSize; nbits <= 160 {
		return sha1Hash
	} else if nbits <= 256 {
		return sha256Hash
	} else if nbits <= 384 {
		return sha384Hash
	} else {
		return sha512Hash
	}
}

func publicKeyString(pk publicKey) string {
	bytes, err := pk.MarshalBinary()
	if err != nil {
		return fmt.Sprintf("<invalid public key: %v>", err)
	}
	const hextable = "0123456789abcdef"
	h := md5.Sum(bytes)
	var repr [md5.Size * 3]byte
	for i, v := range h {
		repr[i*3] = hextable[v>>4]
		repr[i*3+1] = hextable[v&0x0f]
		repr[i*3+2] = ':'
	}
	return string(repr[:len(repr)-1])
}

// unmarshalPublicKey returns a PublicKey object from the DER-encoded PKIX representation of it
// (typically obtianed via PublicKey.MarshalBinary).
func unmarshalPublicKey(bytes []byte) (publicKey, error) {
	key, err := x509.ParsePKIXPublicKey(bytes)
	if err != nil {
		return nil, err
	}
	switch v := key.(type) {
	case *ecdsa.PublicKey:
		return &ecdsaPublicKey{v}, nil
	default:
		return nil, errors.New(fmt.Sprintf("Unrecognized key: %T", key))
	}
}

// newECDSAPublicKey creates a publicKey object that uses the ECDSA algorithm and the provided ECDSA public key.
func newECDSAPublicKey(key *ecdsa.PublicKey) publicKey {
	return &ecdsaPublicKey{key}
}
