Authenticator.go 2.5 KB

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