strongroom 0.0.2 → 1.0.0
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.
- data/.travis.yml +5 -1
- data/Gemfile +1 -1
- data/README.md +2 -0
- data/lib/strongroom/enigma.rb +22 -7
- data/lib/strongroom/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/strongroom_decryptor_spec.rb +23 -18
- data/spec/strongroom_encryptor_spec.rb +13 -13
- data/spec/strongroom_enigma_spec.rb +32 -32
- data/spec/strongroom_has_rsa_key_spec.rb +1 -1
- data/strongroom.gemspec +3 -1
- metadata +94 -70
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
source
|
1
|
+
source "https://rubygems.org"
|
2
2
|
gemspec # See: strongroom.gemspec
|
data/README.md
CHANGED
data/lib/strongroom/enigma.rb
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
require "base64"
|
2
|
+
require "yaml"
|
2
3
|
|
3
4
|
module Strongroom
|
4
5
|
class Enigma
|
5
6
|
|
7
|
+
# "ASCII-8BIT" is Ruby's "BINARY" type:
|
8
|
+
# Encoding.aliases["BINARY"] # => "ASCII-8BIT"
|
9
|
+
BINARY = "ASCII-8BIT"
|
10
|
+
|
6
11
|
def initialize parameters
|
7
12
|
@cipher = parameters.fetch :cipher
|
8
13
|
@ciphertext = parameters.fetch :ciphertext
|
@@ -19,12 +24,11 @@ module Strongroom
|
|
19
24
|
end
|
20
25
|
|
21
26
|
def to_hash
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
}
|
27
|
+
Hash[
|
28
|
+
to_hash_with_default_encoding.map do |key, value|
|
29
|
+
[key.dup.force_encoding(BINARY), value.force_encoding(BINARY)]
|
30
|
+
end
|
31
|
+
]
|
28
32
|
end
|
29
33
|
|
30
34
|
def self.from_hash hash
|
@@ -37,12 +41,23 @@ module Strongroom
|
|
37
41
|
end
|
38
42
|
|
39
43
|
def serialize
|
40
|
-
to_hash.
|
44
|
+
YAML.dump(to_hash).force_encoding(BINARY)
|
41
45
|
end
|
42
46
|
|
43
47
|
def self.deserialize input
|
44
48
|
from_hash YAML.load(input)
|
45
49
|
end
|
46
50
|
|
51
|
+
private
|
52
|
+
|
53
|
+
def to_hash_with_default_encoding
|
54
|
+
{
|
55
|
+
"cipher" => cipher,
|
56
|
+
"ciphertext" => Base64.encode64(ciphertext),
|
57
|
+
"encrypted_key" => Base64.encode64(encrypted_key),
|
58
|
+
"iv" => Base64.encode64(iv)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
47
62
|
end
|
48
63
|
end
|
data/lib/strongroom/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -3,24 +3,24 @@ require_relative "spec_helper"
|
|
3
3
|
describe Strongroom::Decryptor do
|
4
4
|
|
5
5
|
before do
|
6
|
-
@cipher = ::MiniTest::Mock.new
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
@key = ::MiniTest::Mock.new
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
6
|
+
@cipher = ::MiniTest::Mock.new
|
7
|
+
@cipher.expect :decrypt, nil
|
8
|
+
@cipher.expect :key=, "plainkey", [ "plainkey" ]
|
9
|
+
@cipher.expect :iv=, "iv", [ "iv" ]
|
10
|
+
@cipher.expect :update, "original inp", [ "ciphertext==" ]
|
11
|
+
@cipher.expect :final, "ut"
|
12
|
+
|
13
|
+
@key = ::MiniTest::Mock.new
|
14
|
+
def @key.is_a?(type); false; end
|
15
|
+
@key.expect :private_decrypt, "plainkey", [ "ekey" ]
|
16
|
+
|
17
|
+
@enigma = ::MiniTest::Mock.new
|
18
|
+
@enigma.expect :ciphertext, "ciphertext=="
|
19
|
+
@enigma.expect :encrypted_key, "ekey"
|
20
|
+
@enigma.expect :iv, "iv"
|
21
|
+
|
22
|
+
@cipher_locator = ::MiniTest::Mock.new
|
23
|
+
@cipher_locator.expect :for, @cipher, [ @enigma ]
|
24
24
|
end
|
25
25
|
|
26
26
|
it "calls OpenSSL methods" do
|
@@ -28,6 +28,11 @@ describe Strongroom::Decryptor do
|
|
28
28
|
[ @cipher, @key, @enigma ].each &:verify
|
29
29
|
end
|
30
30
|
|
31
|
+
it "uses cipher_locator" do
|
32
|
+
Strongroom::Decryptor.new(@key, @cipher_locator).decrypt(@enigma)
|
33
|
+
@cipher_locator.verify
|
34
|
+
end
|
35
|
+
|
31
36
|
it "returns correct plaintext" do
|
32
37
|
Strongroom::Decryptor.new(@key, @cipher_locator).decrypt(@enigma).tap do |output|
|
33
38
|
output.must_equal "original input"
|
@@ -3,19 +3,19 @@ require_relative "spec_helper"
|
|
3
3
|
describe Strongroom::Encryptor do
|
4
4
|
|
5
5
|
before do
|
6
|
-
@cipher = ::MiniTest::Mock.new
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@key = ::MiniTest::Mock.new
|
17
|
-
|
18
|
-
|
6
|
+
@cipher = ::MiniTest::Mock.new
|
7
|
+
@cipher.expect :name, "AES-128-TEST"
|
8
|
+
@cipher.expect :encrypt, nil
|
9
|
+
@cipher.expect :random_key, "rkey"
|
10
|
+
@cipher.expect :key=, "rkey", [ "rkey" ]
|
11
|
+
@cipher.expect :random_iv, "riv"
|
12
|
+
@cipher.expect :iv=, "riv", [ "riv" ]
|
13
|
+
@cipher.expect :update, "cipherte", [ "input" ]
|
14
|
+
@cipher.expect :final, "xt=="
|
15
|
+
|
16
|
+
@key = ::MiniTest::Mock.new
|
17
|
+
def @key.is_a?(type); false; end
|
18
|
+
@key.expect :public_encrypt, "encryptedkey", [ "rkey" ]
|
19
19
|
end
|
20
20
|
|
21
21
|
it "calls OpenSSL methods" do
|
@@ -2,9 +2,11 @@ require_relative "spec_helper"
|
|
2
2
|
|
3
3
|
describe Strongroom::Enigma do
|
4
4
|
|
5
|
-
#
|
5
|
+
# Generates a string guaranteed to be invalid as US-ASCII or UTF-8.
|
6
|
+
# Encoding set to "ASCII-8BIT" as this is Ruby's "BINARY" type:
|
7
|
+
# Encoding.aliases["BINARY"] # => "ASCII-8BIT"
|
6
8
|
def binary input
|
7
|
-
"\xFF" << input
|
9
|
+
("\xFF" << input).force_encoding("ASCII-8BIT")
|
8
10
|
end
|
9
11
|
|
10
12
|
# input has non-valid-character-encoding byte added, then base64 encoded
|
@@ -35,39 +37,38 @@ describe Strongroom::Enigma do
|
|
35
37
|
|
36
38
|
describe "#to_hash" do
|
37
39
|
it "has string keys, binary values base64 encoded" do
|
38
|
-
enigma.to_hash
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
40
|
+
h = enigma.to_hash
|
41
|
+
h["cipher"].must_equal "AES-128-TEST"
|
42
|
+
h["ciphertext"].must_equal bin64("ct")
|
43
|
+
h["encrypted_key"].must_equal bin64("ek")
|
44
|
+
h["iv"].must_equal bin64("iv")
|
44
45
|
end
|
45
|
-
it "has
|
46
|
-
enigma.to_hash
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
46
|
+
it "has ASCII-8BIT keys and values" do
|
47
|
+
h = enigma.to_hash
|
48
|
+
h.each do |key, value|
|
49
|
+
key.encoding.name.must_equal "ASCII-8BIT"
|
50
|
+
key.valid_encoding?.must_equal true
|
51
|
+
value.encoding.name.must_equal "ASCII-8BIT"
|
52
|
+
value.valid_encoding?.must_equal true
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
57
|
describe ".from_hash" do
|
58
|
-
|
59
|
-
|
58
|
+
let(:hash) do
|
59
|
+
{
|
60
60
|
"cipher" => "AES-128-TEST",
|
61
61
|
"ciphertext" => bin64("test_ct"),
|
62
62
|
"encrypted_key" => bin64("test_ek"),
|
63
63
|
"iv" => bin64("test_iv")
|
64
64
|
}
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
65
|
+
end
|
66
|
+
it "accepts hash with string keys for easy deserialization" do
|
67
|
+
e = Strongroom::Enigma.from_hash(hash)
|
68
|
+
e.cipher.must_equal "AES-128-TEST"
|
69
|
+
e.ciphertext.must_equal binary("test_ct")
|
70
|
+
e.encrypted_key.must_equal binary("test_ek")
|
71
|
+
e.iv.must_equal binary("test_iv")
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -79,20 +80,19 @@ describe Strongroom::Enigma do
|
|
79
80
|
it "is not empty" do
|
80
81
|
s.wont_be_empty
|
81
82
|
end
|
82
|
-
it "
|
83
|
-
s.encoding.name.must_equal "
|
83
|
+
it "is valid ASCII-8BIT" do
|
84
|
+
s.encoding.name.must_equal "ASCII-8BIT"
|
84
85
|
s.valid_encoding?.must_equal true
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
88
89
|
describe ".deserialize" do
|
89
90
|
it "correctly deserializes output from #serialize" do
|
90
|
-
Strongroom::Enigma.deserialize(enigma.serialize)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
91
|
+
e = Strongroom::Enigma.deserialize(enigma.serialize)
|
92
|
+
e.cipher.must_equal "AES-128-TEST"
|
93
|
+
e.ciphertext.must_equal binary("ct")
|
94
|
+
e.encrypted_key.must_equal binary("ek")
|
95
|
+
e.iv.must_equal binary("iv")
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
data/strongroom.gemspec
CHANGED
@@ -17,7 +17,9 @@ Gem::Specification.new do |gem|
|
|
17
17
|
|
18
18
|
gem.required_ruby_version = ">= 1.9.2"
|
19
19
|
|
20
|
+
gem.add_development_dependency "minitest"
|
20
21
|
gem.add_development_dependency "rake"
|
21
|
-
gem.add_development_dependency "simplecov"
|
22
22
|
gem.add_development_dependency "sdoc"
|
23
|
+
gem.add_development_dependency "simplecov"
|
24
|
+
gem.add_development_dependency "turn"
|
23
25
|
end
|
metadata
CHANGED
@@ -1,71 +1,103 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: strongroom
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 2
|
9
|
-
version: 0.0.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Paul Annesley
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
date: 2013-02-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: minitest
|
16
|
+
prerelease: false
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
none: false
|
23
|
+
type: :development
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ! '>='
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
21
31
|
name: rake
|
22
32
|
prerelease: false
|
23
|
-
requirement:
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
none: false
|
39
|
+
type: :development
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sdoc
|
48
|
+
prerelease: false
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
24
54
|
none: false
|
25
|
-
requirements:
|
26
|
-
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
segments:
|
29
|
-
- 0
|
30
|
-
version: "0"
|
31
55
|
type: :development
|
32
|
-
version_requirements:
|
33
|
-
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
none: false
|
62
|
+
- !ruby/object:Gem::Dependency
|
34
63
|
name: simplecov
|
35
64
|
prerelease: false
|
36
|
-
requirement:
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
37
70
|
none: false
|
38
|
-
requirements:
|
39
|
-
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
segments:
|
42
|
-
- 0
|
43
|
-
version: "0"
|
44
71
|
type: :development
|
45
|
-
version_requirements:
|
46
|
-
|
47
|
-
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
none: false
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: turn
|
48
80
|
prerelease: false
|
49
|
-
requirement:
|
81
|
+
requirement: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
50
86
|
none: false
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
segments:
|
55
|
-
- 0
|
56
|
-
version: "0"
|
57
87
|
type: :development
|
58
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ! '>='
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
none: false
|
59
94
|
description: Strong public-key encryption for arbitrary length data.
|
60
|
-
email:
|
95
|
+
email:
|
61
96
|
- paul@annesley.cc
|
62
97
|
executables: []
|
63
|
-
|
64
98
|
extensions: []
|
65
|
-
|
66
99
|
extra_rdoc_files: []
|
67
|
-
|
68
|
-
files:
|
100
|
+
files:
|
69
101
|
- .gitignore
|
70
102
|
- .travis.yml
|
71
103
|
- Gemfile
|
@@ -86,41 +118,32 @@ files:
|
|
86
118
|
- spec/strongroom_has_rsa_key_spec.rb
|
87
119
|
- spec/strongroom_spec.rb
|
88
120
|
- strongroom.gemspec
|
89
|
-
has_rdoc: true
|
90
121
|
homepage: https://github.com/learnable/strongroom
|
91
122
|
licenses: []
|
92
|
-
|
93
123
|
post_install_message:
|
94
124
|
rdoc_options: []
|
95
|
-
|
96
|
-
require_paths:
|
125
|
+
require_paths:
|
97
126
|
- lib
|
98
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
segments:
|
104
|
-
- 1
|
105
|
-
- 9
|
106
|
-
- 2
|
127
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
107
131
|
version: 1.9.2
|
108
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
132
|
none: false
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
none: false
|
116
139
|
requirements: []
|
117
|
-
|
118
140
|
rubyforge_project:
|
119
|
-
rubygems_version: 1.
|
141
|
+
rubygems_version: 1.8.23
|
120
142
|
signing_key:
|
121
143
|
specification_version: 3
|
122
|
-
summary: Strongroom uses RSA and AES encryption from Ruby's OpenSSL bindings to encrypt
|
123
|
-
|
144
|
+
summary: Strongroom uses RSA and AES encryption from Ruby's OpenSSL bindings to encrypt
|
145
|
+
arbitrary length data with a public key.
|
146
|
+
test_files:
|
124
147
|
- spec/fixtures/private_key
|
125
148
|
- spec/fixtures/public_key
|
126
149
|
- spec/spec_helper.rb
|
@@ -129,3 +152,4 @@ test_files:
|
|
129
152
|
- spec/strongroom_enigma_spec.rb
|
130
153
|
- spec/strongroom_has_rsa_key_spec.rb
|
131
154
|
- spec/strongroom_spec.rb
|
155
|
+
has_rdoc:
|