// Copyright 2009 The Go 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 tls

import (
	"bytes";
	"crypto/hmac";
	"crypto/md5";
	"crypto/sha1";
	"hash";
	"os";
	"strings";
)

// Split a premaster secret in two as specified in RFC 4346, section 5.
func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
	s1 = secret[0 : (len(secret)+1)/2];
	s2 = secret[len(secret)/2 : len(secret)];
	return;
}

// pHash implements the P_hash function, as defined in RFC 4346, section 5.
func pHash(result, secret, seed []byte, hash hash.Hash) {
	h := hmac.New(hash, secret);
	h.Write(seed);
	a := h.Sum();

	j := 0;
	for j < len(result) {
		h.Reset();
		h.Write(a);
		h.Write(seed);
		b := h.Sum();
		todo := len(b);
		if j+todo > len(result) {
			todo = len(result) - j
		}
		bytes.Copy(result[j:j+todo], b);
		j += todo;

		h.Reset();
		h.Write(a);
		a = h.Sum();
	}
}

// pRF11 implements the TLS 1.1 pseudo-random function, as defined in RFC 4346, section 5.
func pRF11(result, secret, label, seed []byte) {
	hashSHA1 := sha1.New();
	hashMD5 := md5.New();

	labelAndSeed := make([]byte, len(label)+len(seed));
	bytes.Copy(labelAndSeed, label);
	bytes.Copy(labelAndSeed[len(label):len(labelAndSeed)], seed);

	s1, s2 := splitPreMasterSecret(secret);
	pHash(result, s1, labelAndSeed, hashMD5);
	result2 := make([]byte, len(result));
	pHash(result2, s2, labelAndSeed, hashSHA1);

	for i, b := range result2 {
		result[i] ^= b
	}
}

const (
	tlsRandomLength		= 32;	// Length of a random nonce in TLS 1.1.
	masterSecretLength	= 48;	// Length of a master secret in TLS 1.1.
	finishedVerifyLength	= 12;	// Length of verify_data in a Finished message.
)

var masterSecretLabel = strings.Bytes("master secret")
var keyExpansionLabel = strings.Bytes("key expansion")
var clientFinishedLabel = strings.Bytes("client finished")
var serverFinishedLabel = strings.Bytes("server finished")

// keysFromPreMasterSecret generates the connection keys from the pre master
// secret, given the lengths of the MAC and cipher keys, as defined in RFC
// 4346, section 6.3.
func keysFromPreMasterSecret11(preMasterSecret, clientRandom, serverRandom []byte, macLen, keyLen int) (masterSecret, clientMAC, serverMAC, clientKey, serverKey []byte) {
	var seed [tlsRandomLength * 2]byte;
	bytes.Copy(seed[0:len(clientRandom)], clientRandom);
	bytes.Copy(seed[len(clientRandom):len(seed)], serverRandom);
	masterSecret = make([]byte, masterSecretLength);
	pRF11(masterSecret, preMasterSecret, masterSecretLabel, seed[0:len(seed)]);

	bytes.Copy(seed[0:len(clientRandom)], serverRandom);
	bytes.Copy(seed[len(serverRandom):len(seed)], clientRandom);

	n := 2*macLen + 2*keyLen;
	keyMaterial := make([]byte, n);
	pRF11(keyMaterial, masterSecret, keyExpansionLabel, seed[0:len(seed)]);
	clientMAC = keyMaterial[0:macLen];
	serverMAC = keyMaterial[macLen : macLen*2];
	clientKey = keyMaterial[macLen*2 : macLen*2+keyLen];
	serverKey = keyMaterial[macLen*2+keyLen : len(keyMaterial)];
	return;
}

// A finishedHash calculates the hash of a set of handshake messages suitable
// for including in a Finished message.
type finishedHash struct {
	clientMD5	hash.Hash;
	clientSHA1	hash.Hash;
	serverMD5	hash.Hash;
	serverSHA1	hash.Hash;
}

func newFinishedHash() finishedHash {
	return finishedHash{md5.New(), sha1.New(), md5.New(), sha1.New()}
}

func (h finishedHash) Write(msg []byte) (n int, err os.Error) {
	h.clientMD5.Write(msg);
	h.clientSHA1.Write(msg);
	h.serverMD5.Write(msg);
	h.serverSHA1.Write(msg);
	return len(msg), nil;
}

// finishedSum calculates the contents of the verify_data member of a Finished
// message given the MD5 and SHA1 hashes of a set of handshake messages.
func finishedSum(md5, sha1, label, masterSecret []byte) []byte {
	seed := make([]byte, len(md5)+len(sha1));
	bytes.Copy(seed, md5);
	bytes.Copy(seed[len(md5):len(seed)], sha1);
	out := make([]byte, finishedVerifyLength);
	pRF11(out, masterSecret, label, seed);
	return out;
}

// clientSum returns the contents of the verify_data member of a client's
// Finished message.
func (h finishedHash) clientSum(masterSecret []byte) []byte {
	md5 := h.clientMD5.Sum();
	sha1 := h.clientSHA1.Sum();
	return finishedSum(md5, sha1, clientFinishedLabel, masterSecret);
}

// serverSum returns the contents of the verify_data member of a server's
// Finished message.
func (h finishedHash) serverSum(masterSecret []byte) []byte {
	md5 := h.serverMD5.Sum();
	sha1 := h.serverSHA1.Sum();
	return finishedSum(md5, sha1, serverFinishedLabel, masterSecret);
}
