mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
ITS#7877 assume gnutls provides cipher suites
This commit is contained in:
parent
829027945f
commit
0fd0f24f03
@ -44,38 +44,13 @@
|
|||||||
#include <gnutls/gnutls.h>
|
#include <gnutls/gnutls.h>
|
||||||
#include <gnutls/x509.h>
|
#include <gnutls/x509.h>
|
||||||
|
|
||||||
#if LIBGNUTLS_VERSION_NUMBER >= 0x020200
|
|
||||||
#define HAVE_CIPHERSUITES 1
|
|
||||||
#else
|
|
||||||
#undef HAVE_CIPHERSUITES
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_CIPHERSUITES
|
|
||||||
/* Versions prior to 2.2.0 didn't handle cipher suites, so we had to
|
|
||||||
* kludge them ourselves.
|
|
||||||
*/
|
|
||||||
typedef struct tls_cipher_suite {
|
|
||||||
const char *name;
|
|
||||||
gnutls_kx_algorithm_t kx;
|
|
||||||
gnutls_cipher_algorithm_t cipher;
|
|
||||||
gnutls_mac_algorithm_t mac;
|
|
||||||
gnutls_protocol_t version;
|
|
||||||
} tls_cipher_suite;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct tlsg_ctx {
|
typedef struct tlsg_ctx {
|
||||||
struct ldapoptions *lo;
|
struct ldapoptions *lo;
|
||||||
gnutls_certificate_credentials_t cred;
|
gnutls_certificate_credentials_t cred;
|
||||||
gnutls_dh_params_t dh_params;
|
gnutls_dh_params_t dh_params;
|
||||||
unsigned long verify_depth;
|
unsigned long verify_depth;
|
||||||
int refcount;
|
int refcount;
|
||||||
#ifdef HAVE_CIPHERSUITES
|
|
||||||
gnutls_priority_t prios;
|
gnutls_priority_t prios;
|
||||||
#else
|
|
||||||
int *kx_list;
|
|
||||||
int *cipher_list;
|
|
||||||
int *mac_list;
|
|
||||||
#endif
|
|
||||||
#ifdef LDAP_R_COMPILE
|
#ifdef LDAP_R_COMPILE
|
||||||
ldap_pvt_thread_mutex_t ref_mutex;
|
ldap_pvt_thread_mutex_t ref_mutex;
|
||||||
#endif
|
#endif
|
||||||
@ -87,11 +62,6 @@ typedef struct tlsg_session {
|
|||||||
struct berval peer_der_dn;
|
struct berval peer_der_dn;
|
||||||
} tlsg_session;
|
} tlsg_session;
|
||||||
|
|
||||||
#ifndef HAVE_CIPHERSUITES
|
|
||||||
static tls_cipher_suite *tlsg_ciphers;
|
|
||||||
static int tlsg_n_ciphers;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites );
|
static int tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites );
|
||||||
static int tlsg_cert_verify( tlsg_session *s );
|
static int tlsg_cert_verify( tlsg_session *s );
|
||||||
|
|
||||||
@ -152,35 +122,6 @@ static int
|
|||||||
tlsg_init( void )
|
tlsg_init( void )
|
||||||
{
|
{
|
||||||
gnutls_global_init();
|
gnutls_global_init();
|
||||||
|
|
||||||
#ifndef HAVE_CIPHERSUITES
|
|
||||||
/* GNUtls cipher suite handling: The library ought to parse suite
|
|
||||||
* names for us, but it doesn't. It will return a list of suite names
|
|
||||||
* that it supports, so we can do parsing ourselves. It ought to tell
|
|
||||||
* us how long the list is, but it doesn't do that either, so we just
|
|
||||||
* have to count it manually...
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
tls_cipher_suite *ptr, tmp;
|
|
||||||
char cs_id[2];
|
|
||||||
|
|
||||||
while ( gnutls_cipher_suite_info( i, cs_id, &tmp.kx, &tmp.cipher,
|
|
||||||
&tmp.mac, &tmp.version ))
|
|
||||||
i++;
|
|
||||||
tlsg_n_ciphers = i;
|
|
||||||
|
|
||||||
/* Store a copy */
|
|
||||||
tlsg_ciphers = LDAP_MALLOC(tlsg_n_ciphers * sizeof(tls_cipher_suite));
|
|
||||||
if ( !tlsg_ciphers )
|
|
||||||
return -1;
|
|
||||||
for ( i=0; i<tlsg_n_ciphers; i++ ) {
|
|
||||||
tlsg_ciphers[i].name = gnutls_cipher_suite_info( i, cs_id,
|
|
||||||
&tlsg_ciphers[i].kx, &tlsg_ciphers[i].cipher, &tlsg_ciphers[i].mac,
|
|
||||||
&tlsg_ciphers[i].version );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,11 +131,6 @@ tlsg_init( void )
|
|||||||
static void
|
static void
|
||||||
tlsg_destroy( void )
|
tlsg_destroy( void )
|
||||||
{
|
{
|
||||||
#ifndef HAVE_CIPHERSUITES
|
|
||||||
LDAP_FREE( tlsg_ciphers );
|
|
||||||
tlsg_ciphers = NULL;
|
|
||||||
tlsg_n_ciphers = 0;
|
|
||||||
#endif
|
|
||||||
gnutls_global_deinit();
|
gnutls_global_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,9 +147,7 @@ tlsg_ctx_new ( struct ldapoptions *lo )
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
ctx->refcount = 1;
|
ctx->refcount = 1;
|
||||||
#ifdef HAVE_CIPHERSUITES
|
|
||||||
gnutls_priority_init( &ctx->prios, "NORMAL", NULL );
|
gnutls_priority_init( &ctx->prios, "NORMAL", NULL );
|
||||||
#endif
|
|
||||||
#ifdef LDAP_R_COMPILE
|
#ifdef LDAP_R_COMPILE
|
||||||
ldap_pvt_thread_mutex_init( &ctx->ref_mutex );
|
ldap_pvt_thread_mutex_init( &ctx->ref_mutex );
|
||||||
#endif
|
#endif
|
||||||
@ -243,11 +177,7 @@ tlsg_ctx_free ( tls_ctx *ctx )
|
|||||||
LDAP_MUTEX_UNLOCK( &c->ref_mutex );
|
LDAP_MUTEX_UNLOCK( &c->ref_mutex );
|
||||||
if ( refcount )
|
if ( refcount )
|
||||||
return;
|
return;
|
||||||
#ifdef HAVE_CIPHERSUITES
|
|
||||||
gnutls_priority_deinit( c->prios );
|
gnutls_priority_deinit( c->prios );
|
||||||
#else
|
|
||||||
LDAP_FREE( c->kx_list );
|
|
||||||
#endif
|
|
||||||
gnutls_certificate_free_credentials( c->cred );
|
gnutls_certificate_free_credentials( c->cred );
|
||||||
if ( c->dh_params )
|
if ( c->dh_params )
|
||||||
gnutls_dh_params_deinit( c->dh_params );
|
gnutls_dh_params_deinit( c->dh_params );
|
||||||
@ -425,16 +355,7 @@ tlsg_session_new ( tls_ctx * ctx, int is_server )
|
|||||||
|
|
||||||
session->ctx = c;
|
session->ctx = c;
|
||||||
gnutls_init( &session->session, is_server ? GNUTLS_SERVER : GNUTLS_CLIENT );
|
gnutls_init( &session->session, is_server ? GNUTLS_SERVER : GNUTLS_CLIENT );
|
||||||
#ifdef HAVE_CIPHERSUITES
|
|
||||||
gnutls_priority_set( session->session, c->prios );
|
gnutls_priority_set( session->session, c->prios );
|
||||||
#else
|
|
||||||
gnutls_set_default_priority( session->session );
|
|
||||||
if ( c->kx_list ) {
|
|
||||||
gnutls_kx_set_priority( session->session, c->kx_list );
|
|
||||||
gnutls_cipher_set_priority( session->session, c->cipher_list );
|
|
||||||
gnutls_mac_set_priority( session->session, c->mac_list );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if ( c->cred )
|
if ( c->cred )
|
||||||
gnutls_credentials_set( session->session, GNUTLS_CRD_CERTIFICATE, c->cred );
|
gnutls_credentials_set( session->session, GNUTLS_CRD_CERTIFICATE, c->cred );
|
||||||
|
|
||||||
@ -826,88 +747,11 @@ tlsg_session_peercert( tls_session *sess, struct berval *der )
|
|||||||
static int
|
static int
|
||||||
tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites )
|
tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites )
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CIPHERSUITES
|
|
||||||
const char *err;
|
const char *err;
|
||||||
int rc = gnutls_priority_init( &ctx->prios, suites, &err );
|
int rc = gnutls_priority_init( &ctx->prios, suites, &err );
|
||||||
if ( rc )
|
if ( rc )
|
||||||
ctx->prios = NULL;
|
ctx->prios = NULL;
|
||||||
return rc;
|
return rc;
|
||||||
#else
|
|
||||||
char *ptr, *end;
|
|
||||||
int i, j, len, num;
|
|
||||||
int *list, nkx = 0, ncipher = 0, nmac = 0;
|
|
||||||
int *kx, *cipher, *mac;
|
|
||||||
|
|
||||||
num = 0;
|
|
||||||
ptr = suites;
|
|
||||||
do {
|
|
||||||
end = strchr(ptr, ':');
|
|
||||||
if ( end )
|
|
||||||
len = end - ptr;
|
|
||||||
else
|
|
||||||
len = strlen(ptr);
|
|
||||||
for (i=0; i<tlsg_n_ciphers; i++) {
|
|
||||||
if ( !strncasecmp( tlsg_ciphers[i].name, ptr, len )) {
|
|
||||||
num++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( i == tlsg_n_ciphers ) {
|
|
||||||
/* unrecognized cipher suite */
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
ptr += len + 1;
|
|
||||||
} while (end);
|
|
||||||
|
|
||||||
/* Space for all 3 lists */
|
|
||||||
list = LDAP_MALLOC( (num+1) * sizeof(int) * 3 );
|
|
||||||
if ( !list )
|
|
||||||
return -1;
|
|
||||||
kx = list;
|
|
||||||
cipher = kx+num+1;
|
|
||||||
mac = cipher+num+1;
|
|
||||||
|
|
||||||
ptr = suites;
|
|
||||||
do {
|
|
||||||
end = strchr(ptr, ':');
|
|
||||||
if ( end )
|
|
||||||
len = end - ptr;
|
|
||||||
else
|
|
||||||
len = strlen(ptr);
|
|
||||||
for (i=0; i<tlsg_n_ciphers; i++) {
|
|
||||||
/* For each cipher suite, insert its algorithms into
|
|
||||||
* their respective priority lists. Make sure they
|
|
||||||
* only appear once in each list.
|
|
||||||
*/
|
|
||||||
if ( !strncasecmp( tlsg_ciphers[i].name, ptr, len )) {
|
|
||||||
for (j=0; j<nkx; j++)
|
|
||||||
if ( kx[j] == tlsg_ciphers[i].kx )
|
|
||||||
break;
|
|
||||||
if ( j == nkx )
|
|
||||||
kx[nkx++] = tlsg_ciphers[i].kx;
|
|
||||||
for (j=0; j<ncipher; j++)
|
|
||||||
if ( cipher[j] == tlsg_ciphers[i].cipher )
|
|
||||||
break;
|
|
||||||
if ( j == ncipher )
|
|
||||||
cipher[ncipher++] = tlsg_ciphers[i].cipher;
|
|
||||||
for (j=0; j<nmac; j++)
|
|
||||||
if ( mac[j] == tlsg_ciphers[i].mac )
|
|
||||||
break;
|
|
||||||
if ( j == nmac )
|
|
||||||
mac[nmac++] = tlsg_ciphers[i].mac;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ptr += len + 1;
|
|
||||||
} while (end);
|
|
||||||
kx[nkx] = 0;
|
|
||||||
cipher[ncipher] = 0;
|
|
||||||
mac[nmac] = 0;
|
|
||||||
ctx->kx_list = kx;
|
|
||||||
ctx->cipher_list = cipher;
|
|
||||||
ctx->mac_list = mac;
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user