Authenticator.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // 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. type Authenticator struct {
  30. AVNO int `asn1:"explicit,tag:0"`
  31. CRealm string `asn1:"generalstring,explicit,tag:1"`
  32. CName PrincipalName `asn1:"explicit,tag:2"`
  33. Cksum Checksum `asn1:"explicit,optional,tag:3"`
  34. Cusec int `asn1:"explicit,tag:4"`
  35. CTime time.Time `asn1:"generalized,explicit,tag:5"`
  36. SubKey EncryptionKey `asn1:"explicit,optional,tag:6"`
  37. SeqNumber int `asn1:"explicit,optional,tag:7"`
  38. AuthorizationData AuthorizationData `asn1:"explicit,optional,tag:8"`
  39. }
  40. func NewAuthenticator(realm string, cname PrincipalName) Authenticator {
  41. t := time.Now().UTC()
  42. return Authenticator{
  43. AVNO: iana.PVNO,
  44. CRealm: realm,
  45. CName: cname,
  46. Cksum: Checksum{},
  47. Cusec: int((t.UnixNano() / int64(time.Microsecond)) - (t.Unix() * 1e6)),
  48. CTime: t,
  49. SeqNumber: int(rand.Int31()),
  50. }
  51. }
  52. func (a *Authenticator) GenerateSeqNumberAndSubKey(keyType, keySize int) {
  53. a.SeqNumber = int(rand.Int31())
  54. //Generate subkey value
  55. sk := make([]byte, keySize, keySize)
  56. rand.Read(sk)
  57. a.SubKey = EncryptionKey{
  58. KeyType: keyType,
  59. KeyValue: sk,
  60. }
  61. }
  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. func (a *Authenticator) Marshal() ([]byte, error) {
  67. b, err := asn1.Marshal(*a)
  68. if err != nil {
  69. return nil, err
  70. }
  71. b = asn1tools.AddASNAppTag(b, asnAppTag.Authenticator)
  72. return b, nil
  73. }