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 }