From a5e479cc0c5c85420cc325c839289209819c9459 Mon Sep 17 00:00:00 2001 From: greysoh Date: Sun, 20 Oct 2024 12:13:23 -0400 Subject: [PATCH] chore: Seperate code into multiple files for client and server. --- client/client.go | 100 ----------------------------------------------- client/typing.go | 46 ++++++++++++++++++++++ client/utils.go | 68 ++++++++++++++++++++++++++++++++ commons/enum.go | 30 +++++++++----- server/server.go | 79 ------------------------------------- server/typing.go | 26 ++++++++++++ server/utils.go | 69 ++++++++++++++++++++++++++++++++ 7 files changed, 230 insertions(+), 188 deletions(-) create mode 100644 client/typing.go create mode 100644 client/utils.go create mode 100644 server/typing.go create mode 100644 server/utils.go diff --git a/client/client.go b/client/client.go index f6601aa..d3f26d3 100644 --- a/client/client.go +++ b/client/client.go @@ -1,8 +1,6 @@ package client import ( - "crypto/cipher" - "crypto/rand" "fmt" "net" @@ -12,74 +10,6 @@ import ( "github.com/ProtonMail/gopenpgp/v3/crypto" ) -func (bismuth BismuthClient) encryptMessage(aead cipher.AEAD, msg []byte) ([]byte, error) { - nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead()) - - if _, err := rand.Read(nonce); err != nil { - return []byte{}, err - } - - encryptedMsg := aead.Seal(nonce, nonce, msg, nil) - return encryptedMsg, nil -} - -func (bismuth BismuthClient) decryptMessage(aead cipher.AEAD, encMsg []byte) ([]byte, error) { - if len(encMsg) < aead.NonceSize() { - return []byte{}, fmt.Errorf("ciphertext too short") - } - - // Split nonce and ciphertext. - nonce, ciphertext := encMsg[:aead.NonceSize()], encMsg[aead.NonceSize():] - - // Decrypt the message and check it wasn't tampered with. - decryptedData, err := aead.Open(nil, nonce, ciphertext, nil) - - if err != nil { - return []byte{}, err - } - - return decryptedData, nil -} - -// Checks to see if a certificate is trusted in the client cache. -// -// - `host`: The host of the server. -// - `certificateFingerprint`: A fingerprint of the servers key. -// - `isSelfSigned`: If true, the certificate is either actually self-signed, or -// verification is dsabled (CheckIfCertificatesAreSigned in BismuthClient is false) -// - `isTrustworthy`: If true, the certificate is signed by 51% of peers. -type CertCheckCallback func(host, certificateFingerprint string, isSelfSigned, isTrustworthy bool) bool - -// Connects to a server using a provided method, with host being the host: -// -// OwnConnMethodCallback("google.com:80") -type OwnConnMethodCallback func(address string) (net.Conn, error) - -// Bismuth Client -type BismuthClient struct { - // GOpenPGP public key - PublicKey *crypto.Key - // GOpenPGP private key - PrivateKey *crypto.Key - - // Check if the certificates are signed if enabled. - // - // If true, "cross-verifies" the server to make sure the certificates are signed. - // - // If false, all certificates will be reported as being self signed because we can't - // really prove otherwise. - CheckIfCertificatesAreSigned bool - // Checks to see if a certificate is trusted in the client cache. - // See CertCheckCallback for more typing information. - CertificateSignChecker CertCheckCallback - - // Connects to a server (used for CheckIfCertificatesAreSigned if enabled/set to true). - ConnectToServer OwnConnMethodCallback - - // GopenPGP instance - pgp *crypto.PGPHandle -} - // Initializes the client. Should be done automatically if you call New() // // If you don't call client.New(), you *MUST* call this function before running bismuth.Conn(). @@ -240,33 +170,3 @@ func (bismuth BismuthClient) Conn(conn net.Conn) (net.Conn, error) { Bismuth: &bmConn, }, nil } - -// Creates a new BismuthClient. -// -// Both `pubKey` and `privKey` are armored PGP public and private keys respectively. -func New(pubKey string, privKey string) (*BismuthClient, error) { - publicKey, err := crypto.NewKeyFromArmored(pubKey) - - if err != nil { - return nil, err - } - - privateKey, err := crypto.NewKeyFromArmored(privKey) - - if err != nil { - return nil, err - } - - bismuth := BismuthClient{ - PublicKey: publicKey, - PrivateKey: privateKey, - } - - err = bismuth.InitializeClient() - - if err != nil { - return nil, err - } - - return &bismuth, nil -} diff --git a/client/typing.go b/client/typing.go new file mode 100644 index 0000000..de537ec --- /dev/null +++ b/client/typing.go @@ -0,0 +1,46 @@ +package client + +import ( + "net" + + "github.com/ProtonMail/gopenpgp/v3/crypto" +) + +// Checks to see if a certificate is trusted in the client cache. +// +// - `host`: The host of the server. +// - `certificateFingerprint`: A fingerprint of the servers key. +// - `isSelfSigned`: If true, the certificate is either actually self-signed, or +// verification is dsabled (CheckIfCertificatesAreSigned in BismuthClient is false) +// - `isTrustworthy`: If true, the certificate is signed by 51% of peers. +type CertCheckCallback func(host, certificateFingerprint string, isSelfSigned, isTrustworthy bool) bool + +// Connects to a server using a provided method, with host being the host: +// +// OwnConnMethodCallback("google.com:80") +type OwnConnMethodCallback func(address string) (net.Conn, error) + +// Bismuth Client +type BismuthClient struct { + // GOpenPGP public key + PublicKey *crypto.Key + // GOpenPGP private key + PrivateKey *crypto.Key + + // Check if the certificates are signed if enabled. + // + // If true, "cross-verifies" the server to make sure the certificates are signed. + // + // If false, all certificates will be reported as being self signed because we can't + // really prove otherwise. + CheckIfCertificatesAreSigned bool + // Checks to see if a certificate is trusted in the client cache. + // See CertCheckCallback for more typing information. + CertificateSignChecker CertCheckCallback + + // Connects to a server (used for CheckIfCertificatesAreSigned if enabled/set to true). + ConnectToServer OwnConnMethodCallback + + // GopenPGP instance + pgp *crypto.PGPHandle +} diff --git a/client/utils.go b/client/utils.go new file mode 100644 index 0000000..dc236f5 --- /dev/null +++ b/client/utils.go @@ -0,0 +1,68 @@ +package client + +import ( + "crypto/cipher" + "crypto/rand" + "fmt" + + "github.com/ProtonMail/gopenpgp/v3/crypto" +) + +func (bismuth BismuthClient) encryptMessage(aead cipher.AEAD, msg []byte) ([]byte, error) { + nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead()) + + if _, err := rand.Read(nonce); err != nil { + return []byte{}, err + } + + encryptedMsg := aead.Seal(nonce, nonce, msg, nil) + return encryptedMsg, nil +} + +func (bismuth BismuthClient) decryptMessage(aead cipher.AEAD, encMsg []byte) ([]byte, error) { + if len(encMsg) < aead.NonceSize() { + return []byte{}, fmt.Errorf("ciphertext too short") + } + + // Split nonce and ciphertext. + nonce, ciphertext := encMsg[:aead.NonceSize()], encMsg[aead.NonceSize():] + + // Decrypt the message and check it wasn't tampered with. + decryptedData, err := aead.Open(nil, nonce, ciphertext, nil) + + if err != nil { + return []byte{}, err + } + + return decryptedData, nil +} + +// Creates a new BismuthClient. +// +// Both `pubKey` and `privKey` are armored PGP public and private keys respectively. +func New(pubKey string, privKey string) (*BismuthClient, error) { + publicKey, err := crypto.NewKeyFromArmored(pubKey) + + if err != nil { + return nil, err + } + + privateKey, err := crypto.NewKeyFromArmored(privKey) + + if err != nil { + return nil, err + } + + bismuth := BismuthClient{ + PublicKey: publicKey, + PrivateKey: privateKey, + } + + err = bismuth.InitializeClient() + + if err != nil { + return nil, err + } + + return &bismuth, nil +} diff --git a/commons/enum.go b/commons/enum.go index be1848f..9e78c88 100644 --- a/commons/enum.go +++ b/commons/enum.go @@ -2,32 +2,44 @@ package commons -// Commands +// Core Protocol Commands const ( - // SendPublicKey: Sending public key back and forth + // Sending public key back and forth SendPublicKey = iota - // SwitchToSymmetricKey: Sent by the client along with the symmetric key that is going to be used + // Sent by the client along with the symmetric key that is going to be used SwitchToSymmetricKey - // ClientSendHost: Currently unimplemented. // Client sends what host they are connecting to. + // Currently unimplemented. ClientSendHost - // GetSigningServers: Currently unimplemented. // Gets the signing servers trusting/signing the current server. + // Currently unimplemented. GetSigningServers - // GetTrustedDomains: Currently unimplemented. // Gets the domains that are supported by this certificate (should be cross-checked) + // Currently unimplemented. GetTrustedDomains - // InitiateForwarding: Starts forwarding traffic over this protocol. + // Starts forwarding traffic over this protocol. InitiateForwarding ) -// Encryption algorithms +// Validation API Commands +const ( + // Checks if the domains are valid for a specified key + AreDomainsValidForKey = iota + // Validate a server and keys + ValidateKey + // Status codes + Success + Failure + InternalError +) + +// Encryption Algorithms const ( // Default and only encryption algorithm XChaCha20Poly1305 = iota ) -// Unsigned integer limits +// Unsigned Integer Limits const ( BitLimit24 = 16_777_215 BitLimit16 = 65535 diff --git a/server/server.go b/server/server.go index 4e1c183..b211f6e 100644 --- a/server/server.go +++ b/server/server.go @@ -1,7 +1,6 @@ package server import ( - "fmt" "net" core "git.greysoh.dev/imterah/bismuthd/commons" @@ -13,54 +12,6 @@ import ( "golang.org/x/crypto/chacha20poly1305" ) -// Bismuth Server -type BismuthServer struct { - // Public key to use for transmission - PublicKey *crypto.Key - // Private key to use for transmission - PrivateKey *crypto.Key - - pgp *crypto.PGPHandle - - // Algorithm to use for encryption (currently XChaCha20Poly1305 is the only option) - SymmetricEncryptionAlgorithm int - // Servers that are signing this server. If none, this server becomes self-signed - // in the clients eyes - SigningServers []string - - // Called after a successful handshake & connection. - HandleConnection func(conn net.Conn) error -} - -func (bismuth BismuthServer) encryptMessage(aead cipher.AEAD, msg []byte) ([]byte, error) { - nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead()) - - if _, err := rand.Read(nonce); err != nil { - return []byte{}, err - } - - encryptedMsg := aead.Seal(nonce, nonce, msg, nil) - return encryptedMsg, nil -} - -func (bismuth BismuthServer) decryptMessage(aead cipher.AEAD, encMsg []byte) ([]byte, error) { - if len(encMsg) < aead.NonceSize() { - return []byte{}, fmt.Errorf("ciphertext too short") - } - - // Split nonce and ciphertext. - nonce, ciphertext := encMsg[:aead.NonceSize()], encMsg[aead.NonceSize():] - - // Decrypt the message and check it wasn't tampered with. - decryptedData, err := aead.Open(nil, nonce, ciphertext, nil) - - if err != nil { - return []byte{}, err - } - - return decryptedData, nil -} - // Called to handle a connnection for Bismuth. The conn argument is the client you'd like to handle func (bismuth BismuthServer) HandleProxy(conn net.Conn) error { serverState := "keyHandshake" @@ -229,33 +180,3 @@ func (bismuth BismuthServer) HandleProxy(conn net.Conn) error { } } } - -// Initializes a Bismuth server. -// -// Both `pubKey` and `privKey` are armored PGP public and private keys respectively. -func NewBismuthServer(pubKey string, privKey string, signServers []string, encryptionAlgo int, connHandler func(conn net.Conn) error) (*BismuthServer, error) { - publicKey, err := crypto.NewKeyFromArmored(pubKey) - - if err != nil { - return nil, err - } - - privateKey, err := crypto.NewKeyFromArmored(privKey) - - if err != nil { - return nil, err - } - - pgp := crypto.PGP() - - bismuth := BismuthServer{ - PublicKey: publicKey, - PrivateKey: privateKey, - HandleConnection: connHandler, - SigningServers: signServers, - SymmetricEncryptionAlgorithm: encryptionAlgo, - pgp: pgp, - } - - return &bismuth, nil -} diff --git a/server/typing.go b/server/typing.go new file mode 100644 index 0000000..9f830c3 --- /dev/null +++ b/server/typing.go @@ -0,0 +1,26 @@ +package server + +import ( + "net" + + "github.com/ProtonMail/gopenpgp/v3/crypto" +) + +// Bismuth Server +type BismuthServer struct { + // Public key to use for transmission + PublicKey *crypto.Key + // Private key to use for transmission + PrivateKey *crypto.Key + + pgp *crypto.PGPHandle + + // Algorithm to use for encryption (currently XChaCha20Poly1305 is the only option) + SymmetricEncryptionAlgorithm int + // Servers that are signing this server. If none, this server becomes self-signed + // in the clients eyes + SigningServers []string + + // Called after a successful handshake & connection. + HandleConnection func(conn net.Conn) error +} diff --git a/server/utils.go b/server/utils.go new file mode 100644 index 0000000..3016844 --- /dev/null +++ b/server/utils.go @@ -0,0 +1,69 @@ +package server + +import ( + "crypto/cipher" + "crypto/rand" + "fmt" + "net" + + "github.com/ProtonMail/gopenpgp/v3/crypto" +) + +func (bismuth BismuthServer) encryptMessage(aead cipher.AEAD, msg []byte) ([]byte, error) { + nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead()) + + if _, err := rand.Read(nonce); err != nil { + return []byte{}, err + } + + encryptedMsg := aead.Seal(nonce, nonce, msg, nil) + return encryptedMsg, nil +} + +func (bismuth BismuthServer) decryptMessage(aead cipher.AEAD, encMsg []byte) ([]byte, error) { + if len(encMsg) < aead.NonceSize() { + return []byte{}, fmt.Errorf("ciphertext too short") + } + + // Split nonce and ciphertext. + nonce, ciphertext := encMsg[:aead.NonceSize()], encMsg[aead.NonceSize():] + + // Decrypt the message and check it wasn't tampered with. + decryptedData, err := aead.Open(nil, nonce, ciphertext, nil) + + if err != nil { + return []byte{}, err + } + + return decryptedData, nil +} + +// Initializes a Bismuth server. +// +// Both `pubKey` and `privKey` are armored PGP public and private keys respectively. +func NewBismuthServer(pubKey string, privKey string, signServers []string, encryptionAlgo int, connHandler func(conn net.Conn) error) (*BismuthServer, error) { + publicKey, err := crypto.NewKeyFromArmored(pubKey) + + if err != nil { + return nil, err + } + + privateKey, err := crypto.NewKeyFromArmored(privKey) + + if err != nil { + return nil, err + } + + pgp := crypto.PGP() + + bismuth := BismuthServer{ + PublicKey: publicKey, + PrivateKey: privateKey, + HandleConnection: connHandler, + SigningServers: signServers, + SymmetricEncryptionAlgorithm: encryptionAlgo, + pgp: pgp, + } + + return &bismuth, nil +}