opensecret 0.0.946 → 0.0.951
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/lib/crypto/engineer.rb +20 -8
- data/lib/extension/string.rb +41 -1
- data/lib/factbase/facts.opensecret.io.ini +23 -12
- data/lib/notepad/blow.rb +82 -4
- data/lib/opensecret.rb +10 -0
- data/lib/plugins/cipher.rb +131 -8
- data/lib/plugins/ciphers/aes-256.rb +8 -10
- data/lib/plugins/ciphers/blowfish.rb +3 -3
- data/lib/plugins/usecase.rb +7 -4
- data/lib/plugins/usecases/init.rb +36 -20
- data/lib/plugins/usecases/open.rb +177 -0
- data/lib/using.txt +145 -0
- data/lib/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca35c2727f92f764b83fae65d656062b95520ad6
|
4
|
+
data.tar.gz: 260748f11554e881116e6efd8c4d44c0cdb06284
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10f94cba6fe468750401a38846641c9dddce2258601d981b1fb26e5b2e88c7fea27edb10264ee070d3d4920c6ada9470e0a7b4cb3178a5f5c2a07facb186db1a
|
7
|
+
data.tar.gz: 35aa0ff66488c53859c245c10ba2d3aae348b56df4df90d94963241b190b8065f39f20bbfb63c119159f25488b8262f69f847fd1a3e715d3fe8df13954cbc921
|
data/lib/crypto/engineer.rb
CHANGED
@@ -20,7 +20,7 @@ module OpenSecret
|
|
20
20
|
# --
|
21
21
|
def self.machine_key human_password_length, mix_ratio
|
22
22
|
|
23
|
-
machine_raw_secret =
|
23
|
+
machine_raw_secret = strong_key( human_password_length * ( mix_ratio + 1) )
|
24
24
|
return machine_raw_secret[ 0..( human_password_length * mix_ratio - 1 ) ]
|
25
25
|
|
26
26
|
end
|
@@ -30,7 +30,7 @@ module OpenSecret
|
|
30
30
|
# -- Engineer a raw password that is similar (approximate) in
|
31
31
|
# -- length to the integer parameter.
|
32
32
|
# --
|
33
|
-
def self.
|
33
|
+
def self.strong_key approx_length
|
34
34
|
|
35
35
|
non_alphanum = SecureRandom.urlsafe_base64(approx_length);
|
36
36
|
return non_alphanum.delete("-_")
|
@@ -39,12 +39,24 @@ module OpenSecret
|
|
39
39
|
|
40
40
|
|
41
41
|
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
42
|
+
# Amalgamate the parameter passwords using a specific mix ratio. This method
|
43
|
+
# produces cryptographically stronger secrets than algorithms that simply
|
44
|
+
# concatenate two string keys together. If knowledge of one key were gained, this
|
45
|
+
# amalgamation algorithm still provides extremely strong protection even when
|
46
|
+
# one of the keys has a single digit length.
|
47
|
+
#
|
48
|
+
# This +length constraint formula+ binds the two input strings together with
|
49
|
+
# the integer mix ratio.
|
50
|
+
#
|
51
|
+
# <tt>machine password length = human password length * mix_ratio - 1</tt>
|
52
|
+
#
|
53
|
+
# @param human_password [String] the first password (shorter one) to amalgamate
|
54
|
+
# @param machine_password [String] the second password (longer one) to amalgamate
|
55
|
+
# @param mix_ratio [Fixnum] the mix ratio that must be respected by the
|
56
|
+
# previous two parameters.
|
57
|
+
# @return [String] an amalgamated (reproducible) union of the 2 parameter passwords
|
58
|
+
#
|
59
|
+
# @raise [ArgumentError] if the length constraint assertion does not hold true
|
48
60
|
def self.get_amalgam_password human_password, machine_password, mix_ratio
|
49
61
|
|
50
62
|
size_error_msg = "Human pass length times mix_ratio must equal machine pass length."
|
data/lib/extension/string.rb
CHANGED
@@ -57,6 +57,27 @@ class String
|
|
57
57
|
end
|
58
58
|
|
59
59
|
|
60
|
+
# To hex converts this string to hexadecimal form and returns
|
61
|
+
# the result leaving this string unchanged.
|
62
|
+
# @return [String] hexadecimal representation of this string
|
63
|
+
def to_hex
|
64
|
+
|
65
|
+
return self.unpack("H*").first
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# From hex converts this (assumed) hexadecimal string back into
|
71
|
+
# its normal string form and returns the result leaving this string
|
72
|
+
# unchanged.
|
73
|
+
# @return [String] string that matches the hexadecimal representation
|
74
|
+
def from_hex
|
75
|
+
|
76
|
+
return [self].pack("H*")
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
|
60
81
|
# Flatten (lower) a camel cased string and add periods to
|
61
82
|
# denote separation where the capital letters used to be.
|
62
83
|
#
|
@@ -78,11 +99,30 @@ class String
|
|
78
99
|
# - in => BEAST
|
79
100
|
# - out => b.e.a.s.t
|
80
101
|
#
|
102
|
+
# == Flatten Class Names
|
103
|
+
#
|
104
|
+
# If the string comes in as a class name we can expect it to
|
105
|
+
# contain colons like the below examples.
|
106
|
+
# This::That
|
107
|
+
# ::That
|
108
|
+
# This::That::TheOther
|
109
|
+
#
|
110
|
+
# So we find the last index of a colon and then continue as per
|
111
|
+
# the above with flattening the string.
|
112
|
+
#
|
81
113
|
# @return [String] a flatten (period separated) version of this camel cased string
|
82
114
|
def do_flatten
|
83
115
|
|
116
|
+
to_flatten_str = self
|
117
|
+
|
118
|
+
last_colon_index = to_flatten_str.rindex ":"
|
119
|
+
ends_with_colon = to_flatten_str[-1].eql? ":"
|
120
|
+
unless ( last_colon_index.nil? || ends_with_colon )
|
121
|
+
to_flatten_str = to_flatten_str[ (last_colon_index+1) .. -1 ]
|
122
|
+
end
|
123
|
+
|
84
124
|
snapped_str = ""
|
85
|
-
|
125
|
+
to_flatten_str.each_char do |this_char|
|
86
126
|
is_lower = "#{this_char}".is_all_lowercase?
|
87
127
|
snapped_str += "." unless is_lower || snapped_str.empty?
|
88
128
|
snapped_str += this_char.downcase
|
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
[global]
|
3
3
|
|
4
|
+
name = opensecret
|
4
5
|
min.passwd.len = rb>> 6
|
5
6
|
nickname = godzilla
|
6
7
|
root.domain = devopswiki.co.uk
|
@@ -8,21 +9,31 @@ env.var.name = SECRET_MATERIAL
|
|
8
9
|
ratio = rb>> 3
|
9
10
|
bit.key.size = rb>> 8192
|
10
11
|
key.cipher = rb>> OpenSSL::Cipher.new 'AES-256-CBC'
|
11
|
-
secret.
|
12
|
-
|
13
|
-
|
12
|
+
secret.keydir = rb>> OpenSession::Attributes.instance.get_value @s[:name], "safe"
|
13
|
+
email.address = rb>> OpenSession::Attributes.instance.get_value @s[:name], "email"
|
14
|
+
safe.user = rb>> File.join @s[:secret_keydir], @s[:email_address]
|
15
|
+
master.dirname = master.keys
|
16
|
+
master.dirpath = rb>> File.join @s[:safe_user], @s[:master_dirname]
|
17
|
+
master.pub.name = master.public.key.x.os.txt
|
18
|
+
master.prv.name = master.private.key.x.os.txt
|
19
|
+
master.pub.key = rb>> File.join @s[:master_dirpath], @s[:master_pub_name]
|
20
|
+
master.prv.key = rb>> File.join @s[:master_dirpath], @s[:master_prv_name]
|
14
21
|
|
15
|
-
|
16
|
-
|
17
|
-
## local.gitrepo = rb>> File.join @i[:dir], @s[:repo_name]
|
22
|
+
machine.key.x = machine.key.x
|
23
|
+
separator.a = %$os$%
|
18
24
|
|
19
|
-
|
20
|
-
## public.dirname = public_keys
|
21
|
-
## public.keyroute = rb>> File.join @s[:root_domain], @s[:public_dirname]
|
22
|
-
## public.keydir = rb>> File.join @s[:local_gitrepo], @s[:public_keyroute]
|
23
|
-
## public.keyname = rb>> "public_key." + @s[:nickname] + dot + @s[:root_domain] + ".txt"
|
24
|
-
## public.keypath = rb>> File.join @s[:public_keydir], @s[:public_keyname]
|
25
|
+
repo.name = material_data
|
25
26
|
|
26
27
|
prompt.1 = Enter a Robust Password
|
27
28
|
prompt.2 = Re-enter that Password
|
28
29
|
|
30
|
+
[open]
|
31
|
+
|
32
|
+
open.name = session
|
33
|
+
open.dirname = session.material
|
34
|
+
open.dirpath = rb>> File.join @f[:global][:safe_user], @s[:open_dirname]
|
35
|
+
open.idlen = 9
|
36
|
+
open.keylen = 96
|
37
|
+
open.idname = session.id
|
38
|
+
open.keyname = session.key
|
39
|
+
open.pathname = session.path
|
data/lib/notepad/blow.rb
CHANGED
@@ -6,9 +6,87 @@
|
|
6
6
|
## Trial and Error Scratch-Pad ##
|
7
7
|
## ########################### ##
|
8
8
|
|
9
|
-
x = "messagess"
|
10
9
|
|
11
|
-
|
10
|
+
class Trial
|
12
11
|
|
13
|
-
|
14
|
-
|
12
|
+
|
13
|
+
def self.crypt
|
14
|
+
|
15
|
+
require 'openssl'
|
16
|
+
require "base64"
|
17
|
+
|
18
|
+
key = OpenSSL::PKey::RSA.new(8192)
|
19
|
+
|
20
|
+
|
21
|
+
payload = "55fff4c5895bb247676c6edd2307f17c665305457b3bcfcd985c398246b8780f54e337252c5407afd4895a5e3a2415fce5b703a483da3edc88739cb7787262a19d69fb9416f900fed797c046aaec83b8e15b14edb032ed76535def8ada77108936e5442a839d4078048ca01449a6acd7315c9b7a7b8802dba0c83eb4c13e21b1051efa77a420a3ffd3cbf1fa13182933a0503f23cce95b68787081f3af33c69049657bdbf1fd30d79f108d604faad1fbee198a3e2c1b28cdddf7ebb84b6b0c1d3e9b47665bd96d7df8407e11d00e4d9275e805c7b9e61b6739802d6d87ac8283ef92a593ed53db2096cd1dc9496307f40942cc3d54a7c864ede71e0b192ce152"
|
22
|
+
|
23
|
+
puts ""
|
24
|
+
puts "Payload size is #{payload.length}"
|
25
|
+
puts ""
|
26
|
+
puts ""
|
27
|
+
puts encrypted_string = key.public_encrypt( payload, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
|
28
|
+
puts ""
|
29
|
+
puts base64text = Base64.encode64(encrypted_string)
|
30
|
+
puts ""
|
31
|
+
puts signature = key.sign(OpenSSL::Digest::SHA256.new, payload )
|
32
|
+
puts ""
|
33
|
+
puts hex_data = signature.unpack("H*").first
|
34
|
+
puts ""
|
35
|
+
puts "Length is #{hex_data.length}"
|
36
|
+
puts ""
|
37
|
+
puts key.public_key.verify(OpenSSL::Digest::SHA256.new, signature, payload)
|
38
|
+
puts ""
|
39
|
+
puts encrypted_string.unpack("H*").first
|
40
|
+
puts ""
|
41
|
+
puts key.private_decrypt(encrypted_string, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
|
42
|
+
puts ""
|
43
|
+
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
=begin
|
48
|
+
ddGKDqfhF6HnkJuIdTECZk7J7E9xx9LiYRDywCdIuDxYQQs+if+3qxP37+ah
|
49
|
+
HwGYgjxpIjqS9slhLOveVexSeHUD4DCbjHW2AlMsaUxwoSY0UfgzrO+2LDG9
|
50
|
+
tyizUYA6n8a+vBzJqRFP2BW7/AxwP0jm0yADWwBOGFL1+g==
|
51
|
+
|
52
|
+
<-|@| < || opensecret outer crypt material axis || > |@|->
|
53
|
+
|
54
|
+
HNkUjWaFoI5dPTRUUymyf7uKMaXFhiIZaOq+ZYj4TWPN92qv6ANTd3pRvVa3
|
55
|
+
S+aQSOX7q3FkKIOc5yfWLushGAMSwidgH1kzLvocCf+SSWH5BY3zTb7NAGjW
|
56
|
+
=end
|
57
|
+
|
58
|
+
### Trial.crypt
|
59
|
+
### exit
|
60
|
+
|
61
|
+
def try
|
62
|
+
|
63
|
+
require "pp"
|
64
|
+
require "inifile"
|
65
|
+
new_map = { "string1" => "value1", "string2" => "value2" }
|
66
|
+
|
67
|
+
ini_pairs = IniFile.new
|
68
|
+
ini_pairs["dictionary"] = new_map
|
69
|
+
|
70
|
+
puts ""
|
71
|
+
puts ini_pairs.to_s
|
72
|
+
puts ""
|
73
|
+
|
74
|
+
|
75
|
+
puts "--------------------"
|
76
|
+
puts new_map
|
77
|
+
puts "--------------------"
|
78
|
+
puts "#{pp new_map}"
|
79
|
+
puts "--------------------"
|
80
|
+
puts "#{new_map.to_s}"
|
81
|
+
puts "--------------------"
|
82
|
+
puts ""
|
83
|
+
|
84
|
+
## x = "messagess"
|
85
|
+
## x += "x" until x.bytesize % 8 == 0
|
86
|
+
|
87
|
+
## puts "Now x string is [#{x}]."
|
88
|
+
## puts "x is now [#{x.length}] characters long."
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
data/lib/opensecret.rb
CHANGED
@@ -54,6 +54,16 @@ class CliInterpreter < Thor
|
|
54
54
|
end
|
55
55
|
|
56
56
|
|
57
|
+
# Description of the open "wake-up" call.
|
58
|
+
desc "open", "open up a conduit for adding, subtracting and swapping secrets for a future commit."
|
59
|
+
|
60
|
+
# Open up a conduit from which we can add, subtract, update and list secrets
|
61
|
+
# before they are committed (and pushed) into permanent locked storage.
|
62
|
+
def open
|
63
|
+
OpenSecret::Open.new.flow_of_events
|
64
|
+
end
|
65
|
+
|
66
|
+
|
57
67
|
# Description of the mandatory safe and (safe directory) configuration.
|
58
68
|
desc "safe SAFE_DIR", "SAFE_DIR full path to the (ideally USB key) storage location"
|
59
69
|
|
data/lib/plugins/cipher.rb
CHANGED
@@ -50,7 +50,7 @@ module OpenSecret
|
|
50
50
|
# - <tt>do_symmetric_encryption(plain_text)</tt> - resulting in ciphertext
|
51
51
|
# - <tt>do_symmetric_decryption(ciphertext, encryption_dictionary)</tt> » plaintext
|
52
52
|
#
|
53
|
-
# and also set the <tt>@
|
53
|
+
# and also set the <tt>@dictionary</tt> hash (map) of pertinent
|
54
54
|
# key/value pairs including the encryption algorithm, the encryption key and
|
55
55
|
# the ciphertext signature to thwart any at-rest tampering.
|
56
56
|
#
|
@@ -84,9 +84,36 @@ module OpenSecret
|
|
84
84
|
#
|
85
85
|
TEXT_PADDER = "<-|@|->"
|
86
86
|
|
87
|
+
|
88
|
+
# An unusual string that glues together an encryption dictionary and
|
89
|
+
# a chunk of base64 encoded and encrypted ciphertext.
|
90
|
+
# The string must be unusual enough to ensure it dos not occur within
|
91
|
+
# the dictionary metadata keys or values.
|
92
|
+
INNER_GLUE_STRING = "\n<-|@| < || opensecret inner crypt material axis || > |@|->\n\n"
|
93
|
+
|
94
|
+
|
95
|
+
# An unusual string that glues together the asymmetrically encrypted outer
|
96
|
+
# encryption key with the outer crypted text.
|
97
|
+
OUTER_GLUE_STRING = "\n<-|@| < || opensecret outer crypt material axis || > |@|->\n\n"
|
98
|
+
|
99
|
+
|
100
|
+
# Text header for key-value pairs hash map that will be serialized.
|
101
|
+
DICTIONARY = "dictionary"
|
102
|
+
|
103
|
+
|
87
104
|
@@symmetric_cipher_keyname = "symmetric.cipher"
|
88
105
|
@@encryption_key_keyname = "encryption.key"
|
89
|
-
@@
|
106
|
+
@@payload_signature_keyname = "payload.signature"
|
107
|
+
|
108
|
+
|
109
|
+
# The cipher constructor instantiates the encryption dictionary which
|
110
|
+
# will be collaboratively added to by the parent and child ciphers.
|
111
|
+
def initialize
|
112
|
+
|
113
|
+
@dictionary = {}
|
114
|
+
|
115
|
+
end
|
116
|
+
|
90
117
|
|
91
118
|
# Ciphers use +symmetric algorithms+ to encrypt the given text, which
|
92
119
|
# is then wrapped up along with the encryption key and other +metadata+
|
@@ -103,15 +130,55 @@ module OpenSecret
|
|
103
130
|
# Every component in the pipeline bears the responsibility for nullifying
|
104
131
|
# and rejecting malicious content.
|
105
132
|
#
|
106
|
-
# @param
|
107
|
-
#
|
133
|
+
# @param public_key_text [String] textual portion of an {OpenSSL::PKey::RSA}
|
134
|
+
# public key that does not carry the private key as this method and its
|
135
|
+
# compatriots do not need to know the private key to do their work.
|
136
|
+
#
|
137
|
+
# @param payload_text [String] plaintext (or base64 encoded) text to encrypt
|
138
|
+
# @param payload_signature [String] signature of payload verifiable with public key
|
108
139
|
#
|
109
140
|
# @return [String] doubly (symmetric and asymmetric) encrypted cipher text
|
110
|
-
def encrypt_it
|
141
|
+
def encrypt_it public_key_text, payload_text, payload_signature
|
142
|
+
|
143
|
+
asymmetric_key = OpenSSL::PKey::RSA.new public_key_text
|
144
|
+
|
145
|
+
signature_valid = asymmetric_key.verify(
|
146
|
+
OpenSSL::Digest::SHA256.new,
|
147
|
+
payload_signature,
|
148
|
+
payload_text
|
149
|
+
)
|
111
150
|
|
112
|
-
|
113
|
-
|
114
|
-
|
151
|
+
raise ArgumentError, "Payload not verified by the signature." unless signature_valid
|
152
|
+
@dictionary[@@payload_signature_keyname] = payload_signature.to_hex
|
153
|
+
crypted_payload = do_symmetric_encryption payload_text
|
154
|
+
|
155
|
+
unified_material = unify_hash_and_text crypted_payload
|
156
|
+
blowfish_cryptor = Blowfish.new
|
157
|
+
outer_crypt_key = OpenSecret::Engineer.strong_key( 128 )
|
158
|
+
crypted_material = blowfish_cryptor.do_encrypt_with_key unified_material, outer_crypt_key
|
159
|
+
crypted_cryptkey = do_asymmetric_encryption public_key_text, outer_crypt_key
|
160
|
+
locked_up_string = unify_text_and_text crypted_cryptkey, crypted_material
|
161
|
+
|
162
|
+
return locked_up_string
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
# Thismethod takes the textual public key lacking the private key portion
|
168
|
+
# as it is not needed, and encrypts the secret text with it.
|
169
|
+
# It returns a Base64 encoded version of they encrypted text.
|
170
|
+
#
|
171
|
+
# The public key text must be compatible with {OpenSSL::PKey::RSA} as the
|
172
|
+
# class will be instantiated using the public key text.
|
173
|
+
#
|
174
|
+
# @param public_key_text [String] the textual portion of an RSA public key
|
175
|
+
# @param secret_text [String] secret text to encrypt with the public key
|
176
|
+
#
|
177
|
+
# @return [String] a Base64 encoded version of the encrypted secret text
|
178
|
+
def do_asymmetric_encryption public_key_text, secret_text
|
179
|
+
|
180
|
+
asymmetric_encrypt_key = OpenSSL::PKey::RSA.new public_key_text
|
181
|
+
Base64.encode64( asymmetric_encrypt_key.public_encrypt( secret_text[0..1012] ) )
|
115
182
|
|
116
183
|
end
|
117
184
|
|
@@ -140,6 +207,62 @@ module OpenSecret
|
|
140
207
|
end
|
141
208
|
|
142
209
|
|
210
|
+
# Serialize and then unite a hash map and a textual chunk using
|
211
|
+
# a known but unusual separator string in a manner that protects
|
212
|
+
# the content integrity during the serialize and extraction phases.
|
213
|
+
#
|
214
|
+
# == Why an Unusual Separator String
|
215
|
+
#
|
216
|
+
# The separator string must be unusual to make it unlikely for it
|
217
|
+
# to occur in any of the map's key value pairs nor indeed the chunk
|
218
|
+
# of text being glued. Were this to happen, the separate and reconstitute
|
219
|
+
# phase may not accurately return the same two entities we are employed
|
220
|
+
# to unite.
|
221
|
+
#
|
222
|
+
# == Hash (Map) Contents
|
223
|
+
#
|
224
|
+
# The map contents will effectively be serialized in a simplistic
|
225
|
+
# manner therefore the keys should all be strings and the value
|
226
|
+
# types restricted to
|
227
|
+
#
|
228
|
+
# - strings
|
229
|
+
# - integers and/or floating point numbers
|
230
|
+
# - booleans
|
231
|
+
#
|
232
|
+
# Binary text is not allowed neither in the map or the text chunk.
|
233
|
+
# Any binary should be base64 encoded before being passed to us.
|
234
|
+
#
|
235
|
+
# @param text_chunk [String] the text chunk to be glued at the bottom
|
236
|
+
#
|
237
|
+
# @return [String] serialized and glued together result of map plus text
|
238
|
+
def unify_hash_and_text text_chunk
|
239
|
+
|
240
|
+
nil_or_empty_hash = @dictionary.nil? || @dictionary.empty?
|
241
|
+
raise ArgumentError, "Cannot unify nil or empty metadata." if nil_or_empty_hash
|
242
|
+
|
243
|
+
ini_map = IniFile.new
|
244
|
+
ini_map[ DICTIONARY ] = @dictionary
|
245
|
+
|
246
|
+
return ini_map.to_s + INNER_GLUE_STRING + text_chunk
|
247
|
+
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
|
252
|
+
# Using an outer divider (glue) - attach the asymmetrically encrypted outer
|
253
|
+
# encryption key with the outer encrypted text.
|
254
|
+
#
|
255
|
+
# @param crypt_material_x [String] asymmetrically encrypted (encoded) outer encryption key
|
256
|
+
# @param crypt_material_y [String] symmetrically encrypted inner metadata and payload crypt
|
257
|
+
#
|
258
|
+
# @return [String] concatenated result of the two crypt materials and divider string
|
259
|
+
def unify_text_and_text crypt_material_x, crypt_material_y
|
260
|
+
|
261
|
+
return crypt_material_x + OUTER_GLUE_STRING + crypt_material_y
|
262
|
+
|
263
|
+
end
|
264
|
+
|
265
|
+
|
143
266
|
|
144
267
|
def encrypt_usecase public_key, secret_path, stores, plain_text
|
145
268
|
|
@@ -28,7 +28,7 @@ module OpenSecret
|
|
28
28
|
# - <tt>do_symmetric_encryption(plain_text)</tt> - resulting in ciphertext
|
29
29
|
# - <tt>do_symmetric_decryption(ciphertext, encryption_dictionary)</tt> » plaintext
|
30
30
|
#
|
31
|
-
# and it also sets the <tt>@
|
31
|
+
# and it also sets the <tt>@dictionary</tt> hash (map) of pertinent
|
32
32
|
# key/value pairs including the +encryption algorithm+ and +encryption key+.
|
33
33
|
#
|
34
34
|
# That's It. Cipher children can rely on the {OpenSecret::Cipher} parent to
|
@@ -41,7 +41,7 @@ module OpenSecret
|
|
41
41
|
# Use the AES 256 bit block cipher and a robust strong random key plus
|
42
42
|
# initialization vector (IV) to symmetrically encrypt the plain text.
|
43
43
|
#
|
44
|
-
# Add these key/value pairs to @
|
44
|
+
# Add these key/value pairs to @dictionary instance map.
|
45
45
|
#
|
46
46
|
# - <tt>symmetric.cipher</tt> - the algorithm used to encrypt and decrypt
|
47
47
|
# - <tt>encryption.key</tt> - hex encoded key for encrypting and decrypting
|
@@ -54,15 +54,13 @@ module OpenSecret
|
|
54
54
|
@cipher_name = "aes-256-cbc"
|
55
55
|
|
56
56
|
crypt_cipher = OpenSSL::Cipher.new @cipher_name
|
57
|
-
crypt_cipher.encrypt
|
57
|
+
crypt_cipher.encrypt
|
58
58
|
|
59
|
-
@
|
60
|
-
|
61
|
-
|
62
|
-
@@initialize_vector_keyname => crypt_cipher.random_iv.unpack("H*").first
|
63
|
-
}
|
59
|
+
@dictionary[@@symmetric_cipher_keyname] = @cipher_name
|
60
|
+
@dictionary[@@encryption_key_keyname] = crypt_cipher.random_key.to_hex
|
61
|
+
@dictionary[@@initialize_vector_keyname] = crypt_cipher.random_iv.to_hex
|
64
62
|
|
65
|
-
Base64.encode64( crypt_cipher.update + crypt_cipher.final )
|
63
|
+
return Base64.encode64( crypt_cipher.update( plain_text ) + crypt_cipher.final )
|
66
64
|
|
67
65
|
end
|
68
66
|
|
@@ -73,7 +71,7 @@ module OpenSecret
|
|
73
71
|
#
|
74
72
|
# == Pre-Condition | Encryption Dictionary
|
75
73
|
#
|
76
|
-
# This method requires the <tt>@
|
74
|
+
# This method requires the <tt>@dictionary</tt> instance
|
77
75
|
# variable to have been set and to contain (amongst others)
|
78
76
|
#
|
79
77
|
# - the <tt>encryption.key</tt> - hex encoded key for encrypting and decrypting
|
@@ -24,7 +24,7 @@ module OpenSecret
|
|
24
24
|
|
25
25
|
|
26
26
|
# This method provides the Blowfish algorithm but we reserve the
|
27
|
-
# right to enforce upon it
|
27
|
+
# right to enforce upon it an encryption key of our choosing.
|
28
28
|
#
|
29
29
|
# The key length need not be a multiple of 8 - however it is advisable
|
30
30
|
# to use {Digest::SHA256.digest} to produce a strong 32 character key.
|
@@ -68,13 +68,13 @@ module OpenSecret
|
|
68
68
|
log.info(x) { "os blowfish request to encrypt plain text with provided key." }
|
69
69
|
|
70
70
|
block_txt = plain_text
|
71
|
-
block_txt += ::Cipher::TEXT_PADDER until block_txt.bytesize % OpenSecret::Blowfish::BLOWFISH_BLOCK_LEN == 0
|
71
|
+
block_txt += OpenSecret::Cipher::TEXT_PADDER until block_txt.bytesize % OpenSecret::Blowfish::BLOWFISH_BLOCK_LEN == 0
|
72
72
|
raw_stretched_key = Digest::SHA256.digest(encryption_key)
|
73
73
|
|
74
74
|
blowfish_encryptor = OpenSSL::Cipher.new(OpenSecret::Blowfish::BLOWFISH_CIPHER_ID).encrypt
|
75
75
|
blowfish_encryptor.key = raw_stretched_key
|
76
76
|
|
77
|
-
Base64.encode64( blowfish_encryptor.update(block_txt) << blowfish_encryptor.final )
|
77
|
+
return Base64.encode64( blowfish_encryptor.update(block_txt) << blowfish_encryptor.final )
|
78
78
|
|
79
79
|
end
|
80
80
|
|
data/lib/plugins/usecase.rb
CHANGED
@@ -51,14 +51,13 @@ module OpenSession
|
|
51
51
|
|
52
52
|
pre_validation
|
53
53
|
|
54
|
-
rescue OpenError::
|
54
|
+
rescue OpenError::CliError => e
|
55
55
|
|
56
56
|
puts ""
|
57
57
|
puts "Your command did not complete successfully."
|
58
58
|
puts "Pre validation checks failed."
|
59
59
|
puts ""
|
60
60
|
puts " => #{e.message}"
|
61
|
-
#### puts " => #{e.culprit}"
|
62
61
|
puts ""
|
63
62
|
abort e.message
|
64
63
|
end
|
@@ -80,7 +79,7 @@ module OpenSession
|
|
80
79
|
|
81
80
|
post_validation
|
82
81
|
|
83
|
-
rescue OpenError::
|
82
|
+
rescue OpenError::CliError => e
|
84
83
|
|
85
84
|
puts ""
|
86
85
|
puts "Your command did not complete successfully."
|
@@ -197,6 +196,7 @@ module OpenSession
|
|
197
196
|
return if is_pre_init_usecase
|
198
197
|
|
199
198
|
@ucid_str = self.class.name.do_flatten
|
199
|
+
log.info(x) { "Usecase class [self.class.name] converted to => #{@ucid_str}" }
|
200
200
|
@ucid_sym = @ucid_str.gsub(".", "_").to_sym
|
201
201
|
|
202
202
|
OpenSession::FactFind.instance.instantiate @ucid_str
|
@@ -204,9 +204,12 @@ module OpenSession
|
|
204
204
|
|
205
205
|
@c = OpenSession::FactFind.instance.f
|
206
206
|
@i = OpenSession::FactFind.instance.i
|
207
|
-
@p = OpenSession::FactFind.instance.f[@
|
207
|
+
@p = OpenSession::FactFind.instance.f[@ucid_sym]
|
208
|
+
|
209
|
+
log.info(x) { "assimilated [#{@p.length}] facts specific to the [#{@ucid_str}] use case." }
|
208
210
|
|
209
211
|
@time_stamp = OpenSession::Stamp.instance
|
212
|
+
|
210
213
|
=begin
|
211
214
|
@eco_id_str = SnapFlat.do self.class.name
|
212
215
|
@eco_id_sym = @eco_id_str.gsub(".", "_").to_sym
|
@@ -48,22 +48,24 @@ module OpenSecret
|
|
48
48
|
# So in preparation to execute its modus operandi encryption,
|
49
49
|
# decryption and (if required) transportation use cases opensecret will
|
50
50
|
#
|
51
|
+
# - @todo copy the attributes file to the safestore AND delete it.
|
51
52
|
# - +collect the human password+ (twice), verify robustness (and throw away asap)
|
52
53
|
# - +manufacture workstation key+ that will be encrypted b4 it rests on machine
|
53
54
|
# - +create amalgamated human/workstation password+ for locking the private key
|
54
55
|
# - +create a long cryptographically strong symmetric encryption key+
|
55
56
|
# - +encrypt workstation key+ into <tt>.opensecret/<email>/workstation.key.osx.txt</tt>
|
56
|
-
|
57
57
|
# - +encrypt workstation encryption key+ with human password and email address
|
58
|
-
# - then write into
|
58
|
+
# - then write into the workstation opensecret config file under <tt>machine.key.crypt</tt>
|
59
|
+
# - @todo write machine.key.cipher copy the attributes file to the safestore AND delete it.
|
59
60
|
# - +create a super 8,192 bit private/public key pair+
|
60
|
-
# - use +amalgamated password to encrypt the private key+
|
61
|
-
# - write to <tt><SAFE>/<email>/master.keys/master.private.key.
|
61
|
+
# - use +amalgamated password with AES 256 RSA to encrypt the private key+
|
62
|
+
# - write to <tt><SAFE>/<email>/master.keys/master.private.key.x.os.txt</tt>
|
63
|
+
# - use the +amalgamated password with Blowfish to encrypt the public key+
|
64
|
+
# - write to <tt><SAFE>/<email>/master.keys/master.public.key.x.os.txt</tt>
|
65
|
+
|
62
66
|
# - +create robust salt+ for hashing the path to the (crypted) keys and ciphers
|
63
67
|
# - use +public key to encrypt the salt+
|
64
68
|
# - write crypted salt to <tt><SAFE>/<email>/master.keys/master.path.salt.crypt.txt</tt>
|
65
|
-
# - now +use the public key to encrypt itself+
|
66
|
-
# - write public key crypt to <tt><SAFE>/<email>/master.keys/master.public.key.crypt.txt</tt>
|
67
69
|
# - +create the cryptographic keystore+ inside the safe
|
68
70
|
#
|
69
71
|
# Variables should be first zeroed and then deleted immediately after their last use.
|
@@ -105,32 +107,47 @@ module OpenSecret
|
|
105
107
|
amalgam_key = Amalgam.passwords human_password, machine_key, @c[:global][:ratio]
|
106
108
|
asymmetric_keys = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
|
107
109
|
secured_keytext = asymmetric_keys.export @c[:global][:key_cipher], amalgam_key
|
108
|
-
public_key_text = asymmetric_keys.public_key.to_pem
|
109
110
|
|
110
|
-
machine_key_crypt_key = human_password +
|
111
|
+
machine_key_crypt_key = human_password + @c[:global][:separator_a] + @email_addr
|
111
112
|
blowfish_cipher = OpenSecret::Blowfish.new()
|
112
|
-
|
113
|
+
machine_key_x = blowfish_cipher.do_encrypt_with_key machine_key, machine_key_crypt_key
|
114
|
+
|
115
|
+
OpenSession::Attributes.stash @c[:global][:name], @c[:global][:machine_key_x], machine_key_x
|
116
|
+
FileUtils.mkdir_p @c[:global][:master_dirpath]
|
117
|
+
File.write @c[:global][:master_prv_key], secured_keytext
|
118
|
+
|
119
|
+
public_key_text = asymmetric_keys.public_key.to_pem
|
120
|
+
public_key_crypt = Blowfish.new.do_encrypt_with_key public_key_text, amalgam_key
|
121
|
+
File.write @c[:global][:master_pub_key], public_key_crypt
|
122
|
+
|
123
|
+
payload_signature = asymmetric_keys.sign( OpenSSL::Digest::SHA256.new, public_key_text )
|
124
|
+
|
125
|
+
big_crypted_block = Aes256.new.encrypt_it(
|
126
|
+
public_key_text,
|
127
|
+
public_key_text,
|
128
|
+
payload_signature
|
129
|
+
)
|
113
130
|
|
114
131
|
puts ""
|
115
|
-
puts "
|
116
|
-
puts "
|
132
|
+
puts "=============="
|
133
|
+
puts "Crypted Block"
|
134
|
+
puts "=============="
|
117
135
|
puts ""
|
118
|
-
puts "
|
119
|
-
puts "
|
120
|
-
puts "
|
136
|
+
puts "#{big_crypted_block}"
|
137
|
+
puts ""
|
138
|
+
puts ""
|
139
|
+
puts "Carry on development in init.rb"
|
121
140
|
puts ""
|
122
|
-
exit
|
123
|
-
|
124
141
|
|
125
|
-
Dir.mkdir @p[:secret_keydir] unless File.exists? @p[:secret_keydir]
|
126
|
-
File.write @p[:secret_keypath], secured_keytext
|
127
142
|
|
143
|
+
=begin
|
128
144
|
Crypto.print_secret_env_var @p[:env_var_name], machine_key
|
129
|
-
|
130
145
|
GitFlow.do_clone_repo @p[:public_gitrepo], @p[:local_gitrepo]
|
131
146
|
FileUtils.mkdir_p @p[:public_keydir]
|
132
147
|
File.write @p[:public_keypath], public_key_text
|
133
148
|
GitFlow.push @p[:local_gitrepo], @p[:public_keyname], @c[:time][:stamp]
|
149
|
+
=end
|
150
|
+
|
134
151
|
|
135
152
|
# exit
|
136
153
|
# key4_pem = File.read 'private.secure.pem'
|
@@ -142,7 +159,6 @@ module OpenSecret
|
|
142
159
|
# print decrypted_text, "\n"
|
143
160
|
|
144
161
|
|
145
|
-
|
146
162
|
end
|
147
163
|
|
148
164
|
|
@@ -0,0 +1,177 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
module OpenSecret
|
4
|
+
|
5
|
+
require 'openssl'
|
6
|
+
|
7
|
+
# The <tt>open use case</tt> allows us to add (put), subtract (del)ete and list
|
8
|
+
# the secrets in a file (whether it exists or not). The file can then be locked.
|
9
|
+
# Lookout for the reopen command.
|
10
|
+
#
|
11
|
+
# If the file to open already exists a --with option (giving the master-secret)
|
12
|
+
# must be provided.
|
13
|
+
#
|
14
|
+
# == Observable Value
|
15
|
+
#
|
16
|
+
# $ opensecret open home/wifi
|
17
|
+
#
|
18
|
+
# The observable value delivered by +[open]+ boils down to
|
19
|
+
#
|
20
|
+
# - an openkey (eg asdfx1234) and corresponding open encryption key
|
21
|
+
# - open encryption key written to <tt>~/.opensecret/open.keys/asdfx1234.x.txt</tt>
|
22
|
+
# - the opened path (ending in filename) written to session.cache base in [safe]
|
23
|
+
# - the INI string (were the file to be decrypted) would look like the below
|
24
|
+
#
|
25
|
+
# [session]
|
26
|
+
# base.path = home/wifi
|
27
|
+
#
|
28
|
+
class Open < OpenSession::UseCase
|
29
|
+
|
30
|
+
@@context_name = "opensecret"
|
31
|
+
|
32
|
+
# Execute the <tt>open use case</tt> activities which precedes the ability to
|
33
|
+
# to add (put), subtract (del)ete and list the secrets into the opened session file.
|
34
|
+
# The file can then be locked (committed and pushed to permanent crypted stores).
|
35
|
+
#
|
36
|
+
# If the file to open already exists a --with option (giving the master-secret)
|
37
|
+
# must be provided.
|
38
|
+
#
|
39
|
+
# == Observable Value
|
40
|
+
#
|
41
|
+
# $ opensecret open home/wifi
|
42
|
+
#
|
43
|
+
# The observable value delivered by +[open]+ boils down to
|
44
|
+
#
|
45
|
+
# - a provisioned openkey (eg asdfx1234) and corresponding open encryption key
|
46
|
+
# - open encryption key written to <tt>~/.opensecret/open.keys/asdfx1234.x.txt</tt>
|
47
|
+
# - the opened path (ending in filename) written to session.cache base in [safe]
|
48
|
+
# - the INI string (were the file to be decrypted) would look like the below
|
49
|
+
#
|
50
|
+
# [session]
|
51
|
+
# base.path = home/wifi
|
52
|
+
#
|
53
|
+
# @example
|
54
|
+
# home/wifi can be simply populated like this.
|
55
|
+
#
|
56
|
+
# $ opensecret put bt/ssid g034gdf3455
|
57
|
+
# $ opensecret put bt/password HRAsyf324g4DF
|
58
|
+
#
|
59
|
+
# $ opensecret put virgin.media/ssid 345SDFS
|
60
|
+
# $ opensecret put virgin.media/password HlksHRd043NjPO
|
61
|
+
#
|
62
|
+
# $ opensecret file virgin.media/contract /home/joe/downloads/vm.contract.pdf
|
63
|
+
#
|
64
|
+
# To encrypt (lock-down) these secrets we simply issue
|
65
|
+
#
|
66
|
+
# $ opensecret close
|
67
|
+
#
|
68
|
+
def execute
|
69
|
+
|
70
|
+
FileUtils.mkdir_p @p[:open_dirpath]
|
71
|
+
open_id = Engineer.strong_key @p[:open_idlen]
|
72
|
+
open_key = Engineer.strong_key @p[:open_keylen]
|
73
|
+
|
74
|
+
OpenSession::Attributes.stash @p[:open_name], @p[:open_idname], open_id
|
75
|
+
OpenSession::Attributes.stash @p[:open_name], @p[:open_keyname], open_key
|
76
|
+
OpenSession::Attributes.stash @p[:open_name], @p[:open_pathname], open_path
|
77
|
+
|
78
|
+
|
79
|
+
exit
|
80
|
+
|
81
|
+
|
82
|
+
human_password = Collect.secret_text(
|
83
|
+
@c[:global][:min_passwd_len],
|
84
|
+
true,
|
85
|
+
@c[:global][:prompt_1],
|
86
|
+
@c[:global][:prompt_2]
|
87
|
+
)
|
88
|
+
|
89
|
+
machine_key = Engineer.machine_key human_password.length, @c[:global][:ratio]
|
90
|
+
amalgam_key = Amalgam.passwords human_password, machine_key, @c[:global][:ratio]
|
91
|
+
asymmetric_keys = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
|
92
|
+
secured_keytext = asymmetric_keys.export @c[:global][:key_cipher], amalgam_key
|
93
|
+
|
94
|
+
machine_key_crypt_key = human_password + @c[:global][:separator_a] + @email_addr
|
95
|
+
blowfish_cipher = OpenSecret::Blowfish.new()
|
96
|
+
machine_key_x = blowfish_cipher.do_encrypt_with_key machine_key, machine_key_crypt_key
|
97
|
+
|
98
|
+
OpenSession::Attributes.stash @c[:global][:name], @c[:global][:machine_key_x], machine_key_x
|
99
|
+
FileUtils.mkdir_p @c[:global][:master_dirpath]
|
100
|
+
File.write @c[:global][:master_prv_key], secured_keytext
|
101
|
+
|
102
|
+
public_key_text = asymmetric_keys.public_key.to_pem
|
103
|
+
public_key_crypt = Blowfish.new.do_encrypt_with_key public_key_text, amalgam_key
|
104
|
+
File.write @c[:global][:master_pub_key], public_key_crypt
|
105
|
+
|
106
|
+
payload_signature = asymmetric_keys.sign( OpenSSL::Digest::SHA256.new, public_key_text )
|
107
|
+
|
108
|
+
big_crypted_block = Aes256.new.encrypt_it(
|
109
|
+
public_key_text,
|
110
|
+
public_key_text,
|
111
|
+
payload_signature
|
112
|
+
)
|
113
|
+
|
114
|
+
puts ""
|
115
|
+
puts "=============="
|
116
|
+
puts "Crypted Block"
|
117
|
+
puts "=============="
|
118
|
+
puts ""
|
119
|
+
puts "#{big_crypted_block}"
|
120
|
+
puts ""
|
121
|
+
puts ""
|
122
|
+
puts "Carry on development in init.rb"
|
123
|
+
puts ""
|
124
|
+
|
125
|
+
|
126
|
+
=begin
|
127
|
+
Crypto.print_secret_env_var @p[:env_var_name], machine_key
|
128
|
+
GitFlow.do_clone_repo @p[:public_gitrepo], @p[:local_gitrepo]
|
129
|
+
FileUtils.mkdir_p @p[:public_keydir]
|
130
|
+
File.write @p[:public_keypath], public_key_text
|
131
|
+
GitFlow.push @p[:local_gitrepo], @p[:public_keyname], @c[:time][:stamp]
|
132
|
+
=end
|
133
|
+
|
134
|
+
|
135
|
+
# exit
|
136
|
+
# key4_pem = File.read 'private.secure.pem'
|
137
|
+
# pass_phrase = 'superduperpasswordistoBeENTEREDRIGHT1234HereandRightNOW'
|
138
|
+
# key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
|
139
|
+
# decrypted_text = key4.private_decrypt(Base64.decode64(encrypted_string))
|
140
|
+
|
141
|
+
# print "\nHey we have done the decryption.\n", "\n"
|
142
|
+
# print decrypted_text, "\n"
|
143
|
+
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
# Perform pre-conditional validations in preparation to executing the main flow
|
149
|
+
# of events for this use case. This method may throw the below exceptions.
|
150
|
+
#
|
151
|
+
# @raise [SafeDirNotConfigured] if the safe's url has not been configured
|
152
|
+
# @raise [EmailAddrNotConfigured] if the email address has not been configured
|
153
|
+
# @raise [StoreUrlNotConfigured] if the crypt store url is not configured
|
154
|
+
def pre_validation
|
155
|
+
|
156
|
+
@safe_path = OpenSession::Attributes.instance.get_value @@context_name, "safe"
|
157
|
+
safe_configured = File.exists?( @safe_path ) && File.directory?( @safe_path )
|
158
|
+
@err_msg = "[safe] storage not yet configured. Try =>] opensecret safe /folder/path"
|
159
|
+
raise SafeDirNotConfigured.new @err_msg, @safe_path unless safe_configured
|
160
|
+
|
161
|
+
@email_addr = OpenSession::Attributes.instance.get_value @@context_name, "email"
|
162
|
+
email_configured = !@email_addr.nil? && !@email_addr.empty? && @email_addr.length > 4
|
163
|
+
@err_msg = "viable [email address] not configured. Try =>] opensecret email joe@example.com"
|
164
|
+
raise EmailAddrNotConfigured.new @err_msg, @email_addr unless email_configured
|
165
|
+
|
166
|
+
@store_url = OpenSession::Attributes.instance.get_value @@context_name, "store"
|
167
|
+
store_configured = !@store_url.nil? && !@store_url.empty? && @store_url.length > 0
|
168
|
+
@err_msg = "crypt [store url] not configured. Try =>] opensecret store /path/to/crypt"
|
169
|
+
raise StoreUrlNotConfigured.new @err_msg, @store_url unless store_configured
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
|
177
|
+
end
|
data/lib/using.txt
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
|
2
|
+
==============================================================================================
|
3
|
+
|
4
|
+
open office/laptop
|
5
|
+
(or pull)
|
6
|
+
|
7
|
+
put login/username=myname
|
8
|
+
put login/password=mysecret
|
9
|
+
list
|
10
|
+
put disk/password=anothersecret
|
11
|
+
swap disk/password=bettersecret
|
12
|
+
|
13
|
+
lock
|
14
|
+
(or push)
|
15
|
+
==============================================================================================
|
16
|
+
|
17
|
+
|
18
|
+
open office/laptop --with=asdfasdflkhlkh
|
19
|
+
(or pull)
|
20
|
+
|
21
|
+
list
|
22
|
+
get login
|
23
|
+
get disk
|
24
|
+
trash disk
|
25
|
+
list
|
26
|
+
get login/password
|
27
|
+
|
28
|
+
lock
|
29
|
+
(or push)
|
30
|
+
==============================================================================================
|
31
|
+
|
32
|
+
|
33
|
+
lock <<path/to/a/file.txt>> ## locks (encrypts) the file in-place | you must delete it
|
34
|
+
lock <<path/to/a/folder>> --zip ## zips and encrypts folder (in-place) | you must delete it
|
35
|
+
|
36
|
+
==============================================================================================
|
37
|
+
|
38
|
+
Command => open office/laptop
|
39
|
+
|
40
|
+
Effect1 => Creates in-memory INI string (see below) and writes (in effect2) to file
|
41
|
+
Effect2 => Creates a an openkey eg asdfa234234234sfss and a long password.
|
42
|
+
Effect3 => Creates a file ../<<email>>/opened.files/office/laptop.asdfa234234234sfss.x.txt
|
43
|
+
Effect4 => Puts long password in $HOME/.opensecret/session.keys/asdfa234234234sfss.x.txt
|
44
|
+
|
45
|
+
-------------------------------------
|
46
|
+
in-memory INI string
|
47
|
+
-------------------------------------
|
48
|
+
[opensecret]
|
49
|
+
|
50
|
+
secret.path = office/laptop
|
51
|
+
-------------------------------------
|
52
|
+
|
53
|
+
Assert => no office/laptop exists before opening (if so prompt user to => trash office/laptop
|
54
|
+
|
55
|
+
==============================================================================================
|
56
|
+
|
57
|
+
Command => open office/laptop/login/fullname="Mr Blobby"
|
58
|
+
|
59
|
+
Effect1 => Creates in-memory INI string (see below) and writes (in effect2) to file
|
60
|
+
Effect2 => Creates a file ../<<email>>/opened.files/office/laptop.asdfa234234234sfss.x.txt
|
61
|
+
Effect3 => With its encrypt-key in $HOME/.opensecret/session.keys/asdfa234234234sfss.x.txt
|
62
|
+
|
63
|
+
-------------------------------------
|
64
|
+
in-memory INI string
|
65
|
+
-------------------------------------
|
66
|
+
[opensecret]
|
67
|
+
|
68
|
+
secret.path = office/laptop
|
69
|
+
|
70
|
+
[login]
|
71
|
+
fullname = Mr Blobby
|
72
|
+
-------------------------------------
|
73
|
+
|
74
|
+
Assert => no office/laptop exists before opening (if so prompt user to => trash office/laptop
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
inner_key
|
79
|
+
outer_key
|
80
|
+
filename
|
81
|
+
foldername
|
82
|
+
office/room2/rack6/server4/username
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
open
|
88
|
+
|
89
|
+
get session id as time string
|
90
|
+
use
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
close
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
lock wifi/password
|
102
|
+
|
103
|
+
[keys]
|
104
|
+
wifi = asdff234523
|
105
|
+
password = dfgsdfgsfg
|
106
|
+
|
107
|
+
|
108
|
+
asdff234523/dfgsdfgsfg
|
109
|
+
|
110
|
+
[home]
|
111
|
+
|
112
|
+
wifi=asdfasd
|
113
|
+
alarm=fdghdfg
|
114
|
+
safe1=3456hjk3h45
|
115
|
+
safe2=2n34lijss
|
116
|
+
|
117
|
+
======================================
|
118
|
+
|
119
|
+
in asdfasd (wifi)
|
120
|
+
|
121
|
+
[home/wifi]
|
122
|
+
|
123
|
+
ssid = 3452454
|
124
|
+
password = 2452345
|
125
|
+
|
126
|
+
|
127
|
+
office/room2/rack6/server4/username
|
128
|
+
office/accounts/sage
|
129
|
+
office/alarm/pin
|
130
|
+
office/gmail/username
|
131
|
+
|
132
|
+
|
133
|
+
[office]
|
134
|
+
|
135
|
+
room2 = asddf345
|
136
|
+
accounts = 9o8udfg
|
137
|
+
alarm = 345ljdfg
|
138
|
+
gmail = ldf2345
|
139
|
+
|
140
|
+
|
141
|
+
[office/room2]
|
142
|
+
|
143
|
+
rack6 = asdf234
|
144
|
+
|
145
|
+
[office/room2]
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opensecret
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.951
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Apollo Akora
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-02-
|
11
|
+
date: 2018-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inifile
|
@@ -143,12 +143,14 @@ files:
|
|
143
143
|
- lib/plugins/usecase.rb
|
144
144
|
- lib/plugins/usecases/init.rb
|
145
145
|
- lib/plugins/usecases/on.rb
|
146
|
+
- lib/plugins/usecases/open.rb
|
146
147
|
- lib/plugins/usecases/safe.rb
|
147
148
|
- lib/session/attributes.rb
|
148
149
|
- lib/session/fact.finder.rb
|
149
150
|
- lib/session/require.gem.rb
|
150
151
|
- lib/session/time.stamp.rb
|
151
152
|
- lib/session/user.home.rb
|
153
|
+
- lib/using.txt
|
152
154
|
- lib/version.rb
|
153
155
|
- opensecret.gemspec
|
154
156
|
homepage: https://www.eco-platform.co.uk
|