]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added new interface.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 27 Jan 2013 17:17:35 +0000 (18:17 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 27 Jan 2013 17:18:57 +0000 (18:18 +0100)
14 files changed:
NEWS
lib/Makefile.am
lib/gnutls_cert.c
lib/gnutls_errors.c
lib/includes/Makefile.am
lib/includes/gnutls/gnutls.h.in
lib/includes/gnutls/xssl.h [moved from lib/includes/gnutls/sbuf.h with 57% similarity]
lib/libgnutls.map
lib/xssl.c [moved from lib/sbuf.c with 68% similarity]
lib/xssl.h [moved from lib/sbuf.h with 74% similarity]
lib/xssl_getline.c [moved from lib/sbuf_getline.c with 93% similarity]
tests/Makefile.am
tests/mini-sbuf.c [deleted file]
tests/mini-xssl.c [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 68c924e0cc841fbd70a3cc457767da29aea4f188..32ac683954a349e8991f2565a0ff4b21c61953da 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -37,13 +37,6 @@ extension. Whether length-hiding can be used on a given session can be checked u
 ** API and ABI modifications:
 gnutls_record_set_timeout: Added
 gnutls_record_get_random_padding_status: Added
-gnutls_sbuf_deinit: Added
-gnutls_sbuf_init: Added
-gnutls_sbuf_flush: Added
-gnutls_sbuf_write: Added
-gnutls_sbuf_getdelim: Added
-gnutls_sbuf_read: Added
-gnutls_sbuf_handshake: Added
 gnutls_x509_crt_set_dn: Added
 gnutls_x509_crt_set_issuer_dn: Added
 gnutls_x509_crq_set_dn: Added
@@ -55,6 +48,19 @@ gnutls_record_send_range: Added
 gnutls_record_set_max_empty_records: Added
 gnutls_record_can_use_length_hiding: Added
 gnutls_rnd_refresh: Added
+xssl_deinit: Added
+xssl_flush: Added
+xssl_read: Added
+xssl_getdelim: Added
+xssl_write: Added
+xssl_printf: Added
+xssl_sinit: Added
+xssl_client_init: Added
+xssl_server_init: Added
+xssl_get_session: Added
+xssl_get_verify_status: Added
+xssl_cred_init: Added
+xssl_cred_deinit: Added
 GNUTLS_SEC_PARAM_EXPORT: Added
 GNUTLS_SEC_PARAM_VERY_WEAK: Added
 
index 70d23f3a730953fd3c8453608d466f36712beb02..b313120442677f720708969f6ac8b5505212ff8d 100644 (file)
@@ -78,7 +78,7 @@ COBJECTS = gnutls_range.c gnutls_record.c \
        gnutls_rsa_export.c gnutls_helper.c gnutls_supplemental.c       \
        random.c crypto-api.c gnutls_privkey.c gnutls_pcert.c           \
        gnutls_pubkey.c locks.c gnutls_dtls.c system_override.c \
-       crypto-backend.c verify-tofu.c pin.c tpm.c sbuf.c sbuf_getline.c
+       crypto-backend.c verify-tofu.c pin.c tpm.c xssl.c xssl_getline.c
 
 if ENABLE_PKCS11
 COBJECTS += pkcs11.c pkcs11_privkey.c pkcs11_write.c pkcs11_secret.c
@@ -100,7 +100,7 @@ HFILES = abstract_int.h debug.h gnutls_compress.h gnutls_cipher.h   \
        gnutls_state.h gnutls_x509.h crypto-backend.h                   \
        gnutls_rsa_export.h gnutls_srp.h auth/srp.h auth/srp_passwd.h   \
        gnutls_helper.h gnutls_supplemental.h crypto.h random.h system.h\
-       locks.h gnutls_mbuffers.h gnutls_ecc.h pin.h
+       locks.h gnutls_mbuffers.h gnutls_ecc.h pin.h xssl.h
 
 if ENABLE_PKCS11
 HFILES += pkcs11_int.h
index c451ef5c59ce25e237b5b6663c0627a0113618cb..d43a5fb8ecff4cb76290d7eb7e91860fa1ddc4e2 100644 (file)
@@ -943,7 +943,10 @@ gnutls_certificate_verification_status_print (unsigned int status,
   if (type == GNUTLS_CRT_X509)
     {
       if (status & GNUTLS_CERT_REVOKED)
-        _gnutls_buffer_append_str (&str, _("The certificate chain revoked. "));
+        _gnutls_buffer_append_str (&str, _("The certificate chain is revoked. "));
+
+      if (status & GNUTLS_CERT_MISMATCH)
+        _gnutls_buffer_append_str (&str, _("The certificate doesn't match the local copy (TOFU). "));
 
       if (status & GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED)
          _gnutls_buffer_append_str (&str, _("The revocation data are old and have been superseded. "));
index 95c2b5ac2444d1051b8324bbcc1154f36db53d74..6bef39a47f62ba29cb5ef6caa5899fbe02e5db26 100644 (file)
@@ -154,6 +154,8 @@ static const gnutls_error_entry error_algorithms[] = {
                GNUTLS_E_RECORD_LIMIT_REACHED, 1),
   ERROR_ENTRY (N_("Error in the certificate."), GNUTLS_E_CERTIFICATE_ERROR,
                1),
+  ERROR_ENTRY (N_("Could not authenticate peer."), GNUTLS_E_AUTH_ERROR,
+               1),
   ERROR_ENTRY (N_("Unknown Subject Alternative name in X.509 certificate."),
                GNUTLS_E_X509_UNKNOWN_SAN, 1),
 
index bd48c0cc445f1e3217b51ced895af3998bdcf9e4..2fb86094c6ead6aa93cefb6f2d54874694275664 100644 (file)
@@ -21,7 +21,7 @@
 nobase_include_HEADERS = gnutls/x509.h gnutls/pkcs12.h gnutls/compat.h \
        gnutls/openpgp.h gnutls/crypto.h gnutls/pkcs11.h                \
        gnutls/abstract.h gnutls/dtls.h gnutls/ocsp.h gnutls/tpm.h      \
-       gnutls/sbuf.h
+       gnutls/xssl.h
 
 if ENABLE_CXX
 nobase_include_HEADERS += gnutls/gnutlsxx.h
index f09046687eb3bbd8c32b24c134191ee430252d1f..38182880e18facd0386285786884d3803ea0ebaa 100644 (file)
@@ -450,6 +450,7 @@ extern "C"
  * @GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED: The revocation data are old and have been superseded.
  * @GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE: The revocation data have a future issue date.
  * @GNUTLS_CERT_UNEXPECTED_OWNER: The owner is not the expected one.
+ * @GNUTLS_CERT_MISMATCH: The certificate presented isn't the expected one (TOFU)
  *
  * Enumeration of certificate status codes.  Note that the status
  * bits may have different meanings in OpenPGP keys and X.509
@@ -469,6 +470,7 @@ extern "C"
     GNUTLS_CERT_UNEXPECTED_OWNER = 1<<14,
     GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE = 1<<15,
     GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE = 1<<16,
+    GNUTLS_CERT_MISMATCH = 1<<17,
   } gnutls_certificate_status_t;
 
 /**
@@ -2149,6 +2151,7 @@ typedef int (*gnutls_pin_callback_t) (void *userdata, int attempt,
 #define GNUTLS_E_NO_CERTIFICATE_STATUS -340
 #define GNUTLS_E_OCSP_RESPONSE_ERROR -341
 #define GNUTLS_E_RANDOM_DEVICE_ERROR -342
+#define GNUTLS_E_AUTH_ERROR -343
 
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
 
similarity index 57%
rename from lib/includes/gnutls/sbuf.h
rename to lib/includes/gnutls/xssl.h
index a629949aa659cb837ceb640e4aa89efb00354f03..a71bec190189636755903da98dd7bc3754c385e2 100644 (file)
 #include <gnutls/gnutls.h>
 
 /* Buffered session I/O */
-typedef struct gnutls_sbuf_st *gnutls_sbuf_t;
-typedef struct gnutls_credentials_st *gnutls_credentials_t;
+typedef struct xssl_st *xssl_t;
+typedef struct xssl_cred_st *xssl_cred_t;
 
-ssize_t gnutls_sbuf_printf (gnutls_sbuf_t sb, const char *fmt, ...)
+ssize_t xssl_printf (xssl_t sb, const char *fmt, ...)
 #ifdef __GNUC__
    __attribute__ ((format (printf, 2, 3)))
 #endif
 ;
 
-ssize_t gnutls_sbuf_write (gnutls_sbuf_t sb, const void *data,
+ssize_t xssl_write (xssl_t sb, const void *data,
                            size_t data_size);
 
-ssize_t gnutls_sbuf_flush (gnutls_sbuf_t sb);
+ssize_t xssl_flush (xssl_t sb);
 
-int gnutls_sbuf_handshake(gnutls_sbuf_t sb);
-ssize_t gnutls_sbuf_read(gnutls_sbuf_t sb, void* data, size_t data_size);
+ssize_t xssl_read(xssl_t sb, void* data, size_t data_size);
 
 ssize_t
-gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimiter);
+xssl_getdelim (xssl_t sbuf, char **lineptr, size_t *n, int delimiter);
 
-#define gnutls_sbuf_getline(sbuf, ptr, n) gnutls_sbuf_getdelim(sbuf, ptr, n, '\n')
+#define xssl_getline(sbuf, ptr, n) xssl_getdelim(sbuf, ptr, n, '\n')
 
-void gnutls_sbuf_deinit(gnutls_sbuf_t sb);
+void xssl_deinit(xssl_t sb);
 
-#define GNUTLS_SBUF_WRITE_FLUSHES 1
-int gnutls_sbuf_sinit (gnutls_sbuf_t * isb, gnutls_session_t session,
+#define GNUTLS_SBUF_WRITE_FLUSHES (1<<0)
+int xssl_sinit (xssl_t * isb, gnutls_session_t session,
                        unsigned int flags);
 
-gnutls_session_t gnutls_sbuf_get_session(gnutls_sbuf_t sb);
+gnutls_session_t xssl_get_session(xssl_t sb);
 
-int gnutls_sbuf_client_init (gnutls_sbuf_t * isb, const char* hostname, 
+int xssl_client_init (xssl_t * isb, const char* hostname, 
                              const char* service,
                              gnutls_transport_ptr fd, 
-                             const char* priority, gnutls_credentials_t cred,
+                             const char* priority, xssl_cred_t cred,
+                             unsigned int *status,
                              unsigned int flags);
 
-int gnutls_sbuf_server_init (gnutls_sbuf_t * isb, 
+int xssl_server_init (xssl_t * isb, 
                              gnutls_transport_ptr fd, 
-                             const char* priority, gnutls_credentials_t cred,
+                             const char* priority, xssl_cred_t cred,
+                             unsigned int *status,
                              unsigned int flags);
 
 /* High level credential structures */
@@ -76,8 +77,9 @@ typedef enum
 
 typedef enum
 {
-  GNUTLS_CRED_FILE = 0,
-  GNUTLS_CRED_MEM = 1,
+  GNUTLS_CINPUT_TYPE_FILE = 0,
+  GNUTLS_CINPUT_TYPE_MEM = 1,
+  GNUTLS_CINPUT_TYPE_PIN_FUNC = 2,
 } gnutls_cinput_type_t;
 
 typedef enum
@@ -85,24 +87,33 @@ typedef enum
   GNUTLS_CINPUT_CAS = 1,
   GNUTLS_CINPUT_CRLS = 2,
   GNUTLS_CINPUT_TOFU_DB = 3,
+  GNUTLS_CINPUT_KEYPAIR = 4,
 } gnutls_cinput_contents_t;
 
 typedef struct gnutls_cinput_st {
   gnutls_cinput_type_t type;
-  gnutls_x509_crt_fmt_t fmt; /* if applicable */
   gnutls_cinput_contents_t contents;
+  gnutls_x509_crt_fmt_t fmt; /* if applicable */
+
   union {
+    gnutls_pin_callback_t pin_fn;
     const char* file;
     gnutls_datum_t mem;
-  } i;
-} gnutls_cinput_st;
+  } i1;
 
-int gnutls_credentials_init (gnutls_credentials_t* cred);
-void gnutls_credentials_deinit (gnutls_credentials_t cred);
+  union {
+    void* udata;
+    const char* file;
+    gnutls_datum_t mem;
+  } i2;
+  
+  unsigned long future_pad[8];
+} gnutls_cinput_st;
 
-int gnutls_credentials_set_trust (gnutls_credentials_t cred, unsigned vflags, 
-                                  gnutls_cinput_st* aux,
-                                  unsigned aux_size);
+int xssl_cred_init (xssl_cred_t *c, unsigned vflags, 
+                             gnutls_cinput_st* aux,
+                             unsigned aux_size);
+void xssl_cred_deinit (xssl_cred_t cred);
 
 
 #endif /* GNUTLS_SBUF_H */
index 8eca27684ff97e1a4a2b4a0766429725382e9db3..d44d76d79d00c04d100143c301402df386045582 100644 (file)
@@ -885,18 +885,19 @@ GNUTLS_3_1_0 {
        gnutls_record_set_max_empty_records;
        gnutls_range_split;
        gnutls_record_send_range;
-       gnutls_sbuf_deinit;
-       gnutls_sbuf_flush;
-       gnutls_sbuf_read;
-       gnutls_sbuf_getdelim;
-       gnutls_sbuf_write;
-       gnutls_sbuf_printf;
-       gnutls_sbuf_sinit;
-       gnutls_sbuf_client_init;
-       gnutls_sbuf_get_session;
-       gnutls_credentials_init;
-       gnutls_credentials_deinit;
-       gnutls_credentials_set_trust;
+       xssl_deinit;
+       xssl_flush;
+       xssl_read;
+       xssl_getdelim;
+       xssl_write;
+       xssl_printf;
+       xssl_sinit;
+       xssl_client_init;
+       xssl_server_init;
+       xssl_get_session;
+       xssl_get_verify_status;
+       xssl_cred_init;
+       xssl_cred_deinit;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
similarity index 68%
rename from lib/sbuf.c
rename to lib/xssl.c
index 3b9efa4d1dfa8cce4d0caac45d23f1de637568de..61555591d8dfbc071b5b1f2623d3973624dc5594 100644 (file)
 #include <gnutls_int.h>
 #include <gnutls_errors.h>
 #include <gnutls_num.h>
-#include <gnutls/sbuf.h>
+#include <gnutls/xssl.h>
+#include <auth/cert.h>
 
-#include <sbuf.h>
+#include <xssl.h>
 
 /**
- * gnutls_sbuf_sinit:
- * @isb: is a pointer to a #gnutls_sbuf_t structure.
- * @session: a GnuTLS session
- * @flags: should be zero or %GNUTLS_SBUF_WRITE_FLUSHES
- *
- * This function initializes a #gnutls_sbuf_t structure associated
- * with the provided session. If the flag %GNUTLS_SBUF_WRITE_FLUSHES
- * is set then gnutls_sbuf_queue() will flush when the maximum
- * data size for a record is reached.
- *
- * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
- *
- * Since: 3.1.7
- **/
-int gnutls_sbuf_sinit (gnutls_sbuf_t * isb, gnutls_session_t session,
-                       unsigned int flags)
-{
-struct gnutls_sbuf_st* sb;
-
-  sb = gnutls_malloc(sizeof(*sb));
-  if (sb == NULL)
-    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-
-  _gnutls_buffer_init(&sb->buf);
-  sb->session = session;
-  sb->flags = flags;
-  
-  *isb = sb;
-  
-  return 0;
-}
-
-
-/**
- * gnutls_credentials_deinit:
- * @cred: is a #gnutls_credentials_t structure.
+ * xssl_cred_deinit:
+ * @cred: is a #xssl_cred_t structure.
  *
- * This function deinitializes a #gnutls_credentials_t structure.
+ * This function deinitializes a #xssl_cred_t structure.
  *
  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
  *
  * Since: 3.1.7
  **/
-void gnutls_credentials_deinit (gnutls_credentials_t cred)
+void xssl_cred_deinit (xssl_cred_t cred)
 {
   if (cred->xcred)
     gnutls_certificate_free_credentials(cred->xcred);
   gnutls_free(cred);
 }
 
-/**
- * gnutls_credentials_init:
- * @cred: is a pointer to a #gnutls_credentials_t structure.
- *
- * This function initializes a #gnutls_credentials_t structure.
- *
- * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
- *
- * Since: 3.1.7
- **/
-int gnutls_credentials_init (gnutls_credentials_t* cred)
-{
-  *cred = gnutls_calloc(1, sizeof(*cred));
-  if (*cred == NULL)
-    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
-  
-  return 0;
-}
 
 static int
 _verify_certificate_callback (gnutls_session_t session)
 {
   unsigned int status;
-  gnutls_sbuf_t sb;
+  xssl_t sb;
   int ret, type;
   const char *hostname = NULL;
   const char *service = NULL;
   const char *tofu_file = NULL;
-  
+
   sb = gnutls_session_get_ptr(session);
   if (sb == NULL)
     return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
 
+  if (sb->cred == NULL)
+    return gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+
   if (sb->server_name[0] != 0)
     hostname = sb->server_name;
 
@@ -123,17 +75,20 @@ _verify_certificate_callback (gnutls_session_t session)
   /* This verification function uses the trusted CAs in the credentials
    * structure. So you must have installed one or more CA certificates.
    */
+  sb->vstatus = 0;
   if (sb->cred->vflags & GNUTLS_VMETHOD_SYSTEM_CAS || sb->cred->vflags & GNUTLS_VMETHOD_GIVEN_CAS)
     {
       ret = gnutls_certificate_verify_peers3 (session, hostname, &status);
       if (ret < 0)
-        return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
+        return gnutls_assert_val(GNUTLS_E_AUTH_ERROR);
+      
+      sb->vstatus = status;
 
       if (status != 0) /* Certificate is not trusted */
-        return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
+        return gnutls_assert_val(GNUTLS_E_AUTH_ERROR);
     }
 
-  if (sb->cred->vflags & GNUTLS_VMETHOD_TOFU)
+  if (hostname && sb->cred->vflags & GNUTLS_VMETHOD_TOFU)
     {
       const gnutls_datum_t *cert_list;
       unsigned int cert_list_size;
@@ -143,7 +98,10 @@ _verify_certificate_callback (gnutls_session_t session)
       /* Do SSH verification */
       cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
       if (cert_list == NULL)
-        return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
+        { 
+          sb->vstatus |= GNUTLS_CERT_INVALID;
+          return gnutls_assert_val(GNUTLS_E_AUTH_ERROR);
+        }
 
       /* service may be obtained alternatively using getservbyport() */
       ret = gnutls_verify_stored_pubkey(tofu_file, NULL, hostname, service, 
@@ -155,9 +113,15 @@ _verify_certificate_callback (gnutls_session_t session)
                               type, &cert_list[0], 0, 0);
         }
       else if (ret == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
-        return gnutls_assert_val(GNUTLS_E_CERTIFICATE_ERROR);
+        {
+          sb->vstatus |= GNUTLS_CERT_MISMATCH;
+          return gnutls_assert_val(GNUTLS_E_AUTH_ERROR);
+        }
       else if (ret < 0)
-        return gnutls_assert_val(ret);
+        {
+          sb->vstatus |= GNUTLS_CERT_INVALID;
+          return gnutls_assert_val(GNUTLS_E_AUTH_ERROR);
+        }
     }
   
   /* notify gnutls to continue handshake normally */
@@ -165,14 +129,14 @@ _verify_certificate_callback (gnutls_session_t session)
 }
 
 /**
- * gnutls_credentials_set_trust:
- * @cred: is a #gnutls_credentials_t structure.
+ * xssl_cred_init:
+ * @c: is a pointer to #xssl_cred_t structure.
  * @vflags: the requested peer verification methods
  * @aux: Auxilary data to input any required CA certificate etc.
  * @aux_size: the number of the auxillary data provided
  *
  * This function initializes X.509 certificates in 
- * a #gnutls_credentials_t structure.
+ * a #xssl_cred_t structure.
  *
  * The @ca_file and @crl_file are required only if @vflags includes
  * %GNUTLS_VMETHOD_GIVEN_CAS. The @tofu_file may be set if 
@@ -182,12 +146,20 @@ _verify_certificate_callback (gnutls_session_t session)
  *
  * Since: 3.1.7
  **/
-int gnutls_credentials_set_trust (gnutls_credentials_t cred, unsigned vflags, 
-                                  gnutls_cinput_st* aux,
-                                  unsigned aux_size)
+int xssl_cred_init (xssl_cred_t *c, unsigned vflags, 
+                             gnutls_cinput_st* aux,
+                             unsigned aux_size)
 {
 int ret;
 unsigned len, i;
+xssl_cred_t cred;
+
+  *c = gnutls_calloc(1, sizeof(*cred));
+  if (*c == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+  cred = *c;
+  cred->vflags = vflags;
 
   if (cred->xcred == NULL)
     {
@@ -206,47 +178,75 @@ unsigned len, i;
         }
     }
 
-  if (vflags & GNUTLS_VMETHOD_GIVEN_CAS)
+  for (i=0;i<aux_size;i++)
     {
-      for (i=0;i<aux_size;i++)
+      if (aux[i].contents == GNUTLS_CINPUT_KEYPAIR)
         {
-          if (aux[i].contents == GNUTLS_CINPUT_CAS && aux[i].type == GNUTLS_CRED_FILE)
-            ret = gnutls_certificate_set_x509_trust_file(cred->xcred, aux[i].i.file, aux[i].fmt);
-          else if (aux[i].contents == GNUTLS_CINPUT_CAS && aux[i].type == GNUTLS_CRED_MEM)
-            ret = gnutls_certificate_set_x509_trust_mem(cred->xcred, &aux[i].i.mem, aux[i].fmt);
-          else if (aux[i].contents == GNUTLS_CINPUT_CRLS && aux[i].type == GNUTLS_CRED_FILE)
-            ret = gnutls_certificate_set_x509_crl_file(cred->xcred, aux[i].i.file, aux[i].fmt);
-          else if (aux[i].contents == GNUTLS_CINPUT_CRLS && aux[i].type == GNUTLS_CRED_MEM)
-            ret = gnutls_certificate_set_x509_crl_mem(cred->xcred, &aux[i].i.mem, aux[i].fmt);
-          else
-            ret = 0;
+          if (aux[i].type == GNUTLS_CINPUT_TYPE_FILE)
+            ret = gnutls_certificate_set_x509_key_file(cred->xcred, aux[i].i1.file, aux[i].i2.file, aux[i].fmt);
+          else if (aux[i].type == GNUTLS_CINPUT_TYPE_MEM)
+            ret = gnutls_certificate_set_x509_key_mem(cred->xcred, &aux[i].i1.mem, &aux[i].i2.mem, aux[i].fmt);
+          else if (aux[i].type == GNUTLS_CINPUT_TYPE_PIN_FUNC)
+            {
+              ret = 0;
+              gnutls_certificate_set_pin_function(cred->xcred, aux[i].i1.pin_fn,
+                                                  aux[i].i2.udata);
+            }
+
           if (ret < 0)
             {
               gnutls_assert();
               goto fail1;
             }
         }
-    }
+        
+      if (aux[i].contents == GNUTLS_CINPUT_CAS && (vflags & GNUTLS_VMETHOD_GIVEN_CAS))
+        {
+          if (aux[i].type == GNUTLS_CINPUT_TYPE_FILE)
+            ret = gnutls_certificate_set_x509_trust_file(cred->xcred, aux[i].i1.file, aux[i].fmt);
+          else       
+            ret = gnutls_certificate_set_x509_trust_mem(cred->xcred, &aux[i].i1.mem, aux[i].fmt);
 
-  if (vflags & GNUTLS_VMETHOD_TOFU)
-    {
-      for (i=0;i<aux_size;i++)
+          if (ret < 0)
+            {
+              gnutls_assert();
+              goto fail1;
+            }
+        } 
+
+      if (aux[i].contents == GNUTLS_CINPUT_CRLS && (vflags & GNUTLS_VMETHOD_GIVEN_CAS))
         {
-          if (aux[i].contents == GNUTLS_CINPUT_TOFU_DB)
+          if (aux[i].type == GNUTLS_CINPUT_TYPE_FILE)
+            ret = gnutls_certificate_set_x509_crl_file(cred->xcred, aux[i].i1.file, aux[i].fmt);
+          else       
+            ret = gnutls_certificate_set_x509_crl_mem(cred->xcred, &aux[i].i1.mem, aux[i].fmt);
+
+          if (ret < 0)
             {
-              if (aux[i].type != GNUTLS_CRED_FILE)
-                {
-                  ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-                  goto fail1;
-                }
-              len = strlen(aux[i].i.file);
-      
+              gnutls_assert();
+              goto fail1;
+            }
+        }
+
+      if (aux[i].contents == GNUTLS_CINPUT_TOFU_DB && (vflags & GNUTLS_VMETHOD_TOFU))
+        {
+          if (aux[i].type == GNUTLS_CINPUT_TYPE_FILE)
+            {
+              len = strlen(aux[i].i1.file);
               if (len >= sizeof(cred->tofu_file))
                 {
                   ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
                   goto fail1;
                 }
-              memcpy(cred->tofu_file, aux[i].i.file, len+1);
+              memcpy(cred->tofu_file, aux[i].i1.file, len+1);
+            }
+          else
+            ret = GNUTLS_E_INVALID_REQUEST;
+
+          if (ret < 0)
+            {
+              gnutls_assert();
+              goto fail1;
             }
         }
     }
@@ -257,36 +257,74 @@ unsigned len, i;
 fail1:
   gnutls_certificate_free_credentials(cred->xcred);
   cred->xcred = NULL;
+  gnutls_free(*c);
+
   return ret;
 }
 
+/**
+ * xssl_sinit:
+ * @isb: is a pointer to a #xssl_t structure.
+ * @session: a GnuTLS session
+ * @flags: should be zero or %GNUTLS_SBUF_WRITE_FLUSHES
+ *
+ * This function initializes a #xssl_t structure associated
+ * with the provided session. If the flag %GNUTLS_SBUF_WRITE_FLUSHES
+ * is set then xssl_queue() will flush when the maximum
+ * data size for a record is reached.
+ *
+ * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
+ *
+ * Since: 3.1.7
+ **/
+int xssl_sinit (xssl_t * isb, gnutls_session_t session,
+                       unsigned int flags)
+{
+struct xssl_st* sb;
+
+  sb = gnutls_calloc(1, sizeof(*sb));
+  if (sb == NULL)
+    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+
+  _gnutls_buffer_init(&sb->buf);
+  sb->session = session;
+  sb->flags = flags;
+  
+  *isb = sb;
+  
+  return 0;
+}
 
 /**
- * gnutls_sbuf_client_init:
- * @isb: is a pointer to a #gnutls_sbuf_t structure.
+ * xssl_client_init:
+ * @isb: is a pointer to a #xssl_t structure.
  * @hostname: The name of the host to connect to
  * @service: The name of the host to connect to
  * @fd: a socket descriptor
  * @priority: A priority string to use (use %NULL for default)
  * @cred: A credentials structure
+ * @status: An authentication failure status
  * @flags: should be zero or %GNUTLS_SBUF_WRITE_FLUSHES
  *
- * This function initializes a #gnutls_sbuf_t structure.
+ * This function initializes a #xssl_t structure.
  * If the flag %GNUTLS_SBUF_WRITE_FLUSHES
- * is set then gnutls_sbuf_queue() will flush when the maximum
+ * is set then xssl_queue() will flush when the maximum
  * data size for a record is reached.
  *
+ * If peer verification fails then %GNUTLS_E_AUTH_ERROR is returned.
+ *
  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
  *
  * Since: 3.1.7
  **/
-int gnutls_sbuf_client_init (gnutls_sbuf_t * isb, const char* hostname, 
+int xssl_client_init (xssl_t * isb, const char* hostname, 
                              const char* service,
                              gnutls_transport_ptr fd, 
-                             const char* priority, gnutls_credentials_t cred,
+                             const char* priority, xssl_cred_t cred,
+                             unsigned int *status,
                              unsigned int flags)
 {
-struct gnutls_sbuf_st* sb;
+struct xssl_st* sb;
 gnutls_session_t session;
 int ret;
 unsigned len;
@@ -298,12 +336,14 @@ unsigned len;
   sb = gnutls_calloc(1, sizeof(*sb));
   if (sb == NULL)
     {
+      gnutls_deinit(session);
       ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
       goto fail1;
     }
   _gnutls_buffer_init(&sb->buf);
   sb->session = session;
   sb->flags = flags;
+  sb->cred = cred;
   
   /* set session/handshake info 
    */
@@ -354,15 +394,25 @@ unsigned len;
 
   gnutls_transport_set_ptr (session, fd);
   gnutls_session_set_ptr( session, sb);
-  
+
   do
     {
       ret = gnutls_handshake(session);
     }
   while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
+  if (status) *status = sb->vstatus;
 
   if (ret < 0)
     {
+      int ret2;
+      do
+        {
+          ret2 = gnutls_alert_send_appropriate(sb->session, ret);
+        }
+      while (ret2 < 0 && gnutls_error_is_fatal(ret2) == 0);
+
+      return gnutls_assert_val(ret);
+
       gnutls_assert();
       goto fail1;
     }
@@ -373,35 +423,36 @@ unsigned len;
 
 fail1:
   if (sb)
-    gnutls_sbuf_deinit(sb);
-  gnutls_deinit(session);
+    xssl_deinit(sb);
   
   return ret;
 }
 
 /**
- * gnutls_sbuf_server_init:
- * @isb: is a pointer to a #gnutls_sbuf_t structure.
+ * xssl_server_init:
+ * @isb: is a pointer to a #xssl_t structure.
  * @fd: a socket descriptor
  * @priority: A priority string to use (use %NULL for default)
  * @cred: A credentials structure
+ * @status: An authentication failure status
  * @flags: should be zero or %GNUTLS_SBUF_WRITE_FLUSHES
  *
- * This function initializes a #gnutls_sbuf_t structure.
+ * This function initializes a #xssl_t structure.
  * If the flag %GNUTLS_SBUF_WRITE_FLUSHES
- * is set then gnutls_sbuf_queue() will flush when the maximum
+ * is set then xssl_queue() will flush when the maximum
  * data size for a record is reached.
  *
  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
  *
  * Since: 3.1.7
  **/
-int gnutls_sbuf_server_init (gnutls_sbuf_t * isb,
+int xssl_server_init (xssl_t * isb,
                              gnutls_transport_ptr fd, 
-                             const char* priority, gnutls_credentials_t cred,
+                             const char* priority, xssl_cred_t cred,
+                             unsigned int *status,
                              unsigned int flags)
 {
-struct gnutls_sbuf_st* sb;
+struct xssl_st* sb;
 gnutls_session_t session;
 int ret;
 
@@ -412,12 +463,14 @@ int ret;
   sb = gnutls_calloc(1, sizeof(*sb));
   if (sb == NULL)
     {
+      gnutls_deinit(session);
       ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
       goto fail1;
     }
   _gnutls_buffer_init(&sb->buf);
   sb->session = session;
   sb->flags = flags;
+  sb->cred = cred;
   
   /* set session/handshake info 
    */
@@ -433,15 +486,25 @@ int ret;
   
   if (cred->xcred)
     {
+      if (cred->xcred->ncerts == 0 && cred->xcred->get_cert_callback2 == NULL)
+        {
+          ret = gnutls_assert_val(GNUTLS_E_INSUFFICIENT_CREDENTIALS);
+          goto fail1;
+        }
+      
       ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred->xcred);
       if (ret < 0)
         {
           gnutls_assert();
           goto fail1;
         }
+      
     }
 
-  gnutls_transport_set_ptr (session, fd);
+  if (cred->vflags & GNUTLS_VMETHOD_GIVEN_CAS)
+    gnutls_certificate_server_set_request( session, GNUTLS_CERT_REQUIRE);
+
+  gnutls_transport_set_ptr( session, fd);
   gnutls_session_set_ptr( session, sb);
 
   do
@@ -449,9 +512,19 @@ int ret;
       ret = gnutls_handshake(session);
     }
   while (ret < 0 && gnutls_error_is_fatal (ret) == 0);
+  if (status) *status = sb->vstatus;
 
   if (ret < 0)
     {
+      int ret2;
+      do
+        {
+          ret2 = gnutls_alert_send_appropriate(sb->session, ret);
+        }
+      while (ret2 < 0 && gnutls_error_is_fatal(ret2) == 0);
+
+      return gnutls_assert_val(ret);
+
       gnutls_assert();
       goto fail1;
     }
@@ -462,15 +535,14 @@ int ret;
 
 fail1:
   if (sb)
-    gnutls_sbuf_deinit(sb);
-  gnutls_deinit(session);
+    xssl_deinit(sb);
   
   return ret;
 }
 
 /**
- * gnutls_sbuf_deinit:
- * @sb: is a #gnutls_sbuf_t structure.
+ * xssl_deinit:
+ * @sb: is a #xssl_t structure.
  *
  * This function clears all buffers associated with the @sb
  * structure. The GnuTLS session associated with the structure
@@ -478,7 +550,7 @@ fail1:
  *
  * Since: 3.1.7
  **/
-void gnutls_sbuf_deinit(gnutls_sbuf_t sb)
+void xssl_deinit(xssl_t sb)
 {
   if (sb->session)
     {
@@ -490,14 +562,14 @@ void gnutls_sbuf_deinit(gnutls_sbuf_t sb)
 }
 
 /**
- * gnutls_sbuf_write:
- * @sb: is a #gnutls_sbuf_t structure.
+ * xssl_write:
+ * @sb: is a #xssl_t structure.
  * @data: contains the data to send
  * @data_size: is the length of the data
  *
  * This function is the buffered equivalent of gnutls_record_send().
  * Instead of sending the data immediately the data are buffered
- * until gnutls_sbuf_queue() is called, or if the flag %GNUTLS_SBUF_WRITE_FLUSHES
+ * until xssl_queue() is called, or if the flag %GNUTLS_SBUF_WRITE_FLUSHES
  * is set, until the number of bytes for a full record is reached.
  *
  * This function must only be used with blocking sockets.
@@ -507,7 +579,7 @@ void gnutls_sbuf_deinit(gnutls_sbuf_t sb)
  *
  * Since: 3.1.7
  **/
-ssize_t gnutls_sbuf_write (gnutls_sbuf_t sb, const void *data,
+ssize_t xssl_write (xssl_t sb, const void *data,
                            size_t data_size)
 {
 int ret;
@@ -535,11 +607,11 @@ int ret;
 }
 
 /**
- * gnutls_sbuf_printf:
- * @sb: is a #gnutls_sbuf_t structure.
+ * xssl_printf:
+ * @sb: is a #xssl_t structure.
  * @fmt: printf-style format 
  *
- * This function allows writing to a %gnutls_sbuf_t using printf
+ * This function allows writing to a %xssl_t using printf
  * style arguments.
  *
  * This function must only be used with blocking sockets.
@@ -549,7 +621,7 @@ int ret;
  *
  * Since: 3.1.7
  **/
-ssize_t gnutls_sbuf_printf (gnutls_sbuf_t sb, const char *fmt, ...)
+ssize_t xssl_printf (xssl_t sb, const char *fmt, ...)
 {
 int ret;
 va_list args;
@@ -563,7 +635,7 @@ char* str;
   if (len < 0 || !str)
     return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
   
-  ret = gnutls_sbuf_write (sb, str, len);
+  ret = xssl_write (sb, str, len);
   
   gnutls_free(str);
 
@@ -571,8 +643,8 @@ char* str;
 }
 
 /**
- * gnutls_sbuf_flush:
- * @sb: is a #gnutls_sbuf_t structure.
+ * xssl_flush:
+ * @sb: is a #xssl_t structure.
  *
  * This function flushes the buffer @sb. All the data stored are transmitted.
  *
@@ -582,7 +654,7 @@ char* str;
  *
  * Since: 3.1.7
  **/
-ssize_t gnutls_sbuf_flush (gnutls_sbuf_t sb)
+ssize_t xssl_flush (xssl_t sb)
 {
 int ret;
 ssize_t total = 0;
@@ -606,42 +678,8 @@ ssize_t total = 0;
 }
 
 /**
- * gnutls_sbuf_handshake:
- * @sb: is a #gnutls_sbuf_t structure.
- *
- * This function performs a handshake on the underlying session.
- * Only fatal errors are returned by this function.
- *
- * Returns: On success, zero is returned, otherwise a negative error code.
- *
- * Since: 3.1.7
- **/
-int gnutls_sbuf_handshake(gnutls_sbuf_t sb)
-{
-int ret, ret2;
-
-  do
-    {
-      ret = gnutls_handshake(sb->session);
-    }
-  while (ret < 0 && gnutls_error_is_fatal(ret) == 0);
-  if (ret < 0)
-    {
-      do
-        {
-          ret2 = gnutls_alert_send_appropriate(sb->session, ret);
-        }
-      while (ret2 < 0 && gnutls_error_is_fatal(ret2) == 0);
-
-      return gnutls_assert_val(ret);
-    }
-    
-  return 0;
-}
-
-/**
- * gnutls_sbuf_read:
- * @sb: is a #gnutls_sbuf_t structure.
+ * xssl_read:
+ * @sb: is a #xssl_t structure.
  * @data: the buffer that the data will be read into
  * @data_size: the number of requested bytes
  *
@@ -653,7 +691,7 @@ int ret, ret2;
  *
  * Since: 3.1.7
  **/
-ssize_t gnutls_sbuf_read(gnutls_sbuf_t sb, void* data, size_t data_size)
+ssize_t xssl_read(xssl_t sb, void* data, size_t data_size)
 {
 int ret;
 
@@ -670,14 +708,14 @@ int ret;
 }
 
 /**
- * gnutls_sbuf_get_session:
- * @sb: is a #gnutls_sbuf_t structure.
+ * xssl_get_session:
+ * @sb: is a #xssl_t structure.
  *
  * Returns: The associated session or %NULL.
  *
  * Since: 3.1.7
  **/
-gnutls_session_t gnutls_sbuf_get_session(gnutls_sbuf_t sb)
+gnutls_session_t xssl_get_session(xssl_t sb)
 {
   return sb->session;
 }
similarity index 74%
rename from lib/sbuf.h
rename to lib/xssl.h
index 44ea713604d407997c54ddf2690176c2557c988e..416c36992f71caed8285feba0553a2f25b833e15 100644 (file)
@@ -4,21 +4,22 @@
 #include <gnutls_str.h>
 #include <gnutls/gnutls.h>
 
-struct gnutls_credentials_st {
+struct xssl_cred_st {
   gnutls_certificate_credentials_t xcred;
   char tofu_file[MAX_FILENAME];
   unsigned vflags;
 };
 
-struct gnutls_sbuf_st {
+struct xssl_st {
   gnutls_session_t session;
   gnutls_buffer_st buf;
 
   char server_name[MAX_SERVER_NAME_SIZE];
   char service_name[MAX_SERVER_NAME_SIZE];
 
-  gnutls_credentials_t cred;
+  xssl_cred_t cred;
 
+  unsigned int vstatus; /* the verification status reason */
   unsigned int flags;
 };
 
similarity index 93%
rename from lib/sbuf_getline.c
rename to lib/xssl_getline.c
index 932d9dc96b1315fc34973551f3cf1600e7e93fd1..4f571b8bef21794757b648de726babdb1ddedf10 100644 (file)
 
 #include <gnutls_int.h>
 #include <gnutls_errors.h>
-#include <gnutls/sbuf.h>
-#include <sbuf.h>
+#include <gnutls/xssl.h>
+#include <xssl.h>
 
 #ifndef SSIZE_MAX
 # define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
 #endif
 
 /**
- * gnutls_sbuf_get_delim:
- * @sb: is a #gnutls_sbuf_t structure.
+ * xssl_get_delim:
+ * @sb: is a #xssl_t structure.
  * @lineptr: a pointer.
  * @n: The size of @lineptr.
  * @delimiter: The delimiter to stop reading at.
@@ -49,7 +49,7 @@
  * Since: 3.1.7
  **/
 ssize_t
-gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimiter)
+xssl_getdelim (xssl_t sbuf, char **lineptr, size_t *n, int delimiter)
 {
   ssize_t result;
   size_t cur_len = 0;
@@ -76,7 +76,7 @@ gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimit
     {
       char c;
       
-      result = gnutls_sbuf_read(sbuf, &c, 1);
+      result = xssl_read(sbuf, &c, 1);
       if (result < 0)
         {
           gnutls_assert();
index 26f7ab2a60b5a5ee556743132858b787e3cf46f3..62f757ed6f12f56ca080a4f672bc41a69dd1a56b 100644 (file)
@@ -71,7 +71,7 @@ ctests = mini-deflate simple gc set_pkcs12_cred certder certuniqueid  \
         mini-termination mini-x509-cas mini-x509-2 pkcs12_simple \
         mini-emsgsize-dtls mini-handshake-timeout chainverify-unsorted \
         mini-dtls-heartbeat mini-x509-callbacks key-openssl            \
-        mini-dtls-srtp mini-dtls-record mini-sbuf
+        mini-dtls-srtp mini-dtls-record mini-xssl
 
 if ENABLE_OCSP
 ctests += ocsp
diff --git a/tests/mini-sbuf.c b/tests/mini-sbuf.c
deleted file mode 100644 (file)
index b4b6b13..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2008-2012 Free Software Foundation, Inc.
- *
- * Author: Simon Josefsson
- *
- * This file is part of GnuTLS.
- *
- * GnuTLS is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * GnuTLS 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
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GnuTLS; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/crypto.h>
-#include <gnutls/sbuf.h>
-#include "eagain-common.h"
-
-#include "utils.h"
-
-const char* side = "";
-
-static void
-tls_log_func (int level, const char *str)
-{
-  fprintf (stderr, "%s|<%d>| %s", side, level, str);
-}
-
-#define MAX_BUF 60*1024
-
-static unsigned char server_buf[MAX_BUF];
-static unsigned char client_buf[MAX_BUF];
-
-#define LINE1 "hello there people\n"
-#define LINE2 "how are you doing today, all well?\n"
-
-void
-doit (void)
-{
-  /* Server stuff. */
-  gnutls_anon_server_credentials_t s_anoncred;
-  const gnutls_datum_t p3 = { (unsigned char *) pkcs3, strlen (pkcs3) };
-  static gnutls_dh_params_t dh_params;
-  gnutls_session_t server;
-  gnutls_sbuf_t ssbuf;
-  int sret = GNUTLS_E_AGAIN;
-  /* Client stuff. */
-  gnutls_anon_client_credentials_t c_anoncred;
-  gnutls_session_t client;
-  int cret = GNUTLS_E_AGAIN;
-  /* Need to enable anonymous KX specifically. */
-  int ret;
-  ssize_t left, spos, cpos;
-  char *abuf = NULL;
-  size_t abuf_size = 0;
-
-  /* General init. */
-  gnutls_global_init ();
-  gnutls_global_set_log_function (tls_log_func);
-  if (debug)
-    gnutls_global_set_log_level (4711);
-
-  /* Init server */
-  gnutls_anon_allocate_server_credentials (&s_anoncred);
-  gnutls_dh_params_init (&dh_params);
-  gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM);
-  gnutls_anon_set_server_dh_params (s_anoncred, dh_params);
-  gnutls_init (&server, GNUTLS_SERVER);
-  gnutls_priority_set_direct (server, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
-  gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred);
-  gnutls_dh_set_prime_bits (server, 1024);
-  gnutls_transport_set_push_function (server, server_push);
-  gnutls_transport_set_pull_function (server, server_pull);
-  gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t)server);
-  
-  gnutls_sbuf_init(&ssbuf, server, GNUTLS_SBUF_QUEUE_FLUSHES);
-  
-  gnutls_rnd(GNUTLS_RND_NONCE, server_buf, sizeof(server_buf));
-
-  /* Init client */
-  gnutls_anon_allocate_client_credentials (&c_anoncred);
-  gnutls_init (&client, GNUTLS_CLIENT);
-  gnutls_priority_set_direct (client, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL);
-  gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred);
-  gnutls_transport_set_push_function (client, client_push);
-  gnutls_transport_set_pull_function (client, client_pull);
-  gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t)client);
-
-  memset(client_buf, 0, sizeof(client_buf));
-
-  HANDSHAKE(client, server);
-
-  if (debug)
-    success ("Handshake established\n");
-
-#define SEND_SIZE 100
-  left = sizeof(server_buf);
-  spos = 0;
-  cpos = 0;
-  while (left > 0)
-    {
-      if (left > SEND_SIZE)
-        {
-          ret = gnutls_sbuf_write(ssbuf, server_buf+spos, SEND_SIZE);
-        }
-      else
-        {
-          ret = gnutls_sbuf_write(ssbuf, server_buf+spos, left);
-        }
-
-      if (ret >= 0)
-        {
-          left -= ret;
-          spos += ret;
-          ret = gnutls_sbuf_flush(ssbuf);
-        }
-
-      if (ret < 0)
-        {
-          fail("Error sending %s\n", gnutls_strerror(ret));
-          abort();
-        }
-      
-      if (ret > 0)
-        { /* received in client side */
-          ret = gnutls_record_recv(client, client_buf+cpos, sizeof(client_buf)-cpos);
-          if (ret > 0)
-            cpos += ret;
-
-          if (ret < 0)
-            {
-              fail("Error receiving %s\n", gnutls_strerror(ret));
-              abort();
-            }
-        }
-    }
-    
-  if (memcmp(client_buf, server_buf, sizeof(server_buf)) != 0)
-    {
-      fail("Data do not match!\n");
-      abort();
-    }
-  
-  gnutls_record_send(client, LINE1, sizeof(LINE1)-1);
-  gnutls_record_send(client, LINE2, sizeof(LINE2)-1);
-  
-  ret = gnutls_sbuf_getline(ssbuf, &abuf, &abuf_size);
-  if (ret < 0)
-    {
-      fail("sbuf_getline error %s!\n", gnutls_strerror(ret));
-      abort();
-    }
-
-  if (strcmp(abuf, LINE1) != 0)
-    {
-      fail("LINE1 Data do not match!\n");
-      abort();
-    }
-
-  ret = gnutls_sbuf_getline(ssbuf, &abuf, &abuf_size);
-  if (ret < 0)
-    {
-      fail("sbuf_getline error %s!\n", gnutls_strerror(ret));
-      abort();
-    }
-
-  if (strcmp(abuf, LINE2) != 0)
-    {
-      fail("LINE2 Data do not match!\n");
-      abort();
-    }
-
-  gnutls_free(abuf);
-  gnutls_bye (client, GNUTLS_SHUT_RDWR);
-  gnutls_bye (server, GNUTLS_SHUT_RDWR);
-
-  gnutls_sbuf_deinit (ssbuf);
-  gnutls_deinit (client);
-  gnutls_deinit (server);
-
-  gnutls_anon_free_client_credentials (c_anoncred);
-  gnutls_anon_free_server_credentials (s_anoncred);
-
-  gnutls_dh_params_deinit (dh_params);
-
-  gnutls_global_deinit ();
-}
diff --git a/tests/mini-xssl.c b/tests/mini-xssl.c
new file mode 100644 (file)
index 0000000..e304e7a
--- /dev/null
@@ -0,0 +1,406 @@
+/*
+ * Copyright (C) 2013 Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * GnuTLS is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuTLS 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GnuTLS; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/* Tests for the xssl interface */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined(_WIN32)
+
+int main()
+{
+  exit(77);
+}
+
+#else
+
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/wait.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <gnutls/gnutls.h>
+#include <gnutls/xssl.h>
+#include <signal.h>
+
+#include "utils.h"
+
+#define TOFU_DB_FILE "tofu.tmp.db"
+
+static void terminate(void);
+
+/* This program tests the robustness of record
+ * decoding.
+ */
+
+static time_t mytime (time_t * t)
+{
+  time_t then = 1359304177;
+
+  if (t)
+    *t = then;
+
+  return then;
+}
+
+
+static void
+server_log_func (int level, const char *str)
+{
+//  fprintf (stderr, "server|<%d>| %s", level, str);
+}
+
+static void
+client_log_func (int level, const char *str)
+{
+  fprintf (stderr, "client|<%d>| %s", level, str);
+}
+
+static unsigned char ca_pem[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIIDUDCCAgigAwIBAgIBADANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDEw5HbnVU\n"
+  "TFMgVGVzdCBDQTAeFw0xMTA1MjgwODM2MzBaFw0zODEwMTIwODM2MzNaMBkxFzAV\n"
+  "BgNVBAMTDkdudVRMUyBUZXN0IENBMIIBUjANBgkqhkiG9w0BAQEFAAOCAT8AMIIB\n"
+  "OgKCATEAnORCsX1unl//fy2d1054XduIg/3CqVBaT3Hca65SEoDwh0KiPtQoOgZL\n"
+  "dKY2cobGs/ojYtOjcs0KnlPYdmtjEh6WEhuJU95v4TQdC4OLMiE56eIGq252hZAb\n"
+  "HoTL84Q14DxQWGuzQK830iml7fbw2WcIcRQ8vFGs8SzfXw63+MI6Fq6iMAQIqP08\n"
+  "WzGmRRzL5wvCiPhCVkrPmwbXoABub6AAsYwWPJB91M9/lx5gFH5k9/iPfi3s2Kg3\n"
+  "F8MOcppqFYjxDSnsfiz6eMh1+bYVIAo367vGVYHigXMEZC2FezlwIHaZzpEoFlY3\n"
+  "a7LFJ00yrjQ910r8UE+CEMTYzE40D0olCMo7FA9RCjeO3bUIoYaIdVTUGWEGHWSe\n"
+  "oxGei9Gkm6u+ASj8f+i0jxdD2qXsewIDAQABo0MwQTAPBgNVHRMBAf8EBTADAQH/\n"
+  "MA8GA1UdDwEB/wQFAwMHBgAwHQYDVR0OBBYEFE1Wt2oAWPFnkvSmdVUbjlMBA+/P\n"
+  "MA0GCSqGSIb3DQEBCwUAA4IBMQAesOgjGFi1zOYpA/N3gkUVRcBHDxmN7g2yOcqH\n"
+  "VfhFc+e4zhOehR11WCt2RgzNlnYVmV5zBmQBdTAt8Po/MVhLCDW1BULHlLvL0DFc\n"
+  "4sB1RlcGeQcCKQa4b+Q9VWf4f6TfuEWZQC5j5stiXjVgOqrOMrzKZ2eKWA4JsL9s\n"
+  "V+7ANSZE+hOt1X1mA8moyqe95U2Ecih+nFJSWSBd1WFiEzVnXv4FVWPXbH9HERDK\n"
+  "VbasjofWWmQO1YlQPishLgm1IbwqOkOk4sDgoLuUZ4GgP0DDeN6EmRDOzByrv+9u\n"
+  "f45Bl9IQf4IJNPLU9lEqjyMOydqT6kBi7fjV5ICuQZ4EeVJsOGuX7PqNyoDzJHLv\n"
+  "ferRfNLr6eQSHSxBhS0cVyDjb5gCawK6u7xTU+b7xikEie9k\n"
+  "-----END CERTIFICATE-----\n";
+
+const gnutls_datum_t ca_cert = { ca_pem,
+  sizeof (ca_pem)-1
+};
+
+static unsigned char server_cert_pem[] =
+  "-----BEGIN CERTIFICATE-----\n"
+  "MIICsDCCAWigAwIBAgIETeC0kjANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDEw5H\n"
+  "bnVUTFMgVGVzdCBDQTAeFw0xMTA1MjgwODM4NDNaFw0zODEwMTIwODM4NDZaMDEx\n"
+  "LzAtBgNVBAMTJkdudVRMUyBUZXN0IHNlcnZlciAoRUNEU0EgY2VydGlmaWNhdGUp\n"
+  "ME4wEAYHKoZIzj0CAQYFK4EEACEDOgAE0vMmf/W0rRoUqBxH5Uq+c/sR76ElmyZM\n"
+  "e2zj3U9PRJ0maKstEOHkpaDaSU6s2Hyi9L88wS1ZX0ijgY0wgYowDAYDVR0TAQH/\n"
+  "BAIwADAUBgNVHREEDTALgglsb2NhbGhvc3QwEwYDVR0lBAwwCgYIKwYBBQUHAwEw\n"
+  "DwYDVR0PAQH/BAUDAweAADAdBgNVHQ4EFgQUJ97Q83IFpLgqeOnT1rX/JzCvlTQw\n"
+  "HwYDVR0jBBgwFoAUTVa3agBY8WeS9KZ1VRuOUwED788wDQYJKoZIhvcNAQELBQAD\n"
+  "ggExAErP9z8CCwt7YwA+SHoulNjqcXsngeKAKN9fVgV/XuspG6L2nU1WZvCjjFj6\n"
+  "jggMbJSElyCuLZJKlTC/DihXUgRXyswOzg9qQ7dDv+V/Qi95XH5slXNzYxMQSdoA\n"
+  "IaULVVDZcMFMVSc+TyAchJ6XwUY9umiysz3lSOioMQCch4MA366ZNqqnq5OD4moH\n"
+  "1SUX8CbRjA6SLpvffexLTB2Af+mFi8ReTkXCwB1LGEH1HRp/XzBc+/F9mavy3g/6\n"
+  "Hnjf2E1h2GDYXcJCVfE+ArjNS+R94jJwRMFBvwD/x2hsvpSajDpO0+GIxlGGKdyh\n"
+  "7o4puz/BqHwSzX9h7I7RvFEogDUNUzLgHMdcjq5usnmQpdWNUP8Xs/WqLjML+/PT\n"
+  "+jyCwmll0lPlC2RqAx3pM1XrjjQ=\n"
+  "-----END CERTIFICATE-----\n";
+
+const gnutls_datum_t server_cert = { server_cert_pem,
+  sizeof (server_cert_pem)-1
+};
+
+static unsigned char server_key_pem[] =
+   "-----BEGIN EC PRIVATE KEY-----\n"
+   "MGgCAQEEHHX3xeBOGgIxxtuhhpbwdwZnJztR7+uZTHnYuL+gBwYFK4EEACGhPAM6\n"
+   "AATS8yZ/9bStGhSoHEflSr5z+xHvoSWbJkx7bOPdT09EnSZoqy0Q4eSloNpJTqzY\n"
+   "fKL0vzzBLVlfSA==\n"
+   "-----END EC PRIVATE KEY-----\n";
+
+const gnutls_datum_t server_key = { server_key_pem,
+  sizeof (server_key_pem)-1
+};
+
+#define LINE1 "hello there people\n"
+#define LINE2 "how are you doing today, all well?\n"
+
+static const char* test = NULL;
+
+#define err_quit(r) {fail("%s: Error in line %d: %s\n", test, __LINE__, gnutls_strerror(r)); exit(1);}
+
+static void
+client (int fd, unsigned int vmethod, unsigned use_cert)
+{
+  int ret;
+  char *line = NULL;
+  size_t line_len;
+  xssl_cred_t cred;
+  xssl_t sb;
+  gnutls_cinput_st aux[2];
+  unsigned int status;
+  unsigned aux_size = 0;
+
+  gnutls_global_init ();
+  gnutls_global_set_time_function (mytime);
+
+  if (debug)
+    {
+      gnutls_global_set_log_function (client_log_func);
+      gnutls_global_set_log_level (7);
+    }
+
+  if (vmethod & GNUTLS_VMETHOD_GIVEN_CAS)
+    {
+      aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+      aux[aux_size].contents = GNUTLS_CINPUT_CAS;
+      aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+      aux[aux_size].i1.mem = ca_cert;
+      aux_size++;
+    }
+
+  if (use_cert != 0)
+    {
+      aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+      aux[aux_size].contents = GNUTLS_CINPUT_KEYPAIR;
+      aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+      aux[aux_size].i1.mem = server_cert;
+      aux[aux_size].i2.mem = server_key;
+      aux_size++;
+    }
+
+  if (vmethod & GNUTLS_VMETHOD_TOFU)
+    {
+      aux[aux_size].type = GNUTLS_CINPUT_TYPE_FILE;
+      aux[aux_size].contents = GNUTLS_CINPUT_TOFU_DB;
+      aux[aux_size].i1.file = TOFU_DB_FILE;
+      aux_size++;
+    }
+
+  ret = xssl_cred_init(&cred, vmethod, aux, aux_size);
+  if (ret < 0)
+    err_quit(ret);
+
+  /* Initialize TLS session
+   */
+  ret = xssl_client_init(&sb, "localhost", NULL, (gnutls_transport_ptr_t)fd,
+                                NULL, cred, &status, 0);
+  if (ret < 0)
+    {
+      if (ret == GNUTLS_E_AUTH_ERROR)
+        {
+          gnutls_datum_t txt;
+          
+          gnutls_certificate_verification_status_print(status, GNUTLS_CRT_X509,
+            &txt, 0);
+          
+          fprintf(stderr, "auth[%x]: %s\n", status, txt.data);
+          gnutls_free(txt.data);
+        }
+      err_quit(ret);
+    }
+    
+  ret = xssl_getline(sb, &line, &line_len);
+  if (ret < 0)
+    err_quit(ret);
+  
+  if (strcmp(line, LINE1) != 0)
+    {
+      fail("Error comparing first line\n");
+      exit(1);
+    }
+
+  ret = xssl_getline(sb, &line, &line_len);
+  if (ret < 0)
+    err_quit(ret);
+  
+  if (strcmp(line, LINE2) != 0)
+    {
+      fail("Error comparing first line\n");
+      exit(1);
+    }
+  
+  gnutls_free(line);
+
+  xssl_deinit(sb);
+
+  close (fd);
+
+  xssl_cred_deinit (cred);
+
+  gnutls_global_deinit ();
+}
+
+
+/* These are global */
+pid_t child;
+
+static void terminate(void)
+{
+  kill(child, SIGTERM);
+  exit(1);
+}
+
+static void
+server (int fd, unsigned vmethod)
+{
+  int ret;
+  xssl_cred_t cred;
+  xssl_t sb;
+  gnutls_cinput_st aux[2];
+  unsigned aux_size = 0;
+
+  gnutls_global_init ();
+
+  if (debug)
+    {
+      gnutls_global_set_log_function (client_log_func);
+      gnutls_global_set_log_level (7);
+    }
+
+
+  aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+  aux[aux_size].contents = GNUTLS_CINPUT_KEYPAIR;
+  aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+  aux[aux_size].i1.mem = server_cert;
+  aux[aux_size].i2.mem = server_key;
+  aux_size++;
+
+  if (vmethod & GNUTLS_VMETHOD_GIVEN_CAS)
+    {
+      aux[aux_size].type = GNUTLS_CINPUT_TYPE_MEM;
+      aux[aux_size].contents = GNUTLS_CINPUT_CAS;
+      aux[aux_size].fmt = GNUTLS_X509_FMT_PEM;
+      aux[aux_size].i1.mem = ca_cert;
+      aux_size++;
+    }
+
+  ret = xssl_cred_init(&cred, vmethod, aux, aux_size);
+  if (ret < 0)
+    err_quit(ret);
+
+  /* Initialize TLS session
+   */
+  ret = xssl_server_init(&sb, (gnutls_transport_ptr_t)fd,
+                                NULL, cred, NULL, 0);
+  if (ret < 0)
+    err_quit(ret);
+
+  ret = xssl_write(sb, LINE1, sizeof(LINE1)-1);
+  if (ret < 0)
+    err_quit(ret);
+  
+  ret = xssl_write(sb, LINE2, sizeof(LINE2)-1);
+  if (ret < 0)
+    err_quit(ret);
+    
+  ret = xssl_flush(sb);
+  if (ret < 0)
+    err_quit(ret);
+  
+  xssl_deinit(sb);
+
+  close (fd);
+
+  xssl_cred_deinit (cred);
+
+  gnutls_global_deinit ();
+
+}
+
+static void start (unsigned vc, unsigned vs, unsigned ccert)
+{
+  int fd[2];
+  int ret;
+  
+  ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fd);
+  if (ret < 0)
+    {
+      perror("socketpair");
+      exit(1);
+    }
+
+  child = fork ();
+  if (child < 0)
+    {
+      perror ("fork");
+      fail ("fork");
+      exit(1);
+    }
+
+  if (child)
+    {
+      /* parent */
+      close(fd[1]);
+      server (fd[0], vs);
+      waitpid(-1, NULL, 0);
+      //kill(child, SIGTERM);
+    }
+  else 
+    {
+      close(fd[0]);
+      client (fd[1], vc, ccert);
+      exit(0);
+    }
+}
+
+static void ch_handler(int sig)
+{
+int status = 0;
+
+  waitpid(-1, &status, 0);
+  if (WEXITSTATUS(status) != 0 ||
+      (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV))
+    {
+      if (WIFSIGNALED(status))
+        fail("Child died with sigsegv\n");
+      else
+        fail("Child died with status %d\n", WEXITSTATUS(status));
+      terminate();
+    }
+  return;
+}
+
+void
+doit (void)
+{
+  signal(SIGCHLD, ch_handler);
+
+  test = "test1: no auth";
+  start(GNUTLS_VMETHOD_NO_AUTH, GNUTLS_VMETHOD_NO_AUTH, 0);
+
+  test = "test2: server auth";
+  start(GNUTLS_VMETHOD_GIVEN_CAS, GNUTLS_VMETHOD_NO_AUTH, 0);
+
+  test = "test3: mutual auth";
+  start(GNUTLS_VMETHOD_GIVEN_CAS, GNUTLS_VMETHOD_GIVEN_CAS, 1);
+
+  remove(TOFU_DB_FILE);
+  test = "test4: trust on first use p1";
+  start(GNUTLS_VMETHOD_TOFU, GNUTLS_VMETHOD_NO_AUTH, 0);
+
+  test = "test5: trust on first use p2";
+  start(GNUTLS_VMETHOD_TOFU, GNUTLS_VMETHOD_NO_AUTH, 0);
+  remove(TOFU_DB_FILE);
+
+}
+
+#endif /* _WIN32 */