opensecret 0.0.962 → 0.0.988

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -10
  3. data/bin/opensecret +3 -4
  4. data/bin/ops +5 -0
  5. data/lib/extension/string.rb +114 -0
  6. data/lib/factbase/facts.opensecret.io.ini +9 -21
  7. data/lib/interprete/begin.rb +232 -0
  8. data/lib/interprete/cmd.rb +621 -0
  9. data/lib/{plugins/usecases/unlock.rb → interprete/export.rb} +25 -70
  10. data/lib/interprete/init.rb +205 -0
  11. data/lib/interprete/key.rb +119 -0
  12. data/lib/interprete/open.rb +148 -0
  13. data/lib/{plugins/usecases → interprete}/put.rb +19 -6
  14. data/lib/{plugins/usecases → interprete}/safe.rb +2 -1
  15. data/lib/{plugins/usecases/lock.rb → interprete/seal.rb} +24 -34
  16. data/lib/interprete/set.rb +46 -0
  17. data/lib/interprete/use.rb +43 -0
  18. data/lib/interpreter.rb +165 -0
  19. data/lib/keytools/binary.map.rb +245 -0
  20. data/lib/keytools/digester.rb +245 -0
  21. data/lib/keytools/doc.conversion.to.ones.and.zeroes.ruby +179 -0
  22. data/lib/keytools/doc.rsa.radix.binary-mapping.ruby +190 -0
  23. data/lib/keytools/doc.star.schema.strategy.txt +77 -0
  24. data/lib/keytools/doc.using.pbkdf2.kdf.ruby +95 -0
  25. data/lib/keytools/doc.using.pbkdf2.pkcs.ruby +266 -0
  26. data/lib/keytools/kdf.bcrypt.rb +180 -0
  27. data/lib/keytools/kdf.pbkdf2.rb +164 -0
  28. data/lib/keytools/key.data.rb +227 -0
  29. data/lib/keytools/key.derivation.rb +341 -0
  30. data/lib/keytools/key.module.rb +140 -0
  31. data/lib/keytools/key.rb +481 -0
  32. data/lib/logging/gem.logging.rb +1 -2
  33. data/lib/modules/cryptology.md +43 -0
  34. data/lib/{plugins/ciphers → modules/cryptology}/aes-256.rb +6 -0
  35. data/lib/{crypto → modules/cryptology}/amalgam.rb +6 -0
  36. data/lib/modules/cryptology/blowfish.rb +130 -0
  37. data/lib/modules/cryptology/cipher.rb +207 -0
  38. data/lib/modules/cryptology/collect.rb +118 -0
  39. data/lib/{plugins → modules/cryptology}/crypt.io.rb +5 -0
  40. data/lib/{crypto → modules/cryptology}/engineer.rb +7 -1
  41. data/lib/{crypto → modules/cryptology}/open.bcrypt.rb +0 -0
  42. data/lib/modules/mappers/collateral.rb +282 -0
  43. data/lib/modules/mappers/dictionary.rb +288 -0
  44. data/lib/modules/mappers/envelope.rb +127 -0
  45. data/lib/modules/mappers/settings.rb +170 -0
  46. data/lib/modules/storage/coldstore.rb +186 -0
  47. data/lib/{opensecret/plugins.io/git/git.flow.rb → modules/storage/git.store.rb} +11 -0
  48. data/lib/notepad/scratch.pad.rb +17 -0
  49. data/lib/session/fact.finder.rb +13 -0
  50. data/lib/session/require.gem.rb +5 -0
  51. data/lib/store-commands.txt +180 -0
  52. data/lib/version.rb +1 -1
  53. data/opensecret.gemspec +5 -6
  54. metadata +74 -29
  55. data/lib/crypto/blowfish.rb +0 -85
  56. data/lib/crypto/collect.rb +0 -140
  57. data/lib/crypto/verify.rb +0 -33
  58. data/lib/opensecret.rb +0 -236
  59. data/lib/plugins/cipher.rb +0 -203
  60. data/lib/plugins/ciphers/blowfish.rb +0 -126
  61. data/lib/plugins/coldstore.rb +0 -181
  62. data/lib/plugins/envelope.rb +0 -116
  63. data/lib/plugins/secrets.uc.rb +0 -94
  64. data/lib/plugins/usecase.rb +0 -239
  65. data/lib/plugins/usecases/init.rb +0 -145
  66. data/lib/plugins/usecases/open.rb +0 -108
  67. data/lib/session/attributes.rb +0 -279
  68. data/lib/session/dictionary.rb +0 -191
  69. data/lib/session/file.path.rb +0 -53
  70. data/lib/session/session.rb +0 -80
@@ -4,31 +4,31 @@ module OpenSecret
4
4
 
5
5
  require 'openssl'
6
6
 
7
- # The <tt>unlock use case</tt> moves doubly encrypted material <b>from the frozen</b>
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>Unlock | Pre-Conditions</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>unlock</b> expects
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>Unlock | Alternate Flows</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>Unlock | Observable Value</b>
29
+ # <b>Export | Observable Value</b>
30
30
  #
31
- # The observable value proffered by unlock is
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 unlock geo/countries --with=asdfasdf
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 unlock my/gadgets --with="hUM4n-0pen$3cr3t"
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 Unlock < SecretsUseCase
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
- main_store = ColdStore.new @c[:global][:store_mainpath]
114
- keys_store = ColdStore.new @c[:global][:store_keyspath]
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 = OpenSession::Attributes.instance.get_value @c[:global][:name], @c[:global][:name], @c[:global][:machine_key_x]
128
- original_timestamp = OpenSession::Attributes.instance.get_value @c[:global][:name], @c[:global][:name], @c[:global][:stamp_key]
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], @email_addr, @c[:global][:separator_a], original_timestamp ]
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.new.decryptor workstation_cipher, workstation_lock_x
134
- private_key_lock_x = Amalgam.passwords @master_p4ss, workstation_string, @c[:global][:ratio]
135
- private_key_cipher = File.read @c[:global][:master_prv_key]
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
- # key4_pem = File.read 'private.secure.pem'
174
- # pass_phrase = 'superduperpasswordistoBeENTEREDRIGHT1234HereandRightNOW'
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
+