-
Notifications
You must be signed in to change notification settings - Fork 2
/
dbxupdate-split.py
executable file
·66 lines (52 loc) · 2.24 KB
/
dbxupdate-split.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#!/usr/bin/python3
"""
Split the signature and content from a dbxupdate.bin file (eg.
from /usr/share/secureboot/updates/dbx/ ). That splitted dbxupdate.bin.esl
file can than be used together with https://github.com/awslabs/python-uefivars
Inspired by https://www.powershellgallery.com/packages/SplitDbxContent/1.0
"""
import argparse
import sys
import struct
def _parser():
parser = argparse.ArgumentParser(
description='split a secureboot dbxupdate.bin')
parser.add_argument(
'--content', default='dbxupdate.bin.esl',
help='the content filename to write. default: %(default)s')
parser.add_argument(
'--signature', default='dbxupdate.bin.p7',
help='the signature filename to write. default: %(default)s')
parser.add_argument(
'dbxupdate', help='path to the dbxupdate.bin file')
return parser
if __name__ == '__main__':
parser = _parser()
args = parser.parse_args()
with open(args.dbxupdate, 'rb') as f:
buf = f.read()
# the wCertificateType (UINT16) must be WIN_CERT_TYPE_EFI_GUID
wCertificateType, = struct.unpack('H', buf[22:24])
if wCertificateType != 0x0ef1:
print(f'Certificate type is 0x{wCertificateType:04x} not WIN_CERT_TYPE_EFI_GUID (0x0ef1).', file=sys.stderr)
sys.exit(3)
# Identify file signature
chop = buf[40:]
if hex(chop[0]) != '0x30' or hex(chop[1]) != '0x82':
print('error: can not find signature', file=sys.stderr)
sys.exit(1)
# Signature is known to be ASN size plus header of 4 bytes
signature_length = (chop[2] * 256) + chop[3] + 4
signature = chop[0:signature_length]
if signature_length > (len(buf) + 40):
print('error: signature longer than file size', file=sys.stderr)
sys.exit(2)
# the dbxupdate.bin content without the signature
content = chop[signature_length:]
with open(args.content, 'wb') as c:
for byte in content:
c.write(byte.to_bytes(1, byteorder='big'))
# the dbxupdate.bin signature without the content
with open(args.signature, 'wb') as s:
for byte in signature:
s.write(byte.to_bytes(1, byteorder='big'))