From 005c31bf44d08c80cc7ad76f8eaffd435f3cbf83 Mon Sep 17 00:00:00 2001 From: Pavel Tikhonenko Date: Fri, 30 Sep 2016 03:20:48 -0700 Subject: [PATCH] extract bundle identifier --- TPInAppReceipt/Source/ASN1Helper.swift | 45 +++++++++++++++++++---- TPInAppReceipt/Source/InAppReceipt.swift | 46 ++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/TPInAppReceipt/Source/ASN1Helper.swift b/TPInAppReceipt/Source/ASN1Helper.swift index a48b2c1..6468cd1 100644 --- a/TPInAppReceipt/Source/ASN1Helper.swift +++ b/TPInAppReceipt/Source/ASN1Helper.swift @@ -11,15 +11,15 @@ import openssl func asn1ReadInteger(_ ptr: UnsafeMutablePointer?>, l: Int) -> Int { + var pClass: Int32 = 0 var tag: Int32 = 0 - var type: Int32 = 0 var length: Int = 0 var value: Int = 0 var integer: UnsafeMutablePointer - ASN1_get_object(ptr, &length, &type, &tag, l) - if type != V_ASN1_INTEGER + ASN1_get_object(ptr, &length, &tag, &pClass, l) + if tag != V_ASN1_INTEGER { print("ASN1 error: attribute not an integer") } @@ -33,17 +33,48 @@ func asn1ReadInteger(_ ptr: UnsafeMutablePointer?>, l: Int) func asn1ReadOctectString(_ ptr: UnsafeMutablePointer?>, l: Int) -> Data { + var pClass: Int32 = 0 var tag: Int32 = 0 - var type: Int32 = 0 var length: Int = 0 - ASN1_get_object(ptr, &length, &type, &tag, l) - if type != V_ASN1_OCTET_STRING + ASN1_get_object(ptr, &length, &tag, &pClass, l) + if tag != V_ASN1_OCTET_STRING { print("ASN1 error: value not an octet string") } - return Data(bytes: ptr.pointee!, count: l) + //note increment ptr? + return Data(bytes: ptr.pointee!, count: length) +} + +func asn1ReadString(_ ptr: UnsafeMutablePointer?>, _ l: Int, _ expectedTag: Int32, encoding: String.Encoding) -> String +{ + var tag: Int32 = 0 + var pClass: Int32 = 0 + var length: Int = 0 + + ASN1_get_object(ptr, &length, &tag, &pClass, l) + + if tag != expectedTag + { + print("ASN1 error: value not a string") + } + + let data = Data(bytes: ptr.pointee!, count: length) + + //*pp += length; + + return String(data: data, encoding: encoding)! +} + +func asn1ReadUTF8String(_ ptr: UnsafeMutablePointer?>, _ l: Int) -> String +{ + return asn1ReadString(ptr, l, V_ASN1_UTF8STRING, encoding: .utf8) +} + +func asn1ReadASCIIString(_ ptr: UnsafeMutablePointer?>, _ l: Int) -> String +{ + return asn1ReadString(ptr, l, V_ASN1_IA5STRING, encoding: .ascii) } // diff --git a/TPInAppReceipt/Source/InAppReceipt.swift b/TPInAppReceipt/Source/InAppReceipt.swift index 66ef1ab..730217a 100644 --- a/TPInAppReceipt/Source/InAppReceipt.swift +++ b/TPInAppReceipt/Source/InAppReceipt.swift @@ -8,14 +8,36 @@ import Foundation +public enum InAppReceiptField: Int +{ + case bundleIdentifier = 2 + case appVersion = 3 + case opaqueValue = 4 + case receiptHash = 5 //SHA-1 Hash + case inAppPurchaseReceipt = 17 + case originalAppVersion = 19 + case expirationDate = 21 + + case quantity = 1701 + case productIdentifier = 1702 + case transactionIdentifier = 1703 + case purchaseDate = 1704 + case originalTransactionIdentifier = 1705 + case originalPurchaseDate = 1706 + case subscriptionExpirationDate = 1708 + case webOrderLineItemID = 1711 + case cancellationDate = 1712 +} + public struct InAppReceipt { - public let bundleIdentifier: String + public var bundleIdentifier: String public let appVersion: String public let originalAppVersion: String public let purchases: [InAppPurchase] public let expirationDate: Date + public let quantity: Int public let bundleIdentifierData: Data public let opaqueValue: Data public let receiptHash: Data @@ -30,9 +52,29 @@ public struct InAppReceipt bundleIdentifierData = Data() opaqueValue = Data() receiptHash = Data() + quantity = 0 ans1Data.enumerateASN1Attributes { (attributes) in - print("attributes.type: \(attributes.type)") + if let field = InAppReceiptField(rawValue: attributes.type) + { + let length = attributes.data.count + + var bytes = [UInt8](repeating:0, count: length) + attributes.data.copyBytes(to: &bytes, count: length) + + var ptr = UnsafePointer?(bytes) + + switch field + { + case InAppReceiptField.bundleIdentifier: + let str = asn1ReadUTF8String(&ptr, bytes.count) + bundleIdentifier = str + default: + print("attribute.type = \(attributes.type))") + } + } + + } } }