summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2013-01-27 18:17:35 +0100
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2013-01-27 18:18:57 +0100
commit02ebe6b5143e39eb91b382ae6c301fe88dec8c8a (patch)
tree3fbe01fbf84658c08b1ce960d9b1af074ac55a70
parentb062201a4304c5759c678eeda44755fbf0cd8af1 (diff)
downloadgnutls-02ebe6b5143e39eb91b382ae6c301fe88dec8c8a.tar.gz
Added new interface.
-rw-r--r--NEWS20
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/gnutls_cert.c5
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/includes/Makefile.am2
-rw-r--r--lib/includes/gnutls/gnutls.h.in3
-rw-r--r--lib/includes/gnutls/xssl.h (renamed from lib/includes/gnutls/sbuf.h)65
-rw-r--r--lib/libgnutls.map25
-rw-r--r--lib/xssl.c (renamed from lib/sbuf.c)382
-rw-r--r--lib/xssl.h (renamed from lib/sbuf.h)7
-rw-r--r--lib/xssl_getline.c (renamed from lib/sbuf_getline.c)12
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/mini-sbuf.c204
-rw-r--r--tests/mini-xssl.c406
14 files changed, 703 insertions, 436 deletions
diff --git a/NEWS b/NEWS
index 68c924e0cc..32ac683954 100644
--- 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
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 70d23f3a73..b313120442 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -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
diff --git a/lib/gnutls_cert.c b/lib/gnutls_cert.c
index c451ef5c59..d43a5fb8ec 100644
--- a/lib/gnutls_cert.c
+++ b/lib/gnutls_cert.c
@@ -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. "));
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 95c2b5ac24..6bef39a47f 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -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),
diff --git a/lib/includes/Makefile.am b/lib/includes/Makefile.am
index bd48c0cc44..2fb86094c6 100644
--- a/lib/includes/Makefile.am
+++ b/lib/includes/Makefile.am
@@ -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
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index f09046687e..38182880e1 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -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
diff --git a/lib/includes/gnutls/sbuf.h b/lib/includes/gnutls/xssl.h
index a629949aa6..a71bec1901 100644
--- a/lib/includes/gnutls/sbuf.h
+++ b/lib/includes/gnutls/xssl.h
@@ -24,45 +24,46 @@
#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 */
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 8eca27684f..d44d76d79d 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -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 {
diff --git a/lib/sbuf.c b/lib/xssl.c
index 3b9efa4d1d..61555591d8 100644
--- a/lib/sbuf.c
+++ b/lib/xssl.c
@@ -23,94 +23,46 @@
#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;
}
diff --git a/lib/sbuf.h b/lib/xssl.h
index 44ea713604..416c36992f 100644
--- a/lib/sbuf.h
+++ b/lib/xssl.h
@@ -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;
};
diff --git a/lib/sbuf_getline.c b/lib/xssl_getline.c
index 932d9dc96b..4f571b8bef 100644
--- a/lib/sbuf_getline.c
+++ b/lib/xssl_getline.c
@@ -22,16 +22,16 @@
#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();
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 26f7ab2a60..62f757ed6f 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index b4b6b13fbb..0000000000
--- a/tests/mini-sbuf.c
+++ /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
index 0000000000..e304e7aca9
--- /dev/null
+++ b/tests/mini-xssl.c
@@ -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 */