blob: 536fdb9ec9396176334d726d6883b35b30dce75d [file] [log] [blame]
David K. Bainbridgebd6b2882021-08-26 13:31:02 +00001package messages
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/jcmturner/gofork/encoding/asn1"
8 "github.com/jcmturner/gokrb5/v8/crypto"
9 "github.com/jcmturner/gokrb5/v8/iana/asnAppTag"
10 "github.com/jcmturner/gokrb5/v8/iana/keyusage"
11 "github.com/jcmturner/gokrb5/v8/iana/msgtype"
12 "github.com/jcmturner/gokrb5/v8/krberror"
13 "github.com/jcmturner/gokrb5/v8/types"
14)
15
16type marshalKRBCred struct {
17 PVNO int `asn1:"explicit,tag:0"`
18 MsgType int `asn1:"explicit,tag:1"`
19 Tickets asn1.RawValue `asn1:"explicit,tag:2"`
20 EncPart types.EncryptedData `asn1:"explicit,tag:3"`
21}
22
23// KRBCred implements RFC 4120 KRB_CRED: https://tools.ietf.org/html/rfc4120#section-5.8.1.
24type KRBCred struct {
25 PVNO int
26 MsgType int
27 Tickets []Ticket
28 EncPart types.EncryptedData
29 DecryptedEncPart EncKrbCredPart
30}
31
32// EncKrbCredPart is the encrypted part of KRB_CRED.
33type EncKrbCredPart struct {
34 TicketInfo []KrbCredInfo `asn1:"explicit,tag:0"`
35 Nouce int `asn1:"optional,explicit,tag:1"`
36 Timestamp time.Time `asn1:"generalized,optional,explicit,tag:2"`
37 Usec int `asn1:"optional,explicit,tag:3"`
38 SAddress types.HostAddress `asn1:"optional,explicit,tag:4"`
39 RAddress types.HostAddress `asn1:"optional,explicit,tag:5"`
40}
41
42// KrbCredInfo is the KRB_CRED_INFO part of KRB_CRED.
43type KrbCredInfo struct {
44 Key types.EncryptionKey `asn1:"explicit,tag:0"`
45 PRealm string `asn1:"generalstring,optional,explicit,tag:1"`
46 PName types.PrincipalName `asn1:"optional,explicit,tag:2"`
47 Flags asn1.BitString `asn1:"optional,explicit,tag:3"`
48 AuthTime time.Time `asn1:"generalized,optional,explicit,tag:4"`
49 StartTime time.Time `asn1:"generalized,optional,explicit,tag:5"`
50 EndTime time.Time `asn1:"generalized,optional,explicit,tag:6"`
51 RenewTill time.Time `asn1:"generalized,optional,explicit,tag:7"`
52 SRealm string `asn1:"optional,explicit,ia5,tag:8"`
53 SName types.PrincipalName `asn1:"optional,explicit,tag:9"`
54 CAddr types.HostAddresses `asn1:"optional,explicit,tag:10"`
55}
56
57// Unmarshal bytes b into the KRBCred struct.
58func (k *KRBCred) Unmarshal(b []byte) error {
59 var m marshalKRBCred
60 _, err := asn1.UnmarshalWithParams(b, &m, fmt.Sprintf("application,explicit,tag:%v", asnAppTag.KRBCred))
61 if err != nil {
62 return processUnmarshalReplyError(b, err)
63 }
64 expectedMsgType := msgtype.KRB_CRED
65 if m.MsgType != expectedMsgType {
66 return krberror.NewErrorf(krberror.KRBMsgError, "message ID does not indicate a KRB_CRED. Expected: %v; Actual: %v", expectedMsgType, m.MsgType)
67 }
68 k.PVNO = m.PVNO
69 k.MsgType = m.MsgType
70 k.EncPart = m.EncPart
71 if len(m.Tickets.Bytes) > 0 {
72 k.Tickets, err = unmarshalTicketsSequence(m.Tickets)
73 if err != nil {
74 return krberror.Errorf(err, krberror.EncodingError, "error unmarshaling tickets within KRB_CRED")
75 }
76 }
77 return nil
78}
79
80// DecryptEncPart decrypts the encrypted part of a KRB_CRED.
81func (k *KRBCred) DecryptEncPart(key types.EncryptionKey) error {
82 b, err := crypto.DecryptEncPart(k.EncPart, key, keyusage.KRB_CRED_ENCPART)
83 if err != nil {
84 return krberror.Errorf(err, krberror.DecryptingError, "error decrypting KRB_CRED EncPart")
85 }
86 var denc EncKrbCredPart
87 err = denc.Unmarshal(b)
88 if err != nil {
89 return krberror.Errorf(err, krberror.EncodingError, "error unmarshaling encrypted part of KRB_CRED")
90 }
91 k.DecryptedEncPart = denc
92 return nil
93}
94
95// Unmarshal bytes b into the encrypted part of KRB_CRED.
96func (k *EncKrbCredPart) Unmarshal(b []byte) error {
97 _, err := asn1.UnmarshalWithParams(b, k, fmt.Sprintf("application,explicit,tag:%v", asnAppTag.EncKrbCredPart))
98 if err != nil {
99 return krberror.Errorf(err, krberror.EncodingError, "error unmarshaling EncKrbCredPart")
100 }
101 return nil
102}