Verifying receipt with Xcode 12 + StoreKit configuration file

Viewed 1094

I'm trying to verify receipts with Xcode 12 and a StoreKit config file, but keep getting a 21002 error. According to the docs, I need to use a different cert. I generated the cert but it's not clear what to do with it?

#if DEBUG
        let certificate = “StoreKitTestCertificate” 
#else
        let certificate = “AppleIncRootCertificate” 
#endif

That's great, but what uses certificate?

2 Answers

The following code has been adapted from the Ray Wenderlich tutorial on Receipt Validation:

Note; You'll need to first statically link OpenSSL into your project, after that follow the tutorial in its entirety. This is only to show the context of where Apple's code sample is used.

  private func validateSigning(_ receipt: UnsafeMutablePointer<PKCS7>?) -> Bool {
    #if DEBUG
    let certificateName = "StoreKitTestCertificate"
    #else
    let certificateName = "AppleIncRootCertificate"
    #endif
    
    guard let rootCertURL = Bundle.main.url(forResource: certificateName, withExtension: "cer"),
          let rootCertData = try? Data(contentsOf: rootCertURL) else {
      receiptStatus = .invalidAppleRootCertificate
      return false
    }
    let rootCertBio = BIO_new(BIO_s_mem())
    let rootCertBytes: [UInt8] = .init(rootCertData)
    BIO_write(rootCertBio, rootCertBytes, Int32(rootCertData.count))
    let rootCertX509 = d2i_X509_bio(rootCertBio, nil)
    BIO_free(rootCertBio)
    let store = X509_STORE_new()
    X509_STORE_add_cert(store, rootCertX509)
    
    OPENSSL_init_crypto(UInt64(OPENSSL_INIT_ADD_ALL_DIGESTS), nil)
    
    #if DEBUG
    let verificationResult = PKCS7_verify(receipt, nil, store, nil, nil, PKCS7_NOCHAIN)
    #else
    let verificationResult = PKCS7_verify(receipt, nil, store, nil, nil, nil)
    #endif
    
    guard verificationResult == 1 else {
      receiptStatus = .failedAppleSignature
      return false
    }
    return true
  }

You need to specify StoreKitTestCertificate.crt for local receipt validation via OpenSSL. You can't verify xcode-generated receipts via Apple's /verifyReceipt endpoint.

Related