Authenticator.go 2.9 KB

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