sslProxy, TLS Tutorials#2703
Conversation
…extend URI validation tests - Introduced `productionRouter` in `DummyTestRouter` to enable production mode configuration. - Updated `DispatchingInterceptor` to adjust error messages in production mode. - Expanded `DispatchingInterceptorTest` with production-specific URI validation.
…s in proxies and tests
📝 WalkthroughWalkthroughExtracted the nested Target type from AbstractServiceProxy into a top-level Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
This pull request needs "/ok-to-test" from an authorized committer. |
…n the same port; warn of default certificate also when loading it from a PEM file
…vice-proxy into target-tutorial-tls
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
core/src/main/java/com/predic8/membrane/core/transport/ssl/SSLContextCollection.java (1)
55-60: Potential NoSuchElementException when building with empty contexts.If
useCollectionis set totruebut noSSLContextinstances are added,build()creates anSSLContextCollectionwith an empty list. Subsequent calls (e.g.,wrapAcceptedSocketat line 145 callingsslContexts.getFirst()) will throwNoSuchElementException.Consider adding validation:
🛡️ Proposed fix to add validation
public SSLProvider build() { + if (sslContexts.isEmpty()) { + throw new IllegalStateException("Cannot build SSLProvider: no SSLContext was added"); + } if (sslContexts.size() > 1 || useCollection) { return new SSLContextCollection(sslContexts, dnsNames); } else return sslContexts.getFirst(); }
🧹 Nitpick comments (2)
core/src/main/java/com/predic8/membrane/core/security/KeyStoreUtil.java (1)
58-68: Drop obsoleteKeyStoreExceptionand guardcertnulls.
getDigestno longer accesses a KeyStore, so the checkedKeyStoreException(and its Javadoc) is misleading. Also consider a fail-fast null check for clearer errors.♻️ Proposed update
-import java.util.Optional; +import java.util.Objects; +import java.util.Optional; @@ - * `@throws` KeyStoreException If there's an error accessing the KeyStore. @@ - public static `@org.jetbrains.annotations.NotNull` String getDigest(Certificate cert) throws CertificateEncodingException, KeyStoreException, NoSuchAlgorithmException { - byte[] pkeEnc = cert.getEncoded(); + public static `@NotNull` String getDigest(`@NotNull` Certificate cert) throws CertificateEncodingException, NoSuchAlgorithmException { + Objects.requireNonNull(cert, "cert"); + byte[] pkeEnc = cert.getEncoded();core/src/main/java/com/predic8/membrane/core/transport/ssl/StaticSSLContext.java (1)
319-329: Consider making the warning mechanism more resilient.Two observations:
Thread safety:
defaultCertificateWarnedis accessed without synchronization. Multiple threads could simultaneously pass the check and log duplicate warnings. Consider usingAtomicBoolean:Exception propagation: A warning utility should not fail the main operation. If
getDigest()throws, the entire SSL context creation fails. Consider catching exceptions internally.♻️ Proposed resilient implementation
+import java.util.concurrent.atomic.AtomicBoolean;- private static boolean defaultCertificateWarned = false; + private static final AtomicBoolean defaultCertificateWarned = new AtomicBoolean(false);- private static void warnOfOldCertificate(Certificate cert) throws CertificateEncodingException, KeyStoreException, NoSuchAlgorithmException { - if (!defaultCertificateWarned) { + private static void warnOfOldCertificate(Certificate cert) { + if (defaultCertificateWarned.get()) { + return; + } + try { String digest = getDigest(cert); if (digest.equals(DEFAULT_CERTIFICATE_SHA256_OLD) || digest.equals(DEFAULT_CERTIFICATE_SHA256)) { - log.warn("Using Membrane with the default certificate. This is highly discouraged! " - + "Please run the generate-ssl-keys script in the conf directory."); - defaultCertificateWarned = true; + if (defaultCertificateWarned.compareAndSet(false, true)) { + log.warn("Using Membrane with the default certificate. This is highly discouraged! " + + "Please run the generate-ssl-keys script in the conf directory."); + } } + } catch (CertificateEncodingException | KeyStoreException | NoSuchAlgorithmException e) { + log.debug("Could not check for default certificate: {}", e.getMessage()); } }Note: If you adopt this change, you'll also need to remove the exception declarations from
getCertificates(line 230) if they're no longer thrown elsewhere in that method.
Summary by CodeRabbit
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.