This script parses ASN.1 structure of the Windows driver catalog files, and extracts information about what architecture and windows flavor the driver is suitable for. Signed-off-by: Roman Kagan <rkagan@xxxxxxxxxxxxx> --- util/parsecat.py | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 util/parsecat.py diff --git a/util/parsecat.py b/util/parsecat.py new file mode 100644 index 0000000..02ab45c --- /dev/null +++ b/util/parsecat.py @@ -0,0 +1,166 @@ +#!/usr/bin/python +# +# Copyright 2016 Parallels IP Holdings GmbH +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. +""" +Parse relevant items in the ASN.1 structure of a Windows driver catalog file +""" + +import sys, pprint +from pyasn1_modules import rfc2315 +from pyasn1.type import tag, namedtype, namedval, univ, char, useful +from pyasn1.codec.der import decoder + +class CatalogList(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('oid', univ.ObjectIdentifier()) + ) + +class CatalogListMemberId(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('oid', univ.ObjectIdentifier()), + namedtype.NamedType('null', univ.Null()) + ) + +class CatalogNameValue(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('name', char.BMPString()), + namedtype.NamedType('someInt', univ.Integer()), + namedtype.NamedType('value', univ.OctetString(encoding = 'utf-16-le')) + ) + +class SpcKind(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('oid', univ.ObjectIdentifier()), + namedtype.NamedType('someTh', univ.Any()) + ) + +class SpcIndirectData(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('spcKind', SpcKind()), + namedtype.NamedType('digest', rfc2315.DigestInfo()) + ) + +class MemberAttributeContent(univ.SetOf): + componentType = univ.Any() + +class MemberAttribute(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('oid', univ.ObjectIdentifier()), + namedtype.NamedType('content', MemberAttributeContent()) + ) + +class MemberAttributes(univ.SetOf): + componentType = MemberAttribute() + +class CatalogListMember(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('referenceTag', univ.OctetString()), + namedtype.NamedType('attributes', MemberAttributes()) + ) + +class CatalogMembers(univ.SequenceOf): + componentType = CatalogListMember() + +class CatalogAttribute(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('oid', univ.ObjectIdentifier()), + namedtype.NamedType('content', univ.OctetString()) + ) + +class CatalogAttributes(univ.SequenceOf): + componentType = CatalogAttribute() + tagSet = univ.SequenceOf.tagSet.tagExplicitly(tag.Tag(tag.tagClassContext, + tag.tagFormatConstructed, 0)) + + +class CertTrustList(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('catalogList', CatalogList()), + namedtype.NamedType('someStr0', univ.OctetString()), + namedtype.NamedType('utcTime', useful.UTCTime()), + namedtype.NamedType('catalogListMemberId', CatalogListMemberId()), + namedtype.NamedType('members', CatalogMembers()), + namedtype.OptionalNamedType('attributes', CatalogAttributes()) + ) + +def parseNameValue(attr): + nv, _ = decoder.decode(attr, asn1Spec = CatalogNameValue()) + strtype = type(u'') # python2/3 compat + name, value = str(strtype(nv['name'])), str(strtype(nv['value'])) + assert value[-1] == '\x00' + return name, value[:-1] + +spcKindMap = { + univ.ObjectIdentifier('1.3.6.1.4.1.311.2.1.15'): 'spcPEImageData', + univ.ObjectIdentifier('1.3.6.1.4.1.311.2.1.25'): 'spcLink', + } + +digestAlgoMap = { + univ.ObjectIdentifier('1.3.14.3.2.26'): 'sha1', + univ.ObjectIdentifier('2.16.840.1.101.3.4.2.1'): 'sha256', + } + +def parseSpcIndirectData(attr): + sid, _ = decoder.decode(attr, asn1Spec = SpcIndirectData()) + spcKind, digest = sid['spcKind'], sid['digest'] + algo = digestAlgoMap[digest['digestAlgorithm']['algorithm']] + return 'signature', { + 'kind': spcKindMap[spcKind['oid']], + 'digestAlgorithm': algo, + 'digest': digest['digest'].asOctets() + } + +memberAttrMap = { + univ.ObjectIdentifier('1.3.6.1.4.1.311.12.2.1'): parseNameValue, + univ.ObjectIdentifier('1.3.6.1.4.1.311.12.2.2'): None, + univ.ObjectIdentifier('1.3.6.1.4.1.311.12.2.3'): None, + univ.ObjectIdentifier('1.3.6.1.4.1.311.2.1.4'): parseSpcIndirectData, + } + +def parseCatMember(member): + for attr in member['attributes']: + meth = memberAttrMap[attr['oid']] + if meth: + yield meth(attr['content'][0]) + +contentInfoMap = { + rfc2315.data: rfc2315.Data(), + rfc2315.signedData: rfc2315.SignedData(), + rfc2315.envelopedData: rfc2315.EnvelopedData(), + rfc2315.signedAndEnvelopedData: rfc2315.SignedAndEnvelopedData(), + rfc2315.digestedData: rfc2315.DigestedData(), + rfc2315.encryptedData: rfc2315.EncryptedData() + } + +def parseNameValueObj(nameValue): + assert nameValue['oid'] == univ.ObjectIdentifier('1.3.6.1.4.1.311.12.2.1') + return parseNameValue(nameValue['content']) + +def parseCat(fname): + cat = open(fname, "rb").read() + contentInfo, _ = decoder.decode(cat, asn1Spec = rfc2315.ContentInfo()) + contentType = contentInfo['contentType'] + + content, _ = decoder.decode(contentInfo['content'], + asn1Spec = contentInfoMap[contentType]) + contentInfo = content['contentInfo'] + contentType = contentInfo['contentType'] + assert contentType == univ.ObjectIdentifier('1.3.6.1.4.1.311.10.1') + + ctl, _ = decoder.decode(contentInfo['content'], asn1Spec = CertTrustList()) + assert (ctl['catalogList']['oid'] == + univ.ObjectIdentifier('1.3.6.1.4.1.311.12.1.1')) + assert (ctl['catalogListMemberId']['oid'] in ( + univ.ObjectIdentifier('1.3.6.1.4.1.311.12.1.2'), + univ.ObjectIdentifier('1.3.6.1.4.1.311.12.1.3') + )) + + members = [dict(parseCatMember(member)) for member in ctl['members']] + attributes = dict(parseNameValueObj(attr) for attr in ctl['attributes']) + return attributes, members + +if __name__ == "__main__": + pprint.pprint(parseCat(sys.argv[1])) -- 2.5.0 _______________________________________________ virt-tools-list mailing list virt-tools-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/virt-tools-list