mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Encryption emprovements
This commit is contained in:
parent
b252f4067a
commit
e34584e323
3 changed files with 110 additions and 87 deletions
|
@ -1,3 +1,10 @@
|
|||
2021-06-19 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/GSTLS.m:
|
||||
* Source/NSSocketPort.m:
|
||||
Improve reporting of TLS handshake errors, fix a few leaks and
|
||||
generally make encryption of DO connections better.
|
||||
|
||||
2021-06-17 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Source/Additions/Unicode.m:
|
||||
|
|
|
@ -1102,6 +1102,7 @@ static NSMutableDictionary *credentialsCache = nil;
|
|||
|
||||
if (nil == crt || nil == key)
|
||||
{
|
||||
ENTER_POOL
|
||||
static NSString *tmp = @"organization = SelfSigned\n"
|
||||
@"state = Example\n"
|
||||
@"country = EX\n"
|
||||
|
@ -1113,42 +1114,54 @@ static NSMutableDictionary *credentialsCache = nil;
|
|||
@"encryption_key\n";
|
||||
NSFileManager *mgr = [NSFileManager defaultManager];
|
||||
NSString *path = NSTemporaryDirectory();
|
||||
NSFileHandle *devNull = [NSFileHandle fileHandleWithNullDevice];
|
||||
NSTask *task;
|
||||
NSString *tmpPath;
|
||||
NSString *tmpCrt;
|
||||
NSString *tmpKey;
|
||||
NSString *tmpTmp;
|
||||
|
||||
path = [path stringByAppendingPathComponent: [[NSUUID UUID] UUIDString]];
|
||||
keyPath = [path stringByAppendingPathExtension: @"key"];
|
||||
tmpPath = [path stringByAppendingPathExtension: @"tmp"];
|
||||
crtPath = [path stringByAppendingPathExtension: @"crt"];
|
||||
[tmp writeToFile: tmpPath atomically: NO];
|
||||
tmpCrt = [path stringByAppendingPathExtension: @"crt"];
|
||||
tmpKey = [path stringByAppendingPathExtension: @"key"];
|
||||
tmpTmp = [path stringByAppendingPathExtension: @"tmp"];
|
||||
[tmp writeToFile: tmpTmp atomically: NO];
|
||||
|
||||
task = [NSTask new];
|
||||
[task setLaunchPath: @"certtool"];
|
||||
[task setArguments: [NSArray arrayWithObjects:
|
||||
@"--generate-privkey", @"--sec-param", @"high", @"--outfile", keyPath,
|
||||
@"--generate-privkey", @"--sec-param", @"high", @"--outfile", tmpKey,
|
||||
nil]];
|
||||
[task setStandardOutput: [NSFileHandle fileHandleWithNullDevice]];
|
||||
[task setStandardError: [NSFileHandle fileHandleWithNullDevice]];
|
||||
[task setStandardOutput: devNull];
|
||||
[task setStandardError: devNull];
|
||||
[task launch];
|
||||
[task waitUntilExit];
|
||||
RELEASE(task);
|
||||
key = [NSData dataWithContentsOfFile: keyPath];
|
||||
key = [NSData dataWithContentsOfFile: tmpKey];
|
||||
|
||||
task = [NSTask new];
|
||||
[task setLaunchPath: @"certtool"];
|
||||
[task setArguments: [NSArray arrayWithObjects:
|
||||
@"--generate-self-signed", @"--load-privkey", keyPath,
|
||||
@"--template", tmpPath, @"--outfile", crtPath,
|
||||
@"--generate-self-signed", @"--load-privkey", tmpKey,
|
||||
@"--template", tmpTmp, @"--outfile", tmpCrt,
|
||||
nil]];
|
||||
[task setStandardOutput: [NSFileHandle fileHandleWithNullDevice]];
|
||||
[task setStandardError: [NSFileHandle fileHandleWithNullDevice]];
|
||||
[task setStandardOutput: devNull];
|
||||
[task setStandardError: devNull];
|
||||
[task launch];
|
||||
[task waitUntilExit];
|
||||
crt = [NSData dataWithContentsOfFile: crtPath];
|
||||
RELEASE(task);
|
||||
crt = [NSData dataWithContentsOfFile: tmpCrt];
|
||||
|
||||
[mgr removeFileAtPath: keyPath handler: nil];
|
||||
[mgr removeFileAtPath: tmpPath handler: nil];
|
||||
[mgr removeFileAtPath: crtPath handler: nil];
|
||||
[mgr removeFileAtPath: tmpCrt handler: nil];
|
||||
[mgr removeFileAtPath: tmpKey handler: nil];
|
||||
[mgr removeFileAtPath: tmpTmp handler: nil];
|
||||
|
||||
if (key && crt)
|
||||
{
|
||||
[self setData: crt forTLSFile: crtPath];
|
||||
[self setData: key forTLSFile: keyPath];
|
||||
}
|
||||
|
||||
LEAVE_POOL
|
||||
if (nil == key)
|
||||
{
|
||||
NSLog(@"Failed to make self-signed certificate key using 'certtool'");
|
||||
|
@ -1157,10 +1170,8 @@ static NSMutableDictionary *credentialsCache = nil;
|
|||
if (nil == crt)
|
||||
{
|
||||
NSLog(@"Failed to make self-signed certificate using 'certtool'");
|
||||
return nil;
|
||||
}
|
||||
[self setData: key forTLSFile: keyPath];
|
||||
[self setData: crt forTLSFile: crtPath];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
return [self credentialsFromCAFile: nil
|
||||
|
|
|
@ -74,10 +74,24 @@
|
|||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <wininet.h>
|
||||
#include <process.h>
|
||||
#else
|
||||
|
||||
static int socketError()
|
||||
{
|
||||
int e = WSAGetLastError();
|
||||
|
||||
switch (e)
|
||||
case WSAEWOULDBLOCK: return EAGAIN;
|
||||
case WSAEINTR: return EINTR;
|
||||
default: return e;
|
||||
}
|
||||
}
|
||||
|
||||
#else /* _WIN32 */
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -116,6 +130,10 @@
|
|||
#define SOCKET_ERROR -1
|
||||
#define INVALID_SOCKET -1
|
||||
|
||||
static int socketError()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
/*
|
||||
|
@ -288,25 +306,9 @@ GSTLSHandlePull(gnutls_transport_ptr_t handle, void *buffer, size_t len)
|
|||
#if HAVE_GNUTLS_TRANSPORT_SET_ERRNO
|
||||
if (tls->session && tls->session->session)
|
||||
{
|
||||
int e;
|
||||
int e = socketError(); // Get unix style EINTR/EAGAIN
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* For windows, we need to map winsock errors to unix ones that
|
||||
* gnutls understands.
|
||||
*/
|
||||
e = WSAGetLastError();
|
||||
if (WSAEWOULDBLOCK == e)
|
||||
{
|
||||
e = EAGAIN;
|
||||
}
|
||||
else if (WSAEINTR == e)
|
||||
{
|
||||
e = EINTR;
|
||||
}
|
||||
#else
|
||||
e = errno;
|
||||
#endif
|
||||
gnutls_transport_set_errno (tls->session->session, e);
|
||||
gnutls_transport_set_errno(tls->session->session, e);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -329,24 +331,8 @@ GSTLSHandlePush(gnutls_transport_ptr_t handle, const void *buffer, size_t len)
|
|||
#if HAVE_GNUTLS_TRANSPORT_SET_ERRNO
|
||||
if (tls->session && tls->session->session)
|
||||
{
|
||||
int e;
|
||||
int e = socketError(); // Get unix style EINTR/EAGAIN
|
||||
|
||||
#if defined(_WIN32)
|
||||
/* For windows, we need to map winsock errors to unix ones that
|
||||
* gnutls understands.
|
||||
*/
|
||||
e = WSAGetLastError();
|
||||
if (WSAEWOULDBLOCK == e)
|
||||
{
|
||||
e = EAGAIN;
|
||||
}
|
||||
else if (WSAEINTR == e)
|
||||
{
|
||||
e = EINTR;
|
||||
}
|
||||
#else
|
||||
e = errno;
|
||||
#endif
|
||||
gnutls_transport_set_errno(tls->session->session, e);
|
||||
}
|
||||
#endif
|
||||
|
@ -825,13 +811,6 @@ static Class runLoopClass;
|
|||
- (void) finalize
|
||||
{
|
||||
[self invalidate];
|
||||
#if defined(HAVE_GNUTLS)
|
||||
if (session)
|
||||
{
|
||||
[session disconnect: NO];
|
||||
DESTROY(session);
|
||||
}
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
if (event != WSA_INVALID_EVENT)
|
||||
{
|
||||
|
@ -860,6 +839,13 @@ static Class runLoopClass;
|
|||
}
|
||||
M_UNLOCK(myLock);
|
||||
}
|
||||
#if defined(HAVE_GNUTLS)
|
||||
if (session)
|
||||
{
|
||||
[session disconnect: NO];
|
||||
DESTROY(session);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL) isValid
|
||||
|
@ -916,10 +902,21 @@ static Class runLoopClass;
|
|||
{
|
||||
if ([session handshake])
|
||||
{
|
||||
res = [session read: bytes + rLength length: want - rLength];
|
||||
if (![session active])
|
||||
{
|
||||
NSDebugMLLog(@"GSTcpHandle",
|
||||
@"TLS handshake failed on %p - %@", self, [session problem]);
|
||||
[self invalidate];
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
res = [session read: bytes + rLength length: want - rLength];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EAGAIN;
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
@ -933,18 +930,15 @@ static Class runLoopClass;
|
|||
|
||||
if (res <= 0)
|
||||
{
|
||||
int e = socketError();
|
||||
|
||||
if (res == 0)
|
||||
{
|
||||
NSDebugMLLog(@"GSTcpHandle", @"read eof on %p", self);
|
||||
[self invalidate];
|
||||
return;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
else if (WSAGetLastError()!= WSAEINTR
|
||||
&& WSAGetLastError()!= WSAEWOULDBLOCK)
|
||||
#else
|
||||
else if (errno != EINTR && errno != EAGAIN)
|
||||
#endif /* !_WIN32 */
|
||||
else if (e != EINTR && e != EAGAIN)
|
||||
{
|
||||
NSDebugMLLog(@"GSTcpHandle",
|
||||
@"read failed - %@ on 0x%p", [NSError _last], self);
|
||||
|
@ -1289,10 +1283,19 @@ static Class runLoopClass;
|
|||
{
|
||||
if ([session handshake])
|
||||
{
|
||||
if (![session active])
|
||||
{
|
||||
DESTROY(cData);
|
||||
NSLog(@"connect TLS handshake failed on %p - %@",
|
||||
self, [session problem]);
|
||||
state = GS_H_UNCON;
|
||||
return;
|
||||
}
|
||||
len = [session write: b + cLength length: l - cLength];
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EAGAIN;
|
||||
len = -1;
|
||||
}
|
||||
}
|
||||
|
@ -1306,12 +1309,9 @@ static Class runLoopClass;
|
|||
|
||||
if (len <= 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (WSAGetLastError() != WSAEINTR
|
||||
&& WSAGetLastError() != WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (errno != EINTR && errno != EAGAIN)
|
||||
#endif /* !_WIN32 */
|
||||
int e = socketError();
|
||||
|
||||
if (e != EINTR && e != EAGAIN)
|
||||
{
|
||||
DESTROY(cData);
|
||||
state = GS_H_UNCON;
|
||||
|
@ -1319,8 +1319,8 @@ static Class runLoopClass;
|
|||
[NSError _last]);
|
||||
return;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
#if _WIN32
|
||||
else
|
||||
{
|
||||
readyToSend = NO;
|
||||
}
|
||||
|
@ -1368,10 +1368,18 @@ static Class runLoopClass;
|
|||
{
|
||||
if ([session handshake])
|
||||
{
|
||||
if (![session active])
|
||||
{
|
||||
NSLog(@"accept TLS handshake failed on %p - %@",
|
||||
self, [session problem]);
|
||||
[self invalidate];
|
||||
return;
|
||||
}
|
||||
res = [session write: b + wLength length: l - wLength];
|
||||
}
|
||||
else
|
||||
{
|
||||
errno = EAGAIN;
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
@ -1384,19 +1392,16 @@ static Class runLoopClass;
|
|||
#endif
|
||||
if (res < 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (WSAGetLastError()!= WSAEINTR
|
||||
&& WSAGetLastError()!= WSAEWOULDBLOCK)
|
||||
#else
|
||||
if (errno != EINTR && errno != EAGAIN)
|
||||
#endif /* !_WIN32 */
|
||||
int e = socketError();
|
||||
|
||||
if (e != EINTR && e != EAGAIN)
|
||||
{
|
||||
NSLog(@"write attempt failed - %@", [NSError _last]);
|
||||
[self invalidate];
|
||||
return;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if (WSAGetLastError()== WSAEWOULDBLOCK)
|
||||
#if _WIN32
|
||||
else
|
||||
{
|
||||
readyToSend = NO;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue