github.com/jcmturner/gokrb5/v8@v8.4.4/messages/KRBPriv.go (about) 1 package messages 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/jcmturner/gofork/encoding/asn1" 8 "github.com/jcmturner/gokrb5/v8/asn1tools" 9 "github.com/jcmturner/gokrb5/v8/crypto" 10 "github.com/jcmturner/gokrb5/v8/iana" 11 "github.com/jcmturner/gokrb5/v8/iana/asnAppTag" 12 "github.com/jcmturner/gokrb5/v8/iana/keyusage" 13 "github.com/jcmturner/gokrb5/v8/iana/msgtype" 14 "github.com/jcmturner/gokrb5/v8/krberror" 15 "github.com/jcmturner/gokrb5/v8/types" 16 ) 17 18 // KRBPriv implements RFC 4120 type: https://tools.ietf.org/html/rfc4120#section-5.7.1. 19 type KRBPriv struct { 20 PVNO int `asn1:"explicit,tag:0"` 21 MsgType int `asn1:"explicit,tag:1"` 22 EncPart types.EncryptedData `asn1:"explicit,tag:3"` 23 DecryptedEncPart EncKrbPrivPart `asn1:"optional,omitempty"` // Not part of ASN1 bytes so marked as optional so unmarshalling works 24 } 25 26 // EncKrbPrivPart is the encrypted part of KRB_PRIV. 27 type EncKrbPrivPart struct { 28 UserData []byte `asn1:"explicit,tag:0"` 29 Timestamp time.Time `asn1:"generalized,optional,explicit,tag:1"` 30 Usec int `asn1:"optional,explicit,tag:2"` 31 SequenceNumber int64 `asn1:"optional,explicit,tag:3"` 32 SAddress types.HostAddress `asn1:"explicit,tag:4"` 33 RAddress types.HostAddress `asn1:"optional,explicit,tag:5"` 34 } 35 36 // NewKRBPriv returns a new KRBPriv type. 37 func NewKRBPriv(part EncKrbPrivPart) KRBPriv { 38 return KRBPriv{ 39 PVNO: iana.PVNO, 40 MsgType: msgtype.KRB_PRIV, 41 DecryptedEncPart: part, 42 } 43 } 44 45 // Unmarshal bytes b into the KRBPriv struct. 46 func (k *KRBPriv) Unmarshal(b []byte) error { 47 _, err := asn1.UnmarshalWithParams(b, k, fmt.Sprintf("application,explicit,tag:%v", asnAppTag.KRBPriv)) 48 if err != nil { 49 return processUnmarshalReplyError(b, err) 50 } 51 expectedMsgType := msgtype.KRB_PRIV 52 if k.MsgType != expectedMsgType { 53 return krberror.NewErrorf(krberror.KRBMsgError, "message ID does not indicate a KRB_PRIV. Expected: %v; Actual: %v", expectedMsgType, k.MsgType) 54 } 55 return nil 56 } 57 58 // Unmarshal bytes b into the EncKrbPrivPart struct. 59 func (k *EncKrbPrivPart) Unmarshal(b []byte) error { 60 _, err := asn1.UnmarshalWithParams(b, k, fmt.Sprintf("application,explicit,tag:%v", asnAppTag.EncKrbPrivPart)) 61 if err != nil { 62 return krberror.Errorf(err, krberror.EncodingError, "KRB_PRIV unmarshal error") 63 } 64 return nil 65 } 66 67 // Marshal the KRBPriv. 68 func (k *KRBPriv) Marshal() ([]byte, error) { 69 tk := KRBPriv{ 70 PVNO: k.PVNO, 71 MsgType: k.MsgType, 72 EncPart: k.EncPart, 73 } 74 b, err := asn1.Marshal(tk) 75 if err != nil { 76 return []byte{}, err 77 } 78 b = asn1tools.AddASNAppTag(b, asnAppTag.KRBPriv) 79 return b, nil 80 } 81 82 // EncryptEncPart encrypts the DecryptedEncPart within the KRBPriv. 83 // Use to prepare for marshaling. 84 func (k *KRBPriv) EncryptEncPart(key types.EncryptionKey) error { 85 b, err := asn1.Marshal(k.DecryptedEncPart) 86 if err != nil { 87 return err 88 } 89 b = asn1tools.AddASNAppTag(b, asnAppTag.EncKrbPrivPart) 90 k.EncPart, err = crypto.GetEncryptedData(b, key, keyusage.KRB_PRIV_ENCPART, 1) 91 if err != nil { 92 return err 93 } 94 return nil 95 } 96 97 // DecryptEncPart decrypts the encrypted part of the KRBPriv message. 98 func (k *KRBPriv) DecryptEncPart(key types.EncryptionKey) error { 99 b, err := crypto.DecryptEncPart(k.EncPart, key, keyusage.KRB_PRIV_ENCPART) 100 if err != nil { 101 return fmt.Errorf("error decrypting KRBPriv EncPart: %v", err) 102 } 103 err = k.DecryptedEncPart.Unmarshal(b) 104 if err != nil { 105 return fmt.Errorf("error unmarshaling encrypted part: %v", err) 106 } 107 return nil 108 }