Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ====================
- // 1. If there is no receipt, verification fails.
- CFURLRef receiptURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("receipt"), NULL, CFSTR("_MASReceipt"));
- if(NULL == receiptURL)
- exit(173);
- // ====================
- // 2. If the receipt is not properly signed by Apple, verification fails.
- CFDictionaryRef receiptDictionary = CreateDictionaryForAppStoreReceipt(receiptURL);
- if(NULL == receiptDictionary)
- exit(173);
- // ====================
- // 3. If the bundle identifier in the receipt does not match the value for CFBundleIdentifier in the Info.plist file, verification fails.
- CFStringRef receiptBundleID = CFDictionaryGetValue(receiptDictionary, CFSTR(kReceiptBundleIdentifer));
- if(NULL == receiptBundleID)
- exit(173);
- CFStringRef bundleID = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleIdentifier"));
- if(kCFCompareEqualTo != CFStringCompare(receiptBundleID, bundleID, (CFOptionFlags)0))
- exit(173);
- // ====================
- // 4. If the version identifier string in the receipt does not match the value for CFBundleShortVersionString in the Info.plist file, verification fails.
- CFStringRef receiptVersionID = CFDictionaryGetValue(receiptDictionary, CFSTR(kReceiptVersion));
- if(NULL == receiptVersionID)
- exit(173);
- CFStringRef bundleVersionID = CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), CFSTR("CFBundleShortVersionString"));
- if(kCFCompareEqualTo != CFStringCompare(receiptVersionID, bundleVersionID, (CFOptionFlags)0))
- exit(173);
- // ====================
- // 5. Concatenate the bytes of the computer’s GUID, the opaque value (the attribute of type 4), and the bundle identifier from the receipt. Compute the SHA-1 hash. If the result does not match the hash in the receipt, verification fails.
- CFDataRef guid = CopyMachineGUID();
- CFDataRef receiptOpaqueValue = CFDictionaryGetValue(receiptDictionary, CFSTR(kReceiptOpaqueValue));
- CFDataRef receiptBundleIDData = CFStringCreateExternalRepresentation(kCFAllocatorDefault, receiptBundleID, kCFStringEncodingUTF8, (UInt8)0);
- if(NULL == guid || NULL == receiptOpaqueValue || NULL == receiptBundleIDData)
- exit(173);
- CC_SHA1_CTX sha1;
- CC_SHA1_Init(&sha1);
- CC_SHA1_Update(&sha1, CFDataGetBytePtr(guid), (CC_LONG)CFDataGetLength(guid));
- CC_SHA1_Update(&sha1, CFDataGetBytePtr(receiptOpaqueValue), (CC_LONG)CFDataGetLength(receiptOpaqueValue));
- CC_SHA1_Update(&sha1, CFDataGetBytePtr(receiptBundleIDData), (CC_LONG)CFDataGetLength(receiptBundleIDData));
- unsigned char sha1Digest [CC_SHA1_DIGEST_LENGTH];
- CC_SHA1_Final(sha1Digest, &sha1);
- CFDataRef computedSHA1Hash = CFDataCreate(kCFAllocatorDefault, sha1Digest, (CFIndex)CC_SHA1_DIGEST_LENGTH);
- CFDataRef receiptSHA1Hash = CFDictionaryGetValue(receiptDictionary, CFSTR(kReceiptHash));
- if(kCFCompareEqualTo != CFEqual(computedSHA1Hash, receiptSHA1Hash))
- exit(173);
- // If all of the above checks pass, verification passes.
- CFRelease(computedSHA1Hash), computedSHA1Hash = NULL;
- CFRelease(receiptBundleIDData), receiptBundleIDData = NULL;
- CFRelease(guid), guid = NULL;
- CFRelease(receiptDictionary), receiptDictionary = NULL;
Add Comment
Please, Sign In to add comment