Example #1
0
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')
Example #2
0
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')
Example #3
0
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
Example #5
0
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
Example #6
0
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='
Example #7
0
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=="}],
    )
Example #8
0
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=='
        }])
Example #9
0
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
Example #10
0
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"
Example #11
0
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'
Example #12
0
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()
Example #13
0
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)
Example #15
0
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]
    )