Commit a9af682b authored by Simon Morlat's avatar Simon Morlat

Add two callbacks in belle_tls_crypto_config_t for TLS handshake control: for...

Add two callbacks in belle_tls_crypto_config_t for TLS handshake control: for individual certificate check, and for a postcheck of the peer certificate.
parent cdd7bfdd
......@@ -156,7 +156,7 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth_for_algorith
* Set TLS certificate verification callback
*
* @param callback function pointer for callback, or NULL to unset
*
* @deprecated on 2018/03/31 in favor of belle_tls_crypto_config_set_verify_callback()
* Callback signature is:
* int (*verify_cb_error_cb_t)(unsigned char* der, int length, int depth, int* flags);
* der - raw certificate data, in DER format
......@@ -164,7 +164,7 @@ BELLESIP_EXPORT int belle_sip_auth_helper_compute_response_qop_auth_for_algorith
* depth - position of certificate in cert chain, ending at 0 = root or top
* flags - verification state for CURRENT certificate only
*/
BELLESIP_EXPORT int belle_sip_tls_set_verify_error_cb(void *callback);
BELLESIP_DEPRECATED BELLESIP_EXPORT int belle_sip_tls_set_verify_error_cb(void *callback);
/**
* Format of certificate buffer
......@@ -318,6 +318,43 @@ BELLESIP_EXPORT void belle_tls_crypto_config_set_verify_exceptions(belle_tls_cry
*/
BELLESIP_EXPORT unsigned int belle_tls_crypto_config_get_verify_exceptions(const belle_tls_crypto_config_t *obj);
/**
* Callback prototype to override certificate check at upper level.
* @param user_data the user pointer passed to belle_tls_crypto_config_set_verify_callback()
* @param cert the x509 certificate
* @param depth depth of certificate in the certificate chain (the callback is called for each certificate of the chain
* @param flags i/o parameter containing the error flags reported by the crypto library (BCTBX_CERTIFICATE_VERIFY_* flags).
* The application may freely alterate the flags on output, in order to bypass verifications or add new error flags.
* The flags MUST be set or unset with bctbx_x509_certificate_set_flag() bctbx_x509_certificate_unset_flag()
**/
typedef void (*belle_tls_crypto_config_verify_callback_t)(void *user_data, bctbx_x509_certificate_t *cert , int depth, uint32_t *flags);
/**
* Set a callback function to call during each TLS handshake in order to override certificate verification.
* @param obj the crypto config object
* @param cb the application callback
* @param cb_data an application data pointer that will be passed to callback when invoked.
**/
BELLESIP_EXPORT void belle_tls_crypto_config_set_verify_callback(belle_tls_crypto_config_t *obj, belle_tls_crypto_config_verify_callback_t cb, void *cb_data);
/**
* Callback prototype to check remote certificate once hanshake is completed (post-check).
* @param user_data the user pointer passed to belle_tls_crypto_config_set_postcheck_callback()
* @param cert the peer x509 certificate
* @return 0 if all is good, -1 otherwise
**/
typedef int (*belle_tls_crypto_config_postcheck_callback_t)(void *user_data, const bctbx_x509_certificate_t *cert);
/**
* Set the post-check callback function executed upon successfull TLS handshake..
* @param obj the crypto config object
* @param cb the application callback
* @param cb_data an application data pointer that will be passed to callback when invoked.
**/
BELLESIP_EXPORT void belle_tls_crypto_config_set_postcheck_callback(belle_tls_crypto_config_t *obj, belle_tls_crypto_config_postcheck_callback_t cb, void *cb_data);
/**
* Set the pointer to an externally provided ssl configuration for the crypto library
* @param[in/out] obj The crypto configuration object to set
......
......@@ -51,7 +51,7 @@ void belle_sip_auth_event_destroy(belle_sip_auth_event_t* event) {
DESTROY_STRING(event,passwd);
DESTROY_STRING(event,ha1);
DESTROY_STRING(event,distinguished_name);
DESTROY_STRING(event,algorithm);
DESTROY_STRING(event,algorithm);
if (event->cert) belle_sip_object_unref(event->cert);
if (event->key) belle_sip_object_unref(event->key);
......@@ -169,3 +169,14 @@ void belle_tls_crypto_config_set_ssl_config(belle_tls_crypto_config_t *obj, void
obj->ssl_config = ssl_config;
}
void belle_tls_crypto_config_set_verify_callback(belle_tls_crypto_config_t *obj, belle_tls_crypto_config_verify_callback_t cb, void *cb_data){
obj->verify_cb = cb;
obj->verify_cb_data = cb_data;
}
void belle_tls_crypto_config_set_postcheck_callback(belle_tls_crypto_config_t *obj, belle_tls_crypto_config_postcheck_callback_t cb, void *cb_data){
obj->postcheck_cb = cb;
obj->postcheck_cb_data = cb_data;
}
......@@ -246,6 +246,10 @@ struct belle_tls_crypto_config{
BELLE_TLS_VERIFY_CN_MISMATCH ignore Common Name mismatch exception
BELLE_TLS_VERIFY_ANY_REASON(ignore any exception */
void *ssl_config; /**< externally provided ssl configuration context, will be casted and given to the underlying crypto library, use only if you really know what you're doing */
belle_tls_crypto_config_verify_callback_t verify_cb;
void *verify_cb_data;
belle_tls_crypto_config_postcheck_callback_t postcheck_cb;
void *postcheck_cb_data;
};
#endif
......@@ -329,6 +329,7 @@ char *belle_sip_certificates_chain_get_fingerprint(belle_sip_certificates_chain_
// length - length of certificate DER data
// depth - position of certificate in cert chain, ending at 0 = root or top
// flags - verification state for CURRENT certificate only
// deprecated
typedef int (*verify_cb_error_cb_t)(unsigned char* der, int length, int depth, uint32_t* flags);
static verify_cb_error_cb_t tls_verify_cb_error_cb = NULL;
......@@ -499,19 +500,41 @@ static int belle_sip_client_certificate_request_callback(void *data, bctbx_ssl_c
return 0; /* we couldn't find any certificate, just keep on going, server may decide to abort the handshake */
}
static int tls_handle_postcheck(belle_sip_tls_channel_t* channel){
if (channel->crypto_config && channel->crypto_config->postcheck_cb){
const bctbx_x509_certificate_t *cert = bctbx_ssl_get_peer_certificate(channel->sslctx);
if (!cert){
belle_sip_error("tls_handle_postcheck(): no peer certificate, this should not happen");
return -1;
}
return channel->crypto_config->postcheck_cb(channel->crypto_config->postcheck_cb_data, cert);
}
return 0;
}
static int tls_process_handshake(belle_sip_channel_t *obj){
belle_sip_tls_channel_t* channel=(belle_sip_tls_channel_t*)obj;
char tmp[128];
int err=bctbx_ssl_handshake(channel->sslctx);
if (err==0){
if (err == 0){
belle_sip_message("Channel [%p]: SSL handshake finished, SSL version is [%s], selected ciphersuite is [%s]",obj,
bctbx_ssl_get_version(channel->sslctx), bctbx_ssl_get_ciphersuite(channel->sslctx));
err = tls_handle_postcheck(channel);
if (err != 0) {
snprintf(tmp, sizeof(tmp)-1, "%s", "application level post-check failed.");
}
}
if (err==0){
belle_sip_source_set_timeout((belle_sip_source_t*)obj,-1);
belle_sip_channel_set_ready(obj,(struct sockaddr*)&channel->ss,channel->socklen);
}else if (err==BCTBX_ERROR_NET_WANT_READ || err==BCTBX_ERROR_NET_WANT_WRITE){
belle_sip_message("Channel [%p]: SSL handshake in progress...",obj);
}else{
char tmp[128];
bctbx_strerror(err,tmp,sizeof(tmp));
if (tmp[0] == '\0'){
bctbx_strerror(err,tmp,sizeof(tmp));
}
belle_sip_error("Channel [%p]: SSL handshake failed : %s",obj,tmp);
return -1;
}
......@@ -679,6 +702,7 @@ static int random_generator(void *ctx, unsigned char *ptr, size_t size){
// shim the default certificate handling by adding an external callback
// see "verify_cb_error_cb_t" for the function signature
/*deprecated*/
int belle_sip_tls_set_verify_error_cb(void * callback) {
if (callback) {
......@@ -691,6 +715,7 @@ int belle_sip_tls_set_verify_error_cb(void * callback) {
return 0;
}
//
// Augment certificate verification with certificates stored outside rootca.pem
// PolarSSL calls the verify_cb with each cert in the chain; flags apply to the
......@@ -758,6 +783,9 @@ static int belle_sip_ssl_verify(void *data , bctbx_x509_certificate_t *cert , in
bctbx_x509_certificate_unset_flag(flags, BCTBX_CERTIFICATE_VERIFY_BADCERT_CN_MISMATCH);
}
if (crypto_config->verify_cb){
crypto_config->verify_cb(crypto_config->verify_cb_data, cert, depth, flags);
}
ret = belle_sip_verify_cb_error_wrapper(cert, depth, flags);
belle_sip_free(flags_str);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment