#include <gnutls/x509.h>
#include <gcrypt.h>
-#define DH_BITS (1024)
-
#if LIBGNUTLS_VERSION_NUMBER >= 0x020200
#define HAVE_CIPHERSUITES 1
/* This is a kludge. gcrypt 1.4.x has support. Recent GnuTLS requires gcrypt 1.4.x
LDAP_FREE( c->kx_list );
#endif
gnutls_certificate_free_credentials( c->cred );
+ if ( c->dh_params )
+ gnutls_dh_params_deinit( c->dh_params );
ber_memfree ( c );
}
* then we have to build the cert chain.
*/
if ( max == 1 && !gnutls_x509_crt_check_issuer( certs[0], certs[0] )) {
+#if GNUTLS_VERSION_NUMBER >= 0x020c00
+ unsigned int i;
+ for ( i = 1; i<VERIFY_DEPTH; i++ ) {
+ if ( gnutls_certificate_get_issuer( ctx->cred, certs[i-1], &certs[i], 0 ))
+ break;
+ max++;
+ /* If this CA is self-signed, we're done */
+ if ( gnutls_x509_crt_check_issuer( certs[i], certs[i] ))
+ break;
+ }
+#else
gnutls_x509_crt_t *cas;
unsigned int i, j, ncas;
if ( j == ncas )
break;
}
+#endif
}
rc = gnutls_certificate_set_x509_key( ctx->cred, certs, max, key );
if ( rc ) return -1;
return -1;
}
- if ( lo->ldo_tls_dhfile ) {
- Debug( LDAP_DEBUG_ANY,
- "TLS: warning: ignoring dhfile\n",
- NULL, NULL, NULL );
- }
-
if ( lo->ldo_tls_crlfile ) {
rc = gnutls_certificate_set_x509_crl_file(
ctx->cred,
rc = 0;
}
- /* FIXME: ITS#5992 - this should go be configurable,
+ /* FIXME: ITS#5992 - this should be configurable,
* and V1 CA certs should be phased out ASAP.
*/
gnutls_certificate_set_verify_flags( ctx->cred,
GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT );
- if ( is_server ) {
- gnutls_dh_params_init(&ctx->dh_params);
- gnutls_dh_params_generate2(ctx->dh_params, DH_BITS);
+ if ( is_server && lo->ldo_tls_dhfile ) {
+ gnutls_datum_t buf;
+ rc = tlsg_getfile( lo->ldo_tls_dhfile, &buf );
+ if ( rc ) return -1;
+ rc = gnutls_dh_params_init( &ctx->dh_params );
+ if ( rc == 0 )
+ rc = gnutls_dh_params_import_pkcs3( ctx->dh_params, &buf,
+ GNUTLS_X509_FMT_PEM );
+ LDAP_FREE( buf.data );
+ if ( rc ) return -1;
+ gnutls_certificate_set_dh_params( ctx->cred, ctx->dh_params );
}
return 0;
}
return gnutls_cipher_get_key_size( c ) * 8;
}
+static int
+tlsg_session_unique( tls_session *sess, struct berval *buf, int is_server)
+{
+/* channel bindings added in 2.12.0 */
+#if GNUTLS_VERSION_NUMBER >= 0x020c00
+ tlsg_session *s = (tlsg_session *)sess;
+ gnutls_datum_t cb;
+ int rc;
+
+ rc = gnutls_session_channel_binding( s->session, GNUTLS_CB_TLS_UNIQUE, &cb );
+ if ( rc == 0 ) {
+ int len = cb.size;
+ if ( len > buf->bv_len )
+ len = buf->bv_len;
+ buf->bv_len = len;
+ memcpy( buf->bv_val, cb.data, len );
+ return len;
+ }
+#endif
+ return 0;
+}
+
+static const char *
+tlsg_session_version( tls_session *sess )
+{
+ tlsg_session *s = (tlsg_session *)sess;
+ return gnutls_protocol_get_name(gnutls_protocol_get_version( s->session ));
+}
+
+static const char *
+tlsg_session_cipher( tls_session *sess )
+{
+ tlsg_session *s = (tlsg_session *)sess;
+ return gnutls_cipher_get_name(gnutls_cipher_get( s->session ));
+}
+
+static int
+tlsg_session_peercert( tls_session *sess, struct berval *der )
+{
+ tlsg_session *s = (tlsg_session *)sess;
+ const gnutls_datum_t *peer_cert_list;
+ unsigned int list_size;
+
+ peer_cert_list = gnutls_certificate_get_peers( s->session, &list_size );
+ if (!peer_cert_list)
+ return -1;
+ der->bv_len = peer_cert_list[0].size;
+ der->bv_val = LDAP_MALLOC( der->bv_len );
+ if (!der->bv_val)
+ return -1;
+ memcpy(der->bv_val, peer_cert_list[0].data, der->bv_len);
+ return 0;
+}
+
/* suites is a string of colon-separated cipher suite names. */
static int
tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites )
{
#ifdef HAVE_CIPHERSUITES
const char *err;
- return gnutls_priority_init( &ctx->prios, suites, &err );
+ int rc = gnutls_priority_init( &ctx->prios, suites, &err );
+ if ( rc )
+ ctx->prios = NULL;
+ return rc;
#else
char *ptr, *end;
int i, j, len, num;
tlsg_session_peer_dn,
tlsg_session_chkhost,
tlsg_session_strength,
+ tlsg_session_unique,
+ tlsg_session_version,
+ tlsg_session_cipher,
+ tlsg_session_peercert,
&tlsg_sbio,