Keyword - Apple

Entries feed - Comments feed

Thursday, May 24 2012

Debugging Mac AppStore receipt validation

Setting up receipt validation for Mac OS X application can be a tedious task, especially with all the steps to follow in order to have a proper test environnement. Of course, by using Receigen, the code writing part is easy as pie, but most of the issues occur during the testing.

I have written a shell script that dumps all the information regarding the hardware, the application bundle and the receipt. With one command, you are able to see information like the primary MAC address, the bundle identifier and version and the essential values of the receipt.

So, if you encounter a problem during the testing of the receipt validation, running this script will be give you all the information needed to diagnose the problem.

To use it (assumer the script is located under the current directory):

$> ./receigen_dump.sh /Applications/<Your App>.app

Here is an example of the output for the Xcode.app:

===========================
===== Receigen Dumper =====
===========================

----- BEGIN HARDWARE INFORMATION -----
System Name         : Darwin cupertino 11.4.0 Darwin Kernel Version 11.4.0: Mon Apr  9 19:32:15 PDT 2012; root:xnu-1699.26.8~1/RELEASE_X86_64 x86_64
Primary MAC Address : c4:2c:03:c4:2c:03
----- END HARDWARE INFORMATION -----

----- BEGIN APPLICATION INFORMATION -----
Application Bundle     : /Applications/Xcode.app/
Application Name       : Xcode.app
Application Identifier : com.apple.dt.Xcode
Application Version    : 4.3.2

Signature check
---------------
/Applications/Xcode.app/: valid on disk
/Applications/Xcode.app/: satisfies its Designated Requirement

Signature information
---------------------
Executable=/Applications/Xcode.app/Contents/MacOS/Xcode
Identifier=com.apple.dt.Xcode
Format=bundle with Mach-O thin (x86_64)
CodeDirectory v=20100 size=187 flags=0x200(kill) hashes=3+3 location=embedded
Hash type=sha1 size=20
CDHash=f1cd6c670213af6d6fa7374f04de6a68fdb5e614
Signature size=4169
Authority=Apple Mac OS Application Signing
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Info.plist entries=30
Sealed Resources rules=14 files=45
Internal requirements count=2 size=344

Signed files
------------
Executable=/Applications/Xcode.app/Contents/MacOS/Xcode
/Applications/Xcode.app/Contents/MacOS/Xcode
/Applications/Xcode.app/Contents/_CodeSignature/CodeResources

Designated requirements
-----------------------
Executable=/Applications/Xcode.app/Contents/MacOS/Xcode
designated => (anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or anchor apple generic and certificate 1[field.2.5.29.37] /* exists */ and certificate 1[subject.CN] = "Apple Code Signing Certification Authority" and certificate leaf[field.2.5.29.37] /* exists */ and certificate leaf[subject.CN] = "Software Signing") and identifier "com.apple.dt.Xcode"
library => identifier "libSystem.B.dylib" and anchor apple

Entitlements
------------
Executable=/Applications/Xcode.app/Contents/MacOS/Xcode

----- END APPLICATION INFORMATION -----

----- BEGIN RECEIPT INFORMATION -----
Receipt identifier : com.apple.dt.Xcode
Receipt version    : 4.3.2
Receipt opaque     : 000000000000
Receipt SHA-1      : 4747474747474747474747474747474747474747

subject=/CN=Mac App Store Receipt Signing/OU=Apple Worldwide Developer Relations/O=Apple Inc./C=US
issuer=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority

subject=/C=US/O=Apple Inc./OU=Apple Worldwide Developer Relations/CN=Apple Worldwide Developer Relations Certification Authority
issuer=/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA

subject=/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA
issuer=/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Root CA

----- END RECEIPT INFORMATION -----

The link to the shell script.

Tuesday, May 15 2012

Receigen 1.7.0 is available

I am proud to announce the general availability of Receigen 1.7.0. This new version introduces some bug fixes. My thanks go to Receigen's users for their reports.

Even if the price can seem high, think about the time you would have spent on:

  • writing the validation code
  • making harder to reverse-engineer it
  • obfuscating the strings and the constants
  • shuffling the code each time you generate a new version

With Receigen, the generation is immediate and once you have integrate it into Xcode, just forget about it.

Receigen is available now on the Mac App Store.

Wednesday, March 28 2012

Receigen 1.6.0 is available

I am proud to announce the general availability of Receigen 1.6.0. This new version introduces more options to control the code generation. It also adds UI tweaks coming from user feedback. My thanks go to Receigen's users for their reports.

Even if the price can seem high, think about the time you would have spent on:

  • writing the validation code
  • making harder to reverse-engineer it
  • obfuscating the strings and the constants
  • shuffling the code each time you generate a new version

With Receigen, the generation is immediate and once you have integrate it into Xcode, just forget about it.

Receigen is available now on the Mac App Store.

Thursday, December 1 2011

How-to: Testing the Mac App Store receipt validation

If you are developping an application for the Mac App Store, then you have to implement and test receipt validation. This entry details all the steps needed to be able to test the Map App Store receipt validation.

Note: This entry is based on various information gathered from the Apple website and especially from the Validating Mac App Store Receipts and the Technical Note 2259 documents.

Member Center

As a Mac developer, you must use the Developer Certificate Utility available in the Member Center to complete the following steps:

  • Register an explicit your App ID for your application.
    Explicit App IDs are App IDs whose Bundle Identifier portion is a string without the wildcard ("*") character. If you are the Team Agent, you should be able to navigate to the App IDs section of the Developer Certificate Utility to register an App ID for your application.
  • Certificates
    Create, download, and install a Mac Signing Certificate that uses your App ID.
    If you are the Team Agent, you should be able to navigate to the Certificates section of the Developer Certificate Utility to create a Mac signing certificate.
  • Download the WWDR Intermediate Certificate.
    You also have to download the WWDR Intermediate Certificate available in the Developer Certificate Utility. This certificate is needed to validate developer certificates.

iTunes Connect

To test receipt validation, you need to create test accounts to simulate the purchase. iTunes Connect allows you to create and manage Test User accounts.

  • Create a test user account.
    Apple provides a testing environment, called the sandbox environment, which allows you to test an application purchase without incurring any financial changes. The sandbox environment uses special test user accounts rather than your regular iTunes Connect accounts to test receipt retrieval.
    Your Admin or Technical users should navigate to the Manage Users module on the iTunes Connect home page to create test user accounts. Read the Test User Setup section of the iTunes Connect Developer Guide for more information about creating test user accounts.
  • Declare your application.
    In order for Apple to generate testing receipt, you need to declare your application. Add a new application by providing all the required fields, and at least a screenshot. Leave the application as is; you don't need to upload anything to test receipt validation.

Note: You can use the same test user accounts to test both your iOS and Mac applications. Each test user account is tied to one and only one email address. As such, you cannot reuse an existing email address with another test user account. You can create as many test user accounts as you want in iTunes Connect. Furthermore, you can use the "+" alias provided that it is allowed by your webmail service. For instance, if your email is foo@example.com, then you can use the foo+us@example.com, foo+uk@example.com, and foo+fr@example.com emails when creating test user accounts in iTunes Connect. All communications sent to foo+us@example.com, foo+uk@example.com, and foo+fr@example.com will be routed to foo@example.com.

What's Next?

You have successfully set up your application, and you are ready to test the receipt validation.

  • Launch or create your project in Xcode.
  • Add the receipt validation code (if you look for an easy way to do so, then check out Receigen). Make sure that the bunlde identifier and the bundle version match between your application and the generated code.
  • Build your application in Xcode.
  • Run your application.

Note: You must launch your application from the Finder rather than from Xcode the first time in order to obtain a receipt. When your application is launched, Mac OS X displays a "Sign in to download from the App Store." dialog. Enter your test user account and password as requested. The sandbox provides you with a new receipt upon successful authentication.

Note: Launch your application from the Finder whenever you need a new receipt.

Important: You must not use your test user account to sign into the production environment. This will result in your test user account becoming invalid. Invalid test accounts cannot be used to test receipt validation.

  • Submit your products for review.

Log in to iTunes Connect to submit your application for review by Apple, after you are done thoroughly testing them in the sandbox environment.

Sunday, November 6 2011

Mac OS X Application SandBoxing: what about Apple ?

There is a lot of discussions around the upcoming sandboxing requirement for all the Mac App Store published applications.

There were several publications on the subject with sometimes very elaborate discussion:

These articles lead me to wondering:

  • Apple is going to enforce sandboxing on third-party applications, but what about Apple's own applications ?
  • Sandboxing is said to be a work in progress; the current entitlement keys are sparse and most of the time, developers relies on temporary exceptions to keep their application fully functional. Is there anything in Apple's applications that give a clue of possible entitlement keys ?

So, I decided to take my Terminal and play with the codesign tool. This tool is very useful because if can sign binaries (obviously), but it can also print what is contained in the signature (certificate chain, requirements, entitlements). So I ran it on my Application folder.

cd /Applications
find . -type d -name "*.app" -exec echo {} \; -exec codesign -d --entitlements - {} \;

Here are the applications that contain entitlements (as on 2011-11-06). I have indicated if they mandate the use of sandbox:

  • Address Book
  • App Store
  • FaceTime
  • Font Book
  • Preview (SANDBOXED)
  • TextEdit (SANDBOXED)
  • Activity Monitor
  • Boot Camp Assistant
  • RAID Utility
  • iCal
  • PhotoStreamAgent (in iPhoto)
  • iTunes

Here are the key points:

  • All the Apple applications are signed
  • Only a few of them contain entitlements
  • Only two of them are sandboxed

Digging further into the entitlements, I found:

  • Preview is actually using a temporary entitlement key for global Mach lookup. So don't be shy using them into your applications !
  • A bunch of private entitlement keys: they may be migrated to public entitlement keys as they seems generic.

And finally, here are the private entitlement keys I found:

  • com.apple.private.aps-connection-initiate: it seems related to iCloud, as applications like Address Book, FaceTime, iCal, iTunes and iPhoto (PhotoStreamAgent) have this one.
  • com.apple.private.dark-wake-push: a key to wake up the computer ???
  • com.apple.private.AuthorizationServices: widely used, it seems a good candidate for a future entitlement key.

I hope that by March 2012, Apple would have solved all the details about sandboxing. It would be nice to see a set of versatile entitlement that could protect the end-user and let the developer be inventive.

Saturday, October 29 2011

Receigen, a smart code generator for Mac App Store receipt validation

Receigen has just been made available in the Mac App Store.

If you are developing an application for Mac and want to distribute it in the Mac App Store, you will be inevitably faced to receipt validation. This entry explains what is receipt validation and why Receigen can help you.

What is receipt validation ?

When you purchase an application from the Mac App Store, it installs into the /Applications folder of your Mac. Inside the application bundle, the Mac App Store application places a receipt file. This file is a record of sale that can be used to check if the installed copy of the application is authorized to run. Apple is providing a comprehensive documentation on the technical issues.

Why do I need receipt validation ?

If you fail to property validate the receipt file, anybody with a copy of your application can run it, with or without proper authorization. This happened to some developpers in the early days of Mac App Store.

What are the steps of validation ?

In order to code the receipt validation, you need to understand:

  • how asymetric cryptography works
  • how signature are attached to a container
  • how ASN.1 encodng/decoding works
  • how to obfuscate code to harden the reverse engineering.

Here is the basic workflow to use when validating a receipt:

  1. Locate the receipt file to load it: this is an easy part as its location is fixed inside the application bundle.
  2. Verify that the receipt is properly signed: the receipt file is a PKCS#7 container that contains the receipt data and that is signed by Apple.
  3. Extract the receipt data: the receipt data are encoded in ASN.1 format, which is a compact binary format widely used in cryptography.
  4. Check that the receipt data matches the bundle information and the machine the application is running on.
  5. Make sure that the checking code is secure. You should hide strings, constants, function calls and make sure that the validation code changes between each release of your application.

Damn, that seems a lot of work

Yes, it is. And I am sure that you have better to do than spending hours on this topic. Receigen has been designed to cope with all this tedious work, by ensuring that you can focus on your application and only your application.

Here is what Receigen brings you:

  • Smart generation of validation code: all it needs is the bundle identifier and version.
  • Seamless integration with Xcode: Receigen can be invoked on the command line easily.
  • Human readable code: Receigen produces a human readable code but still obfuscated when compiled.
  • Never twice the same code: Receigen embeds a code generator that produce a different output each time it is invoked.
  • A tiny price: think about the time you will have spent to produce the same code.

So, go and try out Receigen on the Mac App Store.

Wednesday, October 19 2011

Mac AppStore receipt validation testing

This entry tries to list all the required step in order to test a Mac App Store receipt validation.

If you look a smart and simple way to generate the receipt validation code, try Receigen on the Mac App Store.

Previously on receipt validation...

For those who are still wondering what is receipt validation, I suggest them to read this document from Applethat explains what receipt validation is; then this page should give them a good reason to properly implement it.

What is required

In order to correctly test receipt validation, you need to:

  • Declare your application on the iTunes Connect portal. Go to Manage Your Applications and file the form. Note that the bundle identifier and the bundle version are important, as they will be used to generate the receipt. Don't forget to file all the information (even the sales/pricing ones).
  • Declare a test account on the iTunes Connect portal. Go to Manage Users and create it.
  • Sign the application with a valid certificate. The receipt retrieval process is only triggered if the application bundle has been properly signed. Development certificate can be fetched from the Mac Dev Center.

How to proceed

Now that all the pre-requisites are ready, you can test your receipt validation code.

  • Launch the application in the Finder. DO NOT LAUNCH it from Xcode !!! The application must be launched by the launchd daemon.
  • If your receipt validation code is ok, then the lack of receipt should make the application exit with a code 173.
  • This exit will trigger the request for a valid receipt. You should see a Mac App Store login window by now. Use the test account credentials to log-in.
  • If the credentials are valid and that the bundle information match the one you entered, then a valid is generated and installed in the application bundle.
  • After the receipt is installed, the application is re-launched automatically.

Conclusion

Comments and feedback are welcomed to improve this entry.

Thursday, May 19 2011

Monobjc and OpenGL

Some people have noticied that the new major release of Monobjc was lacking of OpenGL support. I am currently working on it and have finalized the new bindings. There will be more complete and flexible, and I expect to provide several sample applications (NSTimer based or Display-Link based) to demonstrate the bindings. I have also started to port the NeHe lessons.

Monobjc now offers CorePlot support

Starting with the release 3.0.1405.0, the Monobjc bridge offers a complete CorePlot support. You can now use this framework for your graphs. Two sample applications have been added for demonstration purpose.

Wednesday, February 23 2011

Mono 64 bits on Mac OS X

If you ever wanted to try (or even use) Mono 64 bits on Mac OS X, I have created a small project on GitHub called Mono-Sixty-Four. This is a simple scrip that creates a minimal 64 bits Mono runtime and merges it with an existing Universal 32 bits Mono runtime. At the end, you get a Universal 32/64 bits Mono runtime.

For the moment, only the Mono runtime supports 64 bits. Additional libraries (GTK, SQLite, etc) ARE not supported.

- page 1 of 3