syde 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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