blob: 484ec5be071db2c66c980850f8c0ec997f28e6a4 [file] [log] [blame]
Scott Baker8461e152019-10-01 14:44:30 -07001package 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 "gopkg.in/jcmturner/gokrb5.v7/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}