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 (GDMac).
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 GDFile
Handle
, 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
GDFil
eManager
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 is not 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"]
BOOL fileCreated = [[GDFileManager defaultManager] createFileAtPath:filePath
contents:fileData
attributes:nil];
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];
NSFileHandle *nsFH = [NSFileHandle fileHandleForUpdatingAtPath:filePath];
int filedesc = [nsFH fileDescriptor];
NSFileHandle* writeFileHandle = [[NSFileHandle alloc] initWithFileDescriptor:filedesc closeOnDealloc:YES];
[writeFileHandle writeData:testNSData];
[writeFileHandle synchronizeFile];
[writeFileHandle closeFile];
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"]
BOOL fileCreated = [[GDFileManager defaultManager] createFileAtPath:filePath
contents:fileData
attributes:nil];
GDFileHandle *gdFH = [GDFileHandle fileHandleForUpdatingAtPath:filePath];
int filedesc = [gdFH fileDescriptor];
GDFileHandle* writeFileHandle = [[GDFileHandle alloc] initWithFileDescriptor:filedesc closeOnDealloc:YES];
[writeFileHandle writeData:testNSData];
[writeFileHandle synchronizeFile];
[writeFileHandle closeFile];
GDFileHandle* readFileHandle = [GDFileHandle fileHandleForReadingAtPath:filePath];
NSData* resData = [readFileHandle readDataToEndOfFile];
NSString *myString = [[NSString alloc] initWithData:resData encoding:NSUTF8StringEncoding];
return myString;
}