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.
Files changed (70) hide show
  1. data/LICENSE +20 -0
  2. data/README.md +82 -0
  3. data/lib/krypt.rb +49 -0
  4. data/lib/krypt/asn1.rb +3 -0
  5. data/lib/krypt/asn1/common.rb +96 -0
  6. data/lib/krypt/asn1/template.rb +257 -0
  7. data/lib/krypt/codec.rb +57 -0
  8. data/lib/krypt/codec/base64.rb +140 -0
  9. data/lib/krypt/codec/base_codec.rb +36 -0
  10. data/lib/krypt/codec/hex.rb +122 -0
  11. data/lib/krypt/digest.rb +112 -0
  12. data/lib/krypt/hmac.rb +69 -0
  13. data/lib/krypt/pkcs5.rb +1 -0
  14. data/lib/krypt/pkcs5/pbkdf2.rb +41 -0
  15. data/lib/krypt/provider.rb +35 -0
  16. data/lib/krypt/x509.rb +3 -0
  17. data/lib/krypt/x509/certificate.rb +36 -0
  18. data/lib/krypt/x509/common.rb +41 -0
  19. data/lib/krypt/x509/crl.rb +33 -0
  20. data/lib/krypt_missing.rb +32 -0
  21. data/spec/krypt-core/MEMO.txt +85 -0
  22. data/spec/krypt-core/asn1/asn1_bit_string_spec.rb +475 -0
  23. data/spec/krypt-core/asn1/asn1_boolean_spec.rb +392 -0
  24. data/spec/krypt-core/asn1/asn1_constants_spec.rb +71 -0
  25. data/spec/krypt-core/asn1/asn1_data_spec.rb +1153 -0
  26. data/spec/krypt-core/asn1/asn1_end_of_contents_spec.rb +133 -0
  27. data/spec/krypt-core/asn1/asn1_enumerated_spec.rb +458 -0
  28. data/spec/krypt-core/asn1/asn1_generalized_time_spec.rb +492 -0
  29. data/spec/krypt-core/asn1/asn1_integer_spec.rb +557 -0
  30. data/spec/krypt-core/asn1/asn1_null_spec.rb +360 -0
  31. data/spec/krypt-core/asn1/asn1_object_id_spec.rb +495 -0
  32. data/spec/krypt-core/asn1/asn1_octet_string_spec.rb +456 -0
  33. data/spec/krypt-core/asn1/asn1_parser_spec.rb +503 -0
  34. data/spec/krypt-core/asn1/asn1_pem_spec.rb +282 -0
  35. data/spec/krypt-core/asn1/asn1_sequence_spec.rb +637 -0
  36. data/spec/krypt-core/asn1/asn1_set_spec.rb +795 -0
  37. data/spec/krypt-core/asn1/asn1_utc_time_spec.rb +495 -0
  38. data/spec/krypt-core/asn1/asn1_utf8_string_spec.rb +404 -0
  39. data/spec/krypt-core/asn1/resources.rb +53 -0
  40. data/spec/krypt-core/base64/base64_spec.rb +97 -0
  41. data/spec/krypt-core/digest/digest_spec.rb +707 -0
  42. data/spec/krypt-core/hex/hex_spec.rb +102 -0
  43. data/spec/krypt-core/pem/pem_decode_spec.rb +235 -0
  44. data/spec/krypt-core/resources.rb +1 -0
  45. data/spec/krypt-core/template/template_choice_parse_spec.rb +289 -0
  46. data/spec/krypt-core/template/template_dsl_spec.rb +351 -0
  47. data/spec/krypt-core/template/template_seq_of_parse_spec.rb +64 -0
  48. data/spec/krypt-core/template/template_seq_parse_spec.rb +1241 -0
  49. data/spec/krypt/codec/base64_decoder_spec.rb +94 -0
  50. data/spec/krypt/codec/base64_encoder_spec.rb +94 -0
  51. data/spec/krypt/codec/base64_mixed_spec.rb +16 -0
  52. data/spec/krypt/codec/hex_decoder_spec.rb +94 -0
  53. data/spec/krypt/codec/hex_encoder_spec.rb +94 -0
  54. data/spec/krypt/codec/hex_mixed_spec.rb +17 -0
  55. data/spec/krypt/codec/identity_shared.rb +119 -0
  56. data/spec/krypt/hmac/hmac_spec.rb +311 -0
  57. data/spec/krypt/pkcs5/pbkdf2_spec.rb +79 -0
  58. data/spec/krypt/provider/provider_spec.rb +83 -0
  59. data/spec/res/ca-bundle.crt +11758 -0
  60. data/spec/res/certificate.cer +0 -0
  61. data/spec/res/certificate.pem +20 -0
  62. data/spec/res/multiple_certs.pem +60 -0
  63. data/spec/resources.rb +66 -0
  64. data/test/helper.rb +8 -0
  65. data/test/res/certificate.cer +0 -0
  66. data/test/resources.rb +48 -0
  67. data/test/scratch.rb +28 -0
  68. data/test/test_krypt_asn1.rb +119 -0
  69. data/test/test_krypt_parser.rb +331 -0
  70. metadata +134 -0
@@ -0,0 +1,557 @@
1
+ # encoding: US-ASCII
2
+
3
+ require 'rspec'
4
+ require 'krypt'
5
+ require 'openssl'
6
+ require_relative './resources'
7
+
8
+ describe Krypt::ASN1::Integer do
9
+ include Krypt::ASN1::Resources
10
+
11
+ let(:mod) { Krypt::ASN1 }
12
+ let(:klass) { mod::Integer }
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::Integer
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 'accepts Integer' do
38
+ let(:value) { 72 }
39
+ its(:tag) { should == Krypt::ASN1::INTEGER }
40
+ its(:tag_class) { should == :UNIVERSAL }
41
+ its(:value) { should == 72 }
42
+ its(:infinite_length) { should == false }
43
+ end
44
+
45
+ context 'accepts 0' do
46
+ let(:value) { 0 }
47
+ its(:value) { should == 0 }
48
+ end
49
+
50
+ context 'accepts 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::INTEGER }
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::INTEGER, 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(true, Krypt::ASN1::INTEGER) }
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 'accepts Integer' do
115
+ let(:value) { 72 }
116
+ its(:tag) { should == Krypt::ASN1::INTEGER }
117
+ its(:tag_class) { should == :UNIVERSAL }
118
+ its(:value) { should == 72 }
119
+ its(:infinite_length) { should == false }
120
+ end
121
+
122
+ context 'accepts 0' do
123
+ let(:value) { 0 }
124
+ its(:value) { should == 0 }
125
+ end
126
+
127
+ context 'accepts 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::INTEGER }
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 == "\x02\x01\x00" }
189
+ end
190
+
191
+ context 1 do
192
+ let(:value) { 1 }
193
+ it { should == "\x02\x01\x01" }
194
+ end
195
+
196
+ context -1 do
197
+ let(:value) { -1 }
198
+ it { should == "\x02\x01\xFF" }
199
+ end
200
+
201
+ context 72 do
202
+ let(:value) { 72 }
203
+ it { should == "\x02\x01\x48" }
204
+ end
205
+
206
+ context 127 do
207
+ let(:value) { 127 }
208
+ it { should == "\x02\x01\x7F" }
209
+ end
210
+
211
+ context -128 do
212
+ let(:value) { -128 }
213
+ it { should == "\x02\x01\x80" }
214
+ end
215
+
216
+ context 128 do
217
+ let(:value) { 128 }
218
+ it { should == "\x02\x02\x00\x80" }
219
+ end
220
+
221
+ context -27066 do
222
+ let(:value) { -27066 }
223
+ it { should == "\x02\x02\x96\x46" }
224
+ end
225
+
226
+ context 'max Fixnum on 32bit box' do
227
+ let(:value) { 2**30-1 }
228
+ it { should == "\x02\x04\x3F\xFF\xFF\xFF" }
229
+ end
230
+
231
+ context 'max Fixnum on 64bit box' do
232
+ let(:value) { 2**62-1 }
233
+ it { should == "\x02\x08\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF" }
234
+ end
235
+
236
+ context 'positive Bignum' do
237
+ let(:value) { 2**12345 }
238
+ it { should == "\x02\x82\x06\x08\x02" + "\x00" * 1543 }
239
+ end
240
+
241
+ context 'negative Bignum' do
242
+ let(:value) { -(2**12345) }
243
+ it { should == "\x02\x82\x06\x08\xFE" + "\x00" * 1543 }
244
+ end
245
+
246
+ context 'nil' do
247
+ let(:value) { nil }
248
+ it { -> { subject }.should raise_error asn1error } # TODO: ossl crashes
249
+ end
250
+
251
+ context 'String' do
252
+ let(:value) { '123' }
253
+ it { -> { subject }.should raise_error asn1error }
254
+ end
255
+ end
256
+
257
+ context 'rejects UNIVERSAL tags > 30' do
258
+ it { -> { klass.new(1, 31, :UNIVERSAL).to_der }.should raise_error asn1error }
259
+ end
260
+
261
+ context 'encodes tag number' do
262
+ subject { klass.new(72, tag, :PRIVATE).to_der }
263
+
264
+ context 'default tag' do
265
+ let(:tag) { Krypt::ASN1::INTEGER }
266
+ it { should == "\xC2\x01\x48" }
267
+ end
268
+
269
+ context 'custom tag' do
270
+ let(:tag) { 14 }
271
+ it { should == "\xCE\x01\x48" }
272
+ end
273
+
274
+ context 'nil' do
275
+ let(:tag) { nil }
276
+ it { -> { subject }.should raise_error asn1error }
277
+ end
278
+ end
279
+
280
+ context 'encodes tag class' do
281
+ subject { klass.new(72, Krypt::ASN1::INTEGER, tag_class).to_der }
282
+
283
+ context 'UNIVERSAL' do
284
+ let(:tag_class) { :UNIVERSAL }
285
+ it { should == "\x02\x01\x48" }
286
+ end
287
+
288
+ context 'APPLICATION' do
289
+ let(:tag_class) { :APPLICATION }
290
+ it { should == "\x42\x01\x48" }
291
+ end
292
+
293
+ context 'CONTEXT_SPECIFIC' do
294
+ let(:tag_class) { :CONTEXT_SPECIFIC }
295
+ it { should == "\x82\x01\x48" }
296
+ end
297
+
298
+ context 'PRIVATE' do
299
+ let(:tag_class) { :PRIVATE }
300
+ it { should == "\xC2\x01\x48" }
301
+ end
302
+
303
+ context 'accepts :IMPLICIT' do
304
+ let(:tag_class) { :IMPLICIT }
305
+ it { should == "\x82\x01\x48" }
306
+ end
307
+
308
+ context 'accepts :EXPLICIT' do
309
+ let(:tag_class) { :EXPLICIT }
310
+ it { should == "\xA2\x03\x02\x01\x48" }
311
+ end
312
+
313
+ context nil do
314
+ let(:tag_class) { nil }
315
+ it { -> { subject }.should raise_error asn1error } # TODO: ossl does not check nil
316
+ end
317
+
318
+ context :no_such_class do
319
+ let(:tag_class) { :no_such_class }
320
+ it { -> { subject }.should raise_error asn1error }
321
+ end
322
+ end
323
+
324
+ context 'encodes values set via accessors' do
325
+ subject {
326
+ o = klass.new(nil)
327
+ o.value = value if defined? value
328
+ o.tag = tag if defined? tag
329
+ o.tag_class = tag_class if defined? tag_class
330
+ o.to_der
331
+ }
332
+
333
+ context 'value: 72' do
334
+ let(:value) { 72 }
335
+ it { should == "\x02\x01\x48" }
336
+ end
337
+
338
+ context 'custom tag' do
339
+ let(:value) { 72 }
340
+ let(:tag) { 14 }
341
+ let(:tag_class) { :PRIVATE }
342
+ it { should == "\xCE\x01\x48" }
343
+ end
344
+
345
+ context 'tag_class' do
346
+ let(:value) { 72 }
347
+ let(:tag_class) { :APPLICATION }
348
+ it { should == "\x42\x01\x48" }
349
+ end
350
+ end
351
+ end
352
+
353
+ describe '#encode_to' do
354
+ context 'encodes to an IO' do
355
+ subject { klass.new(value).encode_to(io); io }
356
+
357
+ context "StringIO" do
358
+ let(:value) { 72 }
359
+ let(:io) { string_io_object }
360
+ its(:written_bytes) { should == "\x02\x01\x48" }
361
+ end
362
+
363
+ context "Object responds to :write" do
364
+ let(:value) { 72 }
365
+ let(:io) { writable_object }
366
+ its(:written_bytes) { should == "\x02\x01\x48" }
367
+ end
368
+
369
+ context "raise IO error transparently" do
370
+ let(:value) { 72 }
371
+ let(:io) { io_error_object }
372
+ it { -> { subject }.should raise_error asn1error }
373
+ end
374
+ end
375
+
376
+ it 'returns self' do
377
+ obj = klass.new(72)
378
+ obj.encode_to(string_io_object).should == obj
379
+ end
380
+ end
381
+
382
+ describe 'extracted from ASN1.decode' do
383
+ subject { decoder.decode(der) }
384
+
385
+ context 'extracted value' do
386
+ context 0 do
387
+ let(:der) { "\x02\x01\x00" }
388
+ its(:class) { should == klass }
389
+ its(:tag) { should == Krypt::ASN1::INTEGER }
390
+ its(:value) { should == 0 }
391
+ end
392
+
393
+ context 1 do
394
+ let(:der) { "\x02\x01\x01" }
395
+ its(:class) { should == klass }
396
+ its(:tag) { should == Krypt::ASN1::INTEGER }
397
+ its(:value) { should == 1 }
398
+ end
399
+
400
+ context -1 do
401
+ let(:der) { "\x02\x01\xFF" }
402
+ its(:class) { should == klass }
403
+ its(:tag) { should == Krypt::ASN1::INTEGER }
404
+ its(:value) { should == -1 }
405
+ end
406
+
407
+ context 72 do
408
+ let(:der) { "\x02\x01\x48" }
409
+ its(:class) { should == klass }
410
+ its(:tag) { should == Krypt::ASN1::INTEGER }
411
+ its(:value) { should == 72 }
412
+ end
413
+
414
+ context 127 do
415
+ let(:der) { "\x02\x01\x7F" }
416
+ its(:class) { should == klass }
417
+ its(:tag) { should == Krypt::ASN1::INTEGER }
418
+ its(:value) { should == 127 }
419
+ end
420
+
421
+ context -128 do
422
+ let(:der) { "\x02\x01\x80" }
423
+ its(:class) { should == klass }
424
+ its(:tag) { should == Krypt::ASN1::INTEGER }
425
+ its(:value) { should == -128 }
426
+ end
427
+
428
+ context 128 do
429
+ let(:der) { "\x02\x02\x00\x80" }
430
+ its(:class) { should == klass }
431
+ its(:tag) { should == Krypt::ASN1::INTEGER }
432
+ its(:value) { should == 128 }
433
+ end
434
+
435
+ context 256 do
436
+ let(:der) { "\x02\x02\x01\x00" }
437
+ its(:class) { should == klass }
438
+ its(:tag) { should == Krypt::ASN1::INTEGER }
439
+ its(:value) { should == 256 }
440
+ end
441
+
442
+ context -256 do
443
+ let(:der) { "\x02\x02\xFF\x00" }
444
+ its(:class) { should == klass }
445
+ its(:tag) { should == Krypt::ASN1::INTEGER }
446
+ its(:value) { should == -256 }
447
+ end
448
+
449
+ context -27066 do
450
+ let(:der) { "\x02\x02\x96\x46" }
451
+ its(:class) { should == klass }
452
+ its(:tag) { should == Krypt::ASN1::INTEGER }
453
+ its(:value) { should == -27066 }
454
+ end
455
+
456
+ context 'max Fixnum on 32bit box' do
457
+ let(:der) { "\x02\x04\x3F\xFF\xFF\xFF" }
458
+ its(:class) { should == klass }
459
+ its(:tag) { should == Krypt::ASN1::INTEGER }
460
+ its(:value) { should == 2**30-1 }
461
+ end
462
+
463
+ context 'max Fixnum on 64bit box' do
464
+ let(:der) { "\x02\x08\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF" }
465
+ its(:class) { should == klass }
466
+ its(:tag) { should == Krypt::ASN1::INTEGER }
467
+ its(:value) { should == 2**62-1 }
468
+ end
469
+
470
+ context 'positive Bignum' do
471
+ let(:der) { "\x02\x82\x06\x08\x02" + "\x00" * 1543 }
472
+ its(:class) { should == klass }
473
+ its(:tag) { should == Krypt::ASN1::INTEGER }
474
+ its(:value) { should == 2**12345 }
475
+ end
476
+
477
+ context 'negative Bignum' do
478
+ let(:der) { "\x02\x82\x06\x08\xFE" + "\x00" * 1543 }
479
+ its(:class) { should == klass }
480
+ its(:tag) { should == Krypt::ASN1::INTEGER }
481
+ its(:value) { should == -(2**12345) }
482
+ end
483
+
484
+ context 'positive Bignum 4722366482869645213696' do
485
+ let(:der) { "\x02\x0A\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
486
+ its(:class) { should == klass }
487
+ its(:tag) { should == Krypt::ASN1::INTEGER }
488
+ its(:value) { should == 4722366482869645213696 }
489
+ end
490
+
491
+ context 'negative Bignum -4722366482869645213696' do
492
+ let(:der) { "\x02\x0A\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
493
+ its(:class) { should == klass }
494
+ its(:tag) { should == Krypt::ASN1::INTEGER }
495
+ its(:value) { should == -4722366482869645213696 }
496
+ end
497
+
498
+ context 'positive Bignum 2361183241434822606593' do
499
+ let(:der) { "\x02\x09\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x01" }
500
+ its(:class) { should == klass }
501
+ its(:tag) { should == Krypt::ASN1::INTEGER }
502
+ its(:value) { should == 2361183241434822606593 }
503
+ end
504
+
505
+ context 'negative Bignum -2361183241434822606593' do
506
+ let(:der) { "\x02\x09\x80\x00\x00\x00\x00\x00\x00\x00\xFF" }
507
+ its(:class) { should == klass }
508
+ its(:tag) { should == Krypt::ASN1::INTEGER }
509
+ its(:value) { should == -(2361183241434822606593) }
510
+ end
511
+
512
+ context 'rejects zero length value' do
513
+ let(:der) { "\x02\x00" }
514
+ it { -> { subject.value }.should raise_error asn1error }
515
+ end
516
+ end
517
+
518
+ context 'extracted tag class' do
519
+ context 'UNIVERSAL' do
520
+ let(:der) { "\x02\x01\x80" }
521
+ its(:tag_class) { should == :UNIVERSAL }
522
+ end
523
+
524
+ context 'APPLICATION' do
525
+ let(:der) { "\x42\x01\x80" }
526
+ its(:tag_class) { should == :APPLICATION }
527
+ end
528
+
529
+ context 'CONTEXT_SPECIFIC' do
530
+ let(:der) { "\x82\x01\x80" }
531
+ its(:tag_class) { should == :CONTEXT_SPECIFIC }
532
+ end
533
+
534
+ context 'PRIVATE' do
535
+ let(:der) { "\xC2\x01\x80" }
536
+ its(:tag_class) { should == :PRIVATE }
537
+ end
538
+
539
+ context "setting IMPLICIT will result in CONTEXT_SPECIFIC" do
540
+ let(:der) { "\x02\x01\x80" }
541
+ it do
542
+ subject.tag_class = :IMPLICIT
543
+ subject.to_der.should == "\x82\x01\x80"
544
+ end
545
+ end
546
+
547
+ context "setting EXPLICIT will reencode as CONTEXT_SPECIFIC" do
548
+ let(:der) { "\x02\x01\x80" }
549
+ it do
550
+ subject.tag_class = :EXPLICIT
551
+ subject.tag = 0
552
+ subject.to_der.should == "\xA0\x03\x02\x01\x80"
553
+ end
554
+ end
555
+ end
556
+ end
557
+ end