asn1-diag 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.
- checksums.yaml +7 -0
- data/asn1-diag.gemspec +18 -0
- data/lib/asn1-pure.rb +166 -0
- metadata +73 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 22eab7283eee7b3cee7b2f88ecd035199a16bed9
|
4
|
+
data.tar.gz: 137ab6083224d66c054215f4d8df09b711e37c12
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 86afff5f012d295130a478f49d157fe0770be13fc6c83d64aed044a8a513251d4fdeb6e53e1fa90452ea23a0afc1e848bcd508e874cbc78d23367696d47b3d8b
|
7
|
+
data.tar.gz: 665e01ce13414356ad3e1aa5e248123c2ea3c399bff59b9e8aa4f1fe04ac67926d99d7e19e50470aba16fcff340e4d878fe175d69419584be5780a28bb11e1e6
|
data/asn1-diag.gemspec
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "asn1-diag"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
s.summary = "ASN1 BER/DER diagnostics"
|
5
|
+
s.description = %q{asn1-diag implements some diagnostics for ASN1 BER (X.690) and DER}
|
6
|
+
s.author = "Carsten Bormann"
|
7
|
+
s.email = "cabo@tzi.org"
|
8
|
+
s.license = "Apache-2.0"
|
9
|
+
s.has_rdoc = false
|
10
|
+
s.files = Dir['lib/**/*.rb'] + %w(asn1-diag.gemspec) + Dir['bin/**/*.rb']
|
11
|
+
s.executables = Dir['bin/**/*.rb'].map {|x| File.basename(x)}
|
12
|
+
s.required_ruby_version = '>= 2.4.1'
|
13
|
+
|
14
|
+
s.require_paths = ["lib"]
|
15
|
+
|
16
|
+
s.add_development_dependency 'bundler', '~>1'
|
17
|
+
s.add_dependency 'json'
|
18
|
+
end
|
data/lib/asn1-pure.rb
ADDED
@@ -0,0 +1,166 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
module ASN1
|
4
|
+
class OutOfBytesError < RuntimeError
|
5
|
+
def initialize(bytes)
|
6
|
+
@bytes = bytes
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_s
|
10
|
+
"Out of bytes to decode: #{@bytes}"
|
11
|
+
end
|
12
|
+
attr_reader :bytes
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.encode(d)
|
16
|
+
Buffer.new.add(d).buffer
|
17
|
+
end
|
18
|
+
def self.encode_seq(ds)
|
19
|
+
out = Buffer.new
|
20
|
+
ds.each do |d|
|
21
|
+
out.add(d)
|
22
|
+
end
|
23
|
+
out.buffer
|
24
|
+
end
|
25
|
+
def self.decode(s)
|
26
|
+
Buffer.new(s).decode_item_final
|
27
|
+
end
|
28
|
+
def self.decode_with_rest(s)
|
29
|
+
Buffer.new(s).decode_item_with_rest
|
30
|
+
end
|
31
|
+
def self.decode_seq(s)
|
32
|
+
Buffer.new(s).decode_items
|
33
|
+
end
|
34
|
+
|
35
|
+
class Buffer
|
36
|
+
|
37
|
+
attr_reader :buffer
|
38
|
+
def initialize(s = String.new)
|
39
|
+
@buffer = s
|
40
|
+
@pos = 0
|
41
|
+
end
|
42
|
+
|
43
|
+
def atleast(n)
|
44
|
+
left = @buffer.bytesize - @pos
|
45
|
+
raise OutOfBytesError.new(n - left) if n > left
|
46
|
+
end
|
47
|
+
|
48
|
+
def take(n)
|
49
|
+
opos = @pos
|
50
|
+
@pos += n
|
51
|
+
raise OutOfBytesError.new(@pos - @buffer.bytesize) if @pos > @buffer.bytesize
|
52
|
+
@buffer[opos, n]
|
53
|
+
end
|
54
|
+
|
55
|
+
def decode_sdnv
|
56
|
+
res = 0
|
57
|
+
while (b = take(1).ord
|
58
|
+
res = (res << 7) + (b & 0x7f)
|
59
|
+
(b & 0x80) != 0)
|
60
|
+
;
|
61
|
+
end
|
62
|
+
res
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.oid_print(s)
|
66
|
+
bu = Buffer.new(s)
|
67
|
+
a = []
|
68
|
+
while !bu.done
|
69
|
+
a << bu.decode_sdnv
|
70
|
+
end
|
71
|
+
ia = a[0]
|
72
|
+
ia1 = [a[0]/40, 2].min
|
73
|
+
a[0..0] = [ia1, ia - 40 * ia1]
|
74
|
+
a.join(".")
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.be_decode(s)
|
78
|
+
ret = 0
|
79
|
+
s.each_byte do |b|
|
80
|
+
ret = (ret << 8) + b
|
81
|
+
end
|
82
|
+
ret
|
83
|
+
end
|
84
|
+
define_method :be_decode, &method(:be_decode)
|
85
|
+
|
86
|
+
READABLE = Hash.new {|h, k| [k]}
|
87
|
+
READABLE[[0x30, 0x10]] = :seq
|
88
|
+
READABLE[[0x31, 0x11]] = :set
|
89
|
+
READABLE[[2, 2]] = :int, ->(s) {be_decode(s)}
|
90
|
+
READABLE[[3, 3]] = :bits
|
91
|
+
READABLE[[4, 4]] = :b
|
92
|
+
READABLE[[5, 5]] = :null, ->(s) {:null}
|
93
|
+
READABLE[[6, 6]] = :oid, ->(s) {oid_print(s)}
|
94
|
+
READABLE[[12, 12]] = :u
|
95
|
+
READABLE[[19, 19]] = :s
|
96
|
+
READABLE[[22, 22]] = :ia5
|
97
|
+
READABLE[[23, 23]] = :t # time
|
98
|
+
(0..15).each do |i|
|
99
|
+
READABLE[[0xA0 + i, i]] = :"exp#{i}"
|
100
|
+
end
|
101
|
+
|
102
|
+
def decode_item
|
103
|
+
ib = take(1).ord
|
104
|
+
cons = ib & 0x20
|
105
|
+
tag = decode_sdnv if (tag = ib & 0x1f) == 0x1f
|
106
|
+
case len = take(1).ord
|
107
|
+
when 0..127
|
108
|
+
when 128
|
109
|
+
len = false # indefinite
|
110
|
+
when 255
|
111
|
+
fail "reserved length @pos"
|
112
|
+
else
|
113
|
+
len = be_decode(take(len - 128))
|
114
|
+
end
|
115
|
+
rtag, rproc = READABLE[[ib, tag]]
|
116
|
+
if cons != 0
|
117
|
+
nest = []
|
118
|
+
if len
|
119
|
+
limit = @pos + len
|
120
|
+
while @pos < limit
|
121
|
+
nest << decode_item
|
122
|
+
end
|
123
|
+
else
|
124
|
+
while (a = decode_item
|
125
|
+
if a != [0, 0, ""]
|
126
|
+
nest << a
|
127
|
+
end)
|
128
|
+
;
|
129
|
+
end
|
130
|
+
fail "no indef yet @pos"
|
131
|
+
end
|
132
|
+
fail [@pos, limit] if @pos != limit
|
133
|
+
else
|
134
|
+
nest = take(len)
|
135
|
+
end
|
136
|
+
rproc ? rproc.(nest) : {rtag => nest}
|
137
|
+
end
|
138
|
+
|
139
|
+
def decode_item_final
|
140
|
+
val = decode_item
|
141
|
+
raise "extra bytes follow after a deserialized object" if @pos != @buffer.size
|
142
|
+
val
|
143
|
+
end
|
144
|
+
|
145
|
+
def decode_item_with_rest
|
146
|
+
val = decode_item
|
147
|
+
[val, @buffer[@pos..-1]]
|
148
|
+
end
|
149
|
+
|
150
|
+
def done
|
151
|
+
@pos == buffer.size
|
152
|
+
end
|
153
|
+
|
154
|
+
def decode_items
|
155
|
+
ret = []
|
156
|
+
while @pos != buffer.size
|
157
|
+
ret << decode_item
|
158
|
+
end
|
159
|
+
ret
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: asn1-diag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Carsten Bormann
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-08-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: asn1-diag implements some diagnostics for ASN1 BER (X.690) and DER
|
42
|
+
email: cabo@tzi.org
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- asn1-diag.gemspec
|
48
|
+
- lib/asn1-pure.rb
|
49
|
+
homepage:
|
50
|
+
licenses:
|
51
|
+
- Apache-2.0
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.4.1
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 2.6.11
|
70
|
+
signing_key:
|
71
|
+
specification_version: 4
|
72
|
+
summary: ASN1 BER/DER diagnostics
|
73
|
+
test_files: []
|