aliquot 0.15.0 → 1.0.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: 54635adaeefcc42d7fb42a854825fb7f88472ab34be2992813d899581f278969
4
- data.tar.gz: 3f66d3b5d5cc20d3a58e0c0e64958906beee8e80f07af26a4868ad27efa68e2d
3
+ metadata.gz: 0cdd20926e96b21c0fb8c494b13fe34995c59646285d71416c33045e907b830a
4
+ data.tar.gz: 32d7e64f5ef20f37404bcc5293672dbaa43f6d299bd0701e49b859ad2e9c1a25
5
5
  SHA512:
6
- metadata.gz: 23548bcc9c7e7a5ad77353bae8eab0283bd7593b3a9cf536298961d501a0b1b3181b722bf3e75ae0805d9c9dfa336d71a037ed5553eb57d0082b69a7e62aa60b
7
- data.tar.gz: a14a66a56577b6de570fa4164f30d2ca96c3a23b5b6b915d136dfd7d825242c0ae6a403cc138ff97e26f76dcad1450ba67d8a733f7b45611141ba46241fafdb8
6
+ metadata.gz: 1b555a97041aaaf6e4cd3e3aaf82c17a94112627f36cc3e0835a4708c28eef8e8f6a4f20e51b978876cc77a1ced87b6a4b6066a7effd52e2a027c5d152a78995
7
+ data.tar.gz: ee081263c8ad3869eaa53127ec7ed300f9bba4c67619c548ed83099932cf0978cf3e0ec48dbca47e054a01f79f747c261a0e96eb84d26e9665846dbfed5a2025
@@ -26,7 +26,7 @@ module Aliquot
26
26
  validation = Aliquot::Validator::Token.new(JSON.parse(token_string))
27
27
  validation.validate
28
28
  rescue JSON::JSONError => e
29
- raise InputError, "invalid token JSON, #{e.message}"
29
+ raise InputError, "token JSON is invalid, #{e.message}"
30
30
  end
31
31
 
32
32
  @token = validation.output
@@ -49,7 +49,7 @@ module Aliquot
49
49
 
50
50
  if protocol_version == 'ECv2'
51
51
  @intermediate_key = validate_intermediate_key
52
- raise InvalidSignatureError, 'intermediate certificate has expired' if intermediate_key_expired?
52
+ raise InvalidSignatureError, 'intermediate certificate is expired' if intermediate_key_expired?
53
53
  end
54
54
 
55
55
  check_signature
@@ -59,22 +59,22 @@ module Aliquot
59
59
  begin
60
60
  aes_key, mac_key = derive_keys(@signed_message[:ephemeralPublicKey], @shared_secret, 'Google')
61
61
  rescue => e
62
- raise KeyDerivationError, "unable to derive keys, #{e.message}"
62
+ raise KeyDerivationError, "cannot derive keys, #{e.message}"
63
63
  end
64
64
 
65
- raise InvalidMacError, 'MAC did not match' unless valid_mac?(mac_key)
65
+ raise InvalidMacError, 'MAC does not match' unless valid_mac?(mac_key)
66
66
 
67
67
  begin
68
68
  @message = JSON.parse(decrypt(aes_key, @signed_message[:encryptedMessage]))
69
69
  rescue JSON::JSONError => e
70
- raise InputError, "invalid encryptedMessage JSON, #{e.message}"
70
+ raise InputError, "encryptedMessage JSON is invalid, #{e.message}"
71
71
  rescue => e
72
72
  raise DecryptionError, "decryption failed, #{e.message}"
73
73
  end
74
74
 
75
75
  @message = validate_message
76
76
 
77
- raise TokenExpiredError, 'token has expired' if expired?
77
+ raise TokenExpiredError, 'token is expired' if expired?
78
78
 
79
79
  @message
80
80
  end
@@ -133,7 +133,7 @@ module Aliquot
133
133
  key.verify(new_digest, message_signature, signed_string_message)
134
134
  end.any?
135
135
 
136
- raise InvalidSignatureError, 'signature of signedMessage did not match' unless success
136
+ raise InvalidSignatureError, 'signature of signedMessage does not match' unless success
137
137
  when 'ECv2'
138
138
  signed_key_signature = ['Google', 'ECv2', @token[:intermediateSigningKey][:signedKey]].map do |str|
139
139
  [str.length].pack('V') + str
@@ -141,7 +141,7 @@ module Aliquot
141
141
 
142
142
  # Check that the intermediate key signed the message
143
143
  pkey = OpenSSL::PKey::EC.new(Base64.strict_decode64(@intermediate_key[:keyValue]))
144
- raise InvalidSignatureError, 'signature of signedMessage did not match' unless pkey.verify(new_digest, message_signature, signed_string_message)
144
+ raise InvalidSignatureError, 'signature of signedMessage does not match' unless pkey.verify(new_digest, message_signature, signed_string_message)
145
145
 
146
146
  intermediate_signatures = @token[:intermediateSigningKey][:signatures]
147
147
 
@@ -152,7 +152,7 @@ module Aliquot
152
152
  signed_key_signature
153
153
  )
154
154
 
155
- raise InvalidSignatureError, 'no valid signature of intermediate key found' unless success
155
+ raise InvalidSignatureError, 'no valid signature of intermediate key' unless success
156
156
  end
157
157
  rescue OpenSSL::PKey::PKeyError => e
158
158
  # Catches problems with verifying signature. Can be caused by signature
@@ -22,6 +22,7 @@ module Aliquot
22
22
  month?: 'must be a month (1..12)',
23
23
  year?: 'must be a year (2000..3000)',
24
24
  base64_asn1?: 'must be base64 encoded asn1 value',
25
+ json_object?: 'must be a JSON object',
25
26
 
26
27
  authMethodCryptogram3DS: 'authMethod CRYPTOGRAM_3DS requires eciIndicator',
27
28
  authMethodCard: 'eciIndicator/cryptogram must be omitted when PAN_ONLY',
@@ -64,6 +65,8 @@ module Aliquot
64
65
  predicate(:year?) { |x| x.between?(2000, 3000) }
65
66
 
66
67
  predicate(:base64_asn1?) { |x| OpenSSL::ASN1.decode(Base64.strict_decode64(x)) rescue false }
68
+
69
+ predicate(:json_object?) { |x| hash?(x) }
67
70
  end
68
71
 
69
72
  # Base for DRY-Validation schemas used in Aliquot.
@@ -78,7 +81,6 @@ module Aliquot
78
81
  IntermediateSigningKeySchema = Dry::Validation.Schema(BaseSchema) do
79
82
  required(:signedKey).filled(:str?, :json_string?)
80
83
 
81
- # TODO: Check if elements of array are valid signatures
82
84
  required(:signatures).filled(:array?) { each { base64? & base64_asn1? } }
83
85
  end
84
86
 
@@ -91,21 +93,19 @@ module Aliquot
91
93
  TokenSchema = Dry::Validation.Schema(BaseSchema) do
92
94
  required(:signature).filled(:str?, :base64?, :base64_asn1?)
93
95
 
94
- # Currently supposed to be ECv1, but may evolve.
95
- required(:protocolVersion).filled(:str?)
96
- required(:signedMessage).filled(:str?, :json_string?)
96
+ required(:protocolVersion).filled(:str?).when(eql?: 'ECv2') do
97
+ required(:intermediateSigningKey)
98
+ end
97
99
 
98
- optional(:intermediateSigningKey).schema(IntermediateSigningKeySchema)
100
+ required(:signedMessage).filled(:str?, :json_string?)
99
101
 
100
- rule('ECv2 implies intermediateSigningKey': %i[protocolVersion intermediateSigningKey]) do |version, intermediatekey|
101
- version.eql?('ECv2') > intermediatekey.filled?
102
- end
102
+ optional(:intermediateSigningKey).value(:json_object?) { schema(IntermediateSigningKeySchema) }
103
103
  end
104
104
 
105
105
  # DRY-Validation schema for signedMessage component Google Pay token
106
106
  SignedMessageSchema = Dry::Validation.Schema(BaseSchema) do
107
107
  required(:encryptedMessage).filled(:str?, :base64?)
108
- required(:ephemeralPublicKey).filled(:str?, :base64?).value(size?: 44)
108
+ required(:ephemeralPublicKey).filled(:str?, :base64?)
109
109
  required(:tag).filled(:str?, :base64?)
110
110
  end
111
111
 
@@ -119,15 +119,15 @@ module Aliquot
119
119
  optional(:cryptogram).filled(:str?)
120
120
  optional(:eciIndicator).filled(:str?, :eci?)
121
121
 
122
- rule('when authMethod is CRYPTOGRAM_3DS, cryptogram': %i[authMethod cryptogram]) do |method, cryptogram|
123
- method.eql?('CRYPTOGRAM_3DS') > cryptogram.filled?
122
+ rule(cryptogram: %i[authMethod cryptogram]) do |method, cryptogram|
123
+ method.eql?('CRYPTOGRAM_3DS') > required(:cryptogram)
124
124
  end
125
125
 
126
- rule('when authMethod is PAN_ONLY, eciIndicator': %i[authMethod eciIndicator]) do |method, eci|
126
+ rule(eciIndicator: %i[authMethod eciIndicator]) do |method, eci|
127
127
  method.eql?('PAN_ONLY').then(eci.none?)
128
128
  end
129
129
 
130
- rule('when authMethod is PAN_ONLY, cryptogram': %i[authMethod cryptogram]) do |method, cryptogram|
130
+ rule(cryptogram: %i[authMethod cryptogram]) do |method, cryptogram|
131
131
  method.eql?('PAN_ONLY').then(cryptogram.none?)
132
132
  end
133
133
  end
@@ -137,7 +137,7 @@ module Aliquot
137
137
  required(:messageExpiration).filled(:str?, :integer_string?)
138
138
  required(:messageId).filled(:str?)
139
139
  required(:paymentMethod).filled(:str?, eql?: 'CARD')
140
- required(:paymentMethodDetails).schema(PaymentMethodDetailsSchema)
140
+ required(:paymentMethodDetails).value(:json_object?) { schema PaymentMethodDetailsSchema }
141
141
  end
142
142
 
143
143
  module InstanceMethods
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aliquot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 1.0.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-17 00:00:00.000000000 Z
11
+ date: 2019-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-validation
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.12.0
61
+ version: 1.0.0
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.12.0
68
+ version: 1.0.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement