diff --git a/cipher_factory.go b/cipher_factory.go index ee77a57..89dec70 100644 --- a/cipher_factory.go +++ b/cipher_factory.go @@ -1 +1,17 @@ package oxicrypt + +import "errors" + +// Add your cipher implementations in factory below + +// GetOxiCipher - ciphers factory, get the object here +func GetOxiCipher(cipherId string) (OxiCipher, error) { + switch cipherId { + case cCryptIDAES25601: + return new(cipherAES256), nil + case cNoneId: + return new(cipherNONE), nil + default: + return nil, errors.New(OXICRPT003cipherNotFound) + } +} diff --git a/ciphers.go b/ciphers.go index f2610f2..f5af2c0 100644 --- a/ciphers.go +++ b/ciphers.go @@ -2,8 +2,8 @@ package oxicrypt // !! IMPORTANT !! Do not change this interface as the change will impact available implementations -// BSCipher - Cipher interface, implement all the methods to attach new cypher to bykovstorage -type BSCipher interface { +// OxiCipher - Cipher interface, implement all the methods to attach new cipher to storage +type OxiCipher interface { CleanAndInit() // Full clean and initialization of the entity // SetPassword should be called before using encryption @@ -24,9 +24,3 @@ type BSCipher interface { GetCryptID() string // Unique ID of cipher implementation, use any alphanumeric symbols, 8 chars GetCipherName() string // Human readable name of the implemented cypher } - -// Ciphers - Add newly implemented cyphers here with `Cyphers append(Cyphers, new(cypherImplementationHere))` -var Ciphers = []BSCipher{ - new(cipherAES256), // AES256 internal implementation - new(cypherNONE), // No encryption -} diff --git a/ciphers_names.go b/ciphers_names.go index ee77a57..c67b91c 100644 --- a/ciphers_names.go +++ b/ciphers_names.go @@ -1 +1,26 @@ package oxicrypt + +// AES 256 + +const AES256Id = cCryptIDAES25601 +const AES256Text = cAES256TextDescription + +// No encryption + +const NoneId = cNoneId +const NoneText = cNoneDescription + +type CipherInfo struct { + ID string + Description string +} + +func GetCiphers() (ci []CipherInfo) { + + aes256 := CipherInfo{AES256Id, AES256Text} + ci = append(ci, aes256) + + none := CipherInfo{NoneId, NoneText} + ci = append(ci, none) + return ci +} diff --git a/consts.go b/consts.go index 53f8cb2..6f23976 100644 --- a/consts.go +++ b/consts.go @@ -1,18 +1,23 @@ package oxicrypt // Rules for errors definition -// Example BSENCRPT00001: Password is not set +// Example OXICRPT001: Password is not set // | Symbols | Possible values | Meaning -// | 1 - 2 | BS | should be always BS to identify that the error is from BykovStorage -// | 3 - 8 | Package ID | ENCRPT if you change this package "bsencryption" -// | 9 - 12 | Digital number | Number of the error -// | 13 - 14 | ": "" | Means that error id is finished, next will be desription -// it is possible to put whatewer you like, I recommend to put there human readable error description in English +// | 1 - 3 | OXI | should be always OXI to identify that the error is from OXI package +// | 4 - 7 | Package ID | CRPT if you change this package "oxicrypt" +// | 8 - 10 | Digital number | Number of the error +// | 11 - 14 | ": "" | Means that error id is finished, next will be +// | human-readable error description +// it is possible to put whatever you like, +// I recommend to put there human-readable error description in English -// BSENCRPT0001EncKeyIsNotSet - BSENCRPT0001: Password is not set, encryption/decryption is not possible -const BSENCRPT0001EncKeyIsNotSet = "BSENCRPT0001: Encryption key is not created, encryption/decryption is not possible" +// OXICRPT001encKeyIsNotSet - OXICRPT001: Password is not set, encryption/decryption is not possible +const OXICRPT001encKeyIsNotSet = "OXICRPT001: Encryption key is not created, encryption/decryption is not possible" -// BSENCRPT0002WrongKeyLength - BSENCRPT0002: key length is wrong -const BSENCRPT0002WrongKeyLength = "BSENCRPT0002: key length is wrong" +// OXICRPT002wrongKeyLength - OXICRPT002: key length is wrong +const OXICRPT002wrongKeyLength = "OXICRPT002: key length is wrong" + +// OXICRPT003cipherNotFound - OXICRPT003: cipher is not found +const OXICRPT003cipherNotFound = "OXICRPT003: cipher is not found" const cSaltLength = 8 diff --git a/general_test.go b/general_test.go index ddbaabe..400dfbf 100644 --- a/general_test.go +++ b/general_test.go @@ -70,15 +70,15 @@ func TestRandomBytesGeneratorFailure(t *testing.T) { } func TestCypherNamesAndIDs(t *testing.T) { - for _, cipher := range Ciphers { - if len(cipher.GetCryptID()) == 0 { - t.Errorf("Crypt ID cannot be empty, should be 8") - } else if len(cipher.GetCryptID()) != 8 { - t.Errorf("Wrong length of crypt ID, should be 8, CryptID: %s", cipher.GetCryptID()) + for _, cipher := range GetCiphers() { + if len(cipher.ID) == 0 { + t.Errorf("Crypt ID cannot be empty, its length should be 8 symbols") + } else if len(cipher.ID) != 8 { + t.Errorf("Wrong length of crypt ID, should be 8, CryptID: %s", cipher.ID) } - if len(cipher.GetCipherName()) == 0 { + if len(cipher.Description) == 0 { t.Errorf("Human readable cipher name is empty, should be at least 3 symbols") - } else if len(cipher.GetCipherName()) < 3 { + } else if len(cipher.Description) < 3 { t.Errorf("Human readable cipher name should be at least 3 symbols") } @@ -106,7 +106,12 @@ func TestShortEncryptionString(t *testing.T) { } func EncryptionCheckHelper(t *testing.T, minLen int, maxLen int) { - for _, cipher := range Ciphers { + for _, cipherInfo := range GetCiphers() { + cipher, errCipher := GetOxiCipher(cipherInfo.ID) + if errCipher != nil { + t.Error(errCipher.Error()) + continue + } cipher.CleanAndInit() password := generateRandomString(1, 20) plainText := generateRandomString(minLen, maxLen) diff --git a/go.mod b/go.mod index 46f5fed..07974f8 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/oxipass/oxicrypt go 1.18 -require golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 +require golang.org/x/crypto v0.6.0 diff --git a/go.sum b/go.sum index 9e65d7d..cdcbe20 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,2 @@ -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= diff --git a/impl_aes256.go b/impl_aes256.go index bb9979d..2804138 100644 --- a/impl_aes256.go +++ b/impl_aes256.go @@ -58,7 +58,7 @@ func (cipher256 *cipherAES256) GetPasswordKey() []byte { func (cipher256 *cipherAES256) SetPasswordKey(keyDataIn []byte) (err error) { if len(keyDataIn) < cAESKeyLength { - return formError(BSENCRPT0002WrongKeyLength, cAES256TextDescription, "SetPasswordKey", "Key length must be at least 32 bytes") + return formError(OXICRPT002wrongKeyLength, cAES256TextDescription, "SetPasswordKey", "Key length must be at least 32 bytes") } cipher256.passwordKey = keyDataIn return nil @@ -91,7 +91,7 @@ func (cipher256 *cipherAES256) EncryptBLOB(text string) ([]byte, error) { func (cipher256 *cipherAES256) EncryptBIN(inData []byte) (outData []byte, err error) { if cipher256.IsPasswordSet() == false { - return nil, formError(BSENCRPT0001EncKeyIsNotSet) + return nil, formError(OXICRPT001encKeyIsNotSet) } if cipher256.cachedFinalKey == nil { @@ -144,7 +144,7 @@ func (cipher256 *cipherAES256) DecryptBLOB(dataIn []byte) (string, error) { func (cipher256 *cipherAES256) DecryptBIN(dataIn []byte) (dataOut []byte, err error) { if cipher256.IsPasswordSet() == false { - return nil, formError(BSENCRPT0001EncKeyIsNotSet, cAES256TextDescription, "DecryptBIN") + return nil, formError(OXICRPT001encKeyIsNotSet, cAES256TextDescription, "DecryptBIN") } if cipher256.cachedFinalKey == nil { cipher256.cachedFinalKey, err = scrypt.Key(cipher256.passwordKey, nil, cLoops, 8, 1, cAESKeyLength) diff --git a/impl_none.go b/impl_none.go index 5a47bcf..81506a9 100644 --- a/impl_none.go +++ b/impl_none.go @@ -1,59 +1,58 @@ package oxicrypt -// No encryption consts -const cryptIDNONE = "7LD92APW" -const humanCryptNone = "NONE" +const cNoneId = "7LD92APW" +const cNoneDescription = "NONE" -type cypherNONE struct { +type cipherNONE struct { passwordKey []byte } -func (cypher *cypherNONE) CleanAndInit() { +func (cipher *cipherNONE) CleanAndInit() { } -func (cypher *cypherNONE) GetCryptID() string { - return cryptIDNONE +func (cipher *cipherNONE) GetCryptID() string { + return cNoneId } -func (cypher *cypherNONE) GetCipherName() string { - return humanCryptNone +func (cipher *cipherNONE) GetCipherName() string { + return cNoneDescription } -func (cypher *cypherNONE) SetPassword(_ string) error { +func (cipher *cipherNONE) SetPassword(_ string) error { return nil } -func (cypher *cypherNONE) SetPasswordKey(passKey []byte) error { - cypher.passwordKey = passKey +func (cipher *cipherNONE) SetPasswordKey(passKey []byte) error { + cipher.passwordKey = passKey return nil } -func (cypher *cypherNONE) IsPasswordSet() bool { +func (cipher *cipherNONE) IsPasswordSet() bool { return true } -func (cypher *cypherNONE) GetPasswordKey() []byte { - return cypher.passwordKey +func (cipher *cipherNONE) GetPasswordKey() []byte { + return cipher.passwordKey } -func (cypher *cypherNONE) EncryptBLOB(inStr string) ([]byte, error) { +func (cipher *cipherNONE) EncryptBLOB(inStr string) ([]byte, error) { return []byte(inStr), nil } -func (cypher *cypherNONE) DecryptBLOB(inData []byte) (string, error) { +func (cipher *cipherNONE) DecryptBLOB(inData []byte) (string, error) { return string(inData[:]), nil } -func (cypher *cypherNONE) EncryptBIN(inData []byte) ([]byte, error) { +func (cipher *cipherNONE) EncryptBIN(inData []byte) ([]byte, error) { return inData, nil } -func (cypher *cypherNONE) DecryptBIN(inData []byte) ([]byte, error) { +func (cipher *cipherNONE) DecryptBIN(inData []byte) ([]byte, error) { return inData, nil } -func (cypher *cypherNONE) Encrypt(text string) (string, error) { +func (cipher *cipherNONE) Encrypt(text string) (string, error) { return text, nil } -func (cypher *cypherNONE) Decrypt(encryptedText string) (string, error) { +func (cipher *cipherNONE) Decrypt(encryptedText string) (string, error) { return encryptedText, nil } diff --git a/impl_none_test.go b/impl_none_test.go index 48d2f10..e08e77d 100644 --- a/impl_none_test.go +++ b/impl_none_test.go @@ -4,7 +4,7 @@ import "testing" func TestNoneEncrypt(t *testing.T) { // As there is no encryption, check if it is the same - var none cypherNONE + var none cipherNONE genInitialText := generateRandomString(40, 100) genPass := generateRandomString(5, 32) err := none.SetPassword(genPass)