strongbox 0.7.0 → 0.7.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 ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MGZhNGI2ODYzOWFjYTk3MTYyNDdjNjIzMDJmMzc4NDc2ZGMyMGEzOQ==
5
+ data.tar.gz: !binary |-
6
+ Yzk0MDNlNWNjYzlmMjkyMDYwYjE2YjUwNjYzNWJhOGIxNzNkMWU4MQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ OTZlY2M1NmMwZjkzMjMyYTlmY2IzODc3MzM4NzIzMmYxYjllMjMxNTczZWYz
10
+ ZTc2ZDc0ZjQyNTVmZDQwYzE0NmIxOWE4Y2FmOTFlY2I4OTlmOWZhN2MyMjE5
11
+ ZGE2YTlhYTI0NGRmZDI3NzM3YjU0NTg0YWY1OGQyNTJlNzBmMjM=
12
+ data.tar.gz: !binary |-
13
+ ODZhNGYzZmJiMWNhNmVhMDU3MzdhNDVjNDI4MDgwMzE0OGI4YzRjZjEyYjQy
14
+ Njc5NzkwMjliZDNhY2JjY2NkYzQ4Yzc5MjA1ODcwZTM2Y2U2NDA4YWE4M2M5
15
+ ZjY0YzVjZDNiNzE2NzIyYjE2YzAyYzQwNGVmMmY5Yzg3ZmM0OWE=
data/README.md CHANGED
@@ -126,6 +126,8 @@ Options to `encrypt_with_public_key` are:
126
126
 
127
127
  * `:ensure_required_columns` - Make sure the required database column(s) exist. Defaults to `true`, set to `false` if you want to encrypt/decrypt data stored outside of the database.
128
128
 
129
+ * `:deferred_encryption` - Defer the encryption to happen before saving the object, instead of on the assignment of the encrypted attribute. Solves issues when using [dynamic keys](http://stuff-things.net/2012/04/18/dynamic-keys-for-strongbox/). Defaults to `false`.
130
+
129
131
  For example, encrypting a small attribute, providing only the public
130
132
  key for extra security, and Base64 encoding the encrypted data:
131
133
 
data/lib/strongbox.rb CHANGED
@@ -5,7 +5,7 @@ require 'strongbox/lock'
5
5
 
6
6
  module Strongbox
7
7
 
8
- VERSION = "0.7.0"
8
+ VERSION = "0.7.1"
9
9
 
10
10
  RSA_PKCS1_PADDING = OpenSSL::PKey::RSA::PKCS1_PADDING
11
11
  RSA_SSLV23_PADDING = OpenSSL::PKey::RSA::SSLV23_PADDING
@@ -20,7 +20,8 @@ module Strongbox
20
20
  :symmetric => :always,
21
21
  :padding => RSA_PKCS1_PADDING,
22
22
  :symmetric_cipher => 'aes-256-cbc',
23
- :ensure_required_columns => true
23
+ :ensure_required_columns => true,
24
+ :deferred_encryption => false
24
25
  }
25
26
  end
26
27
 
@@ -50,20 +51,20 @@ module Strongbox
50
51
  # Argument 0..-2 contains columns to be encrypted
51
52
  def encrypt_with_public_key(*args)
52
53
  include InstanceMethods
53
-
54
+
54
55
  options = args.delete_at(-1) || {}
55
-
56
+
56
57
  unless options.is_a?(Hash)
57
58
  args.push(options)
58
59
  options = {}
59
60
  end
60
-
61
+
61
62
  if args.one?
62
63
  name = args.first
63
64
  else
64
65
  return args.each { |name| encrypt_with_public_key(name, options) }
65
66
  end
66
-
67
+
67
68
  if respond_to?(:class_attribute)
68
69
  self.lock_options = {} if lock_options.nil?
69
70
  else
@@ -77,9 +78,14 @@ module Strongbox
77
78
  end
78
79
 
79
80
  define_method "#{name}=" do | plaintext |
80
- lock_for(name).encrypt plaintext
81
+ lock_for(name).content plaintext
81
82
  end
82
83
 
84
+ if lock_options[name][:deferred_encryption]
85
+ before_save do
86
+ lock_for(name).encrypt!
87
+ end
88
+ end
83
89
  end
84
90
  end
85
91
 
@@ -94,4 +100,3 @@ end
94
100
  if Object.const_defined?("ActiveRecord")
95
101
  ActiveRecord::Base.send(:include, Strongbox)
96
102
  end
97
-
@@ -21,6 +21,20 @@ module Strongbox
21
21
  @symmetric_key = options[:symmetric_key] || "#{name}_key"
22
22
  @symmetric_iv = options[:symmetric_iv] || "#{name}_iv"
23
23
  @ensure_required_columns = options[:ensure_required_columns]
24
+ @deferred_encryption = options[:deferred_encryption]
25
+ end
26
+
27
+ def content plaintext
28
+ if @deferred_encryption
29
+ @raw_content = plaintext
30
+ else
31
+ encrypt plaintext
32
+ end
33
+ end
34
+
35
+ def encrypt!
36
+ encrypt @raw_content
37
+ @raw_content = nil
24
38
  end
25
39
 
26
40
  def encrypt plaintext
@@ -61,11 +75,15 @@ module Strongbox
61
75
  # OpenSSL::PKey::RSAError if the password is wrong.
62
76
 
63
77
  def decrypt password = nil, ciphertext = nil
78
+ return @raw_content if @deferred_encryption && @raw_content
79
+
64
80
  # Given a private key and a nil password OpenSSL::PKey::RSA.new() will
65
81
  # *prompt* for a password, we default to an empty string to avoid that.
66
82
  ciphertext ||= @instance[@name]
67
- return nil if ciphertext.nil?
68
- return "" if ciphertext.empty?
83
+ unless @deferred_encryption
84
+ return nil if ciphertext.nil?
85
+ return "" if ciphertext.empty?
86
+ end
69
87
 
70
88
  return "*encrypted*" if password.nil?
71
89
  unless @private_key
@@ -97,7 +115,7 @@ module Strongbox
97
115
  end
98
116
 
99
117
  def to_s
100
- decrypt
118
+ @raw_content || decrypt
101
119
  end
102
120
 
103
121
  def to_json(options = nil)
@@ -74,4 +74,72 @@ class MethodKeyTest < Test::Unit::TestCase
74
74
 
75
75
  should_encypted_and_decrypt
76
76
  end
77
+
78
+ context "With dynamic keys" do
79
+ setup do
80
+ ActiveRecord::Base.connection.create_table :dummies, :force => true do |table|
81
+ table.string :in_the_clear
82
+ table.binary :secret
83
+ table.binary :secret_key
84
+ table.binary :secret_iv
85
+ table.binary :segreto
86
+
87
+ table.string :key_pair
88
+ end
89
+ rebuild_class :public_key => :key_pair,
90
+ :private_key => :key_pair,
91
+ :deferred_encryption => true
92
+
93
+ Dummy.class_eval do
94
+ attr_accessor :password
95
+
96
+ def key_pair
97
+ unless self['key_pair']
98
+ raise if self.password.blank?
99
+ self['key_pair'] = generate_key_pair(self.password)
100
+ end
101
+ self['key_pair']
102
+ end
103
+ end
104
+
105
+ @password = 'letmein'
106
+ end
107
+
108
+ context 'When just initialized' do
109
+ setup do
110
+ @dummy = Dummy.new
111
+ @dummy.secret = 'Shhhh'
112
+ @dummy.password = @password
113
+ end
114
+
115
+ should 'return secret when not yet locked' do
116
+ assert_equal 'Shhhh', @dummy.secret.decrypt
117
+ end
118
+
119
+ should 'return secret when unlocked' do
120
+ assert_equal 'Shhhh', @dummy.secret.decrypt(@password)
121
+ end
122
+
123
+ context 'Then locked' do
124
+ setup do
125
+ @dummy.secret.encrypt!
126
+ end
127
+ should_encypted_and_decrypt
128
+ end
129
+ end
130
+
131
+ context 'After saving the model, and then loading it from the database' do
132
+ setup do
133
+ Dummy.create!(:secret => 'Shhhh', :password => @password)
134
+ @dummy = Dummy.first
135
+ p 'XXXXXXXXXXXX'
136
+ end
137
+
138
+ should_encypted_and_decrypt
139
+ end
140
+
141
+ teardown do
142
+ rebuild_model
143
+ end
144
+ end
77
145
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strongbox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
5
- prerelease:
4
+ version: 0.7.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Spike Ilacqua
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-14 00:00:00.000000000 Z
11
+ date: 2015-01-19 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: activerecord
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: thoughtbot-shoulda
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: sqlite3
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ~>
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ~>
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: rake
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rdoc
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -128,27 +117,26 @@ files:
128
117
  - test/validations_test.rb
129
118
  homepage: http://stuff-things.net/strongbox
130
119
  licenses: []
120
+ metadata: {}
131
121
  post_install_message:
132
122
  rdoc_options: []
133
123
  require_paths:
134
124
  - lib
135
125
  required_ruby_version: !ruby/object:Gem::Requirement
136
- none: false
137
126
  requirements:
138
127
  - - ! '>='
139
128
  - !ruby/object:Gem::Version
140
129
  version: '0'
141
130
  required_rubygems_version: !ruby/object:Gem::Requirement
142
- none: false
143
131
  requirements:
144
132
  - - ! '>='
145
133
  - !ruby/object:Gem::Version
146
134
  version: '0'
147
135
  requirements: []
148
136
  rubyforge_project:
149
- rubygems_version: 1.8.24
137
+ rubygems_version: 2.4.5
150
138
  signing_key:
151
- specification_version: 3
139
+ specification_version: 4
152
140
  summary: Secures ActiveRecord fields with public key encryption.
153
141
  test_files:
154
142
  - test/database.yml