akero 1.0.3 → 1.0.4

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/README.md CHANGED
@@ -4,13 +4,13 @@ Akero ([ἄγγελος](http://en.wiktionary.org/wiki/%F0%90%80%80%F0%90%80%90%
4
4
 
5
5
  Under the hood Akero uses standard OpenSSL primitives. Each instance wraps a [RSA](http://en.wikipedia.org/wiki/RSA)-keypair, a corresponding [X.509 certificate](http://en.wikipedia.org/wiki/X.509) and exchanges self-signed messages ([PKCS#7](https://tools.ietf.org/html/rfc2315)) with other instances.
6
6
 
7
- Akero does not try to be a substitute for a fully featured [PKI](http://en.wikipedia.org/wiki/Public_key_infrastructure). It is meant to be used as a building block in scenarios where trust-relationships and keyrings can be externally managed, and where the complexity of traditional solutions (X.509 PKI, OpenPGP, homegrown RSA) yields no tangible benefits.
7
+ Akero does not try to be a substitute for a fully featured [PKI](http://en.wikipedia.org/wiki/Public_key_infrastructure). It is meant to be used as a building block in scenarios where trust-relationships and keyrings can be externally managed, and where the complexity of traditional solutions (X.509 PKI, OpenPGP, custom RSA) yields no tangible benefits.
8
8
 
9
9
  ## Features
10
10
 
11
11
  * Secure 1-to-n messaging (sign-only -or- sign->encrypt->sign)
12
- * Low complexity; easy to use, understand and review (only 166 lines of code)
13
- * Transport agnostic; messages and certificates are self-contained, ascii-armored (base64)
12
+ * Low complexity; easy to use, understand and review (only 192 lines of code)
13
+ * Transport agnostic; messages and certificates are self-contained and optionally ascii-armored (base64)
14
14
  * Built on standard OpenSSL primitives, no homegrown algorithms
15
15
  * [100%](https://busyloop.net/oss/akero/coverage/) test coverage
16
16
 
@@ -64,6 +64,13 @@ File.open('/tmp/alice.akr', 'w') { |f| f.write(alice.private_key) }
64
64
  # And load her again
65
65
  new_alice = Akero.load(File.read('/tmp/alice.akr'))
66
66
 
67
+ # By default all messages are ascii armored.
68
+ # In production Alice disables the armoring
69
+ # for better performance.
70
+ signed_msg = alice.sign("Hello world!", false)
71
+ msg = alice.encrypt(alice.public_key, "Hello!", false)
72
+ puts alice.receive(msg).body # => "Hello!"
73
+
67
74
  ```
68
75
 
69
76
  ## Documentation
data/Rakefile CHANGED
@@ -22,4 +22,8 @@ namespace :docs do
22
22
  task :push do
23
23
  `bl_www_sync akero coverage`
24
24
  end
25
+
26
+ task :loc do
27
+ puts `grep -v '^\\s*#' lib/akero.rb | grep -v '^$' | wc -l`
28
+ end
25
29
  end
Binary file
Binary file
data/lib/akero.rb CHANGED
@@ -81,6 +81,7 @@ class Akero
81
81
  PLATE_CRYPTED = ['PKCS7', 'AKERO SECRET MESSAGE'] # @private
82
82
 
83
83
  DEFAULT_RSA_BITS = 2048
84
+ DEFAULT_DIGEST = OpenSSL::Digest::SHA512
84
85
 
85
86
  # Unique fingerprint of this Akero keypair.
86
87
  #
@@ -101,10 +102,10 @@ class Akero
101
102
  # Akero.new(4096, OpenSSL::Digest::SHA512)
102
103
  #
103
104
  # @param [Integer] rsa_bits RSA key length
104
- # @param [OpenSSL::Digest] sign_digest Signature digest
105
+ # @param [OpenSSL::Digest] digest Signature digest
105
106
  # @return [Akero] New Akero instance
106
- def initialize(rsa_bits=DEFAULT_RSA_BITS, sign_digest=OpenSSL::Digest::SHA512)
107
- @key, @cert = generate_keypair(rsa_bits, sign_digest) unless rsa_bits.nil?
107
+ def initialize(rsa_bits=DEFAULT_RSA_BITS, digest=DEFAULT_DIGEST)
108
+ @key, @cert = generate_keypair(rsa_bits, digest) unless rsa_bits.nil?
108
109
  end
109
110
 
110
111
  # Load an Akero identity.
@@ -161,9 +162,11 @@ class Akero
161
162
  # Sign a message.
162
163
  #
163
164
  # @param [String] plaintext The message to sign (binary safe)
165
+ # @param [Boolean] ascii_armor Convert the output in base64?
164
166
  # @return [String] Akero signed message
165
- def sign(plaintext)
166
- Akero.replate(_sign(plaintext).to_s, Akero::PLATE_SIGNED)
167
+ def sign(plaintext, ascii_armor=true)
168
+ out = _sign(plaintext)
169
+ ascii_armor ? Akero.replate(out.to_s, Akero::PLATE_SIGNED) : out.to_der
167
170
  end
168
171
 
169
172
  # Sign->encrypt->sign a message for 1 or more recipients.
@@ -184,8 +187,9 @@ class Akero
184
187
  #
185
188
  # @param [Array] to Akero public keys of recipients
186
189
  # @param [String] plaintext The message to encrypt (binary safe)
190
+ # @param [Boolean] ascii_armor Convert the output to base64?
187
191
  # @return [String] Akero secret message
188
- def encrypt(to, plaintext)
192
+ def encrypt(to, plaintext, ascii_armor=true)
189
193
  to = [to] unless to.is_a? Array
190
194
  to = to.map { |e|
191
195
  case e
@@ -199,7 +203,8 @@ class Akero
199
203
  raise RuntimeError, ERR_INVALID_RECIPIENT
200
204
  end
201
205
  }
202
- Akero.replate(_sign(_encrypt(to, _sign(plaintext, false))).to_s, PLATE_CRYPTED)
206
+ out = _sign(_encrypt(to, _sign(plaintext, false)))
207
+ ascii_armor ? Akero.replate(out.to_s, PLATE_CRYPTED) : out.to_der
203
208
  end
204
209
 
205
210
  # Receive an Akero message.
@@ -207,7 +212,9 @@ class Akero
207
212
  # @param [String] ciphertext Akero Message
208
213
  # @return [Akero::Message] Message_body, signer_certificate, body_type
209
214
  def receive(ciphertext)
210
- ciphertext = Akero.replate(ciphertext, Akero::PLATE_CRYPTED, true)
215
+ if ciphertext.start_with? '-----BEGIN '
216
+ ciphertext = Akero.replate(ciphertext, Akero::PLATE_CRYPTED, true)
217
+ end
211
218
  begin
212
219
  body, signer_cert, body_type = verify(ciphertext, nil)
213
220
  rescue ArgumentError
@@ -316,9 +323,9 @@ class Akero
316
323
  # Generate new RSA keypair and certificate.
317
324
  #
318
325
  # @param [Integer] rsa_bits RSA key length
319
- # @param [OpenSSL::Digest] sign_digest Signature digest
326
+ # @param [OpenSSL::Digest] digest Signature digest
320
327
  # @return [Array] rsa_keypair, certificate
321
- def generate_keypair(rsa_bits=DEFAULT_RSA_BITS, sign_digest=OpenSSL::Digest::SHA512)
328
+ def generate_keypair(rsa_bits=DEFAULT_RSA_BITS, digest=DEFAULT_DIGEST)
322
329
  cn = "Akero #{Akero::VERSION}"
323
330
  rsa = OpenSSL::PKey::RSA.new(rsa_bits)
324
331
 
@@ -342,7 +349,7 @@ class Akero
342
349
  aki = ef.create_extension("authorityKeyIdentifier",
343
350
  "keyid:always,issuer:always")
344
351
  cert.add_extension(aki)
345
- cert.sign(rsa, sign_digest.new)
352
+ cert.sign(rsa, digest.new)
346
353
  [rsa, cert]
347
354
  end
348
355
  end
@@ -15,16 +15,16 @@ class Akero
15
15
  puts "Running size benchmark..."
16
16
 
17
17
  rnd = Random.new
18
- msg_sizes = (8..13).map{|x| 2**x}
19
- key_sizes = [2048, 4096]
18
+ msg_sizes = (8..14).map{|x| 2**x}
19
+ modes = [[2048, false], [2048, true]]
20
20
  results = {}
21
- key_sizes.each do |ksize|
22
- alice = Akero.new(ksize)
23
- bob = Akero.new(ksize)
21
+ modes.each do |mode|
22
+ alice = Akero.new(mode[0])
23
+ bob = Akero.new(mode[0])
24
24
  msg_sizes.each do |msize|
25
25
  msg = rnd.bytes(msize)
26
- ciphertext = alice.encrypt(bob.public_key, msg)
27
- (results["ENCRYPT #{ksize} bits"] ||= []) << [msize, ciphertext.length / msg.length.to_f]
26
+ ciphertext = alice.encrypt(bob.public_key, msg, mode[1])
27
+ (results["ENCRYPT #{mode[0]} bits #{mode[1] ? 'ascii_armor=1' : 'ascii_armor=0'}"] ||= []) << [msize, ciphertext.length / msg.length.to_f]
28
28
  end
29
29
  end
30
30
 
@@ -34,48 +34,48 @@ class Akero
34
34
  def b_timing
35
35
  puts "Running timing benchmark..."
36
36
 
37
- msg_sizes = (4..18).map{|x| 2**x}
38
- key_sizes = [2048, 4096]
37
+ msg_sizes = (8..18).map{|x| 2**x}
38
+ modes = [[2048, false], [2048, true]]
39
39
 
40
40
  rnd = Random.new
41
41
 
42
42
  rounds = 50
43
43
  results = []
44
- key_sizes.each do |ksize|
45
- results << B.enchmark("ENCRYPT #{ksize} bits", :rounds => rounds, :compare => :mean) do
46
- alice = Akero.new(ksize)
47
- bob = Akero.new(ksize)
44
+ modes.each do |mode|
45
+ results << B.enchmark("ENCRYPT #{mode[0]} bits, ascii_armor=#{mode[1]?1:0}", :rounds => rounds, :compare => :mean) do
46
+ alice = Akero.new(mode[0])
47
+ bob = Akero.new(mode[0])
48
48
  msg_sizes.each_with_index do |msize, i|
49
49
  msg = rnd.bytes(msize)
50
50
  job "msg_size #{msize}" do
51
- alice.encrypt(bob.public_key, msg)
51
+ alice.encrypt(bob.public_key, msg, mode[1])
52
52
  end
53
53
  end
54
54
  end
55
55
  end
56
56
 
57
- key_sizes.each do |ksize|
58
- results << B.enchmark("SIGN #{ksize} bits", :rounds => rounds, :compare => :mean) do
59
- alice = Akero.new(ksize)
60
- bob = Akero.new(ksize)
57
+ modes.each do |mode|
58
+ results << B.enchmark("DECRYPT #{mode[0]} bits, ascii_armor=#{mode[1]?1:0}", :rounds => rounds, :compare => :mean) do
59
+ alice = Akero.new(mode[0])
60
+ bob = Akero.new(mode[0])
61
61
  msg_sizes.each_with_index do |msize, i|
62
62
  msg = rnd.bytes(msize)
63
+ msg = alice.encrypt(bob.public_key, msg, mode[1])
63
64
  job "msg_size #{msize}" do
64
- alice.sign(msg)
65
+ bob.receive(msg)
65
66
  end
66
67
  end
67
68
  end
68
69
  end
69
70
 
70
- key_sizes.each do |ksize|
71
- results << B.enchmark("DECRYPT #{ksize} bits", :rounds => rounds, :compare => :mean) do
72
- alice = Akero.new(ksize)
73
- bob = Akero.new(ksize)
71
+ modes.each do |mode|
72
+ results << B.enchmark("SIGN #{mode[0]} bits, ascii_armor=#{mode[1]?1:0}", :rounds => rounds, :compare => :mean) do
73
+ alice = Akero.new(mode[0])
74
+ bob = Akero.new(mode[0])
74
75
  msg_sizes.each_with_index do |msize, i|
75
76
  msg = rnd.bytes(msize)
76
- msg = alice.encrypt(bob.public_key, msg)
77
77
  job "msg_size #{msize}" do
78
- bob.receive(msg)
78
+ alice.sign(msg, mode[1])
79
79
  end
80
80
  end
81
81
  end
data/lib/akero/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class Akero
2
- VERSION = "1.0.3"
2
+ VERSION = "1.0.4"
3
3
  end
data/spec/akero_spec.rb CHANGED
@@ -56,145 +56,150 @@ describe Akero do
56
56
  end
57
57
 
58
58
  describe '#sign' do
59
- describe 'return value' do
60
- it "is a String that looks like an Akero signed message" do
61
- plaintext = "Hello world!"
62
- signed_msg = subject.sign(plaintext)
63
- signed_msg.should be_a String
64
- signed_msg.should match /^-----BEGIN #{Akero::PLATE_SIGNED[1]}-----\n/
65
- signed_msg.should match /\n-----END #{Akero::PLATE_SIGNED[1]}-----\n$/
66
- end
67
-
68
- it "contains valid signature" do
69
- plaintext = "Hello world!"
70
- signed_msg = subject.sign(plaintext)
71
- bob = Akero.new
72
- msg = bob.receive(signed_msg)
73
- msg.from.should == subject.id
74
- msg.from_pk.should == subject.public_key
75
- msg.body.should == plaintext
76
- msg.type.should == :signed
59
+ ([true, false]).each do |ascii_armor|
60
+ describe "ascii_armor=#{ascii_armor}" do
61
+ describe 'return value' do
62
+ if ascii_armor
63
+ it "is a String that looks like an Akero signed message" do
64
+ plaintext = "Hello world!"
65
+ signed_msg = subject.sign(plaintext, ascii_armor)
66
+ signed_msg.should be_a String
67
+ signed_msg.should match /^-----BEGIN #{Akero::PLATE_SIGNED[1]}-----\n/
68
+ signed_msg.should match /\n-----END #{Akero::PLATE_SIGNED[1]}-----\n$/
69
+ end
70
+ end
71
+
72
+ it "contains valid signature" do
73
+ plaintext = "Hello world!"
74
+ signed_msg = subject.sign(plaintext, ascii_armor)
75
+ bob = Akero.new
76
+ msg = bob.receive(signed_msg)
77
+ msg.from.should == subject.id
78
+ msg.from_pk.should == subject.public_key
79
+ msg.body.should == plaintext
80
+ msg.type.should == :signed
81
+ end
82
+ end
77
83
  end
78
84
  end
79
85
  end
80
86
 
81
87
  describe '#encrypt' do
82
- describe 'return value' do
83
- it "is a String that looks like an Akero secret message" do
84
- plaintext = "Hello world!"
85
- ciphertext = subject.encrypt(subject.public_key, plaintext)
86
- ciphertext.should be_a String
87
- ciphertext.should match /^-----BEGIN #{Akero::PLATE_CRYPTED[1]}-----\n/
88
- ciphertext.should match /\n-----END #{Akero::PLATE_CRYPTED[1]}-----\n$/
89
- end
90
-
91
- it "contains valid signature" do
92
- plaintext = "Hello world!"
93
- signed_msg = subject.sign(plaintext)
94
- bob = Akero.new
95
- msg = bob.receive(signed_msg)
96
- msg.from == subject.id
97
- msg.from_pk.should == subject.public_key
98
- msg.body.should == plaintext
99
- msg.type.should == :signed
100
- end
101
-
102
- it "raises RuntimeError on invalid recipient (invalid public key)" do
103
- lambda {
104
- msg = "Hello world!"
105
- ciphertext = subject.encrypt([subject.public_key, 'foo'], msg)
106
- }.should raise_error RuntimeError, Akero::ERR_INVALID_RECIPIENT_CERT
107
- end
108
-
109
- it "raises RuntimeError on invalid recipient (wrong type)" do
110
- lambda {
111
- msg = "Hello world!"
112
- ciphertext = subject.encrypt([subject.public_key, 42], msg)
113
- }.should raise_error RuntimeError, Akero::ERR_INVALID_RECIPIENT
114
- end
115
-
116
- it "raises RuntimeError when message is not String" do
117
- lambda {
118
- msg = "Hello world!"
119
- ciphertext = subject.encrypt(subject.public_key, 42)
120
- }.should raise_error RuntimeError, Akero::ERR_MSG_NOT_STRING_NOR_PKCS7
88
+ ([true, false]).each do |ascii_armor|
89
+ describe "ascii_armor=#{ascii_armor}" do
90
+ describe 'return value' do
91
+ if ascii_armor
92
+ it "is a String that looks like an Akero secret message" do
93
+ plaintext = "Hello world!"
94
+ ciphertext = subject.encrypt(subject.public_key, plaintext, ascii_armor)
95
+ ciphertext.should be_a String
96
+ ciphertext.should match /^-----BEGIN #{Akero::PLATE_CRYPTED[1]}-----\n/
97
+ ciphertext.should match /\n-----END #{Akero::PLATE_CRYPTED[1]}-----\n$/
98
+ end
99
+ end
100
+
101
+ it "raises RuntimeError on invalid recipient (invalid public key)" do
102
+ lambda {
103
+ msg = "Hello world!"
104
+ ciphertext = subject.encrypt([subject.public_key, 'foo'], msg)
105
+ }.should raise_error RuntimeError, Akero::ERR_INVALID_RECIPIENT_CERT
106
+ end
107
+
108
+ it "raises RuntimeError on invalid recipient (wrong type)" do
109
+ lambda {
110
+ msg = "Hello world!"
111
+ ciphertext = subject.encrypt([subject.public_key, 42], msg)
112
+ }.should raise_error RuntimeError, Akero::ERR_INVALID_RECIPIENT
113
+ end
114
+
115
+ it "raises RuntimeError when message is not String" do
116
+ lambda {
117
+ msg = "Hello world!"
118
+ ciphertext = subject.encrypt(subject.public_key, 42)
119
+ }.should raise_error RuntimeError, Akero::ERR_MSG_NOT_STRING_NOR_PKCS7
120
+ end
121
+ end
121
122
  end
122
123
  end
123
124
  end
124
125
 
125
126
  describe '#receive' do
126
- it "decrypts message that was encrypted for self" do
127
- plaintext = "Hello world!"
128
- ciphertext = subject.encrypt(subject.public_key, plaintext)
129
- msg = subject.receive(ciphertext)
130
- msg.body.should == plaintext
131
- msg.type.should == :encrypted
132
- end
133
-
134
- it "decrypts message that was encrypted for self and other recipients" do
135
- plaintext = "Hello world!"
136
- alice = Akero.new
137
- bob = Akero.new
138
- ciphertext = subject.encrypt([alice.public_key, subject.public_key, bob.public_key], plaintext)
139
- msg = subject.receive(ciphertext)
140
- msg.body.should == plaintext
141
- msg.type.should == :encrypted
142
- end
143
-
144
- it "fails to decrypt message that was encrypted only for other recipients" do
145
- lambda {
146
- plaintext = "Hello world!"
147
- alice = Akero.new
148
- bob = Akero.new
149
- ciphertext = subject.encrypt([alice.public_key, bob.public_key], plaintext)
150
- msg = subject.receive(ciphertext)
151
- msg.body.should == plaintext
152
- msg.type.should == :encrypted
153
- }.should raise_error RuntimeError, Akero::ERR_DECRYPT
154
- end
155
-
156
- it "extracts signature from signed message" do
157
- plaintext = "Hello world!"
158
- alice = Akero.new
159
- signed_msg = subject.sign(plaintext)
160
- msg = alice.receive(signed_msg)
161
- msg.body.should == plaintext
162
- msg.type.should == :signed
163
- end
164
-
165
- it "raises RuntimeError on invalid message" do
166
- lambda {
167
- subject.receive("foobar")
168
- }.should raise_error RuntimeError #, Akero::ERR_MSG_MALFORMED_ENV
169
- end
170
-
171
- it "raises RuntimeError when inner does not match outer signature" do
172
- lambda {
173
- oscar = Akero.new
174
- raw_key = subject.send(:instance_variable_get, '@cert')
175
- a = subject.send(:_encrypt, [raw_key], subject.send(:_sign, 'foobar'))
176
- b = oscar.send(:_sign, a).to_s
177
- c = Akero.replate(b, Akero::PLATE_CRYPTED)
178
- subject.receive(c)
179
- }.should raise_error RuntimeError, Akero::ERR_MSG_CORRUPT_CERT
180
- end
181
-
182
- it "raises RuntimeError on malformed inner message" do
183
- lambda {
184
- key, cert = subject.send(:generate_keypair, 1024)
185
- env = OpenSSL::PKCS7::sign(cert, key, 0xff.chr, [], OpenSSL::PKCS7::BINARY)
186
- broken_msg = Akero.replate(env.to_s, Akero::PLATE_CRYPTED)
187
- subject.receive(broken_msg)
188
- }.should raise_error RuntimeError, Akero::ERR_MSG_MALFORMED_BODY
189
- end
190
-
191
- it "raises RuntimeError on unsigned message" do
192
- lambda {
193
- raw_key = subject.send(:instance_variable_get, '@cert')
194
- env = OpenSSL::PKCS7::encrypt([raw_key], 'foobar', OpenSSL::Cipher::new("AES-256-CFB"), OpenSSL::PKCS7::BINARY)
195
- broken_msg = Akero.replate(env.to_s, Akero::PLATE_CRYPTED)
196
- subject.receive(broken_msg)
197
- }.should raise_error RuntimeError, Akero::ERR_MSG_TOO_MANY_SIGNERS
127
+ ([true, false]).each do |ascii_armor|
128
+ describe "ascii_armor=#{ascii_armor}" do
129
+ it "decrypts message that was encrypted for self" do
130
+ plaintext = "Hello world!"
131
+ ciphertext = subject.encrypt(subject.public_key, plaintext, ascii_armor)
132
+ msg = subject.receive(ciphertext)
133
+ msg.body.should == plaintext
134
+ msg.type.should == :encrypted
135
+ end
136
+
137
+ it "decrypts message that was encrypted for self and other recipients" do
138
+ plaintext = "Hello world!"
139
+ alice = Akero.new
140
+ bob = Akero.new
141
+ ciphertext = subject.encrypt([alice.public_key, subject.public_key, bob.public_key], plaintext, ascii_armor)
142
+ msg = subject.receive(ciphertext)
143
+ msg.body.should == plaintext
144
+ msg.type.should == :encrypted
145
+ end
146
+
147
+ it "fails to decrypt message that was encrypted only for other recipients" do
148
+ lambda {
149
+ plaintext = "Hello world!"
150
+ alice = Akero.new
151
+ bob = Akero.new
152
+ ciphertext = subject.encrypt([alice.public_key, bob.public_key], plaintext, ascii_armor)
153
+ msg = subject.receive(ciphertext)
154
+ msg.body.should == plaintext
155
+ msg.type.should == :encrypted
156
+ }.should raise_error RuntimeError, Akero::ERR_DECRYPT
157
+ end
158
+
159
+ it "extracts signature from signed message" do
160
+ plaintext = "Hello world!"
161
+ alice = Akero.new
162
+ signed_msg = subject.sign(plaintext, ascii_armor)
163
+ msg = alice.receive(signed_msg)
164
+ msg.body.should == plaintext
165
+ msg.type.should == :signed
166
+ end
167
+
168
+ it "raises RuntimeError on invalid message" do
169
+ lambda {
170
+ subject.receive("foobar")
171
+ }.should raise_error RuntimeError #, Akero::ERR_MSG_MALFORMED_ENV
172
+ end
173
+
174
+ it "raises RuntimeError when payload does not match envelope signature" do
175
+ lambda {
176
+ oscar = Akero.new
177
+ raw_key = subject.send(:instance_variable_get, '@cert')
178
+ a = subject.send(:_encrypt, [raw_key], subject.send(:_sign, 'foobar'))
179
+ b = oscar.send(:_sign, a)
180
+ c = ascii_armor ? Akero.replate(b.to_s, Akero::PLATE_CRYPTED) : b.to_der
181
+ subject.receive(c)
182
+ }.should raise_error RuntimeError, Akero::ERR_MSG_CORRUPT_CERT
183
+ end
184
+
185
+ it "raises RuntimeError on malformed inner message" do
186
+ lambda {
187
+ key, cert = subject.send(:generate_keypair, 1024)
188
+ env = OpenSSL::PKCS7::sign(cert, key, 0xff.chr, [], OpenSSL::PKCS7::BINARY)
189
+ broken_msg = Akero.replate(env.to_s, Akero::PLATE_CRYPTED)
190
+ subject.receive(broken_msg)
191
+ }.should raise_error RuntimeError, Akero::ERR_MSG_MALFORMED_BODY
192
+ end
193
+
194
+ it "raises RuntimeError on unsigned message" do
195
+ lambda {
196
+ raw_key = subject.send(:instance_variable_get, '@cert')
197
+ env = OpenSSL::PKCS7::encrypt([raw_key], 'foobar', OpenSSL::Cipher::new("AES-256-CFB"), OpenSSL::PKCS7::BINARY)
198
+ broken_msg = Akero.replate(env.to_s, Akero::PLATE_CRYPTED)
199
+ subject.receive(broken_msg)
200
+ }.should raise_error RuntimeError, Akero::ERR_MSG_TOO_MANY_SIGNERS
201
+ end
202
+ end
198
203
  end
199
204
  end
200
205
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: akero
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -190,18 +190,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
190
190
  - - ! '>='
191
191
  - !ruby/object:Gem::Version
192
192
  version: '0'
193
- segments:
194
- - 0
195
- hash: 1654579781693310372
196
193
  required_rubygems_version: !ruby/object:Gem::Requirement
197
194
  none: false
198
195
  requirements:
199
196
  - - ! '>='
200
197
  - !ruby/object:Gem::Version
201
198
  version: '0'
202
- segments:
203
- - 0
204
- hash: 1654579781693310372
205
199
  requirements: []
206
200
  rubyforge_project:
207
201
  rubygems_version: 1.8.23