simplicity_client 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/fido2_client.rb +91 -0
  3. metadata +2 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35ccb4c05970e3765687119f1761b0c1ff47965ab6311f5e86e5fb321b8e87fd
4
- data.tar.gz: dfc4d51cf8d179a2901c62aaa576828193ddf6ef87a9aba6793da75da6825737
3
+ metadata.gz: 3283578b786c0a520eeaee6b46290f1459e9075925f8fdf172534ac533270e33
4
+ data.tar.gz: cee5f3f5ac077c4cea0bc246d7f1a4b2ea03a23db7ad21795485730685ba3959
5
5
  SHA512:
6
- metadata.gz: 6ef0ea4b00d2ae9ae5deaaf317759fe595e7221fbfe46175c48747355e388ab4faaf4f0b272ccd6c57ec7c11fc7f06037dd35b6f9e76998c8258d36a6c406dfb
7
- data.tar.gz: 6c7618d98c48fc47adfa19931cb68a1fe67d612cc17e1e51c0a6cfdd7d708cffedf7dffd3ff96e425a890990c2b56d629541184edb033de49e2634d49f1e5be4
6
+ metadata.gz: 2ddd8ee90c05b00ba4ed232846f5c2e546e087c93c7e2c3a58965c74480640fe04823bea6d94c9b3b0f58e64f41cd738b8b157420b71d5864846cb74e0600185
7
+ data.tar.gz: fbf5d020b63bae7fd804154b34513d95e9991afa39023877905072e69df66879b4afd3e7028251204e314720c4ca472860dc9e81d86d4a90e521202791dd7bbe
@@ -0,0 +1,91 @@
1
+ require "json"
2
+ require "digest"
3
+ require "openssl"
4
+ require "base64"
5
+
6
+ module Fido2Client
7
+ Passkey = Data.define(:credentialId, :keyAlgorithm, :keyCurve, :keyValue, :userHandle)
8
+ Assertion = Data.define(:authenticator_data, :client_data_json, :credential_id, :user_handle, :signature)
9
+
10
+ class Client
11
+ def initialize
12
+ @origin = "https://app.simplicity.kiwi"
13
+ @rp_id = "simplicity.kiwi"
14
+ end
15
+
16
+ def get_assertion(passkey, challenge)
17
+ collected_client_data = {
18
+ type: "webauthn.get",
19
+ challenge: challenge,
20
+ origin: @origin,
21
+ crossOrigin: false,
22
+ }
23
+ client_data_json = JSON.dump(collected_client_data)
24
+ client_data_hash = Digest::SHA256.digest(client_data_json)
25
+
26
+ # Assertion
27
+ auth_data = generate_auth_data
28
+ private_key = parse_private_key(passkey.keyAlgorithm, passkey.keyCurve, passkey.keyValue)
29
+ signature = generate_signature(auth_data, client_data_hash, private_key)
30
+
31
+ Assertion.new(
32
+ authenticator_data: Base64.urlsafe_encode64(auth_data.pack("c*"), padding: false),
33
+ client_data_json: Base64.urlsafe_encode64(client_data_json, padding: false),
34
+ credential_id: Base64.urlsafe_encode64(guid_to_raw_format(passkey.credentialId), padding: false),
35
+ user_handle: passkey.userHandle,
36
+ signature: Base64.urlsafe_encode64(signature, padding: false),
37
+ )
38
+ end
39
+
40
+ private
41
+
42
+ def box(tag, lines)
43
+ lines.unshift "-----BEGIN #{tag}-----"
44
+ lines.push "-----END #{tag}-----"
45
+ lines.join("\n")
46
+ end
47
+
48
+ def der_to_pem(tag, der)
49
+ box tag, Base64.strict_encode64(der).scan(/.{1,64}/)
50
+ end
51
+
52
+ def parse_private_key(key_algorithm, key_curve, key_value)
53
+ raise "Unsupported key algorithm: #{key_algorithm}" unless key_algorithm == "ECDSA"
54
+ raise "Unsupported key curve: #{key_curve}" unless key_curve == "P-256"
55
+
56
+ # Decode the Base64 key value
57
+ key_value_bin = Base64.urlsafe_decode64(key_value)
58
+
59
+ pem = der_to_pem("PRIVATE KEY", key_value_bin)
60
+ OpenSSL::PKey::EC.new(pem)
61
+ end
62
+
63
+ def generate_signature(auth_data, client_data_hash, private_key)
64
+ sig_base = [*auth_data, *client_data_hash.bytes]
65
+ digest = OpenSSL::Digest.new("SHA256")
66
+ private_key.sign(digest, sig_base.pack("c*"))
67
+ end
68
+
69
+ def generate_auth_data
70
+ auth_data = []
71
+ rp_id_hash = Digest::SHA256.digest(@rp_id)
72
+ auth_data += rp_id_hash.bytes
73
+
74
+ # Flags asserted: Backup eligibility, Backup State, User Verification, User Presence
75
+ flags = 0x1D
76
+ auth_data.push(flags)
77
+
78
+ # Counter
79
+ auth_data += [0, 0, 0, 0]
80
+
81
+ auth_data
82
+ end
83
+
84
+ def guid_to_raw_format(guid)
85
+ raise TypeError, "GUID parameter is invalid" unless guid.match?(/\A[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\z/)
86
+
87
+ # Remove the hyphens and pack the string into raw binary
88
+ [guid.delete("-")].pack("H*")
89
+ end
90
+ end
91
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplicity_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - George Dewar
@@ -101,6 +101,7 @@ executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
+ - lib/fido2_client.rb
104
105
  - lib/simplicity_client.rb
105
106
  homepage: https://github.com/GeorgeDewar/simplicity_client
106
107
  licenses: