File: credentials_info.go

package info (click to toggle)
golang-gopkg-jcmturner-gokrb5.v5 5.3.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, bullseye-backports, sid
  • size: 1,168 kB
  • sloc: makefile: 2
file content (127 lines) | stat: -rw-r--r-- 3,860 bytes parent folder | download | duplicates (2)
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package pac

import (
	"encoding/binary"
	"errors"
	"fmt"

	"gopkg.in/jcmturner/gokrb5.v5/crypto"
	"gopkg.in/jcmturner/gokrb5.v5/iana/keyusage"
	"gopkg.in/jcmturner/gokrb5.v5/mstypes"
	"gopkg.in/jcmturner/gokrb5.v5/types"
	"gopkg.in/jcmturner/rpc.v0/ndr"
)

// https://msdn.microsoft.com/en-us/library/cc237931.aspx

// CredentialsInfo implements https://msdn.microsoft.com/en-us/library/cc237953.aspx
type CredentialsInfo struct {
	Version                    uint32
	EType                      uint32
	PACCredentialDataEncrypted []byte
	PACCredentialData          CredentialData
}

// Unmarshal bytes into the CredentialsInfo struct
func (c *CredentialsInfo) Unmarshal(b []byte, k types.EncryptionKey) error {
	//The CredentialsInfo structure is a simple structure that is not NDR-encoded.
	var p int
	var e binary.ByteOrder = binary.LittleEndian

	c.Version = ndr.ReadUint32(&b, &p, &e)
	if c.Version != 0 {
		return errors.New("credentials info version is not zero")
	}
	c.EType = ndr.ReadUint32(&b, &p, &e)
	c.PACCredentialDataEncrypted = ndr.ReadBytes(&b, &p, len(b)-p, &e)

	err := c.DecryptEncPart(k, &e)
	if err != nil {
		return fmt.Errorf("error decrypting PAC Credentials Data: %v", err)
	}
	return nil
}

// DecryptEncPart decrypts the encrypted part of the CredentialsInfo.
func (c *CredentialsInfo) DecryptEncPart(k types.EncryptionKey, e *binary.ByteOrder) error {
	if k.KeyType != int32(c.EType) {
		return fmt.Errorf("key provided is not the correct type. Type needed: %d, type provided: %d", c.EType, k.KeyType)
	}
	pt, err := crypto.DecryptMessage(c.PACCredentialDataEncrypted, k, keyusage.KERB_NON_KERB_SALT)
	if err != nil {
		return err
	}
	var p int
	c.PACCredentialData = ReadPACCredentialData(&pt, &p, e)
	return nil
}

// CredentialData implements https://msdn.microsoft.com/en-us/library/cc237952.aspx
type CredentialData struct {
	CredentialCount uint32
	Credentials     []SECPKGSupplementalCred // Size is the value of CredentialCount
}

// ReadPACCredentialData reads a CredentialData from the byte slice.
func ReadPACCredentialData(b *[]byte, p *int, e *binary.ByteOrder) CredentialData {
	c := ndr.ReadUint32(b, p, e)
	cr := make([]SECPKGSupplementalCred, c, c)
	for i := range cr {
		cr[i] = ReadSECPKGSupplementalCred(b, p, e)
	}
	return CredentialData{
		CredentialCount: c,
		Credentials:     cr,
	}
}

// SECPKGSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237956.aspx
type SECPKGSupplementalCred struct {
	PackageName    mstypes.RPCUnicodeString
	CredentialSize uint32
	Credentials    []uint8 // Is a ptr. Size is the value of CredentialSize
}

// ReadSECPKGSupplementalCred reads a SECPKGSupplementalCred from the byte slice.
func ReadSECPKGSupplementalCred(b *[]byte, p *int, e *binary.ByteOrder) SECPKGSupplementalCred {
	n, _ := mstypes.ReadRPCUnicodeString(b, p, e)
	cs := ndr.ReadUint32(b, p, e)
	c := make([]uint8, cs, cs)
	for i := range c {
		c[i] = ndr.ReadUint8(b, p)
	}
	return SECPKGSupplementalCred{
		PackageName:    n,
		CredentialSize: cs,
		Credentials:    c,
	}
}

// NTLMSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237949.aspx
type NTLMSupplementalCred struct {
	Version    uint32
	Flags      uint32
	LMPassword []byte
	NTPassword []byte
}

// ReadNTLMSupplementalCred reads a NTLMSupplementalCred from the byte slice.
func ReadNTLMSupplementalCred(b *[]byte, p *int, e *binary.ByteOrder) NTLMSupplementalCred {
	v := ndr.ReadUint32(b, p, e)
	f := ndr.ReadUint32(b, p, e)
	l := ndr.ReadBytes(b, p, 16, e)
	n := ndr.ReadBytes(b, p, 16, e)
	return NTLMSupplementalCred{
		Version:    v,
		Flags:      f,
		LMPassword: l,
		NTPassword: n,
	}
}

const (
	// NTLMSupCredLMOWF indicates that the LM OWF member is present and valid.
	NTLMSupCredLMOWF = 31
	// NTLMSupCredNTOWF indicates that the NT OWF member is present and valid.
	NTLMSupCredNTOWF = 30
)