Skip to content

Instantly share code, notes, and snippets.

@anthrotype
Created November 18, 2015 18:26
Show Gist options
  • Select an option

  • Save anthrotype/5687a131e08c43dc3d7d to your computer and use it in GitHub Desktop.

Select an option

Save anthrotype/5687a131e08c43dc3d7d to your computer and use it in GitHub Desktop.
hashfont.py
#!/usr/bin/env python
from __future__ import print_function, division, absolute_import
from fontTools.ttLib import TTFont
import sys
from io import BytesIO
import struct
import hashlib
# bit 0 prevents other parties from also signing the font
DEFAULT_PERMISSION_FLAG = 0b1
def get_content_to_be_signed(ttFont, reorderTables=False,
usFlag=DEFAULT_PERMISSION_FLAG):
# temporarily remove DSIG table
dsig_bak = None
if 'DSIG' in ttFont:
from copy import deepcopy
dsig_bak = deepcopy(ttFont['DSIG'])
del ttFont['DSIG']
with BytesIO() as tmp:
# the OT spec says to "zero out the file checksum in the head table"
# but the MS signcode.exe, i.e. the 'reference' implementation, does
# not do it, so I don't do it either.
ttFont.save(tmp, reorderTables=reorderTables)
data = tmp.getvalue()
# add 'usFlag' permission flags to the stream
data += struct.pack(">H", usFlag)
if dsig_bak:
ttFont['DSIG'] = dsig_bak
return data
def sha1(data, as_hex=False):
""" Return the SHA1 digest of 'data' as generated by hashlib.
If 'as_hex' is True, return hash as a hex string.
"""
hasher = hashlib.sha1()
hasher.update(data)
if as_hex:
return hasher.hexdigest()
else:
return hasher.digest()
if __name__ == '__main__':
if len(sys.argv) < 2:
print("usage: hashfont FONT.ttf")
sys.exit(1)
font = TTFont(sys.argv[1], recalcBBoxes=False, recalcTimestamp=False)
data = get_content_to_be_signed(font)
digest = sha1(data, as_hex=True)
print("SHA1: %s" % digest)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment