[PD1] log fixing

This commit is contained in:
Tiago Sousa 2024-04-28 17:42:43 +01:00
parent d6b8ed48a6
commit f5b3726673
Signed by: tiago
SSH key fingerprint: SHA256:rOmjD81ZIhKdCkFWS9UIKdBi4UByF5x3hRH/0YeXsPI
6 changed files with 79 additions and 37 deletions

View file

@ -1,7 +1,6 @@
package client package client
import ( import (
"encoding/json"
"log" "log"
"time" "time"
) )

View file

@ -3,6 +3,7 @@ package server
import ( import (
"bufio" "bufio"
"fmt" "fmt"
"log"
"os" "os"
) )
@ -12,3 +13,7 @@ func readStdin(message string) string {
scanner.Scan() scanner.Scan()
return scanner.Text() return scanner.Text()
} }
func LogFatal(err error) {
log.Fatalln(err)
}

View file

@ -90,7 +90,10 @@ func Run(port int) {
//Read server keystore //Read server keystore
password := readStdin("Insert keystore passphrase") 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 //Create server listener
server := networking.NewServer[protocol.Packet](&serverKeyStore, port) server := networking.NewServer[protocol.Packet](&serverKeyStore, port)

View file

@ -45,32 +45,32 @@ func ExtractAllOIDValues(cert *x509.Certificate) map[string]string {
return oidValueMap return oidValueMap
} }
func LoadKeyStore(keyStorePath string, password string) KeyStore { func LoadKeyStore(keyStorePath string, password string) (KeyStore, error) {
var privKey *rsa.PrivateKey var privKey *rsa.PrivateKey
keystoreBytes, err := os.ReadFile(keyStorePath) keystoreBytes, err := os.ReadFile(keyStorePath)
if err != nil { if err != nil {
log.Panicln("Provided keystorePath couldn't be opened") return KeyStore{}, err
} }
privKeyInterface, cert, caCerts, err := pkcs12.DecodeChain(keystoreBytes, password) privKeyInterface, cert, caCerts, err := pkcs12.DecodeChain(keystoreBytes, password)
if err != nil { if err != nil {
log.Panicln("PKCS12 key store couldn't be decoded") return KeyStore{}, err
} }
privKey, ok := privKeyInterface.(*rsa.PrivateKey) privKey, ok := privKeyInterface.(*rsa.PrivateKey)
if !ok { if !ok {
log.Panicln("Failed to convert private key to RSA private key") return KeyStore{}, err
} }
if err := privKey.Validate(); err != nil { 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 // 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() caCertPool := x509.NewCertPool()
for _, caCert := range k.caCertChain { for _, caCert := range k.caCertChain {
caCertPool.AddCert(caCert) caCertPool.AddCert(caCert)
@ -82,16 +82,16 @@ func (k KeyStore) CheckCert(cert *x509.Certificate, uid string) bool {
_, err := cert.Verify(opts) _, err := cert.Verify(opts)
if err != nil { if err != nil {
log.Println("Certificate not signed by a trusted CA") log.Println("Certificate not signed by a trusted CA")
return false return err
} }
//Check if the pseudonym field is set to UID //Check if the pseudonym field is set to UID
oidMap := ExtractAllOIDValues(cert) oidMap := ExtractAllOIDValues(cert)
if oidMap["2.5.4.65"] != uid { if oidMap["2.5.4.65"] != uid {
log.Println("Certificate does not belong to the message's receiver") 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 { func (k *KeyStore) GetTLSConfig() *tls.Config {
@ -118,9 +118,25 @@ func (k *KeyStore) GetServerTLSConfig() *tls.Config {
caCertPool.AddCert(caCert) caCertPool.AddCert(caCert)
} }
tlsConfig.ClientCAs = caCertPool tlsConfig.ClientCAs = caCertPool
//FIX: SERVER ACCEPTS CONNECTIONS WITH UNMATCHING OR tlsConfig.ClientAuth = tls.RequireAnyClientCert
// NO CERTIFICATE, NEEDS TO BE CHANGED SOMEHOW tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error {
tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert // 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 return tlsConfig
} }
@ -162,72 +178,67 @@ func (k *KeyStore) GetClientTLSConfig() *tls.Config {
return tlsConfig 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 // Digital envolope
// Create a random symmetric key // Create a random symmetric key
dataKey := make([]byte, 32) dataKey := make([]byte, 32)
if _, err := rand.Read(dataKey); err != nil { if _, err := rand.Read(dataKey); err != nil {
log.Panicln("Could not create dataKey properly: ", err) return nil, err
} }
cipher, err := chacha20poly1305.New(dataKey) cipher, err := chacha20poly1305.New(dataKey)
if err != nil { if err != nil {
log.Panicln("Could not create cipher: ", err) return nil, err
} }
nonce := make([]byte, cipher.NonceSize(), cipher.NonceSize()+len(content)+cipher.Overhead()) nonce := make([]byte, cipher.NonceSize(), cipher.NonceSize()+len(content)+cipher.Overhead())
if _, err = rand.Read(nonce); err != nil { 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 // sign the message and append the signature
hashedContent := sha256.Sum256(content) 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[:]) signature, err := rsa.SignPKCS1v15(nil, k.privKey, crypto.SHA256, hashedContent[:])
if err != nil { if err != nil {
log.Panicln("Could not create content signature: ", err) return nil, err
} }
content = pair(signature, content) content = pair(signature, content)
ciphertext := cipher.Seal(nonce, nonce, content, nil) 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) receiverPubKey := receiverCert.PublicKey.(*rsa.PublicKey)
encryptedDataKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, receiverPubKey, dataKey, nil) encryptedDataKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, receiverPubKey, dataKey, nil)
if err != nil { if err != nil {
log.Panicln("Could not encrypt dataKey: ", err) return nil, err
}
return pair(encryptedDataKey, ciphertext), nil
} }
return pair(encryptedDataKey, ciphertext) func (k KeyStore) DecryptMessageContent(senderCert *x509.Certificate, cipherContent []byte) ([]byte, error) {
}
func (k KeyStore) DecryptMessageContent(senderCert *x509.Certificate, cipherContent []byte) []byte {
encryptedDataKey, encryptedMsg := unPair(cipherContent) encryptedDataKey, encryptedMsg := unPair(cipherContent)
dataKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, k.GetPrivKey(), encryptedDataKey, nil) dataKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, k.GetPrivKey(), encryptedDataKey, nil)
if err != nil { if err != nil {
log.Panicln("Could not decrypt dataKey: ", err) return nil, err
} }
// decrypt ciphertext // decrypt ciphertext
cipher, err := chacha20poly1305.New(dataKey) cipher, err := chacha20poly1305.New(dataKey)
if err != nil { if err != nil {
log.Panicln("Could not create cipher: ", err) return nil, err
} }
nonce, ciphertext := encryptedMsg[:cipher.NonceSize()], encryptedMsg[cipher.NonceSize():] nonce, ciphertext := encryptedMsg[:cipher.NonceSize()], encryptedMsg[cipher.NonceSize():]
contentAndSig, err := cipher.Open(nil, nonce, ciphertext, nil) contentAndSig, err := cipher.Open(nil, nonce, ciphertext, nil)
if err != nil { if err != nil {
log.Panicln("Could not decrypt ciphertext: ", err) return nil, err
} }
// check signature with sender public key // check signature with sender public key
signature, content := unPair(contentAndSig) signature, content := unPair(contentAndSig)
hashedContent := sha256.Sum256(content) hashedContent := sha256.Sum256(content)
senderKey := senderCert.PublicKey.(*rsa.PublicKey) senderKey := senderCert.PublicKey.(*rsa.PublicKey)
if err := rsa.VerifyPKCS1v15(senderKey, crypto.SHA256, hashedContent[:], signature); err != nil { 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 { func pair(l []byte, r []byte) []byte {

View file

@ -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()) listener, err := tls.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", port), serverTLSConfigProvider.GetServerTLSConfig())
if err != nil { if err != nil {
panic("Server could not bind to address") log.Fatalln("Server could not bind to address")
} }
return Server[T]{ return Server[T]{
listener: listener, listener: listener,
@ -33,17 +33,17 @@ func (s *Server[T]) ListenLoop() {
for { for {
listenerConn, err := s.listener.Accept() listenerConn, err := s.listener.Accept()
if err != nil { if err != nil {
panic("Server could not accept connection") log.Fatalln("Server could not accept connection")
} }
tlsConn, ok := listenerConn.(*tls.Conn) tlsConn, ok := listenerConn.(*tls.Conn)
if !ok { if !ok {
panic("Connection is not a TLS connection") log.Fatalln("Connection is not a TLS connection")
} }
tlsConn.Handshake() tlsConn.Handshake()
state := tlsConn.ConnectionState() state := tlsConn.ConnectionState()
if len(state.PeerCertificates) == 0 { 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) conn := NewConnection[T](tlsConn)
s.C <- conn s.C <- conn

24
Projs/PD1/server.go Normal file
View file

@ -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() {
}