VOL-2112 move to voltha-lib-go
Change-Id: I3435b8acb982deeab6b6ac28e798d7722ad01d0a
diff --git a/vendor/gopkg.in/jcmturner/gokrb5.v7/pac/pac_type.go b/vendor/gopkg.in/jcmturner/gokrb5.v7/pac/pac_type.go
new file mode 100644
index 0000000..c73fd06
--- /dev/null
+++ b/vendor/gopkg.in/jcmturner/gokrb5.v7/pac/pac_type.go
@@ -0,0 +1,251 @@
+package pac
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "log"
+
+ "gopkg.in/jcmturner/gokrb5.v7/crypto"
+ "gopkg.in/jcmturner/gokrb5.v7/iana/keyusage"
+ "gopkg.in/jcmturner/gokrb5.v7/types"
+ "gopkg.in/jcmturner/rpc.v1/mstypes"
+)
+
+const (
+ infoTypeKerbValidationInfo uint32 = 1
+ infoTypeCredentials uint32 = 2
+ infoTypePACServerSignatureData uint32 = 6
+ infoTypePACKDCSignatureData uint32 = 7
+ infoTypePACClientInfo uint32 = 10
+ infoTypeS4UDelegationInfo uint32 = 11
+ infoTypeUPNDNSInfo uint32 = 12
+ infoTypePACClientClaimsInfo uint32 = 13
+ infoTypePACDeviceInfo uint32 = 14
+ infoTypePACDeviceClaimsInfo uint32 = 15
+)
+
+// PACType implements: https://msdn.microsoft.com/en-us/library/cc237950.aspx
+type PACType struct {
+ CBuffers uint32
+ Version uint32
+ Buffers []InfoBuffer
+ Data []byte
+ KerbValidationInfo *KerbValidationInfo
+ CredentialsInfo *CredentialsInfo
+ ServerChecksum *SignatureData
+ KDCChecksum *SignatureData
+ ClientInfo *ClientInfo
+ S4UDelegationInfo *S4UDelegationInfo
+ UPNDNSInfo *UPNDNSInfo
+ ClientClaimsInfo *ClientClaimsInfo
+ DeviceInfo *DeviceInfo
+ DeviceClaimsInfo *DeviceClaimsInfo
+ ZeroSigData []byte
+}
+
+// InfoBuffer implements the PAC Info Buffer: https://msdn.microsoft.com/en-us/library/cc237954.aspx
+type InfoBuffer struct {
+ ULType uint32 // A 32-bit unsigned integer in little-endian format that describes the type of data present in the buffer contained at Offset.
+ CBBufferSize uint32 // A 32-bit unsigned integer in little-endian format that contains the size, in bytes, of the buffer in the PAC located at Offset.
+ Offset uint64 // A 64-bit unsigned integer in little-endian format that contains the offset to the beginning of the buffer, in bytes, from the beginning of the PACTYPE structure. The data offset MUST be a multiple of eight. The following sections specify the format of each type of element.
+}
+
+// Unmarshal bytes into the PACType struct
+func (pac *PACType) Unmarshal(b []byte) (err error) {
+ pac.Data = b
+ zb := make([]byte, len(b), len(b))
+ copy(zb, b)
+ pac.ZeroSigData = zb
+ r := mstypes.NewReader(bytes.NewReader(b))
+ pac.CBuffers, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ pac.Version, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ buf := make([]InfoBuffer, pac.CBuffers, pac.CBuffers)
+ for i := range buf {
+ buf[i].ULType, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ buf[i].CBBufferSize, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ buf[i].Offset, err = r.Uint64()
+ if err != nil {
+ return
+ }
+ }
+ pac.Buffers = buf
+ return nil
+}
+
+// ProcessPACInfoBuffers processes the PAC Info Buffers.
+// https://msdn.microsoft.com/en-us/library/cc237954.aspx
+func (pac *PACType) ProcessPACInfoBuffers(key types.EncryptionKey, l *log.Logger) error {
+ for _, buf := range pac.Buffers {
+ p := make([]byte, buf.CBBufferSize, buf.CBBufferSize)
+ copy(p, pac.Data[int(buf.Offset):int(buf.Offset)+int(buf.CBBufferSize)])
+ switch buf.ULType {
+ case infoTypeKerbValidationInfo:
+ if pac.KerbValidationInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k KerbValidationInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ return fmt.Errorf("error processing KerbValidationInfo: %v", err)
+ }
+ pac.KerbValidationInfo = &k
+ case infoTypeCredentials:
+ // Currently PAC parsing is only useful on the service side in gokrb5
+ // The CredentialsInfo are only useful when gokrb5 has implemented RFC4556 and only applied on the client side.
+ // Skipping CredentialsInfo - will be revisited under RFC4556 implementation.
+ continue
+ //if pac.CredentialsInfo != nil {
+ // //Must ignore subsequent buffers of this type
+ // continue
+ //}
+ //var k CredentialsInfo
+ //err := k.Unmarshal(p, key) // The encryption key used is the AS reply key only available to the client.
+ //if err != nil {
+ // return fmt.Errorf("error processing CredentialsInfo: %v", err)
+ //}
+ //pac.CredentialsInfo = &k
+ case infoTypePACServerSignatureData:
+ if pac.ServerChecksum != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k SignatureData
+ zb, err := k.Unmarshal(p)
+ copy(pac.ZeroSigData[int(buf.Offset):int(buf.Offset)+int(buf.CBBufferSize)], zb)
+ if err != nil {
+ return fmt.Errorf("error processing ServerChecksum: %v", err)
+ }
+ pac.ServerChecksum = &k
+ case infoTypePACKDCSignatureData:
+ if pac.KDCChecksum != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k SignatureData
+ zb, err := k.Unmarshal(p)
+ copy(pac.ZeroSigData[int(buf.Offset):int(buf.Offset)+int(buf.CBBufferSize)], zb)
+ if err != nil {
+ return fmt.Errorf("error processing KDCChecksum: %v", err)
+ }
+ pac.KDCChecksum = &k
+ case infoTypePACClientInfo:
+ if pac.ClientInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k ClientInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ return fmt.Errorf("error processing ClientInfo: %v", err)
+ }
+ pac.ClientInfo = &k
+ case infoTypeS4UDelegationInfo:
+ if pac.S4UDelegationInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k S4UDelegationInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process S4U_DelegationInfo: %v", err)
+ continue
+ }
+ pac.S4UDelegationInfo = &k
+ case infoTypeUPNDNSInfo:
+ if pac.UPNDNSInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k UPNDNSInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process UPN_DNSInfo: %v", err)
+ continue
+ }
+ pac.UPNDNSInfo = &k
+ case infoTypePACClientClaimsInfo:
+ if pac.ClientClaimsInfo != nil || len(p) < 1 {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k ClientClaimsInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process ClientClaimsInfo: %v", err)
+ continue
+ }
+ pac.ClientClaimsInfo = &k
+ case infoTypePACDeviceInfo:
+ if pac.DeviceInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k DeviceInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process DeviceInfo: %v", err)
+ continue
+ }
+ pac.DeviceInfo = &k
+ case infoTypePACDeviceClaimsInfo:
+ if pac.DeviceClaimsInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k DeviceClaimsInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process DeviceClaimsInfo: %v", err)
+ continue
+ }
+ pac.DeviceClaimsInfo = &k
+ }
+ }
+
+ if ok, err := pac.verify(key); !ok {
+ return err
+ }
+
+ return nil
+}
+
+func (pac *PACType) verify(key types.EncryptionKey) (bool, error) {
+ if pac.KerbValidationInfo == nil {
+ return false, errors.New("PAC Info Buffers does not contain a KerbValidationInfo")
+ }
+ if pac.ServerChecksum == nil {
+ return false, errors.New("PAC Info Buffers does not contain a ServerChecksum")
+ }
+ if pac.KDCChecksum == nil {
+ return false, errors.New("PAC Info Buffers does not contain a KDCChecksum")
+ }
+ if pac.ClientInfo == nil {
+ return false, errors.New("PAC Info Buffers does not contain a ClientInfo")
+ }
+ etype, err := crypto.GetChksumEtype(int32(pac.ServerChecksum.SignatureType))
+ if err != nil {
+ return false, err
+ }
+ if ok := etype.VerifyChecksum(key.KeyValue,
+ pac.ZeroSigData,
+ pac.ServerChecksum.Signature,
+ keyusage.KERB_NON_KERB_CKSUM_SALT); !ok {
+ return false, errors.New("PAC service checksum verification failed")
+ }
+
+ return true, nil
+}