83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
package handshake
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/honeybbq/teamspeak-go/crypto"
|
|
)
|
|
|
|
var (
|
|
errAlphaNotInitialized = errors.New("alpha is not initialized")
|
|
errInitProofInvalid = errors.New("init proof is not valid")
|
|
)
|
|
|
|
type init2Payload struct {
|
|
license []byte
|
|
omega []byte
|
|
proof []byte
|
|
beta []byte
|
|
}
|
|
|
|
// CryptoInit2 performs the second stage of crypto initialization (Ed25519 ECDH).
|
|
func CryptoInit2(tc *crypto.Crypt, license, omega, proof, beta string, privateKey []byte) error {
|
|
if len(tc.AlphaTmp) == 0 {
|
|
return errAlphaNotInitialized
|
|
}
|
|
payload, err := decodeInit2Payload(license, omega, proof, beta)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
serverPubKey, err := crypto.ImportPublicKey(payload.omega)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if !crypto.VerifySign(serverPubKey, payload.license, payload.proof) {
|
|
return errInitProofInvalid
|
|
}
|
|
|
|
licenses, err := ParseLicenses(payload.license)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
key, err := licenses.DeriveKey()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
sharedSecret, err := crypto.GetSharedSecret2(key, privateKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return tc.SetSharedSecret(tc.AlphaTmp, payload.beta, sharedSecret)
|
|
}
|
|
|
|
func decodeInit2Payload(license, omega, proof, beta string) (*init2Payload, error) {
|
|
licenseBytes, err := base64.StdEncoding.DecodeString(license)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid license: %w", err)
|
|
}
|
|
omegaBytes, err := base64.StdEncoding.DecodeString(omega)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid omega: %w", err)
|
|
}
|
|
proofBytes, err := base64.StdEncoding.DecodeString(proof)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid proof: %w", err)
|
|
}
|
|
betaBytes, err := base64.StdEncoding.DecodeString(beta)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("invalid beta: %w", err)
|
|
}
|
|
|
|
return &init2Payload{
|
|
license: licenseBytes,
|
|
omega: omegaBytes,
|
|
proof: proofBytes,
|
|
beta: betaBytes,
|
|
}, nil
|
|
}
|