2020-04-08 23:39:40 +00:00
|
|
|
package common
|
2020-04-08 19:53:09 +00:00
|
|
|
|
|
|
|
import (
|
2020-12-23 00:02:25 +00:00
|
|
|
"bytes"
|
2020-04-08 19:53:09 +00:00
|
|
|
"encoding/binary"
|
|
|
|
"io"
|
|
|
|
"net"
|
2020-10-17 12:46:22 +00:00
|
|
|
"sync"
|
2020-04-08 19:53:09 +00:00
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
VersionTLS11 = 0x0301
|
|
|
|
VersionTLS13 = 0x0303
|
|
|
|
|
2020-04-10 15:15:23 +00:00
|
|
|
recordLayerLength = 5
|
|
|
|
|
2020-04-08 19:53:09 +00:00
|
|
|
Handshake = 22
|
|
|
|
ApplicationData = 23
|
2020-10-17 14:06:45 +00:00
|
|
|
|
|
|
|
initialWriteBufSize = 14336
|
2020-04-08 19:53:09 +00:00
|
|
|
)
|
|
|
|
|
2020-10-17 14:10:41 +00:00
|
|
|
func AddRecordLayer(input []byte, typ byte, ver uint16) []byte {
|
|
|
|
msgLen := len(input)
|
|
|
|
retLen := msgLen + recordLayerLength
|
|
|
|
var ret []byte
|
2020-10-17 23:46:03 +00:00
|
|
|
ret = make([]byte, retLen)
|
2020-10-17 14:10:41 +00:00
|
|
|
copy(ret[recordLayerLength:], input)
|
|
|
|
ret[0] = typ
|
|
|
|
ret[1] = byte(ver >> 8)
|
|
|
|
ret[2] = byte(ver)
|
|
|
|
ret[3] = byte(msgLen >> 8)
|
|
|
|
ret[4] = byte(msgLen)
|
|
|
|
return ret
|
|
|
|
}
|
2020-04-08 19:53:09 +00:00
|
|
|
|
|
|
|
type TLSConn struct {
|
|
|
|
net.Conn
|
2020-12-23 00:02:25 +00:00
|
|
|
writeBufPool sync.Pool
|
2020-10-17 12:46:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func NewTLSConn(conn net.Conn) *TLSConn {
|
|
|
|
return &TLSConn{
|
2020-12-23 00:02:25 +00:00
|
|
|
Conn: conn,
|
|
|
|
writeBufPool: sync.Pool{New: func() interface{} {
|
|
|
|
return new(bytes.Buffer)
|
|
|
|
}},
|
2020-10-17 12:46:22 +00:00
|
|
|
}
|
2020-04-08 19:53:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) LocalAddr() net.Addr {
|
|
|
|
return tls.Conn.LocalAddr()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) RemoteAddr() net.Addr {
|
|
|
|
return tls.Conn.RemoteAddr()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) SetDeadline(t time.Time) error {
|
|
|
|
return tls.Conn.SetDeadline(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) SetReadDeadline(t time.Time) error {
|
|
|
|
return tls.Conn.SetReadDeadline(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) SetWriteDeadline(t time.Time) error {
|
|
|
|
return tls.Conn.SetWriteDeadline(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) Read(buffer []byte) (n int, err error) {
|
|
|
|
// TCP is a stream. Multiple TLS messages can arrive at the same time,
|
|
|
|
// a single message can also be segmented due to MTU of the IP layer.
|
|
|
|
// This function guareentees a single TLS message to be read and everything
|
|
|
|
// else is left in the buffer.
|
2020-10-17 14:06:45 +00:00
|
|
|
if len(buffer) < recordLayerLength {
|
|
|
|
return 0, io.ErrShortBuffer
|
|
|
|
}
|
2020-04-10 15:15:23 +00:00
|
|
|
_, err = io.ReadFull(tls.Conn, buffer[:recordLayerLength])
|
2020-04-08 19:53:09 +00:00
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
dataLength := int(binary.BigEndian.Uint16(buffer[3:5]))
|
|
|
|
if dataLength > len(buffer) {
|
|
|
|
err = io.ErrShortBuffer
|
|
|
|
return
|
|
|
|
}
|
2020-08-12 10:32:39 +00:00
|
|
|
// we overwrite the record layer here
|
2020-04-08 19:53:09 +00:00
|
|
|
return io.ReadFull(tls.Conn, buffer[:dataLength])
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) Write(in []byte) (n int, err error) {
|
2020-10-17 12:46:22 +00:00
|
|
|
msgLen := len(in)
|
2020-12-23 00:02:25 +00:00
|
|
|
writeBuf := tls.writeBufPool.Get().(*bytes.Buffer)
|
|
|
|
writeBuf.WriteByte(ApplicationData)
|
|
|
|
writeBuf.WriteByte(byte(VersionTLS13 >> 8))
|
|
|
|
writeBuf.WriteByte(byte(VersionTLS13 & 0xFF))
|
|
|
|
writeBuf.WriteByte(byte(msgLen >> 8))
|
|
|
|
writeBuf.WriteByte(byte(msgLen & 0xFF))
|
|
|
|
writeBuf.Write(in)
|
|
|
|
i, err := writeBuf.WriteTo(tls.Conn)
|
|
|
|
tls.writeBufPool.Put(writeBuf)
|
|
|
|
return int(i - recordLayerLength), err
|
2020-04-08 19:53:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (tls *TLSConn) Close() error {
|
|
|
|
return tls.Conn.Close()
|
|
|
|
}
|