Authenticating an HTTP Request with Client Certificates in iOS

I’m writing an app that uses a client-certificate to authenticate while performing a SOAP request. Unfortunately, I’m writing this app in PhoneGap, and the iOS WebView does not support Client Certificates for AJAX requests. I found some various sources of code and examples for doing this, but it took quite a bit of work to get the final result, so I wanted to post my code and explain how I made it work. I wrote this as a PhoneGap plugin, so I can call the method from javascript, and have the result returned (via a callback function) in the normal PhoneGap plugin style, but I suppose this could be used for any client-certificate authenticated request in a native iOS app. Here’s the important code:

The options object contains my url (host) and my soap request (an xml string data)

NSURL *serverURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@", [options objectForKey:@"host"]]];
NSMutableURLRequest *connectionRequest = [NSMutableURLRequest requestWithURL:serverURL

[connectionRequest setHTTPMethod:@"POST"];
[connectionRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
[connectionRequest setHTTPBody:[[options objectForKey:@"data"] dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection * aConnection = [[NSURLConnection alloc] initWithRequest:connectionRequest delegate:self];

Then I have NSURLConnection Delegate Methods to receive the response. One in particular, didReceiveAuthenticationChallenge is where I handle the client-certificate.

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
    // gets a certificate from local resources
    NSString *thePath = [[NSBundle mainBundle] pathForResource:@"MyCertificate" ofType:@"pfx"];
    NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath];
    CFDataRef inPKCS12Data = (CFDataRef)PKCS12Data;
    SecIdentityRef identity;

    // extract the ideneity from the certificate
    [self extractIdentity :inPKCS12Data :&identity];

    SecCertificateRef certificate = NULL;
    SecIdentityCopyCertificate (identity, &certificate);

    const void *certs[] = {certificate};
    CFArrayRef certArray = CFArrayCreate(kCFAllocatorDefault, certs, 1, NULL);

    // create a credential from the certificate and ideneity, then reply to the challenge with the credential
    NSURLCredential *credential = [NSURLCredential credentialWithIdentity:identity certificates:(NSArray*)certArray persistence:NSURLCredentialPersistencePermanent];
    [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
}

Then, We need extractIdentity to pull the identity out of a certificate

- (OSStatus)extractIdentity:(CFDataRef)inP12Data :(SecIdentityRef*)identity {
    OSStatus securityError = errSecSuccess;

    CFStringRef password = CFSTR("MyCertificatePassword");
    const void *keys[] = { kSecImportExportPassphrase };
    const void *values[] = { password };

    CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);

    CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
    securityError = SecPKCS12Import(inP12Data, options, &items);

    if (securityError == 0) {
        CFDictionaryRef ident = CFArrayGetValueAtIndex(items,0);
        const void *tempIdentity = NULL;
        tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);
        *identity = (SecIdentityRef)tempIdentity;
    }

    if (options) {
        CFRelease(options);
    }

    return securityError;
}

Blam! That was the hardest part. From there, just use your other NSURLConnection delegate methods to handle the connection states and events. See my full code below for examples.

SecureRequest.m

Product Review: Nook Simple Touch

I recently got a Nook Simple Touch (sans glow light), and, in short: I love it.

Prior to the Simple Touch, I had a Nook color, the first all-color, touch screen Nook. It was nice for a while, but it had some major flaws. First and foremost, the battery was abysmal. I couldn’t get through a few solid hours of reading without needing a charge, which was wholly unacceptable for vacations and long visits to the in-laws’. The screen was also weirdly touchy, especially with moisture – the pages would start turning sporadically and I’d have to lock the screen to stop it. The screen also attracted much more dirt and spots than other touch-screens with which I’m accustomed, namely iOS devices. It was nice about switching between content easily and quickly. The homescreen had a sort of “most recent reads” list, like the most-recently-used-app multitasking list on iOS. This made switching between multiple books extremely simple. The other great feature was it’s ability to run Dropbox, meaning dropping in files and books was painless and quick.

Upgrading to the Simple Touch was a definite improvement. I don’t miss any apps like games or social networking, as I kept those off the Nook Color, to prevent distractions from reading, in the first place. I do miss Dropbox, however; adding files requires plugging the device into a computer and dropping them on. The battery life is amazing – allowing me to get through most of a long book on a single charge.

Keep in mind that reading speed affects battery life on the Nook Color (i.e., non-epaper screens) but not on the Simple Touch (e-paper screen), because e-paper only needs battery to change the screen. So, excluding wifi and extra menu usage, the Simple Touch battery could be measured roughly by pages, instead of hours.

The Simple Touch has a touch screen, which is nice for looking up words by long-pressing the word, but for scrolling and page turning, I much rather use the hardware buttons. The buttons are well placed and easy to press, while not being too sensitive. The edge of the device is a bit sharp, but nothing uncomfortable for holding. I don’t have it in a case, and I think it’s a great size and weight. I’m a huge proponent of naked devices, not using a case or cover on my iPhone or iPad either, and the Simple Touch is great as-is.

Two negative points I have for the device: switching between multiple books can be a pain the butt. The homescreen only shows the most recent read, and to get back to anything prior (if it was saved from an SD card), you have to manually navigate to the file and load it each time – no quick access to recent files/books. The second is the “pages left in chapter” requires two taps instead of one. I’m a slow reader, so I really like to be able to quickly see how many pages are left in the chapter. On the Nook Color, I could tap once on the screen and see this info. On the Simple Touch, I have to tap on the screen, then tap “go to” to see the pages left in chapter. It seems less painful than it is, because screen loading is so slow.

I didn’t get the glow light because I’d read bad reviews about it, and figured it would just take away from the biggest feature (in my mind) – the especially long battery. I usually read with lights on anyway, meaning it wouldn’t help me much. The second biggest feature I was looking forward to is the epaper screen itself. I love to read outside, but the Nook Color was abysmal at displaying the screen (even at max brightness) when in sunlight. The Simple Touch does this fine. Text on the simple touch is crystal clear and great to read.

Overall product rating: Great. Would recommend.

Creating an Enterprise App Catalog

Motive

One of the challenges faced with developing in-house (or “enterprise”) mobile applications is deployment. For public applications, deployment is handled almost exclusively through platform app stores, like the iOS App Store or the Google Play Store. Deploying apps to employees of a single company, without making use of those stores, is a difficult problem. Android apps can be deployed just by making the apk available, but browsing, versioning and updating is still a problem.

Many companies solve this problem through the use of a Mobile Device Management (MDM) server that includes app catalog or deployment capabilities. Good Mobile Manager and AirWatch are both popular and (according to Gartner) leading platforms for MDM. My company tried out AirWatch, but ultimately decided that it was a bit too buggy and high maintenance, without much benefit.

Without going too much off topic, here’s a brief overview of what AirWatch was, and wasn’t, for us. MDM servers often provide the ability to remotely encrypt and wipe devices, install or uninstall enterprise apps, enforce usage and security policies, and other things. AirWatch did none of these things well, and some didn’t work at all due to platform limitations *AHEM*android*AHEM*. What we really needed was a way for employees to have access to our in-house developed applications. We already had some security control via our exchange server and it’s policies, and we could enforce other levels of security through the apps themselves (i.e., verifying that the device is encrypted, or has a passcode set).

Idea

I designed, proposed, and implemented a custom enterprise app catalog for my company to solve this problem. This app catalog would meet our greatest need by enabling users to download our in-house applications. It also provides us with some statistical information through basic analytics (a combination of Google Analytics and my own user-agent tracking). It also provides us with security of downloads, by authenticating users and download requests against active directory. It does not provide any remote installation/updating/uninstallation, nor any remote wiping capabilities. Some of the other features include:

  • Automatic PLIST generation for iOS over-the-air installation
  • Token based authentication for iOS over-the-air installation (which doesn’t support authentication cookies)
  • Role based app availability (beta testers, for example)
  • User-to-device tracking
  • A management UI for adding or editing users and roles
  • A management UI for adding and editing apps
  • Automatic “compatible app” views based on detection of device platform and version
  • Mobile optimization including standalone “web app” mode on iOS

Implementation

Frameworks

The app catalog I built (cleverly named “App Catalog”) is built with ASP.NET MVC 3, SQL Server, Entity Framework 4, and jQuery Mobile. Honestly, I used Entity Framework because I wanted to try it out. It ended up being extremely useful, combined with linq-to-entities. I can let my entity data model diagram speak for itself about my design.

image

Authentication and Downloading

Unauthenticated users are redirected to a login page, which accepts domain credentials and authenticates against active-directory using forms authentication. I leverage forms authentication cookies to allow users to remain signed in for 14 days.

To explain the authentication of downloads on iOS, I need to take a brief tangent here and explain how iOS OTA installation works. For more information, check out this blog post. To trigger an iOS OTA download, the link must be formatted with a special itms-services:// protocol link. When clicked, it first requests a plist file (which must be returned with the mimetype text/xml) that includes information like the app package name, version, icon url, package url, and a few other various items (this plist file can be generated by Xcode by selecting “distrubute for enterprise” when archiving an application). Then, it uses the package url to download and install the application package. All of this is invisible to the user except for the initial “foo.com would like to install ‘Bar.’ would you like to continue?” message (which occurs between the plist and package (ipa) downloads). Unfortunately, this double-bounce OTA installation does not support cookies, or at least it does not use Safari’s cookies.

Because of this, if the plist or ipa files are behind an authentication wall, the download will fail. In order to authenticate the downloads, when the link to the plist is output on the app catalog page, it is a link to an unsecured action on my controller, with the current authenticated user’s unique download token as a parameter. Then, when the action is requested, that token is authenticated and the plist file is generated from a template (this killed two birds with one stone – authenticating the plist request, while making the plist dynamically generated. Managing the plists manually is a pain, especially with the weird caching that the OTA service does). The proper icon link, file link, app name, and package name are filled in, and returned as a plist file. The package link works the same way – it’s a link to a file download action, with the token as a parameter. When the request comes to this action, the token is verified again, and the app package file is returned (with mimetype application/octet-stream).

It’s important that we go through these steps to authenticate the plist and ipa files, because our Apple Enterprise Developer license only allows employees of the company to download applications signed with our certificate. If our apps were to be vulnerable to anonymous downloads, our certificate and license could be revoked. Much of this is specific to the iOS OTA installation; for Android, the download link points to the app package download action which authenticates the token and returns the app package directly.

Site Behavior

When a user first arrives at the site, they see our company’s in-house apps that are compatible with their device. This compatibility check is done in the request. A request’s user agent is parsed for platform (Android, iOS, Windows) and version, and I use linq-to-entities to get all apps that match the platform and are compatible with their version or lower. Other views allow viewing all apps, or public apps (like recommended applications in public app stores). The apps are presented in a mobile-friendly jQuery Mobile listview with icons, titles, and descriptions, and two-tap downloads (one to confirm).

image

Because we can check for Windows, we also have some listings for common Windows applications that our teams use, and we have a special page for Windows software stored on our network, which simply displays the path to find it on the network, as opposed to a download or installation link.

iOS Supports standalone web applications and webclip (shortcut) icons, so all of these are configured. This provides a more streamlined feel to the website, almost as if it’s an installed application.

Management

I put quite a bit of effort into the management UI for the app catalog. Naturally, we needed the ability to quickly create and update applications in the catalog, without manually copying files and editing the database. There’s an editor form for uploading new icons and app package files, as well as changing any of the properties of the apps, including availability, version, name, description, and platform/platform compatibility. Likewise, there’s a user manager page, where users can be assigned to roles like “tester” or “admin.” All of these management options allow extremely low overhead for updating applications. We even have a module for our apps that checks the app catalog with it’s catalog Id for newer versions, so when a new version goes up, the user is notified right away.

Conclusion

I’m sure there are some features that I’ve missed, or features that are purposely missing that would be deal breakers for others who might need an app deployment solution. For now, it’s been working pretty well. I’ve only had one logged error in the last 3 months, and we’ve hit 200 downloads (300 if you include all of our testers’ downloads) of apps in our company, from the app catalog. I’ve very open to feedback and questions!

HFR XD 3D 1080p HD WTF

Last night I went to see The Hobbit: An Unexpected Journey in HFR XD 3D. The XD seems to just be Cinemark’s name for their new theatre style, because HFR 3D was available not in XD. In any case, we saw the movie in 3D, filmed and played at a high frame rate (HFR) of 48fps vs the usual 24.

Before seeing the movie, I was waiting in line and listening intently to the comments of viewers of the previous showing. Most of them had comments along the lines of it messed with me and it was a little weird. One woman compared the lifelike-ness to watching a soap opera.

This reminded me of my first experience with full 1080p content on a large screen. We were watching an episode of Dexter on a friend’s large tv in a small apartment. My wife didn’t like the HD, because the detail was so great that sets actually looked like sets – similar to the obvious and shoddy sets of soap operas. I remember understanding the sentiment, but I enjoyed the detail and embraced it. I appreciated the elements of high detail that enhanced the show and accepted/ignored those that may have detracted. By now, I’m very used to the super high definition, and love it. I would be very interested to see viewer reactions and sort them by “watches 1080p content at home.”

One of the comments about the HFR in The Hobbit was that it made things look unnaturally fast and jerky – particularly, the first scene, with Bilbo gathering his books. When I saw this scene, it did look a little fast, almost like it was sped up. However, another article I read mentions that the effect makes things like Bilbo putting a napkin on his shirt feel like an acid trip. This one was just ridiculous. I don’t know if there is an HFR adjustment period of sorts, but by the scene with the napkin reference (still very early in the movie), everything just kind of seemed more HD. By this I mean that it didn’t feel wrong or sped up, it just seemed to have great detail, and I liked it.

The big negative for me was not the HFR, but the 3D. I have never enjoyed 3D movies and I hope that they phase out. The HFR was only available in 3D, so we went to experience it. I won’t be doing it again. I’d be willing to pay the same 3D premium for an HFR 2D movie, but I won’t willingly see 3D movies anymore.

iOS 6 Assistive Touch

iOS 6 brought a great new accessibility feature that’s actually pretty handy for general use. The feature, called “Assistive Touch” can be enabled in Settings.app > general > accessibility. When this feature is enabled, a small dot-like button is overlayed on the screen, and can be moved and docked on any screen edge. Oddly, it doesn’t appear in device screenshots.

20120924-150539.jpg

Opening the menu by tapping the dot shows this menu. Selecting favorites shows one default: pinch.

20120924-150815.jpg

Trying this out in maps places a blue overlay line with an arrow at each end. Oddly, this doesn’t show in screenshots either.

What’s great about this is that you can now pinch-to-zoom and plane-rotate the maps, with just a thumb – still holding your phone with one hand.

Switching from AT&T to Verizon for the iPhone 5

My process of switching to Verizon for the iPhone 5 was quick and easy. I had the phone on and working in less than a minute, and it instantly switched my number over automatically. Just to break it down for anyone concerned about the process, here it is:

  1. Check your phone number port eligibility with AT&T’s Tool.
  2. Be sure you have all of your AT&T account information ready, like:
    - Account number
    - Username/Password
    - Account holder personal information
  3. Sign into an existing Verizon account and choose “Add a device” (or you can create an account and get your first device)
  4. Choose your device and plan
  5. Choose the “keep my number” option, and put in all the required information (that you should have gathered in step 2)
  6. Pay, and wait for your phone to arrive via FedEx.
  7. Open your iPhone 5, turn it on, restore from iCloud or iTunes backup (if you have either).
  8. Use your Phone.

I never once spoke with a sales rep from either company about switching my number. My line is still active on AT&T (we’re opting to keep it open until it runs out instead of dealing with cancellation fees), and I just have to talk to someone to get a new (temporary) number assigned to it.

PhoneGap in iOS 6

Update 9/27:  This post relates to PhoneGap 2.0. 2.1 appears to have fixed a number of iOS 6 compatibility issues, and I recommend upgrading.

Today I upgraded my Xcode to 4.5, which now builds apps against the iOS 6 sdk. This included many breakages to my projects that I had to fix, and a couple to my apps themselves.

The two biggest problems were:

1. Apple Mach-O Linker Error. Linker command failed with exit code 1. File is universal but does not contain a(n) armv7s slice.
2. The apps failing to work properly in landscape mode. (The status bar would load landscape, but the webview would load portrait, and never rotate.

To Fix problem 1, I simply had to navigate to Project > Build Settings and change Build Active Architecture Only to “Yes”.

To Fix problem 2, I had to change some of the PhoneGap base code. I found the solution here.

In Classes > AppDelegate.m change the line:

[self.window addSubview:self.viewController.view];

to

self.window.rootViewController = self.viewController;

and in Classes > MainViewController.m, add the line:

 self.webView.frame = CGRectMake ( 0, 20, self.view.frame.size.width, self.view.frame.size.height-20);

right after

  [super viewDidLoad];

That’s it – this makes the WebView inherit from the root view controller instead of a subview, and the additional line allows the webview frame to load without being cut off by the status bar.

15 YesWas this helpful?

Fixing the Trackpad in Windows 8 Installed on a Macbook Pro

Update 5/1/13 - It’s been a while since I booted into Windows 8 on my Macbook Pro. It appears that both Windows and Apple updates have provided most of the functionality now. The below is now unnecessary, though Trackpad++ still boasts more features (gestures, mostly).


Update 1/16/13 – I tried out Trackpad++ despite it’s creepy malware-feel on the site and in the installer. It did successfully restore 2-finger right click and scrolling. I haven’t had any luck with any other Windows 8 specific gestures though. Use at your own risk.


The Apple Boot Camp drivers for Macbook, Macbook Pro, and Macbook Air work pretty well, except for the trackpad. There are forum posts and questions all over the place about how to fix them, and the answer seems to be a simple one I found tucked away on a forum.

  1. Open Device Manager
    This is not the Windows 8 “Devices” menu, but rather the classic device manager window in the desktop. The quickest way to get it is to go to the start menu, type “device manager,” and find it under the “settings” category.
  2. Verify the problem is the trackpad
    Under “Human Interface Devices” there will most likely be two trackpad entries with yellow error indicators. Right click on each of these and select “reinstall driver.” If “reinstall driver” is not available, click “properties” first, then you should see “reinstall driver.”
  3. Install a working driver
     
  4. Enjoy your trackpad
    Unfortunately this fix only gives basic movement and clicking – no multi-touch gestures or two finger scrolling… or even right clicking. This is definitely not a permanent fix, but until the multi-touch drivers are updated, this at least gives usability to the trackpad. Useful when copying files between two drives, seeing as how my macbook only has 2 usb ports, and my mouse didn’t have room.
16 YesWas this helpful?

Hardware vs Software Smartphone Keyboards

My dad is a big proponent of hardware keyboards on smartphones. Partly because of this, he’s a big fan of BlackBerries BlackBerrys BlackBerry® smartphones. We’ve talked about it before, and I’ve shown him products like Spike, that bring tactile feedback to virtual keyboards.

He recently retweeted an article that I really took issue with. It wasn’t so much that I disagreed with the author’s opinion (that hardware keyboards are better), but rather that I disagreed with the arguments and the presentation of them. My opinion about smartphone keyboard differences is simple: it’s user preference; both are valid; neither is superior to the other except in opinions.

The first problem I had with the article is that the author uses the term “QWERTY” to refer to “hardware keyboard.” QWERTY is historically used to refer to a keyboard layout, not to differentiate between hardware and software keyboards. Most smartphone software keyboards are QWERTY. The layout and term have even existed since typewriters.

The second issue I had is that the author writes about autocorrect being a factor. Autocorrect is a software tool used to make up for the difficulty with typing on small smartphone keyboards (and is actually being used in full PC operating systems) and can be used with hardware and software keyboards alike. The author presents autocorrect like it’s a crutch only given to the silly users of software keyboards and says:

I don’t care how much time you spent training your autocorrect software to figure out what you are trying to say, it’s still not going to be as accurate or as fast as you typing out your message right the first time.

…Well that may be true, but he writes it like hardware keyboard users are immune typos. People get used to typing on physical and virtual keyboards alike, and become more proficient with typing as they get used to the keyboard. The same thing happens with users of computers getting used to the differences between mechanical, laptop, and netbook keyboard differences.

The last issue I had with the article was that it presents problems with virtual keyboards that aren’t any different with hardware keyboards, like the responsiveness of the screen, the amount of bacteria on your phone (seriously?) and the size of the keys. Physical keyboards are also limited by the responsiveness of the device and the processing of the input mechanism. Physical keyboards collect bacteria too. Smartphone physical keyboards are often smaller than virtual ones. Example (I sized the images to the best of my ability to reflect proportional sized by width):

 

Basically, I think it’s a silly argument, because it’s all about user preference. I only wrote this post because I think that that was a very poorly written and argued article, and I wanted to make a critique. Keep calm, and type on.