aliquot-pay 0.6.0 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6ef1cc665eda9098620eba68b1ad54f84fbf95a7451000aed962e955df683bc
4
- data.tar.gz: a6126ced2a1928849052ebed350163990d5f74aff97d26100f54a60189bb092f
3
+ metadata.gz: 44e7c529e137eb8f24695acbee32655f9a1099fb129037ae7a6b7fb9df7eb024
4
+ data.tar.gz: 30134f32f42423d14db49b1ddd3d52d1f9e2efc30c8646ffe64f1ffac199863b
5
5
  SHA512:
6
- metadata.gz: 7ad4156b308d5f0cb263f0ceb2b64db99ec373f073bb71339cb0866812979448345cfee99beddebeaf816cdd38e0d17cb793c39832f366dfa108c9d368a257a8
7
- data.tar.gz: 87a621a3d085c84cec0b393a737a3d05ae5d7afa5b144cfecac0babd1e8ce55d06727428b7fabad9f247c3191a2b26c6ae3369b9c2137e0930d4a9fb8f7ab362
6
+ metadata.gz: 8e8475d0481e3a95fa3211a305645921d07bbd5c50ff5d4e7288a7adbb8974da04fc91c886f3f22d628e5acb1cfc06f988f5203605fd59cdf934b13b1ed54f76
7
+ data.tar.gz: 4057c7276c7ce1f0fb9cc6cdfac418fa1a83a0e2a422570ab61205e49b6d0b19cdbdcd64e8c4612be6c4078af5b2a2448c8210a38a478a74b0e1b76fde46faf0
@@ -11,18 +11,18 @@ module AliquotPay
11
11
  private_key.dh_compute_key(public_key)
12
12
  end
13
13
 
14
- def self.derive_keys(ephemeral_public_key, shared_secret, info)
14
+ def self.derive_keys(ephemeral_public_key, shared_secret, info, length: 32)
15
15
  input_keying_material = ephemeral_public_key + shared_secret
16
16
  if OpenSSL.const_defined?(:KDF) && OpenSSL::KDF.respond_to?(:hkdf)
17
17
  h = OpenSSL::Digest::SHA256.new
18
- hbytes = OpenSSL::KDF.hkdf(input_keying_material, hash: h, salt: '', length: 32, info: info)
18
+ hbytes = OpenSSL::KDF.hkdf(input_keying_material, hash: h, salt: '', length: length * 2, info: info)
19
19
  else
20
- hbytes = HKDF.new(input_keying_material, algorithm: 'SHA256', info: info).next_bytes(32)
20
+ hbytes = HKDF.new(input_keying_material, algorithm: 'SHA256', info: info).next_bytes(length * 2)
21
21
  end
22
22
 
23
23
  {
24
- aes_key: hbytes[0..15],
25
- mac_key: hbytes[16..32],
24
+ aes_key: hbytes[0..length - 1],
25
+ mac_key: hbytes[length..2 * length],
26
26
  }
27
27
  end
28
28
 
data/lib/aliquot-pay.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'base64'
2
2
  require 'openssl'
3
+ require 'json'
3
4
 
4
5
  require 'aliquot-pay/util'
5
6
 
@@ -13,23 +14,22 @@ module AliquotPay
13
14
  merchant_id: 'merchant:0123456789',
14
15
  }.freeze
15
16
 
16
- def self.sign(key, encrypted_message)
17
+ def self.sign(key, message)
17
18
  d = OpenSSL::Digest::SHA256.new
18
19
  def key.private?; private_key?; end
19
- Base64.strict_encode64(key.sign(d, encrypted_message))
20
+ Base64.strict_encode64(key.sign(d, message))
20
21
  end
21
22
 
22
- def self.encrypt(cleartext_message, recipient, info = 'Google')
23
+ def self.encrypt(cleartext_message, recipient, cipher, info = 'Google')
23
24
  eph = AliquotPay::Util.generate_ephemeral_key
24
25
  ss = AliquotPay::Util.generate_shared_secret(eph, recipient.public_key)
25
26
 
26
- keys = AliquotPay::Util.derive_keys(eph.public_key.to_bn.to_s(2), ss, info)
27
+ keys = AliquotPay::Util.derive_keys(eph.public_key.to_bn.to_s(2), ss, info, length: cipher.key_len)
27
28
 
28
- c = OpenSSL::Cipher::AES128.new(:CTR)
29
- c.encrypt
30
- c.key = keys[:aes_key]
29
+ cipher.encrypt
30
+ cipher.key = keys[:aes_key]
31
31
 
32
- encrypted_message = c.update(cleartext_message) + c.final
32
+ encrypted_message = cipher.update(cleartext_message) + cipher.final
33
33
 
34
34
  tag = AliquotPay::Util.calculate_tag(keys[:mac_key], encrypted_message)
35
35
 
@@ -72,6 +72,12 @@ module AliquotPay
72
72
  [str.length].pack('V')
73
73
  end
74
74
 
75
+ def self.generate_signature(*args)
76
+ args.map do |s|
77
+ four_byte_length(s) + s
78
+ end.join('')
79
+ end
80
+
75
81
  def self.signature_string(
76
82
  message,
77
83
  recipient_id = DEFAULTS[:merchant_id],
@@ -79,29 +85,46 @@ module AliquotPay
79
85
  protocol_version = 'ECv1'
80
86
  )
81
87
 
82
- four_byte_length(sender_id) +
83
- sender_id +
84
- four_byte_length(recipient_id) +
85
- recipient_id +
86
- four_byte_length(protocol_version) +
87
- protocol_version +
88
- four_byte_length(message) +
89
- message
88
+ generate_signature(sender_id, recipient_id, protocol_version, message)
90
89
  end
91
90
 
92
- # payment:: Google Pay token as a ruby Hash
93
- # signing_key:: OpenSSL::PKEY::EC
94
- # recipient:: OpenSSL::PKey::EC
95
- # encrypted_message:: SignedMessage
96
- def self.generate_token(payment, signing_key, recipient, signed_message = nil)
97
- signed_message ||= JSON.unparse(AliquotPay.encrypt(JSON.unparse(payment), recipient))
98
-
99
- signature_string = AliquotPay.signature_string(signed_message)
91
+ # payment:: Google Pay token as a ruby Hash
92
+ # signing_key:: OpenSSL::PKEY::EC
93
+ # recipient:: OpenSSL::PKey::EC
94
+ # signed_message:: Pass a customized message to sign as signed messaged.
95
+ def self.generate_token_ecv1(payment, signing_key, recipient, signed_message = nil)
96
+ cipher = OpenSSL::Cipher::AES128.new(:CTR)
97
+ signed_message ||= JSON.unparse(encrypt(JSON.unparse(payment), recipient, cipher))
98
+ signature_string = signature_string(signed_message)
100
99
 
101
100
  {
102
101
  'protocolVersion' => 'ECv1',
103
- 'signature' => AliquotPay.sign(signing_key, signature_string),
102
+ 'signature' => sign(signing_key, signature_string),
103
+ 'signedMessage' => signed_message,
104
+ }
105
+ end
106
+
107
+ def self.generate_token_ecv2(payment, signing_key, intermediate_key, recipient, signed_message)
108
+ cipher = OpenSSL::Cipher::AES256.new(:CTR)
109
+ signed_message ||= JSON.unparse(encrypt(JSON.unparse(payment), recipient, cipher))
110
+ signature_string = signature_string(signed_message)
111
+
112
+ signed_key = JSON.unparse(
113
+ 'keyExpiration' => "#{Time.now.to_i + 3600}000",
114
+ 'keyValue' => Base64.strict_encode64(intermediate_key.public_key.to_bn.to_s(2))
115
+ )
116
+
117
+ ik_signature_string = generate_signature('Google', 'ECv2', signed_key)
118
+ signatures = [sign(signing_key, ik_signature_string)]
119
+
120
+ {
121
+ 'protocolVersion' => 'ECv2',
122
+ 'signature' => sign(intermediate_key, signature_string),
104
123
  'signedMessage' => signed_message,
124
+ 'interMediateSigningKey' => {
125
+ 'signedKey' => signed_key,
126
+ 'signatures' => signatures,
127
+ },
105
128
  }
106
129
  end
107
130
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliquot-pay
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Clearhaus
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-08 00:00:00.000000000 Z
11
+ date: 2019-01-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hkdf