Douglas Andreani 5 лет назад
Родитель
Сommit
2f50056e08
4 измененных файлов с 189 добавлено и 0 удалено
  1. 35 0
      unchat/client.go
  2. 77 0
      unchat/crypt-unchat.go
  3. 3 0
      unchat/go.mod
  4. 74 0
      unchat/server.go

+ 35 - 0
unchat/client.go

@@ -0,0 +1,35 @@
+package unchat
+
+import (
+	"bufio"
+	"log"
+	"net"
+)
+
+//A Client is a entity which can be connected to/by a server
+type Client struct {
+	client net.Conn
+	alias  string
+	server *Server
+}
+
+//SendMessage write to the tcp body and sends to the client
+func (c *Client) SendMessage(message string) error {
+	_, err := c.client.Write([]byte(message))
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (c *Client) ReadInput() error {
+	for {
+		msg, err := bufio.NewReader(c.client).ReadString('\n')
+		if err != nil {
+			return err
+		}
+		log.Printf("msg: %s", msg)
+
+	}
+
+}

+ 77 - 0
unchat/crypt-unchat.go

@@ -0,0 +1,77 @@
+package unchat
+
+import (
+	"crypto/rand"
+	"crypto/rsa"
+	"crypto/sha256"
+	"crypto/x509"
+	"encoding/pem"
+	"fmt"
+	"log"
+)
+
+func main() {
+	key_pk, err := rsa.GenerateKey(rand.Reader, 2048)
+	if err != nil {
+		log.Fatalf("could not generate keypair %s", err)
+	}
+
+	pub_key := &key_pk.PublicKey
+
+	msg := []byte("this is a new message to be encrypted")
+	label := []byte("")
+	hash := sha256.New()
+
+	cipher_text, err := rsa.EncryptOAEP(
+		hash,
+		rand.Reader,
+		pub_key,
+		msg,
+		label)
+
+	if err != nil {
+		log.Fatalf("could not encrypt message %s", err)
+	}
+
+	fmt.Printf("message encrypted: \n%x\n", cipher_text)
+
+	plain_text, err := rsa.DecryptOAEP(
+		hash,
+		rand.Reader,
+		key_pk,
+		cipher_text,
+		label)
+	if err != nil {
+		log.Fatalf("could not decrypt message %s", err)
+	}
+	fmt.Printf("message decrypted: \n%s\n", plain_text)
+
+	pem := ExportPrivKeyAsPEM(key_pk)
+	fmt.Printf("PEM Priv Key \n%s\n", pem)
+
+	ParsePrivKeyFromPEM(pem)
+
+}
+
+func ExportPrivKeyAsPEM(privKey *rsa.PrivateKey) string {
+	privkey_bytes := x509.MarshalPKCS1PrivateKey(privKey)
+	privkey_pem := pem.EncodeToMemory(
+		&pem.Block{
+			Type:  "RSA PRIVATE KEY",
+			Bytes: privkey_bytes,
+		},
+	)
+	return string(privkey_pem)
+}
+
+func ParsePrivKeyFromPEM(pemKey string) (*rsa.PrivateKey, error) {
+	block, _ := pem.Decode([]byte(pemKey))
+	if block == nil {
+		return nil, fmt.Errorf("could not read pem string")
+	}
+	priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		return nil, err
+	}
+	return priv, nil
+}

+ 3 - 0
unchat/go.mod

@@ -0,0 +1,3 @@
+module unchat
+
+go 1.14

+ 74 - 0
unchat/server.go

@@ -0,0 +1,74 @@
+package unchat
+
+import (
+	"fmt"
+	"log"
+	"net"
+)
+
+//A Server is a proposed type to hold details about itself and connected clients
+type Server struct {
+	alias    string
+	version  string
+	port     int32
+	clients  map[string]Client
+	listener net.Listener
+}
+
+//NewServer initialize a standard server with common attributes
+func NewServer(alias string) Server {
+	return Server{
+		alias:   alias,
+		port:    9999,
+		version: "default",
+	}
+}
+
+//Open expects the port and the ip address which a TCP listener will be started
+func (s *Server) Open(listenAddress string) {
+
+	var server net.Listener
+	address := fmt.Sprintf("%s:%d", listenAddress, s.port)
+	server, err := net.Listen("TCPV4", address)
+	s.listener = server
+	if err != nil {
+		log.Fatalf("could not listen on %s %s", address, err)
+	}
+	defer s.listener.Close()
+	for {
+		conn, err := s.listener.Accept()
+		if err != nil {
+			log.Fatalf("could not accept connection %s", err)
+		}
+
+		go s.handleConnection(conn)
+		defer conn.Close()
+
+	}
+}
+
+func (s *Server) handleConnection(conn net.Conn) {
+	c := &Client{
+		client: conn,
+		alias:  "undefined",
+		server: s,
+	}
+
+	if s.clients == nil {
+		s.clients = make(map[string]Client)
+	}
+	s.clients[c.alias] = *c
+	s.Broadcast(fmt.Sprintf("> %s has joined the server", c.alias))
+	c.ReadInput()
+}
+
+//Broadcast sends a message to all connected clients
+func (s *Server) Broadcast(message string) error {
+	for _, v := range s.clients {
+		err := v.SendMessage(message)
+		if err != nil {
+			log.Printf("count not broadcast to %s: %s", s.alias, err)
+		}
+	}
+	return nil
+}