// 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
}
