strongroom 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -1 +1,5 @@
1
- rvm: 1.9.2
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ - 1.9.2
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
2
  gemspec # See: strongroom.gemspec
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Strongroom
2
2
  ==========
3
3
 
4
+ [![Build Status](https://travis-ci.org/pda/strongroom.png?branch=master)](https://travis-ci.org/pda/strongroom)
5
+
4
6
  Strong public-key encryption for arbitrary length data.
5
7
 
6
8
 
@@ -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
- "cipher" => cipher,
24
- "ciphertext" => Base64.encode64(ciphertext),
25
- "encrypted_key" => Base64.encode64(encrypted_key),
26
- "iv" => Base64.encode64(iv)
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.to_yaml.encode!("US-ASCII")
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
@@ -1,3 +1,3 @@
1
1
  module Strongroom
2
- VERSION = "0.0.2"
2
+ VERSION = "1.0.0"
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -5,6 +5,7 @@ require "pathname"
5
5
  $LOAD_PATH.unshift Pathname(__FILE__).dirname.parent.join("lib").to_path
6
6
 
7
7
  require "minitest/autorun"
8
+ require "turn"
8
9
 
9
10
  require "strongroom"
10
11
 
@@ -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.tap do |c|
7
- c.expect :decrypt, nil
8
- c.expect :key=, "plainkey", [ "plainkey" ]
9
- c.expect :iv=, "iv", [ "iv" ]
10
- c.expect :update, "original inp", [ "ciphertext==" ]
11
- c.expect :final, "ut"
12
- end
13
- @key = ::MiniTest::Mock.new.tap do |k|
14
- k.expect :private_decrypt, "plainkey", [ "ekey" ]
15
- end
16
- @enigma = ::MiniTest::Mock.new.tap do |e|
17
- e.expect :ciphertext, "ciphertext=="
18
- e.expect :encrypted_key, "ekey"
19
- e.expect :iv, "iv"
20
- end
21
- @cipher_locator = ::MiniTest::Mock.new.tap do |cl|
22
- cl.expect :for, @cipher, [ @enigma ]
23
- end
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.tap do |c|
7
- c.expect :name, "AES-128-TEST"
8
- c.expect :encrypt, nil
9
- c.expect :random_key, "rkey"
10
- c.expect :key=, "rkey", [ "rkey" ]
11
- c.expect :random_iv, "riv"
12
- c.expect :iv=, "riv", [ "riv" ]
13
- c.expect :update, "cipherte", [ "input" ]
14
- c.expect :final, "xt=="
15
- end
16
- @key = ::MiniTest::Mock.new.tap do |k|
17
- k.expect :public_encrypt, "encryptedkey", [ "rkey" ]
18
- end
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
- # binary guaranteed to be invalid as US-ASCII or UTF-8
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.tap do |h|
39
- h["cipher"].must_equal "AES-128-TEST"
40
- h["ciphertext"].must_equal bin64("ct")
41
- h["encrypted_key"].must_equal bin64("ek")
42
- h["iv"].must_equal bin64("iv")
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 US-ASCII keys and values" do
46
- enigma.to_hash.tap do |h|
47
- h.each do |key, value|
48
- key.encoding.name.must_equal "US-ASCII"
49
- key.valid_encoding?.must_equal true
50
- value.encoding.name.must_equal "US-ASCII"
51
- value.valid_encoding?.must_equal true
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
- it "accepts hash with string keys for easy deserialization" do
59
- hash = {
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
- Strongroom::Enigma.from_hash(hash).tap do |e|
66
- e.cipher.must_equal "AES-128-TEST"
67
- e.ciphertext.must_equal binary("test_ct")
68
- e.encrypted_key.must_equal binary("test_ek")
69
- e.iv.must_equal binary("test_iv")
70
- end
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 "has is valid US-ASCII" do
83
- s.encoding.name.must_equal "US-ASCII"
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).tap do |e|
91
- e.cipher.must_equal "AES-128-TEST"
92
- e.ciphertext.must_equal binary("ct")
93
- e.encrypted_key.must_equal binary("ek")
94
- e.iv.must_equal binary("iv")
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
 
@@ -10,7 +10,7 @@ describe Strongroom::HasRsaKey do
10
10
  end
11
11
 
12
12
  it "passes through non-String objects" do
13
- key = MiniTest::Mock.new
13
+ key = Object.new
14
14
  klass.new(key).send(:rsa_key).must_equal key
15
15
  end
16
16
 
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
- prerelease: false
5
- segments:
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
- date: 2011-09-21 00:00:00 +10:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
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: &id001 !ruby/object:Gem::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: *id001
33
- - !ruby/object:Gem::Dependency
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: &id002 !ruby/object:Gem::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: *id002
46
- - !ruby/object:Gem::Dependency
47
- name: sdoc
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: &id003 !ruby/object:Gem::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: *id003
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
- none: false
100
- requirements:
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
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- segments:
114
- - 0
115
- version: "0"
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.3.7
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 arbitrary length data with a public key.
123
- test_files:
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: