From f5b3726673f6bae48a2e8265605473801f81530d Mon Sep 17 00:00:00 2001 From: tsousa111 Date: Sun, 28 Apr 2024 17:42:43 +0100 Subject: [PATCH] [PD1] log fixing --- Projs/PD1/internal/client/datastore.go | 1 - Projs/PD1/internal/server/interface.go | 5 ++ Projs/PD1/internal/server/server.go | 5 +- .../internal/utils/cryptoUtils/cryptoUtils.go | 73 +++++++++++-------- Projs/PD1/internal/utils/networking/server.go | 8 +- Projs/PD1/server.go | 24 ++++++ 6 files changed, 79 insertions(+), 37 deletions(-) create mode 100644 Projs/PD1/server.go diff --git a/Projs/PD1/internal/client/datastore.go b/Projs/PD1/internal/client/datastore.go index 55a38ff..a2d115c 100644 --- a/Projs/PD1/internal/client/datastore.go +++ b/Projs/PD1/internal/client/datastore.go @@ -1,7 +1,6 @@ package client import ( - "encoding/json" "log" "time" ) diff --git a/Projs/PD1/internal/server/interface.go b/Projs/PD1/internal/server/interface.go index 40e156f..b2eec56 100644 --- a/Projs/PD1/internal/server/interface.go +++ b/Projs/PD1/internal/server/interface.go @@ -3,6 +3,7 @@ package server import ( "bufio" "fmt" + "log" "os" ) @@ -12,3 +13,7 @@ func readStdin(message string) string { scanner.Scan() return scanner.Text() } + +func LogFatal(err error) { + log.Fatalln(err) +} diff --git a/Projs/PD1/internal/server/server.go b/Projs/PD1/internal/server/server.go index ffd002c..37652b9 100644 --- a/Projs/PD1/internal/server/server.go +++ b/Projs/PD1/internal/server/server.go @@ -90,7 +90,10 @@ func Run(port int) { //Read server keystore password := readStdin("Insert keystore passphrase") - serverKeyStore := cryptoUtils.LoadKeyStore("certs/server/server.p12", password) + serverKeyStore, err := cryptoUtils.LoadKeyStore("certs/server/server.p12", password) + if err != nil { + LogFatal(err) + } //Create server listener server := networking.NewServer[protocol.Packet](&serverKeyStore, port) diff --git a/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go b/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go index ea1ef73..46a2571 100644 --- a/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go +++ b/Projs/PD1/internal/utils/cryptoUtils/cryptoUtils.go @@ -45,32 +45,32 @@ func ExtractAllOIDValues(cert *x509.Certificate) map[string]string { return oidValueMap } -func LoadKeyStore(keyStorePath string, password string) KeyStore { +func LoadKeyStore(keyStorePath string, password string) (KeyStore, error) { var privKey *rsa.PrivateKey keystoreBytes, err := os.ReadFile(keyStorePath) if err != nil { - log.Panicln("Provided keystorePath couldn't be opened") + return KeyStore{}, err } privKeyInterface, cert, caCerts, err := pkcs12.DecodeChain(keystoreBytes, password) if err != nil { - log.Panicln("PKCS12 key store couldn't be decoded") + return KeyStore{}, err } privKey, ok := privKeyInterface.(*rsa.PrivateKey) if !ok { - log.Panicln("Failed to convert private key to RSA private key") + return KeyStore{}, err } if err := privKey.Validate(); err != nil { - log.Panicln("Private key is not valid") + return KeyStore{}, err } - return KeyStore{cert: cert, caCertChain: caCerts, privKey: privKey} + return KeyStore{cert: cert, caCertChain: caCerts, privKey: privKey}, err } // Check if the cert is signed by the CA and is for the correct user -func (k KeyStore) CheckCert(cert *x509.Certificate, uid string) bool { +func (k KeyStore) CheckCert(cert *x509.Certificate, uid string) error { caCertPool := x509.NewCertPool() for _, caCert := range k.caCertChain { caCertPool.AddCert(caCert) @@ -82,16 +82,16 @@ func (k KeyStore) CheckCert(cert *x509.Certificate, uid string) bool { _, err := cert.Verify(opts) if err != nil { log.Println("Certificate not signed by a trusted CA") - return false + return err } //Check if the pseudonym field is set to UID oidMap := ExtractAllOIDValues(cert) if oidMap["2.5.4.65"] != uid { log.Println("Certificate does not belong to the message's receiver") - return false + return err } - return true + return nil } func (k *KeyStore) GetTLSConfig() *tls.Config { @@ -118,9 +118,25 @@ func (k *KeyStore) GetServerTLSConfig() *tls.Config { caCertPool.AddCert(caCert) } tlsConfig.ClientCAs = caCertPool - //FIX: SERVER ACCEPTS CONNECTIONS WITH UNMATCHING OR - // NO CERTIFICATE, NEEDS TO BE CHANGED SOMEHOW - tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert + tlsConfig.ClientAuth = tls.RequireAnyClientCert + 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 + } + // 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") + } + } + return nil + } return tlsConfig } @@ -162,72 +178,67 @@ func (k *KeyStore) GetClientTLSConfig() *tls.Config { return tlsConfig } -func (k KeyStore) EncryptMessageContent(receiverCert *x509.Certificate, content []byte) []byte { +func (k KeyStore) EncryptMessageContent(receiverCert *x509.Certificate, content []byte) ([]byte, error) { // Digital envolope // Create a random symmetric key dataKey := make([]byte, 32) if _, err := rand.Read(dataKey); err != nil { - log.Panicln("Could not create dataKey properly: ", err) + return nil, err } cipher, err := chacha20poly1305.New(dataKey) if err != nil { - log.Panicln("Could not create cipher: ", err) + return nil, err } nonce := make([]byte, cipher.NonceSize(), cipher.NonceSize()+len(content)+cipher.Overhead()) if _, err = rand.Read(nonce); err != nil { - log.Panicln("Could not create data nonce properly: ", err) + return nil, err } // sign the message and append the signature hashedContent := sha256.Sum256(content) - // NOTE: in this case the sign then encrypt method is used - // but should it be used over the encrypt then sign method? signature, err := rsa.SignPKCS1v15(nil, k.privKey, crypto.SHA256, hashedContent[:]) if err != nil { - log.Panicln("Could not create content signature: ", err) + return nil, err } content = pair(signature, content) ciphertext := cipher.Seal(nonce, nonce, content, nil) - // crypto/rand.Reader is a good source of entropy for randomizing the - // encryption function. receiverPubKey := receiverCert.PublicKey.(*rsa.PublicKey) encryptedDataKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, receiverPubKey, dataKey, nil) if err != nil { - log.Panicln("Could not encrypt dataKey: ", err) + return nil, err } - - return pair(encryptedDataKey, ciphertext) + return pair(encryptedDataKey, ciphertext), nil } -func (k KeyStore) DecryptMessageContent(senderCert *x509.Certificate, cipherContent []byte) []byte { +func (k KeyStore) DecryptMessageContent(senderCert *x509.Certificate, cipherContent []byte) ([]byte, error) { encryptedDataKey, encryptedMsg := unPair(cipherContent) dataKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, k.GetPrivKey(), encryptedDataKey, nil) if err != nil { - log.Panicln("Could not decrypt dataKey: ", err) + return nil, err } // decrypt ciphertext cipher, err := chacha20poly1305.New(dataKey) if err != nil { - log.Panicln("Could not create cipher: ", err) + return nil, err } nonce, ciphertext := encryptedMsg[:cipher.NonceSize()], encryptedMsg[cipher.NonceSize():] contentAndSig, err := cipher.Open(nil, nonce, ciphertext, nil) if err != nil { - log.Panicln("Could not decrypt ciphertext: ", err) + return nil, err } // check signature with sender public key signature, content := unPair(contentAndSig) hashedContent := sha256.Sum256(content) senderKey := senderCert.PublicKey.(*rsa.PublicKey) if err := rsa.VerifyPKCS1v15(senderKey, crypto.SHA256, hashedContent[:], signature); err != nil { - log.Panicln("Signature is not valid: ", err) + return nil, err } - return content + return content, nil } func pair(l []byte, r []byte) []byte { diff --git a/Projs/PD1/internal/utils/networking/server.go b/Projs/PD1/internal/utils/networking/server.go index 49f5948..16bf4a7 100644 --- a/Projs/PD1/internal/utils/networking/server.go +++ b/Projs/PD1/internal/utils/networking/server.go @@ -20,7 +20,7 @@ func NewServer[T any](serverTLSConfigProvider ServerTLSConfigProvider, port int) 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") + log.Fatalln("Server could not bind to address") } return Server[T]{ listener: listener, @@ -33,17 +33,17 @@ func (s *Server[T]) ListenLoop() { for { listenerConn, err := s.listener.Accept() if err != nil { - panic("Server could not accept connection") + log.Fatalln("Server could not accept connection") } tlsConn, ok := listenerConn.(*tls.Conn) if !ok { - panic("Connection is not a TLS connection") + log.Fatalln("Connection is not a TLS connection") } tlsConn.Handshake() state := tlsConn.ConnectionState() if len(state.PeerCertificates) == 0 { - log.Panicln("Client did not provide a certificate") + log.Fatalln("Client did not provide a certificate") } conn := NewConnection[T](tlsConn) s.C <- conn diff --git a/Projs/PD1/server.go b/Projs/PD1/server.go new file mode 100644 index 0000000..37ba781 --- /dev/null +++ b/Projs/PD1/server.go @@ -0,0 +1,24 @@ +package main + +import ( + "time" +) + +type Message struct { + sender string + timestamp time.Time + subject string +} + +type User struct { + uid string + queue []Message +} + +type State struct { + +} + +func main() { + +}