ACFileHandle class for AppConnect secure file I/O

The AppConnect for iOS SDK provides one Objective-C subclass for secure file I/O:

 

@interface ACFileHandle:NSFileHandle

ACFileHandle is declared in ACFileHandle.h.

To secure the contents of your app’s files, your app can use ACFileHandle instead of NSFileHandle. Note that ACFileHandle:

Works only on regular files.

It does not work on directories, sockets, pipes, or devices as NSFileHandle does.

Overrides most of the NSFileHandle methods, encrypting all file contents when writing, and decrypting the contents when reading.

Adds methods to support a special error indicating that the encryption key is not available. These methods encrypt all file contents when writing, and decrypt when reading.

Each of these added methods correspond to an overridden method. The difference is that the added method takes a pointer to an NSError object as a parameter.

Always use the added method that has an NSError parameter rather than the corresponding overridden method. The NSError parameter allows you to code the error handling necessary when the encryption key is not available.

Does not support asynchronous file I/O.

ACFileHandle does not override the methods of NSFileHandle related to asynchronous I/O. Calling one of the NSFileHandle asynchronous I/O methods on a ACFileHandle object throws an exception.

Cannot be used if secure services are not available.

Overridden and added NSFileHandle methods

ACFileHandle overrides many methods of NSFileHandle to provide secure file I/O. It also adds methods corresponding to overridden methods to support an NSError parameter. The NSError parameter allows you to code the error handling necessary when the encryption key is not available.

The following table lists the overridden and added methods. Use the methods just as you would use the corresponding NSFileHandle methods, with the differences given in the table.

If an overridden method has a corresponding added method that includes an NSError parameter, always use the added method.

 

Table 22.   NSFileHandle overridden and added methods

Overridden and added methods

Usage differences with NSFileHandle method

+ (id) fileHandleForReadingAtPath:(NSString *)path;

The path parameter must be a regular file.

Do not use. Use instead the corresponding added method that includes an NSError parameter.

+ (id) fileHandleForReadingAtPath:(NSString *)path

error:(NSError *__autoreleasing *) error;

The path parameter must be a regular file.

Adds an NSError parameter.

+ (id) fileHandleForReadingFromURL:(NSURL *)url

error:(NSError *__autoreleasing *) error;

The url parameter must be a file URL, and point to a regular file.

+ (id) fileHandleForUpdatingAtPath:(NSString *)path;

The path parameter must be a regular file.

Do not use. Use instead the corresponding added method that includes an NSError parameter.

+ (id) fileHandleForUpdatingAtPath:(NSString *)path

error:(NSError *__autoreleasing *) error;

The path parameter must be a regular file.

Adds an NSError parameter.

+ (id) fileHandleForUpdatingURL:(NSURL *)url

error:(NSError *__autoreleasing *) error;

The url parameter must be a file URL, and point to a regular file.

+ (id) fileHandleForWritingAtPath:(NSString *)path;

The path parameter must be a regular file.

Do not use. Use instead the corresponding added method that includes an NSError parameter.

+ (id) fileHandleForWritingAtPath:(NSString *)path

error:(NSError *__autoreleasing *) error;

The path parameter must be a regular file.

Adds an NSError parameter.

+ (id) fileHandleForWritingToURL:(NSURL *)url

error:(NSError *__autoreleasing *)error;

The url parameter must be a file URL, and point to a regular file.

- (NSData *) availableData;

No usage differences.

Do not use. Use instead the corresponding added method that includes an NSError parameter.

- (NSData *) availableDataWithError:

(NSError *__autoreleasing *)error;

Adds an NSError parameter.

- (NSData *) readDataToEndOfFile;

No usage differences.

Do not use. Use instead the corresponding added method that includes an NSError parameter.

- (NSData *) readDataToEndOfFileWithError:

(NSError *__autoreleasing *)error;

Adds an NSError parameter.

- (NSData *) readDataOfLength:(NSUInteger) length;

No usage differences.

Do not use. Use instead the corresponding added method that includes an NSError parameter.

- (NSData *) readDataOfLength:(NSUInteger) length

(NSError *__autoreleasing *)error;

Adds an NSError parameter.

- (void) writeData:(NSData *) data;

No usage differences.

Do not use. Use instead the corresponding added method that includes an NSError parameter.

- (void) writeData:(NSData *) data

(NSError *__autoreleasing *)error;

Adds an NSError parameter.

- (unsigned long long) offsetInFile;

No usage differences.

- (unsigned long long) seekToEndOfFile;

No usage differences.

- (void) seekToFileOffset:

(unsigned long long)offset;

No usage differences.

- (void) truncateFileAtOffset:

(unsigned long long)offset;

No usage differences.

- (void) synchronizeFile;

No usage differences.

- (void) closeFile;

No usage differences.

ACFileHandle example

The following example makes a secure copy of an unsecured file. Specifically, the example:

1. Creates a secure file.
2. Writes the contents of the unsecured file /etc/group into it.
3. Reads the contents of the secure file.

For brevity, the example does not include error handling.

- (void) ACFileHandleExample
{
	NSString *secureFileName = @"/tmp/secureGroup";
	NSError *error;
 
	// Read the contents of /etc/group
	NSData *etcGroupData = [NSData dataWithContentsOfFile:@"/etc/group"];
 
	// Use the default file manager to create the secure file.
	[[NSFileManager defaultManager] createFileAtPath:secureFileName 
							contents:nil attributes:nil];
 
	// Get the file handle for writing to the secure file just created. 
	ACFileHandle *acFileHandle = 
			[ACFileHandle fileHandleForWritingAtPath:secureFileName error:&error];
 
	// Write the contents of /etc/group to the secure file.
	[acFileHandle writeData:etcGroupData error:&error];
 
	// Close the secure file. 
	[acFileHandle closeFile];
 
	// Open the secure file for reading. 
	acFileHandle = [ACFileHandle fileHandleForReadingAtPath:secureFileName error:&error];
 
	//read entire contents of the secure file.
	NSData *duplicate = [acFileHandle readDataToEndOfFileWithError:&error];
 
	// Close the secure file 
	[acFileHandle closeFile];
 
	// Note: The contents of NSData objects 'duplicate' and 'etcGroupData' 
	// are identical.
}