Source

MYCrypto / README.textile

MYCrypto

Version 0.2 — 12 April 2009

By Jens Alfke <br>
Based in part on code by Wade Tregaskis, <br>
and sample code by Apple Computer.

Introduction

MYCrypto is a high-level cryptography API for Mac OS X and iPhone. It’s an Objective-C wrapper around the system
Keychain
and CSSM APIs, which are notoriously hard to use, as well as CommonCrypto, which is easier but quite limited.

MYCrypto gives you easy object-oriented interfaces to:

  • Symmmetric cryptography (session keys and password-based encryption)
  • Asymmetric cryptography (public and private keys; digital signatures)
  • Identity certificates (for use with SSL and CMS)
  • Cryptographic digests/hashes (effectively-unique IDs for data)
  • The Keychain (a secure, encrypted storage system for keys and passwords)
  • Cryptographic Message Syntax [CMS] for signing/encrypting data

It’s open source, released under a friendly BSD license.

Requirements

  • Mac OS X 10.5 or later [has been tested on 10.5.6]
  • or iPhone OS 2.0 or later [not yet tested; see Limitations section below]
  • or iPhone Simulator, for iPhone OS 2.0 or later
  • The MYUtilities library, which is used by MYCrypto.
  • Some understanding of security and cryptography on your part! Even with convenient APIs, cryptographic operations still require care and knowledge to be used safely. There are already too many examples of insecure systems that were incorrectly assembled from secure primitives; don’t add your app to that list. Please read a good overview like Practical Cryptography before attempting anything the least bit fancy.

How To Get It

hg clone http://mooseyard.com/hg/hgwebdir.cgi/MYCrypto/ MYCrypto

How To Build It

With Xcode, of course. But before the first time you build MYCrypto.xcode, you’ll need to tell Xcode where the MYUtilities sources are. You do this by setting up a named 'Source Tree’:

  1. Open Xcode’s Preferences panel
  2. Click the “Source Trees” icon at the top
  3. Click the “+” button to add a new item to the list
  4. Fill in the Setting Name as “@MYUtilities@”, the Display Name also as “@MYUtilities@”, and the Path as the absolute filesystem path to where you downloaded MYUtilities to. Do not use a “~” in this path! The compiler won’t understand it and will give you errors.

Now you’re golden. From now on you can just open MYCrypto.xcode and press the Build button.

(So far, the MYCrypto project doesn’t build anything that’s useful to you, like a framework … just a tiny program that runs the unit-tests. You can add the source files to your own projects to use them.)

Overview

The class hierarchy of MYCrypto looks like this:

(Italicized classes are abstract.)

Examples

Creating an RSA key-pair

<pre>
MYPrivateKey *keyPair = [[MYKeychain defaultKeychain] generateRSAKeyPairOfSize: 2048];
</pre>

Creating a self-signed identity certificate:

<pre>
NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys: "alice", “Common Name”, "Alice", “Given Name”, "Lidell", “Surname”, nil];
MYIdentity *ident = [keyPair createSelfSignedIdentityWithAttributes: attrs];

NSData *certData = ident.certificateData;
</pre>

Signing and encrypting a message:

<pre>
NSData *cleartext = [@“Attack at dawn” dataUsingEncoding: NSUTF8StringEncoding];
MYEncoder *encoder = [[MYEncoder alloc] init];
[encoder addSigner: ident];
[encoder addRecipient: bob];
[encoder addRecipient: carla];
[encoder addData: cleartext];
[encoder finish];
NSData *ciphertext = encoder.encodedData;

sendMessage(ciphertext);
</pre>

Verifying and decoding a message:

<pre>
NSData *ciphertext = receiveMessage();
NSError *error;
MYDecoder *decoder = [[MYDecoder alloc] initWithData: ciphertext error: &error];
if (!decoder) return NO;

if (!decoder.isSigned) return NO;
decoder.policy = [MYCertificate X509Policy];
NSMutableArray *signerCerts = [NSMutableArray array];
for (MYSigner *signer in decoder.signers) { if (signer.status != kCMSSignerValid) { return NO; [signerCerts addObject: signer.certificate];
}

NSData *plaintext = decoder.content;
processMessage(plaintext, signerCerts);
</pre>

Current Limitations

First off, the biggest caveat of all:

  • MYCrypto 0.2 is new code and has not yet been used in any real projects. Expect bugs. (I’m talking about my wrapper/glue code. The underlying cryptographic functionality provided by the OS is robust.)

Further issues with the 0.2 release:

  • MYCrypto does not yet work on the iPhone. It currently builds, but runs into problems at runtime. I’m currently trying to figure these out. (The iPhone OS Security APIs are very different from the Mac OS X ones, and I’m much less familiar with them.) However, it does work in the iPhone Simulator, which uses the OS X APIs.
  • Exporting symmetric keys in wrapped (encrypted) form will fail. Currently they can be exported only as raw key data.
  • Importing symmetric keys, in any form, will fail … kind of a deal-breaker for using them across two computers, unfortunately.

Current API limitations, to be remedied in the future:

  • No API for accessing passwords; fortunately there are several other utility libraries that provide this. And if your code is doing cryptographic operations, it probably needs to store the keys themselves, not passwords.
  • No evaluation of trust in certificates (i.e. SecTrust and related APIs.)
  • Error reporting is too limited. Most methods indicate an error by returning nil, NULL or NO, but don’t provide the standard “out” NSError parameter to provide more information. Expect the API to be refactored in the near future to remedy this.

References

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.