func GenerateSessionKeys() (pub, priv []byte, err error) {

	pub, priv, err = dhgroup14.GenerateKeyPair(rand.Reader)
	if err != nil {

		return
	}

	return
}
Exemple #2
0
// Handshake runs handshake if it has not yet been run. Most users of this
// package need not call Handshake explicitly: the first Read or Write will
// call it automatically.
func (c *Conn) Handshake() error {
	c.handshakeMutex.Lock()
	defer c.handshakeMutex.Unlock()

	if c.handshakePerformed {
		return nil
	}

	var nonces [32 + 32 + dhgroup14.SharedKeySize]byte
	if _, err := io.ReadFull(rand.Reader, nonces[:64]); err != nil {
		return err
	}
	nonceC := nonces[0:32]
	nonceS := nonces[32:64]

	// Send and receive random nonces.
	if c.isClient {
		if err := c.sendBytes(nonceC); err != nil {
			return err
		}
		if err := c.receiveBytes(nonceS); err != nil {
			return err
		}
	} else {
		if err := c.receiveBytes(nonceC); err != nil {
			return err
		}
		if err := c.sendBytes(nonceS); err != nil {
			return err
		}
	}

	// Generate dhmac_C and dhmac_S.
	dk1 := pbkdf2.Key(c.secretKey, nonces[:64], 1, 64, sha256.New)
	dhmacC := dk1[0:32]
	dhmacS := dk1[32:64]

	var myDHMac, theirDHMac []byte
	if c.isClient {
		myDHMac = dhmacC
		theirDHMac = dhmacS
	} else {
		myDHMac = dhmacS
		theirDHMac = dhmacC
	}

	// Generate DH key pair.
	myPublicKey, myPrivateKey, err := dhgroup14.GenerateKeyPair(rand.Reader)
	if err != nil {
		return err
	}

	// Prepare my public key for sending.
	var myAuthPublicKey [256 + 32]byte
	copy(myAuthPublicKey[:], myPublicKey)

	// Authenticate my public key.
	h := hmac.New(sha256.New, myDHMac)
	h.Write(myAuthPublicKey[0:256])
	h.Sum(myAuthPublicKey[256:256])

	var theirAuthPublicKey [256 + 32]byte

	if c.isClient {
		// If client, send our authenticated public key.
		if err := c.sendBytes(myAuthPublicKey[:]); err != nil {
			return err
		}
	}

	// Receive their authenticated public key.
	if err := c.receiveBytes(theirAuthPublicKey[:]); err != nil {
		return err
	}

	// Check their public key authenticator.
	var sum [32]byte
	h = hmac.New(sha256.New, theirDHMac)
	h.Write(theirAuthPublicKey[0:256])
	if subtle.ConstantTimeCompare(h.Sum(sum[:0]), theirAuthPublicKey[256:]) != 1 {
		return errors.New("spipe: authentication failed")
	}

	if !c.isClient {
		// If server, send our authenticated public key.
		if err := c.sendBytes(myAuthPublicKey[:]); err != nil {
			return err
		}
	}

	// Calculate DH shared key.
	theirPublicKey := theirAuthPublicKey[:256]
	dhSharedKey, err := dhgroup14.SharedKey(rand.Reader, theirPublicKey, myPrivateKey)
	if err != nil {
		return err
	}

	// Derive final encryption and MAC keys.
	copy(nonces[64:], dhSharedKey)
	dk2 := pbkdf2.Key(c.secretKey, nonces[:], 1, 128, sha256.New)

	eC, hC, eS, hS := dk2[0:32], dk2[32:64], dk2[64:96], dk2[96:128]

	// Set reader and writer depending on our role.
	if c.isClient {
		c.w = newEncryptor(c.conn, eC, hC)
		c.r = newDecryptor(c.conn, eS, hS)
	} else {
		c.w = newEncryptor(c.conn, eS, hS)
		c.r = newDecryptor(c.conn, eC, hC)
	}
	c.handshakePerformed = true
	return nil
}