opensecret 0.0.962 → 0.0.988
Sign up to get free protection for your applications and to get access to all the features.
- 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
|