mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-22 07:39:35 -05:00
Add options to use DER format cert+keys directly
Instead of loading from files.
This commit is contained in:
parent
2b920ecaec
commit
b402a2805f
4 changed files with 93 additions and 6 deletions
|
|
@ -162,6 +162,9 @@ LDAP_BEGIN_DECL
|
||||||
#define LDAP_OPT_X_TLS_VERSION 0x6013 /* read-only */
|
#define LDAP_OPT_X_TLS_VERSION 0x6013 /* read-only */
|
||||||
#define LDAP_OPT_X_TLS_CIPHER 0x6014 /* read-only */
|
#define LDAP_OPT_X_TLS_CIPHER 0x6014 /* read-only */
|
||||||
#define LDAP_OPT_X_TLS_PEERCERT 0x6015 /* read-only */
|
#define LDAP_OPT_X_TLS_PEERCERT 0x6015 /* read-only */
|
||||||
|
#define LDAP_OPT_X_TLS_CACERT 0x6016
|
||||||
|
#define LDAP_OPT_X_TLS_CERT 0x6017
|
||||||
|
#define LDAP_OPT_X_TLS_KEY 0x6018
|
||||||
|
|
||||||
#define LDAP_OPT_X_TLS_NEVER 0
|
#define LDAP_OPT_X_TLS_NEVER 0
|
||||||
#define LDAP_OPT_X_TLS_HARD 1
|
#define LDAP_OPT_X_TLS_HARD 1
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,9 @@ struct ldaptls {
|
||||||
char *lt_randfile; /* OpenSSL only */
|
char *lt_randfile; /* OpenSSL only */
|
||||||
char *lt_ecname; /* OpenSSL only */
|
char *lt_ecname; /* OpenSSL only */
|
||||||
int lt_protocol_min;
|
int lt_protocol_min;
|
||||||
|
struct berval lt_cacert;
|
||||||
|
struct berval lt_cert;
|
||||||
|
struct berval lt_key;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -258,6 +261,9 @@ struct ldapoptions {
|
||||||
#define ldo_tls_protocol_min ldo_tls_info.lt_protocol_min
|
#define ldo_tls_protocol_min ldo_tls_info.lt_protocol_min
|
||||||
#define ldo_tls_crlfile ldo_tls_info.lt_crlfile
|
#define ldo_tls_crlfile ldo_tls_info.lt_crlfile
|
||||||
#define ldo_tls_randfile ldo_tls_info.lt_randfile
|
#define ldo_tls_randfile ldo_tls_info.lt_randfile
|
||||||
|
#define ldo_tls_cacert ldo_tls_info.lt_cacert
|
||||||
|
#define ldo_tls_cert ldo_tls_info.lt_cert
|
||||||
|
#define ldo_tls_key ldo_tls_info.lt_key
|
||||||
int ldo_tls_mode;
|
int ldo_tls_mode;
|
||||||
int ldo_tls_require_cert;
|
int ldo_tls_require_cert;
|
||||||
int ldo_tls_impl;
|
int ldo_tls_impl;
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,9 @@ ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
|
||||||
tls_init( ti );
|
tls_init( ti );
|
||||||
|
|
||||||
if ( is_server && !lts.lt_certfile && !lts.lt_keyfile &&
|
if ( is_server && !lts.lt_certfile && !lts.lt_keyfile &&
|
||||||
!lts.lt_cacertfile && !lts.lt_cacertdir ) {
|
!lts.lt_cacertfile && !lts.lt_cacertdir &&
|
||||||
|
!lts.lt_cacert.bv_val && !lts.lt_cert.bv_val &&
|
||||||
|
!lts.lt_key.bv_val ) {
|
||||||
/* minimum configuration not provided */
|
/* minimum configuration not provided */
|
||||||
return LDAP_NOT_SUPPORTED;
|
return LDAP_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
@ -864,6 +866,36 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
|
||||||
ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
|
ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
|
||||||
lo->ldo_tls_ctx = NULL;
|
lo->ldo_tls_ctx = NULL;
|
||||||
return ldap_int_tls_init_ctx( lo, *(int *)arg );
|
return ldap_int_tls_init_ctx( lo, *(int *)arg );
|
||||||
|
case LDAP_OPT_X_TLS_CACERT:
|
||||||
|
if ( !arg ) return -1;
|
||||||
|
if ( lo->ldo_tls_cacert.bv_val )
|
||||||
|
LDAP_FREE( lo->ldo_tls_cacert.bv_val );
|
||||||
|
lo->ldo_tls_cacert.bv_len = ((struct berval *)arg)->bv_len;
|
||||||
|
lo->ldo_tls_cacert.bv_val = LDAP_MALLOC( lo->ldo_tls_cacert.bv_len );
|
||||||
|
if ( !lo->ldo_tls_cacert.bv_val )
|
||||||
|
return -1;
|
||||||
|
AC_MEMCPY( lo->ldo_tls_cacert.bv_val, ((struct berval *)arg)->bv_val, lo->ldo_tls_cacert.bv_len );
|
||||||
|
break;
|
||||||
|
case LDAP_OPT_X_TLS_CERT:
|
||||||
|
if ( !arg ) return -1;
|
||||||
|
if ( lo->ldo_tls_cert.bv_val )
|
||||||
|
LDAP_FREE( lo->ldo_tls_cert.bv_val );
|
||||||
|
lo->ldo_tls_cert.bv_len = ((struct berval *)arg)->bv_len;
|
||||||
|
lo->ldo_tls_cert.bv_val = LDAP_MALLOC( lo->ldo_tls_cert.bv_len );
|
||||||
|
if ( !lo->ldo_tls_cert.bv_val )
|
||||||
|
return -1;
|
||||||
|
AC_MEMCPY( lo->ldo_tls_cert.bv_val, ((struct berval *)arg)->bv_val, lo->ldo_tls_cert.bv_len );
|
||||||
|
break;
|
||||||
|
case LDAP_OPT_X_TLS_KEY:
|
||||||
|
if ( !arg ) return -1;
|
||||||
|
if ( lo->ldo_tls_key.bv_val )
|
||||||
|
LDAP_FREE( lo->ldo_tls_key.bv_val );
|
||||||
|
lo->ldo_tls_key.bv_len = ((struct berval *)arg)->bv_len;
|
||||||
|
lo->ldo_tls_key.bv_val = LDAP_MALLOC( lo->ldo_tls_key.bv_len );
|
||||||
|
if ( !lo->ldo_tls_key.bv_val )
|
||||||
|
return -1;
|
||||||
|
AC_MEMCPY( lo->ldo_tls_key.bv_val, ((struct berval *)arg)->bv_val, lo->ldo_tls_key.bv_len );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ static void tlso_thr_init( void ) {}
|
||||||
#endif /* OpenSSL 1.1 */
|
#endif /* OpenSSL 1.1 */
|
||||||
|
|
||||||
static STACK_OF(X509_NAME) *
|
static STACK_OF(X509_NAME) *
|
||||||
tlso_ca_list( char * bundle, char * dir )
|
tlso_ca_list( char * bundle, char * dir, X509 *cert )
|
||||||
{
|
{
|
||||||
STACK_OF(X509_NAME) *ca_list = NULL;
|
STACK_OF(X509_NAME) *ca_list = NULL;
|
||||||
|
|
||||||
|
|
@ -136,6 +136,12 @@ tlso_ca_list( char * bundle, char * dir )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if ( cert ) {
|
||||||
|
X509_NAME *xn = X509_get_subject_name( cert );
|
||||||
|
xn = X509_NAME_dup( xn );
|
||||||
|
if ( xn )
|
||||||
|
sk_X509_NAME_push( ca_list, xn );
|
||||||
|
}
|
||||||
return ca_list;
|
return ca_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,7 +272,8 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( lo->ldo_tls_cacertfile == NULL && lo->ldo_tls_cacertdir == NULL ) {
|
if ( lo->ldo_tls_cacertfile == NULL && lo->ldo_tls_cacertdir == NULL &&
|
||||||
|
lo->ldo_tls_cacert.bv_val == NULL ) {
|
||||||
if ( !SSL_CTX_set_default_verify_paths( ctx ) ) {
|
if ( !SSL_CTX_set_default_verify_paths( ctx ) ) {
|
||||||
Debug( LDAP_DEBUG_ANY, "TLS: "
|
Debug( LDAP_DEBUG_ANY, "TLS: "
|
||||||
"could not use default certificate paths", 0, 0, 0 );
|
"could not use default certificate paths", 0, 0, 0 );
|
||||||
|
|
@ -274,7 +281,19 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( !SSL_CTX_load_verify_locations( ctx,
|
X509 *cert = NULL;
|
||||||
|
if ( lo->ldo_tls_cacert.bv_val ) {
|
||||||
|
const unsigned char *pp = lo->ldo_tls_cacert.bv_val;
|
||||||
|
cert = d2i_X509( NULL, &pp, lo->ldo_tls_cacert.bv_len );
|
||||||
|
X509_STORE *store = SSL_CTX_get_cert_store( ctx );
|
||||||
|
if ( !X509_STORE_add_cert( store, cert )) {
|
||||||
|
Debug( LDAP_DEBUG_ANY, "TLS: "
|
||||||
|
"could not use CA certificate", 0, 0, 0 );
|
||||||
|
tlso_report_error();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (( lt->lt_cacertfile || lt->lt_cacertdir ) && !SSL_CTX_load_verify_locations( ctx,
|
||||||
lt->lt_cacertfile, lt->lt_cacertdir ) )
|
lt->lt_cacertfile, lt->lt_cacertdir ) )
|
||||||
{
|
{
|
||||||
Debug( LDAP_DEBUG_ANY, "TLS: "
|
Debug( LDAP_DEBUG_ANY, "TLS: "
|
||||||
|
|
@ -289,7 +308,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
|
||||||
if ( is_server ) {
|
if ( is_server ) {
|
||||||
STACK_OF(X509_NAME) *calist;
|
STACK_OF(X509_NAME) *calist;
|
||||||
/* List of CA names to send to a client */
|
/* List of CA names to send to a client */
|
||||||
calist = tlso_ca_list( lt->lt_cacertfile, lt->lt_cacertdir );
|
calist = tlso_ca_list( lt->lt_cacertfile, lt->lt_cacertdir, cert );
|
||||||
if ( !calist ) {
|
if ( !calist ) {
|
||||||
Debug( LDAP_DEBUG_ANY, "TLS: "
|
Debug( LDAP_DEBUG_ANY, "TLS: "
|
||||||
"could not load client CA list (file:`%s',dir:`%s').\n",
|
"could not load client CA list (file:`%s',dir:`%s').\n",
|
||||||
|
|
@ -302,20 +321,47 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
|
||||||
|
|
||||||
SSL_CTX_set_client_CA_list( ctx, calist );
|
SSL_CTX_set_client_CA_list( ctx, calist );
|
||||||
}
|
}
|
||||||
|
if ( cert )
|
||||||
|
X509_free( cert );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( lo->ldo_tls_cert.bv_val )
|
||||||
|
{
|
||||||
|
const unsigned char *pp = lo->ldo_tls_cert.bv_val;
|
||||||
|
X509 *cert = d2i_X509( NULL, &pp, lo->ldo_tls_cert.bv_len );
|
||||||
|
if ( !SSL_CTX_use_certificate( ctx, cert )) {
|
||||||
|
Debug( LDAP_DEBUG_ANY,
|
||||||
|
"TLS: could not use certificate.\n", 0,0,0);
|
||||||
|
tlso_report_error();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
X509_free( cert );
|
||||||
|
} else
|
||||||
if ( lo->ldo_tls_certfile &&
|
if ( lo->ldo_tls_certfile &&
|
||||||
!SSL_CTX_use_certificate_file( ctx,
|
!SSL_CTX_use_certificate_file( ctx,
|
||||||
lt->lt_certfile, SSL_FILETYPE_PEM ) )
|
lt->lt_certfile, SSL_FILETYPE_PEM ) )
|
||||||
{
|
{
|
||||||
Debug( LDAP_DEBUG_ANY,
|
Debug( LDAP_DEBUG_ANY,
|
||||||
"TLS: could not use certificate `%s'.\n",
|
"TLS: could not use certificate file `%s'.\n",
|
||||||
lo->ldo_tls_certfile,0,0);
|
lo->ldo_tls_certfile,0,0);
|
||||||
tlso_report_error();
|
tlso_report_error();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Key validity is checked automatically if cert has already been set */
|
/* Key validity is checked automatically if cert has already been set */
|
||||||
|
if ( lo->ldo_tls_key.bv_val )
|
||||||
|
{
|
||||||
|
const unsigned char *pp = lo->ldo_tls_key.bv_val;
|
||||||
|
EVP_PKEY *pkey = d2i_AutoPrivateKey( NULL, &pp, lo->ldo_tls_key.bv_len );
|
||||||
|
if ( !SSL_CTX_use_PrivateKey( ctx, pkey ))
|
||||||
|
{
|
||||||
|
Debug( LDAP_DEBUG_ANY,
|
||||||
|
"TLS: could not use private key.\n", 0,0,0);
|
||||||
|
tlso_report_error();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
EVP_PKEY_free( pkey );
|
||||||
|
} else
|
||||||
if ( lo->ldo_tls_keyfile &&
|
if ( lo->ldo_tls_keyfile &&
|
||||||
!SSL_CTX_use_PrivateKey_file( ctx,
|
!SSL_CTX_use_PrivateKey_file( ctx,
|
||||||
lt->lt_keyfile, SSL_FILETYPE_PEM ) )
|
lt->lt_keyfile, SSL_FILETYPE_PEM ) )
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue