credify 0.1.0 → 0.2.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: e2d00a170decb583685246f229dced080b4eb29399773680f0e8599ee8873af7
4
- data.tar.gz: 12d6f970b75bd07c67cfa444e2c8ae7e7a2a5c70ed014cb52b375fb81a21cf20
3
+ metadata.gz: 22b70b4ef4e0b030632a418609e96ff5f84002c57c2ab03f0b8dfa96c2269079
4
+ data.tar.gz: 27e4c5183a0ddd41131a00ba8ef76ceab4a335c13047a8285ad4c11f3855cd82
5
5
  SHA512:
6
- metadata.gz: 8a7b1682b30baffd0ef0c413ae6b26e9a24203323da32be9e59fc63f8a37c25c95b2dbc9ce4423ff9fb917429431693680d47a70275e9c12cb2cea41e70be470
7
- data.tar.gz: '058461c70f4d213b42216407bd996237cfe207883e732bfb19d1cd1dd7b53bc35efc081c439312491c0e2780ea52277cace79e42a61e0c697546890baa77a0c5'
6
+ metadata.gz: cd20625b4eaecd91a65127d140d5fb746076ae15b064dac3a27d88f5802049f14129543ef810a166838ba71352ade6cb58b051abb4a6e6b17565d8cc0cd03d60
7
+ data.tar.gz: 3bfc34738682cab00664f8264e0a9f19118964b7ce4b218e47c14a507f4152711178425caf7235a9a5d869bda59badfd2fbb4f2b6ff6c5cf17795fb095fa79f3
data/README.md CHANGED
@@ -40,6 +40,27 @@ def existing_key_is_used
40
40
  valid = signing.verify "message", signature
41
41
  puts valid
42
42
  end
43
+
44
+ def generate_approval_token
45
+ signing = Signing.new
46
+ signing.generate_key_pair
47
+ token = signing.generate_approval_token 'client_id', 'entity_id', ['openid', 'email', 'phone'], 'offer-code'
48
+ puts token
49
+ end
50
+
51
+ def generate_request_token
52
+ signing = Signing.new
53
+ signing.generate_key_pair
54
+ token = signing.generate_request_token 'client_id', 'encryption_public_key', ['openid', 'email', 'phone'], 'offer-code'
55
+ puts token
56
+ end
57
+
58
+ def generate_claim_token
59
+ signing = Signing.new
60
+ signing.generate_key_pair
61
+ result = signing.generate_claim_token 'provider_id', 'entity_id', 'credify-score', { score: 100 }
62
+ puts result
63
+ end
43
64
  ```
44
65
 
45
66
  ### Encryption
@@ -54,6 +75,8 @@ def new_key_is_generated
54
75
  encryption.generate_key_pair
55
76
  cipher_text = encryption.encrypt "secret message"
56
77
  plain_text = encryption.decrypt cipher_text
78
+ pem = encryption.export_private_key
79
+ puts pem
57
80
  end
58
81
 
59
82
  def existing_key_is_used
data/lib/credify.rb CHANGED
@@ -1,6 +1,36 @@
1
1
  require "credify/version"
2
+ require 'base64'
3
+ require 'securerandom'
2
4
 
3
5
  module Credify
4
6
  class Error < StandardError; end
5
- # Your code goes here...
7
+
8
+ class Helpers
9
+ def self.sha256(message)
10
+ base64 = Digest::SHA256.base64digest(message)
11
+ Helpers.short_urlsafe_encode64(Base64.decode64(base64))
12
+ end
13
+
14
+ #
15
+ # short_urlsafe_encode64
16
+ # @param [Binary] - str
17
+ # @return [String] - Base64 URL encoded string without padding
18
+ def self.short_urlsafe_encode64(bytes)
19
+ Base64.urlsafe_encode64(bytes).delete('=')
20
+ end
21
+
22
+ #
23
+ # short_urlsafe_decode64
24
+ # @return [Binary]
25
+ def self.short_urlsafe_decode64(str)
26
+ Base64.urlsafe_decode64(str + '=' * (-1 * str.size & 3))
27
+ end
28
+
29
+ def self.generate_commitment(bytes = 32)
30
+ random_bytes = SecureRandom.random_bytes(bytes)
31
+ short_urlsafe_encode64(random_bytes)
32
+ end
33
+
34
+ end
35
+
6
36
  end
@@ -2,6 +2,7 @@ require 'openssl'
2
2
  require 'openssl/oaep'
3
3
  require "base64"
4
4
  require 'openssl_pkcs8_pure'
5
+ require 'credify'
5
6
 
6
7
  class Encryption
7
8
  attr_reader :private_key, :public_key
@@ -43,7 +44,7 @@ class Encryption
43
44
  # @param [String] payload - Base64 URL encoded string
44
45
  # @return [Boolean]
45
46
  def import_private_key_base64_url(payload)
46
- bytes = short_urlsafe_decode64(payload)
47
+ bytes = Credify::Helpers.short_urlsafe_decode64(payload)
47
48
  base64 = Base64.encode64(bytes)
48
49
  formatted = base64.scan(/.{1,64}/).join("\n")
49
50
  pem = add_box('PRIVATE KEY', formatted)
@@ -55,7 +56,7 @@ class Encryption
55
56
  # @param [String] payload - Base64 URL encoded string
56
57
  # @return [Boolean]
57
58
  def import_public_key_base64_url(payload)
58
- bytes = short_urlsafe_decode64(payload)
59
+ bytes = Credify::Helpers.short_urlsafe_decode64(payload)
59
60
  base64 = Base64.encode64(bytes)
60
61
  formatted = base64.scan(/.{1,64}/).join("\n")
61
62
  pem = add_box('PUBLIC KEY', formatted)
@@ -73,7 +74,7 @@ class Encryption
73
74
  label = ''
74
75
  md = OpenSSL::Digest::SHA256
75
76
  cipher_text = @public_key.public_encrypt_oaep(message, label, md)
76
- short_urlsafe_encode64(cipher_text)
77
+ Credify::Helpers.short_urlsafe_encode64(cipher_text)
77
78
  end
78
79
 
79
80
  #
@@ -86,7 +87,7 @@ class Encryption
86
87
  end
87
88
  label = ''
88
89
  md = OpenSSL::Digest::SHA256
89
- raw_cipher = short_urlsafe_decode64(cipher)
90
+ raw_cipher = Credify::Helpers.short_urlsafe_decode64(cipher)
90
91
  raw_text = @private_key.private_decrypt_oaep(raw_cipher, label, md)
91
92
  raw_text
92
93
  end
@@ -94,7 +95,7 @@ class Encryption
94
95
  #
95
96
  # export_private_key
96
97
  # @param [Boolean] in_base64_url
97
- # @return [Signing] - PCKS8 PEM or Base64 URL encoded string
98
+ # @return [Signing | String] - PCKS8 PEM or Base64 URL encoded string
98
99
  def export_private_key(in_base64_url = false)
99
100
  if @private_key.nil?
100
101
  raise Exception.new 'Please pass private key'
@@ -103,7 +104,7 @@ class Encryption
103
104
 
104
105
  if in_base64_url
105
106
  formatted = remove_box('PRIVATE KEY', pem)
106
- short_urlsafe_encode64(Base64.decode64(formatted))
107
+ Credify::Helpers.short_urlsafe_encode64(Base64.decode64(formatted))
107
108
  else
108
109
  pem
109
110
  end
@@ -112,7 +113,7 @@ class Encryption
112
113
  #
113
114
  # export_public_key
114
115
  # @param [Boolean] in_base64_url
115
- # @return [Signing] - PCKS8 PEM or Base64 URL encoded string
116
+ # @return [Signing | String] - PCKS8 PEM or Base64 URL encoded string
116
117
  def export_public_key(in_base64_url = false)
117
118
  if @public_key.nil?
118
119
  raise Exception.new 'Please pass public key'
@@ -122,7 +123,7 @@ class Encryption
122
123
 
123
124
  if in_base64_url
124
125
  formatted = remove_box('PUBLIC KEY', pem)
125
- short_urlsafe_encode64(Base64.decode64(formatted))
126
+ Credify::Helpers.short_urlsafe_encode64(Base64.decode64(formatted))
126
127
  else
127
128
  pem
128
129
  end
@@ -131,7 +132,7 @@ class Encryption
131
132
 
132
133
  protected
133
134
 
134
-
135
+ #
135
136
  # remove_box
136
137
  # @param [String] tag - Either 'PUBLIC KEY' or 'PRIVATE KEY'
137
138
  # @param [String] pem - String value loaded from a PEM file
@@ -152,18 +153,4 @@ class Encryption
152
153
  "-----BEGIN #{tag}-----\n" << payload << "\n-----END #{tag}-----"
153
154
  end
154
155
 
155
- #
156
- # short_urlsafe_encode64
157
- # @param [Binary] - str
158
- # @return [String] - Base64 URL encoded string without padding
159
- def short_urlsafe_encode64(bytes)
160
- Base64.urlsafe_encode64(bytes).delete('=')
161
- end
162
-
163
- #
164
- # short_urlsafe_decode64
165
- # @return [Binary]
166
- def short_urlsafe_decode64(str)
167
- Base64.urlsafe_decode64(str + '=' * (-1 * str.size & 3))
168
- end
169
156
  end
@@ -1,6 +1,8 @@
1
1
  require "ed25519"
2
2
  require "base64"
3
+ require 'json'
3
4
  require 'openssl_pkcs8_pure'
5
+ require 'credify'
4
6
 
5
7
  class Signing
6
8
  attr_reader :signing_key
@@ -31,7 +33,7 @@ class Signing
31
33
  raise Exception.new 'Please pass signing key'
32
34
  end
33
35
  signature = @signing_key.sign(message)
34
- short_urlsafe_encode64(signature)
36
+ Credify::Helpers.short_urlsafe_encode64(signature)
35
37
  end
36
38
 
37
39
  #
@@ -43,7 +45,7 @@ class Signing
43
45
  if @signing_key.nil?
44
46
  raise Exception.new 'Please pass signing key'
45
47
  end
46
- raw_sign = short_urlsafe_decode64(signature)
48
+ raw_sign = Credify::Helpers.short_urlsafe_decode64(signature)
47
49
  @signing_key.verify_key.verify raw_sign, message
48
50
  end
49
51
 
@@ -57,21 +59,134 @@ class Signing
57
59
  Base64.encode64(@signing_key.seed)
58
60
  end
59
61
 
60
- protected
62
+ #
63
+ # generate_jwt
64
+ # @param [Hash] payload
65
+ # @return [String]
66
+ def generate_jwt(payload)
67
+ if payload.empty?
68
+ raise Exception.new 'Invalid payload'
69
+ end
70
+ header = {
71
+ alg: 'EdDSA',
72
+ typ: 'JWT'
73
+ }
74
+ message = compose_message(header, payload)
75
+ signature = sign(message)
76
+ message << '.' << signature
77
+ end
78
+
79
+ #
80
+ # parse_jwt
81
+ # @param [String] jwt
82
+ # @return [Hash] - { header: '', payload: {}, signature: '' }
83
+ def parse_jwt(jwt)
84
+ components = jwt.split('.')
85
+ unless components.length == 3
86
+ raise Exception 'JST is invalid'
87
+ end
88
+
89
+ header = JSON.parse(Credify::Helpers.short_urlsafe_decode64(components[0]))
90
+ payload = JSON.parse(Credify::Helpers.short_urlsafe_decode64(components[1]))
91
+ { header: header, payload: payload, signature: components[2] }
92
+ end
93
+
94
+ #
95
+ # verify_jwt
96
+ # @param [Hash] jwt - { header: '', payload: {}, signature: '' }
97
+ # @return [Boolean]
98
+ def verify_jwt(jwt)
99
+ message = compose_message(jwt[:header], jwt[:payload])
100
+ verify(jwt[:signature], message)
101
+ end
61
102
 
62
103
  #
63
- # short_urlsafe_encode64
64
- # @param [Binary] - str
65
- # @return [String] - Base64 URL encoded string without padding
66
- def short_urlsafe_encode64(bytes)
67
- Base64.urlsafe_encode64(bytes).delete('=')
104
+ # generate_approval_token
105
+ # @param [String] client_id
106
+ # @param [String] entity_id
107
+ # @param [String[]] approved_scopes
108
+ # @param [String | nil] offer_code
109
+ # @return [String]
110
+ def generate_approval_token(client_id, entity_id, approved_scopes, offer_code = nil)
111
+ # minus 60 just in case this timestamp could collide one in the server side.
112
+ now = Time.now.to_i - 60
113
+ payload = {
114
+ client_id: client_id,
115
+ iat: now,
116
+ iss: entity_id,
117
+ scopes: approved_scopes.join(' ')
118
+ }
119
+ unless offer_code.nil?
120
+ payload[:offer_code] = offer_code
121
+ end
122
+ generate_jwt(payload)
123
+ end
124
+
125
+ #
126
+ # generate_claim_token
127
+ # @param [String] provider_id
128
+ # @param [String] entity_id
129
+ # @param [String] scope_name
130
+ # @param [Hash] claim
131
+ # @return [Hash]
132
+ def generate_claim_token(provider_id, entity_id, scope_name, claim)
133
+ # minus 60 just in case this timestamp could collide one in the server side.
134
+ now = Time.now.to_i - 60
135
+ commitment = Credify::Helpers.generate_commitment
136
+ data = claim[:"#{scope_name}:commitment"] = commitment
137
+ scope_hash = Credify::Helpers.sha256(data)
138
+ puts scope_hash
139
+ payload = {
140
+ iat: now,
141
+ iss: provider_id,
142
+ user_id: entity_id,
143
+ scope_name: scope_name,
144
+ scope_hash: scope_hash
145
+ }
146
+ token = generate_jwt(payload)
147
+ { token: token, commitment: commitment }
68
148
  end
69
149
 
70
150
  #
71
- # short_urlsafe_decode64
72
- # @return [Binary]
73
- def short_urlsafe_decode64(str)
74
- Base64.urlsafe_decode64(str + '=' * (-1 * str.size & 3))
151
+ # generate_request_token
152
+ # @param [String] client_id
153
+ # @param [String] encryption_public_key - Encryption public key in Base64 URL
154
+ # @param [String[]] scopes
155
+ # @param [String | nil] offer_code
156
+ # @return [String]
157
+ def generate_request_token(client_id, encryption_public_key, scopes, offer_code = nil)
158
+ unless scopes.include?('openid')
159
+ raise Exception 'scopes need to contain openid'
160
+ end
161
+ # minus 60 just in case this timestamp could collide one in the server side.
162
+ now = Time.now.to_i - 60
163
+ payload = {
164
+ iat: now,
165
+ iss: client_id,
166
+ encryption_public_key: encryption_public_key,
167
+ scopes: scopes.join(' ')
168
+ }
169
+ unless offer_code.nil?
170
+ payload[:offer_code] = offer_code
171
+ end
172
+ generate_jwt(payload)
173
+ end
174
+
175
+ protected
176
+
177
+
178
+ # compose_message
179
+ # @param [Hash] header
180
+ # @param [Hash] payload
181
+ # @return [String]
182
+ def compose_message(header, payload)
183
+ encoded_header = header.to_json
184
+ h = Credify::Helpers.short_urlsafe_encode64(encoded_header)
185
+
186
+ encoded_payload = payload.to_json
187
+ p = Credify::Helpers.short_urlsafe_encode64(encoded_payload)
188
+
189
+ h << '.' << p
75
190
  end
76
191
 
77
192
  end
@@ -1,3 +1,3 @@
1
1
  module Credify
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: credify
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - credify-pte-ltd