From 0231d55db669883cc1fd61ea0e6517573df98c6d Mon Sep 17 00:00:00 2001 From: Daniel Heid Date: Fri, 3 Nov 2023 12:30:49 +0100 Subject: [PATCH] Allow to disable SSL checks --- .editorconfig | 48 ++++++------ README.md | 11 ++- .../java/org/matomo/java/tracking/Sender.java | 77 +++++++++++++++---- .../java/tracking/TrackerConfiguration.java | 23 +++++- .../tracking/TrustingHostnameVerifier.java | 18 +++++ .../tracking/TrustingX509TrustManager.java | 28 +++++++ .../org/matomo/java/tracking/SenderIT.java | 46 +++++++++-- .../TrustingHostnameVerifierTest.java | 17 ++++ .../TrustingX509TrustManagerTest.java | 28 +++++++ 9 files changed, 247 insertions(+), 49 deletions(-) create mode 100644 src/main/java/org/matomo/java/tracking/TrustingHostnameVerifier.java create mode 100644 src/main/java/org/matomo/java/tracking/TrustingX509TrustManager.java create mode 100644 src/test/java/org/matomo/java/tracking/TrustingHostnameVerifierTest.java create mode 100644 src/test/java/org/matomo/java/tracking/TrustingX509TrustManagerTest.java diff --git a/.editorconfig b/.editorconfig index 7525a5d7..13e36c31 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,7 +11,7 @@ ij_formatter_off_tag = @formatter:off ij_formatter_on_tag = @formatter:on ij_formatter_tags_enabled = true ij_smart_tabs = false -ij_visual_guides = +ij_visual_guides = ij_wrap_on_typing = false [*.java] @@ -67,7 +67,7 @@ ij_java_blank_lines_before_package = 1 ij_java_block_brace_style = end_of_line ij_java_block_comment_add_space = false ij_java_block_comment_at_first_column = true -ij_java_builder_methods = +ij_java_builder_methods = ij_java_call_parameters_new_line_after_left_paren = true ij_java_call_parameters_right_paren_on_new_line = true ij_java_call_parameters_wrap = on_every_item @@ -105,8 +105,8 @@ ij_java_enum_constants_wrap = split_into_lines ij_java_extends_keyword_wrap = normal ij_java_extends_list_wrap = on_every_item ij_java_field_annotation_wrap = split_into_lines -ij_java_field_name_prefix = -ij_java_field_name_suffix = +ij_java_field_name_prefix = +ij_java_field_name_suffix = ij_java_finally_on_new_line = false ij_java_for_brace_force = always ij_java_for_statement_new_line_after_left_paren = false @@ -115,7 +115,7 @@ ij_java_for_statement_wrap = on_every_item ij_java_generate_final_locals = false ij_java_generate_final_parameters = false ij_java_if_brace_force = always -ij_java_imports_layout = $*, |, * +ij_java_imports_layout = $*,|,* ij_java_indent_case_from_switch = true ij_java_insert_inner_class_imports = false ij_java_insert_override_annotation = true @@ -140,8 +140,8 @@ ij_java_layout_static_imports_separately = true ij_java_line_comment_add_space = false ij_java_line_comment_add_space_on_reformat = false ij_java_line_comment_at_first_column = true -ij_java_local_variable_name_prefix = -ij_java_local_variable_name_suffix = +ij_java_local_variable_name_prefix = +ij_java_local_variable_name_suffix = ij_java_method_annotation_wrap = split_into_lines ij_java_method_brace_style = end_of_line ij_java_method_call_chain_wrap = on_every_item @@ -154,17 +154,17 @@ ij_java_names_count_to_use_import_on_demand = 999 ij_java_new_line_after_lparen_in_annotation = true ij_java_new_line_after_lparen_in_deconstruction_pattern = true ij_java_new_line_after_lparen_in_record_header = true -ij_java_packages_to_use_import_on_demand = +ij_java_packages_to_use_import_on_demand = ij_java_parameter_annotation_wrap = split_into_lines -ij_java_parameter_name_prefix = -ij_java_parameter_name_suffix = +ij_java_parameter_name_prefix = +ij_java_parameter_name_suffix = ij_java_parentheses_expression_new_line_after_left_paren = true ij_java_parentheses_expression_right_paren_on_new_line = true ij_java_place_assignment_sign_on_next_line = false ij_java_prefer_longer_names = true ij_java_prefer_parameters_wrap = false ij_java_record_components_wrap = on_every_item -ij_java_repeat_annotations = +ij_java_repeat_annotations = ij_java_repeat_synchronized = true ij_java_replace_instanceof_and_cast = false ij_java_replace_null_check = true @@ -254,13 +254,13 @@ ij_java_spaces_within_synchronized_parentheses = false ij_java_spaces_within_try_parentheses = false ij_java_spaces_within_while_parentheses = false ij_java_special_else_if_treatment = true -ij_java_static_field_name_prefix = -ij_java_static_field_name_suffix = -ij_java_subclass_name_prefix = +ij_java_static_field_name_prefix = +ij_java_static_field_name_suffix = +ij_java_subclass_name_prefix = ij_java_subclass_name_suffix = Impl ij_java_ternary_operation_signs_on_next_line = false ij_java_ternary_operation_wrap = normal -ij_java_test_name_prefix = +ij_java_test_name_prefix = ij_java_test_name_suffix = Test ij_java_throws_keyword_wrap = normal ij_java_throws_list_wrap = on_every_item @@ -397,7 +397,7 @@ ij_groovy_ginq_on_wrap_policy = 1 ij_groovy_ginq_space_after_keyword = true ij_groovy_if_brace_force = never ij_groovy_import_annotation_wrap = 2 -ij_groovy_imports_layout = *, |, javax.**, java.**, |, $* +ij_groovy_imports_layout = *,|,javax.**,java.**,|,$* ij_groovy_indent_case_from_switch = true ij_groovy_indent_label_blocks = true ij_groovy_insert_inner_class_imports = false @@ -428,7 +428,7 @@ ij_groovy_method_parameters_right_paren_on_new_line = false ij_groovy_method_parameters_wrap = off ij_groovy_modifier_list_wrap = false ij_groovy_names_count_to_use_import_on_demand = 3 -ij_groovy_packages_to_use_import_on_demand = java.awt.*, javax.swing.* +ij_groovy_packages_to_use_import_on_demand = java.awt.*,javax.swing.* ij_groovy_parameter_annotation_wrap = off ij_groovy_parentheses_expression_new_line_after_left_paren = false ij_groovy_parentheses_expression_right_paren_on_new_line = false @@ -542,23 +542,23 @@ ij_json_spaces_within_brackets = false ij_json_wrap_long_lines = false [{*.htm,*.html,*.sht,*.shtm,*.shtml}] -ij_html_add_new_line_before_tags = body, div, p, form, h1, h2, h3 +ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 ij_html_align_attributes = true ij_html_align_text = false ij_html_attribute_wrap = normal ij_html_block_comment_add_space = false ij_html_block_comment_at_first_column = true ij_html_do_not_align_children_of_min_lines = 0 -ij_html_do_not_break_if_inline_tags = title, h1, h2, h3, h4, h5, h6, p -ij_html_do_not_indent_children_of_tags = html, body, thead, tbody, tfoot +ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p +ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot ij_html_enforce_quotes = false -ij_html_inline_tags = a, abbr, acronym, b, basefont, bdo, big, br, cite, cite, code, dfn, em, font, i, img, input, kbd, label, q, s, samp, select, small, span, strike, strong, sub, sup, textarea, tt, u, var +ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var ij_html_keep_blank_lines = 2 ij_html_keep_indents_on_empty_lines = false ij_html_keep_line_breaks = true ij_html_keep_line_breaks_in_text = true ij_html_keep_whitespaces = false -ij_html_keep_whitespaces_inside = span, pre, textarea +ij_html_keep_whitespaces_inside = span,pre,textarea ij_html_line_comment_at_first_column = true ij_html_new_line_after_last_attribute = never ij_html_new_line_before_first_attribute = never @@ -603,7 +603,7 @@ ij_kotlin_field_annotation_wrap = split_into_lines ij_kotlin_finally_on_new_line = false ij_kotlin_if_rparen_on_new_line = false ij_kotlin_import_nested_classes = false -ij_kotlin_imports_layout = *, java.**, javax.**, kotlin.**, ^ +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ ij_kotlin_insert_whitespaces_in_simple_one_line_method = true ij_kotlin_keep_blank_lines_before_right_brace = 2 ij_kotlin_keep_blank_lines_in_code = 2 @@ -623,7 +623,7 @@ ij_kotlin_method_parameters_right_paren_on_new_line = false ij_kotlin_method_parameters_wrap = off ij_kotlin_name_count_to_use_star_import = 5 ij_kotlin_name_count_to_use_star_import_for_members = 3 -ij_kotlin_packages_to_use_import_on_demand = java.util.*, kotlinx.android.synthetic.**, io.ktor.** +ij_kotlin_packages_to_use_import_on_demand = java.util.*,kotlinx.android.synthetic.**,io.ktor.** ij_kotlin_parameter_annotation_wrap = off ij_kotlin_space_after_comma = true ij_kotlin_space_after_extend_colon = true diff --git a/README.md b/README.md index 83036daf..7c59ce12 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Features include: * Supports custom dimensions and custom variables * Includes tracking parameters for campaigns, events, downloads, outlinks, site search, devices, visiors * Supports Java 8 and higher +* Allows you to skip SSL certificate validation (not recommended for production) * Contains nearly no dependencies * Allows asynchronous requests * Supports Matomo 4 and 5 @@ -29,7 +30,7 @@ Further information on Matomo and Matomo HTTP tracking: * [Matomo PHP Tracker](https://github.com/matomo-org/matomo-php-tracker) * [Matomo Tracking HTTP API](https://developer.matomo.org/api-reference/tracking-api) -* [Introducting the Matomo Java Tracker](https://matomo.org/blog/2015/11/introducing-piwik-java-tracker/) +* [Introducing the Matomo Java Tracker](https://matomo.org/blog/2015/11/introducing-piwik-java-tracker/) * [Tracking API User Guide](https://matomo.org/guide/apis/tracking-api/) * [Matomo Developer](https://developer.matomo.org/) * [The Matomo project](https://matomo.org/) @@ -222,10 +223,14 @@ The Matomo Tracker currently supports the following builder methods: * `.proxyHost(...)` The hostname or IP address of an optional HTTP proxy. `proxyPort` must be configured as well * `.proxyPort(...)` The port of an HTTP proxy. `proxyHost` must be configured as well. -* `.proxyUserName(...)` If the HTTP proxy requires a user name for basic authentication, it can be +* `.proxyUserName(...)` If the HTTP proxy requires a username for basic authentication, it can be configured with this method. Proxy host, port and password must also be set. * `.proxyPassword(...)` The corresponding password for the basic auth proxy user. The proxy host, - port and user name must be set as well. + port and username must be set as well. +* `.disableSslCertValidation(...)` If set to true, the SSL certificate of the Matomo server will not be validated. This + should only be used for testing purposes. Default: false +* `.disableSslHostVerification(...)` If set to true, the SSL host of the Matomo server will not be validated. This should + only be used for testing purposes. Default: false To send a single request synchronously via GET, call diff --git a/src/main/java/org/matomo/java/tracking/Sender.java b/src/main/java/org/matomo/java/tracking/Sender.java index 12a2c561..086dc6ec 100644 --- a/src/main/java/org/matomo/java/tracking/Sender.java +++ b/src/main/java/org/matomo/java/tracking/Sender.java @@ -23,6 +23,7 @@ import java.net.URI; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -30,6 +31,9 @@ import java.util.concurrent.Executor; import java.util.stream.Collectors; import java.util.stream.StreamSupport; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -37,6 +41,12 @@ @RequiredArgsConstructor class Sender { + private static final TrustManager[] TRUST_ALL_MANAGERS = new TrustManager[] { + new TrustingX509TrustManager() + }; + public static final TrustingHostnameVerifier TRUSTING_HOSTNAME_VERIFIER = + new TrustingHostnameVerifier(); + private final TrackerConfiguration trackerConfiguration; private final QueryCreator queryCreator; @@ -87,28 +97,64 @@ void sendSingle( } private HttpURLConnection openConnection(URL url) { + HttpURLConnection connection; try { if (isEmpty(trackerConfiguration.getProxyHost()) || trackerConfiguration.getProxyPort() <= 0) { log.debug("Proxy host or proxy port not configured. Will create connection without proxy"); - return (HttpURLConnection) url.openConnection(); - } - InetSocketAddress proxyAddress = new InetSocketAddress( - trackerConfiguration.getProxyHost(), - trackerConfiguration.getProxyPort() - ); - Proxy proxy = new Proxy(Proxy.Type.HTTP, proxyAddress); - if (!isEmpty(trackerConfiguration.getProxyUserName()) - && !isEmpty(trackerConfiguration.getProxyPassword())) { - Authenticator.setDefault(new ProxyAuthenticator( - trackerConfiguration.getProxyUserName(), - trackerConfiguration.getProxyPassword() - )); + connection = (HttpURLConnection) url.openConnection(); + } else { + connection = openProxiedConnection(url); } - return (HttpURLConnection) url.openConnection(proxy); } catch (IOException e) { throw new MatomoException("Could not open connection", e); } + if (connection instanceof HttpsURLConnection) { + applySslConfiguration((HttpsURLConnection) connection); + } + return connection; + } + + private void applySslConfiguration( + @NonNull + HttpsURLConnection connection + ) { + requireNonNull(connection, "Connection must not be null"); + if (trackerConfiguration.isDisableSslCertValidation()) { + try { + SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, TRUST_ALL_MANAGERS, new SecureRandom()); + connection.setSSLSocketFactory(sslContext.getSocketFactory()); + } catch (Exception e) { + throw new MatomoException("Could not disable SSL certification validation", e); + } + } + if (trackerConfiguration.isDisableSslHostVerification()) { + connection.setHostnameVerifier(TRUSTING_HOSTNAME_VERIFIER); + } + } + + private HttpURLConnection openProxiedConnection(@NonNull URL url) throws IOException { + requireNonNull(url, "URL must not be null"); + requireNonNull(trackerConfiguration.getProxyHost(), "Proxy host must not be null"); + if (trackerConfiguration.getProxyPort() <= 0) { + throw new IllegalArgumentException("Proxy port must be configured"); + } + InetSocketAddress proxyAddress = new InetSocketAddress(trackerConfiguration.getProxyHost(), + trackerConfiguration.getProxyPort() + ); + Proxy proxy = new Proxy(Proxy.Type.HTTP, proxyAddress); + if (!isEmpty(trackerConfiguration.getProxyUserName()) + && !isEmpty(trackerConfiguration.getProxyPassword())) { + Authenticator.setDefault(new ProxyAuthenticator(trackerConfiguration.getProxyUserName(), + trackerConfiguration.getProxyPassword() + )); + } + log.debug("Using proxy {} on port {}", + trackerConfiguration.getProxyHost(), + trackerConfiguration.getProxyPort() + ); + return (HttpURLConnection) url.openConnection(proxy); } private void configureAgentsAndTimeouts(HttpURLConnection connection) { @@ -168,8 +214,7 @@ private void sendBulk( } preparePostConnection(connection); configureAgentsAndTimeouts(connection); - log.debug( - "Sending bulk request using URI {} asynchronously", + log.debug("Sending bulk request using URI {} asynchronously", trackerConfiguration.getApiEndpoint() ); OutputStream outputStream = null; diff --git a/src/main/java/org/matomo/java/tracking/TrackerConfiguration.java b/src/main/java/org/matomo/java/tracking/TrackerConfiguration.java index be22aeed..81a89c33 100644 --- a/src/main/java/org/matomo/java/tracking/TrackerConfiguration.java +++ b/src/main/java/org/matomo/java/tracking/TrackerConfiguration.java @@ -98,10 +98,31 @@ public class TrackerConfiguration { @NonNull String userAgent = "MatomoJavaClient"; /** - * Logs if the Matomo Tracking API endpoint responds with an erroneous HTTP code. + * Logs if the Matomo Tracking API endpoint responds with an erroneous HTTP code. Defaults to + * false. */ boolean logFailedTracking; + /** + * Disables SSL certificate validation. This is useful for testing with self-signed certificates. + * Do not use in production environments. Defaults to false. + * + *

Attention: This slows down performance + + * @see #disableSslHostVerification + */ + boolean disableSslCertValidation; + + /** + * Disables SSL host verification. This is useful for testing with self-signed certificates. Do + * not use in production environments. Defaults to false. + * + *

Attention: This slows down performance + * + * @see #disableSslCertValidation + */ + boolean disableSslHostVerification; + /** * Validates the auth token. The auth token must be exactly 32 characters long. */ diff --git a/src/main/java/org/matomo/java/tracking/TrustingHostnameVerifier.java b/src/main/java/org/matomo/java/tracking/TrustingHostnameVerifier.java new file mode 100644 index 00000000..341487d6 --- /dev/null +++ b/src/main/java/org/matomo/java/tracking/TrustingHostnameVerifier.java @@ -0,0 +1,18 @@ +package org.matomo.java.tracking; + +import edu.umd.cs.findbugs.annotations.Nullable; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLSession; + +class TrustingHostnameVerifier implements HostnameVerifier { + + @Override + public boolean verify( + @Nullable + String hostname, + @Nullable + SSLSession session + ) { + return true; + } +} diff --git a/src/main/java/org/matomo/java/tracking/TrustingX509TrustManager.java b/src/main/java/org/matomo/java/tracking/TrustingX509TrustManager.java new file mode 100644 index 00000000..790db746 --- /dev/null +++ b/src/main/java/org/matomo/java/tracking/TrustingX509TrustManager.java @@ -0,0 +1,28 @@ +package org.matomo.java.tracking; + +import edu.umd.cs.findbugs.annotations.Nullable; +import java.security.cert.X509Certificate; +import javax.net.ssl.X509TrustManager; + +class TrustingX509TrustManager implements X509TrustManager { + + @Override + @Nullable + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted( + @Nullable X509Certificate[] chain, @Nullable String authType + ) { + // no operation + } + + @Override + public void checkServerTrusted( + @Nullable X509Certificate[] chain, @Nullable String authType + ) { + // no operation + } +} diff --git a/src/test/java/org/matomo/java/tracking/SenderIT.java b/src/test/java/org/matomo/java/tracking/SenderIT.java index 96301c2b..c571ddaa 100644 --- a/src/test/java/org/matomo/java/tracking/SenderIT.java +++ b/src/test/java/org/matomo/java/tracking/SenderIT.java @@ -1,5 +1,9 @@ package org.matomo.java.tracking; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.status; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.github.tomakehurst.wiremock.WireMockServer; @@ -12,7 +16,7 @@ class SenderIT { private static final WireMockServer wireMockServer = - new WireMockServer(WireMockConfiguration.options().dynamicPort()); + new WireMockServer(WireMockConfiguration.options().dynamicPort().dynamicHttpsPort()); @BeforeAll static void beforeAll() { @@ -33,8 +37,12 @@ void sendSingleFailsIfQueryIsMalformed() { @Test void failsIfEndpointReturnsNotFound() { - TrackerConfiguration trackerConfiguration = - TrackerConfiguration.builder().apiEndpoint(URI.create(wireMockServer.baseUrl())).build(); + TrackerConfiguration trackerConfiguration = TrackerConfiguration + .builder() + .apiEndpoint(URI.create(wireMockServer.baseUrl())) + .disableSslHostVerification(true) + .disableSslCertValidation(true) + .build(); Sender sender = new Sender(trackerConfiguration, new QueryCreator(trackerConfiguration), Runnable::run); @@ -62,6 +70,8 @@ void connectsViaProxy() throws Exception { TrackerConfiguration trackerConfiguration = TrackerConfiguration .builder() .apiEndpoint(URI.create(wireMockServer.baseUrl())) + .disableSslCertValidation(true) + .disableSslHostVerification(true) .proxyHost("localhost") .proxyPort(wireMockServer.port()) .build(); @@ -71,7 +81,7 @@ void connectsViaProxy() throws Exception { assertThatThrownBy(() -> sender.sendSingle(new MatomoRequest())) .isInstanceOf(MatomoException.class) - .hasMessage("Tracking endpoint responded with code 400"); + .hasMessage("Could not send request via GET"); } @Test @@ -79,6 +89,8 @@ void connectsViaProxyWithProxyUserNameAndPassword() throws Exception { TrackerConfiguration trackerConfiguration = TrackerConfiguration .builder() .apiEndpoint(URI.create(wireMockServer.baseUrl())) + .disableSslCertValidation(true) + .disableSslHostVerification(true) .proxyHost("localhost") .proxyPort(wireMockServer.port()) .proxyUserName("user") @@ -90,7 +102,7 @@ void connectsViaProxyWithProxyUserNameAndPassword() throws Exception { assertThatThrownBy(() -> sender.sendSingle(new MatomoRequest())) .isInstanceOf(MatomoException.class) - .hasMessage("Tracking endpoint responded with code 400"); + .hasMessage("Could not send request via GET"); } @Test @@ -98,6 +110,8 @@ void logsFailedTracking() throws Exception { TrackerConfiguration trackerConfiguration = TrackerConfiguration .builder() .apiEndpoint(URI.create(wireMockServer.baseUrl())) + .disableSslCertValidation(true) + .disableSslHostVerification(true) .logFailedTracking(true) .build(); @@ -109,4 +123,26 @@ void logsFailedTracking() throws Exception { .hasMessage("Tracking endpoint responded with code 404"); } + @Test + void skipSslCertificationValidation() { + wireMockServer.stubFor(get(urlPathEqualTo("/matomo_ssl.php")).willReturn(status(204))); + TrackerConfiguration trackerConfiguration = + TrackerConfiguration + .builder() + .apiEndpoint(URI.create(String.format("https://localhost:%d/matomo_ssl.php", + wireMockServer.httpsPort() + ))) + .disableSslCertValidation(true) + .disableSslHostVerification(true) + .build(); + + Sender sender = + new Sender(trackerConfiguration, new QueryCreator(trackerConfiguration), Runnable::run); + + sender.sendSingle(new MatomoRequest()); + + wireMockServer.verify(getRequestedFor(urlPathEqualTo("/matomo_ssl.php"))); + + } + } diff --git a/src/test/java/org/matomo/java/tracking/TrustingHostnameVerifierTest.java b/src/test/java/org/matomo/java/tracking/TrustingHostnameVerifierTest.java new file mode 100644 index 00000000..e3e61969 --- /dev/null +++ b/src/test/java/org/matomo/java/tracking/TrustingHostnameVerifierTest.java @@ -0,0 +1,17 @@ +package org.matomo.java.tracking; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; + +class TrustingHostnameVerifierTest { + + @Test + void verifyAlwaysReturnsTrue() { + + boolean verified = new TrustingHostnameVerifier().verify(null, null); + + assertThat(verified).isTrue(); + } + +} \ No newline at end of file diff --git a/src/test/java/org/matomo/java/tracking/TrustingX509TrustManagerTest.java b/src/test/java/org/matomo/java/tracking/TrustingX509TrustManagerTest.java new file mode 100644 index 00000000..895017de --- /dev/null +++ b/src/test/java/org/matomo/java/tracking/TrustingX509TrustManagerTest.java @@ -0,0 +1,28 @@ +package org.matomo.java.tracking; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.security.cert.X509Certificate; +import org.junit.jupiter.api.Test; + +class TrustingX509TrustManagerTest { + + private final TrustingX509TrustManager trustingX509TrustManager = new TrustingX509TrustManager(); + + @Test + void acceptedIssuersIsAlwaysNull() { + X509Certificate[] acceptedIssuers = trustingX509TrustManager.getAcceptedIssuers(); + assertThat(acceptedIssuers).isNull(); + } + + @Test + void checkClientTrustedDoesNothing() { + trustingX509TrustManager.checkClientTrusted(null, null); + } + + @Test + void checkServerTrustedDoesNothing() { + trustingX509TrustManager.checkServerTrusted(null, null); + } + +} \ No newline at end of file