safedb 0.01.0001

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.
Files changed (90) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.yardopts +3 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +21 -0
  6. data/README.md +793 -0
  7. data/Rakefile +16 -0
  8. data/bin/safe +5 -0
  9. data/lib/configs/README.md +58 -0
  10. data/lib/extension/array.rb +162 -0
  11. data/lib/extension/dir.rb +35 -0
  12. data/lib/extension/file.rb +123 -0
  13. data/lib/extension/hash.rb +33 -0
  14. data/lib/extension/string.rb +572 -0
  15. data/lib/factbase/facts.safedb.net.ini +38 -0
  16. data/lib/interprete.rb +462 -0
  17. data/lib/keytools/PRODUCE_RAND_SEQ_USING_DEV_URANDOM.txt +0 -0
  18. data/lib/keytools/kdf.api.rb +243 -0
  19. data/lib/keytools/kdf.bcrypt.rb +265 -0
  20. data/lib/keytools/kdf.pbkdf2.rb +262 -0
  21. data/lib/keytools/kdf.scrypt.rb +190 -0
  22. data/lib/keytools/key.64.rb +326 -0
  23. data/lib/keytools/key.algo.rb +109 -0
  24. data/lib/keytools/key.api.rb +1391 -0
  25. data/lib/keytools/key.db.rb +330 -0
  26. data/lib/keytools/key.docs.rb +195 -0
  27. data/lib/keytools/key.error.rb +110 -0
  28. data/lib/keytools/key.id.rb +271 -0
  29. data/lib/keytools/key.ident.rb +243 -0
  30. data/lib/keytools/key.iv.rb +107 -0
  31. data/lib/keytools/key.local.rb +259 -0
  32. data/lib/keytools/key.now.rb +402 -0
  33. data/lib/keytools/key.pair.rb +259 -0
  34. data/lib/keytools/key.pass.rb +120 -0
  35. data/lib/keytools/key.rb +585 -0
  36. data/lib/logging/gem.logging.rb +132 -0
  37. data/lib/modules/README.md +43 -0
  38. data/lib/modules/cryptology/aes-256.rb +154 -0
  39. data/lib/modules/cryptology/amalgam.rb +70 -0
  40. data/lib/modules/cryptology/blowfish.rb +130 -0
  41. data/lib/modules/cryptology/cipher.rb +207 -0
  42. data/lib/modules/cryptology/collect.rb +138 -0
  43. data/lib/modules/cryptology/crypt.io.rb +225 -0
  44. data/lib/modules/cryptology/engineer.rb +99 -0
  45. data/lib/modules/mappers/dictionary.rb +288 -0
  46. data/lib/modules/storage/coldstore.rb +186 -0
  47. data/lib/modules/storage/git.store.rb +399 -0
  48. data/lib/session/fact.finder.rb +334 -0
  49. data/lib/session/require.gem.rb +112 -0
  50. data/lib/session/time.stamp.rb +340 -0
  51. data/lib/session/user.home.rb +49 -0
  52. data/lib/usecase/cmd.rb +487 -0
  53. data/lib/usecase/config/README.md +57 -0
  54. data/lib/usecase/docker/README.md +146 -0
  55. data/lib/usecase/docker/docker.rb +49 -0
  56. data/lib/usecase/edit/README.md +43 -0
  57. data/lib/usecase/edit/delete.rb +46 -0
  58. data/lib/usecase/export.rb +40 -0
  59. data/lib/usecase/files/README.md +37 -0
  60. data/lib/usecase/files/eject.rb +56 -0
  61. data/lib/usecase/files/file_me.rb +78 -0
  62. data/lib/usecase/files/read.rb +169 -0
  63. data/lib/usecase/files/write.rb +89 -0
  64. data/lib/usecase/goto.rb +57 -0
  65. data/lib/usecase/id.rb +36 -0
  66. data/lib/usecase/import.rb +157 -0
  67. data/lib/usecase/init.rb +63 -0
  68. data/lib/usecase/jenkins/README.md +146 -0
  69. data/lib/usecase/jenkins/jenkins.rb +208 -0
  70. data/lib/usecase/login.rb +71 -0
  71. data/lib/usecase/logout.rb +28 -0
  72. data/lib/usecase/open.rb +71 -0
  73. data/lib/usecase/print.rb +40 -0
  74. data/lib/usecase/put.rb +81 -0
  75. data/lib/usecase/set.rb +44 -0
  76. data/lib/usecase/show.rb +138 -0
  77. data/lib/usecase/terraform/README.md +91 -0
  78. data/lib/usecase/terraform/terraform.rb +121 -0
  79. data/lib/usecase/token.rb +35 -0
  80. data/lib/usecase/update/README.md +55 -0
  81. data/lib/usecase/update/rename.rb +180 -0
  82. data/lib/usecase/use.rb +41 -0
  83. data/lib/usecase/verse.rb +20 -0
  84. data/lib/usecase/view.rb +71 -0
  85. data/lib/usecase/vpn/README.md +150 -0
  86. data/lib/usecase/vpn/vpn.ini +31 -0
  87. data/lib/usecase/vpn/vpn.rb +54 -0
  88. data/lib/version.rb +3 -0
  89. data/safedb.gemspec +34 -0
  90. metadata +193 -0
@@ -0,0 +1,326 @@
1
+ #!/usr/bin/ruby
2
+
3
+ module SafeDb
4
+
5
+ # First use the class methods to source keys, then use a key's instance
6
+ # methods to access its properties and in concert with other symmetrical
7
+ # information, you can use the keys to lock (encrypt) or unlock (decrypt)
8
+ # other keys and objects.
9
+ #
10
+ # == Sourcing and Deriving Keys
11
+ #
12
+ # Keys can be
13
+ #
14
+ # - sourced from a secure random byte generating function
15
+ # - sourced from ciphertext and another (decryption) key
16
+ # - generated by passing a secret through key derivation functions
17
+ # - regenerated from a secret and previously stored salts
18
+ # - sourced from the current unique workstation shell environment
19
+ # - sourced from an environment variable containing ciphertext
20
+ #
21
+ #
22
+ # Keys need to be viewed (represented) in multiple ways and the essence
23
+ # of the key viewer is to input keys {as_bits}, {as_bytes} and {as_base64}
24
+ # and then output the same key (in as far as is possible) - as bits, as
25
+ # bytes and as base64.
26
+ #
27
+ # == Key | To and From Behaviour
28
+ #
29
+ # Use the <b>From</b> methods to create Keys from a variety of resources
30
+ # such as
31
+ #
32
+ # - a base64 encoded string
33
+ # - a binary byte string
34
+ # - a string of one and zero bits
35
+ # - a hexadecimal representation
36
+ #
37
+ # Once you have instantiated the key, you will then be able to convert it
38
+ # (within reason due to bit, byte and base64 lengths) to any of the above
39
+ # key representations.
40
+ #
41
+ # == Key | Bits Bytes and Base64
42
+ #
43
+ # The shoe doesn't always fit when its on the other foot and this is best
44
+ # illustratd with a table that maps bits to 8 bit bytes and 6 bit Base64
45
+ # characters.
46
+ #
47
+ # | --------- | -------- | ------------ | ------------------------------- |
48
+ # | Fit? | Bits | Bytes | (and) Base64 |
49
+ # | --------- | -------- | ------------ | ------------------------------- |
50
+ # | Perfect | 168 Bits | is 21 bytes | 28 Chars - bcrypt chops to this |
51
+ # | Perfect | 216 Bits | is 27 bytes | 36 Chars - |
52
+ # | Perfect | 264 Bits | is 33 bytes | 44 Chars - holder 4 256bit keys |
53
+ # | Perfect | 384 Bits | is 48 bytes | 64 Chars - 216 + 168 equals 384 |
54
+ # | --------- | -------- | ------------ | ------------------------------- |
55
+ # | Imperfect | 128 Bits | 16 precisely | 22 Chars - 21 + 2 remain bits |
56
+ # | Imperfect | 186 Bits | 23 remain 2 | 31 Characers precisely |
57
+ # | Imperfect | 256 Bits | 32 precisely | 43 Chars - 42 + 4 remain bits |
58
+ # | --------- | -------- | ------------ | ------------------------------- |
59
+ #
60
+ # Yes, the shoe doesn't always fit when it's on the other foot.
61
+ #
62
+ # == Schoolboy Error
63
+ #
64
+ # <b>The strategy is so simple, we call it a schoolboy error.</b>
65
+ #
66
+ # If we want to use a key with n bits and either n % 6 or n % 8 (or both)
67
+ # are not zero - <b>we instantiate a Key</b> with the lowest common
68
+ # denominator of 6 and 8 that exceeds n.
69
+ #
70
+ # So when we request a byte, or base64 representation the viewer will
71
+ # truncate (not round down) to the desired length.
72
+ #
73
+ #
74
+ # == YACHT 64 | Yet Another Character Table
75
+ #
76
+ # This binary key class is a dab hand at converting base64 strings
77
+ # into their 6-bit binary string equivalents.
78
+ #
79
+ # It can convert non-alphanumeric characters within either Base64 or
80
+ # Radix64 into the SafeDb YACHT64 standard which has a forward slash
81
+ # but neither a plus sign nor a period character.
82
+ #
83
+ # <b>The Big4 Character Sets | Base64 | UrlSafe64 | Radix64 | YACHT64</b>
84
+ #
85
+ # Base64 and Radix64 (from OpenBSD) differ in both the order of characters
86
+ # and their choice of the two non-alphanumeric characters. Base64 can also
87
+ # contain line breaks and equal signs for padding. UrlSafe base64 has different
88
+ # choices for the two non alphanum characters in keeping with URL standards.
89
+ #
90
+ # The character sets for each of the four 64 fomats are as follows.
91
+ #
92
+ # - Base-64 is <b>A to Z</b> then <b>a to z</b> then <b>0 to 9</b> then <b>+</b> then <b>/</b>
93
+ # - Radix64 is <b>.</b> then <b>/</b> then <b>0 to 9</b> then <b>A to Z</b> then <b>a to z</b>
94
+ # - UrlSafeBase64 is Base64 but chars 63/64 are an <b>underscore (_)</b> and <b>hyphen (-)</b>
95
+ # - UrlSafeBase64 <b>does not have line breaks and carriage returns</b> (unlike Base64)
96
+ # - <b>SafeDb 64 (YACHT64)</b> uses the same 62 characters plus an @ sign and a forward slash
97
+ # - The 64 <b>SafeDb 64</b> characters are <b>obfuscated into a random order</b>
98
+ #
99
+ # == 4 Non-AlphaNumerics | Base64 | Radix64 | YACHT64
100
+ #
101
+ # The behaviour here is happy to convert base64 strings produced by either
102
+ # Radix64 or Base64 or UrlSafe Base64. Howeverr it aware of the
103
+ # <b>non alpha-numeric characters</b> and converts them before processing
104
+ # with the modus operandi that says
105
+ #
106
+ # - ignore the forward slash in <b>YACHT64, Base64 and Radix64</b>
107
+ # - convert the <b>plus (+)</b> in Base64 to the <b>@ symbol</b> in YACHT64
108
+ # - convert the <b>period (.)</b> in <b>Radix64</b> to the @ symbol in YACHT64
109
+ # - convert <b>hyphen (-)</b> in <b>Url Safe Base64</b> into a fwd slash
110
+ # - convert <b>underscore (_)</b> in <b>Url Safe Base64</b> to an @ sign
111
+ # - <b>delete the (=) equals</b> padding character used by Base64
112
+ #
113
+ # Neither the OpenBSD backed Radix64 nor the SafeDb (YACHT64) entertain the
114
+ # concept of padding.
115
+ #
116
+ # == Mapping Each Character to 6 Binary Bits
117
+ #
118
+ # We need 6 binary bits to represent a base64 character (and 4
119
+ # bits for hexadecimal). Here is an example mapping between
120
+ # a base 64 character, an integer and the six bit binary.
121
+ #
122
+ # Character Integer Binary (6 Bit)
123
+ #
124
+ # a 0 000000
125
+ # b 1 000001
126
+ # c 2 000010
127
+ #
128
+ # y 25 011001
129
+ # z 26 011010
130
+ # A 27 011011
131
+ # B 28 011100
132
+ #
133
+ # 8 60 111100
134
+ # 9 61 111101
135
+ # / 62 111110
136
+ # + 63 111111
137
+ #
138
+ class Key64
139
+
140
+ # YACHT stands for <b>Yet Another Character Table</b> and it
141
+ # can map binary sequences onto 64 well chosen characters.
142
+ #
143
+ # The 64 character sets are all similar in that they hold 64
144
+ # characters and they define two non alphanumeric characters
145
+ # because the 26 lowercase, 26 uppercase and 10 digits only
146
+ # adds up to an <b><em>agonisingly close</em></b> 62 characters.
147
+ #
148
+ YACHT64_CHARACTER_SET = [
149
+ "a", "9", "W", "B", "f", "K", "O", "z",
150
+ "3", "s", "1", "5", "c", "n", "E", "J",
151
+ "L", "A", "l", "6", "I", "w", "o", "g",
152
+ "k", "N", "t", "Y", "S", "%", "T", "b",
153
+ "V", "R", "H", "0", "@", "Z", "8", "F",
154
+ "G", "j", "u", "m", "M", "h", "4", "p",
155
+ "q", "d", "7", "v", "e", "2", "U", "X",
156
+ "r", "C", "y", "Q", "D", "x", "P", "i"
157
+ ]
158
+
159
+
160
+ # Radix64 strings can contain period characters in their midst.
161
+ PERIOD = "."
162
+
163
+ # Radix64 strings can contain forward slashes in their midst.
164
+ FORWARD_SLASH = "/"
165
+
166
+ # YACHT64 strings can contain at symbols in their midst.
167
+ AT_SYMBOL = "@"
168
+
169
+ # YACHT64 strings can contain percent signs in their midst.
170
+ PERCENT_SIGN = "%"
171
+
172
+
173
+ # Convert the parameter string of ones and zeroes into an
174
+ # internal base64 character set known as YACHT for yet another
175
+ # character table.
176
+ #
177
+ # @param bit_string [String]
178
+ # a string of ones and zeroes that can be sliced into
179
+ # six character chunks with each chunk then being mapped
180
+ # to a YACHT64 character.
181
+ #
182
+ # @return [String]
183
+ # printable characters from a set of 62 alpha-numerics
184
+ # plus an @ symbol and a percent % sign.
185
+ #
186
+ # @raise ArgumentError
187
+ # If the bit string is nil.
188
+ # Or if the bit string length is not a multiple of six.
189
+ # Or if it contains any character that is not a 1 or 0.
190
+ def self.from_bits bit_string
191
+
192
+ nil_err_msg = "The parameter bit string cannot be nil."
193
+ raise ArgumentError, nil_err_msg if bit_string.nil?
194
+
195
+ bit_size_msg = "The bit string length is not a multiple of #{SIX}."
196
+ raise ArgumentError, bit_size_msg unless bit_string.length % SIX == 0
197
+
198
+ num_unknowns = bit_string.delete("10").length
199
+ unknowns_msg = "The bit string has #{num_unknowns} characters that are not 1 or 0."
200
+ raise ArgumentError, unknowns_msg if num_unknowns > 0
201
+
202
+ characters64 = ""
203
+ char_count = bit_string.length / SIX
204
+ for n in 0 .. (char_count-1)
205
+ six_bit_chunk = bit_string[ (n*SIX), SIX ]
206
+ six_bit_index = six_bit_chunk.to_i(2)
207
+ characters64 += Key64.character(six_bit_index)
208
+ end
209
+
210
+ code_size_msg = "Length is #{characters64.length} but #{char_count} is expected."
211
+ raise RuntimeError, code_size_msg unless characters64.length == char_count
212
+
213
+ return characters64
214
+
215
+ end
216
+
217
+
218
+ # Convert the parameter characters based on an internal base64
219
+ # character set (known as YACHT) into a <b>bit string</b> of ones
220
+ # and zeroes.
221
+ #
222
+ # @param char64_string [String]
223
+ # The base64 character sequence which which will be used to
224
+ # derive the returned bit string. Naturally this character
225
+ # sequencee cannot be nil, nor can it contain any characters
226
+ # that are not present in {Key64::YACHT64_CHARACTER_SET}.
227
+ #
228
+ # @return [String]
229
+ # a string of ones and zeroes that have been strung out
230
+ # from each YACHT64 character. The returned string length of
231
+ # ones and zeroes will be exactly 6 times the length of the
232
+ # input parameter.
233
+ #
234
+ # @raise [ArgumentError]
235
+ # If a nil or zero length character string is received.
236
+ # Or if the character sequence contains a character not present
237
+ # in the {Key64::YACHT64_CHARACTER_SET}.
238
+ #
239
+ # @raise [RuntimeError]
240
+ # if the conversion does not result in 6 bits for every character
241
+ # in the parameter string.
242
+ def self.to_bits char64_string
243
+
244
+ bit_string = ""
245
+ char64_string.each_char do |the_char|
246
+
247
+ yacht64_index = YACHT64_CHARACTER_SET.index(the_char)
248
+ assert_yacht64_index( the_char, yacht64_index )
249
+ bit_string += "%06d" % [ yacht64_index.to_s(2) ]
250
+
251
+ end
252
+
253
+ assert_bit_lengths char64_string, bit_string
254
+ return bit_string
255
+
256
+ end
257
+
258
+
259
+ # Convert a string of Radix64 characters into a bit representation which
260
+ # will be 6 times longer than the input parameter. This method first
261
+ # converts the string into the internal YACHT64 format and then converts
262
+ # that to a bit string using the {Key64.to_bits} method.
263
+ #
264
+ # @param radix64_string [String]
265
+ # the radix64 string to convert into bits. This string will be a subset
266
+ # of the usual 62 character suspects together with period and forward
267
+ # slash characters.
268
+ #
269
+ # This parameter should not contain newlines nor carriage returns.
270
+ #
271
+ # @return [String]
272
+ # a string of ones and zeroes that represent the bits converted from the
273
+ # radix64 input. The return value will be exactly 6 times the number of
274
+ # input characters.
275
+ def self.from_radix64_to_bits radix64_string
276
+
277
+ yacht64_chars = radix64_string.gsub( PERIOD, AT_SYMBOL ).gsub( FORWARD_SLASH, PERCENT_SIGN )
278
+ out_bitstring = to_bits( yacht64_chars )
279
+ assert_bit_lengths( radix64_string, out_bitstring )
280
+ return out_bitstring
281
+
282
+ end
283
+
284
+
285
+
286
+ private
287
+
288
+
289
+
290
+ SIX = 6
291
+
292
+ def self.character char_index
293
+
294
+ index_oob_msg = "The character index must be between 0 and 63 inclusive."
295
+ index_is_oob = char_index < 0 || char_index > 63
296
+ raise ArgumentError, index_oob_msg if index_is_oob
297
+ return YACHT64_CHARACTER_SET[ char_index ]
298
+
299
+ end
300
+
301
+ def self.assert_bit_lengths( in_string, out_string )
302
+
303
+ in_length = in_string.length
304
+ out_length = out_string.length
305
+ good_ratio = out_length == in_length * SIX
306
+ size_msg = "Bit string length [#{out_length}] not 6 times more than [#{in_length}]."
307
+ raise RuntimeError, size_msg unless good_ratio
308
+
309
+ end
310
+
311
+ def self.assert_yacht64_index the_char, yacht64_index
312
+
313
+ nil_msg = "Character [ #{the_char} ] not in YACHT character set."
314
+ raise ArgumentError, nil_msg if yacht64_index.nil?
315
+
316
+ index_msg = "Index of character [ #{the_char} ] not within expected bounds."
317
+ all_good = ( yacht64_index >= 0 ) && ( yacht64_index <= 63 )
318
+ raise ArgumentError, index_msg unless all_good
319
+
320
+ end
321
+
322
+
323
+ end
324
+
325
+
326
+ end
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/ruby
2
+ # coding: utf-8
3
+
4
+ module SafeDb
5
+
6
+ # Algorithms that are quality catalysts in the derivation and entropy spread
7
+ # of keys, identifiers and base64 character numbers.
8
+ class KeyAlgo
9
+
10
+
11
+ # Cherry pick a given number of characters from the character pool
12
+ # so that a good spread is achieved. This picker is the anti-pattern
13
+ # of just axing the first 5 characters from a 100 character string
14
+ # essentially wasting over 90% of the available entropy.
15
+ #
16
+ # This is the <b>algorithem to cherry pick</b> a spread of characters
17
+ # from the pool in the second parameter.
18
+ #
19
+ # - if the character pool length is a multiple of num_chars all is good otherwise
20
+ # - constrict to the <b>highest multiple of the pick size below</b> the pool length
21
+ # - divide that number by num_chars to get the first offset and character spacing
22
+ # - if spacing is 3, the first character is the 3rd, the second the 6th and so on
23
+ # - then return the cherry picked characters
24
+ #
25
+ # @param pick_size [FixNum] the number of characters to cherry pick
26
+ # @param char_pool [String] a pool of characters to cherry pick from
27
+ # @return [String]
28
+ # a string whose length is the one indicated by the first parameter
29
+ # and whose characters contain a predictable, repeatable spread from
30
+ # the character pool parameter
31
+ def self.cherry_picker( pick_size, char_pool )
32
+
33
+ hmb_limit = highest_multiple_below( pick_size, char_pool.length )
34
+ jump_size = hmb_limit / pick_size
35
+ read_point = jump_size
36
+ picked_chars = ""
37
+ loop do
38
+ picked_chars += char_pool[ read_point - 1 ]
39
+ read_point += jump_size
40
+ break if read_point > hmb_limit
41
+ end
42
+
43
+ err_msg = "Expected cherry pick size to be #{pick_size} but it was #{picked_chars.length}."
44
+ raise RuntimeError, err_msg unless picked_chars.length == pick_size
45
+
46
+ return picked_chars
47
+
48
+ end
49
+
50
+
51
+ # Affectionately known as <b>a hmb</b>, this method returns the
52
+ # <b>highest multiple</b> of the first parameter that is below
53
+ # <b>(either less than or equal to)</b> the second parameter.
54
+ #
55
+ # - -------- - ------- - ----------------- -
56
+ # | Small | Big | Highest Multiple |
57
+ # | Number | Number | Below Big Num |
58
+ # | -------- - ------- - ----------------- |
59
+ # | 5 | 25 | 25 |
60
+ # | 3 | 20 | 18 |
61
+ # | 8 | 63 | 56 |
62
+ # | 1 | 1 | 1 |
63
+ # | 26 | 28 | 26 |
64
+ # | 1 | 7 | 7 |
65
+ # | 16 | 16 | 16 |
66
+ # | -------- - ------- - ----------------- |
67
+ # | 10 | 8 | ERROR |
68
+ # | -4 | 17 | ERROR |
69
+ # | 4 | -17 | ERROR |
70
+ # | 0 | 32 | ERROR |
71
+ # | 29 | 0 | ERROR |
72
+ # | -4 | 0 | ERROR |
73
+ # | -------- - ------- - ----------------- |
74
+ # - -------- - ------- - ----------------- -
75
+ #
76
+ # Zeroes and negative numbers cannot be entertained, nor can the
77
+ # small number be larger than the big one.
78
+ #
79
+ # @param small_num [FixNum]
80
+ # the highest multiple of this number below the one in the
81
+ # next parameter is what will be returned.
82
+ #
83
+ # @param big_num [FixNum]
84
+ # returns either this number or the nearest below it that is
85
+ # a multiple of the number in the first parameter.
86
+ #
87
+ # @raise [ArgumentError]
88
+ # if the first parameter is greater than the second
89
+ # if either or both parameters are zero or negative
90
+ def self.highest_multiple_below small_num, big_num
91
+
92
+ arg_issue = (small_num > big_num) || small_num < 1 || big_num < 1
93
+ err_msg = "Invalid args #{small_num} and #{big_num} to HMB function."
94
+ raise ArgumentError, err_msg if arg_issue
95
+
96
+ for index in 0 .. ( big_num - 1 )
97
+ invex = big_num - index # an [invex] is an inverted index
98
+ return invex if invex % small_num == 0
99
+ end
100
+
101
+ raise ArgumentError, "Could not find a multiple of #{small_num} lower than #{big_num}"
102
+
103
+ end
104
+
105
+
106
+ end
107
+
108
+
109
+ end