class Ssbx::Box
This is the encryption logic. This uses File
to read and write data, but the actual encryption logic is in here.
Constants
- SYMETRIC_CIPHER_NAME
The symetric cipher name used for the symetric parts of this algorithm.
Public Class Methods
new(file)
click to toggle source
Create a new box.
# File lib/ssbx/box.rb, line 15 def initialize(file) if file.is_a? IO @file = File.new @file.read(file) elsif file.is_a? Ssbx::File @file = file else raise Exception.new("Unsupported input type #{file.class}. Try Ssbx::File or IO.") end end
Public Instance Methods
list()
click to toggle source
# File lib/ssbx/box.rb, line 110 def list @file.keys.map { |r| r[0] } end
read(instream, userid, password)
click to toggle source
Decrypt the data user the given user ID and password.
# File lib/ssbx/box.rb, line 78 def read(instream, userid, password) @file.read(instream) userrecord = @file.keys.select { |k| k[0] == userid } # Find or get our user record. if userrecord.length == 0 raise Exception.new("User #{userid} not found in the file.") else userrecord = userrecord[0] end privkey = OpenSSL::PKey::RSA.new(userrecord[1], password) cipher = OpenSSL::Cipher.new(SYMETRIC_CIPHER_NAME) cipher.decrypt cipher.key = privkey.private_decrypt(userrecord[3]) cipher.iv = userrecord[4] data = cipher.update(@file.data) data += cipher.final data end
remove_user(user)
click to toggle source
Remove a user from the memory representation of this file. You must do a valid write of the file to force credential rotation and remove the user from the file on disk.
# File lib/ssbx/box.rb, line 106 def remove_user(user) @file.keys.reject! { |k| k[0] == user } end
write(outstream, userid, password, data)
click to toggle source
Write the data given the userid and password. If the user is not in the file, they are added.
# File lib/ssbx/box.rb, line 28 def write(outstream, userid, password, data) userrecord = @file.keys.select { |k| k[0] == userid } # Find or get our user record. if userrecord.length == 0 privkey = OpenSSL::PKey::RSA.new(2048) userrecord = [ userid ] userrecord << privkey.to_pem(OpenSSL::Cipher.new(SYMETRIC_CIPHER_NAME), password) userrecord << privkey.public_key.to_pem userrecord << '' # Private Key userrecord << '' # Initialization Vector. @file.keys << userrecord else userrecord = userrecord[0] privkey = OpenSSL::PKey::RSA.new(2048) # Rotate user record entries. userrecord[1] = privkey.to_pem(OpenSSL::Cipher.new(SYMETRIC_CIPHER_NAME), password) userrecord[2] = privkey.public_key.to_pem userrecord[3] = '' # Private Key userrecord[4] = '' # Initialization Vector. end # Make semetric cipher. cipher = OpenSSL::Cipher.new(SYMETRIC_CIPHER_NAME) cipher.encrypt key = cipher.random_key iv = cipher.random_iv # Encrypt data with key. ciphertext = cipher.update(data) ciphertext += cipher.final @file.data = ciphertext # Now update all key records with the new key and iv. @file.keys.each do |key_rec| # k[0 id, 1 priv, 2 pub, 3 key, 4 iv] k = OpenSSL::PKey::RSA.new(key_rec[2]) key_rec[3] = k.public_encrypt(key) key_rec[4] = iv end @file.write(outstream) end