diff --git a/Projs/PD1/internal/client/client.go b/Projs/PD1/internal/client/client.go
index 0f7dccb..4268ca5 100644
--- a/Projs/PD1/internal/client/client.go
+++ b/Projs/PD1/internal/client/client.go
@@ -2,6 +2,7 @@ package client
 
 import (
 	"PD1/internal/protocol"
+	"PD1/internal/utils/cryptoUtils"
 	"PD1/internal/utils/networking"
 	"flag"
 	"fmt"
@@ -24,16 +25,19 @@ func Run() {
 		}
 		uid := flag.Arg(1)
 		subject := flag.Arg(2)
-		// Read message content from stdin
         messageContent := readMessageContent()
-        cl := networking.NewClient[protocol.Packet]()
+
+        clientCert := cryptoUtils.LoadKeyStore("userdata.p12")
+
+        cl := networking.NewClient[protocol.Packet](clientCert)
 	    defer cl.Connection.Conn.Close()
-        // TODO: getuserinfo client cert
-        // TODO: ask server for the recieving client's cert
+
+
         certRequestPacket := protocol.NewRequestUserCertPacket(uid)
         cl.Connection.Send(certRequestPacket)
         certPacket := cl.Connection.Receive()
-        // TODO: cipherContent := cryptoUtils.encryptMessageContent()
+
+        // TODO: Encrypt message
         submitMessage(cl,uid,cipherContent)
 
 	case "askqueue":
@@ -52,7 +56,7 @@ func Run() {
         showHelp()
 
 	default:
-		fmt.Println("Invalid command. Use 'help' for instructions.")
+        commandError() 
 	}
 
 }
diff --git a/Projs/PD1/internal/client/interface.go b/Projs/PD1/internal/client/interface.go
index 490a1dd..0e48357 100644
--- a/Projs/PD1/internal/client/interface.go
+++ b/Projs/PD1/internal/client/interface.go
@@ -14,6 +14,9 @@ func readMessageContent() string {
 	return scanner.Text()
 }
 
+//FIX: Why is this function in the client if it's called by crypto?
+// It should be called by the client and the result
+// should then be passed into the crypto library
 func AskUserPassword() string {
 	fmt.Println("Enter message content (limited to 1000 bytes):")
 	scanner := bufio.NewScanner(os.Stdin)
@@ -22,6 +25,12 @@ func AskUserPassword() string {
 	return scanner.Text()
 }
 
+func commandError() {
+    fmt.Println("MSG SERVICE: command error!")
+    showHelp()
+}
+
+
 func showHelp() {
 	fmt.Println("Comandos da aplicação cliente:")
 	fmt.Println("-user <FNAME>: Especifica o ficheiro com dados do utilizador. Por omissão, será assumido que esse ficheiro é userdata.p12.")
diff --git a/Projs/PD1/internal/server/server.go b/Projs/PD1/internal/server/server.go
index fcd2073..046b7a3 100644
--- a/Projs/PD1/internal/server/server.go
+++ b/Projs/PD1/internal/server/server.go
@@ -2,6 +2,7 @@ package server
 
 import (
 	"PD1/internal/protocol"
+	"PD1/internal/utils/cryptoUtils"
 	"PD1/internal/utils/networking"
 	"fmt"
 )
@@ -34,8 +35,13 @@ func Run(port int) {
 	dataStore := OpenDB()
 	defer dataStore.db.Close()
 
+    //TODO: Get the server's keystore path instead of hardcoding it
+
+    //Read server keystore
+    serverKeyStore := cryptoUtils.LoadKeyStore("serverdata.p12")
+
 	//Create server listener
-	server := networking.NewServer[protocol.Packet](port)
+	server := networking.NewServer[protocol.Packet](serverKeyStore,port)
 	go server.ListenLoop()
 
 	for {
diff --git a/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go b/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go
index f6dcf07..ce91c51 100644
--- a/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go
+++ b/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go
@@ -2,31 +2,41 @@ package cryptoUtils
 
 import (
 	"PD1/internal/client"
-	"PD1/internal/protocol"
 	"crypto/rsa"
+	"crypto/tls"
 	"crypto/x509"
-	"fmt"
+	"encoding/pem"
 	"log"
 	"os"
 
 	"software.sslmate.com/src/go-pkcs12"
 )
 
-func Print() {
-	fmt.Println("crypto package")
+type KeyStore struct {
+	cert        *x509.Certificate
+	caCertChain []*x509.Certificate
+	privKey     rsa.PrivateKey
 }
 
-func getUserInfo(certFilename string) (
-	rsa.PrivateKey,
-	*x509.Certificate,
-	[]*x509.Certificate,
-	error) {
+func (k KeyStore) GetCert() *x509.Certificate {
+	return k.cert
+}
+
+func (k KeyStore) GetCACertChain() []*x509.Certificate {
+	return k.caCertChain
+}
+
+func (k KeyStore) GetPrivKey() rsa.PrivateKey {
+	return k.privKey
+}
+
+func LoadKeyStore(keyStorePath string) KeyStore {
+
 	var privKey rsa.PrivateKey
 
-	certFile, err := os.ReadFile(certFilename)
+	certFile, err := os.ReadFile(keyStorePath)
 	if err != nil {
-		log.Panicln("Provided certificate %v couldn't be opened", certFilename)
-		return rsa.PrivateKey{}, nil, nil, err
+		log.Panicln("Provided certificate %v couldn't be opened", keyStorePath)
 	}
 
 	password := client.AskUserPassword()
@@ -34,16 +44,49 @@ func getUserInfo(certFilename string) (
 	privKey = privKeyInterface.(rsa.PrivateKey)
 	if err != nil {
 		log.Panicln("PKCS12 key store couldn't be decoded")
-		return rsa.PrivateKey{}, nil, nil, err
 	}
 	if err := privKey.Validate(); err != nil {
 		log.Panicln("Private key is not valid")
-		return rsa.PrivateKey{}, nil, nil, err
 	}
-	return privKey, cert, caCerts, nil
+	return KeyStore{cert: cert, caCertChain: caCerts, privKey: privKey}
 }
 
-func encryptMessageContent(privKey rsa.PrivateKey, peerPubKey rsa.PublicKey, content []byte) []byte {
+func (k KeyStore)GetTLSConfig() *tls.Config {
+    certificate ,err := tls.X509KeyPair(k.cert.Raw, pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(&k.privKey)}))
+    if err!=nil{
+        log.Panicln("Could not load certificate and privkey to TLS")
+    }
+    
+    //Add the CA certificate chain to a CertPool
+    caCertPool := x509.NewCertPool()
+	for _, caCert := range k.caCertChain {
+		caCertPool.AddCert(caCert)
+	}
+
+    config := &tls.Config{
+		Certificates: []tls.Certificate{certificate},
+		ClientCAs:    caCertPool,
+	}
+    return config
+}
+
+func (k KeyStore)GetTLSConfigServer() *tls.Config {
+	config := k.GetTLSConfig()
+
+	config.ClientAuth = tls.RequireAndVerifyClientCert
+
+	return config
+}
+
+func (k KeyStore)GetTLSConfigClient() *tls.Config {
+	config:= k.GetTLSConfig()
+
+	config.ServerName = "SERVER"
+
+	return config
+}
+
+func (k KeyStore)EncryptMessageContent(peerPubKey rsa.PublicKey, content []byte) []byte {
 	// Digital envolope
-
+    return nil
 }
diff --git a/Projs/PD1/internal/utils/networking/client.go b/Projs/PD1/internal/utils/networking/client.go
index d9d8a58..292c13a 100644
--- a/Projs/PD1/internal/utils/networking/client.go
+++ b/Projs/PD1/internal/utils/networking/client.go
@@ -1,13 +1,21 @@
 package networking
 
-import "net"
+import (
+	"crypto/tls"
+	"net"
+)
+
+
+type ClientTLSConfigProvider interface {
+    GetTLSConfigClient() *tls.Config
+}
 
 type Client[T any] struct {
 	Connection Connection[T]
 }
 
-func NewClient[T any]() Client[T] {
-	dialConn, err := net.Dial("tcp", "localhost:8080")
+func NewClient[T any](clientTLSConfigProvider ClientTLSConfigProvider) Client[T] {
+    dialConn, err := tls.Dial("tcp", "localhost:8080", clientTLSConfigProvider.GetTLSConfigClient())
 	if err != nil {
 		panic("Could not open connection to server")
 	}
diff --git a/Projs/PD1/internal/utils/networking/server.go b/Projs/PD1/internal/utils/networking/server.go
index 38e5d1c..0d86cdd 100644
--- a/Projs/PD1/internal/utils/networking/server.go
+++ b/Projs/PD1/internal/utils/networking/server.go
@@ -1,18 +1,23 @@
 package networking
 
 import (
+	"crypto/tls"
 	"fmt"
 	"net"
 )
 
+type ServerTLSConfigProvider interface {
+    GetServerTLSConfig() *tls.Config
+}
+
 type Server[T any] struct {
 	listener net.Listener
 	C        chan Connection[T]
 }
 
-func NewServer[T any](port int) Server[T]{
+func NewServer[T any](serverTLSConfigProvider ServerTLSConfigProvider,port int) Server[T]{
 
-    listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port))
+    listener, err := tls.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port), serverTLSConfigProvider.GetServerTLSConfig())
 	if err != nil {
 		panic("Server could not bind to address")
 	}