* Add support for latest HTTP Signatures spec draft
https://www.ietf.org/id/draft-ietf-httpbis-message-signatures-00.html
- add support for the “hs2019” signature algorithm (assumed to be equivalent
to RSA-SHA256, since we do not have a mechanism to specify the algorithm
within the key metadata yet)
- add support for (created) and (expires) pseudo-headers and related
signature parameters, when using the hs2019 signature algorithm
- adjust default “headers” parameter while being backwards-compatible with
previous implementation
- change the acceptable time window logic from 12 hours surrounding the “date”
header to accepting signatures created up to 1 hour in the future and
expiring up to 1 hour in the past (but only allowing expiration dates up to
12 hours after the creation date)
This doesn't conform with the current draft, as it doesn't permit accounting
for clock skew.
This, however, should be addressed in a next version of the draft:
https://github.com/httpwg/http-extensions/pull/1235
* Add additional signature requirements
* Rewrite signature params parsing using Parslet
* Make apparent which signature algorithm Mastodon on verification failure
Mastodon uses RSASSA-PKCS1-v1_5, which is not recommended for new applications,
and new implementers may thus unknowingly use RSASSA-PSS.
* Add workaround for PeerTube's invalid signature header
The previous parser allowed incorrect Signature headers, such as
those produced by old versions of the `http-signature` node.js package,
and seemingly used by PeerTube.
This commit adds a workaround for that.
* Fix `signature_key_id` raising an exception
Previously, parsing failures would result in `signature_key_id` being nil,
but the parser changes made that result in an exception.
This commit changes the `signature_key_id` method to return `nil` in case
of parsing failures.
* Move extra HTTP signature helper methods to private methods
* Relax (request-target) requirement to (request-target) || digest
This lets requests from Plume work without lowering security significantly.
raiseSignatureVerificationError,'Request not signed'unlesssigned_request?
@signature_verification_failure_reason='Request not signed'
raiseSignatureVerificationError,'Incompatible request signature. keyId and signature are required'ifmissing_required_signature_parameters?
@signed_request_account=nil
raiseSignatureVerificationError,'Unsupported signature algorithm (only rsa-sha256 and hs2019 are supported)'unless%w(rsa-sha256 hs2019).include?(signature_algorithm)
return
raiseSignatureVerificationError,'Signed request date outside acceptable time window'unlessmatches_time_window?
@signature_verification_failure_reason="Verification failed for #{account.username}@#{account.domain}#{account.uri}"
@signature_verification_failure_reason="Verification failed for #{account.username}@#{account.domain}#{account.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)"
raiseSignatureVerificationError,'Mastodon requires the Date header or (created) pseudo-header to be signed'unlesssigned_headers.include?('date')||signed_headers.include?('(created)')
raiseSignatureVerificationError,'Mastodon requires the Digest header or (request-target) pseudo-header to be signed'unlesssigned_headers.include?(Request::REQUEST_TARGET)||signed_headers.include?('digest')
raiseSignatureVerificationError,'Mastodon requires the Host header to be signed'unlesssigned_headers.include?('host')
raiseSignatureVerificationError,'Mastodon requires the Digest header to be signed when doing a POST request'ifrequest.post?&&!signed_headers.include?('digest')