[virt-tools-list] [PATCH RFC virtio-win-pkg-scripts 1/2] add parser for driver catalog files
Roman Kagan
rkagan at virtuozzo.com
Mon Jan 18 14:15:20 UTC 2016
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 at virtuozzo.com>
---
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
More information about the virt-tools-list
mailing list