better error management + shortcode overflow control
This commit is contained in:
87
asymcrypt.go
87
asymcrypt.go
@@ -7,8 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/helper"
|
"github.com/ProtonMail/gopenpgp/v2/helper"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type KeyPair struct {
|
type KeyPair struct {
|
||||||
@@ -27,7 +25,7 @@ func NewKeyPair() (*KeyPair, error) { // Return error!
|
|||||||
}
|
}
|
||||||
pub, err := keys.GetArmoredPublicKey()
|
pub, err := keys.GetArmoredPublicKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get public key: %w", err)
|
return nil, fmt.Errorf("gopenpgp: unable to get public key: %w", err)
|
||||||
}
|
}
|
||||||
priv, err := keys.Armor()
|
priv, err := keys.Armor()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -39,27 +37,26 @@ func NewKeyPair() (*KeyPair, error) { // Return error!
|
|||||||
return &kp, nil
|
return &kp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Kp *KeyPair) GetCryptoKeyObject() *crypto.Key {
|
func (Kp *KeyPair) GetCryptoKeyObject() (*crypto.Key, error) {
|
||||||
priv, err := base64.StdEncoding.DecodeString(Kp.Private)
|
priv, err := base64.StdEncoding.DecodeString(Kp.Private)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Create key from armoured b64 failed")
|
return nil, fmt.Errorf("failed to decode private key: %w", err)
|
||||||
}
|
}
|
||||||
key, err := crypto.NewKeyFromArmored(string(priv))
|
key, err := crypto.NewKeyFromArmored(string(priv))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Create key from armoured failed")
|
return nil, fmt.Errorf("Ccreate key from armoured failed: %w", err)
|
||||||
}
|
}
|
||||||
return key
|
return key, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AsymEncrypt(publicKey string, data []byte) ([]byte, error) {
|
func AsymEncrypt(publicKey string, data []byte) ([]byte, error) {
|
||||||
pub, err := base64.StdEncoding.DecodeString(publicKey)
|
pub, err := base64.StdEncoding.DecodeString(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message encryption b64 failed")
|
return nil, fmt.Errorf("Message encryption b64 failed: %w", err)
|
||||||
}
|
}
|
||||||
ciphertext, err := encryptMessage(string(pub), crypto.NewPlainMessage(data))
|
ciphertext, err := encryptMessage(string(pub), crypto.NewPlainMessage(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message encryption failed")
|
return nil, fmt.Errorf("Message encryption failed: %w", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ciphertext.GetBinary(), err
|
return ciphertext.GetBinary(), err
|
||||||
@@ -68,11 +65,11 @@ func AsymEncrypt(publicKey string, data []byte) ([]byte, error) {
|
|||||||
func AsymDecrypt(PrivateKey string, data []byte) ([]byte, error) {
|
func AsymDecrypt(PrivateKey string, data []byte) ([]byte, error) {
|
||||||
priv, err := base64.StdEncoding.DecodeString(PrivateKey)
|
priv, err := base64.StdEncoding.DecodeString(PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message decryption b64 failed")
|
return nil, fmt.Errorf("Message decryption b64 failed: %w", err)
|
||||||
}
|
}
|
||||||
decrypted, err := decryptMessage(string(priv), nil, crypto.NewPGPMessage(data))
|
decrypted, err := decryptMessage(string(priv), nil, crypto.NewPGPMessage(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message decryption failed")
|
return nil, fmt.Errorf("Message decryption failed: %w", err)
|
||||||
}
|
}
|
||||||
return decrypted.GetBinary(), err
|
return decrypted.GetBinary(), err
|
||||||
}
|
}
|
||||||
@@ -80,11 +77,11 @@ func AsymDecrypt(PrivateKey string, data []byte) ([]byte, error) {
|
|||||||
func AsymEncryptArmored(PublicKey string, data []byte) ([]byte, error) {
|
func AsymEncryptArmored(PublicKey string, data []byte) ([]byte, error) {
|
||||||
pub, err := base64.StdEncoding.DecodeString(PublicKey)
|
pub, err := base64.StdEncoding.DecodeString(PublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message encryption b64 failed")
|
return nil, fmt.Errorf("Message encryption b64 failed: %w", err)
|
||||||
}
|
}
|
||||||
armor, err := helper.EncryptBinaryMessageArmored(string(pub), data)
|
armor, err := helper.EncryptBinaryMessageArmored(string(pub), data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message encryption failed")
|
return nil, fmt.Errorf("Message encryption failed: %w", err)
|
||||||
}
|
}
|
||||||
return []byte(armor), err
|
return []byte(armor), err
|
||||||
}
|
}
|
||||||
@@ -92,11 +89,11 @@ func AsymEncryptArmored(PublicKey string, data []byte) ([]byte, error) {
|
|||||||
func AsymDecryptArmored(PrivateKey string, data []byte) ([]byte, error) {
|
func AsymDecryptArmored(PrivateKey string, data []byte) ([]byte, error) {
|
||||||
priv, err := base64.StdEncoding.DecodeString(PrivateKey)
|
priv, err := base64.StdEncoding.DecodeString(PrivateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message decryption b64 failed")
|
return nil, fmt.Errorf("Message decryption b64 failed: %w", err)
|
||||||
}
|
}
|
||||||
decrypted, err := helper.DecryptBinaryMessageArmored(string(priv), nil, string(data))
|
decrypted, err := helper.DecryptBinaryMessageArmored(string(priv), nil, string(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message decryption failed")
|
return nil, fmt.Errorf("Message decryption failed: %w", err)
|
||||||
}
|
}
|
||||||
return []byte(decrypted), err
|
return []byte(decrypted), err
|
||||||
}
|
}
|
||||||
@@ -145,7 +142,7 @@ func encryptMessage(key string, message *crypto.PlainMessage) (*crypto.PGPMessag
|
|||||||
|
|
||||||
ciphertext, err := publicKeyRing.Encrypt(message, nil)
|
ciphertext, err := publicKeyRing.Encrypt(message, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
return nil, fmt.Errorf("gopenpgp: unable to encrypt message: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
@@ -154,24 +151,24 @@ func encryptMessage(key string, message *crypto.PlainMessage) (*crypto.PGPMessag
|
|||||||
func decryptMessage(privateKey string, passphrase []byte, ciphertext *crypto.PGPMessage) (*crypto.PlainMessage, error) {
|
func decryptMessage(privateKey string, passphrase []byte, ciphertext *crypto.PGPMessage) (*crypto.PlainMessage, error) {
|
||||||
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to parse the private key")
|
return nil, fmt.Errorf("gopenpgp: unable to parse the private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
|
return nil, fmt.Errorf("gopenpgp: unable to unlock key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer privateKeyUnlocked.ClearPrivateParams()
|
defer privateKeyUnlocked.ClearPrivateParams()
|
||||||
|
|
||||||
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to create the private key ring")
|
return nil, fmt.Errorf("gopenpgp: unable to create the private key ring: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
message, err := privateKeyRing.Decrypt(ciphertext, nil, 0)
|
message, err := privateKeyRing.Decrypt(ciphertext, nil, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message")
|
return nil, fmt.Errorf("gopenpgp: unable to decrypt message: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return message, nil
|
return message, nil
|
||||||
@@ -180,19 +177,19 @@ func decryptMessage(privateKey string, passphrase []byte, ciphertext *crypto.PGP
|
|||||||
func createPublicKeyRing(publicKey string) (*crypto.KeyRing, error) {
|
func createPublicKeyRing(publicKey string) (*crypto.KeyRing, error) {
|
||||||
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey)
|
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to parse public key")
|
return nil, fmt.Errorf("gopenpgp: unable to parse public key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if publicKeyObj.IsPrivate() {
|
if publicKeyObj.IsPrivate() {
|
||||||
publicKeyObj, err = publicKeyObj.ToPublic()
|
publicKeyObj, err = publicKeyObj.ToPublic()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to extract public key from private key")
|
return nil, fmt.Errorf("gopenpgp: unable to extract public key from private key: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publicKeyRing, err := crypto.NewKeyRing(publicKeyObj)
|
publicKeyRing, err := crypto.NewKeyRing(publicKeyObj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
return nil, fmt.Errorf("gopenpgp: unable to create new keyring: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return publicKeyRing, nil
|
return publicKeyRing, nil
|
||||||
@@ -202,18 +199,15 @@ func AsymEncryptAndSign(PublicEncryptionKey string, PrivateSignatureKey string,
|
|||||||
var enc EncryptedMessage
|
var enc EncryptedMessage
|
||||||
pub, err := base64.StdEncoding.DecodeString(PublicEncryptionKey)
|
pub, err := base64.StdEncoding.DecodeString(PublicEncryptionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message encryption and sign b64 failed")
|
return nil, fmt.Errorf("Message encryption and sign b64 failed: %w", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
priv, err := base64.StdEncoding.DecodeString(PrivateSignatureKey)
|
priv, err := base64.StdEncoding.DecodeString(PrivateSignatureKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message encryption and sign b64 failed")
|
return nil, fmt.Errorf("Message encryption and sign b64 failed: %w", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
ciphertext, signature, err := encryptAndSignMessage(string(pub), string(priv), crypto.NewPlainMessage(data))
|
ciphertext, signature, err := encryptAndSignMessage(string(pub), string(priv), crypto.NewPlainMessage(data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message encryption failed")
|
return nil, fmt.Errorf("Message encryption failed: %w", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
enc.Data = ciphertext.GetBinary()
|
enc.Data = ciphertext.GetBinary()
|
||||||
enc.Signature = []byte(signature)
|
enc.Signature = []byte(signature)
|
||||||
@@ -223,18 +217,15 @@ func AsymEncryptAndSign(PublicEncryptionKey string, PrivateSignatureKey string,
|
|||||||
func AsymDecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey string, data []byte, Signature []byte) (DecryptedMessage []byte, err error) {
|
func AsymDecryptAndCheck(MyPrivateEncryptionKey string, MyContactPublicKey string, data []byte, Signature []byte) (DecryptedMessage []byte, err error) {
|
||||||
priv, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey)
|
priv, err := base64.StdEncoding.DecodeString(MyPrivateEncryptionKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message decryption and sign b64 failed")
|
return nil, fmt.Errorf("Message decryption and sign b64 failed: %w", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
pub, err := base64.StdEncoding.DecodeString(MyContactPublicKey)
|
pub, err := base64.StdEncoding.DecodeString(MyContactPublicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message decryption and sign b64 failed")
|
return nil, fmt.Errorf("Message decryption and sign b64 failed: %w", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
DecryptedMessage, err = decryptAndCheckMessage(string(pub), string(priv), crypto.NewPGPMessage(data), crypto.NewPGPSignature(Signature))
|
DecryptedMessage, err = decryptAndCheckMessage(string(pub), string(priv), crypto.NewPGPMessage(data), crypto.NewPGPSignature(Signature))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Msg("Message decryption and sign failed")
|
return nil, fmt.Errorf("Message decryption and sign failed: %w", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return DecryptedMessage, err
|
return DecryptedMessage, err
|
||||||
}
|
}
|
||||||
@@ -248,30 +239,30 @@ func encryptAndSignMessage(pub string, priv string, message *crypto.PlainMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
return nil, nil, fmt.Errorf("gopenpgp: unable to encrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil {
|
if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
|
return nil, nil, fmt.Errorf("gopenpgp: unable to parse private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if unlockedKeyObj, err = privateKeyObj.Unlock(nil); err != nil {
|
if unlockedKeyObj, err = privateKeyObj.Unlock(nil); err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
|
return nil, nil, fmt.Errorf("gopenpgp: unable to unlock key")
|
||||||
}
|
}
|
||||||
defer unlockedKeyObj.ClearPrivateParams()
|
defer unlockedKeyObj.ClearPrivateParams()
|
||||||
|
|
||||||
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "gopenpgp: unable to create private keyring")
|
return nil, nil, fmt.Errorf("gopenpgp: unable to create private keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
ciphertext, err := publicKeyRing.Encrypt(message, nil)
|
ciphertext, err := publicKeyRing.Encrypt(message, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
return nil, nil, fmt.Errorf("gopenpgp: unable to encrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
signature, err := privateKeyRing.SignDetached(message)
|
signature, err := privateKeyRing.SignDetached(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
return nil, nil, fmt.Errorf("gopenpgp: unable to encrypt message")
|
||||||
}
|
}
|
||||||
return ciphertext, signature.GetBinary(), nil
|
return ciphertext, signature.GetBinary(), nil
|
||||||
}
|
}
|
||||||
@@ -285,30 +276,30 @@ func decryptAndCheckMessage(pub string, priv string, message *crypto.PGPMessage,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
return nil, fmt.Errorf("gopenpgp: unable to encrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil {
|
if privateKeyObj, err = crypto.NewKeyFromArmored(priv); err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
|
return nil, fmt.Errorf("gopenpgp: unable to parse private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if unlockedKeyObj, err = privateKeyObj.Unlock(nil); err != nil {
|
if unlockedKeyObj, err = privateKeyObj.Unlock(nil); err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
|
return nil, fmt.Errorf("gopenpgp: unable to unlock key")
|
||||||
}
|
}
|
||||||
defer unlockedKeyObj.ClearPrivateParams()
|
defer unlockedKeyObj.ClearPrivateParams()
|
||||||
|
|
||||||
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to create private keyring")
|
return nil, fmt.Errorf("gopenpgp: unable to create private keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
plainmessage, err := privateKeyRing.Decrypt(message, nil, 0)
|
plainmessage, err := privateKeyRing.Decrypt(message, nil, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message")
|
return nil, fmt.Errorf("gopenpgp: unable to decrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = publicKeyRing.VerifyDetached(plainmessage, signature, crypto.GetUnixTime())
|
err = publicKeyRing.VerifyDetached(plainmessage, signature, crypto.GetUnixTime())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to check message signature")
|
return nil, fmt.Errorf("gopenpgp: unable to check message signature")
|
||||||
}
|
}
|
||||||
return plainmessage.GetBinary(), nil
|
return plainmessage.GetBinary(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,12 +57,21 @@ func TestGetKey(t *testing.T) {
|
|||||||
}
|
}
|
||||||
// fmt.Println(kp.Public)
|
// fmt.Println(kp.Public)
|
||||||
// fmt.Println(kp.Private)
|
// fmt.Println(kp.Private)
|
||||||
key := kp.GetCryptoKeyObject()
|
key, err := kp.GetCryptoKeyObject()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
// fmt.Println(key.Armor())
|
// fmt.Println(key.Armor())
|
||||||
Armpubkey, _ := key.GetArmoredPublicKey()
|
Armpubkey, err := key.GetArmoredPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
pubkey := base64.StdEncoding.EncodeToString([]byte(Armpubkey))
|
pubkey := base64.StdEncoding.EncodeToString([]byte(Armpubkey))
|
||||||
println(len([]byte(pubkey)))
|
println(len([]byte(pubkey)))
|
||||||
binpubkey, _ := key.GetPublicKey()
|
binpubkey, err := key.GetPublicKey()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
println(len(binpubkey))
|
println(len(binpubkey))
|
||||||
assert.Equal(t, kp.Public, pubkey, "The two public keys should be the same.")
|
assert.Equal(t, kp.Public, pubkey, "The two public keys should be the same.")
|
||||||
//if kp.Public != pubkey {
|
//if kp.Public != pubkey {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package client
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
@@ -65,6 +66,18 @@ func GetConfig() *Config {
|
|||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) Validate() error {
|
||||||
|
if c.StoragePath == "" {
|
||||||
|
return errors.New("storage_path is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.Chunksize < 1024 || c.Chunksize > 10*1024*1024 {
|
||||||
|
return fmt.Errorf("chunksize must be between 1KB and 10MB, got %d", c.Chunksize)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Config) Load(filename string) error {
|
func (c *Config) Load(filename string) error {
|
||||||
data, err := os.ReadFile(filename)
|
data, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -74,6 +87,9 @@ func (c *Config) Load(filename string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err := c.Validate(); err != nil {
|
||||||
|
return fmt.Errorf("invalid config: %w", err)
|
||||||
|
}
|
||||||
// override values if not set or wrong
|
// override values if not set or wrong
|
||||||
if c.HttpTimeOut <= 0 {
|
if c.HttpTimeOut <= 0 {
|
||||||
c.HttpTimeOut = 10
|
c.HttpTimeOut = 10
|
||||||
|
|||||||
@@ -44,7 +44,10 @@ func StoreMessage(peer *Peer, usermessage *meowlib.UserMessage, filenames []stri
|
|||||||
dbid = peer.DbIds[len(peer.DbIds)-1]
|
dbid = peer.DbIds[len(peer.DbIds)-1]
|
||||||
}
|
}
|
||||||
// Open Db
|
// Open Db
|
||||||
db, _ := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, dbid+GetConfig().DbSuffix)) // Open the created SQLite File
|
db, err := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, dbid+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
// Detach Files
|
// Detach Files
|
||||||
hiddenFilenames := []string{}
|
hiddenFilenames := []string{}
|
||||||
@@ -114,7 +117,10 @@ func GetNewMessages(peer *Peer, lastDbId int, password string) ([]*InternalUserM
|
|||||||
}
|
}
|
||||||
fileidx := len(peer.DbIds) - 1
|
fileidx := len(peer.DbIds) - 1
|
||||||
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
||||||
db, _ := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, peer.DbIds[fileidx]+GetConfig().DbSuffix)) // Open the created SQLite File
|
db, err := sql.Open("sqlite3", filepath.Join(cfg.StoragePath, identity.Uuid, peer.DbIds[fileidx]+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
// if it's first app query, it won't hold a lastIndex, so let's start from end
|
// if it's first app query, it won't hold a lastIndex, so let's start from end
|
||||||
if lastDbId == 0 {
|
if lastDbId == 0 {
|
||||||
@@ -184,7 +190,10 @@ func GetMessagesHistory(peer *Peer, inAppMsgCount int, lastDbId int, wantMore in
|
|||||||
countStack += newCount
|
countStack += newCount
|
||||||
}
|
}
|
||||||
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
||||||
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, peer.DbIds[fileidx]+GetConfig().DbSuffix)) // Open the created SQLite File
|
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, peer.DbIds[fileidx]+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
// if it's first app query, it won't hold a lastIndex, so let's start from end
|
// if it's first app query, it won't hold a lastIndex, so let's start from end
|
||||||
if lastDbId == 0 {
|
if lastDbId == 0 {
|
||||||
@@ -231,7 +240,10 @@ func GetMessagesHistory(peer *Peer, inAppMsgCount int, lastDbId int, wantMore in
|
|||||||
|
|
||||||
func GetDbMessage(dbFile string, dbId int64, password string) (*meowlib.DbMessage, error) {
|
func GetDbMessage(dbFile string, dbId int64, password string) (*meowlib.DbMessage, error) {
|
||||||
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
// There fileidx should provide the db that we need (unless wantMore overlaps the next DB)
|
||||||
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite File
|
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite dbFile
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
stm, err := db.Prepare("SELECT id, m FROM message WHERE id=?")
|
stm, err := db.Prepare("SELECT id, m FROM message WHERE id=?")
|
||||||
@@ -267,7 +279,10 @@ func GetDbMessage(dbFile string, dbId int64, password string) (*meowlib.DbMessag
|
|||||||
}
|
}
|
||||||
|
|
||||||
func UpdateDbMessage(dbm *meowlib.DbMessage, dbFile string, dbId int64, password string) error {
|
func UpdateDbMessage(dbm *meowlib.DbMessage, dbFile string, dbId int64, password string) error {
|
||||||
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite File
|
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbFile+GetConfig().DbSuffix)) // Open the created SQLite dbFile
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
// Encrypt message
|
// Encrypt message
|
||||||
out, err := proto.Marshal(dbm)
|
out, err := proto.Marshal(dbm)
|
||||||
@@ -325,11 +340,14 @@ func InternalUserMessagePreview(msg *InternalUserMessage, password string) ([]by
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getMessageCount(dbid string) (int, error) {
|
func getMessageCount(dbid string) (int, error) {
|
||||||
db, _ := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbid+GetConfig().DbSuffix)) // Open the created SQLite File
|
db, err := sql.Open("sqlite3", filepath.Join(GetConfig().StoragePath, GetConfig().GetIdentity().Uuid, dbid+GetConfig().DbSuffix)) // Open the created SQLite File
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
var count int
|
var count int
|
||||||
query := "SELECT COUNT(*) FROM message"
|
query := "SELECT COUNT(*) FROM message"
|
||||||
err := db.QueryRow(query).Scan(&count)
|
err = db.QueryRow(query).Scan(&count)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import (
|
|||||||
"github.com/go-redis/redis"
|
"github.com/go-redis/redis"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const MaxShortcodeLength = 64
|
||||||
|
|
||||||
func (r *RedisRouter) StoreInvitation(invitation []byte, timeout int, password string, serverTimeout int, urlLen int) (string, time.Time, error) {
|
func (r *RedisRouter) StoreInvitation(invitation []byte, timeout int, password string, serverTimeout int, urlLen int) (string, time.Time, error) {
|
||||||
id, err := r.createShortId(urlLen)
|
id, err := r.createShortId(urlLen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -84,10 +86,10 @@ func (r *RedisRouter) GetInvitation(id string, password string) ([]byte, error)
|
|||||||
|
|
||||||
// deleteInvitation removes all invitation-related keys from Redis
|
// deleteInvitation removes all invitation-related keys from Redis
|
||||||
func (r *RedisRouter) deleteInvitation(id string) {
|
func (r *RedisRouter) deleteInvitation(id string) {
|
||||||
r.Client.Del("mwiv:" + id) // invitation data
|
r.Client.Del("mwiv:" + id) // invitation data
|
||||||
r.Client.Del("mwpw:" + id) // password
|
r.Client.Del("mwpw:" + id) // password
|
||||||
r.Client.Del("mwfa:" + id) // failed attempts
|
r.Client.Del("mwfa:" + id) // failed attempts
|
||||||
r.Client.Del("mwan:" + id) // answer to invitation
|
r.Client.Del("mwan:" + id) // answer to invitation
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RedisRouter) StoreAnswerToInvitation(id string, timeout int, invitation []byte, serverTimeout int) time.Time {
|
func (r *RedisRouter) StoreAnswerToInvitation(id string, timeout int, invitation []byte, serverTimeout int) time.Time {
|
||||||
@@ -110,6 +112,9 @@ func (r *RedisRouter) createShortId(length int) (string, error) {
|
|||||||
alphabet := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
alphabet := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||||
alphabetLen := big.NewInt(int64(len(alphabet)))
|
alphabetLen := big.NewInt(int64(len(alphabet)))
|
||||||
|
|
||||||
|
if length < 1 || length > MaxShortcodeLength {
|
||||||
|
return "", fmt.Errorf("invalid shortcode length: %d (must be 1-%d)", length, MaxShortcodeLength)
|
||||||
|
}
|
||||||
// for not in redis
|
// for not in redis
|
||||||
for {
|
for {
|
||||||
var id strings.Builder
|
var id strings.Builder
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
package meowlib
|
package meowlib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func SymEncrypt(password string, data []byte) ([]byte, error) {
|
func SymEncrypt(password string, data []byte) ([]byte, error) {
|
||||||
@@ -12,7 +13,7 @@ func SymEncrypt(password string, data []byte) ([]byte, error) {
|
|||||||
|
|
||||||
pgpMessage, err = crypto.EncryptMessageWithPassword(message, []byte(password))
|
pgpMessage, err = crypto.EncryptMessageWithPassword(message, []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt message with password")
|
return nil, fmt.Errorf("gopenpgp: unable to encrypt message with password: %w", err)
|
||||||
}
|
}
|
||||||
return pgpMessage.GetBinary(), nil
|
return pgpMessage.GetBinary(), nil
|
||||||
}
|
}
|
||||||
@@ -25,7 +26,7 @@ func SymDecrypt(password string, data []byte) ([]byte, error) {
|
|||||||
pgpMessage = crypto.NewPGPMessage(data)
|
pgpMessage = crypto.NewPGPMessage(data)
|
||||||
message, err = crypto.DecryptMessageWithPassword(pgpMessage, []byte(password))
|
message, err = crypto.DecryptMessageWithPassword(pgpMessage, []byte(password))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message with password")
|
return nil, fmt.Errorf("gopenpgp: unable to decrypt message with password: %w", err)
|
||||||
}
|
}
|
||||||
return message.GetBinary(), nil
|
return message.GetBinary(), nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user