SSL/TLS certificate enhancements.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@37103 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2013-09-18 12:49:07 +00:00
parent 67ca781fb0
commit 2e99b562d8
5 changed files with 119 additions and 5 deletions

View file

@ -1,3 +1,13 @@
2013-09-18 Richard Frith-Macdonald <rfm@gnu.org>
* Source/GSTLS.h:
* Source/GSTLS.m:
* Source/NSFileHandle.m:
* Headers/Foundation/NSFileHandle.h:
Add mechanism to set the contents of TLS certificate and key files
in memory rather than reading from disk. Expose TLS property keys
in the NSFileHandle header to allow more control over certificates.
2013-09-10 Richard Frith-Macdonald <rfm@gnu.org>
* configure.ac: Check for another unicode header

View file

@ -273,7 +273,9 @@ GS_EXPORT NSString * const NSFileHandleOperationException;
* Sets options to be used to configure this channel before the handshake.<br />
* Returns nil on success, or an error message if some options could not
* be set.<br />
* Expects key value pairs with the follwiing names/meanings:
* You may use the same options as property settings with the GNUstep
* implementation of NSStream.<br />
* Expects key value pairs with the follwing names/meanings:
* <deflist>
* <term>GSTLSCAFile</term>
* <desc>A string identifying the full path to the file containing any
@ -324,8 +326,22 @@ GS_EXPORT NSString * const NSFileHandleOperationException;
*/
- (NSString*) sslSetOptions: (NSDictionary*)options;
/** Sets the known (cached) data content for the specified file name.<br />
* Calling this with a nil data object will remove any existing value
* from the cache.<br />
* You may use this method to control what data is used for specified
* file names when those file names are used as a result of SSL/TLS
* options being set for a file handle or stream.
*/
+ (void) setData: (NSData*)data forTLSFile: (NSString*)fileName;
@end
/** Dictionary key for the path to a PEM encoded certificate authority
* file.
*/
GS_EXPORT NSString * const GSTLSCAFile;
/** Dictionary key for the path to a PEM encoded certificate used
* to identify this end of a connection.
*/
@ -341,6 +357,27 @@ GS_EXPORT NSString * const GSTLSCertificateKeyFile;
*/
GS_EXPORT NSString * const GSTLSCertificateKeyPassword;
/** Dictionary key for a boolean to enable TLS debug for a session.
*/
GS_EXPORT NSString * const GSTLSDebug;
/** Dictionary key for a GNUTLS priority setting for a session.
*/
GS_EXPORT NSString * const GSTLSPriority;
/** Dictionary key for a list of hosts to use in certificate verification.
*/
GS_EXPORT NSString * const GSTLSRemoteHosts;
/** Dictionary key for the path to a PEM encoded certificate revocation
* file.
*/
GS_EXPORT NSString * const GSTLSRevokeFile;
/** Dictionary key for a boolean to enable certificate verification.
*/
GS_EXPORT NSString * const GSTLSVerify;
// GNUstep Notification names.
/**
@ -360,6 +397,7 @@ GS_EXPORT NSString * const GSFileHandleWriteCompletionNotification;
* operation.
*/
GS_EXPORT NSString * const GSFileHandleNotificationError;
#endif
#if defined(__cplusplus)

View file

@ -53,9 +53,27 @@ extern NSString * const GSTLSVerify;
#undef id
/* This class is used to ensure that the GNUTLS system is initialised
* and thread-safe.
* and thread-safe. It also provides a mechanism to save certificate
* and key information in memory by associating a 'filename' with the
* cached data.
*/
@interface GSTLSObject : NSObject
/** Returns either the cached data for this file name (if any), or the
* result of calling [NSData+dataWithContentsOfFile:] if there is no
* cached data.<br />
* This method is used internally to load certificates and keys.
*/
+ (NSData*) dataForTLSFile: (NSString*)fileName;
/** Sets the known (cached) data content for the specified file name.<br />
* Calling this with a nil data object will remove any existing value
* from the cache.<br />
* You may use this method to control what data is used for specified
* file names.
*/
+ (void) setData: (NSData*)data forTLSFile: (NSString*)fileName;
@end
/* This class provides the current autogenerated Diffie Hellman parameters

View file

@ -152,6 +152,9 @@ static gnutls_anon_client_credentials_t anoncred;
*/
@implementation GSTLSObject
static NSLock *fileLock = nil;
static NSMutableDictionary *fileMap = nil;
+ (void) _defaultsChanged: (NSNotification*)n
{
NSString *str;
@ -214,6 +217,25 @@ static gnutls_anon_client_credentials_t anoncred;
gnutls_global_set_log_level(globalDebug);
}
+ (NSData*) dataForTLSFile: (NSString*)fileName
{
NSData *result;
if (NO == [fileName isKindOfClass: [NSString class]])
{
[NSException raise: NSInvalidArgumentException
format: @"[GSTLS+dataForTLSFile:] called with bad file name"];
}
[fileLock lock];
result = [[fileMap objectForKey: fileName] retain];
[fileLock unlock];
if (nil == result)
{
return [NSData dataWithContentsOfFile: fileName];
}
return [result autorelease];
}
+ (void) initialize
{
if ([GSTLSObject class] == self)
@ -230,6 +252,9 @@ static gnutls_anon_client_credentials_t anoncred;
bundle = [NSBundle bundleForClass: [NSObject class]];
fileLock = [NSLock new];
fileMap = [NSMutableDictionary new];
/* Let the GS_TLS_CA_FILE environment variable override the
* default certificate authority location.
*/
@ -309,6 +334,23 @@ static gnutls_anon_client_credentials_t anoncred;
}
}
+ (void) setData: (NSData*)data forTLSFile: (NSString*)fileName
{
if (nil != data && NO == [data isKindOfClass: [NSData class]])
{
[NSException raise: NSInvalidArgumentException
format: @"[GSTLS+setData:forTLSFile:] called with bad data"];
}
if (NO == [fileName isKindOfClass: [NSString class]])
{
[NSException raise: NSInvalidArgumentException
format: @"[GSTLS+setData:forTLSFile:] called with bad file"];
}
[fileLock lock];
[fileMap setObject: data forKey: fileName];
[fileLock unlock];
}
@end
@implementation GSTLSDHParams
@ -440,7 +482,7 @@ static GSTLSDHParams *paramsCurrent = nil;
int ret;
gnutls_datum_t datum;
data = [NSData dataWithContentsOfFile: f];
data = [[self class] dataForTLSFile: f];
if (nil == data)
{
NSLog(@"Unable to read DF params file '%@'", f);
@ -629,7 +671,7 @@ static NSMutableDictionary *certificateListCache = nil;
unsigned int count = 100;
gnutls_x509_crt_t crts[count];
data = [NSData dataWithContentsOfFile: f];
data = [[self class] dataForTLSFile: f];
if (nil == data)
{
NSLog(@"Unable to read certificate file '%@'", f);
@ -832,7 +874,7 @@ static NSMutableDictionary *privateKeyCache1 = nil;
int ret;
gnutls_datum_t datum;
data = [NSData dataWithContentsOfFile: f];
data = [[self class] dataForTLSFile: f];
if (nil == data)
{
NSLog(@"Unable to read private key file '%@'", f);

View file

@ -710,6 +710,12 @@ NSString * const NSFileHandleOperationException
@end
@implementation NSFileHandle (GNUstepTLS)
+ (void) setData: (NSData*)data forTLSFile: (NSString*)fileName
{
[GSTLSObject setData: data forTLSFile: fileName];
}
/**
* returns the concrete class used to implement SSL/TLS connections.
*/