ubiq-security 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 20d4dacbe17d8162ab7d308069b82e2b54b89cf7a7253763919742ef350597e3
4
- data.tar.gz: 370015b19528bc6a81678e3b0f7f270b0524b6309f23dc6087d04256edad1e27
3
+ metadata.gz: a7988726fc44204d81c5fd65b343c14d34ff24e2fc6883b6fed4acdfc71afb98
4
+ data.tar.gz: c22cc110f282e5b93dd42fe49be499a1dff208d6fce0726329499a5b0b0fb93a
5
5
  SHA512:
6
- metadata.gz: 7ed8203d50dbe828d649af7decc40f300f1b2b5d74e912db9119e84444c840dc45a8fcc1c8e0b3fa49a8d7a6ebf73fbb9ce935e7244c1669d9d072af61674c52
7
- data.tar.gz: ddd4e2690d2d47a737fda60d53524d9b57eec456410f14f5e4a56cb61e447e632f6c7a70bc0cc2dfc5126b95191df739dd6484089e07e6126f2d848989b28841
6
+ metadata.gz: 91e17a9b5b5d52dc2f107585884bdda8e3a12cf2e405329b5204835ac28a9dd416bd044fc0fb530e6b43382d1ec6ecc9b0b9771b4317744fcfef6ae7bd9b9757
7
+ data.tar.gz: a428124dc92b6b956a8f5be93d19e00bc4541144894b73f3ee692f6db22bb8514e2be77f8977b140ed04f8f0ed3504d20523c5bec1d5f08399dda4654218afcc
data/README.md CHANGED
@@ -7,7 +7,7 @@ to encrypt and decrypt data
7
7
 
8
8
  ## Documentation
9
9
 
10
- See the [Ruby API docs](https://ubiqsecurity.com/docs/api?lang=ruby).
10
+ See the [Ruby API docs][apidocs].
11
11
 
12
12
 
13
13
 
@@ -78,8 +78,7 @@ credentials = Credentials(access_key_id = "...", secret_signing_key = "...", sec
78
78
 
79
79
  ### Encrypt a simple block of data
80
80
 
81
- Pass credentials and data into the encryption function. The encrypted data
82
- will be returned.
81
+ Pass credentials and data into the encryption function. The encrypted data will be returned.
83
82
 
84
83
 
85
84
  ```ruby
@@ -92,8 +91,7 @@ encrypted_data = encrypt(credentials, plaintext_data)
92
91
 
93
92
  ### Decrypt a simple block of data
94
93
 
95
- Pass credentials and encrypted data into the decryption function. The plaintext data
96
- will be returned.
94
+ Pass credentials and encrypted data into the decryption function. The plaintext data will be returned.
97
95
 
98
96
  ```ruby
99
97
  require "ubiq-security"
@@ -183,6 +181,6 @@ BLOCK_SIZE = 1024 * 1024
183
181
  [gem]: https://rubygems.org/gems/uniq-security
184
182
  [dashboard]:https://dev.ubiqsecurity.com/docs/dashboard
185
183
  [credentials]:https://dev.ubiqsecurity.com/docs/how-to-create-api-keys
186
-
184
+ [apidocs]:https://dev.ubiqsecurity.com/docs/api
187
185
 
188
186
 
@@ -13,10 +13,9 @@
13
13
  #
14
14
  # https://ubiqsecurity.com/legal
15
15
 
16
- require "ubiq/version"
17
- require "ubiq/encrypt"
18
- require "ubiq/decrypt"
19
- require "ubiq/credentials"
20
-
21
-
16
+ # frozen_string_literal: true
22
17
 
18
+ require 'ubiq/version'
19
+ require 'ubiq/encrypt'
20
+ require 'ubiq/decrypt'
21
+ require 'ubiq/credentials'
@@ -14,56 +14,60 @@
14
14
  # https://ubiqsecurity.com/legal
15
15
  #
16
16
 
17
- require "active_support/all"
17
+ # frozen_string_literal: true
18
+
19
+ require 'active_support/all'
18
20
  require 'openssl'
19
21
 
20
22
  module Ubiq
23
+ # Class to provide some basic information mapping between an
24
+ # encryption algorithm name and the cooresponding
25
+ # key size, initialization vector length, and tag
26
+ class Algo
27
+ def set_algo
28
+ @algorithm = {
29
+ 'aes-256-gcm' => {
30
+ id: 0,
31
+ algorithm: OpenSSL::Cipher::AES256,
32
+ mode: OpenSSL::Cipher::AES256.new(:GCM),
33
+ key_length: 32,
34
+ iv_length: 12,
35
+ tag_length: 16
36
+ }
37
+ }
38
+ end
21
39
 
22
- class Algo
40
+ def get_algo(name)
41
+ set_algo[name]
42
+ end
23
43
 
24
- def set_algo
25
- @algorithm = {
26
- "aes-256-gcm"=>{
27
- id:0,
28
- algorithm: OpenSSL::Cipher::AES256,
29
- mode: OpenSSL::Cipher::AES256.new(:GCM),
30
- key_length: 32,
31
- iv_length: 12,
32
- tag_length: 16
33
- },
34
- }
35
- end
44
+ def encryptor(obj, key, iv = nil)
45
+ # key : A byte string containing the key to be used with this encryption
46
+ # If the caller specifies the initialization vector, it must be
47
+ # the correct length and, if so, will be used. If it is not
48
+ # specified, the function will generate a new one
36
49
 
37
- def get_algo(name)
38
- set_algo[name]
39
- end
50
+ raise RuntimeError, 'Invalid key length' if key.length != obj[:key_length]
40
51
 
41
- def encryptor(obj,key, iv=nil)
42
- # key : A byte string containing the key to be used with this encryption
43
- # If the caller specifies the initialization vector, it must be
44
- # the correct length and, if so, will be used. If it is not
45
- # specified, the function will generate a new one
52
+ raise RuntimeError, 'Invalid initialization vector length' if !iv.nil? && iv.length != obj[:iv_length]
46
53
 
47
- cipher = obj[:mode]
48
- raise RuntimeError, 'Invalid key length' if key.length != obj[:key_length]
54
+ cipher = obj[:mode]
55
+ cipher.encrypt
56
+ cipher.key = key
57
+ iv = cipher.random_iv
58
+ return cipher, iv
59
+ end
49
60
 
50
- raise RuntimeError, 'Invalid initialization vector length' if (iv!= nil and iv.length != obj[:iv_length])
51
- cipher.encrypt
52
- cipher.key = key
53
- iv = cipher.random_iv
54
- return cipher, iv
55
- end
61
+ def decryptor(obj, key, iv)
62
+ raise RuntimeError, 'Invalid key length' if key.length != obj[:key_length]
56
63
 
57
- def decryptor(obj, key, iv)
58
- cipher = obj[:mode]
59
- raise RuntimeError, 'Invalid key length' if key.length != obj[:key_length]
64
+ raise RuntimeError, 'Invalid initialization vector length' if !iv.nil? && iv.length != obj[:iv_length]
60
65
 
61
- raise RuntimeError, 'Invalid initialization vector length' if (iv!= nil and iv.length != obj[:iv_length])
62
- cipher = obj[:mode]
63
- cipher.decrypt
64
- cipher.key = key
65
- cipher.iv = iv
66
- return cipher
66
+ cipher = obj[:mode]
67
+ cipher.decrypt
68
+ cipher.key = key
69
+ cipher.iv = iv
70
+ return cipher
71
+ end
67
72
  end
68
73
  end
69
- end
@@ -13,87 +13,88 @@
13
13
  #
14
14
  # https://ubiqsecurity.com/legal
15
15
  #
16
- require "active_support/all"
17
16
 
18
- module Ubiq
17
+ # frozen_string_literal: true
18
+
19
+ require 'active_support/all'
19
20
 
20
- class Auth
21
+ module Ubiq
21
22
  # HTTP Authentication for the Ubiq Platform
22
23
 
23
24
  # This module implements HTTP authentication for the Ubiq platform
24
25
  # via message signing as described by the IETF httpbis-message-signatures
25
26
  # draft specification.
26
-
27
- def self.build_headers(papi, sapi, endpoint, query, host, http_method)
28
-
29
- # This function calculates the signature for the message, adding the Signature header
30
- # to contain the data. Certain HTTP headers are required for
31
- # signature calculation and will be added by this code as
32
- # necessary. The constructed headers object is returned
33
-
34
- # the '(request-target)' is part of the signed data.
35
- # it's value is 'http_method path?query'
36
- reqt = "#{http_method} #{endpoint}"
37
-
38
- # The time at which the signature was created expressed as the unix epoch
39
- created = Time.now.to_i
40
-
41
- # the Digest header is always included/overridden by
42
- # this code. it is a hash of the body of the http message
43
- # and is always present even if the body is empty
44
- hash_sha512 = OpenSSL::Digest::SHA512.new
45
- hash_sha512 << JSON.dump(query)
46
- digest = 'SHA-512='+Base64.strict_encode64(hash_sha512.digest)
47
-
48
- # Initialize the headers object to be returned via this method
49
- all_headers = {}
50
- # The content type of request
51
- all_headers['content-type'] = 'application/json'
52
- # The request target calculated above(reqt)
53
- all_headers['(request-target)'] = reqt
54
- # The date and time in GMT format
55
- all_headers['date'] = get_date
56
- # The host specified by the caller
57
- all_headers['host'] = get_host(host)
58
- all_headers['(created)'] = created
59
- all_headers['digest'] = digest
60
- headers = ['content-type', 'date', 'host', '(created)', '(request-target)', 'digest']
61
-
62
- # include the specified headers in the hmac calculation. each
63
- # header is of the form 'header_name: header value\n'
64
- # included headers are also added to an ordered list of headers
65
- # which is included in the message
66
- hmac = OpenSSL::HMAC.new(sapi, OpenSSL::Digest::SHA512.new)
67
- headers.each do |header|
68
- if all_headers.key?(header)
69
- hmac << "#{header}: #{all_headers[header]}\n"
27
+ class Auth
28
+ def self.build_headers(papi, sapi, endpoint, query, host, http_method)
29
+
30
+ # This function calculates the signature for the message, adding the Signature header
31
+ # to contain the data. Certain HTTP headers are required for
32
+ # signature calculation and will be added by this code as
33
+ # necessary. The constructed headers object is returned
34
+
35
+ # the '(request-target)' is part of the signed data.
36
+ # it's value is 'http_method path?query'
37
+ reqt = "#{http_method} #{endpoint}"
38
+
39
+ # The time at which the signature was created expressed as the unix epoch
40
+ created = Time.now.to_i
41
+
42
+ # the Digest header is always included/overridden by
43
+ # this code. it is a hash of the body of the http message
44
+ # and is always present even if the body is empty
45
+ hash_sha512 = OpenSSL::Digest::SHA512.new
46
+ hash_sha512 << JSON.dump(query)
47
+ digest = 'SHA-512=' + Base64.strict_encode64(hash_sha512.digest)
48
+
49
+ # Initialize the headers object to be returned via this method
50
+ all_headers = {}
51
+ # The content type of request
52
+ all_headers['content-type'] = 'application/json'
53
+ # The request target calculated above(reqt)
54
+ all_headers['(request-target)'] = reqt
55
+ # The date and time in GMT format
56
+ all_headers['date'] = get_date
57
+ # The host specified by the caller
58
+ all_headers['host'] = get_host(host)
59
+ all_headers['(created)'] = created
60
+ all_headers['digest'] = digest
61
+ headers = ['content-type', 'date', 'host', '(created)', '(request-target)', 'digest']
62
+
63
+ # include the specified headers in the hmac calculation. each
64
+ # header is of the form 'header_name: header value\n'
65
+ # included headers are also added to an ordered list of headers
66
+ # which is included in the message
67
+ hmac = OpenSSL::HMAC.new(sapi, OpenSSL::Digest::SHA512.new)
68
+ headers.each do |header|
69
+ if all_headers.key?(header)
70
+ hmac << "#{header}: #{all_headers[header]}\n"
71
+ end
70
72
  end
71
- end
72
-
73
- all_headers.delete('(created)')
74
- all_headers.delete('(request-target)')
75
- all_headers.delete('host')
76
-
77
- # Build the Signature header itself
78
- all_headers['signature'] = 'keyId="' + papi + '"'
79
- all_headers['signature'] += ', algorithm="hmac-sha512"'
80
- all_headers['signature'] += ', created=' + created.to_s
81
- all_headers['signature'] += ', headers="' + headers.join(" ") + '"'
82
- all_headers['signature'] += ', signature="'
83
- all_headers['signature'] += Base64.strict_encode64(hmac.digest)
84
- all_headers['signature'] += '"'
85
73
 
86
- return all_headers
87
- end
74
+ all_headers.delete('(created)')
75
+ all_headers.delete('(request-target)')
76
+ all_headers.delete('host')
77
+
78
+ # Build the Signature header itself
79
+ all_headers['signature'] = 'keyId="' + papi + '"'
80
+ all_headers['signature'] += ', algorithm="hmac-sha512"'
81
+ all_headers['signature'] += ', created=' + created.to_s
82
+ all_headers['signature'] += ', headers="' + headers.join(' ') + '"'
83
+ all_headers['signature'] += ', signature="'
84
+ all_headers['signature'] += Base64.strict_encode64(hmac.digest)
85
+ all_headers['signature'] += '"'
86
+
87
+ return all_headers
88
+ end
88
89
 
89
- def self.get_host(host)
90
- uri = URI(host)
91
- return "#{uri.hostname}:#{uri.port}"
92
- end
90
+ def self.get_host(host)
91
+ uri = URI(host)
92
+ return "#{uri.hostname}:#{uri.port}"
93
+ end
93
94
 
94
- def self.get_date
95
- DateTime.now.in_time_zone('GMT').strftime("%a, %d %b %Y") + " " + DateTime.now.in_time_zone('GMT').strftime("%H:%M:%S") + " GMT"
95
+ def self.get_date
96
+ DateTime.now.in_time_zone('GMT').strftime('%a, %d %b %Y') + ' ' +
97
+ DateTime.now.in_time_zone('GMT').strftime('%H:%M:%S') + ' GMT'
98
+ end
96
99
  end
97
-
98
- end
99
100
  end
@@ -13,93 +13,103 @@
13
13
  #
14
14
  # https://ubiqsecurity.com/legal
15
15
  #
16
+
17
+ # frozen_string_literal: true
18
+
16
19
  require 'configparser'
17
20
  require 'rb-readline'
18
21
  require 'byebug'
19
22
 
20
23
  module Ubiq
24
+ # Access Credentials used by the library to validate service calls
25
+ class CredentialsInfo
26
+ def initialize(access_key_id, secret_signing_key, secret_crypto_access_key, host)
27
+ @access_key_id = access_key_id
28
+ @secret_signing_key = secret_signing_key
29
+ @secret_crypto_access_key = secret_crypto_access_key
30
+ @host = host
31
+ end
21
32
 
22
- class CredentialsInfo
23
-
24
- def initialize(access_key_id, secret_signing_key, secret_crypto_access_key, host)
25
- @access_key_id = access_key_id
26
- @secret_signing_key = secret_signing_key
27
- @secret_crypto_access_key = secret_crypto_access_key
28
- @host = host
29
- end
30
-
31
- def set_attributes
32
- return OpenStruct.new(access_key_id: @access_key_id, secret_signing_key: @secret_signing_key, secret_crypto_access_key: @secret_crypto_access_key, host: @host)
33
- end
34
- end
35
-
36
-
37
- class ConfigCredentials < CredentialsInfo
38
- def initialize(config_file, profile)
39
- # If config file is not found
40
- if config_file != nil and !File.exists?(config_file)
41
- raise RuntimeError, "Unable to open config file #{config_file} or contains missing values"
33
+ def set_attributes
34
+ return OpenStruct.new(
35
+ access_key_id: @access_key_id,
36
+ secret_signing_key: @secret_signing_key,
37
+ secret_crypto_access_key: @secret_crypto_access_key,
38
+ host: @host
39
+ )
42
40
  end
41
+ end
43
42
 
44
- if config_file == nil
45
- config_file = "~/.ubiq/credentials"
43
+ # Class to load a credentials file or the default
44
+ # and read the credentials from either a supplied
45
+ # profile or use the default
46
+ class ConfigCredentials < CredentialsInfo
47
+ def initialize(config_file, profile)
48
+ # If config file is not found
49
+ if !config_file.nil? && !File.exist?(config_file)
50
+ raise RuntimeError, "Unable to open config file #{config_file} or contains missing values"
51
+ end
52
+
53
+ if config_file.nil?
54
+ config_file = '~/.ubiq/credentials'
55
+ end
56
+
57
+ # If config file is found
58
+ if File.exist?(File.expand_path(config_file))
59
+ @creds = load_config_file(config_file, profile)
60
+ end
46
61
  end
47
62
 
48
- # If config file is found
49
- if File.exists?(File.expand_path(config_file))
50
- @creds = load_config_file(config_file, profile)
63
+ def get_attributes
64
+ return @creds
51
65
  end
52
- end
53
66
 
54
- def get_attributes
55
- return @creds
56
- end
67
+ def load_config_file(file, profile)
68
+ config = ConfigParser.new(File.expand_path(file))
57
69
 
58
- def load_config_file(file, profile)
59
- config = ConfigParser.new(File.expand_path(file))
70
+ # Create empty dictionaries for the default and supplied profile
71
+ p = {}
72
+ d = {}
60
73
 
61
- # Create empty dictionaries for the default and supplied profile
62
- p = {}
63
- d = {}
74
+ # get the default profile if there is one
75
+ if config['default'].present?
76
+ d = config['default']
77
+ end
64
78
 
65
- # get the default profile if there is one
66
- if config['default'].present?
67
- d = config['default']
68
- end
79
+ # get the supplied profile if there is one
80
+ if config[profile].present?
81
+ p = config[profile]
82
+ end
69
83
 
70
- # get the supplied profile if there is one
71
- if config[profile].present?
72
- p = config[profile]
73
- end
84
+ # Use given profile if it is available, otherwise use default.
85
+ access_key_id = p.key?('ACCESS_KEY_ID') ? p['ACCESS_KEY_ID'] : d['ACCESS_KEY_ID']
86
+ secret_signing_key = p.key?('SECRET_SIGNING_KEY') ? p['SECRET_SIGNING_KEY'] : d['SECRET_SIGNING_KEY']
87
+ secret_crypto_access_key = p.key?('SECRET_CRYPTO_ACCESS_KEY') ? p['SECRET_CRYPTO_ACCESS_KEY'] : d['SECRET_CRYPTO_ACCESS_KEY']
88
+ host = p.key?('SERVER') ? p['SERVER'] : d['SERVER']
74
89
 
75
- # Use given profile if it is available, otherwise use default.
76
- access_key_id = p.key?('ACCESS_KEY_ID') ? p['ACCESS_KEY_ID'] : d['ACCESS_KEY_ID']
77
- secret_signing_key = p.key?('SECRET_SIGNING_KEY') ? p['SECRET_SIGNING_KEY'] : d['SECRET_SIGNING_KEY']
78
- secret_crypto_access_key = p.key?('SECRET_CRYPTO_ACCESS_KEY') ? p['SECRET_CRYPTO_ACCESS_KEY'] : d['SECRET_CRYPTO_ACCESS_KEY']
79
- host = p.key?('SERVER') ? p['SERVER'] : d['SERVER']
90
+ # If the provided host does not contain http protocol then add to it
91
+ if !host.include?('http://') && !host.include?('https://')
92
+ host = 'https://' + host
93
+ end
80
94
 
81
- # If the provided host does not contain http protocol then add to it
82
- if !host.include?('http://') and !host.include?('https://')
83
- host = 'https://' + host
95
+ return CredentialsInfo.new(access_key_id, secret_signing_key, secret_crypto_access_key, host).set_attributes
84
96
  end
85
-
86
- return CredentialsInfo.new(access_key_id, secret_signing_key, secret_crypto_access_key, host).set_attributes
87
97
  end
88
- end
89
98
 
90
- class Credentials < CredentialsInfo
91
-
92
- def initialize(papi, sapi, srsa, host)
93
- @access_key_id = papi.present? ? papi : ENV['UBIQ_ACCESS_KEY_ID']
94
- @secret_signing_key = sapi.present? ? sapi : ENV['UBIQ_SECRET_SIGNING_KEY']
95
- @secret_crypto_access_key = srsa.present? ? srsa : ENV['UBIQ_SECRET_CRYPTO_ACCESS_KEY']
96
- @host = host.present? ? host : ENV['UBIQ_SERVER']
97
- end
99
+ # Class where the credentials can be explicitly set or
100
+ # will use the Environment variables instead
101
+ class Credentials < CredentialsInfo
102
+ def initialize(papi, sapi, srsa, host)
103
+ @access_key_id = papi.present? ? papi : ENV['UBIQ_ACCESS_KEY_ID']
104
+ @secret_signing_key = sapi.present? ? sapi : ENV['UBIQ_SECRET_SIGNING_KEY']
105
+ @secret_crypto_access_key = srsa.present? ? srsa : ENV['UBIQ_SECRET_CRYPTO_ACCESS_KEY']
106
+ @host = host.present? ? host : ENV['UBIQ_SERVER']
107
+ end
98
108
 
99
- @creds = CredentialsInfo.new(@access_key_id, @secret_signing_key, @secret_crypto_access_key, @host).set_attributes
109
+ @creds = CredentialsInfo.new(@access_key_id, @secret_signing_key, @secret_crypto_access_key, @host).set_attributes
100
110
 
101
- def get_attributes
102
- return @creds
111
+ def get_attributes
112
+ return @creds
113
+ end
103
114
  end
104
115
  end
105
- end