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  }