// Copyright (c) 2020, Google Inc.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

package subprocess

import (
	"encoding/binary"
	"encoding/hex"
	"encoding/json"
	"fmt"
)

type tlsKDFVectorSet struct {
	Groups []tlsKDFTestGroup `json:"testGroups"`
}

type tlsKDFTestGroup struct {
	ID           uint64       `json:"tgId"`
	Hash         string       `json:"hashAlg"`
	TLSVersion   string       `json:"tlsVersion"`
	KeyBlockBits uint64       `json:"keyBlockLength"`
	PMSLength    uint64       `json:"preMasterSecretLength"`
	Tests        []tlsKDFTest `json:"tests"`
}

type tlsKDFTest struct {
	ID     uint64 `json:"tcId"`
	PMSHex string `json:"preMasterSecret"`
	// ClientHelloRandomHex and ServerHelloRandomHex are used for deriving the
	// master secret. ClientRandomHex and ServerRandomHex are used for deriving the
	// key block. Having different values for these is not possible in a TLS
	// handshake unless you squint at a resumption handshake and somehow rederive
	// the master secret from the session information during resumption.
	ClientHelloRandomHex string `json:"clientHelloRandom"`
	ServerHelloRandomHex string `json:"serverHelloRandom"`
	ClientRandomHex      string `json:"clientRandom"`
	ServerRandomHex      string `json:"serverRandom"`
}

type tlsKDFTestGroupResponse struct {
	ID    uint64               `json:"tgId"`
	Tests []tlsKDFTestResponse `json:"tests"`
}

type tlsKDFTestResponse struct {
	ID              uint64 `json:"tcId"`
	MasterSecretHex string `json:"masterSecret"`
	KeyBlockHex     string `json:"keyBlock"`
}

type tlsKDF struct{}

func (k *tlsKDF) Process(vectorSet []byte, m Transactable) (interface{}, error) {
	var parsed tlsKDFVectorSet
	if err := json.Unmarshal(vectorSet, &parsed); err != nil {
		return nil, err
	}

	// See https://usnistgov.github.io/ACVP/draft-celi-acvp-kdf-tls.html
	var ret []tlsKDFTestGroupResponse
	for _, group := range parsed.Groups {
		response := tlsKDFTestGroupResponse{
			ID: group.ID,
		}

		var tlsVer string
		switch group.TLSVersion {
		case "v1.0/1.1":
			tlsVer = "1.0"
		case "v1.2":
			tlsVer = "1.2"
		default:
			return nil, fmt.Errorf("unknown TLS version %q", group.TLSVersion)
		}

		hashIsTLS10 := false
		switch group.Hash {
		case "SHA-1":
			hashIsTLS10 = true
		case "SHA2-256", "SHA2-384", "SHA2-512":
			break
		default:
			return nil, fmt.Errorf("unknown hash %q", group.Hash)
		}

		if (tlsVer == "1.0") != hashIsTLS10 {
			return nil, fmt.Errorf("hash %q not permitted with TLS version %q", group.Hash, group.TLSVersion)
		}

		if group.KeyBlockBits%8 != 0 {
			return nil, fmt.Errorf("requested key-block length (%d bits) is not a whole number of bytes", group.KeyBlockBits)
		}

		method := "TLSKDF/" + tlsVer + "/" + group.Hash

		for _, test := range group.Tests {
			pms, err := hex.DecodeString(test.PMSHex)
			if err != nil {
				return nil, err
			}

			clientHelloRandom, err := hex.DecodeString(test.ClientHelloRandomHex)
			if err != nil {
				return nil, err
			}

			serverHelloRandom, err := hex.DecodeString(test.ServerHelloRandomHex)
			if err != nil {
				return nil, err
			}

			clientRandom, err := hex.DecodeString(test.ClientRandomHex)
			if err != nil {
				return nil, err
			}

			serverRandom, err := hex.DecodeString(test.ServerRandomHex)
			if err != nil {
				return nil, err
			}

			const (
				masterSecretLength = 48
				masterSecretLabel  = "master secret"
				keyBlockLabel      = "key expansion"
			)

			var outLenBytes [4]byte
			binary.LittleEndian.PutUint32(outLenBytes[:], uint32(masterSecretLength))
			result, err := m.Transact(method, 1, outLenBytes[:], pms, []byte(masterSecretLabel), clientHelloRandom, serverHelloRandom)
			if err != nil {
				return nil, err
			}

			binary.LittleEndian.PutUint32(outLenBytes[:], uint32(group.KeyBlockBits/8))
			// TLS 1.0, 1.1, and 1.2 use a different order for the client and server
			// randoms when computing the key block.
			result2, err := m.Transact(method, 1, outLenBytes[:], result[0], []byte(keyBlockLabel), serverRandom, clientRandom)
			if err != nil {
				return nil, err
			}

			response.Tests = append(response.Tests, tlsKDFTestResponse{
				ID:              test.ID,
				MasterSecretHex: hex.EncodeToString(result[0]),
				KeyBlockHex:     hex.EncodeToString(result2[0]),
			})
		}

		ret = append(ret, response)
	}

	return ret, nil
}
