// CONTRACT: data smaller than dataMaxSize is read atomically. func (sc *SecretConnection) Read(data []byte) (n int, err error) { if 0 < len(sc.recvBuffer) { n_ := copy(data, sc.recvBuffer) sc.recvBuffer = sc.recvBuffer[n_:] return } sealedFrame := make([]byte, sealedFrameSize) _, err = io.ReadFull(sc.conn, sealedFrame) if err != nil { return } // decrypt the frame var frame = make([]byte, totalFrameSize) // fmt.Printf("secretbox.Open(sealed:%X,recvNonce:%X,shrSecret:%X\n", sealedFrame, sc.recvNonce, sc.shrSecret) _, ok := secretbox.Open(frame[:0], sealedFrame, sc.recvNonce, sc.shrSecret) if !ok { return n, errors.New("Failed to decrypt SecretConnection") } incr2Nonce(sc.recvNonce) // end decryption var chunkLength = binary.BigEndian.Uint16(frame) // read the first two bytes if chunkLength > dataMaxSize { return 0, errors.New("chunkLength is greater than dataMaxSize") } var chunk = frame[dataLenSize : dataLenSize+chunkLength] n = copy(data, chunk) sc.recvBuffer = chunk[n:] return }
// OpenAfterPrecomputation performs the same actions as Open, but takes a // shared key as generated by Precompute. func OpenAfterPrecomputation(out, box []byte, nonce *[24]byte, sharedKey *[32]byte) ([]byte, bool) { return secretbox.Open(out, box, nonce, sharedKey) }
// Open authenticates and decrypts a box produced by Seal and appends the // message to out, which must not overlap box. The output will be Overhead // bytes smaller than box. func Open(out, box []byte, nonce *[24]byte, peersPublicKey, privateKey *[32]byte) ([]byte, bool) { var sharedKey [32]byte Precompute(&sharedKey, peersPublicKey, privateKey) return secretbox.Open(out, box, nonce, &sharedKey) }