opensecret 0.0.988 → 0.0.9925
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +56 -159
- data/bin/opensecret +2 -2
- data/bin/ops +17 -2
- data/lib/extension/string.rb +14 -16
- data/lib/{interpreter.rb → interprete.rb} +53 -29
- data/lib/keytools/binary.map.rb +49 -0
- data/lib/keytools/kdf.api.rb +249 -0
- data/lib/keytools/kdf.bcrypt.rb +64 -29
- data/lib/keytools/kdf.pbkdf2.rb +92 -83
- data/lib/keytools/kdf.scrypt.rb +190 -0
- data/lib/keytools/key.64.rb +326 -0
- data/lib/keytools/key.algo.rb +109 -0
- data/lib/keytools/key.api.rb +1281 -0
- data/lib/keytools/key.db.rb +265 -0
- data/lib/keytools/{key.module.rb → key.docs.rb} +55 -0
- data/lib/keytools/key.error.rb +110 -0
- data/lib/keytools/key.id.rb +271 -0
- data/lib/keytools/key.iv.rb +107 -0
- data/lib/keytools/key.local.rb +265 -0
- data/lib/keytools/key.mach.rb +248 -0
- data/lib/keytools/key.now.rb +402 -0
- data/lib/keytools/key.pair.rb +259 -0
- data/lib/keytools/key.pass.rb +120 -0
- data/lib/keytools/key.rb +428 -298
- data/lib/keytools/keydebug.txt +295 -0
- data/lib/logging/gem.logging.rb +3 -3
- data/lib/modules/cryptology/collect.rb +20 -0
- data/lib/session/require.gem.rb +1 -1
- data/lib/usecase/cmd.rb +417 -0
- data/lib/usecase/id.rb +36 -0
- data/lib/usecase/import.rb +174 -0
- data/lib/usecase/init.rb +78 -0
- data/lib/usecase/login.rb +70 -0
- data/lib/usecase/logout.rb +30 -0
- data/lib/usecase/open.rb +126 -0
- data/lib/{interprete → usecase}/put.rb +100 -47
- data/lib/usecase/read.rb +89 -0
- data/lib/{interprete → usecase}/safe.rb +0 -0
- data/lib/{interprete → usecase}/set.rb +0 -0
- data/lib/usecase/token.rb +111 -0
- data/lib/{interprete → usecase}/use.rb +0 -0
- data/lib/version.rb +1 -1
- data/opensecret.gemspec +4 -3
- metadata +39 -33
- data/lib/exception/cli.error.rb +0 -53
- data/lib/exception/errors/cli.errors.rb +0 -31
- data/lib/interprete/begin.rb +0 -232
- data/lib/interprete/cmd.rb +0 -621
- data/lib/interprete/export.rb +0 -163
- data/lib/interprete/init.rb +0 -205
- data/lib/interprete/key.rb +0 -119
- data/lib/interprete/open.rb +0 -148
- data/lib/interprete/seal.rb +0 -129
- data/lib/keytools/digester.rb +0 -245
- data/lib/keytools/key.data.rb +0 -227
- data/lib/keytools/key.derivation.rb +0 -341
- data/lib/modules/mappers/collateral.rb +0 -282
- data/lib/modules/mappers/envelope.rb +0 -127
- data/lib/modules/mappers/settings.rb +0 -170
- data/lib/notepad/scratch.pad.rb +0 -224
- data/lib/store-commands.txt +0 -180
data/lib/interprete/export.rb
DELETED
@@ -1,163 +0,0 @@
|
|
1
|
-
#!/usr/bin/ruby
|
2
|
-
|
3
|
-
module OpenSecret
|
4
|
-
|
5
|
-
require 'openssl'
|
6
|
-
|
7
|
-
# The <tt>export use case</tt> moves doubly encrypted material <b>from the frozen</b>
|
8
|
-
# (key and crypt) stores, <b>into an (encrypted) session envelope</b>.
|
9
|
-
#
|
10
|
-
# Material within the auspices of the session envelope can be manipulated by commands
|
11
|
-
# like {OpenSecret::Put} and remove and also read by commands like peep, look and update.
|
12
|
-
#
|
13
|
-
# <b>Export | Pre-Conditions</b>
|
14
|
-
#
|
15
|
-
# To deliver on its core promise of moving the encrypted (key and crypt) stores
|
16
|
-
# to an encrypted session envelope, <b>export</b> expects
|
17
|
-
#
|
18
|
-
# - the local key and crypt stores to be pulled (refreshed) from remote
|
19
|
-
# - the destination session path to either be empty (or)
|
20
|
-
# - a populated session path containing equivalent data (ie cannot be overwritten)
|
21
|
-
# - both the human (agent) password and workstation key to be correct
|
22
|
-
#
|
23
|
-
# <b>Export | Alternate Flows</b>
|
24
|
-
#
|
25
|
-
# This use case requires the human (agent) password unless the <tt>--no-human-password</tt>
|
26
|
-
# flag was posted along with the <tt>init</tt> command. In this instance an agent password
|
27
|
-
# will have been generated and encrypted with the user's home tree.
|
28
|
-
#
|
29
|
-
# <b>Export | Observable Value</b>
|
30
|
-
#
|
31
|
-
# The observable value proffered by export is
|
32
|
-
#
|
33
|
-
# - validating the existence of the requested secret path
|
34
|
-
# - validation of the human password and workstation key
|
35
|
-
# - the keys and crypt at the paths are decrypted
|
36
|
-
# - the session envelope is stuffed with the crypted material
|
37
|
-
# - an encrypted session envelope (post-stuffing)
|
38
|
-
#
|
39
|
-
# @example
|
40
|
-
#
|
41
|
-
# These use case steps are implemented and ready to go.
|
42
|
-
#
|
43
|
-
# $ opensecret open geo/countries
|
44
|
-
# $ opensecret put uganda/capital kampala
|
45
|
-
# $ opensecret put kenya/capital nairobi
|
46
|
-
# $ opensecret put france/capital paris
|
47
|
-
# $ opensecret put france/population 23000000
|
48
|
-
# $ opensecret lock
|
49
|
-
# $ opensecret export geo/countries --with=asdfasdf
|
50
|
-
#
|
51
|
-
# Below are future examples with use cases like list and print
|
52
|
-
# which curently have not been implemented.
|
53
|
-
#
|
54
|
-
# $ opensecret init bobby@example.com --with="hUM4n-0pen$3cr3t"
|
55
|
-
#
|
56
|
-
# $ opensecret open my/gadgets
|
57
|
-
#
|
58
|
-
# $ opensecret put laptop/login/username bob
|
59
|
-
# $ opensecret put laptop/login/password bob$_p455w0rd
|
60
|
-
# $ opensecret put iphone/pin 8529
|
61
|
-
#
|
62
|
-
# $ opensecret lock
|
63
|
-
# $ opensecret list
|
64
|
-
#
|
65
|
-
# $ opensecret export my/gadgets --with="hUM4n-0pen$3cr3t"
|
66
|
-
# $ opensecret print
|
67
|
-
#
|
68
|
-
# $ opensecret put wifi/ssid Virgin-HGPAS
|
69
|
-
# $ opensecret put wifi/password SDBLJHGPASDFA1234ZNF
|
70
|
-
#
|
71
|
-
# $ opensecret print
|
72
|
-
# $ opensecret lock
|
73
|
-
#
|
74
|
-
class Export < Command
|
75
|
-
|
76
|
-
attr_writer :outer_path, :master_p4ss
|
77
|
-
|
78
|
-
|
79
|
-
# The <tt>lock use case</tt> is called after {OpenSecret::Open} and {OpenSecret::Put}
|
80
|
-
# and its effect is to dispatch the doubly encrypted materrial to the configured storage
|
81
|
-
# platform, be it Git, S3, SSH or just an accessible file-system.
|
82
|
-
#
|
83
|
-
# <b>Main Flow of Events</b>
|
84
|
-
#
|
85
|
-
# To seal the envelope built up by put, file and add amongst others requires
|
86
|
-
# that we
|
87
|
-
#
|
88
|
-
# - get the encrypted envelope
|
89
|
-
# - create a strong asymmetric key
|
90
|
-
# - lock the envelope using opensecret's double encrypt modus operandi
|
91
|
-
# - place the doubly encrypted result into the crypt store
|
92
|
-
# - lock the asymmetric key again with opensecret's double encrypt modus operandi
|
93
|
-
# - place the doubly encrypted result into the key store
|
94
|
-
#
|
95
|
-
# The second double lock of the crypted envelope is done with the public key
|
96
|
-
# aspect of an asymmetric key created here.
|
97
|
-
#
|
98
|
-
# The second double lock of the crypted private key (created here) is done with
|
99
|
-
# the master public key created in the {Init.execute} use case main flow.
|
100
|
-
#
|
101
|
-
# <b>Lock | Observable Value</b>
|
102
|
-
#
|
103
|
-
# The observable value after the lock use case has completed entails
|
104
|
-
#
|
105
|
-
# - a doubly encrypted data envelope placed in the backend store
|
106
|
-
# - a doubly encrypted private key placed in the frontend store
|
107
|
-
# - both stores sync'd with off-machine Git (S3, ...) mirrors
|
108
|
-
# - deletion of the (encrypted) envelope {Open}ed and stuffed with {Put}
|
109
|
-
# - deletion of {Open}ed session data to locate and decrypt envelope
|
110
|
-
def execute
|
111
|
-
|
112
|
-
instantiate_collateral
|
113
|
-
|
114
|
-
keys_store = Store::ColdStore.new( @collateral.frontend_keystore_path )
|
115
|
-
main_store = Store::ColdStore.new( @collateral.backend_cryptstore_path )
|
116
|
-
|
117
|
-
keys_crypt = keys_store.read @outer_path
|
118
|
-
main_crypt = main_store.read @outer_path
|
119
|
-
|
120
|
-
unless @master_p4ss
|
121
|
-
@master_p4ss = ToolBelt::Collect.secret_text(
|
122
|
-
@c[:global][:min_passwd_len],
|
123
|
-
false,
|
124
|
-
"Enter Master Password "
|
125
|
-
)
|
126
|
-
end
|
127
|
-
|
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]
|
130
|
-
workstation_cipher = Base64.urlsafe_decode64( workstation_rawkey )
|
131
|
-
crypt_key_segments = [ @master_p4ss, @c[:global][:separator_a], original_timestamp ]
|
132
|
-
workstation_lock_x = crypt_key_segments.alphanumeric_union.concat_length
|
133
|
-
|
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
|
137
|
-
private_key_object = unlock_private_key( private_key_cipher, private_key_lock_x )
|
138
|
-
|
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 )
|
141
|
-
|
142
|
-
puts
|
143
|
-
puts JSON.pretty_generate( JSON.parse( plain_message_text ) )
|
144
|
-
puts
|
145
|
-
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
|
-
# Perform pre-conditional validations in preparation to executing the main flow
|
150
|
-
# of events for this use case. This method may throw the below exceptions.
|
151
|
-
#
|
152
|
-
# @raise [SafeDirNotConfigured] if the safe's url has not been configured
|
153
|
-
# @raise [EmailAddrNotConfigured] if the email address has not been configured
|
154
|
-
# @raise [StoreUrlNotConfigured] if the crypt store url is not configured
|
155
|
-
def pre_validation
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
|
-
end
|
data/lib/interprete/init.rb
DELETED
@@ -1,205 +0,0 @@
|
|
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
|
data/lib/interprete/key.rb
DELETED
@@ -1,119 +0,0 @@
|
|
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
|
-
|