예제 #1
0
// Encode a packet
func Encode(pkt *Packet) (*bufpool.Buffer, error) {
	var (
		p      *bufpool.Buffer
		hdrLen int
		err    error
	)

	if pkt == nil {
		return bufpool.New().SetLen(2), nil
	}

	buf := byteBufferPool.Get().(*bytes.Buffer)
	buf.WriteByte(0)
	buf.WriteByte(0)

	if !pkt.header.IsZero() {
		if !pkt.header.IsBinary() {
			err = pkt.header.writeTo(buf)
			if err != nil {
				buf.Reset()
				byteBufferPool.Put(buf)
				return nil, err
			}
			hdrLen = buf.Len() - 2
			if hdrLen < 7 {
				buf.Reset()
				byteBufferPool.Put(buf)
				return nil, ErrInvalidPacket
			}
		} else {
			hdrLen = len(pkt.header.Bytes)
			if hdrLen >= 7 {
				buf.Reset()
				byteBufferPool.Put(buf)
				return nil, ErrInvalidPacket
			}
			buf.Write(pkt.header.Bytes)
		}
	}

	if pkt.body.Len() > 0 {
		pkt.body.WriteTo(buf)
	}

	p = bufpool.New()
	p.Set(buf.Bytes())
	binary.BigEndian.PutUint16(p.RawBytes(), uint16(hdrLen))

	buf.Reset()
	byteBufferPool.Put(buf)

	return p, nil
}
예제 #2
0
func (mod *module) peerVia(router *e3x.Exchange, to hashname.H, body *bufpool.Buffer) error {
	ch, err := router.Open("peer", false)
	if err != nil {
		return err
	}
	defer ch.Kill()

	pkt := lob.New(body.RawBytes())
	pkt.Header().SetString("peer", string(to))
	ch.WritePacket(pkt)

	return nil
}
예제 #3
0
func (mod *module) connect(ex *e3x.Exchange, inner *bufpool.Buffer) error {
	ch, err := ex.Open("connect", false)
	if err != nil {
		return err
	}

	defer ch.Kill()

	err = ch.WritePacket(lob.New(inner.RawBytes()))
	if err != nil {
		return err
	}

	return nil
}
예제 #4
0
// Decode a packet
func Decode(p *bufpool.Buffer) (*Packet, error) {
	var (
		length int
		head   []byte
		body   []byte
		bytes  = p.RawBytes()
	)

	if len(bytes) < 2 {
		return nil, ErrInvalidPacket
	}

	length = int(binary.BigEndian.Uint16(bytes))
	if length+2 > len(bytes) {
		return nil, ErrInvalidPacket
	}

	head = bytes[2 : 2+length]
	if len(head) == 0 {
		head = nil
	}

	pkt := pktPool.Get().(*Packet)

	body = bytes[2+length:]
	if len(body) > 0 {
		pkt.body = bufpool.New().Set(body)
	}

	if len(head) >= 7 {
		err := parseHeader(pkt.Header(), head)
		if err != nil {
			pkt.Free()
			return nil, ErrInvalidPacket
		}
	} else if len(head) > 0 {
		pkt.Header().Bytes = append(make([]byte, 0, len(head)), head...)
	}

	return pkt, nil
}
예제 #5
0
func (s *state) EncryptPacket(pkt *lob.Packet) (*lob.Packet, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	var (
		outer   *lob.Packet
		inner   *bufpool.Buffer
		body    *bufpool.Buffer
		bodyRaw []byte
		nonce   [16]byte
		ctLen   int
		err     error
	)

	if !s.CanEncryptPacket() {
		return nil, cipherset.ErrInvalidState
	}
	if pkt == nil {
		return nil, nil
	}

	// encode inner packet
	inner, err = lob.Encode(pkt)
	if err != nil {
		return nil, err
	}

	ctLen = inner.Len()

	// make nonce
	_, err = io.ReadFull(rand.Reader, nonce[:4])
	if err != nil {
		return nil, err
	}

	// alloc enough space
	body = bufpool.New().SetLen(16 + 4 + ctLen + 4)
	bodyRaw = body.RawBytes()

	// copy token
	copy(bodyRaw[:16], (*s.remoteToken)[:])

	// copy nonce
	copy(bodyRaw[16:16+4], nonce[:])

	{ // encrypt inner
		aesBlock, err := aes.NewCipher(s.lineEncryptionKey)
		if err != nil {
			return nil, err
		}

		aes := Cipher.NewCTR(aesBlock, nonce[:])
		if aes == nil {
			return nil, cipherset.ErrInvalidMessage
		}

		aes.XORKeyStream(bodyRaw[16+4:16+4+ctLen], inner.RawBytes())
	}

	{ // compute HMAC
		macKey := append(s.lineEncryptionKey, bodyRaw[16:16+4]...)

		h := hmac.New(sha256.New, macKey)
		h.Write(bodyRaw[16+4 : 16+4+ctLen])
		sum := h.Sum(nil)
		copy(bodyRaw[16+4+ctLen:], fold(sum, 4))
	}

	outer = lob.New(body.RawBytes())
	inner.Free()
	body.Free()

	return outer, nil
}
예제 #6
0
func (s *state) EncryptPacket(pkt *lob.Packet) (*lob.Packet, error) {
	s.mtx.RLock()
	defer s.mtx.RUnlock()

	var (
		outer   *lob.Packet
		inner   *bufpool.Buffer
		body    *bufpool.Buffer
		bodyRaw []byte
		nonce   [lenNonce]byte
		ctLen   int
		err     error
	)

	if !s.CanEncryptPacket() {
		return nil, cipherset.ErrInvalidState
	}
	if pkt == nil {
		return nil, nil
	}

	// encode inner packet
	inner, err = lob.Encode(pkt)
	if err != nil {
		return nil, err
	}

	// make nonce
	copy(nonce[:], s.pktNoncePrefix[:])
	nonceSuffix := atomic.AddUint64(&s.pktNonceSuffix, 1)
	binary.BigEndian.PutUint64(nonce[16:], nonceSuffix)

	// alloc enough space
	body = bufpool.New().SetLen(lenToken + lenNonce + inner.Len() + box.Overhead)
	bodyRaw = body.RawBytes()

	// copy token
	copy(bodyRaw[:lenToken], s.remoteToken[:])

	// copy nonce
	copy(bodyRaw[lenToken:lenToken+lenNonce], nonce[:])

	// encrypt inner packet
	ctLen = len(box.SealAfterPrecomputation(
		bodyRaw[lenToken+lenNonce:lenToken+lenNonce], inner.RawBytes(), &nonce, s.lineEncryptionKey))
	body.SetLen(lenToken + lenNonce + ctLen)

	outer = lob.New(body.RawBytes())
	inner.Free()
	body.Free()

	return outer, nil
}