webauthn 2.0.0.beta1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
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