webauthn 1.2.0 → 1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +1 -1
- data/lib/webauthn/attestation_statement.rb +7 -1
- data/lib/webauthn/attestation_statement/base.rb +3 -1
- data/lib/webauthn/attestation_statement/packed.rb +91 -0
- data/lib/webauthn/authenticator_data/attested_credential_data.rb +12 -1
- data/lib/webauthn/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8dd2e6fbccb0b180e0a36f4980939a1ba3a66d0cc744a7d50b140feb01917a35
|
4
|
+
data.tar.gz: 403281bfe63aa4ca9929bd0ca2e8cc9ff3af4ae66b21251f26118138fb355051
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ab428637bed52191bdee14a96a9676df44019170ffab49862bc28e84c59202f3fb8302b36fd0bc29321608352712ea18cdecbe0311dfc02a167da1b2bf1d3b5
|
7
|
+
data.tar.gz: cb98ae9cbfbe66804e2bea396121da2874b667b6e25ee58790195dbfd2a6b6d936cca70e50d7b9d796f2af0928c164cbdd3093987a202171f19e365bbdefd6a1
|
data/CHANGELOG.md
CHANGED
@@ -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
|
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 '#{
|
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?(
|
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
|
data/lib/webauthn/version.rb
CHANGED
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.
|
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-
|
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
|