gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PATCH: use gnutls for SSL in NSFileHandle


From: Derek Zhou
Subject: PATCH: use gnutls for SSL in NSFileHandle
Date: Sat, 22 Mar 2008 23:30:21 -0700
User-agent: KMail/1.9.7

Looks like base links to gnutls by default already. This patch provide SSL 
operation for NSFileHandle with gnutls; the functionality was provided by
the SSL bundle. Since it is so simple I think making a bundle for it is 
unnecessary. The code is lightly tested with blocking client side read/write.
Here is the patch:

Index: Source/GNUmakefile
===================================================================
--- Source/GNUmakefile  (revision 26371)
+++ Source/GNUmakefile  (working copy)
@@ -270,8 +270,12 @@
 BASE_MFILES += NSNetServices.m
 endif
 
+ifeq ($(GNUSTEP_BASE_HAVE_GNUTLS), 1)
+BASE_MFILES += GSTLSHandle.m 
 endif
 
+endif
+
 ifeq ($(WITH_FFI),libffi)
 GNU_MFILES += cifframe.m
 BASE_MFILES += GSFFIInvocation.m
Index: Source/NSFileHandle.m
===================================================================
--- Source/NSFileHandle.m       (revision 26371)
+++ Source/NSFileHandle.m       (working copy)
@@ -34,7 +34,9 @@
 #include "Foundation/NSPathUtilities.h"
 #include "Foundation/NSBundle.h"
 #include "GNUstepBase/GSFileHandle.h"
-
+#if     defined(HAVE_GNUTLS)
+#include "GSTLSHandle.h"
+#endif
 // GNUstep Notification names
 
 NSString * const GSFileHandleConnectCompletionNotification
@@ -72,6 +74,9 @@
     {
       NSFileHandle_abstract_class = self;
       NSFileHandle_concrete_class = [GSFileHandle class];
+#if     defined(HAVE_GNUTLS)
+      NSFileHandle_ssl_class = [GSTLSHandle class];
+#endif
     }
 }
 
@@ -708,21 +713,6 @@
  */
 + (Class) sslClass
 {
-  if (NSFileHandle_ssl_class == 0)
-    {
-      NSString  *path;
-      NSBundle *bundle;
-
-      path = [[NSBundle bundleForClass: [NSObject class]] bundlePath];
-      path = [path stringByAppendingPathComponent: @"SSL.bundle"];
-
-      bundle = [NSBundle bundleWithPath: path];
-      NSFileHandle_ssl_class = [bundle principalClass];
-      if (NSFileHandle_ssl_class == 0 && bundle != nil)
-       {
-         NSLog(@"Failed to load principal class from bundle (%@)", path);
-       }
-    }
   return NSFileHandle_ssl_class;
 }
 
Index: Source/GSTLSHandle.h
===================================================================
--- Source/GSTLSHandle.h        (revision 0)
+++ Source/GSTLSHandle.h        (revision 0)
@@ -0,0 +1,48 @@
+/** Implementation for GSTLSHandle for GNUStep
+   Copyright (C) 1997-2008 Free Software Foundation, Inc.
+
+   Written by:  Richard Frith-Macdonald <address@hidden>
+   Date: 1997
+   Written by:  Derek Zhou <address@hidden>
+   Date: 2008
+
+   This file is part of the GNUstep Base Library.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02111 USA.
+   */
+
+#ifndef INCLUDED_GSTLSHANDLE_H
+#define INCLUDED_GSTLSHANDLE_H
+
+#include <gnutls/gnutls.h>
+
address@hidden  GSTLSHandle : GSFileHandle <GCFinalization>
+{
+  gnutls_session_t session;
+  gnutls_certificate_credentials_t xcred;
+  BOOL xcredAllocated;
+  BOOL         connected;
+}
+
+- (BOOL) sslAccept;
+- (BOOL) sslConnect;
+- (void) sslDisconnect;
+- (void) sslSetCertificate: (NSString*)certFile
+               privateKey: (NSString*)privateKey
+                PEMpasswd: (NSString*)PEMpasswd;
address@hidden
+
+#endif
Index: Source/GSTLSHandle.m
===================================================================
--- Source/GSTLSHandle.m        (revision 0)
+++ Source/GSTLSHandle.m        (revision 0)
@@ -0,0 +1,192 @@
+/** Implementation for GSTLSHandle for GNUStep
+   Copyright (C) 1997-2008 Free Software Foundation, Inc.
+
+   Written by:  Richard Frith-Macdonald <address@hidden>
+   Date: 1997
+   Written by:  Derek Zhou <address@hidden>
+   Date: 2008
+
+   This file is part of the GNUstep Base Library.
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02111 USA.
+   */
+
+
+#include "config.h"
+
+#include <GNUstepBase/GSFileHandle.h>
+#include "GSTLSHandle.h"
+
address@hidden  GSTLSHandle
++ (void) initialize
+{
+  if (self == [GSTLSHandle class])
+    {
+      gnutls_global_init ();
+    }
+}
+
+- (void) closeFile
+{
+  [self sslDisconnect];
+  [super closeFile];
+}
+
+- (void) gcFinalize
+{
+  [self sslDisconnect];
+  [super gcFinalize];
+}
+
+- (int) read: (void*)buf length: (int)len
+{
+  if (connected)
+    {
+      return gnutls_record_recv(session, buf, len);
+    }
+  return [super read: buf length: len];
+}
+
+- (BOOL) sslAccept
+{
+  int          ret;
+
+  if (connected == YES)
+    {
+      return YES;      /* Already connected.   */
+    }
+  if (isStandardFile == YES)
+    {
+      NSLog(@"Attempt to make ssl connection to a standard file");
+      return NO;
+    }
+
+  if (!xcredAllocated)
+    {
+      gnutls_certificate_allocate_credentials (&xcred);
+      xcredAllocated = YES;
+    }
+  gnutls_init (&session, GNUTLS_SERVER);
+  gnutls_set_default_priority (session);
+  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
+  gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUEST);
+  /*
+   * Don't know how to do non-blocking handshake, I'll do the blocking for now
+   */
+  [self setNonBlocking: NO];
+  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) descriptor);
+  ret = gnutls_handshake (session);
+  if (ret != 0)
+    {
+      NSLog(@"Failed to do TLS handshake  - %s", gnutls_strerror(ret));
+      gnutls_deinit(session);
+      return NO;
+    }
+  connected = YES;
+  return YES;
+}
+
+- (BOOL) sslConnect
+{
+  int          ret;
+
+  if (connected == YES)
+    {
+      return YES;      /* Already connected.   */
+    }
+  if (isStandardFile == YES)
+    {
+      NSLog(@"Attempt to make ssl connection to a standard file");
+      return NO;
+    }
+
+  if (!xcredAllocated)
+    {
+      gnutls_certificate_allocate_credentials (&xcred);
+      xcredAllocated = YES;
+    }
+  gnutls_init (&session, GNUTLS_CLIENT);
+  gnutls_set_default_priority (session);
+  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
+  /*
+   * Don't know how to do non-blocking handshake, I'll do the blocking for now
+   */
+  [self setNonBlocking: NO];
+  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) descriptor);
+  ret = gnutls_handshake (session);
+  if (ret != 0)
+    {
+      NSLog(@"Failed to do TLS handshake  - %s", gnutls_strerror(ret));
+      gnutls_deinit(session);
+      return NO;
+    }
+  connected = YES;
+  return YES;
+}
+
+- (void) sslDisconnect
+{
+  if (connected == YES)
+    {
+      gnutls_bye(session, GNUTLS_SHUT_RDWR);
+      gnutls_deinit(session);
+    }
+  if (xcredAllocated)
+    {
+      gnutls_certificate_free_credentials(xcred);
+      xcredAllocated = NO;
+    }
+  connected = NO;
+}
+
+- (void) sslSetCertificate: (NSString*)certFile
+               privateKey: (NSString*)privateKey
+                PEMpasswd: (NSString*)PEMpasswd
+{
+  int  ret;
+
+  if (isStandardFile == YES)
+    {
+      NSLog(@"Attempt to set ssl certificate for a standard file");
+      return;
+    }
+  if (!xcredAllocated)
+    {
+      gnutls_certificate_allocate_credentials (&xcred);
+      xcredAllocated = YES;
+    }
+  ret = gnutls_certificate_set_x509_key_file (xcred, 
+                                              [certFile UTF8String], 
+                                              [privateKey UTF8String],
+                                              GNUTLS_X509_FMT_PEM);
+  if (ret!=0)
+    {
+      NSLog(@"Failed to set certificqte/private key file to %@/%@ - %s",
+           certFile, privateKey, gnutls_strerror(ret));
+    }
+}
+
+- (int) write: (const void*)buf length: (int)len
+{
+  if (connected)
+    {
+      return gnutls_record_send(session, buf, len);
+    }
+  return [super write: buf length: len];
+}
+
address@hidden
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]