From f5e3b63997b31d5faaac66aca1d9a0a16a892396 Mon Sep 17 00:00:00 2001 From: Simon Josefsson Date: Sun, 25 Feb 2007 15:34:29 +0000 Subject: Add. --- doc/examples/ex-client-authz.c | 191 +++++++++++++++++++++++++++++++++++++++++ doc/gnutls.texi | 10 +++ 2 files changed, 201 insertions(+) create mode 100644 doc/examples/ex-client-authz.c (limited to 'doc') diff --git a/doc/examples/ex-client-authz.c b/doc/examples/ex-client-authz.c new file mode 100644 index 0000000000..c3c1aa96f4 --- /dev/null +++ b/doc/examples/ex-client-authz.c @@ -0,0 +1,191 @@ +#if HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +/* A basic TLS client, with X.509 authentication, and support for + the authorization extension. + */ + +#define MAX_BUF 1024 +#define CAFILE "ca.pem" +#define MSG "GET / HTTP/1.0\r\n\r\n" + +int server_authorized_p = 0; + +extern int tcp_connect (void); +extern void tcp_close (int sd); + +int +authz_recv_callback (gnutls_session_t session, + const int *authz_formats, + gnutls_datum_t *infos, + const int *hashtypes, + gnutls_datum_t *hash) +{ + size_t i, j; + + /* This function receives authorization data. */ + + for (i = 0; authz_formats[i]; i++) + { + printf ("- Received authorization data, format %02x of %d bytes\n", + authz_formats[i], infos[i].size); + + printf (" data: "); + for (j = 0; j < infos[i].size; j++) + printf ("%02x", infos[i].data[j]); + printf ("\n"); + + if (hash[i].size > 0) + { + printf (" hash: "); + for (j = 0; j < hash[i].size; j++) + printf ("%02x", hash[i].data[j]); + printf (" type %02x\n", hashtypes[i]); + } + } + + /* You would typically actually _validate_ the data here... if you + need access to authentication details, store the authorization + data and do the validation inside main(). */ + + server_authorized_p = 1; + + return 0; +} + +int +authz_send_callback (gnutls_session_t session, + const int *client_formats, + const int *server_formats) +{ + const char *str = "saml assertion"; + /* Send the authorization data here. client_formats and + server_formats contains a list of negotiated authorization + formats. */ + return gnutls_authz_send_saml_assertion (session, str, sizeof (str)); +} + +int +main (void) +{ + int ret, sd, ii; + gnutls_session_t session; + char buffer[MAX_BUF + 1]; + gnutls_certificate_credentials_t xcred; + /* Allow connections to servers that have OpenPGP keys as well. + */ + const int cert_type_priority[3] = { GNUTLS_CRT_X509, + GNUTLS_CRT_OPENPGP, 0 + }; + const int authz_client_formats[] = { + GNUTLS_AUTHZ_SAML_ASSERTION, + }; + const int authz_server_formats[] = { + GNUTLS_AUTHZ_X509_ATTR_CERT, + GNUTLS_AUTHZ_SAML_ASSERTION, + GNUTLS_AUTHZ_X509_ATTR_CERT_URL, + GNUTLS_AUTHZ_SAML_ASSERTION_URL + }; + + gnutls_global_init (); + + /* X509 stuff */ + gnutls_certificate_allocate_credentials (&xcred); + + /* sets the trusted cas file + */ + gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM); + + /* Initialize TLS session + */ + gnutls_init (&session, GNUTLS_CLIENT); + + /* Use default priorities */ + gnutls_set_default_priority (session); + gnutls_certificate_type_set_priority (session, cert_type_priority); + + /* put the x509 credentials to the current session + */ + gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); + + /* connect to the peer + */ + sd = tcp_connect (); + + gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); + + gnutls_authz_enable (session, authz_client_formats, authz_server_formats, + authz_recv_callback, authz_send_callback); + + /* Perform the TLS handshake + */ + ret = gnutls_handshake (session); + + if (ret < 0) + { + fprintf (stderr, "*** Handshake failed\n"); + gnutls_perror (ret); + goto end; + } + else + { + printf ("- Handshake was completed\n"); + } + + if (!server_authorized_p) + { + fprintf (stderr, "*** Not authorized, giving up...\n"); + ret = gnutls_alert_send (session, GNUTLS_AL_FATAL, + GNUTLS_A_ACCESS_DENIED); + if (ret < 0) + { + gnutls_perror (ret); + goto end; + } + } + + gnutls_record_send (session, MSG, strlen (MSG)); + + ret = gnutls_record_recv (session, buffer, MAX_BUF); + if (ret == 0) + { + printf ("- Peer has closed the TLS connection\n"); + goto end; + } + else if (ret < 0) + { + fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret)); + goto end; + } + + printf ("- Received %d bytes: ", ret); + for (ii = 0; ii < ret; ii++) + { + fputc (buffer[ii], stdout); + } + fputs ("\n", stdout); + + gnutls_bye (session, GNUTLS_SHUT_RDWR); + +end: + + tcp_close (sd); + + gnutls_deinit (session); + + gnutls_certificate_free_credentials (xcred); + + gnutls_global_deinit (); + + return 0; +} diff --git a/doc/gnutls.texi b/doc/gnutls.texi index 6554a0b72a..d7d3ef96a4 100644 --- a/doc/gnutls.texi +++ b/doc/gnutls.texi @@ -1910,6 +1910,7 @@ implemented by another example. * Client with Resume capability example:: * Simple client example with SRP authentication:: * Simple client example with TLS/IA support:: +* Simple client example with authorization support:: * Helper function for TCP connections:: @end menu @@ -2005,6 +2006,15 @@ The following client is a simple client which uses the @verbatiminclude examples/ex-client-tlsia.c +@node Simple client example with authorization support +@subsection Simple client example with authorization support + +The following client require that the server sends authorization data, +and the client will send authorization data to the server as well. +For authentication, X.509 is used. + +@verbatiminclude examples/ex-client-authz.c + @node Helper function for TCP connections @subsection Helper function for TCP connections -- cgit v1.2.1