opensecret 0.0.957 → 0.0.959

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9681f58d24288c4f1b13d0b83187dff72f9909f5
4
- data.tar.gz: 850a7fc15a960497f1f6b209d7f30a9c1b26b2fd
3
+ metadata.gz: ced0dc3656c2318960d7c747cd24e8eacb189224
4
+ data.tar.gz: dcca8f54f93da21ef00d6fbbdba0e8975ac7ddca
5
5
  SHA512:
6
- metadata.gz: a3e87ecc9eaf58507d26d92ab6665a3cc4f5f0ea86a1b577b685394af57e6c8db0b2271d399eb9100beb3acf301e863ee43c17a3a7f58751626f6a5264ffbb38
7
- data.tar.gz: 626b3bbdc2becea5b6d1dfa4eefac208a8dca4d33504598e0e7d6bef6a05629188a2cae69edb981a21db8b6fca1bc2e7af9ed1d3a421b26bfe071f061c3c9dbc
6
+ metadata.gz: 219cd0fe00537778fb1364d6a214856bea94be3196e399177bbcbd912ffab087dda9bb01fb906ad1fd7f078f15f27b9d1c24d82894fb1790f592e838487aa10e
7
+ data.tar.gz: 2ba3881642795bf29de00431cbd7926b664b3d0a0031f18eb17b2dc5d79d282f8df7ccb32559720e614be52229e2ec8eb59b924282b88596960ab10fa52bc8cf
@@ -16,10 +16,8 @@ master.dirname = master.keys
16
16
  master.dirpath = rb>> File.join @s[:safe_user], @s[:master_dirname]
17
17
 
18
18
  master.sig.file = master.signature.os.txt
19
- ########### -----> master.pub.name = master.public.key.os.txt
20
19
  master.prv.name = master.private.key.xx.txt
21
20
  master.sig.path = rb>> File.join @s[:master_dirpath], @s[:master_sig_file]
22
- ########### -----> master.pub.key = rb>> File.join @s[:master_dirpath], @s[:master_pub_name]
23
21
  master.prv.key = rb>> File.join @s[:master_dirpath], @s[:master_prv_name]
24
22
 
25
23
  stamp.key = stamp
data/lib/notepad/blow.rb CHANGED
@@ -9,6 +9,18 @@
9
9
 
10
10
  class Trial
11
11
 
12
+ def self.ciphername
13
+
14
+ require 'openssl'
15
+ require "base64"
16
+
17
+ crypt_cipher = OpenSSL::Cipher::AES256.new(:CBC)
18
+ puts "Cipher Name => #{crypt_cipher.class.name}"
19
+
20
+ end
21
+
22
+ Trial.ciphername
23
+
12
24
 
13
25
  def self.certify
14
26
 
@@ -82,7 +94,7 @@ payload = "55fff4c5895bb247676c6edd2307f17c665305457b3bcfcd985c398246b8780f54e33
82
94
  puts ""
83
95
  puts encrypted_string = key.public_encrypt( payload, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
84
96
  puts ""
85
- puts base64text = Base64.encode64(encrypted_string)
97
+ puts base64text = Base64.urlsafe_encode64(encrypted_string)
86
98
  puts ""
87
99
  puts signature = key.sign(OpenSSL::Digest::SHA256.new, payload )
88
100
  puts ""
@@ -112,8 +124,8 @@ payload = "55fff4c5895bb247676c6edd2307f17c665305457b3bcfcd985c398246b8780f54e33
112
124
  context_string_dirty = secured_privatekey + public_key_text + email_address + time_stamp
113
125
  context_string_clean = context_string_dirty.delete("^A-Za-z0-9")
114
126
  context_string_clean += context_string_clean.length.to_s
115
- #### context_signature_str = Base64.encode64(second_key.sign OpenSSL::Digest::SHA256.new, context_string_clean)
116
- context_signature_str = Base64.encode64(key.sign OpenSSL::Digest::SHA256.new, context_string_clean)
127
+ #### context_signature_str = Base64.urlsafe_encode64(second_key.sign OpenSSL::Digest::SHA256.new, context_string_clean)
128
+ context_signature_str = Base64.urlsafe_encode64(key.sign OpenSSL::Digest::SHA256.new, context_string_clean)
117
129
 
118
130
 
119
131
  ## --------------------------------------------------------------------------------------------
@@ -121,7 +133,7 @@ payload = "55fff4c5895bb247676c6edd2307f17c665305457b3bcfcd985c398246b8780f54e33
121
133
 
122
134
  reinstated_key = OpenSSL::PKey::RSA.new "#{public_key_text}"
123
135
  ### reinstated_key = OpenSSL::PKey::RSA.new "#{second_public_key_text}"
124
- raw_signature_text = Base64.decode64(context_signature_str)
136
+ raw_signature_text = Base64.urlsafe_decode64(context_signature_str)
125
137
  is_valid = reinstated_key.public_key.verify OpenSSL::Digest::SHA256.new, raw_signature_text, (context_string_clean)
126
138
  raise ArgumentError, "Keys not validated" unless is_valid
127
139
 
data/lib/opensecret.rb CHANGED
@@ -56,6 +56,15 @@ class CliInterpreter < Thor
56
56
  end
57
57
 
58
58
 
59
+ # Description of the lock use case command line call.
60
+ desc "lock", "Lock away the (secret stuffed) envelope into key and crypt stores."
61
+
62
+ # Lock away the (secret stuffed) envelope into key and crypt stores.
63
+ def lock
64
+ OpenSecret::Lock.new.flow_of_events
65
+ end
66
+
67
+
59
68
  # Description of the open "wake-up" call.
60
69
  desc "open CONTEXT_PATH", "CONTEXT_PATH context path to the family of secrets to be created."
61
70
 
@@ -28,7 +28,6 @@ module OpenSecret
28
28
  # with a powerful symmetric encryption algorithm which could be any one of the
29
29
  # leading ciphers such as TwoFish or the Advanced Encryption Standard (AES).
30
30
  #
31
- #
32
31
  # == How to Implement a Cipher
33
32
  #
34
33
  # Extend this base class to inherit lots of +unexciting+ functionality
@@ -100,10 +99,23 @@ module OpenSecret
100
99
  # Text header for key-value pairs hash map that will be serialized.
101
100
  DICTIONARY = "dictionary"
102
101
 
102
+ # Name for the class of cipher employed.
103
+ DICT_CIPHER_NAME = "cipher.class"
104
+
105
+ # Name for the {Base64} encoded symmetric (lock/unlock) crypt key.
106
+ DICT_CRYPT_KEY = "encryption.key"
107
+
108
+ # Name for the {Base64} encoded plain text digest.
109
+ DICT_PLAINTEXT_DIGEST = "plaintext.digest"
110
+
111
+ # Name for the {Base64} encoded crypt material digest.
112
+ DICT_MATERIAL_DIGEST = "cipher.digest"
103
113
 
104
- @@symmetric_cipher_keyname = "symmetric.cipher"
105
- @@encryption_key_keyname = "encryption.key"
106
- @@payload_signature_keyname = "payload.signature"
114
+ # Name for the plain text initialization vector (iv).
115
+ DICT_INIT_VECTOR = "crypt.init.vector"
116
+
117
+ # Name for the {Base64} encoded crypted cipher text.
118
+ DICT_CIPHER_TEXT = "cipher.text"
107
119
 
108
120
 
109
121
  # The cipher constructor instantiates the encryption dictionary which
@@ -131,40 +143,30 @@ module OpenSecret
131
143
  # and rejecting malicious content.
132
144
  #
133
145
  # @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.
146
+ # public key. There is no need for an asymmetric encryption agent to know
147
+ # the asymmetic private key.
136
148
  #
137
149
  # @param payload_text [String] plaintext (or base64 encoded) text to encrypt
138
- # @param payload_signature [String] signature of payload verifiable with public key
139
150
  #
140
151
  # @return [String] doubly (symmetric and asymmetric) encrypted cipher text
141
- def encrypt_it public_key_text, payload_text, payload_signature
142
-
143
- asymmetric_key = OpenSSL::PKey::RSA.new public_key_text
152
+ def encrypt_it public_key_text, payload_text
144
153
 
145
- signature_valid = asymmetric_key.verify(
146
- OpenSSL::Digest::SHA256.new,
147
- payload_signature,
148
- payload_text
149
- )
150
-
151
- raise ArgumentError, "Payload not verified by the signature." unless signature_valid
152
- @dictionary[@@payload_signature_keyname] = payload_signature.to_hex
153
154
  crypted_payload = do_symmetric_encryption payload_text
154
155
 
156
+ ######### puts JSON.pretty_generate(@dictionary)
157
+
155
158
  unified_material = unify_hash_and_text crypted_payload
156
- blowfish_cryptor = Blowfish.new
157
159
  outer_crypt_key = OpenSecret::Engineer.strong_key( 128 )
158
- crypted_material = blowfish_cryptor.encryptor unified_material, outer_crypt_key
159
160
  crypted_cryptkey = do_asymmetric_encryption public_key_text, outer_crypt_key
160
- locked_up_string = unify_text_and_text crypted_cryptkey, crypted_material
161
+ crypted_material = Base64.encode64(Blowfish.new.encryptor unified_material, outer_crypt_key)
162
+ locked_ciphertxt = unify_text_and_text crypted_cryptkey, crypted_material
161
163
 
162
- return locked_up_string
164
+ return locked_ciphertxt
163
165
 
164
166
  end
165
167
 
166
168
 
167
- # Thismethod takes the textual public key lacking the private key portion
169
+ # This method takes the textual public key lacking the private key portion
168
170
  # as it is not needed, and encrypts the secret text with it.
169
171
  # It returns a Base64 encoded version of they encrypted text.
170
172
  #
@@ -7,7 +7,7 @@ module OpenSecret
7
7
  # {OpenSecret::Cipher} base class in order to implement plug and play
8
8
  # symmetric encryption.
9
9
  #
10
- # == Aes256 Symmetric Encrypt/Decrypt Dictionary
10
+ # == Aes256 Symmetric Encrypt/Decrypt
11
11
  #
12
12
  # To facilitate decryption - this cipher produces a key/value pair
13
13
  # dictionary which will be stored along with the ciphertext itself.
@@ -51,16 +51,20 @@ module OpenSecret
51
51
  # @return [String] the symmetrically encrypted cipher text
52
52
  def do_symmetric_encryption plain_text
53
53
 
54
- @cipher_name = "aes-256-cbc"
55
-
56
- crypt_cipher = OpenSSL::Cipher.new @cipher_name
54
+ crypt_cipher = OpenSSL::Cipher::AES256.new(:CBC)
57
55
  crypt_cipher.encrypt
58
56
 
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
57
+ @dictionary[DICT_CIPHER_NAME] = crypt_cipher.class.name
58
+ @dictionary[DICT_CRYPT_KEY] = Base64.urlsafe_encode64 crypt_cipher.random_key
59
+ @dictionary[DICT_INIT_VECTOR] = Base64.urlsafe_encode64 crypt_cipher.random_iv
60
+ @dictionary[DICT_PLAINTEXT_DIGEST] = Base64.urlsafe_encode64(Digest::SHA256.digest(plain_text))
61
+
62
+ cipher_text = crypt_cipher.update( plain_text ) + crypt_cipher.final
63
+
64
+ @dictionary[DICT_CIPHER_TEXT] = Base64.urlsafe_encode64( cipher_text )
65
+ @dictionary[DICT_MATERIAL_DIGEST] = Base64.urlsafe_encode64(Digest::SHA256.digest(cipher_text))
62
66
 
63
- return Base64.encode64( crypt_cipher.update( plain_text ) + crypt_cipher.final )
67
+ return cipher_text
64
68
 
65
69
  end
66
70
 
@@ -69,7 +73,7 @@ module OpenSecret
69
73
  # and initialization vector (iv) sitting in the encryption_dictionary,
70
74
  # to symmetrically decrypt the parameter cipher text.
71
75
  #
72
- # == Pre-Condition | Encryption Dictionary
76
+ # == Pre-Condition | Encryption ...
73
77
  #
74
78
  # This method requires the <tt>@dictionary</tt> instance
75
79
  # variable to have been set and to contain (amongst others)
@@ -112,7 +116,7 @@ crypt_text += encode_cipher.update line5
112
116
  crypt_text += encode_cipher.update line6
113
117
  crypt_text += encode_cipher.update line7
114
118
  crypt_text += encode_cipher.final
115
- coded_crypt_text = Base64.encode64(crypt_text)
119
+ coded_crypt_text = Base64.urlsafe_encode64(crypt_text)
116
120
 
117
121
  puts ""
118
122
  puts "The key is #{hex_key}"
@@ -133,13 +137,13 @@ puts "========================"
133
137
  puts ""
134
138
  puts ""
135
139
 
136
- unencoded_crypt_text = Base64.decode64(coded_crypt_text)
140
+ unencoded_crypt_text = Base64.urlsafe_decode64(coded_crypt_text)
137
141
  decode_cipher = OpenSSL::Cipher.new('aes-256-cbc')
138
142
 
139
143
  decode_cipher.decrypt
140
144
  decode_cipher.key = [hex_key].pack("H*")
141
145
  decode_cipher.iv = [hex_iv].pack("H*")
142
- first_part = decode_cipher.update( Base64.decode64(coded_crypt_text) )
146
+ first_part = decode_cipher.update( Base64.urlsafe_decode64(coded_crypt_text) )
143
147
  second_part = ""
144
148
  second_part << decode_cipher.final
145
149
 
@@ -34,7 +34,7 @@ module OpenSecret
34
34
  # takes care of it and its sister method {self.decryptor} will also perform
35
35
  # the correct reversal activities to give you back the original plain text.
36
36
  #
37
- # {Base64.encode64} facilitates the ciphertext encoding returning text that
37
+ # {Base64.urlsafe_encode64} facilitates the ciphertext encoding returning text that
38
38
  # is safe to write to a file.
39
39
  #
40
40
  # @param plain_text [String]
@@ -66,16 +66,14 @@ module OpenSecret
66
66
 
67
67
  blowfish_encryptor = OpenSSL::Cipher.new(OpenSecret::Blowfish::BLOWFISH_CIPHER_ID).encrypt
68
68
  blowfish_encryptor.key = raw_stretched_key
69
- encrypted_lines = blowfish_encryptor.update(block_txt) << blowfish_encryptor.final
70
-
71
- return Base64.encode64( encrypted_lines ).chomp
69
+ return blowfish_encryptor.update(block_txt) << blowfish_encryptor.final
72
70
 
73
71
  end
74
72
 
75
73
 
76
74
  # Decrypt the cipher text parameter using the symmetric decryption key
77
- # specified in the second parameter. The cipher text is expected to be
78
- # base64 encoded as per our sister method {self.encryptor}.
75
+ # specified in the second parameter. The cipher text is expected to have
76
+ # already been decoded if necessary.
79
77
  #
80
78
  # Its okay to use a bespoke encryptor - just ensure you encode the result
81
79
  # and override the padding constant.
@@ -87,8 +85,8 @@ module OpenSecret
87
85
  # takes care of the reversing the activities carried out by {self.encryptor}.
88
86
  #
89
87
  # @param cipher_text [String]
90
- # This incoming cipher text should be encoded using {Base64.encode64}
91
- # and it will be +chomped and stripped upon receipt+ followed by
88
+ # This incoming cipher text should already be encoded but it
89
+ # will <b>chomped and stripped upon receipt</b> followed by
92
90
  # decryption using the Blowfish algorithm.
93
91
  #
94
92
  # @param decryption_key [String]
@@ -109,13 +107,12 @@ module OpenSecret
109
107
  #
110
108
  def decryptor cipher_text, decryption_key
111
109
 
112
- decoded_text = Base64.decode64(cipher_text.chomp.strip)
113
110
  digested_key = Digest::SHA256.digest decryption_key
114
111
 
115
112
  decrypt_tool = OpenSSL::Cipher.new(OpenSecret::Blowfish::BLOWFISH_CIPHER_ID).decrypt
116
113
  decrypt_tool.key = digested_key
117
114
 
118
- padded_plaintxt = decrypt_tool.update(decoded_text) << decrypt_tool.final
115
+ padded_plaintxt = decrypt_tool.update(cipher_text) << decrypt_tool.final
119
116
  pad_begin_index = padded_plaintxt.index OpenSecret::Cipher::TEXT_PADDER
120
117
  return padded_plaintxt if pad_begin_index.nil?
121
118
  return padded_plaintxt[ 0 .. (pad_begin_index-1) ]
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ module OpenSecret
5
+
6
+ require 'json'
7
+
8
+ # An envelope knows how to manipulate a JSON backed data structure
9
+ # (put, add etc) <b>after reading and then decrypting it</b> from a
10
+ # file and <b>before encrypting and then writing it</b> to a file.
11
+ #
12
+ # It provides behaviour to which we can create, append (add), update
13
+ # (change), read parts and delete essentially two structures
14
+ #
15
+ # - a collection of name/value pairs
16
+ # - an ordered list of values
17
+ #
18
+ # == JSON is Not Exposed in the Interface
19
+ #
20
+ # An envelope doesn't expose the data format used in the implementation
21
+ # allowing this to be changed seamlessly to YAMl or other formats.
22
+ #
23
+ # == Symmetric Encryption and Decryption
24
+ #
25
+ # An envelope supports operations to <b>read from</b> and <b>write to</b>
26
+ # a known filepath and with a symmetric key it can
27
+ #
28
+ # - decrypt <b>after reading from</b> a file and
29
+ # - encrypt <b>before writing to</b> a (the same) file
30
+ #
31
+ # == Hashes as the Primary Data Structure
32
+ #
33
+ # Envelope extends {Hash} as the core data structure for holding
34
+ #
35
+ # - strings
36
+ # - arrays
37
+ # - other hashes
38
+ # - booleans
39
+ # - integers and floats
40
+ class Envelope < Hash
41
+
42
+
43
+ # Write the data in this envelope hash map into a file-system
44
+ # backed mirror whose path was specified in the {self.read} method.
45
+ #
46
+ # Technology for encryption at rest is supported by this dictionary
47
+ # and to this aim, please endeavour to post a robust symmetric
48
+ # encryption key.
49
+ #
50
+ # Calling this {self.write} method when the file at the prescribed path
51
+ # does not exist results in the directory structure being created
52
+ # (if necessary) and then the encrypted file being written.
53
+ #
54
+ # @param encryption_key [String]
55
+ # encryption at rest is a given so this mandatory parameter must
56
+ # contain a robust symmetric encryption key. The symmetric key will
57
+ # be used for the decryption after the read. Note that the decryption
58
+ # key does not linger meaning it isn't cached in an instance variable.
59
+ def write encryption_key
60
+
61
+ FileUtils.mkdir_p(File.dirname(@filepath))
62
+ cipher_text = Base64.encode64 Blowfish.new.encryptor( self.to_json, encryption_key )
63
+ File.write @filepath, cipher_text
64
+
65
+ end
66
+
67
+
68
+ # Read and inject into this envelope, the data structure found in a
69
+ # file at the path specified in the first parameter.
70
+ #
71
+ # Symmetric cryptography is mandatory for the envelope so we must
72
+ # <b>encrypt before writing</b> and <b>decrypt after reading</b>.
73
+ #
74
+ # An argument error will result if a suitable key is not provided.
75
+ #
76
+ # If the file does not exist (denoting the first read) all this method
77
+ # does is to stash the filepath as an instance variable and igore the
78
+ # decryption key which can be nil (or ommitted).
79
+ #
80
+ # @param the_filepath [String]
81
+ # absolute path to the file which acts as the persistent mirror to
82
+ # this data structure envelope.
83
+ #
84
+ # @param decryption_key [String]
85
+ # encryption at rest is a given so this mandatory parameter must
86
+ # contain a robust symmetric decryption key. The key will be used
87
+ # for decryption after the read and it will not linger (ie not cached
88
+ # as an instance variable).
89
+ #
90
+ # @raise [ArgumentError] if the decryption key is not robust enough.
91
+ def read the_filepath, decryption_key = nil
92
+
93
+ @filepath = the_filepath
94
+ return unless File.exists? @filepath
95
+
96
+ cipher_text = Base64.decode64( File.read( @filepath ).strip )
97
+ plain_text = OpenSecret::Blowfish.new.decryptor( cipher_text, decryption_key )
98
+
99
+ puts ""
100
+ puts "=== ============================"
101
+ puts "=== Envelope After Decryption"
102
+ puts "=== ============================"
103
+ puts plain_text
104
+ puts "=== ============================"
105
+ puts ""
106
+
107
+ data_structure = JSON.parse plain_text
108
+ self.merge! data_structure
109
+
110
+ end
111
+
112
+
113
+ end
114
+
115
+
116
+ end
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ module OpenSecret
5
+
6
+ # The parent OpenSecret use case is designed to be extended by the cli
7
+ # (command line) use cases like {OpenSecret::Open}, {OpenSecret::Put} and
8
+ # {OpenSecret::Lock} because it describes behaviour common to at least two
9
+ # (but usually more) of the use cases.
10
+ #
11
+ # == Behaviour Reuse
12
+ #
13
+ # Behaviour that is reusable by any use case fits within {OpenSession::UseCase}
14
+ # whilst behaviour common to two or more {OpenSecret} use cases belongs here.
15
+ # Therefore the only behaviour in the named use case is detailed and must belong
16
+ # solely to it.
17
+ #
18
+ # == Fact Reuse
19
+ #
20
+ # Fact evaluation rules are born with reuse in mind. <b>Use case facts</b>
21
+ # are evaluated when they belong to either the class or its parent or any
22
+ # ancestors.
23
+ class SecretsUseCase < OpenSession::UseCase
24
+
25
+ @@context_name = "opensecret"
26
+
27
+ # Get the envelope that <b>was opened</b> by the open command but
28
+ # <b>not locked</b> with the lock command.
29
+ #
30
+ # @return [Envelope]
31
+ # return the Envelope that has been opened. The state carried alongside an
32
+ # open envelope is an id, an encryption key and a filepath all inside the
33
+ # userhome configuration file.
34
+ def get_envelope
35
+
36
+ encrypt_key = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_keyname]
37
+ rel_filepath = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_pathname]
38
+
39
+ put_filepath = File.join @c[:open][:open_dirpath], rel_filepath
40
+ the_envelope = Envelope.new
41
+ the_envelope.read put_filepath, encrypt_key
42
+ return the_envelope
43
+
44
+ end
45
+
46
+
47
+ end
48
+
49
+
50
+ end
@@ -32,7 +32,7 @@ module OpenSecret
32
32
  #
33
33
  # <b>opensecret</b> thwarts this by continual verification against an
34
34
  # encrypted <em>public key signature</em> aboard the workstation.
35
- class Init < OpenSession::UseCase
35
+ class Init < SecretsUseCase
36
36
 
37
37
  attr_writer :safe_path, :email_addr, :store_url
38
38
  @@context_name = "opensecret"
@@ -83,18 +83,20 @@ module OpenSecret
83
83
  secured_keytext = asymmetric_keys.export @c[:global][:key_cipher], amalgam_key
84
84
 
85
85
  crypt_key_segments = [ human_password, @c[:global][:separator_a], @email_addr, @c[:global][:separator_a], @c[:global][:stamp_23] ]
86
+
86
87
  machine_key_crypt_key = crypt_key_segments.alphanumeric_union.concat_length
87
- blowfish_cipher = OpenSecret::Blowfish.new()
88
- machine_key_x = blowfish_cipher.encryptor machine_key, machine_key_crypt_key
89
- public_key_text = asymmetric_keys.public_key.to_pem
88
+ machine_key_x = Base64.urlsafe_encode64(
89
+ Blowfish.new.encryptor(machine_key, machine_key_crypt_key)
90
+ )
91
+ public_key_64 = Base64.urlsafe_encode64 asymmetric_keys.public_key.to_pem
90
92
 
91
93
  OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:machine_key_x], machine_key_x
92
94
  OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:stamp_key], @c[:global][:stamp_23]
93
- OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:publickey_id], public_key_text.to_hex
95
+ OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:publickey_id], public_key_64
94
96
 
95
- to_sign_segments = [ secured_keytext, public_key_text, @email_addr, @c[:global][:stamp_23] ]
97
+ to_sign_segments = [ secured_keytext, public_key_64, @email_addr, @c[:global][:stamp_23] ]
96
98
  to_sign_packet = to_sign_segments.alphanumeric_union.concat_length
97
- signature_string = Base64.encode64( asymmetric_keys.sign( OpenSSL::Digest::SHA256.new, to_sign_packet ) )
99
+ signature_string = Base64.urlsafe_encode64( asymmetric_keys.sign( OpenSSL::Digest::SHA256.new, to_sign_packet ) )
98
100
 
99
101
  FileUtils.mkdir_p @c[:global][:master_dirpath]
100
102
  File.write @c[:global][:master_prv_key], secured_keytext
@@ -10,97 +10,110 @@ module OpenSecret
10
10
  #
11
11
  # The 3 core scenarios that this lock use case is equiped to handle are
12
12
  #
13
- # - a new source &raquo; as yet uncommitted
14
- # - an updated source &raquo; to overwrite
15
- # - an empty source &raquo; to delete
13
+ # - a new source that is as yet uncommitted
14
+ # - updating (overwriting) an existing source
15
+ # - requiring the destination to be deleted
16
16
  #
17
- # == Observable Value
17
+ # <b>Lock | Observable Value</b>
18
18
  #
19
- # $ opensecret lock
19
+ # The observable value after the lock use case has completed entails
20
+ #
21
+ # - a doubly encrypted data envelope placed in the backend store
22
+ # - a doubly encrypted private key placed in the frontend store
23
+ # - both stores sync'd with off-machine Git (S3, ...) mirrors
24
+ # - deletion of the (encrypted) envelope {Open}ed and stuffed with {Put}
25
+ # - deletion of {Open}ed session data to locate and decrypt envelope
20
26
  #
21
- # The observable value for a new or updated secrets package is
27
+ # @example
22
28
  #
23
- # - a doubly encrypted keyset within the safe keystore
24
- # - a doubly encrypted secrets crypt in the backend crypt store
25
- # - a crypt store sync'd with its off-machine Git (or S3, or ...) mirror
26
- # - a public key that is verifid against its encrypted signature
27
- # - deleted session material created (and encrypted) by the put use case
28
- class Lock < OpenSession::UseCase
29
+ # $ opensecret lock
30
+ #
31
+ class Lock < SecretsUseCase
29
32
 
30
33
  attr_writer :secret_id, :secret_value
31
34
  @@context_name = "opensecret"
32
35
 
33
36
 
34
- # Execute the <tt>open use case</tt> activities which precedes the ability to
35
- # to add (put), subtract (del)ete and list the secrets into the opened session file.
36
- # The file can then be locked (committed and pushed to permanent crypted stores).
37
+ # The <tt>lock use case</tt> is called after {OpenSecret::Open} and {OpenSecret::Put}
38
+ # and its effect is to dispatch the doubly encrypted materrial to the configured storage
39
+ # platform, be it Git, S3, SSH or just an accessible file-system.
40
+ #
41
+ # <b>Main Flow of Events</b>
37
42
  #
38
- # If the file to open already exists a --with option (giving the master-secret)
39
- # must be provided.
43
+ # To seal the envelope built up by put, file and add amongst others requires
44
+ # that we
40
45
  #
41
- # <b>Observable Value | Lock Use Case</b>
46
+ # - get the encrypted envelope
47
+ # - create a strong asymmetric key
48
+ # - lock the envelope using opensecret's double encrypt modus operandi
49
+ # - place the doubly encrypted result into the crypt store
50
+ # - lock the asymmetric key again with opensecret's double encrypt modus operandi
51
+ # - place the doubly encrypted result into the key store
42
52
  #
43
- # The observable value for a new or updated secrets package is
53
+ # The second double lock of the crypted envelope is done with the public key
54
+ # aspect of an asymmetric key created here.
44
55
  #
45
- # - a doubly encrypted keyset within the safe keystore
46
- # - a doubly encrypted secrets crypt in the backend crypt store
47
- # - a crypt store sync'd with its off-machine Git (or S3, or ...) mirror
48
- # - a public key that is verifid against its encrypted signature
49
- # - deleted session material created (and encrypted) by the put use case
56
+ # The second double lock of the crypted private key (created here) is done with
57
+ # the master public key created in the {Init.execute} use case main flow.
58
+ #
59
+ # <b>Lock | Observable Value</b>
60
+ #
61
+ # The observable value after the lock use case has completed entails
62
+ #
63
+ # - a doubly encrypted data envelope placed in the backend store
64
+ # - a doubly encrypted private key placed in the frontend store
65
+ # - both stores sync'd with off-machine Git (S3, ...) mirrors
66
+ # - deletion of the (encrypted) envelope {Open}ed and stuffed with {Put}
67
+ # - deletion of {Open}ed session data to locate and decrypt envelope
50
68
  def execute
51
69
 
52
- session_id = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_idname]
53
- encrypt_key = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_keyname]
54
- rel_filepath = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_pathname]
55
-
56
- put_filepath = File.join @c[:open][:open_dirpath], rel_filepath
57
-
58
- x_dictionary = OpenSession::Dictionary.new
59
- x_dictionary.read put_filepath, true, encrypt_key
70
+ envelope = get_envelope
71
+ asym_key = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
72
+ lockdown = Aes256.new.encrypt_it( asym_key.public_key.to_pem, envelope.to_json )
60
73
 
61
- secret_ids = @secret_id.split("/")
62
- if ( x_dictionary.has_key? secret_ids.first )
63
- x_dictionary[secret_ids.first][secret_ids.last] = @secret_value
64
- else
65
- x_dictionary[secret_ids.first] = { secret_ids.last => @secret_value }
66
- end
74
+ #### ###########################################
75
+ #### ###########################################
76
+ #### Now Give lockdown to the Backend Store
77
+ #### ###########################################
78
+ #### ###########################################
67
79
 
68
- new_encryption_key = Engineer.strong_key @c[:open][:open_keylen]
69
- OpenSession::Attributes.stash @@context_name, @c[:open][:open_name], @c[:open][:open_keyname], new_encryption_key
70
- x_dictionary.write new_encryption_key
80
+ master_public_key = Base64.urlsafe_decode64( OpenSession::Attributes.instance.get_value @c[:global][:name], @c[:global][:name], "public.key" )
71
81
 
82
+ lockedup = Aes256.new.encrypt_it( master_public_key, asym_key.export )
72
83
 
73
- #############################################################################################
74
- #############################################################################################
84
+ puts "#### #############################"
85
+ puts "#### The Crypt Store Suitcase"
86
+ puts "#### #############################"
87
+ puts ""
88
+ puts lockdown
89
+ puts ""
90
+ puts "#### #############################"
91
+ puts "#### The Key Store Suitcase"
92
+ puts "#### #############################"
93
+ puts ""
94
+ puts lockedup
95
+ puts ""
96
+ puts "================================================================================================="
97
+ puts "Now Continue with Unencoding the public key and then locking down the above asym_key.export"
98
+ puts "================================================================================================="
99
+ puts ""
75
100
 
101
+ exit
76
102
 
77
103
 
104
+ locked_block = Aes256.new.encrypt_it( asym_key.public_key.to_pem, asym_key.export )
78
105
 
79
- #############################################################################################
80
- #############################################################################################
106
+ secured_keytext = asym_key.export
107
+ ## public_key_text = asymmetric_keys.public_key.to_pem
81
108
 
82
109
 
83
- public_key_crypt = Blowfish.new.encryptor public_key_text, amalgam_key
84
- File.write @c[:global][:master_pub_key], public_key_crypt
110
+ Aes256.new.encrypt_it( "rubbish", secrets_dictionary.to_s )
85
111
 
86
- payload_signature = asymmetric_keys.sign( OpenSSL::Digest::SHA256.new, public_key_text )
112
+ the_encrypted_stuff = Aes256.new.encrypt_it( "rubbish", )
87
113
 
88
- big_crypted_block = Aes256.new.encrypt_it(
89
- public_key_text,
90
- public_key_text,
91
- payload_signature
92
- )
93
114
 
94
- puts ""
95
- puts "=============="
96
- puts "Crypted Block"
97
- puts "=============="
98
- puts ""
99
- puts "#{big_crypted_block}"
100
- puts ""
101
- puts ""
102
- puts "Carry on development in init.rb"
103
- puts ""
115
+ #############################################################################################
116
+ #############################################################################################
104
117
 
105
118
 
106
119
  =begin
@@ -116,7 +129,7 @@ module OpenSecret
116
129
  # key4_pem = File.read 'private.secure.pem'
117
130
  # pass_phrase = 'superduperpasswordistoBeENTEREDRIGHT1234HereandRightNOW'
118
131
  # key4 = OpenSSL::PKey::RSA.new key4_pem, pass_phrase
119
- # decrypted_text = key4.private_decrypt(Base64.decode64(encrypted_string))
132
+ # decrypted_text = key4.private_decrypt(Base64.urlsafe_decode64(encrypted_string))
120
133
 
121
134
  # print "\nHey we have done the decryption.\n", "\n"
122
135
  # print decrypted_text, "\n"
@@ -126,35 +139,6 @@ module OpenSecret
126
139
  #############################################################################################
127
140
  #############################################################################################
128
141
 
129
-
130
- machine_key = Engineer.machine_key human_password.length, @c[:global][:ratio]
131
- amalgam_key = Amalgam.passwords human_password, machine_key, @c[:global][:ratio]
132
- asymmetric_keys = OpenSSL::PKey::RSA.new @c[:global][:bit_key_size]
133
- secured_keytext = asymmetric_keys.export @c[:global][:key_cipher], amalgam_key
134
-
135
- crypt_key_segments = [ human_password, @c[:global][:separator_a], @email_addr, @c[:global][:separator_a], @c[:global][:stamp_23] ]
136
- machine_key_crypt_key = crypt_key_segments.alphanumeric_union.concat_length
137
- blowfish_cipher = OpenSecret::Blowfish.new()
138
- machine_key_x = blowfish_cipher.encryptor machine_key, machine_key_crypt_key
139
- public_key_text = asymmetric_keys.public_key.to_pem
140
-
141
- OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:machine_key_x], machine_key_x
142
- OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:stamp_key], @c[:global][:stamp_23]
143
- OpenSession::Attributes.stash @c[:global][:name], @c[:global][:name], @c[:global][:publickey_id], public_key_text.to_hex
144
-
145
- to_sign_segments = [ secured_keytext, public_key_text, @email_addr, @c[:global][:stamp_23] ]
146
- to_sign_packet = to_sign_segments.alphanumeric_union.concat_length
147
- signature_string = Base64.encode64( asymmetric_keys.sign( OpenSSL::Digest::SHA256.new, to_sign_packet ) )
148
-
149
- FileUtils.mkdir_p @c[:global][:master_dirpath]
150
- File.write @c[:global][:master_prv_key], secured_keytext
151
- File.write @c[:global][:master_sig_path], signature_string
152
-
153
-
154
- #############################################################################################
155
- #############################################################################################
156
-
157
-
158
142
  end
159
143
 
160
144
 
@@ -25,7 +25,7 @@ module OpenSecret
25
25
  # [session]
26
26
  # base.path = home/wifi
27
27
  #
28
- class Open < OpenSession::UseCase
28
+ class Open < SecretsUseCase
29
29
 
30
30
  attr_writer :context_path
31
31
  @@context_name = "opensecret"
@@ -5,9 +5,9 @@ module OpenSecret
5
5
  require 'openssl'
6
6
 
7
7
  # The <b>put use case</b> follows <b>open</b> and it adds secrets into an
8
- # <em>(encrypted at rest)</em> opened file. Put can be called many times to
9
- # add secrets. Finally the <b>lock use case</b> commits all opened secrets
10
- # into the configured storage engines.
8
+ # <em>(encrypted at rest)</em> <b>envelope</b>. Put can be called many times
9
+ # and when done, the <b>lock use case</b> can be called to commit all opened
10
+ # secrets into the configured storage engines.
11
11
  #
12
12
  # Calling <em>put</em> <b>before</b> calling open or <b>after</b> calling lock
13
13
  # is not allowed and will result in an error.
@@ -50,8 +50,7 @@ module OpenSecret
50
50
  #
51
51
  # @example
52
52
  #
53
- # $ opensecret email bill.clinton@example.com
54
- # $ opensecret init
53
+ # $ opensecret init bill.clinton@example.com
55
54
  # $ opensecret open my/friends
56
55
  #
57
56
  # $ opensecret put monica/surname lewinsky
@@ -64,7 +63,15 @@ module OpenSecret
64
63
  #
65
64
  # $ opensecret lock
66
65
  #
67
- class Put < OpenSession::UseCase
66
+ # Soon follow up use cases will be unveiled, enabling us to
67
+ #
68
+ # - <b>get</b>
69
+ # - <b>read</b>
70
+ # - <b>list</b>
71
+ # - <b>look</b>
72
+ # - <b>peep</b> and
73
+ # - <b>peek</b>
74
+ class Put < SecretsUseCase
68
75
 
69
76
  attr_writer :secret_id, :secret_value
70
77
  @@context_name = "opensecret"
@@ -94,25 +101,18 @@ module OpenSecret
94
101
  # - a new session id and encryption key is generated and used to re-encrypt
95
102
  def execute
96
103
 
97
- session_id = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_idname]
98
- encrypt_key = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_keyname]
99
- rel_filepath = OpenSession::Attributes.instance.get_value @@context_name, @c[:open][:open_name], @c[:open][:open_pathname]
100
-
101
- put_filepath = File.join @c[:open][:open_dirpath], rel_filepath
102
-
103
- x_dictionary = OpenSession::Dictionary.new
104
- x_dictionary.read put_filepath, true, encrypt_key
104
+ envelope = get_envelope
105
105
 
106
106
  secret_ids = @secret_id.split("/")
107
- if ( x_dictionary.has_key? secret_ids.first )
108
- x_dictionary[secret_ids.first][secret_ids.last] = @secret_value
107
+ if ( envelope.has_key? secret_ids.first )
108
+ envelope[secret_ids.first][secret_ids.last] = @secret_value
109
109
  else
110
- x_dictionary[secret_ids.first] = { secret_ids.last => @secret_value }
110
+ envelope[secret_ids.first] = { secret_ids.last => @secret_value }
111
111
  end
112
112
 
113
113
  new_encryption_key = Engineer.strong_key @c[:open][:open_keylen]
114
114
  OpenSession::Attributes.stash @@context_name, @c[:open][:open_name], @c[:open][:open_keyname], new_encryption_key
115
- x_dictionary.write new_encryption_key
115
+ envelope.write new_encryption_key
116
116
 
117
117
  end
118
118
 
@@ -14,7 +14,7 @@ module OpenSecret
14
14
  # Stash the path into the host machine's configuration file and proceed
15
15
  # to create the path directory chain if it does not already exist.
16
16
  #
17
- class Safe < OpenSession::UseCase
17
+ class Safe < SecretsUseCase
18
18
 
19
19
  attr_writer :safe_path
20
20
  @@context_name = "opensecret"
@@ -15,7 +15,7 @@ module OpenSession
15
15
  # - decrypt +after reading from+ a file
16
16
  # - encrypt +before writing to+ a file
17
17
  #
18
- # Dictionary extends {Hash} in order to deliver on its core key value
18
+ # This dictionary extends {Hash} in order to deliver on its core key value
19
19
  # store, report and retrieve use cases.
20
20
  #
21
21
  # @example
@@ -80,13 +80,13 @@ module OpenSession
80
80
 
81
81
  puts ""
82
82
  puts "============================"
83
- puts "Before Encryption Dictionary"
83
+ puts "Before Encryption"
84
84
  puts "============================"
85
85
  puts ini_string
86
86
  puts "============================"
87
87
  puts ""
88
88
 
89
- ini_string = OpenSecret::Blowfish.new.encryptor(ini_string,encrypt_key) if @encrypt_at_rest
89
+ ini_string = Base64.encode64( OpenSecret::Blowfish.new.encryptor(ini_string,encrypt_key) ) if @encrypt_at_rest
90
90
 
91
91
  File.write @filepath, ini_string
92
92
 
@@ -127,12 +127,12 @@ module OpenSession
127
127
 
128
128
  file_contents = File.read( @filepath ).strip
129
129
  if @encrypt_at_rest then
130
- file_contents = OpenSecret::Blowfish.new.decryptor( file_contents, decrypt_key )
130
+ file_contents = OpenSecret::Blowfish.new.decryptor( Base64.decode64(file_contents), decrypt_key )
131
131
  end
132
132
 
133
133
  puts ""
134
134
  puts "==========================="
135
- puts "After Decryption Dictionary"
135
+ puts "After Decryption"
136
136
  puts "==========================="
137
137
  puts file_contents
138
138
  puts "==========================="
data/lib/using.txt CHANGED
@@ -1,4 +1,6 @@
1
1
 
2
+
3
+
2
4
  ==============================================================================================
3
5
 
4
6
  open office/laptop
data/lib/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module OpenSecret
2
- VERSION = "0.0.957"
2
+ VERSION = "0.0.959"
3
3
  end
data/opensecret.gemspec CHANGED
@@ -28,8 +28,8 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency 'thor'
29
29
 
30
30
  spec.add_development_dependency "bundler", "~> 1.16"
31
- spec.add_development_dependency "rake", "~> 10.0"
32
- spec.add_development_dependency "minitest", "~> 5.0"
31
+ #### in standard library ==> spec.add_development_dependency "rake", "~> 10.0"
32
+ #### in standard library ==> spec.add_development_dependency "minitest", "~> 5.0"
33
33
 
34
34
 
35
35
  end
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.957
4
+ version: 0.0.959
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-03-04 00:00:00.000000000 Z
11
+ date: 2018-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inifile
@@ -52,34 +52,6 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '1.16'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '10.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '10.0'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '5.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '5.0'
83
55
  description: opensecret stashes uncrackable secrets into your Git, S3, DropBox, Google
84
56
  Drive and filesystems backends. You interface with its intuitive Linux, Windows,
85
57
  iOS front ends and it offers SDKs and plugins for Ruby, Python, Java, Jenkins, CodeShip,
@@ -127,6 +99,8 @@ files:
127
99
  - lib/plugins/cipher.rb
128
100
  - lib/plugins/ciphers/aes-256.rb
129
101
  - lib/plugins/ciphers/blowfish.rb
102
+ - lib/plugins/envelope.rb
103
+ - lib/plugins/secrets.uc.rb
130
104
  - lib/plugins/stores/store.rb
131
105
  - lib/plugins/usecase.rb
132
106
  - lib/plugins/usecases/init.rb