opensecret 0.0.962 → 0.0.988
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -10
- data/bin/opensecret +3 -4
- data/bin/ops +5 -0
- data/lib/extension/string.rb +114 -0
- data/lib/factbase/facts.opensecret.io.ini +9 -21
- data/lib/interprete/begin.rb +232 -0
- data/lib/interprete/cmd.rb +621 -0
- data/lib/{plugins/usecases/unlock.rb → interprete/export.rb} +25 -70
- data/lib/interprete/init.rb +205 -0
- data/lib/interprete/key.rb +119 -0
- data/lib/interprete/open.rb +148 -0
- data/lib/{plugins/usecases → interprete}/put.rb +19 -6
- data/lib/{plugins/usecases → interprete}/safe.rb +2 -1
- data/lib/{plugins/usecases/lock.rb → interprete/seal.rb} +24 -34
- data/lib/interprete/set.rb +46 -0
- data/lib/interprete/use.rb +43 -0
- data/lib/interpreter.rb +165 -0
- data/lib/keytools/binary.map.rb +245 -0
- data/lib/keytools/digester.rb +245 -0
- data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +179 -0
- data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +190 -0
- data/lib/keytools/doc.star.schema.strategy.txt +77 -0
- data/lib/keytools/doc.using.pbkdf2.kdf.ruby +95 -0
- data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +266 -0
- data/lib/keytools/kdf.bcrypt.rb +180 -0
- data/lib/keytools/kdf.pbkdf2.rb +164 -0
- data/lib/keytools/key.data.rb +227 -0
- data/lib/keytools/key.derivation.rb +341 -0
- data/lib/keytools/key.module.rb +140 -0
- data/lib/keytools/key.rb +481 -0
- data/lib/logging/gem.logging.rb +1 -2
- data/lib/modules/cryptology.md +43 -0
- data/lib/{plugins/ciphers → modules/cryptology}/aes-256.rb +6 -0
- data/lib/{crypto → modules/cryptology}/amalgam.rb +6 -0
- data/lib/modules/cryptology/blowfish.rb +130 -0
- data/lib/modules/cryptology/cipher.rb +207 -0
- data/lib/modules/cryptology/collect.rb +118 -0
- data/lib/{plugins → modules/cryptology}/crypt.io.rb +5 -0
- data/lib/{crypto → modules/cryptology}/engineer.rb +7 -1
- data/lib/{crypto → modules/cryptology}/open.bcrypt.rb +0 -0
- data/lib/modules/mappers/collateral.rb +282 -0
- data/lib/modules/mappers/dictionary.rb +288 -0
- data/lib/modules/mappers/envelope.rb +127 -0
- data/lib/modules/mappers/settings.rb +170 -0
- data/lib/modules/storage/coldstore.rb +186 -0
- data/lib/{opensecret/plugins.io/git/git.flow.rb → modules/storage/git.store.rb} +11 -0
- data/lib/notepad/scratch.pad.rb +17 -0
- data/lib/session/fact.finder.rb +13 -0
- data/lib/session/require.gem.rb +5 -0
- data/lib/store-commands.txt +180 -0
- data/lib/version.rb +1 -1
- data/opensecret.gemspec +5 -6
- metadata +74 -29
- data/lib/crypto/blowfish.rb +0 -85
- data/lib/crypto/collect.rb +0 -140
- data/lib/crypto/verify.rb +0 -33
- data/lib/opensecret.rb +0 -236
- data/lib/plugins/cipher.rb +0 -203
- data/lib/plugins/ciphers/blowfish.rb +0 -126
- data/lib/plugins/coldstore.rb +0 -181
- data/lib/plugins/envelope.rb +0 -116
- data/lib/plugins/secrets.uc.rb +0 -94
- data/lib/plugins/usecase.rb +0 -239
- data/lib/plugins/usecases/init.rb +0 -145
- data/lib/plugins/usecases/open.rb +0 -108
- data/lib/session/attributes.rb +0 -279
- data/lib/session/dictionary.rb +0 -191
- data/lib/session/file.path.rb +0 -53
- data/lib/session/session.rb +0 -80
@@ -1,126 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
module OpenSecret
|
5
|
-
|
6
|
-
# Blowfish is a symmetric encryption cipher which inherits extends the
|
7
|
-
# {OpenSecret::Cipher} base class in order to implement plug and play
|
8
|
-
# symmetric encryption.
|
9
|
-
#
|
10
|
-
# Blowfish is still uncrackable - however its successor (TwoFish) has
|
11
|
-
# been reinforced to counter the growth of super-computer brute force
|
12
|
-
# resources.
|
13
|
-
class Blowfish < OpenSecret::Cipher
|
14
|
-
|
15
|
-
|
16
|
-
# The blowfish cipher id constant is used to +initialize+
|
17
|
-
# an {OpenSSL::Cipher} class instance.
|
18
|
-
BLOWFISH_CIPHER_ID = "BF-ECB"
|
19
|
-
|
20
|
-
|
21
|
-
# Blowfish constrains the length of +incoming plain text+ forcing it
|
22
|
-
# to be a multiple of eight (8).
|
23
|
-
BLOWFISH_BLOCK_LEN = 8
|
24
|
-
|
25
|
-
|
26
|
-
# Encrypt the (plain) text parameter using the symmetric encryption key
|
27
|
-
# specified in the second parameter and return the base64 encoded
|
28
|
-
# representation of the cipher text.
|
29
|
-
#
|
30
|
-
# Blowfish is a block cipher meaning it needs both the key and the plain
|
31
|
-
# text inputted to conform to a divisible block length.
|
32
|
-
#
|
33
|
-
# Don't worry about this block length requirement as this encrption method
|
34
|
-
# takes care of it and its sister method {self.decryptor} will also perform
|
35
|
-
# the correct reversal activities to give you back the original plain text.
|
36
|
-
#
|
37
|
-
# {Base64.urlsafe_encode64} facilitates the ciphertext encoding returning text that
|
38
|
-
# is safe to write to a file.
|
39
|
-
#
|
40
|
-
# @param plain_text [String]
|
41
|
-
# This parameter should be the non-nil text to encrypt using Blowfish.
|
42
|
-
# Before encryption the text will be padded using a text string from
|
43
|
-
# the {OpenSecret::Cipher::TEXT_PADDER} constant until it results in
|
44
|
-
# a string with the required block length.
|
45
|
-
#
|
46
|
-
# @param encryption_key [String]
|
47
|
-
# send a long strong unencoded key which does not have to be a multiple of
|
48
|
-
# eight even though the algorithm demands it. Before the encryption this key
|
49
|
-
# will be passed through a digest using behaviour from {Digest::SHA256.digest}
|
50
|
-
#
|
51
|
-
# This behaviour returns a key whose length is a multiple of eight.
|
52
|
-
#
|
53
|
-
# @return [String] base64 representation of blowfish crypted ciphertext
|
54
|
-
#
|
55
|
-
# @raise [OpenSSL::Cipher::CipherError]
|
56
|
-
# An (encryption) <tt>key length too short</tt> error is raised for short keys.
|
57
|
-
def encryptor plain_text, encryption_key
|
58
|
-
|
59
|
-
shortkey_msg = "The #{encryption_key.length} character encryption key is too short."
|
60
|
-
raise ArgumentError, shortkey_msg unless encryption_key.length > 8
|
61
|
-
log.info(x) { "os blowfish request to encrypt plain text with provided key." }
|
62
|
-
|
63
|
-
block_txt = plain_text
|
64
|
-
block_txt += CryptIO::TEXT_PADDER until block_txt.bytesize % OpenSecret::Blowfish::BLOWFISH_BLOCK_LEN == 0
|
65
|
-
raw_stretched_key = Digest::SHA256.digest(encryption_key)
|
66
|
-
|
67
|
-
blowfish_encryptor = OpenSSL::Cipher.new(OpenSecret::Blowfish::BLOWFISH_CIPHER_ID).encrypt
|
68
|
-
blowfish_encryptor.key = raw_stretched_key
|
69
|
-
return blowfish_encryptor.update(block_txt) << blowfish_encryptor.final
|
70
|
-
|
71
|
-
end
|
72
|
-
|
73
|
-
|
74
|
-
# Decrypt the cipher text parameter using the symmetric decryption key
|
75
|
-
# specified in the second parameter. The cipher text is expected to have
|
76
|
-
# already been decoded if necessary.
|
77
|
-
#
|
78
|
-
# Its okay to use a bespoke encryptor - just ensure you encode the result
|
79
|
-
# and override the padding constant.
|
80
|
-
#
|
81
|
-
# Blowfish is a block cipher meaning it needs both the key and the plain
|
82
|
-
# text inputted to conform to a divisible block length.
|
83
|
-
#
|
84
|
-
# Don't worry about this block length requirement as this decrption method
|
85
|
-
# takes care of the reversing the activities carried out by {self.encryptor}.
|
86
|
-
#
|
87
|
-
# @param cipher_text [String]
|
88
|
-
# This incoming cipher text should already be encoded but it
|
89
|
-
# will <b>chomped and stripped upon receipt</b> followed by
|
90
|
-
# decryption using the Blowfish algorithm.
|
91
|
-
#
|
92
|
-
# @param decryption_key [String]
|
93
|
-
# Send the same key that was used during the encryption phase. The encryption
|
94
|
-
# phase passed the key through the {Digest::SHA256.digest} digest so here
|
95
|
-
# the decryption does the exact same thing.
|
96
|
-
#
|
97
|
-
# The digest processing guarantees a symmetric key whose length conforms to
|
98
|
-
# the multiple of eight block length requirement.
|
99
|
-
#
|
100
|
-
# @return [String]
|
101
|
-
# After decoding and decryption the plain text string will still be padded,
|
102
|
-
# +but not with spaces+. The unlikely to occur padding string constant used
|
103
|
-
# is the {OpenSecret::Cipher::TEXT_PADDER}.
|
104
|
-
#
|
105
|
-
# If the plaintext ended with spaces these would be preserved. After padder
|
106
|
-
# removal any trailing spaces will be preserved in the returned plain text.
|
107
|
-
#
|
108
|
-
def decryptor cipher_text, decryption_key
|
109
|
-
|
110
|
-
digested_key = Digest::SHA256.digest decryption_key
|
111
|
-
|
112
|
-
decrypt_tool = OpenSSL::Cipher.new(OpenSecret::Blowfish::BLOWFISH_CIPHER_ID).decrypt
|
113
|
-
decrypt_tool.key = digested_key
|
114
|
-
|
115
|
-
padded_plaintxt = decrypt_tool.update(cipher_text) << decrypt_tool.final
|
116
|
-
pad_begin_index = padded_plaintxt.index CryptIO::TEXT_PADDER
|
117
|
-
return padded_plaintxt if pad_begin_index.nil?
|
118
|
-
return padded_plaintxt[ 0 .. (pad_begin_index-1) ]
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
end
|
data/lib/plugins/coldstore.rb
DELETED
@@ -1,181 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
module OpenSecret
|
5
|
-
|
6
|
-
# Cold storage can sync repositories with a <b>bias during conflicts</b>
|
7
|
-
# either to the <em>remote repository</em> <b>when pulling</b>, and then
|
8
|
-
# conversely to the <em>local reposiory</em> <b>when pushing</b>.
|
9
|
-
#
|
10
|
-
# In between the sync operations a ColdStore can create, read, update and
|
11
|
-
# delete to and from the local mirror.
|
12
|
-
#
|
13
|
-
# == ColdStore | Use Cases
|
14
|
-
#
|
15
|
-
# Any <b>self-respecting coldstore</b> must, after initialization, provide
|
16
|
-
# some basic (and mandatory) behaviour.
|
17
|
-
#
|
18
|
-
# These include
|
19
|
-
#
|
20
|
-
# - <b>read</b> - reading text from a (possibly unavailable) frozen path
|
21
|
-
# - <b>write</b> - writing text (effectively freezing it) to a path
|
22
|
-
# - <b>pull</b> - sync with a <b>collision bias</b> that favours the remote mirror
|
23
|
-
# - <b>push</b> - sync with a <b>collision bias</b> that favours the local mirror
|
24
|
-
#
|
25
|
-
# <b>Cold Storage</b> is borrowed from BitCoin and represents offline storage
|
26
|
-
# for keys and crypts. opensecret separates keys and crypts so that you can
|
27
|
-
# transfer and share secrets by moving keys (not the crypts).
|
28
|
-
#
|
29
|
-
# == Houses and Gold Bullion
|
30
|
-
#
|
31
|
-
# You don't carry houses or gold bullion around to rent, share or transfer
|
32
|
-
# their ownership.
|
33
|
-
#
|
34
|
-
# You copy keys to rent secrets and when the tenure is up (or you change your
|
35
|
-
# mind) you revoke access with a metaphorical lock change.
|
36
|
-
#
|
37
|
-
# opensecret embodies concepts like an owner who rents as opposed to a change
|
38
|
-
# in ownership.
|
39
|
-
#
|
40
|
-
# == trade secrets | commoditizing secrets
|
41
|
-
#
|
42
|
-
# opensecret is a conduit through which secrets can be bought and sold.
|
43
|
-
#
|
44
|
-
# It commoditizes secrets so that they can be owned, traded, leased and
|
45
|
-
# auctioned. Options to acquire or relinquish them at set prices can easily
|
46
|
-
# be taken out.
|
47
|
-
class ColdStore
|
48
|
-
|
49
|
-
# @param base_path [String]
|
50
|
-
# path to the store's (mirror) base directory.
|
51
|
-
# If the denoted directory does not exist an attempt will be made to
|
52
|
-
# create it. If a file exists at this path an error will be thrown.
|
53
|
-
#
|
54
|
-
# @param domain [String]
|
55
|
-
# the domain is an identifier (and namespace) denoting which opensecret
|
56
|
-
# "account" is being accessed. opensecret allows the creation and use of
|
57
|
-
# multiple domains.
|
58
|
-
def initialize local_path
|
59
|
-
|
60
|
-
@store_path = local_path
|
61
|
-
FileUtils.mkdir_p @store_path
|
62
|
-
|
63
|
-
end
|
64
|
-
|
65
|
-
|
66
|
-
# Read the file frozen (in this store mirror) at this path and
|
67
|
-
# return its contents.
|
68
|
-
#
|
69
|
-
# Coldstores are usually frozen offline (offmachine) so for this
|
70
|
-
# to work the {ColdStore.pull} behaviour must have executed to
|
71
|
-
# create a local store mirror. This method reads from that mirror.
|
72
|
-
#
|
73
|
-
# @param from_path [String]
|
74
|
-
# read the file frozen at this path and return its contents
|
75
|
-
# so that the defreeze process can begin.
|
76
|
-
#
|
77
|
-
# This path is relative to the base of the store defined in
|
78
|
-
# the constructor.
|
79
|
-
#
|
80
|
-
# @return [String]
|
81
|
-
# return the text frozen in a file at the denoted local path
|
82
|
-
#
|
83
|
-
# nil is reurned if no file can be found in the local mirror
|
84
|
-
# at the configured path
|
85
|
-
#
|
86
|
-
# @raise [RuntimeError]
|
87
|
-
# unless the path exists in this coldstore and that path is
|
88
|
-
# a directory (as opposed to a file).
|
89
|
-
#
|
90
|
-
# @raise [ArgumentError]
|
91
|
-
# if more than one file match is made at the path specified.
|
92
|
-
def read from_path
|
93
|
-
|
94
|
-
frozen_filepath = File.join @store_path, from_path
|
95
|
-
frozen_dir_path = File.dirname(frozen_filepath)
|
96
|
-
|
97
|
-
log.info(x) { "Coldstore will search in folder [#{frozen_dir_path.hr_path}]" }
|
98
|
-
|
99
|
-
exists_msg = "Directory #{frozen_dir_path} does not exist in store."
|
100
|
-
is_dir_msg = "Path #{frozen_dir_path} should be a directory (not a file)."
|
101
|
-
raise RuntimeError, exists_msg unless File.exists? frozen_dir_path
|
102
|
-
raise RuntimeError, is_dir_msg unless File.directory? frozen_dir_path
|
103
|
-
|
104
|
-
full_filepath = ""
|
105
|
-
file_matched = false
|
106
|
-
|
107
|
-
Dir.glob("#{frozen_dir_path}/**/*.os.txt").each do |matched_path|
|
108
|
-
|
109
|
-
log.info(x) { "Coldstore search with [#{from_path}] has matched [#{matched_path.hr_path}]" }
|
110
|
-
log.info(x) { "Ignore directory at [#{matched_path.hr_path}]." } if File.directory? matched_path
|
111
|
-
next if File.directory? matched_path
|
112
|
-
|
113
|
-
two_match_msg = "More than one file matched. The second is #{matched_path}."
|
114
|
-
raise ArgumentError, two_match_msg if file_matched
|
115
|
-
file_matched = true
|
116
|
-
|
117
|
-
full_filepath = matched_path
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
no_file_msg = "Coldstore could not find path [#{from_path}] from [#{@store_path}]."
|
122
|
-
raise RuntimeError, no_file_msg unless file_matched
|
123
|
-
|
124
|
-
log.info(x) { "Coldstore matched exactly one envelope at [#{full_filepath.hr_path}]." }
|
125
|
-
return File.read full_filepath
|
126
|
-
|
127
|
-
end
|
128
|
-
|
129
|
-
|
130
|
-
# Write (freeze) the text into a file at the denoted path. The
|
131
|
-
# folder path will be created if need be.
|
132
|
-
#
|
133
|
-
# Coldstores are usually frozen offline (offmachine) so after
|
134
|
-
# this method completes the {ColdStore.push} behaviour must be
|
135
|
-
# executed to synchronize the local coldstore freezer with the
|
136
|
-
# remote mirror.
|
137
|
-
#
|
138
|
-
# @param this_text [String]
|
139
|
-
# this is the text that needs to be frozen into the local and
|
140
|
-
# subsequently the remote coldstore freezer.
|
141
|
-
#
|
142
|
-
# @param to_path [String]
|
143
|
-
# write the text (effectively freezing it) into the file at
|
144
|
-
# this path. An attempt will be made to put down the necessary
|
145
|
-
# directory structure.
|
146
|
-
#
|
147
|
-
# This path is relative to the base of the store defined in
|
148
|
-
# the constructor.
|
149
|
-
def write this_text, to_path
|
150
|
-
|
151
|
-
freeze_filepath = File.join @store_path, to_path
|
152
|
-
|
153
|
-
log.info(x) { "ColdStore freezing #{this_text.length} characters of worthless text."}
|
154
|
-
log.info(x) { "ColdStore freeze file path => #{freeze_filepath.hr_path}"}
|
155
|
-
|
156
|
-
FileUtils.mkdir_p(File.dirname(freeze_filepath))
|
157
|
-
File.write freeze_filepath, this_text
|
158
|
-
|
159
|
-
end
|
160
|
-
|
161
|
-
|
162
|
-
private
|
163
|
-
|
164
|
-
# @todo - write sync (with a local bias during conflicts)
|
165
|
-
# The open up to the public (published) api.
|
166
|
-
def push
|
167
|
-
|
168
|
-
|
169
|
-
end
|
170
|
-
|
171
|
-
# @todo - write sync (with a rmote bias during conflicts)
|
172
|
-
# The open up to the public (published) api.
|
173
|
-
def pull
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
|
178
|
-
end
|
179
|
-
|
180
|
-
|
181
|
-
end
|
data/lib/plugins/envelope.rb
DELETED
@@ -1,116 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
module OpenSecret
|
5
|
-
|
6
|
-
require 'json'
|
7
|
-
|
8
|
-
# An envelope knows how to manipulate a JSON backed data structure
|
9
|
-
# (put, add etc) <b>after reading and then decrypting it</b> from a
|
10
|
-
# file and <b>before encrypting and then writing it</b> to a file.
|
11
|
-
#
|
12
|
-
# It provides behaviour to which we can create, append (add), update
|
13
|
-
# (change), read parts and delete essentially two structures
|
14
|
-
#
|
15
|
-
# - a collection of name/value pairs
|
16
|
-
# - an ordered list of values
|
17
|
-
#
|
18
|
-
# == JSON is Not Exposed in the Interface
|
19
|
-
#
|
20
|
-
# An envelope doesn't expose the data format used in the implementation
|
21
|
-
# allowing this to be changed seamlessly to YAMl or other formats.
|
22
|
-
#
|
23
|
-
# == Symmetric Encryption and Decryption
|
24
|
-
#
|
25
|
-
# An envelope supports operations to <b>read from</b> and <b>write to</b>
|
26
|
-
# a known filepath and with a symmetric key it can
|
27
|
-
#
|
28
|
-
# - decrypt <b>after reading from</b> a file and
|
29
|
-
# - encrypt <b>before writing to</b> a (the same) file
|
30
|
-
#
|
31
|
-
# == Hashes as the Primary Data Structure
|
32
|
-
#
|
33
|
-
# Envelope extends {Hash} as the core data structure for holding
|
34
|
-
#
|
35
|
-
# - strings
|
36
|
-
# - arrays
|
37
|
-
# - other hashes
|
38
|
-
# - booleans
|
39
|
-
# - integers and floats
|
40
|
-
class Envelope < Hash
|
41
|
-
|
42
|
-
|
43
|
-
# Read and inject into this envelope, the data structure found in a
|
44
|
-
# file at the path specified in the first parameter.
|
45
|
-
#
|
46
|
-
# Symmetric cryptography is mandatory for the envelope so we must
|
47
|
-
# <b>encrypt before writing</b> and <b>decrypt after reading</b>.
|
48
|
-
#
|
49
|
-
# An argument error will result if a suitable key is not provided.
|
50
|
-
#
|
51
|
-
# If the file does not exist (denoting the first read) all this method
|
52
|
-
# does is to stash the filepath as an instance variable and igore the
|
53
|
-
# decryption key which can be nil (or ommitted).
|
54
|
-
#
|
55
|
-
# @param the_filepath [String]
|
56
|
-
# absolute path to the file which acts as the persistent mirror to
|
57
|
-
# this data structure envelope.
|
58
|
-
#
|
59
|
-
# @param decryption_key [String]
|
60
|
-
# encryption at rest is a given so this mandatory parameter must
|
61
|
-
# contain a robust symmetric decryption key. The key will be used
|
62
|
-
# for decryption after the read and it will not linger (ie not cached
|
63
|
-
# as an instance variable).
|
64
|
-
#
|
65
|
-
# @raise [ArgumentError] if the decryption key is not robust enough.
|
66
|
-
def read the_filepath, decryption_key = nil
|
67
|
-
|
68
|
-
@filepath = the_filepath
|
69
|
-
return unless File.exists? @filepath
|
70
|
-
|
71
|
-
cipher_text = Base64.decode64( File.read( @filepath ).strip )
|
72
|
-
plain_text = OpenSecret::Blowfish.new.decryptor( cipher_text, decryption_key )
|
73
|
-
|
74
|
-
puts ""
|
75
|
-
puts "=== ============================"
|
76
|
-
puts "=== Envelope After Decryption"
|
77
|
-
puts "=== ============================"
|
78
|
-
puts plain_text
|
79
|
-
puts "=== ============================"
|
80
|
-
puts ""
|
81
|
-
|
82
|
-
data_structure = JSON.parse plain_text
|
83
|
-
self.merge! data_structure
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
|
88
|
-
# Write the data in this envelope hash map into a file-system
|
89
|
-
# backed mirror whose path was specified in the {self.read} method.
|
90
|
-
#
|
91
|
-
# Technology for encryption at rest is supported by this dictionary
|
92
|
-
# and to this aim, please endeavour to post a robust symmetric
|
93
|
-
# encryption key.
|
94
|
-
#
|
95
|
-
# Calling this {self.write} method when the file at the prescribed path
|
96
|
-
# does not exist results in the directory structure being created
|
97
|
-
# (if necessary) and then the encrypted file being written.
|
98
|
-
#
|
99
|
-
# @param encryption_key [String]
|
100
|
-
# encryption at rest is a given so this mandatory parameter must
|
101
|
-
# contain a robust symmetric encryption key. The symmetric key will
|
102
|
-
# be used for the decryption after the read. Note that the decryption
|
103
|
-
# key does not linger meaning it isn't cached in an instance variable.
|
104
|
-
def write encryption_key
|
105
|
-
|
106
|
-
FileUtils.mkdir_p(File.dirname(@filepath))
|
107
|
-
cipher_text = Base64.encode64 Blowfish.new.encryptor( self.to_json, encryption_key )
|
108
|
-
File.write @filepath, cipher_text
|
109
|
-
|
110
|
-
end
|
111
|
-
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
|
-
|
116
|
-
end
|
data/lib/plugins/secrets.uc.rb
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
# coding: utf-8
|
3
|
-
|
4
|
-
module OpenSecret
|
5
|
-
|
6
|
-
# The parent OpenSecret use case is designed to be extended by the cli
|
7
|
-
# (command line) use cases like {OpenSecret::Open}, {OpenSecret::Put} and
|
8
|
-
# {OpenSecret::Lock} because it describes behaviour common to at least two
|
9
|
-
# (but usually more) of the use cases.
|
10
|
-
#
|
11
|
-
# == Behaviour Reuse
|
12
|
-
#
|
13
|
-
# Behaviour that is reusable by any use case fits within {OpenSession::UseCase}
|
14
|
-
# whilst behaviour common to two or more {OpenSecret} use cases belongs here.
|
15
|
-
# Therefore the only behaviour in the named use case is detailed and must belong
|
16
|
-
# solely to it.
|
17
|
-
#
|
18
|
-
# == Fact Reuse
|
19
|
-
#
|
20
|
-
# Fact evaluation rules are born with reuse in mind. <b>Use case facts</b>
|
21
|
-
# are evaluated when they belong to either the class or its parent or any
|
22
|
-
# ancestors.
|
23
|
-
class SecretsUseCase < OpenSession::UseCase
|
24
|
-
|
25
|
-
@@context_name = "opensecret"
|
26
|
-
|
27
|
-
# Get the envelope that <b>was opened</b> by the open command but
|
28
|
-
# <b>not locked</b> with the lock command.
|
29
|
-
#
|
30
|
-
# @return [Envelope]
|
31
|
-
# return the Envelope that has been opened. The state carried alongside an
|
32
|
-
# open envelope is an id, an encryption key and a filepath all inside the
|
33
|
-
# userhome configuration file.
|
34
|
-
def get_envelope
|
35
|
-
|
36
|
-
encrypt_key = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_keyname]
|
37
|
-
rel_filepath = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_pathname]
|
38
|
-
|
39
|
-
put_filepath = File.join @c[:open][:open_dirpath], rel_filepath
|
40
|
-
the_envelope = Envelope.new
|
41
|
-
the_envelope.read put_filepath, encrypt_key
|
42
|
-
return the_envelope
|
43
|
-
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
# Unlock the {OpenSSL::PKey::RSA} private key and return the cipher object
|
48
|
-
# usable for asymmetric encryption, decryption, signing and signature
|
49
|
-
# verification use cases.
|
50
|
-
#
|
51
|
-
# The returned private key can be used to generate its twin public key
|
52
|
-
# and should be used to verify the same public key as (if) and when the
|
53
|
-
# need arises.
|
54
|
-
#
|
55
|
-
# @param locked_private_key [String]
|
56
|
-
# the locked up private key ciphertext
|
57
|
-
#
|
58
|
-
# @param unlock_key [String]
|
59
|
-
# the symmetric encryption key that can be used to unlock the private
|
60
|
-
# key ciphertext in the first parameter.
|
61
|
-
#
|
62
|
-
# @return [OpenSSL::PKey::RSA]
|
63
|
-
# return the {OpenSSL::PKey::RSA} private key that will be
|
64
|
-
# usable for asymmetric encryption, decryption, signing and signature
|
65
|
-
# verification.
|
66
|
-
def unlock_private_key locked_private_key, unlock_key
|
67
|
-
return OpenSSL::PKey::RSA.new locked_private_key, unlock_key
|
68
|
-
end
|
69
|
-
|
70
|
-
|
71
|
-
# Return the {OpenSSL::PKey::RSA} private key which is a cipher object
|
72
|
-
# usable for asymmetric encryption, decryption, signing and signature
|
73
|
-
# verification use cases.
|
74
|
-
#
|
75
|
-
# The returned private key can be used to generate its twin public key
|
76
|
-
# and should be used to verify the same public key as (if) and when the
|
77
|
-
# need arises.
|
78
|
-
#
|
79
|
-
# @param private_key_text [String]
|
80
|
-
# the private key plain text
|
81
|
-
#
|
82
|
-
# @return [OpenSSL::PKey::RSA]
|
83
|
-
# return the {OpenSSL::PKey::RSA} private key that will be
|
84
|
-
# usable for asymmetric encryption, decryption, signing and signature
|
85
|
-
# verification.
|
86
|
-
def to_private_key private_key_text
|
87
|
-
return OpenSSL::PKey::RSA.new private_key_text
|
88
|
-
end
|
89
|
-
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
|
94
|
-
end
|