Пример #1
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
}