Skip to content

Commit 4135cf4

Browse files
committed
Added ASN1 visitors: base, mapping, and validation with specs. #LLM
LLM based addition that creates a visitor pattern (allowing a DER / ASN1 structure like much of Apple formats are) to be handled in a map/reduce and recursive way.
1 parent 48d7b33 commit 4135cf4

27 files changed

Lines changed: 1758 additions & 25 deletions

Gemfile.lock

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ PATH
1111
lzfse
1212
lzss
1313
plist
14+
rasn1
1415
ruby-lzma
1516
ruby-macho
1617
rubyzip
@@ -223,6 +224,8 @@ GEM
223224
racc (1.8.1)
224225
rainbow (3.1.1)
225226
rake (13.4.2)
227+
rasn1 (0.16.3)
228+
strptime (~> 0.2.5)
226229
rb-fsevent (0.11.2)
227230
rb-inotify (0.11.1)
228231
ffi (~> 1.0)
@@ -332,6 +335,7 @@ GEM
332335
strscan (>= 1.0.0)
333336
terminal-table (>= 2, < 5)
334337
uri (>= 0.12.0)
338+
strptime (0.2.5)
335339
strscan (3.1.8)
336340
terminal-table (3.0.2)
337341
unicode-display_width (>= 1.1.1, < 3)
@@ -531,6 +535,7 @@ CHECKSUMS
531535
racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
532536
rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
533537
rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
538+
rasn1 (0.16.3) sha256=56ed058761a1738921879239f2945d3163c2b1b2ef5d44b92c2ecde1a0eab3ff
534539
rb-fsevent (0.11.2) sha256=43900b972e7301d6570f64b850a5aa67833ee7d87b458ee92805d56b7318aefe
535540
rb-inotify (0.11.1) sha256=a0a700441239b0ff18eb65e3866236cd78613d6b9f78fea1f9ac47a85e47be6e
536541
rbi (0.4.3) sha256=cc090ae62c3246412b992954f54077d6046c9b04f1537a4d24bfae8714503eac
@@ -572,6 +577,7 @@ CHECKSUMS
572577
sorbet-static-and-runtime (0.6.13409) sha256=81841ba616bcfc473add238c7a9e2ee1693ee91706c6018557f02074357aa1e0
573578
spoom (1.8.7) sha256=81960502cdf23aa991f015988aa5dd43325e23ae4318b8e00d541299cbdb70f6
574579
steep (2.0.0) sha256=6eb0ecc09637bbb54f0a5f2cf63daea6d3208ccace64b4f1107d976333605c30
580+
strptime (0.2.5) sha256=98ed77ff7717a47387ba473614f478e78b162d70a64072fd71d54f547e079af9
575581
strscan (3.1.8) sha256=aae2db611a225559f21ffbb71765c9a4e60fd262534a9ea84f4f11c7f32f679e
576582
terminal-table (3.0.2) sha256=f951b6af5f3e00203fb290a669e0a85c5dd5b051b3b023392ccfd67ba5abae91
577583
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73

Rakefile

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,10 @@
22

33
Rake.add_rakelib 'tasks'
44

5-
6-
75
desc 'Default task to run with no specification'
86
task default: :spec
97

108
desc 'Build environment by loading the gem'
119
task :environment do
1210
require_relative 'lib/mootool'
1311
end
14-
15-
16-
17-
18-

lib/mootool.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
require 'net/http'
1616
require 'fileutils'
1717
require 'apple_data'
18+
require 'rasn1'
1819

1920
require 'zeitwerk'
2021

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
require 'openssl'
4+
5+
module OpenSSL
6+
module ASN1
7+
class ASN1Data
8+
# Returns true if this ASN1 object uses a PRIVATE tag class.
9+
#
10+
# @return [Boolean]
11+
def private_tag?
12+
tag_class == :PRIVATE
13+
end
14+
15+
# Returns true if this ASN1 object uses a CONTEXT_SPECIFIC tag class.
16+
#
17+
# @return [Boolean]
18+
def context_specific?
19+
tag_class == :CONTEXT_SPECIFIC
20+
end
21+
22+
# Returns true if this ASN1 object uses a UNIVERSAL tag class.
23+
#
24+
# @return [Boolean]
25+
def universal?
26+
tag_class == :UNIVERSAL
27+
end
28+
29+
# Returns true if this ASN1 object is a Constructive (Sequence, Set, or tagged constructed).
30+
#
31+
# @return [Boolean]
32+
def constructive?
33+
is_a?(OpenSSL::ASN1::Constructive)
34+
end
35+
36+
# Returns the tag value as a 4CC symbol when applicable (PRIVATE tags).
37+
#
38+
# @return [Symbol, Integer] The 4CC symbol or raw tag integer.
39+
def tag_label
40+
if private_tag? && tag.respond_to?(:to_4cc)
41+
tag.to_4cc
42+
else
43+
tag
44+
end
45+
end
46+
end
47+
end
48+
end

lib/mootool/config/initializers/inflections.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@
1717
inflect.acronym 'DWARF'
1818
inflect.acronym 'ASN1'
1919
inflect.acronym 'RSA'
20+
inflect.acronym 'RASN1'
21+
inflect.acronym 'SSL'
2022
end

lib/mootool/helpers/img4.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ module IMG4
1919

2020
# Tags that require special decoding logic
2121
DECODE_TAGS = parse_4cc(
22-
%w[prid time clid]
22+
%w[prid time clid FSCl]
2323
)
2424

2525
# Tags containing raw octet strings (often digests or IDs)
@@ -39,7 +39,7 @@ module IMG4
3939
smb0 auxi wmac smb1 smb2 upcl udid seid ESEC BNCH EPRO DSEC DPRO smb5 ronh AMNM trpk faic augs inst
4040
prid spih hrlp stng tbms vnum clas cnch fchp ndom pave styp type DGST EPRO ESEC CEPO SDOM SDOM BNCH
4141
EKEY CSEC CPRO BORD CHIP ECID uidm rpnh esdm apmv srvn eg0n prtp oppd sdkp snon snuf lpnh tatp tagt
42-
tstp love kuid vuid rolp nish lobo nsih bmac faus fsca iuos rfcg esic epse]
42+
tstp love kuid vuid rolp nish lobo nsih bmac faus fsca iuos rfcg esic epse FSC2 iCCl MSRk FSCl hop0]
4343
)
4444

4545
# Tags identifying firmware entries
@@ -50,7 +50,7 @@ module IMG4
5050
pmpf rans rcio rdc2 rdcp rdtr recm rfts rkrn sptm rlg1 rlg2 rlgo bstc chg0 chg1 ciof stg1 csys dtre
5151
dcp2 dcpf isys dven ftap ftsp gfxf glyP ibdt ibec ibot ibss illb ispf ipdf rfta krnl logo msys mtfw
5252
mtpf pmcf pmpf rans rcio rdc2 rdcp rdtr recm rfts rkrn sptm rlg1 rlg2 rlgo rosi rsep tsep rspt rtmu
53-
rtrx sepi siof lpol trxm trst tmuf bsys ADCL cfel hmmr pert phlt rbmt diag]
53+
rtrx sepi siof lpol trxm trst tmuf bsys ADCL cfel hmmr pert phlt rbmt diag FSC2 iCCl MSRk]
5454
)
5555

5656
# Mapping of IMG4 algorithm IDs to their Symbolic names

lib/mootool/models/decompressor.rb

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,6 @@ def parse_based_on_hint(value, hint)
132132
}
133133
when :scrt
134134
Models::Certificate.new(OpenSSL::X509::Certificate.new(value))
135-
when :FSC2
136-
@constructed.map do |item|
137-
case item
138-
when Integer
139-
item.to_4cc
140-
when Hash
141-
item.transform_keys(&:to_4cc)
142-
end
143-
end
144135
else
145136
{ hint => construct(@asn1) }
146137
end
@@ -179,7 +170,7 @@ def extract_to(path)
179170
def to_tree
180171
node = Helpers::TreeNode.new('Decompressor')
181172

182-
node.children << Helpers::TreeNode.new("Length: #{@value.size.ai}")
173+
node.children << Helpers::TreeNode.new("Length: #{@value&.size.ai}")
183174
node.children << Helpers::TreeNode.new('Hash', [Helpers::TreeNode.new(to_hash(@hash))])
184175
node.children << Helpers::TreeNode.new("Encoding: #{@compression.ai}") if @compression
185176

lib/mootool/models/descriptor_result.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ def initialize(key, string_name)
1818
@string_name = string_name
1919
end
2020

21+
def inspect
22+
@string_name.blank? ? @key.ai : "#{@key.ai}:#{string_name.ai}"
23+
end
24+
2125
# Compares this descriptor with another
2226
#
2327
# @param other [DescriptorResult, String, Symbol] The object to compare with.

lib/mootool/models/img4/img4_payload.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,10 @@ def parse_keybag(input)
7474
# @return [Hash] A validation status hash with :valid and :hash keys.
7575
def validate(manifest)
7676
firmware_tag = manifest.firmware_tag(@type)
77+
return nil unless firmware_tag
7778

7879
match = hashes.select do |hash|
80+
puts(firmware_tag.ai) if firmware_tag.is_a? Array
7981
hash == firmware_tag.digest
8082
end
8183
@validated = {

lib/mootool/visitors.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# frozen_string_literal: true
2+
3+
module MooTool
4+
# Visitor pattern implementations for traversing ASN1 structures.
5+
#
6+
# Provides a base visitor with depth and parent tracking, along with
7+
# concrete visitors for mapping ASN1 to native Ruby types and for
8+
# validating structures against RASN1 models.
9+
#
10+
# Supports both OpenSSL::ASN1 and RASN1::Types nodes via the
11+
# {MooTool::Visitors::Adapters} adapter layer.
12+
module Visitors
13+
end
14+
end

0 commit comments

Comments
 (0)