2 GoVPN -- simple secure free software virtual private network daemon
3 Copyright (C) 2014-2015 Sergey Matveev <stargrave@stargrave.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 "golang.org/x/crypto/xtea"
34 type PeerId [IDSize]byte
36 func (id PeerId) String() string {
37 return hex.EncodeToString(id[:])
40 type cipherCache map[PeerId]*xtea.Cipher
47 // Initialize (pre-cache) available peers info.
48 func PeersInit(path string) {
50 IDsCache = make(map[PeerId]*xtea.Cipher)
54 // Refresh IDsCache: remove disappeared keys, add missing ones with
55 // initialized ciphers.
56 func (cc cipherCache) refresh() {
57 dir, err := os.Open(PeersPath)
61 peerIds, err := dir.Readdirnames(0)
65 available := make(map[PeerId]bool)
66 for _, peerId := range peerIds {
67 id := IDDecode(peerId)
73 // Cleanup deleted ones from cache
74 for k, _ := range cc {
75 if _, exists := available[k]; !exists {
77 log.Println("Cleaning key: ", k)
81 for peerId, _ := range available {
82 if _, exists := cc[peerId]; !exists {
83 log.Println("Adding key", peerId)
84 cipher, err := xtea.NewCipher(peerId[:])
93 // Try to find peer's identity (that equals to an encryption key)
94 // by providing cipher and plain texts.
95 func (cc cipherCache) Find(plaintext, ciphertext []byte) *PeerId {
97 buf := make([]byte, xtea.BlockSize)
98 for pid, cipher := range cc {
99 cipher.Decrypt(buf, ciphertext)
100 if subtle.ConstantTimeCompare(buf, plaintext) == 1 {
108 // Decode identification string.
109 // It must be 32 hexadecimal characters long.
110 // If it is not the valid one, then return nil.
111 func IDDecode(raw string) *PeerId {
112 if len(raw) != IDSize*2 {
115 idDecoded, err := hex.DecodeString(raw)
119 idP := new([IDSize]byte)
120 copy(idP[:], idDecoded)