-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New crypto implementation #155
Merged
Changes from 19 commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
17a8892
New crypto wip
kleewho 3ce91e7
Stuck on the how and when to put Header into Writer in EncryptStream
kleewho 2958f30
Implementation + property based tests of reader enc/dec
kleewho 35829b8
Some contract tests are working
kleewho 37a1ef2
Reduce number of layers
kleewho e2f48e1
Fix old tests
kleewho 5a9ce3f
Check for lenght shorter than sentinel
kleewho 10d198f
Use new crypto module in pubnub
kleewho cc43c10
Fix method calls
kleewho 6af0c16
Support first mutation of config.CipherKey
kleewho 555db45
Fixes to contract tests
kleewho 2f6b5fc
Remove unneeded step
kleewho 95f655f
Hopefully now
kleewho abc1251
Stupid stupid stupid
kleewho a1b0e73
Demodemodemodemodemodemodemodemo
kleewho 0a4e162
Fixes
kleewho 77158c6
Make e2e tests easier to run
kleewho 0c7027a
Apply suggestions from code review
kleewho 9cbfda0
After review changes
kleewho 4ef0fec
After review changes. Next part
kleewho 969ddef
Fix history_request_test.go file
kleewho dcb5113
Fix it better ;)
kleewho 1d0e989
Maybe?
kleewho 3a5f86c
Remove deprecation
kleewho 654155e
Put correct cryptor data size if it's larger than 254
kleewho 108c460
Add proper info in Deprecation of UseRandomInitializationVector
kleewho 800988b
Include empty data checks
kleewho 91718de
Fix fire request
kleewho a327a26
Simplify the objectsV2 tests significantly
kleewho 1715618
PubNub SDK v7.2.0 release.
pubnub-release-bot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package crypto | ||
|
||
import ( | ||
"crypto/aes" | ||
"crypto/cipher" | ||
"crypto/sha256" | ||
"errors" | ||
"fmt" | ||
"io" | ||
) | ||
|
||
type aesCbcCryptor struct { | ||
block cipher.Block | ||
} | ||
|
||
func NewAesCbcCryptor(cipherKey string) (ExtendedCryptor, error) { | ||
block, e := aesCipher(cipherKey) | ||
if e != nil { | ||
return nil, e | ||
} | ||
|
||
return &aesCbcCryptor{ | ||
block: block, | ||
}, nil | ||
} | ||
|
||
var crivId = "ACRH" | ||
|
||
func (c *aesCbcCryptor) Id() string { | ||
return crivId | ||
} | ||
|
||
func (c *aesCbcCryptor) Encrypt(message []byte) (*EncryptedData, error) { | ||
message = padWithPKCS7(message) | ||
iv := generateIV(aes.BlockSize) | ||
blockmode := cipher.NewCBCEncrypter(c.block, iv) | ||
|
||
encryptedBytes := make([]byte, len(message)) | ||
blockmode.CryptBlocks(encryptedBytes, message) | ||
|
||
return &EncryptedData{ | ||
Metadata: iv, | ||
Data: encryptedBytes, | ||
}, nil | ||
} | ||
|
||
func (c *aesCbcCryptor) Decrypt(encryptedData *EncryptedData) (r []byte, e error) { | ||
decrypter := cipher.NewCBCDecrypter(c.block, encryptedData.Metadata) | ||
//to handle decryption errors | ||
defer func() { | ||
if rec := recover(); rec != nil { | ||
r, e = nil, fmt.Errorf("decrypt error: %s", rec) | ||
} | ||
}() | ||
|
||
decrypted := make([]byte, len(encryptedData.Data)) | ||
decrypter.CryptBlocks(decrypted, encryptedData.Data) | ||
val, err := unpadPKCS7(decrypted) | ||
if err != nil { | ||
return nil, fmt.Errorf("decrypt error: %s", err) | ||
} | ||
|
||
return val, nil | ||
} | ||
|
||
func (c *aesCbcCryptor) EncryptStream(reader io.Reader) (*EncryptedStreamData, error) { | ||
iv := generateIV(aes.BlockSize) | ||
|
||
return &EncryptedStreamData{ | ||
Metadata: iv, | ||
Reader: newBlockModeEncryptingReader(reader, cipher.NewCBCEncrypter(c.block, iv)), | ||
}, nil | ||
} | ||
|
||
func (c *aesCbcCryptor) DecryptStream(encryptedData *EncryptedStreamData) (io.Reader, error) { | ||
if encryptedData.Metadata == nil { | ||
return nil, errors.New("missing metadata") | ||
} | ||
return newBlockModeDecryptingReader(encryptedData.Reader, cipher.NewCBCDecrypter(c.block, encryptedData.Metadata)), nil | ||
} | ||
|
||
func aesCipher(cipherKey string) (cipher.Block, error) { | ||
hash := sha256.New() | ||
hash.Write([]byte(cipherKey)) | ||
|
||
block, err := aes.NewCipher(hash.Sum(nil)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return block, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package crypto | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"testing" | ||
"testing/quick" | ||
) | ||
|
||
var defaultPropertyTestConfig = &quick.Config{ | ||
MaxCount: 1000, | ||
} | ||
|
||
func canDecryptEncryptStreamResult(in []byte) bool { | ||
cryptor, e := NewAesCbcCryptor("enigma") | ||
if e != nil { | ||
return false | ||
} | ||
|
||
output, err := cryptor.EncryptStream(bytes.NewReader(in)) | ||
if err != nil { | ||
return false | ||
} | ||
|
||
encrData, err := io.ReadAll(output.Reader) | ||
|
||
decrypted, err := cryptor.Decrypt(&EncryptedData{ | ||
Data: encrData, | ||
Metadata: output.Metadata, | ||
}) | ||
if err != nil { | ||
return false | ||
} | ||
return bytes.Equal(in, decrypted) | ||
} | ||
|
||
func canDecryptStreamEncryptResult(in []byte) bool { | ||
cryptor, e := NewAesCbcCryptor("enigma") | ||
if e != nil { | ||
return false | ||
} | ||
|
||
output, err := cryptor.Encrypt(in) | ||
if err != nil { | ||
println(err.Error()) | ||
return false | ||
} | ||
|
||
decryptingReader, err := cryptor.DecryptStream(&EncryptedStreamData{ | ||
Reader: bytes.NewReader(output.Data), | ||
Metadata: output.Metadata, | ||
}) | ||
if err != nil { | ||
println(err.Error()) | ||
return false | ||
} | ||
|
||
decrypted, err := io.ReadAll(decryptingReader) | ||
if err != nil { | ||
println(err.Error()) | ||
return false | ||
} | ||
|
||
return bytes.Equal(in, decrypted) | ||
} | ||
|
||
func Test_AesCBC_EncryptStream(t *testing.T) { | ||
if err := quick.Check(canDecryptEncryptStreamResult, defaultPropertyTestConfig); err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func Test_AesCBC_DecryptStream(t *testing.T) { | ||
if err := quick.Check(canDecryptStreamEncryptResult, defaultPropertyTestConfig); err != nil { | ||
t.Error(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package crypto | ||
|
||
import "io" | ||
|
||
type EncryptedData struct { | ||
Metadata []byte | ||
Data []byte | ||
} | ||
|
||
type Cryptor interface { | ||
Id() string | ||
Encrypt(message []byte) (*EncryptedData, error) | ||
Decrypt(encryptedData *EncryptedData) ([]byte, error) | ||
} | ||
|
||
type EncryptedStreamData struct { | ||
Metadata []byte | ||
Reader io.Reader | ||
} | ||
|
||
type ExtendedCryptor interface { | ||
Cryptor | ||
EncryptStream(reader io.Reader) (*EncryptedStreamData, error) | ||
DecryptStream(encryptedData *EncryptedStreamData) (io.Reader, error) | ||
} | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that extended interface. Imo it works much better than having a big one cryptor - especially that file crypto is something a little bit different than raw data.