Skip to content

Commit

Permalink
ECDH process is improved between peers
Browse files Browse the repository at this point in the history
  • Loading branch information
berkkirtay committed Sep 22, 2024
1 parent 3baab8d commit 5b677c9
Show file tree
Hide file tree
Showing 15 changed files with 175 additions and 112 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ main
PRIVATE_KEY
PUBLIC_KEY
SIGN
keys/
2 changes: 1 addition & 1 deletion src/api/controllers/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func getPeers(c *gin.Context) {
res := peer.GetPeers()
res := peer.GetPeers(c.Query("hostname"), c.Query("role"))
if len(res) == 0 {
c.JSON(http.StatusNotFound, res)
} else {
Expand Down
4 changes: 3 additions & 1 deletion src/api/middlewares/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func InitializeRouters(routerGroup *gin.RouterGroup) {

func handleGenericPanic(c *gin.Context, err any) {
defer func() {
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"Error:": err})
c.AbortWithStatusJSON(
http.StatusInternalServerError,
gin.H{"Error:": err})
}()
}
12 changes: 7 additions & 5 deletions src/api/middlewares/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ func InitializeSession(app *gin.Engine) {
func ValidateAuthentication() gin.HandlerFunc {
return func(c *gin.Context) {
if !isAuthenticated(c) {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"Error:": "Connection is not authorized."})
c.AbortWithStatusJSON(
http.StatusUnauthorized,
gin.H{"Error:": "Connection is not authorized."})
}
c.Next()
}

}

func isAuthenticated(c *gin.Context) bool {
Expand All @@ -39,9 +40,10 @@ func isAuthenticated(c *gin.Context) bool {
userId := c.Request.Header.Get("Session")
publicKey := c.Request.Header.Get("PublicKey")
if publicKey != "" {
// var token string =
auth.InitializeSessionWithDiffieHellman(c, publicKey, userId)
// return token == authToken
authToken = auth.CalculateDiffieHellmanUserAuthentication(
userId,
publicKey,
authToken)
}
sessionId := session.Get(authToken)
return sessionId == userId
Expand Down
6 changes: 6 additions & 0 deletions src/commands/file_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ package commands

import (
"os"
"path/filepath"
)

func dumpToFile(data string, fileName string) {
dir := filepath.Dir(fileName)
err := os.MkdirAll(dir, os.ModePerm)
if err != nil {
panic(err)
}
file, err := os.Create(fileName)
if err != nil {
panic(err)
Expand Down
28 changes: 17 additions & 11 deletions src/commands/peer_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func InitializeAMasterPeer(hostname string, address string) {

// TODO review here:
func RegisterPeer(targetAddress string, hostname string, address string) {
//peer.UpdatePeerEllipticKeys(&assignedPeer)
var newPeer peer.Peer = peer.CreatePeer(
peer.WithHostname(hostname),
peer.WithAddress(address),
Expand All @@ -31,7 +32,6 @@ func RegisterPeer(targetAddress string, hostname string, address string) {
body, err := json.Marshal(newPeer)
if err != nil {
panic("err")

}
res := http.POST(assignedPeer, targetAddress+"/peer", string(body), &newPeer)
if res.StatusCode != http.CREATED {
Expand All @@ -48,25 +48,31 @@ func RegisterPeer(targetAddress string, hostname string, address string) {
func DeletePeer(peer.Peer) {
res := http.DELETE(assignedPeer, assignedPeer.Address+"/peer", nil, "hostId", assignedPeer.Hostname)
if res.StatusCode != http.OK {
fmt.Printf("Error removing the peer.")
fmt.Printf("Error removing the peer.\n")
}
}

func IsPeerInitialized() bool {
var currentPeers []peer.Peer = peer.GetPeers()
var currentPeers []peer.Peer = peer.GetPeers(string(""), string(""))
for _, currentPeer := range currentPeers {
if currentPeer.Role == peer.OUTBOUND && isPeerOnline(currentPeer) {
assignedPeer = currentPeer
if currentPeer.Role == peer.OUTBOUND {
assignedPeer = synchronizeWithPeer(currentPeer)
}
}
return assignedPeer.Address != ""
}

func isPeerOnline(peer peer.Peer) bool {
res := http.GET(peer, peer.Address+"/peer", nil)
if res == nil || (res != nil && res.StatusCode != http.OK) {
fmt.Printf("Peer %s is offline.\n", peer.Hostname)
return false
func synchronizeWithPeer(currentPeer peer.Peer) peer.Peer {
synchronizedPeer := make([]peer.Peer, 5)
res := http.GET(
currentPeer,
currentPeer.Address+"/peer",
&synchronizedPeer,
"hostname",
currentPeer.Hostname)
if res == nil || res.StatusCode != http.OK {
fmt.Printf("Peer %s is offline.\n", currentPeer.Hostname)
return peer.CreateDefaultPeer()
}
return true
return synchronizedPeer[0]
}
14 changes: 10 additions & 4 deletions src/commands/room_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func HandleGetRooms() {
fmt.Printf("------------\n")
}
} else {
fmt.Printf("No rooms found.")
fmt.Printf("No room found.\n")
}
}

Expand Down Expand Up @@ -73,8 +73,13 @@ func HandleText(command string) {
fmt.Printf("Error: %s", err)
return
}

res := http.POST(assignedPeer, assignedPeer.Address+"/room/messages", string(body), message, "id", currentRoom.Id)
res := http.POST(
assignedPeer,
assignedPeer.Address+"/room/messages",
string(body),
message,
"id",
currentRoom.Id)
if res.StatusCode != http.CREATED {
fmt.Printf("Message could not be sent.")
return
Expand Down Expand Up @@ -115,6 +120,7 @@ func joinRoom(roomId string, roomPassword string) {
}
}

// TODO: Can we implement a event listener instead of polling the peer constantly?
func messageLoop() {
for {
if !retrieveMessagesFlag {
Expand All @@ -124,7 +130,7 @@ func messageLoop() {
if messageSize > 0 {
getMessages(messageSize)
}
time.Sleep(500 * time.Millisecond)
time.Sleep(3000 * time.Millisecond)
}
}

Expand Down
16 changes: 9 additions & 7 deletions src/commands/user_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ func HandleRegister(command []string) {

name := command[1]
userCrypto := cryptography.CreateCommonCrypto(name)
dumpToFile(userCrypto.PrivateKey, "PRIVATE_KEY")
dumpToFile(userCrypto.PublicKey, "PUBLIC_KEY")
dumpToFile(userCrypto.Sign, "SIGN")
dumpToFile(userCrypto.PublicKey, fmt.Sprintf("./keys/PUBLIC_KEY_%s", name))
dumpToFile(userCrypto.PrivateKey, fmt.Sprintf("./keys/PRIVATE_KEY_%s", name))
dumpToFile(userCrypto.Sign, fmt.Sprintf("./keys/SIGN_%s", name))
userCrypto.PrivateKey = ""
userCrypto.Elliptic.PrivateKey = nil
var user user.User = user.CreateUser(
Expand Down Expand Up @@ -75,9 +75,10 @@ func HandleLogin(command []string) {
}

func loginWithPKCS(userLogin string, userId string) auth.AuthenticationModel {
publicKey := readFromFile("PUBLIC_KEY")
privateKey := readFromFile("PRIVATE_KEY")
sign := readFromFile("SIGN")
publicKey := readFromFile(fmt.Sprintf("./keys/PUBLIC_KEY_%s", userLogin))
privateKey := readFromFile(fmt.Sprintf("./keys/PRIVATE_KEY_%s", userLogin))
sign := readFromFile(fmt.Sprintf("./keys/SIGN_%s", userLogin))

ellipticPrivate, ellipticPublic := cryptography.GenerateEllipticCurveKeys()
userCrypto := cryptography.CreateCryptography(
cryptography.WithSign(sign),
Expand All @@ -92,9 +93,10 @@ func loginWithPKCS(userLogin string, userId string) auth.AuthenticationModel {
auth.WithCryptography(userCrypto)))

if authentication.Id != "" {
authentication.Token = cryptography.DiffieHellman(
key := cryptography.DiffieHellman(
ellipticPrivate,
assignedPeer.Cryptography.Elliptic.PublicKey)
authentication.Token = cryptography.DecryptAES(authentication.Token, key)
authentication.Cryptography.PrivateKey = privateKey
}
return authentication
Expand Down
68 changes: 39 additions & 29 deletions src/infra/http/http_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import (
)

/*
* Service to make HTTP requests. Handles session cookies upon user authentication.
* Service to make HTTP requests.
* Handles session cookies upon user authentication.
*/

const (
Expand All @@ -25,18 +26,13 @@ const (
INTERNAL_SERVER_ERROR = 500
)

var sessionAuth *auth.AuthenticationModel
var sessionHeader HeaderModel
var client *http.Client

func InitializeService(sessionAuth *auth.AuthenticationModel) {
if sessionAuth != nil && sessionAuth.Token != "" {
sessionHeader = CreateHeaderModel(
WithContentType("application/json"),
WithCookie(sessionAuth.Cookies),
WithSession(sessionAuth.Id),
WithAuthorization(sessionAuth.Token),
WithPublicKey(sessionAuth.Cryptography.PublicKey))

func InitializeService(auth *auth.AuthenticationModel) {
if auth != nil && auth.Token != "" {
sessionAuth = auth
}
if client == nil {
jar, err := cookiejar.New(nil)
Expand All @@ -49,20 +45,29 @@ func InitializeService(sessionAuth *auth.AuthenticationModel) {
}
}

func generateANewWithDiffieHellmanAuthKey(peer peer.Peer) {
privateKey, publicKey := cryptography.GenerateEllipticCurveKeys()
var token string = cryptography.DiffieHellman(privateKey, peer.Cryptography.Elliptic.PublicKey)
sessionHeader = CreateHeaderModel(
WithContentType("application/json"),
WithCookie(sessionHeader.Cookie),
WithSession(sessionHeader.Session),
WithAuthorization(token),
WithPublicKey(publicKey))
func generateNextEncryptedToken(peer peer.Peer) {
if sessionAuth != nil && sessionAuth.Token != "" {
privateKey, publicKey := cryptography.GenerateEllipticCurveKeys()
key := cryptography.DiffieHellman(
privateKey,
peer.Cryptography.Elliptic.PublicKey)
encryptedToken := cryptography.EncryptAES(sessionAuth.Token, key)
sessionHeader = CreateHeaderModel(
WithContentType("application/json"),
WithCookie(sessionAuth.Cookies),
WithSession(sessionAuth.Id),
WithAuthorization(encryptedToken),
WithPublicKey(publicKey))
}
}

func GET(peer peer.Peer, path string, respType interface{}, params ...string) *http.Response {
func GET(
peer peer.Peer,
path string,
respType interface{},
params ...string) *http.Response {
InitializeService(nil)
generateANewWithDiffieHellmanAuthKey(peer)
generateNextEncryptedToken(peer)
path = handleQueryParams(path, params)
req, err := http.NewRequest(http.MethodGet, path, nil)
if err != nil {
Expand All @@ -88,9 +93,14 @@ func GET(peer peer.Peer, path string, respType interface{}, params ...string) *h
return res
}

func POST(peer peer.Peer, path string, payload string, respType interface{}, params ...string) *http.Response {
func POST(
peer peer.Peer,
path string,
payload string,
respType interface{},
params ...string) *http.Response {
InitializeService(nil)
generateANewWithDiffieHellmanAuthKey(peer)
generateNextEncryptedToken(peer)
path = handleQueryParams(path, params)
req, err := http.NewRequest(http.MethodPost, path, strings.NewReader(payload))
if err != nil {
Expand Down Expand Up @@ -120,9 +130,13 @@ func PUT() {

}

func DELETE(peer peer.Peer, path string, respType interface{}, params ...string) *http.Response {
func DELETE(
peer peer.Peer,
path string,
respType interface{},
params ...string) *http.Response {
InitializeService(nil)
generateANewWithDiffieHellmanAuthKey(peer)
generateNextEncryptedToken(peer)
path = handleQueryParams(path, params)
req, err := http.NewRequest(http.MethodDelete, path, nil)
if err != nil {
Expand All @@ -144,10 +158,6 @@ func prepareHeadersForRequest(req *http.Request) {
for key, value := range headerMap {
req.Header.Add(key, value)
}
// urlObj, _ := url.Parse("/")
// if len(sessionHeader.Cookie) > 0 {
// client.Jar.SetCookies(urlObj, sessionHeader.Cookie)
// }
}

func handleQueryParams(url string, params []string) string {
Expand Down
17 changes: 11 additions & 6 deletions src/p2p/broadcast.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
const (
LOCAL_BROADCAST_ADDRESS string = "224.0.0.1:9999"
NETWORK_NAME string = "udp4"
MAX_BROADCAST_AMOUNT int = 1
MAX_BROADCAST_AMOUNT int = 2
ADDRESS_FORMAT string = HTTP + "%s" + PORT + API
)

Expand All @@ -54,20 +54,22 @@ func startPeerBroadcast() {

// Continuously check if the current host has established a connection with any peer:
for i := 0; i < MAX_BROADCAST_AMOUNT; i++ {
if commands.IsPeerInitialized() {
return
}
fmt.Printf("Broadcasting for an active peer... %d\n", i)
_, err = broadcast.Write([]byte(strconv.Itoa(unique_udp_request_identifier)))
if err != nil {
panic(err)
}
if commands.IsPeerInitialized() {
return
}
time.Sleep(1 * time.Second)
}

// Become a main peer in case no other peer exists:
fmt.Println("No active peer found, making yourself an active peer.")
commands.InitializeAMasterPeer(currentHost, fmt.Sprintf(ADDRESS_FORMAT, currentHost))
commands.InitializeAMasterPeer(
currentHost,
fmt.Sprintf(ADDRESS_FORMAT, currentHost))
}

func listenForPeerBroadcast() {
Expand Down Expand Up @@ -101,7 +103,10 @@ func listenForPeerBroadcast() {
// Send your peer info to the sender and conclude broadcasting:
var remote_udp_request_identifier, _ = strconv.Atoi(string(buf[:n]))
if remote_udp_request_identifier != unique_udp_request_identifier {
var targetAddress string = fmt.Sprintf(ADDRESS_FORMAT, strings.Split(addr.String(), ":")[0])
var targetAddress string = fmt.Sprintf(
ADDRESS_FORMAT,
strings.Split(addr.String(),
":")[0])
commands.RegisterPeer(
targetAddress,
currentHost,
Expand Down
Loading

0 comments on commit 5b677c9

Please sign in to comment.