mirror of
https://github.com/PretendoNetwork/nex-go.git
synced 2025-04-02 11:02:14 -04:00
89 lines
2 KiB
Go
89 lines
2 KiB
Go
package nex
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/hmac"
|
|
"crypto/md5"
|
|
"crypto/rc4"
|
|
"fmt"
|
|
)
|
|
|
|
// KerberosEncryption is used to encrypt/decrypt using Kerberos
|
|
type KerberosEncryption struct {
|
|
key []byte
|
|
cipher *rc4.Cipher
|
|
}
|
|
|
|
// Ticket represents a Kerberos authentication ticket
|
|
type Ticket struct {
|
|
sessionKey []byte
|
|
serverPID uint32
|
|
ticketData []byte
|
|
}
|
|
|
|
// TicketData contains the encrypted ticket info and an optional key used for deriving the encryption key for TicketInfo
|
|
type TicketData struct {
|
|
ticketKey []byte
|
|
ticketInfo []byte
|
|
}
|
|
|
|
// TicketInfo contains the actual data of the ticket
|
|
type TicketInfo struct {
|
|
datetime uint64
|
|
userPID uint32
|
|
sessionKey []byte
|
|
}
|
|
|
|
// Encrypt will encrypt the given data using Kerberos
|
|
func (encryption *KerberosEncryption) Encrypt(buffer []byte) []byte {
|
|
encrypted := make([]byte, len(buffer))
|
|
encryption.cipher.XORKeyStream(encrypted, buffer)
|
|
|
|
mac := hmac.New(md5.New, []byte(encryption.key))
|
|
mac.Write(encrypted)
|
|
hmac := mac.Sum(nil)
|
|
|
|
return append(encrypted, hmac...)
|
|
}
|
|
|
|
// Decrypt will decrypt the given data using Kerberos
|
|
func (encryption *KerberosEncryption) Decrypt(buffer []byte) []byte {
|
|
if !encryption.Validate(buffer) {
|
|
fmt.Println("INVALID KERB CHECKSUM")
|
|
}
|
|
|
|
offset := len(buffer)
|
|
offset = offset + -0x10
|
|
|
|
encrypted := buffer[:offset]
|
|
|
|
decrypted := make([]byte, len(encrypted))
|
|
encryption.cipher.XORKeyStream(decrypted, encrypted)
|
|
|
|
return decrypted
|
|
}
|
|
|
|
// Validate will check the HMAC of the encrypted data
|
|
func (encryption *KerberosEncryption) Validate(buffer []byte) bool {
|
|
offset := len(buffer)
|
|
offset = offset + -0x10
|
|
|
|
data := buffer[:offset]
|
|
checksum := buffer[offset:]
|
|
|
|
cipher := hmac.New(md5.New, []byte(encryption.key))
|
|
cipher.Write(data)
|
|
mac := cipher.Sum(nil)
|
|
|
|
return bytes.Equal(mac, checksum)
|
|
}
|
|
|
|
// NewKerberosEncryption returns a new KerberosEncryption instance
|
|
func NewKerberosEncryption(key []byte) *KerberosEncryption {
|
|
cipher, _ := rc4.NewCipher(key)
|
|
|
|
return &KerberosEncryption{
|
|
key: key,
|
|
cipher: cipher,
|
|
}
|
|
}
|