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  }