[PD1] log fixing
This commit is contained in:
parent
d6b8ed48a6
commit
f5b3726673
6 changed files with 79 additions and 37 deletions
|
@ -1,7 +1,6 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"log"
|
"log"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 {
|
func (k KeyStore) DecryptMessageContent(senderCert *x509.Certificate, cipherContent []byte) ([]byte, error) {
|
||||||
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 {
|
||||||
|
|
|
@ -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
24
Projs/PD1/server.go
Normal 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() {
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue