Initial commit, based mostly on https://github.com/austburn/gocrypt
This commit is contained in:
commit
f17df4ce88
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"cSpell.words": [
|
||||||
|
"netgiv"
|
||||||
|
]
|
||||||
|
}
|
55
client.go
Normal file
55
client.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/tardisx/netgiv/secure"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
port int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Connect() error {
|
||||||
|
address := fmt.Sprintf("127.0.0.1:%d", c.port)
|
||||||
|
serverAddress, _ := net.ResolveTCPAddr("tcp", address)
|
||||||
|
|
||||||
|
conn, err := net.DialTCP("tcp", nil, serverAddress)
|
||||||
|
if err != nil {
|
||||||
|
return errors.New("Problem connecting to server, is it running?\n")
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
fmt.Printf("Connection on %s\n", address)
|
||||||
|
|
||||||
|
sharedKey := secure.Handshake(conn)
|
||||||
|
secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey}
|
||||||
|
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
|
for {
|
||||||
|
fmt.Print("> ")
|
||||||
|
// Read up to the newline character
|
||||||
|
msg, _ := reader.ReadBytes(0xA)
|
||||||
|
// Kill the newline char
|
||||||
|
msg = msg[:len(msg)-1]
|
||||||
|
|
||||||
|
_, err := secureConnection.Write(msg)
|
||||||
|
|
||||||
|
response := make([]byte, 1024)
|
||||||
|
|
||||||
|
_, err = secureConnection.Read(response)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print("Connection to the server was closed.\n")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", response)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
8
go.mod
Normal file
8
go.mod
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
module github.com/tardisx/netgiv
|
||||||
|
|
||||||
|
go 1.17
|
||||||
|
|
||||||
|
require (
|
||||||
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
|
||||||
|
)
|
4
go.sum
Normal file
4
go.sum
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
|
||||||
|
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
|
||||||
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
25
main.go
Normal file
25
main.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
port := flag.Int("p", 9000, "Port to run server/client on.")
|
||||||
|
isServer := flag.Bool("s", false, "Set if running the server.")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *isServer {
|
||||||
|
fmt.Printf("Server running on %d\n", *port)
|
||||||
|
s := Server{port: *port}
|
||||||
|
s.Run()
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Client running on %d\n", *port)
|
||||||
|
c := Client{port: *port}
|
||||||
|
err := c.Connect()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
82
secure/secure.go
Normal file
82
secure/secure.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package secure
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/nacl/box"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SecureMessage struct {
|
||||||
|
Msg []byte
|
||||||
|
Nonce [24]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecureMessage) toByteArray() []byte {
|
||||||
|
return append(s.Nonce[:], s.Msg[:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConstructSecureMessage(sm []byte) SecureMessage {
|
||||||
|
var nonce [24]byte
|
||||||
|
nonceArray := sm[:24]
|
||||||
|
copy(nonce[:], nonceArray)
|
||||||
|
|
||||||
|
// Trim out all unnecessary bytes
|
||||||
|
msg := bytes.Trim(sm[24:], "\x00")
|
||||||
|
|
||||||
|
return SecureMessage{Msg: msg, Nonce: nonce}
|
||||||
|
}
|
||||||
|
|
||||||
|
type SecureConnection struct {
|
||||||
|
Conn *net.TCPConn
|
||||||
|
SharedKey *[32]byte
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecureConnection) Read(p []byte) (int, error) {
|
||||||
|
message := make([]byte, 2048)
|
||||||
|
// Read the message from the buffer
|
||||||
|
n, err := s.Conn.Read(message)
|
||||||
|
|
||||||
|
secureMessage := ConstructSecureMessage(message)
|
||||||
|
decryptedMessage, ok := box.OpenAfterPrecomputation(nil, secureMessage.Msg, &secureMessage.Nonce, s.SharedKey)
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return 0, errors.New("Problem decrypting the message.\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actually copy it to the destination byte array
|
||||||
|
n = copy(p, decryptedMessage)
|
||||||
|
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *SecureConnection) Write(p []byte) (int, error) {
|
||||||
|
var nonce [24]byte
|
||||||
|
|
||||||
|
// Create a new nonce for each message sent
|
||||||
|
rand.Read(nonce[:])
|
||||||
|
|
||||||
|
encryptedMessage := box.SealAfterPrecomputation(nil, p, &nonce, s.SharedKey)
|
||||||
|
sm := SecureMessage{Msg: encryptedMessage, Nonce: nonce}
|
||||||
|
|
||||||
|
// Write it to the connection
|
||||||
|
return s.Conn.Write(sm.toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Handshake(conn *net.TCPConn) *[32]byte {
|
||||||
|
var peerKey, sharedKey [32]byte
|
||||||
|
|
||||||
|
publicKey, privateKey, _ := box.GenerateKey(rand.Reader)
|
||||||
|
|
||||||
|
conn.Write(publicKey[:])
|
||||||
|
|
||||||
|
peerKeyArray := make([]byte, 32)
|
||||||
|
conn.Read(peerKeyArray)
|
||||||
|
copy(peerKey[:], peerKeyArray)
|
||||||
|
|
||||||
|
box.Precompute(&sharedKey, &peerKey, privateKey)
|
||||||
|
|
||||||
|
return &sharedKey
|
||||||
|
}
|
51
server.go
Normal file
51
server.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/tardisx/netgiv/secure"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Server struct {
|
||||||
|
port int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) Run() {
|
||||||
|
address := fmt.Sprintf("127.0.0.1:%d", s.port)
|
||||||
|
networkAddress, _ := net.ResolveTCPAddr("tcp", address)
|
||||||
|
|
||||||
|
listener, err := net.ListenTCP("tcp", networkAddress)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
os.Exit(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
conn, err := listener.AcceptTCP()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Print(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
go handleConnection(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleConnection(conn *net.TCPConn) {
|
||||||
|
defer conn.Close()
|
||||||
|
sharedKey := secure.Handshake(conn)
|
||||||
|
secureConnection := secure.SecureConnection{Conn: conn, SharedKey: sharedKey}
|
||||||
|
|
||||||
|
for {
|
||||||
|
msg := make([]byte, 1024)
|
||||||
|
_, err := secureConnection.Read(msg)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
secureConnection.Write(msg)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user