ohlol-nachos 0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/LICENSE +25 -0
  2. data/README.markdown +26 -0
  3. data/lib/nachos.rb +194 -0
  4. metadata +57 -0
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2009, Scott Smith <scott@ohlol.net>
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name of the Author (Scott Smith) nor the names of contributors
13
+ to this software may be used to endorse or promote products derived from
14
+ this software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,26 @@
1
+ NACHOS
2
+ ------
3
+
4
+ Nachos keeps people from taking your stuff. It's mine, nachos!
5
+
6
+ You need to generate a public and private key to bootstrap it.
7
+
8
+ EXAMPLE USAGE
9
+ -------------
10
+
11
+ ...to store:
12
+
13
+ require 'ohlol-nachos'
14
+
15
+ e = Nachos::Encryptor('password')
16
+ e.clear_data = 'foo bar baz'
17
+ e.secret_data = e.encrypt(e.clear_data)
18
+ e.save_data
19
+
20
+ ...to load:
21
+
22
+ require 'ohlol-nachos'
23
+
24
+ e = Nachos::Encryptor('password)'
25
+ e.load_data
26
+ puts e.clear_data
@@ -0,0 +1,194 @@
1
+ module Nachos
2
+ require 'openssl'
3
+ require 'yaml'
4
+ require 'base64'
5
+
6
+ def config
7
+ @@config
8
+ end
9
+
10
+ def config=(config = {})
11
+ if config.empty?
12
+ config_dir = File.join(File.dirname(__FILE__), '../conf')
13
+
14
+ @@config = {
15
+ :public_key => config_dir + '/public.pem',
16
+ :private_key => config_dir + '/private.pem',
17
+ :secret_key => config_dir + '/secret-key.yml',
18
+ :data_store => config_dir + '/secret-data.enc'
19
+ }
20
+ else
21
+ @@config = {
22
+ :public_key => config[:public_key],
23
+ :private_key => config[:private_key],
24
+ :secret_key => config[:secret_key],
25
+ :data_store => config[:data_store]
26
+ }
27
+ end
28
+ end
29
+
30
+ class EncryptorException < IOError; end
31
+ class KeyStoreException < IOError; end
32
+ end
33
+
34
+ class Nachos::Encryptor
35
+ include Nachos
36
+
37
+ # secret_key, secret_iv, data are encrypted and readable by the caller
38
+ # clear_data is writeable/readable by the caller
39
+ attr_reader :secret_key, :secret_iv
40
+ attr_accessor :clear_data, :encrypted_data
41
+ attr_reader :keystore
42
+
43
+ # pass an optional encrypted secret key & iv
44
+ # we'll decrypt it and store it for private use
45
+ def initialize(password, config = {})
46
+ self.config = config
47
+ @secret_key = @secret_iv = @clear_data = @encrypted_data = ''
48
+
49
+ begin
50
+ @public_key = OpenSSL::PKey::RSA.new(File.open(self.config[:public_key]))
51
+ @private_key =
52
+ OpenSSL::PKey::RSA.new(File.open(self.config[:private_key]), password)
53
+ @cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
54
+
55
+ @keystore = Nachos::KeyStore.new
56
+
57
+ keypair
58
+ rescue Errno::ENOENT
59
+ raise Nachos::EncryptorException, "Public or private key missing! " +
60
+ "(maybe both!)"
61
+ rescue Nachos::KeyStoreException => e
62
+ raise
63
+ rescue => e
64
+ raise Nachos::EncryptorException, "There was a problem loading or " +
65
+ "decrypting the keypair and/or keystore! (#{e})"
66
+ end
67
+ end
68
+
69
+ def keypair
70
+ if @keystore.secret_key.empty? || @keystore.secret_iv.empty?
71
+ begin
72
+ @clear_secret_key = @cipher.random_key
73
+ @clear_secret_iv = @cipher.random_iv
74
+
75
+ @secret_key = @keystore.secret_key encrypt(@clear_secret_key)
76
+ @secret_iv = @keystore.secret_iv = encrypt(@clear_secret_iv)
77
+ @keystore.save_secrets
78
+ rescue => e
79
+ raise Nachos::EncryptorException, "There was a problem generating" +
80
+ "random secret key and/or IV!"
81
+ end
82
+ else
83
+ p "foo"
84
+ @secret_key = @keystore.secret_key
85
+ @secret_iv = @keystore.secret_iv
86
+ end
87
+
88
+ @clear_secret_key = decrypt(@secret_key)
89
+ @clear_secret_iv = decrypt(@secret_iv)
90
+ end
91
+
92
+ def encrypt(str)
93
+ if str.empty?
94
+ raise Nachos::EncryptorException, "What do you want to encrypt?"
95
+ else
96
+ begin
97
+ @cipher.encrypt
98
+ str = @public_key.public_encrypt(str)
99
+ rescue => e
100
+ raise Nachos::EncryptorException, "Couldn't encrypt the data! (#{e})"
101
+ end
102
+ end
103
+ end
104
+
105
+ def decrypt(str)
106
+ if str.empty?
107
+ raise Nachos::EncryptorException, "What do you want to decrypt?"
108
+ else
109
+ begin
110
+ @cipher.decrypt
111
+ str = @private_key.private_decrypt(str)
112
+ rescue => e
113
+ raise Nachos::decryptorException, "Couldn't decrypt the data! (#{e})"
114
+ end
115
+ end
116
+ end
117
+
118
+ def load_data
119
+ begin
120
+ @encrypted_data = ''
121
+
122
+ File.open(self.config[:data_store], 'r') do |f|
123
+ @encrypted_data = @encrypted_data + f.gets
124
+ end
125
+
126
+ @encrypted_data.chomp!
127
+ @clear_data = decrypt(@encrypted_data)
128
+ rescue Errno::ENOENT
129
+ rescue => e
130
+ raise Nachos::EncryptorException, "There was a problem reading the " +
131
+ "data store! (#{e})"
132
+ end
133
+ end
134
+
135
+ def save_data
136
+ if @encrypted_data.empty?
137
+ encrypt
138
+ end
139
+
140
+ begin
141
+ File.open(self.config[:data_store], 'w') do |f|
142
+ f.puts @encrypted_data
143
+ end
144
+ rescue
145
+ raise Nachos::EncryptorException, "There was a problem saving the data " +
146
+ "store!"
147
+ end
148
+ end
149
+ end
150
+
151
+ class Nachos::KeyStore
152
+ include Nachos
153
+
154
+ attr_accessor :secret_key, :secret_iv
155
+
156
+ def initialize
157
+ @secret_key = @secret_iv = ''
158
+ get_secrets
159
+ end
160
+
161
+ def get_secrets
162
+ begin
163
+ y_data = YAML::load(File.open(self.config[:secret_key]))
164
+
165
+ if y_data
166
+ @secret_key = Base64.decode64(y_data[:key])
167
+ @secret_iv = Base64.decode64(y_data[:iv])
168
+ end
169
+ # file was empty for some reason, we'll have to generate a new set.
170
+ # hope we didn't need to decrypt anything!
171
+ rescue Errno::ENOENT
172
+ # fail silently; we'll just generate a new set
173
+ rescue => e
174
+ raise Nachos::KeyStoreException, "There was a problem loading the " +
175
+ "keystore! (#{e})"
176
+ end
177
+ end
178
+
179
+ def save_secrets
180
+ stuff = {
181
+ :key => Base64.encode64(@secret_key),
182
+ :iv => Base64.encode64(@secret_iv)
183
+ }
184
+
185
+ begin
186
+ File.open(self.config[:secret_key], 'w') do |f|
187
+ f.puts stuff.to_yaml
188
+ end
189
+ rescue => e
190
+ raise Nachos::KeyStoreException, "There was a problem saving the " +
191
+ "keystore! (#{e})"
192
+ end
193
+ end
194
+ end
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ohlol-nachos
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.2"
5
+ platform: ruby
6
+ authors:
7
+ - Scott Smith
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-13 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Nachos is a Ruby library for managing an encrypted data store.
17
+ email: scott@ohlol.net
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - LICENSE
26
+ - README.markdown
27
+ - lib
28
+ - lib/nachos.rb
29
+ has_rdoc: false
30
+ homepage: http://github.com/ohlol/nachos"
31
+ post_install_message:
32
+ rdoc_options:
33
+ - --inline-source
34
+ - --charset=UTF-8
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: "0"
42
+ version:
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ requirements: []
50
+
51
+ rubyforge_project: nachos
52
+ rubygems_version: 1.2.0
53
+ signing_key:
54
+ specification_version: 2
55
+ summary: Nachos is a Ruby library for managing an encrypted data store.
56
+ test_files: []
57
+