-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(crypto): add crypto module Add crypto module that allows to configure SDK to encrypt and decrypt messages. fix(crypto): fix legacy cryptor Improved security of crypto implementation by adding enhanced AES-CBC cryptor. --------- Co-authored-by: Michał Dobrzański <[email protected]>
- Loading branch information
1 parent
c6166a5
commit 312e266
Showing
42 changed files
with
1,021 additions
and
175 deletions.
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 |
---|---|---|
@@ -1 +1 @@ | ||
ruby jruby-9.3.8.0 | ||
ruby 3.2.2 |
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
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,29 @@ | ||
PubNub Software Development Kit License Agreement | ||
Copyright © 2023 PubNub Inc. All rights reserved. | ||
|
||
Subject to the terms and conditions of the license, you are hereby granted | ||
a non-exclusive, worldwide, royalty-free license to (a) copy and modify | ||
the software in source code or binary form for use with the software services | ||
and interfaces provided by PubNub, and (b) redistribute unmodified copies | ||
of the software to third parties. The software may not be incorporated in | ||
or used to provide any product or service competitive with the products | ||
and services of PubNub. | ||
|
||
The above copyright notice and this license shall be included | ||
in or with all copies or substantial portions of the software. | ||
|
||
This license does not grant you permission to use the trade names, trademarks, | ||
service marks, or product names of PubNub, except as required for reasonable | ||
and customary use in describing the origin of the software and reproducing | ||
the content of this license. | ||
|
||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF | ||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO | ||
EVENT SHALL PUBNUB OR THE AUTHORS OR COPYRIGHT HOLDERS OF THE SOFTWARE BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF | ||
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
|
||
https://www.pubnub.com/ | ||
https://www.pubnub.com/terms |
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1 +1 @@ | ||
5.2.2 | ||
5.3.0 |
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,99 @@ | ||
# frozen_string_literal: true | ||
# | ||
require 'pubnub' | ||
|
||
Given(/^Crypto module with '([^']*)' cryptor$/) do |cryptor_id| | ||
@cryptor_ids = [cryptor_id] | ||
end | ||
|
||
Given(/^Crypto module with default '([^']*)' and additional '([^']*)' cryptors$/) do |cryptor_id1, cryptor_id2| | ||
@cryptor_ids = [cryptor_id1, cryptor_id2] | ||
end | ||
|
||
Given(/^Legacy code with '([^']*)' cipher key and '(random|constant|-)' vector$/) do |cipher_key, use_random_iv| | ||
use_random_iv = use_random_iv != 'constant' | ||
@legacy_cryptor = Cryptor.new cipher_key, use_random_iv | ||
end | ||
|
||
Then(/^with '([^']*)' cipher key$/) do |cipher_key| | ||
@cipher_key = cipher_key | ||
end | ||
|
||
Then(/^with '(random|constant|-)' vector$/) do |use_random_iv| | ||
@use_random_iv = use_random_iv != 'constant' | ||
end | ||
|
||
When(/^I encrypt '([^']*)' file as '([^']*)'$/) do |file_name, _| | ||
@source_file_name = file_name | ||
@source_file_content = File.binread "sdk-specifications/features/encryption/assets/#{file_name}" | ||
@encrypted_content = crypto_module.encrypt @source_file_content | ||
if file_name.include? 'empty' | ||
@encrypt_status = 'encryption error' if @encrypted_content.nil? && @encrypt_status.nil? | ||
@encrypt_status = 'success' if !@encrypted_content.nil? && @encrypt_status.nil? | ||
else | ||
expect(@encrypted_content).not_to eq nil | ||
end | ||
end | ||
|
||
When(/^I decrypt '([^']*)' file$/) do |file_name| | ||
file_content = File.binread "sdk-specifications/features/encryption/assets/#{file_name}" | ||
|
||
begin | ||
@decrypted_content = crypto_module.decrypt file_content | ||
rescue Pubnub::UnknownCryptorError | ||
@decrypt_status = 'unknown cryptor error' | ||
end | ||
@decrypt_status = 'decryption error' if @decrypted_content.nil? && @decrypt_status.nil? | ||
@decrypt_status = 'success' if !@decrypted_content.nil? && @decrypt_status.nil? | ||
end | ||
|
||
When(/^I decrypt '([^']*)' file as '([^']*)'$/) do |file_name, _| | ||
file_content = File.binread "sdk-specifications/features/encryption/assets/#{file_name}" | ||
|
||
begin | ||
@decrypted_content = crypto_module.decrypt file_content | ||
rescue Pubnub::UnknownCryptorError | ||
@decrypt_status = 'unknown cryptor error' | ||
end | ||
@decrypt_status = 'decryption error' if @decrypted_content.nil? && @decrypt_status.nil? | ||
@decrypt_status = 'success' if !@decrypted_content.nil? && @decrypt_status.nil? | ||
end | ||
|
||
Then(/^Decrypted file content equal to the '([^']*)' file content$/) do |file_name| | ||
file_content = File.binread "sdk-specifications/features/encryption/assets/#{file_name}" | ||
expect(@decrypted_content).not_to eq nil | ||
expect(@decrypted_content).to eq file_content | ||
end | ||
|
||
Then('Successfully decrypt an encrypted file with legacy code') do | ||
expect(@legacy_cryptor).not_to eq nil | ||
base64_encoded = Base64.strict_encode64(@encrypted_content) | ||
decrypted_content = @legacy_cryptor.decrypt(base64_encoded) | ||
expect(decrypted_content).not_to eq nil | ||
expect(decrypted_content).to eq @source_file_content | ||
end | ||
|
||
Then(/^I receive '([^']*)'$/) do |outcome| | ||
expect(@encrypt_status || @decrypt_status).not_to eq nil | ||
expect(@encrypt_status || @decrypt_status).to eq outcome | ||
end | ||
|
||
# Crypto module | ||
# | ||
# @return [Pubnub::Crypto::CryptoModule] Crypto module instance. | ||
def crypto_module | ||
cryptors = [] | ||
@cryptor_ids.each do |cryptor_id| | ||
cryptor = if cryptor_id == 'acrh' | ||
Pubnub::Crypto::AesCbcCryptor.new @cipher_key | ||
elsif cryptor_id == 'legacy' | ||
Pubnub::Crypto::LegacyCryptor.new @cipher_key, @use_random_iv | ||
end | ||
cryptors.push(cryptor) unless cryptor.nil? | ||
end | ||
|
||
raise ArgumentError, "No crypto identifiers specified: #{@cryptor_ids}" if cryptors.empty? | ||
|
||
default_cryptor = cryptors.shift | ||
Pubnub::Crypto::CryptoModule.new default_cryptor, cryptors unless default_cryptor.nil? | ||
end |
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,58 @@ | ||
# Internal Crypto class used for message encryption and decryption | ||
class Cryptor | ||
def initialize(cipher_key, use_random_iv) | ||
@alg = 'AES-256-CBC' | ||
sha256_key = Digest::SHA256.hexdigest(cipher_key.to_s) | ||
@key = sha256_key.slice(0, 32) | ||
@using_random_iv = use_random_iv | ||
@iv = @using_random_iv == true ? random_iv : '0123456789012345' | ||
end | ||
|
||
def encrypt(message) | ||
aes = OpenSSL::Cipher.new(@alg) | ||
aes.encrypt | ||
aes.key = @key | ||
aes.iv = @iv | ||
|
||
json_message = message.to_json | ||
cipher = @using_random_iv == true ? @iv : '' | ||
cipher << aes.update(json_message) | ||
cipher << aes.final | ||
|
||
Base64.strict_encode64(cipher) | ||
end | ||
|
||
def decrypt(cipher_text) | ||
undecoded_text = Base64.decode64(cipher_text) | ||
iv = @iv | ||
|
||
if cipher_text.length > 16 && @using_random_iv == true | ||
iv = undecoded_text.slice!(0..15) | ||
end | ||
|
||
decode_cipher = OpenSSL::Cipher.new(@alg).decrypt | ||
decode_cipher.key = @key | ||
decode_cipher.iv = iv | ||
|
||
plain_text = decryption(undecoded_text, decode_cipher) | ||
|
||
plain_text | ||
end | ||
|
||
private | ||
|
||
def decryption(cipher_text, decode_cipher) | ||
plain_text = decode_cipher.update(cipher_text) | ||
plain_text << decode_cipher.final | ||
rescue StandardError => e | ||
puts "Pubnub :: DECRYPTION ERROR: #{e}" | ||
'"DECRYPTION ERROR"' | ||
end | ||
|
||
private | ||
|
||
def random_iv | ||
random_bytes = Random.new.bytes(16).unpack('NnnnnN') | ||
format('%08x%04x%04x', *random_bytes) | ||
end | ||
end |
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
Oops, something went wrong.