Author: rfm
Date: Fri Sep  2 09:59:08 2016
New Revision: 40067

URL: http://svn.gna.org/viewcvs/gnustep?rev=40067&view=rev
Log:
Add diagnostic code

Modified:
    libs/base/trunk/Resources/GSTLS/README
    libs/base/trunk/Source/GSTLS.h
    libs/base/trunk/Source/GSTLS.m

Modified: libs/base/trunk/Resources/GSTLS/README
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Resources/GSTLS/README?rev=40067&r1=40066&r2=40067&view=diff
==============================================================================
--- libs/base/trunk/Resources/GSTLS/README      (original)
+++ libs/base/trunk/Resources/GSTLS/README      Fri Sep  2 09:59:08 2016
@@ -5,7 +5,7 @@
         a list of PEM encoded certificates of trusted authorities
 
         NB. This is just the list of trusted authorities from my personal
-        machine, it may bot be suitable for you ... please replace/remove
+        machine, it may not be suitable for you ... please replace/remove
         to meet your own needs.
 
 revoke.crl

Modified: libs/base/trunk/Source/GSTLS.h
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/GSTLS.h?rev=40067&r1=40066&r2=40067&view=diff
==============================================================================
--- libs/base/trunk/Source/GSTLS.h      (original)
+++ libs/base/trunk/Source/GSTLS.h      Fri Sep  2 09:59:08 2016
@@ -116,8 +116,15 @@
   unsigned int          count;
 }
 + (GSTLSCertificateList*) listFromFile: (NSString*)f;
+
+/* Return the list of x509 certificates.
+ */
 - (gnutls_x509_crt_t*) certificateList;
+
+/* Return number of certificates in list.
+ */
 - (unsigned int) count;
+
 @end
 
 /* This encapsulates private keys used to unlock certificates
@@ -155,6 +162,8 @@
                                    asClient: (BOOL)client
                                       debug: (BOOL)debug;
 - (gnutls_certificate_credentials_t) credentials;
+- (GSTLSPrivateKey*) key;
+- (GSTLSCertificateList*) list;
 - (BOOL) trust;
 @end
 
@@ -199,6 +208,14 @@
  */
 - (BOOL) active;
 
+/* Returns the credentials object ofr this session.
+ */
+- (GSTLSCredentials*) credentials;
+
+/* Return the current debug mode.
+ */
+- (BOOL) debug;
+
 /* Disconnects and closes down the session.<br />
  * The reusable flag specifies whether we intend to reuse the underlying
  * connection.<br />

Modified: libs/base/trunk/Source/GSTLS.m
URL: 
http://svn.gna.org/viewcvs/gnustep/libs/base/trunk/Source/GSTLS.m?rev=40067&r1=40066&r2=40067&view=diff
==============================================================================
--- libs/base/trunk/Source/GSTLS.m      (original)
+++ libs/base/trunk/Source/GSTLS.m      Fri Sep  2 09:59:08 2016
@@ -716,14 +716,15 @@
           [l release];
           return nil;
         }
-      l->crts = malloc(sizeof(gnutls_x509_crt_t) * count);
-      memcpy(l->crts, crts, sizeof(gnutls_x509_crt_t) * count);
-      l->count = count;
 
       if (count > 0)
         {
           time_t        now = (time_t)[[NSDate date] timeIntervalSince1970];
-          unsigned int  i;
+          unsigned int  i = count;
+
+          l->crts = malloc(sizeof(gnutls_x509_crt_t) * count);
+          memcpy(l->crts, crts, sizeof(gnutls_x509_crt_t) * count);
+          l->count = count;
 
           for (i = 0; i < count; i++)
             {
@@ -778,9 +779,9 @@
         {
           while (count-- > 0)
             {
-              gnutls_x509_crt_deinit(crts[count]);
-            }
-          free(crts);
+              if (crts) gnutls_x509_crt_deinit(crts[count]);
+            }
+          if (crts) free(crts);
         }
     }
   [super dealloc];
@@ -1193,7 +1194,7 @@
             }
         }
 
-      /* Load our certificate (may be a list) ifthe file is specified.
+      /* Load our certificate (may be a list) if the file is specified.
        */
       if (nil != cf)
         {
@@ -1262,6 +1263,16 @@
   return certcred;
 }
 
+- (GSTLSPrivateKey*) key
+{
+  return key;
+}
+
+- (GSTLSCertificateList*) list
+{
+  return list;
+}
+
 - (BOOL) trust
 {
   return trust;
@@ -1269,7 +1280,83 @@
 @end
 
 
-
+/* Callback used only when debug is enabled, to print the request for a
+ * certificate and the response to that request.
+ * NB. This function always returns the certificate set for the session
+ * even if that certificate does not match the CAs or algorithms requested
+ * by the server.  This differs from the default behavior which is for the
+ * library code to only return a certificate matching the request.
+ * So, the logging of a returned certificate does not guarantee that the
+ * certificate is acceptable to the server.
+ */
+static int
+retrieve_callback(gnutls_session_t session,
+  const gnutls_datum_t *req_ca_rdn,
+  int nreqs,
+  const gnutls_pk_algorithm_t *sign_algos,
+  int sign_algos_length,
+  gnutls_retr2_st *st)
+{
+  GSTLSSession  *s = gnutls_session_get_ptr(session);
+  char          issuer_dn[256];
+  int           i;
+  int           ret;
+  size_t        len;
+
+  /* Print the server's trusted CAs
+   */
+  if (nreqs > 0)
+    NSLog(@"- Server's trusted authorities:");
+  else
+    NSLog(@"- Server did not send us any trusted authorities names.");
+
+  /* print the names (if any) */
+  for (i = 0; i < nreqs; i++)
+    {
+      len = sizeof(issuer_dn);
+      ret = gnutls_x509_rdn_get(&req_ca_rdn[i], issuer_dn, &len);
+      if (ret >= 0)
+        {
+          NSLog(@"   [%d]: %s", i, issuer_dn);
+        }
+    }
+
+  /* Select a certificate and return it.
+   * The certificate must be of any of the "sign algorithms"
+   * supported by the server.
+   */
+  if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509)
+    {
+      GSTLSCredentials          *credentials = [s credentials];
+      GSTLSPrivateKey           *key = [credentials key];
+      GSTLSCertificateList      *list = [credentials list];
+      int                       count = (int)[list count];
+      gnutls_x509_crt_t         *crts = [list certificateList];
+      NSMutableString           *m;
+
+      m = [NSMutableString stringWithCapacity: 2000];
+      for (i = 0; i < count; i++)
+        {
+          [GSTLSCertificateList certInfo: crts[i]
+                                      to: m];
+        }
+      if (0 == count)
+        {
+          [m appendString: @"None."];
+        }
+      NSLog(@"Certificates retrieved for sending to peer -\n%@", m);
+
+      st->cert_type = GNUTLS_CRT_X509;
+      st->ncerts = count;
+      st->cert.x509 = crts;
+      st->key.x509 = [key key];
+      return 0;
+    }
+  else
+    {
+      return -1;
+    }
+}
 
 @implementation GSTLSSession
 
@@ -1294,6 +1381,11 @@
   return active;
 }
 
+- (GSTLSCredentials*) credentials
+{
+  return credentials;
+}
+
 - (void) dealloc
 {
   [self finalize];
@@ -1301,6 +1393,11 @@
   DESTROY(credentials);
   DESTROY(problem);
   [super dealloc];
+}
+
+- (BOOL) debug
+{
+  return debug;
 }
 
 - (BOOL) disconnect: (BOOL)reusable
@@ -1407,6 +1504,11 @@
               gnutls_certificate_server_set_request(session,
                 GNUTLS_CERT_IGNORE);
             }
+          else
+            {
+              gnutls_certificate_server_set_request(session,
+                GNUTLS_CERT_REQUEST);
+            }
         }
       setup = YES;
 
@@ -1447,7 +1549,7 @@
             @" the GS_TLS_CA_FILE environment variable, then the system will"
             @" have attempted to use the GSTLS/ca-certificates.crt file in the"
             @" gnustep-base resource bundle.  Unfortunately, it has not been"
-            @" possible to ready any trusted certificate authoritied from"
+            @" possible to read any trusted certificate authorities from"
             @" these locations.");
         }
 
@@ -1538,6 +1640,17 @@
       gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE,
         [credentials credentials]);
 
+      if (YES == outgoing && YES == debug)
+        {
+          /* Set a callback to log handling of a request (from the server)
+           * for the client certificate.  The callback always returns the
+           * certificate set for this session, even if that does not match
+           * the server's request.
+           */
+          gnutls_certificate_set_retrieve_function(
+            [credentials credentials], retrieve_callback);
+        }
+      
       /* Set transport layer to use 
        */
 #if GNUTLS_VERSION_NUMBER < 0x020C00
@@ -1546,6 +1659,7 @@
       gnutls_transport_set_pull_function(session, pullFunc);
       gnutls_transport_set_push_function(session, pushFunc);
       gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)handle);
+      gnutls_session_set_ptr(session, (void*)self);
     }
 
   return self;
@@ -1824,54 +1938,26 @@
         break;
 
       case GNUTLS_CRD_CERTIFICATE:       /* certificate authentication */
-      {
-        unsigned int            cert_list_size = 0;
-        const gnutls_datum_t    *cert_list;
-        gnutls_x509_crt_t       cert;
-
-        /* Check if we have been using ephemeral Diffie-Hellman.
-         */
-        if (GNUTLS_KX_DHE_RSA == kx || GNUTLS_KX_DHE_DSS == kx)
-          {
-            dhe = 1;
-            ecdh = 0;
-          }
+      /* Check if we have been using ephemeral Diffie-Hellman.
+       */
+      if (GNUTLS_KX_DHE_RSA == kx || GNUTLS_KX_DHE_DSS == kx)
+        {
+          dhe = 1;
+          ecdh = 0;
+        }
 #if 0
-        if (GNUTLS_KX_ECDHE_RSA == kx || GNUTLS_KX_ECDHE_ECDSA == kx)
-          {
-            dhe = 0;
-            ecdh = 1;
-          }
+      if (GNUTLS_KX_ECDHE_RSA == kx || GNUTLS_KX_ECDHE_ECDSA == kx)
+        {
+          dhe = 0;
+          ecdh = 1;
+        }
 #endif
-        
-        /* if the certificate list is available, then
-         * print some information about it.
-         */
-        cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
-        if (cert_list_size > 0
-          && gnutls_certificate_type_get(session) == GNUTLS_CRT_X509)
-          {
-            int cert_num;
-        
-            for (cert_num = 0; cert_num < cert_list_size; cert_num++)
-              {
-                gnutls_x509_crt_init(&cert);
-                /* NB. the list of peer certificate is in memory in native
-                 * format (DER) rather than the normal file format (PEM).
-                 */
-                gnutls_x509_crt_import(cert,
-                  &cert_list[cert_num], GNUTLS_X509_FMT_DER);
-
-                [str appendString: @"\n"];
-                [str appendFormat: _(@"- Certificate %d info:\n"), cert_num];
-
-                [GSTLSCertificateList certInfo: cert to: str];
-
-                gnutls_x509_crt_deinit(cert);
-              }
-          }
-      }
-      break;
+        tmp = gnutls_certificate_type_get_name(
+          gnutls_certificate_type_get(session));
+        [str appendFormat: _(@"- Authentication using certificate type: %s\n"),
+          tmp];
+
+        break;
     }                           /* switch */
 
   if (ecdh != 0)
@@ -1889,16 +1975,52 @@
         gnutls_dh_get_prime_bits(session)];
     }
 
-  /* print the protocol's name (ie TLS 1.0) 
+  /* print the protocol's name (eg TLS 1.0) 
    */
   tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(session));
   [str appendFormat: _(@"- Protocol: %s\n"), tmp];
 
-  /* print the certificate type of the peer.
-   * ie X.509
+  /* print the certificates of the peer.
    */
-  tmp = gnutls_certificate_type_get_name(gnutls_certificate_type_get(session));
-  [str appendFormat: _(@"- Certificate Type: %s\n"), tmp];
+  if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509)
+    {
+      unsigned int            cert_list_size = 0;
+      const gnutls_datum_t    *cert_list;
+      gnutls_x509_crt_t       cert;
+
+      cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
+      if (0 == cert_list_size)
+        {
+          [str appendString: _(@"- Peer provided no certificate.\n")];
+        }
+      else
+        {
+          int cert_num;
+      
+          for (cert_num = 0; cert_num < cert_list_size; cert_num++)
+            {
+              gnutls_x509_crt_init(&cert);
+              /* NB. the list of peer certificate is in memory in native
+               * format (DER) rather than the normal file format (PEM).
+               */
+              gnutls_x509_crt_import(cert,
+                &cert_list[cert_num], GNUTLS_X509_FMT_DER);
+
+              [str appendString: @"\n"];
+              [str appendFormat: _(@"- Certificate %d info:\n"), cert_num];
+
+              [GSTLSCertificateList certInfo: cert to: str];
+
+              gnutls_x509_crt_deinit(cert);
+            }
+        }
+    }
+  else
+    {
+      tmp = gnutls_certificate_type_get_name(
+        gnutls_certificate_type_get(session));
+      [str appendFormat: _(@"- Certificate Type: %s\n"), tmp];
+    }
 
   /* print the compression algorithm (if any)
    */
@@ -1906,13 +2028,13 @@
   [str appendFormat: _(@"- Compression: %s\n"), tmp];
 
   /* print the name of the cipher used.
-   * ie 3DES.
+   * eg 3DES.
    */
   tmp = gnutls_cipher_get_name(gnutls_cipher_get(session));
   [str appendFormat: _(@"- Cipher: %s\n"), tmp];
 
   /* Print the MAC algorithms name.
-   * ie SHA1
+   * eg SHA1
    */
   tmp = gnutls_mac_get_name(gnutls_mac_get(session));
   [str appendFormat: _(@"- MAC: %s\n"), tmp];
@@ -1933,7 +2055,7 @@
   /* This verification function uses the trusted CAs in the credentials
    * structure. So you must have installed one or more CA certificates.
    */
-  ret = gnutls_certificate_verify_peers2 (session, &status);
+  ret = gnutls_certificate_verify_peers2(session, &status);
   if (ret < 0)
     {
       str = [NSString stringWithFormat:


_______________________________________________
Gnustep-cvs mailing list
Gnustep-cvs@gna.org
https://mail.gna.org/listinfo/gnustep-cvs

Reply via email to