Module: AppInfo::Helper::Signatures

Included in:
Android::Signature::V2, Android::Signature::V3
Defined in:
lib/app_info/helper/signatures.rb

Overview

Signature Block helper

Instance Method Summary collapse

Instance Method Details

#signature_algorithms(signatures) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/app_info/helper/signatures.rb', line 130

def signature_algorithms(signatures)
  algorithems = []
  loop_length_prefix_io(
    signatures,
    name: 'Signature Algorithms',
    max_bytes: AppInfo::Android::Signature::UINT64_SIZE,
    logger: logger
  ) do |signature|
    algorithm = signature.read(AppInfo::Android::Signature::UINT32_SIZE).unpack('C*')
    digest = algorithm_match(algorithm)
    next unless digest

    signature = length_prefix_block(signature, raw: true)
    algorithems << {
      id: algorithm,
      digest: digest,
      signature: signature
    }
  end

  algorithems
end

#signed_data_certs(io) ⇒ Object



78
79
80
81
82
83
84
# File 'lib/app_info/helper/signatures.rb', line 78

def signed_data_certs(io)
  certificates = []
  loop_length_prefix_io(io, name: 'Certificates', raw: true) do |cert_data|
    certificates << AppInfo::Certificate.parse(cert_data)
  end
  certificates
end

#signed_data_digests(io) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/app_info/helper/signatures.rb', line 86

def signed_data_digests(io)
  content_digests = {}
  loop_length_prefix_io(
    io,
    name: 'Digests',
    max_bytes: AppInfo::Android::Signature::UINT64_SIZE
  ) do |digest|
    algorithm = digest.read(AppInfo::Android::Signature::UINT32_SIZE).unpack('C*')
    digest_name = algorithm_match(algorithm)
    next unless digest_name

    content = length_prefix_block(digest)
    content_digests[digest_name] = {
      id: algorithm,
      content: content
    }
  end

  content_digests
end

#singers_block(block_id) ⇒ Object

Raises:

  • (SecurityError)


71
72
73
74
75
76
# File 'lib/app_info/helper/signatures.rb', line 71

def singers_block(block_id)
  info = AppInfo::Android::Signature::Info.new(@version, @parser, logger)
  raise SecurityError, 'ZIP64 APK not supported' if info.zip64?

  info.signers(block_id)
end

#verify_additional_attrs(attrs, _certs) ⇒ Object

FIXME: this code not work, need fix.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/app_info/helper/signatures.rb', line 108

def verify_additional_attrs(attrs, _certs)
  loop_length_prefix_io(
    attrs, name: 'Additional Attributes', ignore_left_size_precheck: true
  ) do |attr|
    id = attr.read(AppInfo::Android::Signature::UINT32_SIZE)
    logger.debug "ID #{id} / #{id.size} / #{id.unpack('H*')} / #{id.unpack('C*')}"
    if id.unpack('C*') == AppInfo::Helper::Algorithm::SIG_STRIPPING_PROTECTION_ATTR_ID
      offset = attr.size - attr.pos
      if offset < AppInfo::Android::Signature::UINT32_SIZE
        raise SecurityError,
              "V2 Signature Scheme Stripping Protection Attribute value too small. Expected #{UINT32_SIZE} bytes, but found #{offset}"
      end

      # value = attr.read(UINT32_SIZE).unpack1('I')
      if @version == AppInfo::Android::Signature::Version::V3
        raise SecurityError,
              'V2 signature indicates APK is signed using APK Signature Scheme v3, but none was found. Signature stripped?'
      end
    end
  end
end