Index: tests/conftest.py
===================================================================
--- tests/conftest.py	(revision 376e21b3865f5979339d98773fc106b2673d35a9)
+++ tests/conftest.py	(revision d7499cad8c700086cf682c7c11caf3a253c4fcc6)
@@ -1,8 +1,11 @@
 # tests/stubs/single_choice_question.py
+from dataclasses import dataclass, field
 import pytest
+import platform
+from pathlib import Path
 from datetime import datetime
-from dataclasses import dataclass, field
 from typing import List
-from flexoentity import FlexOID, FlexoEntity, EntityType, EntityState, Domain
+from flexoentity import FlexOID, FlexoEntity, EntityType, EntityState, Domain, get_signing_backend, CertificateReference
+
 
 @pytest.fixture
@@ -98,2 +101,84 @@
     q._update_fingerprint()
     return q
+
+SYSTEM = platform.system()
+
+
+# ─────────────────────────────────────────────────────────────
+# Basic test data directory + PEM test files
+# ─────────────────────────────────────────────────────────────
+
+@pytest.fixture(scope="session")
+def test_data_dir():
+    return Path(__file__).parent / "data"
+
+
+@pytest.fixture(scope="session")
+def test_cert(test_data_dir):
+    return test_data_dir / "testcert.pem"
+
+
+@pytest.fixture(scope="session")
+def test_key(test_data_dir):
+    return test_data_dir / "testkey.pem"
+
+
+# ─────────────────────────────────────────────────────────────
+# CertificateReference fixtures for each platform
+# ─────────────────────────────────────────────────────────────
+
+@pytest.fixture(scope="session")
+def cert_ref_linux(test_cert, test_key):
+    """Linux: Uses OpenSSL CMS with PEM cert + PEM private key."""
+    return CertificateReference(
+        platform="LINUX",
+        identifier=str(test_cert),
+        private_key_path=str(test_key),
+        public_cert_path=str(test_cert),
+    )
+
+
+@pytest.fixture(scope="session")
+def cert_ref_macos(test_cert):
+    """
+    macOS: Uses Keychain identity with Common Name (CN).
+    The test cert must be imported into the login keychain with CN=FlexOSignerTest.
+    """
+    return CertificateReference(
+        platform="MACOS",
+        identifier="FlexOSignerTest",
+        public_cert_path=str(test_cert),
+    )
+
+@pytest.fixture(scope="session")
+def backend(test_cert, test_key):
+    """Return the correct backend for the current platform."""
+
+    if SYSTEM == "Linux":
+        cert_ref = CertificateReference(
+            platform="LINUX",
+            identifier=str(test_cert),
+            private_key_path=str(test_key),
+            public_cert_path=str(test_cert),
+        )
+
+    elif SYSTEM == "Darwin":
+        cert_ref = CertificateReference(
+            platform="MACOS",
+            identifier="FlexOSignerTest",
+            public_cert_path=str(test_cert),
+        )
+
+    elif SYSTEM == "Windows":
+        pytest.skip("Windows signing tests not implemented yet")
+
+    else:
+        pytest.skip(f"Unsupported platform: {SYSTEM}")
+
+    try:
+        backend = get_signing_backend(cert_ref)
+        # sanity check: ensures cert exists and command is available
+        _ = backend.certificate_thumbprint
+        return backend
+    except Exception as e:
+        pytest.skip(f"Backend unavailable or misconfigured: {e}")
Index: tests/data/testcert.pem
===================================================================
--- tests/data/testcert.pem	(revision d7499cad8c700086cf682c7c11caf3a253c4fcc6)
+++ tests/data/testcert.pem	(revision d7499cad8c700086cf682c7c11caf3a253c4fcc6)
@@ -0,0 +1,31 @@
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIUChNYApno8zSGa2I1CAigI6Wm5JIwDQYJKoZIhvcNAQEL
+BQAwRTEYMBYGA1UEAwwPRmxleE9TaWduZXJUZXN0MQ4wDAYDVQQKDAVGbGV4TzEM
+MAoGA1UECwwDRGV2MQswCQYDVQQGEwJERTAeFw0yNTExMjQxMzIwMDhaFw0zNTEx
+MjIxMzIwMDhaMEUxGDAWBgNVBAMMD0ZsZXhPU2lnbmVyVGVzdDEOMAwGA1UECgwF
+RmxleE8xDDAKBgNVBAsMA0RldjELMAkGA1UEBhMCREUwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQDD/z/PnDWjAh4Vpp80MzsxD1K6vgsEV8IEsAa31a5V
+4+0BX9RfsmfNkHMR6iwVQStuOJtdBj9VivETx66DTMII6kL0l+HURMu1zv1GNwUz
+ZT4eKIbEc+uUI8bAs+Unoi42LWhKcgQV8lsi5DHsFkio7/pRPp06JHCV4fPy4aBY
+03/nOUlAC9GGfpai7wtuc8peeVDBIWJWOTrfm8hlekkMBKSAA2uqoA0ONqZzkNXd
+ZI5r0Cb0U7yaNISoo0wHG6CsnXO+CXwARwzc0iQdN4CLzmlO3kYTBbiCMnWexNzt
+4xmKWDk0JPL2hr4EqqJiAd/Fvu9WQwSjtHQMUlfvafgwK9B8RHBIuXv7W38QVPoR
+lk22o9cbfGznmsfGzoHB7wc8PR4msj8USVf4naagG/XyCpnUxXdonatxsbaS0jpi
+9ItJ/o9jTxJT5dzVARzKUZnRDR2Mma4JuBf9b+9/VTXwOJAML+4Il43UOC+ZU2Mt
+4vlJsnEIHboIgDsYkIb9xh++K62YHxrh/bDOAr91kDovBsMVVCFDOrHh2m1jkPeE
+54jBousXe7aKW/sgjwO6g2nDA+hiIE6TffmM5m7b93s7YwuoiGI+S6J3XluEHNRv
+rzZ3GRG3YW2wdgfJezm7Et6FL9jS6AmvowGFgTXcJTh1jnxkuBt/U/0cgQtFQR7F
+PwIDAQABo1MwUTAdBgNVHQ4EFgQUwQFLZ303o+o6mA/zzCKDtne/jSEwHwYDVR0j
+BBgwFoAUwQFLZ303o+o6mA/zzCKDtne/jSEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
+hkiG9w0BAQsFAAOCAgEAQyzDHm8iXLCWIimclnG3vhweWf7pNiG9FkNaJo83lfIs
+skRB7tfvC1P1KNBSpKxiogPc9iIWMj48oRcRYPhrCLrPApZtViH32MmcFFizECxH
+sHjLhy2Xr4HpqW1nF3pGC3BSt0uphiIjjAxFF58Ah/LkUjftMyao6PQX/OZOqzEJ
+uIUCmsgZJuGQ0EwwAkua8eP6DyTfemg3YgqgB1BlZET4fQ7mfQpPv6hZgrGWYB5o
+FGUPRWhpE6jo18s1zUchFepW3AfYqi2Bt52vhJKu8MLbCCwM+tyjT2jcrXRbP9Gw
+dpsjrLkCY2XDBjgRJFlprFUhfPMlMH/XidVke7bBA01jnxxbsOL/FxMLFGyNW1WR
+DNbIVgTI9lTwrg88M6erJVPEfjBkZuAAigklMmOCjVAXDORdjvjhzu2HypvLXA/1
+ffX3CS8XDeLDu8i0UpxOVlPr5ax9pNjQ6LtznBLThIQ/3N3NkURLgtbs+gHMG5lY
+wNwAbMmCp6wi6QIJEOjKt5j/QEZFklKao1h8BjRvTK0vCrJvbqBRUi9bEbYzP+Z1
+6OQDKsglPjxZE5OgSbgStgYgmiZhjon45BDmn2TejYVcxdrVPIeHBc1E55Q/vrxm
+v4BVI1OJgW4Qj8SQTGEwJLWhy2FQvwaOqkjGBtItfC+qtkX2yRupOhtUI3v7f8U=
+-----END CERTIFICATE-----
Index: tests/data/testkey.pem
===================================================================
--- tests/data/testkey.pem	(revision d7499cad8c700086cf682c7c11caf3a253c4fcc6)
+++ tests/data/testkey.pem	(revision d7499cad8c700086cf682c7c11caf3a253c4fcc6)
@@ -0,0 +1,52 @@
+-----BEGIN PRIVATE KEY-----
+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
+COTzylGJM5V2427v9SqnT+ic1kCvejw=
+-----END PRIVATE KEY-----
Index: tests/test_signing.py
===================================================================
--- tests/test_signing.py	(revision d7499cad8c700086cf682c7c11caf3a253c4fcc6)
+++ tests/test_signing.py	(revision d7499cad8c700086cf682c7c11caf3a253c4fcc6)
@@ -0,0 +1,63 @@
+import platform
+import pytest
+from uuid import uuid4
+from flexoentity import FlexOID, EntityState, EntityType, FlexoSignature, get_signing_backend
+
+def test_sign_and_verify_linux(backend):
+    data = b"Hello Flex-O signing!"
+
+    signature = backend.sign(data)
+    assert isinstance(signature, bytes)
+    assert len(signature) > 20      # sanity check
+
+    assert backend.verify(data, signature) is True
+
+def test_sign_and_verify_macos(backend):
+    data = b"Hello Flex-O signing!"
+
+    signature = backend.sign(data)
+    assert isinstance(signature, bytes)
+    assert len(signature) > 20      # sanity check
+
+    assert backend.verify(data, signature) is True
+
+def test_verify_fails_with_wrong_data(backend):
+    data = b"Original Data"
+    wrong_data = b"Tampered Data"
+
+    signature = backend.sign(data)
+
+    assert backend.verify(data, signature) == True
+    assert backend.verify(wrong_data, signature) == False
+
+def test_verify_fails_with_invalid_signature(backend):
+    data = b"Hello world"
+    invalid_sig = b"\x00\x01\x02garbagepkcs7data"
+
+    assert backend.verify(data, invalid_sig) is False
+
+def test_signature_entity_create_and_verify(backend):
+    entity_id = FlexOID.safe_generate(
+        domain_id="TEST",
+        entity_type=EntityType.ATTESTATION.value,
+        state=EntityState.DRAFT.value,
+        text="abc",
+        version=1,
+    )
+    signer = uuid4()
+    data = b"Hello Entity Signing"
+
+    sig = FlexoSignature.create_signed(
+        data=data,
+        entity=entity_id,
+        signer_id=signer,
+        backend=backend,
+    )
+
+    assert isinstance(sig.signature_data, str)
+    assert sig.signature_type == "PKCS7-DER"
+    assert sig.signed_entity == entity_id
+    assert sig.signer_id == signer
+    assert sig.certificate_thumbprint != ""
+
+    assert sig.verify(data, backend) is True
