credentials_info.go 2.5 KB

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