mirror of
https://github.com/yuzu-emu/mbedtls.git
synced 2024-11-22 16:55:42 +01:00
Add support for multiple server certificates
This commit is contained in:
parent
834ea8587f
commit
3ebb2cdb52
@ -492,6 +492,9 @@ struct _ssl_handshake_params
|
|||||||
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
|
#if defined(POLARSSL_ECDH_C) || defined(POLARSSL_ECDSA_C)
|
||||||
int ec_curve; /*!< Selected elliptic curve */
|
int ec_curve; /*!< Selected elliptic curve */
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
|
ssl_key_cert *key_cert; /*!< Own key/cert in use */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checksum contexts
|
* Checksum contexts
|
||||||
@ -1517,12 +1520,14 @@ md_type_t ssl_md_alg_from_hash( unsigned char hash );
|
|||||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
static inline pk_context *ssl_own_key( ssl_context *ssl )
|
static inline pk_context *ssl_own_key( ssl_context *ssl )
|
||||||
{
|
{
|
||||||
return( ssl->key_cert == NULL ? NULL : ssl->key_cert->key );
|
return( ssl->handshake->key_cert == NULL ? NULL
|
||||||
|
: ssl->handshake->key_cert->key );
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline x509_crt *ssl_own_cert( ssl_context *ssl )
|
static inline x509_crt *ssl_own_cert( ssl_context *ssl )
|
||||||
{
|
{
|
||||||
return( ssl->key_cert == NULL ? NULL : ssl->key_cert->cert );
|
return( ssl->handshake->key_cert == NULL ? NULL
|
||||||
|
: ssl->handshake->key_cert->cert );
|
||||||
}
|
}
|
||||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||||
|
|
||||||
|
@ -1271,7 +1271,8 @@ static int ssl_parse_client_hello( ssl_context *ssl )
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Search for a matching ciphersuite
|
* Search for a matching ciphersuite
|
||||||
* (At the end because we need information from the EC-based extensions)
|
* (At the end because we need information from the EC-based extensions
|
||||||
|
* and certificate from the SNI callback triggered by the SNI extension.)
|
||||||
*/
|
*/
|
||||||
ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
|
ciphersuites = ssl->ciphersuite_list[ssl->minor_ver];
|
||||||
for( i = 0; ciphersuites[i] != 0; i++ )
|
for( i = 0; ciphersuites[i] != 0; i++ )
|
||||||
@ -1301,14 +1302,32 @@ static int ssl_parse_client_hello( ssl_context *ssl )
|
|||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If ciphersuite requires us to have a private key of a
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
* certain type, make sure we do */
|
/*
|
||||||
#if defined(POLARSSL_PK_C)
|
* Final check: if ciphersuite requires us to have a
|
||||||
|
* certificate/key of a particular type:
|
||||||
|
* - select the appropriate certificate if we have one, or
|
||||||
|
* - try the next ciphersuite if we don't
|
||||||
|
* This must be done last since we modify the key_cert list.
|
||||||
|
*/
|
||||||
pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
|
pk_alg = ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info );
|
||||||
if( pk_alg != POLARSSL_PK_NONE &&
|
if( pk_alg != POLARSSL_PK_NONE )
|
||||||
( ssl_own_key( ssl ) == NULL ||
|
{
|
||||||
! pk_can_do( ssl_own_key( ssl ), pk_alg ) ) )
|
ssl_key_cert *good = NULL;
|
||||||
continue;
|
ssl_key_cert *cur = ssl->key_cert;
|
||||||
|
|
||||||
|
while( cur != NULL && good == NULL )
|
||||||
|
{
|
||||||
|
if( pk_can_do( cur->key, pk_alg ) )
|
||||||
|
good = cur;
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( good == NULL )
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
ssl->handshake->key_cert = good;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
goto have_ciphersuite;
|
goto have_ciphersuite;
|
||||||
|
@ -3849,6 +3849,10 @@ int ssl_handshake( ssl_context *ssl )
|
|||||||
|
|
||||||
SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
|
SSL_DEBUG_MSG( 2, ( "=> handshake" ) );
|
||||||
|
|
||||||
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
|
ssl->handshake->key_cert = ssl->key_cert;
|
||||||
|
#endif
|
||||||
|
|
||||||
while( ssl->state != SSL_HANDSHAKE_OVER )
|
while( ssl->state != SSL_HANDSHAKE_OVER )
|
||||||
{
|
{
|
||||||
ret = ssl_handshake_step( ssl );
|
ret = ssl_handshake_step( ssl );
|
||||||
|
@ -56,6 +56,8 @@
|
|||||||
#define DFL_CA_PATH ""
|
#define DFL_CA_PATH ""
|
||||||
#define DFL_CRT_FILE ""
|
#define DFL_CRT_FILE ""
|
||||||
#define DFL_KEY_FILE ""
|
#define DFL_KEY_FILE ""
|
||||||
|
#define DFL_CRT_FILE2 ""
|
||||||
|
#define DFL_KEY_FILE2 ""
|
||||||
#define DFL_PSK ""
|
#define DFL_PSK ""
|
||||||
#define DFL_PSK_IDENTITY "Client_identity"
|
#define DFL_PSK_IDENTITY "Client_identity"
|
||||||
#define DFL_FORCE_CIPHER 0
|
#define DFL_FORCE_CIPHER 0
|
||||||
@ -91,8 +93,10 @@ struct options
|
|||||||
int debug_level; /* level of debugging */
|
int debug_level; /* level of debugging */
|
||||||
const char *ca_file; /* the file with the CA certificate(s) */
|
const char *ca_file; /* the file with the CA certificate(s) */
|
||||||
const char *ca_path; /* the path with the CA certificate(s) reside */
|
const char *ca_path; /* the path with the CA certificate(s) reside */
|
||||||
const char *crt_file; /* the file with the client certificate */
|
const char *crt_file; /* the file with the server certificate */
|
||||||
const char *key_file; /* the file with the client key */
|
const char *key_file; /* the file with the server key */
|
||||||
|
const char *crt_file2; /* the file with the 2nd server certificate */
|
||||||
|
const char *key_file2; /* the file with the 2nd server key */
|
||||||
const char *psk; /* the pre-shared key */
|
const char *psk; /* the pre-shared key */
|
||||||
const char *psk_identity; /* the pre-shared key identity */
|
const char *psk_identity; /* the pre-shared key identity */
|
||||||
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
|
int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
|
||||||
@ -114,6 +118,56 @@ static void my_debug( void *ctx, int level, const char *str )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
|
static int parse_cert_key( x509_crt *crt, const char *crt_file,
|
||||||
|
pk_context *key, const char *key_file )
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
#if defined(POLARSSL_FS_IO)
|
||||||
|
if( strlen( crt_file ) )
|
||||||
|
ret = x509_crt_parse_file( crt, crt_file );
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#if defined(POLARSSL_CERTS_C)
|
||||||
|
ret = x509_crt_parse( crt, (const unsigned char *) test_srv_crt,
|
||||||
|
strlen( test_srv_crt ) );
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
printf("POLARSSL_CERTS_C not defined.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(POLARSSL_FS_IO)
|
||||||
|
if( strlen( key_file ) )
|
||||||
|
ret = pk_parse_keyfile( key, key_file, "" );
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#if defined(POLARSSL_CERTS_C)
|
||||||
|
ret = pk_parse_key( key, (const unsigned char *) test_srv_key,
|
||||||
|
strlen( test_srv_key ), NULL, 0 );
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
ret = 1;
|
||||||
|
printf("POLARSSL_CERTS_C not defined.");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if( ret != 0 )
|
||||||
|
{
|
||||||
|
printf( " failed\n ! pk_parse_key returned -0x%x\n\n", -ret );
|
||||||
|
return( ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
return( 0 );
|
||||||
|
}
|
||||||
|
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||||
|
|
||||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
#if defined(POLARSSL_FS_IO)
|
#if defined(POLARSSL_FS_IO)
|
||||||
#define USAGE_IO \
|
#define USAGE_IO \
|
||||||
@ -123,7 +177,10 @@ static void my_debug( void *ctx, int level, const char *str )
|
|||||||
" default: \"\" (pre-loaded) (overrides ca_file)\n" \
|
" default: \"\" (pre-loaded) (overrides ca_file)\n" \
|
||||||
" crt_file=%%s Your own cert and chain (in bottom to top order, top may be omitted)\n" \
|
" crt_file=%%s Your own cert and chain (in bottom to top order, top may be omitted)\n" \
|
||||||
" default: \"\" (pre-loaded)\n" \
|
" default: \"\" (pre-loaded)\n" \
|
||||||
" key_file=%%s default: \"\" (pre-loaded)\n"
|
" key_file=%%s default: \"\" (pre-loaded)\n" \
|
||||||
|
" crt_file2=%%s Your second cert and chain (in bottom to top order, top may be omitted)\n" \
|
||||||
|
" default: \"\" (pre-loaded)\n" \
|
||||||
|
" key_file2=%%s default: \"\" (pre-loaded)\n"
|
||||||
#else
|
#else
|
||||||
#define USAGE_IO \
|
#define USAGE_IO \
|
||||||
"\n" \
|
"\n" \
|
||||||
@ -212,6 +269,8 @@ int main( int argc, char *argv[] )
|
|||||||
x509_crt cacert;
|
x509_crt cacert;
|
||||||
x509_crt srvcert;
|
x509_crt srvcert;
|
||||||
pk_context pkey;
|
pk_context pkey;
|
||||||
|
x509_crt srvcert2;
|
||||||
|
pk_context pkey2;
|
||||||
#endif
|
#endif
|
||||||
#if defined(POLARSSL_SSL_CACHE_C)
|
#if defined(POLARSSL_SSL_CACHE_C)
|
||||||
ssl_cache_context cache;
|
ssl_cache_context cache;
|
||||||
@ -237,6 +296,8 @@ int main( int argc, char *argv[] )
|
|||||||
x509_crt_init( &cacert );
|
x509_crt_init( &cacert );
|
||||||
x509_crt_init( &srvcert );
|
x509_crt_init( &srvcert );
|
||||||
pk_init( &pkey );
|
pk_init( &pkey );
|
||||||
|
x509_crt_init( &srvcert2 );
|
||||||
|
pk_init( &pkey2 );
|
||||||
#endif
|
#endif
|
||||||
#if defined(POLARSSL_SSL_CACHE_C)
|
#if defined(POLARSSL_SSL_CACHE_C)
|
||||||
ssl_cache_init( &cache );
|
ssl_cache_init( &cache );
|
||||||
@ -270,6 +331,8 @@ int main( int argc, char *argv[] )
|
|||||||
opt.ca_path = DFL_CA_PATH;
|
opt.ca_path = DFL_CA_PATH;
|
||||||
opt.crt_file = DFL_CRT_FILE;
|
opt.crt_file = DFL_CRT_FILE;
|
||||||
opt.key_file = DFL_KEY_FILE;
|
opt.key_file = DFL_KEY_FILE;
|
||||||
|
opt.crt_file2 = DFL_CRT_FILE2;
|
||||||
|
opt.key_file2 = DFL_KEY_FILE2;
|
||||||
opt.psk = DFL_PSK;
|
opt.psk = DFL_PSK;
|
||||||
opt.psk_identity = DFL_PSK_IDENTITY;
|
opt.psk_identity = DFL_PSK_IDENTITY;
|
||||||
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
|
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
|
||||||
@ -308,6 +371,10 @@ int main( int argc, char *argv[] )
|
|||||||
opt.crt_file = q;
|
opt.crt_file = q;
|
||||||
else if( strcmp( p, "key_file" ) == 0 )
|
else if( strcmp( p, "key_file" ) == 0 )
|
||||||
opt.key_file = q;
|
opt.key_file = q;
|
||||||
|
else if( strcmp( p, "crt_file2" ) == 0 )
|
||||||
|
opt.crt_file2 = q;
|
||||||
|
else if( strcmp( p, "key_file2" ) == 0 )
|
||||||
|
opt.key_file2 = q;
|
||||||
else if( strcmp( p, "psk" ) == 0 )
|
else if( strcmp( p, "psk" ) == 0 )
|
||||||
opt.psk = q;
|
opt.psk = q;
|
||||||
else if( strcmp( p, "psk_identity" ) == 0 )
|
else if( strcmp( p, "psk_identity" ) == 0 )
|
||||||
@ -550,45 +617,11 @@ int main( int argc, char *argv[] )
|
|||||||
printf( " . Loading the server cert. and key..." );
|
printf( " . Loading the server cert. and key..." );
|
||||||
fflush( stdout );
|
fflush( stdout );
|
||||||
|
|
||||||
#if defined(POLARSSL_FS_IO)
|
if( parse_cert_key( &srvcert, opt.crt_file, &pkey, opt.key_file ) != 0 )
|
||||||
if( strlen( opt.crt_file ) )
|
|
||||||
ret = x509_crt_parse_file( &srvcert, opt.crt_file );
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#if defined(POLARSSL_CERTS_C)
|
|
||||||
ret = x509_crt_parse( &srvcert, (const unsigned char *) test_srv_crt,
|
|
||||||
strlen( test_srv_crt ) );
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
ret = 1;
|
|
||||||
printf("POLARSSL_CERTS_C not defined.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( ret != 0 )
|
|
||||||
{
|
|
||||||
printf( " failed\n ! x509_crt_parse returned -0x%x\n\n", -ret );
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(POLARSSL_FS_IO)
|
if( parse_cert_key( &srvcert2, opt.crt_file2, &pkey2, opt.key_file2 ) != 0 )
|
||||||
if( strlen( opt.key_file ) )
|
|
||||||
ret = pk_parse_keyfile( &pkey, opt.key_file, "" );
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
#if defined(POLARSSL_CERTS_C)
|
|
||||||
ret = pk_parse_key( &pkey, (const unsigned char *) test_srv_key,
|
|
||||||
strlen( test_srv_key ), NULL, 0 );
|
|
||||||
#else
|
|
||||||
{
|
|
||||||
ret = 1;
|
|
||||||
printf("POLARSSL_CERTS_C not defined.");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if( ret != 0 )
|
|
||||||
{
|
|
||||||
printf( " failed\n ! pk_parse_key returned -0x%x\n\n", -ret );
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
|
||||||
|
|
||||||
printf( " ok\n" );
|
printf( " ok\n" );
|
||||||
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
#endif /* POLARSSL_X509_CRT_PARSE_C */
|
||||||
@ -647,6 +680,7 @@ int main( int argc, char *argv[] )
|
|||||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
|
ssl_set_ca_chain( &ssl, &cacert, NULL, NULL );
|
||||||
ssl_set_own_cert( &ssl, &srvcert, &pkey );
|
ssl_set_own_cert( &ssl, &srvcert, &pkey );
|
||||||
|
ssl_set_own_cert( &ssl, &srvcert2, &pkey2 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
|
#if defined(POLARSSL_KEY_EXCHANGE_PSK_ENABLED)
|
||||||
@ -875,9 +909,11 @@ exit:
|
|||||||
|
|
||||||
net_close( client_fd );
|
net_close( client_fd );
|
||||||
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
#if defined(POLARSSL_X509_CRT_PARSE_C)
|
||||||
x509_crt_free( &srvcert );
|
|
||||||
x509_crt_free( &cacert );
|
x509_crt_free( &cacert );
|
||||||
|
x509_crt_free( &srvcert );
|
||||||
pk_free( &pkey );
|
pk_free( &pkey );
|
||||||
|
x509_crt_free( &srvcert2 );
|
||||||
|
pk_free( &pkey2 );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ssl_free( &ssl );
|
ssl_free( &ssl );
|
||||||
|
Loading…
Reference in New Issue
Block a user