Class: AppleReceipt::Validator

Inherits:
Object
  • Object
show all
Defined in:
lib/apple_receipt/validator.rb

Overview

Validator allows one to check the validity of a receipt.

Constant Summary collapse

INTERMEDIATE_CERT_MAPPING =
{
  3 => 'AppleWorldwideDeveloperRelationsCertificationAuthority',
  2 => 'AppleITunesStoreCertificationAuthority'
}.freeze

Instance Method Summary collapse

Constructor Details

#initialize(receipt, certificates: []) ⇒ Validator

Returns a new instance of Validator.



13
14
15
16
# File 'lib/apple_receipt/validator.rb', line 13

def initialize(receipt, certificates: [])
  populate_certificate_store(receipt.version, certificates)
  @receipt = receipt
end

Instance Method Details

#add_certificates(certificates) ⇒ Object



33
34
35
36
37
# File 'lib/apple_receipt/validator.rb', line 33

def add_certificates(certificates)
  certificates.each do |cert|
    store.add_cert(cert)
  end
end

#add_named_certificate(name) ⇒ Object



27
28
29
30
31
# File 'lib/apple_receipt/validator.rb', line 27

def add_named_certificate(name)
  cert_path = File.expand_path("../../certificates/#{name}.cer", __dir__)
  cert_file = File.read(cert_path)
  store.add_cert(OpenSSL::X509::Certificate.new(cert_file))
end

#populate_certificate_store(version, provided_certificates) ⇒ Object



18
19
20
21
22
23
24
25
# File 'lib/apple_receipt/validator.rb', line 18

def populate_certificate_store(version, provided_certificates)
  if provided_certificates.any?
    add_certificates(provided_certificates)
  else
    add_named_certificate('AppleRootCA')
    add_named_certificate(INTERMEDIATE_CERT_MAPPING[version])
  end
end

#public_keyObject



45
46
47
# File 'lib/apple_receipt/validator.rb', line 45

def public_key
  receipt.certificate.public_key
end

#signed_dataObject



49
50
51
# File 'lib/apple_receipt/validator.rb', line 49

def signed_data
  [receipt.version, receipt.data].pack('CA*')
end

#storeObject



53
54
55
# File 'lib/apple_receipt/validator.rb', line 53

def store
  @store ||= OpenSSL::X509::Store.new
end

#valid?Boolean

Returns:

  • (Boolean)


39
40
41
42
43
# File 'lib/apple_receipt/validator.rb', line 39

def valid?
  store.verify(receipt.certificate) &&
    public_key.verify(OpenSSL::Digest::SHA1.new,
                      receipt.signature, signed_data)
end