Simpler `stunnel` replacement.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

59 lines
1.0 KiB

package ttunnel
import (
"crypto/sha512"
"hash"
)
// In order to generate matching certificates on a client and server, we need a
// deterministic reader for random data. The reader is seeded with the
// password and uses multiple hashings to generate additional bytes.
type RandReader struct {
seed []byte
close chan bool
stream chan byte
h hash.Hash
}
func NewRandReader(seed []byte) *RandReader {
rr := RandReader{
seed: seed,
close: make(chan bool),
stream: make(chan byte),
h: sha512.New(),
}
go rr.run()
return &rr
}
func (rr *RandReader) run() {
buf := []byte{}
for {
_, _ = rr.h.Write(rr.seed) // Never returns an error (see docs).
buf = buf[:]
buf = rr.h.Sum(buf)
for _, b := range buf {
select {
case <-rr.close:
return
case rr.stream <- b:
// Continue
}
}
}
}
func (rr *RandReader) Read(p []byte) (n int, err error) {
for i := range p {
p[i] = <-rr.stream
}
return len(p), nil
}
func (rr *RandReader) Close() {
rr.close <- true
}