chore: Seperate code into multiple files for client and server.
This commit is contained in:
parent
a977e69aef
commit
a5e479cc0c
7 changed files with 230 additions and 188 deletions
100
client/client.go
100
client/client.go
|
@ -1,8 +1,6 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/cipher"
|
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
|
@ -12,74 +10,6 @@ import (
|
||||||
"github.com/ProtonMail/gopenpgp/v3/crypto"
|
"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()
|
// 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().
|
// 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,
|
Bismuth: &bmConn,
|
||||||
}, nil
|
}, 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
|
|
||||||
}
|
|
||||||
|
|
46
client/typing.go
Normal file
46
client/typing.go
Normal file
|
@ -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
|
||||||
|
}
|
68
client/utils.go
Normal file
68
client/utils.go
Normal file
|
@ -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
|
||||||
|
}
|
|
@ -2,32 +2,44 @@
|
||||||
|
|
||||||
package commons
|
package commons
|
||||||
|
|
||||||
// Commands
|
// Core Protocol Commands
|
||||||
const (
|
const (
|
||||||
// SendPublicKey: Sending public key back and forth
|
// Sending public key back and forth
|
||||||
SendPublicKey = iota
|
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
|
SwitchToSymmetricKey
|
||||||
// ClientSendHost: Currently unimplemented.
|
|
||||||
// Client sends what host they are connecting to.
|
// Client sends what host they are connecting to.
|
||||||
|
// Currently unimplemented.
|
||||||
ClientSendHost
|
ClientSendHost
|
||||||
// GetSigningServers: Currently unimplemented.
|
|
||||||
// Gets the signing servers trusting/signing the current server.
|
// Gets the signing servers trusting/signing the current server.
|
||||||
|
// Currently unimplemented.
|
||||||
GetSigningServers
|
GetSigningServers
|
||||||
// GetTrustedDomains: Currently unimplemented.
|
|
||||||
// Gets the domains that are supported by this certificate (should be cross-checked)
|
// Gets the domains that are supported by this certificate (should be cross-checked)
|
||||||
|
// Currently unimplemented.
|
||||||
GetTrustedDomains
|
GetTrustedDomains
|
||||||
// InitiateForwarding: Starts forwarding traffic over this protocol.
|
// Starts forwarding traffic over this protocol.
|
||||||
InitiateForwarding
|
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 (
|
const (
|
||||||
// Default and only encryption algorithm
|
// Default and only encryption algorithm
|
||||||
XChaCha20Poly1305 = iota
|
XChaCha20Poly1305 = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unsigned integer limits
|
// Unsigned Integer Limits
|
||||||
const (
|
const (
|
||||||
BitLimit24 = 16_777_215
|
BitLimit24 = 16_777_215
|
||||||
BitLimit16 = 65535
|
BitLimit16 = 65535
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
core "git.greysoh.dev/imterah/bismuthd/commons"
|
core "git.greysoh.dev/imterah/bismuthd/commons"
|
||||||
|
@ -13,54 +12,6 @@ import (
|
||||||
"golang.org/x/crypto/chacha20poly1305"
|
"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
|
// 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 {
|
func (bismuth BismuthServer) HandleProxy(conn net.Conn) error {
|
||||||
serverState := "keyHandshake"
|
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
|
|
||||||
}
|
|
||||||
|
|
26
server/typing.go
Normal file
26
server/typing.go
Normal file
|
@ -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
|
||||||
|
}
|
69
server/utils.go
Normal file
69
server/utils.go
Normal file
|
@ -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
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue