mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-04-24 06:02:44 +00:00
Merge pull request #5620 from gstrauss/dn_hints
Add accessors to config DN hints for cert request
This commit is contained in:
commit
bae7a1a5a6
3
ChangeLog.d/mbedtls_ssl_dn_hint.txt
Normal file
3
ChangeLog.d/mbedtls_ssl_dn_hint.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Features
|
||||||
|
* Add accessors to configure DN hints for certificate request:
|
||||||
|
mbedtls_ssl_conf_dn_hints() and mbedtls_ssl_set_hs_dn_hints()
|
@ -1496,6 +1496,10 @@ struct mbedtls_ssl_config
|
|||||||
#if defined(MBEDTLS_SSL_SRV_C)
|
#if defined(MBEDTLS_SSL_SRV_C)
|
||||||
mbedtls_ssl_hs_cb_t MBEDTLS_PRIVATE(f_cert_cb); /*!< certificate selection callback */
|
mbedtls_ssl_hs_cb_t MBEDTLS_PRIVATE(f_cert_cb); /*!< certificate selection callback */
|
||||||
#endif /* MBEDTLS_SSL_SRV_C */
|
#endif /* MBEDTLS_SSL_SRV_C */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
const mbedtls_x509_crt *MBEDTLS_PRIVATE(dn_hints);/*!< acceptable client cert issuers */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mbedtls_ssl_context
|
struct mbedtls_ssl_context
|
||||||
@ -3128,6 +3132,26 @@ void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf,
|
|||||||
mbedtls_x509_crt *ca_chain,
|
mbedtls_x509_crt *ca_chain,
|
||||||
mbedtls_x509_crl *ca_crl );
|
mbedtls_x509_crl *ca_crl );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
/**
|
||||||
|
* \brief Set DN hints sent to client in CertificateRequest message
|
||||||
|
*
|
||||||
|
* \note If not set, subject distinguished names (DNs) are taken
|
||||||
|
* from \c mbedtls_ssl_conf_ca_chain()
|
||||||
|
* or \c mbedtls_ssl_set_hs_ca_chain())
|
||||||
|
*
|
||||||
|
* \param conf SSL configuration
|
||||||
|
* \param crt crt chain whose subject DNs are issuer DNs of client certs
|
||||||
|
* from which the client should select client peer certificate.
|
||||||
|
*/
|
||||||
|
static inline
|
||||||
|
void mbedtls_ssl_conf_dn_hints( mbedtls_ssl_config *conf,
|
||||||
|
const mbedtls_x509_crt *crt )
|
||||||
|
{
|
||||||
|
conf->MBEDTLS_PRIVATE(dn_hints) = crt;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
|
||||||
|
|
||||||
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
|
#if defined(MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK)
|
||||||
/**
|
/**
|
||||||
* \brief Set the trusted certificate callback.
|
* \brief Set the trusted certificate callback.
|
||||||
@ -3652,6 +3676,21 @@ void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
|
|||||||
mbedtls_x509_crt *ca_chain,
|
mbedtls_x509_crt *ca_chain,
|
||||||
mbedtls_x509_crl *ca_crl );
|
mbedtls_x509_crl *ca_crl );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
/**
|
||||||
|
* \brief Set DN hints sent to client in CertificateRequest message
|
||||||
|
*
|
||||||
|
* \note Same as \c mbedtls_ssl_conf_dn_hints() but for use within
|
||||||
|
* the SNI callback or the certificate selection callback.
|
||||||
|
*
|
||||||
|
* \param ssl SSL context
|
||||||
|
* \param crt crt chain whose subject DNs are issuer DNs of client certs
|
||||||
|
* from which the client should select client peer certificate.
|
||||||
|
*/
|
||||||
|
void mbedtls_ssl_set_hs_dn_hints( mbedtls_ssl_context *ssl,
|
||||||
|
const mbedtls_x509_crt *crt );
|
||||||
|
#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set authmode for the current handshake.
|
* \brief Set authmode for the current handshake.
|
||||||
*
|
*
|
||||||
|
@ -850,6 +850,9 @@ struct mbedtls_ssl_handshake_params
|
|||||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||||
const unsigned char *sni_name; /*!< raw SNI */
|
const unsigned char *sni_name; /*!< raw SNI */
|
||||||
size_t sni_name_len; /*!< raw SNI len */
|
size_t sni_name_len; /*!< raw SNI len */
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
const mbedtls_x509_crt *dn_hints; /*!< acceptable client cert issuers */
|
||||||
|
#endif
|
||||||
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1472,6 +1472,14 @@ void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl,
|
|||||||
ssl->handshake->sni_ca_crl = ca_crl;
|
ssl->handshake->sni_ca_crl = ca_crl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
void mbedtls_ssl_set_hs_dn_hints( mbedtls_ssl_context *ssl,
|
||||||
|
const mbedtls_x509_crt *crt)
|
||||||
|
{
|
||||||
|
ssl->handshake->dn_hints = crt;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED */
|
||||||
|
|
||||||
void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
|
void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl,
|
||||||
int authmode )
|
int authmode )
|
||||||
{
|
{
|
||||||
|
@ -2534,6 +2534,7 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
|
|||||||
size_t sig_alg_len;
|
size_t sig_alg_len;
|
||||||
#if defined(MBEDTLS_DEBUG_C)
|
#if defined(MBEDTLS_DEBUG_C)
|
||||||
unsigned char *sig_alg;
|
unsigned char *sig_alg;
|
||||||
|
unsigned char *dn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) );
|
||||||
@ -2681,6 +2682,43 @@ static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl )
|
|||||||
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
|
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_DEBUG_C)
|
||||||
|
dn = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n - dn_len;
|
||||||
|
for( size_t i = 0, dni_len = 0; i < dn_len; i += 2 + dni_len )
|
||||||
|
{
|
||||||
|
unsigned char *p = dn + i + 2;
|
||||||
|
mbedtls_x509_name name;
|
||||||
|
mbedtls_x509_name *name_cur, *name_prv;
|
||||||
|
size_t asn1_len;
|
||||||
|
char s[MBEDTLS_X509_MAX_DN_NAME_SIZE];
|
||||||
|
memset( &name, 0, sizeof( name ) );
|
||||||
|
dni_len = MBEDTLS_GET_UINT16_BE( dn + i, 0 );
|
||||||
|
if( dni_len > dn_len - i - 2 ||
|
||||||
|
mbedtls_asn1_get_tag( &p, p + dni_len, &asn1_len,
|
||||||
|
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) != 0 ||
|
||||||
|
mbedtls_x509_get_name( &p, p + asn1_len, &name ) != 0 )
|
||||||
|
{
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) );
|
||||||
|
mbedtls_ssl_send_alert_message(
|
||||||
|
ssl,
|
||||||
|
MBEDTLS_SSL_ALERT_LEVEL_FATAL,
|
||||||
|
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
|
||||||
|
return( MBEDTLS_ERR_SSL_DECODE_ERROR );
|
||||||
|
}
|
||||||
|
MBEDTLS_SSL_DEBUG_MSG( 3,
|
||||||
|
( "DN hint: %.*s",
|
||||||
|
mbedtls_x509_dn_gets( s, sizeof(s), &name ), s ) );
|
||||||
|
name_cur = name.next;
|
||||||
|
while( name_cur != NULL )
|
||||||
|
{
|
||||||
|
name_prv = name_cur;
|
||||||
|
name_cur = name_cur->next;
|
||||||
|
mbedtls_platform_zeroize( name_prv, sizeof( mbedtls_x509_name ) );
|
||||||
|
mbedtls_free( name_prv );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
|
MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) );
|
||||||
|
|
||||||
|
@ -2489,6 +2489,16 @@ static int ssl_write_certificate_request( mbedtls_ssl_context *ssl )
|
|||||||
* `mbedtls_ssl_conf_ca_cb()`, then the
|
* `mbedtls_ssl_conf_ca_cb()`, then the
|
||||||
* CertificateRequest is currently left empty. */
|
* CertificateRequest is currently left empty. */
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||||
|
if( ssl->handshake->dn_hints != NULL )
|
||||||
|
crt = ssl->handshake->dn_hints;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if( ssl->conf->dn_hints != NULL )
|
||||||
|
crt = ssl->conf->dn_hints;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||||
if( ssl->handshake->sni_ca_chain != NULL )
|
if( ssl->handshake->sni_ca_chain != NULL )
|
||||||
crt = ssl->handshake->sni_ca_chain;
|
crt = ssl->handshake->sni_ca_chain;
|
||||||
|
@ -116,6 +116,7 @@ int main( void )
|
|||||||
#define DFL_CID_VALUE_RENEGO NULL
|
#define DFL_CID_VALUE_RENEGO NULL
|
||||||
#define DFL_AUTH_MODE -1
|
#define DFL_AUTH_MODE -1
|
||||||
#define DFL_CERT_REQ_CA_LIST MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED
|
#define DFL_CERT_REQ_CA_LIST MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED
|
||||||
|
#define DFL_CERT_REQ_DN_HINT 0
|
||||||
#define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE
|
#define DFL_MFL_CODE MBEDTLS_SSL_MAX_FRAG_LEN_NONE
|
||||||
#define DFL_TRUNC_HMAC -1
|
#define DFL_TRUNC_HMAC -1
|
||||||
#define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED
|
#define DFL_TICKETS MBEDTLS_SSL_SESSION_TICKETS_ENABLED
|
||||||
@ -506,6 +507,7 @@ int main( void )
|
|||||||
" options: none, optional, required\n" \
|
" options: none, optional, required\n" \
|
||||||
" cert_req_ca_list=%%d default: 1 (send ca list)\n" \
|
" cert_req_ca_list=%%d default: 1 (send ca list)\n" \
|
||||||
" options: 1 (send ca list), 0 (don't send)\n" \
|
" options: 1 (send ca list), 0 (don't send)\n" \
|
||||||
|
" 2 (send conf dn hint), 3 (send hs dn hint)\n" \
|
||||||
USAGE_IO \
|
USAGE_IO \
|
||||||
USAGE_KEY_OPAQUE \
|
USAGE_KEY_OPAQUE \
|
||||||
"\n" \
|
"\n" \
|
||||||
@ -629,6 +631,7 @@ struct options
|
|||||||
int allow_sha1; /* flag for SHA-1 support */
|
int allow_sha1; /* flag for SHA-1 support */
|
||||||
int auth_mode; /* verify mode for connection */
|
int auth_mode; /* verify mode for connection */
|
||||||
int cert_req_ca_list; /* should we send the CA list? */
|
int cert_req_ca_list; /* should we send the CA list? */
|
||||||
|
int cert_req_dn_hint; /* mode to set DN hints for CA list to send */
|
||||||
unsigned char mfl_code; /* code for maximum fragment length */
|
unsigned char mfl_code; /* code for maximum fragment length */
|
||||||
int trunc_hmac; /* accept truncated hmac? */
|
int trunc_hmac; /* accept truncated hmac? */
|
||||||
int tickets; /* enable / disable session tickets */
|
int tickets; /* enable / disable session tickets */
|
||||||
@ -1597,6 +1600,7 @@ int main( int argc, char *argv[] )
|
|||||||
opt.allow_sha1 = DFL_SHA1;
|
opt.allow_sha1 = DFL_SHA1;
|
||||||
opt.auth_mode = DFL_AUTH_MODE;
|
opt.auth_mode = DFL_AUTH_MODE;
|
||||||
opt.cert_req_ca_list = DFL_CERT_REQ_CA_LIST;
|
opt.cert_req_ca_list = DFL_CERT_REQ_CA_LIST;
|
||||||
|
opt.cert_req_dn_hint = DFL_CERT_REQ_DN_HINT;
|
||||||
opt.mfl_code = DFL_MFL_CODE;
|
opt.mfl_code = DFL_MFL_CODE;
|
||||||
opt.trunc_hmac = DFL_TRUNC_HMAC;
|
opt.trunc_hmac = DFL_TRUNC_HMAC;
|
||||||
opt.tickets = DFL_TICKETS;
|
opt.tickets = DFL_TICKETS;
|
||||||
@ -1923,8 +1927,13 @@ int main( int argc, char *argv[] )
|
|||||||
else if( strcmp( p, "cert_req_ca_list" ) == 0 )
|
else if( strcmp( p, "cert_req_ca_list" ) == 0 )
|
||||||
{
|
{
|
||||||
opt.cert_req_ca_list = atoi( q );
|
opt.cert_req_ca_list = atoi( q );
|
||||||
if( opt.cert_req_ca_list < 0 || opt.cert_req_ca_list > 1 )
|
if( opt.cert_req_ca_list < 0 || opt.cert_req_ca_list > 3 )
|
||||||
goto usage;
|
goto usage;
|
||||||
|
if( opt.cert_req_ca_list > 1 )
|
||||||
|
{
|
||||||
|
opt.cert_req_dn_hint = opt.cert_req_ca_list;
|
||||||
|
opt.cert_req_ca_list = MBEDTLS_SSL_CERT_REQ_CA_LIST_ENABLED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( strcmp( p, "max_frag_len" ) == 0 )
|
else if( strcmp( p, "max_frag_len" ) == 0 )
|
||||||
{
|
{
|
||||||
@ -2732,6 +2741,16 @@ int main( int argc, char *argv[] )
|
|||||||
if( opt.cert_req_ca_list != DFL_CERT_REQ_CA_LIST )
|
if( opt.cert_req_ca_list != DFL_CERT_REQ_CA_LIST )
|
||||||
mbedtls_ssl_conf_cert_req_ca_list( &conf, opt.cert_req_ca_list );
|
mbedtls_ssl_conf_cert_req_ca_list( &conf, opt.cert_req_ca_list );
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
/* exercise setting DN hints for server certificate request
|
||||||
|
* (Intended for use where the client cert expected has been signed by
|
||||||
|
* a specific CA which is an intermediate in a CA chain, not the root) */
|
||||||
|
if( opt.cert_req_dn_hint == 2 && key_cert_init2 )
|
||||||
|
mbedtls_ssl_conf_dn_hints( &conf, &srvcert2 );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
#if defined(MBEDTLS_SSL_PROTO_DTLS)
|
||||||
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
|
if( opt.hs_to_min != DFL_HS_TO_MIN || opt.hs_to_max != DFL_HS_TO_MAX )
|
||||||
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
|
mbedtls_ssl_conf_handshake_timeout( &conf, opt.hs_to_min, opt.hs_to_max );
|
||||||
@ -3332,6 +3351,20 @@ reset:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_X509_CRT_PARSE_C)
|
||||||
|
#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION)
|
||||||
|
#if defined(MBEDTLS_KEY_EXCHANGE_CERT_REQ_ALLOWED_ENABLED)
|
||||||
|
/* exercise setting DN hints for server certificate request
|
||||||
|
* (Intended for use where the client cert expected has been signed by
|
||||||
|
* a specific CA which is an intermediate in a CA chain, not the root)
|
||||||
|
* (Additionally, the CA choice would typically be influenced by SNI
|
||||||
|
* if being set per-handshake using mbedtls_ssl_set_hs_dn_hints()) */
|
||||||
|
if( opt.cert_req_dn_hint == 3 && key_cert_init2 )
|
||||||
|
mbedtls_ssl_set_hs_dn_hints( &ssl, &srvcert2 );
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
mbedtls_printf( " ok\n" );
|
mbedtls_printf( " ok\n" );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -5116,6 +5116,39 @@ run_test "Authentication: send CA list in CertificateRequest, client self sig
|
|||||||
-c "! mbedtls_ssl_handshake returned" \
|
-c "! mbedtls_ssl_handshake returned" \
|
||||||
-s "X509 - Certificate verification failed"
|
-s "X509 - Certificate verification failed"
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||||
|
run_test "Authentication: send alt conf DN hints in CertificateRequest" \
|
||||||
|
"$P_SRV debug_level=3 auth_mode=optional cert_req_ca_list=2 \
|
||||||
|
crt_file2=data_files/server1.crt \
|
||||||
|
key_file2=data_files/server1.key" \
|
||||||
|
"$P_CLI debug_level=3 auth_mode=optional \
|
||||||
|
crt_file=data_files/server6.crt \
|
||||||
|
key_file=data_files/server6.key" \
|
||||||
|
0 \
|
||||||
|
-c "DN hint: C=NL, O=PolarSSL, CN=PolarSSL Server 1"
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||||
|
run_test "Authentication: send alt conf DN hints in CertificateRequest (2)" \
|
||||||
|
"$P_SRV debug_level=3 auth_mode=optional cert_req_ca_list=2 \
|
||||||
|
crt_file2=data_files/server2.crt \
|
||||||
|
key_file2=data_files/server2.key" \
|
||||||
|
"$P_CLI debug_level=3 auth_mode=optional \
|
||||||
|
crt_file=data_files/server6.crt \
|
||||||
|
key_file=data_files/server6.key" \
|
||||||
|
0 \
|
||||||
|
-c "DN hint: C=NL, O=PolarSSL, CN=localhost"
|
||||||
|
|
||||||
|
requires_config_enabled MBEDTLS_SSL_PROTO_TLS1_2
|
||||||
|
run_test "Authentication: send alt hs DN hints in CertificateRequest" \
|
||||||
|
"$P_SRV debug_level=3 auth_mode=optional cert_req_ca_list=3 \
|
||||||
|
crt_file2=data_files/server1.crt \
|
||||||
|
key_file2=data_files/server1.key" \
|
||||||
|
"$P_CLI debug_level=3 auth_mode=optional \
|
||||||
|
crt_file=data_files/server6.crt \
|
||||||
|
key_file=data_files/server6.key" \
|
||||||
|
0 \
|
||||||
|
-c "DN hint: C=NL, O=PolarSSL, CN=PolarSSL Server 1"
|
||||||
|
|
||||||
# Tests for auth_mode, using CA callback, these are duplicated from the authentication tests
|
# Tests for auth_mode, using CA callback, these are duplicated from the authentication tests
|
||||||
# When updating these tests, modify the matching authentication tests accordingly
|
# When updating these tests, modify the matching authentication tests accordingly
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user