gss.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package gss
  2. import (
  3. "encoding/asn1"
  4. "fmt"
  5. "log"
  6. "imuslab.com/smb/driver/mod/smb/encoder"
  7. )
  8. // https://www.rfc-editor.org/rfc/rfc4178.html#section-4.1
  9. type MechTypeOid string
  10. const SpnegoOid = "1.3.6.1.5.5.2"
  11. const NtLmSSPMechTypeOid MechTypeOid = "1.3.6.1.4.1.311.2.2.10"
  12. // const KRB5SSPMechTypeOid MechTypeOid = "1.3.6.1.5.2.5"
  13. const GssStateAcceptCompleted = 0
  14. const GssStateAcceptIncomplete = 1
  15. const GssStateReject = 2
  16. const GssStateRequestMic = 3
  17. type NegTokenInitData struct {
  18. MechTypes []asn1.ObjectIdentifier `asn1:"explicit,tag:0"`
  19. ReqFlags asn1.BitString `asn1:"explicit,optional,omitempty,tag:1"`
  20. MechToken []byte `asn1:"explicit,optional,omitempty,tag:2"`
  21. MechTokenMIC []byte `asn1:"explicit,optional,omitempty,tag:3"`
  22. }
  23. type NegTokenInit struct {
  24. OID asn1.ObjectIdentifier
  25. Data NegTokenInitData `asn1:"explicit"`
  26. }
  27. type NegState int
  28. const (
  29. Accept_completed NegState = 0
  30. Accept_incomplete NegState = 1
  31. Reject NegState = 2
  32. Request_mic NegState = 3
  33. )
  34. type NegTokenResp struct {
  35. NegResult asn1.Enumerated `asn1:"explicit,optional,omitempty,tag:0"` //NegState
  36. SupportedMech asn1.ObjectIdentifier `asn1:"explicit,optional,omitempty,tag:1"`
  37. ResponseToken []byte `asn1:"explicit,optional,omitempty,tag:2"`
  38. MechListMIC []byte `asn1:"explicit,optional,omitempty,tag:3"`
  39. }
  40. // gsswrapped used to force ASN1 encoding to include explicit sequence tags
  41. // Type does not fulfill the BinaryMarshallable interfce and is used only as a
  42. // helper to marshal a NegTokenResp
  43. type gsswrapped struct{ G interface{} }
  44. func NewNegTokenInit(MechType MechTypeOid) (*NegTokenInit, error) {
  45. oid, err := ObjectIDStrToInt(SpnegoOid)
  46. if err != nil {
  47. return &NegTokenInit{}, err
  48. }
  49. mechType, err := ObjectIDStrToInt(MechType)
  50. if err != nil {
  51. return &NegTokenInit{}, err
  52. }
  53. return &NegTokenInit{
  54. OID: oid,
  55. Data: NegTokenInitData{
  56. MechTypes: []asn1.ObjectIdentifier{mechType},
  57. ReqFlags: asn1.BitString{},
  58. MechToken: []byte{},
  59. MechTokenMIC: []byte{},
  60. },
  61. }, nil
  62. }
  63. func NewNegTokenResp() *NegTokenResp {
  64. return &NegTokenResp{}
  65. }
  66. var _ encoder.BinaryMarshallable = (*NegTokenInit)(nil)
  67. func (n *NegTokenInit) MarshalBinary(meta *encoder.Metadata) ([]byte, error) {
  68. buf, err := asn1.Marshal(*n)
  69. if err != nil {
  70. log.Panicln(err)
  71. return nil, err
  72. }
  73. // When marshalling struct, asn1 uses 30 (sequence) tag by default.
  74. // Override to set 60 (application) to remain consistent with GSS/SMB
  75. buf[0] = 0x60
  76. return buf, nil
  77. }
  78. func (n *NegTokenInit) UnmarshalBinary(buf []byte, meta *encoder.Metadata) (interface{}, error) {
  79. data := NegTokenInit{}
  80. if _, err := asn1.UnmarshalWithParams(buf, &data, "application"); err != nil {
  81. return nil, err
  82. }
  83. *n = data
  84. return nil, nil
  85. }
  86. var _ encoder.BinaryMarshallable = (*NegTokenInit)(nil)
  87. func (r *NegTokenResp) MarshalBinary(meta *encoder.Metadata) ([]byte, error) {
  88. // Oddities in Go's ASN1 package vs SMB encoding mean we have to wrap our
  89. // struct in another struct to ensure proper tags and lengths are added
  90. // to encoded data
  91. wrapped := &gsswrapped{*r}
  92. ans, _ := wrapped.MarshalBinary(meta)
  93. fmt.Println("MAR", meta, ans)
  94. //return wrapped.MarshalBinary(meta)
  95. ans, err := wrapped.MarshalBinary(meta)
  96. if len(ans) == 4 && ans[0] == 0xa1 && ans[1] == 0x02 && ans[2] == 0x30 && ans[3] == 00 {
  97. return []byte{0xa1, 0x07, 0x30, 0x05, 0xa0, 0x03, 0x0a, 0x01, 0x00}, nil
  98. }
  99. return ans, err
  100. //return []byte{0xa1, 0x07, 0x30, 0x05, 0xa0, 0x03, 0x0a, 0x01, 0x00}, nil
  101. }
  102. func (r *NegTokenResp) UnmarshalBinary(buf []byte, meta *encoder.Metadata) (interface{}, error) {
  103. data := NegTokenResp{}
  104. if _, err := asn1.UnmarshalWithParams(buf, &data, "explicit,tag:1"); err != nil {
  105. return nil, err
  106. }
  107. *r = data
  108. return nil, nil
  109. }
  110. func (g *gsswrapped) MarshalBinary(meta *encoder.Metadata) ([]byte, error) {
  111. buf, err := asn1.Marshal(*g)
  112. if err != nil {
  113. return nil, err
  114. }
  115. buf[0] = 0xa1
  116. return buf, nil
  117. }