123
str = [NSString stringWithFormat: @"%s", ERR_reason_error_string(err)];
125
const char *s = ERR_reason_error_string(err);
131
ERR_error_string(err, buf);
132
str = [NSString stringWithFormat: @"%s", buf];
136
str = [NSString stringWithFormat: @"%s", s];
130
143
static NSLock **locks = 0;
133
locking_function(int mode, int n, const char *file, int line)
146
locking_function(int mode, int n, const char *file, int line)
135
148
if (mode & CRYPTO_LOCK)
141
154
[locks[n] unlock];
145
158
#if defined(HAVE_CRYPTO_THREADID_SET_CALLBACK)
147
threadid_function(CRYPTO_THREADID *ref)
160
threadid_function(CRYPTO_THREADID *ref)
149
162
CRYPTO_THREADID_set_pointer(ref, GSCurrentThread());
152
165
static unsigned long
155
168
return (unsigned long) GSCurrentThread();
169
180
- (void) sslDisconnect;
170
181
- (BOOL) sslHandshakeEstablished: (BOOL*)result outgoing: (BOOL)isOutgoing;
171
- (void) sslSetCertificate: (NSString*)certFile
172
privateKey: (NSString*)privateKey
173
PEMpasswd: (NSString*)PEMpasswd;
182
- (NSString*) sslSetOptions: (NSDictionary*)options;
176
static BOOL permitSSLv2 = NO;
177
static NSString *cipherList = nil;
179
185
@implementation GSSSLHandle
180
+ (void) _defaultsChanged: (NSNotification*)n
183
= [[NSUserDefaults standardUserDefaults] boolForKey: @"GSPermitSSLv2"];
185
= [[NSUserDefaults standardUserDefaults] stringForKey: @"GSCipherList"];
188
187
+ (void) initialize
190
189
if (self == [GSSSLHandle class])
192
NSUserDefaults *defs;
195
193
SSL_library_init();
201
199
locks[count] = [NSLock new];
203
CRYPTO_set_locking_callback(locking_function);
201
CRYPTO_set_locking_callback(locking_function);
204
202
#if defined(HAVE_CRYPTO_THREADID_SET_CALLBACK)
205
CRYPTO_THREADID_set_callback(threadid_function);
203
CRYPTO_THREADID_set_callback(threadid_function);
207
CRYPTO_set_id_callback(threadid_function);
205
CRYPTO_set_id_callback(threadid_function);
218
216
inf = [[[NSProcessInfo processInfo] globallyUniqueString] UTF8String];
219
217
RAND_seed(inf, strlen(inf));
221
defs = [NSUserDefaults standardUserDefaults];
222
permitSSLv2 = [defs boolForKey: @"GSPermitSSLv2"];
223
cipherList = [defs stringForKey: @"GSCipherList"];
224
[[NSNotificationCenter defaultCenter]
226
selector: @selector(_defaultsChanged:)
227
name: NSUserDefaultsDidChangeNotification
250
240
return [super read: buf length: len];
257
if (YES == isStandardFile)
259
NSLog(@"Attempt to make ssl connection to a standard file");
262
if (NO == [self sslHandshakeEstablished: &result outgoing: NO])
266
IF_NO_GC([self retain];) // Don't get destroyed during runloop
267
loop = [NSRunLoop currentRunLoop];
268
[loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
269
if (NO == [self sslHandshakeEstablished: &result outgoing: NO])
273
NSTimeInterval last = 0.0;
274
NSTimeInterval limit = 0.1;
276
final = [[NSDate alloc] initWithTimeIntervalSinceNow: 30.0];
277
when = [NSDate alloc];
279
while (NO == [self sslHandshakeEstablished: &result outgoing: NO]
280
&& [final timeIntervalSinceNow] > 0.0)
282
NSTimeInterval tmp = limit;
291
when = [when initWithTimeIntervalSinceNow: limit];
292
[loop runUntilDate: when];
306
if (YES == isStandardFile)
308
NSLog(@"Attempt to make ssl connection to a standard file");
311
if (NO == [self sslHandshakeEstablished: &result outgoing: YES])
315
IF_NO_GC([self retain];) // Don't get destroyed during runloop
316
loop = [NSRunLoop currentRunLoop];
317
[loop runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.01]];
318
if (NO == [self sslHandshakeEstablished: &result outgoing: YES])
322
NSTimeInterval last = 0.0;
323
NSTimeInterval limit = 0.1;
325
final = [[NSDate alloc] initWithTimeIntervalSinceNow: 30.0];
326
when = [NSDate alloc];
328
while (NO == [self sslHandshakeEstablished: &result outgoing: YES]
329
&& [final timeIntervalSinceNow] > 0.0)
331
NSTimeInterval tmp = limit;
340
when = [when initWithTimeIntervalSinceNow: limit];
341
[loop runUntilDate: when];
351
243
- (void) sslDisconnect
389
281
* Ensure we have a context and handle to connect with.
393
285
ctx = SSL_CTX_new(SSLv23_client_method());
394
if (permitSSLv2 == NO)
396
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
398
if (nil != cipherList)
400
SSL_CTX_set_cipher_list(ctx, [cipherList UTF8String]);
286
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
405
290
ssl = SSL_new(ctx);
409
* Set non-blocking so accept won't hang if remote end goes wrong.
411
[self setNonBlocking: YES];
412
ret = SSL_set_fd(ssl, descriptor);
293
if (SSL_get_fd(ssl) == descriptor)
299
/* Set non-blocking so accept won't hang if remote end goes wrong.
301
[self setNonBlocking: YES];
302
ret = SSL_set_fd(ssl, descriptor);
415
306
if (YES == isOutgoing)
444
- (void) sslSetCertificate: (NSString*)certFile
445
privateKey: (NSString*)privateKey
446
PEMpasswd: (NSString*)PEMpasswd
335
- (NSString*) sslSetOptions: (NSDictionary*)options
338
NSString *privateKey;
342
certFile = [options objectForKey: GSTLSCertificateFile];
343
privateKey = [options objectForKey: GSTLSCertificateKeyFile];
344
PEMpasswd = [options objectForKey: GSTLSCertificateKeyPassword];
450
346
if (isStandardFile == YES)
452
NSLog(@"Attempt to set ssl certificate for a standard file");
348
return @"Attempt to set ssl certificate for a standard file";
456
352
* Ensure we have a context to set the certificate for.
460
356
ctx = SSL_CTX_new(SSLv23_method());
461
if (permitSSLv2 == NO)
463
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
465
if (nil != cipherList)
467
SSL_CTX_set_cipher_list(ctx, [cipherList UTF8String]);
357
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
470
359
if ([PEMpasswd length] > 0)
480
369
NSLog(@"Failed to set certificate file to %@ - %@",
481
370
certFile, sslError(ERR_get_error()));
371
return @"Failed to set certificate file";
484
374
if ([privateKey length] > 0)
490
380
NSLog(@"Failed to set private key file to %@ - %@",
491
381
privateKey, sslError(ERR_get_error()));
382
return @"Failed to set key file";
496
388
- (NSInteger) write: (const void*)buf length: (NSUInteger)len