syde 0.0.1 → 0.0.2

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.
File without changes
data/README.md CHANGED
@@ -21,6 +21,7 @@ To contribute:
21
21
 
22
22
  * Fork it
23
23
  * Make a new feature branch: `git checkout -b some-new-thing master`
24
+ * Hack away and add tests
24
25
  * Pull request
25
26
 
26
27
  Basic usage
@@ -64,7 +65,7 @@ To delete something in the vault, use `delete`:
64
65
  vault.contents #=> ["foo"]
65
66
  string = vault.contents.first #=> "foo"
66
67
  string.replace("bar")
67
- vault.contents #=> ["bar"]
68
+ vault.contents #=> ["foo"]
68
69
 
69
70
  Objects in the vault are serialised and then deserialised and as such are not modifiable.
70
71
 
@@ -1,3 +1,6 @@
1
+ # Copyright (c) 2010 Adam Prescott
2
+ # Licensed under the MIT license. See LICENSE.
3
+
1
4
  require "openssl"
2
5
  require "yaml"
3
6
  require "fileutils"
@@ -10,7 +13,7 @@ FileUtils.mkdir(File.expand_path("~/.syde")) unless File.exist?(File.expand_path
10
13
  module Syde
11
14
  SYDE_VERSION_MAJOR = "0"
12
15
  SYDE_VERSION_MINOR = "0"
13
- SYDE_VERSION_TINY = "1"
16
+ SYDE_VERSION_TINY = "2"
14
17
 
15
18
  SYDE_VERSION = [SYDE_VERSION_MAJOR, SYDE_VERSION_MINOR, SYDE_VERSION_TINY].join(".")
16
19
 
@@ -1,15 +1,14 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "syde"
3
- s.version = "0.0.1"
3
+ s.version = "0.0.2"
4
4
  s.authors = ["Adam Prescott"]
5
5
  s.email = ["adam@aprescott.com"]
6
6
  s.homepage = "https://github.com/aprescott/syde"
7
7
  s.summary = "Symmetric data encryption library."
8
8
  s.description = "Syde is a symmetric data encryption library written in Ruby, licensed under the MIT license. It provides a saved encrypted data storage under a single password."
9
- s.files = Dir["{lib/**/*,test/**/*}"] + %w[LICENSE.mit Gemfile rakefile README.md syde.gemspec .gemtest]
9
+ s.files = Dir["{lib/**/*,test/**/*}"] + %w[LICENSE Gemfile rakefile README.md syde.gemspec .gemtest]
10
10
  s.require_path = "lib"
11
11
  s.test_files = Dir["test/*"]
12
- s.has_rdoc = false
13
12
  s.add_development_dependency "rake"
14
13
  s.required_ruby_version = "~> 1.8.7"
15
14
  s.requirements << "Ruby 1.8.7, does not work with 1.9 (yet) due to encodings"
@@ -65,4 +65,13 @@ class TC_Syde_Vault < Test::Unit::TestCase
65
65
  @vault.unlock("test_password", 0)
66
66
  assert @vault.locked?
67
67
  end
68
- end
68
+
69
+ def test_contents_not_overridable
70
+ @vault.unlock!("test_password")
71
+ @vault << "foo"
72
+ assert @vault.contents.last == "foo"
73
+ @vault.contents.last.replace("bar")
74
+ assert @vault.contents.last == "foo"
75
+ assert @vault.contents.last != "bar"
76
+ end
77
+ end
metadata CHANGED
@@ -1,8 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: syde
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 27
4
5
  prerelease:
5
- version: 0.0.1
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
6
11
  platform: ruby
7
12
  authors:
8
13
  - Adam Prescott
@@ -10,8 +15,7 @@ autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2011-05-17 00:00:00 +01:00
14
- default_executable:
18
+ date: 2011-05-19 00:00:00 Z
15
19
  dependencies:
16
20
  - !ruby/object:Gem::Dependency
17
21
  name: rake
@@ -21,6 +25,9 @@ dependencies:
21
25
  requirements:
22
26
  - - ">="
23
27
  - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
24
31
  version: "0"
25
32
  type: :development
26
33
  version_requirements: *id001
@@ -37,7 +44,6 @@ files:
37
44
  - lib/syde.rb
38
45
  - lib/syde.rb~
39
46
  - lib/syde/vault.rb
40
- - lib/syde/vault.rb~
41
47
  - lib/syde/errors.rb
42
48
  - lib/syde/storage.rb
43
49
  - lib/syde/crypto.rb
@@ -45,13 +51,12 @@ files:
45
51
  - test/test_vault.rb
46
52
  - test/_test.rb
47
53
  - test/test_crypto.rb
48
- - LICENSE.mit
54
+ - LICENSE
49
55
  - Gemfile
50
56
  - rakefile
51
57
  - README.md
52
58
  - syde.gemspec
53
59
  - .gemtest
54
- has_rdoc: true
55
60
  homepage: https://github.com/aprescott/syde
56
61
  licenses: []
57
62
 
@@ -65,17 +70,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
70
  requirements:
66
71
  - - ~>
67
72
  - !ruby/object:Gem::Version
73
+ hash: 57
74
+ segments:
75
+ - 1
76
+ - 8
77
+ - 7
68
78
  version: 1.8.7
69
79
  required_rubygems_version: !ruby/object:Gem::Requirement
70
80
  none: false
71
81
  requirements:
72
82
  - - ">="
73
83
  - !ruby/object:Gem::Version
84
+ hash: 3
85
+ segments:
86
+ - 0
74
87
  version: "0"
75
88
  requirements:
76
89
  - Ruby 1.8.7, does not work with 1.9 (yet) due to encodings
77
90
  rubyforge_project:
78
- rubygems_version: 1.6.2
91
+ rubygems_version: 1.8.2
79
92
  signing_key:
80
93
  specification_version: 3
81
94
  summary: Symmetric data encryption library.
@@ -1,214 +0,0 @@
1
- module Syde
2
- class Vault
3
- include Errors
4
-
5
- attr_accessor :plaintext_secret_key
6
- attr_reader :file
7
-
8
- def self.open(file = Storage::DefaultStorageFile)
9
- file = File.expand_path(file)
10
- FileUtils.touch(file) unless File.exist?(file)
11
-
12
- Vault.new(YAML.load_file(file) || "", file)
13
- end
14
-
15
- def self.create(password, file = Storage::DefaultStorageFile)
16
- file = File.expand_path(file)
17
-
18
- raise "#{file} contains content -- refusing to override." if File.exist?(file) && File.size(file) > 0
19
-
20
- FileUtils.touch(file) unless File.exist?(file)
21
-
22
- h = {}
23
- [:plaintext, :encrypted].each { |e| h[e] = {} }
24
-
25
- h[:plaintext][:iv] = Crypto.new_iv
26
- new_secret_key = Vault.new_secret_key(password, h[:plaintext][:iv])
27
- encrypted_key = new_secret_key[:encrypted_key]
28
- hash = new_secret_key[:plaintext_key_hash]
29
- plaintext_key = new_secret_key[:plaintext_key]
30
-
31
- h[:encrypted][:secret_key] = encrypted_key
32
- h[:plaintext][:secret_key_hash] = hash
33
-
34
- h[:encrypted][:contents] = Crypto.encrypt(plaintext_key, h[:plaintext][:iv], YAML.dump([]))
35
- h[:plaintext][:contents] = []
36
-
37
- File.open(file, "w") do |f|
38
- f << YAML.dump(h)
39
- end
40
-
41
- Vault.new(h, file)
42
- end
43
-
44
- def initialize(data, file)
45
- @data = data
46
- @file = file.freeze
47
-
48
- raise ArgumentError, "unable to find any stored data." if @data.empty?
49
- raise ArgumentError, "data is not valid." unless Storage.valid_format?(@data)
50
- end
51
-
52
- def data
53
- if locked?
54
- public_data
55
- else
56
- internal_data
57
- end
58
- end
59
-
60
- def public_data
61
- public_data = YAML.load(YAML.dump(internal_data))
62
- public_data[:plaintext].delete(:contents)
63
- public_data
64
- end
65
-
66
- private
67
-
68
- def internal_data
69
- @data
70
- end
71
-
72
- public
73
-
74
- def iv
75
- internal_data[:plaintext][:iv]
76
- end
77
-
78
- def secret_key_hash
79
- internal_data[:plaintext][:secret_key_hash]
80
- end
81
-
82
- def decrypt_secret_key(password)
83
- Crypto.aes(:decrypt, password, iv, internal_data[:encrypted][:secret_key])
84
- end
85
-
86
- def lock
87
- internal_data[:encrypted][:contents] = Crypto.encrypt(@plaintext_secret_key, iv, YAML.dump(internal_data[:plaintext][:contents]))
88
- internal_data[:plaintext][:contents] = nil
89
- @plaintext_secret_key = nil
90
- end
91
-
92
- def unlock!(password = nil)
93
- raise MissingPasswordError, "no password given." unless password
94
-
95
- plaintext_secret_key = decrypt_secret_key(password)
96
- if Crypto.digest(plaintext_secret_key) != secret_key_hash
97
- raise PasswordIncorrectError
98
- else
99
- @plaintext_secret_key = plaintext_secret_key
100
- internal_data[:encrypted][:contents] ||= Crypto.encrypt(@plaintext_secret_key, iv, YAML.dump([]))
101
- internal_data[:plaintext][:contents] = YAML.load(Crypto.decrypt(@plaintext_secret_key, iv, internal_data[:encrypted][:contents]))
102
- end
103
- end
104
-
105
- def unlock(password = nil, timeout = 5 * 60)
106
- return false unless timeout > 0
107
- unlock!(password)
108
- start_locking_timer(timeout)
109
- true
110
- end
111
-
112
- def start_locking_timer(seconds)
113
- Thread.new do
114
- sleep seconds
115
- self.lock
116
- end
117
- end
118
-
119
- def locked?
120
- if plaintext_secret_key
121
- false
122
- else
123
- true
124
- end
125
- end
126
-
127
- def plaintext_contents
128
- raise AccessError, "vault is locked; unable to access vault contents." if locked?
129
-
130
- YAML.load(YAML.dump(internal_contents))
131
- end
132
-
133
- private
134
-
135
- def internal_contents
136
- internal_data[:plaintext][:contents]
137
- end
138
-
139
- public
140
-
141
- def contents
142
- if locked?
143
- public_contents
144
- else
145
- plaintext_contents
146
- end
147
- end
148
-
149
- def public_contents
150
- raise AccessError, "vault is locked; unable to access vault contents." if locked?
151
-
152
- public_data[:plaintext][:contents]
153
- end
154
-
155
- private
156
-
157
- def update_contents(new_content)
158
- internal_data[:encrypted][:contents] = Crypto.encrypt(@plaintext_secret_key, iv, YAML.dump(internal_contents))
159
-
160
- Storage.write(YAML.dump(public_data), file)
161
-
162
- plaintext_contents
163
- end
164
-
165
- public
166
-
167
- def contents=(new_content)
168
- raise AccessError, "vault is locked; unable to modify vault contents." if locked?
169
-
170
- internal_contents.replace(new_content)
171
-
172
- update_contents(new_content)
173
- end
174
-
175
- def add(*contents)
176
- raise AccessError, "vault is locked; unable to add content to vault." if locked?
177
-
178
- contents.each do |content|
179
- internal_contents << content
180
- end
181
-
182
- update_contents(internal_contents)
183
- end
184
- alias_method :<<, :add
185
-
186
- def remove(*contents)
187
- raise AccessError, "vault is locked; unable to remove content from vault." if locked?
188
-
189
- contents.each do |content|
190
- internal_contents.delete(content)
191
- end
192
-
193
- update_contents(internal_contents)
194
- end
195
-
196
- def status
197
- locked? ? "locked" : "unlocked"
198
- end
199
-
200
- def inspect
201
- %Q{#<Vault (#{status})>}
202
- end
203
-
204
- def self.new_secret_key(password, iv)
205
- plaintext = Crypto.digest(Crypto.random_bytes(4096))
206
- new_key = Crypto.aes(:encrypt, password, iv, plaintext)
207
- #? plaintext = nil
208
- #? GC.start
209
- { :encrypted_key => new_key,
210
- :plaintext_key_hash => Crypto.digest(plaintext),
211
- :plaintext_key => plaintext }
212
- end
213
- end
214
- end