forked from PretendoNetwork/nex-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kerberos.go
89 lines (70 loc) · 1.97 KB
/
kerberos.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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,
}
}