diff --git a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/SSLFactory.java b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/SSLFactory.java index efee4b13..fe7f5e48 100644 --- a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/SSLFactory.java +++ b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/SSLFactory.java @@ -868,16 +868,16 @@ public SSLFactory build() { SSLParameters baseSslParameters = createSslParameters(baseSslContext); SSLContext sslContext = new FenixSSLContext(baseSslContext, baseSslParameters); - HostnameVerifier hostnameVerifier = Optional.ofNullable(hostnameVerifierEnhancer) - .map(enhancer -> HostnameVerifierUtils.createEnhanceable(this.hostnameVerifier, enhancer)) - .orElse(this.hostnameVerifier); + HostnameVerifier resolvedHostnameVerifier = Optional.ofNullable(hostnameVerifierEnhancer) + .map(enhancer -> HostnameVerifierUtils.createEnhanceable(hostnameVerifier, enhancer)) + .orElse(hostnameVerifier); SSLMaterial sslMaterial = new SSLMaterial.Builder() .withSslContext(sslContext) .withKeyManager(keyManager) .withTrustManager(trustManager) .withSslParameters(baseSslParameters) - .withHostnameVerifier(hostnameVerifier) + .withHostnameVerifier(resolvedHostnameVerifier) .withCiphers(Collections.unmodifiableList(Arrays.asList(baseSslParameters.getCipherSuites()))) .withProtocols(Collections.unmodifiableList(Arrays.asList(baseSslParameters.getProtocols()))) .build(); diff --git a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/hostnameverifier/HostnameCommon.java b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/hostnameverifier/HostnameCommon.java index cf60ebfd..90e81c3b 100644 --- a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/hostnameverifier/HostnameCommon.java +++ b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/hostnameverifier/HostnameCommon.java @@ -52,12 +52,9 @@ static boolean containsInvalidLabelLengths(String hostname) { if (labelLength < 1 || labelLength > 63) { return true; } - if (dot == -1) { + if (dot == -1 || dot == hostname.length() - 1 ) { break; } - if (dot == hostname.length() - 1) { - break; // Trailing '.' is allowed. - } labelStart = dot + 1; } diff --git a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManager.java b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManager.java index 45711c3f..3365e151 100644 --- a/sslcontext-kickstart/src/main/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManager.java +++ b/sslcontext-kickstart/src/main/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManager.java @@ -60,7 +60,7 @@ public class InflatableX509ExtendedTrustManager extends HotSwappableX509ExtendedTrustManager { private static final Logger LOGGER = LoggerFactory.getLogger(InflatableX509ExtendedTrustManager.class); - private static final BiPredicate IGNORE_DUPLICATE_CHECKER = (trustStore, certificate) -> false; + private static final BiPredicate IGNORE_DUPLICATE_CHECKER = (t, c) -> false; private final KeyStore trustStore; private final Path trustStorePath; diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManagerShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManagerShould.java index ea80b1ad..7482f87d 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManagerShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/trustmanager/InflatableX509ExtendedTrustManagerShould.java @@ -17,7 +17,9 @@ import nl.altindag.log.LogCaptor; import nl.altindag.log.model.LogEvent; +import nl.altindag.ssl.exception.GenericKeyStoreException; import nl.altindag.ssl.model.TrustManagerParameters; +import nl.altindag.ssl.util.CertificateUtils; import nl.altindag.ssl.util.KeyStoreUtils; import org.junit.jupiter.api.Test; import org.mockito.MockedStatic; @@ -46,9 +48,11 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Predicate; +import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; +import static nl.altindag.ssl.TestConstants.DER_LOCATION; import static nl.altindag.ssl.TestConstants.HOME_DIRECTORY; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -56,6 +60,8 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -265,8 +271,10 @@ void addNewlyTrustedCertificatesWhileAlsoWritingToAKeyStoreOnTheFileSystem() thr assertThat(trustedCerts).hasSizeGreaterThan(0); - Path trustStoreDestination = Paths.get(HOME_DIRECTORY, "inflatable-truststore.p12"); - assertThat(Files.exists(trustStoreDestination)).isFalse(); + Path destinationDirectory = Paths.get(HOME_DIRECTORY, "hakky54-ssl"); + Path trustStoreDestination = destinationDirectory.resolve("inflatable-truststore.p12"); + Files.createDirectories(destinationDirectory); + assertThat(Files.exists(destinationDirectory)).isTrue(); InflatableX509ExtendedTrustManager trustManager = new InflatableX509ExtendedTrustManager(trustStoreDestination, "secret".toCharArray(), "PKCS12", trustManagerParameters -> true); trustManager.addCertificates(Arrays.asList(trustedCerts)); @@ -278,7 +286,27 @@ void addNewlyTrustedCertificatesWhileAlsoWritingToAKeyStoreOnTheFileSystem() thr KeyStore inflatedTrustStore = KeyStoreUtils.loadKeyStore(trustStoreDestination, "secret".toCharArray(), "PKCS12"); assertThat(KeyStoreTestUtils.getTrustedX509Certificates(inflatedTrustStore)).containsExactly(trustedCerts); - Files.delete(trustStoreDestination); + Files.deleteIfExists(trustStoreDestination); + Files.deleteIfExists(destinationDirectory); + } + + @Test + void addOnlyOnceNewlyTrustedCertificates() throws KeyStoreException { + LogCaptor logCaptor = LogCaptor.forClass(InflatableX509ExtendedTrustManager.class); + KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD); + X509Certificate[] trustedCerts = KeyStoreTestUtils.getTrustedX509Certificates(trustStore); + + assertThat(trustedCerts).hasSizeGreaterThan(0); + + InflatableX509ExtendedTrustManager trustManager = new InflatableX509ExtendedTrustManager(null, null, null, trustManagerParameters -> true); + trustManager.addCertificates(Arrays.asList(trustedCerts)); + + assertThat(trustManager.getAcceptedIssuers()).containsExactly(trustedCerts); + assertThat(logCaptor.getInfoLogs()).containsExactly("Added certificate for [cn=googlecom_o=google-llc_l=mountain-view_st=california_c=us]"); + logCaptor.clearLogs(); + + trustManager.addCertificates(Arrays.asList(trustedCerts)); + assertThat(logCaptor.getInfoLogs()).isEmpty(); } @Test @@ -310,6 +338,26 @@ void callPredicateAndAddCertificatesIfTrusted() throws KeyStoreException, IOExce Files.delete(trustStoreDestination); } + @Test + void notAddCertificateIfInnerTrustManagerHasTrustedTheNewCertificateFromADifferentThread() throws KeyStoreException, CertificateException { + X509ExtendedTrustManager innerTrustManager = mock(X509ExtendedTrustManager.class); + doThrow(new CertificateException("KABOOOM!")) + .doNothing() + .when(innerTrustManager) + .checkServerTrusted(any(), anyString()); + + KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD); + X509Certificate notYetTrustedCert = KeyStoreTestUtils.getTrustedX509Certificates(trustStore)[0]; + + AtomicBoolean shouldTrust = new AtomicBoolean(true); + Predicate predicate = trustManagerParameters -> shouldTrust.get(); + InflatableX509ExtendedTrustManager trustManager = new InflatableX509ExtendedTrustManager(null, null, null, predicate); + trustManager.setTrustManager(innerTrustManager); + + trustManager.checkServerTrusted(new X509Certificate[] {notYetTrustedCert}, "RSA"); + assertThat(trustManager.getInnerTrustManager()).isEqualTo(innerTrustManager); + } + @Test void onlyCallPredicateOnceWhenConcurrentThreadsCheckForTheSameCertificate() throws KeyStoreException, IOException, InterruptedException, ExecutionException { LogCaptor logCaptor = LogCaptor.forClass(InflatableX509ExtendedTrustManager.class); @@ -478,4 +526,55 @@ void checkClientTrustedWithSSLEngine() throws CertificateException { verify(innerTrustManager, times(1)).checkClientTrusted(chain, authType, sslEngine); } + @Test + void wrapKeyStoreExceptionIntoGenericKeyStoreExceptionWhenCallingGenerateAlias() throws KeyStoreException, IOException { + LogCaptor logCaptor = LogCaptor.forClass(InflatableX509ExtendedTrustManager.class); + + KeyStore trustStore = spy(KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD)); + doThrow(new KeyStoreException("KABOOM!")).when(trustStore).containsAlias(anyString()); + + List notYetTrustedCerts = CertificateUtils.loadCertificate(DER_LOCATION + "digicert.cer") + .stream() + .filter(X509Certificate.class::isInstance) + .map(X509Certificate.class::cast) + .collect(Collectors.toList()); + + assertThat(notYetTrustedCerts).hasSize(1); + + Path destinationDirectory = Paths.get(HOME_DIRECTORY, "hakky54-ssl"); + Path trustStoreDestination = destinationDirectory.resolve("inflatable-truststore.p12"); + Files.createDirectories(destinationDirectory); + assertThat(Files.exists(destinationDirectory)).isTrue(); + + KeyStoreUtils.write(trustStoreDestination, trustStore, TRUSTSTORE_PASSWORD); + assertThat(Files.exists(trustStoreDestination)).isTrue(); + + try(MockedStatic mockedStatic = mockStatic(KeyStoreUtils.class, invocationOnMock -> { + Method method = invocationOnMock.getMethod(); + if ("loadKeyStore".equals(method.getName())) { + return trustStore; + } else { + return invocationOnMock.callRealMethod(); + } + })) { + InflatableX509ExtendedTrustManager trustManager = new InflatableX509ExtendedTrustManager(trustStoreDestination, "secret".toCharArray(), "PKCS12", trustManagerParameters -> true); + assertThat(trustManager.getAcceptedIssuers()).hasSize(1); + + trustManager.addCertificates(notYetTrustedCerts); + assertThat(trustManager.getAcceptedIssuers()).hasSize(1); + + List logEvents = logCaptor.getLogEvents(); + assertThat(logEvents).hasSize(1); + + LogEvent logEvent = logEvents.get(0); + assertThat(logEvent.getLevel()).isEqualTo("ERROR"); + assertThat(logEvent.getMessage()).isEqualTo("Cannot add certificate"); + assertThat(logEvent.getThrowable()).isPresent(); + assertThat(logEvent.getThrowable().get()).isInstanceOf(GenericKeyStoreException.class); + } finally { + Files.deleteIfExists(trustStoreDestination); + Files.deleteIfExists(destinationDirectory); + } + } + } diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java index cd09b53f..6127aa6e 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/CertificateUtilsShould.java @@ -37,10 +37,10 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.KeyStore; -import java.security.KeyStoreException; +import java.security.*; import java.security.cert.Certificate; import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; @@ -62,6 +62,7 @@ import static nl.altindag.ssl.TestConstants.TRUSTSTORE_PASSWORD; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -535,6 +536,54 @@ void isNotSelfSigned() { assertThat(selfSigned).isFalse(); } + @Test + void wrapCertificateExceptionIntoGenericCertificateExceptionWhenIsSelfSignedCallFails() throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException, NoSuchProviderException { + List certificates = CertificateUtils.loadCertificate(PEM_LOCATION + "not-self-signed.pem"); + assertThat(certificates).hasSize(1); + Certificate certificate = spy(certificates.get(0)); + + doThrow(new CertificateException("KABOOM!")).when(certificate).verify(any()); + + assertThatThrownBy(() -> CertificateUtils.isSelfSigned(certificate)) + .isInstanceOf(GenericCertificateException.class); + } + + @Test + void wrapNoSuchAlgorithmExceptionIntoGenericCertificateExceptionWhenIsSelfSignedCallFails() throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException, NoSuchProviderException { + List certificates = CertificateUtils.loadCertificate(PEM_LOCATION + "not-self-signed.pem"); + assertThat(certificates).hasSize(1); + Certificate certificate = spy(certificates.get(0)); + + doThrow(new NoSuchAlgorithmException("KABOOM!")).when(certificate).verify(any()); + + assertThatThrownBy(() -> CertificateUtils.isSelfSigned(certificate)) + .isInstanceOf(GenericCertificateException.class); + } + + @Test + void wrapInvalidKeyExceptionIntoGenericCertificateExceptionWhenIsSelfSignedCallFails() throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException, NoSuchProviderException { + List certificates = CertificateUtils.loadCertificate(PEM_LOCATION + "not-self-signed.pem"); + assertThat(certificates).hasSize(1); + Certificate certificate = spy(certificates.get(0)); + + doThrow(new InvalidKeyException("KABOOM!")).when(certificate).verify(any()); + + assertThatThrownBy(() -> CertificateUtils.isSelfSigned(certificate)) + .isInstanceOf(GenericCertificateException.class); + } + + @Test + void wrapNoSuchProviderExceptionIntoGenericCertificateExceptionWhenIsSelfSignedCallFails() throws CertificateException, NoSuchAlgorithmException, SignatureException, InvalidKeyException, NoSuchProviderException { + List certificates = CertificateUtils.loadCertificate(PEM_LOCATION + "not-self-signed.pem"); + assertThat(certificates).hasSize(1); + Certificate certificate = spy(certificates.get(0)); + + doThrow(new NoSuchProviderException("KABOOM!")).when(certificate).verify(any()); + + assertThatThrownBy(() -> CertificateUtils.isSelfSigned(certificate)) + .isInstanceOf(GenericCertificateException.class); + } + @Test void notAddSubjectAndIssuerAsHeaderWhenCertificateTypeIsNotX509Certificate() throws CertificateEncodingException { Certificate certificate = mock(Certificate.class); diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/HostnameVerifierUtilsShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/HostnameVerifierUtilsShould.java index fcdfc702..41b454a2 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/HostnameVerifierUtilsShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/HostnameVerifierUtilsShould.java @@ -16,6 +16,7 @@ package nl.altindag.ssl.util; import nl.altindag.ssl.hostnameverifier.BasicHostnameVerifier; +import nl.altindag.ssl.hostnameverifier.FenixHostnameVerifier; import nl.altindag.ssl.hostnameverifier.UnsafeHostnameVerifier; import org.junit.jupiter.api.Test; @@ -46,4 +47,22 @@ void createUnsafe() { .isInstanceOf(UnsafeHostnameVerifier.class); } + @Test + void createFenix() { + HostnameVerifier hostnameVerifier = HostnameVerifierUtils.createFenix(); + + assertThat(hostnameVerifier) + .isNotNull() + .isInstanceOf(FenixHostnameVerifier.class); + } + + @Test + void createDefault() { + HostnameVerifier hostnameVerifier = HostnameVerifierUtils.createDefault(); + + assertThat(hostnameVerifier) + .isNotNull() + .isInstanceOf(FenixHostnameVerifier.class); + } + } diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/KeyStoreUtilsShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/KeyStoreUtilsShould.java index 52511a2a..e5bd2f1c 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/KeyStoreUtilsShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/KeyStoreUtilsShould.java @@ -362,6 +362,25 @@ void createTrustStoreFromMultipleTrustManagers() throws KeyStoreException { assertThat(trustStore.size()).isEqualTo(jdkTrustManager.getAcceptedIssuers().length + customTrustManager.getAcceptedIssuers().length); } + @Test + void returnTrueWhenItDoesContainsCertificate() { + KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD); + X509ExtendedTrustManager trustManager = TrustManagerUtils.createTrustManager(trustStore); + X509Certificate[] acceptedIssuers = trustManager.getAcceptedIssuers(); + assertThat(acceptedIssuers).isNotEmpty(); + + X509Certificate certificates = acceptedIssuers[0]; + assertThat(KeyStoreUtils.containsCertificate(trustStore, certificates)).isTrue(); + } + + @Test + void returnFalseWhenItDoesNotContainsCertificate() { + KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD); + + X509Certificate certificates = mock(X509Certificate.class); + assertThat(KeyStoreUtils.containsCertificate(trustStore, certificates)).isFalse(); + } + @Test void countAmountOfTrustMaterial() { KeyStore trustStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + TRUSTSTORE_FILE_NAME, TRUSTSTORE_PASSWORD); @@ -666,7 +685,7 @@ void getAliasToCertificate() { void getAliasToCertificateFiltersOutKeyMaterial() throws KeyStoreException { KeyStore keyStore = KeyStoreUtils.loadKeyStore(KEYSTORE_LOCATION + IDENTITY_FILE_NAME, KEYSTORE_PASSWORD); - assertThat(keyStore.size()).isGreaterThan(0); + assertThat(keyStore.size()).isPositive(); Map aliasToCertificate = KeyStoreUtils.getAliasToCertificate(keyStore); assertThat(aliasToCertificate).isEmpty(); @@ -700,6 +719,28 @@ void createKeyStoreIfAvailableReturnsFilledKeyStore() { } } + @Test + void wrapKeyStoreExceptionIntoAGenericKeyStoreExceptionWhenCallingContainsCertificateFails() throws KeyStoreException { + KeyStore keyStore = mock(KeyStore.class); + Certificate certificate = mock(Certificate.class); + + doThrow((new KeyStoreException("KABOOM!"))).when(keyStore).getCertificateAlias(certificate); + + assertThatThrownBy(() -> KeyStoreUtils.containsCertificate(keyStore, certificate)) + .isInstanceOf(GenericKeyStoreException.class); + } + + @Test + void wrapKeyStoreExceptionIntoAGenericKeyStoreExceptionWhenCallingContainsTrustMaterialFails() throws KeyStoreException { + KeyStore keyStore = mock(KeyStore.class); + + when(keyStore.aliases()).thenReturn(Collections.enumeration(Collections.singletonList("some-alias"))); + doThrow((new KeyStoreException("KABOOM!"))).when(keyStore).isCertificateEntry("some-alias"); + + assertThatThrownBy(() -> KeyStoreUtils.containsTrustMaterial(keyStore)) + .isInstanceOf(GenericKeyStoreException.class); + } + @Test void createKeyStoreIfAvailableReturnsFilledKeyStoreWithoutLoggingIfDebugIsDisabled() { LogCaptor logCaptor = LogCaptor.forClass(KeyStoreUtils.class); diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/LinuxCertificateUtilsShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/LinuxCertificateUtilsShould.java index 33022615..2a06981c 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/LinuxCertificateUtilsShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/LinuxCertificateUtilsShould.java @@ -35,7 +35,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.times; /** * @author Hakan Altindag @@ -299,6 +301,38 @@ void wrapAnIOExceptionInAGenericIOExceptionWhenFilesWalkFails() { resetOsName(); } + @Test + void ignoreAnyErrorWhenCallingLoadCertificate() { + try (MockedStatic certificateUtilsMockedStatic = mockStatic(CertificateUtils.class, invocation -> { + Method method = invocation.getMethod(); + if ("loadCertificate".equals(method.getName())) { + throw new IOException("KABOOM"); + } else { + return invocation.callRealMethod(); + } + }); + MockedStatic filesMockedStatic = mockStatic(Files.class, invocation -> { + Method method = invocation.getMethod(); + if ("exists".equals(method.getName())) { + return true; + } else if ("isRegularFile".equals(method.getName())) { + return true; + } else { + return invocation.callRealMethod(); + } + })) { + + System.setProperty("os.name", "linux"); + + List certificates = LinuxCertificateUtils.getCertificates(); + assertThat(certificates).isEmpty(); + + certificateUtilsMockedStatic.verify(() -> CertificateUtils.loadCertificate(any(Path.class)), times(8)); + + resetOsName(); + } + } + @Test void notGetCertificatesIfPathIsNotARegularFileAndAlsoNotADirectory() { System.setProperty("os.name", "linux"); diff --git a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/internal/UriUtilsShould.java b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/internal/UriUtilsShould.java index 50936e6c..915c8b16 100644 --- a/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/internal/UriUtilsShould.java +++ b/sslcontext-kickstart/src/test/java/nl/altindag/ssl/util/internal/UriUtilsShould.java @@ -34,7 +34,13 @@ void extractHost() { } @Test - void throwExceptionWhenInvalidUriIsProvided() { + void extractPort() { + int port = UriUtils.extractPort("https://my-first-domain.com:443"); + assertThat(port).isEqualTo(443); + } + + @Test + void throwExceptionWhenInvalidUriIsProvidedWhileExtractingTheHost() { assertThatThrownBy(() -> UriUtils.extractHost("https://my-first-domain.com/q/h?s=^IXIC")) .isInstanceOf(IllegalArgumentException.class); } @@ -62,4 +68,10 @@ void throwExceptionWhenHostIsProvidedWithoutAValidHostnameIsProvidedWhenValidate .hasMessage("Hostname should be defined for the given input: [https:/]"); } + @Test + void throwExceptionWhenInvalidUriIsProvidedWhileExtractingThePort() { + assertThatThrownBy(() -> UriUtils.extractPort("https://my-first-domain.com/q/h?s=^IXIC")) + .isInstanceOf(IllegalArgumentException.class); + } + }