Category: Objective-C


PREVENTING USER AND HARDWARE TRACKING IN MOBILE DEVICES
by 
David Robert Stites

B.S., Purdue University, 2007

Thesis directed by Professor Rory Lewis

A thesis submitted to the Graduate Faculty of the University of Colorado at Colorado Springs in partial fulfillment of the requirements for the degree of Master of Science
Department of Computer Science

© Copyright By David Robert Stites 2012 
All Rights Reserved

Mobile devices, such as smartphones or PDAs, have become increasingly popular with consumers and often provide essential functionality in their everyday life. Usually these mobile devices contain a great deal of sensitive information such as addresses, contacts, ingoing/outgoing call logs, SMS messages and, on the latest models, a calendar, emails and potentially the user’s current location. A smartphone or mobile device today can be as powerful as a desktop or laptop in some respects and, while the latest models feature a complete OS, for many users these devices are “just phones” so there is an underestimation of the risk connected to mobile device privacy. There is a currently existing privacy problem associated with user and hardware tracking in mobile devices. Users can be tracked without their knowledge and consent and have rich profiles built about them using their hardware interface address regarding their location and preferences. This information can be potentially cross correlated to other existing datasets to build advertising profiles for these users. The mitigation to this problem using a framework to support randomly generated, disposable hardware addresses.

Full text of the document can be found here: PDF

Some new classes were introduced in Foundation.framework as part of Mac OS X 10.8 (Mountain Lion) to help ease the pain associated with performing IPC (inter-process communication) in Mac OS applications. Among them were NSXPCConnection, NSXPCListener, NSXPCListenerDelegate and NSXPCInterface. You can find the documentation inside the development portal or as part of the Xcode bundle but this post is meant to show you how easy it truly is to package up messages and send them off to other processes.

But first, a bit of background. What is IPC? Courtesy of WikiPedia, “IPC is a set of methods for the exchange of data among multiple threads in one or more processes. Processes may be running on one or more computers connected by a network. IPC methods are divided into methods for message passing, synchronization, shared memory, and remote procedure calls (RPC). The method of IPC used may vary based on the bandwidth and latency of communication between the threads, and the type of data being communicated.”

Originally, you could have done IPC in OS X using mach messages, which is how drivers traditionally communicated.

While information sharing and modularity are definitely some of the benefits of IPC, one of the biggest wins in my mind is the fact that we can perform privilege separation with IPC. Consider the following: you have wrote some code that will take some user input and crunch on it and then return a result. Note that this doesn’t have to be intensive computation, it could be as easy as interpolating an NSString. User input is a taint source, meaning that the input data is untrusted and could potentially (and perhaps unintentionally) be malicious. If your program were running in a privileged mode or had some increased set of ACLs, then if the input were able to exploit a vulnerability, then it would be able to inherit the same privilege level as the application.

Another benefit of this separation is that suppose the input causes the program to crash. If the processing were done in the main application, it would crash the entire application. If the processing is done in the daemon, then the daemon can crash and the application would still be alive and well.

I have attached a project that demonstrates NSURLConnection’s ability to say “Hello.” hello.tar.gz

Everyone knows — or at least everyone SHOULD know — that email is not a secure form of communication. It’s a lot like yelling across a parking lot. Your message is sent “in the clear” along most of the connections that lie between you and the recipient. For the times when you want to send a message that does NOT stand out in the open for others to read, StegaGram is your answer.

Double Armor
StegaGram protects your communication in two ways. First, it locks the message so that it can only be read by the person to whom you’re sending the message. Then, it hides the locked message inside a picture, so that it doesn’t even look like a locked message is being sent. As an analogy, consider keeping your valuables in a strong safe, located in your front yard. It’s a great safe, but why invite attention to the fact that you have it? Using StegaGram is like keeping that strong safe hidden in a secret panel behind a picture in your house.

No Password, No Problem
Short passwords are not very secure because they can be quickly guessed by computer programs. Long passwords are better, but can be hard to remember. We chose to avoid these problems altogether by using long strings of random numbers, known as keys. If you want more details you can read more below. Otherwise, suffice it to say that it’s stronger than a password but you don’t need to remember anything. You just need to pass a key to your friend using a QR Code — those barcode-looking squares you see all over the place.

Under the Hood
You know those cars that look cool from the outside but lack actual power and performance when driving? Yeah, that’s not us. StegaGram is clean and easy to use, but also employs the latest methods of cryptography and steganography. In fact, our initial version was denied for public distribution because it was too strong. We had to tone it down a bit. As for our hiding methods, they don’t just avoid detection by the human eye. We use a technique that passes well under the radar of digital analysis programs which search for anomalies in histograms.

For the Nerds
StegaGram uses a combination of asymmetric cryptography and an optimized version of the Graph-Theoretic approach to steganography. The asymmetry of the cryptographic keys allows for a distributed authentication model, similar to that used in the PGP community. Our initial version uses 2048-bit RSA encryption. As for the key exchange, the QR-Code method prevents the classic ‘Man-in-the-Middle Attack’ used against the Diffe-Helman pattern, because there is no communication over a network during the exchange. In addition, our steganographic algorithm preserves first-order statistics, unlike most other freely-available steganographic software. For more details, take a look through our research paper.

Fine Print
This application was created for academic and recreational purposes, and comes with no guarantees or warrantees for its information protection. It’s pretty burly, as mentioned above, but is used at your own risk. Thank you to Alex Renger for the idea of StegaGram and for the steganographic algorithm. Thank you to Dr. Yue from the University of Colorado at Colorado Springs for his teaching and support.

Normally, I think that simpler is better. I enjoy simple things and not just necessarily things like the smell of cut grass, an ice cold beer at a friends BBQ, the first snowfall of winter or reading a book. After all, Occam was on to something (the law of succinctness is a principle which generally recommends selecting the competing hypothesis that makes the fewest new assumptions, when the hypotheses are equal in other respects). Simple is good – less moving parts, less things to break.

I also enjoy simple software and hardware interfaces. Things that I can just pick up and know instantly how to use without reading an instruction manual. Something so simple that Grandma could use it. Apple products always have incredibly simple, unified interfaces: “One Interface to rule them all, One Interface to find them, One Interface to bring them all, and in the darkness bind them.” Simple people living in a simple world. However, simple does NOT imply intuitive.

Ever since the dawn of the electronics age, electronics have had buttons or some sort of interface that had something you could push, pull, or manipulate in some other fashion. Now, there are rumors that iPad2 and iPhone5 will not have home buttons.  In Johnathan Geller’s post:

“We just got some pretty wild information … while it’s hard to believe at first, it does make sense. … The iPad will be losing the home button. … Instead of button taps, you will use new multitouch gestures to navigate to the home screen and … launch the app switcher.
We’re told that this change will make its way over to the iPhone as well. … Apple employees are already testing iPads and iPhones with no home buttons on the Apple campus. … Steve Jobs didn’t want any physical buttons on the original iPhone … it looks like he may soon get his wish.”

So what will be replacing the home button?  In iOS 4.3, which was seeded to developers yesterday, there are new gestures that be done with four or five fingers.  This is particularly a stretch since previous iOS releases supported UIGestureRecognizer to simplify recognizing things like taps, pinch-in and pinch-out.  You could customize the number of fingers needed to perform the gesture and this is simply an extension of existing functionality.  In iOS 4.3, a four or five finger pinch brings you to the home screen,  a swipe up or down reveals the multi-tasking bar and a swipe left or right allows switching between apps.

I am going to do what a devoted Applephite would never do and disagree with what Steve wants.  I think that this is a bad decision because, unlike Steve, regular users actually like buttons!  They like the tactile feel of pushing something, the affirmative “click” that something was done or something will happen.  Consider some software that would process information for whole minutes at a time without providing feedback in the form of a spinner or a progress bar.  Most users would get fed up and try to quit the application.  Without the feedback, user’s may not know what to do.  While these gestures may be fine for people who have been around technology their whole life (think GenY and younger), there are a lot of users who would have problems picking  up the device and straight away being able to use it.  I would even go so far to say that they may never discover some of the features without reading the manual or browsing forums for tips.  Apple has always pride themselves, on simple AND intuitive, easy to use software.  I don’t think regular users are ready for this.

To make my point even clearer, there are still people I know with iOS 4.2 that don’t know that double-tapping the home button brings up the task bar.  They literally have over 75 applications “running” and if it weren’t for me, they would have continued on into their own blissful world, not knowing of that functionality.  And that’s WITH a button.  These gestures should be included in the software in addition so user’s can have their choice of methods of how they want to interact with the device.

Usability aside, how would we perform operations such as recovering crashed phones?

Personally, I would rather see support for a 4G network and WiFi-less FaceTime support.  Although, who knows what the new feature set will be because apparently iOS 4.3 drops support for arm6 (3G).

As engineers, we should attempt to cross the boundary of developers vs. front-end UI design engineers. Typically, people who write code are not very good UI engineers because they just don’t have the experience. It isn’t that we want to make a bad interface, we are just very accustomed to using standard UI components. However, the standard UI components can’t always get the job done in the most effective or user friendly manner. This was precisely the case when I needed to come up with a quick, intuitive way to filter information in one of my iPhone applications.

The horizontal scroll wheel is great because it is built out of standard UI components (UIImageView and UIScrollView) and there is no subclassing to be done to make the widget work. It can be dropped into any application. There is little code to support the layout and generation of the scroll wheel, and all layout calculations are done dynamically so you can have as many or as few items in the list as desired. Also, you can easily create additional value with the audio framework and Core Animation that is extremely simple to do.

For users, it is great because it is an easy to use and understand, quick method to filter a UITableView. The component requires no explanation. A sign of good UI design is a WYSIWYG type approach where the interface is so intuitive it is a joy to use. Create components that users can’t stop playing with.

Let’s get started already. By the way, this tutorial assumes you know Objective-C, Cocoa and basic programming principles. I welcome feedback on any of the code.

ScrollWheel.h

#import <UIKit/UIKit.h>;
#import "ChannelCategory.h"
#import "NSArray+FirstObject.h"
#import "Colors.h"
#import "Debugger.h"

#define SCROLL_WHEEL_CATEGORY_CHANGED @"ScrollWheelCategoryChanged"
#define SCROLL_WHEEL_CATEGORY_ADDED @"ScrollWheelCategoryAdded"

@interface CategoryScrollWheel : UIView <UIScrollViewDelegate> {
  IBOutlet UIScrollView *_scrollView;
}

@property (nonatomic, retain) IBOutlet UIScrollView *_scrollView;

- (void) setupCategories: (NSArray *) categories;
- (void) scrollToButton: (id) sender;
- (void) rebuildCategories;
- (NSArray *) loadNewsCategories;
@end

ScrollWheel.m

#import "CategoryScrollWheel.h"

@implementation CategoryScrollWheel

@synthesize _scrollView;

- (id)initWithFrame:(CGRect)frame {
  if ((self = [super initWithFrame:frame])) {
    // Initialization code
  }
  return self;
}

- (void) rebuildCategories {
  // release the previous wheel and alloc a new one

  [_scrollView release], _scrollView = nil;
  _scrollView = [[UIScrollView alloc] init];

  // reload the categories into the scroll wheel

  [self setupCategories: [NSArray arrayWithArray: [self loadNewsCategories]]];
}

- (NSArray *) loadNewsCategories {
  NSManagedObjectContext *managedObjectContext = [(RSSAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];

  NSFetchRequest *request = [[NSFetchRequest alloc] init];
  NSError *error;
  NSArray *fetchResults;
  NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:NO];
  NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];

  [request setEntity: [NSEntityDescription entityForName:@"ChannelCategory" inManagedObjectContext: managedObjectContext]];
  [request setSortDescriptors: sortDescriptors];

  if ((fetchResults = [managedObjectContext executeFetchRequest: request error: &amp;error]) == nil) {
    ALog("%@", error);
    [request release], request = nil;
    [sortDescriptor release], sortDescriptor = nil;
    [sortDescriptors release], sortDescriptors = nil;
    return nil;
  }

  [sortDescriptor release], sortDescriptor = nil;
  [sortDescriptors release], sortDescriptors = nil;

  if([fetchResults count] == 0) {
    // no feeds to refresh
    [request release], request = nil;
    return nil;
  }
  else {
    return fetchResults;
  }
}

- (void) setupCategories: (NSArray *) categories {
  // our variable x will keep track of how far our scroll view extends
  // we need to add a half scroll view width to get the arrow in the middle to
  // be able to center up

  double x = ([self _scrollView].frame.size.width / 2);
  double lastHoldover = 0;
  
  for(ChannelCategory *category in categories) {
    UIButton *button = [[UIButton alloc] init];
    [button setTitle: [category name] forState: UIControlStateNormal];
    [[button titleLabel] setFont: [UIFont fontWithName: @"Helvetica-Bold" size: 11]];
    [[button titleLabel] setTextColor: UI_COLOR_LIGHT_GREY];
    
    CGRect rect = CGRectMake(x, 0, [[category name] sizeWithFont: [UIFont fontWithName: @"Helvetica-Bold" size: 11]].width, 30);

    if([category isEqual: [categories firstObject]]) {
      x -= (rect.size.width / 2);
      rect.origin.x = x;
    }

    [button setFrame: rect];
    [button addTarget: self action: @selector(scrollToButton:) forControlEvents: UIControlEventTouchUpInside];

    [[self _scrollView] addSubview: button];

    x += button.frame.size.width + 10;

    if([category isEqual: [categories lastObject]]) {
      lastHoldover = (button.frame.size.width / 2);
      // bad hack to lop off the extra 10 on the last item
      x -= 10;
    }

    [button release], button = nil;
  }

  // this adds a half scrollview width to the end of the scrollview

  x += ([self _scrollView].frame.size.width / 2);
  x -= lastHoldover;

  CGSize size = CGSizeMake(x, 30);

  [[self _scrollView] setContentSize: size];
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
  // we add the offset and half the view together to bring it into line with the
  // arrow in the middle
  double val = [[self _scrollView] contentOffset].x + ([self _scrollView].frame.size.width / 2);

  // loop through and see which button is closest.  snap to that button
  // using scrollToButton

  UIButton *closestButton;
  double closest = 100;

  for (UIButton *view in [[self _scrollView] subviews]) {
    if ([view isKindOfClass:[UIButton class]]) {
      double calculatedValue = abs(view.frame.origin.x -  val);

      if(calculatedValue &lt; closest) {
        closestButton = (UIButton *)view;
        closest = calculatedValue;
      }
    }
  }

  CGPoint offset = closestButton.frame.origin;
  CGRect scrollViewFrame = [[self _scrollView] frame];
  offset.x -= (scrollViewFrame.size.width / 2) - (closestButton.frame.size.width / 2);

  [[self _scrollView] setContentOffset:offset animated:YES];
  [[NSNotificationCenter defaultCenter] postNotificationName: SCROLL_WHEEL_CATEGORY_CHANGED object: [[closestButton titleLabel] text]];
}

- (void) scrollToButton: (id) sender {
  CGPoint offset = ((UIButton *)sender).frame.origin;
  CGRect scrollViewFrame = [[self _scrollView] frame];

  offset.x -= (scrollViewFrame.size.width / 2) - (((UIButton *)sender).frame.size.width / 2);

  [[self _scrollView] setContentOffset:offset animated:YES];
  [[NSNotificationCenter defaultCenter] postNotificationName: SCROLL_WHEEL_CATEGORY_CHANGED object: [[sender titleLabel] text]];
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
  // Drawing code
}
*/

- (void)dealloc {
  [super dealloc];
}

@end

ScrollWheel.xib

In my ScrollWheel.xib, I have 2 UIImageViews and a UIScrollView. Literally, it is that easy. The image view is meant to create a nice frame around the scroll view giving the illusion of “limited view.” The top UIImageView may even have a small arrow pointing down to indicate which item is currently selected. The UIScrollView is the one referenced in the code above.

So there it is – a neat, clean, compact way of taking standard UI components and turning it into a custom UI to allow for selection of categories. If you have any questions or comments on how to improve the code, please let me know!

All code owned and written by David Stites and published on this blog is licensed under MIT/BSD.