+/*****************************************************************************
+ * tls_ClientCreate:
+ *****************************************************************************
+ * Initializes client-side TLS session data.
+ *****************************************************************************/
+static tls_session_t *
+gnutls_ClientCreate( tls_t *p_tls, const char *psz_ca_path )
+{
+ tls_session_t *p_session;
+ tls_client_sys_t *p_sys;
+ int i_val;
+ const int cert_type_priority[3] =
+ {
+ GNUTLS_CRT_X509,
+ 0
+ };
+
+ p_sys = (tls_client_sys_t *)malloc( sizeof(struct tls_client_sys_t) );
+ if( p_sys == NULL )
+ return NULL;
+
+ i_val = gnutls_certificate_allocate_credentials( &p_sys->x509_cred );
+ if( i_val != 0 )
+ {
+ msg_Err( p_tls, "Cannot allocate X509 credentials : %s",
+ gnutls_strerror( i_val ) );
+ free( p_sys );
+ return NULL;
+ }
+
+ if( psz_ca_path != NULL )
+ {
+ i_val = gnutls_certificate_set_x509_trust_file( p_sys->x509_cred,
+ psz_ca_path,
+ GNUTLS_X509_FMT_PEM );
+ if( i_val != 0 )
+ {
+ msg_Err( p_tls, "Cannot add trusted CA (%s) : %s", psz_ca_path,
+ gnutls_strerror( i_val ) );
+ gnutls_certificate_free_credentials( p_sys->x509_cred );
+ free( p_sys );
+ return NULL;
+ }
+ }
+
+ i_val = gnutls_init( &p_sys->session, GNUTLS_CLIENT );
+ if( i_val != 0 )
+ {
+ msg_Err( p_tls, "Cannot initialize TLS session : %s",
+ gnutls_strerror( i_val ) );
+ gnutls_certificate_free_credentials( p_sys->x509_cred );
+ free( p_sys );
+ return NULL;
+ }
+
+ i_val = gnutls_set_default_priority( p_sys->session );
+ if( i_val < 0 )
+ {
+ msg_Err( p_tls, "Cannot set ciphers priorities : %s",
+ gnutls_strerror( i_val ) );
+ gnutls_deinit( p_sys->session );
+ gnutls_certificate_free_credentials( p_sys->x509_cred );
+ free( p_sys );
+ return NULL;
+ }
+
+ i_val = gnutls_certificate_type_set_priority( p_sys->session, cert_type_priority );
+ if( i_val < 0 )
+ {
+ msg_Err( p_tls, "Cannot set certificate type priorities : %s",
+ gnutls_strerror( i_val ) );
+ gnutls_deinit( p_sys->session );
+ gnutls_certificate_free_credentials( p_sys->x509_cred );
+ free( p_sys );
+ return NULL;
+ }
+
+ i_val = gnutls_credentials_set( p_sys->session, GNUTLS_CRD_CERTIFICATE,
+ p_sys->x509_cred );
+ if( i_val < 0 )
+ {
+ msg_Err( p_tls, "Cannot set TLS session credentials : %s",
+ gnutls_strerror( i_val ) );
+ gnutls_deinit( p_sys->session );
+ gnutls_certificate_free_credentials( p_sys->x509_cred );
+ free( p_sys );
+ return NULL;
+ }
+
+ p_session = malloc( sizeof (struct tls_session_t) );
+ if( p_session == NULL )
+ {
+ gnutls_deinit( p_sys->session );
+ gnutls_certificate_free_credentials( p_sys->x509_cred );
+ free( p_sys );
+ return NULL;
+ }
+
+ p_session->p_tls = p_tls;
+ p_session->p_server = NULL;
+ p_session->p_sys = p_sys;
+ p_session->pf_handshake = gnutls_SessionHandshake;
+ p_session->pf_close = gnutls_SessionClose;
+ p_session->pf_send = gnutls_Send;
+ p_session->pf_recv = gnutls_Recv;
+
+ return p_session;
+}
+
+