krypt 0.0.1
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/LICENSE +20 -0
- data/README.md +82 -0
- data/lib/krypt.rb +49 -0
- data/lib/krypt/asn1.rb +3 -0
- data/lib/krypt/asn1/common.rb +96 -0
- data/lib/krypt/asn1/template.rb +257 -0
- data/lib/krypt/codec.rb +57 -0
- data/lib/krypt/codec/base64.rb +140 -0
- data/lib/krypt/codec/base_codec.rb +36 -0
- data/lib/krypt/codec/hex.rb +122 -0
- data/lib/krypt/digest.rb +112 -0
- data/lib/krypt/hmac.rb +69 -0
- data/lib/krypt/pkcs5.rb +1 -0
- data/lib/krypt/pkcs5/pbkdf2.rb +41 -0
- data/lib/krypt/provider.rb +35 -0
- data/lib/krypt/x509.rb +3 -0
- data/lib/krypt/x509/certificate.rb +36 -0
- data/lib/krypt/x509/common.rb +41 -0
- data/lib/krypt/x509/crl.rb +33 -0
- data/lib/krypt_missing.rb +32 -0
- data/spec/krypt-core/MEMO.txt +85 -0
- data/spec/krypt-core/asn1/asn1_bit_string_spec.rb +475 -0
- data/spec/krypt-core/asn1/asn1_boolean_spec.rb +392 -0
- data/spec/krypt-core/asn1/asn1_constants_spec.rb +71 -0
- data/spec/krypt-core/asn1/asn1_data_spec.rb +1153 -0
- data/spec/krypt-core/asn1/asn1_end_of_contents_spec.rb +133 -0
- data/spec/krypt-core/asn1/asn1_enumerated_spec.rb +458 -0
- data/spec/krypt-core/asn1/asn1_generalized_time_spec.rb +492 -0
- data/spec/krypt-core/asn1/asn1_integer_spec.rb +557 -0
- data/spec/krypt-core/asn1/asn1_null_spec.rb +360 -0
- data/spec/krypt-core/asn1/asn1_object_id_spec.rb +495 -0
- data/spec/krypt-core/asn1/asn1_octet_string_spec.rb +456 -0
- data/spec/krypt-core/asn1/asn1_parser_spec.rb +503 -0
- data/spec/krypt-core/asn1/asn1_pem_spec.rb +282 -0
- data/spec/krypt-core/asn1/asn1_sequence_spec.rb +637 -0
- data/spec/krypt-core/asn1/asn1_set_spec.rb +795 -0
- data/spec/krypt-core/asn1/asn1_utc_time_spec.rb +495 -0
- data/spec/krypt-core/asn1/asn1_utf8_string_spec.rb +404 -0
- data/spec/krypt-core/asn1/resources.rb +53 -0
- data/spec/krypt-core/base64/base64_spec.rb +97 -0
- data/spec/krypt-core/digest/digest_spec.rb +707 -0
- data/spec/krypt-core/hex/hex_spec.rb +102 -0
- data/spec/krypt-core/pem/pem_decode_spec.rb +235 -0
- data/spec/krypt-core/resources.rb +1 -0
- data/spec/krypt-core/template/template_choice_parse_spec.rb +289 -0
- data/spec/krypt-core/template/template_dsl_spec.rb +351 -0
- data/spec/krypt-core/template/template_seq_of_parse_spec.rb +64 -0
- data/spec/krypt-core/template/template_seq_parse_spec.rb +1241 -0
- data/spec/krypt/codec/base64_decoder_spec.rb +94 -0
- data/spec/krypt/codec/base64_encoder_spec.rb +94 -0
- data/spec/krypt/codec/base64_mixed_spec.rb +16 -0
- data/spec/krypt/codec/hex_decoder_spec.rb +94 -0
- data/spec/krypt/codec/hex_encoder_spec.rb +94 -0
- data/spec/krypt/codec/hex_mixed_spec.rb +17 -0
- data/spec/krypt/codec/identity_shared.rb +119 -0
- data/spec/krypt/hmac/hmac_spec.rb +311 -0
- data/spec/krypt/pkcs5/pbkdf2_spec.rb +79 -0
- data/spec/krypt/provider/provider_spec.rb +83 -0
- data/spec/res/ca-bundle.crt +11758 -0
- data/spec/res/certificate.cer +0 -0
- data/spec/res/certificate.pem +20 -0
- data/spec/res/multiple_certs.pem +60 -0
- data/spec/resources.rb +66 -0
- data/test/helper.rb +8 -0
- data/test/res/certificate.cer +0 -0
- data/test/resources.rb +48 -0
- data/test/scratch.rb +28 -0
- data/test/test_krypt_asn1.rb +119 -0
- data/test/test_krypt_parser.rb +331 -0
- metadata +134 -0
@@ -0,0 +1,133 @@
|
|
1
|
+
# encoding: US-ASCII
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'krypt'
|
5
|
+
require 'openssl'
|
6
|
+
require_relative './resources'
|
7
|
+
|
8
|
+
describe Krypt::ASN1::EndOfContents do
|
9
|
+
include Krypt::ASN1::Resources
|
10
|
+
|
11
|
+
let(:mod) { Krypt::ASN1 }
|
12
|
+
let(:klass) { mod::EndOfContents }
|
13
|
+
let(:decoder) { mod }
|
14
|
+
let(:asn1error) { mod::ASN1Error }
|
15
|
+
|
16
|
+
# For test against OpenSSL
|
17
|
+
#
|
18
|
+
#let(:mod) { OpenSSL::ASN1 }
|
19
|
+
#let(:klass) { mod::EndOfContent }
|
20
|
+
|
21
|
+
describe '#new' do
|
22
|
+
context 'constructs without value' do
|
23
|
+
subject { klass.new }
|
24
|
+
|
25
|
+
its(:tag) { should == Krypt::ASN1::END_OF_CONTENTS }
|
26
|
+
its(:tag_class) { should == :UNIVERSAL }
|
27
|
+
its(:value) { should == nil } # TODO: ossl returns ''
|
28
|
+
its(:infinite_length) { should == false }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'constructs with nil' do
|
32
|
+
subject { klass.new(nil) }
|
33
|
+
|
34
|
+
its(:tag) { should == Krypt::ASN1::END_OF_CONTENTS }
|
35
|
+
its(:tag_class) { should == :UNIVERSAL }
|
36
|
+
its(:value) { should == nil }
|
37
|
+
its(:infinite_length) { should == false }
|
38
|
+
end
|
39
|
+
|
40
|
+
it "only accepts nil as the value argument" do
|
41
|
+
-> { klass.new(1) }.should raise_error(ArgumentError)
|
42
|
+
end
|
43
|
+
|
44
|
+
context "does not accept tag and tag_class arguments" do
|
45
|
+
it { -> { klass.new(nil, 0) }.should raise_error(ArgumentError) }
|
46
|
+
it { -> { klass.new(nil, 0, :UNIVERSAL) }.should raise_error(ArgumentError) }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'accessors' do
|
51
|
+
describe '#value' do
|
52
|
+
subject { o = klass.new(nil); o.value = value; o }
|
53
|
+
|
54
|
+
context 'accepts nil' do
|
55
|
+
let(:value) { nil }
|
56
|
+
its(:value) { should == nil }
|
57
|
+
end
|
58
|
+
|
59
|
+
it "accepts objects other than nil as the value argument, but raises on encoding" do
|
60
|
+
asn1 = klass.new
|
61
|
+
asn1.value = 1
|
62
|
+
-> { asn1.to_der }.should raise_error asn1error
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#to_der' do
|
68
|
+
context 'encodes without value' do
|
69
|
+
subject { klass.new.to_der }
|
70
|
+
it { should == "\x00\x00" }
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'encodes a given value' do
|
74
|
+
subject { klass.new(nil).to_der }
|
75
|
+
it { should == "\x00\x00" }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'encodes values set via accessors' do
|
79
|
+
subject {
|
80
|
+
o = klass.new(nil)
|
81
|
+
o.value = nil
|
82
|
+
o.to_der
|
83
|
+
}
|
84
|
+
|
85
|
+
it { should == "\x00\x00" }
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#encode_to' do
|
90
|
+
context 'encodes to an IO' do
|
91
|
+
subject { klass.new(value).encode_to(io); io }
|
92
|
+
|
93
|
+
context "StringIO" do
|
94
|
+
let(:value) { nil }
|
95
|
+
let(:io) { string_io_object }
|
96
|
+
its(:written_bytes) { should == "\x00\x00" }
|
97
|
+
end
|
98
|
+
|
99
|
+
context "Object responds to :write" do
|
100
|
+
let(:value) { nil }
|
101
|
+
let(:io) { writable_object }
|
102
|
+
its(:written_bytes) { should == "\x00\x00" }
|
103
|
+
end
|
104
|
+
|
105
|
+
context "raise IO error transparently" do
|
106
|
+
let(:value) { nil }
|
107
|
+
let(:io) { io_error_object }
|
108
|
+
it { -> { subject }.should raise_error asn1error }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'returns self' do
|
113
|
+
obj = klass.new(nil)
|
114
|
+
obj.encode_to(string_io_object).should == obj
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'extracted from ASN1.decode' do
|
119
|
+
subject { decoder.decode(der) }
|
120
|
+
|
121
|
+
context 'extracted value' do
|
122
|
+
let(:der) { "\x00\x00" }
|
123
|
+
its(:class) { should == klass }
|
124
|
+
its(:tag) { should == Krypt::ASN1::END_OF_CONTENTS }
|
125
|
+
its(:value) { should == nil }
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'rejects values with a lenght > 0' do
|
129
|
+
let(:der) { "\x00\x01\x00" }
|
130
|
+
it { -> { subject.value }.should raise_error asn1error }
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -0,0 +1,458 @@
|
|
1
|
+
# encoding: US-ASCII
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'krypt'
|
5
|
+
require 'openssl'
|
6
|
+
require_relative './resources'
|
7
|
+
|
8
|
+
describe Krypt::ASN1::Enumerated do
|
9
|
+
include Krypt::ASN1::Resources
|
10
|
+
|
11
|
+
let(:mod) { Krypt::ASN1 }
|
12
|
+
let(:klass) { mod::Enumerated }
|
13
|
+
let(:decoder) { mod }
|
14
|
+
let(:asn1error) { mod::ASN1Error }
|
15
|
+
|
16
|
+
# For test against OpenSSL
|
17
|
+
#
|
18
|
+
#let(:mod) { OpenSSL::ASN1 }
|
19
|
+
#
|
20
|
+
# OpenSSL stub for signature mismatch
|
21
|
+
class OpenSSL::ASN1::Enumerated
|
22
|
+
class << self
|
23
|
+
alias old_new new
|
24
|
+
def new(*args)
|
25
|
+
if args.size > 1
|
26
|
+
args = [args[0], args[1], :IMPLICIT, args[2]]
|
27
|
+
end
|
28
|
+
old_new(*args)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#new' do
|
34
|
+
context 'gets value for construct' do
|
35
|
+
subject { klass.new(value) }
|
36
|
+
|
37
|
+
context 'Integer' do
|
38
|
+
let(:value) { 72 }
|
39
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
40
|
+
its(:tag_class) { should == :UNIVERSAL }
|
41
|
+
its(:value) { should == 72 }
|
42
|
+
its(:infinite_length) { should == false }
|
43
|
+
end
|
44
|
+
|
45
|
+
context '0' do
|
46
|
+
let(:value) { 0 }
|
47
|
+
its(:value) { should == 0 }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'negative Integer' do
|
51
|
+
let(:value) { -72 }
|
52
|
+
its(:value) { should == -72 }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'gets explicit tag number as the 2nd argument' do
|
57
|
+
subject { klass.new(72, tag, :PRIVATE) }
|
58
|
+
|
59
|
+
context 'accepts default tag' do
|
60
|
+
let(:tag) { Krypt::ASN1::ENUMERATED }
|
61
|
+
its(:tag) { should == tag }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'accepts custom tag' do
|
65
|
+
let(:tag) { 14 }
|
66
|
+
its(:tag) { should == tag }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'gets tag class symbol as the 3rd argument' do
|
71
|
+
subject { klass.new(72, Krypt::ASN1::ENUMERATED, tag_class) }
|
72
|
+
|
73
|
+
context 'accepts :UNIVERSAL' do
|
74
|
+
let(:tag_class) { :UNIVERSAL }
|
75
|
+
its(:tag_class) { should == tag_class }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'accepts :APPLICATION' do
|
79
|
+
let(:tag_class) { :APPLICATION }
|
80
|
+
its(:tag_class) { should == tag_class }
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'accepts :CONTEXT_SPECIFIC' do
|
84
|
+
let(:tag_class) { :CONTEXT_SPECIFIC }
|
85
|
+
its(:tag_class) { should == tag_class }
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'accepts :PRIVATE' do
|
89
|
+
let(:tag_class) { :PRIVATE }
|
90
|
+
its(:tag_class) { should == tag_class }
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'accepts :IMPLICIT' do
|
94
|
+
let(:tag_class) { :IMPLICIT }
|
95
|
+
its(:tag_class) { should == tag_class }
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'accepts :EXPLICIT' do
|
99
|
+
let(:tag_class) { :EXPLICIT }
|
100
|
+
its(:tag_class) { should == tag_class }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when the 2nd argument is given but 3rd argument is omitted' do
|
105
|
+
subject { klass.new(72, Krypt::ASN1::ENUMERATED) }
|
106
|
+
its(:tag_class) { should == :CONTEXT_SPECIFIC }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'accessors' do
|
111
|
+
describe '#value' do
|
112
|
+
subject { o = klass.new(nil); o.value = value; o }
|
113
|
+
|
114
|
+
context 'Integer' do
|
115
|
+
let(:value) { 72 }
|
116
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
117
|
+
its(:tag_class) { should == :UNIVERSAL }
|
118
|
+
its(:value) { should == 72 }
|
119
|
+
its(:infinite_length) { should == false }
|
120
|
+
end
|
121
|
+
|
122
|
+
context '0' do
|
123
|
+
let(:value) { 0 }
|
124
|
+
its(:value) { should == 0 }
|
125
|
+
end
|
126
|
+
|
127
|
+
context 'negative Integer' do
|
128
|
+
let(:value) { -72 }
|
129
|
+
its(:value) { should == -72 }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe '#tag' do
|
134
|
+
subject { o = klass.new(nil); o.tag = tag; o }
|
135
|
+
|
136
|
+
context 'accepts default tag' do
|
137
|
+
let(:tag) { Krypt::ASN1::ENUMERATED }
|
138
|
+
its(:tag) { should == tag }
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'accepts custom tag' do
|
142
|
+
let(:tag) { 14 }
|
143
|
+
its(:tag) { should == tag }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe '#tag_class' do
|
148
|
+
subject { o = klass.new(nil); o.tag_class = tag_class; o }
|
149
|
+
|
150
|
+
context 'accepts :UNIVERSAL' do
|
151
|
+
let(:tag_class) { :UNIVERSAL }
|
152
|
+
its(:tag_class) { should == tag_class }
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'accepts :APPLICATION' do
|
156
|
+
let(:tag_class) { :APPLICATION }
|
157
|
+
its(:tag_class) { should == tag_class }
|
158
|
+
end
|
159
|
+
|
160
|
+
context 'accepts :CONTEXT_SPECIFIC' do
|
161
|
+
let(:tag_class) { :CONTEXT_SPECIFIC }
|
162
|
+
its(:tag_class) { should == tag_class }
|
163
|
+
end
|
164
|
+
|
165
|
+
context 'accepts :PRIVATE' do
|
166
|
+
let(:tag_class) { :PRIVATE }
|
167
|
+
its(:tag_class) { should == tag_class }
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'accepts :IMPLICIT' do
|
171
|
+
let(:tag_class) { :IMPLICIT }
|
172
|
+
its(:tag_class) { should == tag_class }
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'accepts :EXPLICIT' do
|
176
|
+
let(:tag_class) { :EXPLICIT }
|
177
|
+
its(:tag_class) { should == tag_class }
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe '#to_der' do
|
183
|
+
context 'encodes a given value' do
|
184
|
+
subject { klass.new(value).to_der }
|
185
|
+
|
186
|
+
context 0 do
|
187
|
+
let(:value) { 0 }
|
188
|
+
it { should == "\x0A\x01\x00" }
|
189
|
+
end
|
190
|
+
|
191
|
+
context 72 do
|
192
|
+
let(:value) { 72 }
|
193
|
+
it { should == "\x0A\x01\x48" }
|
194
|
+
end
|
195
|
+
|
196
|
+
context 127 do
|
197
|
+
let(:value) { 127 }
|
198
|
+
it { should == "\x0A\x01\x7F" }
|
199
|
+
end
|
200
|
+
|
201
|
+
context -128 do
|
202
|
+
let(:value) { -128 }
|
203
|
+
it { should == "\x0A\x01\x80" }
|
204
|
+
end
|
205
|
+
|
206
|
+
context 128 do
|
207
|
+
let(:value) { 128 }
|
208
|
+
it { should == "\x0A\x02\x00\x80" }
|
209
|
+
end
|
210
|
+
|
211
|
+
context -27066 do
|
212
|
+
let(:value) { -27066 }
|
213
|
+
it { should == "\x0A\x02\x96\x46" }
|
214
|
+
end
|
215
|
+
|
216
|
+
context 'max Fixnum on 32bit box' do
|
217
|
+
let(:value) { 2**30-1 }
|
218
|
+
it { should == "\x0A\x04\x3F\xFF\xFF\xFF" }
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'max Fixnum on 64bit box' do
|
222
|
+
let(:value) { 2**62-1 }
|
223
|
+
it { should == "\x0A\x08\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF" }
|
224
|
+
end
|
225
|
+
|
226
|
+
context 'nil' do
|
227
|
+
let(:value) { nil }
|
228
|
+
it { -> { subject }.should raise_error asn1error } # TODO: ossl crashes
|
229
|
+
end
|
230
|
+
|
231
|
+
context 'String' do
|
232
|
+
let(:value) { '123' }
|
233
|
+
it { -> { subject }.should raise_error asn1error }
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context 'encodes tag number' do
|
238
|
+
subject { klass.new(72, tag, :PRIVATE).to_der }
|
239
|
+
|
240
|
+
context 'default tag' do
|
241
|
+
let(:tag) { Krypt::ASN1::ENUMERATED }
|
242
|
+
it { should == "\xCA\x01\x48" }
|
243
|
+
end
|
244
|
+
|
245
|
+
context 'custom tag' do
|
246
|
+
let(:tag) { 14 }
|
247
|
+
it { should == "\xCE\x01\x48" }
|
248
|
+
end
|
249
|
+
|
250
|
+
context 'nil' do
|
251
|
+
let(:tag) { nil }
|
252
|
+
it { -> { subject }.should raise_error asn1error }
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
context 'encodes tag class' do
|
257
|
+
subject { klass.new(72, Krypt::ASN1::ENUMERATED, tag_class).to_der }
|
258
|
+
|
259
|
+
context 'UNIVERSAL' do
|
260
|
+
let(:tag_class) { :UNIVERSAL }
|
261
|
+
it { should == "\x0A\x01\x48" }
|
262
|
+
end
|
263
|
+
|
264
|
+
context 'APPLICATION' do
|
265
|
+
let(:tag_class) { :APPLICATION }
|
266
|
+
it { should == "\x4A\x01\x48" }
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'CONTEXT_SPECIFIC' do
|
270
|
+
let(:tag_class) { :CONTEXT_SPECIFIC }
|
271
|
+
it { should == "\x8A\x01\x48" }
|
272
|
+
end
|
273
|
+
|
274
|
+
context 'PRIVATE' do
|
275
|
+
let(:tag_class) { :PRIVATE }
|
276
|
+
it { should == "\xCA\x01\x48" }
|
277
|
+
end
|
278
|
+
|
279
|
+
context 'IMPLICIT' do
|
280
|
+
let(:tag_class) { :IMPLICIT }
|
281
|
+
it { should == "\x8A\x01\x48" }
|
282
|
+
end
|
283
|
+
|
284
|
+
context 'EXPLICIT' do
|
285
|
+
let(:tag_class) { :EXPLICIT }
|
286
|
+
it { should == "\xAA\x03\x0A\x01\x48" }
|
287
|
+
end
|
288
|
+
|
289
|
+
context nil do
|
290
|
+
let(:tag_class) { nil }
|
291
|
+
it { -> { subject }.should raise_error asn1error } # TODO: ossl does not check nil
|
292
|
+
end
|
293
|
+
|
294
|
+
context :no_such_class do
|
295
|
+
let(:tag_class) { :no_such_class }
|
296
|
+
it { -> { subject }.should raise_error asn1error }
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
context 'encodes values set via accessors' do
|
301
|
+
subject {
|
302
|
+
o = klass.new(nil)
|
303
|
+
o.value = value if defined? value
|
304
|
+
o.tag = tag if defined? tag
|
305
|
+
o.tag_class = tag_class if defined? tag_class
|
306
|
+
o.to_der
|
307
|
+
}
|
308
|
+
|
309
|
+
context 'value: 72' do
|
310
|
+
let(:value) { 72 }
|
311
|
+
it { should == "\x0A\x01\x48" }
|
312
|
+
end
|
313
|
+
|
314
|
+
context 'custom tag' do
|
315
|
+
let(:value) { 72 }
|
316
|
+
let(:tag) { 14 }
|
317
|
+
let(:tag_class) { :PRIVATE }
|
318
|
+
it { should == "\xCE\x01\x48" }
|
319
|
+
end
|
320
|
+
|
321
|
+
context 'tag_class' do
|
322
|
+
let(:value) { 72 }
|
323
|
+
let(:tag_class) { :APPLICATION }
|
324
|
+
it { should == "\x4A\x01\x48" }
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
describe '#encode_to' do
|
330
|
+
context 'encodes to an IO' do
|
331
|
+
subject { klass.new(value).encode_to(io); io }
|
332
|
+
|
333
|
+
context "StringIO" do
|
334
|
+
let(:value) { 72 }
|
335
|
+
let(:io) { string_io_object }
|
336
|
+
its(:written_bytes) { should == "\x0A\x01\x48" }
|
337
|
+
end
|
338
|
+
|
339
|
+
context "Object responds to :write" do
|
340
|
+
let(:value) { 72 }
|
341
|
+
let(:io) { writable_object }
|
342
|
+
its(:written_bytes) { should == "\x0A\x01\x48" }
|
343
|
+
end
|
344
|
+
|
345
|
+
context "raise IO error transparently" do
|
346
|
+
let(:value) { 72 }
|
347
|
+
let(:io) { io_error_object }
|
348
|
+
it { -> { subject }.should raise_error asn1error }
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'returns self' do
|
353
|
+
obj = klass.new(72)
|
354
|
+
obj.encode_to(string_io_object).should == obj
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
describe 'extracted from ASN1.decode' do
|
359
|
+
subject { decoder.decode(der) }
|
360
|
+
|
361
|
+
context 'extracted value' do
|
362
|
+
context 0 do
|
363
|
+
let(:der) { "\x0A\x01\x00" }
|
364
|
+
its(:class) { should == klass }
|
365
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
366
|
+
its(:value) { should == 0 }
|
367
|
+
end
|
368
|
+
|
369
|
+
context 72 do
|
370
|
+
let(:der) { "\x0A\x01\x48" }
|
371
|
+
its(:class) { should == klass }
|
372
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
373
|
+
its(:value) { should == 72 }
|
374
|
+
end
|
375
|
+
|
376
|
+
context 127 do
|
377
|
+
let(:der) { "\x0A\x01\x7F" }
|
378
|
+
its(:class) { should == klass }
|
379
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
380
|
+
its(:value) { should == 127 }
|
381
|
+
end
|
382
|
+
|
383
|
+
context -128 do
|
384
|
+
let(:der) { "\x0A\x01\x80" }
|
385
|
+
its(:class) { should == klass }
|
386
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
387
|
+
its(:value) { should == -128 } # TODO: ossl returns 128 (positive value)
|
388
|
+
end
|
389
|
+
|
390
|
+
context 128 do
|
391
|
+
let(:der) { "\x0A\x02\x00\x80" }
|
392
|
+
its(:class) { should == klass }
|
393
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
394
|
+
its(:value) { should == 128 }
|
395
|
+
end
|
396
|
+
|
397
|
+
context -27066 do
|
398
|
+
let(:der) { "\x0A\x02\x96\x46" }
|
399
|
+
its(:class) { should == klass }
|
400
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
401
|
+
its(:value) { should == -27066 } # TODO: ossl returns 27066 (positive value)
|
402
|
+
end
|
403
|
+
|
404
|
+
context 'max Fixnum on 32bit box' do
|
405
|
+
let(:der) { "\x0A\x04\x3F\xFF\xFF\xFF" }
|
406
|
+
its(:class) { should == klass }
|
407
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
408
|
+
its(:value) { should == 2**30-1 }
|
409
|
+
end
|
410
|
+
|
411
|
+
context 'max Fixnum on 64bit box' do
|
412
|
+
let(:der) { "\x0A\x08\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF" }
|
413
|
+
its(:class) { should == klass }
|
414
|
+
its(:tag) { should == Krypt::ASN1::ENUMERATED }
|
415
|
+
its(:value) { should == 2**62-1 }
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
context 'extracted tag class' do
|
420
|
+
context 'UNIVERSAL' do
|
421
|
+
let(:der) { "\x0A\x02\x00\x80" }
|
422
|
+
its(:tag_class) { should == :UNIVERSAL }
|
423
|
+
end
|
424
|
+
|
425
|
+
context 'APPLICATION' do
|
426
|
+
let(:der) { "\x4A\x02\x00\x80" }
|
427
|
+
its(:tag_class) { should == :APPLICATION }
|
428
|
+
end
|
429
|
+
|
430
|
+
context 'CONTEXT_SPECIFIC' do
|
431
|
+
let(:der) { "\x8A\x02\x00\x80" }
|
432
|
+
its(:tag_class) { should == :CONTEXT_SPECIFIC }
|
433
|
+
end
|
434
|
+
|
435
|
+
context 'PRIVATE' do
|
436
|
+
let(:der) { "\xCA\x02\x00\x80" }
|
437
|
+
its(:tag_class) { should == :PRIVATE }
|
438
|
+
end
|
439
|
+
|
440
|
+
context "setting IMPLICIT will result in CONTEXT_SPECIFIC" do
|
441
|
+
let(:der) { "\x0A\x02\x00\x80" }
|
442
|
+
it do
|
443
|
+
subject.tag_class = :IMPLICIT
|
444
|
+
subject.to_der.should == "\x8A\x02\x00\x80"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
context "setting EXPLICIT will reencode as CONTEXT_SPECIFIC" do
|
449
|
+
let(:der) { "\x0A\x02\x00\x80" }
|
450
|
+
it do
|
451
|
+
subject.tag_class = :EXPLICIT
|
452
|
+
subject.tag = 0
|
453
|
+
subject.to_der.should == "\xA0\x04\x0A\x02\x00\x80"
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|