blackberry.com
BlackBerry Dynamics
Runtime library for iOS applications
from the application developer portal
Public Member Functions | Static Public Member Functions | Properties

GDFileHandle Class Reference

File handle access to the secure file system. More...

#import <GDFileHandle.h>

List of all members.

Public Member Functions

Static Public Member Functions

Properties


Detailed Description

This class is a subclass of the native NSFileHandle class, for access to the BlackBerry Dynamics secure file system.

Secure File System

The secure file system is part of the BlackBerry Dynamics Secure Storage feature.

For applications, the BlackBerry Dynamics secure file system behaves like the default file system, with the following differences.

  • All data within the secure file system is stored on the device in an encrypted form.
  • Directory and file names are also encrypted.
  • The secure file system cannot be accessed until BlackBerry Dynamics authorization processing is complete, see under authorize (GDiOS).

Every operating system has a maximum supported length for the names of files and directories. For example, iOS 11 supports a maximum length of 255 bytes, given by the NAME_MAX constant. The encrypted form of the name of a directory or file will typically be longer than the plaintext, and it is the encrypted form that must be within the limits supported by the operating system. This means that names in the secure file system have a shorter effective maximum supported length. It isn't possible to give a simple maximum but the following should be expected.

  • Names that are 16 bytes or longer will be increased by a factor of 4:3 approximately.
  • Shorter names will be increased to a length of 20 bytes approximately.

Encryption and decryption is transparent to the application code:

  • The application passes its data to a file writing interface. The BlackBerry Dynamics runtime encrypts the data and stores it on the device.
  • When a file-reading interface is utilized, the runtime decrypts and returns the data.
  • Path access interfaces accept plaintext parameters for directory and file names. The runtime encrypts the parameter values in order to create paths in the secure store.
  • Directory and file names provided as return values are plaintext. The runtime decrypts paths in the secure store in order to generate the return values.

The encryption method used by the BlackBerry Dynamics runtime generally requires that the user has entered a security password, from which an encryption key is derived.

Usage

This class is a subclass of the native NSFileHandle class. It should be easy to replace references to NSFileHandle with references to GDFileHandle, in order to convert code that utilizes the native file system into code that utilizes the secure file system.

The differences between this class and NSFileHandle are:

  • Only files can be represented, not sockets nor other types of data stream.
  • Read and write access is limited to the secure store.
  • Extracted file descriptors can only be used with BlackBerry Dynamics programming interfaces, see below.
  • The "factory" style initializers, for example fileHandleWithStandardError, cannot be used.
  • The asynchronous communication functions cannot be used.
  • The NSFile notifications are never dispatched.
  • Error codes could be in the specific GDFileManager error domain, or could be general NS error codes.

File descriptors extracted from instances of this class can only be used with this class, and with other BlackBerry Dynamics programming interfaces such as the BlackBerry Dynamics C language programming interface. They cannot be used with, for example, the native POSIX programming interfaces, nor with NSFileHandle.

The functions in this API utilize NSError in a conventional way. Function calls accept as a parameter the location of a pointer to NSError, i.e. a pointer to a pointer, with type NSError**. The location may be nil. If the location isn't nil, and an error occurs, the BlackBerry Dynamics runtime overwrites the pointer at the specified location with the address of an object that describes the error that occurred.

The programming interface of this class has the same semantics as the base class. The documentation of this class lists the elements of the programming interface but doesn't describe them. See the documentation of the base class, NSFileHandle, for descriptions.

See also:
NSFileHandle class reference on the apple.com developer website.
GDFileManager Error Domain
Error Handling Programming Guide on the apple.com developer website.
Secure SQL Database API
GDPersistentStoreCoordinator
GDFileManager
C Language Programming Interface List

Code Snippets

The following code snippets illustrate some common tasks. In each snippet, a function that uses native file handles is converted to use secure file handles instead. The conversion is simple.

Create file from NSData and read back

The second function in the snippet is the original; the third is the converted version. The changed line is flagged with a comment. The first function in the snippet is a utility that is used by both the original and the converted function, with no changes.

 - (NSString *)documentsFolderPathForFileNamed:(NSString *)fileName
 {
     NSArray *paths =
     NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                         NSUserDomainMask,
                                         YES);
     NSString *documentsDirectory = [paths objectAtIndex:0];
     return [documentsDirectory stringByAppendingPathComponent:fileName];
 }

 - (NSString *)writeAndReadWithNSFileHandle
 {
     NSString *text = @"Text that is not protected.";
     NSData *fileData = [text dataUsingEncoding:NSUTF8StringEncoding];

     NSString* filePath = [self documentsFolderPathForFileNamed:@"MyFile.txt"]

     BOOL fileCreated = [[NSFileManager defaultManager] createFileAtPath:filePath
                                                        contents:fileData
                                                        attributes:nil];
      
     NSFileHandle* fileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
     NSData* resData = [fileHandle availableData];

     NSString *myString = [[NSString alloc] initWithData:resData encoding:NSUTF8StringEncoding];

     return myString;
 }

 - (NSString *)writeAndReadWithGDFileHandle
 {
     NSString *text = @"Text that is to be protected by GD SDK.";
     NSData *fileData = [text dataUsingEncoding:NSUTF8StringEncoding];

     NSString* filePath = [self documentsFolderPathForFileNamed:@"MyFile.txt"]

     // Following uses GDFileManager instead of NSFileManager.
     BOOL fileCreated = [[GDFileManager defaultManager] createFileAtPath:filePath
                                                        contents:fileData
                                                        attributes:nil];

     // Following uses GDFileHandle instead of NSFileHandle.
     GDFileHandle* fileHandle = [GDFileHandle fileHandleForReadingAtPath:filePath];
     NSData* resData = [fileHandle availableData];

     NSString *myString = [[NSString alloc] initWithData:resData encoding:NSUTF8StringEncoding];

     return myString;
 }

Create file by writing and read back

The second function in the snippet is the original; the third is the converted version. The changed line is flagged with a comment. The first function in the snippet is a utility that is used by both the original and the converted function, with no changes.

 - (NSString *)documentsFolderPathForFileNamed:(NSString *)fileName
 {
     NSArray *paths =
     NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
                                         NSUserDomainMask,
                                         YES);
     NSString *documentsDirectory = [paths objectAtIndex:0];
     return [documentsDirectory stringByAppendingPathComponent:fileName];
 }

 - (NSString *)writeAndReadWithMultipleNSFileHandles
 {
     NSString *text = @"Text that is not protected.";
     NSData *fileData = [text dataUsingEncoding:NSUTF8StringEncoding];

     NSString* filePath = [self documentsFolderPathForFileNamed:@"MyFile.txt"]

     BOOL fileCreated = [[NSFileManager defaultManager] createFileAtPath:filePath
                                                        contents:fileData
                                                        attributes:nil];

     // get a filehandle for Updating (read & write) and file descriptor
     NSFileHandle *nsFH = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
     int filedesc = [nsFH fileDescriptor];

     // get another filehandle with the existing filedescriptor and perform write operation
     NSFileHandle* writeFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:filedesc closeOnDealloc:YES];
     [writeFileHandle writeData:testNSData];
     [writeFileHandle synchronizeFile];
     [writeFileHandle closeFile];

     // get a filehandle for Reading
     NSFileHandle* readFileHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
     NSData* resData = [readFileHandle readDataToEndOfFile];

     NSString *myString = [[NSString alloc] initWithData:resData encoding:NSUTF8StringEncoding];

     return myString;
 }

 - (NSString *)writeAndReadWithMultipleGDFileHandles
 {
     NSString *text = @"Text that is to be protected by GD SDK.";
     NSData *fileData = [text dataUsingEncoding:NSUTF8StringEncoding];

     NSString* filePath = [self documentsFolderPathForFileNamed:@"MyFile.txt"]

     // Following uses GDFileManager instead of NSFileManager.
     BOOL fileCreated = [[GDFileManager defaultManager] createFileAtPath:filePath
                                                        contents:fileData
                                                        attributes:nil];

     // Following uses GDFileHandle instead of NSFileHandle.
     // get a filehandle for Updating (read & write) and file descriptor
     GDFileHandle *gdFH = [GDFileHandle fileHandleForUpdatingAtPath:filePath];
     int filedesc = [gdFH fileDescriptor];

     // Following uses GDFileHandle instead of NSFileHandle.
     // get another filehandle with the existing filedescriptor and perform write operation
     GDFileHandle* writeFileHandle = [[GDFileHandle alloc] initWithFileDescriptor:filedesc closeOnDealloc:YES];
     [writeFileHandle writeData:testNSData];
     [writeFileHandle synchronizeFile];
     [writeFileHandle closeFile];

     // Following uses GDFileHandle instead of NSFileHandle.
     // get a filehandle for Reading
     GDFileHandle* readFileHandle = [GDFileHandle fileHandleForReadingAtPath:filePath];
     NSData* resData = [readFileHandle readDataToEndOfFile];

     NSString *myString = [[NSString alloc] initWithData:resData encoding:NSUTF8StringEncoding];

     return myString;
 }

Member Function Documentation

- (NSData *) readDataToEndOfFile
- (NSData *) readDataOfLength: (NSUInteger)  length
- (void) writeData: (NSData *)  data
- (unsigned long long) seekToEndOfFile
- (void) seekToFileOffset: (unsigned long long)  offset
- (void) truncateFileAtOffset: (unsigned long long)  offset
- (void) synchronizeFile
- (void) closeFile
- (instancetype) initWithFileDescriptor: (int)  fd
closeOnDealloc: (BOOL)  closeopt 
- (instancetype) initWithCoder: (NSCoder *)  NS_DESIGNATED_INITIALIZER
+ (instancetype) fileHandleForReadingAtPath: (NSString *)  path
+ (instancetype) fileHandleForWritingAtPath: (NSString *)  path
+ (instancetype) fileHandleForUpdatingAtPath: (NSString *)  path
+ (instancetype) fileHandleForReadingFromURL: (NSURL *)  url
error: (NSError **)  error 
+ (instancetype) fileHandleForWritingToURL: (NSURL *)  url
error: (NSError **)  error 
+ (instancetype) fileHandleForUpdatingURL: (NSURL *)  url
error: (NSError **)  error 
+ (NSFileHandle *) fileHandleWithStandardInput
+ (NSFileHandle *) fileHandleWithStandardOutput
+ (NSFileHandle *) fileHandleWithStandardError
+ (NSFileHandle *) fileHandleWithNullDevice
- (void) readInBackgroundAndNotifyForModes: (NSArray *)  modes
- (void) readInBackgroundAndNotify
- (void) readToEndOfFileInBackgroundAndNotifyForModes: (NSArray *)  modes
- (void) readToEndOfFileInBackgroundAndNotify
- (void) acceptConnectionInBackgroundAndNotifyForModes: (NSArray *)  modes
- (void) acceptConnectionInBackgroundAndNotify
- (void) waitForDataInBackgroundAndNotifyForModes: (NSArray *)  modes
- (void) waitForDataInBackgroundAndNotify

Property Documentation

- (NSData*) availableData [read, copy]
- (unsigned long long) offsetInFile [read, assign]
- (int) fileDescriptor [read, assign]

The documentation for this class was generated from the following file: