diff --git a/ChangeLog b/ChangeLog index 133ccbdb..3cc44cef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ * 201?-??-??: Version 1.?.? + * Specify locations at which CA certificates for verification purposes + are located: getdns_context_set_CApath() getdns_context_set_CAfile() * Bugfix #359: edns_client_subnet_private should set family Thanks Daniel Areiza diff --git a/src/const-info.c b/src/const-info.c index 2c582ed1..b1bd4f96 100644 --- a/src/const-info.c +++ b/src/const-info.c @@ -86,6 +86,8 @@ static struct const_info consts_info[] = { { 626, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_CA_TEXT }, { 627, "GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL", GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT }, { 628, "GETDNS_CONTEXT_CODE_APPDATA_DIR", GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT }, + { 630, "GETDNS_CONTEXT_CODE_CAPATH", GETDNS_CONTEXT_CODE_CAPATH_TEXT }, + { 631, "GETDNS_CONTEXT_CODE_CAFILE", GETDNS_CONTEXT_CODE_CAFILE_TEXT }, { 700, "GETDNS_CALLBACK_COMPLETE", GETDNS_CALLBACK_COMPLETE_TEXT }, { 701, "GETDNS_CALLBACK_CANCEL", GETDNS_CALLBACK_CANCEL_TEXT }, { 702, "GETDNS_CALLBACK_TIMEOUT", GETDNS_CALLBACK_TIMEOUT_TEXT }, @@ -156,6 +158,8 @@ static struct const_name_info consts_name_info[] = { { "GETDNS_CALLBACK_TIMEOUT", 702 }, { "GETDNS_CONTEXT_CODE_APPDATA_DIR", 628 }, { "GETDNS_CONTEXT_CODE_APPEND_NAME", 607 }, + { "GETDNS_CONTEXT_CODE_CAFILE", 631 }, + { "GETDNS_CONTEXT_CODE_CAPATH", 630 }, { "GETDNS_CONTEXT_CODE_DNSSEC_ALLOWED_SKEW", 614 }, { "GETDNS_CONTEXT_CODE_DNSSEC_TRUST_ANCHORS", 609 }, { "GETDNS_CONTEXT_CODE_DNS_ROOT_SERVERS", 604 }, diff --git a/src/context.c b/src/context.c index b5b37630..ef5126eb 100644 --- a/src/context.c +++ b/src/context.c @@ -1498,6 +1498,8 @@ getdns_context_create_with_extended_memory_functions( result->trust_anchors_verify_email = NULL; result->trust_anchors_verify_CA = NULL; result->appdata_dir = NULL; + result->CApath = NULL; + result->CAfile = NULL; (void) memset(&result->root_ksk, 0, sizeof(result->root_ksk)); @@ -1773,6 +1775,11 @@ getdns_context_destroy(struct getdns_context *context) , context->trust_anchors_verify_email); if (context->appdata_dir) GETDNS_FREE(context->mf, context->appdata_dir); + if (context->CApath) + GETDNS_FREE(context->mf, context->CApath); + if (context->CAfile) + GETDNS_FREE(context->mf, context->CAfile); + #ifdef USE_WINSOCK WSACleanup(); @@ -3568,10 +3575,14 @@ _getdns_context_prepare_for_resolution(getdns_context *context) return GETDNS_RETURN_BAD_CONTEXT; /* For strict authentication, we must have local root certs available Set up is done only when the tls_ctx is created (per getdns_context)*/ + if ((context->CAfile || context->CApath) && + SSL_CTX_load_verify_locations(context->tls_ctx + , context->CAfile, context->CApath)) + ; /* pass */ # ifndef USE_WINSOCK - if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) { + else if (!SSL_CTX_set_default_verify_paths(context->tls_ctx)) { # else - if (!add_WIN_cacerts_to_openssl_store(context->tls_ctx)) { + else if (!add_WIN_cacerts_to_openssl_store(context->tls_ctx)) { # endif /* USE_WINSOCK */ if (context->tls_auth_min == GETDNS_AUTHENTICATION_REQUIRED) return GETDNS_RETURN_BAD_CONTEXT; @@ -3868,6 +3879,10 @@ _get_context_settings(getdns_context* context) (void) getdns_dict_util_set_string(result, "trust_anchors_verify_CA", str_value); if (!getdns_context_get_trust_anchors_verify_email(context, &str_value) && str_value) (void) getdns_dict_util_set_string(result, "trust_anchors_verify_email", str_value); + if (!getdns_context_get_CApath(context, &str_value) && str_value) + (void) getdns_dict_util_set_string(result, "CApath", str_value); + if (!getdns_context_get_CAfile(context, &str_value) && str_value) + (void) getdns_dict_util_set_string(result, "CAfile", str_value); return result; error: @@ -4564,6 +4579,8 @@ _getdns_context_config_setting(getdns_context *context, CONTEXT_SETTING_STRING(trust_anchors_verify_CA) CONTEXT_SETTING_STRING(trust_anchors_verify_email) CONTEXT_SETTING_STRING(appdata_dir) + CONTEXT_SETTING_STRING(CApath) + CONTEXT_SETTING_STRING(CAfile) /**************************************/ /**** ****/ @@ -5008,5 +5025,50 @@ getdns_context_set_appdata_dir( return GETDNS_RETURN_GOOD; } +getdns_return_t +getdns_context_set_CApath(getdns_context *context, const char *CApath) +{ + if (!context || !CApath) + return GETDNS_RETURN_INVALID_PARAMETER; + if (context->CApath) + GETDNS_FREE(context->mf, context->CApath); + context->CApath = _getdns_strdup(&context->mf, CApath); + + dispatch_updated(context, GETDNS_CONTEXT_CODE_CAPATH); + return GETDNS_RETURN_GOOD; +} + +getdns_return_t +getdns_context_get_CApath(getdns_context *context, const char **CApath) +{ + if (!context || !CApath) + return GETDNS_RETURN_INVALID_PARAMETER; + + *CApath = context->CApath; + return GETDNS_RETURN_GOOD; +} + +getdns_return_t +getdns_context_set_CAfile(getdns_context *context, const char *CAfile) +{ + if (!context || !CAfile) + return GETDNS_RETURN_INVALID_PARAMETER; + if (context->CAfile) + GETDNS_FREE(context->mf, context->CAfile); + context->CAfile = _getdns_strdup(&context->mf, CAfile); + + dispatch_updated(context, GETDNS_CONTEXT_CODE_CAFILE); + return GETDNS_RETURN_GOOD; +} + +getdns_return_t +getdns_context_get_CAfile(getdns_context *context, const char **CAfile) +{ + if (!context || !CAfile) + return GETDNS_RETURN_INVALID_PARAMETER; + + *CAfile = context->CAfile; + return GETDNS_RETURN_GOOD; +} /* context.c */ diff --git a/src/context.h b/src/context.h index 1a6d93a4..4d174e60 100644 --- a/src/context.h +++ b/src/context.h @@ -346,6 +346,9 @@ struct getdns_context { char *appdata_dir; _getdns_property can_write_appdata; + char *CApath; + char *CAfile; + getdns_upstreams *upstreams; uint16_t limit_outstanding_queries; uint32_t dnssec_allowed_skew; diff --git a/src/getdns/getdns_extra.h.in b/src/getdns/getdns_extra.h.in index ca62b2fb..f803d503 100644 --- a/src/getdns/getdns_extra.h.in +++ b/src/getdns/getdns_extra.h.in @@ -88,6 +88,10 @@ extern "C" { #define GETDNS_CONTEXT_CODE_TRUST_ANCHORS_VERIFY_EMAIL_TEXT "Change related to getdns_context_set_trust_anchors_verify_email" #define GETDNS_CONTEXT_CODE_APPDATA_DIR 628 #define GETDNS_CONTEXT_CODE_APPDATA_DIR_TEXT "Change related to getdns_context_set_appdata_dir" +#define GETDNS_CONTEXT_CODE_CAPATH 630 +#define GETDNS_CONTEXT_CODE_CAPATH_TEXT "Change related to getdns_context_set_CApath" +#define GETDNS_CONTEXT_CODE_CAFILE 631 +#define GETDNS_CONTEXT_CODE_CAFILE_TEXT "Change related to getdns_context_set_CAfile" /** @} */ @@ -680,6 +684,31 @@ getdns_return_t getdns_context_set_trust_anchors_verify_email( getdns_context *context, const char *verify_email); +/** + * Specify where the location for CA certificates for verification purposes + * are located. + * @see getdns_context_get_CApath + * @see getdns_context_set_CAfile + * @param[in] context The context to configure + * @param[in] CApath Directory with Certificate Authority certificates. + * @return GETDNS_RETURN_GOOD when successful + * @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL. + */ +getdns_return_t +getdns_context_set_CApath(getdns_context *context, const char *CApath); + +/** + * Specify the file with CA certificates for verification purposes. + * @see getdns_context_get_CAfile + * @see getdns_context_set_CApath + * @param[in] context The context to configure + * @param[in] CAfile The file with Certificate Authority certificates. + * @return GETDNS_RETURN_GOOD when successful + * @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL. + */ +getdns_return_t +getdns_context_set_CAfile(getdns_context *context, const char *CAfile); + /** * Get the current resolution type setting from this context. * @see getdns_context_set_resolution_type @@ -1134,6 +1163,32 @@ getdns_return_t getdns_context_get_trust_anchors_verify_email( getdns_context *context, const char **verify_email); +/** + * Get the location of the directory for CA certificates for verification + * purposes. + * @see getdns_context_set_CApath + * @see getdns_context_get_CAfile + * @param[in] context The context to configure + * @param[out] CApath Directory with Certificate Authority certificates + * or NULL when one was not configured. + * @return GETDNS_RETURN_GOOD when successful + * @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL. + */ +getdns_return_t +getdns_context_get_CApath(getdns_context *context, const char **CApath); + +/** + * Get the file location with CA certificates for verification purposes. + * @see getdns_context_set_CAfile + * @see getdns_context_get_CApath + * @param[in] context The context to configure + * @param[out] CAfile The file with Certificate Authority certificates + * or NULL when one was not configured. + * @return GETDNS_RETURN_GOOD when successful + * @return GETDNS_RETURN_INVALID_PARAMETER when context was NULL. + */ +getdns_return_t +getdns_context_get_CAfile(getdns_context *context, const char **CAfile); /** @} */ diff --git a/src/libgetdns.symbols b/src/libgetdns.symbols index 3f26578a..300baa70 100644 --- a/src/libgetdns.symbols +++ b/src/libgetdns.symbols @@ -7,6 +7,8 @@ getdns_context_create_with_extended_memory_functions getdns_context_create_with_memory_functions getdns_context_destroy getdns_context_detach_eventloop +getdns_context_get_CAfile +getdns_context_get_CApath getdns_context_get_api_information getdns_context_get_append_name getdns_context_get_dns_root_servers @@ -40,6 +42,8 @@ getdns_context_get_update_callback getdns_context_get_upstream_recursive_servers getdns_context_process_async getdns_context_run +getdns_context_set_CAfile +getdns_context_set_CApath getdns_context_set_appdata_dir getdns_context_set_append_name getdns_context_set_context_update_callback