func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) error { buffer := make([]byte, 0, 300) buffer = append(buffer, request.Version()) buffer = append(buffer, request.UserHash()...) encryptionBegin := len(buffer) randomLength := mrand.Intn(32) + 1 randomContent := make([]byte, randomLength) _, err := rand.Read(randomContent) if err != nil { return err } buffer = append(buffer, byte(randomLength)) buffer = append(buffer, randomContent...) buffer = append(buffer, request.RequestIV()...) buffer = append(buffer, request.RequestKey()...) buffer = append(buffer, request.ResponseHeader()...) buffer = append(buffer, request.Command()) buffer = append(buffer, request.portBytes()...) buffer = append(buffer, request.targetAddressType()) buffer = append(buffer, request.targetAddressBytes()...) paddingLength := blockSize - 1 - (len(buffer)-encryptionBegin)%blockSize if paddingLength == 0 { paddingLength = blockSize } paddingBuffer := make([]byte, paddingLength) _, err = rand.Read(paddingBuffer) if err != nil { return err } buffer = append(buffer, byte(paddingLength)) buffer = append(buffer, paddingBuffer...) encryptionEnd := len(buffer) userId, valid := w.vUserSet.IsValidUserId(request.UserHash()) if !valid { return ErrorInvalidUser } aesCipher, err := aes.NewCipher(userId.Hash([]byte("PWD"))) if err != nil { return err } aesMode := cipher.NewCBCEncrypter(aesCipher, make([]byte, blockSize)) cWriter := v2io.NewCryptionWriter(aesMode, writer) _, err = writer.Write(buffer[0:encryptionBegin]) if err != nil { return err } _, err = cWriter.Write(buffer[encryptionBegin:encryptionEnd]) if err != nil { return err } return nil }
func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) error { buffer := make([]byte, 0, 300) counter := w.randomRangeInt64(time.Now().UTC().Unix(), 30) idHash := w.idHash.Hash(request.UserId.Bytes, counter) log.Debug("Writing userhash: %v", idHash) buffer = append(buffer, idHash...) encryptionBegin := len(buffer) randomLength := mrand.Intn(32) + 1 randomContent := make([]byte, randomLength) _, err := rand.Read(randomContent) if err != nil { return err } buffer = append(buffer, byte(randomLength)) buffer = append(buffer, randomContent...) buffer = append(buffer, request.Version) buffer = append(buffer, request.RequestIV[:]...) buffer = append(buffer, request.RequestKey[:]...) buffer = append(buffer, request.ResponseHeader[:]...) buffer = append(buffer, request.Command) portBytes := make([]byte, 2) binary.BigEndian.PutUint16(portBytes, request.Address.Port) buffer = append(buffer, portBytes...) switch { case request.Address.IsIPv4(): buffer = append(buffer, addrTypeIPv4) buffer = append(buffer, request.Address.IP...) case request.Address.IsIPv6(): buffer = append(buffer, addrTypeIPv6) buffer = append(buffer, request.Address.IP...) case request.Address.IsDomain(): buffer = append(buffer, addrTypeDomain) buffer = append(buffer, byte(len(request.Address.Domain))) buffer = append(buffer, []byte(request.Address.Domain)...) } paddingLength := mrand.Intn(32) + 1 paddingBuffer := make([]byte, paddingLength) _, err = rand.Read(paddingBuffer) if err != nil { return err } buffer = append(buffer, byte(paddingLength)) buffer = append(buffer, paddingBuffer...) encryptionEnd := len(buffer) aesCipher, err := aes.NewCipher(request.UserId.CmdKey()) if err != nil { return err } aesStream := cipher.NewCFBEncrypter(aesCipher, v2hash.Int64Hash(counter)) cWriter := v2io.NewCryptionWriter(aesStream, writer) _, err = writer.Write(buffer[0:encryptionBegin]) if err != nil { return err } _, err = cWriter.Write(buffer[encryptionBegin:encryptionEnd]) if err != nil { return err } return nil }
func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) error { buffer := make([]byte, 0, 300) buffer = append(buffer, request.Version) buffer = append(buffer, request.UserId.Hash([]byte("ASK"))...) encryptionBegin := len(buffer) randomLength := mrand.Intn(32) + 1 randomContent := make([]byte, randomLength) _, err := rand.Read(randomContent) if err != nil { return err } buffer = append(buffer, byte(randomLength)) buffer = append(buffer, randomContent...) buffer = append(buffer, request.RequestIV[:]...) buffer = append(buffer, request.RequestKey[:]...) buffer = append(buffer, request.ResponseHeader[:]...) buffer = append(buffer, request.Command) portBytes := make([]byte, 2) binary.BigEndian.PutUint16(portBytes, request.Address.Port) buffer = append(buffer, portBytes...) switch { case request.Address.IsIPv4(): buffer = append(buffer, addrTypeIPv4) buffer = append(buffer, request.Address.IP...) case request.Address.IsIPv6(): buffer = append(buffer, addrTypeIPv6) buffer = append(buffer, request.Address.IP...) case request.Address.IsDomain(): buffer = append(buffer, addrTypeDomain) buffer = append(buffer, byte(len(request.Address.Domain))) buffer = append(buffer, []byte(request.Address.Domain)...) } paddingLength := blockSize - 1 - (len(buffer)-encryptionBegin)%blockSize if paddingLength == 0 { paddingLength = blockSize } paddingBuffer := make([]byte, paddingLength) _, err = rand.Read(paddingBuffer) if err != nil { return err } buffer = append(buffer, byte(paddingLength)) buffer = append(buffer, paddingBuffer...) encryptionEnd := len(buffer) aesCipher, err := aes.NewCipher(request.UserId.Hash([]byte("PWD"))) if err != nil { return err } aesMode := cipher.NewCBCEncrypter(aesCipher, make([]byte, blockSize)) cWriter := v2io.NewCryptionWriter(aesMode, writer) _, err = writer.Write(buffer[0:encryptionBegin]) if err != nil { return err } _, err = cWriter.Write(buffer[encryptionBegin:encryptionEnd]) if err != nil { return err } return nil }
func (w *VMessRequestWriter) Write(writer io.Writer, request *VMessRequest) error { buffer := make([]byte, 0, 300) userHash, timeSec := request.UserId.TimeRangeHash(30) log.Debug("Writing userhash: %v", userHash) buffer = append(buffer, userHash...) encryptionBegin := len(buffer) randomLength := mrand.Intn(32) + 1 randomContent := make([]byte, randomLength) _, err := rand.Read(randomContent) if err != nil { return err } buffer = append(buffer, byte(randomLength)) buffer = append(buffer, randomContent...) buffer = append(buffer, request.Version) buffer = append(buffer, request.RequestIV[:]...) buffer = append(buffer, request.RequestKey[:]...) buffer = append(buffer, request.ResponseHeader[:]...) buffer = append(buffer, request.Command) portBytes := make([]byte, 2) binary.BigEndian.PutUint16(portBytes, request.Address.Port) buffer = append(buffer, portBytes...) switch { case request.Address.IsIPv4(): buffer = append(buffer, addrTypeIPv4) buffer = append(buffer, request.Address.IP...) case request.Address.IsIPv6(): buffer = append(buffer, addrTypeIPv6) buffer = append(buffer, request.Address.IP...) case request.Address.IsDomain(): buffer = append(buffer, addrTypeDomain) buffer = append(buffer, byte(len(request.Address.Domain))) buffer = append(buffer, []byte(request.Address.Domain)...) } paddingLength := blockSize - 1 - (len(buffer)-encryptionBegin)%blockSize if paddingLength == 0 { paddingLength = blockSize } paddingBuffer := make([]byte, paddingLength) _, err = rand.Read(paddingBuffer) if err != nil { return err } buffer = append(buffer, byte(paddingLength)) buffer = append(buffer, paddingBuffer...) encryptionEnd := len(buffer) aesCipher, err := aes.NewCipher(request.UserId.CmdKey()) if err != nil { return err } aesStream := cipher.NewCFBEncrypter(aesCipher, core.TimestampHash(timeSec)) cWriter := v2io.NewCryptionWriter(aesStream, writer) _, err = writer.Write(buffer[0:encryptionBegin]) if err != nil { return err } _, err = cWriter.Write(buffer[encryptionBegin:encryptionEnd]) if err != nil { return err } return nil }