async def test_gpg_autograph(context, mocker, tmp_path): tmp = tmp_path / "file.txt" tmp.write_text("hello world") context.task = { 'scopes': ['project:releng:signing:cert:dep-signing'], } context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", ["autograph_gpg"], "autograph") ] } mocked_sign = mocker.patch.object(sign, 'sign_with_autograph') mocked_sign.return_value = asyncio.Future() mocked_sign.return_value.set_result("--- FAKE SIG ---") result = await sign.sign_gpg_with_autograph(context, tmp, 'autograph_gpg') assert result == [tmp, f"{tmp}.asc"] with pytest.raises(SigningScriptError): result = await sign.sign_gpg_with_autograph(context, tmp, 'gpg')
async def test_sign_mar384_with_autograph_hash_keyid(context, mocker): context.task = {'scopes': ['project:releng:signing:cert:dep-signing']} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", ["autograph_hash_only_mar384"], "autograph") ] } open_mock = mocker.mock_open(read_data=b'0xdeadbeef') mocker.patch('builtins.open', open_mock, create=True) mocker.patch('signingscript.sign.add_signature_block') mar_reader = mocker.patch('signingscript.sign.MarReader') mar_reader.calculate_hashes.return_value = [[None, b'b64marhash']] mocker.patch('signingscript.sign.verify_mar_signature') f = asyncio.Future() f.set_result(b"#" * 512) ag = mocker.patch('signingscript.sign.sign_hash_with_autograph') ag.return_value = f assert await sign.sign_mar384_with_autograph_hash( context, 'from', 'autograph_hash_only_mar384:keyid1') == 'from' assert ag.called_with(keyid='keyid1')
async def test_sign_mar384_with_autograph_hash_keyid(context, mocker): context.task = {"scopes": ["project:releng:signing:cert:dep-signing"]} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", ["autograph_hash_only_mar384"], "autograph", ) ] } open_mock = mocker.mock_open(read_data=b"0xdeadbeef") mocker.patch("builtins.open", open_mock, create=True) mocker.patch("signingscript.sign.add_signature_block") mar_reader = mocker.patch("signingscript.sign.MarReader") mar_reader.calculate_hashes.return_value = [[None, b"b64marhash"]] mocker.patch("signingscript.sign.verify_mar_signature") f = asyncio.Future() f.set_result(b"#" * 512) ag = mocker.patch("signingscript.sign.sign_hash_with_autograph") ag.return_value = f assert ( await sign.sign_mar384_with_autograph_hash( context, "from", "autograph_hash_only_mar384:keyid1" ) == "from" ) assert ag.called_with(keyid="keyid1")
async def test_integration_autograph_custom_digest_algorithm( context, tmpdir, format, expected_algorithm ): file_name = "app.apk" original_file_path = os.path.join(TEST_DATA_DIR, file_name) shutil.copy(original_file_path, tmpdir) apk_path = os.path.join(tmpdir, file_name) async with aiohttp.ClientSession() as session: context.session = session context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( *[ "http://localhost:5500", "bob", "1234567890abcdefghijklmnopqrstuvwxyz1234567890abcd", [format], "autograph", ] ) ] } context.task = _craft_task([file_name], signing_format=format) await sign_file_with_autograph(context, apk_path, format) assert _extract_apk_signature_algorithm(apk_path) == expected_algorithm
def test_get_suitable_signing_servers(context, formats, expected): expected_servers = [] for info in expected: expected_servers.append(SigningServer(*info)) assert sign.get_suitable_signing_servers(context.signing_servers, TEST_CERT_TYPE, formats) == expected_servers
def test_signreq_task_keyid(): input_bytes = b"hello world" fmt = "autograph_hash_only_mar384" s = SigningServer("https://autograph-hsm.dev.mozaws.net", "alice", "bob", [fmt], "autograph") req = sign.make_signing_req(input_bytes, s, fmt, "newkeyid") assert req[0]['keyid'] == 'newkeyid' assert req[0]['input'] == 'aGVsbG8gd29ybGQ='
async def test_sign_mar384_with_autograph_hash_returns_invalid_signature_length( context, mocker, to, expected ): open_mock = mocker.mock_open(read_data=b"0xdeadbeef") mocker.patch("builtins.open", open_mock, create=True) session_mock = mocker.MagicMock() session_mock.post.return_value.json.return_value = [ {"signature": base64.b64encode(b"0")} ] Session_mock = mocker.Mock() Session_mock.return_value.__enter__ = mocker.Mock(return_value=session_mock) Session_mock.return_value.__exit__ = mocker.Mock() mocker.patch("signingscript.sign.requests.Session", Session_mock, create=True) add_signature_mock = mocker.Mock() mocker.patch( "signingscript.sign.add_signature_block", add_signature_mock, create=True ) m_mock = mocker.MagicMock() m_mock.calculate_hashes.return_value = [[None, b"b64marhash"]] MarReader_mock = mocker.Mock() MarReader_mock.return_value.__enter__ = mocker.Mock(return_value=m_mock) MarReader_mock.return_value.__exit__ = mocker.Mock() mocker.patch("signingscript.sign.MarReader", MarReader_mock, create=True) context.task = {"scopes": ["project:releng:signing:cert:dep-signing"]} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", ["autograph_hash_only_mar384"], "autograph", ) ] } with pytest.raises(SigningScriptError): assert ( await sign.sign_mar384_with_autograph_hash( context, "from", "autograph_hash_only_mar384", to=to ) == expected ) open_mock.assert_called() add_signature_mock.assert_called() MarReader_mock.assert_called() m_mock.calculate_hashes.assert_called() session_mock.post.assert_called_with( "https://autograph-hsm.dev.mozaws.net/sign/hash", auth=mocker.ANY, json=[{"input": "YjY0bWFyaGFzaA=="}], )
async def test_sign_mar384_with_autograph_hash_returns_invalid_signature_length( context, mocker, to, expected): open_mock = mocker.mock_open(read_data=b'0xdeadbeef') mocker.patch('builtins.open', open_mock, create=True) session_mock = mocker.MagicMock() session_mock.post.return_value.json.return_value = [{ 'signature': base64.b64encode(b'0') }] Session_mock = mocker.Mock() Session_mock.return_value.__enter__ = mocker.Mock( return_value=session_mock) Session_mock.return_value.__exit__ = mocker.Mock() mocker.patch('signingscript.sign.requests.Session', Session_mock, create=True) add_signature_mock = mocker.Mock() mocker.patch('signingscript.sign.add_signature_block', add_signature_mock, create=True) m_mock = mocker.MagicMock() m_mock.calculate_hashes.return_value = [[None, b'b64marhash']] MarReader_mock = mocker.Mock() MarReader_mock.return_value.__enter__ = mocker.Mock(return_value=m_mock) MarReader_mock.return_value.__exit__ = mocker.Mock() mocker.patch('signingscript.sign.MarReader', MarReader_mock, create=True) context.task = {'scopes': ['project:releng:signing:cert:dep-signing']} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", ["autograph_hash_only_mar384"], "autograph") ] } with pytest.raises(SigningScriptError): assert await sign.sign_mar384_with_autograph_hash( context, 'from', 'autograph_hash_only_mar384', to=to) == expected open_mock.assert_called() add_signature_mock.assert_called() MarReader_mock.assert_called() m_mock.calculate_hashes.assert_called() session_mock.post.assert_called_with( 'https://autograph-hsm.dev.mozaws.net/sign/hash', auth=mocker.ANY, json=[{ 'input': 'YjY0bWFyaGFzaA==' }])
async def test_sign_file_autograph(context, mocker, to, expected): context.task = {'scopes': ['project:releng:signing:cert:dep-signing']} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer(*[ "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", ["autograph_mar"], "autograph" ]) ] } mocker.patch.object(sign, 'sign_file_with_autograph', new=noop_async) assert await sign.sign_file(context, 'from', 'autograph_mar', to=to) == expected
def test_signreq_task_omnija(): input_bytes = b"hello world" fmt = "autograph_omnija" s = SigningServer( "https://autograph-hsm.dev.mozaws.net", "alice", "bob", [fmt], "autograph" ) req = sign.make_signing_req( input_bytes, s, fmt, "newkeyid", extension_id="*****@*****.**" ) assert req[0]["keyid"] == "newkeyid" assert req[0]["input"] == "aGVsbG8gd29ybGQ=" assert req[0]["options"]["id"] == "*****@*****.**" assert isinstance(req[0]["options"]["cose_algorithms"], type([])) assert len(req[0]["options"]["cose_algorithms"]) == 1 assert req[0]["options"]["cose_algorithms"][0] == "ES256" assert req[0]["options"]["pkcs7_digest"] == "SHA256"
def test_signreq_task_omnija(): input_bytes = b"hello world" fmt = "autograph_omnija" s = SigningServer("https://autograph-hsm.dev.mozaws.net", "alice", "bob", [fmt], "autograph") req = sign.make_signing_req(input_bytes, s, fmt, "newkeyid", extension_id='*****@*****.**') assert req[0]['keyid'] == 'newkeyid' assert req[0]['input'] == 'aGVsbG8gd29ybGQ=' assert req[0]['options']['id'] == '*****@*****.**' assert isinstance(req[0]['options']['cose_algorithms'], type([])) assert len(req[0]['options']['cose_algorithms']) == 1 assert req[0]['options']['cose_algorithms'][0] == 'ES256' assert req[0]['options']['pkcs7_digest'] == 'SHA256'
async def test_sign_file_with_autograph_raises_http_error( context, mocker, to, expected ): open_mock = mocker.mock_open(read_data=b"0xdeadbeef") mocker.patch("builtins.open", open_mock, create=True) session_mock = mocker.MagicMock() post_mock_response = session_mock.post.return_value post_mock_response.raise_for_status.side_effect = ( sign.requests.exceptions.RequestException ) post_mock_response.json.return_value = [{"signed_file": "bW96aWxsYQ=="}] @contextmanager def session_context(): yield session_mock mocker.patch("signingscript.sign.requests.Session", session_context) async def fake_retry_async(func, args=(), attempts=5, sleeptime_kwargs=None): await func(*args) mocker.patch.object(sign, "retry_async", new=fake_retry_async) context.task = {"scopes": ["project:releng:signing:cert:dep-signing"]} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( *[ "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", ["autograph_mar"], "autograph", ] ) ] } with pytest.raises(sign.requests.exceptions.RequestException): await sign.sign_file_with_autograph(context, "from", "autograph_mar", to=to) open_mock.assert_called()
async def test_sign_file_with_autograph(context, mocker, to, expected, format, options): open_mock = mocker.mock_open(read_data=b'0xdeadbeef') mocker.patch('builtins.open', open_mock, create=True) session_mock = mocker.MagicMock() session_mock.post.return_value.json.return_value = [{ 'signed_file': 'bW96aWxsYQ==' }] Session_mock = mocker.Mock() Session_mock.return_value.__enter__ = mocker.Mock( return_value=session_mock) Session_mock.return_value.__exit__ = mocker.Mock() mocker.patch('signingscript.sign.requests.Session', Session_mock, create=True) context.task = {'scopes': ['project:releng:signing:cert:dep-signing']} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer(*[ "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", [format], "autograph" ]) ] } assert await sign.sign_file_with_autograph(context, '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])
async def test_integration_autograph_authenticode(context, tmpdir): context.config["authenticode_cert"] = os.path.join(TEST_DATA_DIR, "windows.crt") context.config["authenticode_timestamp_style"] = None context.config["authenticode_url"] = "https://example.com" context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( *[ "http://localhost:5500", "charlie", "abcdefghijklmnopqrstuvwxyz1234567890abcdefghijklmn", ["autograph_authenticode"], "autograph", ] ) ] } context.config["signing_server_config"] = _write_server_config(tmpdir) _copy_files_to_work_dir("windows.zip", context) context.task = _craft_task(["windows.zip"], signing_format="autograph_authenticode") await async_main(context)
async def test_sign_file_with_autograph(context, mocker, to, expected, format, options): open_mock = mocker.mock_open(read_data=b"0xdeadbeef") mocker.patch("builtins.open", open_mock, create=True) session_mock = mocker.MagicMock() session_mock.post.return_value.json.return_value = [{"signed_file": "bW96aWxsYQ=="}] Session_mock = mocker.Mock() Session_mock.return_value.__enter__ = mocker.Mock(return_value=session_mock) Session_mock.return_value.__exit__ = mocker.Mock() mocker.patch("signingscript.sign.requests.Session", Session_mock, create=True) context.task = {"scopes": ["project:releng:signing:cert:dep-signing"]} context.signing_servers = { "project:releng:signing:cert:dep-signing": [ SigningServer( *[ "https://autograph-hsm.dev.mozaws.net", "alice", "fs5wgcer9qj819kfptdlp8gm227ewxnzvsuj9ztycsx08hfhzu", [format], "autograph", ] ) ] } assert ( await sign.sign_file_with_autograph(context, "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] )