along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-// Package aont stand for All-Or-Nothing-Transform, based on OAEP.
+// Package aont stands for All-Or-Nothing-Transform, based on OAEP.
//
// This package implements OAEP (Optimal Asymmetric Encryption Padding)
// (http://cseweb.ucsd.edu/~mihir/papers/oaep.html)
)
const (
- // HSize TODO
+ // HSize size of generated hash output in terms of OAEP
HSize = 32
- // RSize TODO
+ // RSize size of generated random output in terms of OAEP
RSize = 16
)
"cypherpunks.ru/govpn"
)
-// Protocol is a GoVPN supported protocol: UDP, TCP or both
+// Protocol is a GoVPN supported protocol: either UDP, TCP or both
type Protocol int
const (
- // ProtocolUDP GoVPN over UDP
+ // ProtocolUDP is UDP transport protocol
ProtocolUDP Protocol = iota
- // ProtocolTCP GoVPN over TCP
+ // ProtocolTCP is TCP transport protocol
ProtocolTCP
)
-// Configuration hold GoVPN client configuration
+// Configuration holds GoVPN client configuration
type Configuration struct {
PrivateKey *[ed25519.PrivateKeySize]byte
Peer *govpn.PeerConf
MTU int
}
-// Validate return an error if a configuration is invalid
+// Validate returns an error if a configuration is invalid
func (c *Configuration) Validate() error {
if c.MTU > govpn.MTUMax {
return fmt.Errorf("Invalid MTU %d, maximum allowable is %d", c.MTU, govpn.MTUMax)
}
}
-// NewClient return a configured GoVPN client, to trigger connection MainCycle must be executed
+// NewClient returns a configured GoVPN client, to trigger connection
+// MainCycle must be executed.
func NewClient(conf Configuration, verifier *govpn.Verifier, termSignal chan os.Signal) *Client {
client := Client{
idsCache: govpn.NewMACCache(),
"cypherpunks.ru/govpn"
)
-// PeerState hold server side state of a single connecting/connected peer
+// PeerState holds server side state of a single connecting/connected peer
type PeerState struct {
peer *govpn.Peer
terminator chan struct{}
"golang.org/x/crypto/poly1305"
)
-// EnlargeFactor TODO
+// EnlargeFactor tells how many output bytes will produce single input byte
const EnlargeFactor = 16 * poly1305.TagSize
func zero(in []byte) {
const (
TimeoutDefault = 60
EtherSize = 14
- // MTUMax is maximum MTU size of ethernet packet
+ // MTUMax is maximum MTU size of Ethernet packet
MTUMax = 9000 + EtherSize + 1
- // MTUDefault is default MTU size of ethernet packet
+ // MTUDefault is default MTU size of Ethernet packet
MTUDefault = 1500 + EtherSize + 1
ENV_IFACE = "GOVPN_IFACE"
)
var (
- // Version hold release string set at build time
+ // Version holds release string set at build time
Version string
)
-// ScriptCall call external program/script.
+// ScriptCall calls external program/script.
// You have to specify path to it and (inteface name as a rule) something
// that will be the first argument when calling it. Function will return
// it's output and possible error.
// Rand is a source of entropy
var Rand = rand.Reader
-// EGDRand is a EGD source of entropy
+// EGDRand is a EGD (Entropy Gathering Daemon) source of entropy
type EGDRand string
// Read n bytes from EGD, blocking mode.
return io.ReadFull(conn, b)
}
-// EGDInit set random source to a EGD socket
+// EGDInit sets random source to a EGD socket
func EGDInit(path string) {
Rand = EGDRand(path)
}
"cypherpunks.ru/govpn/cnw"
)
-// EnclessEnlargeSize TODO
+// EnclessEnlargeSize is number of bytes overhead for each message
const EnclessEnlargeSize = aont.HSize + aont.RSize*cnw.EnlargeFactor
-// EnclessEncode is a confidentiality preserving (but encryptionless) encoding.
+// EnclessEncode is encryptionless, but confidentiality preserving encoding.
//
// It uses Chaffing-and-Winnowing technology (it is neither
// encryption nor steganography) over All-Or-Nothing-Transformed data.
return out, nil
}
-// EnclessDecode decode EnclessEncode-ed data.
+// EnclessDecode decodes EnclessEncode-ed data.
func EnclessDecode(authKey *[32]byte, nonce *[16]byte, in []byte) ([]byte, error) {
var err error
winnowed, err := cnw.Winnow(
-// Package govpn is a simple secure, DPI/censorship-resistant free software VPN client and server.
+// Package govpn is a simple secure, DPI/censorship-resistant free
+// software VPN client and server.
package govpn
-// Warranty is GoVPN license
+// Warranty is GoVPN warranty information
const Warranty = `This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
)
const (
- // RSize TODO
+ // RSize is size in bytes of channel binding random value
RSize = 8
- // SSize TODO
+ // SSize is size in bytes of shared secret half
SSize = 32
)
return &hashed
}
-// NewHandshake create new handshake state.
+// NewHandshake creates new handshake state.
func NewHandshake(addr string, conn io.Writer, conf *PeerConf) *Handshake {
state := Handshake{
addr: addr,
return sum[len(sum)-8:]
}
-// HandshakeStart start handshake's procedure from the client. It is the entry point
-// for starting the handshake procedure.
+// HandshakeStarts start handshake's procedure from the client.
+// It is the entry point for starting the handshake procedure.
// First handshake packet will be sent immediately.
func HandshakeStart(addr string, conn io.Writer, conf *PeerConf) *Handshake {
state := NewHandshake(addr, conn, conf)
return state
}
-// Server process handshake message on the server side.
+// Server processes handshake message on the server side.
// This function is intended to be called on server's side.
// If this is the final handshake message, then new Peer object
// will be created and used as a transport. If no mutually
return nil
}
-// Client process handshake message on the client side.
+// Client processes handshake message on the client side.
// This function is intended to be called on client's side.
// If this is the final handshake message, then new Peer object
// will be created and used as a transport. If no mutually
"golang.org/x/crypto/blake2b"
)
-// IDSize is size a GoVPN peer ID must be
+// IDSize is a size of GoVPN peer's identity
const IDSize = 128 / 8
// PeerID is identifier of a single GoVPN peer (client)
type PeerID [IDSize]byte
-// String return a string from a peer ID
+// String returns peer's ID in stringified form
func (id PeerID) String() string {
return base64.RawStdEncoding.EncodeToString(id[:])
}
-// MarshalJSON return a JSON string from a peer ID
+// MarshalJSON returns a JSON serialized peer's ID
func (id PeerID) MarshalJSON() ([]byte, error) {
return []byte(`"` + id.String() + `"`), nil
}
l sync.Mutex
}
-// MACCache cache all MACAndTimeSync for peers allowed to connect
+// MACCache caches all MACAndTimeSync for peers allowed to connect
type MACCache struct {
cache map[PeerID]*MACAndTimeSync
l sync.RWMutex
}
-// NewMACCache return a new MACCache instance
+// NewMACCache returns a new MACCache instance
func NewMACCache() *MACCache {
return &MACCache{cache: make(map[PeerID]*MACAndTimeSync)}
}
-// Update remove disappeared keys, add missing ones with initialized MACs.
+// Update removes disappeared keys, add missing ones with initialized MACs.
func (mc *MACCache) Update(peers *map[PeerID]*PeerConf) {
mc.l.Lock()
for pid := range mc.cache {
mc.l.Unlock()
}
-// AddTimeSync XOR timestamp with data if timeSync > 0
+// AddTimeSync XORs timestamp with data if timeSync > 0
func AddTimeSync(ts int, data []byte) {
if ts == 0 {
return
}
}
-// Find try to find peer's identity (that equals to MAC)
+// Find tries to find peer's identity (that equals to MAC)
// by taking first blocksize sized bytes from data at the beginning
// as plaintext and last bytes as cyphertext.
func (mc *MACCache) Find(data []byte) *PeerID {
)
const (
- // NonceSize is nounce size
+ // NonceSize is nonce size
NonceSize = 8
NonceBucketSize = 256
TagSize = poly1305.TagSize
// S20BS is ChaCha20's internal blocksize in bytes
S20BS = 64
- // MaxBytesPerKey maximal amount of bytes transfered with single key (4 GiB)
+ // MaxBytesPerKey is maximal amount of bytes transferred with single key (4 GiB)
MaxBytesPerKey uint64 = 1 << 32
// Heartbeat rate, relative to Timeout
TimeoutHeartbeat = 4
- // MinPktLength minimal valid packet length
+ // MinPktLength is minimal valid packet length
MinPktLength = 1 + 16 + 8
// Padding byte
PadByte = byte(0x80)
return &peer
}
-// EthProcess process incoming Ethernet packet.
+// EthProcess processes incoming Ethernet packet.
// ready channel is TAPListen's synchronization channel used to tell him
// that he is free to receive new packets. Encrypted and authenticated
// packets will be sent to remote Peer side immediately.
p.BusyT.Unlock()
}
-// PktProcess process data of a single packet
+// PktProcess processes data of a single packet
func (p *Peer) PktProcess(data []byte, tap io.Writer, reorderable bool) bool {
if len(data) < MinPktLength {
return false
return true
}
-// PeerTapProcessor process a TUN/TAP peer
+// PeerTapProcessor processes a TUN/TAP peer
func PeerTapProcessor(peer *Peer, tap *TAP, terminator chan struct{}) {
var data []byte
var now time.Time
taps = make(map[string]*TAP)
)
-// NewTAP create a new TUN/TAP virtual interface
+// NewTAP creates a new TUN/TAP virtual interface
func NewTAP(ifaceName string, mtu int) (*TAP, error) {
tapRaw, err := newTAPer(ifaceName)
if err != nil {
return t.dev.Write(data)
}
-// TAPListen open an existing TAP, if none exists, open one
+// TAPListen opens an existing TAP (creates if none exists)
func TAPListen(ifaceName string, mtu int) (*TAP, error) {
tap, exists := taps[ifaceName]
if exists {
)
const (
- // DefaultS default Balloon space cost
+ // DefaultS is default Balloon space cost
DefaultS = 1 << 20 / 32
- // DefaultT default Balloon time cost
+ // DefaultT is default Balloon time cost
DefaultT = 1 << 4
- // DefaultP default Balloon number of job
+ // DefaultP is default Balloon number of jobs
DefaultP = 2
)
-// Verifier is used to verify a peer
+// Verifier is used to authenticate a peer
type Verifier struct {
S int
T int
Pub *[ed25519.PublicKeySize]byte
}
-// VerifierNew generate new verifier for given peer, with specified password and
-// hashing parameters.
+// VerifierNew generates new verifier for given peer,
+// with specified password and hashing parameters.
func VerifierNew(s, t, p int, id *PeerID) *Verifier {
return &Verifier{S: s, T: t, P: p, ID: id}
}
return h
}
-// PasswordApply apply the password: create Ed25519 keypair based on it, save public
-// key in verifier.
+// PasswordApply applies the password: create Ed25519 keypair based on it,
+// saves public key in verifier.
func (v *Verifier) PasswordApply(password string) *[ed25519.PrivateKeySize]byte {
r := balloon.H(blake2bKeyless, []byte(password), v.ID[:], v.S, v.T, v.P)
defer SliceZero(r)
return prv
}
-// VerifierFromString parse either short or long verifier form.
+// VerifierFromString parses either short or long verifier form.
func VerifierFromString(input string) (*Verifier, error) {
ss := strings.Split(input, "$")
if len(ss) < 4 || ss[1] != "balloon" {
return &v, nil
}
-// ShortForm short verifier string form -- it is useful for the client.
-// Does not include public key.
+// ShortForm outputs the short verifier string form -- it is useful
+// for the client. It does not include public key.
func (v *Verifier) ShortForm() string {
return fmt.Sprintf(
"$balloon$s=%d,t=%d,p=%d$%s",
)
}
-// LongForm long verifier string form -- it is useful for the server.
-// Includes public key.
+// LongForm outputs long verifier string form -- it is useful for the server.
+// It includes public key.
func (v *Verifier) LongForm() string {
return fmt.Sprintf(
"%s$%s", v.ShortForm(),
)
}
-// KeyRead read the key either from text file (if path is specified), or
+// KeyRead reads the key either from text file (if path is specified), or
// from the terminal.
func KeyRead(path string) (string, error) {
var p []byte