Class: Safire::Protocols::UdapSignedMetadataValidator Private

Inherits:
Object
  • Object
show all
Includes:
URIValidation
Defined in:
lib/safire/protocols/udap_signed_metadata_validator.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Validates the signed_metadata JWT included in a UDAP server discovery response per UDAP Security STU2 §Signed Metadata Elements.

This is an internal class used by Udap and UdapMetadata. Do not instantiate it directly.

Constant Summary collapse

ALLOWED_ALGORITHMS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

%w[RS256].freeze
MAX_VALIDITY_SECONDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

365 * 24 * 3600
REQUIRED_ENDPOINT_CLAIMS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

%w[token_endpoint registration_endpoint].freeze
ENDPOINT_CLAIMS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

(REQUIRED_ENDPOINT_CLAIMS + %w[authorization_endpoint]).freeze

Instance Method Summary collapse

Constructor Details

#initialize(signed_metadata_jwt, unsigned_metadata) ⇒ UdapSignedMetadataValidator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of UdapSignedMetadataValidator.

Parameters:

  • signed_metadata_jwt (String)

    the compact-JWS value from the discovery response

  • unsigned_metadata (Hash)

    the raw (unsigned) discovery response body



25
26
27
28
# File 'lib/safire/protocols/udap_signed_metadata_validator.rb', line 25

def initialize(, )
  @jwt      = 
  @unsigned = .respond_to?(:to_h) ? .to_h.stringify_keys : {}
end

Instance Method Details

#signed_endpoint_claims(base_url:, trusted_anchors: [], crls: [], revocation_checker: nil, verify_chain: true) ⇒ Hash?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Validates the signed metadata JWT and returns the signed endpoint claims to merge over the unsigned discovery values.

Each validation failure is logged as a warning without raising, except for malformed certificate DER in x5c, which raises Errors::CertificateError because the input is unparseable rather than merely non-conformant.

Parameters:

  • base_url (String)

    the server's base URL; must equal the iss claim

  • trusted_anchors (Array<OpenSSL::X509::Certificate>) (defaults to: [])

    trust anchors for chain verification

  • crls (Array<OpenSSL::X509::CRL>) (defaults to: [])

    certificate revocation lists for fail-closed chain validation

  • revocation_checker (#call, nil) (defaults to: nil)

    custom revocation policy; must return true to pass

  • verify_chain (Boolean) (defaults to: true)

    when false, skips X.509 chain validation (dev/test only)

Returns:

  • (Hash, nil)

    signed endpoint claims to merge, or nil if validation fails

Raises:



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/safire/protocols/udap_signed_metadata_validator.rb', line 44

def signed_endpoint_claims(base_url:, trusted_anchors: [], crls: [], revocation_checker: nil, verify_chain: true)
  decoded = decode_and_validate_jwt
  return unless decoded

  payload, header = decoded
  leaf_cert = parse_leaf_cert(header['x5c'].first)
  trust_policy = { trusted_anchors:, crls:, revocation_checker:, verify_chain: }
  return unless signature_and_chain_valid?(header, leaf_cert, trust_policy)

  return unless claims_valid?(payload, base_url, leaf_cert)

  extract_endpoint_claims(payload)
end

#valid?(base_url:, trusted_anchors: [], crls: [], revocation_checker: nil, verify_chain: true) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns true when #signed_endpoint_claims succeeds.

Parameters:

  • base_url (String)

    the server's base URL

  • trusted_anchors (Array<OpenSSL::X509::Certificate>) (defaults to: [])

    trust anchors for chain verification

  • crls (Array<OpenSSL::X509::CRL>) (defaults to: [])

    certificate revocation lists for fail-closed chain validation

  • revocation_checker (#call, nil) (defaults to: nil)

    custom revocation policy; must return true to pass

  • verify_chain (Boolean) (defaults to: true)

    when false, skips X.509 chain validation

Returns:

  • (Boolean)


66
67
68
# File 'lib/safire/protocols/udap_signed_metadata_validator.rb', line 66

def valid?(base_url:, trusted_anchors: [], crls: [], revocation_checker: nil, verify_chain: true)
  signed_endpoint_claims(base_url:, trusted_anchors:, crls:, revocation_checker:, verify_chain:).present?
end