VerificationResult Class
Overview
The VerificationResult
class contains the results of cryptographic signature verification operations. It provides information about whether signatures are valid, who signed the data, and additional verification details.
Package: keychain.gateway
from keychain.gateway import VerificationResult
Class Definition
class VerificationResult(KeychainObject):
"""Contains the results of signature verification operations."""
Constructor
def __init__(self, c_pointer) -> None
Initialize a VerificationResult object with a C library pointer. VerificationResult objects are typically created through verification methods in Gateway
, Persona
, or Contact
classes rather than direct construction.
Parameters:
-
c_pointer
- C library pointer to the verification result object
Status Methods
is_verified()
def is_verified(self) -> bool
Check if the signature verification was successful.
Returns: True
if the signature is valid, False
otherwise
Example:
# Verify signed data
result = gateway.verify(persona, signed_data)
if result.is_verified():
print("✓ Signature is valid")
else:
print("✗ Signature verification failed")
signer_is_known()
def signer_is_known(self) -> bool
Check if the signer is known (exists in the verifying persona’s contact list).
Returns: True
if the signer is a known contact, False
otherwise
Example:
result = gateway.verify(persona, signed_data)
if result.is_verified():
if result.signer_is_known():
print("Signature from known contact")
else:
print("Signature from unknown signer")
Signer Information
signer()
def signer(self) -> Optional[Contact]
Get the contact object representing the signer (if known).
Returns: Contact
object if signer is known, None
otherwise
Example:
result = gateway.verify(persona, signed_data)
if result.is_verified() and result.signer_is_known():
signer_contact = result.signer()
if signer_contact:
print(f"Signed by: {signer_contact.name}.{signer_contact.subname}")
print(f"Signer DID: {signer_contact.did}")
Attestation Information
attestation
@property
def attestation(self) -> Optional[Attestation]
Get the attestation object from the verification result.
Returns: Attestation
object if available, None
otherwise
Example:
result = gateway.verify(persona, signed_data)
if result.is_verified():
attestation = result.attestation
if attestation:
print("Attestation information available")
# Access attestation details
Complete Verification Examples
Basic Verification Workflow
from keychain.gateway import Gateway
from keychain.constants import SecurityLevel, DataType
from keychain.core.serialized_data import SerializedData
# Initialize gateway
settings = Gateway.init("keychain.config")
gateway = Gateway(settings)
try:
# Get or create personas
alice = gateway.find_persona("alice", "company.com")
bob = gateway.find_persona("bob", "company.com")
# Alice adds Bob as a contact
bob_contact = alice.add_contact("bob", "company.com", bob.did)
# Bob adds Alice as a contact
alice_contact = bob.add_contact("alice", "company.com", alice.did)
# Alice signs a document
document = SerializedData.from_string(
"Important contract terms",
DataType.UTF8_STRING
)
signed_document = alice.sign(
cleartext=document,
is_approval=True
)
print("Document signed by Alice")
# Bob verifies Alice's signature
result = bob.verify(signed_document)
# Analyze verification result
print("\n=== Verification Result ===")
print(f"Signature valid: {result.is_verified()}")
print(f"Signer known: {result.signer_is_known()}")
if result.is_verified():
if result.signer_is_known():
signer = result.signer()
if signer:
print(f"Signed by: {signer.name}.{signer.subname}")
print(f"Signer DID: {signer.did}")
print(f"Signer algorithms: {signer.signature_algorithm}")
else:
print("Signature is valid but signer is unknown")
# Check attestation details
attestation = result.attestation
if attestation:
print("Attestation information is available")
finally:
Gateway.close()
Advanced Verification Analysis
from keychain.gateway import Gateway
from keychain.core.tag_set import TagSet
import time
def analyze_verification_result(result: VerificationResult, operation_name: str):
"""Provide detailed analysis of verification result."""
print(f"\n=== Verification Analysis: {operation_name} ===")
# Basic verification status
is_valid = result.is_verified()
is_known = result.signer_is_known()
print(f"Signature Status: {'VALID' if is_valid else 'INVALID'}")
print(f"Signer Status: {'KNOWN' if is_known else 'UNKNOWN'}")
if not is_valid:
print("⚠️ Signature verification failed!")
print(" - Document may have been tampered with")
print(" - Signature may be forged")
print(" - Cryptographic keys may be invalid")
return False
# Analyze signer information
if is_known:
signer = result.signer()
if signer:
print(f"✓ Verified signature from known contact:")
print(f" Name: {signer.name}.{signer.subname}")
print(f" DID: {signer.did}")
print(f" Encryption: {signer.encryption_algorithm} ({signer.encryption_key_size} bits)")
print(f" Signature: {signer.signature_algorithm} ({signer.signature_key_size} bits)")
print(f" Contact Status: Known={signer.is_known}, Mature={signer.is_mature}")
else:
print("⚠️ Signer marked as known but contact object unavailable")
else:
print("⚠️ Valid signature from unknown signer")
print(" - Signer not in contact list")
print(" - May need to add signer as a contact")
# Analyze attestation
attestation = result.attestation
if attestation:
print("✓ Attestation information available")
# Note: Attestation methods would depend on actual implementation
else:
print("ℹ️ No attestation information available")
return is_valid and is_known
def comprehensive_verification_workflow():
"""Demonstrate comprehensive verification workflows."""
settings = Gateway.init("keychain.config")
gateway = Gateway(settings)
try:
# Setup personas and contacts
alice = gateway.create_persona("alice", "company.com", SecurityLevel.HIGH, True)
bob = gateway.create_persona("bob", "company.com", SecurityLevel.HIGH, True)
charlie = gateway.create_persona("charlie", "partner.org", SecurityLevel.MEDIUM, True)
# Wait for maturity
for persona in [alice, bob, charlie]:
if not persona.is_mature():
persona.await_maturity()
# Setup contact relationships
alice.add_contact("bob", "company.com", bob.did)
alice.add_contact("charlie", "partner.org", charlie.did)
bob.add_contact("alice", "company.com", alice.did)
bob.add_contact("charlie", "partner.org", charlie.did)
charlie.add_contact("alice", "company.com", alice.did)
# Note: Charlie doesn't have Bob as a contact
# Create different types of signed data
document = SerializedData.from_string("Contract Agreement", DataType.UTF8_STRING)
# 1. Alice signs a document
alice_signed = alice.sign(document, is_approval=True)
# 2. Create a credential signed by Alice
claims = TagSet()
claims.set_tag_value("", "role", "Manager")
claims.set_tag_value("", "department", "Engineering")
now = int(time.time() * 1000)
one_year = now + (365 * 24 * 60 * 60 * 1000)
credential = alice.create_credential(
credential_id="mgr-001",
credential_type="ManagerCredential",
subject_id="did:keychain:bob.company.com",
start_timestamp=now,
end_timestamp=one_year,
claims=claims
)
print("=== Verification Test Scenarios ===")
# Scenario 1: Bob verifies Alice's signature (known signer)
print("\n1. Bob verifies Alice's document signature:")
result1 = bob.verify(alice_signed)
success1 = analyze_verification_result(result1, "Known Signer Verification")
# Scenario 2: Bob verifies Alice's credential (known issuer)
print("\n2. Bob verifies Alice's credential:")
result2 = bob.verify(credential)
success2 = analyze_verification_result(result2, "Credential Verification")
# Scenario 3: Charlie verifies Alice's signature (known signer)
print("\n3. Charlie verifies Alice's document signature:")
result3 = charlie.verify(alice_signed)
success3 = analyze_verification_result(result3, "Cross-Organization Verification")
# Scenario 4: Bob signs and Charlie verifies (unknown signer)
bob_signed = bob.sign(document, is_approval=False)
print("\n4. Charlie verifies Bob's signature (unknown signer):")
result4 = charlie.verify(bob_signed)
success4 = analyze_verification_result(result4, "Unknown Signer Verification")
# Summary
print(f"\n=== Verification Summary ===")
scenarios = [
("Bob → Alice (known)", success1),
("Bob → Alice credential", success2),
("Charlie → Alice (known)", success3),
("Charlie → Bob (unknown)", success4)
]
for scenario, success in scenarios:
status = "✓ TRUSTED" if success else "⚠️ UNTRUSTED"
print(f" {scenario}: {status}")
# Security recommendations
print(f"\n=== Security Recommendations ===")
if not success4:
print("• Add Bob as a contact for Charlie to enable trusted verification")
print("• Always check both is_verified() and signer_is_known() for security-critical operations")
print("• Regularly refresh contact information to maintain up-to-date PKI data")
print("• Use verification results to make authorization decisions")
finally:
Gateway.close()
if __name__ == "__main__":
comprehensive_verification_workflow()
Verification Result Patterns
def verification_result_patterns():
"""Demonstrate common verification result patterns."""
def handle_verification_result(result: VerificationResult, operation: str) -> bool:
"""Standard verification result handling pattern."""
if not result.is_verified():
print(f"❌ {operation}: Signature verification FAILED")
return False
if not result.signer_is_known():
print(f"⚠️ {operation}: Valid signature from UNKNOWN signer")
print(" Consider adding signer as a contact for future operations")
return False # Or True, depending on security policy
signer = result.signer()
if signer:
print(f"✅ {operation}: Valid signature from {signer.name}.{signer.subname}")
return True
else:
print(f"⚠️ {operation}: Signer marked as known but unavailable")
return False
# Example usage patterns
settings = Gateway.init("keychain.config")
gateway = Gateway(settings)
try:
# Setup test environment
alice = gateway.find_persona("alice", "company.com")
bob = gateway.find_persona("bob", "company.com")
document = SerializedData.from_string("Test document", DataType.UTF8_STRING)
signed_doc = alice.sign(document)
# Pattern 1: Simple verification
result = bob.verify(signed_doc)
if handle_verification_result(result, "Document verification"):
print("✓ Document is trusted - proceed with operation")
else:
print("✗ Document is not trusted - abort operation")
# Pattern 2: Verification with fallback
result = bob.verify(signed_doc)
if result.is_verified():
if result.signer_is_known():
print("✅ Fully trusted signature")
proceed = True
else:
print("⚠️ Valid but unknown signer - requesting manual approval")
# In real app, might prompt user or check whitelist
proceed = False # Or prompt user
else:
print("❌ Invalid signature - rejecting")
proceed = False
# Pattern 3: Verification with signer details
result = bob.verify(signed_doc)
if result.is_verified() and result.signer_is_known():
signer = result.signer()
if signer:
# Make decisions based on signer identity
if signer.name == "alice" and signer.subname == "company.com":
print("✅ Authorized signer - high trust level")
elif signer.subname == "company.com":
print("✅ Internal signer - medium trust level")
else:
print("⚠️ External signer - low trust level")
return True
finally:
Gateway.close()
Error Handling
VerificationResult methods generally don’t raise exceptions, but the underlying verification operations can fail:
Example:
from keychain.exceptions import KeychainSecurityError, KeychainValidationError
try:
# Verification operation
result = gateway.verify(persona, signed_data)
# Safe to check result properties
if result.is_verified():
print("Signature is valid")
if result.signer_is_known():
signer = result.signer()
# signer might be None even if signer_is_known() is True
if signer:
print(f"Signed by: {signer.name}.{signer.subname}")
except KeychainSecurityError as e:
print(f"Cryptographic verification failed: {e}")
except KeychainValidationError as e:
print(f"Input validation failed: {e}")
except Exception as e:
print(f"Unexpected error during verification: {e}")
Security Considerations
-
Always check both conditions: Verify both
is_verified()
andsigner_is_known()
for security-critical operations -
Handle unknown signers: Decide how to handle valid signatures from unknown signers based on your security policy
-
Null signer objects: Even if
signer_is_known()
returnsTrue
, thesigner()
method might returnNone
-
Attestation analysis: Examine attestation objects when available for additional verification context
See Also
-
Gateway Class - Verification operations
-
Persona Class - Persona verification methods
-
Contact Class - Signer information
-
Attestation Class - Signature attestations
-
Exception Classes - Error handling