Skip to content

Commit

Permalink
feat: avoid hardcoding widevine signing format
Browse files Browse the repository at this point in the history
  • Loading branch information
bhearsum committed Jan 16, 2025
1 parent 5cf8652 commit b82cc6a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 21 deletions.
7 changes: 3 additions & 4 deletions iscript/src/iscript/autograph.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@


# sign_widevine_dir {{{1
async def sign_widevine_dir(config, sign_config, app_dir):
async def sign_widevine_dir(config, sign_config, app_dir, autograph_fmt):
"""Sign the internals of a tarfile with the widevine key.
Extract the entire tarball, but only sign a handful of files (see
Expand Down Expand Up @@ -98,7 +98,7 @@ async def sign_widevine_dir(config, sign_config, app_dir):
to = _get_mac_sigpath(from_)
log.debug("Adding %s to the sigfile paths...", to)
makedirs(os.path.dirname(to))
tasks.append(asyncio.ensure_future(sign_widevine_with_autograph(sign_config, from_, "blessed" in fmt, to=to)))
tasks.append(asyncio.ensure_future(sign_widevine_with_autograph(sign_config, from_, autograph_fmt, "blessed" in fmt, to=to)))
all_files.append(to)
await raise_future_exceptions(tasks)
remove_extra_files(app_dir, all_files)
Expand Down Expand Up @@ -439,7 +439,7 @@ async def merge_omnija_files(orig, signed, to):


# sign_widevine_with_autograph {{{1
async def sign_widevine_with_autograph(sign_config, from_, blessed, to=None):
async def sign_widevine_with_autograph(sign_config, from_, fmt, blessed, to=None):
"""Create a widevine signature using autograph as a backend.
Args:
Expand All @@ -462,7 +462,6 @@ async def sign_widevine_with_autograph(sign_config, from_, blessed, to=None):

to = to or f"{from_}.sig"
flags = 1 if blessed else 0
fmt = "autograph_widevine"

h = widevine.generate_widevine_hash(from_, flags)

Expand Down
5 changes: 3 additions & 2 deletions iscript/src/iscript/hardened_sign.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ async def sign_hardened_behavior(config, task, create_pkg=False, **kwargs):
# sign widevine
futures = []
for app in all_apps:
if {"autograph_widevine", "widevine"} & set(app.formats):
futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path)))
fmt = next((f for f in app.formats if "widevine" in f), None)
if fmt:
futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path, fmt)))
await raise_future_exceptions(futures)
await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"])
futures = []
Expand Down
5 changes: 3 additions & 2 deletions iscript/src/iscript/mac.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,9 @@ async def sign_all_apps(config, sign_config, entitlements_path, all_paths, provi
# sign widevine
futures = []
for app in all_paths:
if {"autograph_widevine", "widevine"} & set(app.formats):
futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path)))
fmt = next((f for f in app.formats if "widevine" in f), None)
if fmt:
futures.append(asyncio.ensure_future(sign_widevine_dir(config, sign_config, app.app_path, fmt)))
await raise_future_exceptions(futures)
await unlock_keychain(sign_config["signing_keychain"], sign_config["keychain_password"])
futures = []
Expand Down
65 changes: 52 additions & 13 deletions iscript/tests/test_autograph.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ def sign_config():
"langpack_url": "https://autograph-hsm.dev.mozaws.net/langpack",
"langpack_user": "langpack_user",
"langpack_pass": "langpack_pass",
"stage_widevine_url": "https://autograph-stage.dev.mozaws.net",
"stage_widevine_user": "widevine_user",
"stage_widevine_pass": "widevine_pass",
"stage_widevine_cert": "widevine_cert",
"stage_langpack_url": "https://autograph-stage.dev.mozaws.net/langpack",
"stage_langpack_user": "langpack_user",
"stage_langpack_pass": "langpack_pass",
"gcp_prod_widevine_url": "https://autograph-gcp.dev.mozaws.net",
"gcp_prod_widevine_user": "widevine_user",
"gcp_prod_widevine_pass": "widevine_pass",
"gcp_prod_widevine_cert": "widevine_cert",
"gcp_prod_langpack_url": "https://autograph-gcp.dev.mozaws.net/langpack",
"gcp_prod_langpack_user": "langpack_user",
"gcp_prod_langpack_pass": "langpack_pass",
}


Expand All @@ -42,8 +56,16 @@ def noop_sync(*args, **kwargs): ...

# sign_file_with_autograph {{{1
@pytest.mark.asyncio
@pytest.mark.parametrize("to,expected,format,options", ((None, "from", "autograph_widevine", None), ("to", "to", "autograph_widevine", None)))
async def test_sign_file_with_autograph(sign_config, mocker, to, expected, format, options):
@pytest.mark.parametrize(
"to,expected,format,url",
(
(None, "from", "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"),
("to", "to", "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"),
("to", "to", "stage_autograph_widevine", "https://autograph-stage.dev.mozaws.net"),
("to", "to", "gcp_prod_autograph_widevine", "https://autograph-gcp.dev.mozaws.net"),
),
)
async def test_sign_file_with_autograph(sign_config, mocker, to, expected, format, url):
open_mock = mocker.mock_open(read_data=b"0xdeadbeef")
mocker.patch("builtins.open", open_mock, create=True)

Expand All @@ -58,9 +80,8 @@ async def test_sign_file_with_autograph(sign_config, mocker, to, expected, forma
assert await autograph.sign_file_with_autograph(sign_config, "from", format, to=to) == expected
open_mock.assert_called()
kwargs = {"input": "MHhkZWFkYmVlZg=="}
if options:
kwargs["options"] = options
session_mock.post.assert_called_with("https://autograph-hsm.dev.mozaws.net/sign/file", auth=mocker.ANY, json=[kwargs])
expected_url = f"{url}/sign/file"
session_mock.post.assert_called_with(expected_url, auth=mocker.ANY, json=[kwargs])


@pytest.mark.asyncio
Expand Down Expand Up @@ -140,7 +161,7 @@ def fake_isfile(path):
mocker.patch.object(os.path, "isfile", new=fake_isfile)
mocker.patch.object(os, "walk", new=fake_walk)

await autograph.sign_widevine_dir(config, sign_config, filename)
await autograph.sign_widevine_dir(config, sign_config, filename, fmt)


# _get_widevine_signing_files {{{1
Expand Down Expand Up @@ -240,13 +261,22 @@ async def test_bad_autograph_method():


@pytest.mark.asyncio
@pytest.mark.parametrize("blessed", (True, False))
async def test_widevine_autograph(mocker, tmp_path, blessed, sign_config):
@pytest.mark.parametrize(
"blessed,fmt,expected_url",
(
(True, "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"),
(False, "autograph_widevine", "https://autograph-hsm.dev.mozaws.net"),
(False, "stage_autograph_widevine", "https://autograph-stage.dev.mozaws.net"),
(False, "gcp_prod_autograph_widevine", "https://autograph-gcp.dev.mozaws.net"),
),
)
async def test_widevine_autograph(mocker, tmp_path, blessed, sign_config, fmt, expected_url):
wv = mocker.patch("iscript.autograph.widevine")
wv.generate_widevine_hash.return_value = b"hashhashash"
wv.generate_widevine_signature.return_value = b"sigwidevinesig"

async def fake_call(*args, **kwargs):
async def fake_call(url, *args, **kwargs):
assert expected_url in url
return [{"signature": base64.b64encode(b"sigwidevinesig")}]

mocker.patch.object(autograph, "call_autograph", fake_call)
Expand All @@ -256,21 +286,30 @@ async def fake_call(*args, **kwargs):
sign_config["widevine_cert"] = cert

to = tmp_path / "signed.sig"
to = await autograph.sign_widevine_with_autograph(sign_config, "from", blessed, to=to)
to = await autograph.sign_widevine_with_autograph(sign_config, "from", fmt, blessed, to=to)

assert b"sigwidevinesig" == to.read_bytes()


@pytest.mark.asyncio
async def test_no_widevine(mocker, tmp_path):
async def fake_call(*args, **kwargs):
@pytest.mark.parametrize(
"fmt,expected_url",
(
("autograph_widevine", "https://autograph-hsm.dev.mozaws.net"),
("stage_autograph_widevine", "https://autograph-stage.dev.mozaws.net"),
("gcp_prod_autograph_widevine", "https://autograph-gcp.dev.mozaws.net"),
),
)
async def test_no_widevine(mocker, tmp_path, fmt, expected_url):
async def fake_call(url, *args, **kwargs):
assert expected_url in url
return [{"signature": b"sigautographsig"}]

mocker.patch.object(autograph, "call_autograph", fake_call)

with pytest.raises(ImportError):
to = tmp_path / "signed.sig"
to = await autograph.sign_widevine_with_autograph({}, "from", True, to=to)
to = await autograph.sign_widevine_with_autograph({}, "from", fmt, True, to=to)


# omnija {{{1
Expand Down

0 comments on commit b82cc6a

Please sign in to comment.