<div dir="ltr"><div>Responses below</div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Tue, 7 Jan 2025 at 22:15, Sean Mullan <<a href="mailto:sean.mullan@oracle.com">sean.mullan@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><u></u>
<div>
<p>Some additional thoughts below.<br>
</p>
<div>On 1/4/25 3:45 AM, Tim Jacomb wrote:<br>
</div>
<blockquote type="cite">
<div>Following on from:</div>
<div><a href="https://bugs.openjdk.org/browse/JDK-8320362" target="_blank">https://bugs.openjdk.org/browse/JDK-8320362</a></div>
<div><br>
</div>
<div>It's now possible to get system roots on macOS devices in the
truststore: KeychainStore-ROOT.</div>
<div>That's quite useful.</div>
<div><br>
</div>
<div>Unfortunately it doesn't cover everything though.</div>
<div>In practice there's two issues I've found in trying to use
it:</div>
<div><br>
</div>
<div>1. It is missing custom CA certificates, (which would have
been included if Apple APIs
- SecTrustCopyCustomAnchorCertificates were used, see discussion
at
<a href="https://github.com/openjdk/jdk/pull/16722#issuecomment-1948542783" target="_blank">https://github.com/openjdk/jdk/pull/16722#issuecomment-1948542783</a>)<br>
</div>
</blockquote>
<p>I don't think you are suggesting this, but I don't think it
should include custom CA certificates if they are stored or
trusted differently than roots. <span>KeychainStore-ROOT
should represent the System Roots that have been approved by
Apple's root program. It is important that we don't change that
meaning. </span></p></div></blockquote><div>No, I'm not suggesting we change the meaning. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p><span>If there is a way to import a custom CA into System
Roots and mark it trusted, then maybe it would just work. Have
you tried that?<br></span></p></div></blockquote><div>System Roots is read-only and can't be modified by the user, (yes I have tried).</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><p><span>
</span></p>
<blockquote type="cite">
<div>2. It is missing intermediate certificates which are required
for custom CA certificates, (these are not included with
SecTrustCopyCustomAnchorCertificates although the root CAs above
are).</div>
</blockquote>
Why do you need to include intermediate CA certificates? </div></blockquote><div><br></div><div>Private CA solution that utilises intermediate, ZScaler has an intermediate CA for resigning certificates but does not have the company root CA.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Typically,
these would be sent by a TLS server and validated as part of a
certificate chain. </div></blockquote><div><br></div><div>It is also valid for them to be trusted by the OS.</div><div>For example, Chrome, Rust and Python are all capable of doing this just fine.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>If you are sending a truncated chain and
short-circuiting the validation process by trusting the intermediate
CA directly, then maybe those intermediate CAs should be treated
just like a root CA, as they really are anchors.<br></div></blockquote><div><br></div><div> Yes they are roughly, they shouldn't be set as 'trustAsRoot' though as then the chain of trust isn't verified to the root only to the intermediate, and e.g. if the root cert was removed or marked as distrusted validation would still pass if the intermediate CA was configured as a root.</div><div><br></div><div>I've implemented validation in <a href="https://github.com/openjdk/jdk/pull/22911">https://github.com/openjdk/jdk/pull/22911</a> as per <a href="https://developer.apple.com/documentation/security/sectrustsettingscopytrustsettings(_:_:_:)?language=objc">https://developer.apple.com/documentation/security/sectrustsettingscopytrustsettings(_:_:_:)?language=objc</a>.</div><div><br></div><div>Specifically "However, an empty trust settings array isn’t the same as no trust settings, where the trustSettings parameter returns NULL. No trust-settings array means “this certificate must be verifiable using a known trusted certificate”.</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
<blockquote type="cite">
<div><br>
</div>
<div>The architecture at my company that is using ZScaler MiTM
proxy is:</div>
<div>Root CA -> Intermediate 1 -> Intermediate 2 -> Leaf</div>
<div><br>
</div>
<div>Where:</div>
<div>
<ul>
<li>All certs are in admin domain kSecTrustSettingsDomainAdmin</li>
<li>Root CA is marked as always trust</li>
<li>Intermediate 1 and 2 are Unspecified</li>
</ul>
<div>Not all certificates get re-signed by Zscaler, some URLs
are bypassed.</div>
<div>So I need to be able to trust both custom CAs and the
predefined roots.</div>
<div><br>
</div>
<div>I was thinking of creating a new truststore:
KeychainStore-ALL.</div>
<div>I think it could just reuse all the existing code, and work
pretty seamlessly, (I have a separate patch for intermediate
certs not working correctly -
<a href="https://github.com/openjdk/jdk/pull/22911" target="_blank">https://github.com/openjdk/jdk/pull/22911</a>).</div>
</div>
</blockquote>
Based on my questions above, I am not sure yet whether this
Enhancement is something that would be useful.<br>
<br>
If you are proposing that we look at your contribution, have you
signed the OCA?: <a href="https://openjdk.org/guide/#sign-the-oca" target="_blank">https://openjdk.org/guide/#sign-the-oca</a>. </div></blockquote><div><br></div><div>I've requested my employer to sign, hopefully, should be resolved soon.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>But even
before we look at that, I think you need to describe the use case
more, and the motivation. Can you explain how your server
certificate is configured and how the TLS handshake fails and why?<br></div></blockquote><div><br></div><div>Which use-case are you asking about? If its about intermediate CA's with the implementation in <a href="https://github.com/openjdk/jdk/pull/22911">https://github.com/openjdk/jdk/pull/22911</a> then:</div><div><br></div><div>The use-case is so that Java is able to handle intermediate certificates in internal PKI, specifically here is with developer laptops that have an enterprise CA which is performing MiTM on most URLs.</div><div><br></div><div>There's a self-contained runnable reproducer in <a href="https://github.com/timja/openjdk-intermediate-ca-reproducer">https://github.com/timja/openjdk-intermediate-ca-reproducer</a></div><div><br></div><div>TLS handshake fails with PKIX path building error.</div><div><br></div><div>Chain is Root -> Intermediate -> Leaf in the runnable example although in our real-world use-case its Root -> Intermediate 1 -> Intermediate 2 -> Leaf</div><div>If I run the example only with Root -> Leaf then it works fine...</div><div><br></div><div>Thanks</div><div>Tim</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
<br>
Thanks,<br>
Sean<br>
<br>
<blockquote type="cite">
<div>
<div><br>
</div>
<div>It could be improved at the expense of more code to use the
Apple APIs directly (SecTrustCopyCustomAnchorCertificates) and
not read the keychain file.</div>
<div><br>
</div>
<div>What do you think?</div>
</div>
</blockquote>
</div>
</blockquote></div></div>