David K. Bainbridge | bd6b288 | 2021-08-26 13:31:02 +0000 | [diff] [blame] | 1 | package messages |
| 2 | |
| 3 | import ( |
| 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 | |
| 16 | type 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. |
| 24 | type 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. |
| 33 | type 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. |
| 43 | type 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. |
| 58 | func (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. |
| 81 | func (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. |
| 96 | func (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 | } |