blob: 1fdba78a37d4bb07c93db0fbc98c683f534ef149 [file] [log] [blame]
khenaidood948f772021-08-11 17:49:24 -04001// Package types provides Kerberos 5 data types.
2package types
3
4import (
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
20type 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.
33func 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(),
47 }, nil
48}
49
50// GenerateSeqNumberAndSubKey sets the Authenticator's sequence number and subkey.
51func (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()
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.
68func (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.
74func (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}