Class: WSDL::Security::Verifier
- Inherits:
-
Object
- Object
- WSDL::Security::Verifier
- Defined in:
- lib/wsdl/security/verifier.rb,
lib/wsdl/security/verifier/base.rb,
lib/wsdl/security/verifier/reference_validator.rb,
lib/wsdl/security/verifier/signature_validator.rb,
lib/wsdl/security/verifier/structure_validator.rb,
lib/wsdl/security/verifier/timestamp_validator.rb,
lib/wsdl/security/verifier/certificate_resolver.rb,
lib/wsdl/security/verifier/certificate_validator.rb,
lib/wsdl/security/verifier/element_position_validator.rb
Overview
Verifies XML Digital Signatures and timestamps in SOAP responses.
This class coordinates multiple validation steps to provide comprehensive security verification including:
- Structural Validation — Detects XML Signature Wrapping (XSW) attacks
- Certificate Resolution — Extracts or validates signing certificates
- Certificate Validation — Checks validity period and trust chain
- Reference Verification — Validates digests of signed elements
- Signature Verification — Cryptographic validation of SignatureValue
- Timestamp Validation — Freshness checks to prevent replay attacks
The verification process follows W3C XML Signature Best Practices, running structural checks before expensive cryptographic operations.
Defined Under Namespace
Classes: Base, CertificateResolver, CertificateValidator, ElementPositionValidator, ReferenceValidator, SignatureValidator, StructureValidator, TimestampValidator
Constant Summary collapse
- SecurityNS =
Local aliases for namespace constants
Constants::NS::Security
- SignatureNS =
Alias for XML Signature namespace constants.
Constants::NS::Signature
- VALID_ID_PATTERN =
Pattern for valid XML element IDs (NCName production). Inherited from Base which defines the canonical pattern.
Base::VALID_ID_PATTERN
Instance Attribute Summary collapse
-
#certificate ⇒ OpenSSL::X509::Certificate?
readonly
Certificate used for verification.
-
#errors ⇒ Array<String>
readonly
Errors encountered during verification.
Instance Method Summary collapse
-
#digest_algorithm ⇒ String?
Returns the digest algorithm URI from the first reference.
-
#initialize(xml, certificate: nil, trust_store: nil, check_validity: true, validate_timestamp: true, clock_skew: 300) ⇒ Verifier
constructor
Creates a new Verifier instance.
-
#signature_algorithm ⇒ String?
Returns the signature algorithm URI.
-
#signature_present? ⇒ Boolean
Returns whether a signature is present in the document.
-
#signed_element_ids ⇒ Array<String>
Returns the IDs of all signed elements.
-
#signed_elements ⇒ Array<String>
Returns the names of all signed elements.
-
#timestamp ⇒ Hash?
Returns the parsed timestamp information.
-
#timestamp_errors ⇒ Array<String>
Returns timestamp validation errors.
-
#timestamp_present? ⇒ Boolean
Returns whether a timestamp is present in the document.
-
#timestamp_valid? ⇒ Boolean
Returns whether the timestamp is valid (fresh).
-
#valid? ⇒ Boolean
Returns whether the signature (and timestamp, if enabled) is valid.
Constructor Details
#initialize(xml, certificate: nil, trust_store: nil, check_validity: true, validate_timestamp: true, clock_skew: 300) ⇒ Verifier
Creates a new Verifier instance.
rubocop:disable Metrics/ParameterLists
104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/wsdl/security/verifier.rb', line 104 def initialize(xml, certificate: nil, trust_store: nil, check_validity: true, validate_timestamp: true, clock_skew: 300) # rubocop:enable Metrics/ParameterLists @document = parse_document(xml) @provided_certificate = certificate @trust_store = trust_store @check_validity = check_validity = @clock_skew = clock_skew @errors = [] @certificate = normalize_certificate(certificate) if certificate end |
Instance Attribute Details
#certificate ⇒ OpenSSL::X509::Certificate? (readonly)
Returns certificate used for verification.
82 83 84 |
# File 'lib/wsdl/security/verifier.rb', line 82 def certificate @certificate end |
#errors ⇒ Array<String> (readonly)
Returns errors encountered during verification.
79 80 81 |
# File 'lib/wsdl/security/verifier.rb', line 79 def errors @errors end |
Instance Method Details
#digest_algorithm ⇒ String?
Returns the digest algorithm URI from the first reference.
173 174 175 |
# File 'lib/wsdl/security/verifier.rb', line 173 def digest_algorithm signed_info_node&.at_xpath('ds:Reference/ds:DigestMethod/@Algorithm', ns)&.value end |
#signature_algorithm ⇒ String?
Returns the signature algorithm URI.
166 167 168 |
# File 'lib/wsdl/security/verifier.rb', line 166 def signature_algorithm signature_validator&.signature_algorithm end |
#signature_present? ⇒ Boolean
Returns whether a signature is present in the document.
143 144 145 |
# File 'lib/wsdl/security/verifier.rb', line 143 def signature_present? structure_validator.signature_present? end |
#signed_element_ids ⇒ Array<String>
Returns the IDs of all signed elements.
150 151 152 153 154 |
# File 'lib/wsdl/security/verifier.rb', line 150 def signed_element_ids return [] unless signature_present? reference_validator.referenced_ids end |
#signed_elements ⇒ Array<String>
Returns the names of all signed elements.
159 160 161 |
# File 'lib/wsdl/security/verifier.rb', line 159 def signed_elements signed_element_ids.filter_map { |id| find_element_by_id(id)&.name } end |
#timestamp ⇒ Hash?
Returns the parsed timestamp information.
199 200 201 |
# File 'lib/wsdl/security/verifier.rb', line 199 def . end |
#timestamp_errors ⇒ Array<String>
Returns timestamp validation errors.
Each call re-evaluates timestamp freshness against the current time, ensuring errors reflect the latest state.
209 210 211 212 213 |
# File 'lib/wsdl/security/verifier.rb', line 209 def validator = validator.valid? validator.errors.dup end |
#timestamp_present? ⇒ Boolean
Returns whether a timestamp is present in the document.
180 181 182 |
# File 'lib/wsdl/security/verifier.rb', line 180 def . end |
#timestamp_valid? ⇒ Boolean
Returns whether the timestamp is valid (fresh).
Returns true if:
- No timestamp is present (timestamps are optional per spec)
- Timestamp is present and within acceptable time bounds
191 192 193 |
# File 'lib/wsdl/security/verifier.rb', line 191 def .valid? end |
#valid? ⇒ Boolean
Returns whether the signature (and timestamp, if enabled) is valid.
Phases 1-5 (structural, certificate, reference, and signature verification) are deterministic for a given document and are cached after the first evaluation.
Phase 6 (timestamp freshness) is time-dependent and is re-evaluated on every call so that a Verifier held across a time boundary correctly detects expiration.
128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/wsdl/security/verifier.rb', line 128 def valid? verify_crypto unless defined?(@crypto_valid) # Reset errors to the crypto baseline for this evaluation @errors = @crypto_errors.dup return false unless @crypto_valid # Phase 6: Timestamp freshness — always re-evaluate end |