github.com/jcmturner/gokrb5/v8@v8.4.4/pac/credentials_info.go (about)

     1  package pac
     2  
     3  import (
     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
    18  type 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
    26  func (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.
    57  func (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
    73  type 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.
    79  func (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  }