along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-// All-Or-Nothing-Transform, based on OAEP.
+// Package aont stand 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 = 32
+ // RSize TODO
RSize = 16
)
"cypherpunks.ru/govpn"
)
+// Protocol is a GoVPN supported protocol: UDP, TCP or both
type Protocol int
const (
+ // ProtocolUDP GoVPN over UDP
ProtocolUDP Protocol = iota
+ // ProtocolTCP GoVPN over TCP
ProtocolTCP
)
+// Configuration hold GoVPN client configuration
type Configuration struct {
PrivateKey *[ed25519.PrivateKeySize]byte
Peer *govpn.PeerConf
MTU int
}
+// Validate return 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)
return len(c.ProxyAddress) > 0
}
+// Client is a GoVPN client
type Client struct {
idsCache *govpn.MACCache
tap *govpn.TAP
Error chan error
}
+// MainCycle main loop of a connecting/connected client
func (c *Client) MainCycle() {
var err error
c.tap, err = govpn.TAPListen(c.config.InterfaceName, c.config.MTU)
}
}
+// NewClient return 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
type PeerState struct {
peer *govpn.Peer
terminator chan struct{}
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-// Chaffing-and-Winnowing.
+// Package cnw stand for Chaffing-and-Winnowing.
//
// This package implements Chaffing-and-Winnowing technology
// (http://people.csail.mit.edu/rivest/chaffing-980701.txt).
"golang.org/x/crypto/poly1305"
)
-const (
- EnlargeFactor = 16 * poly1305.TagSize
-)
+// EnlargeFactor TODO
+const EnlargeFactor = 16 * poly1305.TagSize
func zero(in []byte) {
for i := 0; i < len(in); i++ {
const (
TimeoutDefault = 60
EtherSize = 14
- MTUMax = 9000 + EtherSize + 1
- MTUDefault = 1500 + EtherSize + 1
+ // MTUMax is maximum MTU size of ethernet packet
+ MTUMax = 9000 + EtherSize + 1
+ // MTUDefault is default MTU size of ethernet packet
+ MTUDefault = 1500 + EtherSize + 1
ENV_IFACE = "GOVPN_IFACE"
ENV_REMOTE = "GOVPN_REMOTE"
)
var (
+ // Version hold release string set at build time
Version string
)
-// Call external program/script.
+// ScriptCall call 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.
"github.com/agl/ed25519"
)
+// PeerConf is configuration of a single GoVPN Peer (client)
type PeerConf struct {
ID *PeerID `yaml:"-"`
Name string `yaml:"name"`
"net"
)
-var (
- Rand = rand.Reader
-)
+// Rand is a source of entropy
+var Rand = rand.Reader
+// EGDRand is a EGD 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
func EGDInit(path string) {
Rand = EGDRand(path)
}
"cypherpunks.ru/govpn/cnw"
)
-const (
- EnclessEnlargeSize = aont.HSize + aont.RSize*cnw.EnlargeFactor
-)
+// EnclessEnlargeSize TODO
+const EnclessEnlargeSize = aont.HSize + aont.RSize*cnw.EnlargeFactor
-// Confidentiality preserving (but encryptionless) encoding.
+// EnclessEncode is a confidentiality preserving (but encryptionless) encoding.
//
// It uses Chaffing-and-Winnowing technology (it is neither
// encryption nor steganography) over All-Or-Nothing-Transformed data.
return out, nil
}
-// Decode EnclessEncode-ed data.
+// EnclessDecode decode EnclessEncode-ed data.
func EnclessDecode(authKey *[32]byte, nonce *[16]byte, in []byte) ([]byte, error) {
var err error
winnowed, err := cnw.Winnow(
-// Simple secure, DPI/censorship-resistant free software VPN daemon.
+// Package govpn is a simple secure, DPI/censorship-resistant free software VPN client and server.
package govpn
-const (
- Warranty = `This program is free software: you can redistribute it and/or modify
+// Warranty is GoVPN license
+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
(at your option) any later version.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.`
-)
)
const (
+ // RSize TODO
RSize = 8
+ // SSize TODO
SSize = 32
)
+// Handshake is state of a handshake/negotiation between client and server
type Handshake struct {
addr string
conn io.Writer
return &hashed
}
-// Create new handshake state.
+// NewHandshake create new handshake state.
func NewHandshake(addr string, conn io.Writer, conf *PeerConf) *Handshake {
state := Handshake{
addr: addr,
return sum[len(sum)-8:]
}
-// Start handshake's procedure from the client. It is the entry point
+// HandshakeStart 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 {
return state
}
-// Process handshake message on the server side.
+// Server process 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
}
-// Process handshake message on the client side.
+// Client process 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"
)
-const (
- IDSize = 128 / 8
-)
+// IDSize is size a GoVPN peer ID must be
+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
func (id PeerID) String() string {
return base64.RawStdEncoding.EncodeToString(id[:])
}
+// MarshalJSON return a JSON string from a peer ID
func (id PeerID) MarshalJSON() ([]byte, error) {
return []byte(`"` + id.String() + `"`), nil
}
+// MACAndTimeSync is a single peer MAC and timesync
type MACAndTimeSync struct {
mac hash.Hash
ts int
l sync.Mutex
}
+// MACCache cache all MACAndTimeSync for peers allowed to connect
type MACCache struct {
cache map[PeerID]*MACAndTimeSync
l sync.RWMutex
}
+// NewMACCache return a new MACCache instance
func NewMACCache() *MACCache {
return &MACCache{cache: make(map[PeerID]*MACAndTimeSync)}
}
-// Remove disappeared keys, add missing ones with initialized MACs.
+// Update remove 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()
}
-// If timeSync > 0, then XOR timestamp with the data.
+// AddTimeSync XOR timestamp with data if timeSync > 0
func AddTimeSync(ts int, data []byte) {
if ts == 0 {
return
}
}
-// Try to find peer's identity (that equals to MAC)
+// Find try 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 = 8
NonceBucketSize = 256
TagSize = poly1305.TagSize
// S20BS is ChaCha20's internal blocksize in bytes
S20BS = 64
- // Maximal amount of bytes transfered with single key (4 GiB)
+ // MaxBytesPerKey maximal amount of bytes transfered with single key (4 GiB)
MaxBytesPerKey uint64 = 1 << 32
// Heartbeat rate, relative to Timeout
TimeoutHeartbeat = 4
- // Minimal valid packet length
+ // MinPktLength minimal valid packet length
MinPktLength = 1 + 16 + 8
// Padding byte
PadByte = byte(0x80)
return nonces
}
+// Peer is a GoVPN peer (client)
type Peer struct {
// Statistics (they are at the beginning for correct int64 alignment)
BytesIn uint64
return &peer
}
-// Process incoming Ethernet packet.
+// EthProcess process 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
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
func PeerTapProcessor(peer *Peer, tap *TAP, terminator chan struct{}) {
var data []byte
var now time.Time
RWTimeout = 10 * time.Second
)
+// KnownPeers map of all connected GoVPN peers
type KnownPeers map[string]**Peer
// StatsProcessor is assumed to be run in background. It accepts
"io"
)
+// TAP is a TUN or a TAP interface.
type TAP struct {
Name string
Sink chan []byte
taps = make(map[string]*TAP)
)
+// NewTAP create 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
func TAPListen(ifaceName string, mtu int) (*TAP, error) {
tap, exists := taps[ifaceName]
if exists {
)
const (
+ // DefaultS default Balloon space cost
DefaultS = 1 << 20 / 32
+ // DefaultT default Balloon time cost
DefaultT = 1 << 4
+ // DefaultP default Balloon number of job
DefaultP = 2
)
+// Verifier is used to verify a peer
type Verifier struct {
S int
T int
Pub *[ed25519.PublicKeySize]byte
}
-// Generate new verifier for given peer, with specified password and
+// VerifierNew generate 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
}
-// Apply the password: create Ed25519 keypair based on it, save public
+// PasswordApply apply the password: create Ed25519 keypair based on it, save 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)
return prv
}
-// Parse either short or long verifier form.
+// VerifierFromString parse 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
}
-// Short verifier string form -- it is useful for the client.
+// ShortForm short verifier string form -- it is useful for the client.
// Does not include public key.
func (v *Verifier) ShortForm() string {
return fmt.Sprintf(
)
}
-// Long verifier string form -- it is useful for the server.
+// LongForm long verifier string form -- it is useful for the server.
// Includes public key.
func (v *Verifier) LongForm() string {
return fmt.Sprintf(
)
}
-// Read the key either from text file (if path is specified), or
+// KeyRead read the key either from text file (if path is specified), or
// from the terminal.
func KeyRead(path string) (string, error) {
var p []byte