blob: a8c2c3ca7f8db56b66e9f0bb04afd6b665d77ecc [file] [log] [blame]
Scott Baker8487c5d2019-10-18 12:49:46 -07001package pac
2
3import (
4 "bytes"
5 "errors"
6 "fmt"
7
8 "gopkg.in/jcmturner/gokrb5.v7/crypto"
9 "gopkg.in/jcmturner/gokrb5.v7/iana/keyusage"
10 "gopkg.in/jcmturner/gokrb5.v7/types"
11 "gopkg.in/jcmturner/rpc.v1/mstypes"
12 "gopkg.in/jcmturner/rpc.v1/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
44 err = c.DecryptEncPart(k)
45 if err != nil {
46 err = fmt.Errorf("error decrypting PAC Credentials Data: %v", err)
47 return
48 }
49 return
50}
51
52// DecryptEncPart decrypts the encrypted part of the CredentialsInfo.
53func (c *CredentialsInfo) DecryptEncPart(k types.EncryptionKey) error {
54 if k.KeyType != int32(c.EType) {
55 return fmt.Errorf("key provided is not the correct type. Type needed: %d, type provided: %d", c.EType, k.KeyType)
56 }
57 pt, err := crypto.DecryptMessage(c.PACCredentialDataEncrypted, k, keyusage.KERB_NON_KERB_SALT)
58 if err != nil {
59 return err
60 }
61 err = c.PACCredentialData.Unmarshal(pt)
62 if err != nil {
63 return err
64 }
65 return nil
66}
67
68// CredentialData implements https://msdn.microsoft.com/en-us/library/cc237952.aspx
69// This structure is encrypted prior to being encoded in any other structures.
70// Encryption is performed by first serializing the data structure via Network Data Representation (NDR) encoding, as specified in [MS-RPCE].
71// Once serialized, the data is encrypted using the key and cryptographic system selected through the AS protocol and the KRB_AS_REP message
72// Fields (for capturing this information) and cryptographic parameters are specified in PAC_CREDENTIAL_INFO (section 2.6.1).
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}