Class: SafeDb::Content

Inherits:
Object
  • Object
show all
Defined in:
lib/model/content.rb

Overview

This class both locks content, writing the ciphertext to a file, and unlocks content after reading ciphertext from a file.

It supports the encryption of large bodies of text or binary because it uses the efficient and effective AES asymmetric algorithm.

Class Method Summary collapse

Class Method Details

.lock_chapter(data_store, content_body) ⇒ Object

Lock the content body provided - place the resulting ciphertext inside a file named by a random identifier, then write this identifier along wih the initialization and encryption key into the provided key-value map (hash).

The content ciphertext derived from encrypting the body is stored in a file.

Parameters:

  • data_store (DataMap)

    either DataMap or DataStore containing the content id and random iv

  • content_body (String)

    content to encryt and the ciphertext will be stored



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/model/content.rb', line 71

def self.lock_chapter( data_store, content_body )

  branch_id = Identifier.derive_branch_id( Branch.to_token() )
  branch_indices_file = FileTree.branch_indices_filepath( branch_id )
  book_id = DataMap.new( branch_indices_file ).read( Indices::BRANCH_DATA, Indices::CURRENT_BRANCH_BOOK_ID )

  old_content_id = data_store[ Indices::CONTENT_IDENTIFIER ] if data_store.has_key?(Indices::CONTENT_IDENTIFIER)

  new_content_id = Identifier.get_random_identifier( Indices::CONTENT_ID_LENGTH )
  data_store.store( Indices::CONTENT_IDENTIFIER, new_content_id )

  new_chapter_crypt_path = FileTree.branch_crypts_filepath( book_id, branch_id, new_content_id )

  iv_base64 = KeyIV.new().for_storage()
  data_store.store( Indices::CONTENT_RANDOM_IV, iv_base64 )
  random_iv = KeyIV.in_binary( iv_base64 )

  crypt_key = Key.from_random()
  data_store.store( Indices::CRYPT_CIPHER_TEXT, crypt_key.to_char64() )

  lock_it( new_chapter_crypt_path, crypt_key, random_iv, content_body, TextChunk.crypt_header( book_id ) )

  unless old_content_id.nil?
    old_chapter_crypt_path = FileTree.branch_crypts_filepath( book_id, branch_id, old_content_id )
    File.delete( old_chapter_crypt_path )
  end

end

.lock_it(crypt_path, crypt_key, random_iv, content_body, crypt_header) ⇒ Object

Use the crypt key and random init vector to transform the plain text message into an encrypted ciphertext message.

Use the chunk of plain text (header) information along with the ciphertext and the expected file location at the crypt path to write out the crypt and header content into a file.

Parameters:

  • crypt_path (File)

    path to the crypt file holding the encrypted ciphertext

  • crypt_key (Key)

    the key used to (symmetrically) encrypt the content provided

  • random_iv (String)

    the random initialization vector for the encryption

  • content_body (String)

    content to encryt and the ciphertext will be stored

  • crypt_header (String)

    string that tops and tails the content’s ciphertext



114
115
116
117
118
119
# File 'lib/model/content.rb', line 114

def self.lock_it( crypt_path, crypt_key, random_iv, content_body, crypt_header )

  binary_ctext = crypt_key.do_encrypt_text( random_iv, content_body )
  binary_to_write( crypt_path, crypt_header, binary_ctext )

end

.lock_master(book_id, crypt_key, data_store, content_body) ⇒ Object

Lock the content body provided - place the resulting ciphertext inside a file named by a random identifier, then write this identifier along wih the initialization and encryption key into the provided key-value map (hash).

The content ciphertext derived from encrypting the body is stored in a file underneath the provided content header.

Finally

Parameters:

  • book_id (String)

    used to determine the book’s master crypt folder

  • crypt_key (Key)

    the key used to (symmetrically) encrypt the content provided

  • data_store (DataMap)

    either DataMap or DataStore containing the content id and random iv

  • content_body (String)

    content to encryt and the ciphertext will be stored



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/model/content.rb', line 46

def self.lock_master( book_id, crypt_key, data_store, content_body )

  content_id = Identifier.get_random_identifier( Indices::CONTENT_ID_LENGTH )
  data_store.set( Indices::CONTENT_IDENTIFIER, content_id )
  master_crypt_path = FileTree.master_crypts_filepath( book_id, content_id )
  iv_base64 = KeyIV.new().for_storage()
  data_store.set( Indices::CONTENT_RANDOM_IV, iv_base64 )
  random_iv = KeyIV.in_binary( iv_base64 )

  lock_it( master_crypt_path, crypt_key, random_iv, content_body, TextChunk.crypt_header( book_id ) )

end

.unlock_branch_chapter(data_store) ⇒ String

Use the content’s external id to find the ciphertext file that is to be unlocked. Then use the unlock key from the parameter along with the random IV that is inside the DataMap or DataStore to decrypt and return the ciphertext.

Parameters:

Returns:

  • (String)

    the resulting decrypted text that was encrypted with the parameter key



129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/model/content.rb', line 129

def self.unlock_branch_chapter( data_store )

  branch_id = Identifier.derive_branch_id( Branch.to_token() )
  branch_indices_file = FileTree.branch_indices_filepath( branch_id )
  book_id = DataMap.new( branch_indices_file ).read( Indices::BRANCH_DATA, Indices::CURRENT_BRANCH_BOOK_ID )

  content_id = data_store[ Indices::CONTENT_IDENTIFIER ]
  crypt_key = Key.from_char64( data_store[ Indices::CRYPT_CIPHER_TEXT ] )
  random_iv = KeyIV.in_binary( data_store[ Indices::CONTENT_RANDOM_IV ] )

  crypt_path = FileTree.branch_crypts_filepath( book_id, branch_id, content_id )
  return DataStore.from_json( unlock_it( crypt_path, crypt_key, random_iv ) )

end

.unlock_it(crypt_path, unlock_key, random_iv) ⇒ String

Use the content’s external id to find the ciphertext file that is to be unlocked. Then use the unlock key from the parameter along with the random IV that is inside the DataMap or DataStore to decrypt and return the ciphertext.

Parameters:

  • crypt_path (File)

    path to the crypt file holding the encrypted ciphertext

  • unlock_key (Key)

    symmetric key that was used to encrypt the ciphertext

  • random_iv (String)

    the random initialization vector for the encryption

Returns:

  • (String)

    the resulting decrypted text that was encrypted with the parameter key



173
174
175
176
177
# File 'lib/model/content.rb', line 173

def self.unlock_it( crypt_path, unlock_key, random_iv )

  return unlock_key.do_decrypt_text( random_iv, binary_from_read( crypt_path ) )

end

.unlock_master(unlock_key, data_store) ⇒ String

Use the content’s external id to find the ciphertext file that is to be unlocked. Then use the unlock key from the parameter along with the random IV that is inside the DataMap or DataStore to decrypt and return the ciphertext.

Parameters:

  • unlock_key (Key)

    symmetric key that was used to encrypt the ciphertext

  • data_store (DataMap)

    either DataMap or DataStore containing content id and random iv

Returns:

  • (String)

    the resulting decrypted text that was encrypted with the parameter key



21
22
23
24
25
26
27
28
# File 'lib/model/content.rb', line 21

def self.unlock_master( unlock_key, data_store )

  book_id = data_store.section()
  crypt_path = FileTree.master_crypts_filepath( book_id, data_store.get( Indices::CONTENT_IDENTIFIER ) )
  random_iv = KeyIV.in_binary( data_store.get( Indices::CONTENT_RANDOM_IV ) )
  return unlock_it( crypt_path, unlock_key, random_iv )

end

.unlock_master_chapter(book_id, data_store) ⇒ String

Use the content’s external id to find the ciphertext file that is to be unlocked. Then use the unlock key from the parameter along with the random IV that is inside the DataMap or DataStore to decrypt and return the ciphertext.

Parameters:

  • book_id (String)

    ID of the book to unlock the chapter of

  • data_store (DataMap)

    either DataMap or DataStore containing content id and random iv

Returns:

  • (String)

    the resulting decrypted text that was encrypted with the parameter key



153
154
155
156
157
158
159
160
161
# File 'lib/model/content.rb', line 153

def self.unlock_master_chapter( book_id, data_store )

  random_iv = KeyIV.in_binary( data_store[ Indices::CONTENT_RANDOM_IV ] )
  crypt_key = Key.from_char64( data_store[ Indices::CRYPT_CIPHER_TEXT ] )
  content_id = data_store[ Indices::CONTENT_IDENTIFIER ]
  crypt_path = FileTree.master_crypts_filepath( book_id, content_id )
  return DataStore.from_json( unlock_it( crypt_path, crypt_key, random_iv ) )

end