itunes_receipt_decoder 0.2.3 → 0.3.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
  SHA1:
3
- metadata.gz: 7249d3ca881c622ef2e0ccd6d94be8da200eece2
4
- data.tar.gz: ccea5b7c522881e76705920a20a6ab49a396d7ea
3
+ metadata.gz: be8ac7da532b84da681984f7e5e51e8677133d77
4
+ data.tar.gz: fc0888f8a80f019e20059535fe6e926ed5c56e40
5
5
  SHA512:
6
- metadata.gz: 812a954786a1bb1dc53677e68a8fe8494b6f8f46765d5ce8404132354680bccffc774bd2fb909e1d76e06e643493da1b4b010eb701b3e680270c91093e86b562
7
- data.tar.gz: 0887a6b967bdd98309bc052812bfee0500d3cdcec88725e8cf0f109f3e0e0ff2de186e5624bfc73ce46d68ccedf820d7cc41c4f2d9cc0f2adb767b036db21394
6
+ metadata.gz: 056453f28cb7f4b62464736c07cbdc90bfe53aa1802d371075fe418146646d11312047cbec620edea1620c4f0b1b4a80319992db6bbf63f93b28314ce3ada481
7
+ data.tar.gz: b9d31eb78fef4c3753aa19f610cf092474757bee9b01339b303e8a853a286c30405244fcea628a00bb375a9460b97c4cd9b48e3fbab4bb8b1577a8989c39ae89
@@ -1,8 +1,4 @@
1
- require 'time'
2
- require 'openssl'
3
- require 'cfpropertylist'
4
1
  require 'itunes_receipt_decoder/version'
5
- require 'itunes_receipt_decoder/decode/base'
6
2
  require 'itunes_receipt_decoder/decode/transaction_receipt'
7
3
  require 'itunes_receipt_decoder/decode/unified_receipt'
8
4
 
@@ -9,7 +9,7 @@ module ItunesReceiptDecoder
9
9
  class Base
10
10
  ##
11
11
  # The raw receipt, i.e. not base64 encoded
12
- attr_reader :raw_receipt, :receipt, :options, :style, :environment
12
+ attr_reader :raw_receipt, :receipt, :options, :environment
13
13
 
14
14
  ##
15
15
  # Initializes with a raw (base64 decoded receipt)
@@ -1,3 +1,7 @@
1
+ require 'openssl'
2
+ require 'cfpropertylist'
3
+ require 'itunes_receipt_decoder/decode/base'
4
+
1
5
  ##
2
6
  # ItunesReceiptDecoder
3
7
  module ItunesReceiptDecoder
@@ -7,9 +11,33 @@ module ItunesReceiptDecoder
7
11
  ##
8
12
  # ItunesReceiptDecoder::Decode::TransactionReceipt
9
13
  class TransactionReceipt < Base
10
- def initialize(raw_receipt, options = {})
11
- @style = :transaction
12
- super
14
+ PUBLIC_KEY = OpenSSL::PKey::RSA.new <<-PUBLIC_KEY
15
+ -----BEGIN PUBLIC KEY-----
16
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApLyvMpRDPgu8N4fNY4ny
17
+ zNm+IE1atP6HZ9Ka3hpUnaLz34fkTMuTEXigMI80QcHTvmZtR2yYuOx61cndpeTq
18
+ xnD0NdCR97PYChGZqzpiOr179FZP258kk1FQfCDVZk1m8xikE5YiFv0xp/Q5Zpv7
19
+ YmlcS5+UqEvo7FtkWhh5ihZ1Y0KkSdmMM96te9Y5BPTinQppjOtLEihLNEgHmw5Z
20
+ +R9isAOfNrhOo9N1WdTzOgXKxTM7+MAGCQiT2+dNvxHzUiylFjUV80ECzQLR/PX4
21
+ xYS9Y2qG1raZ9oauX/0D1CiKWl2vvGV00fcaw5II9BytaegCTA6VFQe8vmpvwbOt
22
+ oQIDAQAB
23
+ -----END PUBLIC KEY-----
24
+ PUBLIC_KEY
25
+
26
+ def style
27
+ :transaction
28
+ end
29
+
30
+ def signature_valid?
31
+ version, sig, cert_length, cert =
32
+ payload.fetch('signature').unpack('m').first.unpack('c a128 N a*')
33
+ return false unless
34
+ version == 2 &&
35
+ sig.size == 128 &&
36
+ cert.size == cert_length &&
37
+ (cert = OpenSSL::X509::Certificate.new(cert)) &&
38
+ cert.verify(PUBLIC_KEY)
39
+ data = [version, purchase_info].pack('ca*')
40
+ cert.public_key.verify(OpenSSL::Digest::SHA1.new, sig, data)
13
41
  end
14
42
 
15
43
  private
@@ -24,16 +52,16 @@ module ItunesReceiptDecoder
24
52
  end
25
53
 
26
54
  def parse_purchase_info
27
- purchase_info.keys.each do |key|
55
+ result = parse_plist(purchase_info)
56
+ result.keys.each do |key|
28
57
  new_key = key.tr('-', '_').to_sym
29
- purchase_info[new_key] = purchase_info.delete(key)
58
+ result[new_key] = result.delete(key)
30
59
  end
31
- purchase_info
60
+ result
32
61
  end
33
62
 
34
63
  def purchase_info
35
- @purchase_info ||=
36
- parse_plist(payload.fetch('purchase-info').unpack('m').first)
64
+ @purchase_info ||= payload.fetch('purchase-info').unpack('m').first
37
65
  end
38
66
 
39
67
  def payload
@@ -1,3 +1,7 @@
1
+ require 'time'
2
+ require 'openssl'
3
+ require 'itunes_receipt_decoder/decode/base'
4
+
1
5
  ##
2
6
  # ItunesReceiptDecoder
3
7
  module ItunesReceiptDecoder
@@ -7,6 +11,18 @@ module ItunesReceiptDecoder
7
11
  ##
8
12
  # ItunesReceiptDecoder::Decode::UnifiedReceipt
9
13
  class UnifiedReceipt < Base
14
+ PUBLIC_KEY = OpenSSL::PKey::RSA.new <<-PUBLIC_KEY
15
+ -----BEGIN PUBLIC KEY-----
16
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyjhUpstWqsgkOUjpjO7s
17
+ X7h/JpG8NFN6znxjgGF3ZF6lByO2Of5QLRVWWHAtfsRuwUqFPi/w3oQaoVfJr3sY
18
+ /2r6FRJJFQgZrKrbKjLtlmNoUhU9jIrsv2sYleADrAF9lwVnzg6FlTdq7Qm2rmfN
19
+ UWSfxlzRvFduZzWAdjakh4FuOI/YKxVOeyXYWr9Og8GN0pPVGnG1YJydM05V+RJY
20
+ DIa4Fg3B5XdFjVBIuist5JSF4ejEncZopbCj/Gd+cLoCWUt3QpE5ufXN4UzvwDtI
21
+ jKblIV39amq7pxY1YNLmrfNGKcnow4vpecBqYWcVsvD95Wi8Yl9uz5nd7xtj/pJl
22
+ qwIDAQAB
23
+ -----END PUBLIC KEY-----
24
+ PUBLIC_KEY
25
+
10
26
  ##
11
27
  # ASN.1 Field types
12
28
  #
@@ -15,6 +31,8 @@ module ItunesReceiptDecoder
15
31
  0 => :environment,
16
32
  2 => :bundle_id,
17
33
  3 => :application_version,
34
+ 4 => :opaque_value,
35
+ 5 => :sha1_hash,
18
36
  12 => :creation_date,
19
37
  17 => :in_app,
20
38
  19 => :original_application_version,
@@ -34,9 +52,22 @@ module ItunesReceiptDecoder
34
52
  original_purchase_date expires_date
35
53
  cancellation_date)
36
54
 
37
- def initialize(raw_receipt, options = {})
38
- @style = :unified
39
- super
55
+ def style
56
+ :unified
57
+ end
58
+
59
+ def uuid_valid?(uuid)
60
+ digest = OpenSSL::Digest::SHA1.new
61
+ digest << uuid.scan(/[0-9A-F]{2}/).map(&:hex).pack('c*')
62
+ digest << @receipt[:opaque_value]
63
+ digest << @raw_bundle_id
64
+ digest.digest == @receipt[:sha1_hash]
65
+ end
66
+
67
+ def signature_valid?
68
+ serial = pkcs7.signers.first.serial.to_i
69
+ cert = pkcs7.certificates.find { |c| c.serial.to_i == serial }
70
+ cert && cert.verify(PUBLIC_KEY)
40
71
  end
41
72
 
42
73
  private
@@ -55,7 +86,12 @@ module ItunesReceiptDecoder
55
86
  fields.each do |seq|
56
87
  type, _version, value = seq.value.map(&:value)
57
88
  next unless (field = RECEIPT_FIELDS[type.to_i])
58
- build_result(result, field, value)
89
+ if %i(opaque_value sha1_hash).include?(field)
90
+ result[field] = value
91
+ else
92
+ @raw_bundle_id = value if field == :bundle_id
93
+ build_result(result, field, value)
94
+ end
59
95
  end
60
96
  result
61
97
  end
@@ -3,5 +3,5 @@
3
3
  module ItunesReceiptDecoder
4
4
  ##
5
5
  # Gem version
6
- VERSION = '0.2.3'
6
+ VERSION = '0.3.0'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itunes_receipt_decoder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mbaasy.com
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-07 00:00:00.000000000 Z
11
+ date: 2015-12-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: CFPropertyList