From 7b58fb1d1c02aedb612f74ac88455a40fba12d78 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Apr 2019 12:52:21 +0100 Subject: [PATCH 01/10] Improve documentation of mbedtls_ssl_conf_verify() --- include/mbedtls/ssl.h | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index b793ac04b..12a210c7b 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1366,13 +1366,17 @@ void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ); /** * \brief Set the verification callback (Optional). * - * If set, the verify callback is called for each - * certificate in the chain. For implementation - * information, please see \c mbedtls_x509_crt_verify() + * If set, the provided verify callback is called for each + * certificate in the peer's CRT chain, including the trusted + * root. For more information, please see the documentation of + * \c mbedtls_x509_crt_verify(). * - * \param conf SSL configuration - * \param f_vrfy verification function - * \param p_vrfy verification parameter + * \note For per context callbacks and contexts, please use + * mbedtls_ssl_set_verify() instead. + * + * \param conf The SSL configuration to use. + * \param f_vrfy The verification callback to use during CRT verification. + * \param p_vrfy The opaque context to be passed to the callback. */ void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), From 726c97a825bc5c48db92650901f85bdec33ca88b Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Apr 2019 12:52:35 +0100 Subject: [PATCH 02/10] Add context-specific CRT verification callbacks --- include/mbedtls/ssl.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 12a210c7b..b8215a404 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1494,6 +1494,30 @@ void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); #endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/** + * \brief Set a connection-specific verification callback (optional). + * + * If set, the provided verify callback is called for each + * certificate in the peer's CRT chain, including the trusted + * root. For more information, please see the documentation of + * \c mbedtls_x509_crt_verify(). + * + * \note This call is analogous to mbedtls_ssl_conf_verify() but + * binds the verification callback and context to an SSL context + * as opposed to an SSL configuration. + * If mbedtls_ssl_conf_verify() and mbedtls_ssl_set_verify() + * are both used, mbedtls_ssl_set_verify() takes precedence. + * + * \param conf The SSL context to use. + * \param f_vrfy The verification callback to use during CRT verification. + * \param p_vrfy The opaque context to be passed to the callback. + */ +void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + /** * \brief Set the timeout period for mbedtls_ssl_read() * (Default: no timeout.) From 8927c833129a8d467a0f8e9192b37ea5c66c98b8 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Apr 2019 12:52:50 +0100 Subject: [PATCH 03/10] Implement context-specific verification callbacks --- include/mbedtls/ssl.h | 6 ++++++ library/ssl_tls.c | 26 +++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index b8215a404..bbe9a8383 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1090,6 +1090,12 @@ struct mbedtls_ssl_context unsigned badmac_seen; /*!< records with a bad MAC received */ #endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /** Callback to customize X.509 certificate chain verification */ + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); + void *p_vrfy; /*!< context for X.509 verify calllback */ +#endif + mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ mbedtls_ssl_recv_t *f_recv; /*!< Callback for network receive */ mbedtls_ssl_recv_timeout_t *f_recv_timeout; diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 660d548e4..8800cc7ec 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6038,6 +6038,9 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, mbedtls_x509_crt *ca_chain; mbedtls_x509_crl *ca_crl; + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); + void *p_vrfy; + if( authmode == MBEDTLS_SSL_VERIFY_NONE ) return( 0 ); @@ -6054,6 +6057,17 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, ca_crl = ssl->conf->ca_crl; } + if( ssl->f_vrfy != NULL ) + { + f_vrfy = ssl->f_vrfy; + p_vrfy = ssl->p_vrfy; + } + else + { + f_vrfy = ssl->conf->f_vrfy; + p_vrfy = ssl->conf->p_vrfy; + } + /* * Main check: verify certificate */ @@ -6063,7 +6077,7 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, ssl->conf->cert_profile, ssl->hostname, &ssl->session_negotiate->verify_result, - ssl->conf->f_vrfy, ssl->conf->p_vrfy, rs_ctx ); + f_vrfy, p_vrfy, rs_ctx ); if( ret != 0 ) { @@ -7902,6 +7916,16 @@ void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, } #endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) +void mbedtls_ssl_set_verify( mbedtls_ssl_context *ssl, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) +{ + ssl->f_vrfy = f_vrfy; + ssl->p_vrfy = p_vrfy; +} +#endif + #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) /* * Set EC J-PAKE password for current handshake From bb425dbb1b3f1025c8ef763068d202c065647e20 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Apr 2019 12:59:58 +0100 Subject: [PATCH 04/10] Add cmd to use context-specific CRT callback in ssl_client2 --- programs/ssl/ssl_client2.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index f7e24598d..170ce73bc 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -80,6 +80,7 @@ int main( void ) #define DFL_REQUEST_PAGE "/" #define DFL_REQUEST_SIZE -1 #define DFL_DEBUG_LEVEL 0 +#define DFL_CONTEXT_CRT_CB 0 #define DFL_NBIO 0 #define DFL_EVENT 0 #define DFL_READ_TIMEOUT 0 @@ -126,6 +127,16 @@ int main( void ) #define GET_REQUEST "GET %s HTTP/1.0\r\nExtra-header: " #define GET_REQUEST_END "\r\n\r\n" +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#define USAGE_CALLBACK \ + " context_crt_cb=%%d This determines whether the CRT verification callback is bound\n" \ + " to the SSL configuration of the SSL context.\n" \ + " Possible values:\n"\ + " - 0 (default): Use CRT callback bound to configuration\n" \ + " - 1: Use CRT callback bound to SSL context\n" +#else +#define USAGE_CALLBACK "" +#endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_FS_IO) #define USAGE_IO \ @@ -326,6 +337,7 @@ int main( void ) USAGE_TICKETS \ USAGE_MAX_FRAG_LEN \ USAGE_TRUNC_HMAC \ + USAGE_CALLBACK \ USAGE_ALPN \ USAGE_FALLBACK \ USAGE_EMS \ @@ -419,6 +431,7 @@ struct options int dgram_packing; /* allow/forbid datagram packing */ int extended_ms; /* negotiate extended master secret? */ int etm; /* negotiate encrypt then mac? */ + int context_crt_cb; /* use context-specific CRT verify callback */ } opt; int query_config( const char *config ); @@ -685,6 +698,7 @@ int main( int argc, char *argv[] ) opt.debug_level = DFL_DEBUG_LEVEL; opt.nbio = DFL_NBIO; opt.event = DFL_EVENT; + opt.context_crt_cb = DFL_CONTEXT_CRT_CB; opt.read_timeout = DFL_READ_TIMEOUT; opt.max_resend = DFL_MAX_RESEND; opt.request_page = DFL_REQUEST_PAGE; @@ -759,6 +773,12 @@ int main( int argc, char *argv[] ) if( opt.debug_level < 0 || opt.debug_level > 65535 ) goto usage; } + else if( strcmp( p, "context_crt_cb" ) == 0 ) + { + opt.context_crt_cb = atoi( q ); + if( opt.context_crt_cb != 0 && opt.context_crt_cb != 1 ) + goto usage; + } else if( strcmp( p, "nbio" ) == 0 ) { opt.nbio = atoi( q ); @@ -1511,7 +1531,9 @@ int main( int argc, char *argv[] ) mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test ); } - mbedtls_ssl_conf_verify( &conf, my_verify, NULL ); + if( opt.context_crt_cb == 0 ) + mbedtls_ssl_conf_verify( &conf, my_verify, NULL ); + memset( peer_crt_info, 0, sizeof( peer_crt_info ) ); #endif /* MBEDTLS_X509_CRT_PARSE_C */ @@ -1715,6 +1737,11 @@ int main( int argc, char *argv[] ) } #endif +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( opt.context_crt_cb == 1 ) + mbedtls_ssl_set_verify( &ssl, my_verify, NULL ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + if( opt.nbio == 2 ) mbedtls_ssl_set_bio( &ssl, &server_fd, my_send, my_recv, NULL ); else From efb440afec3d90a17da7f4a3205c186abbd5f9ab Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Apr 2019 13:04:33 +0100 Subject: [PATCH 05/10] Add test exercising context-specific CRT callback to ssl-opt.sh --- library/ssl_tls.c | 2 ++ tests/ssl-opt.sh | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 8800cc7ec..e030195bb 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -6059,11 +6059,13 @@ static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl, if( ssl->f_vrfy != NULL ) { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use context-specific verification callback" ) ); f_vrfy = ssl->f_vrfy; p_vrfy = ssl->p_vrfy; } else { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Use configuration-specific verification callback" ) ); f_vrfy = ssl->conf->f_vrfy; p_vrfy = ssl->conf->p_vrfy; } diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index d952f33fd..59786afdf 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1008,6 +1008,20 @@ run_test "Unique IV in GCM" \ -u "IV used" \ -U "IV used" +# Test for context-specific CRT verification callback +run_test "Context-specific CRT verification callback" \ + "$P_SRV debug_level=3" \ + "$P_CLI context_crt_cb=1 debug_level=3" \ + 0 \ + -s "Protocol is TLSv1.2" \ + -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256" \ + -s "client hello v3, signature_algorithm ext: 6" \ + -s "ECDHE curve: secp521r1" \ + -S "error" \ + -c "Use context-specific verification callback"\ + -C "Use configuration-specific verification callback"\ + -C "error" + # Tests for rc4 option requires_config_enabled MBEDTLS_REMOVE_ARC4_CIPHERSUITES From f345bafd30c41aae6a89163abe4674e3395811e1 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Wed, 3 Apr 2019 13:43:15 +0100 Subject: [PATCH 06/10] Fix doxygen documentation of mbedtls_ssl_set_verify() --- include/mbedtls/ssl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index bbe9a8383..04f8c17a9 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1515,7 +1515,7 @@ void mbedtls_ssl_set_mtu( mbedtls_ssl_context *ssl, uint16_t mtu ); * If mbedtls_ssl_conf_verify() and mbedtls_ssl_set_verify() * are both used, mbedtls_ssl_set_verify() takes precedence. * - * \param conf The SSL context to use. + * \param ssl The SSL context to use. * \param f_vrfy The verification callback to use during CRT verification. * \param p_vrfy The opaque context to be passed to the callback. */ From ee11be6572e0b6429748296108f9c4485ddb299b Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 4 Apr 2019 12:03:30 +0100 Subject: [PATCH 07/10] Add test for configuration specific CRT callback --- tests/ssl-opt.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index 59786afdf..ac6736d4c 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1008,7 +1008,21 @@ run_test "Unique IV in GCM" \ -u "IV used" \ -U "IV used" -# Test for context-specific CRT verification callback +# Tests for certificate verification callback +run_test "Configuration-specific CRT verification callback" \ + "$P_SRV debug_level=3" \ + "$P_CLI context_crt_cb=0 debug_level=3" \ + 0 \ + -s "Protocol is TLSv1.2" \ + -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256" \ + -s "client hello v3, signature_algorithm ext: 6" \ + -s "ECDHE curve: secp521r1" \ + -S "error" \ + -c "Verify requested for " \ + -c "Use configuration-specific verification callback" \ + -C "Use context-specific verification callback" \ + -C "error" + run_test "Context-specific CRT verification callback" \ "$P_SRV debug_level=3" \ "$P_CLI context_crt_cb=1 debug_level=3" \ @@ -1018,8 +1032,9 @@ run_test "Context-specific CRT verification callback" \ -s "client hello v3, signature_algorithm ext: 6" \ -s "ECDHE curve: secp521r1" \ -S "error" \ - -c "Use context-specific verification callback"\ - -C "Use configuration-specific verification callback"\ + -c "Verify requested for " \ + -c "Use context-specific verification callback" \ + -C "Use configuration-specific verification callback" \ -C "error" # Tests for rc4 option From 924270f7690b338fee49338e506488075353735a Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Thu, 4 Apr 2019 12:49:44 +0100 Subject: [PATCH 08/10] Fix typo --- include/mbedtls/ssl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mbedtls/ssl.h b/include/mbedtls/ssl.h index 04f8c17a9..78f294f62 100644 --- a/include/mbedtls/ssl.h +++ b/include/mbedtls/ssl.h @@ -1093,7 +1093,7 @@ struct mbedtls_ssl_context #if defined(MBEDTLS_X509_CRT_PARSE_C) /** Callback to customize X.509 certificate chain verification */ int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *); - void *p_vrfy; /*!< context for X.509 verify calllback */ + void *p_vrfy; /*!< context for X.509 verify callback */ #endif mbedtls_ssl_send_t *f_send; /*!< Callback for network send */ From ae13beb1d9f185632db54c1baca8f61982f2cea3 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 5 Apr 2019 14:06:58 +0100 Subject: [PATCH 09/10] Rename constant in client2.c --- programs/ssl/ssl_client2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c index 170ce73bc..fba02ac78 100644 --- a/programs/ssl/ssl_client2.c +++ b/programs/ssl/ssl_client2.c @@ -128,14 +128,14 @@ int main( void ) #define GET_REQUEST_END "\r\n\r\n" #if defined(MBEDTLS_X509_CRT_PARSE_C) -#define USAGE_CALLBACK \ +#define USAGE_CONTEXT_CRT_CB \ " context_crt_cb=%%d This determines whether the CRT verification callback is bound\n" \ " to the SSL configuration of the SSL context.\n" \ " Possible values:\n"\ " - 0 (default): Use CRT callback bound to configuration\n" \ " - 1: Use CRT callback bound to SSL context\n" #else -#define USAGE_CALLBACK "" +#define USAGE_CONTEXT_CRT_CB "" #endif /* MBEDTLS_X509_CRT_PARSE_C */ #if defined(MBEDTLS_X509_CRT_PARSE_C) #if defined(MBEDTLS_FS_IO) @@ -337,7 +337,7 @@ int main( void ) USAGE_TICKETS \ USAGE_MAX_FRAG_LEN \ USAGE_TRUNC_HMAC \ - USAGE_CALLBACK \ + USAGE_CONTEXT_CRT_CB \ USAGE_ALPN \ USAGE_FALLBACK \ USAGE_EMS \ From 4031b314eddd677835d4cbb623a13778d8224620 Mon Sep 17 00:00:00 2001 From: Janos Follath Date: Fri, 5 Apr 2019 14:13:45 +0100 Subject: [PATCH 10/10] Make CRT callback tests more robust --- tests/ssl-opt.sh | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/ssl-opt.sh b/tests/ssl-opt.sh index ac6736d4c..7e11f8944 100755 --- a/tests/ssl-opt.sh +++ b/tests/ssl-opt.sh @@ -1013,10 +1013,6 @@ run_test "Configuration-specific CRT verification callback" \ "$P_SRV debug_level=3" \ "$P_CLI context_crt_cb=0 debug_level=3" \ 0 \ - -s "Protocol is TLSv1.2" \ - -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256" \ - -s "client hello v3, signature_algorithm ext: 6" \ - -s "ECDHE curve: secp521r1" \ -S "error" \ -c "Verify requested for " \ -c "Use configuration-specific verification callback" \ @@ -1027,10 +1023,6 @@ run_test "Context-specific CRT verification callback" \ "$P_SRV debug_level=3" \ "$P_CLI context_crt_cb=1 debug_level=3" \ 0 \ - -s "Protocol is TLSv1.2" \ - -s "Ciphersuite is TLS-ECDHE-RSA-WITH-CHACHA20-POLY1305-SHA256" \ - -s "client hello v3, signature_algorithm ext: 6" \ - -s "ECDHE curve: secp521r1" \ -S "error" \ -c "Verify requested for " \ -c "Use context-specific verification callback" \