1package types 2 3// Reference: https://www.ietf.org/rfc/rfc4120.txt 4// Section: 5.2.7 5import ( 6 "fmt" 7 "time" 8 9 "github.com/jcmturner/gofork/encoding/asn1" 10 "github.com/jcmturner/gokrb5/v8/iana/patype" 11) 12 13// PAData implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7 14type PAData struct { 15 PADataType int32 `asn1:"explicit,tag:1"` 16 PADataValue []byte `asn1:"explicit,tag:2"` 17} 18 19// PADataSequence implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7 20type PADataSequence []PAData 21 22// MethodData implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.9.1 23type MethodData []PAData 24 25// PAEncTimestamp implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.2 26type PAEncTimestamp EncryptedData 27 28// PAEncTSEnc implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.2 29type PAEncTSEnc struct { 30 PATimestamp time.Time `asn1:"generalized,explicit,tag:0"` 31 PAUSec int `asn1:"explicit,optional,tag:1"` 32} 33 34// Contains tests if a PADataSequence contains PA Data of a certain type. 35func (pas *PADataSequence) Contains(patype int32) bool { 36 for _, pa := range *pas { 37 if pa.PADataType == patype { 38 return true 39 } 40 } 41 return false 42} 43 44// GetPAEncTSEncAsnMarshalled returns the bytes of a PAEncTSEnc. 45func GetPAEncTSEncAsnMarshalled() ([]byte, error) { 46 t := time.Now().UTC() 47 p := PAEncTSEnc{ 48 PATimestamp: t, 49 PAUSec: int((t.UnixNano() / int64(time.Microsecond)) - (t.Unix() * 1e6)), 50 } 51 b, err := asn1.Marshal(p) 52 if err != nil { 53 return b, fmt.Errorf("error mashaling PAEncTSEnc: %v", err) 54 } 55 return b, nil 56} 57 58// ETypeInfoEntry implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.4 59type ETypeInfoEntry struct { 60 EType int32 `asn1:"explicit,tag:0"` 61 Salt []byte `asn1:"explicit,optional,tag:1"` 62} 63 64// ETypeInfo implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.4 65type ETypeInfo []ETypeInfoEntry 66 67// ETypeInfo2Entry implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.5 68type ETypeInfo2Entry struct { 69 EType int32 `asn1:"explicit,tag:0"` 70 Salt string `asn1:"explicit,optional,generalstring,tag:1"` 71 S2KParams []byte `asn1:"explicit,optional,tag:2"` 72} 73 74// ETypeInfo2 implements RFC 4120 types: https://tools.ietf.org/html/rfc4120#section-5.2.7.5 75type ETypeInfo2 []ETypeInfo2Entry 76 77// PAReqEncPARep PA Data Type 78type PAReqEncPARep struct { 79 ChksumType int32 `asn1:"explicit,tag:0"` 80 Chksum []byte `asn1:"explicit,tag:1"` 81} 82 83// Unmarshal bytes into the PAData 84func (pa *PAData) Unmarshal(b []byte) error { 85 _, err := asn1.Unmarshal(b, pa) 86 return err 87} 88 89// Unmarshal bytes into the PADataSequence 90func (pas *PADataSequence) Unmarshal(b []byte) error { 91 _, err := asn1.Unmarshal(b, pas) 92 return err 93} 94 95// Unmarshal bytes into the PAReqEncPARep 96func (pa *PAReqEncPARep) Unmarshal(b []byte) error { 97 _, err := asn1.Unmarshal(b, pa) 98 return err 99} 100 101// Unmarshal bytes into the PAEncTimestamp 102func (pa *PAEncTimestamp) Unmarshal(b []byte) error { 103 _, err := asn1.Unmarshal(b, pa) 104 return err 105} 106 107// Unmarshal bytes into the PAEncTSEnc 108func (pa *PAEncTSEnc) Unmarshal(b []byte) error { 109 _, err := asn1.Unmarshal(b, pa) 110 return err 111} 112 113// Unmarshal bytes into the ETypeInfo 114func (a *ETypeInfo) Unmarshal(b []byte) error { 115 _, err := asn1.Unmarshal(b, a) 116 return err 117} 118 119// Unmarshal bytes into the ETypeInfoEntry 120func (a *ETypeInfoEntry) Unmarshal(b []byte) error { 121 _, err := asn1.Unmarshal(b, a) 122 return err 123} 124 125// Unmarshal bytes into the ETypeInfo2 126func (a *ETypeInfo2) Unmarshal(b []byte) error { 127 _, err := asn1.Unmarshal(b, a) 128 return err 129} 130 131// Unmarshal bytes into the ETypeInfo2Entry 132func (a *ETypeInfo2Entry) Unmarshal(b []byte) error { 133 _, err := asn1.Unmarshal(b, a) 134 return err 135} 136 137// GetETypeInfo returns an ETypeInfo from the PAData. 138func (pa *PAData) GetETypeInfo() (d ETypeInfo, err error) { 139 if pa.PADataType != patype.PA_ETYPE_INFO { 140 err = fmt.Errorf("PAData does not contain PA EType Info data. TypeID Expected: %v; Actual: %v", patype.PA_ETYPE_INFO, pa.PADataType) 141 return 142 } 143 _, err = asn1.Unmarshal(pa.PADataValue, &d) 144 return 145} 146 147// GetETypeInfo2 returns an ETypeInfo2 from the PAData. 148func (pa *PAData) GetETypeInfo2() (d ETypeInfo2, err error) { 149 if pa.PADataType != patype.PA_ETYPE_INFO2 { 150 err = fmt.Errorf("PAData does not contain PA EType Info 2 data. TypeID Expected: %v; Actual: %v", patype.PA_ETYPE_INFO2, pa.PADataType) 151 return 152 } 153 _, err = asn1.Unmarshal(pa.PADataValue, &d) 154 return 155} 156