#============================================================================
#Name : iadinfo.py
#Part of : Helium
#Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
#All rights reserved.
#This component and the accompanying materials are made available
#under the terms of the License "Eclipse Public License v1.0"
#which accompanies this distribution, and is available
#at the URL "http://www.eclipse.org/legal/epl-v10.html".
#
#Initial Contributors:
#Nokia Corporation - initial contribution.
#
#Contributors:
#
#Description:
#===============================================================================
""" IAD info """
import sys, os
import struct
import zlib
PyASN1Availabe = True
try:
from pyasn1.codec.der import decoder
from pyasn1.type import base
except ImportError:
PyASN1Availabe = False
def _findItem(item, itemParent, index, objectIdentifier):
"""find Item"""
if isinstance(item, base.AbstractSimpleAsn1Item):
if item == objectIdentifier:
return itemParent[index + 1]
else:
for i_item in range(len(item)):
found = _findItem(item[i_item], item, i_item, objectIdentifier)
if found:
return found
def findItem(decodedCert, objectIdentifier):
"""find item"""
return _findItem(decodedCert, None, 0, objectIdentifier)
class CertificateOrganization:
""" This class holds organisation details of certificate issuer or signer """
def __init__(self):
self.commonName = None
self.countryCode = None
self.locality = None
self.state = None
self.street = None
self.organization = None
def parse(self, decodedCert):
"""parse certificate Organisation"""
self.commonName = findItem(decodedCert, (2, 5, 4, 3))
self.countryCode = findItem(decodedCert, (2, 5, 4, 6))
self.locality = findItem(decodedCert, (2, 5, 4, 7))
self.state = findItem(decodedCert, (2, 5, 4, 8))
self.street = findItem(decodedCert, (2, 5, 4, 9))
self.organization = findItem(decodedCert, (2, 5, 4, 10))
def readableStr(self):
"""readable String"""
buf = ""
if self.commonName:
buf += self.commonName.prettyPrint() + "\n"
if self.countryCode:
buf += self.countryCode.prettyPrint() + "\n"
if self.locality:
buf += self.locality.prettyPrint() + "\n"
if self.state:
buf += self.state.prettyPrint() + "\n"
if self.street:
buf += self.street.prettyPrint() + "\n"
if self.organization:
buf += self.organization.prettyPrint()
return buf
class CertificateInfo:
""" This class holds certificate information such as certificate signer and issuer """
def __init__(self):
self.issuer = None
self.signer = None
def parse(self, decodedCert):
"""parse"""
self.issuer = CertificateOrganization()
self.issuer.parse(decodedCert[0][3])
self.signer = CertificateOrganization()
self.signer.parse(decodedCert[0][5])
def readableStr(self):
"""readable String"""
buf = "Signer:\n " + "\n ".join(self.signer.readableStr().split('\n')) + "\n"
buf += "Issuer:\n " + "\n ".join(self.issuer.readableStr().split('\n')) + "\n"
return buf
class SISFileHeader:
""" Class SIS File header """
def __init__(self):
self.uid1 = 0
self.uid2 = 0
self.uid3 = 0
self.uidChecksum = 0
class SISField:
""" Class SIS Field """
def __init__(self):
self.type_ = 0
self.length = None
self.subFields = []
def readFieldLength(self, fileReader):
"""read Field Length"""
length = fileReader.readBytesAsUint(4)
if length & 0x80000000 > 0:
length = length << 32
length |= fileReader.readBytesAsUint(4)
return length
def findField(self, fieldType, startIndex=0):
"""find Field"""
result = None
index = startIndex
for field in self.subFields[startIndex:]:
if field.type_ == fieldType:
result = field
break
index = index + 1
return (result, index)
def readableStr(self):
"""readable String"""
return ""
def traverse(self, handler, depth=0):
""" traverse"""
handler.handleField(self, depth)
for field in self.subFields:
field.traverse(handler, depth + 1)
class SISUnsupportedField(SISField):
""" Class SIS UnsupportedField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialisation From File"""
self.length = self.readFieldLength(fileReader)
fileReader.readPlainBytes(self.length)
class SISStringField(SISField):
""" Class SIS StringField """
def __init__(self):
SISField.__init__(self)
self.data = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
buf = fileReader.readPlainBytes(self.length)
self.data = u""
while len(buf) > 0:
temp = buf[:2]
buf = buf[2:]
self.data += unichr(ord(temp[0]) | ord(temp[1]) << 8)
def readableStr(self):
"""readable String"""
return self.data
class SISArrayField(SISField):
""" Class SIS ArrayField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
type_ = fileReader.readBytesAsInt(4)
l_len = self.length - 4
while l_len > 0:
field = SISFieldTypes[type_]()
field.type_ = type_
field.initFromFile(fileReader)
self.subFields.append(field)
l_len -= field.length + 4 # field length + the length field
padding = fileReader.skipPadding()
l_len -= padding
class SISCompressedField(SISField):
""" Class SIS CompressedField """
def __init__(self):
SISField.__init__(self)
self.algorithm = None
self.uncompressedDataSize = None
self.data = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.algorithm = fileReader.readBytesAsUint(4)
self.uncompressedDataSize = fileReader.readBytesAsUint(8)
data = fileReader.readPlainBytes(self.length - 4 - 8)
if self.algorithm == 0:
self.data = data
elif self.algorithm == 1:
self.data = zlib.decompress(data)
class SISVersionField(SISField):
""" Class SIS VersionField """
def __init__(self):
SISField.__init__(self)
self.version = (- 1, - 1, - 1)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
major = fileReader.readBytesAsInt(4)
minor = fileReader.readBytesAsInt(4)
build = fileReader.readBytesAsInt(4)
self.version = (major, minor, build)
def readableStr(self):
"""readable string"""
return str(self.version)
class SISVersionRangeField(SISField):
""" Class SIS VersionRangeField """
def __init__(self):
SISField.__init__(self)
self.fromVersion = None
self.toVersion = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.fromVersion = fieldParser.parseField(fileReader)
if self.length - fieldParser.lastReadBytes > 0 :
self.toVersion = fieldParser.parseField(fileReader)
class SISDateField(SISField):
""" Class SIS DateField """
def __init__(self):
SISField.__init__(self)
self.year = None
self.month = None
self.day = None
def initFromFile(self, fileReader):
"""initialise from File"""
self.length = self.readFieldLength(fileReader)
self.year = fileReader.readBytesAsUint(2)
self.month = fileReader.readBytesAsUint(1)
self.day = fileReader.readBytesAsUint(1)
def readableStr(self):
"""readable string"""
return str(self.year) + "." + str(self.month) + "." + str(self.day)
class SISTimeField(SISField):
""" Class SIS TimeField """
def __init__(self):
SISField.__init__(self)
self.hours = None
self.minutes = None
self.seconds = None
def initFromFile(self, fileReader):
"""initialise from File"""
self.length = self.readFieldLength(fileReader)
self.hours = fileReader.readBytesAsUint(1)
self.minutes = fileReader.readBytesAsUint(1)
self.seconds = fileReader.readBytesAsUint(1)
def readableStr(self):
"""readable String"""
return str(self.hours) + ":" + str(self.minutes) + ":" + str(self.seconds)
class SISDateTimeField(SISField):
""" Class SIS DateTimeField """
def __init__(self):
SISField.__init__(self)
self.date = None
self.time = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.date = fieldParser.parseField(fileReader)
self.time = fieldParser.parseField(fileReader)
class SISUidField(SISField):
""" Class SIS UidField """
def __init__(self):
SISField.__init__(self)
self.uid = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.uid = fileReader.readBytesAsUint(4)
def readableStr(self):
"""readable String"""
return hex(self.uid)
class SISLanguageField(SISField):
""" Class SIS LanguageField """
def __init__(self):
SISField.__init__(self)
self.language = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.language = fileReader.readBytesAsUint(4)
def readableStr(self):
"""readable String"""
return str(self.language)
class SISContentsField(SISField):
""" Class SIS ContentsField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
field = fieldParser.parseField(fileReader)
while field:
if field.type_ == 3: # compressed<conroller>
bufferReader = SISBufferReader(field.data)
field = fieldParser.parseField(bufferReader)
self.subFields.append(field)
field = fieldParser.parseField(fileReader)
class SISControllerField(SISField):
""" Class SIS ControllerField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
bufferReader = SISBufferReader(fileReader.readPlainBytes(self.length))
field = fieldParser.parseField(bufferReader)
while field:
self.subFields.append(field)
field = fieldParser.parseField(bufferReader)
class SISInfoField(SISField):
""" Class SIS InfoField """
def __init__(self):
SISField.__init__(self)
self.installType = None
self.installFlags = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # UID
self.subFields.append(fieldParser.parseField(fileReader)) # Vendor name unique
self.subFields.append(fieldParser.parseField(fileReader)) # names
self.subFields.append(fieldParser.parseField(fileReader)) # vendor names
self.subFields.append(fieldParser.parseField(fileReader)) # version
self.subFields.append(fieldParser.parseField(fileReader)) # creation time
self.installType = fileReader.readBytesAsUint(1)
self.installFlags = fileReader.readBytesAsUint(1)
class SISSupportedLanguagesField(SISField):
""" Class SISSupportedLanguagesField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # languages
class SISSupportedOptionsField(SISField):
""" Class SISSupportedOptionsField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # options
class SISPrerequisitiesField(SISField):
""" Class SISPrerequisitiesField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # target devices
self.subFields.append(fieldParser.parseField(fileReader)) # dependencies
class SISDependencyField(SISField):
""" Class SISDependencyField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # UID
field = fieldParser.parseField(fileReader)
# Version range field is optional
if field.type_ == VersionRangeField:
self.subFields.append(field) # version range
self.subFields.append(fieldParser.parseField(fileReader)) # dependency names
else:
self.subFields.append(field) # dependency names
class SISPropertiesField(SISField):
""" Class SISPropertiesField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # properties
class SISPropertyField(SISField):
""" Class SISPropertyField """
def __init__(self):
SISField.__init__(self)
self.key = None
self.value = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.key = fileReader.readBytesAsInt(4)
self.value = fileReader.readBytesAsInt(4)
class SISSignaturesField(SISUnsupportedField):
""" Class SISSignaturesField There is a type for this field, but there is no definition of the field contents"""
pass
class SISCertificateChainField(SISField):
""" Class SISCertificateChainField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # certificate data
class SISLogoField(SISField):
""" Class SISLogoField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # logo file
class SISFileDescriptionField(SISField):
""" Class SISFileDescriptionField """
def __init__(self):
SISField.__init__(self)
self.operation = None
self.operationOptions = None
self.compressedLength = None
self.uncompressedLength = None
self.fileIndex = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader))
self.subFields.append(fieldParser.parseField(fileReader))
field = fieldParser.parseField(fileReader)
self.subFields.append(field)
if field.type_ == 41: # read field was capabilities ==> there is one more field left
self.subFields.append(fieldParser.parseField(fileReader))
self.operation = fileReader.readBytesAsUint(4)
self.operationOptions = fileReader.readBytesAsUint(4)
self.compressedLength = fileReader.readBytesAsUint(8)
self.uncompressedLength = fileReader.readBytesAsUint(8)
self.fileIndex = fileReader.readBytesAsUint(4)
def readableStr(self):
"""readable string"""
return "index: " + str(self.fileIndex)
class SISHashField(SISField):
""" Class SISHashField """
def __init__(self):
SISField.__init__(self)
self.algorithm = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.algorithm = fileReader.readBytesAsUint(4)
self.subFields.append(fieldParser.parseField(fileReader)) # logo file
class SISIfField(SISField):
""" Class SISIfField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # expression
self.subFields.append(fieldParser.parseField(fileReader)) # install block
self.subFields.append(fieldParser.parseField(fileReader)) # else ifs
class SISElseIfField(SISField):
""" Class SISElseIfField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # expression
self.subFields.append(fieldParser.parseField(fileReader)) # install block
class SISInstallBlockField(SISField):
""" Class SISInstallBlockField """
def __init__(self):
SISField.__init__(self)
self.files = None
self.embeddedSISFiles = None
self.ifBlocks = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader))
self.subFields.append(fieldParser.parseField(fileReader))
self.subFields.append(fieldParser.parseField(fileReader))
class SISExpressionField(SISField):
""" Class SISExpressionField """
def __init__(self):
SISField.__init__(self)
self.operator = None
self.integerValue = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.operator = fileReader.readBytesAsUint(4)
self.integerValue = fileReader.readBytesAsInt(4)
if self.operator == 10 or self.operator == 13:
self.subFields.append(fieldParser.parseField(fileReader))
if self.operator == 1 or self.operator == 2 or self.operator == 3 or self.operator == 4 or self.operator == 5 or self.operator == 6 or self.operator == 7 or self.operator == 8 or self.operator == 11 or self.operator == 12:
self.subFields.append(fieldParser.parseField(fileReader))
if not (self.operator == 13 or self.operator == 14 or self.operator == 15 or self.operator == 16 or self.operator == 10):
self.subFields.append(fieldParser.parseField(fileReader))
class SISDataField(SISField):
""" Class SISDataField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # data units
class SISDataUnitField(SISField):
""" Class SISDataUnitField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # file data
class SISFileDataField(SISField):
""" Class SISFileDataField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # raw file data
class SISSupportedOptionField(SISField):
""" Class SISSupportedOptionField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # names
class SISControllerChecksumField(SISField):
""" Class SISControllerChecksumField """
def __init__(self):
SISField.__init__(self)
self.checksum = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.checksum = fileReader.readBytesAsUint(2)
class SISDataChecksumField(SISField):
""" Class SISDataChecksumField """
def __init__(self):
SISField.__init__(self)
self.checksum = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.checksum = fileReader.readBytesAsUint(2)
class SISSignatureField(SISField):
""" Class SISSignatureField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # signature algorithm
self.subFields.append(fieldParser.parseField(fileReader)) # signature data
class SISBlobField(SISField):
""" Class SISBlobField """
def __init__(self):
SISField.__init__(self)
self.data = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.data = fileReader.readPlainBytes(self.length)
class SISSignatureAlgorithmField(SISField):
""" Class SISSignatureAlgorithmField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # algorithm identifier
class SISSignatureCertificateChainField(SISField):
""" Class SISSignatureCertificateChainField """
def __init__(self):
SISField.__init__(self)
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
fieldParser = SISFieldParser()
self.subFields.append(fieldParser.parseField(fileReader)) # signatures
self.subFields.append(fieldParser.parseField(fileReader)) # certificate chain
class SISDataIndexField(SISField):
""" Class SISDataIndexField """
def __init__(self):
SISField.__init__(self)
self.dataIndex = None
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.dataIndex = fileReader.readBytesAsUint(4)
class SISCapabilitiesField(SISField):
""" Class SISCapabilitiesField """
def __init__(self):
SISField.__init__(self)
self.capabilities = 0
self.readableCaps = []
def initFromFile(self, fileReader):
"""initialise From File"""
self.length = self.readFieldLength(fileReader)
self.capabilities = fileReader.readBytesAsUint(self.length)
for i in range(20):
if (self.capabilities >> i) & 0x01:
self.readableCaps.append(CapabilityNames[i])
def readableStr(self):
"""readable string"""
return " ".join(self.readableCaps)
SISFieldTypes = {
1: SISStringField,
2: SISArrayField,
3: SISCompressedField,
4: SISVersionField,
5: SISVersionRangeField,
6: SISDateField,
7: SISTimeField,
8: SISDateTimeField,
9: SISUidField,
10: SISUnsupportedField,
11: SISLanguageField,
12: SISContentsField,
13: SISControllerField,
14: SISInfoField,
15: SISSupportedLanguagesField,
16: SISSupportedOptionsField,
17: SISPrerequisitiesField,
18: SISDependencyField,
19: SISPropertiesField,
20: SISPropertyField,
21: SISSignaturesField,
22: SISCertificateChainField,
23: SISLogoField,
24: SISFileDescriptionField,
25: SISHashField,
26: SISIfField,
27: SISElseIfField,
28: SISInstallBlockField,
29: SISExpressionField,
30: SISDataField,
31: SISDataUnitField,
32: SISFileDataField,
33: SISSupportedOptionField,
34: SISControllerChecksumField,
35: SISDataChecksumField,
36: SISSignatureField,
37: SISBlobField,
38: SISSignatureAlgorithmField,
39: SISSignatureCertificateChainField,
40: SISDataIndexField,
41: SISCapabilitiesField
}
[StringField,
ArrayField,
CompressedField,
VersionField,
VersionRangeField,
DateField,
TimeField,
DateTimeField,
UidField,
UnusedField,
LanguageField,
ContentsField,
ControllerField,
InfoField,
SupportedLanguagesField,
SupportedOptionsField,
PrerequisitiesField,
DependencyField,
PropertiesField,
PropertyField,
SignaturesField,
CertificateChainField,
LogoField,
FileDescriptionField,
HashField,
IfField,
ElseIfField,
InstallBlockField,
ExpressionField,
DataField,
DataUnitField,
FileDataField,
SupportedOptionField,
ControllerChecksumField,
DataChecksumField,
SignatureField,
BlobField,
SignatureAlgorithmField,
SignatureCertificateChainField,
DataIndexField,
CapabilitiesField] = range(1, 42)
FieldNames = {
0: "ROOT",
StringField: "StringField",
ArrayField: "ArrayField",
CompressedField: "CompressedField",
VersionField: "VersionField",
VersionRangeField: "VersionRangeField",
DateField: "DateField",
TimeField: "TimeField",
DateTimeField: "DateTimeField",
UidField: "UidField",
UnusedField: "UnusedField",
LanguageField: "LanguageField",
ContentsField: "ContentsField",
ControllerField: "ControllerField",
InfoField: "InfoField",
SupportedLanguagesField: "SupportedLanguagesField",
SupportedOptionsField: "SupportedOptionsField",
PrerequisitiesField: "PrerequisitiesField",
DependencyField: "DependencyField",
PropertiesField: "PropertiesField",
PropertyField: "PropertyField",
SignaturesField: "SignaturesField",
CertificateChainField: "CertificateChainField",
LogoField: "LogoField",
FileDescriptionField: "FileDescriptionField",
HashField: "HashField",
IfField: "IfField",
ElseIfField: "ElseIfField",
InstallBlockField: "InstallBlockField",
ExpressionField: "ExpressionField",
DataField: "DataField",
DataUnitField: "DataUnitField",
FileDataField: "FileDataField",
SupportedOptionField: "SupportedOptionField",
ControllerChecksumField: "ControllerChecksumField",
DataChecksumField: "DataChecksumField",
SignatureField: "SignatureField",
BlobField: "BlobField",
SignatureAlgorithmField: "SignatureAlgorithmField",
SignatureCertificateChainField: "SignatureCertificateChainField",
DataIndexField: "DataIndexField",
CapabilitiesField: "CapabilitiesField"
}
CapabilityNames = {
0: "TCB",
1: "CommDD",
2: "PowerMgmt",
3: "MultimediaDD",
4: "ReadDeviceData",
5: "WriteDeviceData",
6: "DRM",
7: "TrustedUI",
8: "ProtServ",
9: "DiskAdmin",
10: "NetworkControl",
11: "AllFiles",
12: "SwEvent",
13: "NetworkServices",
14: "LocalServices",
15: "ReadUserData",
16: "WriteUserData",
17: "Location",
18: "SurroundingsDD",
19: "UserEnvironment"
}
InstallTypes = {
0: "SA",
1: "SP",
2: "PU",
3: "PA",
4: "PP"
}
class SISReader:
""" SIS Reader """
def __init__(self):
self.bytesRead = 0
def readUnsignedBytes(self, numBytes):
"""read Unsigned bytes"""
buf = self.readPlainBytes(numBytes)
if len(buf) < numBytes:
return []
format_ = ""
for _ in range(numBytes):
format_ += "B"
return struct.unpack(format_, buf)
def readSignedBytes(self, numBytes):
"""read signed bytes"""
buf = self.readPlainBytes(numBytes)
if len(buf) < numBytes:
return []
format_ = ""
for _ in range(numBytes):
format_ += "b"
return struct.unpack(format_, buf)
def readBytesAsUint(self, numBytes):
"""read bytes as Unit"""
result = 0
bytes_ = self.readUnsignedBytes(numBytes)
if len(bytes_) == numBytes:
for i_byte in range(numBytes):
result |= bytes_[i_byte] << (i_byte * 8)
return result
def readBytesAsInt(self, numBytes):
"""read bytes as Integer"""
result = 0
bytes_ = self.readSignedBytes(numBytes)
if len(bytes_) == numBytes:
for i_byte in range(numBytes):
result |= bytes_[i_byte] << (i_byte * 8)
return result
def skipPadding(self):
"""skip padding"""
result = 0
if self.bytesRead % 4 != 0:
paddingLength = 4 - self.bytesRead % 4
self.readPlainBytes(paddingLength)
result = paddingLength
return result
def readPlainBytes(self, numBytes):
"""read plain bytes"""
pass
class SISFileReader(SISReader):
""" SIS File Reader """
def __init__(self, inStream):
SISReader.__init__(self)
self.inStream = inStream
self.eof = False
self.bytesRead = 0
def readPlainBytes(self, numBytes):
"""read Plain byytes"""
if self.eof:
return ""
if numBytes == 0:
return ""
buf = ""
buf = self.inStream.read(numBytes)
if len(buf) < numBytes:
self.eof = True
return ""
self.bytesRead += numBytes
return buf
def isEof(self):
"""is it End of File"""
return self.eof
class SISBufferReader(SISReader):
""" SIS Buffer reader """
def __init__(self, buffer_):
SISReader.__init__(self)
self.buffer_ = buffer_
self.bytesRead = 0
def readPlainBytes(self, numBytes):
"""read Plain bytes"""
if self.isEof():
return ""
if numBytes == 0:
return ""
result = self.buffer_[self.bytesRead:self.bytesRead + numBytes]
self.bytesRead += numBytes
return result
def isEof(self):
"""is it End of File"""
return self.bytesRead >= len(self.buffer_)
class SISFieldParser:
""" Parser to read a SIS field """
def __init__(self):
self.lastReadBytes = 0
def parseField(self, fileReader):
"""Reads the next field from the fileReader stream and returns it"""
field = None
self.lastReadBytes = 0
type_ = fileReader.readBytesAsUint(4)
self.lastReadBytes += 4
if type_ != 0:
field = SISFieldTypes[type_]()
field.type_ = type_
field.initFromFile(fileReader)
self.lastReadBytes += field.length + 4 # Field length + length field
self.lastReadBytes += fileReader.skipPadding()
return field
class SISInfo(SISField):
""" SIS file information """
def __init__(self):
SISField.__init__(self)
self.fin = None
self.fileHeader = SISFileHeader()
def parse(self, filename):
"""parse"""
fin = open(filename, 'rb')
fileReader = SISFileReader(fin)
self.parseHeader(fileReader)
self.parseSISFields(fileReader)
def parseHeader(self, fileReader):
"""parse Holder"""
self.fileHeader.uid1 = fileReader.readBytesAsUint(4)
self.fileHeader.uid2 = fileReader.readBytesAsUint(4)
self.fileHeader.uid3 = fileReader.readBytesAsUint(4)
self.fileHeader.uidChecksum = fileReader.readBytesAsUint(4)
def parseSISFields(self, fileReader):
"""parse SIS Fileds"""
parser = SISFieldParser()
while not fileReader.isEof():
self.subFields.append(parser.parseField(fileReader))
class Handler:
""" A handler class """
def __init__(self):
self.files = []
self.fileDatas = []
self.signatureCertificateChains = []
def handleField(self, field, _):
"""handle Field"""
if field.type_ == FileDescriptionField:
self.files.append(field)
elif field.type_ == FileDataField:
self.fileDatas.append(field)
elif field.type_ == SignatureCertificateChainField :
self.signatureCertificateChains.append(field)
def execute(self, options):
"""execute"""
for f_file in self.files:
if options.info:
buf = " " + f_file.findField(StringField)[0].readableStr()
caps = f_file.findField(CapabilitiesField)[0]
if caps:
buf += " [" + " ".join(f_file.findField(CapabilitiesField)[0].readableCaps) + "]"
print buf
if options.extract:
parts = f_file.findField(StringField)[0].readableStr().split("\\")
if len(parts[len(parts) - 1]) > 0:
path = os.path.abspath(options.extract)
path += os.sep + os.sep.join(parts[1: - 1])
if not os.path.exists(path):
os.makedirs(path)
newFile = file(path + os.sep + parts[len(parts) - 1], "wb")
newFile.write(self.fileDatas[f_file.fileIndex].findField(CompressedField)[0].data)
newFile.close()
for sig in self.signatureCertificateChains:
if options.certificate:
buf = sig.findField(CertificateChainField)[0].subFields[0].data
print "Certificate chain:"
i_num = 1
while len(buf) > 0:
print " Certificate " + str(i_num) + ":"
i_num += 1
decoded = decoder.decode(buf)
cer = CertificateInfo()
cer.parse(decoded[0])
readableStr = cer.readableStr()
print " " + "\n ".join(readableStr.split('\n'))
buf = decoded[1]
class ContentPrinter:
""" A handler class which prints the field contents """
def __init__(self):
pass
def handleField(self, field, depth):
"""handle Field"""
buf = ""
for _ in range(depth):
buf += " "
buf += FieldNames[field.type_] + " "
if len(field.readableStr()) > 0:
buf += field.readableStr()
print buf
class IADHandler:
""" IAD handler class """
def __init__(self):
self.packageVersion = (0, 0, 0)
self.packageUid = 0
self.vendorName = ""
self.packageNames = []
self.packageNamesFields = []
self.languages = []
self.platformDependencies = []
self.packageDependencies = []
self.installType = 0
self.installFlags = 0
self.packageVersionField = None
self.packageUidField = None
self.vendorNameField = None
def handleDependency(self, field):
"""handle dependancy"""
dep = [0, - 1, - 1, - 1, - 1, - 1, - 1]
dep[0] = field.subFields[0].uid
if field.subFields[1] and field.subFields[1].type_ == VersionRangeField:
res = field.subFields[1]
if res.fromVersion != None:
dep[1] = res.fromVersion.version[0]
dep[2] = res.fromVersion.version[1]
dep[3] = res.fromVersion.version[2]
if res.toVersion != None:
dep[4] = res.toVersion.version[0]
dep[5] = res.toVersion.version[1]
dep[6] = res.toVersion.version[2]
return dep
def handleField(self, field, _):
"""handle Field"""
if field.type_ == InfoField:
self.packageVersion = field.subFields[4].version
self.packageVersionField = field.subFields[4]
self.packageUid = field.subFields[0].uid
self.packageUidField = field.subFields[0]
self.vendorName = field.subFields[1].data
self.vendorNameField = field.subFields[1]
self.installType = field.installType
self.installFlags = field.installFlags
for name in field.subFields[2].subFields:
self.packageNames.append(name.data)
elif field.type_ == LanguageField:
self.languages.append(field.language)
elif field.type_ == PrerequisitiesField:
for f_field in field.subFields[0].subFields:
dependency = self.handleDependency(f_field)
self.platformDependencies.append(dependency)
for f_field in field.subFields[1].subFields:
dependency = self.handleDependency(f_field)
self.packageDependencies.append(dependency)
def getInfo (self, fileName):
"""get Info"""
sisInfo = SISInfo()
sisInfo.parse(fileName)
handler = IADHandler()
sisInfo.traverse(handler)
info = "<sisinfo>\n" \
+ " <uid>" + hex(handler.packageUid) + "</uid>\n" \
+ " <vendor>" + handler.vendorName + "</vendor>\n" \
+ " <version>" \
+ "<major>" + repr(handler.packageVersion[0]) + "</major>" \
+ "<minor>" + repr(handler.packageVersion[1]) + "</minor>" \
+ "<build>" + repr(handler.packageVersion[2]) + "</build>" \
+ "</version>\n" \
+ " <type>" + InstallTypes[self.installType] + "</type>\n"
for num, name in enumerate(handler.packageNames):
info += " <name language='" + repr(handler.languages[num]) + "'>" + name + "</name>\n"
for language in handler.languages:
info += " <language>" + repr(language) + "</language>\n"
for platDep in handler.platformDependencies:
info += " <platform_dependency><uid>" + hex(platDep[0]) + "</uid>\n"
info += " <from>" \
+ "<major>" + repr(platDep[1]) + "</major>" \
+ "<minor>" + repr(platDep[2]) + "</minor>"
# info += "<build>" + repr(platDep[3]) + "</build>"
info += "</from>\n <to>" \
+ "<major>" + repr(platDep[4]) + "</major>" \
+ "<minor>" + repr(platDep[5]) + "</minor>"
# info += "<build>" + repr(platDep[6]) + "</build>"
info += "</to>\n" \
+ " </platform_dependency>\n"
for packageDep in handler.packageDependencies:
info += " <package_dependency><uid>" + hex(packageDep[0]) + "</uid>\n"
info += " <from>" \
+ "<major>" + repr(packageDep[1]) + "</major>" \
+ "<minor>" + repr(packageDep[2]) + "</minor>"
# info += "<build>" + repr(packageDep[3]) + "</build>"
info += "</from>\n <to>" \
+ "<major>" + repr(packageDep[4]) + "</major>" \
+ "<minor>" + repr(packageDep[5]) + "</minor>"
# info += "<build>" + repr(packageDep[6]) + "</build>"
info += "</to>\n" \
+ " </package_dependency>\n"
info += "</sisinfo>\n"
return info
if __name__ == "__main__":
_handler = IADHandler()
print (_handler.getInfo (sys.argv[1]))