]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
updates in the sbuf API.
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 27 Jan 2013 12:58:46 +0000 (13:58 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Sun, 27 Jan 2013 12:58:46 +0000 (13:58 +0100)
lib/includes/gnutls/sbuf.h
lib/libgnutls.map
lib/sbuf.c

index d80df6462113172cfa32388032c07113997634fc..a629949aa659cb837ceb640e4aa89efb00354f03 100644 (file)
 typedef struct gnutls_sbuf_st *gnutls_sbuf_t;
 typedef struct gnutls_credentials_st *gnutls_credentials_t;
 
-typedef enum
-{
-  GNUTLS_VMETHOD_INSECURE = 0,
-  GNUTLS_VMETHOD_TOFU = 1<<0,
-  GNUTLS_VMETHOD_SINGLE_CA = 1<<1,
-  GNUTLS_VMETHOD_SYSTEM_CAS = 1<<2
-} gnutls_vmethod_t;
-
 ssize_t gnutls_sbuf_printf (gnutls_sbuf_t sb, const char *fmt, ...)
 #ifdef __GNUC__
    __attribute__ ((format (printf, 2, 3)))
@@ -54,25 +46,63 @@ gnutls_sbuf_getdelim (gnutls_sbuf_t sbuf, char **lineptr, size_t *n, int delimit
 
 #define gnutls_sbuf_getline(sbuf, ptr, n) gnutls_sbuf_getdelim(sbuf, ptr, n, '\n')
 
-#define GNUTLS_SBUF_QUEUE_FLUSHES 1
 void gnutls_sbuf_deinit(gnutls_sbuf_t sb);
 
+#define GNUTLS_SBUF_WRITE_FLUSHES 1
 int gnutls_sbuf_sinit (gnutls_sbuf_t * isb, gnutls_session_t session,
                        unsigned int flags);
 
+gnutls_session_t gnutls_sbuf_get_session(gnutls_sbuf_t sb);
+
 int gnutls_sbuf_client_init (gnutls_sbuf_t * isb, const char* hostname, 
                              const char* service,
                              gnutls_transport_ptr fd, 
                              const char* priority, gnutls_credentials_t cred,
                              unsigned int flags);
 
+int gnutls_sbuf_server_init (gnutls_sbuf_t * isb, 
+                             gnutls_transport_ptr fd, 
+                             const char* priority, gnutls_credentials_t cred,
+                             unsigned int flags);
+
 /* High level credential structures */
+typedef enum
+{
+  GNUTLS_VMETHOD_NO_AUTH = 0,
+  GNUTLS_VMETHOD_TOFU = 1<<0,
+  GNUTLS_VMETHOD_GIVEN_CAS = 1<<1,
+  GNUTLS_VMETHOD_SYSTEM_CAS = 1<<2
+} gnutls_vmethod_t;
+
+typedef enum
+{
+  GNUTLS_CRED_FILE = 0,
+  GNUTLS_CRED_MEM = 1,
+} gnutls_cinput_type_t;
+
+typedef enum
+{
+  GNUTLS_CINPUT_CAS = 1,
+  GNUTLS_CINPUT_CRLS = 2,
+  GNUTLS_CINPUT_TOFU_DB = 3,
+} 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;
+  union {
+    const char* file;
+    gnutls_datum_t mem;
+  } i;
+} gnutls_cinput_st;
+
 int gnutls_credentials_init (gnutls_credentials_t* cred);
 void gnutls_credentials_deinit (gnutls_credentials_t cred);
 
 int gnutls_credentials_set_trust (gnutls_credentials_t cred, unsigned vflags, 
-                                  const char* ca_file, const char* crl_file,
-                                  const char* tofu_file);
+                                  gnutls_cinput_st* aux,
+                                  unsigned aux_size);
 
 
 #endif /* GNUTLS_SBUF_H */
index 57de4f2442ebbbb4bbdda49b6c11f19f7c3e0003..8eca27684ff97e1a4a2b4a0766429725382e9db3 100644 (file)
@@ -877,10 +877,6 @@ GNUTLS_3_1_0 {
        gnutls_pubkey_import_x509_crq;
        gnutls_pubkey_print;
        gnutls_record_get_random_padding_status;
-       gnutls_sbuf_deinit;
-       gnutls_sbuf_init;
-       gnutls_sbuf_flush;
-       gnutls_sbuf_read;
        gnutls_x509_crt_set_dn;
        gnutls_x509_crq_set_dn;
        gnutls_x509_crt_set_issuer_dn;
@@ -889,8 +885,18 @@ 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;
 } GNUTLS_3_0_0;
 
 GNUTLS_PRIVATE {
index da645614a1e6d54c11404b8de94c55fb7487c81d..3b9efa4d1dfa8cce4d0caac45d23f1de637568de 100644 (file)
  * gnutls_sbuf_sinit:
  * @isb: is a pointer to a #gnutls_sbuf_t structure.
  * @session: a GnuTLS session
- * @flags: should be zero or %GNUTLS_SBUF_QUEUE_FLUSHES
+ * @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_QUEUE_FLUSHES
+ * 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.
  *
@@ -123,7 +123,7 @@ _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.
    */
-  if (sb->cred->vflags & GNUTLS_VMETHOD_SYSTEM_CAS || sb->cred->vflags & GNUTLS_VMETHOD_SINGLE_CA)
+  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)
@@ -168,15 +168,14 @@ _verify_certificate_callback (gnutls_session_t session)
  * gnutls_credentials_set_trust:
  * @cred: is a #gnutls_credentials_t structure.
  * @vflags: the requested peer verification methods
- * @ca_file: a PEM file storing the certificate authority
- * @crl_file: a PEM file storing any CRLs of the certificate authority
- * @tofu_file: a file to store the trust on first use database
+ * @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.
  *
  * The @ca_file and @crl_file are required only if @vflags includes
- * %GNUTLS_VMETHOD_SINGLE_CA. The @tofu_file may be set if 
+ * %GNUTLS_VMETHOD_GIVEN_CAS. The @tofu_file may be set if 
  * %GNUTLS_VMETHOD_TOFU is specified.
  *
  * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
@@ -184,11 +183,11 @@ _verify_certificate_callback (gnutls_session_t session)
  * Since: 3.1.7
  **/
 int gnutls_credentials_set_trust (gnutls_credentials_t cred, unsigned vflags, 
-                                  const char* ca_file, const char* crl_file,
-                                  const char* tofu_file)
+                                  gnutls_cinput_st* aux,
+                                  unsigned aux_size)
 {
 int ret;
-unsigned len;
+unsigned len, i;
 
   if (cred->xcred == NULL)
     {
@@ -207,30 +206,49 @@ unsigned len;
         }
     }
 
-  if (vflags & GNUTLS_VMETHOD_SINGLE_CA)
+  if (vflags & GNUTLS_VMETHOD_GIVEN_CAS)
     {
-      ret = gnutls_certificate_set_x509_trust_file(cred->xcred, ca_file, GNUTLS_X509_FMT_PEM);
-      if (ret < 0)
-        {
-          gnutls_assert();
-          goto fail1;
-        }
-
-      ret = gnutls_certificate_set_x509_crl_file(cred->xcred, crl_file, GNUTLS_X509_FMT_PEM);
-      if (ret < 0)
+      for (i=0;i<aux_size;i++)
         {
-          gnutls_assert();
-          goto fail1;
+          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 (ret < 0)
+            {
+              gnutls_assert();
+              goto fail1;
+            }
         }
     }
-  
+
   if (vflags & GNUTLS_VMETHOD_TOFU)
     {
-      len = strlen(tofu_file);
+      for (i=0;i<aux_size;i++)
+        {
+          if (aux[i].contents == GNUTLS_CINPUT_TOFU_DB)
+            {
+              if (aux[i].type != GNUTLS_CRED_FILE)
+                {
+                  ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+                  goto fail1;
+                }
+              len = strlen(aux[i].i.file);
       
-      if (len >= sizeof(cred->tofu_file))
-        return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
-      memcpy(cred->tofu_file, tofu_file, len+1);
+              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);
+            }
+        }
     }
   
   gnutls_certificate_set_verify_function (cred->xcred, _verify_certificate_callback);
@@ -251,10 +269,10 @@ fail1:
  * @fd: a socket descriptor
  * @priority: A priority string to use (use %NULL for default)
  * @cred: A credentials structure
- * @flags: should be zero or %GNUTLS_SBUF_QUEUE_FLUSHES
+ * @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_QUEUE_FLUSHES
+ * This function initializes a #gnutls_sbuf_t structure.
+ * 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.
  *
@@ -291,6 +309,7 @@ unsigned len;
    */
   gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
   
+  if (priority == NULL) priority = "NORMAL:%COMPAT";
   ret = gnutls_priority_set_direct(session, priority, NULL);
   if (ret < 0)
     {
@@ -334,6 +353,7 @@ unsigned len;
     }
 
   gnutls_transport_set_ptr (session, fd);
+  gnutls_session_set_ptr( session, sb);
   
   do
     {
@@ -348,7 +368,95 @@ unsigned len;
     }
   
   *isb = sb;
+  
+  return 0;
+
+fail1:
+  if (sb)
+    gnutls_sbuf_deinit(sb);
+  gnutls_deinit(session);
+  
+  return ret;
+}
+
+/**
+ * gnutls_sbuf_server_init:
+ * @isb: is a pointer to a #gnutls_sbuf_t structure.
+ * @fd: a socket descriptor
+ * @priority: A priority string to use (use %NULL for default)
+ * @cred: A credentials structure
+ * @flags: should be zero or %GNUTLS_SBUF_WRITE_FLUSHES
+ *
+ * This function initializes a #gnutls_sbuf_t structure.
+ * 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_server_init (gnutls_sbuf_t * isb,
+                             gnutls_transport_ptr fd, 
+                             const char* priority, gnutls_credentials_t cred,
+                             unsigned int flags)
+{
+struct gnutls_sbuf_st* sb;
+gnutls_session_t session;
+int ret;
+
+  ret = gnutls_init(&session, GNUTLS_SERVER);
+  if (ret < 0)
+    return gnutls_assert_val(ret);
+
+  sb = gnutls_calloc(1, sizeof(*sb));
+  if (sb == NULL)
+    {
+      ret = gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
+      goto fail1;
+    }
+  _gnutls_buffer_init(&sb->buf);
+  sb->session = session;
+  sb->flags = flags;
+  
+  /* set session/handshake info 
+   */
+  gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
+  
+  if (priority == NULL) priority = "NORMAL:%COMPAT";
+  ret = gnutls_priority_set_direct(session, priority, NULL);
+  if (ret < 0)
+    {
+      gnutls_assert();
+      goto fail1;
+    }
+  
+  if (cred->xcred)
+    {
+      ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred->xcred);
+      if (ret < 0)
+        {
+          gnutls_assert();
+          goto fail1;
+        }
+    }
+
+  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 (ret < 0)
+    {
+      gnutls_assert();
+      goto fail1;
+    }
+  
+  *isb = sb;
   
   return 0;
 
@@ -372,6 +480,11 @@ fail1:
  **/
 void gnutls_sbuf_deinit(gnutls_sbuf_t sb)
 {
+  if (sb->session)
+    {
+      gnutls_bye(sb->session, GNUTLS_SHUT_WR);
+      gnutls_deinit(sb->session);
+    }
   _gnutls_buffer_clear(&sb->buf);
   gnutls_free(sb);
 }
@@ -384,7 +497,7 @@ void gnutls_sbuf_deinit(gnutls_sbuf_t sb)
  *
  * 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_QUEUE_FLUSHES
+ * until gnutls_sbuf_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.
@@ -403,7 +516,7 @@ int ret;
   if (ret < 0)
     return gnutls_assert_val(ret);
   
-  while ((sb->flags & GNUTLS_SBUF_QUEUE_FLUSHES) && 
+  while ((sb->flags & GNUTLS_SBUF_WRITE_FLUSHES) && 
        sb->buf.length >= MAX_RECORD_SEND_SIZE(sb->session))
     {
       do
@@ -555,3 +668,16 @@ int ret;
 
   return 0;
 }
+
+/**
+ * gnutls_sbuf_get_session:
+ * @sb: is a #gnutls_sbuf_t structure.
+ *
+ * Returns: The associated session or %NULL.
+ *
+ * Since: 3.1.7
+ **/
+gnutls_session_t gnutls_sbuf_get_session(gnutls_sbuf_t sb)
+{
+  return sb->session;
+}