opensecret 0.0.962 → 0.0.988
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +16 -10
- data/bin/opensecret +3 -4
- data/bin/ops +5 -0
- data/lib/extension/string.rb +114 -0
- data/lib/factbase/facts.opensecret.io.ini +9 -21
- data/lib/interprete/begin.rb +232 -0
- data/lib/interprete/cmd.rb +621 -0
- data/lib/{plugins/usecases/unlock.rb → interprete/export.rb} +25 -70
- data/lib/interprete/init.rb +205 -0
- data/lib/interprete/key.rb +119 -0
- data/lib/interprete/open.rb +148 -0
- data/lib/{plugins/usecases → interprete}/put.rb +19 -6
- data/lib/{plugins/usecases → interprete}/safe.rb +2 -1
- data/lib/{plugins/usecases/lock.rb → interprete/seal.rb} +24 -34
- data/lib/interprete/set.rb +46 -0
- data/lib/interprete/use.rb +43 -0
- data/lib/interpreter.rb +165 -0
- data/lib/keytools/binary.map.rb +245 -0
- data/lib/keytools/digester.rb +245 -0
- data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +179 -0
- data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +190 -0
- data/lib/keytools/doc.star.schema.strategy.txt +77 -0
- data/lib/keytools/doc.using.pbkdf2.kdf.ruby +95 -0
- data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +266 -0
- data/lib/keytools/kdf.bcrypt.rb +180 -0
- data/lib/keytools/kdf.pbkdf2.rb +164 -0
- data/lib/keytools/key.data.rb +227 -0
- data/lib/keytools/key.derivation.rb +341 -0
- data/lib/keytools/key.module.rb +140 -0
- data/lib/keytools/key.rb +481 -0
- data/lib/logging/gem.logging.rb +1 -2
- data/lib/modules/cryptology.md +43 -0
- data/lib/{plugins/ciphers → modules/cryptology}/aes-256.rb +6 -0
- data/lib/{crypto → modules/cryptology}/amalgam.rb +6 -0
- data/lib/modules/cryptology/blowfish.rb +130 -0
- data/lib/modules/cryptology/cipher.rb +207 -0
- data/lib/modules/cryptology/collect.rb +118 -0
- data/lib/{plugins → modules/cryptology}/crypt.io.rb +5 -0
- data/lib/{crypto → modules/cryptology}/engineer.rb +7 -1
- data/lib/{crypto → modules/cryptology}/open.bcrypt.rb +0 -0
- data/lib/modules/mappers/collateral.rb +282 -0
- data/lib/modules/mappers/dictionary.rb +288 -0
- data/lib/modules/mappers/envelope.rb +127 -0
- data/lib/modules/mappers/settings.rb +170 -0
- data/lib/modules/storage/coldstore.rb +186 -0
- data/lib/{opensecret/plugins.io/git/git.flow.rb → modules/storage/git.store.rb} +11 -0
- data/lib/notepad/scratch.pad.rb +17 -0
- data/lib/session/fact.finder.rb +13 -0
- data/lib/session/require.gem.rb +5 -0
- data/lib/store-commands.txt +180 -0
- data/lib/version.rb +1 -1
- data/opensecret.gemspec +5 -6
- metadata +74 -29
- data/lib/crypto/blowfish.rb +0 -85
- data/lib/crypto/collect.rb +0 -140
- data/lib/crypto/verify.rb +0 -33
- data/lib/opensecret.rb +0 -236
- data/lib/plugins/cipher.rb +0 -203
- data/lib/plugins/ciphers/blowfish.rb +0 -126
- data/lib/plugins/coldstore.rb +0 -181
- data/lib/plugins/envelope.rb +0 -116
- data/lib/plugins/secrets.uc.rb +0 -94
- data/lib/plugins/usecase.rb +0 -239
- data/lib/plugins/usecases/init.rb +0 -145
- data/lib/plugins/usecases/open.rb +0 -108
- data/lib/session/attributes.rb +0 -279
- data/lib/session/dictionary.rb +0 -191
- data/lib/session/file.path.rb +0 -53
- data/lib/session/session.rb +0 -80
@@ -4,31 +4,31 @@ module OpenSecret
|
|
4
4
|
|
5
5
|
require 'openssl'
|
6
6
|
|
7
|
-
# The <tt>
|
7
|
+
# The <tt>export use case</tt> moves doubly encrypted material <b>from the frozen</b>
|
8
8
|
# (key and crypt) stores, <b>into an (encrypted) session envelope</b>.
|
9
9
|
#
|
10
10
|
# Material within the auspices of the session envelope can be manipulated by commands
|
11
11
|
# like {OpenSecret::Put} and remove and also read by commands like peep, look and update.
|
12
12
|
#
|
13
|
-
# <b>
|
13
|
+
# <b>Export | Pre-Conditions</b>
|
14
14
|
#
|
15
15
|
# To deliver on its core promise of moving the encrypted (key and crypt) stores
|
16
|
-
# to an encrypted session envelope, <b>
|
16
|
+
# to an encrypted session envelope, <b>export</b> expects
|
17
17
|
#
|
18
18
|
# - the local key and crypt stores to be pulled (refreshed) from remote
|
19
19
|
# - the destination session path to either be empty (or)
|
20
20
|
# - a populated session path containing equivalent data (ie cannot be overwritten)
|
21
21
|
# - both the human (agent) password and workstation key to be correct
|
22
22
|
#
|
23
|
-
# <b>
|
23
|
+
# <b>Export | Alternate Flows</b>
|
24
24
|
#
|
25
25
|
# This use case requires the human (agent) password unless the <tt>--no-human-password</tt>
|
26
26
|
# flag was posted along with the <tt>init</tt> command. In this instance an agent password
|
27
27
|
# will have been generated and encrypted with the user's home tree.
|
28
28
|
#
|
29
|
-
# <b>
|
29
|
+
# <b>Export | Observable Value</b>
|
30
30
|
#
|
31
|
-
# The observable value proffered by
|
31
|
+
# The observable value proffered by export is
|
32
32
|
#
|
33
33
|
# - validating the existence of the requested secret path
|
34
34
|
# - validation of the human password and workstation key
|
@@ -46,7 +46,7 @@ module OpenSecret
|
|
46
46
|
# $ opensecret put france/capital paris
|
47
47
|
# $ opensecret put france/population 23000000
|
48
48
|
# $ opensecret lock
|
49
|
-
# $ opensecret
|
49
|
+
# $ opensecret export geo/countries --with=asdfasdf
|
50
50
|
#
|
51
51
|
# Below are future examples with use cases like list and print
|
52
52
|
# which curently have not been implemented.
|
@@ -62,7 +62,7 @@ module OpenSecret
|
|
62
62
|
# $ opensecret lock
|
63
63
|
# $ opensecret list
|
64
64
|
#
|
65
|
-
# $ opensecret
|
65
|
+
# $ opensecret export my/gadgets --with="hUM4n-0pen$3cr3t"
|
66
66
|
# $ opensecret print
|
67
67
|
#
|
68
68
|
# $ opensecret put wifi/ssid Virgin-HGPAS
|
@@ -71,10 +71,9 @@ module OpenSecret
|
|
71
71
|
# $ opensecret print
|
72
72
|
# $ opensecret lock
|
73
73
|
#
|
74
|
-
class
|
74
|
+
class Export < Command
|
75
75
|
|
76
76
|
attr_writer :outer_path, :master_p4ss
|
77
|
-
@@context_name = "opensecret"
|
78
77
|
|
79
78
|
|
80
79
|
# The <tt>lock use case</tt> is called after {OpenSecret::Open} and {OpenSecret::Put}
|
@@ -110,76 +109,39 @@ module OpenSecret
|
|
110
109
|
# - deletion of {Open}ed session data to locate and decrypt envelope
|
111
110
|
def execute
|
112
111
|
|
113
|
-
|
114
|
-
|
112
|
+
instantiate_collateral
|
113
|
+
|
114
|
+
keys_store = Store::ColdStore.new( @collateral.frontend_keystore_path )
|
115
|
+
main_store = Store::ColdStore.new( @collateral.backend_cryptstore_path )
|
115
116
|
|
116
117
|
keys_crypt = keys_store.read @outer_path
|
117
118
|
main_crypt = main_store.read @outer_path
|
118
119
|
|
119
120
|
unless @master_p4ss
|
120
|
-
@master_p4ss = Collect.secret_text(
|
121
|
+
@master_p4ss = ToolBelt::Collect.secret_text(
|
121
122
|
@c[:global][:min_passwd_len],
|
122
123
|
false,
|
123
124
|
"Enter Master Password "
|
124
125
|
)
|
125
126
|
end
|
126
127
|
|
127
|
-
workstation_rawkey =
|
128
|
-
original_timestamp =
|
128
|
+
workstation_rawkey = Mapper::Settings.read @collateral.domain_name, @c[:global][:machine_key_id]
|
129
|
+
original_timestamp = Mapper::Settings.read @collateral.domain_name, @c[:global][:time_stamp_id]
|
129
130
|
workstation_cipher = Base64.urlsafe_decode64( workstation_rawkey )
|
130
|
-
crypt_key_segments = [ @master_p4ss, @c[:global][:separator_a],
|
131
|
+
crypt_key_segments = [ @master_p4ss, @c[:global][:separator_a], original_timestamp ]
|
131
132
|
workstation_lock_x = crypt_key_segments.alphanumeric_union.concat_length
|
132
133
|
|
133
|
-
workstation_string = Blowfish.
|
134
|
-
private_key_lock_x = Amalgam.passwords @master_p4ss, workstation_string, @c[:global][:ratio]
|
135
|
-
private_key_cipher =
|
134
|
+
workstation_string = ToolBelt::Blowfish.decryptor workstation_cipher, workstation_lock_x
|
135
|
+
private_key_lock_x = ToolBelt::Amalgam.passwords @master_p4ss, workstation_string, @c[:global][:ratio]
|
136
|
+
private_key_cipher = @collateral.read_private_key
|
136
137
|
private_key_object = unlock_private_key( private_key_cipher, private_key_lock_x )
|
137
138
|
|
138
|
-
string_private_key = Cipher.decrypt_it( private_key_object, keys_crypt )
|
139
|
-
plain_message_text = Cipher.decrypt_it( to_private_key(string_private_key), main_crypt )
|
140
|
-
|
141
|
-
puts ""
|
142
|
-
puts "==== ======================================= ===="
|
143
|
-
puts "==== The Exported Plain Text Structured Data ===="
|
144
|
-
puts "==== ======================================= ===="
|
145
|
-
puts ""
|
146
|
-
puts plain_message_text
|
147
|
-
puts ""
|
148
|
-
puts ""
|
149
|
-
puts JSON.pretty_generate( JSON.parse( plain_message_text ) )
|
150
|
-
puts ""
|
151
|
-
|
152
|
-
exit
|
153
|
-
|
154
|
-
#############################################################################################
|
155
|
-
#############################################################################################
|
156
|
-
|
157
|
-
rel_filepath = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_pathname]
|
158
|
-
master_public_key = Base64.urlsafe_decode64( OpenSession::Attributes.instance.get_value @c[:global][:name], @c[:global][:name], "public.key" )
|
159
|
-
|
160
|
-
|
161
|
-
#############################################################################################
|
162
|
-
#############################################################################################
|
163
|
-
|
164
|
-
=begin
|
165
|
-
Crypto.print_secret_env_var @p[:env_var_name], machine_key
|
166
|
-
GitFlow.do_clone_repo @p[:public_gitrepo], @p[:local_gitrepo]
|
167
|
-
FileUtils.mkdir_p @p[:public_keydir]
|
168
|
-
File.write @p[:public_keypath], public_key_text
|
169
|
-
GitFlow.push @p[:local_gitrepo], @p[:public_keyname], @c[:time][:stamp]
|
170
|
-
=end
|
139
|
+
string_private_key = ToolBelt::Cipher.decrypt_it( private_key_object, keys_crypt )
|
140
|
+
plain_message_text = ToolBelt::Cipher.decrypt_it( to_private_key(string_private_key), main_crypt )
|
171
141
|
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
# key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
|
176
|
-
# decrypted_text = key4.private_decrypt(Base64.urlsafe_decode64(encrypted_string))
|
177
|
-
|
178
|
-
# print "\nHey we have done the decryption.\n", "\n"
|
179
|
-
# print decrypted_text, "\n"
|
180
|
-
|
181
|
-
#############################################################################################
|
182
|
-
#############################################################################################
|
142
|
+
puts
|
143
|
+
puts JSON.pretty_generate( JSON.parse( plain_message_text ) )
|
144
|
+
puts
|
183
145
|
|
184
146
|
end
|
185
147
|
|
@@ -192,11 +154,6 @@ module OpenSecret
|
|
192
154
|
# @raise [StoreUrlNotConfigured] if the crypt store url is not configured
|
193
155
|
def pre_validation
|
194
156
|
|
195
|
-
@email_addr = OpenSession::Attributes.instance.get_value @@context_name, @@context_name, "email"
|
196
|
-
email_configured = !@email_addr.nil? && !@email_addr.empty? && @email_addr.length > 4
|
197
|
-
@err_msg = "viable [email address] not configured. Try =>] opensecret email joe@example.com"
|
198
|
-
raise EmailAddrNotConfigured.new @err_msg, @email_addr unless email_configured
|
199
|
-
|
200
157
|
end
|
201
158
|
|
202
159
|
|
@@ -204,5 +161,3 @@ module OpenSecret
|
|
204
161
|
|
205
162
|
|
206
163
|
end
|
207
|
-
|
208
|
-
|
@@ -0,0 +1,205 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
module OpenSecret
|
4
|
+
|
5
|
+
require 'openssl'
|
6
|
+
|
7
|
+
# The <b>init use case</b> initializes opensecret thus preparing it
|
8
|
+
# for the ability to lock secrets, unlock them, transport their keys and
|
9
|
+
# much more.
|
10
|
+
#
|
11
|
+
# Like all use cases, +init+ validates to ensure that the pre-conditions
|
12
|
+
# have been met and then proceeds to execute its core offering and deliver
|
13
|
+
# observable value.
|
14
|
+
#
|
15
|
+
# == RAGE | Resource Allocation Geography
|
16
|
+
#
|
17
|
+
# Resources are situated in a manner that delivers the maximum possible
|
18
|
+
# security, with as much usability and simplicity that can be accomodated
|
19
|
+
# and all the while ensuring the owner retains access to the secrets in
|
20
|
+
# the face of multiple disasters befalling the environment.
|
21
|
+
#
|
22
|
+
# The session concept married with public/private key cryptology are the
|
23
|
+
# main vehicles for delivering both simplicity and security. A system that
|
24
|
+
# enables one to lock away secrets without exposing the master password
|
25
|
+
# is more secure than those that don't.
|
26
|
+
#
|
27
|
+
#
|
28
|
+
# == Frontend Store | USB Connected Device ( eg Keys, Phones )
|
29
|
+
#
|
30
|
+
# The frontend store (usually on a USB or other external but filesystem accessible
|
31
|
+
# drive) contains the
|
32
|
+
#
|
33
|
+
# - encrypted private key | created by {Init}, updated by {ReKey}, read by {Open} {Export}
|
34
|
+
# - public key | created by {Init}, updated by {ReKey}, read by {Seal} {Post} {Open}
|
35
|
+
# - encrypted open envelopes tree | created/read/updated by {Put} {Add}, deleted by {Discard}
|
36
|
+
# - encrypted libary keys tree | created by {Seal}, updated by {ReKey}, read by {Open} {Export}
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# == Workstation Configuration File
|
40
|
+
#
|
41
|
+
# The global configuration filepath is <tt>~/.opensecret.io/opensecret.io.configuration.ini</tt>
|
42
|
+
#
|
43
|
+
# The global configuration file is managed through the {OpenSecret::Mapper::Settings} and
|
44
|
+
# the {OpenSecret::Mapper::Collateral.config_file} classes and points to the
|
45
|
+
#
|
46
|
+
# - current domain | created/updated by {Init}, updated by {Set}, read by most
|
47
|
+
# - domain frontend path | created by {Init}, updated by {Set} and read by most
|
48
|
+
# - domain store id | created/updated by {Set}, read by {Post}
|
49
|
+
# - the domain's initialization time stamp | created by {Init}, read by {Seal}
|
50
|
+
# - the encrypted machine (workstation) key | created by {Init}, read by {Seal}
|
51
|
+
#
|
52
|
+
# As well as the global config file, the workstation store contains the logs and most
|
53
|
+
# importantly the mirrored departures/arrival lounge.
|
54
|
+
#
|
55
|
+
#
|
56
|
+
# == Workstation Departure/Arrival Lounge
|
57
|
+
#
|
58
|
+
# The departures and arrivals lounge holds sealed envelopes that are either
|
59
|
+
#
|
60
|
+
# - waiting to (depart) be posted to the remote mirror
|
61
|
+
# - waiting to be read/updated after (arrival) from the remote mirror
|
62
|
+
# - posing as the remote mirror whilst no backend store exists
|
63
|
+
#
|
64
|
+
# The contents of the backend mirror (aka departure/arrival lounge) are
|
65
|
+
#
|
66
|
+
# - created by {Seal} and two-way {Post}
|
67
|
+
# - read by {Open}
|
68
|
+
# - deleted by {Delete}
|
69
|
+
#
|
70
|
+
#
|
71
|
+
# == Workstation | Share and Transfers Lounge
|
72
|
+
#
|
73
|
+
# The self-evident power of opensecret blooms when you share secrets with others in
|
74
|
+
# and out of a domain. The simplest application is when two users belong to the same
|
75
|
+
# domain - the only thing they actually share is the remote back-end store and their
|
76
|
+
# public keys. The lounge tree contains
|
77
|
+
#
|
78
|
+
# - key envelopes for ownership transfer
|
79
|
+
# - key envelopes for sharing
|
80
|
+
# - key envelopes for telling (sender never actual owns the sealed envelope)
|
81
|
+
#
|
82
|
+
#
|
83
|
+
# == Observable Value
|
84
|
+
#
|
85
|
+
# The observable value from the <b>init use case</b> init boils down to
|
86
|
+
#
|
87
|
+
# - the public key and <b>8192 bit encrypted private key</b> in the safe
|
88
|
+
# - the <b>encrypted workstation key</b> in the user's configuration file
|
89
|
+
# - the <b>encrypted public key signature</b> in the user's configuration file
|
90
|
+
# - a robust password (for unlocking secrets) +stashed in a human brain+
|
91
|
+
# - successful test of the open, put, list, lock, read and tell use cases
|
92
|
+
#
|
93
|
+
# No cloud or other external access occurs as per the opensecret policy.
|
94
|
+
#
|
95
|
+
# == Thwart Public Key Switch Attacks
|
96
|
+
#
|
97
|
+
# A <b><em>public key switch attack</em></b> tries to access <b>future secrets</b>
|
98
|
+
# (not the ones already encrypted) via unwitting encryption using a public key
|
99
|
+
# the attacker controls.
|
100
|
+
#
|
101
|
+
# <b>opensecret</b> thwarts this by continual verification against an
|
102
|
+
# encrypted <em>public key signature</em> aboard the workstation.
|
103
|
+
class Init < Command
|
104
|
+
|
105
|
+
attr_writer :master_p4ss, :domain_name, :base_path
|
106
|
+
|
107
|
+
|
108
|
+
# The init use case prepares <b>opensecret</b> so that you can <b>open</b> a packet,
|
109
|
+
# <b>put</b> secrets into it and then <b>lock</b> it, effectively writing the crypt
|
110
|
+
# material into the backend store.
|
111
|
+
#
|
112
|
+
# <b>Main Flow of Events</b>
|
113
|
+
#
|
114
|
+
# So to prepare for the <b><em>modus operandi</em></b> that encrypts, decrypts and if
|
115
|
+
# required transports secrets, we
|
116
|
+
#
|
117
|
+
# - if the base path exists, look for base.opensecret.io below, in and above the path
|
118
|
+
# - if found we configure the config path as appropriate
|
119
|
+
#
|
120
|
+
#
|
121
|
+
#
|
122
|
+
# - collect the human password (twice) and verify its robustness
|
123
|
+
# - manufacture workstation key that will be encrypted b4 it rests on machine
|
124
|
+
# - create amalgamated human/workstation password for locking the private key
|
125
|
+
# - create a long cryptographically strong symmetric encryption key
|
126
|
+
# - encrypt workstation key and put crypt into the opensecret configuration file
|
127
|
+
# - create a super sized 8192 bit private key (and its asymmetric public key)
|
128
|
+
# - write the AES 256bit encrypted private key into safe-store's master keys
|
129
|
+
# - create a text bundle for signing composed of the keys, email and date/time
|
130
|
+
# - sign the bundle and save the signature in the master keys store
|
131
|
+
# - put the public key in the configuration file (off the homedirectory)
|
132
|
+
# - test the core open, put, list, lock, read and tell use case commands
|
133
|
+
#
|
134
|
+
# <b>Observable (Configuration) Value</b>
|
135
|
+
#
|
136
|
+
# The <tt>init use case</tt> observable value post-conditions are
|
137
|
+
#
|
138
|
+
# - the domain_name (group) and domain_path (key) exist in configuration file
|
139
|
+
# - a directory called <tt>ops.<domain_name></tt> exists at/below or above domain_path
|
140
|
+
#
|
141
|
+
#
|
142
|
+
# - the <b>8192 bit encrypted private key</b> in the master keys safe
|
143
|
+
# - the <b>public key</b>, time stamp and encrypted workstation key in config
|
144
|
+
# - the <b>encrypted workstation key</b> in the user's configuration file
|
145
|
+
# - the <b>asymmetric keys, time stamp and email</b> signature in master keys safe
|
146
|
+
# - a robust password (for unlocking secrets) +stashed in a human brain+
|
147
|
+
#
|
148
|
+
# <b>Alternate Flows</b>
|
149
|
+
#
|
150
|
+
# - if the base path exists, look for base.opensecret.io below, in and above the path
|
151
|
+
# - two or more different domains under the same base is fine however there is a catch
|
152
|
+
# - domain names cannot be duplicated (even if a different base path is given)
|
153
|
+
# - domain duplication is disallowed as domains are group keys in the config file
|
154
|
+
#
|
155
|
+
# <b>Error Flows</b>
|
156
|
+
#
|
157
|
+
# An error will be thrown
|
158
|
+
#
|
159
|
+
# - if ops can't create or extend the base directory
|
160
|
+
# - if the domain is already in the configuration file
|
161
|
+
# - if domain has non alphanums, excl hyphens, underscores, @ symbols, periods
|
162
|
+
# - if domain does not begin or end with alphanums.
|
163
|
+
# - if non alpha-nums (excl at signs) appear consecutively
|
164
|
+
# - if no alpha-nums appear in the string
|
165
|
+
# - if the domain string's length is less than 5
|
166
|
+
# - if "base.opensecret.io" appears twice (or more) in a directory tree
|
167
|
+
#
|
168
|
+
def execute
|
169
|
+
|
170
|
+
return unless ops_key_exists?
|
171
|
+
|
172
|
+
Mapper::Settings.stash @c[:global][:domain_now_id], @domain_name
|
173
|
+
Mapper::Settings.write @domain_name, @c[:global][:front_path_id], @base_path
|
174
|
+
|
175
|
+
instantiate_collateral
|
176
|
+
unless @master_p4ss
|
177
|
+
@master_p4ss = ToolBelt::Collect.secret_text(
|
178
|
+
@c[:global][:min_passwd_len],
|
179
|
+
true,
|
180
|
+
@c[:global][:prompt_1],
|
181
|
+
@c[:global][:prompt_2]
|
182
|
+
)
|
183
|
+
end
|
184
|
+
|
185
|
+
locking_key = create_crypt_store_locking_key
|
186
|
+
|
187
|
+
asymmetric_keys = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
|
188
|
+
secured_keytext = asymmetric_keys.export @c[:global][:key_cipher], locking_key
|
189
|
+
@collateral.write_public_key asymmetric_keys.public_key.to_pem
|
190
|
+
@collateral.write_private_key secured_keytext
|
191
|
+
|
192
|
+
print_success_initializing
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
|
197
|
+
def pre_validation
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
module OpenSecret
|
4
|
+
|
5
|
+
# The <tt>key use case</tt> prints out an encrypted session key tied
|
6
|
+
# to the workstation and shell environment. It should be called like this
|
7
|
+
# and <tt>printenv</tt> can be used to verify that a shell-scoped
|
8
|
+
# environment variable tying OPS_KEY to an (approximately) 48 character
|
9
|
+
# session password, has been created.
|
10
|
+
#
|
11
|
+
# export OPS_KEY=`ops key`
|
12
|
+
# printenv
|
13
|
+
#
|
14
|
+
# Note the <b>back-ticks</b> surrounding the <tt>ops key</tt> call.
|
15
|
+
#
|
16
|
+
# == Algorithm or Creating the Key
|
17
|
+
#
|
18
|
+
# An (approximately) 48 character key is acquired and then the four
|
19
|
+
# data points below are used to symmetrically encrypt it.
|
20
|
+
#
|
21
|
+
# - <b>the parent shell's ID</b>
|
22
|
+
# - <em>the first MAC address</em>
|
23
|
+
# - <b>the machine's hostname</b>
|
24
|
+
# - <em>the current timestamp</em>
|
25
|
+
#
|
26
|
+
# The result is Base64 encoded in url safe mode and printed to standard
|
27
|
+
# out <b>without a trailing newline</b>.
|
28
|
+
#
|
29
|
+
# == Removing Equals from Key
|
30
|
+
#
|
31
|
+
# An environment variable holds the key's value and the <b>equals sign</b>
|
32
|
+
# is not allowed within environment variables (in some operating systems)
|
33
|
+
# mainly due to the fact that it is used as the key/value separator.
|
34
|
+
#
|
35
|
+
# The url safe base64 coding may produce one, two or three equal signs in
|
36
|
+
# a bid to pad the string into a multiple of 4 length.
|
37
|
+
#
|
38
|
+
# Thus, we replace the equals signs with the @ symbol when encoding and
|
39
|
+
# vice versa when decoding.
|
40
|
+
#
|
41
|
+
# For added security the key should auto time (or be zeroed) out.
|
42
|
+
class Key < Command
|
43
|
+
|
44
|
+
|
45
|
+
# The <tt>key use case</tt> prints out an encrypted session key tied
|
46
|
+
# to the workstation and shell environment. It should be called like this
|
47
|
+
# and <tt>printenv</tt> can be used to verify that a shell-scoped
|
48
|
+
# environment variable tying OPS_KEY to an (approximately) 48 character
|
49
|
+
# session password, has been created.
|
50
|
+
#
|
51
|
+
# export OPS_KEY=`ops key`
|
52
|
+
# printenv
|
53
|
+
#
|
54
|
+
# Note the <b>back-ticks</b> surrounding the <tt>ops key</tt> call.
|
55
|
+
#
|
56
|
+
# <b>The 3 Session Keys</b>
|
57
|
+
#
|
58
|
+
# Three keys are involved here.
|
59
|
+
#
|
60
|
+
# - the 48 character random session key
|
61
|
+
# - the encryption key which is an amalgam
|
62
|
+
# - the base64 encoded key cipher text
|
63
|
+
#
|
64
|
+
#
|
65
|
+
# == Removing Equals from Key
|
66
|
+
#
|
67
|
+
# An environment variable holds the key's value and the <b>equals sign</b>
|
68
|
+
# is not allowed within environment variables (in some operating systems)
|
69
|
+
# mainly due to the fact that it is used as the key/value separator.
|
70
|
+
#
|
71
|
+
# The url safe base64 coding may produce one, two or three equal signs in
|
72
|
+
# a bid to pad the string into a multiple of 4 length.
|
73
|
+
#
|
74
|
+
# Thus, we replace the equals signs with the @ symbol when encoding and
|
75
|
+
# vice versa when decoding.
|
76
|
+
#
|
77
|
+
# @example
|
78
|
+
#
|
79
|
+
# Session Key => QE6tlTt1fgwvKCYj9aG1K3cwks0EBMy9RgPT1KLqbnDUVRCdlq1EMxirW3ixyaSA
|
80
|
+
# Encrypt Key => 20cf3067dec35817data-crunch18083.0321.02.878296898
|
81
|
+
# An Open Key => FvxETEpmoVUetyJ0jJk19aus1pQkzLZ8OVJccatYnC9GxDE4Iy3AyWNZ...
|
82
|
+
#
|
83
|
+
# $ printenv
|
84
|
+
# $ export OPS_KEY=`ops key`
|
85
|
+
# $ printenv
|
86
|
+
#
|
87
|
+
# The 2nd printenv should reveal a shell specific environment variable.
|
88
|
+
#
|
89
|
+
# OPS_KEY=FvxETEpmoVUetyJ0jJk19aus1pQkzLZ8OVJccatYnC9GxDE4Iy3AyWNZ...
|
90
|
+
#
|
91
|
+
def execute
|
92
|
+
|
93
|
+
session_key = ToolBelt::Engineer.strong_key( 48 )
|
94
|
+
openkey_key = Base64.urlsafe_encode64(
|
95
|
+
ToolBelt::Blowfish.encryptor( session_key, session_key_password )
|
96
|
+
).gsub("=","@")
|
97
|
+
|
98
|
+
print openkey_key
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
# Perform pre-conditional validations in preparation to executing the main flow
|
104
|
+
# of events for this use case. This method may throw the below exceptions.
|
105
|
+
#
|
106
|
+
# @raise [SafeDirNotConfigured] if the safe's url has not been configured
|
107
|
+
# @raise [EmailAddrNotConfigured] if the email address has not been configured
|
108
|
+
# @raise [StoreUrlNotConfigured] if the crypt store url is not configured
|
109
|
+
def pre_validation
|
110
|
+
|
111
|
+
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
end
|
119
|
+
|