mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-04-06 15:00:40 +08:00
ITS#7398 add LDAP_OPT_X_TLS_PEERCERT
retrieve peer cert for an active TLS session
This commit is contained in:
parent
0045e56c34
commit
16f8b0902c
@ -732,6 +732,14 @@ A non-zero value pointed to by
|
||||
.BR invalue
|
||||
tells the library to create a context for a server.
|
||||
.TP
|
||||
.B LDAP_OPT_X_TLS_PEERCERT
|
||||
Gets the peer's certificate in DER format from an established TLS session.
|
||||
.BR outvalue
|
||||
must be
|
||||
.BR "struct berval *" ,
|
||||
and the data it returns needs to be freed by the caller using
|
||||
.BR ldap_memfree (3).
|
||||
.TP
|
||||
.B LDAP_OPT_X_TLS_PROTOCOL_MIN
|
||||
Sets/gets the minimum protocol version.
|
||||
.BR invalue
|
||||
|
@ -161,6 +161,7 @@ LDAP_BEGIN_DECL
|
||||
#define LDAP_OPT_X_TLS_ECNAME 0x6012
|
||||
#define LDAP_OPT_X_TLS_VERSION 0x6013 /* 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_NEVER 0
|
||||
#define LDAP_OPT_X_TLS_HARD 1
|
||||
|
@ -43,6 +43,7 @@ typedef int (TI_session_chkhost)(LDAP *ld, tls_session *s, const char *name_in);
|
||||
typedef int (TI_session_strength)(tls_session *sess);
|
||||
typedef int (TI_session_unique)(tls_session *sess, struct berval *buf, int is_server);
|
||||
typedef const char *(TI_session_name)(tls_session *s);
|
||||
typedef int (TI_session_peercert)(tls_session *s, struct berval *der);
|
||||
|
||||
typedef void (TI_thr_init)(void);
|
||||
|
||||
@ -69,6 +70,7 @@ typedef struct tls_impl {
|
||||
TI_session_unique *ti_session_unique;
|
||||
TI_session_name *ti_session_version;
|
||||
TI_session_name *ti_session_cipher;
|
||||
TI_session_peercert *ti_session_peercert;
|
||||
|
||||
Sockbuf_IO *ti_sbio;
|
||||
|
||||
|
@ -718,6 +718,22 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
|
||||
*(char **)arg = retval ? LDAP_STRDUP( retval ) : NULL;
|
||||
break;
|
||||
}
|
||||
case LDAP_OPT_X_TLS_PEERCERT: {
|
||||
void *sess = NULL;
|
||||
struct berval *bv = arg;
|
||||
bv->bv_len = 0;
|
||||
bv->bv_val = NULL;
|
||||
if ( ld != NULL ) {
|
||||
LDAPConn *conn = ld->ld_defconn;
|
||||
if ( conn != NULL ) {
|
||||
Sockbuf *sb = conn->lconn_sb;
|
||||
sess = ldap_pvt_tls_sb_ctx( sb );
|
||||
if ( sess != NULL )
|
||||
return ldap_pvt_tls_get_peercert( sess, bv );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
@ -1050,6 +1066,13 @@ ldap_pvt_tls_get_cipher( void *s )
|
||||
tls_session *session = s;
|
||||
return tls_imp->ti_session_cipher( session );
|
||||
}
|
||||
|
||||
int
|
||||
ldap_pvt_tls_get_peercert( void *s, struct berval *der )
|
||||
{
|
||||
tls_session *session = s;
|
||||
return tls_imp->ti_session_peercert( session, der );
|
||||
}
|
||||
#endif /* HAVE_TLS */
|
||||
|
||||
int
|
||||
|
@ -830,6 +830,24 @@ tlsg_session_cipher( tls_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 )
|
||||
@ -1166,6 +1184,7 @@ tls_impl ldap_int_tls_impl = {
|
||||
tlsg_session_unique,
|
||||
tlsg_session_version,
|
||||
tlsg_session_cipher,
|
||||
tlsg_session_peercert,
|
||||
|
||||
&tlsg_sbio,
|
||||
|
||||
|
@ -2891,6 +2891,22 @@ tlsm_session_cipher( tls_session *sess )
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static int
|
||||
tlsm_session_peercert( tls_session *sess, struct berval *der )
|
||||
{
|
||||
tlsm_session *s = (tlsm_session *)sess;
|
||||
CERTCertificate *cert;
|
||||
cert = SSL_PeerCertificate( s );
|
||||
if (!cert)
|
||||
return -1;
|
||||
der->bv_len = cert->derCert.len;
|
||||
der->bv_val = LDAP_MALLOC( der->bv_len );
|
||||
if (!der->bv_val)
|
||||
return -1;
|
||||
memcpy( der->bv_val, cert->derCert.data, der->bv_len );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS support for LBER Sockbufs
|
||||
*/
|
||||
@ -3322,6 +3338,7 @@ tls_impl ldap_int_tls_impl = {
|
||||
tlsm_session_unique,
|
||||
tlsm_session_version,
|
||||
tlsm_session_cipher,
|
||||
tlsm_session_peercert,
|
||||
|
||||
&tlsm_sbio,
|
||||
|
||||
|
@ -721,6 +721,21 @@ tlso_session_cipher( tls_session *sess )
|
||||
return SSL_CIPHER_get_name(SSL_get_current_cipher(s));
|
||||
}
|
||||
|
||||
static int
|
||||
tlso_session_peercert( tls_session *sess, struct berval *der )
|
||||
{
|
||||
tlso_session *s = (tlso_session *)sess;
|
||||
unsigned char *ptr;
|
||||
X509 *x = SSL_get_peer_certificate(s);
|
||||
der->bv_len = i2d_X509(x, NULL);
|
||||
der->bv_val = LDAP_MALLOC(der->bv_len);
|
||||
if ( !der->bv_val )
|
||||
return -1;
|
||||
ptr = der->bv_val;
|
||||
i2d_X509(x, &ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS support for LBER Sockbufs
|
||||
*/
|
||||
@ -1229,6 +1244,7 @@ tls_impl ldap_int_tls_impl = {
|
||||
tlso_session_unique,
|
||||
tlso_session_version,
|
||||
tlso_session_cipher,
|
||||
tlso_session_peercert,
|
||||
|
||||
&tlso_sbio,
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user