async def test_sign_resign(
    image_config: ImageConfig,
    image_config_signed: ImageConfig,
    config_digest_canonical: str,
):
    """Test configuration resigning for signed and unsigned configurations."""

    signer = FakeSigner()
    assert (
        await image_config.sign(signer, SignatureTypes.RESIGN) == signer.signature_value
    )
    assert (
        await image_config_signed.sign(signer, SignatureTypes.RESIGN)
        == signer.signature_value
    )

    # Previously unsigned configurations should now contain the new signature.
    assert b"BEGIN FAKE SIGNATURE" in image_config.get_bytes()
    signatures = image_config.get_signature_list()
    assert len(signatures) == 1
    assert signatures[0]["digest"] == config_digest_canonical
    assert signatures[0]["signature"] == signer.signature_value

    # Previously signed configurations should now contain (only) the new signature.
    assert b"BEGIN FAKE SIGNATURE" in image_config_signed.get_bytes()
    assert b"BEGIN PGP SIGNATURE" not in image_config_signed.get_bytes()
    signatures_signed = image_config_signed.get_signature_list()
    assert len(signatures_signed) == 1
    assert signatures[0]["digest"] == config_digest_canonical
    assert signatures[0]["signature"] == signer.signature_value
Esempio n. 2
0
async def test_sign_resign(
    config_digest_canonical: str,
    gnupg_keypair: GnuPGKeypair,
    image_config: ImageConfig,
    image_config_signed: ImageConfig,
):
    """Test configuration resigning for signed and unsigned configurations."""

    signer = GPGSigner(
        keyid=gnupg_keypair.keyid,
        passphrase=gnupg_keypair.passphrase,
        homedir=gnupg_keypair.gnupg_home,
    )
    sig = await image_config.sign(signer, SignatureTypes.RESIGN)
    assert "PGP SIGNATURE" in sig
    sig_signed = await image_config_signed.sign(signer, SignatureTypes.RESIGN)
    assert "PGP SIGNATURE" in sig_signed

    # Previously unsigned configurations should now contain the new signature.
    signatures = image_config.get_signature_list()
    assert len(signatures) == 1
    assert signatures[0].digest == config_digest_canonical
    assert signatures[0].signature == sig

    # Previously signed configurations should now contain (only) the new signature.
    assert image_config_signed.get_bytes().count(b"BEGIN PGP SIGNATURE") == 1
    signatures_signed = image_config_signed.get_signature_list()
    assert len(signatures_signed) == 1
    assert signatures[0].digest == config_digest_canonical
    assert signatures[0].signature == sig_signed
async def test_sign_endorse(
    image_config: ImageConfig,
    image_config_signed: ImageConfig,
    config_digest_canonical: str,
    config_digest_signed_canonical: str,
    signature: str,
):
    """Test configuration endorsement for signed and unsigned configurations."""

    signer = FakeSigner()
    assert (
        await image_config.sign(signer, SignatureTypes.ENDORSE)
        == signer.signature_value
    )
    assert (
        await image_config_signed.sign(signer, SignatureTypes.ENDORSE)
        == signer.signature_value
    )

    # Previously unsigned configurations should now contain the new signature.
    assert b"BEGIN FAKE SIGNATURE" in image_config.get_bytes()
    signatures = image_config.get_signature_list()
    assert len(signatures) == 1
    assert signatures[0]["digest"] == config_digest_canonical
    assert signatures[0]["signature"] == signer.signature_value

    # Previously signed configurations should now contain the original signature(s) and the new signature.
    assert b"BEGIN FAKE SIGNATURE" in image_config_signed.get_bytes()
    assert b"BEGIN PGP SIGNATURE" in image_config_signed.get_bytes()
    signatures_signed = image_config_signed.get_signature_list()
    assert len(signatures_signed) == 2
    assert signatures_signed[0]["digest"] == config_digest_canonical
    assert signatures_signed[0]["signature"] == signature
    assert signatures_signed[1]["digest"] == config_digest_signed_canonical
    assert signatures_signed[1]["signature"] == signer.signature_value
Esempio n. 4
0
async def test_sign_endorse(
    config_digest_canonical: str,
    config_digest_signed_canonical: str,
    gnupg_keypair: GnuPGKeypair,
    image_config: ImageConfig,
    image_config_signed: ImageConfig,
    signature: str,
):
    """Test configuration endorsement for signed and unsigned configurations."""

    signer = GPGSigner(
        keyid=gnupg_keypair.keyid,
        passphrase=gnupg_keypair.passphrase,
        homedir=gnupg_keypair.gnupg_home,
    )
    sig = await image_config.sign(signer, SignatureTypes.ENDORSE)
    assert "PGP SIGNATURE" in sig
    sig_signed = await image_config_signed.sign(signer, SignatureTypes.ENDORSE)
    assert "PGP SIGNATURE" in sig_signed

    # Previously unsigned configurations should now contain the new signature.
    signatures = image_config.get_signature_list()
    assert len(signatures) == 1
    assert signatures[0].digest == config_digest_canonical
    assert signatures[0].signature == sig

    # Previously signed configurations should now contain the original signature(s) and the new signature.
    assert image_config_signed.get_bytes().count(b"BEGIN PGP SIGNATURE") == 2
    signatures_signed = image_config_signed.get_signature_list()
    assert len(signatures_signed) == 2
    assert signatures_signed[0].digest == config_digest_canonical
    assert signatures_signed[0].signature == signature
    assert signatures_signed[1].digest == config_digest_signed_canonical
    assert signatures_signed[1].signature == sig_signed
def test_clear_signature_list(
    image_config: ImageConfig, image_config_signed: ImageConfig
):
    """Test signature data parsing for signed and unsigned configurations."""
    image_config_signed.clear_signature_list()
    assert not image_config_signed.get_signature_list()

    image_config.clear_signature_list()
    signatures_unsigned = image_config.get_signature_list()
    assert not signatures_unsigned
Esempio n. 6
0
async def test_verify_signatures_manipulated_signatures(
    gnupg_keypair: GnuPGKeypair, image_config: ImageConfig
):
    """Test that signature verification detects manipulated signatures."""

    signer = GPGSigner(
        keyid=gnupg_keypair.keyid,
        passphrase=gnupg_keypair.passphrase,
        homedir=gnupg_keypair.gnupg_home,
    )

    # Add a single signature ...
    await image_config.sign(signer)
    response = await image_config.verify_signatures(
        signer_kwargs={GPGSigner.__name__: {"homedir": gnupg_keypair.gnupg_home}}
    )
    assert response.results[0].valid

    # Modify the digest value of the (first) signature ...
    signatures = image_config.get_signature_list()
    temp = deepcopy(signatures)
    temp[0] = ImageConfigSignatureEntry(
        digest=FormattedSHA256.calculate(b"tampertampertamper"),
        signature=temp[0].signature,
    )
    image_config.set_signature_list(temp)

    # An exception should be raised if digest value from the signature does not match the canonical digest of the image
    # configuration (without any signatures).
    with pytest.raises(DigestMismatchError) as exception:
        await image_config.verify_signatures()
    assert str(exception.value).startswith("Image config canonical digest mismatch:")

    # Restore the unmodified signature and endorse ...
    image_config.set_signature_list(signatures)
    await image_config.sign(signer, SignatureTypes.ENDORSE)
    response = await image_config.verify_signatures(
        signer_kwargs={GPGSigner.__name__: {"homedir": gnupg_keypair.gnupg_home}}
    )
    assert response.results[0].valid

    # Modify the digest value of the second signature ...
    signatures = image_config.get_signature_list()
    temp = deepcopy(signatures)
    temp[1] = ImageConfigSignatureEntry(
        digest=FormattedSHA256.calculate(b"tampertampertamper"),
        signature=temp[1].signature,
    )
    image_config.set_signature_list(temp)

    # An exception should be raised if digest value from the signature does not match the canonical digest of the image
    # configuration (including the first signature).
    with pytest.raises(DigestMismatchError) as exception:
        await image_config.verify_signatures()
    assert str(exception.value).startswith("Image config canonical digest mismatch:")
async def test_verify_signatures_manipulated_signatures(image_config: ImageConfig):
    """Test that signature verification detects manipulated signatures."""

    # Add a single signature ...
    signer = FakeSigner()
    assert await image_config.sign(signer) == signer.signature_value

    # Replace the class method for resolving signature providers ...
    original_method = Signer.for_signature
    Signer.for_signature = _signer_for_signature

    # Sanity check
    response = await image_config.verify_signatures()
    assert response["results"][0]["valid"] is True

    # Modify the digest value of the (first) signature ...
    signatures = image_config.get_signature_list()
    temp = deepcopy(signatures)
    temp[0]["digest"] = "tampertampertamper"
    image_config.set_signature_list(temp)

    # An exception should be raised if digest value from the signature does not match the canonical digest of the image
    # configuration (without any signatures).
    with pytest.raises(DigestMismatchError) as exception:
        await image_config.verify_signatures()
    assert str(exception.value).startswith("Image config canonical digest mismatch:")

    # Restore the unmodified signature and endorse ...
    image_config.set_signature_list(signatures)
    assert (
        await image_config.sign(signer, SignatureTypes.ENDORSE)
        == signer.signature_value
    )

    # Sanity check
    response = await image_config.verify_signatures()
    assert response["results"][0]["valid"] is True

    # Modify the digest value of the second signature ...
    signatures = image_config.get_signature_list()
    temp = deepcopy(signatures)
    temp[1]["digest"] = "tampertampertamper"
    image_config.set_signature_list(temp)

    # An exception should be raised if digest value from the signature does not match the canonical digest of the image
    # configuration (including the first signature).
    with pytest.raises(DigestMismatchError) as exception:
        await image_config.verify_signatures()
    assert str(exception.value).startswith("Image config canonical digest mismatch:")

    # Restore the original class method
    Signer.for_signature = original_method
def test_get_signature_list(
    image_config: ImageConfig,
    image_config_signed: ImageConfig,
    config_digest_canonical: str,
    signature: str,
):
    """Test signature data parsing for signed and unsigned configurations."""
    signatures_signed = image_config_signed.get_signature_list()
    assert len(signatures_signed) == 1
    assert signatures_signed[0]["digest"] == config_digest_canonical
    assert signatures_signed[0]["signature"] == signature

    signatures_unsigned = image_config.get_signature_list()
    assert not signatures_unsigned
async def test_minimal():
    """Test minimal image configuration (for non-conformant labels)k."""

    # Note: At a minimum, [Cc]onfig key must exist with non-null value
    image_config = ImageConfig(b'{"Config":{}}')
    config_digest_canonical = image_config.get_digest_canonical()
    signer = FakeSigner()
    assert await image_config.sign(signer) == signer.signature_value

    # A signature should always be able to be added ...
    assert b"BEGIN FAKE SIGNATURE" in image_config.get_bytes()
    signatures = image_config.get_signature_list()
    assert len(signatures) == 1
    assert signatures[0]["digest"] == config_digest_canonical
    assert signatures[0]["signature"] == signer.signature_value
Esempio n. 10
0
async def test_minimal(gnupg_keypair: GnuPGKeypair):
    """Test minimal image configuration (for non-conformant labels)k."""

    signer = GPGSigner(
        keyid=gnupg_keypair.keyid,
        passphrase=gnupg_keypair.passphrase,
        homedir=gnupg_keypair.gnupg_home,
    )

    # Note: At a minimum, [Cc]onfig key must exist with non-null value
    image_config = ImageConfig(b'{"Config":{}}')
    config_digest_canonical = image_config.get_digest_canonical()
    signature = await image_config.sign(signer)
    assert "PGP SIGNATURE" in signature

    # A signature should always be able to be added ...
    assert b"BEGIN PGP SIGNATURE" in image_config.get_bytes()
    signatures = image_config.get_signature_list()
    assert len(signatures) == 1
    assert signatures[0].digest == config_digest_canonical
    assert signatures[0].signature == signature