blob: 0c7ccd4263e5020a320cf4c8085bf54ddb3600e5 [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001package pac
2
3import (
4 "bytes"
5 "errors"
6 "fmt"
7
8 "github.com/jcmturner/gokrb5/v8/crypto"
9 "github.com/jcmturner/gokrb5/v8/iana/keyusage"
10 "github.com/jcmturner/gokrb5/v8/types"
11 "github.com/jcmturner/rpc/v2/mstypes"
12 "github.com/jcmturner/rpc/v2/ndr"
13)
14
15// https://msdn.microsoft.com/en-us/library/cc237931.aspx
16
17// CredentialsInfo implements https://msdn.microsoft.com/en-us/library/cc237953.aspx
18type CredentialsInfo struct {
19 Version uint32 // A 32-bit unsigned integer in little-endian format that defines the version. MUST be 0x00000000.
20 EType uint32
21 PACCredentialDataEncrypted []byte // Key usage number for encryption: KERB_NON_KERB_SALT (16)
22 PACCredentialData CredentialData
23}
24
25// Unmarshal bytes into the CredentialsInfo struct
26func (c *CredentialsInfo) Unmarshal(b []byte, k types.EncryptionKey) (err error) {
27 //The CredentialsInfo structure is a simple structure that is not NDR-encoded.
28 r := mstypes.NewReader(bytes.NewReader(b))
29
30 c.Version, err = r.Uint32()
31 if err != nil {
32 return
33 }
34 if c.Version != 0 {
35 err = errors.New("credentials info version is not zero")
36 return
37 }
38 c.EType, err = r.Uint32()
39 if err != nil {
40 return
41 }
42 c.PACCredentialDataEncrypted, err = r.ReadBytes(len(b) - 8)
43 if err != nil {
44 err = fmt.Errorf("error reading PAC Credetials Data: %v", err)
45 return
46 }
47
48 err = c.DecryptEncPart(k)
49 if err != nil {
50 err = fmt.Errorf("error decrypting PAC Credentials Data: %v", err)
51 return
52 }
53 return
54}
55
56// DecryptEncPart decrypts the encrypted part of the CredentialsInfo.
57func (c *CredentialsInfo) DecryptEncPart(k types.EncryptionKey) error {
58 if k.KeyType != int32(c.EType) {
59 return fmt.Errorf("key provided is not the correct type. Type needed: %d, type provided: %d", c.EType, k.KeyType)
60 }
61 pt, err := crypto.DecryptMessage(c.PACCredentialDataEncrypted, k, keyusage.KERB_NON_KERB_SALT)
62 if err != nil {
63 return err
64 }
65 err = c.PACCredentialData.Unmarshal(pt)
66 if err != nil {
67 return err
68 }
69 return nil
70}
71
72// CredentialData implements https://msdn.microsoft.com/en-us/library/cc237952.aspx
73type CredentialData struct {
74 CredentialCount uint32
75 Credentials []SECPKGSupplementalCred // Size is the value of CredentialCount
76}
77
78// Unmarshal converts the bytes provided into a CredentialData type.
79func (c *CredentialData) Unmarshal(b []byte) (err error) {
80 dec := ndr.NewDecoder(bytes.NewReader(b))
81 err = dec.Decode(c)
82 if err != nil {
83 err = fmt.Errorf("error unmarshaling KerbValidationInfo: %v", err)
84 }
85 return
86}