web_authn 0.1.1 → 0.2.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/VERSION +1 -1
- data/lib/web_authn/attestation_object.rb +1 -1
- data/lib/web_authn/attested_credential_data.rb +6 -3
- data/lib/web_authn/authenticator_data.rb +1 -1
- data/lib/web_authn/context/authentication.rb +19 -8
- data/lib/web_authn/context/registration.rb +1 -1
- data/samples/authentication_response.rb +5 -0
- data/samples/registration_response.rb +3 -0
- data/spec/context/registration_spec.rb +1 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07b7a1b06a7ad5f04c3d303de0f8f099c0ce71038e78934268bf99243600d86c
|
4
|
+
data.tar.gz: 60a474a75148dff57396fc3e939fc94a83a58496ef95bca71f5a29747674651b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5876b9449153f9309057f48632121f0302b3a7fb663d968b441a374b40c09f9b88447b64101d44e92c2b1be6287e2f11c0373b44ca2c2532aa96d1b658d7899d
|
7
|
+
data.tar.gz: b598691bcb6d42ef76f72ae650931d47888cf573f5ad45759d2d834c3174256f69521f9496a101caf206386d366b9f476efe99864100e8bc9ad78cee7d4be7ae
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -5,7 +5,7 @@ module WebAuthn
|
|
5
5
|
alias_method :att_stmt, :attestation_statement
|
6
6
|
alias_method :auth_data, :authenticator_data
|
7
7
|
|
8
|
-
%i(credential_id rp_id_hash flags public_key sign_count).each do |method|
|
8
|
+
%i(credential_id rp_id_hash flags public_key public_cose_key sign_count).each do |method|
|
9
9
|
delegate method, to: :authenticator_data
|
10
10
|
end
|
11
11
|
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module WebAuthn
|
2
2
|
class AttestedCredentialData
|
3
|
-
attr_accessor :aaguid, :credential_id, :public_key
|
3
|
+
attr_accessor :aaguid, :credential_id, :public_key, :public_cose_key
|
4
4
|
|
5
|
-
def initialize(aaguid:, credential_id:, public_key:)
|
5
|
+
def initialize(aaguid:, credential_id:, public_key:, public_cose_key:)
|
6
6
|
self.aaguid = aaguid
|
7
7
|
self.credential_id = credential_id
|
8
8
|
self.public_key = public_key
|
9
|
+
self.public_cose_key = public_cose_key
|
9
10
|
end
|
10
11
|
|
11
12
|
class << self
|
@@ -21,10 +22,12 @@ module WebAuthn
|
|
21
22
|
attested_credential_data.byteslice(18...(18 + length)),
|
22
23
|
attested_credential_data.byteslice((18 + length)..-1),
|
23
24
|
]
|
25
|
+
cose_key = COSE::Key.decode(cose_key_cbor)
|
24
26
|
new(
|
25
27
|
aaguid: Base64.urlsafe_encode64(aaguid, padding: false),
|
26
28
|
credential_id: Base64.urlsafe_encode64(credential_id, padding: false),
|
27
|
-
public_key:
|
29
|
+
public_key: cose_key.to_key,
|
30
|
+
public_cose_key: cose_key
|
28
31
|
)
|
29
32
|
end
|
30
33
|
end
|
@@ -2,7 +2,7 @@ module WebAuthn
|
|
2
2
|
class AuthenticatorData
|
3
3
|
attr_accessor :rp_id_hash, :flags, :sign_count, :attested_credential_data, :raw
|
4
4
|
|
5
|
-
%i(credential_id public_key).each do |method|
|
5
|
+
%i(credential_id public_key public_cose_key).each do |method|
|
6
6
|
delegate method, to: :attested_credential_data, allow_nil: true
|
7
7
|
end
|
8
8
|
|
@@ -12,13 +12,17 @@ module WebAuthn
|
|
12
12
|
true
|
13
13
|
end
|
14
14
|
|
15
|
-
def verify!(encoded_authenticator_data,
|
15
|
+
def verify!(encoded_authenticator_data, sign_count:, signature:, public_key: nil, public_cose_key: nil, digest: OpenSSL::Digest::SHA256.new)
|
16
|
+
unless public_key || public_cose_key
|
17
|
+
raise ArgumentError, 'missing keyword: public_key or public_cose_key'
|
18
|
+
end
|
19
|
+
|
16
20
|
self.authenticator_data = AuthenticatorData.decode(
|
17
21
|
Base64.urlsafe_decode64 encoded_authenticator_data
|
18
22
|
)
|
19
23
|
verify_flags!
|
20
24
|
verify_sign_count!(sign_count)
|
21
|
-
verify_signature!(public_key, signature)
|
25
|
+
verify_signature!(public_key, public_cose_key, signature, digest)
|
22
26
|
self
|
23
27
|
end
|
24
28
|
|
@@ -39,16 +43,23 @@ module WebAuthn
|
|
39
43
|
end
|
40
44
|
end
|
41
45
|
|
42
|
-
def verify_signature!(public_key, signature)
|
43
|
-
# TODO:
|
44
|
-
# needs to handle digest size based on COSE key algorithm.
|
45
|
-
# how to get COSE key alg header at this point?
|
46
|
+
def verify_signature!(public_key, public_cose_key, signature, digest)
|
46
47
|
signature_base_string = [
|
47
48
|
authenticator_data.raw,
|
48
49
|
OpenSSL::Digest::SHA256.digest(client_data_json.raw)
|
49
50
|
].join
|
50
|
-
|
51
|
-
|
51
|
+
if public_cose_key
|
52
|
+
public_key, digest = [public_cose_key, public_cose_key.digest]
|
53
|
+
end
|
54
|
+
verification_method = case public_key
|
55
|
+
when OpenSSL::PKey::RSA
|
56
|
+
:verify_pss
|
57
|
+
when OpenSSL::PKey::EC
|
58
|
+
:verify
|
59
|
+
end
|
60
|
+
result = public_key.send(
|
61
|
+
verification_method,
|
62
|
+
digest,
|
52
63
|
Base64.urlsafe_decode64(signature),
|
53
64
|
signature_base_string
|
54
65
|
)
|
@@ -4,7 +4,7 @@ module WebAuthn
|
|
4
4
|
attr_accessor :attestation_object
|
5
5
|
|
6
6
|
# TODO: will need more methods, or let developers access deep methods by themselves.
|
7
|
-
%i(credential_id rp_id_hash flags public_key sign_count).each do |method|
|
7
|
+
%i(credential_id rp_id_hash flags public_key public_cose_key sign_count).each do |method|
|
8
8
|
delegate method, to: :attestation_object
|
9
9
|
end
|
10
10
|
|
@@ -30,7 +30,12 @@ raise unless context.authentication?
|
|
30
30
|
|
31
31
|
context.verify!(
|
32
32
|
authenticator_data,
|
33
|
+
# NOTE:
|
34
|
+
# either 'public_key' or 'public_cose_key' is required.
|
35
|
+
# if `public_key` is given, you can also specify `digest` (default: `OpenSSL::Digest::SHA256.new`).
|
36
|
+
# if `public_cose_key` is given, it includes digest size information, so no `digest` is required.
|
33
37
|
public_key: public_key,
|
38
|
+
# public_cose_key: public_cose_key,
|
34
39
|
sign_count: sign_count,
|
35
40
|
signature: signature
|
36
41
|
)
|
@@ -38,6 +38,7 @@ RSpec.describe WebAuthn::Context::Registration do
|
|
38
38
|
its(:rp_id_hash) { should == rp_id_hash }
|
39
39
|
its(:flags) { should == flags }
|
40
40
|
its(:public_key) { should be_instance_of OpenSSL::PKey::EC }
|
41
|
+
its(:public_cose_key) { should be_instance_of COSE::Key::EC2 }
|
41
42
|
its(:public_key_pem) do
|
42
43
|
subject.public_key.to_pem.should == public_key_pem
|
43
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: web_authn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nov matake
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|