index.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package tf
  2. import (
  3. "encoding/binary"
  4. )
  5. const (
  6. recordLayerHeaderLen int = 5
  7. handshakeHeaderLen int = 6
  8. randomDataLen int = 32
  9. sessionIDHeaderLen int = 1
  10. cipherSuiteHeaderLen int = 2
  11. compressMethodHeaderLen int = 1
  12. extensionsHeaderLen int = 2
  13. extensionHeaderLen int = 4
  14. sniExtensionHeaderLen int = 5
  15. contentType uint8 = 22
  16. handshakeType uint8 = 1
  17. sniExtensionType uint16 = 0
  18. sniNameDNSHostnameType uint8 = 0
  19. tlsVersionBitmask uint16 = 0xFFFC
  20. tls13 uint16 = 0x0304
  21. )
  22. type MyServerName struct {
  23. Index int
  24. Length int
  25. ServerName string
  26. }
  27. func IndexTLSServerName(payload []byte) *MyServerName {
  28. if len(payload) < recordLayerHeaderLen || payload[0] != contentType {
  29. return nil
  30. }
  31. segmentLen := binary.BigEndian.Uint16(payload[3:5])
  32. if len(payload) < recordLayerHeaderLen+int(segmentLen) {
  33. return nil
  34. }
  35. serverName := indexTLSServerNameFromHandshake(payload[recordLayerHeaderLen:])
  36. if serverName == nil {
  37. return nil
  38. }
  39. serverName.Index += recordLayerHeaderLen
  40. return serverName
  41. }
  42. func indexTLSServerNameFromHandshake(handshake []byte) *MyServerName {
  43. if len(handshake) < handshakeHeaderLen+randomDataLen+sessionIDHeaderLen {
  44. return nil
  45. }
  46. if handshake[0] != handshakeType {
  47. return nil
  48. }
  49. handshakeLen := uint32(handshake[1])<<16 | uint32(handshake[2])<<8 | uint32(handshake[3])
  50. if len(handshake[4:]) != int(handshakeLen) {
  51. return nil
  52. }
  53. tlsVersion := uint16(handshake[4])<<8 | uint16(handshake[5])
  54. if tlsVersion&tlsVersionBitmask != 0x0300 && tlsVersion != tls13 {
  55. return nil
  56. }
  57. sessionIDLen := handshake[38]
  58. currentIndex := handshakeHeaderLen + randomDataLen + sessionIDHeaderLen + int(sessionIDLen)
  59. if len(handshake) < currentIndex {
  60. return nil
  61. }
  62. cipherSuites := handshake[currentIndex:]
  63. if len(cipherSuites) < cipherSuiteHeaderLen {
  64. return nil
  65. }
  66. csLen := uint16(cipherSuites[0])<<8 | uint16(cipherSuites[1])
  67. if len(cipherSuites) < cipherSuiteHeaderLen+int(csLen)+compressMethodHeaderLen {
  68. return nil
  69. }
  70. compressMethodLen := uint16(cipherSuites[cipherSuiteHeaderLen+int(csLen)])
  71. currentIndex += cipherSuiteHeaderLen + int(csLen) + compressMethodHeaderLen + int(compressMethodLen)
  72. if len(handshake) < currentIndex {
  73. return nil
  74. }
  75. serverName := indexTLSServerNameFromExtensions(handshake[currentIndex:])
  76. if serverName == nil {
  77. return nil
  78. }
  79. serverName.Index += currentIndex
  80. return serverName
  81. }
  82. func indexTLSServerNameFromExtensions(exs []byte) *MyServerName {
  83. if len(exs) == 0 {
  84. return nil
  85. }
  86. if len(exs) < extensionsHeaderLen {
  87. return nil
  88. }
  89. exsLen := uint16(exs[0])<<8 | uint16(exs[1])
  90. exs = exs[extensionsHeaderLen:]
  91. if len(exs) < int(exsLen) {
  92. return nil
  93. }
  94. for currentIndex := extensionsHeaderLen; len(exs) > 0; {
  95. if len(exs) < extensionHeaderLen {
  96. return nil
  97. }
  98. exType := uint16(exs[0])<<8 | uint16(exs[1])
  99. exLen := uint16(exs[2])<<8 | uint16(exs[3])
  100. if len(exs) < extensionHeaderLen+int(exLen) {
  101. return nil
  102. }
  103. sex := exs[extensionHeaderLen : extensionHeaderLen+int(exLen)]
  104. switch exType {
  105. case sniExtensionType:
  106. if len(sex) < sniExtensionHeaderLen {
  107. return nil
  108. }
  109. sniType := sex[2]
  110. if sniType != sniNameDNSHostnameType {
  111. return nil
  112. }
  113. sniLen := uint16(sex[3])<<8 | uint16(sex[4])
  114. sex = sex[sniExtensionHeaderLen:]
  115. return &MyServerName{
  116. Index: currentIndex + extensionHeaderLen + sniExtensionHeaderLen,
  117. Length: int(sniLen),
  118. ServerName: string(sex),
  119. }
  120. }
  121. exs = exs[4+exLen:]
  122. currentIndex += 4 + int(exLen)
  123. }
  124. return nil
  125. }