From 4cf7880e571b1c3a309884c825ca13261dfbe71a Mon Sep 17 00:00:00 2001 From: afonso Date: Fri, 19 Apr 2024 02:19:22 +0100 Subject: [PATCH] [PD1] FIXED TLS Handshake --- Projs/PD1/internal/server/server.go | 21 +++---- .../internal/utils/cryptoUtils/cryptoUtils.go | 62 +++++++++++++++++-- Projs/PD1/internal/utils/networking/client.go | 6 +- Projs/PD1/internal/utils/networking/server.go | 6 +- Projs/PD1/tokefile.toml | 4 ++ 5 files changed, 77 insertions(+), 22 deletions(-) diff --git a/Projs/PD1/internal/server/server.go b/Projs/PD1/internal/server/server.go index ab637b2..c2b4c19 100644 --- a/Projs/PD1/internal/server/server.go +++ b/Projs/PD1/internal/server/server.go @@ -9,17 +9,16 @@ import ( func clientHandler(connection networking.Connection[protocol.Packet], dataStore DataStore) { defer connection.Conn.Close() - - clientCert := connection.GetPeerCertificate() - oidValueMap := cryptoUtils.ExtractAllOIDValues(clientCert) - fmt.Println(oidValueMap) - + _ = dataStore + clientCert := connection.GetPeerCertificate() + oidValueMap := cryptoUtils.ExtractAllOIDValues(clientCert) + fmt.Println(oidValueMap) for { pac := connection.Receive() switch pac.Flag { case protocol.ReqUserCertPkt: - //userCertPacket := dataStore.GetUserCertificate(uid) + //userCertPacket := dataStore.GetUserCertificate(uid) //connection.Send(userCertPacket) case protocol.ReqAllMsgPkt: fmt.Println("ReqAllMsg") @@ -37,14 +36,14 @@ func Run(port int) { dataStore := OpenDB() defer dataStore.db.Close() - //FIX: Get the server's keystore path instead of hardcoding it + //FIX: Get the server's keystore path instead of hardcoding it - //Read server keystore - password := AskServerPassword() - serverKeyStore := cryptoUtils.LoadKeyStore("certs/server/server.p12",password) + //Read server keystore + password := AskServerPassword() + serverKeyStore := cryptoUtils.LoadKeyStore("certs/server/server.p12", password) //Create server listener - server := networking.NewServer[protocol.Packet](&serverKeyStore,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 e0a0031..58a0fbe 100644 --- a/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go +++ b/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go @@ -8,7 +8,9 @@ import ( "crypto/tls" "crypto/x509" "encoding/binary" - "fmt" + "errors" + + //"errors" "log" "os" @@ -65,7 +67,6 @@ func LoadKeyStore(keyStorePath string, password string) KeyStore { if err := privKey.Validate(); err != nil { log.Panicln("Private key is not valid") } - fmt.Println(cert.SignatureAlgorithm) return KeyStore{cert: cert, caCertChain: caCerts, privKey: privKey} } @@ -80,13 +81,64 @@ func (k *KeyStore) GetTLSConfig() *tls.Config { } config := &tls.Config{ Certificates: []tls.Certificate{certificate}, - ClientCAs: caCertPool, - RootCAs: caCertPool, - ClientAuth: tls.RequireAndVerifyClientCert, } return config } +func (k *KeyStore) GetServerTLSConfig() *tls.Config { + tlsConfig := k.GetTLSConfig() + + //Add the CA certificate chain to a CertPool + caCertPool := x509.NewCertPool() + for _, caCert := range k.caCertChain { + caCertPool.AddCert(caCert) + } + tlsConfig.ClientCAs = caCertPool + //Request one valid or invalid certificate + //FIX: SERVER ACCEPTS CONNECTIONS WITH UNMATCHING OR + // NO CERTIFICATE, NEEDS TO BE CHANGED SOMEHOW + tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert + return tlsConfig +} + +func (k *KeyStore) GetClientTLSConfig() *tls.Config { + tlsConfig := k.GetTLSConfig() + + //Add the CA certificate chain to a CertPool + caCertPool := x509.NewCertPool() + for _, caCert := range k.caCertChain { + caCertPool.AddCert(caCert) + } + tlsConfig.RootCAs = caCertPool + tlsConfig.InsecureSkipVerify = true + tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { + // Verify the peer's certificate + opts := x509.VerifyOptions{ + Roots: caCertPool, + } + for _, certBytes := range rawCerts { + cert, err := x509.ParseCertificate(certBytes) + if err != nil { + return err + } + oidMap := ExtractAllOIDValues(cert) + + // Check if the certificate is signed by the specified CA + _, err = cert.Verify(opts) + if err != nil { + return errors.New("certificate not signed by trusted CA") + } + + //Check if the pseudonym field is set to "SERVER" + if oidMap["2.5.4.65"] != "SERVER"{ + return errors.New("peer isn't the server") + } + } + return nil + } + return tlsConfig +} + func (k KeyStore) EncryptMessageContent(receiverCert *x509.Certificate, content []byte) []byte { // Digital envolope diff --git a/Projs/PD1/internal/utils/networking/client.go b/Projs/PD1/internal/utils/networking/client.go index 49019ef..19ebb05 100644 --- a/Projs/PD1/internal/utils/networking/client.go +++ b/Projs/PD1/internal/utils/networking/client.go @@ -7,7 +7,7 @@ import ( type ClientTLSConfigProvider interface { - GetTLSConfig() *tls.Config + GetClientTLSConfig() *tls.Config } type Client[T any] struct { @@ -15,9 +15,9 @@ type Client[T any] struct { } func NewClient[T any](clientTLSConfigProvider ClientTLSConfigProvider) Client[T] { - dialConn, err := tls.Dial("tcp", "localhost:8080", clientTLSConfigProvider.GetTLSConfig()) + dialConn, err := tls.Dial("tcp", "localhost:8080", clientTLSConfigProvider.GetClientTLSConfig()) if err != nil { - log.Panicln("Could not open connection to server",err) + log.Panicln("Server connection error:\n",err) } conn := NewConnection[T](dialConn) return Client[T]{Connection: conn} diff --git a/Projs/PD1/internal/utils/networking/server.go b/Projs/PD1/internal/utils/networking/server.go index 1bb7dd8..60e9c70 100644 --- a/Projs/PD1/internal/utils/networking/server.go +++ b/Projs/PD1/internal/utils/networking/server.go @@ -8,7 +8,7 @@ import ( ) type ServerTLSConfigProvider interface { - GetTLSConfig() *tls.Config + GetServerTLSConfig() *tls.Config } type Server[T any] struct { @@ -18,7 +18,7 @@ type Server[T any] struct { func NewServer[T any](serverTLSConfigProvider ServerTLSConfigProvider, port int) Server[T] { - listener, err := tls.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port), serverTLSConfigProvider.GetTLSConfig()) + 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") } @@ -39,7 +39,7 @@ func (s *Server[T]) ListenLoop() { if !ok { panic("Connection is not a TLS connection") } - fmt.Println(tlsConn) + tlsConn.Handshake() state := tlsConn.ConnectionState() if len(state.PeerCertificates) == 0 { diff --git a/Projs/PD1/tokefile.toml b/Projs/PD1/tokefile.toml index 3106007..2c6fe08 100644 --- a/Projs/PD1/tokefile.toml +++ b/Projs/PD1/tokefile.toml @@ -17,6 +17,10 @@ cmd="go run ./cmd/server/server.go" deps=["check"] cmd="go run ./cmd/client/client.go -user certs/client1/client1.p12 send CLI1 testsubject" +[targets.FakeClient1] +deps=["check"] +cmd="go run ./cmd/client/client.go -user certs/FakeClient1/client1.p12 send CLI1 testsubject" + [targets.client2] deps=["check"] cmd="go run ./cmd/client/client.go -user certs/client2/client2.p12 send CLI1 testsubject"