webauthn 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae88f2e29c3d4c734f5d7efec59b6dd3824a2976a10c5cb7bc03ff525d79852c
4
- data.tar.gz: b62bcde957604db6eb660ccd515c66bdb894178a3e6173a783483a0ee0378ac2
3
+ metadata.gz: 8dd2e6fbccb0b180e0a36f4980939a1ba3a66d0cc744a7d50b140feb01917a35
4
+ data.tar.gz: 403281bfe63aa4ca9929bd0ca2e8cc9ff3af4ae66b21251f26118138fb355051
5
5
  SHA512:
6
- metadata.gz: 6b40ec846092c70e19e79656325e24f1ed43231b911b37fe3fb9be20afbcd276b8d1e46f2e3bd719c92f0f031738f364581514db542c981028369ffbca28afe3
7
- data.tar.gz: dd26ac18ca8db8ae98007a9f566e521a7d24998f244583099ff7f7bac4a8776d5ab2fa8f76fc2f2c8d7291d3119b21efcb422d46ee892dea6e83045c51b85878
6
+ metadata.gz: 4ab428637bed52191bdee14a96a9676df44019170ffab49862bc28e84c59202f3fb8302b36fd0bc29321608352712ea18cdecbe0311dfc02a167da1b2bf1d3b5
7
+ data.tar.gz: cb98ae9cbfbe66804e2bea396121da2874b667b6e25ee58790195dbfd2a6b6d936cca70e50d7b9d796f2af0928c164cbdd3093987a202171f19e365bbdefd6a1
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.3.0] - 2018-10-11
4
+
5
+ ### Added
6
+
7
+ - _Registration_ ceremony
8
+ - `WebAuthn::AuthenticatorAttestationResponse.valid?` supports `packed` attestation statements. Thank you @sorah!
9
+
3
10
  ## [v1.2.0] - 2018-10-08
4
11
 
5
12
  ### Added
@@ -71,6 +78,7 @@ Note: Both additions should help making it compatible with Chrome for Android 70
71
78
  - `WebAuthn::AuthenticatorAttestationResponse.valid?` can be used to validate fido-u2f attestations returned by the browser
72
79
  - Works with ruby 2.5
73
80
 
81
+ [v1.3.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.2.0...v1.3.0/
74
82
  [v1.2.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.1.0...v1.2.0/
75
83
  [v1.1.0]: https://github.com/cedarcode/webauthn-ruby/compare/v1.0.0...v1.1.0/
76
84
  [v1.0.0]: https://github.com/cedarcode/webauthn-ruby/compare/v0.2.0...v1.0.0/
data/README.md CHANGED
@@ -21,7 +21,7 @@ This gem will help your ruby server act as a conforming [_Relying-Party_](https:
21
21
  Currently supporting [Web Authentication API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API):
22
22
  - [Mozilla Firefox](https://www.mozilla.org/firefox/) 60+
23
23
  - [Google Chrome](https://www.google.com/chrome/) 67+
24
- - Google Chrome 65 & 66 (Disabled by default, go to chrome://flags to enable Web Authentication API feature)
24
+ - [Google Chrome for Android Beta](https://play.google.com/store/apps/details?id=com.chrome.beta) 70+
25
25
 
26
26
  ### A conforming Authenticator
27
27
 
@@ -2,8 +2,11 @@
2
2
 
3
3
  module WebAuthn
4
4
  module AttestationStatement
5
+ class FormatNotSupportedError < StandardError; end
6
+
5
7
  ATTESTATION_FORMAT_NONE = "none"
6
8
  ATTESTATION_FORMAT_FIDO_U2F = "fido-u2f"
9
+ ATTESTATION_FORMAT_PACKED = 'packed'
7
10
 
8
11
  def self.from(format, statement)
9
12
  case format
@@ -13,8 +16,11 @@ module WebAuthn
13
16
  when ATTESTATION_FORMAT_FIDO_U2F
14
17
  require "webauthn/attestation_statement/fido_u2f"
15
18
  WebAuthn::AttestationStatement::FidoU2f.new(statement)
19
+ when ATTESTATION_FORMAT_PACKED
20
+ require "webauthn/attestation_statement/packed"
21
+ WebAuthn::AttestationStatement::Packed.new(statement)
16
22
  else
17
- raise "Unsupported attestation format '#{attestation_format}'"
23
+ raise FormatNotSupportedError, "Unsupported attestation format '#{format}'"
18
24
  end
19
25
  end
20
26
  end
@@ -3,11 +3,13 @@
3
3
  module WebAuthn
4
4
  module AttestationStatement
5
5
  class Base
6
+ class NotSupportedError < StandardError; end
7
+
6
8
  def initialize(statement)
7
9
  @statement = statement
8
10
  end
9
11
 
10
- def valid?(*_args)
12
+ def valid?(_authenticator_data, _client_data_hash)
11
13
  raise NotImpelementedError
12
14
  end
13
15
 
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openssl"
4
+ require "webauthn/attestation_statement/base"
5
+
6
+ module WebAuthn
7
+ # Implements https://www.w3.org/TR/2018/CR-webauthn-20180807/#packed-attestation
8
+ # ECDAA attestation is unsupported.
9
+ module AttestationStatement
10
+ class Packed < Base
11
+ # Follows "Verification procedure"
12
+ def valid?(authenticator_data, client_data_hash)
13
+ check_unsupported_feature
14
+
15
+ valid_format? &&
16
+ valid_certificate_chain?(authenticator_data.credential) &&
17
+ meet_certificate_requirement? &&
18
+ valid_signature?(authenticator_data, client_data_hash)
19
+ end
20
+
21
+ private
22
+
23
+ def algorithm
24
+ statement["alg"]
25
+ end
26
+
27
+ def signature
28
+ statement["sig"]
29
+ end
30
+
31
+ def raw_attestation_certificates
32
+ statement["x5c"]
33
+ end
34
+
35
+ def raw_ecdaa_key_id
36
+ statement["ecdaaKeyId"]
37
+ end
38
+
39
+ def valid_format?
40
+ algorithm && signature && (
41
+ [raw_attestation_certificates, raw_ecdaa_key_id].compact.size < 2
42
+ )
43
+ end
44
+
45
+ def check_unsupported_feature
46
+ if raw_ecdaa_key_id
47
+ raise NotSupportedError, "ecdaaKeyId of the packed attestation format is not implemented yet"
48
+ end
49
+ end
50
+
51
+ def attestation_certificate_chain
52
+ @attestation_certificate_chain ||= raw_attestation_certificates&.map do |cert|
53
+ OpenSSL::X509::Certificate.new(cert)
54
+ end
55
+ end
56
+
57
+ def attestation_certificate
58
+ attestation_certificate_chain&.first
59
+ end
60
+
61
+ def valid_certificate_chain?(credential)
62
+ public_keys = attestation_certificate_chain&.map(&:public_key) || [credential.public_key_object]
63
+ public_keys.all? do |public_key|
64
+ public_key.is_a?(OpenSSL::PKey::EC) && public_key.check_key
65
+ end
66
+ end
67
+
68
+ # Check https://www.w3.org/TR/2018/CR-webauthn-20180807/#packed-attestation-cert-requirements
69
+ def meet_certificate_requirement?
70
+ return true unless attestation_certificate
71
+ subject = attestation_certificate.subject.to_a
72
+
73
+ attestation_certificate.version == 2 &&
74
+ subject.assoc('OU')&.at(1) == "Authenticator Attestation" &&
75
+ attestation_certificate.extensions.find { |ext| ext.oid == 'basicConstraints' }&.value == 'CA:FALSE'
76
+ end
77
+
78
+ def valid_signature?(authenticator_data, client_data_hash)
79
+ (attestation_certificate&.public_key || authenticator_data.credential.public_key_object).verify(
80
+ "SHA256",
81
+ signature,
82
+ verification_data(authenticator_data, client_data_hash)
83
+ )
84
+ end
85
+
86
+ def verification_data(authenticator_data, client_data_hash)
87
+ authenticator_data.data + client_data_hash
88
+ end
89
+ end
90
+ end
91
+ end
@@ -12,7 +12,18 @@ module WebAuthn
12
12
  UINT16_BIG_ENDIAN_FORMAT = "n*"
13
13
 
14
14
  # FIXME: use keyword_init when we dropped Ruby 2.4 support
15
- Credential = Struct.new(:id, :public_key)
15
+ Credential = Struct.new(:id, :public_key) do
16
+ def public_key_object
17
+ group = OpenSSL::PKey::EC::Group.new("prime256v1")
18
+ key = OpenSSL::PKey::EC.new(group)
19
+
20
+ bn = OpenSSL::BN.new(public_key, 2)
21
+ point = OpenSSL::PKey::EC::Point.new(group, bn)
22
+ key.public_key = point
23
+
24
+ key
25
+ end
26
+ end
16
27
 
17
28
  def initialize(data)
18
29
  @data = data
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebAuthn
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webauthn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gonzalo Rodriguez
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-10-08 00:00:00.000000000 Z
12
+ date: 2018-10-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cbor
@@ -134,6 +134,7 @@ files:
134
134
  - lib/webauthn/attestation_statement/base.rb
135
135
  - lib/webauthn/attestation_statement/fido_u2f.rb
136
136
  - lib/webauthn/attestation_statement/none.rb
137
+ - lib/webauthn/attestation_statement/packed.rb
137
138
  - lib/webauthn/authenticator_assertion_response.rb
138
139
  - lib/webauthn/authenticator_attestation_response.rb
139
140
  - lib/webauthn/authenticator_data.rb