Class: Imp::EncryptedTree

Inherits:
EncryptedFile show all
Includes:
Enumerable
Defined in:
lib/imp/encrypted_tree.rb

Overview

A tree loaded from an encrypted file.

All values are themselves encrypted with the key again. This doesn’t add additional security, but prevents them from appearing in memory in plaintext if avoidable. Note that any program designed specifically to tap into this programs memory will have no problem with this.

Instance Attribute Summary

Attributes inherited from EncryptedFile

#cont

Instance Method Summary collapse

Methods inherited from EncryptedFile

#close, #flush

Constructor Details

#initialize(passwd, file) ⇒ EncryptedTree

Creates a new tree / load an existing one from a file.

Parameters:

  • passwd (String)

    The password to decrypt the file. Discarded after this call (although the key is kept in memory)

  • file (String)

    The location of the file to decrypt. If this does not exist, a new tree is made.



25
26
27
28
29
30
# File 'lib/imp/encrypted_tree.rb', line 25

def initialize(passwd, file)
  super(passwd, file)
  if @cont == nil
    @cont = Tree.new
  end
end

Instance Method Details

#[](key) ⇒ String

Retrieves a node label following a forward-slash seperated list of edge labels.

Parameters:

  • key (String)

    The forward-slash seperated list of edge labels.

Returns:

  • (String)

    The decrypted value of the corresponding node label.



37
38
39
# File 'lib/imp/encrypted_tree.rb', line 37

def [](key)
  Crypto.decrypt(@key, @cont.descendant(key).val)
end

#[]=(key, val) ⇒ Object

Sets a node label corresponding to a forward-slash seperated list of edge labels.

Parameters:

  • key (String)

    The list of edge labels.

  • val (String)

    The value to set the node label to. This will be encrypted.



47
48
49
# File 'lib/imp/encrypted_tree.rb', line 47

def []=(key, val)
  @cont.descendant(key, true).val = Crypto.encrypt(@key, val)
end

#delete(key) ⇒ Object

Deletes a node corresponding to a forward-slash seperated list of edge labels.

Parameters:

  • key (String)

    The list of edge labels. Must be a valid key.



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/imp/encrypted_tree.rb', line 78

def delete(key)
  # We seperate the last key from the first keys.
  key = key.split('/')
  finalkey = key[-1]
  key = key[0...-1]
  
  # Instead of using descendant we reduce over the root. This also handels
  # the root being the parent node well.
  node = key.reduce(@cont, :[])
  node.delete finalkey
end

#each(keys = [], subtree = @cont) {|String, String| ... } ⇒ Object

Iterates over key/value pairs.

Parameters:

  • keys (Array<String>) (defaults to: [])

    A list of the keys followed to reach the current subtree.

  • subtree (Tree) (defaults to: @cont)

    The tree currently iterating over.

Yields:

  • (String, String)

    Key, value pairs where the key is a forward slash seperated string of edge labels. Values are not decrypted or processed.



59
60
61
62
63
64
65
# File 'lib/imp/encrypted_tree.rb', line 59

def each(keys = [], subtree = @cont, &block)
  # Yield the subtree's value unless it is the root.
  yield [keys.join('/'), subtree.val] unless keys == []
  subtree.each do |key, tree|
    each(keys + [key], tree, &block)
  end
end

#include?(item) ⇒ Boolean

Checks whether a tree contains a key.

Parameters:

  • item (String)

    The forward slash seperated string of edge labels.

Returns:

  • (Boolean)


70
71
72
# File 'lib/imp/encrypted_tree.rb', line 70

def include?(item)
  @cont.descendant(key) != nil
end

#password=(passwd) ⇒ Object

Sets a new password for the file.

Parameters:

  • The (String)

    new password to generate a key from.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/imp/encrypted_tree.rb', line 108

def password=(passwd)
  key = @key
  # Super call.
  EncryptedFile.instance_method(:password=).bind(self).call(passwd)
  # If the file is still being initialized, @cont may be nil. In this case
  # return.
  return unless @cont
  each do |k, v|
    # Don't change nil values.
    next unless v
    # Otherwise decrypt with the old key and encrypt with the new.
    # (Encryption is done automatically by #[]=)
    self[k] = Crypto.decrypt(key, v)
  end
end

#pruneObject

Iteratively removes any leaves with a nil value. Not terribly efficient but there is no need to be.



92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/imp/encrypted_tree.rb', line 92

def prune
  pruned = true
  while pruned
    pruned = false
    self.each do |key, value|
      if value == nil && @cont.descendant(key).leaf?
        delete(key)
        pruned = true
      end
    end
  end
end

#to_sString

Delegates to the tree for string representation.

Returns:

  • (String)

    The string representation of the tree.



127
128
129
# File 'lib/imp/encrypted_tree.rb', line 127

def to_s
  @cont.to_s
end