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