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 +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
|