2024-05-28 20:08:25 +01:00
|
|
|
package gateway
|
|
|
|
|
2024-05-29 17:33:36 +01:00
|
|
|
import (
|
|
|
|
"PD1/internal/protocol"
|
2024-05-30 00:54:19 +01:00
|
|
|
"PD1/internal/utils/cryptoUtils"
|
|
|
|
"crypto/x509"
|
2024-05-29 17:33:36 +01:00
|
|
|
"fmt"
|
2024-05-30 00:54:19 +01:00
|
|
|
"log"
|
2024-05-29 17:33:36 +01:00
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
|
|
|
|
2024-05-30 00:54:19 +01:00
|
|
|
func HandleGetMessage(c *gin.Context) {
|
|
|
|
fmt.Println("Get Message Handler")
|
2024-05-29 17:33:36 +01:00
|
|
|
|
|
|
|
}
|
2024-05-30 00:54:19 +01:00
|
|
|
func HandleGetUnreadMsgsInfo(c *gin.Context) {
|
|
|
|
fmt.Println("Get Unread Messages Info Handler")
|
2024-05-29 17:33:36 +01:00
|
|
|
|
|
|
|
}
|
2024-05-30 00:54:19 +01:00
|
|
|
func HandleGetUserCert(c *gin.Context) {
|
|
|
|
fmt.Println("Get User Cert Handler")
|
2024-05-29 17:33:36 +01:00
|
|
|
|
|
|
|
}
|
2024-05-30 00:54:19 +01:00
|
|
|
func HandleSendMessage(c *gin.Context) {
|
|
|
|
fmt.Println("Send Message Handler")
|
2024-05-29 17:33:36 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-05-30 00:54:19 +01:00
|
|
|
func HandleRegister(c *gin.Context, dataStore DataStore, keyStore cryptoUtils.KeyStore) {
|
|
|
|
var postRegister protocol.PostRegister
|
|
|
|
err := c.Bind(postRegister)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest,gin.H{"error": "Request body is not a PostRegister"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
//Check if the certificate pseudonym matches the uid in postRegister
|
|
|
|
//And if it's signed by the CA
|
|
|
|
userCert, err := x509.ParseCertificate(postRegister.Certificate)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest,gin.H{"error": "User certificate is invalid"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
oidMap := cryptoUtils.ExtractAllOIDValues(userCert)
|
|
|
|
//Check if certificate usage is MSG SERVICE
|
|
|
|
usage := oidMap["2.5.4.11"]
|
|
|
|
if usage != "MSG SERVICE" {
|
|
|
|
c.JSON(http.StatusBadRequest,gin.H{"error": "Certificate usage is not \"MSG SERVICE\""})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
err = keyStore.CheckCert(userCert, postRegister.UID)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest,gin.H{"error": "User certificate is invalid, not trusted or belongs to another user"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
hashedPassword, err := HashPassword(postRegister.Password)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Could not hash the password")
|
|
|
|
}
|
|
|
|
|
|
|
|
err = dataStore.InsertUser(postRegister.UID, hashedPassword)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Could not insert user into DB")
|
|
|
|
}
|
|
|
|
|
|
|
|
//TODO: Send the certificate to the server
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{})
|
|
|
|
|
2024-05-29 17:33:36 +01:00
|
|
|
}
|
|
|
|
|
2024-05-30 00:54:19 +01:00
|
|
|
func HandleLogin(c *gin.Context, dataStore DataStore, keyStore cryptoUtils.KeyStore) {
|
|
|
|
var postLogin protocol.PostLogin
|
|
|
|
err := c.Bind(postLogin)
|
|
|
|
if err != nil {
|
|
|
|
c.AbortWithStatus(http.StatusBadRequest)
|
|
|
|
}
|
|
|
|
|
|
|
|
hashedPassword, err := dataStore.GetPassword(postLogin.UID)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user id or password"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
err = CheckPassword(hashedPassword, postLogin.Password)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user id or password"})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
jwToken, err := GenerateJWT(postLogin.UID)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to create token"})
|
|
|
|
}
|
|
|
|
//Send token to user
|
|
|
|
c.JSON(http.StatusOK, gin.H{"token":jwToken})
|
2024-05-29 17:33:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-05-30 00:54:19 +01:00
|
|
|
func AuthMiddleware(c *gin.Context) {
|
|
|
|
fmt.Println("Authentication Middleware")
|
|
|
|
tokenList := c.Request.Header["Token"]
|
|
|
|
if tokenList == nil {
|
|
|
|
c.JSON(http.StatusUnauthorized,gin.H{"error": "No authentication token provided"})
|
|
|
|
}
|
|
|
|
// We only care about the first entry
|
|
|
|
token := tokenList[0]
|
|
|
|
|
|
|
|
uid, err := ValidateJWT(token)
|
|
|
|
if err!= nil {
|
|
|
|
c.JSON(http.StatusUnauthorized,gin.H{"error": "Token is invalid or has expired"})
|
|
|
|
}
|
|
|
|
c.Set("uid", uid)
|
|
|
|
c.Next()
|
|
|
|
}
|
|
|
|
|
|
|
|
func Run() {
|
|
|
|
dataStore, err := OpenDB()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln("Error opening the database")
|
|
|
|
}
|
|
|
|
defer dataStore.db.Close()
|
|
|
|
|
|
|
|
passphrase := readStdin("Insert keystore passphrase")
|
|
|
|
keyStore, err := cryptoUtils.LoadKeyStore("certs/gateway/gateway.p12", passphrase)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalln(err.Error())
|
|
|
|
}
|
|
|
|
|
|
|
|
router := gin.Default()
|
|
|
|
|
|
|
|
auth := router.Group("/", func(c *gin.Context) {
|
|
|
|
AuthMiddleware(c)
|
|
|
|
})
|
2024-05-29 17:33:36 +01:00
|
|
|
|
|
|
|
auth.GET("/message/:num", func(c *gin.Context) {
|
|
|
|
HandleGetMessage(c)
|
|
|
|
})
|
|
|
|
|
|
|
|
auth.GET("/queue", func(c *gin.Context) {
|
|
|
|
HandleGetUnreadMsgsInfo(c)
|
|
|
|
})
|
|
|
|
|
|
|
|
auth.GET("/cert/:user", func(c *gin.Context) {
|
|
|
|
HandleGetUserCert(c)
|
|
|
|
})
|
|
|
|
|
|
|
|
auth.POST("/message", func(c *gin.Context) {
|
|
|
|
HandleSendMessage(c)
|
|
|
|
})
|
|
|
|
|
2024-05-30 00:54:19 +01:00
|
|
|
router.POST("/register", func(c *gin.Context) {
|
|
|
|
HandleRegister(c, dataStore, keyStore)
|
|
|
|
})
|
|
|
|
|
|
|
|
router.POST("/login", func(c *gin.Context) {
|
|
|
|
HandleLogin(c, dataStore, keyStore)
|
|
|
|
})
|
2024-05-29 17:33:36 +01:00
|
|
|
|
|
|
|
server := http.Server{
|
|
|
|
Addr: "0.0.0.0:8080",
|
|
|
|
Handler: router,
|
|
|
|
TLSConfig: serverKeyStore.GetServerTLSConfig(),
|
|
|
|
}
|
2024-05-28 20:08:25 +01:00
|
|
|
|
2024-05-30 00:54:19 +01:00
|
|
|
err := server.ListenAndServeTLS("", "")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err.Error())
|
|
|
|
}
|
2024-05-28 20:08:25 +01:00
|
|
|
}
|