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