From 0b4e16aa2ded768909bba4166f8bc494be752141 Mon Sep 17 00:00:00 2001 From: Dan Ungureanu Date: Wed, 9 Feb 2022 13:56:45 +0200 Subject: [PATCH] FEATURE: RS512, RS384 and RS256 COSE algorithms (#15868) * FEATURE: RS512, RS384 and RS256 COSE algorithms These algorithms are not implemented by cose-ruby, but used in the web authentication API and were marked as supported. * FEATURE: Use all algorithms supported by cose-ruby Previously only a subset of the algorithms were allowed. --- lib/freedom_patches/cose_rsapkcs1.rb | 50 +++++++++++++++++++ lib/webauthn.rb | 2 +- ...ecurity_key_authentication_service_spec.rb | 6 +++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 lib/freedom_patches/cose_rsapkcs1.rb diff --git a/lib/freedom_patches/cose_rsapkcs1.rb b/lib/freedom_patches/cose_rsapkcs1.rb new file mode 100644 index 0000000000..d407260dc8 --- /dev/null +++ b/lib/freedom_patches/cose_rsapkcs1.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'cose' +require 'openssl/signature_algorithm/rsapkcs1' + +# 'cose' gem does not implement all algorithms from the Web Authentication +# (WebAuthn) standard specification. This patch implements one of the missing +# ones, RSASSA-PKCS1-v1_5. +module COSE + module Algorithm + def self.registered_algorithm_ids + @registered_by_id.keys + end + + class RSAPKCS1 < SignatureAlgorithm + attr_reader :hash_function + + def initialize(*args, hash_function:) + super(*args) + + @hash_function = hash_function + end + + private + + def valid_key?(key) + to_cose_key(key).is_a?(COSE::Key::RSA) + end + + def signature_algorithm_class + OpenSSL::SignatureAlgorithm::RSAPKCS1 + end + + def to_pkey(key) + case key + when COSE::Key::RSA + key.to_pkey + when OpenSSL::PKey::RSA + key + else + raise(COSE::Error, 'Incompatible key for algorithm') + end + end + end + + register(RSAPKCS1.new(-257, 'RS256', hash_function: 'SHA256')) + register(RSAPKCS1.new(-258, 'RS384', hash_function: 'SHA384')) + register(RSAPKCS1.new(-259, 'RS512', hash_function: 'SHA512')) + end +end diff --git a/lib/webauthn.rb b/lib/webauthn.rb index 4734b660ca..089913f31c 100644 --- a/lib/webauthn.rb +++ b/lib/webauthn.rb @@ -10,7 +10,7 @@ module Webauthn # -7 - ES256 # -257 - RS256 (Windows Hello supported alg.) - SUPPORTED_ALGORITHMS = [-7, -257].freeze + SUPPORTED_ALGORITHMS = COSE::Algorithm.registered_algorithm_ids.freeze VALID_ATTESTATION_FORMATS = ['none', 'packed', 'fido-u2f'].freeze class SecurityKeyError < StandardError; end diff --git a/spec/lib/webauthn/security_key_authentication_service_spec.rb b/spec/lib/webauthn/security_key_authentication_service_spec.rb index 52e18c7988..ee83dde77e 100644 --- a/spec/lib/webauthn/security_key_authentication_service_spec.rb +++ b/spec/lib/webauthn/security_key_authentication_service_spec.rb @@ -157,4 +157,10 @@ describe Webauthn::SecurityKeyAuthenticationService do ) end end + + it 'all supported algorithms are implemented' do + Webauthn::SUPPORTED_ALGORITHMS.each do |alg| + expect(COSE::Algorithm.find(alg)).not_to be_nil + end + end end