github.com/jcmturner/gokrb5/v8@v8.4.4/types/Authenticator.go (about)

     1  // Package types provides Kerberos 5 data types.
     2  package types
     3  
     4  import (
     5  	"crypto/rand"
     6  	"fmt"
     7  	"math"
     8  	"math/big"
     9  	"time"
    10  
    11  	"github.com/jcmturner/gofork/encoding/asn1"
    12  	"github.com/jcmturner/gokrb5/v8/asn1tools"
    13  	"github.com/jcmturner/gokrb5/v8/iana"
    14  	"github.com/jcmturner/gokrb5/v8/iana/asnAppTag"
    15  )
    16  
    17  // Authenticator - A record containing information that can be shown to have been recently generated using the session
    18  // key known only by the client and server.
    19  // https://tools.ietf.org/html/rfc4120#section-5.5.1
    20  type Authenticator struct {
    21  	AVNO              int               `asn1:"explicit,tag:0"`
    22  	CRealm            string            `asn1:"generalstring,explicit,tag:1"`
    23  	CName             PrincipalName     `asn1:"explicit,tag:2"`
    24  	Cksum             Checksum          `asn1:"explicit,optional,tag:3"`
    25  	Cusec             int               `asn1:"explicit,tag:4"`
    26  	CTime             time.Time         `asn1:"generalized,explicit,tag:5"`
    27  	SubKey            EncryptionKey     `asn1:"explicit,optional,tag:6"`
    28  	SeqNumber         int64             `asn1:"explicit,optional,tag:7"`
    29  	AuthorizationData AuthorizationData `asn1:"explicit,optional,tag:8"`
    30  }
    31  
    32  // NewAuthenticator creates a new Authenticator.
    33  func NewAuthenticator(realm string, cname PrincipalName) (Authenticator, error) {
    34  	seq, err := rand.Int(rand.Reader, big.NewInt(math.MaxUint32))
    35  	if err != nil {
    36  		return Authenticator{}, err
    37  	}
    38  	t := time.Now().UTC()
    39  	return Authenticator{
    40  		AVNO:      iana.PVNO,
    41  		CRealm:    realm,
    42  		CName:     cname,
    43  		Cksum:     Checksum{},
    44  		Cusec:     int((t.UnixNano() / int64(time.Microsecond)) - (t.Unix() * 1e6)),
    45  		CTime:     t,
    46  		SeqNumber: seq.Int64() & 0x3fffffff,
    47  	}, nil
    48  }
    49  
    50  // GenerateSeqNumberAndSubKey sets the Authenticator's sequence number and subkey.
    51  func (a *Authenticator) GenerateSeqNumberAndSubKey(keyType int32, keySize int) error {
    52  	seq, err := rand.Int(rand.Reader, big.NewInt(math.MaxUint32))
    53  	if err != nil {
    54  		return err
    55  	}
    56  	a.SeqNumber = seq.Int64() & 0x3fffffff
    57  	//Generate subkey value
    58  	sk := make([]byte, keySize, keySize)
    59  	rand.Read(sk)
    60  	a.SubKey = EncryptionKey{
    61  		KeyType:  keyType,
    62  		KeyValue: sk,
    63  	}
    64  	return nil
    65  }
    66  
    67  // Unmarshal bytes into the Authenticator.
    68  func (a *Authenticator) Unmarshal(b []byte) error {
    69  	_, err := asn1.UnmarshalWithParams(b, a, fmt.Sprintf("application,explicit,tag:%v", asnAppTag.Authenticator))
    70  	return err
    71  }
    72  
    73  // Marshal the Authenticator.
    74  func (a *Authenticator) Marshal() ([]byte, error) {
    75  	b, err := asn1.Marshal(*a)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  	b = asn1tools.AddASNAppTag(b, asnAppTag.Authenticator)
    80  	return b, nil
    81  }