webauthn 2.0.0.beta1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +65 -13
  4. data/.travis.yml +22 -18
  5. data/Appraisals +4 -0
  6. data/CHANGELOG.md +72 -25
  7. data/CONTRIBUTING.md +0 -5
  8. data/README.md +172 -15
  9. data/SECURITY.md +4 -4
  10. data/gemfiles/openssl_2_2.gemfile +7 -0
  11. data/lib/cose/rsapkcs1_algorithm.rb +43 -0
  12. data/lib/webauthn/attestation_object.rb +43 -0
  13. data/lib/webauthn/attestation_statement.rb +20 -20
  14. data/lib/webauthn/attestation_statement/android_key.rb +28 -30
  15. data/lib/webauthn/attestation_statement/android_safetynet.rb +30 -20
  16. data/lib/webauthn/attestation_statement/base.rb +124 -14
  17. data/lib/webauthn/attestation_statement/fido_u2f.rb +13 -9
  18. data/lib/webauthn/attestation_statement/packed.rb +14 -42
  19. data/lib/webauthn/attestation_statement/tpm.rb +38 -54
  20. data/lib/webauthn/authenticator_assertion_response.rb +7 -36
  21. data/lib/webauthn/authenticator_attestation_response.rb +24 -46
  22. data/lib/webauthn/authenticator_data.rb +51 -51
  23. data/lib/webauthn/authenticator_data/attested_credential_data.rb +29 -50
  24. data/lib/webauthn/authenticator_response.rb +15 -10
  25. data/lib/webauthn/configuration.rb +23 -0
  26. data/lib/webauthn/credential.rb +4 -4
  27. data/lib/webauthn/credential_creation_options.rb +1 -1
  28. data/lib/webauthn/fake_authenticator.rb +7 -3
  29. data/lib/webauthn/fake_authenticator/attestation_object.rb +7 -3
  30. data/lib/webauthn/fake_authenticator/authenticator_data.rb +2 -4
  31. data/lib/webauthn/fake_client.rb +17 -4
  32. data/lib/webauthn/public_key.rb +68 -0
  33. data/lib/webauthn/public_key_credential.rb +13 -3
  34. data/lib/webauthn/public_key_credential/creation_options.rb +2 -2
  35. data/lib/webauthn/u2f_migrator.rb +5 -4
  36. data/lib/webauthn/version.rb +1 -1
  37. data/script/ci/install-openssl +7 -0
  38. data/script/ci/install-ruby +13 -0
  39. data/webauthn.gemspec +14 -9
  40. metadata +70 -42
  41. data/lib/android_safetynet/attestation_response.rb +0 -84
  42. data/lib/cose/algorithm.rb +0 -38
  43. data/lib/tpm/constants.rb +0 -22
  44. data/lib/tpm/s_attest.rb +0 -26
  45. data/lib/tpm/s_attest/s_certify_info.rb +0 -14
  46. data/lib/tpm/sized_buffer.rb +0 -13
  47. data/lib/tpm/t_public.rb +0 -32
  48. data/lib/tpm/t_public/s_ecc_parms.rb +0 -17
  49. data/lib/tpm/t_public/s_rsa_parms.rb +0 -17
  50. data/lib/webauthn/attestation_statement/android_key/authorization_list.rb +0 -39
  51. data/lib/webauthn/attestation_statement/android_key/key_description.rb +0 -37
  52. data/lib/webauthn/attestation_statement/tpm/cert_info.rb +0 -44
  53. data/lib/webauthn/attestation_statement/tpm/pub_area.rb +0 -85
  54. data/lib/webauthn/signature_verifier.rb +0 -65
@@ -1,15 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "cose"
3
4
  require "openssl"
4
5
  require "webauthn/attestation_statement/base"
5
6
  require "webauthn/attestation_statement/fido_u2f/public_key"
6
- require "webauthn/signature_verifier"
7
7
 
8
8
  module WebAuthn
9
9
  module AttestationStatement
10
10
  class FidoU2f < Base
11
11
  VALID_ATTESTATION_CERTIFICATE_COUNT = 1
12
12
  VALID_ATTESTATION_CERTIFICATE_ALGORITHM = COSE::Algorithm.by_name("ES256")
13
+ VALID_ATTESTATION_CERTIFICATE_KEY_CURVE = COSE::Key::Curve.by_name("P-256")
13
14
 
14
15
  def valid?(authenticator_data, client_data_hash)
15
16
  valid_format? &&
@@ -17,19 +18,20 @@ module WebAuthn
17
18
  valid_credential_public_key?(authenticator_data.credential.public_key) &&
18
19
  valid_aaguid?(authenticator_data.attested_credential_data.raw_aaguid) &&
19
20
  valid_signature?(authenticator_data, client_data_hash) &&
20
- [WebAuthn::AttestationStatement::ATTESTATION_TYPE_BASIC_OR_ATTCA, [attestation_certificate]]
21
+ trustworthy?(attestation_certificate_key_id: attestation_certificate_key_id) &&
22
+ [attestation_type, attestation_trust_path]
21
23
  end
22
24
 
23
25
  private
24
26
 
25
27
  def valid_format?
26
- !!(raw_attestation_certificates && signature) &&
27
- raw_attestation_certificates.length == VALID_ATTESTATION_CERTIFICATE_COUNT
28
+ !!(raw_certificates && signature) &&
29
+ raw_certificates.length == VALID_ATTESTATION_CERTIFICATE_COUNT
28
30
  end
29
31
 
30
32
  def valid_certificate_public_key?
31
33
  certificate_public_key.is_a?(OpenSSL::PKey::EC) &&
32
- certificate_public_key.group.curve_name == VALID_ATTESTATION_CERTIFICATE_ALGORITHM.key_curve &&
34
+ certificate_public_key.group.curve_name == VALID_ATTESTATION_CERTIFICATE_KEY_CURVE.pkey_name &&
33
35
  certificate_public_key.check_key
34
36
  end
35
37
 
@@ -45,10 +47,8 @@ module WebAuthn
45
47
  attested_credential_data_aaguid == WebAuthn::AuthenticatorData::AttestedCredentialData::ZEROED_AAGUID
46
48
  end
47
49
 
48
- def valid_signature?(authenticator_data, client_data_hash)
49
- WebAuthn::SignatureVerifier
50
- .new(VALID_ATTESTATION_CERTIFICATE_ALGORITHM, certificate_public_key)
51
- .verify(signature, verification_data(authenticator_data, client_data_hash))
50
+ def algorithm
51
+ VALID_ATTESTATION_CERTIFICATE_ALGORITHM.id
52
52
  end
53
53
 
54
54
  def verification_data(authenticator_data, client_data_hash)
@@ -62,6 +62,10 @@ module WebAuthn
62
62
  def public_key_u2f(cose_key_data)
63
63
  PublicKey.new(cose_key_data)
64
64
  end
65
+
66
+ def attestation_type
67
+ WebAuthn::AttestationStatement::ATTESTATION_TYPE_BASIC_OR_ATTCA
68
+ end
65
69
  end
66
70
  end
67
71
  end
@@ -2,25 +2,21 @@
2
2
 
3
3
  require "openssl"
4
4
  require "webauthn/attestation_statement/base"
5
- require "webauthn/signature_verifier"
6
5
 
7
6
  module WebAuthn
8
7
  # Implements https://www.w3.org/TR/2018/CR-webauthn-20180807/#packed-attestation
9
- # ECDAA attestation is unsupported.
10
8
  module AttestationStatement
11
9
  class Packed < Base
12
10
  # Follows "Verification procedure"
13
11
  def valid?(authenticator_data, client_data_hash)
14
- check_unsupported_feature
15
-
16
12
  valid_format? &&
17
13
  valid_algorithm?(authenticator_data.credential) &&
18
- valid_certificate_chain? &&
19
14
  valid_ec_public_keys?(authenticator_data.credential) &&
20
15
  meet_certificate_requirement? &&
21
16
  matching_aaguid?(authenticator_data.attested_credential_data.raw_aaguid) &&
22
17
  valid_signature?(authenticator_data, client_data_hash) &&
23
- attestation_type_and_trust_path
18
+ trustworthy?(aaguid: authenticator_data.aaguid) &&
19
+ [attestation_type, attestation_trust_path]
24
20
  end
25
21
 
26
22
  private
@@ -30,31 +26,15 @@ module WebAuthn
30
26
  end
31
27
 
32
28
  def self_attestation?
33
- !raw_attestation_certificates && !raw_ecdaa_key_id
29
+ !raw_certificates
34
30
  end
35
31
 
36
32
  def valid_format?
37
- algorithm && signature && (
38
- [raw_attestation_certificates, raw_ecdaa_key_id].compact.size < 2
39
- )
40
- end
41
-
42
- def check_unsupported_feature
43
- if raw_ecdaa_key_id
44
- raise NotSupportedError, "ecdaaKeyId of the packed attestation format is not implemented yet"
45
- end
46
- end
47
-
48
- def valid_certificate_chain?
49
- if attestation_certificate_chain
50
- attestation_certificate_chain[1..-1].all? { |c| certificate_in_use?(c) }
51
- else
52
- true
53
- end
33
+ algorithm && signature
54
34
  end
55
35
 
56
36
  def valid_ec_public_keys?(credential)
57
- (attestation_certificate_chain&.map(&:public_key) || [credential.public_key_object])
37
+ (certificates&.map(&:public_key) || [credential.public_key_object])
58
38
  .select { |pkey| pkey.is_a?(OpenSSL::PKey::EC) }
59
39
  .all? { |pkey| pkey.check_key }
60
40
  end
@@ -65,7 +45,6 @@ module WebAuthn
65
45
  subject = attestation_certificate.subject.to_a
66
46
 
67
47
  attestation_certificate.version == 2 &&
68
- certificate_in_use?(attestation_certificate) &&
69
48
  subject.assoc('OU')&.at(1) == "Authenticator Attestation" &&
70
49
  attestation_certificate.extensions.find { |ext| ext.oid == 'basicConstraints' }&.value == 'CA:FALSE'
71
50
  else
@@ -73,27 +52,20 @@ module WebAuthn
73
52
  end
74
53
  end
75
54
 
76
- def certificate_in_use?(certificate)
77
- now = Time.now
78
-
79
- certificate.not_before < now && now < certificate.not_after
55
+ def attestation_type
56
+ if attestation_trust_path
57
+ WebAuthn::AttestationStatement::ATTESTATION_TYPE_BASIC_OR_ATTCA # FIXME: use metadata if available
58
+ else
59
+ WebAuthn::AttestationStatement::ATTESTATION_TYPE_SELF
60
+ end
80
61
  end
81
62
 
82
63
  def valid_signature?(authenticator_data, client_data_hash)
83
- signature_verifier = WebAuthn::SignatureVerifier.new(
84
- algorithm,
64
+ super(
65
+ authenticator_data,
66
+ client_data_hash,
85
67
  attestation_certificate&.public_key || authenticator_data.credential.public_key_object
86
68
  )
87
-
88
- signature_verifier.verify(signature, authenticator_data.data + client_data_hash)
89
- end
90
-
91
- def attestation_type_and_trust_path
92
- if raw_attestation_certificates&.any?
93
- [WebAuthn::AttestationStatement::ATTESTATION_TYPE_BASIC_OR_ATTCA, attestation_certificate_chain]
94
- else
95
- [WebAuthn::AttestationStatement::ATTESTATION_TYPE_SELF, nil]
96
- end
97
69
  end
98
70
  end
99
71
  end
@@ -2,73 +2,63 @@
2
2
 
3
3
  require "cose/algorithm"
4
4
  require "openssl"
5
+ require "tpm/key_attestation"
5
6
  require "webauthn/attestation_statement/base"
6
- require "webauthn/attestation_statement/tpm/cert_info"
7
- require "webauthn/attestation_statement/tpm/pub_area"
8
- require "webauthn/signature_verifier"
9
7
 
10
8
  module WebAuthn
11
9
  module AttestationStatement
12
10
  class TPM < Base
13
- CERTIFICATE_V3 = 2
14
- CERTIFICATE_EMPTY_NAME = OpenSSL::X509::Name.new([]).freeze
15
- OID_TCG_KP_AIK_CERTIFICATE = "2.23.133.8.3"
16
11
  TPM_V2 = "2.0"
17
12
 
18
- def valid?(authenticator_data, client_data_hash)
19
- case attestation_type
20
- when ATTESTATION_TYPE_ATTCA
21
- att_to_be_signed = authenticator_data.data + client_data_hash
13
+ COSE_ALG_TO_TPM = {
14
+ "RS1" => { signature: ::TPM::ALG_RSASSA, hash: ::TPM::ALG_SHA1 },
15
+ "RS256" => { signature: ::TPM::ALG_RSASSA, hash: ::TPM::ALG_SHA256 },
16
+ "PS256" => { signature: ::TPM::ALG_RSAPSS, hash: ::TPM::ALG_SHA256 },
17
+ "ES256" => { signature: ::TPM::ALG_ECDSA, hash: ::TPM::ALG_SHA256 },
18
+ }.freeze
22
19
 
20
+ def valid?(authenticator_data, client_data_hash)
21
+ attestation_type == ATTESTATION_TYPE_ATTCA &&
23
22
  ver == TPM_V2 &&
24
- valid_signature? &&
25
- valid_attestation_certificate? &&
26
- pub_area.valid?(authenticator_data.credential.public_key) &&
27
- cert_info.valid?(statement["pubArea"], OpenSSL::Digest.digest(cose_algorithm.hash, att_to_be_signed)) &&
28
- matching_aaguid?(authenticator_data.attested_credential_data.raw_aaguid) &&
29
- [attestation_type, attestation_trust_path]
30
- when ATTESTATION_TYPE_ECDAA
31
- raise(
32
- WebAuthn::AttestationStatement::Base::NotSupportedError,
33
- "Attestation type ECDAA is not supported"
34
- )
35
- end
23
+ valid_key_attestation?(
24
+ authenticator_data.data + client_data_hash,
25
+ authenticator_data.credential.public_key_object,
26
+ authenticator_data.aaguid
27
+ ) &&
28
+ matching_aaguid?(authenticator_data.attested_credential_data.raw_aaguid) &&
29
+ trustworthy?(aaguid: authenticator_data.aaguid) &&
30
+ [attestation_type, attestation_trust_path]
36
31
  end
37
32
 
38
33
  private
39
34
 
40
- def valid_signature?
41
- WebAuthn::SignatureVerifier
42
- .new(algorithm, attestation_certificate.public_key)
43
- .verify(signature, verification_data, rsa_pss_salt_length: :auto)
44
- end
45
-
46
- def valid_attestation_certificate?
47
- extensions = attestation_certificate.extensions
48
-
49
- attestation_certificate.version == CERTIFICATE_V3 &&
50
- attestation_certificate.subject.eql?(CERTIFICATE_EMPTY_NAME) &&
51
- certificate_in_use?(attestation_certificate) &&
52
- extensions.find { |ext| ext.oid == 'basicConstraints' }&.value == "CA:FALSE" &&
53
- extensions.find { |ext| ext.oid == "extendedKeyUsage" }&.value == OID_TCG_KP_AIK_CERTIFICATE
54
- end
55
-
56
- def certificate_in_use?(certificate)
57
- now = Time.now
35
+ def valid_key_attestation?(certified_extra_data, key, aaguid)
36
+ key_attestation =
37
+ ::TPM::KeyAttestation.new(
38
+ statement["certInfo"],
39
+ signature,
40
+ statement["pubArea"],
41
+ certificates,
42
+ OpenSSL::Digest.digest(cose_algorithm.hash_function, certified_extra_data),
43
+ signature_algorithm: tpm_algorithm[:signature],
44
+ hash_algorithm: tpm_algorithm[:hash],
45
+ root_certificates: root_certificates(aaguid: aaguid)
46
+ )
58
47
 
59
- certificate.not_before < now && now < certificate.not_after
48
+ key_attestation.valid? && key_attestation.key && key_attestation.key.to_pem == key.to_pem
60
49
  end
61
50
 
62
- def verification_data
63
- statement["certInfo"]
51
+ def valid_certificate_chain?(**_)
52
+ # Already performed as part of #valid_key_attestation?
53
+ true
64
54
  end
65
55
 
66
- def cert_info
67
- @cert_info ||= CertInfo.new(statement["certInfo"])
56
+ def default_root_certificates
57
+ ::TPM::KeyAttestation::ROOT_CERTIFICATES
68
58
  end
69
59
 
70
- def pub_area
71
- @pub_area ||= PubArea.new(statement["pubArea"])
60
+ def tpm_algorithm
61
+ COSE_ALG_TO_TPM[cose_algorithm.name] || raise("Unsupported algorithm #{cose_algorithm.name}")
72
62
  end
73
63
 
74
64
  def ver
@@ -80,18 +70,12 @@ module WebAuthn
80
70
  end
81
71
 
82
72
  def attestation_type
83
- if raw_attestation_certificates && !raw_ecdaa_key_id
73
+ if raw_certificates
84
74
  ATTESTATION_TYPE_ATTCA
85
- elsif raw_ecdaa_key_id && !raw_attestation_certificates
86
- ATTESTATION_TYPE_ECDAA
87
75
  else
88
76
  raise "Attestation type invalid"
89
77
  end
90
78
  end
91
-
92
- def attestation_trust_path
93
- attestation_certificate_chain
94
- end
95
79
  end
96
80
  end
97
81
  end
@@ -1,12 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "cose/algorithm"
4
- require "cose/key"
5
- require "webauthn/attestation_statement/fido_u2f/public_key"
6
3
  require "webauthn/authenticator_data"
7
4
  require "webauthn/authenticator_response"
8
5
  require "webauthn/encoder"
9
- require "webauthn/signature_verifier"
6
+ require "webauthn/public_key"
10
7
 
11
8
  module WebAuthn
12
9
  class SignatureVerificationError < VerificationError; end
@@ -32,34 +29,31 @@ module WebAuthn
32
29
  attr_reader :user_handle
33
30
 
34
31
  def initialize(authenticator_data:, signature:, user_handle: nil, **options)
35
- super(options)
32
+ super(**options)
36
33
 
37
34
  @authenticator_data_bytes = authenticator_data
38
35
  @signature = signature
39
36
  @user_handle = user_handle
40
37
  end
41
38
 
42
- def verify(expected_challenge, expected_origin = nil, public_key:, sign_count:, user_verification: nil,
43
- rp_id: nil)
39
+ def verify(expected_challenge, expected_origin = nil, public_key:, sign_count:, user_verification: nil, rp_id: nil)
44
40
  super(expected_challenge, expected_origin, user_verification: user_verification, rp_id: rp_id)
45
- verify_item(:signature, credential_cose_key(public_key))
41
+ verify_item(:signature, WebAuthn::PublicKey.deserialize(public_key))
46
42
  verify_item(:sign_count, sign_count)
47
43
 
48
44
  true
49
45
  end
50
46
 
51
47
  def authenticator_data
52
- @authenticator_data ||= WebAuthn::AuthenticatorData.new(authenticator_data_bytes)
48
+ @authenticator_data ||= WebAuthn::AuthenticatorData.deserialize(authenticator_data_bytes)
53
49
  end
54
50
 
55
51
  private
56
52
 
57
53
  attr_reader :authenticator_data_bytes, :signature
58
54
 
59
- def valid_signature?(credential_cose_key)
60
- WebAuthn::SignatureVerifier
61
- .new(credential_cose_key.alg, credential_cose_key.to_pkey)
62
- .verify(signature, authenticator_data_bytes + client_data.hash)
55
+ def valid_signature?(webauthn_public_key)
56
+ webauthn_public_key.verify(signature, authenticator_data_bytes + client_data.hash)
63
57
  end
64
58
 
65
59
  def valid_sign_count?(stored_sign_count)
@@ -71,29 +65,6 @@ module WebAuthn
71
65
  end
72
66
  end
73
67
 
74
- def credential_cose_key(public_key)
75
- if WebAuthn::AttestationStatement::FidoU2f::PublicKey.uncompressed_point?(public_key)
76
- # Gem version v1.11.0 and lower, used to behave so that Credential#public_key
77
- # returned an EC P-256 uncompressed point.
78
- #
79
- # Because of https://github.com/cedarcode/webauthn-ruby/issues/137 this was changed
80
- # and Credential#public_key started returning the unchanged COSE_Key formatted
81
- # credentialPublicKey (as in https://www.w3.org/TR/webauthn/#credentialpublickey).
82
- #
83
- # Given that the credential public key is expected to be stored long-term by the gem
84
- # user and later be passed as the public_key argument in the
85
- # AuthenticatorAssertionResponse.verify call, we then need to support the two formats.
86
- COSE::Key::EC2.new(
87
- alg: COSE::Algorithm.by_name("ES256").id,
88
- crv: 1,
89
- x: public_key[1..32],
90
- y: public_key[33..-1]
91
- )
92
- else
93
- COSE::Key.deserialize(public_key)
94
- end
95
- end
96
-
97
68
  def type
98
69
  WebAuthn::TYPES[:get]
99
70
  end
@@ -1,20 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "cbor"
4
+ require "forwardable"
4
5
  require "uri"
5
6
  require "openssl"
6
7
 
7
- require "webauthn/authenticator_data"
8
+ require "webauthn/attestation_object"
8
9
  require "webauthn/authenticator_response"
9
- require "webauthn/attestation_statement"
10
10
  require "webauthn/client_data"
11
11
  require "webauthn/encoder"
12
12
 
13
13
  module WebAuthn
14
14
  class AttestationStatementVerificationError < VerificationError; end
15
+ class AttestationTrustworthinessVerificationError < VerificationError; end
15
16
  class AttestedCredentialVerificationError < VerificationError; end
16
17
 
17
18
  class AuthenticatorAttestationResponse < AuthenticatorResponse
19
+ extend Forwardable
20
+
18
21
  def self.from_client(response)
19
22
  encoder = WebAuthn.configuration.encoder
20
23
 
@@ -27,76 +30,51 @@ module WebAuthn
27
30
  attr_reader :attestation_type, :attestation_trust_path
28
31
 
29
32
  def initialize(attestation_object:, **options)
30
- super(options)
33
+ super(**options)
31
34
 
32
- @attestation_object = attestation_object
35
+ @attestation_object_bytes = attestation_object
33
36
  end
34
37
 
35
38
  def verify(expected_challenge, expected_origin = nil, user_verification: nil, rp_id: nil)
36
39
  super
37
40
 
38
41
  verify_item(:attested_credential)
39
- verify_item(:attestation_statement) if WebAuthn.configuration.verify_attestation_statement
42
+ if WebAuthn.configuration.verify_attestation_statement
43
+ verify_item(:attestation_statement)
44
+ end
40
45
 
41
46
  true
42
47
  end
43
48
 
44
- def credential
45
- authenticator_data.credential
46
- end
47
-
48
- def attestation_statement
49
- @attestation_statement ||=
50
- WebAuthn::AttestationStatement.from(attestation["fmt"], attestation["attStmt"])
51
- end
52
-
53
- def authenticator_data
54
- @authenticator_data ||= WebAuthn::AuthenticatorData.new(attestation["authData"])
55
- end
56
-
57
- def attestation_format
58
- attestation["fmt"]
49
+ def attestation_object
50
+ @attestation_object ||= WebAuthn::AttestationObject.deserialize(attestation_object_bytes)
59
51
  end
60
52
 
61
- def attestation
62
- @attestation ||= CBOR.decode(attestation_object)
63
- end
64
-
65
- def aaguid
66
- raw_aaguid = authenticator_data.attested_credential_data.raw_aaguid
67
- unless raw_aaguid == WebAuthn::AuthenticatorData::AttestedCredentialData::ZEROED_AAGUID
68
- authenticator_data.attested_credential_data.aaguid
69
- end
70
- end
53
+ def_delegators(
54
+ :attestation_object,
55
+ :aaguid,
56
+ :attestation_statement,
57
+ :attestation_certificate_key_id,
58
+ :authenticator_data,
59
+ :credential
60
+ )
71
61
 
72
- def attestation_certificate_key
73
- raw_subject_key_identifier(attestation_statement.attestation_certificate)&.unpack("H*")&.[](0)
74
- end
62
+ alias_method :attestation_certificate_key, :attestation_certificate_key_id
75
63
 
76
64
  private
77
65
 
78
- attr_reader :attestation_object
66
+ attr_reader :attestation_object_bytes
79
67
 
80
68
  def type
81
69
  WebAuthn::TYPES[:create]
82
70
  end
83
71
 
84
72
  def valid_attested_credential?
85
- authenticator_data.attested_credential_data_included? &&
86
- authenticator_data.attested_credential_data.valid?
73
+ attestation_object.valid_attested_credential?
87
74
  end
88
75
 
89
76
  def valid_attestation_statement?
90
- @attestation_type, @attestation_trust_path = attestation_statement.valid?(authenticator_data, client_data.hash)
91
- end
92
-
93
- def raw_subject_key_identifier(certificate)
94
- extension = certificate.extensions.detect { |ext| ext.oid == "subjectKeyIdentifier" }
95
- return unless extension
96
-
97
- ext_asn1 = OpenSSL::ASN1.decode(extension.to_der)
98
- ext_value = ext_asn1.value.last
99
- OpenSSL::ASN1.decode(ext_value.value).value
77
+ @attestation_type, @attestation_trust_path = attestation_object.valid_attestation_statement?(client_data.hash)
100
78
  end
101
79
  end
102
80
  end