Module: BSV::Auth::ValidateCertificates
- Defined in:
- lib/bsv/auth/validate_certificates.rb
Overview
Utility module for validating certificates received in an authenticated message.
Exposes a single module method, call, which is also available as BSV::Auth.validate_certificates via extend.
Algorithm:
-
Raise
AuthErrorifmessage[:certificates]is nil or empty. -
For each certificate in the array:
-
Verify cert subject == message identity key.
-
Construct a
VerifiableCertificateif the input is a plain Hash. -
Call
cert.verify— raise if signature is invalid. -
If
requested_certificatesis provided, check certifier and type. -
Call cert.decrypt_fields(wallet) — wrap any error in
AuthError.
-
Wallet is duck-typed — any object responding to verify_signature and decrypt is accepted.
Class Method Summary collapse
-
.validate_certificates(wallet, message, requested_certificates = nil) ⇒ Object
Validates certificates attached to an incoming authenticated message.
Class Method Details
.validate_certificates(wallet, message, requested_certificates = nil) ⇒ Object
Validates certificates attached to an incoming authenticated message.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/bsv/auth/validate_certificates.rb', line 33 def validate_certificates(wallet, , requested_certificates = nil) certs = [:certificates] || ['certificates'] raise AuthError, 'No certificates were provided in the message.' if certs.nil? || certs.empty? identity_key = [:identity_key] || ['identity_key'] certs.each do |incoming_cert| subject = if incoming_cert.is_a?(Hash) incoming_cert[:subject] || incoming_cert['subject'] else incoming_cert.subject end if subject != identity_key raise AuthError, "The subject of one of your certificates (\"#{subject}\") is not the same as " \ "the message sender (\"#{identity_key}\")." end cert = if incoming_cert.is_a?(VerifiableCertificate) incoming_cert else VerifiableCertificate.from_hash(incoming_cert) end begin valid = cert.verify rescue ArgumentError => e raise AuthError, "Certificate signature verification failed: #{e.}" end unless valid raise AuthError, "The signature for the certificate with serial number #{cert.serial_number} is invalid!" end if requested_certificates certifiers = requested_certificates[:certifiers] || requested_certificates['certifiers'] || [] types = requested_certificates[:types] || requested_certificates['types'] || {} unless certifiers.include?(cert.certifier) raise AuthError, "Certificate with serial number #{cert.serial_number} has an unrequested certifier: #{cert.certifier}" end unless types.key?(cert.type) raise AuthError, "Certificate with type #{cert.type} was not requested" end end begin cert.decrypt_fields(wallet) rescue ArgumentError, RuntimeError => e raise AuthError, "Failed to decrypt certificate fields: #{e.}" end end end |