github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/shadowsocksr/protocol/verify_sha1.go (about) 1 package protocol 2 3 import ( 4 "bytes" 5 "crypto" 6 "encoding/binary" 7 8 ssr "github.com/Asutorufa/yuhaiin/pkg/net/proxy/shadowsocksr/utils" 9 ) 10 11 type verifySHA1 struct { 12 Protocol 13 hasSentHeader bool 14 chunkId uint32 15 hmac ssr.HMAC 16 } 17 18 const ( 19 oneTimeAuthMask byte = 0x10 20 ) 21 22 func NewVerifySHA1(info Protocol) protocol { 23 a := &verifySHA1{ 24 Protocol: info, 25 hmac: ssr.HMAC(crypto.SHA1), 26 } 27 return a 28 } 29 30 func (v *verifySHA1) otaConnectAuth(data []byte) []byte { 31 return append(data, v.hmac.HMAC(append(v.IV, v.Key()...), data, nil)...) 32 } 33 34 func (v *verifySHA1) otaReqChunkAuth(buffer *bytes.Buffer, chunkId uint32, data []byte) { 35 nb := make([]byte, 2) 36 binary.BigEndian.PutUint16(nb, uint16(len(data))) 37 chunkIdBytes := make([]byte, 4) 38 binary.BigEndian.PutUint32(chunkIdBytes, chunkId) 39 40 buffer.Write(nb) 41 buffer.Write(v.hmac.HMAC(append(v.IV, chunkIdBytes...), data, nil)) 42 buffer.Write(data) 43 } 44 45 func (v *verifySHA1) otaVerifyAuth(iv []byte, chunkId uint32, data []byte, expectedHmacSha1 []byte) bool { 46 chunkIdBytes := make([]byte, 4) 47 binary.BigEndian.PutUint32(chunkIdBytes, chunkId) 48 actualHmacSha1 := v.hmac.HMAC(append(iv, chunkIdBytes...), data, nil) 49 return bytes.Equal(expectedHmacSha1, actualHmacSha1) 50 } 51 52 func (v *verifySHA1) getAndIncreaseChunkId() (chunkId uint32) { 53 chunkId = v.chunkId 54 v.chunkId += 1 55 return 56 } 57 58 func (v *verifySHA1) EncryptStream(buffer *bytes.Buffer, data []byte) (err error) { 59 dataLength := len(data) 60 offset := 0 61 if !v.hasSentHeader { 62 data[0] |= oneTimeAuthMask 63 buffer.Write(v.otaConnectAuth(data[:v.HeadSize])) 64 v.hasSentHeader = true 65 dataLength -= v.HeadSize 66 offset += v.HeadSize 67 } 68 const blockSize = 4096 69 for dataLength > blockSize { 70 chunkId := v.getAndIncreaseChunkId() 71 v.otaReqChunkAuth(buffer, chunkId, data[offset:offset+blockSize]) 72 dataLength -= blockSize 73 offset += blockSize 74 } 75 if dataLength > 0 { 76 chunkId := v.getAndIncreaseChunkId() 77 v.otaReqChunkAuth(buffer, chunkId, data[offset:]) 78 } 79 return nil 80 } 81 82 func (v *verifySHA1) DecryptStream(dst *bytes.Buffer, data []byte) (int, error) { 83 return dst.Write(data) 84 } 85 86 func (v *verifySHA1) GetOverhead() int { 87 return 0 88 } 89 90 func (a *verifySHA1) EncryptPacket(b []byte) ([]byte, error) { 91 return b, nil 92 } 93 func (a *verifySHA1) DecryptPacket(b []byte) ([]byte, error) { 94 return b, nil 95 }